}
// Not nice but we have broken hierarchy.
- public virtual void CheckMarshalByRefAccess ()
+ public virtual void CheckMarshalByRefAccess (EmitContext ec)
{
}
- public virtual bool GetAttributableValue (Type valueType, out object value)
+ public virtual bool GetAttributableValue (Type value_type, out object value)
{
Attribute.Error_AttributeArgumentNotValid (loc);
value = null;
return TypeManager.IsPrivateAccessible (invocation_type, mi.DeclaringType) ||
TypeManager.IsNestedChildOf (invocation_type, mi.DeclaringType);
- if (mi.DeclaringType.Assembly == invocation_type.Assembly ||
- TypeManager.IsFriendAssembly (mi.DeclaringType.Assembly)) {
+ if (TypeManager.IsThisOrFriendAssembly (mi.DeclaringType.Assembly)) {
if (ma == MethodAttributes.Assembly || ma == MethodAttributes.FamORAssem)
return true;
} else {
return true;
}
+ public virtual bool IsNull {
+ get {
+ return false;
+ }
+ }
+
/// <summary>
/// Performs semantic analysis on the Expression
/// </summary>
if (TypeManager.IsGenericParameter (Type) && TypeManager.IsGenericParameter (target) && type.Name == target.Name) {
#if GMCS_SOURCE
- string sig1 = Type.DeclaringMethod == null ?
- TypeManager.CSharpName (Type.DeclaringType) :
- TypeManager.CSharpSignature (Type.DeclaringMethod);
+ 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);
/// </remarks>
public abstract void Emit (EmitContext ec);
- public virtual void EmitBranchable (EmitContext ec, Label target, bool onTrue)
+ public virtual void EmitBranchable (EmitContext ec, Label target, bool on_true)
{
Emit (ec);
- ec.ig.Emit (onTrue ? OpCodes.Brtrue : OpCodes.Brfalse, target);
+ ec.ig.Emit (on_true ? OpCodes.Brtrue : OpCodes.Brfalse, target);
}
/// <summary>
/// Returns a fully formed expression after a MemberLookup
/// </summary>
///
- public static Expression ExprClassFromMemberInfo (Type containerType, MemberInfo mi, Location loc)
+ public static Expression ExprClassFromMemberInfo (Type container_type, MemberInfo mi, Location loc)
{
if (mi is EventInfo)
return new EventExpr ((EventInfo) mi, loc);
- else if (mi is FieldInfo)
- return new FieldExpr ((FieldInfo) mi, loc);
- else if (mi is PropertyInfo)
- return new PropertyExpr (containerType, (PropertyInfo) mi, loc);
- else if (mi is Type){
+ else if (mi is FieldInfo) {
+ FieldInfo fi = (FieldInfo) mi;
+ if (fi.IsLiteral || (fi.IsInitOnly && fi.FieldType == TypeManager.decimal_type))
+ return new ConstantExpr (fi, loc);
+ return new FieldExpr (fi, loc);
+ } else if (mi is PropertyInfo)
+ return new PropertyExpr (container_type, (PropertyInfo) mi, loc);
+ else if (mi is Type) {
return new TypeExpression ((System.Type) mi, loc);
}
return null;
}
- protected static ArrayList almostMatchedMembers = new ArrayList (4);
+ protected static ArrayList almost_matched_members = new ArrayList (4);
//
// FIXME: Probably implement a cache for (t,name,current_access_set)?
string name, MemberTypes mt,
BindingFlags bf, Location loc)
{
- almostMatchedMembers.Clear ();
+ almost_matched_members.Clear ();
MemberInfo [] mi = TypeManager.MemberLookup (container_type, qualifier_type,
- queried_type, mt, bf, name, almostMatchedMembers);
+ queried_type, mt, bf, name, almost_matched_members);
if (mi == null)
return null;
Type queried_type, string name, string class_name,
MemberTypes mt, BindingFlags bf)
{
- if (almostMatchedMembers.Count != 0) {
- for (int i = 0; i < almostMatchedMembers.Count; ++i) {
- MemberInfo m = (MemberInfo) almostMatchedMembers [i];
+ if (almost_matched_members.Count != 0) {
+ for (int i = 0; i < almost_matched_members.Count; ++i) {
+ MemberInfo m = (MemberInfo) almost_matched_members [i];
for (int j = 0; j < i; ++j) {
- if (m == almostMatchedMembers [j]) {
+ if (m == almost_matched_members [j]) {
m = null;
break;
}
ErrorIsInaccesible (loc, TypeManager.GetFullNameSignature (m));
}
}
- almostMatchedMembers.Clear ();
+ almost_matched_members.Clear ();
return null;
}
return new MethodGroupExpr (members, type, loc);
}
+ protected virtual void Error_NegativeArrayIndex (Location loc)
+ {
+ throw new NotImplementedException ();
+ }
+
/// <summary>
/// Returns an expression that can be used to invoke operator true
/// on the expression if it exists.
static Expression GetOperatorTrueOrFalse (EmitContext ec, Expression e, bool is_true, Location loc)
{
MethodGroupExpr operator_group;
-
-#if GMCS_SOURCE
- if (TypeManager.IsNullableType (e.Type))
- return new Nullable.OperatorTrueOrFalse (e, is_true, loc).Resolve (ec);
-#endif
-
operator_group = MethodLookup (ec.ContainerType, e.Type, is_true ? "op_True" : "op_False", loc) as MethodGroupExpr;
if (operator_group == null)
return null;
ArrayList arguments = new ArrayList (1);
arguments.Add (new Argument (e, Argument.AType.Expression));
operator_group = operator_group.OverloadResolve (
- ec, arguments, false, loc);
+ ec, ref arguments, false, loc);
if (operator_group == null)
return null;
- return new StaticCallExpr ((MethodInfo) operator_group, arguments, loc);
+ return new UserOperatorCall (operator_group, arguments, null, loc);
}
/// <summary>
if (t == TypeManager.enum_type)
ig.Emit (OpCodes.Ldind_Ref);
else
- LoadFromPtr (ig, TypeManager.EnumToUnderlying (t));
+ LoadFromPtr (ig, TypeManager.GetEnumUnderlyingType (t));
} else if (t.IsValueType || TypeManager.IsGenericParameter (t))
ig.Emit (OpCodes.Ldobj, t);
else if (t.IsPointer)
public static void StoreFromPtr (ILGenerator ig, Type type)
{
if (TypeManager.IsEnumType (type))
- type = TypeManager.EnumToUnderlying (type);
+ type = TypeManager.GetEnumUnderlyingType (type);
if (type == TypeManager.int32_type || type == TypeManager.uint32_type)
ig.Emit (OpCodes.Stind_I4);
else if (type == TypeManager.int64_type || type == TypeManager.uint64_type)
return 0;
}
- public static void Error_NegativeArrayIndex (Location loc)
- {
- Report.Error (248, loc, "Cannot create an array with a negative size");
- }
-
protected void Error_CannotCallAbstractBase (string name)
{
Report.Error (205, loc, "Cannot call an abstract base member `{0}'", name);
}
+ protected void Error_CannotModifyIntermediateExpressionValue (EmitContext ec)
+ {
+ Report.SymbolRelatedToPreviousError (type);
+ if (ec.CurrentInitializerVariable != null) {
+ Report.Error (1918, loc, "Members of a value type property `{0}' cannot be assigned with an object initializer",
+ GetSignatureForError ());
+ } else {
+ Report.Error (1612, loc, "Cannot modify a value type return value of `{0}'. Consider storing the value in a temporary variable",
+ GetSignatureForError ());
+ }
+ }
+
//
// Converts `source' to an int, uint, long or ulong.
//
- public Expression ExpressionToArrayArgument (EmitContext ec, Expression source, Location loc)
+ public Expression ConvertExpressionToArrayIndex (EmitContext ec, Expression source)
{
- Expression target;
+ Expression converted;
using (ec.With (EmitContext.Flags.CheckState, true)) {
- target = Convert.ImplicitConversion (ec, source, TypeManager.int32_type, loc);
- if (target == null)
- target = Convert.ImplicitConversion (ec, source, TypeManager.uint32_type, loc);
- if (target == null)
- target = Convert.ImplicitConversion (ec, source, TypeManager.int64_type, loc);
- if (target == null)
- target = Convert.ImplicitConversion (ec, source, TypeManager.uint64_type, loc);
-
- if (target == null) {
- source.Error_ValueCannotBeConverted (ec, loc, TypeManager.int32_type, false);
+ converted = Convert.ImplicitConversion (ec, source, TypeManager.int32_type, source.loc);
+ if (converted == null)
+ converted = Convert.ImplicitConversion (ec, source, TypeManager.uint32_type, source.loc);
+ if (converted == null)
+ converted = Convert.ImplicitConversion (ec, source, TypeManager.int64_type, source.loc);
+ if (converted == null)
+ converted = Convert.ImplicitConversion (ec, source, TypeManager.uint64_type, source.loc);
+
+ if (converted == null) {
+ source.Error_ValueCannotBeConverted (ec, source.loc, TypeManager.int32_type, false);
return null;
}
}
//
// Only positive constants are allowed at compile time
//
- if (target is Constant){
- if (target is IntConstant){
- if (((IntConstant) target).Value < 0){
- Error_NegativeArrayIndex (loc);
- return null;
- }
+ Constant c = converted as Constant;
+ if (c != null) {
+ if (c.IsNegative) {
+ Error_NegativeArrayIndex (source.loc);
}
-
- if (target is LongConstant){
- if (((LongConstant) target).Value < 0){
- Error_NegativeArrayIndex (loc);
- return null;
- }
- }
-
+ return c;
}
- return target;
+ return new ArrayIndexCast (converted).Resolve (ec);
}
//
return cloned;
}
+
+ public virtual Expression CreateExpressionTree (EmitContext ec)
+ {
+ throw new NotImplementedException (
+ "Expression tree conversion not implemented for " + GetType ());
+ }
+
+ protected Expression CreateExpressionFactoryCall (string name, ArrayList args)
+ {
+ return CreateExpressionFactoryCall (name, null, args, loc);
+ }
+
+ protected Expression CreateExpressionFactoryCall (string name, TypeArguments typeArguments, ArrayList args)
+ {
+ return CreateExpressionFactoryCall (name, typeArguments, args, loc);
+ }
+
+ public static Expression CreateExpressionFactoryCall (string name, TypeArguments typeArguments, ArrayList args, Location loc)
+ {
+ TypeExpr texpr = TypeManager.expression_type_expr;
+ if (texpr == null) {
+ Type t = TypeManager.CoreLookupType ("System.Linq.Expressions", "Expression", Kind.Class, true);
+ if (t == null)
+ return null;
+
+ TypeManager.expression_type_expr = texpr = new TypeExpression (t, Location.Null);
+ }
+
+ return new Invocation (new MemberAccess (texpr, name, typeArguments, loc), args);
+ }
}
/// <summary>
if (c != null)
return new EmptyConstantCast (c, type);
+ //
+ // No double conversion required when wrapping nullable types
+ //
+ if (TypeManager.IsNullableType (type)) {
+ EmptyCast empty_cast = child as EmptyCast;
+ if (empty_cast != null) {
+ if (TypeManager.IsNullableTypeOf (empty_cast.type, type))
+ throw new InternalErrorException ("Missing nullable underlying type conversion {0} != {1}",
+ TypeManager.CSharpName (empty_cast.type), TypeManager.CSharpName (type));
+
+ empty_cast.type = type;
+ return empty_cast;
+ }
+ }
+
return new EmptyCast (child, type);
- }
+ }
+
+ public override Expression CreateExpressionTree (EmitContext ec)
+ {
+ ArrayList args = new ArrayList (2);
+ args.Add (new Argument (child.CreateExpressionTree (ec)));
+ args.Add (new Argument (new TypeOf (new TypeExpression (type, loc), loc)));
+ return CreateExpressionFactoryCall (ec.CheckState ? "ConvertChecked" : "Convert", args);
+ }
public override Expression DoResolve (EmitContext ec)
{
child.Emit (ec);
}
- public override bool GetAttributableValue (Type valueType, out object value)
+ public override bool GetAttributableValue (Type value_type, out object value)
{
- return child.GetAttributableValue (valueType, out value);
+ return child.GetAttributableValue (value_type, out value);
}
protected override void CloneTo (CloneContext clonectx, Expression t)
foreach (MethodInfo oper in mi) {
ParameterData pd = TypeManager.GetParameterData (oper);
- if (pd.ParameterType (0) == child.Type && oper.ReturnType == type)
+ if (pd.ParameterType (0) == child.Type && TypeManager.TypeToCoreType (oper.ReturnType) == type)
return oper;
}
foreach (MethodInfo oper in mi) {
ParameterData pd = TypeManager.GetParameterData (oper);
- if (pd.ParameterType (0) == child.Type && oper.ReturnType == type)
+ if (pd.ParameterType (0) == child.Type && TypeManager.TypeToCoreType (oper.ReturnType) == type)
return oper;
}
foreach (MethodInfo oper in all_oper) {
ParameterData pd = TypeManager.GetParameterData (oper);
if (pd.ParameterType (0) == TypeManager.decimal_type)
- operators.Add (oper.ReturnType, oper);
+ operators.Add (TypeManager.TypeToCoreType (oper.ReturnType), oper);
}
}
return child.GetValue ();
}
- public override Constant ConvertExplicitly (bool inCheckedContext, Type target_type)
+ public override Constant ConvertExplicitly (bool in_checked_context, Type target_type)
{
// FIXME: check that 'type' can be converted to 'target_type' first
- return child.ConvertExplicitly (inCheckedContext, target_type);
+ return child.ConvertExplicitly (in_checked_context, target_type);
}
public override Constant Increment ()
get { return child.IsNegative; }
}
+ public override bool IsNull {
+ get { return child.IsNull; }
+ }
+
public override bool IsZeroInteger {
get { return child.IsZeroInteger; }
}
Child.Emit (ec);
}
- public override bool GetAttributableValue (Type valueType, out object value)
+ public override bool GetAttributableValue (Type value_type, out object value)
{
value = GetTypedValue ();
return true;
}
}
- public override Constant ConvertExplicitly(bool inCheckedContext, Type target_type)
+ public override Constant ConvertExplicitly(bool in_checked_context, Type target_type)
{
if (Child.Type == target_type)
return Child;
- return Child.ConvertExplicitly (inCheckedContext, target_type);
+ return Child.ConvertExplicitly (in_checked_context, target_type);
}
public override Constant ConvertImplicitly (Type type)
second_valid = true;
}
+ public override Expression CreateExpressionTree (EmitContext ec)
+ {
+ // A cast has no expresion tree representation
+ return child.CreateExpressionTree (ec);
+ }
+
public override Expression DoResolve (EmitContext ec)
{
// This should never be invoked, we are born in fully
if (second_valid)
ec.ig.Emit (op2);
- }
+ }
+
+ public Type UnderlyingType {
+ get { return child.Type; }
+ }
}
/// <summary>
ec.ig.Emit (OpCodes.Castclass, type);
}
}
+
+ //
+ // Used when resolved expression has different representations for
+ // expression trees and emit phase
+ //
+ public class ReducedExpression : Expression
+ {
+ class ReducedConstantExpression : Constant
+ {
+ readonly Constant expr;
+ readonly Expression orig_expr;
+
+ public ReducedConstantExpression (Constant expr, Expression orig_expr)
+ : base (expr.Location)
+ {
+ this.expr = expr;
+ this.orig_expr = orig_expr;
+ }
+
+ public override string AsString ()
+ {
+ return expr.AsString ();
+ }
+
+ public override Expression CreateExpressionTree (EmitContext ec)
+ {
+ return orig_expr.CreateExpressionTree (ec);
+ }
+
+ public override object GetValue ()
+ {
+ return expr.GetValue ();
+ }
+
+ public override Constant ConvertExplicitly (bool in_checked_context, Type target_type)
+ {
+ throw new NotImplementedException ();
+ }
+
+ public override Expression DoResolve (EmitContext ec)
+ {
+ eclass = expr.eclass;
+ type = expr.Type;
+ return this;
+ }
+
+ public override Constant Increment ()
+ {
+ throw new NotImplementedException ();
+ }
+
+ public override bool IsDefaultValue {
+ get {
+ return expr.IsDefaultValue;
+ }
+ }
+
+ public override bool IsNegative {
+ get {
+ return expr.IsNegative;
+ }
+ }
+
+ public override void Emit (EmitContext ec)
+ {
+ expr.Emit (ec);
+ }
+ }
+
+ readonly Expression expr, orig_expr;
+
+ private ReducedExpression (Expression expr, Expression orig_expr)
+ {
+ this.expr = expr;
+ this.orig_expr = orig_expr;
+ }
+
+ public static Expression Create (Constant expr, Expression original_expr)
+ {
+ return new ReducedConstantExpression (expr, original_expr);
+ }
+
+ public static Expression Create (Expression expr, Expression original_expr)
+ {
+ Constant c = expr as Constant;
+ if (c != null)
+ return Create (c, original_expr);
+
+ return new ReducedExpression (expr, original_expr);
+ }
+
+ public override Expression CreateExpressionTree (EmitContext ec)
+ {
+ return orig_expr.CreateExpressionTree (ec);
+ }
+
+ public override Expression DoResolve (EmitContext ec)
+ {
+ eclass = expr.eclass;
+ type = expr.Type;
+ return this;
+ }
+
+ public override void Emit (EmitContext ec)
+ {
+ expr.Emit (ec);
+ }
+ }
/// <summary>
/// SimpleName expressions are formed of a single word and only happen at the beginning
return SimpleNameResolve (ec, null, intermediate);
}
- private bool IsNestedChild (Type t, Type parent)
+ static bool IsNestedChild (Type t, Type parent)
{
- if (parent == null)
- return false;
-
while (parent != null) {
- parent = TypeManager.DropGenericTypeArguments (parent);
- if (TypeManager.IsNestedChildOf (t, parent))
+ if (TypeManager.IsNestedChildOf (t, TypeManager.DropGenericTypeArguments (parent)))
return true;
parent = parent.BaseType;
return null;
DeclSpace ds = ec.DeclContainer;
- while (ds != null) {
- if (IsNestedChild (t, ds.TypeBuilder))
- break;
-
+ while (ds != null && !IsNestedChild (t, ds.TypeBuilder))
ds = ds.Parent;
- }
if (ds == null)
return null;
if (Arguments != null) {
FullNamedExpression retval = ec.DeclContainer.LookupNamespaceOrType (SimpleName.RemoveGenericArity (Name), loc, true);
if (retval != null) {
- Namespace.Error_TypeArgumentsCannotBeUsed (retval.Type, loc, "type");
+ Namespace.Error_TypeArgumentsCannotBeUsed (retval.Type, loc);
return;
}
}
e = null;
}
- if (almost_matched == null && almostMatchedMembers.Count > 0) {
+ if (almost_matched == null && almost_matched_members.Count > 0) {
almost_matched_type = lookup_ds.TypeBuilder;
- almost_matched = (ArrayList) almostMatchedMembers.Clone ();
+ almost_matched = (ArrayList) almost_matched_members.Clone ();
}
}
if (e == null) {
- if (almost_matched == null && almostMatchedMembers.Count > 0) {
+ if (almost_matched == null && almost_matched_members.Count > 0) {
almost_matched_type = ec.ContainerType;
- almost_matched = (ArrayList) almostMatchedMembers.Clone ();
+ almost_matched = (ArrayList) almost_matched_members.Clone ();
}
e = ResolveAsTypeStep (ec, true);
}
}
if (almost_matched != null)
- almostMatchedMembers = almost_matched;
+ almost_matched_members = almost_matched;
if (almost_matched_type == null)
almost_matched_type = ec.ContainerType;
Error_MemberLookupFailed (ec.ContainerType, null, almost_matched_type, Name,
if (!me.IsStatic &&
(!intermediate || !IdenticalNameAndTypeName (ec, me, loc))) {
Error_ObjectRefRequired (ec, loc, me.GetSignatureForError ());
- return EmptyExpression.Null;
+ return null;
}
//
left = new TypeExpression (ec.ContainerType, loc);
}
- e = me.ResolveMemberAccess (ec, left, loc, null);
- if (e == null)
- return null;
-
- me = e as MemberExpr;
+ me = me.ResolveMemberAccess (ec, left, loc, null);
if (me == null)
- return e;
+ return null;
if (Arguments != null) {
- MethodGroupExpr mg = me as MethodGroupExpr;
- if (mg == null)
- return null;
-
- return mg.ResolveGeneric (ec, Arguments);
+ Arguments.Resolve (ec);
+ me.SetTypeArguments (Arguments);
}
if (!me.IsStatic && (me.InstanceExpression != null) &&
return ds.CheckAccessLevel (Type);
}
- public virtual bool AsAccessible (DeclSpace ds, int flags)
+ public virtual bool AsAccessible (DeclSpace ds)
{
- return ds.AsAccessible (Type, flags);
+ return ds.IsAccessibleAs (Type);
}
public virtual bool IsClass {
return texpr.CheckAccessLevel (ds);
}
- public override bool AsAccessible (DeclSpace ds, int flags)
+ public override bool AsAccessible (DeclSpace ds)
{
- return texpr.AsAccessible (ds, flags);
+ return texpr.AsAccessible (ds);
}
public override bool IsClass {
/// </summary>
public abstract class MemberExpr : Expression
{
+ protected bool is_base;
+
/// <summary>
/// The name of this member.
/// </summary>
get;
}
+ //
+ // When base.member is used
+ //
+ public bool IsBase {
+ get { return is_base; }
+ set { is_base = value; }
+ }
+
/// <summary>
/// Whether this is an instance member.
/// </summary>
// TODO: possible optimalization
// Cache resolved constant result in FieldBuilder <-> expression map
- public virtual Expression ResolveMemberAccess (EmitContext ec, Expression left, Location loc,
+ public virtual MemberExpr ResolveMemberAccess (EmitContext ec, Expression left, Location loc,
SimpleName original)
{
//
if (original != null && original.IdenticalNameAndTypeName (ec, left, loc))
return this;
- error176 (loc, GetSignatureForError ());
- return null;
+ return ResolveExtensionMemberAccess (left);
}
InstanceExpression = left;
+ return this;
+ }
+ protected virtual MemberExpr ResolveExtensionMemberAccess (Expression left)
+ {
+ error176 (loc, GetSignatureForError ());
return this;
}
if (prepare_for_load)
ec.ig.Emit (OpCodes.Dup);
}
+
+ public virtual void SetTypeArguments (TypeArguments ta)
+ {
+ // TODO: need to get correct member type
+ Report.Error (307, loc, "The property `{0}' cannot be used with type arguments",
+ GetSignatureForError ());
+ }
}
///
///
public class ExtensionMethodGroupExpr : MethodGroupExpr
{
- readonly NamespaceEntry namespaceEntry;
+ readonly NamespaceEntry namespace_entry;
public Expression ExtensionExpression;
Argument extension_argument;
public ExtensionMethodGroupExpr (ArrayList list, NamespaceEntry n, Type extensionType, Location l)
: base (list, extensionType, l)
{
- this.namespaceEntry = n;
- }
-
- public override bool IsBase {
- get { return true; }
+ this.namespace_entry = n;
}
public override bool IsStatic {
}
public bool IsTopLevel {
- get { return namespaceEntry == null; }
+ get { return namespace_entry == null; }
}
public override void EmitArguments (EmitContext ec, ArrayList arguments)
base.EmitCall (ec, arguments);
}
- public override MethodGroupExpr OverloadResolve (EmitContext ec, ArrayList arguments, bool may_fail, Location loc)
+ public override MethodGroupExpr OverloadResolve (EmitContext ec, ref ArrayList arguments, bool may_fail, Location loc)
{
- if ((ExtensionExpression.eclass & (ExprClass.Value | ExprClass.Variable)) == 0)
- return base.OverloadResolve (ec, arguments, may_fail, loc);
-
if (arguments == null)
arguments = new ArrayList (1);
arguments.Insert (0, new Argument (ExtensionExpression));
- MethodGroupExpr mg = ResolveOverloadExtensions (ec, arguments, namespaceEntry, loc);
+ MethodGroupExpr mg = ResolveOverloadExtensions (ec, arguments, namespace_entry, loc);
// Store resolved argument and restore original arguments
if (mg != null)
MethodGroupExpr ResolveOverloadExtensions (EmitContext ec, ArrayList arguments, NamespaceEntry ns, Location loc)
{
// Use normal resolve rules
- MethodGroupExpr mg = base.OverloadResolve (ec, arguments, ns != null, loc);
+ MethodGroupExpr mg = base.OverloadResolve (ec, ref arguments, ns != null, loc);
if (mg != null)
return mg;
// Search continues
ExtensionMethodGroupExpr e = ns.LookupExtensionMethod (type, null, Name);
if (e == null)
- return base.OverloadResolve (ec, arguments, false, loc);
+ return base.OverloadResolve (ec, ref arguments, false, loc);
e.ExtensionExpression = ExtensionExpression;
- return e.ResolveOverloadExtensions (ec, arguments, e.namespaceEntry, loc);
+ return e.ResolveOverloadExtensions (ec, arguments, e.namespace_entry, loc);
}
}
bool NoExactMatch (EmitContext ec, MethodBase method);
}
- public static IErrorHandler CustomErrorHandler;
+ public IErrorHandler CustomErrorHandler;
public MethodBase [] Methods;
MethodBase best_candidate;
- bool has_type_arguments;
+ // TODO: make private
+ public TypeArguments type_arguments;
bool identical_type_name;
- bool is_base;
+ Type delegate_type;
public MethodGroupExpr (MemberInfo [] mi, Type type, Location l)
: this (type, l)
public override Type DeclaringType {
get {
- //
- // We assume that the top-level type is in the end
- //
+ //
+ // We assume that the top-level type is in the end
+ //
return Methods [Methods.Length - 1].DeclaringType;
- //return Methods [0].DeclaringType;
+ //return Methods [0].DeclaringType;
}
}
- public bool HasTypeArguments {
- get {
- return has_type_arguments;
+ public Type DelegateType {
+ set {
+ delegate_type = value;
}
}
}
}
- public virtual bool IsBase {
- get {
- return is_base;
- }
- set {
- is_base = value;
- }
- }
-
public override string GetSignatureForError ()
{
if (best_candidate != null)
public override bool IsInstance {
get {
+ if (best_candidate != null)
+ return !best_candidate.IsStatic;
+
foreach (MethodBase mb in Methods)
if (!mb.IsStatic)
return true;
public override bool IsStatic {
get {
+ if (best_candidate != null)
+ return best_candidate.IsStatic;
+
foreach (MethodBase mb in Methods)
if (mb.IsStatic)
return true;
return (MethodInfo)mg.best_candidate;
}
- /// <summary>
- /// Determines "better conversion" as specified in 14.4.2.3
- ///
- /// Returns : p if a->p is better,
- /// q if a->q is better,
- /// null if neither is better
- /// </summary>
- static Type BetterConversion (EmitContext ec, Argument a, Type p, Type q)
+ //
+ // 7.4.3.3 Better conversion from expression
+ // Returns : 1 if a->p is better,
+ // 2 if a->q is better,
+ // 0 if neither is better
+ //
+ static int BetterExpressionConversion (EmitContext ec, Argument a, Type p, Type q)
{
Type argument_type = TypeManager.TypeToCoreType (a.Type);
- Expression argument_expr = a.Expr;
+ if (argument_type == TypeManager.anonymous_method_type && RootContext.Version > LanguageVersion.ISO_2) {
+ //
+ // Uwrap delegate from Expression<T>
+ //
+ if (TypeManager.DropGenericTypeArguments (p) == TypeManager.expression_type) {
+ p = TypeManager.GetTypeArguments (p) [0];
+ q = TypeManager.GetTypeArguments (q) [0];
+ }
+ p = Delegate.GetInvokeMethod (null, p).ReturnType;
+ q = Delegate.GetInvokeMethod (null, q).ReturnType;
+ } else {
+ if (argument_type == p)
+ return 1;
- if (argument_type == null)
- throw new Exception ("Expression of type " + a.Expr +
- " does not resolve its type");
+ if (argument_type == q)
+ return 2;
+ }
- if (p == null || q == null)
- throw new InternalErrorException ("BetterConversion Got a null conversion");
+ return BetterTypeConversion (ec, p, q);
+ }
- if (p == q)
- return null;
+ //
+ // 7.4.3.4 Better conversion from type
+ //
+ public static int BetterTypeConversion (EmitContext ec, Type p, Type q)
+ {
+ if (p == null || q == null)
+ throw new InternalErrorException ("BetterTypeConversion got a null conversion");
- if (argument_expr is NullLiteral)
- {
- //
- // If the argument is null and one of the types to compare is 'object' and
- // the other is a reference type, we prefer the other.
- //
- // This follows from the usual rules:
- // * There is an implicit conversion from 'null' to type 'object'
- // * There is an implicit conversion from 'null' to any reference type
- // * There is an implicit conversion from any reference type to type 'object'
- // * There is no implicit conversion from type 'object' to other reference types
- // => Conversion of 'null' to a reference type is better than conversion to 'object'
- //
- // FIXME: This probably isn't necessary, since the type of a NullLiteral is the
- // null type. I think it used to be 'object' and thus needed a special
- // case to avoid the immediately following two checks.
- //
- if (!p.IsValueType && q == TypeManager.object_type)
- return p;
- if (!q.IsValueType && p == TypeManager.object_type)
- return q;
+ if (p == TypeManager.int32_type) {
+ if (q == TypeManager.uint32_type || q == TypeManager.uint64_type)
+ return 1;
+ } else if (p == TypeManager.int64_type) {
+ if (q == TypeManager.uint64_type)
+ 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)
+ return 1;
+ } else if (p == TypeManager.short_type) {
+ if (q == TypeManager.ushort_type || q == TypeManager.uint32_type ||
+ q == TypeManager.uint64_type)
+ return 1;
}
-
- if (argument_type == p)
- return p;
- if (argument_type == q)
- return q;
+ if (q == TypeManager.int32_type) {
+ if (p == TypeManager.uint32_type || p == TypeManager.uint64_type)
+ return 2;
+ } if (q == TypeManager.int64_type) {
+ if (p == TypeManager.uint64_type)
+ 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)
+ return 2;
+ } if (q == TypeManager.short_type) {
+ if (p == TypeManager.ushort_type || p == TypeManager.uint32_type ||
+ p == TypeManager.uint64_type)
+ return 2;
+ }
+ // TODO: this is expensive
Expression p_tmp = new EmptyExpression (p);
Expression q_tmp = new EmptyExpression (q);
bool q_to_p = Convert.ImplicitConversionExists (ec, q_tmp, p);
if (p_to_q && !q_to_p)
- return p;
+ return 1;
if (q_to_p && !p_to_q)
- return q;
-
- if (p == TypeManager.sbyte_type)
- if (q == TypeManager.byte_type || q == TypeManager.ushort_type ||
- q == TypeManager.uint32_type || q == TypeManager.uint64_type)
- return p;
- if (q == TypeManager.sbyte_type)
- if (p == TypeManager.byte_type || p == TypeManager.ushort_type ||
- p == TypeManager.uint32_type || p == TypeManager.uint64_type)
- return q;
-
- if (p == TypeManager.short_type)
- if (q == TypeManager.ushort_type || q == TypeManager.uint32_type ||
- q == TypeManager.uint64_type)
- return p;
- if (q == TypeManager.short_type)
- if (p == TypeManager.ushort_type || p == TypeManager.uint32_type ||
- p == TypeManager.uint64_type)
- return q;
-
- if (p == TypeManager.int32_type)
- if (q == TypeManager.uint32_type || q == TypeManager.uint64_type)
- return p;
- if (q == TypeManager.int32_type)
- if (p == TypeManager.uint32_type || p == TypeManager.uint64_type)
- return q;
-
- if (p == TypeManager.int64_type)
- if (q == TypeManager.uint64_type)
- return p;
- if (q == TypeManager.int64_type)
- if (p == TypeManager.uint64_type)
- return q;
+ return 2;
- return null;
+ return 0;
}
/// <summary>
continue;
same = false;
- Type better = BetterConversion (ec, a, ct, bt);
+ int result = BetterExpressionConversion (ec, a, ct, bt);
// for each argument, the conversion to 'ct' should be no worse than
// the conversion to 'bt'.
- if (better == bt)
+ if (result == 2)
return false;
// for at least one argument, the conversion to 'ct' should be better than
// the conversion to 'bt'.
- if (better == ct)
+ if (result != 0)
better_at_least_one = true;
}
return false;
}
- public override Expression ResolveMemberAccess (EmitContext ec, Expression left, Location loc,
+ protected override MemberExpr ResolveExtensionMemberAccess (Expression left)
+ {
+ if (!IsStatic)
+ return base.ResolveExtensionMemberAccess (left);
+
+ //
+ // When left side is an expression and at least one candidate method is
+ // static, it can be extension method
+ //
+ InstanceExpression = left;
+ return this;
+ }
+
+ public override MemberExpr ResolveMemberAccess (EmitContext ec, Expression left, Location loc,
SimpleName original)
{
if (!(left is TypeExpr) &&
return base.ResolveMemberAccess (ec, left, loc, original);
}
+
+ public override Expression CreateExpressionTree (EmitContext ec)
+ {
+ return new Cast (new TypeExpression (typeof (MethodInfo), loc),
+ new TypeOfMethod ((MethodInfo)best_candidate, loc));
+ }
override public Expression DoResolve (EmitContext ec)
{
public virtual void EmitArguments (EmitContext ec, ArrayList arguments)
{
- Invocation.EmitArguments (ec, best_candidate, arguments, false, null);
+ Invocation.EmitArguments (ec, arguments, false, null);
}
public virtual void EmitCall (EmitContext ec, ArrayList arguments)
}
protected virtual void Error_InvalidArguments (EmitContext ec, Location loc, int idx, MethodBase method,
- Type delegate_type, Argument a, ParameterData expected_par)
+ Argument a, ParameterData expected_par, Type paramType)
{
if (a is CollectionElementInitializer.ElementInitializerArgument) {
Report.SymbolRelatedToPreviousError (method);
Parameter.Modifier mod = expected_par.ParameterModifier (idx);
string index = (idx + 1).ToString ();
- if ((mod & Parameter.Modifier.ISBYREF) != (a.Modifier & Parameter.Modifier.ISBYREF) ||
- (mod & Parameter.Modifier.ISBYREF) != 0) {
- if ((mod & (Parameter.Modifier.REF | Parameter.Modifier.OUT)) == 0)
+ if (((mod & (Parameter.Modifier.REF | Parameter.Modifier.OUT)) ^
+ (a.Modifier & (Parameter.Modifier.REF | Parameter.Modifier.OUT))) != 0) {
+ if ((mod & Parameter.Modifier.ISBYREF) == 0)
Report.Error (1615, loc, "Argument `{0}' should not be passed with the `{1}' keyword",
index, Parameter.GetModifierSignature (a.Modifier));
else
Report.Error (1620, loc, "Argument `{0}' must be passed with the `{1}' keyword",
index, Parameter.GetModifierSignature (mod));
} else {
- string p1 = Argument.FullDesc (a);
- string p2 = TypeManager.CSharpName (expected_par.ParameterType (idx));
+ string p1 = a.GetSignatureForError ();
+ string p2 = TypeManager.CSharpName (paramType);
if (p1 == p2) {
Report.ExtraInformation (loc, "(equally named types possibly from different assemblies in previous ");
Report.SymbolRelatedToPreviousError (a.Expr.Type);
- Report.SymbolRelatedToPreviousError (expected_par.ParameterType (idx));
+ Report.SymbolRelatedToPreviousError (paramType);
}
Report.Error (1503, loc, "Argument {0}: Cannot convert type `{1}' to `{2}'", index, p1, p2);
}
/// 0 = the best, int.MaxValue = the worst
///
public int IsApplicable (EmitContext ec,
- ArrayList arguments, int arg_count, ref MethodBase method)
+ ArrayList arguments, int arg_count, ref MethodBase method, ref bool params_expanded_form)
{
MethodBase candidate = method;
ParameterData pd = TypeManager.GetParameterData (candidate);
int param_count = GetApplicableParametersCount (candidate, pd);
- if (arg_count != param_count)
- return int.MaxValue;
-
- //
- // 1. Infer type arguments for generic method
- //
-#if GMCS_SOURCE
- if (!HasTypeArguments && TypeManager.IsGenericMethod (method)) {
- int score = TypeManager.InferTypeArguments (ec, arguments, ref candidate);
- if (score != 0)
- return --score;
-
- if (TypeManager.IsGenericMethodDefinition (candidate))
- throw new InternalErrorException ("a generic method definition took part in overload resolution");
-
- pd = TypeManager.GetParameterData (candidate);
+ if (arg_count != param_count) {
+ if (!pd.HasParams)
+ return int.MaxValue - 10000 + Math.Abs (arg_count - param_count);
+ if (arg_count < param_count - 1)
+ return int.MaxValue - 10000 + Math.Abs (arg_count - param_count);
}
-#endif
+#if GMCS_SOURCE
//
- // 2. Each argument has to be implicitly converible to method parameter
+ // 1. Handle generic method using type arguments when specified or type inference
//
- for (int i = arg_count; i > 0; ) {
- i--;
+ if (TypeManager.IsGenericMethod (candidate)) {
+ if (type_arguments != null) {
+ Type [] g_args = candidate.GetGenericArguments ();
+ if (g_args.Length != type_arguments.Count)
+ return int.MaxValue - 20000 + Math.Abs (type_arguments.Count - g_args.Length);
+
+ // TODO: Don't create new method, create Parameters only
+ method = ((MethodInfo) candidate).MakeGenericMethod (type_arguments.Arguments);
+ candidate = method;
+ pd = TypeManager.GetParameterData (candidate);
+ } else {
+ int score = TypeManager.InferTypeArguments (ec, arguments, ref candidate);
+ if (score != 0)
+ return score - 20000;
- Argument a = (Argument) arguments [i];
+ if (TypeManager.IsGenericMethodDefinition (candidate))
+ throw new InternalErrorException ("A generic method `{0}' definition took part in overload resolution",
+ TypeManager.CSharpSignature (candidate));
+
+ pd = TypeManager.GetParameterData (candidate);
+ }
+ } else {
+ if (type_arguments != null)
+ return int.MaxValue - 15000;
+ }
+#endif
+ //
+ // 2. Each argument has to be implicitly convertible to method parameter
+ //
+ method = candidate;
+ Parameter.Modifier p_mod = 0;
+ Type pt = null;
+ for (int i = 0; i < arg_count; i++) {
+ Argument a = (Argument) arguments [i];
Parameter.Modifier a_mod = a.Modifier &
~(Parameter.Modifier.OUTMASK | Parameter.Modifier.REFMASK);
- Parameter.Modifier p_mod = pd.ParameterModifier (i) &
- ~(Parameter.Modifier.OUTMASK | Parameter.Modifier.REFMASK | Parameter.Modifier.PARAMS);
+ if (p_mod != Parameter.Modifier.PARAMS) {
+ p_mod = pd.ParameterModifier (i) & ~(Parameter.Modifier.OUTMASK | Parameter.Modifier.REFMASK);
- Type pt = pd.ParameterType (i);
+ if (p_mod == Parameter.Modifier.ARGLIST) {
+ if (a.Type == TypeManager.runtime_argument_handle_type)
+ continue;
- // FIXME: Kill this abomination (EmitContext.TempEc)
- EmitContext prevec = EmitContext.TempEc;
- EmitContext.TempEc = ec;
- try {
- if (pt.IsByRef)
- pt = pt.GetElementType ();
-
- if (!Convert.ImplicitConversionExists (ec, a.Expr, pt))
- return ++i * 2;
+ p_mod = 0;
+ }
- if (a_mod != p_mod)
- return ++i * 2 - 1;
+ pt = pd.ParameterType (i);
+ } else {
+ params_expanded_form = true;
+ }
- } finally {
- EmitContext.TempEc = prevec;
+ int score = 1;
+ if (!params_expanded_form)
+ score = IsArgumentCompatible (ec, a_mod, a, p_mod & ~Parameter.Modifier.PARAMS, pt);
+
+ if (score != 0 && (p_mod & Parameter.Modifier.PARAMS) != 0) {
+ // It can be applicable in expanded form
+ score = IsArgumentCompatible (ec, a_mod, a, 0, pt.GetElementType ());
+ if (score == 0)
+ params_expanded_form = true;
+ }
+
+ if (score != 0) {
+ if (params_expanded_form)
+ ++score;
+ return (arg_count - i) * 2 + score;
}
}
+
+ if (arg_count != param_count)
+ params_expanded_form = true;
+
+ return 0;
+ }
+
+ int IsArgumentCompatible (EmitContext ec, Parameter.Modifier arg_mod, Argument argument, Parameter.Modifier param_mod, Type parameter)
+ {
+ //
+ // Types have to be identical when ref or out modifer is used
+ //
+ if (arg_mod != 0 || param_mod != 0) {
+ if (TypeManager.HasElementType (parameter))
+ parameter = parameter.GetElementType ();
+
+ Type a_type = argument.Type;
+ if (TypeManager.HasElementType (a_type))
+ a_type = a_type.GetElementType ();
+
+ if (a_type != parameter)
+ return 2;
+
+ return 0;
+ }
+
+ // FIXME: Kill this abomination (EmitContext.TempEc)
+ EmitContext prevec = EmitContext.TempEc;
+ EmitContext.TempEc = ec;
+ try {
+ if (delegate_type != null ?
+ !Delegate.IsTypeCovariant (argument.Expr, parameter) :
+ !Convert.ImplicitConversionExists (ec, argument.Expr, parameter))
+ return 2;
+
+ if (arg_mod != param_mod)
+ return 1;
+
+ } finally {
+ EmitContext.TempEc = prevec;
+ }
- method = candidate;
return 0;
}
return true;
}
- public bool IsParamsMethodApplicable (EmitContext ec,
- ArrayList arguments, int arg_count,
- ref MethodBase candidate)
- {
- return IsParamsMethodApplicable (
- ec, arguments, arg_count, false, ref candidate) ||
- IsParamsMethodApplicable (
- ec, arguments, arg_count, true, ref candidate);
-
-
- }
-
- bool IsParamsMethodApplicable (EmitContext ec,
- ArrayList arguments, int arg_count,
- bool do_varargs, ref MethodBase candidate)
- {
-#if GMCS_SOURCE
- if (!HasTypeArguments &&
- !TypeManager.InferParamsTypeArguments (ec, arguments, ref candidate))
- return false;
-
- if (TypeManager.IsGenericMethodDefinition (candidate))
- throw new InternalErrorException ("a generic method definition took part in overload resolution");
-#endif
-
- return IsParamsMethodApplicable (
- ec, arguments, arg_count, candidate, do_varargs);
- }
-
- /// <summary>
- /// Determines if the candidate method, if a params method, is applicable
- /// in its expanded form to the given set of arguments
- /// </summary>
- bool IsParamsMethodApplicable (EmitContext ec, ArrayList arguments,
- int arg_count, MethodBase candidate,
- bool do_varargs)
- {
- ParameterData pd = TypeManager.GetParameterData (candidate);
- int pd_count = GetApplicableParametersCount (candidate, pd);
- if (pd_count == 0)
- return false;
-
- int count = pd_count - 1;
- if (do_varargs) {
- if (pd.ParameterModifier (count) != Parameter.Modifier.ARGLIST)
- return false;
- if (pd_count != arg_count)
- return false;
-
- if (!(((Argument) arguments [count]).Expr is Arglist))
- return false;
- --pd_count;
- } else {
- if (!pd.HasParams)
- return false;
- }
-
- if (count > arg_count)
- return false;
-
- if (pd_count == 1 && arg_count == 0)
- return true;
-
- //
- // If we have come this far, the case which
- // remains is when the number of parameters is
- // less than or equal to the argument count.
- //
- int argument_index = 0;
- Argument a;
- for (int i = 0; i < pd_count; ++i) {
-
- if ((pd.ParameterModifier (i) & Parameter.Modifier.PARAMS) != 0) {
- Type element_type = TypeManager.GetElementType (pd.ParameterType (i));
- int params_args_count = arg_count - pd_count;
- if (params_args_count < 0)
- continue;
-
- do {
- a = (Argument) arguments [argument_index++];
-
- if (!Convert.ImplicitConversionExists (ec, a.Expr, element_type))
- return false;
- } while (params_args_count-- > 0);
- continue;
- }
-
- a = (Argument) arguments [argument_index++];
-
- Parameter.Modifier a_mod = a.Modifier &
- (unchecked (~(Parameter.Modifier.OUTMASK | Parameter.Modifier.REFMASK)));
- Parameter.Modifier p_mod = pd.ParameterModifier (i) &
- (unchecked (~(Parameter.Modifier.OUTMASK | Parameter.Modifier.REFMASK)));
-
- if (a_mod == p_mod) {
-
- if (a_mod == Parameter.Modifier.NONE)
- if (!Convert.ImplicitConversionExists (ec,
- a.Expr,
- pd.ParameterType (i)))
- return false;
-
- if ((a_mod & Parameter.Modifier.ISBYREF) != 0) {
- Type pt = pd.ParameterType (i);
-
- if (!pt.IsByRef)
- pt = TypeManager.GetReferenceType (pt);
-
- if (pt != a.Type)
- return false;
- }
- } else
- return false;
-
- }
-
- return true;
- }
-
public static MethodGroupExpr MakeUnionSet (Expression mg1, Expression mg2, Location loc)
{
MemberInfo [] miset;
/// that is the best match of me on Arguments.
///
/// </summary>
- public virtual MethodGroupExpr OverloadResolve (EmitContext ec, ArrayList Arguments,
+ public virtual MethodGroupExpr OverloadResolve (EmitContext ec, ref ArrayList Arguments,
bool may_fail, Location loc)
{
bool method_params = false;
int j = 0;
for (int i = 0; i < Methods.Length; ++i) {
MethodBase m = Methods [i];
-#if GMCS_SOURCE
- Type [] gen_args = null;
- if (m.IsGenericMethod && !m.IsGenericMethodDefinition)
- gen_args = m.GetGenericArguments ();
-#endif
if (TypeManager.IsOverride (m)) {
if (candidate_overrides == null)
candidate_overrides = new ArrayList ();
candidate_overrides.Add (m);
m = TypeManager.TryGetBaseDefinition (m);
-#if GMCS_SOURCE
- if (m != null && gen_args != null) {
- if (!m.IsGenericMethodDefinition)
- throw new InternalErrorException ("GetBaseDefinition didn't return a GenericMethodDefinition");
- m = ((MethodInfo) m).MakeGenericMethod (gen_args);
- }
-#endif
}
if (m != null)
Methods [j++] = m;
//
// Check if candidate is applicable (section 14.4.2.1)
- // Is candidate applicable in normal form?
//
- int candidate_rate = IsApplicable (ec, Arguments, arg_count, ref Methods [i]);
-
- if (candidate_rate != 0 && IsParamsMethodApplicable (ec, Arguments, arg_count, ref Methods [i])) {
- MethodBase candidate = Methods [i];
- if (candidate_to_form == null)
- candidate_to_form = new PtrHashtable ();
- candidate_to_form [candidate] = candidate;
- // Candidate is applicable in expanded form
- candidate_rate = 0;
- }
+ bool params_expanded_form = false;
+ int candidate_rate = IsApplicable (ec, Arguments, arg_count, ref Methods [i], ref params_expanded_form);
if (candidate_rate < best_candidate_rate) {
best_candidate_rate = candidate_rate;
best_candidate = Methods [i];
}
+
+ if (params_expanded_form) {
+ if (candidate_to_form == null)
+ candidate_to_form = new PtrHashtable ();
+ MethodBase candidate = Methods [i];
+ candidate_to_form [candidate] = candidate;
+ }
if (candidate_rate != 0) {
if (msg_recorder != null)
}
msg_recorder = null;
-
candidates.Add (Methods [i]);
if (applicable_type == null)
int candidate_top = candidates.Count;
if (applicable_type == null) {
- if (ec.IsInProbingMode || may_fail)
+ //
+ // When we found a top level method which does not match and it's
+ // not an extension method. We start extension methods lookup from here
+ //
+ if (InstanceExpression != null) {
+ ExtensionMethodGroupExpr ex_method_lookup = ec.TypeContainer.LookupExtensionMethod (type, Name);
+ if (ex_method_lookup != null) {
+ ex_method_lookup.ExtensionExpression = InstanceExpression;
+ ex_method_lookup.SetTypeArguments (type_arguments);
+ return ex_method_lookup.OverloadResolve (ec, ref Arguments, may_fail, loc);
+ }
+ }
+
+ if (may_fail)
return null;
//
if (CustomErrorHandler.NoExactMatch (ec, best_candidate))
return null;
}
-
- if (TypeManager.IsGenericMethod (best_candidate)) {
- Report.Error (411, loc,
- "The type arguments for method `{0}' cannot be inferred from " +
- "the usage. Try specifying the type arguments explicitly",
- TypeManager.CSharpSignature (best_candidate));
- } else {
- VerifyArgumentsCompat (ec, Arguments, arg_count, best_candidate, false, null, may_fail, loc);
- }
- return null;
+ ParameterData pd = TypeManager.GetParameterData (best_candidate);
+ bool cand_params = candidate_to_form != null && candidate_to_form.Contains (best_candidate);
+ if (arg_count == pd.Count || pd.HasParams) {
+ if (TypeManager.IsGenericMethodDefinition (best_candidate)) {
+ if (type_arguments == null) {
+ Report.Error (411, loc,
+ "The type arguments for method `{0}' cannot be inferred from " +
+ "the usage. Try specifying the type arguments explicitly",
+ TypeManager.CSharpSignature (best_candidate));
+ return null;
+ }
+
+ Type [] g_args = TypeManager.GetGenericArguments (best_candidate);
+ if (type_arguments.Count != g_args.Length) {
+ Report.SymbolRelatedToPreviousError (best_candidate);
+ Report.Error (305, loc, "Using the generic method `{0}' requires `{1}' type argument(s)",
+ TypeManager.CSharpSignature (best_candidate),
+ g_args.Length.ToString ());
+ return null;
+ }
+ } else {
+ if (type_arguments != null && !TypeManager.IsGenericMethod (best_candidate)) {
+ Namespace.Error_TypeArgumentsCannotBeUsed (best_candidate, loc);
+ return null;
+ }
+ }
+
+ if (!VerifyArgumentsCompat (ec, ref Arguments, arg_count, best_candidate, cand_params, may_fail, loc))
+ return null;
+ }
}
- if (almostMatchedMembers.Count != 0) {
+ if (almost_matched_members.Count != 0) {
Error_MemberLookupFailed (ec.ContainerType, type, type, ".ctor",
null, MemberTypes.Constructor, AllBindingFlags);
return null;
}
//
- // We failed to find any match
+ // We failed to find any method with correct argument count
//
if (Name == ConstructorInfo.ConstructorName) {
Report.SymbolRelatedToPreviousError (type);
"The type `{0}' does not contain a constructor that takes `{1}' arguments",
TypeManager.CSharpName (type), arg_count);
} else {
- string report_name = Name;
- if (report_name == ConstructorInfo.ConstructorName)
- report_name = TypeManager.CSharpName (DeclaringType);
-
- Invocation.Error_WrongNumArguments (loc, report_name, arg_count);
+ Report.Error (1501, loc, "No overload for method `{0}' takes `{1}' arguments",
+ Name, arg_count.ToString ());
}
return null;
//
best_candidate = (MethodBase) candidates [0];
- method_params = candidate_to_form != null && candidate_to_form.Contains (best_candidate);
+ if (delegate_type == null)
+ method_params = candidate_to_form != null && candidate_to_form.Contains (best_candidate);
+
for (int ix = 1; ix < candidate_top; ix++) {
MethodBase candidate = (MethodBase) candidates [ix];
// should be better than all the others
//
MethodBase ambiguous = null;
- for (int ix = 0; ix < candidate_top; ix++) {
+ for (int ix = 1; ix < candidate_top; ix++) {
MethodBase candidate = (MethodBase) candidates [ix];
if (candidate == best_candidate)
throw new InternalErrorException (
"Should not happen. An 'override' method took part in overload resolution: " + best_candidate);
- if (candidate_overrides != null)
+ if (candidate_overrides != null) {
+ Type[] gen_args = null;
+ bool gen_override = false;
+ if (TypeManager.IsGenericMethod (best_candidate))
+ gen_args = TypeManager.GetGenericArguments (best_candidate);
+
foreach (MethodBase candidate in candidate_overrides) {
- if (IsOverride (candidate, best_candidate))
+ if (TypeManager.IsGenericMethod (candidate)) {
+ if (gen_args == null)
+ continue;
+
+ if (gen_args.Length != TypeManager.GetGenericArguments (candidate).Length)
+ continue;
+ } else {
+ if (gen_args != null)
+ continue;
+ }
+
+ if (IsOverride (candidate, best_candidate)) {
+ gen_override = true;
best_candidate = candidate;
+ }
}
- }
- // We can stop here when probing is on
- if (ec.IsInProbingMode)
- return this;
+ if (gen_override && gen_args != null) {
+#if GMCS_SOURCE
+ best_candidate = ((MethodInfo) best_candidate).MakeGenericMethod (gen_args);
+#endif
+ }
+ }
+ }
//
// And now check if the arguments are all
// necessary etc. and return if everything is
// all right
//
- if (!VerifyArgumentsCompat (ec, Arguments, arg_count, best_candidate,
- method_params, null, may_fail, loc))
+ if (!VerifyArgumentsCompat (ec, ref Arguments, arg_count, best_candidate,
+ method_params, may_fail, loc))
return null;
if (best_candidate == null)
return this;
}
- public Expression ResolveGeneric (EmitContext ec, TypeArguments args)
+ public override void SetTypeArguments (TypeArguments ta)
{
-#if GMCS_SOURCE
- if (!args.Resolve (ec))
- return null;
+ type_arguments = ta;
+ }
- Type[] atypes = args.Arguments;
+ public bool VerifyArgumentsCompat (EmitContext ec, ref ArrayList arguments,
+ int arg_count, MethodBase method,
+ bool chose_params_expanded,
+ bool may_fail, Location loc)
+ {
+ ParameterData pd = TypeManager.GetParameterData (method);
- int first_count = 0;
- MethodInfo first = null;
+ int errors = Report.Errors;
+ Parameter.Modifier p_mod = 0;
+ Type pt = null;
+ int a_idx = 0, a_pos = 0;
+ Argument a = null;
+ ArrayList params_initializers = null;
- ArrayList list = new ArrayList ();
- foreach (MethodBase mb in Methods) {
- MethodInfo mi = mb as MethodInfo;
- if ((mi == null) || !mb.IsGenericMethod)
- continue;
+ for (; a_idx < arg_count; a_idx++, ++a_pos) {
+ a = (Argument) arguments [a_idx];
+ if (p_mod != Parameter.Modifier.PARAMS) {
+ p_mod = pd.ParameterModifier (a_idx);
+ pt = pd.ParameterType (a_idx);
- Type[] gen_params = mb.GetGenericArguments ();
+ if (p_mod == Parameter.Modifier.ARGLIST) {
+ if (a.Type != TypeManager.runtime_argument_handle_type)
+ break;
+ continue;
+ }
- if (first == null) {
- first = mi;
- first_count = gen_params.Length;
+ if (pt.IsPointer && !ec.InUnsafe) {
+ if (may_fail)
+ return false;
+
+ UnsafeError (loc);
+ }
+
+ if (p_mod == Parameter.Modifier.PARAMS) {
+ if (chose_params_expanded) {
+ params_initializers = new ArrayList (arg_count - a_idx);
+ pt = TypeManager.GetElementType (pt);
+ }
+ } else if (p_mod != 0) {
+ pt = TypeManager.GetElementType (pt);
+ }
}
- if (gen_params.Length != atypes.Length)
+ //
+ // Types have to be identical when ref or out modifer is used
+ //
+ if (a.Modifier != 0 || (p_mod & ~Parameter.Modifier.PARAMS) != 0) {
+ if ((p_mod & ~Parameter.Modifier.PARAMS) != a.Modifier)
+ break;
+
+ if (!TypeManager.IsEqual (a.Expr.Type, pt))
+ break;
+
continue;
+ }
+
+ Expression conv;
+ if (TypeManager.IsEqual (a.Type, pt)) {
+ conv = a.Expr;
+ } else {
+ conv = Convert.ImplicitConversion (ec, a.Expr, pt, loc);
+ if (conv == null)
+ break;
+ }
- mi = mi.MakeGenericMethod (atypes);
- list.Add (mi);
-
-#if MS_COMPATIBLE
- // MS implementation throws NotSupportedException for GetParameters
- // on unbaked generic method
- Parameters p = TypeManager.GetParameterData (mi) as Parameters;
- if (p != null) {
- p = p.Clone ();
- p.InflateTypes (gen_params, atypes);
- TypeManager.RegisterMethod (mi, p);
+ //
+ // Convert params arguments to an array initializer
+ //
+ if (params_initializers != null) {
+ params_initializers.Add (conv);
+ arguments.RemoveAt (a_idx--);
+ --arg_count;
+ continue;
}
-#endif
+
+ // Update the argument with the implicit conversion
+ a.Expr = conv;
}
- if (list.Count > 0) {
- this.Methods = (MethodBase []) list.ToArray (typeof (MethodBase));
- has_type_arguments = true;
- return this;
+ //
+ // Fill not provided arguments required by params modifier
+ //
+ if (params_initializers == null && pd.HasParams && arg_count < pd.Count && a_idx + 1 == pd.Count) {
+ if (arguments == null)
+ arguments = new ArrayList (1);
+
+ pt = pd.Types [GetApplicableParametersCount (method, pd) - 1];
+ pt = TypeManager.GetElementType (pt);
+ params_initializers = new ArrayList (0);
}
- if (first != null) {
- Report.SymbolRelatedToPreviousError (first);
- Report.Error (
- 305, loc, "Using the generic method `{0}' requires `{1}' type arguments",
- TypeManager.CSharpSignature (first), first_count.ToString ());
- } else
- Report.Error (
- 308, loc, "The non-generic method `{0}' " +
- "cannot be used with type arguments", Name);
+ if (a_idx == arg_count) {
+ //
+ // Append an array argument with all params arguments
+ //
+ if (params_initializers != null) {
+ arguments.Add (new Argument (
+ new ArrayCreation (new TypeExpression (pt, loc), "[]",
+ params_initializers, loc).Resolve (ec)));
+ }
+ return true;
+ }
- return null;
-#else
- throw new NotImplementedException ();
-#endif
+ if (!may_fail && Report.Errors == errors) {
+ if (CustomErrorHandler != null)
+ CustomErrorHandler.NoExactMatch (ec, best_candidate);
+ else
+ Error_InvalidArguments (ec, loc, a_pos, method, a, pd, pt);
+ }
+ return false;
}
+ }
- public bool VerifyArgumentsCompat (EmitContext ec, ArrayList Arguments,
- int arg_count, MethodBase method,
- bool chose_params_expanded,
- Type delegate_type, bool may_fail, Location loc)
- {
- ParameterData pd = TypeManager.GetParameterData (method);
- int param_count = GetApplicableParametersCount (method, pd);
-
- int j;
- int a_idx = 0;
- Argument a = null;
- int errors = Report.Errors;
- for (j = 0; j < param_count; j++) {
- Type parameter_type = pd.ParameterType (j);
- Parameter.Modifier pm = pd.ParameterModifier (j);
+ public class ConstantExpr : MemberExpr
+ {
+ FieldInfo constant;
- if (pm == Parameter.Modifier.ARGLIST) {
- a = (Argument) Arguments [a_idx];
- if (!(a.Expr is Arglist))
- break;
- ++a_idx;
- continue;
- }
+ public ConstantExpr (FieldInfo constant, Location loc)
+ {
+ this.constant = constant;
+ this.loc = loc;
+ }
- int params_arg_count = 1;
- if (pm == Parameter.Modifier.PARAMS) {
- pm = Parameter.Modifier.NONE;
- params_arg_count = arg_count - param_count + 1;
- if (chose_params_expanded)
- parameter_type = TypeManager.GetElementType (parameter_type);
- }
+ public override string Name {
+ get { throw new NotImplementedException (); }
+ }
- while (params_arg_count > 0) {
- a = (Argument) Arguments [a_idx];
- if (pm != a.Modifier)
- break;
+ public override bool IsInstance {
+ get { return !IsStatic; }
+ }
- if (!TypeManager.IsEqual (a.Type, parameter_type)) {
- if (pm == Parameter.Modifier.OUT || pm == Parameter.Modifier.REF)
- break;
+ public override bool IsStatic {
+ get { return constant.IsStatic; }
+ }
- Expression conv = Convert.ImplicitConversion (ec, a.Expr, parameter_type, loc);
- if (conv == null)
- break;
+ public override Type DeclaringType {
+ get { return constant.DeclaringType; }
+ }
- // Update the argument with the implicit conversion
- if (a.Expr != conv)
- a.Expr = conv;
- }
+ public override MemberExpr ResolveMemberAccess (EmitContext ec, Expression left, Location loc, SimpleName original)
+ {
+ constant = TypeManager.GetGenericFieldDefinition (constant);
- --params_arg_count;
- ++a_idx;
+ IConstant ic = TypeManager.GetConstant (constant);
+ if (ic == null) {
+ if (constant.IsLiteral) {
+ ic = new ExternalConstant (constant);
+ } else {
+ ic = ExternalConstant.CreateDecimal (constant);
+ // HACK: decimal field was not resolved as constant
+ if (ic == null)
+ return new FieldExpr (constant, loc).ResolveMemberAccess (ec, left, loc, original);
}
- if (params_arg_count > 0)
- break;
+ TypeManager.RegisterConstant (constant, ic);
+ }
- if (parameter_type.IsPointer && !ec.InUnsafe) {
- if (!may_fail)
- UnsafeError (loc);
- return false;
- }
+ return base.ResolveMemberAccess (ec, left, loc, original);
+ }
+
+ public override Expression DoResolve (EmitContext ec)
+ {
+ IConstant ic = TypeManager.GetConstant (constant);
+ if (ic.ResolveValue ()) {
+ if (!ec.IsInObsoleteScope)
+ ic.CheckObsoleteness (loc);
}
- if (a_idx == arg_count)
- return true;
+ return ic.CreateConstantReference (loc);
+ }
- if (!may_fail && Report.Errors == errors)
- Error_InvalidArguments (ec, loc, a_idx, method, delegate_type, a, pd);
- return false;
+ public override void Emit (EmitContext ec)
+ {
+ throw new NotSupportedException ();
+ }
+
+ public override string GetSignatureForError ()
+ {
+ return TypeManager.GetFullNameSignature (constant);
}
}
}
}
- public override Expression ResolveMemberAccess (EmitContext ec, Expression left, Location loc,
+ public override MemberExpr ResolveMemberAccess (EmitContext ec, Expression left, Location loc,
SimpleName original)
{
FieldInfo fi = TypeManager.GetGenericFieldDefinition (FieldInfo);
-
Type t = fi.FieldType;
- if (fi.IsLiteral || (fi.IsInitOnly && t == TypeManager.decimal_type)) {
- IConstant ic = TypeManager.GetConstant (fi);
- if (ic == null) {
- if (fi.IsLiteral) {
- ic = new ExternalConstant (fi);
- } else {
- ic = ExternalConstant.CreateDecimal (fi);
- if (ic == null) {
- return base.ResolveMemberAccess (ec, left, loc, original);
- }
- }
- TypeManager.RegisterConstant (fi, ic);
- }
-
- bool left_is_type = left is TypeExpr;
- if (!left_is_type && (original == null || !original.IdenticalNameAndTypeName (ec, left, loc))) {
- Report.SymbolRelatedToPreviousError (FieldInfo);
- error176 (loc, TypeManager.GetFullNameSignature (FieldInfo));
- return null;
- }
-
- if (ic.ResolveValue ()) {
- if (!ec.IsInObsoleteScope)
- ic.CheckObsoleteness (loc);
- }
-
- return ic.CreateConstantReference (loc);
- }
-
if (t.IsPointer && !ec.InUnsafe) {
UnsafeError (loc);
}
if (InstanceExpression == null)
return null;
- InstanceExpression.CheckMarshalByRefAccess ();
+ using (ec.Set (EmitContext.Flags.OmitStructFlowAnalysis)) {
+ InstanceExpression.CheckMarshalByRefAccess (ec);
+ }
}
if (!in_initializer && !ec.IsInFieldInitializer) {
Report.Error (1666, loc, "You cannot use fixed size buffers contained in unfixed expressions. Try using the fixed statement");
}
- if (!(InstanceExpression is LocalVariableReference) &&
- !(InstanceExpression is This)) {
+ if (InstanceExpression.eclass != ExprClass.Variable) {
Report.SymbolRelatedToPreviousError (FieldInfo);
Report.Error (1708, loc, "`{0}': Fixed size buffers can only be accessed through locals or fields",
TypeManager.GetFullNameSignature (FieldInfo));
}
if (right_side == EmptyExpression.OutAccess &&
- !IsStatic && !(InstanceExpression is This) && DeclaringType.IsSubclassOf (TypeManager.mbr_type)) {
+ !IsStatic && !(InstanceExpression is This) && TypeManager.mbr_type != null && TypeManager.IsSubclassOf (DeclaringType, TypeManager.mbr_type)) {
Report.SymbolRelatedToPreviousError (DeclaringType);
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",
return this;
}
- public override void CheckMarshalByRefAccess ()
+ public override void CheckMarshalByRefAccess (EmitContext ec)
{
- if (!IsStatic && Type.IsValueType && !(InstanceExpression is This) && DeclaringType.IsSubclassOf (TypeManager.mbr_type)) {
+ if (!IsStatic && Type.IsValueType && !(InstanceExpression is This) && TypeManager.mbr_type != null && TypeManager.IsSubclassOf (DeclaringType, TypeManager.mbr_type)) {
Report.SymbolRelatedToPreviousError (DeclaringType);
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",
GetSignatureForError ());
}
}
- //
- // A FieldExpr whose address can not be taken
- //
- public class FieldExprNoAddress : FieldExpr, IMemoryLocation {
- public FieldExprNoAddress (FieldInfo fi, Location loc) : base (fi, loc)
- {
- }
-
- public new void AddressOf (EmitContext ec, AddressOp mode)
- {
- Report.Error (-215, "Report this: Taking the address of a remapped parameter not supported");
- }
- }
/// <summary>
/// Expression that evaluates to a Property. The Assign class
/// </summary>
public class PropertyExpr : MemberExpr, IAssignMethod {
public readonly PropertyInfo PropertyInfo;
-
- //
- // This is set externally by the `BaseAccess' class
- //
- public bool IsBase;
MethodInfo getter, setter;
bool is_static;
LocalTemporary temp;
bool prepared;
- public PropertyExpr (Type containerType, PropertyInfo pi, Location l)
+ public PropertyExpr (Type container_type, PropertyInfo pi, Location l)
{
PropertyInfo = pi;
eclass = ExprClass.PropertyAccess;
type = TypeManager.TypeToCoreType (pi.PropertyType);
- ResolveAccessors (containerType);
+ ResolveAccessors (container_type);
}
public override string Name {
return is_static;
}
}
-
+
+ public override Expression CreateExpressionTree (EmitContext ec)
+ {
+ if (IsSingleDimensionalArrayLength ()) {
+ ArrayList args = new ArrayList (1);
+ args.Add (new Argument (InstanceExpression.CreateExpressionTree (ec)));
+ return CreateExpressionFactoryCall ("ArrayLength", args);
+ }
+
+ // TODO: it's waiting for PropertyExpr refactoring
+ //ArrayList args = new ArrayList (2);
+ //args.Add (new Argument (InstanceExpression.CreateExpressionTree (ec)));
+ //args.Add (getter expression);
+ //return CreateExpressionFactoryCall ("Property", args);
+ return base.CreateExpressionTree (ec);
+ }
+
public override Type DeclaringType {
get {
return PropertyInfo.DeclaringType;
// hold the information for the accessibility of its setter/getter
//
// TODO: Refactor to use some kind of cache together with GetPropertyFromAccessor
- void ResolveAccessors (Type containerType)
+ void ResolveAccessors (Type container_type)
{
- FindAccessors (containerType);
+ FindAccessors (container_type);
if (getter != null) {
MethodBase the_getter = TypeManager.DropGenericMethodArguments (getter);
if (InstanceExpression == null)
return false;
- InstanceExpression.CheckMarshalByRefAccess ();
+ InstanceExpression.CheckMarshalByRefAccess (ec);
if (must_do_cs1540_check && (InstanceExpression != EmptyExpression.Null) &&
!TypeManager.IsInstantiationOfSameGenericType (InstanceExpression.Type, ec.ContainerType) &&
Error_TypeDoesNotContainDefinition (loc, PropertyInfo.DeclaringType, Name);
return;
}
-
+
StringBuilder sig = new StringBuilder (TypeManager.CSharpName (mi.DeclaringType));
sig.Append ('.');
ParameterData iparams = TypeManager.GetParameterData (mi);
return accessor != null && IsAccessorAccessible (invocation_type, accessor, out dummy);
}
+ bool IsSingleDimensionalArrayLength ()
+ {
+ if (DeclaringType != TypeManager.array_type || getter == null || Name != "Length")
+ return false;
+
+ string t_name = InstanceExpression.Type.Name;
+ int t_name_len = t_name.Length;
+ return t_name_len > 2 && t_name [t_name_len - 2] == '[' && t_name [t_name_len - 3] != ']';
+ }
+
override public Expression DoResolve (EmitContext ec)
{
if (resolved)
}
if (right_side == EmptyExpression.LValueMemberAccess || right_side == EmptyExpression.LValueMemberOutAccess) {
- Report.Error (1612, loc, "Cannot modify the return value of `{0}' because it is not a variable",
- GetSignatureForError ());
- return null;
+ Error_CannotModifyIntermediateExpressionValue (ec);
}
if (setter == null){
//
// Special case: length of single dimension array property is turned into ldlen
//
- if ((getter == TypeManager.system_int_array_get_length) ||
- (getter == TypeManager.int_array_get_length)){
- Type iet = InstanceExpression.Type;
-
- //
- // System.Array.Length can be called, but the Type does not
- // support invoking GetArrayRank, so test for that case first
- //
- if (iet != TypeManager.array_type && (iet.GetArrayRank () == 1)) {
- if (!prepared)
- EmitInstance (ec, false);
- ec.ig.Emit (OpCodes.Ldlen);
- ec.ig.Emit (OpCodes.Conv_I4);
- return;
- }
+ if (IsSingleDimensionalArrayLength ()) {
+ if (!prepared)
+ EmitInstance (ec, false);
+ ec.ig.Emit (OpCodes.Ldlen);
+ ec.ig.Emit (OpCodes.Conv_I4);
+ return;
}
Invocation.EmitCall (ec, IsBase, InstanceExpression, getter, null, loc, prepared, false);
/// </summary>
public class EventExpr : MemberExpr {
public readonly EventInfo EventInfo;
- public bool IsBase;
bool is_static;
MethodInfo add_accessor, remove_accessor;
return EventInfo.DeclaringType;
}
}
+
+ void Error_AssignmentEventOnly ()
+ {
+ Report.Error (79, loc, "The event `{0}' can only appear on the left hand side of `+=' or `-=' operator",
+ GetSignatureForError ());
+ }
- public override Expression ResolveMemberAccess (EmitContext ec, Expression left, Location loc,
+ public override MemberExpr ResolveMemberAccess (EmitContext ec, Expression left, Location loc,
SimpleName original)
{
//
if (!ec.IsInObsoleteScope)
mi.CheckObsoleteness (loc);
+ if ((mi.ModFlags & (Modifiers.ABSTRACT | Modifiers.EXTERN)) != 0 && !ec.IsInCompoundAssignment)
+ Error_AssignmentEventOnly ();
+
FieldExpr ml = new FieldExpr (mi.FieldBuilder, loc);
InstanceExpression = null;
return ml.ResolveMemberAccess (ec, left, loc, original);
}
}
+
+ if (left is This && !ec.IsInCompoundAssignment)
+ Error_AssignmentEventOnly ();
return base.ResolveMemberAccess (ec, left, loc, original);
}
//
if (must_do_cs1540_check && InstanceExpression != EmptyExpression.Null &&
InstanceExpression.Type != ec.ContainerType &&
- ec.ContainerType.IsSubclassOf (InstanceExpression.Type)) {
+ TypeManager.IsSubclassOf (ec.ContainerType, InstanceExpression.Type)) {
Report.SymbolRelatedToPreviousError (EventInfo);
ErrorIsInaccesible (loc, TypeManager.CSharpSignature (EventInfo));
return false;
public override void Emit (EmitContext ec)
{
- if (InstanceExpression is This)
- Report.Error (79, loc, "The event `{0}' can only appear on the left hand side of += or -=", GetSignatureForError ());
- else
- Report.Error (70, loc, "The event `{0}' can only appear on the left hand side of += or -= "+
- "(except on the defining type)", Name);
+ Report.Error (70, loc, "The event `{0}' can only appear on the left hand side of += or -= "+
+ "(except on the defining type)", GetSignatureForError ());
}
public override string GetSignatureForError ()
// Used for error reporting only
ArrayList initializer;
- public VarExpr (string name, Location loc)
- : base (name, loc)
+ public VarExpr (Location loc)
+ : base ("var", loc)
{
}
protected override void Error_TypeOrNamespaceNotFound (IResolveContext ec)
{
- if (ec is FieldBase) {
- Report.Error (825, loc, "The contextual keyword `var' may only appear within a local variable declaration");
- return;
- }
-
- base.Error_TypeOrNamespaceNotFound (ec);
+ Report.Error (825, loc, "The contextual keyword `var' may only appear within a local variable declaration");
}
public override TypeExpr ResolveAsContextualType (IResolveContext rc, bool silent)
if (initializer == null)
return null;
- // TODO: refactor, the error is reported too many times
if (initializer.Count > 1) {
Location loc = ((Mono.CSharp.CSharpParser.VariableDeclaration)initializer [1]).Location;
Report.Error (819, loc, "An implicitly typed local variable declaration cannot include multiple declarators");
+ initializer = null;
return null;
}