// This is used if the expression should be resolved as a type or namespace name.
// the default implementation fails.
//
- public virtual TypeExpr ResolveAsType (IMemberContext mc, bool silent)
+ public virtual TypeSpec ResolveAsType (IMemberContext mc)
{
- if (!silent) {
- ResolveContext ec = new ResolveContext (mc);
- 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;
}
continue;
}
- if (non_method == null || member is MethodSpec) {
+ if (non_method == null || member is MethodSpec || non_method.IsNotCSharpCompatible) {
non_method = member;
- } else if (!errorMode) {
+ } else if (!errorMode && !member.IsNotCSharpCompatible) {
ambig_non_method = member;
}
}
{
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);
{
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);
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;
this.expr = expr;
}
+ public Expression Expr {
+ get {
+ return expr;
+ }
+ }
+
protected override void CloneTo (CloneContext clonectx, Expression t)
{
if (expr == null)
throw new InternalErrorException ("Missing Resolve call");
}
- public Expression Expr {
- get { return expr; }
- }
}
//
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)
{
- if (ec.CurrentType != null) {
- if (ec.CurrentMemberDefinition != null) {
- MemberCore mc = ec.CurrentMemberDefinition.Parent.GetDefinition (Name);
+ return SimpleNameResolve (ec, right_side, false);
+ }
+
+ protected virtual void Error_TypeOrNamespaceNotFound (IMemberContext ctx)
+ {
+ if (ctx.CurrentType != null) {
+ if (ctx.CurrentMemberDefinition != null) {
+ MemberCore mc = ctx.CurrentMemberDefinition.Parent.GetDefinition (Name);
if (mc != null) {
- Error_UnexpectedKind (ec.Module.Compiler.Report, mc, "type", GetMemberType (mc), loc);
+ Error_UnexpectedKind (ctx.Module.Compiler.Report, mc, "type", GetMemberType (mc), 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, retval.Type, Arity, loc);
-/*
- 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;
}
- NamespaceContainer.Error_NamespaceNotFound (loc, Name, ec.Module.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 ResolveAsTypeOrNamespace (IMemberContext ec, bool silent)
+ public override FullNamedExpression ResolveAsTypeOrNamespace (IMemberContext ec)
{
- int errors = ec.Module.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.ResolveAsType (ec, false);
+ if (ct.ResolveAsType (ec) == null)
+ return null;
+
+ return ct;
}
return new GenericOpenTypeExpr (fne.Type, loc);
ec.Module.PredefinedAttributes.Dynamic.GetSignatureForError ());
}
- return new DynamicTypeExpr (loc).ResolveAsType (ec, silent);
+ fne = new DynamicTypeExpr (loc);
+ fne.ResolveAsType (ec);
}
if (fne != null)
return fne;
- if (silent || errors != ec.Module.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;
// Stage 3: Lookup nested types, namespaces and type parameters in the context
//
if ((restrictions & MemberLookupRestrictions.InvocableOnly) == 0 && !variable_found) {
- e = ResolveAsTypeOrNamespace (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);
}
}
} while (ct != null);
}
- var retval = rc.LookupNamespaceOrType (Name, -System.Math.Max (1, Arity), loc, true);
- if (retval != null) {
- Error_TypeArgumentsCannotBeUsed (rc, retval.Type, Arity, loc);
- } else {
- rc.Report.Error (103, loc, "The name `{0}' does not exist in the current context", Name);
+ 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 (rc.Module.Evaluator != null) {
}
lookup_arity = 0;
- restrictions &= ~MemberLookupRestrictions.InvocableOnly;
errorMode = true;
}
}
throw new NotSupportedException ("ET");
}
- public abstract FullNamedExpression ResolveAsTypeOrNamespace (IMemberContext mc, 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 TypeExpr ResolveAsType (IMemberContext mc, bool silent)
+ public override TypeSpec ResolveAsType (IMemberContext mc)
{
- // FIXME: THIS IS TOO SLOW and it should not be needed either
- int errors = mc.Module.Compiler.Report.Errors;
-
- FullNamedExpression fne = ResolveAsTypeOrNamespace (mc, silent);
+ FullNamedExpression fne = ResolveAsTypeOrNamespace (mc);
if (fne == null)
return null;
TypeExpr te = fne as TypeExpr;
if (te == null) {
- if (!silent && errors == mc.Module.Compiler.Report.Errors)
- fne.Error_UnexpectedKind (mc.Module.Compiler.Report, null, "type", loc);
+ fne.Error_UnexpectedKind (mc.Module.Compiler.Report, null, "type", loc);
return null;
}
- if (!te.type.IsAccessible (mc)) {
- mc.Module.Compiler.Report.SymbolRelatedToPreviousError (te.Type);
- ErrorIsInaccesible (mc, te.Type.GetSignatureForError (), loc);
- }
-
te.loc = loc;
- var dep = te.type.GetMissingDependencies ();
+ 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 dependecies to be set but we are just resolving them
+ // require type dependencies to be set but we are in process of resolving them
//
- if (!silent && !(mc is TypeContainer.BaseContext)) {
- ObsoleteAttribute obsolete_attr = te.Type.GetAttributeObsolete ();
+ 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 te;
+ return type;
}
/// </summary>
public abstract class TypeExpr : FullNamedExpression
{
- public sealed override FullNamedExpression ResolveAsTypeOrNamespace (IMemberContext mc, bool silent)
+ public sealed override FullNamedExpression ResolveAsTypeOrNamespace (IMemberContext mc)
{
- return ResolveAsType (mc, silent);
+ ResolveAsType (mc);
+ return this;
}
protected sealed override Expression DoResolve (ResolveContext ec)
{
- return ResolveAsType (ec, false);
+ ResolveAsType (ec);
+ return this;
}
public override bool Equals (object obj)
loc = l;
}
- public sealed override TypeExpr ResolveAsType (IMemberContext ec, bool silent)
+ public sealed override TypeSpec ResolveAsType (IMemberContext ec)
{
- return this;
+ return type;
}
}
get;
}
- // TODO: Not needed
protected abstract TypeSpec DeclaringType {
get;
}
// 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
//
// 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;
}
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");
}
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);
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);
}
//
// 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;
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<Y1>, and Q has a return type Task<Y2>
+ // 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;
//
// 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) {
}
}
+ //
+ // 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 ();
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);
public bool IsMarshalByRefAccess (ResolveContext rc)
{
// Checks possible ldflda of field access expression
- return !spec.IsStatic && TypeManager.IsValueType (spec.MemberType) && !(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 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) {
{
eclass = ExprClass.PropertyAccess;
- if (best_candidate.IsNotRealProperty) {
+ if (best_candidate.IsNotCSharpCompatible) {
Error_PropertyNotValid (rc);
}