X-Git-Url: http://wien.tomnetworks.com/gitweb/?a=blobdiff_plain;f=mcs%2Fmcs%2Fecore.cs;h=4316031cbaf9573d09dd945ca01ddf092f02e255;hb=76ce601441e821a12585ae269d29fa34c2143864;hp=99671878955cae0bd44f5c92e69b0815b1c08ceb;hpb=6f47ef4a710d1326a11eccb5074660c1d4bcb920;p=mono.git diff --git a/mcs/mcs/ecore.cs b/mcs/mcs/ecore.cs index 99671878955..4316031cbaf 100644 --- a/mcs/mcs/ecore.cs +++ b/mcs/mcs/ecore.cs @@ -183,68 +183,19 @@ namespace Mono.CSharp { // This is used if the expression should be resolved as a type or namespace name. // the default implementation fails. // - public virtual FullNamedExpression ResolveAsTypeStep (IMemberContext rc, bool silent) + public virtual TypeSpec ResolveAsType (IMemberContext mc) { - if (!silent) { - ResolveContext ec = new ResolveContext (rc); - Expression e = Resolve (ec); - if (e != null) - e.Error_UnexpectedKind (ec, ResolveFlags.Type, loc); - } + ResolveContext ec = new ResolveContext (mc); + Expression e = Resolve (ec); + if (e != null) + e.Error_UnexpectedKind (ec, ResolveFlags.Type, loc); return null; } - // - // This is used to resolve the expression as a type, a null - // value will be returned if the expression is not a type - // reference - // - public virtual TypeExpr ResolveAsTypeTerminal (IMemberContext ec , bool silent) - { - int errors = ec.Compiler.Report.Errors; - - FullNamedExpression fne = ResolveAsTypeStep (ec, silent); - - if (fne == null) - return null; - - TypeExpr te = fne as TypeExpr; - if (te == null) { - if (!silent && errors == ec.Compiler.Report.Errors) - fne.Error_UnexpectedKind (ec.Compiler.Report, null, "type", loc); - return null; - } - - if (!te.type.IsAccessible (ec.CurrentType)) { - ec.Compiler.Report.SymbolRelatedToPreviousError (te.Type); - ErrorIsInaccesible (ec, te.Type.GetSignatureForError (), loc); - } - - te.loc = loc; - - var dep = te.type.GetMissingDependencies (); - if (dep != null) { - ImportedTypeDefinition.Error_MissingDependency (ec.Compiler, dep, loc); - } - - // - // Obsolete checks cannot be done when resolving base context as they - // require type dependecies to be set but we are just resolving them - // - if (!silent && !(ec is TypeContainer.BaseContext)) { - ObsoleteAttribute obsolete_attr = te.Type.GetAttributeObsolete (); - if (obsolete_attr != null && !ec.IsObsolete) { - AttributeTester.Report_ObsoleteMessage (obsolete_attr, te.GetSignatureForError (), Location, ec.Compiler.Report); - } - } - - return te; - } - public static void ErrorIsInaccesible (IMemberContext rc, string member, Location loc) { - rc.Compiler.Report.Error (122, loc, "`{0}' is inaccessible due to its protection level", member); + rc.Module.Compiler.Report.Error (122, loc, "`{0}' is inaccessible due to its protection level", member); } public void Error_ExpressionMustBeConstant (ResolveContext rc, Location loc, string e_name) @@ -285,28 +236,16 @@ namespace Mono.CSharp { if (type == InternalType.AnonymousMethod) return; -/* - if (TypeManager.IsGenericParameter (Type) && TypeManager.IsGenericParameter (target) && type.Name == target.Name) { - string sig1 = type.DeclaringMethod == null ? - TypeManager.CSharpName (type.DeclaringType) : - TypeManager.CSharpSignature (type.DeclaringMethod); - string sig2 = target.DeclaringMethod == null ? - TypeManager.CSharpName (target.DeclaringType) : - TypeManager.CSharpSignature (target.DeclaringMethod); - ec.Report.ExtraInformation (loc, - String.Format ( - "The generic parameter `{0}' of `{1}' cannot be converted to the generic parameter `{0}' of `{2}' (in the previous ", - Type.Name, sig1, sig2)); - } else if (Type.MetaInfo.FullName == target.MetaInfo.FullName) { - ec.Report.ExtraInformation (loc, - String.Format ( - "The type `{0}' has two conflicting definitions, one comes from `{1}' and the other from `{2}' (in the previous ", - Type.MetaInfo.FullName, Type.Assembly.FullName, target.Assembly.FullName)); - } -*/ + string from_type = type.GetSignatureForError (); + string to_type = target.GetSignatureForError (); + if (from_type == to_type) { + from_type = type.GetSignatureForErrorIncludingAssemblyName (); + to_type = target.GetSignatureForErrorIncludingAssemblyName (); + } + if (expl) { ec.Report.Error (30, loc, "Cannot convert type `{0}' to `{1}'", - TypeManager.CSharpName (type), TypeManager.CSharpName (target)); + from_type, to_type); return; } @@ -315,20 +254,20 @@ namespace Mono.CSharp { ec.Report.EnableReporting (); if (expl_exists) { - ec.Report.Error (266, loc, "Cannot implicitly convert type `{0}' to `{1}'. " + - "An explicit conversion exists (are you missing a cast?)", - TypeManager.CSharpName (Type), TypeManager.CSharpName (target)); - return; + ec.Report.Error (266, loc, + "Cannot implicitly convert type `{0}' to `{1}'. An explicit conversion exists (are you missing a cast?)", + from_type, to_type); + } else { + ec.Report.Error (29, loc, "Cannot implicitly convert type `{0}' to `{1}'", + from_type, to_type); } - - ec.Report.Error (29, loc, "Cannot implicitly convert type `{0}' to `{1}'", - type.GetSignatureForError (), target.GetSignatureForError ()); } - public void Error_TypeArgumentsCannotBeUsed (Report report, Location loc, MemberSpec member, int arity) + public void Error_TypeArgumentsCannotBeUsed (IMemberContext context, MemberSpec member, int arity, Location loc) { // Better message for possible generic expressions if (member != null && (member.Kind & MemberKind.GenericMask) != 0) { + var report = context.Module.Compiler.Report; report.SymbolRelatedToPreviousError (member); if (member is TypeSpec) member = ((TypeSpec) member).GetDefinition (); @@ -344,13 +283,13 @@ namespace Mono.CSharp { name, member.GetSignatureForError ()); } } else { - Error_TypeArgumentsCannotBeUsed (report, ExprClassName, GetSignatureForError (), loc); + Error_TypeArgumentsCannotBeUsed (context, ExprClassName, GetSignatureForError (), loc); } } - public void Error_TypeArgumentsCannotBeUsed (Report report, string exprType, string name, Location loc) + public void Error_TypeArgumentsCannotBeUsed (IMemberContext context, string exprType, string name, Location loc) { - report.Error (307, loc, "The {0} `{1}' cannot be used with type arguments", + context.Module.Compiler.Report.Error (307, loc, "The {0} `{1}' cannot be used with type arguments", exprType, name); } @@ -432,7 +371,7 @@ namespace Mono.CSharp { return e; } catch (Exception ex) { - if (loc.IsNull || Report.DebugFlags > 0 || ex is CompletionResult || ec.Report.IsDisabled) + if (loc.IsNull || ec.Module.Compiler.Settings.DebugFlags > 0 || ex is CompletionResult || ec.Report.IsDisabled) throw; ec.Report.Error (584, loc, "Internal compiler error: {0}", ex.Message); @@ -459,7 +398,7 @@ namespace Mono.CSharp { public Expression ResolveLValue (ResolveContext ec, Expression right_side) { int errors = ec.Report.Errors; - bool out_access = right_side == EmptyExpression.OutAccess.Instance; + bool out_access = right_side == EmptyExpression.OutAccess; Expression e = DoResolveLValue (ec, right_side); @@ -493,7 +432,7 @@ namespace Mono.CSharp { public virtual void EncodeAttributeValue (IMemberContext rc, AttributeEncoder enc, TypeSpec targetType) { - rc.Compiler.Report.Error (182, loc, + rc.Module.Compiler.Report.Error (182, loc, "An attribute argument must be a constant expression, typeof expression or array creation expression"); } @@ -573,7 +512,15 @@ namespace Mono.CSharp { } var r = new OverloadResolver (ctors, OverloadResolver.Restrictions.NoBaseMembers, loc); - return r.ResolveMember (rc, ref args); + var ctor = r.ResolveMember (rc, ref args); + if (ctor == null) + return null; + + if ((ctor.Modifiers & Modifiers.PROTECTED) != 0 && !rc.HasSet (ResolveContext.Options.BaseInitializer)) { + MemberExpr.CheckProtectedMemberAccess (rc, ctor, ctor.DeclaringType, loc); + } + + return ctor; } [Flags] @@ -589,7 +536,7 @@ namespace Mono.CSharp { // Lookup type `queried_type' for code in class `container_type' with a qualifier of // `qualifier_type' or null to lookup members in the current class. // - public static Expression MemberLookup (ResolveContext rc, TypeSpec currentType, TypeSpec queried_type, string name, int arity, MemberLookupRestrictions restrictions, Location loc) + public static Expression MemberLookup (IMemberContext rc, bool errorMode, TypeSpec queried_type, string name, int arity, MemberLookupRestrictions restrictions, Location loc) { var members = MemberCache.FindMembers (queried_type, name, false); if (members == null) @@ -597,7 +544,6 @@ namespace Mono.CSharp { MemberSpec non_method = null; MemberSpec ambig_non_method = null; - currentType = currentType ?? InternalType.FakeInternalType; do { for (int i = 0; i < members.Count; ++i) { var member = members[i]; @@ -609,8 +555,8 @@ namespace Mono.CSharp { if ((arity > 0 || (restrictions & MemberLookupRestrictions.ExactArity) != 0) && member.Arity != arity) continue; - if (rc != null) { - if (!member.IsAccessible (currentType)) + if (!errorMode) { + if (!member.IsAccessible (rc)) continue; // @@ -627,7 +573,7 @@ namespace Mono.CSharp { // } // } // - if (rc.Compiler.IsRuntimeBinder && !member.DeclaringType.IsAccessible (currentType)) + if (rc.Module.Compiler.IsRuntimeBinder && !member.DeclaringType.IsAccessible (rc)) continue; } @@ -639,18 +585,19 @@ namespace Mono.CSharp { continue; } - if (non_method == null || member is MethodSpec) { + if (non_method == null || member is MethodSpec || non_method.IsNotCSharpCompatible) { non_method = member; - } else if (currentType != null) { + } else if (!errorMode && !member.IsNotCSharpCompatible) { ambig_non_method = member; } } if (non_method != null) { if (ambig_non_method != null && rc != null) { - rc.Report.SymbolRelatedToPreviousError (non_method); - rc.Report.SymbolRelatedToPreviousError (ambig_non_method); - rc.Report.Error (229, loc, "Ambiguity between `{0}' and `{1}'", + var report = rc.Module.Compiler.Report; + report.SymbolRelatedToPreviousError (non_method); + report.SymbolRelatedToPreviousError (ambig_non_method); + report.Error (229, loc, "Ambiguity between `{0}' and `{1}'", non_method.GetSignatureForError (), ambig_non_method.GetSignatureForError ()); } @@ -811,34 +758,6 @@ namespace Mono.CSharp { Report.Error (214, loc, "Pointers and fixed size buffers may only be used in an unsafe context"); } - - // - // Returns the size of type `t' if known, otherwise, 0 - // - public static int GetTypeSize (TypeSpec t) - { - if (t == TypeManager.int32_type || - t == TypeManager.uint32_type || - t == TypeManager.float_type) - return 4; - else if (t == TypeManager.int64_type || - t == TypeManager.uint64_type || - t == TypeManager.double_type) - return 8; - else if (t == TypeManager.byte_type || - t == TypeManager.sbyte_type || - t == TypeManager.bool_type) - return 1; - else if (t == TypeManager.short_type || - t == TypeManager.char_type || - t == TypeManager.ushort_type) - return 2; - else if (t == TypeManager.decimal_type) - return 16; - else - return 0; - } - protected void Error_CannotModifyIntermediateExpressionValue (ResolveContext ec) { ec.Report.SymbolRelatedToPreviousError (type); @@ -856,25 +775,27 @@ namespace Mono.CSharp { // protected Expression ConvertExpressionToArrayIndex (ResolveContext ec, Expression source) { - if (source.type == InternalType.Dynamic) { + var btypes = ec.BuiltinTypes; + + if (source.type.BuiltinType == BuiltinTypeSpec.Type.Dynamic) { Arguments args = new Arguments (1); args.Add (new Argument (source)); - return new DynamicConversion (TypeManager.int32_type, CSharpBinderFlags.ConvertArrayIndex, args, loc).Resolve (ec); + return new DynamicConversion (btypes.Int, CSharpBinderFlags.ConvertArrayIndex, args, loc).Resolve (ec); } Expression converted; using (ec.Set (ResolveContext.Options.CheckedScope)) { - converted = Convert.ImplicitConversion (ec, source, TypeManager.int32_type, source.loc); + converted = Convert.ImplicitConversion (ec, source, btypes.Int, source.loc); if (converted == null) - converted = Convert.ImplicitConversion (ec, source, TypeManager.uint32_type, source.loc); + converted = Convert.ImplicitConversion (ec, source, btypes.UInt, source.loc); if (converted == null) - converted = Convert.ImplicitConversion (ec, source, TypeManager.int64_type, source.loc); + converted = Convert.ImplicitConversion (ec, source, btypes.Long, source.loc); if (converted == null) - converted = Convert.ImplicitConversion (ec, source, TypeManager.uint64_type, source.loc); + converted = Convert.ImplicitConversion (ec, source, btypes.ULong, source.loc); if (converted == null) { - source.Error_ValueCannotBeConverted (ec, source.loc, TypeManager.int32_type, false); + source.Error_ValueCannotBeConverted (ec, source.loc, btypes.Int, false); return null; } } @@ -887,10 +808,10 @@ namespace Mono.CSharp { Error_NegativeArrayIndex (ec, source.loc); // No conversion needed to array index - if (converted.Type == TypeManager.int32_type) + if (converted.Type.BuiltinType == BuiltinTypeSpec.Type.Int) return converted; - return new ArrayIndexCast (converted).Resolve (ec); + return new ArrayIndexCast (converted, btypes.Int).Resolve (ec); } // @@ -948,7 +869,7 @@ namespace Mono.CSharp { protected static TypeExpr CreateExpressionTypeExpression (ResolveContext ec, Location loc) { - var t = ec.Module.PredefinedTypes.Expression.Resolve (loc); + var t = ec.Module.PredefinedTypes.Expression.Resolve (); if (t == null) return null; @@ -1036,7 +957,7 @@ namespace Mono.CSharp { { Arguments args = new Arguments (2); args.Add (new Argument (child.CreateExpressionTree (ec))); - args.Add (new Argument (new TypeOf (new TypeExpression (type, loc), loc))); + args.Add (new Argument (new TypeOf (type, loc))); if (type.IsPointer || child.Type.IsPointer) Error_PointerInsideExpressionTree (ec); @@ -1109,113 +1030,50 @@ namespace Mono.CSharp { } // - // Used for predefined class library user casts (no obsolete check, etc.) + // Used for predefined type user operator (no obsolete check, etc.) // - public class OperatorCast : TypeCast { - MethodSpec conversion_operator; - - public OperatorCast (Expression child, TypeSpec target_type) - : this (child, target_type, false) - { - } - - public OperatorCast (Expression child, TypeSpec target_type, bool find_explicit) - : base (child, target_type) - { - conversion_operator = GetConversionOperator (find_explicit); - if (conversion_operator == null) - throw new InternalErrorException ("Outer conversion routine is out of sync"); - } - - // Returns the implicit operator that converts from - // 'child.Type' to our target type (type) - MethodSpec GetConversionOperator (bool find_explicit) - { - var op = find_explicit ? Operator.OpType.Explicit : Operator.OpType.Implicit; - - var mi = MemberCache.GetUserOperator (child.Type, op, true); - if (mi == null){ - mi = MemberCache.GetUserOperator (type, op, true); - } - - foreach (MethodSpec oper in mi) { - if (oper.ReturnType != type) - continue; - - if (oper.Parameters.Types [0] == child.Type) - return oper; - } - - return null; - } + public class OperatorCast : TypeCast + { + readonly MethodSpec conversion_operator; - public override void Emit (EmitContext ec) - { - child.Emit (ec); - ec.Emit (OpCodes.Call, conversion_operator); - } - } - - /// - /// This is a numeric cast to a Decimal - /// - public class CastToDecimal : OperatorCast { - public CastToDecimal (Expression child) - : this (child, false) + public OperatorCast (Expression expr, TypeSpec target_type) + : this (expr, target_type, target_type, false) { } - - public CastToDecimal (Expression child, bool find_explicit) - : base (child, TypeManager.decimal_type, find_explicit) + + public OperatorCast (Expression expr, TypeSpec target_type, bool find_explicit) + : this (expr, target_type, target_type, find_explicit) { } - } - - /// - /// This is an explicit numeric cast from a Decimal - /// - public class CastFromDecimal : TypeCast - { - static Dictionary operators; - - public CastFromDecimal (Expression child, TypeSpec return_type) - : base (child, return_type) + + public OperatorCast (Expression expr, TypeSpec declaringType, TypeSpec returnType, bool isExplicit) + : base (expr, returnType) { - if (child.Type != TypeManager.decimal_type) - throw new ArgumentException ("Expected decimal child " + child.Type.GetSignatureForError ()); - } + var op = isExplicit ? Operator.OpType.Explicit : Operator.OpType.Implicit; + var mi = MemberCache.GetUserOperator (declaringType, op, true); - // Returns the explicit operator that converts from an - // express of type System.Decimal to 'type'. - public Expression Resolve () - { - if (operators == null) { - var all_oper = MemberCache.GetUserOperator (TypeManager.decimal_type, Operator.OpType.Explicit, true); + if (mi != null) { + foreach (MethodSpec oper in mi) { + if (oper.ReturnType != returnType) + continue; - operators = new Dictionary (); - foreach (MethodSpec oper in all_oper) { - AParametersCollection pd = oper.Parameters; - if (pd.Types [0] == TypeManager.decimal_type) - operators.Add (oper.ReturnType, oper); + if (oper.Parameters.Types[0] == expr.Type) { + conversion_operator = oper; + return; + } } } - return operators.ContainsKey (type) ? this : null; + throw new InternalErrorException ("Missing predefined user operator between `{0}' and `{1}'", + returnType.GetSignatureForError (), expr.Type.GetSignatureForError ()); } public override void Emit (EmitContext ec) { child.Emit (ec); - - ec.Emit (OpCodes.Call, operators [type]); - } - - public static void Reset () - { - operators = null; + ec.Emit (OpCodes.Call, conversion_operator); } } - // // Constant specialization of EmptyCast. @@ -1224,7 +1082,7 @@ namespace Mono.CSharp { // public class EmptyConstantCast : Constant { - public Constant child; + public readonly Constant child; public EmptyConstantCast (Constant child, TypeSpec type) : base (child.Location) @@ -1237,16 +1095,6 @@ namespace Mono.CSharp { this.type = type; } - public override string AsString () - { - return child.AsString (); - } - - public override object GetValue () - { - return child.GetValue (); - } - public override Constant ConvertExplicitly (bool in_checked_context, TypeSpec target_type) { if (child.Type == target_type) @@ -1260,7 +1108,7 @@ namespace Mono.CSharp { { Arguments args = Arguments.CreateForExpressionTree (ec, null, child.CreateExpressionTree (ec), - new TypeOf (new TypeExpression (type, loc), loc)); + new TypeOf (type, loc)); if (type.IsPointer) Error_PointerInsideExpressionTree (ec); @@ -1288,11 +1136,6 @@ namespace Mono.CSharp { get { return child.IsZeroInteger; } } - protected override Expression DoResolve (ResolveContext rc) - { - return this; - } - public override void Emit (EmitContext ec) { child.Emit (ec); @@ -1312,12 +1155,31 @@ namespace Mono.CSharp { child.EmitSideEffect (ec); } - public override Constant ConvertImplicitly (ResolveContext rc, TypeSpec target_type) + public override object GetValue () + { + return child.GetValue (); + } + + public override string GetValueAsLiteral () { + return child.GetValueAsLiteral (); + } + + public override long GetValueAsLong () + { + return child.GetValueAsLong (); + } + + public override Constant ConvertImplicitly (TypeSpec target_type) + { + if (type == target_type) + return this; + // FIXME: Do we need to check user conversions? if (!Convert.ImplicitStandardConversionExists (this, target_type)) return null; - return child.ConvertImplicitly (rc, target_type); + + return child.ConvertImplicitly (target_type); } } @@ -1332,6 +1194,8 @@ namespace Mono.CSharp { : base (child.Location) { this.Child = child; + + this.eclass = ExprClass.Value; this.type = enum_type; } @@ -1340,13 +1204,6 @@ namespace Mono.CSharp { { } - protected override Expression DoResolve (ResolveContext rc) - { - Child = Child.Resolve (rc); - this.eclass = ExprClass.Value; - return this; - } - public override void Emit (EmitContext ec) { Child.Emit (ec); @@ -1390,10 +1247,15 @@ namespace Mono.CSharp { return System.Enum.ToObject (type.GetMetaInfo (), Child.GetValue ()); } #endif - - public override string AsString () + + public override string GetValueAsLiteral () { - return Child.AsString (); + return Child.GetValueAsLiteral (); + } + + public override long GetValueAsLong () + { + return Child.GetValueAsLong (); } public EnumConstant Increment() @@ -1425,7 +1287,7 @@ namespace Mono.CSharp { return Child.ConvertExplicitly (in_checked_context, target_type); } - public override Constant ConvertImplicitly (ResolveContext rc, TypeSpec type) + public override Constant ConvertImplicitly (TypeSpec type) { if (this.type == type) { return this; @@ -1435,7 +1297,7 @@ namespace Mono.CSharp { return null; } - return Child.ConvertImplicitly (rc, type); + return Child.ConvertImplicitly (type); } } @@ -1464,7 +1326,7 @@ namespace Mono.CSharp { public override void EncodeAttributeValue (IMemberContext rc, AttributeEncoder enc, TypeSpec targetType) { // Only boxing to object type is supported - if (targetType != TypeManager.object_type) { + if (targetType.BuiltinType != BuiltinTypeSpec.Type.Object) { base.EncodeAttributeValue (rc, enc, targetType); return; } @@ -1484,8 +1346,8 @@ namespace Mono.CSharp { { // boxing is side-effectful, since it involves runtime checks, except when boxing to Object or ValueType // so, we need to emit the box+pop instructions in most cases - if (TypeManager.IsStruct (child.Type) && - (type == TypeManager.object_type || type == TypeManager.value_type)) + if (child.Type.IsStruct && + (type.BuiltinType == BuiltinTypeSpec.Type.Object || type.BuiltinType == BuiltinTypeSpec.Type.ValueType)) child.EmitSideEffect (ec); else base.EmitSideEffect (ec); @@ -1840,9 +1702,9 @@ namespace Mono.CSharp { this.orig_expr = orig_expr; } - public override Constant ConvertImplicitly (ResolveContext rc, TypeSpec target_type) + public override Constant ConvertImplicitly (TypeSpec target_type) { - Constant c = base.ConvertImplicitly (rc, target_type); + Constant c = base.ConvertImplicitly (target_type); if (c != null) c = new ReducedConstantExpression (c, orig_expr); @@ -1872,6 +1734,9 @@ namespace Mono.CSharp { { this.orig_expr = orig; this.stm = stm; + this.eclass = stm.eclass; + this.type = stm.Type; + this.loc = orig.Location; } @@ -1882,8 +1747,6 @@ namespace Mono.CSharp { protected override Expression DoResolve (ResolveContext ec) { - eclass = stm.eclass; - type = stm.Type; return this; } @@ -1935,15 +1798,23 @@ namespace Mono.CSharp { return new ReducedExpressionStatement (s, orig); } + public static Expression Create (Expression expr, Expression original_expr) + { + return Create (expr, original_expr, true); + } + // // Creates unresolved reduce expression. The original expression has to be - // already resolved + // already resolved. Created expression is constant based based on `expr' + // value unless canBeConstant is used // - public static Expression Create (Expression expr, Expression original_expr) + public static Expression Create (Expression expr, Expression original_expr, bool canBeConstant) { - Constant c = expr as Constant; - if (c != null) - return Create (c, original_expr); + if (canBeConstant) { + Constant c = expr as Constant; + if (c != null) + return Create (c, original_expr); + } ExpressionStatement s = expr as ExpressionStatement; if (s != null) @@ -1986,7 +1857,7 @@ namespace Mono.CSharp { // public abstract class CompositeExpression : Expression { - Expression expr; + protected Expression expr; protected CompositeExpression (Expression expr) { @@ -1994,18 +1865,18 @@ namespace Mono.CSharp { this.loc = expr.Location; } - public override Expression CreateExpressionTree (ResolveContext ec) + public override Expression CreateExpressionTree (ResolveContext rc) { - return expr.CreateExpressionTree (ec); + return expr.CreateExpressionTree (rc); } public Expression Child { get { return expr; } } - protected override Expression DoResolve (ResolveContext ec) + protected override Expression DoResolve (ResolveContext rc) { - expr = expr.Resolve (ec); + expr = expr.Resolve (rc); if (expr != null) { type = expr.Type; eclass = expr.eclass; @@ -2036,6 +1907,12 @@ namespace Mono.CSharp { this.expr = expr; } + public Expression Expr { + get { + return expr; + } + } + protected override void CloneTo (CloneContext clonectx, Expression t) { if (expr == null) @@ -2055,9 +1932,6 @@ namespace Mono.CSharp { throw new InternalErrorException ("Missing Resolve call"); } - public Expression Expr { - get { return expr; } - } } // @@ -2186,77 +2060,57 @@ namespace Mono.CSharp { return new SimpleName (Name, targs, loc); } - protected virtual void Error_TypeOrNamespaceNotFound (IMemberContext ec) + protected override Expression DoResolve (ResolveContext ec) + { + return SimpleNameResolve (ec, null, false); + } + + public override Expression DoResolveLValue (ResolveContext ec, Expression right_side) + { + return SimpleNameResolve (ec, right_side, false); + } + + protected virtual void Error_TypeOrNamespaceNotFound (IMemberContext ctx) { - if (ec.CurrentType != null) { - if (ec.CurrentMemberDefinition != null) { - MemberCore mc = ec.CurrentMemberDefinition.Parent.GetDefinition (Name); + if (ctx.CurrentType != null) { + if (ctx.CurrentMemberDefinition != null) { + MemberCore mc = ctx.CurrentMemberDefinition.Parent.GetDefinition (Name); if (mc != null) { - Error_UnexpectedKind (ec.Compiler.Report, mc, "type", GetMemberType (mc), loc); + Error_UnexpectedKind (ctx.Module.Compiler.Report, mc, "type", GetMemberType (mc), loc); return; } } - - /* - // TODO MemberCache: Implement - - string ns = ec.CurrentType.Namespace; - string fullname = (ns.Length > 0) ? ns + "." + Name : Name; - foreach (Assembly a in GlobalRootNamespace.Instance.Assemblies) { - var type = a.GetType (fullname); - if (type != null) { - ec.Compiler.Report.SymbolRelatedToPreviousError (type); - Expression.ErrorIsInaccesible (loc, TypeManager.CSharpName (type), ec.Compiler.Report); - return; - } - } - - if (ec.CurrentTypeDefinition != null) { - TypeSpec t = ec.CurrentTypeDefinition.LookupAnyGeneric (Name); - if (t != null) { - Namespace.Error_InvalidNumberOfTypeArguments (ec.Compiler.Report, t, loc); - return; - } - } - */ } - FullNamedExpression retval = ec.LookupNamespaceOrType (Name, -System.Math.Max (1, Arity), loc, true); + // MSAF + var retval = ctx.LookupNamespaceOrType (Name, Arity, LookupMode.IgnoreAccessibility, loc); if (retval != null) { - Error_TypeArgumentsCannotBeUsed (ec.Compiler.Report, loc, retval.Type, Arity); -/* - var te = retval as TypeExpr; - if (HasTypeArguments && te != null && !te.Type.IsGeneric) - retval.Error_TypeArgumentsCannotBeUsed (ec.Compiler.Report, loc); - else - Namespace.Error_InvalidNumberOfTypeArguments (ec.Compiler.Report, retval.Type, loc); -*/ + ctx.Module.Compiler.Report.SymbolRelatedToPreviousError (retval.Type); + ErrorIsInaccesible (ctx, retval.GetSignatureForError (), loc); return; } - NamespaceEntry.Error_NamespaceNotFound (loc, Name, ec.Compiler.Report); - } - - protected override Expression DoResolve (ResolveContext ec) - { - return SimpleNameResolve (ec, null, false); - } + retval = ctx.LookupNamespaceOrType (Name, -System.Math.Max (1, Arity), LookupMode.Probing, loc); + if (retval != null) { + Error_TypeArgumentsCannotBeUsed (ctx, retval.Type, Arity, loc); + return; + } - public override Expression DoResolveLValue (ResolveContext ec, Expression right_side) - { - return SimpleNameResolve (ec, right_side, false); + NamespaceContainer.Error_NamespaceNotFound (loc, Name, ctx.Module.Compiler.Report); } - public override FullNamedExpression ResolveAsTypeStep (IMemberContext ec, bool silent) + public override FullNamedExpression ResolveAsTypeOrNamespace (IMemberContext ec) { - int errors = ec.Compiler.Report.Errors; - FullNamedExpression fne = ec.LookupNamespaceOrType (Name, Arity, loc, /*ignore_cs0104=*/ false); + FullNamedExpression fne = ec.LookupNamespaceOrType (Name, Arity, LookupMode.Normal, loc); if (fne != null) { if (fne.Type != null && Arity > 0) { if (HasTypeArguments) { GenericTypeExpr ct = new GenericTypeExpr (fne.Type, targs, loc); - return ct.ResolveAsTypeStep (ec, false); + if (ct.ResolveAsType (ec) == null) + return null; + + return ct; } return new GenericOpenTypeExpr (fne.Type, loc); @@ -2269,26 +2123,29 @@ namespace Mono.CSharp { return fne; } - if (Arity == 0 && Name == "dynamic" && RootContext.Version > LanguageVersion.V_3) { + if (Arity == 0 && Name == "dynamic" && ec.Module.Compiler.Settings.Version > LanguageVersion.V_3) { if (!ec.Module.PredefinedAttributes.Dynamic.IsDefined) { - ec.Compiler.Report.Error (1980, Location, + ec.Module.Compiler.Report.Error (1980, Location, "Dynamic keyword requires `{0}' to be defined. Are you missing System.Core.dll assembly reference?", ec.Module.PredefinedAttributes.Dynamic.GetSignatureForError ()); } - return new DynamicTypeExpr (loc); + fne = new DynamicTypeExpr (loc); + fne.ResolveAsType (ec); } if (fne != null) return fne; - if (silent || errors != ec.Compiler.Report.Errors) - return null; - Error_TypeOrNamespaceNotFound (ec); return null; } + public bool IsPossibleTypeOrNamespace (IMemberContext mc) + { + return mc.LookupNamespaceOrType (Name, Arity, LookupMode.Probing, loc) != null; + } + public override Expression LookupNameExpression (ResolveContext rc, MemberLookupRestrictions restrictions) { int lookup_arity = Arity; @@ -2315,7 +2172,7 @@ namespace Mono.CSharp { e = variable.CreateReferenceExpression (rc, loc); if (e != null) { if (Arity > 0) - Error_TypeArgumentsCannotBeUsed (rc.Report, "variable", Name, loc); + Error_TypeArgumentsCannotBeUsed (rc, "variable", Name, loc); return e; } @@ -2327,9 +2184,8 @@ namespace Mono.CSharp { // Stage 2: Lookup members if we are inside a type up to top level type for nested types // TypeSpec member_type = rc.CurrentType; - TypeSpec current_type = member_type; for (; member_type != null; member_type = member_type.DeclaringType) { - e = MemberLookup (errorMode ? null : rc, current_type, member_type, Name, lookup_arity, restrictions, loc); + e = MemberLookup (rc, errorMode, member_type, Name, lookup_arity, restrictions, loc); if (e == null) continue; @@ -2372,12 +2228,12 @@ namespace Mono.CSharp { // Break as there is no other overload available anyway if ((restrictions & MemberLookupRestrictions.ReadAccess) != 0) { - if (!pe.PropertyInfo.HasGet || !pe.PropertyInfo.Get.IsAccessible (current_type)) + if (!pe.PropertyInfo.HasGet || !pe.PropertyInfo.Get.IsAccessible (rc)) break; pe.Getter = pe.PropertyInfo.Get; } else { - if (!pe.PropertyInfo.HasSet || !pe.PropertyInfo.Set.IsAccessible (current_type)) + if (!pe.PropertyInfo.HasSet || !pe.PropertyInfo.Set.IsAccessible (rc)) break; pe.Setter = pe.PropertyInfo.Set; @@ -2401,14 +2257,13 @@ namespace Mono.CSharp { // Stage 3: Lookup nested types, namespaces and type parameters in the context // if ((restrictions & MemberLookupRestrictions.InvocableOnly) == 0 && !variable_found) { - e = ResolveAsTypeStep (rc, lookup_arity == 0 || !errorMode); - if (e != null) { + if (IsPossibleTypeOrNamespace (rc)) { if (variable != null) { rc.Report.SymbolRelatedToPreviousError (variable.Location, Name); rc.Report.Error (135, loc, "`{0}' conflicts with a declaration in a child block", Name); } - return e; + return ResolveAsTypeOrNamespace (rc); } } @@ -2416,20 +2271,62 @@ namespace Mono.CSharp { if (variable_found) { rc.Report.Error (841, loc, "A local variable `{0}' cannot be used before it is declared", Name); } else { + if (Arity > 0) { + TypeParameter[] tparams = rc.CurrentTypeParameters; + if (tparams != null) { + foreach (var ctp in tparams) { + if (ctp.Name == Name) { + Error_TypeArgumentsCannotBeUsed (rc, "type parameter", Name, loc); + return null; + } + } + } + + var ct = rc.CurrentType; + do { + if (ct.MemberDefinition.TypeParametersCount > 0) { + foreach (var ctp in ct.MemberDefinition.TypeParameters) { + if (ctp.Name == Name) { + Error_TypeArgumentsCannotBeUsed (rc, "type parameter", Name, loc); + return null; + } + } + } + + ct = ct.DeclaringType; + } while (ct != null); + } + + if ((restrictions & MemberLookupRestrictions.InvocableOnly) == 0) { + e = rc.LookupNamespaceOrType (Name, Arity, LookupMode.IgnoreAccessibility, loc); + if (e != null) { + rc.Report.SymbolRelatedToPreviousError (e.Type); + ErrorIsInaccesible (rc, e.GetSignatureForError (), loc); + return e; + } + } + + e = rc.LookupNamespaceOrType (Name, -System.Math.Max (1, Arity), LookupMode.Probing, loc); + if (e != null) { + if (!(e is TypeExpr) || (restrictions & MemberLookupRestrictions.InvocableOnly) == 0 || !e.Type.IsDelegate) { + Error_TypeArgumentsCannotBeUsed (rc, e.Type, Arity, loc); + return e; + } + } + rc.Report.Error (103, loc, "The name `{0}' does not exist in the current context", Name); } - return null; + return ErrorExpression.Instance; } - if (RootContext.EvalMode) { - var fi = Evaluator.LookupField (Name); + if (rc.Module.Evaluator != null) { + var fi = rc.Module.Evaluator.LookupField (Name); if (fi != null) return new FieldExpr (fi.Item1, loc); } lookup_arity = 0; - restrictions &= ~MemberLookupRestrictions.InvocableOnly; errorMode = true; } } @@ -2474,11 +2371,50 @@ namespace Mono.CSharp { throw new NotSupportedException ("ET"); } - public override FullNamedExpression ResolveAsTypeStep (IMemberContext ec, bool silent) + public abstract FullNamedExpression ResolveAsTypeOrNamespace (IMemberContext mc); + + // + // This is used to resolve the expression as a type, a null + // value will be returned if the expression is not a type + // reference + // + public override TypeSpec ResolveAsType (IMemberContext mc) { - return this; + FullNamedExpression fne = ResolveAsTypeOrNamespace (mc); + + if (fne == null) + return null; + + TypeExpr te = fne as TypeExpr; + if (te == null) { + fne.Error_UnexpectedKind (mc.Module.Compiler.Report, null, "type", loc); + return null; + } + + te.loc = loc; + + type = te.Type; + + var dep = type.GetMissingDependencies (); + if (dep != null) { + ImportedTypeDefinition.Error_MissingDependency (mc, dep, loc); + } + + // + // Obsolete checks cannot be done when resolving base context as they + // require type dependencies to be set but we are in process of resolving them + // + if (!(mc is TypeContainer.BaseContext)) { + ObsoleteAttribute obsolete_attr = type.GetAttributeObsolete (); + if (obsolete_attr != null && !mc.IsObsolete) { + AttributeTester.Report_ObsoleteMessage (obsolete_attr, te.GetSignatureForError (), Location, mc.Module.Compiler.Report); + } + } + + return type; } + public override void Emit (EmitContext ec) { throw new InternalErrorException ("FullNamedExpression `{0}' found in resolved tree", @@ -2489,24 +2425,20 @@ namespace Mono.CSharp { /// /// Expression that evaluates to a type /// - public abstract class TypeExpr : FullNamedExpression { - public override FullNamedExpression ResolveAsTypeStep (IMemberContext ec, bool silent) + public abstract class TypeExpr : FullNamedExpression + { + public sealed override FullNamedExpression ResolveAsTypeOrNamespace (IMemberContext mc) { - TypeExpr t = DoResolveAsTypeStep (ec); - if (t == null) - return null; - - eclass = ExprClass.Type; - return t; + ResolveAsType (mc); + return this; } - protected override Expression DoResolve (ResolveContext ec) + protected sealed override Expression DoResolve (ResolveContext ec) { - return ResolveAsTypeTerminal (ec, false); + ResolveAsType (ec); + return this; } - protected abstract TypeExpr DoResolveAsTypeStep (IMemberContext ec); - public override bool Equals (object obj) { TypeExpr tobj = obj as TypeExpr; @@ -2525,7 +2457,8 @@ namespace Mono.CSharp { /// /// Fully resolved Expression that already evaluated to a type /// - public class TypeExpression : TypeExpr { + public class TypeExpression : TypeExpr + { public TypeExpression (TypeSpec t, Location l) { Type = t; @@ -2533,14 +2466,9 @@ namespace Mono.CSharp { loc = l; } - protected override TypeExpr DoResolveAsTypeStep (IMemberContext ec) + public sealed override TypeSpec ResolveAsType (IMemberContext ec) { - return this; - } - - public override TypeExpr ResolveAsTypeTerminal (IMemberContext ec, bool silent) - { - return this; + return type; } } @@ -2584,7 +2512,6 @@ namespace Mono.CSharp { get; } - // TODO: Not needed protected abstract TypeSpec DeclaringType { get; } @@ -2604,7 +2531,7 @@ namespace Mono.CSharp { // 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) { + if ((method.Modifiers & (Modifiers.ABSTRACT | Modifiers.VIRTUAL | Modifiers.OVERRIDE)) != 0) { // // The method could already be what we are looking for // @@ -2640,7 +2567,7 @@ namespace Mono.CSharp { } if (targs != null) - method = method.MakeGenericMethod (targs); + method = method.MakeGenericMethod (rc, targs); } // @@ -2658,18 +2585,26 @@ namespace Mono.CSharp { if (InstanceExpression == null) return; - if ((member.Modifiers & Modifiers.AccessibilityMask) == Modifiers.PROTECTED && !(InstanceExpression is This)) { - var ct = rc.CurrentType; - var expr_type = InstanceExpression.Type; - if (ct != expr_type) { - expr_type = expr_type.GetDefinition (); - if (ct != expr_type && !IsSameOrBaseQualifier (ct, expr_type)) { - rc.Report.SymbolRelatedToPreviousError (member); - rc.Report.Error (1540, loc, - "Cannot access protected member `{0}' via a qualifier of type `{1}'. The qualifier must be of type `{2}' or derived from it", - member.GetSignatureForError (), expr_type.GetSignatureForError (), ct.GetSignatureForError ()); - } - } + if ((member.Modifiers & Modifiers.PROTECTED) != 0 && !(InstanceExpression is This)) { + CheckProtectedMemberAccess (rc, member, InstanceExpression.Type, loc); + } + } + + public static void CheckProtectedMemberAccess (ResolveContext rc, T member, TypeSpec qualifier, Location loc) where T : MemberSpec + { + var ct = rc.CurrentType; + if (ct == qualifier) + return; + + if ((member.Modifiers & Modifiers.INTERNAL) != 0 && member.DeclaringType.MemberDefinition.IsInternalAsPublic (ct.MemberDefinition.DeclaringAssembly)) + return; + + qualifier = qualifier.GetDefinition (); + if (ct != qualifier && !IsSameOrBaseQualifier (ct, qualifier)) { + rc.Report.SymbolRelatedToPreviousError (member); + rc.Report.Error (1540, loc, + "Cannot access protected member `{0}' via a qualifier of type `{1}'. The qualifier must be of type `{2}' or derived from it", + member.GetSignatureForError (), qualifier.GetSignatureForError (), ct.GetSignatureForError ()); } } @@ -2700,7 +2635,7 @@ namespace Mono.CSharp { var dep = member.GetMissingDependencies (); if (dep != null) { - ImportedTypeDefinition.Error_MissingDependency (rc.Compiler, dep, loc); + ImportedTypeDefinition.Error_MissingDependency (rc, dep, loc); } if (!rc.IsObsolete) { @@ -2731,9 +2666,7 @@ namespace Mono.CSharp { // a constant, field, property, local variable, or parameter with the same type as the meaning of E as a type-name if (left is MemberExpr || left is VariableReference) { - rc.Report.DisableReporting (); - Expression identical_type = rc.LookupNamespaceOrType (name.Name, 0, loc, true) as TypeExpr; - rc.Report.EnableReporting (); + var identical_type = rc.LookupNamespaceOrType (name.Name, 0, LookupMode.Probing, loc) as TypeExpr; if (identical_type != null && identical_type.Type == left.Type) return identical_type; } @@ -2807,7 +2740,7 @@ namespace Mono.CSharp { me.ResolveInstanceExpression (rc, rhs); var fe = me as FieldExpr; - if (fe != null && fe.IsMarshalByRefAccess ()) { + if (fe != null && fe.IsMarshalByRefAccess (rc)) { rc.Report.SymbolRelatedToPreviousError (me.DeclaringType); rc.Report.Warning (1690, 1, loc, "Cannot call methods, properties, or indexers on `{0}' because it is a value type member of a marshal-by-reference class", @@ -2843,7 +2776,7 @@ namespace Mono.CSharp { public virtual MemberExpr ResolveMemberAccess (ResolveContext ec, Expression left, SimpleName original) { - if (left != null && left.IsNull && TypeManager.IsReferenceType (left.Type)) { + if (left != null && left.IsNull && TypeSpec.IsReferenceType (left.Type)) { ec.Report.Warning (1720, 1, left.Location, "Expression will always cause a `{0}'", "System.NullReferenceException"); } @@ -2855,9 +2788,9 @@ namespace Mono.CSharp { protected void EmitInstance (EmitContext ec, bool prepare_for_load) { TypeSpec instance_type = InstanceExpression.Type; - if (TypeManager.IsValueType (instance_type)) { + if (TypeSpec.IsValueType (instance_type)) { if (InstanceExpression is IMemoryLocation) { - ((IMemoryLocation) InstanceExpression).AddressOf (ec, AddressOp.LoadStore); + ((IMemoryLocation) InstanceExpression).AddressOf (ec, AddressOp.Load); } else { LocalTemporary t = new LocalTemporary (instance_type); InstanceExpression.Emit (ec); @@ -2868,7 +2801,7 @@ namespace Mono.CSharp { InstanceExpression.Emit (ec); // Only to make verifier happy - if (instance_type.IsGenericParameter && !(InstanceExpression is This) && TypeManager.IsReferenceType (instance_type)) + if (instance_type.IsGenericParameter && !(InstanceExpression is This) && TypeSpec.IsReferenceType (instance_type)) ec.Emit (OpCodes.Box, instance_type); } @@ -2884,10 +2817,10 @@ namespace Mono.CSharp { // class ExtensionMethodGroupExpr : MethodGroupExpr, OverloadResolver.IErrorHandler { - NamespaceEntry namespace_entry; + NamespaceContainer namespace_entry; public readonly Expression ExtensionExpression; - public ExtensionMethodGroupExpr (IList list, NamespaceEntry n, Expression extensionExpr, Location l) + public ExtensionMethodGroupExpr (IList list, NamespaceContainer n, Expression extensionExpr, Location l) : base (list.Cast().ToList (), extensionExpr.Type, l) { this.namespace_entry = n; @@ -3023,6 +2956,12 @@ namespace Mono.CSharp { } } + public IList Candidates { + get { + return Methods; + } + } + protected override TypeSpec DeclaringType { get { return queried_type; @@ -3088,7 +3027,7 @@ namespace Mono.CSharp { return null; } - if (best_candidate.IsConditionallyExcluded (loc)) + if (best_candidate.IsConditionallyExcluded (ec.Module.Compiler, loc)) ec.Report.Error (765, loc, "Partial methods with only a defining declaration or removed conditional methods cannot be used in an expression tree"); @@ -3240,7 +3179,7 @@ namespace Mono.CSharp { return null; int arity = type_arguments == null ? 0 : type_arguments.Count; - NamespaceEntry methods_scope = null; + NamespaceContainer methods_scope = null; var methods = rc.LookupExtensionMethod (InstanceExpression.Type, Methods[0].Name, arity, ref methods_scope); if (methods == null) return null; @@ -3424,11 +3363,11 @@ namespace Mono.CSharp { // // If argument is an anonymous function // - if (argument_type == InternalType.AnonymousMethod && RootContext.Version > LanguageVersion.ISO_2) { + if (argument_type == InternalType.AnonymousMethod && ec.Module.Compiler.Settings.Version > LanguageVersion.ISO_2) { // // p and q are delegate types or expression tree types // - if (p.GetDefinition () == TypeManager.expression_type || q.GetDefinition () == TypeManager.expression_type) { + if (p.IsExpressionTreeType || q.IsExpressionTreeType) { if (q.MemberDefinition != p.MemberDefinition) { return 0; } @@ -3440,13 +3379,13 @@ namespace Mono.CSharp { p = TypeManager.GetTypeArguments (p)[0]; } - var p_m = Delegate.GetInvokeMethod (ec.Compiler, p); - var q_m = Delegate.GetInvokeMethod (ec.Compiler, q); + var p_m = Delegate.GetInvokeMethod (p); + var q_m = Delegate.GetInvokeMethod (q); // // With identical parameter lists // - if (!TypeSpecComparer.Equals (p_m.Parameters.Types,q_m.Parameters.Types)) + if (!TypeSpecComparer.Equals (p_m.Parameters.Types, q_m.Parameters.Types)) return 0; p = p_m.ReturnType; @@ -3455,16 +3394,38 @@ namespace Mono.CSharp { // // if p is void returning, and q has a return type Y, then C2 is the better conversion. // - if (p == TypeManager.void_type) { - return q != TypeManager.void_type ? 2 : 0; + if (p.Kind == MemberKind.Void) { + return q.Kind != MemberKind.Void ? 2 : 0; } // // if p has a return type Y, and q is void returning, then C1 is the better conversion. // - if (q == TypeManager.void_type) { - return p != TypeManager.void_type ? 1: 0; + if (q.Kind == MemberKind.Void) { + return p.Kind != MemberKind.Void ? 1: 0; } + + // + // When anonymous method is an asynchronous, and P has a return type Task, and Q has a return type Task + // better conversion is performed between underlying types Y1 and Y2 + // + if (p.IsGenericTask || q.IsGenericTask) { + if (p.IsGenericTask != q.IsGenericTask) { + return 0; + } + + var async_am = a.Expr as AnonymousMethodExpression; + if (async_am == null || !async_am.IsAsync) + return 0; + + q = q.TypeArguments[0]; + p = p.TypeArguments[0]; + } + + // + // The parameters are identicial and return type is not void, use better type conversion + // on return type to determine better one + // } else { if (argument_type == p) return 1; @@ -3484,40 +3445,64 @@ namespace Mono.CSharp { if (p == null || q == null) throw new InternalErrorException ("BetterTypeConversion got a null conversion"); - if (p == TypeManager.int32_type) { - if (q == TypeManager.uint32_type || q == TypeManager.uint64_type) + switch (p.BuiltinType) { + case BuiltinTypeSpec.Type.Int: + if (q.BuiltinType == BuiltinTypeSpec.Type.UInt || q.BuiltinType == BuiltinTypeSpec.Type.ULong) return 1; - } else if (p == TypeManager.int64_type) { - if (q == TypeManager.uint64_type) + break; + case BuiltinTypeSpec.Type.Long: + if (q.BuiltinType == BuiltinTypeSpec.Type.ULong) return 1; - } else if (p == TypeManager.sbyte_type) { - if (q == TypeManager.byte_type || q == TypeManager.ushort_type || - q == TypeManager.uint32_type || q == TypeManager.uint64_type) + break; + case BuiltinTypeSpec.Type.SByte: + switch (q.BuiltinType) { + case BuiltinTypeSpec.Type.Byte: + case BuiltinTypeSpec.Type.UShort: + case BuiltinTypeSpec.Type.UInt: + case BuiltinTypeSpec.Type.ULong: return 1; - } else if (p == TypeManager.short_type) { - if (q == TypeManager.ushort_type || q == TypeManager.uint32_type || - q == TypeManager.uint64_type) + } + break; + case BuiltinTypeSpec.Type.Short: + switch (q.BuiltinType) { + case BuiltinTypeSpec.Type.UShort: + case BuiltinTypeSpec.Type.UInt: + case BuiltinTypeSpec.Type.ULong: return 1; - } else if (p == InternalType.Dynamic) { + } + break; + case BuiltinTypeSpec.Type.Dynamic: // Dynamic is never better return 2; } - if (q == TypeManager.int32_type) { - if (p == TypeManager.uint32_type || p == TypeManager.uint64_type) + switch (q.BuiltinType) { + case BuiltinTypeSpec.Type.Int: + if (p.BuiltinType == BuiltinTypeSpec.Type.UInt || p.BuiltinType == BuiltinTypeSpec.Type.ULong) return 2; - } if (q == TypeManager.int64_type) { - if (p == TypeManager.uint64_type) + break; + case BuiltinTypeSpec.Type.Long: + if (p.BuiltinType == BuiltinTypeSpec.Type.ULong) return 2; - } else if (q == TypeManager.sbyte_type) { - if (p == TypeManager.byte_type || p == TypeManager.ushort_type || - p == TypeManager.uint32_type || p == TypeManager.uint64_type) + break; + case BuiltinTypeSpec.Type.SByte: + switch (p.BuiltinType) { + case BuiltinTypeSpec.Type.Byte: + case BuiltinTypeSpec.Type.UShort: + case BuiltinTypeSpec.Type.UInt: + case BuiltinTypeSpec.Type.ULong: return 2; - } if (q == TypeManager.short_type) { - if (p == TypeManager.ushort_type || p == TypeManager.uint32_type || - p == TypeManager.uint64_type) + } + break; + case BuiltinTypeSpec.Type.Short: + switch (p.BuiltinType) { + case BuiltinTypeSpec.Type.UShort: + case BuiltinTypeSpec.Type.UInt: + case BuiltinTypeSpec.Type.ULong: return 2; - } else if (q == InternalType.Dynamic) { + } + break; + case BuiltinTypeSpec.Type.Dynamic: // Dynamic is never better return 1; } @@ -3688,7 +3673,7 @@ namespace Mono.CSharp { var best_def_pd = ((IParametersMember) best.MemberDefinition).Parameters; bool specific_at_least_once = false; - for (j = 0; j < candidate_param_count; ++j) { + for (j = 0; j < args_count; ++j) { NamedArgument na = args_count == 0 ? null : args [j] as NamedArgument; if (na != null) { ct = candidate_def_pd.Types[cparam.GetParameterIndexByName (na.Name)]; @@ -3750,20 +3735,18 @@ namespace Mono.CSharp { } } - int args_gap = System.Math.Abs (arg_count - param_count); if (optional_count != 0) { - if (args_gap > optional_count) - return int.MaxValue - 10000 + args_gap - optional_count; - // Readjust expected number when params used if (cpd.HasParams) { optional_count--; if (arg_count < param_count) param_count--; } else if (arg_count > param_count) { + int args_gap = System.Math.Abs (arg_count - param_count); return int.MaxValue - 10000 + args_gap; } } else if (arg_count != param_count) { + int args_gap = System.Math.Abs (arg_count - param_count); if (!cpd.HasParams) return int.MaxValue - 10000 + args_gap; if (arg_count < param_count - 1) @@ -3860,7 +3843,7 @@ namespace Mono.CSharp { if (g_args_count != type_arguments.Count) return int.MaxValue - 20000 + System.Math.Abs (type_arguments.Count - g_args_count); - ms = ms.MakeGenericMethod (type_arguments.Arguments); + ms = ms.MakeGenericMethod (ec, type_arguments.Arguments); } else { // TODO: It should not be here (we don't know yet whether any argument is lambda) but // for now it simplifies things. I should probably add a callback to ResolveContext @@ -3877,7 +3860,7 @@ namespace Mono.CSharp { return ti.InferenceScore - 20000; if (i_args.Length != 0) { - ms = ms.MakeGenericMethod (i_args); + ms = ms.MakeGenericMethod (ec, i_args); } cc.IgnoreInferredDynamic = true; @@ -3900,7 +3883,7 @@ namespace Mono.CSharp { // if (candidate != pm) { MethodSpec override_ms = (MethodSpec) pm; - var inflator = new TypeParameterInflator (ms.DeclaringType, override_ms.GenericDefinition.TypeParameters, ms.TypeArguments); + var inflator = new TypeParameterInflator (ec, ms.DeclaringType, override_ms.GenericDefinition.TypeParameters, ms.TypeArguments); returnType = inflator.Inflate (returnType); } else { returnType = ms.ReturnType; @@ -3938,7 +3921,7 @@ namespace Mono.CSharp { // // LAMESPEC: No idea what the exact rules are for System.Reflection.Missing.Value instead of null // - if (e == EmptyExpression.MissingValue && ptypes[i] == TypeManager.object_type || ptypes[i] == InternalType.Dynamic) { + if (e == EmptyExpression.MissingValue && ptypes[i].BuiltinType == BuiltinTypeSpec.Type.Object || ptypes[i].BuiltinType == BuiltinTypeSpec.Type.Dynamic) { e = new MemberAccess (new MemberAccess (new MemberAccess ( new QualifiedAliasMember (QualifiedAliasMember.GlobalAlias, "System", loc), "Reflection", loc), "Missing", loc), "Value", loc); } else { @@ -3970,8 +3953,8 @@ namespace Mono.CSharp { // var at = a.Type; if (at == pt || TypeSpecComparer.IsEqual (at, pt) || - Convert.ImplicitReferenceConversionExists (a.Expr, pt) || - Convert.ImplicitBoxingConversion (EmptyExpression.Null, at, pt) != null) { + Convert.ImplicitReferenceConversionExists (at, pt) || + Convert.ImplicitBoxingConversion (null, at, pt) != null) { score = 0; continue; } @@ -4046,7 +4029,7 @@ namespace Mono.CSharp { // // Using dynamic for ref/out parameter can still succeed at runtime // - if (argument.Type == InternalType.Dynamic && argument.Modifier == 0 && (restrictions & Restrictions.CovariantDelegate) == 0) + if (argument.Type.BuiltinType == BuiltinTypeSpec.Type.Dynamic && argument.Modifier == 0 && (restrictions & Restrictions.CovariantDelegate) == 0) return -1; return 2; @@ -4057,20 +4040,20 @@ namespace Mono.CSharp { // // Using dynamic for ref/out parameter can still succeed at runtime // - if (argument.Type == InternalType.Dynamic && argument.Modifier == 0 && (restrictions & Restrictions.CovariantDelegate) == 0) + if (argument.Type.BuiltinType == BuiltinTypeSpec.Type.Dynamic && argument.Modifier == 0 && (restrictions & Restrictions.CovariantDelegate) == 0) return -1; return 1; } } else { - if (argument.Type == InternalType.Dynamic && (restrictions & Restrictions.CovariantDelegate) == 0) + if (argument.Type.BuiltinType == BuiltinTypeSpec.Type.Dynamic && (restrictions & Restrictions.CovariantDelegate) == 0) return -1; // // Deploy custom error reporting for lambda methods. When probing lambda methods // keep all errors reported in separate set and once we are done and no best - // candidate found, this set is used to report more details about what was wrong + // candidate was found, this set is used to report more details about what was wrong // with lambda body // if (argument.Expr.Type == InternalType.AnonymousMethod) { @@ -4080,6 +4063,10 @@ namespace Mono.CSharp { } } + // + // Use implicit conversion in all modes to return same candidates when the expression + // is used as argument or delegate conversion + // if (!Convert.ImplicitConversionExists (ec, argument.Expr, parameter)) { if (lambda_conv_msgs != null) { lambda_conv_msgs.EndSession (); @@ -4149,7 +4136,6 @@ namespace Mono.CSharp { Arguments candidate_args = args; bool error_mode = false; - var current_type = rc.CurrentType; MemberSpec invocable_member = null; // Be careful, cannot return until error reporter is restored @@ -4172,10 +4158,10 @@ namespace Mono.CSharp { continue; if (!error_mode) { - if (!member.IsAccessible (current_type)) + if (!member.IsAccessible (rc)) continue; - if (rc.Compiler.IsRuntimeBinder && !member.DeclaringType.IsAccessible (current_type)) + if (rc.IsRuntimeBinder && !member.DeclaringType.IsAccessible (rc)) continue; } @@ -4235,7 +4221,7 @@ namespace Mono.CSharp { if (best_candidate.DeclaringType.IsInterface && member.DeclaringType.ImplementsInterface (best_candidate.DeclaringType, false)) { // // We pack all interface members into top level type which makes the overload resolution - // more complicated for interfaces. We accomodate for this by removing methods with same + // more complicated for interfaces. We compensate it by removing methods with same // signature when building the cache hence this path should not really be hit often // // Example: @@ -4339,6 +4325,13 @@ namespace Mono.CSharp { return null; } + // + // These flags indicates we are running delegate probing conversion. No need to + // do more expensive checks + // + if ((restrictions & (Restrictions.ProbingOnly | Restrictions.CovariantDelegate)) == (Restrictions.CovariantDelegate | Restrictions.ProbingOnly)) + return (T) best_candidate; + if (ambiguous_candidates != null) { // // Now check that there are no ambiguities i.e the selected method @@ -4389,7 +4382,7 @@ namespace Mono.CSharp { var dep = best_candidate.GetMissingDependencies (); if (dep != null) { - ImportedTypeDefinition.Error_MissingDependency (rc.Compiler, dep, loc); + ImportedTypeDefinition.Error_MissingDependency (rc, dep, loc); } best_candidate.MemberDefinition.SetIsUsed (); @@ -4438,14 +4431,13 @@ namespace Mono.CSharp { else ec.Report.Error (1620, loc, "Argument `#{0}' is missing `{1}' modifier", index, Parameter.GetModifierSignature (mod)); - } else { + } else if (a.Expr != ErrorExpression.Instance) { string p1 = a.GetSignatureForError (); string p2 = TypeManager.CSharpName (paramType); if (p1 == p2) { - ec.Report.ExtraInformation (loc, "(equally named types possibly from different assemblies in previous "); - ec.Report.SymbolRelatedToPreviousError (a.Expr.Type); - ec.Report.SymbolRelatedToPreviousError (paramType); + p1 = a.Type.GetSignatureForErrorIncludingAssemblyName (); + p2 = paramType.GetSignatureForErrorIncludingAssemblyName (); } ec.Report.Error (1503, loc, @@ -4463,7 +4455,7 @@ namespace Mono.CSharp { if (ta_count != best_candidate.Arity && (ta_count > 0 || ((IParametersMember) best_candidate).Parameters.IsEmpty)) { var mg = new MethodGroupExpr (new [] { best_candidate }, best_candidate.DeclaringType, loc); - mg.Error_TypeArgumentsCannotBeUsed (rc.Report, loc, best_candidate, ta_count); + mg.Error_TypeArgumentsCannotBeUsed (rc, best_candidate, ta_count, loc); return; } @@ -4479,7 +4471,7 @@ namespace Mono.CSharp { int unexpanded_count = ((IParametersMember) best_candidate).Parameters.HasParams ? pm.Parameters.Count - 1 : pm.Parameters.Count; if (pm.Parameters.Count == arg_count || params_expanded || unexpanded_count == arg_count) { // Reject any inaccessible member - if (!best_candidate.IsAccessible (rc.CurrentType) || !best_candidate.DeclaringType.IsAccessible (rc.CurrentType)) { + if (!best_candidate.IsAccessible (rc) || !best_candidate.DeclaringType.IsAccessible (rc)) { rc.Report.SymbolRelatedToPreviousError (best_candidate); Expression.ErrorIsInaccesible (rc, best_candidate.GetSignatureForError (), loc); return; @@ -4599,10 +4591,10 @@ namespace Mono.CSharp { } } - if (a.Expr.Type == InternalType.Dynamic) + if (a.Expr.Type.BuiltinType == BuiltinTypeSpec.Type.Dynamic) continue; - if ((restrictions & Restrictions.CovariantDelegate) != 0 && !Delegate.IsTypeCovariant (a.Expr, pt)) { + if ((restrictions & Restrictions.CovariantDelegate) != 0 && !Delegate.IsTypeCovariant (ec, a.Expr.Type, pt)) { custom_errors.NoArgumentMatch (ec, member); return false; } @@ -4676,7 +4668,7 @@ namespace Mono.CSharp { if (type_arguments == null && member.IsGeneric) { var ms = (MethodSpec) member; foreach (var ta in ms.TypeArguments) { - if (!ta.IsAccessible (ec.CurrentType)) { + if (!ta.IsAccessible (ec)) { ec.Report.SymbolRelatedToPreviousError (ta); Expression.ErrorIsInaccesible (ec, member.GetSignatureForError (), loc); break; @@ -4690,7 +4682,7 @@ namespace Mono.CSharp { public class ConstantExpr : MemberExpr { - ConstSpec constant; + readonly ConstSpec constant; public ConstantExpr (ConstSpec constant, Location loc) { @@ -4727,7 +4719,7 @@ namespace Mono.CSharp { var c = constant.GetConstant (rc); // Creates reference expression to the constant value - return Constant.CreateConstant (rc, constant.MemberType, c.GetValue (), loc); + return Constant.CreateConstant (constant.MemberType, c.GetValue (), loc); } public override void Emit (EmitContext ec) @@ -4742,7 +4734,7 @@ namespace Mono.CSharp { public override void SetTypeArguments (ResolveContext ec, TypeArguments ta) { - Error_TypeArgumentsCannotBeUsed (ec.Report, "constant", GetSignatureForError (), loc); + Error_TypeArgumentsCannotBeUsed (ec, "constant", GetSignatureForError (), loc); } } @@ -4826,12 +4818,12 @@ namespace Mono.CSharp { return TypeManager.GetFullNameSignature (spec); } - public bool IsMarshalByRefAccess () + public bool IsMarshalByRefAccess (ResolveContext rc) { // Checks possible ldflda of field access expression - return !spec.IsStatic && TypeManager.IsValueType (spec.MemberType) && - TypeSpec.IsBaseClass (spec.DeclaringType, TypeManager.mbr_type, false) && - !(InstanceExpression is This); + return !spec.IsStatic && TypeSpec.IsValueType (spec.MemberType) && !(InstanceExpression is This) && + rc.Module.PredefinedTypes.MarshalByRefObject.Define () && + TypeSpec.IsBaseClass (spec.DeclaringType, rc.Module.PredefinedTypes.MarshalByRefObject.TypeSpec, false); } public void SetHasAddressTaken () @@ -4871,32 +4863,34 @@ namespace Mono.CSharp { { bool lvalue_instance = rhs != null && IsInstance && spec.DeclaringType.IsStruct; - if (ResolveInstanceExpression (ec, rhs)) { - // Resolve the field's instance expression while flow analysis is turned - // off: when accessing a field "a.b", we must check whether the field - // "a.b" is initialized, not whether the whole struct "a" is initialized. + if (rhs != this) { + if (ResolveInstanceExpression (ec, rhs)) { + // Resolve the field's instance expression while flow analysis is turned + // off: when accessing a field "a.b", we must check whether the field + // "a.b" is initialized, not whether the whole struct "a" is initialized. - if (lvalue_instance) { - using (ec.With (ResolveContext.Options.DoFlowAnalysis, false)) { - bool out_access = rhs == EmptyExpression.OutAccess.Instance || rhs == EmptyExpression.LValueMemberOutAccess; + if (lvalue_instance) { + using (ec.With (ResolveContext.Options.DoFlowAnalysis, false)) { + bool out_access = rhs == EmptyExpression.OutAccess || rhs == EmptyExpression.LValueMemberOutAccess; - Expression right_side = - out_access ? EmptyExpression.LValueMemberOutAccess : EmptyExpression.LValueMemberAccess; + Expression right_side = + out_access ? EmptyExpression.LValueMemberOutAccess : EmptyExpression.LValueMemberAccess; - InstanceExpression = InstanceExpression.ResolveLValue (ec, right_side); - } - } else { - using (ec.With (ResolveContext.Options.DoFlowAnalysis, false)) { - InstanceExpression = InstanceExpression.Resolve (ec, ResolveFlags.VariableOrValue); + InstanceExpression = InstanceExpression.ResolveLValue (ec, right_side); + } + } else { + using (ec.With (ResolveContext.Options.DoFlowAnalysis, false)) { + InstanceExpression = InstanceExpression.Resolve (ec, ResolveFlags.VariableOrValue); + } } + + if (InstanceExpression == null) + return null; } - if (InstanceExpression == null) - return null; + DoBestMemberChecks (ec, spec); } - DoBestMemberChecks (ec, spec); - var fb = spec as FixedFieldSpec; IVariableReference var = InstanceExpression as IVariableReference; @@ -4961,7 +4955,7 @@ namespace Mono.CSharp { Expression Report_AssignToReadonly (ResolveContext ec, Expression right_side) { int i = 0; - if (right_side == EmptyExpression.OutAccess.Instance || right_side == EmptyExpression.LValueMemberOutAccess) + if (right_side == EmptyExpression.OutAccess || right_side == EmptyExpression.LValueMemberOutAccess) i += 1; if (IsStatic) i += 2; @@ -4981,7 +4975,7 @@ namespace Mono.CSharp { spec.MemberDefinition.SetIsAssigned (); - if ((right_side == EmptyExpression.UnaryAddress || right_side == EmptyExpression.OutAccess.Instance) && + if ((right_side == EmptyExpression.UnaryAddress || right_side == EmptyExpression.OutAccess) && (spec.Modifiers & Modifiers.VOLATILE) != 0) { ec.Report.Warning (420, 1, loc, "`{0}': A volatile field references will not be treated as volatile", @@ -5007,8 +5001,7 @@ namespace Mono.CSharp { } } - if (right_side == EmptyExpression.OutAccess.Instance && - !IsStatic && !(InstanceExpression is This) && TypeManager.mbr_type != null && TypeSpec.IsBaseClass (spec.DeclaringType, TypeManager.mbr_type, false)) { + if (right_side == EmptyExpression.OutAccess && IsMarshalByRefAccess (ec)) { ec.Report.SymbolRelatedToPreviousError (spec.DeclaringType); ec.Report.Warning (197, 1, loc, "Passing `{0}' as ref or out or taking its address may cause a runtime exception because it is a field of a marshal-by-reference class", @@ -5072,7 +5065,7 @@ namespace Mono.CSharp { EmitInstance (ec, false); // Optimization for build-in types - if (TypeManager.IsStruct (type) && type == ec.MemberContext.CurrentType && InstanceExpression.Type == type) { + if (type.IsStruct && type == ec.CurrentType && InstanceExpression.Type == type) { ec.EmitLoadFromPtr (type); } else { var ff = spec as FixedFieldSpec; @@ -5099,11 +5092,21 @@ namespace Mono.CSharp { public void EmitAssign (EmitContext ec, Expression source, bool leave_copy, bool prepare_for_load) { - prepared = prepare_for_load && !(source is DynamicExpressionStatement); - if (IsInstance) - EmitInstance (ec, prepared); + var await_expr = source as Await; + if (await_expr != null) { + // + // Await is not ordinary expression (it contains jump), hence the usual flow cannot be used + // to emit instance load before expression + // + await_expr.EmitAssign (ec, this); + } else { + prepared = prepare_for_load && !(source is DynamicExpressionStatement); + if (IsInstance) + EmitInstance (ec, prepared); + + source.Emit (ec); + } - source.Emit (ec); if (leave_copy) { ec.Emit (OpCodes.Dup); if (!IsStatic) { @@ -5156,7 +5159,7 @@ namespace Mono.CSharp { bool need_copy; if (spec.IsReadOnly){ need_copy = true; - if (ec.HasSet (EmitContext.Options.ConstructorScope)){ + if (ec.HasSet (EmitContext.Options.ConstructorScope) && spec.DeclaringType == ec.CurrentType) { if (IsStatic){ if (ec.IsStatic) need_copy = false; @@ -5203,7 +5206,7 @@ namespace Mono.CSharp { public override void SetTypeArguments (ResolveContext ec, TypeArguments ta) { - Error_TypeArgumentsCannotBeUsed (ec.Report, "field", GetSignatureForError (), loc); + Error_TypeArgumentsCannotBeUsed (ec, "field", GetSignatureForError (), loc); } } @@ -5313,7 +5316,7 @@ namespace Mono.CSharp { bool IsSingleDimensionalArrayLength () { - if (best_candidate.DeclaringType != TypeManager.array_type || !best_candidate.HasGet || Name != "Length") + if (best_candidate.DeclaringType.BuiltinType != BuiltinTypeSpec.Type.Array || !best_candidate.HasGet || Name != "Length") return false; ArrayContainer ac = InstanceExpression.Type as ArrayContainer; @@ -5385,7 +5388,7 @@ namespace Mono.CSharp { { eclass = ExprClass.PropertyAccess; - if (best_candidate.IsNotRealProperty) { + if (best_candidate.IsNotCSharpCompatible) { Error_PropertyNotValid (rc); } @@ -5405,7 +5408,7 @@ namespace Mono.CSharp { public override void SetTypeArguments (ResolveContext ec, TypeArguments ta) { - Error_TypeArgumentsCannotBeUsed (ec.Report, "property", GetSignatureForError (), loc); + Error_TypeArgumentsCannotBeUsed (ec, "property", GetSignatureForError (), loc); } } @@ -5464,7 +5467,7 @@ namespace Mono.CSharp { public override Expression DoResolveLValue (ResolveContext ec, Expression right_side) { - if (right_side == EmptyExpression.OutAccess.Instance) { + if (right_side == EmptyExpression.OutAccess) { // TODO: best_candidate can be null at this point INamedBlockVariable variable = null; if (best_candidate != null && ec.CurrentBlock.ParametersBlock.TopBlock.GetLocalName (best_candidate.Name, ec.CurrentBlock, ref variable) && variable is Linq.RangeVariable) { @@ -5520,7 +5523,7 @@ namespace Mono.CSharp { best_candidate.GetSignatureForError ()); return false; } - } else if (!best_candidate.Get.IsAccessible (rc.CurrentType)) { + } else if (!best_candidate.Get.IsAccessible (rc)) { if (best_candidate.HasDifferentAccessibility) { rc.Report.SymbolRelatedToPreviousError (best_candidate.Get); rc.Report.Error (271, loc, "The property or indexer `{0}' cannot be used in this context because the get accessor is inaccessible", @@ -5547,7 +5550,7 @@ namespace Mono.CSharp { return false; } - if (!best_candidate.Set.IsAccessible (rc.CurrentType)) { + if (!best_candidate.Set.IsAccessible (rc)) { if (best_candidate.HasDifferentAccessibility) { rc.Report.SymbolRelatedToPreviousError (best_candidate.Set); rc.Report.Error (272, loc, "The property or indexer `{0}' cannot be used in this context because the set accessor is inaccessible", @@ -5733,7 +5736,7 @@ namespace Mono.CSharp { public override void SetTypeArguments (ResolveContext ec, TypeArguments ta) { - Error_TypeArgumentsCannotBeUsed (ec.Report, "event", GetSignatureForError (), loc); + Error_TypeArgumentsCannotBeUsed (ec, "event", GetSignatureForError (), loc); } } @@ -5877,7 +5880,7 @@ namespace Mono.CSharp { throw new InternalErrorException ("An implicitly typed local variable could not be redefined"); type = right_side.Type; - if (type == InternalType.Null || type == TypeManager.void_type || type == InternalType.AnonymousMethod || type == InternalType.MethodGroup) { + if (type == InternalType.NullLiteral || type.Kind == MemberKind.Void || type == InternalType.AnonymousMethod || type == InternalType.MethodGroup) { ec.Report.Error (815, loc, "An implicitly typed local variable declaration cannot be initialized with `{0}'", type.GetSignatureForError ()); @@ -5890,10 +5893,10 @@ namespace Mono.CSharp { protected override void Error_TypeOrNamespaceNotFound (IMemberContext ec) { - if (RootContext.Version < LanguageVersion.V_3) + if (ec.Module.Compiler.Settings.Version < LanguageVersion.V_3) base.Error_TypeOrNamespaceNotFound (ec); else - ec.Compiler.Report.Error (825, loc, "The contextual keyword `var' may only appear within a local variable declaration"); + ec.Module.Compiler.Report.Error (825, loc, "The contextual keyword `var' may only appear within a local variable declaration"); } } }