return e;
} catch (Exception ex) {
- if (loc.IsNull || Report.DebugFlags > 0 || ex is CompletionResult)
+ if (loc.IsNull || Report.DebugFlags > 0 || ex is CompletionResult || ec.Report.IsDisabled)
throw;
ec.Report.Error (584, loc, "Internal compiler error: {0}", ex.Message);
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) {
// When base.member is used
//
public bool IsBase {
- get { return QueriedBaseType != null; }
+ get { return InstanceExpression is BaseThis; }
}
- //
- // A type used for base.member lookup or null
- //
- public TypeSpec QueriedBaseType { get; set; }
-
/// <summary>
/// Whether this is an instance member.
/// </summary>
get;
}
- public static void Error_BaseAccessInExpressionTree (ResolveContext ec, Location loc)
- {
- ec.Report.Error (831, loc, "An expression tree may not contain a base access");
- }
-
//
// Converts best base candidate for virtual method starting from QueriedBaseType
//
- protected MethodSpec CandidateToBaseOverride (MethodSpec method)
+ protected MethodSpec CandidateToBaseOverride (ResolveContext rc, MethodSpec method)
{
//
- // Only when base.member is used
+ // Only when base.member is used and method is virtual
//
- if (QueriedBaseType == null || method.DeclaringType == QueriedBaseType)
+ 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 (QueriedBaseType, new MemberFilter (method), BindingRestriction.InstanceOnly) as MethodSpec;
+ 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)
- return base_override.MakeGenericMethod (method.TypeArguments);
+ base_override = base_override.MakeGenericMethod (method.TypeArguments);
+
+ if (rc.CurrentAnonymousMethod != null)
+ throw new NotImplementedException ("base call hoisting");
return base_override;
}
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 mg.best_candidate;
+ return new MethodGroupExpr (best, queriedType, loc) {
+ best_candidate = best
+ };
+ }
+
+ public override string GetSignatureForError ()
+ {
+ 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);
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);
}
// 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;
return this;
}
- if (IsBase)
- best_candidate = CandidateToBaseOverride (best_candidate);
+ best_candidate = CandidateToBaseOverride (ec, best_candidate);
//
// And now check if the arguments are all
if (best_candidate.Kind == MemberKind.Method) {
if (InstanceExpression != null) {
- if (best_candidate.IsStatic) {
+ if (best_candidate.IsStatic && simple_name != null) {
InstanceExpression = ProbeIdenticalTypeName (ec, InstanceExpression, simple_name);
}
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 ();
}
}
return CreateExpressionFactoryCall (ec, "ArrayLength", args);
}
- if (IsBase) {
- 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 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 ());
+ 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)) {
UnsafeError (ec, loc);
}
- getter = CandidateToBaseOverride (spec.Get);
+ getter = CandidateToBaseOverride (ec, spec.Get);
//
// Only base will allow this invocation to happen.
if (!InstanceResolve (ec, TypeManager.IsStruct (spec.DeclaringType), must_do_cs1540_check))
return null;
- setter = CandidateToBaseOverride (spec.Set);
+ setter = CandidateToBaseOverride (ec, spec.Set);
//
// Only base will allow this invocation to happen.
return;
}
- Invocation.EmitCall (ec, IsBase, InstanceExpression, getter, 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, setter, 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 (mi != null && mi.HasBackingField) {
- mi.SetIsUsed ();
- if (!ec.IsObsolete)
- mi.CheckObsoleteness (loc);
+ if (spec.BackingField != null) {
+ spec.MemberDefinition.SetIsUsed ();
+
+ 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;
{
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);
}
}