if (eclass != ExprClass.Unresolved)
return this;
- Expression e = DoResolve (ec);
+
+ Expression e;
+ try {
+ e = DoResolve (ec);
- if (e == null)
- return null;
+ if (e == null)
+ return null;
- if ((flags & e.ExprClassToResolveFlags) == 0) {
- e.Error_UnexpectedKind (ec, flags, loc);
- return null;
- }
+ if ((flags & e.ExprClassToResolveFlags) == 0) {
+ e.Error_UnexpectedKind (ec, flags, loc);
+ return null;
+ }
- if (e.type == null)
- throw new InternalErrorException ("Expression `{0}' didn't set its type in DoResolve", e.GetType ());
+ if (e.type == null)
+ throw new InternalErrorException ("Expression `{0}' didn't set its type in DoResolve", e.GetType ());
- return e;
+ return e;
+ } catch (Exception ex) {
+ if (loc.IsNull || Report.DebugFlags > 0 || ex is CompletionResult || ec.Report.IsDisabled)
+ throw;
+
+ ec.Report.Error (584, loc, "Internal compiler error: {0}", ex.Message);
+ return EmptyExpression.Null;
+ }
}
/// <summary>
name, arity, MemberKind.All, binding | BindingRestriction.AccessibleOnly, loc);
}
- public static MethodGroupExpr MethodLookup (CompilerContext ctx, TypeSpec container_type, TypeSpec queried_type,
- MemberKind kind, string name, int arity, Location loc)
- {
- return (MethodGroupExpr)MemberLookup (ctx, container_type, null, queried_type, name, arity,
- kind, BindingRestriction.AccessibleOnly, loc);
- }
-
/// <summary>
/// This is a wrapper for MemberLookup that is not used to "probe", but
/// to find a final definition. If the final definition is not found, we
mge.SetTypeArguments (ec, new TypeArguments (new FullNamedExpression [arity]));
}
- return mge;
+ return mge.Resolve (ec);
}
protected virtual MemberExpr Error_MemberLookupFailed (ResolveContext ec, TypeSpec type, IList<MemberSpec> members)
static Expression GetOperatorTrueOrFalse (ResolveContext ec, Expression e, bool is_true, Location loc)
{
- MethodGroupExpr operator_group;
- string mname = Operator.GetMetadataName (is_true ? Operator.OpType.True : Operator.OpType.False);
- operator_group = MethodLookup (ec.Compiler, ec.CurrentType, e.Type, MemberKind.Operator, mname, 0, loc) as MethodGroupExpr;
- if (operator_group == null)
+ var op = is_true ? Operator.OpType.True : Operator.OpType.False;
+ var methods = MemberCache.GetUserOperator (e.type, op, false);
+ if (methods == null)
return null;
+ var mg = new MethodGroupExpr (methods, e.type, loc);
+
Arguments arguments = new Arguments (1);
arguments.Add (new Argument (e));
- operator_group = operator_group.OverloadResolve (
- ec, ref arguments, false, loc);
+ mg = mg.OverloadResolve (ec, ref arguments, false, loc);
- if (operator_group == null)
+ if (mg == null)
return null;
- return new UserOperatorCall (operator_group, arguments, null, loc);
+ return new UserOperatorCall (mg, arguments, null, loc);
}
-
+
public virtual string ExprClassName
{
get {
// 'child.Type' to our target type (type)
MethodSpec GetConversionOperator (bool find_explicit)
{
- string operator_name = find_explicit ? "op_Explicit" : "op_Implicit";
-
- // Operators are always public
- var mi = TypeManager.MemberLookup (child.Type, child.Type, child.Type, MemberKind.Operator,
- BindingRestriction.None, operator_name, 0, null);
+ var op = find_explicit ? Operator.OpType.Explicit : Operator.OpType.Implicit;
+ var mi = MemberCache.GetUserOperator (child.Type, op, true);
if (mi == null){
- mi = TypeManager.MemberLookup (type, type, type, MemberKind.Operator,
- BindingRestriction.None, operator_name, 0, null);
+ mi = MemberCache.GetUserOperator (type, op, true);
}
foreach (MethodSpec oper in mi) {
- AParametersCollection pd = oper.Parameters;
+ if (oper.ReturnType != type)
+ continue;
- if (pd.Types [0] == child.Type && oper.ReturnType == type)
+ if (oper.Parameters.Types [0] == child.Type)
return oper;
}
public Expression Resolve ()
{
if (operators == null) {
- var all_oper = TypeManager.MemberLookup (TypeManager.decimal_type,
- TypeManager.decimal_type, TypeManager.decimal_type, MemberKind.Operator,
- BindingRestriction.None, "op_Explicit", 0, null);
+ var all_oper = MemberCache.GetUserOperator (TypeManager.decimal_type, Operator.OpType.Explicit, true);
operators = new Dictionary<TypeSpec, MethodSpec> ();
foreach (MethodSpec oper in all_oper) {
FullNamedExpression fne = ec.LookupNamespaceOrType (Name, Arity, loc, /*ignore_cs0104=*/ false);
if (fne != null) {
- if (HasTypeArguments && fne.Type != null && TypeManager.IsGenericType (fne.Type)) {
- GenericTypeExpr ct = new GenericTypeExpr (fne.Type, targs, loc);
- return ct.ResolveAsTypeStep (ec, false);
+ if (fne.Type != null && Arity > 0) {
+ if (HasTypeArguments) {
+ GenericTypeExpr ct = new GenericTypeExpr (fne.Type, targs, loc);
+ return ct.ResolveAsTypeStep (ec, false);
+ }
+
+ return new GenericOpenTypeExpr (fne.Type, loc);
}
- return fne;
+ //
+ // dynamic namespace is ignored when dynamic is allowed (does not apply to types)
+ //
+ if (!(fne is Namespace))
+ return fne;
}
- if (!HasTypeArguments && Name == "dynamic" &&
- RootContext.Version > LanguageVersion.V_3 &&
- RootContext.MetadataCompatibilityVersion > MetadataVersion.v2) {
-
+ if (Arity == 0 && Name == "dynamic" && RootContext.Version > LanguageVersion.V_3) {
if (!PredefinedAttributes.Get.Dynamic.IsDefined) {
ec.Compiler.Report.Error (1980, Location,
"Dynamic keyword requires `{0}' to be defined. Are you missing System.Core.dll assembly reference?",
return new DynamicTypeExpr (loc);
}
+ if (fne != null)
+ return fne;
+
if (silent || errors != ec.Compiler.Report.Errors)
return null;
}
}
- if (HasTypeArguments && e != null)
+ if (e != null && Arity > 0)
e.Error_TypeArgumentsCannotBeUsed (ec.Report, loc, null, 0);
return e;
else
e = e.Resolve (ec);
- if (HasTypeArguments && e != null)
+ if (e != null && Arity > 0)
e.Error_TypeArgumentsCannotBeUsed (ec.Report, loc, null, 0);
return e;
// TypeSpec almost_matched_type = null;
// IList<MemberSpec> almost_matched = null;
for (TypeSpec lookup_ds = ec.CurrentType; lookup_ds != null; lookup_ds = lookup_ds.DeclaringType) {
- e = MemberLookup (ec.Compiler, ec.CurrentType, lookup_ds, Name, arity, BindingRestriction.NoOverrides, loc);
+ e = MemberLookup (ec.Compiler, ec.CurrentType, lookup_ds, Name, arity, BindingRestriction.DefaultMemberLookup, loc);
if (e != null) {
PropertyExpr pe = e as PropertyExpr;
if (pe != null) {
}
}
- //
- // Used to create types from a fully qualified name. These are just used
- // by the parser to setup the core types.
- //
- public sealed class TypeLookupExpression : TypeExpr {
-
- public TypeLookupExpression (TypeSpec type)
- {
- eclass = ExprClass.Type;
- this.type = type;
- }
-
- protected override TypeExpr DoResolveAsTypeStep (IMemberContext ec)
- {
- return this;
- }
- }
-
/// <summary>
/// This class denotes an expression which evaluates to a member
/// of a struct or a class.
/// </summary>
public abstract class MemberExpr : Expression
{
- protected bool is_base;
-
//
// An instance expression associated with this member, if it's a
// non-static member
// When base.member is used
//
public bool IsBase {
- get { return is_base; }
- set { is_base = value; }
+ get { return InstanceExpression is BaseThis; }
}
/// <summary>
get;
}
- public static void Error_BaseAccessInExpressionTree (ResolveContext ec, Location loc)
+ //
+ // Converts best base candidate for virtual method starting from QueriedBaseType
+ //
+ protected MethodSpec CandidateToBaseOverride (ResolveContext rc, MethodSpec method)
{
- ec.Report.Error (831, loc, "An expression tree may not contain a base access");
+ //
+ // Only when base.member is used and method is virtual
+ //
+ if (!IsBase || method.DeclaringType == InstanceExpression.Type)
+ return method;
+
+ //
+ // Overload resulution works on virtual or non-virtual members only (no overrides). That
+ // means for base.member access we have to find the closest match after we found best candidate
+ //
+ if ((method.Modifiers & (Modifiers.ABSTRACT | Modifiers.VIRTUAL | Modifiers.STATIC)) != Modifiers.STATIC) {
+ var base_override = MemberCache.FindMember (InstanceExpression.Type, new MemberFilter (method), BindingRestriction.InstanceOnly) as MethodSpec;
+ if (base_override != null && base_override.DeclaringType != method.DeclaringType) {
+ if (base_override.IsGeneric)
+ base_override = base_override.MakeGenericMethod (method.TypeArguments);
+
+ if (rc.CurrentAnonymousMethod != null)
+ throw new NotImplementedException ("base call hoisting");
+
+ return base_override;
+ }
+ }
+
+ return method;
}
//
AttributeTester.Report_ObsoleteMessage (oa, InstanceExpression.GetSignatureForError (), loc, rc.Report);
}
} else {
- rc.Report.Error (176, loc,
- "Static member `{0}' cannot be accessed with an instance reference, qualify it with a type name instead",
- GetSignatureForError ());
+ var runtime_expr = InstanceExpression as RuntimeValueExpression;
+ if (runtime_expr == null || !runtime_expr.IsSuggestionOnly) {
+ rc.Report.Error (176, loc,
+ "Static member `{0}' cannot be accessed with an instance reference, qualify it with a type name instead",
+ GetSignatureForError ());
+ }
}
InstanceExpression = null;
}
if (InstanceExpression == null || InstanceExpression is TypeExpr) {
- if (!This.IsThisAvailable (rc, true) || InstanceExpression is TypeExpr) {
+ if (InstanceExpression != null || !This.IsThisAvailable (rc, true)) {
if (rc.HasSet (ResolveContext.Options.FieldInitializerScope))
rc.Report.Error (236, loc,
"A field initializer cannot reference the nonstatic field, method, or property `{0}'",
public virtual MemberExpr ResolveMemberAccess (ResolveContext ec, Expression left, SimpleName original)
{
- Constant c = left as Constant;
- if (c != null && c.GetValue () == null) {
+ if (left != null && left.IsNull && TypeManager.IsReferenceType (left.Type)) {
ec.Report.Warning (1720, 1, left.Location,
"Expression will always cause a `{0}'", "System.NullReferenceException");
}
{
public interface IErrorHandler
{
- bool AmbiguousCall (ResolveContext ec, MethodSpec ambiguous);
+ bool AmbiguousCall (ResolveContext ec, MethodGroupExpr mg, MethodSpec ambiguous);
bool NoExactMatch (ResolveContext ec, MethodSpec method);
}
public IErrorHandler CustomErrorHandler;
- public IList<MemberSpec> Methods;
+ protected IList<MemberSpec> Methods;
MethodSpec best_candidate;
// TODO: make private
public TypeArguments type_arguments;
queried_type = type;
}
- public override TypeSpec DeclaringType {
+ #region Properties
+
+ public MethodSpec BestCandidate {
get {
- return queried_type;
+ return best_candidate;
}
}
- public MethodSpec BestCandidate {
+ public override TypeSpec DeclaringType {
get {
- return best_candidate;
+ return queried_type;
}
}
}
}
- public override string GetSignatureForError ()
- {
- if (best_candidate != null)
- return best_candidate.GetSignatureForError ();
-
- return Methods.First ().GetSignatureForError ();
- }
-
- public override string Name {
- get {
- return Methods.First ().Name;
- }
- }
-
public override bool IsInstance {
get {
if (best_candidate != null)
}
}
- public static explicit operator MethodSpec (MethodGroupExpr mg)
+ public override string Name {
+ get {
+ if (best_candidate != null)
+ return best_candidate.Name;
+
+ // TODO: throw ?
+ return Methods.First ().Name;
+ }
+ }
+
+ #endregion
+
+ //
+ // When best candidate is already know this factory can be used
+ // to avoid expensive overload resolution to be called
+ //
+ // NOTE: InstanceExpression has to be set manually
+ //
+ public static MethodGroupExpr CreatePredefined (MethodSpec best, TypeSpec queriedType, Location loc)
+ {
+ return new MethodGroupExpr (best, queriedType, loc) {
+ best_candidate = best
+ };
+ }
+
+ public override string GetSignatureForError ()
{
- return mg.best_candidate;
+ if (best_candidate != null)
+ return best_candidate.GetSignatureForError ();
+
+ return Methods.First ().GetSignatureForError ();
}
//
override public void Emit (EmitContext ec)
{
throw new NotSupportedException ();
- // ReportUsageError ();
}
public void EmitCall (EmitContext ec, Arguments arguments)
{
- Invocation.EmitCall (ec, IsBase, InstanceExpression, best_candidate, arguments, loc);
+ Invocation.EmitCall (ec, InstanceExpression, best_candidate, arguments, loc);
}
void Error_AmbiguousCall (ResolveContext ec, MethodSpec ambiguous)
{
- if (CustomErrorHandler != null && CustomErrorHandler.AmbiguousCall (ec, ambiguous))
+ if (CustomErrorHandler != null && CustomErrorHandler.AmbiguousCall (ec, this, ambiguous))
return;
ec.Report.SymbolRelatedToPreviousError (best_candidate);
protected virtual IList<MemberSpec> GetBaseTypeMethods (ResolveContext rc, TypeSpec type)
{
var arity = type_arguments == null ? -1 : type_arguments.Count;
+
return TypeManager.MemberLookup (rc.CurrentType, null, type,
- MemberKind.Method, BindingRestriction.AccessibleOnly | BindingRestriction.NoOverrides,
+ MemberKind.Method, BindingRestriction.AccessibleOnly | BindingRestriction.DefaultMemberLookup,
Name, arity, null);
}
bool GetBaseTypeMethods (ResolveContext rc)
{
- var base_type = Methods.First ().DeclaringType.BaseType;
+ var base_type = Methods [0].DeclaringType.BaseType;
if (base_type == null)
return false;
// Types have to be identical when ref or out modifer is used
//
if (arg_mod != 0 || param_mod != 0) {
- if (TypeManager.HasElementType (parameter))
- parameter = TypeManager.GetElementType (parameter);
-
- TypeSpec a_type = argument.Type;
- if (TypeManager.HasElementType (a_type))
- a_type = TypeManager.GetElementType (a_type);
-
- if (a_type != parameter) {
- if (a_type == InternalType.Dynamic)
+ if (argument.Type != parameter) {
+ if (argument.Type == InternalType.Dynamic)
return 0;
return 2;
return 0;
}
- public static MethodGroupExpr MakeUnionSet (MethodGroupExpr mg1, MethodGroupExpr mg2, Location loc)
- {
- if (mg1 == null) {
- if (mg2 == null)
- return null;
- return mg2;
- }
-
- if (mg2 == null)
- return mg1;
-
- var all = new List<MemberSpec> (mg1.Methods);
- foreach (MethodSpec m in mg2.Methods){
- if (!TypeManager.ArrayContainsMethod (all, m, false))
- all.Add (m);
- }
-
- return new MethodGroupExpr (all, null, loc);
- }
-
static TypeSpec MoreSpecific (TypeSpec p, TypeSpec q)
{
if (TypeManager.IsGenericParameter (p) && !TypeManager.IsGenericParameter (q))
public virtual MethodGroupExpr OverloadResolve (ResolveContext ec, ref Arguments Arguments,
bool may_fail, Location loc)
{
+ // TODO: causes some issues with linq
+ //if (best_candidate != null)
+ // return this;
+
var candidates = new List<MethodSpec> (2);
List<MethodSpec> params_candidates = null;
//
var msg_recorder = new SessionReportPrinter ();
var prev_recorder = ec.Report.SetPrinter (msg_recorder);
-
- do {
- //
- // Methods in a base class are not candidates if any method in a derived
- // class is applicable
- //
- int best_candidate_rate = int.MaxValue;
-
- foreach (var member in Methods) {
- var m = member as MethodSpec;
- if (m == null) {
- // TODO: It's wrong when non-member is before applicable method
- // TODO: Should report only when at least 1 from the batch is applicable
- if (candidates.Count != 0) {
- ec.Report.SymbolRelatedToPreviousError (candidates [0]);
- ec.Report.SymbolRelatedToPreviousError (member);
- ec.Report.Warning (467, 2, loc, "Ambiguity between method `{0}' and non-method `{1}'. Using method `{0}'",
- candidates[0].GetSignatureForError (), member.GetSignatureForError ());
- }
- continue;
- }
-
+ try {
+ do {
//
- // Check if candidate is applicable (section 14.4.2.1)
+ // Methods in a base class are not candidates if any method in a derived
+ // class is applicable
//
- bool params_expanded_form = false;
- int candidate_rate = IsApplicable (ec, ref candidate_args, arg_count, ref m, ref params_expanded_form);
-
- if (candidate_rate < best_candidate_rate) {
- best_candidate_rate = candidate_rate;
- best_candidate = m;
- }
+ int best_candidate_rate = int.MaxValue;
+
+ foreach (var member in Methods) {
+ var m = member as MethodSpec;
+ if (m == null) {
+ // TODO: It's wrong when non-member is before applicable method
+ // TODO: Should report only when at least 1 from the batch is applicable
+ if (candidates.Count != 0) {
+ ec.Report.SymbolRelatedToPreviousError (candidates[0]);
+ ec.Report.SymbolRelatedToPreviousError (member);
+ ec.Report.Warning (467, 2, loc, "Ambiguity between method `{0}' and non-method `{1}'. Using method `{0}'",
+ candidates[0].GetSignatureForError (), member.GetSignatureForError ());
+ }
+ continue;
+ }
- if (params_expanded_form) {
- if (params_candidates == null)
- params_candidates = new List<MethodSpec> (2);
- params_candidates.Add (m);
- }
+ //
+ // Check if candidate is applicable (section 14.4.2.1)
+ //
+ bool params_expanded_form = false;
+ int candidate_rate = IsApplicable (ec, ref candidate_args, arg_count, ref m, ref params_expanded_form);
- if (candidate_args != Arguments) {
- if (candidates_expanded == null)
- candidates_expanded = new Dictionary<MethodSpec, Arguments> (2);
+ if (candidate_rate < best_candidate_rate) {
+ best_candidate_rate = candidate_rate;
+ best_candidate = m;
+ }
- candidates_expanded.Add (m, candidate_args);
- candidate_args = Arguments;
- }
+ if (params_expanded_form) {
+ if (params_candidates == null)
+ params_candidates = new List<MethodSpec> (2);
+ params_candidates.Add (m);
+ }
- if (candidate_rate != 0 || has_inaccessible_candidates_only) {
- if (msg_recorder != null)
- msg_recorder.EndSession ();
- continue;
- }
+ if (candidate_args != Arguments) {
+ if (candidates_expanded == null)
+ candidates_expanded = new Dictionary<MethodSpec, Arguments> (2);
- msg_recorder = null;
- candidates.Add (m);
- }
- } while (candidates.Count == 0 && GetBaseTypeMethods (ec));
+ candidates_expanded.Add (m, candidate_args);
+ candidate_args = Arguments;
+ }
- ec.Report.SetPrinter (prev_recorder);
- if (msg_recorder != null && !msg_recorder.IsEmpty) {
- if (!may_fail)
- msg_recorder.Merge (prev_recorder);
+ if (candidate_rate != 0 || has_inaccessible_candidates_only) {
+ if (msg_recorder != null)
+ msg_recorder.EndSession ();
+ continue;
+ }
- return null;
+ msg_recorder = null;
+ candidates.Add (m);
+ }
+ } while (candidates.Count == 0 && GetBaseTypeMethods (ec));
+ } finally {
+ ec.Report.SetPrinter (prev_recorder);
}
int candidate_top = candidates.Count;
if (ex_method_lookup != null) {
ex_method_lookup.ExtensionExpression = InstanceExpression.Resolve (ec);
ex_method_lookup.SetTypeArguments (ec, type_arguments);
- return ex_method_lookup.OverloadResolve (ec, ref Arguments, may_fail, loc);
+ var emg = ex_method_lookup.OverloadResolve (ec, ref Arguments, may_fail, loc);
+ if (emg != null)
+ return emg;
}
}
-
+
+ if (msg_recorder != null && !msg_recorder.IsEmpty) {
+ if (!may_fail)
+ msg_recorder.Merge (prev_recorder);
+
+ return null;
+ }
+
if (may_fail)
return null;
return this;
}
+ best_candidate = CandidateToBaseOverride (ec, best_candidate);
+
//
// And now check if the arguments are all
// compatible, perform conversions if
return null;
if (best_candidate.Kind == MemberKind.Method) {
- if (InstanceExpression != null && best_candidate.IsStatic) {
- InstanceExpression = ProbeIdenticalTypeName (ec, InstanceExpression, simple_name);
+ if (InstanceExpression != null) {
+ if (best_candidate.IsStatic && simple_name != null) {
+ InstanceExpression = ProbeIdenticalTypeName (ec, InstanceExpression, simple_name);
+ }
+
+ InstanceExpression.Resolve (ec);
}
ResolveInstanceExpression (ec);
//
if (params_initializers != null) {
arguments.Add (new Argument (
- new ArrayCreation (new TypeExpression (pt, loc), "[]", params_initializers, loc).Resolve (ec)));
+ new ArrayCreation (new TypeExpression (pt, loc), params_initializers, loc).Resolve (ec)));
arg_count++;
}
if (!rc.IsObsolete) {
var oa = constant.GetAttributeObsolete ();
if (oa != null)
- AttributeTester.Report_ObsoleteMessage (oa, TypeManager.GetFullNameSignature (constant), loc, rc.Report);
+ AttributeTester.Report_ObsoleteMessage (oa, constant.GetSignatureForError (), loc, rc.Report);
}
- // Constants are resolved on-demand
- var c = constant.Value.Resolve (rc) as Constant;
+ var c = constant.GetConstant (rc);
// Creates reference expression to the constant value
return Constant.CreateConstant (rc, constant.MemberType, c.GetValue (), loc);
public override string GetSignatureForError ()
{
- return TypeManager.GetFullNameSignature (constant);
+ return constant.GetSignatureForError ();
}
}
public class PropertyExpr : MemberExpr, IDynamicAssign
{
PropertySpec spec;
+
+ // getter and setter can be different for base calls
+ MethodSpec getter, setter;
+
TypeArguments targs;
-
LocalTemporary temp;
bool prepared;
}
}
+ public PropertySpec PropertyInfo {
+ get {
+ return spec;
+ }
+ }
+
#endregion
public override Expression CreateExpressionTree (ResolveContext ec)
return CreateExpressionFactoryCall (ec, "ArrayLength", args);
}
- if (is_base) {
- Error_BaseAccessInExpressionTree (ec, loc);
- return null;
- }
-
args = new Arguments (2);
if (InstanceExpression == null)
args.Add (new Argument (new NullLiteral (loc)));
else
args.Add (new Argument (InstanceExpression.CreateExpressionTree (ec)));
- args.Add (new Argument (new TypeOfMethod (spec.Get, loc)));
+ args.Add (new Argument (new TypeOfMethod (getter, loc)));
return CreateExpressionFactoryCall (ec, "Property", args);
}
public Expression CreateSetterTypeOfExpression ()
{
- return new TypeOfMethod (spec.Set, loc);
+ return new TypeOfMethod (setter, loc);
}
public override TypeSpec DeclaringType {
public SLE.Expression MakeAssignExpression (BuilderContext ctx)
{
- return SLE.Expression.Property (InstanceExpression.MakeExpression (ctx), (MethodInfo) spec.Set.GetMetaInfo ());
+ return SLE.Expression.Property (InstanceExpression.MakeExpression (ctx), (MethodInfo) setter.GetMetaInfo ());
}
public override SLE.Expression MakeExpression (BuilderContext ctx)
{
- return SLE.Expression.Property (InstanceExpression.MakeExpression (ctx), (MethodInfo) spec.Get.GetMetaInfo ());
- }
-
- public PropertySpec PropertyInfo {
- get {
- return spec;
- }
+ return SLE.Expression.Property (InstanceExpression.MakeExpression (ctx), (MethodInfo) getter.GetMetaInfo ());
}
bool InstanceResolve (ResolveContext ec, bool lvalue_instance, bool must_do_cs1540_check)
InstanceExpression.CheckMarshalByRefAccess (ec);
if (must_do_cs1540_check && (InstanceExpression != EmptyExpression.Null) &&
+ !(InstanceExpression is BaseThis) &&
!TypeManager.IsInstantiationOfSameGenericType (InstanceExpression.Type, ec.CurrentType) &&
!TypeManager.IsNestedChildOf (ec.CurrentType, InstanceExpression.Type) &&
!TypeManager.IsSubclassOf (InstanceExpression.Type, ec.CurrentType)) {
if (!InstanceResolve (ec, false, must_do_cs1540_check))
return null;
+ if (type.IsPointer && !ec.IsUnsafe) {
+ UnsafeError (ec, loc);
+ }
+
+ getter = CandidateToBaseOverride (ec, spec.Get);
+
//
// Only base will allow this invocation to happen.
//
- if (IsBase && spec.IsAbstract) {
+ if (IsBase && getter.IsAbstract) {
Error_CannotCallAbstractBase (ec, spec.GetSignatureForError ());
}
- if (type.IsPointer && !ec.IsUnsafe){
- UnsafeError (ec, loc);
- }
-
if (!ec.IsObsolete) {
ObsoleteAttribute oa = spec.GetAttributeObsolete ();
if (oa != null)
if (!InstanceResolve (ec, TypeManager.IsStruct (spec.DeclaringType), must_do_cs1540_check))
return null;
+
+ setter = CandidateToBaseOverride (ec, spec.Set);
//
// Only base will allow this invocation to happen.
//
- if (IsBase && spec.IsAbstract){
- Error_CannotCallAbstractBase (ec, TypeManager.GetFullNameSignature (spec));
+ if (IsBase && setter.IsAbstract){
+ Error_CannotCallAbstractBase (ec, setter.GetSignatureForError ());
}
if (spec.MemberType.IsPointer && !ec.IsUnsafe) {
return;
}
- Invocation.EmitCall (ec, IsBase, InstanceExpression, spec.Get, null, loc, prepared, false);
+ Invocation.EmitCall (ec, InstanceExpression, getter, null, loc, prepared, false);
if (leave_copy) {
ec.Emit (OpCodes.Dup);
Arguments args = new Arguments (1);
args.Add (new Argument (my_source));
- Invocation.EmitCall (ec, IsBase, InstanceExpression, spec.Set, args, loc, false, prepared);
+ Invocation.EmitCall (ec, InstanceExpression, setter, args, loc, false, prepared);
if (temp != null) {
temp.Emit (ec);
TypeManager.IsNestedChildOf(ec.CurrentType, spec.DeclaringType)) {
// TODO: Breaks dynamic binder as currect context fields are imported and not compiled
- EventField mi = spec.MemberDefinition as EventField;
+ // EventField mi = spec.MemberDefinition as EventField;
+
+ if (spec.BackingField != null) {
+ spec.MemberDefinition.SetIsUsed ();
- if (mi != null && mi.HasBackingField) {
- mi.SetIsUsed ();
- if (!ec.IsObsolete)
- mi.CheckObsoleteness (loc);
+ if (!ec.IsObsolete) {
+ ObsoleteAttribute oa = spec.GetAttributeObsolete ();
+ if (oa != null)
+ AttributeTester.Report_ObsoleteMessage (oa, spec.GetSignatureForError (), loc, ec.Report);
+ }
- if ((mi.ModFlags & (Modifiers.ABSTRACT | Modifiers.EXTERN)) != 0 && !ec.HasSet (ResolveContext.Options.CompoundAssignmentScope))
+ if ((spec.Modifiers & (Modifiers.ABSTRACT | Modifiers.EXTERN)) != 0 && !ec.HasSet (ResolveContext.Options.CompoundAssignmentScope))
Error_AssignmentEventOnly (ec);
- FieldExpr ml = new FieldExpr (mi.BackingField, loc);
+ FieldExpr ml = new FieldExpr (spec.BackingField, loc);
InstanceExpression = null;
bool InstanceResolve (ResolveContext ec, bool must_do_cs1540_check)
{
+ if (IsBase && spec.IsAbstract) {
+ Error_CannotCallAbstractBase (ec, spec.GetSignatureForError ());
+ }
+
if (!ResolveInstanceExpression (ec))
return true;
- if (IsBase && spec.IsAbstract) {
- Error_CannotCallAbstractBase (ec, TypeManager.CSharpSignature(spec));
- return false;
- }
+ InstanceExpression.Resolve (ec);
//
// This is using the same mechanism as the CS1540 check in PropertyExpr.
{
Arguments args = new Arguments (1);
args.Add (new Argument (source));
- Invocation.EmitCall (ec, IsBase, InstanceExpression,
- is_add ? spec.AccessorAdd : spec.AccessorRemove,
- args, loc);
+ Invocation.EmitCall (ec, InstanceExpression, is_add ? spec.AccessorAdd : spec.AccessorRemove, args, loc);
}
}