X-Git-Url: http://wien.tomnetworks.com/gitweb/?a=blobdiff_plain;f=mcs%2Fmcs%2Fecore.cs;h=dd3681529e0eb04c33be636a1d283bfb610cab05;hb=896975c58ebfe1fdcb6b7a16943b2d5fce3dd535;hp=cec0a6f2243a5e423baf708bffd9777338d75910;hpb=cff9f25510fa795e15a4492e26d4daeb6d62ea26;p=mono.git diff --git a/mcs/mcs/ecore.cs b/mcs/mcs/ecore.cs index cec0a6f2243..dd3681529e0 100644 --- a/mcs/mcs/ecore.cs +++ b/mcs/mcs/ecore.cs @@ -152,6 +152,35 @@ namespace Mono.CSharp { } } + // + // Used to workaround parser limitation where we cannot get + // start of statement expression location + // + public virtual Location StartLocation { + get { + return loc; + } + } + + public virtual MethodGroupExpr CanReduceLambda (AnonymousMethodBody body) + { + // + // Return method-group expression when the expression can be used as + // lambda replacement. A good example is array sorting where instead of + // code like + // + // Array.Sort (s, (a, b) => String.Compare (a, b)); + // + // we can use method group directly + // + // Array.Sort (s, String.Compare); + // + // Correct overload will be used because we do the reduction after + // best candidate was found. + // + return null; + } + // // Returns true when the expression during Emit phase breaks stack // by using await expression @@ -222,7 +251,7 @@ namespace Mono.CSharp { public void Error_ConstantCanBeInitializedWithNullOnly (ResolveContext rc, TypeSpec type, Location loc, string name) { rc.Report.Error (134, loc, "A constant `{0}' of reference type `{1}' can only be initialized with null", - name, TypeManager.CSharpName (type)); + name, type.GetSignatureForError ()); } protected virtual void Error_InvalidExpressionStatement (Report report, Location loc) @@ -253,7 +282,10 @@ namespace Mono.CSharp { protected void Error_ValueCannotBeConvertedCore (ResolveContext ec, Location loc, TypeSpec target, bool expl) { // The error was already reported as CS1660 - if (type == InternalType.AnonymousMethod || type == InternalType.ErrorType) + if (type == InternalType.AnonymousMethod) + return; + + if (type == InternalType.ErrorType || target == InternalType.ErrorType) return; string from_type = type.GetSignatureForError (); @@ -322,13 +354,15 @@ namespace Mono.CSharp { { ec.Report.SymbolRelatedToPreviousError (type); ec.Report.Error (117, loc, "`{0}' does not contain a definition for `{1}'", - TypeManager.CSharpName (type), name); + type.GetSignatureForError (), name); } public virtual void Error_ValueAssignment (ResolveContext rc, Expression rhs) { if (rhs == EmptyExpression.LValueMemberAccess || rhs == EmptyExpression.LValueMemberOutAccess) { // Already reported as CS1612 + } else if (rhs == EmptyExpression.OutAccess) { + rc.Report.Error (1510, loc, "A ref or out argument must be an assignable variable"); } else { rc.Report.Error (131, loc, "The left-hand side of an assignment must be a variable, a property or an indexer"); } @@ -463,10 +497,7 @@ namespace Mono.CSharp { if (e == null) { if (errors == ec.Report.Errors) { - if (out_access) - ec.Report.Error (1510, loc, "A ref or out argument must be an assignable variable"); - else - Error_ValueAssignment (ec, right_side); + Error_ValueAssignment (ec, right_side); } return null; } @@ -480,6 +511,23 @@ namespace Mono.CSharp { return e; } + public Constant ResolveLabelConstant (ResolveContext rc) + { + var expr = Resolve (rc); + if (expr == null) + return null; + + Constant c = expr as Constant; + if (c == null) { + if (c.type != InternalType.ErrorType) + rc.Report.Error (150, StartLocation, "A constant value is expected"); + + return null; + } + + return c; + } + public virtual void EncodeAttributeValue (IMemberContext rc, AttributeEncoder enc, TypeSpec targetType) { rc.Module.Compiler.Report.Error (182, loc, @@ -1055,8 +1103,8 @@ namespace Mono.CSharp { /// being that they would support an extra Emition interface that /// does not leave a result on the stack. /// - public abstract class ExpressionStatement : Expression { - + public abstract class ExpressionStatement : Expression + { public ExpressionStatement ResolveStatement (BlockContext ec) { Expression e = Resolve (ec); @@ -1446,7 +1494,7 @@ namespace Mono.CSharp { public override string GetSignatureForError() { - return TypeManager.CSharpName (Type); + return Type.GetSignatureForError (); } public override object GetValue () @@ -1505,7 +1553,7 @@ namespace Mono.CSharp { } } - public override Constant ConvertExplicitly(bool in_checked_context, TypeSpec target_type) + public override Constant ConvertExplicitly (bool in_checked_context, TypeSpec target_type) { if (Child.Type == target_type) return Child; @@ -2389,15 +2437,15 @@ namespace Mono.CSharp { } } - public override FullNamedExpression ResolveAsTypeOrNamespace (IMemberContext ec) + public override FullNamedExpression ResolveAsTypeOrNamespace (IMemberContext mc) { - FullNamedExpression fne = ec.LookupNamespaceOrType (Name, Arity, LookupMode.Normal, loc); + FullNamedExpression fne = mc.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); - if (ct.ResolveAsType (ec) == null) + if (ct.ResolveAsType (mc) == null) return null; return ct; @@ -2413,21 +2461,21 @@ namespace Mono.CSharp { return fne; } - if (Arity == 0 && Name == "dynamic" && ec.Module.Compiler.Settings.Version > LanguageVersion.V_3) { - if (!ec.Module.PredefinedAttributes.Dynamic.IsDefined) { - ec.Module.Compiler.Report.Error (1980, Location, + if (Arity == 0 && Name == "dynamic" && mc.Module.Compiler.Settings.Version > LanguageVersion.V_3) { + if (!mc.Module.PredefinedAttributes.Dynamic.IsDefined) { + mc.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 ()); + mc.Module.PredefinedAttributes.Dynamic.GetSignatureForError ()); } fne = new DynamicTypeExpr (loc); - fne.ResolveAsType (ec); + fne.ResolveAsType (mc); } if (fne != null) return fne; - Error_TypeOrNamespaceNotFound (ec); + Error_TypeOrNamespaceNotFound (mc); return null; } @@ -3215,7 +3263,7 @@ namespace Mono.CSharp { class ExtensionMethodGroupExpr : MethodGroupExpr, OverloadResolver.IErrorHandler { ExtensionMethodCandidates candidates; - public readonly Expression ExtensionExpression; + public Expression ExtensionExpression; public ExtensionMethodGroupExpr (ExtensionMethodCandidates candidates, Expression extensionExpr, Location loc) : base (candidates.Methods.Cast().ToList (), extensionExpr.Type, loc) @@ -3259,8 +3307,16 @@ namespace Mono.CSharp { if (arguments == null) arguments = new Arguments (1); + ExtensionExpression = ExtensionExpression.Resolve (ec); + if (ExtensionExpression == null) + return null; + + var cand = candidates; arguments.Insert (0, new Argument (ExtensionExpression, Argument.AType.ExtensionType)); var res = base.OverloadResolve (ec, ref arguments, ehandler ?? this, restr); + + // Restore candidates in case we are running in probing mode + candidates = cand; // Store resolved argument and restore original arguments if (res == null) { @@ -3470,7 +3526,7 @@ namespace Mono.CSharp { public override void Error_ValueCannotBeConverted (ResolveContext ec, TypeSpec target, bool expl) { ec.Report.Error (428, loc, "Cannot convert method group `{0}' to non-delegate type `{1}'. Consider using parentheses to invoke the method", - Name, TypeManager.CSharpName (target)); + Name, target.GetSignatureForError ()); } public static bool IsExtensionMethodArgument (Expression expr) @@ -4522,17 +4578,18 @@ namespace Mono.CSharp { // It can be applicable in expanded form (when not doing exact match like for delegates) // if (score != 0 && (p_mod & Parameter.Modifier.PARAMS) != 0 && (restrictions & Restrictions.CovariantDelegate) == 0) { - if (!params_expanded_form) + if (!params_expanded_form) { pt = ((ElementTypeSpec) pt).Element; + } if (score > 0) score = IsArgumentCompatible (ec, a, Parameter.Modifier.NONE, pt); - if (score == 0) { - params_expanded_form = true; - } else if (score < 0) { + if (score < 0) { params_expanded_form = true; dynamicArgument = true; + } else if (score == 0 || arg_count > pd.Count) { + params_expanded_form = true; } } @@ -5011,14 +5068,14 @@ namespace Mono.CSharp { string index = (idx + 1).ToString (); if (((mod & Parameter.Modifier.RefOutMask) ^ (a.Modifier & Parameter.Modifier.RefOutMask)) != 0) { if ((mod & Parameter.Modifier.RefOutMask) == 0) - ec.Report.Error (1615, loc, "Argument `#{0}' does not require `{1}' modifier. Consider removing `{1}' modifier", + ec.Report.Error (1615, a.Expr.Location, "Argument `#{0}' does not require `{1}' modifier. Consider removing `{1}' modifier", index, Parameter.GetModifierSignature (a.Modifier)); else - ec.Report.Error (1620, loc, "Argument `#{0}' is missing `{1}' modifier", + ec.Report.Error (1620, a.Expr.Location, "Argument `#{0}' is missing `{1}' modifier", index, Parameter.GetModifierSignature (mod)); } else { string p1 = a.GetSignatureForError (); - string p2 = TypeManager.CSharpName (paramType); + string p2 = paramType.GetSignatureForError (); if (p1 == p2) { p1 = a.Type.GetSignatureForErrorIncludingAssemblyName (); @@ -5611,6 +5668,11 @@ namespace Mono.CSharp { override public Expression DoResolveLValue (ResolveContext ec, Expression right_side) { + if (spec is FixedFieldSpec) { + // It could be much better error message but we want to be error compatible + Error_ValueAssignment (ec, right_side); + } + Expression e = DoResolve (ec, right_side); if (e == null) @@ -5929,6 +5991,21 @@ namespace Mono.CSharp { #endregion + public override MethodGroupExpr CanReduceLambda (AnonymousMethodBody body) + { + if (best_candidate == null || !(best_candidate.IsStatic || InstanceExpression is This)) + return null; + + var args_count = arguments == null ? 0 : arguments.Count; + if (args_count != body.Parameters.Count && args_count == 0) + return null; + + var mg = MethodGroupExpr.CreatePredefined (best_candidate.Get, DeclaringType, loc); + mg.InstanceExpression = InstanceExpression; + + return mg; + } + public static PropertyExpr CreatePredefined (PropertySpec spec, Location loc) { return new PropertyExpr (spec, loc) { @@ -6550,8 +6627,9 @@ namespace Mono.CSharp { // Don't capture temporary variables except when using // state machine redirection and block yields // - if (ec.CurrentAnonymousMethod != null && ec.CurrentAnonymousMethod.IsIterator && - ec.CurrentBlock.Explicit.HasYield && ec.IsVariableCapturingRequired) { + if (ec.CurrentAnonymousMethod != null && ec.CurrentAnonymousMethod is StateMachineInitializer && + (ec.CurrentBlock.Explicit.HasYield || ec.CurrentBlock.Explicit.HasAwait) && + ec.IsVariableCapturingRequired) { AnonymousMethodStorey storey = li.Block.Explicit.CreateAnonymousMethodStorey (ec); storey.CaptureLocalVariable (ec, li); }