}
}
+ //
+ // 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
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)
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 ();
{
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");
}
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;
}
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,
/// being that they would support an extra Emition interface that
/// does not leave a result on the stack.
/// </summary>
- public abstract class ExpressionStatement : Expression {
-
+ public abstract class ExpressionStatement : Expression
+ {
public ExpressionStatement ResolveStatement (BlockContext ec)
{
Expression e = Resolve (ec);
public override string GetSignatureForError()
{
- return TypeManager.CSharpName (Type);
+ return Type.GetSignatureForError ();
}
public override object GetValue ()
}
}
- 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;
}
}
- 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;
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;
}
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<MemberSpec>().ToList (), extensionExpr.Type, loc)
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) {
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)
// 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;
}
}
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 ();
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)
#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) {
// 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);
}