//
//
+using System;
+using System.Collections.Generic;
+using System.Diagnostics;
+using System.Reflection;
+using System.Reflection.Emit;
+using System.Text;
+using SLE = System.Linq.Expressions;
+using System.Linq;
+
namespace Mono.CSharp {
- using System;
- using System.Collections;
- using System.Diagnostics;
- using System.Reflection;
- using System.Reflection.Emit;
- using System.Text;
/// <remarks>
/// The ExprClass class contains the is used to pass the
/// nothing).
/// </remarks>
public enum ExprClass : byte {
- Invalid,
+ Unresolved = 0,
Value,
Variable,
// Mask of all the expression class flags.
MaskExprClass = VariableOrValue | Type | MethodGroup | TypeParameter,
- // Disable control flow analysis while resolving the expression.
- // This is used when resolving the instance expression of a field expression.
- DisableFlowAnalysis = 1 << 10,
-
// Set if this is resolving the first part of a MemberAccess.
Intermediate = 1 << 11,
-
- // Disable control flow analysis _of struct_ while resolving the expression.
- // This is used when resolving the instance expression of a field expression.
- DisableStructFlowAnalysis = 1 << 12,
-
}
//
get { return loc; }
}
- /// <summary>
- /// Utility wrapper routine for Error, just to beautify the code
- /// </summary>
- public void Error (int error, string s)
- {
- Report.Error (error, loc, s);
- }
-
// Not nice but we have broken hierarchy.
- public virtual void CheckMarshalByRefAccess (EmitContext ec)
+ public virtual void CheckMarshalByRefAccess (ResolveContext ec)
{
}
- public virtual bool GetAttributableValue (EmitContext ec, Type value_type, out object value)
+ public virtual bool GetAttributableValue (ResolveContext ec, Type value_type, out object value)
{
- Attribute.Error_AttributeArgumentNotValid (loc);
+ Attribute.Error_AttributeArgumentNotValid (ec, loc);
value = null;
return false;
}
return TypeManager.CSharpName (type);
}
- public static bool IsAccessorAccessible (Type invocation_type, MethodInfo mi, out bool must_do_cs1540_check)
+ public static bool IsAccessorAccessible (Type invocation_type, MethodSpec mi, out bool must_do_cs1540_check)
{
- MethodAttributes ma = mi.Attributes & MethodAttributes.MemberAccessMask;
+ var ma = mi.Modifiers & Modifiers.AccessibilityMask;
must_do_cs1540_check = false; // by default we do not check for this
- if (ma == MethodAttributes.Public)
+ if (ma == Modifiers.PUBLIC)
return true;
//
// If only accessible to the current class or children
//
- if (ma == MethodAttributes.Private)
+ if (ma == Modifiers.PRIVATE)
return TypeManager.IsPrivateAccessible (invocation_type, mi.DeclaringType) ||
TypeManager.IsNestedChildOf (invocation_type, mi.DeclaringType);
- if (TypeManager.IsThisOrFriendAssembly (mi.DeclaringType.Assembly)) {
- if (ma == MethodAttributes.Assembly || ma == MethodAttributes.FamORAssem)
- return true;
- } else {
- if (ma == MethodAttributes.Assembly || ma == MethodAttributes.FamANDAssem)
- return false;
+ if ((ma & Modifiers.INTERNAL) != 0) {
+ var b = TypeManager.IsThisOrFriendAssembly (invocation_type.Assembly, mi.DeclaringType.Assembly);
+ if (b || ma == Modifiers.INTERNAL)
+ return b;
}
// Family and FamANDAssem require that we derive.
/// to a valid type (this is the type of the
/// expression).
/// </remarks>
- public abstract Expression DoResolve (EmitContext ec);
+ protected abstract Expression DoResolve (ResolveContext rc);
- public virtual Expression DoResolveLValue (EmitContext ec, Expression right_side)
+ public virtual Expression DoResolveLValue (ResolveContext rc, Expression right_side)
{
return null;
}
// This is used if the expression should be resolved as a type or namespace name.
// the default implementation fails.
//
- public virtual FullNamedExpression ResolveAsTypeStep (IResolveContext rc, bool silent)
+ public virtual FullNamedExpression ResolveAsTypeStep (IMemberContext rc, bool silent)
{
if (!silent) {
- Expression e = this;
- EmitContext ec = rc as EmitContext;
- if (ec != null)
- e = e.Resolve (ec);
+ ResolveContext ec = new ResolveContext (rc);
+ Expression e = Resolve (ec);
if (e != null)
- e.Error_UnexpectedKind (ResolveFlags.Type, loc);
+ e.Error_UnexpectedKind (ec, ResolveFlags.Type, loc);
}
+
return null;
}
// C# 3.0 introduced contextual keywords (var) which behaves like a type if type with
// same name exists or as a keyword when no type was found
//
- public virtual TypeExpr ResolveAsContextualType (IResolveContext rc, bool silent)
+ public virtual TypeExpr ResolveAsContextualType (IMemberContext rc, bool silent)
{
return ResolveAsTypeTerminal (rc, silent);
}
// value will be returned if the expression is not a type
// reference
//
- public virtual TypeExpr ResolveAsTypeTerminal (IResolveContext ec, bool silent)
+ public virtual TypeExpr ResolveAsTypeTerminal (IMemberContext ec, bool silent)
{
TypeExpr te = ResolveAsBaseTerminal (ec, silent);
if (te == null)
if (!silent) { // && !(te is TypeParameterExpr)) {
ObsoleteAttribute obsolete_attr = AttributeTester.GetObsoleteAttribute (te.Type);
- if (obsolete_attr != null && !ec.IsInObsoleteScope) {
- AttributeTester.Report_ObsoleteMessage (obsolete_attr, te.GetSignatureForError (), Location);
+ if (obsolete_attr != null && !ec.IsObsolete) {
+ AttributeTester.Report_ObsoleteMessage (obsolete_attr, te.GetSignatureForError (), Location, ec.Compiler.Report);
}
}
GenericTypeExpr ct = te as GenericTypeExpr;
if (ct != null) {
- // Skip constrains check for overrides and explicit implementations
- // TODO: they should use different overload
- GenericMethod gm = ec.GenericDeclContainer as GenericMethod;
+ //
+ // TODO: Constrained type parameters check for parameters of generic method overrides is broken
+ // There are 2 solutions.
+ // 1, Skip this check completely when we are in override/explicit impl scope
+ // 2, Copy type parameters constraints from base implementation and pass (they have to be emitted anyway)
+ //
+ MemberCore gm = ec as GenericMethod;
+ if (gm == null)
+ gm = ec as Method;
if (gm != null && ((gm.ModFlags & Modifiers.OVERRIDE) != 0 || gm.MemberName.Left != null)) {
te.loc = loc;
return te;
return te;
}
- public TypeExpr ResolveAsBaseTerminal (IResolveContext ec, bool silent)
+ public TypeExpr ResolveAsBaseTerminal (IMemberContext ec, bool silent)
{
- int errors = Report.Errors;
+ int errors = ec.Compiler.Report.Errors;
FullNamedExpression fne = ResolveAsTypeStep (ec, silent);
TypeExpr te = fne as TypeExpr;
if (te == null) {
- if (!silent && errors == Report.Errors)
- fne.Error_UnexpectedKind (null, "type", loc);
+ if (!silent && errors == ec.Compiler.Report.Errors)
+ fne.Error_UnexpectedKind (ec.Compiler.Report, null, "type", loc);
return null;
}
- if (!te.CheckAccessLevel (ec.GenericDeclContainer)) {
- Report.SymbolRelatedToPreviousError (te.Type);
- ErrorIsInaccesible (loc, TypeManager.CSharpName (te.Type));
+ if (!te.CheckAccessLevel (ec)) {
+ ec.Compiler.Report.SymbolRelatedToPreviousError (te.Type);
+ ErrorIsInaccesible (loc, TypeManager.CSharpName (te.Type), ec.Compiler.Report);
return null;
}
return te;
}
- public static void ErrorIsInaccesible (Location loc, string name)
+ public static void ErrorIsInaccesible (Location loc, string name, Report Report)
{
Report.Error (122, loc, "`{0}' is inaccessible due to its protection level", name);
}
- protected static void Error_CannotAccessProtected (Location loc, MemberInfo m, Type qualifier, Type container)
+ protected static void Error_CannotAccessProtected (ResolveContext ec, Location loc, MemberInfo m, Type qualifier, Type container)
{
- Report.Error (1540, loc, "Cannot access protected member `{0}' via a qualifier of type `{1}'."
+ ec.Report.Error (1540, loc, "Cannot access protected member `{0}' via a qualifier of type `{1}'."
+ " The qualifier must be of type `{2}' or derived from it",
TypeManager.GetFullNameSignature (m),
TypeManager.CSharpName (qualifier),
}
- public static void Error_InvalidExpressionStatement (Location loc)
+ public void Error_ExpressionMustBeConstant (ResolveContext rc, Location loc, string e_name)
{
- Report.Error (201, loc, "Only assignment, call, increment, decrement, and new object " +
- "expressions can be used as a statement");
+ rc.Report.Error (133, loc, "The expression being assigned to `{0}' must be constant", e_name);
}
-
- public void Error_InvalidExpressionStatement ()
+
+ public void Error_ConstantCanBeInitializedWithNullOnly (ResolveContext rc, Type type, Location loc, string name)
{
- Error_InvalidExpressionStatement (loc);
+ rc.Report.Error (134, loc, "A constant `{0}' of reference type `{1}' can only be initialized with null",
+ name, TypeManager.CSharpName (type));
}
- protected void Error_CannotAssign (string to, string roContext)
+ public static void Error_InvalidExpressionStatement (Report Report, Location loc)
+ {
+ Report.Error (201, loc, "Only assignment, call, increment, decrement, and new object " +
+ "expressions can be used as a statement");
+ }
+
+ public void Error_InvalidExpressionStatement (BlockContext ec)
{
- Report.Error (1656, loc, "Cannot assign to `{0}' because it is a `{1}'",
- to, roContext);
+ Error_InvalidExpressionStatement (ec.Report, loc);
}
- public static void Error_VoidInvalidInTheContext (Location loc)
+ public static void Error_VoidInvalidInTheContext (Location loc, Report Report)
{
Report.Error (1547, loc, "Keyword `void' cannot be used in this context");
}
- public virtual void Error_ValueCannotBeConverted (EmitContext ec, Location loc, Type target, bool expl)
+ public virtual void Error_ValueCannotBeConverted (ResolveContext ec, Location loc, Type target, bool expl)
{
Error_ValueCannotBeConvertedCore (ec, loc, target, expl);
}
- protected void Error_ValueCannotBeConvertedCore (EmitContext ec, Location loc, Type target, bool expl)
+ protected void Error_ValueCannotBeConvertedCore (ResolveContext ec, Location loc, Type target, bool expl)
{
// The error was already reported as CS1660
if (type == InternalType.AnonymousMethod)
return;
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 sig2 = target.DeclaringMethod == null ?
TypeManager.CSharpName (target.DeclaringType) :
TypeManager.CSharpSignature (target.DeclaringMethod);
- Report.ExtraInformation (loc,
+ ec.Report.ExtraInformation (loc,
String.Format (
"The generic parameter `{0}' of `{1}' cannot be converted to the generic parameter `{0}' of `{2}' (in the previous ",
Type.Name, sig1, sig2));
-#endif
} else if (Type.FullName == target.FullName){
- Report.ExtraInformation (loc,
+ ec.Report.ExtraInformation (loc,
String.Format (
"The type `{0}' has two conflicting definitions, one comes from `{1}' and the other from `{2}' (in the previous ",
Type.FullName, Type.Assembly.FullName, target.Assembly.FullName));
}
if (expl) {
- Report.Error (30, loc, "Cannot convert type `{0}' to `{1}'",
+ ec.Report.Error (30, loc, "Cannot convert type `{0}' to `{1}'",
TypeManager.CSharpName (type), TypeManager.CSharpName (target));
return;
}
- Report.DisableReporting ();
+ ec.Report.DisableReporting ();
bool expl_exists = Convert.ExplicitConversion (ec, this, target, Location.Null) != null;
- Report.EnableReporting ();
+ ec.Report.EnableReporting ();
if (expl_exists) {
- Report.Error (266, loc, "Cannot implicitly convert type `{0}' to `{1}'. " +
+ ec.Report.Error (266, loc, "Cannot implicitly convert type `{0}' to `{1}'. " +
"An explicit conversion exists (are you missing a cast?)",
TypeManager.CSharpName (Type), TypeManager.CSharpName (target));
return;
}
- Report.Error (29, loc, "Cannot implicitly convert type `{0}' to `{1}'",
+ ec.Report.Error (29, loc, "Cannot implicitly convert type `{0}' to `{1}'",
TypeManager.CSharpName (type),
TypeManager.CSharpName (target));
}
- public virtual void Error_VariableIsUsedBeforeItIsDeclared (string name)
+ public virtual void Error_VariableIsUsedBeforeItIsDeclared (Report Report, string name)
{
Report.Error (841, loc, "A local variable `{0}' cannot be used before it is declared", name);
}
- protected virtual void Error_TypeDoesNotContainDefinition (Type type, string name)
+ public void Error_TypeArgumentsCannotBeUsed (Report report, Location loc)
{
- Error_TypeDoesNotContainDefinition (loc, type, name);
+ // Better message for possible generic expressions
+ if (eclass == ExprClass.MethodGroup || eclass == ExprClass.Type) {
+ if (this is TypeExpr)
+ report.SymbolRelatedToPreviousError (type);
+
+ string name = eclass == ExprClass.Type ? ExprClassName : "method";
+ report.Error (308, loc, "The non-generic {0} `{1}' cannot be used with the type arguments",
+ name, GetSignatureForError ());
+ } else {
+ report.Error (307, loc, "The {0} `{1}' cannot be used with type arguments",
+ ExprClassName, GetSignatureForError ());
+ }
}
- public static void Error_TypeDoesNotContainDefinition (Location loc, Type type, string name)
+ protected virtual void Error_TypeDoesNotContainDefinition (ResolveContext ec, Type type, string name)
{
- Report.SymbolRelatedToPreviousError (type);
- Report.Error (117, loc, "`{0}' does not contain a definition for `{1}'",
- TypeManager.CSharpName (type), name);
+ Error_TypeDoesNotContainDefinition (ec, loc, type, name);
}
- protected static void Error_ValueAssignment (Location loc)
+ public static void Error_TypeDoesNotContainDefinition (ResolveContext ec, Location loc, Type type, string name)
{
- Report.Error (131, loc, "The left-hand side of an assignment must be a variable, a property or an indexer");
+ ec.Report.SymbolRelatedToPreviousError (type);
+ ec.Report.Error (117, loc, "`{0}' does not contain a definition for `{1}'",
+ TypeManager.CSharpName (type), name);
}
- ResolveFlags ExprClassToResolveFlags
+ protected static void Error_ValueAssignment (ResolveContext ec, Location loc)
{
+ ec.Report.Error (131, loc, "The left-hand side of an assignment must be a variable, a property or an indexer");
+ }
+
+ ResolveFlags ExprClassToResolveFlags {
get {
switch (eclass) {
case ExprClass.Type:
/// Currently Resolve wraps DoResolve to perform sanity
/// checking and assertion checking on what we expect from Resolve.
/// </remarks>
- public Expression Resolve (EmitContext ec, ResolveFlags flags)
+ public Expression Resolve (ResolveContext ec, ResolveFlags flags)
{
- if ((flags & ResolveFlags.MaskExprClass) == ResolveFlags.Type)
- return ResolveAsTypeStep (ec, false);
-
- bool do_flow_analysis = ec.DoFlowAnalysis;
- bool omit_struct_analysis = ec.OmitStructFlowAnalysis;
- if ((flags & ResolveFlags.DisableFlowAnalysis) != 0)
- do_flow_analysis = false;
- if ((flags & ResolveFlags.DisableStructFlowAnalysis) != 0)
- omit_struct_analysis = true;
+ if (eclass != ExprClass.Unresolved)
+ return this;
Expression e;
- using (ec.WithFlowAnalysis (do_flow_analysis, omit_struct_analysis)) {
- if (this is SimpleName) {
- bool intermediate = (flags & ResolveFlags.Intermediate) == ResolveFlags.Intermediate;
- e = ((SimpleName) this).DoResolve (ec, intermediate);
- } else {
- e = DoResolve (ec);
- }
+ if (this is SimpleName) {
+ e = ((SimpleName) this).DoResolve (ec, (flags & ResolveFlags.Intermediate) != 0);
+ } else {
+ e = DoResolve (ec);
}
if (e == null)
return null;
if ((flags & e.ExprClassToResolveFlags) == 0) {
- e.Error_UnexpectedKind (flags, loc);
+ e.Error_UnexpectedKind (ec, flags, loc);
return null;
}
- if (e.type == null && !(e is Namespace)) {
- throw new Exception (
- "Expression " + e.GetType () +
- " did not set its type after Resolve\n" +
- "called from: " + this.GetType ());
- }
+ if (e.type == null)
+ throw new InternalErrorException ("Expression `{0}' didn't set its type in DoResolve", e.GetType ());
return e;
}
/// <summary>
/// Resolves an expression and performs semantic analysis on it.
/// </summary>
- public Expression Resolve (EmitContext ec)
+ public Expression Resolve (ResolveContext rc)
{
- Expression e = Resolve (ec, ResolveFlags.VariableOrValue | ResolveFlags.MethodGroup);
-
- if (e != null && e.eclass == ExprClass.MethodGroup && RootContext.Version == LanguageVersion.ISO_1) {
- ((MethodGroupExpr) e).ReportUsageError ();
- return null;
- }
- return e;
- }
-
- public Constant ResolveAsConstant (EmitContext ec, MemberCore mc)
- {
- Expression e = Resolve (ec);
- if (e == null)
- return null;
-
- Constant c = e as Constant;
- if (c != null)
- return c;
-
- if (type != null && TypeManager.IsReferenceType (type))
- Const.Error_ConstantCanBeInitializedWithNullOnly (type, loc, mc.GetSignatureForError ());
- else
- Const.Error_ExpressionMustBeConstant (loc, mc.GetSignatureForError ());
-
- return null;
+ return Resolve (rc, ResolveFlags.VariableOrValue | ResolveFlags.MethodGroup);
}
/// <summary>
/// Currently ResolveLValue wraps DoResolveLValue to perform sanity
/// checking and assertion checking on what we expect from Resolve
/// </remarks>
- public Expression ResolveLValue (EmitContext ec, Expression right_side)
+ public Expression ResolveLValue (ResolveContext ec, Expression right_side)
{
- int errors = Report.Errors;
- bool out_access = right_side == EmptyExpression.OutAccess;
+ int errors = ec.Report.Errors;
+ bool out_access = right_side == EmptyExpression.OutAccess.Instance;
Expression e = DoResolveLValue (ec, right_side);
}
if (e == null) {
- if (errors == Report.Errors) {
+ if (errors == ec.Report.Errors) {
if (out_access)
- Report.Error (1510, loc, "A ref or out argument must be an assignable variable");
+ ec.Report.Error (1510, loc, "A ref or out argument must be an assignable variable");
else
- Error_ValueAssignment (loc);
+ Error_ValueAssignment (ec, loc);
}
return null;
}
- if (e.eclass == ExprClass.Invalid)
+ if (e.eclass == ExprClass.Unresolved)
throw new Exception ("Expression " + e + " ExprClass is Invalid after resolve");
if ((e.type == null) && !(e is GenericTypeExpr))
protected Expression ()
{
- eclass = ExprClass.Invalid;
- type = null;
}
/// <summary>
public static Expression ExprClassFromMemberInfo (Type container_type, MemberInfo mi, Location loc)
{
if (mi is EventInfo)
- return new EventExpr ((EventInfo) mi, loc);
+ return new EventExpr (Import.CreateEvent ((EventInfo) mi), loc);
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);
+ var spec = Import.CreateField (fi);
+ if (spec is ConstSpec)
+ return new ConstantExpr ((ConstSpec) spec, loc);
+ return new FieldExpr (spec, loc);
} else if (mi is PropertyInfo)
- return new PropertyExpr (container_type, (PropertyInfo) mi, loc);
+ return new PropertyExpr (container_type, Import.CreateProperty ((PropertyInfo) mi), loc);
else if (mi is Type) {
return new TypeExpression ((System.Type) mi, loc);
}
}
// TODO: [Obsolete ("Can be removed")]
- protected static ArrayList almost_matched_members = new ArrayList (4);
+ protected static IList<MemberInfo> almost_matched_members = new List<MemberInfo> (4);
//
// FIXME: Probably implement a cache for (t,name,current_access_set)?
// FIXME: Potential optimization, have a static ArrayList
//
- public static Expression MemberLookup (Type container_type, Type queried_type, string name,
+ public static Expression MemberLookup (CompilerContext ctx, Type container_type, Type queried_type, string name,
MemberTypes mt, BindingFlags bf, Location loc)
{
- return MemberLookup (container_type, null, queried_type, name, mt, bf, loc);
+ return MemberLookup (ctx, container_type, null, queried_type, name, mt, bf, loc);
}
//
// `qualifier_type' or null to lookup members in the current class.
//
- public static Expression MemberLookup (Type container_type,
+ public static Expression MemberLookup (CompilerContext ctx, Type container_type,
Type qualifier_type, Type queried_type,
string name, MemberTypes mt,
BindingFlags bf, Location loc)
if (mi.Length > 1) {
bool is_interface = qualifier_type != null && qualifier_type.IsInterface;
- ArrayList methods = new ArrayList (2);
- ArrayList non_methods = null;
+ var methods = new List<MethodSpec> (2);
+ List<MemberInfo> non_methods = null;
- foreach (MemberInfo m in mi) {
+ foreach (var m in mi) {
if (m is MethodBase) {
- methods.Add (m);
+ methods.Add (Import.CreateMethod ((MethodBase) m));
continue;
}
- if (non_methods == null) {
- non_methods = new ArrayList (2);
- non_methods.Add (m);
- continue;
+ if (non_methods == null)
+ non_methods = new List<MemberInfo> (2);
+
+ bool is_candidate = true;
+ for (int i = 0; i < non_methods.Count; ++i) {
+ MemberInfo n_m = non_methods [i];
+ if (n_m.DeclaringType.IsInterface && TypeManager.ImplementsInterface (m.DeclaringType, n_m.DeclaringType)) {
+ non_methods.Remove (n_m);
+ --i;
+ } else if (m.DeclaringType.IsInterface && TypeManager.ImplementsInterface (n_m.DeclaringType, m.DeclaringType)) {
+ is_candidate = false;
+ break;
+ }
}
-
- foreach (MemberInfo n_m in non_methods) {
- if (m.DeclaringType.IsInterface && TypeManager.ImplementsInterface (m.DeclaringType, n_m.DeclaringType))
- continue;
-
- Report.SymbolRelatedToPreviousError (m);
- Report.Error (229, loc, "Ambiguity between `{0}' and `{1}'",
- TypeManager.GetFullNameSignature (m), TypeManager.GetFullNameSignature (n_m));
- return null;
+
+ if (is_candidate) {
+ non_methods.Add (m);
}
}
+
+ if (methods.Count == 0 && non_methods != null && non_methods.Count > 1) {
+ ctx.Report.SymbolRelatedToPreviousError (non_methods [1]);
+ ctx.Report.SymbolRelatedToPreviousError (non_methods [0]);
+ ctx.Report.Error (229, loc, "Ambiguity between `{0}' and `{1}'",
+ TypeManager.GetFullNameSignature (non_methods [1]),
+ TypeManager.GetFullNameSignature (non_methods [0]));
+ return null;
+ }
if (methods.Count == 0)
return ExprClassFromMemberInfo (container_type, (MemberInfo)non_methods [0], loc);
- if (non_methods != null) {
- MethodBase method = (MethodBase) methods [0];
+ if (non_methods != null && non_methods.Count > 0) {
+ var method = methods [0];
MemberInfo non_method = (MemberInfo) non_methods [0];
if (method.DeclaringType == non_method.DeclaringType) {
// Cannot happen with C# code, but is valid in IL
- Report.SymbolRelatedToPreviousError (method);
- Report.SymbolRelatedToPreviousError (non_method);
- Report.Error (229, loc, "Ambiguity between `{0}' and `{1}'",
+ ctx.Report.SymbolRelatedToPreviousError (method.MetaInfo);
+ ctx.Report.SymbolRelatedToPreviousError (non_method);
+ ctx.Report.Error (229, loc, "Ambiguity between `{0}' and `{1}'",
TypeManager.GetFullNameSignature (non_method),
- TypeManager.CSharpSignature (method));
+ TypeManager.CSharpSignature (method.MetaInfo));
return null;
}
if (is_interface) {
- Report.SymbolRelatedToPreviousError (method);
- Report.SymbolRelatedToPreviousError (non_method);
- Report.Warning (467, 2, loc, "Ambiguity between method `{0}' and non-method `{1}'. Using method `{0}'",
- TypeManager.CSharpSignature (method), TypeManager.GetFullNameSignature (non_method));
+ ctx.Report.SymbolRelatedToPreviousError (method.MetaInfo);
+ ctx.Report.SymbolRelatedToPreviousError (non_method);
+ ctx.Report.Warning (467, 2, loc, "Ambiguity between method `{0}' and non-method `{1}'. Using method `{0}'",
+ TypeManager.CSharpSignature (method.MetaInfo), TypeManager.GetFullNameSignature (non_method));
}
}
}
if (mi [0] is MethodBase)
- return new MethodGroupExpr (mi, queried_type, loc);
+ return new MethodGroupExpr (mi.Select (l => Import.CreateMethod ((MethodBase) l)).ToArray (), queried_type, loc);
return ExprClassFromMemberInfo (container_type, mi [0], loc);
}
BindingFlags.Static |
BindingFlags.Instance;
- public static Expression MemberLookup (Type container_type, Type queried_type,
+ public static Expression MemberLookup (CompilerContext ctx, Type container_type, Type queried_type,
string name, Location loc)
{
- return MemberLookup (container_type, null, queried_type, name,
+ return MemberLookup (ctx, container_type, null, queried_type, name,
AllMemberTypes, AllBindingFlags, loc);
}
- public static Expression MemberLookup (Type container_type, Type qualifier_type,
+ public static Expression MemberLookup (CompilerContext ctx, Type container_type, Type qualifier_type,
Type queried_type, string name, Location loc)
{
- return MemberLookup (container_type, qualifier_type, queried_type,
+ return MemberLookup (ctx, container_type, qualifier_type, queried_type,
name, AllMemberTypes, AllBindingFlags, loc);
}
- public static MethodGroupExpr MethodLookup (Type container_type, Type queried_type,
+ public static MethodGroupExpr MethodLookup (CompilerContext ctx, Type container_type, Type queried_type,
string name, Location loc)
{
- return (MethodGroupExpr)MemberLookup (container_type, null, queried_type, name,
+ return (MethodGroupExpr)MemberLookup (ctx, container_type, null, queried_type, name,
MemberTypes.Method, AllBindingFlags, loc);
}
/// look for private members and display a useful debugging message if we
/// find it.
/// </summary>
- protected Expression MemberLookupFinal (EmitContext ec, Type qualifier_type,
+ protected Expression MemberLookupFinal (ResolveContext ec, Type qualifier_type,
Type queried_type, string name,
MemberTypes mt, BindingFlags bf,
Location loc)
{
Expression e;
- int errors = Report.Errors;
- e = MemberLookup (ec.ContainerType, qualifier_type, queried_type, name, mt, bf, loc);
+ int errors = ec.Report.Errors;
+ e = MemberLookup (ec.Compiler, ec.CurrentType, qualifier_type, queried_type, name, mt, bf, loc);
- if (e != null || errors != Report.Errors)
+ if (e != null || errors != ec.Report.Errors)
return e;
// No errors were reported by MemberLookup, but there was an error.
- return Error_MemberLookupFailed (ec.ContainerType, qualifier_type, queried_type,
+ return Error_MemberLookupFailed (ec, ec.CurrentType, qualifier_type, queried_type,
name, null, mt, bf);
}
- protected virtual Expression Error_MemberLookupFailed (Type container_type, Type qualifier_type,
+ protected virtual Expression Error_MemberLookupFailed (ResolveContext ec, Type container_type, Type qualifier_type,
Type queried_type, string name, string class_name,
MemberTypes mt, BindingFlags bf)
{
name, null);
if (lookup != null) {
- Expression e = Error_MemberLookupFailed (queried_type, lookup);
+ Expression e = Error_MemberLookupFailed (ec, queried_type, lookup);
//
// FIXME: This is still very wrong, it should be done inside
//
if (e == null || (mt & (MemberTypes.Method | MemberTypes.Constructor)) == 0) {
MemberInfo mi = lookup[0];
- Report.SymbolRelatedToPreviousError (mi);
+ ec.Report.SymbolRelatedToPreviousError (mi);
if (qualifier_type != null && container_type != null && qualifier_type != container_type &&
TypeManager.IsNestedFamilyAccessible (container_type, mi.DeclaringType)) {
// Although a derived class can access protected members of
// its base class it cannot do so through an instance of the
// base class (CS1540). If the qualifier_type is a base of the
- // ec.ContainerType and the lookup succeeds with the latter one,
+ // ec.CurrentType and the lookup succeeds with the latter one,
// then we are in this situation.
- Error_CannotAccessProtected (loc, mi, qualifier_type, container_type);
+ Error_CannotAccessProtected (ec, loc, mi, qualifier_type, container_type);
} else {
- ErrorIsInaccesible (loc, TypeManager.GetFullNameSignature (mi));
+ ErrorIsInaccesible (loc, TypeManager.GetFullNameSignature (mi), ec.Report);
}
}
if (lookup == null) {
if (class_name != null) {
- Report.Error (103, loc, "The name `{0}' does not exist in the current context",
+ ec.Report.Error (103, loc, "The name `{0}' does not exist in the current context",
name);
} else {
- Error_TypeDoesNotContainDefinition (queried_type, name);
+ Error_TypeDoesNotContainDefinition (ec, queried_type, name);
}
return null;
}
if ((lookup.Length == 1) && (lookup [0] is Type)) {
Type t = (Type) lookup [0];
- Report.Error (305, loc,
+ ec.Report.Error (305, loc,
"Using the generic type `{0}' " +
"requires {1} type arguments",
TypeManager.CSharpName (t),
}
}
- return Error_MemberLookupFailed (queried_type, lookup);
+ return Error_MemberLookupFailed (ec, queried_type, lookup);
}
- protected virtual Expression Error_MemberLookupFailed (Type type, MemberInfo[] members)
+ protected virtual Expression Error_MemberLookupFailed (ResolveContext ec, Type type, MemberInfo[] members)
{
+ List<MethodSpec> methods = new List<MethodSpec> ();
for (int i = 0; i < members.Length; ++i) {
if (!(members [i] is MethodBase))
return null;
+
+ methods.Add (Import.CreateMethod (members[i] as MethodBase));
}
// By default propagate the closest candidates upwards
- return new MethodGroupExpr (members, type, loc, true);
+ return new MethodGroupExpr (methods.ToArray (), type, loc, true);
}
- protected virtual void Error_NegativeArrayIndex (Location loc)
+ protected virtual void Error_NegativeArrayIndex (ResolveContext ec, Location loc)
{
throw new NotImplementedException ();
}
- protected void Error_PointerInsideExpressionTree ()
+ protected void Error_PointerInsideExpressionTree (ResolveContext ec)
{
- Report.Error (1944, loc, "An expression tree cannot contain an unsafe pointer operation");
+ ec.Report.Error (1944, loc, "An expression tree cannot contain an unsafe pointer operation");
}
/// <summary>
/// Returns an expression that can be used to invoke operator true
/// on the expression if it exists.
/// </summary>
- static public Expression GetOperatorTrue (EmitContext ec, Expression e, Location loc)
+ protected static Expression GetOperatorTrue (ResolveContext ec, Expression e, Location loc)
{
return GetOperatorTrueOrFalse (ec, e, true, loc);
}
/// Returns an expression that can be used to invoke operator false
/// on the expression if it exists.
/// </summary>
- static public Expression GetOperatorFalse (EmitContext ec, Expression e, Location loc)
+ static public Expression GetOperatorFalse (ResolveContext ec, Expression e, Location loc)
{
return GetOperatorTrueOrFalse (ec, e, false, loc);
}
- static Expression GetOperatorTrueOrFalse (EmitContext ec, Expression e, bool is_true, Location loc)
+ static Expression GetOperatorTrueOrFalse (ResolveContext ec, Expression e, bool is_true, Location loc)
{
MethodGroupExpr operator_group;
string mname = Operator.GetMetadataName (is_true ? Operator.OpType.True : Operator.OpType.False);
- operator_group = MethodLookup (ec.ContainerType, e.Type, mname, loc) as MethodGroupExpr;
+ operator_group = MethodLookup (ec.Compiler, ec.CurrentType, e.Type, mname, loc) as MethodGroupExpr;
if (operator_group == null)
return null;
return new UserOperatorCall (operator_group, arguments, null, loc);
}
- /// <summary>
- /// Resolves the expression `e' into a boolean expression: either through
- /// an implicit conversion, or through an `operator true' invocation
- /// </summary>
- public static Expression ResolveBoolean (EmitContext ec, Expression e, Location loc)
- {
- e = e.Resolve (ec);
- if (e == null)
- return null;
-
- if (e.Type == TypeManager.bool_type)
- return e;
-
- Expression converted = Convert.ImplicitConversion (ec, e, TypeManager.bool_type, Location.Null);
-
- if (converted != null)
- return converted;
-
- //
- // If no implicit conversion to bool exists, try using `operator true'
- //
- converted = Expression.GetOperatorTrue (ec, e, loc);
- if (converted == null){
- e.Error_ValueCannotBeConverted (ec, loc, TypeManager.bool_type, false);
- return null;
- }
- return converted;
- }
-
public virtual string ExprClassName
{
get {
switch (eclass){
- case ExprClass.Invalid:
- return "Invalid";
+ case ExprClass.Unresolved:
+ return "Unresolved";
case ExprClass.Value:
return "value";
case ExprClass.Variable:
/// <summary>
/// Reports that we were expecting `expr' to be of class `expected'
/// </summary>
- public void Error_UnexpectedKind (DeclSpace ds, string expected, Location loc)
+ public void Error_UnexpectedKind (Report r, MemberCore mc, string expected, Location loc)
{
- Error_UnexpectedKind (ds, expected, ExprClassName, loc);
+ Error_UnexpectedKind (r, mc, expected, ExprClassName, loc);
}
- public void Error_UnexpectedKind (DeclSpace ds, string expected, string was, Location loc)
+ public void Error_UnexpectedKind (Report r, MemberCore mc, string expected, string was, Location loc)
{
- string name = GetSignatureForError ();
- if (ds != null)
- name = ds.GetSignatureForError () + '.' + name;
+ string name;
+ if (mc != null)
+ name = mc.GetSignatureForError ();
+ else
+ name = GetSignatureForError ();
- Report.Error (118, loc, "`{0}' is a `{1}' but a `{2}' was expected",
+ r.Error (118, loc, "`{0}' is a `{1}' but a `{2}' was expected",
name, was, expected);
}
- public void Error_UnexpectedKind (ResolveFlags flags, Location loc)
+ public void Error_UnexpectedKind (ResolveContext ec, ResolveFlags flags, Location loc)
{
string [] valid = new string [4];
int count = 0;
sb.Append (valid [count - 1]);
}
- Report.Error (119, loc,
+ ec.Report.Error (119, loc,
"Expression denotes a `{0}', where a `{1}' was expected", ExprClassName, sb.ToString ());
}
- public static void UnsafeError (Location loc)
+ public static void UnsafeError (ResolveContext ec, Location loc)
+ {
+ UnsafeError (ec.Report, loc);
+ }
+
+ public static void UnsafeError (Report Report, Location loc)
{
Report.Error (214, loc, "Pointers and fixed size buffers may only be used in an unsafe context");
}
return 0;
}
- protected void Error_CannotCallAbstractBase (string name)
+ protected void Error_CannotCallAbstractBase (ResolveContext ec, string name)
{
- Report.Error (205, loc, "Cannot call an abstract base member `{0}'", name);
+ ec.Report.Error (205, loc, "Cannot call an abstract base member `{0}'", name);
}
- protected void Error_CannotModifyIntermediateExpressionValue (EmitContext ec)
+ protected void Error_CannotModifyIntermediateExpressionValue (ResolveContext ec)
{
- Report.SymbolRelatedToPreviousError (type);
+ ec.Report.SymbolRelatedToPreviousError (type);
if (ec.CurrentInitializerVariable != null) {
- Report.Error (1918, loc, "Members of value type `{0}' cannot be assigned using a property `{1}' object initializer",
+ ec.Report.Error (1918, loc, "Members of value type `{0}' cannot be assigned using a property `{1}' object initializer",
TypeManager.CSharpName (type), GetSignatureForError ());
} else {
- Report.Error (1612, loc, "Cannot modify a value type return value of `{0}'. Consider storing the value in a temporary variable",
+ ec.Report.Error (1612, loc, "Cannot modify a value type return value of `{0}'. Consider storing the value in a temporary variable",
GetSignatureForError ());
}
}
- public void Error_ExpressionCannotBeGeneric (Location loc)
- {
- Report.Error (307, loc, "The {0} `{1}' cannot be used with type arguments",
- ExprClassName, GetSignatureForError ());
- }
-
//
// Converts `source' to an int, uint, long or ulong.
//
- public Expression ConvertExpressionToArrayIndex (EmitContext ec, Expression source)
+ protected Expression ConvertExpressionToArrayIndex (ResolveContext ec, Expression source)
{
+ if (TypeManager.IsDynamicType (source.type)) {
+ Arguments args = new Arguments (1);
+ args.Add (new Argument (source));
+ return new DynamicConversion (TypeManager.int32_type, CSharpBinderFlags.ConvertArrayIndex, args, loc).Resolve (ec);
+ }
+
Expression converted;
- using (ec.With (EmitContext.Flags.CheckState, true)) {
+ using (ec.Set (ResolveContext.Options.CheckedScope)) {
converted = Convert.ImplicitConversion (ec, source, TypeManager.int32_type, source.loc);
if (converted == null)
converted = Convert.ImplicitConversion (ec, source, TypeManager.uint32_type, source.loc);
// Only positive constants are allowed at compile time
//
Constant c = converted as Constant;
- if (c != null) {
- if (c.IsNegative) {
- Error_NegativeArrayIndex (source.loc);
- }
- return c;
- }
+ if (c != null && c.IsNegative)
+ Error_NegativeArrayIndex (ec, source.loc);
+
+ // No conversion needed to array index
+ if (converted.Type == TypeManager.int32_type)
+ return converted;
return new ArrayIndexCast (converted).Resolve (ec);
}
//
// Implementation of expression to expression tree conversion
//
- public abstract Expression CreateExpressionTree (EmitContext ec);
+ public abstract Expression CreateExpressionTree (ResolveContext ec);
- protected Expression CreateExpressionFactoryCall (string name, Arguments args)
+ protected Expression CreateExpressionFactoryCall (ResolveContext ec, string name, Arguments args)
{
- return CreateExpressionFactoryCall (name, null, args, loc);
+ return CreateExpressionFactoryCall (ec, name, null, args, loc);
}
- protected Expression CreateExpressionFactoryCall (string name, TypeArguments typeArguments, Arguments args)
+ protected Expression CreateExpressionFactoryCall (ResolveContext ec, string name, TypeArguments typeArguments, Arguments args)
{
- return CreateExpressionFactoryCall (name, typeArguments, args, loc);
+ return CreateExpressionFactoryCall (ec, name, typeArguments, args, loc);
}
- public static Expression CreateExpressionFactoryCall (string name, TypeArguments typeArguments, Arguments args, Location loc)
+ public static Expression CreateExpressionFactoryCall (ResolveContext ec, string name, TypeArguments typeArguments, Arguments args, Location loc)
{
- return new Invocation (new MemberAccess (CreateExpressionTypeExpression (loc), name, typeArguments, loc), args);
+ return new Invocation (new MemberAccess (CreateExpressionTypeExpression (ec, loc), name, typeArguments, loc), args);
}
- protected static TypeExpr CreateExpressionTypeExpression (Location loc)
+ protected static TypeExpr CreateExpressionTypeExpression (ResolveContext ec, Location loc)
{
TypeExpr texpr = TypeManager.expression_type_expr;
if (texpr == null) {
- Type t = TypeManager.CoreLookupType ("System.Linq.Expressions", "Expression", Kind.Class, true);
+ Type t = TypeManager.CoreLookupType (ec.Compiler, "System.Linq.Expressions", "Expression", MemberKind.Class, true);
if (t == null)
return null;
return texpr;
}
+ //
+ // Implemented by all expressions which support conversion from
+ // compiler expression to invokable runtime expression. Used by
+ // dynamic C# binder.
+ //
+ public virtual SLE.Expression MakeExpression (BuilderContext ctx)
+ {
+ throw new NotImplementedException ("MakeExpression for " + GetType ());
+ }
+
public virtual void MutateHoistedGenericType (AnonymousMethodStorey storey)
{
// TODO: It should probably be type = storey.MutateType (type);
/// </summary>
public abstract class ExpressionStatement : Expression {
- public virtual ExpressionStatement ResolveStatement (EmitContext ec)
+ public virtual ExpressionStatement ResolveStatement (BlockContext ec)
{
Expression e = Resolve (ec);
if (e == null)
ExpressionStatement es = e as ExpressionStatement;
if (es == null)
- Error_InvalidExpressionStatement ();
+ Error_InvalidExpressionStatement (ec);
return es;
}
this.child = child;
}
- public override Expression CreateExpressionTree (EmitContext ec)
+ public override Expression CreateExpressionTree (ResolveContext ec)
{
Arguments args = new Arguments (2);
args.Add (new Argument (child.CreateExpressionTree (ec)));
args.Add (new Argument (new TypeOf (new TypeExpression (type, loc), loc)));
if (type.IsPointer || child.Type.IsPointer)
- Error_PointerInsideExpressionTree ();
+ Error_PointerInsideExpressionTree (ec);
- return CreateExpressionFactoryCall (ec.CheckState ? "ConvertChecked" : "Convert", args);
+ return CreateExpressionFactoryCall (ec, ec.HasSet (ResolveContext.Options.CheckedScope) ? "ConvertChecked" : "Convert", args);
}
- public override Expression DoResolve (EmitContext ec)
+ protected override Expression DoResolve (ResolveContext ec)
{
// This should never be invoked, we are born in fully
// initialized state.
child.Emit (ec);
}
- public override bool GetAttributableValue (EmitContext ec, Type value_type, out object value)
+ public override bool GetAttributableValue (ResolveContext ec, Type value_type, out object value)
{
return child.GetAttributableValue (ec, value_type, out value);
}
+ public override SLE.Expression MakeExpression (BuilderContext ctx)
+ {
+ return ctx.HasSet (BuilderContext.Options.CheckedScope) ?
+ SLE.Expression.ConvertChecked (child.MakeExpression (ctx), type) :
+ SLE.Expression.Convert (child.MakeExpression (ctx), type);
+ }
+
public override void MutateHoistedGenericType (AnonymousMethodStorey storey)
{
type = storey.MutateType (type);
/// </summary>
public class CastFromDecimal : TypeCast
{
- static IDictionary operators;
+ static Dictionary<Type, MethodInfo> operators;
public CastFromDecimal (Expression child, Type return_type)
: base (child, return_type)
public Expression Resolve ()
{
if (operators == null) {
- MemberInfo[] all_oper = TypeManager.MemberLookup (TypeManager.decimal_type,
- TypeManager.decimal_type, TypeManager.decimal_type, MemberTypes.Method,
- BindingFlags.Static | BindingFlags.Public, "op_Explicit", null);
+ MemberInfo[] all_oper = TypeManager.MemberLookup (TypeManager.decimal_type,
+ TypeManager.decimal_type, TypeManager.decimal_type, MemberTypes.Method,
+ BindingFlags.Static | BindingFlags.Public, "op_Explicit", null);
- operators = new System.Collections.Specialized.HybridDictionary ();
+ operators = new Dictionary<Type, MethodInfo> (ReferenceEquality<Type>.Default);
foreach (MethodInfo oper in all_oper) {
AParametersCollection pd = TypeManager.GetParameterData (oper);
if (pd.Types [0] == TypeManager.decimal_type)
}
}
- return operators.Contains (type) ? this : null;
+ return operators.ContainsKey (type) ? this : null;
}
public override void Emit (EmitContext ec)
ILGenerator ig = ec.ig;
child.Emit (ec);
- ig.Emit (OpCodes.Call, (MethodInfo)operators [type]);
+ ig.Emit (OpCodes.Call, operators [type]);
}
}
//
public class EmptyConstantCast : Constant
{
- public readonly Constant child;
+ public Constant child;
- public EmptyConstantCast(Constant child, Type type)
+ public EmptyConstantCast (Constant child, Type type)
: base (child.Location)
{
- eclass = child.eclass;
+ if (child == null)
+ throw new ArgumentNullException ("child");
+
this.child = child;
+ this.eclass = child.eclass;
this.type = type;
}
public override Constant ConvertExplicitly (bool in_checked_context, Type target_type)
{
+ if (child.Type == target_type)
+ return child;
+
// FIXME: check that 'type' can be converted to 'target_type' first
return child.ConvertExplicitly (in_checked_context, target_type);
}
- public override Expression CreateExpressionTree (EmitContext ec)
+ public override Expression CreateExpressionTree (ResolveContext ec)
{
Arguments args = Arguments.CreateForExpressionTree (ec, null,
child.CreateExpressionTree (ec),
new TypeOf (new TypeExpression (type, loc), loc));
if (type.IsPointer)
- Error_PointerInsideExpressionTree ();
-
- return CreateExpressionFactoryCall ("Convert", args);
- }
+ Error_PointerInsideExpressionTree (ec);
- public override Constant Increment ()
- {
- return child.Increment ();
+ return CreateExpressionFactoryCall (ec, "Convert", args);
}
public override bool IsDefaultValue {
public override bool IsNull {
get { return child.IsNull; }
}
+
+ public override bool IsOneInteger {
+ get { return child.IsOneInteger; }
+ }
public override bool IsZeroInteger {
get { return child.IsZeroInteger; }
}
+
+ protected override Expression DoResolve (ResolveContext rc)
+ {
+ return this;
+ }
public override void Emit (EmitContext ec)
{
{
child.EmitBranchable (ec, label, on_true);
-#if GMCS_SOURCE
// Only to make verifier happy
if (TypeManager.IsGenericParameter (type) && child.IsNull)
ec.ig.Emit (OpCodes.Unbox_Any, type);
-#endif
}
public override void EmitSideEffect (EmitContext ec)
child.EmitSideEffect (ec);
}
- public override Constant ConvertImplicitly (Type target_type)
+ public override Constant ConvertImplicitly (ResolveContext rc, Type target_type)
{
// FIXME: Do we need to check user conversions?
if (!Convert.ImplicitStandardConversionExists (this, target_type))
return null;
- return child.ConvertImplicitly (target_type);
+ return child.ConvertImplicitly (rc, target_type);
}
public override void MutateHoistedGenericType (AnonymousMethodStorey storey)
}
}
-
/// <summary>
/// This class is used to wrap literals which belong inside Enums
/// </summary>
- public class EnumConstant : Constant {
+ public class EnumConstant : Constant
+ {
public Constant Child;
- public EnumConstant (Constant child, Type enum_type):
- base (child.Location)
+ public EnumConstant (Constant child, Type enum_type)
+ : base (child.Location)
{
- eclass = child.eclass;
this.Child = child;
- type = enum_type;
+ this.type = enum_type;
}
-
- public override Expression DoResolve (EmitContext ec)
+
+ protected EnumConstant (Location loc)
+ : base (loc)
{
- // This should never be invoked, we are born in fully
- // initialized state.
+ }
+ protected override Expression DoResolve (ResolveContext rc)
+ {
+ Child = Child.Resolve (rc);
+ this.eclass = ExprClass.Value;
return this;
}
Child.EmitSideEffect (ec);
}
- public override bool GetAttributableValue (EmitContext ec, Type value_type, out object value)
+ public override bool GetAttributableValue (ResolveContext ec, Type value_type, out object value)
{
value = GetTypedValue ();
return true;
//
// This works only sometimes
//
- if (type.Module == RootContext.ToplevelTypes.Builder)
+ if (TypeManager.IsBeingCompiled (type))
return Child.GetValue ();
#endif
return Child.AsString ();
}
- public override Constant Increment()
+ public EnumConstant Increment()
{
- return new EnumConstant (Child.Increment (), type);
+ return new EnumConstant (((IntegralConstant) Child).Increment (), type);
}
public override bool IsDefaultValue {
return Child.ConvertExplicitly (in_checked_context, target_type);
}
- public override Constant ConvertImplicitly (Type type)
+ public override Constant ConvertImplicitly (ResolveContext rc, Type type)
{
Type this_type = TypeManager.DropGenericTypeArguments (Type);
type = TypeManager.DropGenericTypeArguments (type);
Type child_type = TypeManager.DropGenericTypeArguments (Child.Type);
if (type.UnderlyingSystemType != child_type)
- Child = Child.ConvertImplicitly (type.UnderlyingSystemType);
+ Child = Child.ConvertImplicitly (rc, type.UnderlyingSystemType);
return this;
}
return null;
}
- return Child.ConvertImplicitly(type);
+ return Child.ConvertImplicitly (rc, type);
}
-
}
/// <summary>
eclass = ExprClass.Value;
}
- public override Expression DoResolve (EmitContext ec)
+ protected override Expression DoResolve (ResolveContext ec)
{
// This should never be invoked, we are born in fully
// initialized state.
{
}
- public override Expression DoResolve (EmitContext ec)
+ protected override Expression DoResolve (ResolveContext ec)
{
// This should never be invoked, we are born in fully
// initialized state.
return this;
}
- public override Expression DoResolveLValue (EmitContext ec, Expression right_side)
+ public override Expression DoResolveLValue (ResolveContext ec, Expression right_side)
{
if (right_side == EmptyExpression.LValueMemberAccess || right_side == EmptyExpression.LValueMemberOutAccess)
- Report.Error (445, loc, "Cannot modify the result of an unboxing conversion");
+ ec.Report.Error (445, loc, "Cannot modify the result of an unboxing conversion");
return base.DoResolveLValue (ec, right_side);
}
base.Emit (ec);
ILGenerator ig = ec.ig;
-
-#if GMCS_SOURCE
ig.Emit (OpCodes.Unbox_Any, type);
-#else
- ig.Emit (OpCodes.Unbox, type);
- LoadFromPtr (ig, type);
-#endif
}
public override void MutateHoistedGenericType (AnonymousMethodStorey storey)
U2_I1, U2_U1, U2_I2, U2_CH,
I4_I1, I4_U1, I4_I2, I4_U2, I4_U4, I4_U8, I4_CH,
U4_I1, U4_U1, U4_I2, U4_U2, U4_I4, U4_CH,
- I8_I1, I8_U1, I8_I2, I8_U2, I8_I4, I8_U4, I8_U8, I8_CH,
- U8_I1, U8_U1, U8_I2, U8_U2, U8_I4, U8_U4, U8_I8, U8_CH,
+ I8_I1, I8_U1, I8_I2, I8_U2, I8_I4, I8_U4, I8_U8, I8_CH, I8_I,
+ U8_I1, U8_U1, U8_I2, U8_U2, U8_I4, U8_U4, U8_I8, U8_CH, U8_I,
CH_I1, CH_U1, CH_I2,
R4_I1, R4_U1, R4_I2, R4_U2, R4_I4, R4_U4, R4_I8, R4_U8, R4_CH,
- R8_I1, R8_U1, R8_I2, R8_U2, R8_I4, R8_U4, R8_I8, R8_U8, R8_CH, R8_R4
+ R8_I1, R8_U1, R8_I2, R8_U2, R8_I4, R8_U4, R8_I8, R8_U8, R8_CH, R8_R4,
+ I_I8,
}
Mode mode;
mode = m;
}
- public override Expression DoResolve (EmitContext ec)
+ protected override Expression DoResolve (ResolveContext ec)
{
// This should never be invoked, we are born in fully
// initialized state.
base.Emit (ec);
- if (ec.CheckState){
+ if (ec.HasSet (EmitContext.Options.CheckedScope)) {
switch (mode){
case Mode.I1_U1: ig.Emit (OpCodes.Conv_Ovf_U1); break;
case Mode.I1_U2: ig.Emit (OpCodes.Conv_Ovf_U2); break;
case Mode.I8_U4: ig.Emit (OpCodes.Conv_Ovf_U4); break;
case Mode.I8_U8: ig.Emit (OpCodes.Conv_Ovf_U8); break;
case Mode.I8_CH: ig.Emit (OpCodes.Conv_Ovf_U2); break;
+ case Mode.I8_I: ig.Emit (OpCodes.Conv_Ovf_U); break;
case Mode.U8_I1: ig.Emit (OpCodes.Conv_Ovf_I1_Un); break;
case Mode.U8_U1: ig.Emit (OpCodes.Conv_Ovf_U1_Un); break;
case Mode.U8_U4: ig.Emit (OpCodes.Conv_Ovf_U4_Un); break;
case Mode.U8_I8: ig.Emit (OpCodes.Conv_Ovf_I8_Un); break;
case Mode.U8_CH: ig.Emit (OpCodes.Conv_Ovf_U2_Un); break;
+ case Mode.U8_I: ig.Emit (OpCodes.Conv_Ovf_U_Un); break;
case Mode.CH_I1: ig.Emit (OpCodes.Conv_Ovf_I1_Un); break;
case Mode.CH_U1: ig.Emit (OpCodes.Conv_Ovf_U1_Un); break;
case Mode.R8_U8: ig.Emit (OpCodes.Conv_Ovf_U8); break;
case Mode.R8_CH: ig.Emit (OpCodes.Conv_Ovf_U2); break;
case Mode.R8_R4: ig.Emit (OpCodes.Conv_R4); break;
+
+ case Mode.I_I8: ig.Emit (OpCodes.Conv_Ovf_I8_Un); break;
}
} else {
switch (mode){
case Mode.I8_U4: ig.Emit (OpCodes.Conv_U4); break;
case Mode.I8_U8: /* nothing */ break;
case Mode.I8_CH: ig.Emit (OpCodes.Conv_U2); break;
+ case Mode.I8_I: ig.Emit (OpCodes.Conv_U); break;
case Mode.U8_I1: ig.Emit (OpCodes.Conv_I1); break;
case Mode.U8_U1: ig.Emit (OpCodes.Conv_U1); break;
case Mode.U8_U4: ig.Emit (OpCodes.Conv_U4); break;
case Mode.U8_I8: /* nothing */ break;
case Mode.U8_CH: ig.Emit (OpCodes.Conv_U2); break;
+ case Mode.U8_I: ig.Emit (OpCodes.Conv_U); break;
case Mode.CH_I1: ig.Emit (OpCodes.Conv_I1); break;
case Mode.CH_U1: ig.Emit (OpCodes.Conv_U1); break;
case Mode.R8_U8: ig.Emit (OpCodes.Conv_U8); break;
case Mode.R8_CH: ig.Emit (OpCodes.Conv_U2); break;
case Mode.R8_R4: ig.Emit (OpCodes.Conv_R4); break;
+
+ case Mode.I_I8: ig.Emit (OpCodes.Conv_U8); break;
}
}
}
this.op = op;
}
- public override Expression DoResolve (EmitContext ec)
+ protected override Expression DoResolve (ResolveContext ec)
{
// This should never be invoked, we are born in fully
// initialized state.
{
base.Emit (ec);
-#if GMCS_SOURCE
bool gen = TypeManager.IsGenericParameter (child.Type);
if (gen)
ec.ig.Emit (OpCodes.Box, child.Type);
if (gen && !forced)
return;
-#endif
ec.ig.Emit (OpCodes.Castclass, type);
}
this.orig_expr = orig_expr;
}
- public override Constant ConvertImplicitly (Type target_type)
+ public override Constant ConvertImplicitly (ResolveContext rc, Type target_type)
{
- Constant c = base.ConvertImplicitly (target_type);
+ Constant c = base.ConvertImplicitly (rc, target_type);
if (c != null)
c = new ReducedConstantExpression (c, orig_expr);
+
return c;
}
- public override Expression CreateExpressionTree (EmitContext ec)
+ public override Expression CreateExpressionTree (ResolveContext ec)
{
return orig_expr.CreateExpressionTree (ec);
}
- public override bool GetAttributableValue (EmitContext ec, Type value_type, out object value)
+ public override bool GetAttributableValue (ResolveContext ec, Type value_type, out object value)
{
//
// Even if resolved result is a constant original expression was not
// and attribute accepts constants only
//
- Attribute.Error_AttributeArgumentNotValid (orig_expr.Location);
+ Attribute.Error_AttributeArgumentNotValid (ec, orig_expr.Location);
value = null;
return false;
}
this.loc = orig.Location;
}
- public override Expression CreateExpressionTree (EmitContext ec)
+ public override Expression CreateExpressionTree (ResolveContext ec)
{
return orig_expr.CreateExpressionTree (ec);
}
- public override Expression DoResolve (EmitContext ec)
+ protected override Expression DoResolve (ResolveContext ec)
{
eclass = stm.eclass;
type = stm.Type;
private ReducedExpression (Expression expr, Expression orig_expr)
{
this.expr = expr;
+ this.eclass = expr.eclass;
+ this.type = expr.Type;
this.orig_expr = orig_expr;
this.loc = orig_expr.Location;
}
+ //
+ // Creates fully resolved expression switcher
+ //
public static Constant Create (Constant expr, Expression original_expr)
{
+ if (expr.eclass == ExprClass.Unresolved)
+ throw new ArgumentException ("Unresolved expression");
+
return new ReducedConstantExpression (expr, original_expr);
}
return new ReducedExpressionStatement (s, orig);
}
+ //
+ // Creates unresolved reduce expression. The original expression has to be
+ // already resolved
+ //
public static Expression Create (Expression expr, Expression original_expr)
{
Constant c = expr as Constant;
if (s != null)
return Create (s, original_expr);
+ if (expr.eclass == ExprClass.Unresolved)
+ throw new ArgumentException ("Unresolved expression");
+
return new ReducedExpression (expr, original_expr);
}
- public override Expression CreateExpressionTree (EmitContext ec)
+ public override Expression CreateExpressionTree (ResolveContext ec)
{
return orig_expr.CreateExpressionTree (ec);
}
- public override Expression DoResolve (EmitContext ec)
+ protected override Expression DoResolve (ResolveContext ec)
{
- eclass = expr.eclass;
- type = expr.Type;
return this;
}
expr.EmitBranchable (ec, target, on_true);
}
+ public override SLE.Expression MakeExpression (BuilderContext ctx)
+ {
+ return orig_expr.MakeExpression (ctx);
+ }
+
public override void MutateHoistedGenericType (AnonymousMethodStorey storey)
{
expr.MutateHoistedGenericType (storey);
}
}
+ //
+ // Standard composite pattern
+ //
+ public abstract class CompositeExpression : Expression
+ {
+ Expression expr;
+
+ protected CompositeExpression (Expression expr)
+ {
+ this.expr = expr;
+ this.loc = expr.Location;
+ }
+
+ public override Expression CreateExpressionTree (ResolveContext ec)
+ {
+ return expr.CreateExpressionTree (ec);
+ }
+
+ public Expression Child {
+ get { return expr; }
+ }
+
+ protected override Expression DoResolve (ResolveContext ec)
+ {
+ expr = expr.Resolve (ec);
+ if (expr != null) {
+ type = expr.Type;
+ eclass = expr.eclass;
+ }
+
+ return this;
+ }
+
+ public override void Emit (EmitContext ec)
+ {
+ expr.Emit (ec);
+ }
+
+ public override bool IsNull {
+ get { return expr.IsNull; }
+ }
+ }
+
+ //
+ // Base of expressions used only to narrow resolve flow
+ //
+ public abstract class ShimExpression : Expression
+ {
+ protected Expression expr;
+
+ protected ShimExpression (Expression expr)
+ {
+ this.expr = expr;
+ }
+
+ protected override void CloneTo (CloneContext clonectx, Expression t)
+ {
+ if (expr == null)
+ return;
+
+ ShimExpression target = (ShimExpression) t;
+ target.expr = expr.Clone (clonectx);
+ }
+
+ public override Expression CreateExpressionTree (ResolveContext ec)
+ {
+ throw new NotSupportedException ("ET");
+ }
+
+ public override void Emit (EmitContext ec)
+ {
+ throw new InternalErrorException ("Missing Resolve call");
+ }
+
+ public Expression Expr {
+ get { return expr; }
+ }
+
+ public override void MutateHoistedGenericType (AnonymousMethodStorey storey)
+ {
+ throw new InternalErrorException ("Missing Resolve call");
+ }
+ }
+
//
// Unresolved type name expressions
//
public abstract class ATypeNameExpression : FullNamedExpression
{
- public readonly string Name;
+ string name;
protected TypeArguments targs;
protected ATypeNameExpression (string name, Location l)
{
- Name = name;
+ this.name = name;
loc = l;
}
protected ATypeNameExpression (string name, TypeArguments targs, Location l)
{
- Name = name;
+ this.name = name;
this.targs = targs;
loc = l;
}
return Name;
}
+
+ public string Name {
+ get {
+ return name;
+ }
+ set {
+ name = value;
+ }
+ }
+
+ public TypeArguments TypeArguments {
+ get {
+ return targs;
+ }
+ }
}
/// <summary>
/// SimpleName expressions are formed of a single word and only happen at the beginning
/// of a dotted-name.
/// </summary>
- public class SimpleName : ATypeNameExpression {
- bool in_transit;
-
+ public class SimpleName : ATypeNameExpression
+ {
public SimpleName (string name, Location l)
: base (name, l)
{
return new SimpleName (RemoveGenericArity (Name), targs, loc);
}
- public static void Error_ObjectRefRequired (EmitContext ec, Location l, string name)
+ public static void Error_ObjectRefRequired (ResolveContext ec, Location l, string name)
{
- if (ec.IsInFieldInitializer)
- Report.Error (236, l,
+ if (ec.HasSet (ResolveContext.Options.FieldInitializerScope))
+ ec.Report.Error (236, l,
"A field initializer cannot reference the nonstatic field, method, or property `{0}'",
name);
else
- Report.Error (120, l,
+ ec.Report.Error (120, l,
"An object reference is required to access non-static member `{0}'",
name);
}
- public bool IdenticalNameAndTypeName (EmitContext ec, Expression resolved_to, Location loc)
+ public bool IdenticalNameAndTypeName (IMemberContext mc, Expression resolved_to, Location loc)
{
return resolved_to != null && resolved_to.Type != null &&
resolved_to.Type.Name == Name &&
- (ec.DeclContainer.LookupNamespaceOrType (Name, loc, /* ignore_cs0104 = */ true) != null);
+ (mc.LookupNamespaceOrType (Name, loc, /* ignore_cs0104 = */ true) != null);
}
- public override Expression DoResolve (EmitContext ec)
+ protected override Expression DoResolve (ResolveContext ec)
{
return SimpleNameResolve (ec, null, false);
}
- public override Expression DoResolveLValue (EmitContext ec, Expression right_side)
+ public override Expression DoResolveLValue (ResolveContext ec, Expression right_side)
{
return SimpleNameResolve (ec, right_side, false);
}
-
- public Expression DoResolve (EmitContext ec, bool intermediate)
+ public Expression DoResolve (ResolveContext ec, bool intermediate)
{
return SimpleNameResolve (ec, null, intermediate);
}
return false;
}
- FullNamedExpression ResolveNested (IResolveContext ec, Type t)
+ FullNamedExpression ResolveNested (Type t)
{
if (!TypeManager.IsGenericTypeDefinition (t) && !TypeManager.IsGenericType (t))
return null;
- DeclSpace ds = ec.DeclContainer;
- while (ds != null && !IsNestedChild (t, ds.TypeBuilder))
- ds = ds.Parent;
+ Type ds = t;
+ while (ds != null && !IsNestedChild (t, ds))
+ ds = ds.DeclaringType;
if (ds == null)
return null;
int arg_count = targs != null ? targs.Count : 0;
- for (; (ds != null) && ds.IsGeneric; ds = ds.Parent) {
- if (arg_count + ds.CountTypeParameters == gen_params.Length) {
+ for (; (ds != null) && TypeManager.IsGenericType (ds); ds = ds.DeclaringType) {
+ Type[] gargs = TypeManager.GetTypeArguments (ds);
+ if (arg_count + gargs.Length == gen_params.Length) {
TypeArguments new_args = new TypeArguments ();
- foreach (TypeParameter param in ds.TypeParameters)
- new_args.Add (new TypeParameterExpr (param, loc));
+ foreach (Type param in gargs)
+ new_args.Add (new TypeExpression (param, loc));
if (targs != null)
new_args.Add (targs);
return null;
}
- public override FullNamedExpression ResolveAsTypeStep (IResolveContext ec, bool silent)
+ public override FullNamedExpression ResolveAsTypeStep (IMemberContext ec, bool silent)
{
- FullNamedExpression fne = ec.GenericDeclContainer.LookupGeneric (Name, loc);
- if (fne != null)
- return fne.ResolveAsTypeStep (ec, silent);
-
- int errors = Report.Errors;
- fne = ec.DeclContainer.LookupNamespaceOrType (Name, loc, /*ignore_cs0104=*/ false);
+ int errors = ec.Compiler.Report.Errors;
+ FullNamedExpression fne = ec.LookupNamespaceOrType (Name, loc, /*ignore_cs0104=*/ false);
if (fne != null) {
if (fne.Type == null)
return fne;
- FullNamedExpression nested = ResolveNested (ec, fne.Type);
+ FullNamedExpression nested = ResolveNested (fne.Type);
if (nested != null)
return nested.ResolveAsTypeStep (ec, false);
if (targs != null) {
- GenericTypeExpr ct = new GenericTypeExpr (fne.Type, targs, loc);
- return ct.ResolveAsTypeStep (ec, false);
+ if (TypeManager.IsGenericType (fne.Type)) {
+ GenericTypeExpr ct = new GenericTypeExpr (fne.Type, targs, loc);
+ return ct.ResolveAsTypeStep (ec, false);
+ }
+
+ fne.Error_TypeArgumentsCannotBeUsed (ec.Compiler.Report, loc);
}
return fne;
}
- if (silent || errors != Report.Errors)
+ if (!HasTypeArguments && Name == "dynamic" &&
+ RootContext.Version > LanguageVersion.V_3 &&
+ RootContext.MetadataCompatibilityVersion > MetadataVersion.v2) {
+
+ if (!PredefinedAttributes.Get.Dynamic.IsDefined) {
+ ec.Compiler.Report.Error (1980, Location,
+ "Dynamic keyword requires `{0}' to be defined. Are you missing System.Core.dll assembly reference?",
+ PredefinedAttributes.Get.Dynamic.GetSignatureForError ());
+ }
+
+ return new DynamicTypeExpr (loc);
+ }
+
+ if (silent || errors != ec.Compiler.Report.Errors)
return null;
Error_TypeOrNamespaceNotFound (ec);
return null;
}
- protected virtual void Error_TypeOrNamespaceNotFound (IResolveContext ec)
+ protected virtual void Error_TypeOrNamespaceNotFound (IMemberContext ec)
{
- MemberCore mc = ec.DeclContainer.GetDefinition (Name);
- if (mc != null) {
- Error_UnexpectedKind (ec.DeclContainer, "type", GetMemberType (mc), loc);
- return;
- }
+ if (ec.CurrentType != null) {
+ if (ec.CurrentTypeDefinition != null) {
+ MemberCore mc = ec.CurrentTypeDefinition.GetDefinition (Name);
+ if (mc != null) {
+ Error_UnexpectedKind (ec.Compiler.Report, mc, "type", GetMemberType (mc), loc);
+ return;
+ }
+ }
- string ns = ec.DeclContainer.NamespaceEntry.NS.Name;
- string fullname = (ns.Length > 0) ? ns + "." + Name : Name;
- foreach (Assembly a in GlobalRootNamespace.Instance.Assemblies) {
- Type type = a.GetType (fullname);
- if (type != null) {
- Report.SymbolRelatedToPreviousError (type);
- Expression.ErrorIsInaccesible (loc, TypeManager.CSharpName (type));
- return;
+ string ns = ec.CurrentType.Namespace;
+ string fullname = (ns.Length > 0) ? ns + "." + Name : Name;
+ foreach (Assembly a in GlobalRootNamespace.Instance.Assemblies) {
+ Type type = a.GetType (fullname);
+ if (type != null) {
+ ec.Compiler.Report.SymbolRelatedToPreviousError (type);
+ Expression.ErrorIsInaccesible (loc, TypeManager.CSharpName (type), ec.Compiler.Report);
+ return;
+ }
}
- }
- Type t = ec.DeclContainer.LookupAnyGeneric (Name);
- if (t != null) {
- Namespace.Error_InvalidNumberOfTypeArguments (t, loc);
- return;
+ if (ec.CurrentTypeDefinition != null) {
+ Type t = ec.CurrentTypeDefinition.LookupAnyGeneric (Name);
+ if (t != null) {
+ Namespace.Error_InvalidNumberOfTypeArguments (ec.Compiler.Report, t, loc);
+ return;
+ }
+ }
}
if (targs != null) {
- FullNamedExpression retval = ec.DeclContainer.LookupNamespaceOrType (SimpleName.RemoveGenericArity (Name), loc, true);
+ FullNamedExpression retval = ec.LookupNamespaceOrType (SimpleName.RemoveGenericArity (Name), loc, true);
if (retval != null) {
- Namespace.Error_TypeArgumentsCannotBeUsed (retval, loc);
+ retval.Error_TypeArgumentsCannotBeUsed (ec.Compiler.Report, loc);
return;
}
}
- NamespaceEntry.Error_NamespaceNotFound (loc, Name);
+ NamespaceEntry.Error_NamespaceNotFound (loc, Name, ec.Compiler.Report);
}
// TODO: I am still not convinced about this. If someone else will need it
return "type";
}
- Expression SimpleNameResolve (EmitContext ec, Expression right_side, bool intermediate)
+ Expression SimpleNameResolve (ResolveContext ec, Expression right_side, bool intermediate)
{
- if (in_transit)
- return null;
-
- in_transit = true;
Expression e = DoSimpleNameResolve (ec, right_side, intermediate);
- in_transit = false;
if (e == null)
return null;
/// Type is both an instance variable and a Type; Type.GetType
/// is the static method not an instance method of type.
/// </remarks>
- Expression DoSimpleNameResolve (EmitContext ec, Expression right_side, bool intermediate)
+ Expression DoSimpleNameResolve (ResolveContext ec, Expression right_side, bool intermediate)
{
Expression e = null;
if (current_block != null){
LocalInfo vi = current_block.GetLocalInfo (Name);
if (vi != null){
- LocalVariableReference var = new LocalVariableReference (ec.CurrentBlock, Name, loc);
+ e = new LocalVariableReference (ec.CurrentBlock, Name, loc);
+
if (right_side != null) {
- return var.ResolveLValue (ec, right_side);
+ e = e.ResolveLValue (ec, right_side);
} else {
- ResolveFlags rf = ResolveFlags.VariableOrValue;
- if (intermediate)
- rf |= ResolveFlags.DisableFlowAnalysis;
- return var.Resolve (ec, rf);
+ if (intermediate) {
+ using (ec.With (ResolveContext.Options.DoFlowAnalysis, false)) {
+ e = e.Resolve (ec, ResolveFlags.VariableOrValue);
+ }
+ } else {
+ e = e.Resolve (ec, ResolveFlags.VariableOrValue);
+ }
}
+
+ if (targs != null && e != null)
+ e.Error_TypeArgumentsCannotBeUsed (ec.Report, loc);
+
+ return e;
}
- Expression expr = current_block.Toplevel.GetParameterReference (Name, loc);
- if (expr != null) {
+ e = current_block.Toplevel.GetParameterReference (Name, loc);
+ if (e != null) {
if (right_side != null)
- return expr.ResolveLValue (ec, right_side);
+ e = e.ResolveLValue (ec, right_side);
+ else
+ e = e.Resolve (ec);
- return expr.Resolve (ec);
+ if (targs != null && e != null)
+ e.Error_TypeArgumentsCannotBeUsed (ec.Report, loc);
+
+ return e;
}
}
//
Type almost_matched_type = null;
- ArrayList almost_matched = null;
- for (DeclSpace lookup_ds = ec.DeclContainer; lookup_ds != null; lookup_ds = lookup_ds.Parent) {
- // either RootDeclSpace or GenericMethod
- if (lookup_ds.TypeBuilder == null)
- continue;
-
- e = MemberLookup (ec.ContainerType, lookup_ds.TypeBuilder, Name, loc);
+ IList<MemberInfo> almost_matched = null;
+ for (Type lookup_ds = ec.CurrentType; lookup_ds != null; lookup_ds = lookup_ds.DeclaringType) {
+ e = MemberLookup (ec.Compiler, ec.CurrentType, lookup_ds, Name, loc);
if (e != null) {
PropertyExpr pe = e as PropertyExpr;
if (pe != null) {
// since TypeManager.MemberLookup doesn't know if we're doing a lvalue access or not,
// it doesn't know which accessor to check permissions against
- if (param.IsEmpty && pe.IsAccessibleFrom (ec.ContainerType, right_side != null))
+ if (param.IsEmpty && pe.IsAccessibleFrom (ec.CurrentType, right_side != null))
break;
} else if (e is EventExpr) {
- if (((EventExpr) e).IsAccessibleFrom (ec.ContainerType))
+ if (((EventExpr) e).IsAccessibleFrom (ec.CurrentType))
break;
} else if (targs != null && e is TypeExpression) {
e = new GenericTypeExpr (e.Type, targs, loc).ResolveAsTypeStep (ec, false);
}
if (almost_matched == null && almost_matched_members.Count > 0) {
- almost_matched_type = lookup_ds.TypeBuilder;
- almost_matched = (ArrayList) almost_matched_members.Clone ();
+ almost_matched_type = lookup_ds;
+ almost_matched = new List<MemberInfo>(almost_matched_members);
}
}
if (e == null) {
if (almost_matched == null && almost_matched_members.Count > 0) {
- almost_matched_type = ec.ContainerType;
- almost_matched = (ArrayList) almost_matched_members.Clone ();
+ almost_matched_type = ec.CurrentType;
+ almost_matched = new List<MemberInfo> (almost_matched_members);
}
e = ResolveAsTypeStep (ec, true);
}
if (li != null)
li.Used = true;
- Error_VariableIsUsedBeforeItIsDeclared (Name);
+ Error_VariableIsUsedBeforeItIsDeclared (ec.Report, Name);
return null;
}
}
if (RootContext.EvalMode){
FieldInfo fi = Evaluator.LookupField (Name);
if (fi != null)
- return new FieldExpr (fi, loc).Resolve (ec);
+ return new FieldExpr (Import.CreateField (fi), loc).Resolve (ec);
}
if (almost_matched != null)
almost_matched_members = almost_matched;
if (almost_matched_type == null)
- almost_matched_type = ec.ContainerType;
- return Error_MemberLookupFailed (ec.ContainerType, null, almost_matched_type, Name,
- ec.DeclContainer.Name, AllMemberTypes, AllBindingFlags);
+ almost_matched_type = ec.CurrentType;
+
+ string type_name = ec.MemberContext.CurrentType == null ? null : ec.MemberContext.CurrentType.Name;
+ return Error_MemberLookupFailed (ec, ec.CurrentType, null, almost_matched_type, Name,
+ type_name, AllMemberTypes, AllBindingFlags);
}
if (e is MemberExpr) {
Expression left;
if (me.IsInstance) {
- if (ec.IsStatic || ec.IsInFieldInitializer) {
+ if (ec.IsStatic || ec.HasAny (ResolveContext.Options.FieldInitializerScope | ResolveContext.Options.BaseInitializer | ResolveContext.Options.ConstantScope)) {
//
// Note that an MemberExpr can be both IsInstance and IsStatic.
// An unresolved MethodGroupExpr can contain both kinds of methods
left = ec.GetThis (loc);
}
} else {
- left = new TypeExpression (ec.ContainerType, loc);
+ left = new TypeExpression (ec.CurrentType, loc);
}
me = me.ResolveMemberAccess (ec, left, loc, null);
if (!targs.Resolve (ec))
return null;
- me.SetTypeArguments (targs);
+ me.SetTypeArguments (ec, targs);
}
if (!me.IsStatic && (me.InstanceExpression != null && me.InstanceExpression != EmptyExpression.Null) &&
me.InstanceExpression.Type != me.DeclaringType &&
!TypeManager.IsFamilyAccessible (me.InstanceExpression.Type, me.DeclaringType) &&
(!intermediate || !IdenticalNameAndTypeName (ec, e, loc))) {
- Report.Error (38, loc, "Cannot access a nonstatic member of outer type `{0}' via nested type `{1}'",
+ ec.Report.Error (38, loc, "Cannot access a nonstatic member of outer type `{0}' via nested type `{1}'",
TypeManager.CSharpName (me.DeclaringType), TypeManager.CSharpName (me.InstanceExpression.Type));
return null;
}
return (right_side != null)
? me.DoResolveLValue (ec, right_side)
- : me.DoResolve (ec);
+ : me.Resolve (ec);
}
return e;
// resolved to different type
}
- public override Expression CreateExpressionTree (EmitContext ec)
+ public override Expression CreateExpressionTree (ResolveContext ec)
{
throw new NotSupportedException ("ET");
}
throw new NotSupportedException ();
}
- public override FullNamedExpression ResolveAsTypeStep (IResolveContext ec, bool silent)
+ public override FullNamedExpression ResolveAsTypeStep (IMemberContext ec, bool silent)
{
return this;
}
/// Expression that evaluates to a type
/// </summary>
public abstract class TypeExpr : FullNamedExpression {
- public override FullNamedExpression ResolveAsTypeStep (IResolveContext ec, bool silent)
+ public override FullNamedExpression ResolveAsTypeStep (IMemberContext ec, bool silent)
{
TypeExpr t = DoResolveAsTypeStep (ec);
if (t == null)
return t;
}
- override public Expression DoResolve (EmitContext ec)
+ protected override Expression DoResolve (ResolveContext ec)
{
return ResolveAsTypeTerminal (ec, false);
}
- public virtual bool CheckAccessLevel (DeclSpace ds)
+ public virtual bool CheckAccessLevel (IMemberContext mc)
{
- return ds.CheckAccessLevel (Type);
+ return mc.CurrentTypeDefinition.CheckAccessLevel (Type);
}
public virtual bool IsClass {
return true;
}
- protected abstract TypeExpr DoResolveAsTypeStep (IResolveContext ec);
+ protected abstract TypeExpr DoResolveAsTypeStep (IMemberContext ec);
public override bool Equals (object obj)
{
loc = l;
}
- protected override TypeExpr DoResolveAsTypeStep (IResolveContext ec)
+ protected override TypeExpr DoResolveAsTypeStep (IMemberContext ec)
{
return this;
}
- public override TypeExpr ResolveAsTypeTerminal (IResolveContext ec, bool silent)
+ public override TypeExpr ResolveAsTypeTerminal (IMemberContext ec, bool silent)
{
return this;
}
eclass = ExprClass.Type;
}
- public override TypeExpr ResolveAsTypeTerminal (IResolveContext ec, bool silent)
+ public override TypeExpr ResolveAsTypeTerminal (IMemberContext ec, bool silent)
{
//
// It's null only during mscorlib bootstrap when DefineType
//
if (type == null) {
Namespace ns = GlobalRootNamespace.Instance.GetNamespace (ns_name, false);
- FullNamedExpression fne = ns.Lookup (null, name, loc);
+ FullNamedExpression fne = ns.Lookup (ec.Compiler, name, loc);
if (fne != null)
type = fne.Type;
}
return this;
}
- protected override TypeExpr DoResolveAsTypeStep (IResolveContext ec)
+ protected override TypeExpr DoResolveAsTypeStep (IMemberContext ec)
{
return this;
}
/// </summary>
public Expression InstanceExpression;
- public static void error176 (Location loc, string name)
+ public static void error176 (ResolveContext ec, Location loc, string name)
{
- Report.Error (176, loc, "Static member `{0}' cannot be accessed " +
+ ec.Report.Error (176, loc, "Static member `{0}' cannot be accessed " +
"with an instance reference, qualify it with a type name instead", name);
}
- public static void Error_BaseAccessInExpressionTree (Location loc)
+ public static void Error_BaseAccessInExpressionTree (ResolveContext ec, Location loc)
{
- Report.Error (831, loc, "An expression tree may not contain a base access");
+ ec.Report.Error (831, loc, "An expression tree may not contain a base access");
}
public override void MutateHoistedGenericType (AnonymousMethodStorey storey)
// TODO: possible optimalization
// Cache resolved constant result in FieldBuilder <-> expression map
- public virtual MemberExpr ResolveMemberAccess (EmitContext ec, Expression left, Location loc,
+ public virtual MemberExpr ResolveMemberAccess (ResolveContext ec, Expression left, Location loc,
SimpleName original)
{
//
// TODO: Same problem as in class.cs, TypeTerminal does not
// always do all necessary checks
ObsoleteAttribute oa = AttributeTester.GetObsoleteAttribute (left.Type);
- if (oa != null && !ec.IsInObsoleteScope) {
- AttributeTester.Report_ObsoleteMessage (oa, left.GetSignatureForError (), loc);
+ if (oa != null && !ec.IsObsolete) {
+ AttributeTester.Report_ObsoleteMessage (oa, left.GetSignatureForError (), loc, ec.Report);
}
GenericTypeExpr ct = left as GenericTypeExpr;
if (original != null && original.IdenticalNameAndTypeName (ec, left, loc))
return this;
- return ResolveExtensionMemberAccess (left);
+ return ResolveExtensionMemberAccess (ec, left);
}
InstanceExpression = left;
return this;
}
- protected virtual MemberExpr ResolveExtensionMemberAccess (Expression left)
+ protected virtual MemberExpr ResolveExtensionMemberAccess (ResolveContext ec, Expression left)
{
- error176 (loc, GetSignatureForError ());
+ error176 (ec, loc, GetSignatureForError ());
return this;
}
return;
if (InstanceExpression == EmptyExpression.Null) {
- SimpleName.Error_ObjectRefRequired (ec, loc, GetSignatureForError ());
+ // FIXME: This should not be here at all
+ SimpleName.Error_ObjectRefRequired (new ResolveContext (ec.MemberContext), loc, GetSignatureForError ());
return;
}
ec.ig.Emit (OpCodes.Dup);
}
- public virtual void SetTypeArguments (TypeArguments ta)
+ public virtual void SetTypeArguments (ResolveContext ec, TypeArguments ta)
{
// TODO: need to get correct member type
- Report.Error (307, loc, "The property `{0}' cannot be used with type arguments",
+ ec.Report.Error (307, loc, "The property `{0}' cannot be used with type arguments",
GetSignatureForError ());
}
}
public Expression ExtensionExpression;
Argument extension_argument;
- public ExtensionMethodGroupExpr (ArrayList list, NamespaceEntry n, Type extensionType, Location l)
+ public ExtensionMethodGroupExpr (List<MethodSpec> list, NamespaceEntry n, Type extensionType, Location l)
: base (list, extensionType, l)
{
this.namespace_entry = n;
base.MutateHoistedGenericType (storey);
}
- public override MethodGroupExpr OverloadResolve (EmitContext ec, ref Arguments arguments, bool may_fail, Location loc)
+ public override MethodGroupExpr OverloadResolve (ResolveContext ec, ref Arguments arguments, bool may_fail, Location loc)
{
if (arguments == null)
arguments = new Arguments (1);
return mg;
}
- MethodGroupExpr ResolveOverloadExtensions (EmitContext ec, ref Arguments arguments, NamespaceEntry ns, Location loc)
+ MethodGroupExpr ResolveOverloadExtensions (ResolveContext ec, ref Arguments arguments, NamespaceEntry ns, Location loc)
{
// Use normal resolve rules
MethodGroupExpr mg = base.OverloadResolve (ec, ref arguments, ns != null, loc);
return null;
// Search continues
- ExtensionMethodGroupExpr e = ns.LookupExtensionMethod (type, null, Name, loc);
+ ExtensionMethodGroupExpr e = ns.LookupExtensionMethod (type, Name, loc);
if (e == null)
return base.OverloadResolve (ec, ref arguments, false, loc);
e.ExtensionExpression = ExtensionExpression;
- e.SetTypeArguments (type_arguments);
+ e.SetTypeArguments (ec, type_arguments);
return e.ResolveOverloadExtensions (ec, ref arguments, e.namespace_entry, loc);
}
}
{
public interface IErrorHandler
{
- bool AmbiguousCall (MethodBase ambiguous);
- bool NoExactMatch (EmitContext ec, MethodBase method);
+ bool AmbiguousCall (ResolveContext ec, MethodSpec ambiguous);
+ bool NoExactMatch (ResolveContext ec, MethodSpec method);
}
- public IErrorHandler CustomErrorHandler;
- public MethodBase [] Methods;
- MethodBase best_candidate;
+ public IErrorHandler CustomErrorHandler;
+ public MethodSpec [] Methods;
+ MethodSpec best_candidate;
// TODO: make private
public TypeArguments type_arguments;
bool identical_type_name;
Type delegate_type;
Type queried_type;
- public MethodGroupExpr (MemberInfo [] mi, Type type, Location l)
+ public MethodGroupExpr (MethodSpec [] mi, Type type, Location l)
: this (type, l)
{
- Methods = new MethodBase [mi.Length];
+ Methods = new MethodSpec[mi.Length];
mi.CopyTo (Methods, 0);
}
- public MethodGroupExpr (MemberInfo[] mi, Type type, Location l, bool inacessibleCandidatesOnly)
+ public MethodGroupExpr (MethodSpec[] mi, Type type, Location l, bool inacessibleCandidatesOnly)
: this (mi, type, l)
{
has_inaccessible_candidates_only = inacessibleCandidatesOnly;
}
- public MethodGroupExpr (ArrayList list, Type type, Location l)
+ public MethodGroupExpr (List<MethodSpec> list, Type type, Location l)
: this (type, l)
{
try {
- Methods = (MethodBase[])list.ToArray (typeof (MethodBase));
+ Methods = list.ToArray ();
} catch {
- foreach (MemberInfo m in list){
- if (!(m is MethodBase)){
- Console.WriteLine ("Name " + m.Name);
- Console.WriteLine ("Found a: " + m.GetType ().FullName);
- }
- }
+ //foreach (MemberInfo m in list){
+ // if (!(m is MethodBase)){
+ // Console.WriteLine ("Name " + m.Name);
+ // Console.WriteLine ("Found a: " + m.GetType ().FullName);
+ // }
+ //}
throw;
}
}
}
+ public MethodSpec BestCandidate {
+ get {
+ return best_candidate;
+ }
+ }
+
public Type DelegateType {
set {
delegate_type = value;
public override string GetSignatureForError ()
{
if (best_candidate != null)
- return TypeManager.CSharpSignature (best_candidate);
+ return TypeManager.CSharpSignature (best_candidate.MetaInfo);
- return TypeManager.CSharpSignature (Methods [0]);
+ return TypeManager.CSharpSignature (Methods [0].MetaInfo);
}
public override string Name {
if (best_candidate != null)
return !best_candidate.IsStatic;
- foreach (MethodBase mb in Methods)
+ foreach (var mb in Methods)
if (!mb.IsStatic)
return true;
if (best_candidate != null)
return best_candidate.IsStatic;
- foreach (MethodBase mb in Methods)
+ foreach (var mb in Methods)
if (mb.IsStatic)
return true;
return false;
}
}
-
- public static explicit operator ConstructorInfo (MethodGroupExpr mg)
- {
- return (ConstructorInfo)mg.best_candidate;
- }
- public static explicit operator MethodInfo (MethodGroupExpr mg)
+ public static explicit operator MethodSpec (MethodGroupExpr mg)
{
- return (MethodInfo)mg.best_candidate;
+ return mg.best_candidate;
}
//
// 2 if a->q is better,
// 0 if neither is better
//
- static int BetterExpressionConversion (EmitContext ec, Argument a, Type p, Type q)
+ static int BetterExpressionConversion (ResolveContext ec, Argument a, Type p, Type q)
{
Type argument_type = TypeManager.TypeToCoreType (a.Type);
if (argument_type == InternalType.AnonymousMethod && RootContext.Version > LanguageVersion.ISO_2) {
q = TypeManager.GetTypeArguments (q) [0];
}
- p = Delegate.GetInvokeMethod (null, p).ReturnType;
- q = Delegate.GetInvokeMethod (null, q).ReturnType;
+ p = Delegate.GetInvokeMethod (ec.Compiler, null, p).ReturnType;
+ q = Delegate.GetInvokeMethod (ec.Compiler, null, q).ReturnType;
if (p == TypeManager.void_type && q != TypeManager.void_type)
return 2;
if (q == TypeManager.void_type && p != TypeManager.void_type)
//
// 7.4.3.4 Better conversion from type
//
- public static int BetterTypeConversion (EmitContext ec, Type p, Type q)
+ public static int BetterTypeConversion (ResolveContext ec, Type p, Type q)
{
if (p == null || q == null)
throw new InternalErrorException ("BetterTypeConversion got a null conversion");
if (q == TypeManager.ushort_type || q == TypeManager.uint32_type ||
q == TypeManager.uint64_type)
return 1;
+ } else if (p == InternalType.Dynamic) {
+ if (q == TypeManager.object_type)
+ return 2;
}
if (q == TypeManager.int32_type) {
if (p == TypeManager.ushort_type || p == TypeManager.uint32_type ||
p == TypeManager.uint64_type)
return 2;
+ } else if (q == InternalType.Dynamic) {
+ if (p == TypeManager.object_type)
+ return 1;
}
// TODO: this is expensive
/// false if candidate ain't better
/// true if candidate is better than the current best match
/// </remarks>
- static bool BetterFunction (EmitContext ec, Arguments args, int argument_count,
- MethodBase candidate, bool candidate_params,
- MethodBase best, bool best_params)
+ static bool BetterFunction (ResolveContext ec, Arguments args, int argument_count,
+ MethodSpec candidate, bool candidate_params,
+ MethodSpec best, bool best_params)
{
- AParametersCollection candidate_pd = TypeManager.GetParameterData (candidate);
- AParametersCollection best_pd = TypeManager.GetParameterData (best);
+ AParametersCollection candidate_pd = candidate.Parameters;
+ AParametersCollection best_pd = best.Parameters;
bool better_at_least_one = false;
bool same = true;
bt = TypeManager.GetElementType (bt);
--b_idx;
}
-
- if (ct.Equals (bt))
+
+ if (TypeManager.IsEqual (ct, bt))
continue;
same = false;
//
// The two methods have equal parameter types. Now apply tie-breaking rules
//
- if (TypeManager.IsGenericMethod (best)) {
- if (!TypeManager.IsGenericMethod (candidate))
+ if (best.IsGenericMethod) {
+ if (!candidate.IsGenericMethod)
return true;
- } else if (TypeManager.IsGenericMethod (candidate)) {
+ } else if (candidate.IsGenericMethod) {
return false;
}
return false;
}
- protected override MemberExpr ResolveExtensionMemberAccess (Expression left)
+ protected override MemberExpr ResolveExtensionMemberAccess (ResolveContext ec, Expression left)
{
if (!IsStatic)
- return base.ResolveExtensionMemberAccess (left);
+ return base.ResolveExtensionMemberAccess (ec, left);
//
// When left side is an expression and at least one candidate method is
return this;
}
- public override MemberExpr ResolveMemberAccess (EmitContext ec, Expression left, Location loc,
+ public override MemberExpr ResolveMemberAccess (ResolveContext ec, Expression left, Location loc,
SimpleName original)
{
if (!(left is TypeExpr) &&
return base.ResolveMemberAccess (ec, left, loc, original);
}
- public override Expression CreateExpressionTree (EmitContext ec)
+ public override Expression CreateExpressionTree (ResolveContext ec)
{
if (best_candidate == null) {
- Report.Error (1953, loc, "An expression tree cannot contain an expression with method group");
+ ec.Report.Error (1953, loc, "An expression tree cannot contain an expression with method group");
return null;
}
- if (best_candidate.IsConstructor)
- return new TypeOfConstructorInfo (best_candidate, loc);
-
- IMethodData md = TypeManager.GetMethod (best_candidate);
+ IMethodData md = TypeManager.GetMethod (best_candidate.MetaInfo);
if (md != null && md.IsExcluded ())
- Report.Error (765, loc,
+ ec.Report.Error (765, loc,
"Partial methods with only a defining declaration or removed conditional methods cannot be used in an expression tree");
- return new TypeOfMethodInfo (best_candidate, loc);
+ return new TypeOfMethod (best_candidate, loc);
}
- override public Expression DoResolve (EmitContext ec)
+ protected override Expression DoResolve (ResolveContext ec)
{
+ this.eclass = ExprClass.MethodGroup;
+
if (InstanceExpression != null) {
- InstanceExpression = InstanceExpression.DoResolve (ec);
+ InstanceExpression = InstanceExpression.Resolve (ec);
if (InstanceExpression == null)
return null;
}
return this;
}
- public void ReportUsageError ()
+ public void ReportUsageError (ResolveContext ec)
{
- Report.Error (654, loc, "Method `" + DeclaringType + "." +
+ ec.Report.Error (654, loc, "Method `" + DeclaringType + "." +
Name + "()' is referenced without parentheses");
}
override public void Emit (EmitContext ec)
{
- ReportUsageError ();
+ throw new NotSupportedException ();
+ // ReportUsageError ();
}
public void EmitCall (EmitContext ec, Arguments arguments)
Invocation.EmitCall (ec, IsBase, InstanceExpression, best_candidate, arguments, loc);
}
- void Error_AmbiguousCall (MethodBase ambiguous)
+ void Error_AmbiguousCall (ResolveContext ec, MethodSpec ambiguous)
{
- if (CustomErrorHandler != null && CustomErrorHandler.AmbiguousCall (ambiguous))
+ if (CustomErrorHandler != null && CustomErrorHandler.AmbiguousCall (ec, ambiguous))
return;
- Report.SymbolRelatedToPreviousError (best_candidate);
- Report.Error (121, loc, "The call is ambiguous between the following methods or properties: `{0}' and `{1}'",
- TypeManager.CSharpSignature (ambiguous), TypeManager.CSharpSignature (best_candidate));
+ ec.Report.SymbolRelatedToPreviousError (best_candidate.MetaInfo);
+ ec.Report.Error (121, loc, "The call is ambiguous between the following methods or properties: `{0}' and `{1}'",
+ TypeManager.CSharpSignature (ambiguous), TypeManager.CSharpSignature (best_candidate.MetaInfo));
}
- protected virtual void Error_InvalidArguments (EmitContext ec, Location loc, int idx, MethodBase method,
+ protected virtual void Error_InvalidArguments (ResolveContext ec, Location loc, int idx, MethodSpec method,
Argument a, AParametersCollection expected_par, Type paramType)
{
ExtensionMethodGroupExpr emg = this as ExtensionMethodGroupExpr;
if (a is CollectionElementInitializer.ElementInitializerArgument) {
- Report.SymbolRelatedToPreviousError (method);
+ ec.Report.SymbolRelatedToPreviousError (method.MetaInfo);
if ((expected_par.FixedParameters [idx].ModFlags & Parameter.Modifier.ISBYREF) != 0) {
- Report.Error (1954, loc, "The best overloaded collection initalizer method `{0}' cannot have 'ref', or `out' modifier",
+ ec.Report.Error (1954, loc, "The best overloaded collection initalizer method `{0}' cannot have 'ref', or `out' modifier",
TypeManager.CSharpSignature (method));
return;
}
- Report.Error (1950, loc, "The best overloaded collection initalizer method `{0}' has some invalid arguments",
+ ec.Report.Error (1950, loc, "The best overloaded collection initalizer method `{0}' has some invalid arguments",
TypeManager.CSharpSignature (method));
} else if (TypeManager.IsDelegateType (method.DeclaringType)) {
- Report.Error (1594, loc, "Delegate `{0}' has some invalid arguments",
+ ec.Report.Error (1594, loc, "Delegate `{0}' has some invalid arguments",
TypeManager.CSharpName (method.DeclaringType));
} else {
- Report.SymbolRelatedToPreviousError (method);
+ ec.Report.SymbolRelatedToPreviousError (method.MetaInfo);
if (emg != null) {
- Report.Error (1928, loc,
+ ec.Report.Error (1928, loc,
"Type `{0}' does not contain a member `{1}' and the best extension method overload `{2}' has some invalid arguments",
emg.ExtensionExpression.GetSignatureForError (),
emg.Name, TypeManager.CSharpSignature (method));
} else {
- Report.Error (1502, loc, "The best overloaded method match for `{0}' has some invalid arguments",
+ ec.Report.Error (1502, loc, "The best overloaded method match for `{0}' has some invalid arguments",
TypeManager.CSharpSignature (method));
}
}
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}' does not require `{1}' modifier. Consider removing `{1}' modifier",
+ ec.Report.Error (1615, loc, "Argument `#{0}' does not require `{1}' modifier. Consider removing `{1}' modifier",
index, Parameter.GetModifierSignature (a.Modifier));
else
- Report.Error (1620, loc, "Argument `#{0}' is missing `{1}' modifier",
+ ec.Report.Error (1620, loc, "Argument `#{0}' is missing `{1}' modifier",
index, Parameter.GetModifierSignature (mod));
} else {
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 (paramType);
+ ec.Report.ExtraInformation (loc, "(equally named types possibly from different assemblies in previous ");
+ ec.Report.SymbolRelatedToPreviousError (a.Expr.Type);
+ ec.Report.SymbolRelatedToPreviousError (paramType);
}
if (idx == 0 && emg != null) {
- Report.Error (1929, loc,
+ ec.Report.Error (1929, loc,
"Extension method instance type `{0}' cannot be converted to `{1}'", p1, p2);
} else {
- Report.Error (1503, loc,
+ ec.Report.Error (1503, loc,
"Argument `#{0}' cannot convert `{1}' expression to type `{2}'", index, p1, p2);
}
}
}
- public override void Error_ValueCannotBeConverted (EmitContext ec, Location loc, Type target, bool expl)
+ public override void Error_ValueCannotBeConverted (ResolveContext ec, Location loc, Type target, bool expl)
{
- Report.Error (428, loc, "Cannot convert method group `{0}' to non-delegate type `{1}'. Consider using parentheses to invoke the method",
+ 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));
}
- void Error_ArgumentCountWrong (int arg_count)
+ void Error_ArgumentCountWrong (ResolveContext ec, int arg_count)
{
- Report.Error (1501, loc, "No overload for method `{0}' takes `{1}' arguments",
+ ec.Report.Error (1501, loc, "No overload for method `{0}' takes `{1}' arguments",
Name, arg_count.ToString ());
}
- protected virtual int GetApplicableParametersCount (MethodBase method, AParametersCollection parameters)
+ protected virtual int GetApplicableParametersCount (MethodSpec method, AParametersCollection parameters)
{
return parameters.Count;
}
/// A return value rates candidate method compatibility,
/// 0 = the best, int.MaxValue = the worst
///
- public int IsApplicable (EmitContext ec,
- ref Arguments arguments, int arg_count, ref MethodBase method, ref bool params_expanded_form)
+ public int IsApplicable (ResolveContext ec,
+ ref Arguments arguments, int arg_count, ref MethodSpec method, ref bool params_expanded_form)
{
- MethodBase candidate = method;
+ var candidate = method;
- AParametersCollection pd = TypeManager.GetParameterData (candidate);
+ AParametersCollection pd = candidate.Parameters;
int param_count = GetApplicableParametersCount (candidate, pd);
int optional_count = 0;
}
}
- int args_gap = Math.Abs (arg_count - param_count);
+ int args_gap = System.Math.Abs (arg_count - param_count);
if (optional_count != 0) {
if (args_gap > optional_count)
return int.MaxValue - 10000 + args_gap - optional_count;
optional_count--;
if (arg_count < param_count)
param_count--;
+ } else if (arg_count > param_count) {
+ return int.MaxValue - 10000 + args_gap;
}
} else if (arg_count != param_count) {
if (!pd.HasParams)
if (na == null)
break;
- int index = pd.GetParameterIndexByName (na.Name.Value);
+ int index = pd.GetParameterIndexByName (na.Name);
// Named parameter not found or already reordered
if (index <= i)
arg_count = arguments.Count;
}
-#if GMCS_SOURCE
//
// 1. Handle generic method using type arguments when specified or type inference
//
- if (TypeManager.IsGenericMethod (candidate)) {
+ if (candidate.IsGenericMethod) {
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);
+ return int.MaxValue - 20000 + System.Math.Abs (type_arguments.Count - g_args.Length);
- // TODO: Don't create new method, create Parameters only
- method = ((MethodInfo) candidate).MakeGenericMethod (type_arguments.Arguments);
+ method = candidate.Inflate (type_arguments.Arguments);
candidate = method;
- pd = TypeManager.GetParameterData (candidate);
+ pd = candidate.Parameters;
} else {
int score = TypeManager.InferTypeArguments (ec, arguments, ref candidate);
if (score != 0)
return score - 20000;
- if (TypeManager.IsGenericMethodDefinition (candidate))
+ if (TypeManager.IsGenericMethodDefinition (candidate.MetaInfo))
throw new InternalErrorException ("A generic method `{0}' definition took part in overload resolution",
- TypeManager.CSharpSignature (candidate));
+ TypeManager.CSharpSignature (candidate.MetaInfo));
- pd = TypeManager.GetParameterData (candidate);
+ pd = candidate.Parameters;
}
} else {
if (type_arguments != null)
return int.MaxValue - 15000;
}
-#endif
//
// 2. Each argument has to be implicitly convertible to method parameter
return 0;
}
- int IsArgumentCompatible (EmitContext ec, Parameter.Modifier arg_mod, Argument argument, Parameter.Modifier param_mod, Type parameter)
+ int IsArgumentCompatible (ResolveContext 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 (TypeManager.HasElementType (a_type))
a_type = TypeManager.GetElementType (a_type);
- if (a_type != parameter)
+ if (a_type != parameter) {
+ if (TypeManager.IsDynamicType (a_type))
+ return 0;
+
return 2;
+ }
} else {
- if (!Convert.ImplicitConversionExists (ec, argument.Expr, parameter))
+ if (!Convert.ImplicitConversionExists (ec, argument.Expr, parameter)) {
+ if (TypeManager.IsDynamicType (argument.Type))
+ return 0;
+
return 2;
+ }
}
if (arg_mod != param_mod)
if (mg2 == null)
return mg1;
-
- ArrayList all = new ArrayList (mg1.Methods);
- foreach (MethodBase m in mg2.Methods){
- if (!TypeManager.ArrayContainsMethod (mg1.Methods, m, false))
+
+ var all = new List<MethodSpec> (mg1.Methods);
+ foreach (var m in mg2.Methods){
+ if (!TypeManager.ArrayContainsMethod (mg1.Methods.Select (l => l.MetaInfo).ToArray (), m.MetaInfo, false))
all.Add (m);
}
for (int i = 0; i < pargs.Length; i++)
{
- Type specific = MoreSpecific (pargs [i], qargs [i]);
+ Type specific = MoreSpecific (TypeManager.TypeToCoreType (pargs [i]), TypeManager.TypeToCoreType (qargs [i]));
if (specific == pargs [i])
p_specific_at_least_once = true;
if (specific == qargs [i])
{
base.MutateHoistedGenericType (storey);
- MethodInfo mi = best_candidate as MethodInfo;
- if (mi != null) {
- best_candidate = storey.MutateGenericMethod (mi);
- return;
+ if (best_candidate.IsConstructor) {
+ storey.MutateConstructor (best_candidate);
+ } else {
+ storey.MutateGenericMethod (best_candidate);
}
-
- best_candidate = storey.MutateConstructor ((ConstructorInfo) this);
}
/// <summary>
/// that is the best match of me on Arguments.
///
/// </summary>
- public virtual MethodGroupExpr OverloadResolve (EmitContext ec, ref Arguments Arguments,
+ public virtual MethodGroupExpr OverloadResolve (ResolveContext ec, ref Arguments Arguments,
bool may_fail, Location loc)
{
bool method_params = false;
Type applicable_type = null;
- ArrayList candidates = new ArrayList (2);
- ArrayList candidate_overrides = null;
+ var candidates = new List<MethodSpec> (2);
+ List<MethodSpec> candidate_overrides = null;
//
// Used to keep a map between the candidate
//
// false is normal form, true is expanded form
//
- Hashtable candidate_to_form = null;
- Hashtable candidates_expanded = null;
+ Dictionary<MethodSpec, MethodSpec> candidate_to_form = null;
+ Dictionary<MethodSpec, Arguments> candidates_expanded = null;
Arguments candidate_args = Arguments;
int arg_count = Arguments != null ? Arguments.Count : 0;
if (RootContext.Version == LanguageVersion.ISO_1 && Name == "Invoke" && TypeManager.IsDelegateType (DeclaringType)) {
if (!may_fail)
- Report.Error (1533, loc, "Invoke cannot be called directly on a delegate");
+ ec.Report.Error (1533, loc, "Invoke cannot be called directly on a delegate");
return null;
}
// with non-C# libraries which change the visibility of overrides (#75636)
//
int j = 0;
+ MethodBase mb = null;
for (int i = 0; i < Methods.Length; ++i) {
- MethodBase m = Methods [i];
+ var m = Methods [i];
+ mb = m.MetaInfo;
if (TypeManager.IsOverride (m)) {
if (candidate_overrides == null)
- candidate_overrides = new ArrayList ();
+ candidate_overrides = new List<MethodSpec> ();
candidate_overrides.Add (m);
- m = TypeManager.TryGetBaseDefinition (m);
+ mb = TypeManager.TryGetBaseDefinition (mb);
+ if (mb != null && Array.Exists (Methods, l => l.MetaInfo == mb))
+ continue;
}
- if (m != null)
- Methods [j++] = m;
+ if (mb != null)
+ Methods [j++] = Import.CreateMethod (mb);
}
nmethods = j;
}
//
// Enable message recording, it's used mainly by lambda expressions
//
- Report.IMessageRecorder msg_recorder = new Report.MessageRecorder ();
- Report.IMessageRecorder prev_recorder = Report.SetMessageRecorder (msg_recorder);
+ SessionReportPrinter msg_recorder = new SessionReportPrinter ();
+ ReportPrinter prev_recorder = ec.Report.SetPrinter (msg_recorder);
//
// First we construct the set of applicable methods
if (params_expanded_form) {
if (candidate_to_form == null)
- candidate_to_form = new PtrHashtable ();
- MethodBase candidate = Methods [i];
+ candidate_to_form = new Dictionary<MethodSpec, MethodSpec> (4, ReferenceEquality<MethodSpec>.Default);
+ var candidate = Methods [i];
candidate_to_form [candidate] = candidate;
}
if (candidate_args != Arguments) {
if (candidates_expanded == null)
- candidates_expanded = new Hashtable (2);
+ candidates_expanded = new Dictionary<MethodSpec, Arguments> (4, ReferenceEquality<MethodSpec>.Default);
candidates_expanded.Add (Methods [i], candidate_args);
candidate_args = Arguments;
}
}
- Report.SetMessageRecorder (prev_recorder);
+ ec.Report.SetPrinter (prev_recorder);
if (msg_recorder != null && !msg_recorder.IsEmpty) {
if (!may_fail)
- msg_recorder.PrintMessages ();
+ msg_recorder.Merge (prev_recorder);
return null;
}
// not an extension method. We start extension methods lookup from here
//
if (InstanceExpression != null) {
- ExtensionMethodGroupExpr ex_method_lookup = ec.TypeContainer.LookupExtensionMethod (type, Name, loc);
+ ExtensionMethodGroupExpr ex_method_lookup = ec.LookupExtensionMethod (type, Name, loc);
if (ex_method_lookup != null) {
ex_method_lookup.ExtensionExpression = InstanceExpression;
- ex_method_lookup.SetTypeArguments (type_arguments);
+ ex_method_lookup.SetTypeArguments (ec, type_arguments);
return ex_method_lookup.OverloadResolve (ec, ref Arguments, may_fail, loc);
}
}
if (CustomErrorHandler != null && !has_inaccessible_candidates_only && CustomErrorHandler.NoExactMatch (ec, best_candidate))
return null;
- AParametersCollection 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 (has_inaccessible_candidates_only) {
- if (InstanceExpression != null && type != ec.ContainerType && TypeManager.IsNestedFamilyAccessible (ec.ContainerType, best_candidate.DeclaringType)) {
- // Although a derived class can access protected members of
- // its base class it cannot do so through an instance of the
- // base class (CS1540). If the qualifier_type is a base of the
- // ec.ContainerType and the lookup succeeds with the latter one,
- // then we are in this situation.
- Error_CannotAccessProtected (loc, best_candidate, queried_type, ec.ContainerType);
- } else {
- Report.SymbolRelatedToPreviousError (best_candidate);
- ErrorIsInaccesible (loc, GetSignatureForError ());
- }
- }
-
- if (!VerifyArgumentsCompat (ec, ref Arguments, arg_count, best_candidate, cand_params, may_fail, loc))
- return null;
-
- if (has_inaccessible_candidates_only)
- return null;
-
- throw new InternalErrorException ("VerifyArgumentsCompat didn't find any problem with rejected candidate " + best_candidate);
- }
+ if (NoExactMatch (ec, ref Arguments, candidate_to_form))
+ return null;
}
//
// We failed to find any method with correct argument count
//
if (Name == ConstructorInfo.ConstructorName) {
- Report.SymbolRelatedToPreviousError (queried_type);
- Report.Error (1729, loc,
+ ec.Report.SymbolRelatedToPreviousError (queried_type);
+ ec.Report.Error (1729, loc,
"The type `{0}' does not contain a constructor that takes `{1}' arguments",
TypeManager.CSharpName (queried_type), arg_count);
} else {
- Error_ArgumentCountWrong (arg_count);
+ Error_ArgumentCountWrong (ec, arg_count);
}
return null;
}
+ if (arg_count != 0 && Arguments.HasDynamic) {
+ best_candidate = null;
+ return this;
+ }
+
if (!is_sorted) {
//
// At this point, applicable_type is _one_ of the most derived types
int j = finalized; // where to put the next finalized candidate
int k = finalized; // where to put the next undiscarded candidate
for (int i = finalized; i < candidate_top; ++i) {
- MethodBase candidate = (MethodBase) candidates [i];
+ var candidate = candidates [i];
Type decl_type = candidate.DeclaringType;
if (decl_type == applicable_type) {
// Now we actually find the best method
//
- best_candidate = (MethodBase) candidates [0];
- method_params = candidate_to_form != null && candidate_to_form.Contains (best_candidate);
+ best_candidate = candidates [0];
+ method_params = candidate_to_form != null && candidate_to_form.ContainsKey (best_candidate);
//
// TODO: Broken inverse order of candidates logic does not work with optional
// parameters used for method overrides and I am not going to fix it for SRE
//
- if (candidates_expanded != null && candidates_expanded.Contains (best_candidate)) {
- candidate_args = (Arguments) candidates_expanded [best_candidate];
+ if (candidates_expanded != null && candidates_expanded.ContainsKey (best_candidate)) {
+ candidate_args = candidates_expanded [best_candidate];
arg_count = candidate_args.Count;
}
for (int ix = 1; ix < candidate_top; ix++) {
- MethodBase candidate = (MethodBase) candidates [ix];
+ var candidate = candidates [ix];
- if (candidate == best_candidate)
+ if (candidate.MetaInfo == best_candidate.MetaInfo)
continue;
- bool cand_params = candidate_to_form != null && candidate_to_form.Contains (candidate);
+ bool cand_params = candidate_to_form != null && candidate_to_form.ContainsKey (candidate);
if (BetterFunction (ec, candidate_args, arg_count,
candidate, cand_params,
// Now check that there are no ambiguities i.e the selected method
// should be better than all the others
//
- MethodBase ambiguous = null;
+ MethodSpec ambiguous = null;
for (int ix = 1; ix < candidate_top; ix++) {
- MethodBase candidate = (MethodBase) candidates [ix];
+ var candidate = candidates [ix];
- if (candidate == best_candidate)
+ if (candidate.MetaInfo == best_candidate.MetaInfo)
continue;
- bool cand_params = candidate_to_form != null && candidate_to_form.Contains (candidate);
+ bool cand_params = candidate_to_form != null && candidate_to_form.ContainsKey (candidate);
if (!BetterFunction (ec, candidate_args, arg_count,
best_candidate, method_params,
candidate, cand_params))
{
if (!may_fail)
- Report.SymbolRelatedToPreviousError (candidate);
+ ec.Report.SymbolRelatedToPreviousError (candidate.MetaInfo);
ambiguous = candidate;
}
}
if (ambiguous != null) {
- Error_AmbiguousCall (ambiguous);
+ Error_AmbiguousCall (ec, ambiguous);
return this;
}
if (candidate_overrides != null) {
Type[] gen_args = null;
bool gen_override = false;
- if (TypeManager.IsGenericMethod (best_candidate))
- gen_args = TypeManager.GetGenericArguments (best_candidate);
+ if (best_candidate.IsGenericMethod)
+ gen_args = TypeManager.GetGenericArguments (best_candidate.MetaInfo);
- foreach (MethodBase candidate in candidate_overrides) {
- if (TypeManager.IsGenericMethod (candidate)) {
+ foreach (var candidate in candidate_overrides) {
+ if (candidate.IsGenericMethod) {
if (gen_args == null)
continue;
- if (gen_args.Length != TypeManager.GetGenericArguments (candidate).Length)
+ if (gen_args.Length != TypeManager.GetGenericArguments (candidate.MetaInfo).Length)
continue;
} else {
if (gen_args != null)
continue;
}
- if (IsOverride (candidate, best_candidate)) {
+ if (IsOverride (candidate.MetaInfo, best_candidate.MetaInfo)) {
gen_override = true;
best_candidate = candidate;
}
}
if (gen_override && gen_args != null) {
-#if GMCS_SOURCE
- best_candidate = ((MethodInfo) best_candidate).MakeGenericMethod (gen_args);
-#endif
+ best_candidate = best_candidate.Inflate (gen_args);
}
}
}
MethodBase the_method = TypeManager.DropGenericMethodArguments (best_candidate);
if (TypeManager.IsGenericMethodDefinition (the_method) &&
- !ConstraintChecker.CheckConstraints (ec, the_method, best_candidate, loc))
+ !ConstraintChecker.CheckConstraints (ec, the_method, best_candidate.MetaInfo, loc))
return null;
//
// Check ObsoleteAttribute on the best method
//
ObsoleteAttribute oa = AttributeTester.GetMethodObsoleteAttribute (the_method);
- if (oa != null && !ec.IsInObsoleteScope)
- AttributeTester.Report_ObsoleteMessage (oa, GetSignatureForError (), loc);
+ if (oa != null && !ec.IsObsolete)
+ AttributeTester.Report_ObsoleteMessage (oa, GetSignatureForError (), loc, ec.Report);
IMethodData data = TypeManager.GetMethod (the_method);
if (data != null)
- data.SetMemberIsUsed ();
+ data.SetIsUsed ();
Arguments = candidate_args;
return this;
}
+
+ bool NoExactMatch (ResolveContext ec, ref Arguments Arguments, IDictionary<MethodSpec, MethodSpec> candidate_to_form)
+ {
+ AParametersCollection pd = best_candidate.Parameters;
+ int arg_count = Arguments == null ? 0 : Arguments.Count;
+
+ if (arg_count == pd.Count || pd.HasParams) {
+ if (TypeManager.IsGenericMethodDefinition (best_candidate.MetaInfo)) {
+ if (type_arguments == null) {
+ ec.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.MetaInfo));
+ return true;
+ }
+
+ Type[] g_args = TypeManager.GetGenericArguments (best_candidate.MetaInfo);
+ if (type_arguments.Count != g_args.Length) {
+ ec.Report.SymbolRelatedToPreviousError (best_candidate.MetaInfo);
+ ec.Report.Error (305, loc, "Using the generic method `{0}' requires `{1}' type argument(s)",
+ TypeManager.CSharpSignature (best_candidate.MetaInfo),
+ g_args.Length.ToString ());
+ return true;
+ }
+ } else {
+ if (type_arguments != null && !best_candidate.IsGenericMethod) {
+ Error_TypeArgumentsCannotBeUsed (ec.Report, loc);
+ return true;
+ }
+ }
+
+ if (has_inaccessible_candidates_only) {
+ if (InstanceExpression != null && type != ec.CurrentType && TypeManager.IsNestedFamilyAccessible (ec.CurrentType, best_candidate.DeclaringType)) {
+ // Although a derived class can access protected members of
+ // its base class it cannot do so through an instance of the
+ // base class (CS1540). If the qualifier_type is a base of the
+ // ec.CurrentType and the lookup succeeds with the latter one,
+ // then we are in this situation.
+ Error_CannotAccessProtected (ec, loc, best_candidate.MetaInfo, queried_type, ec.CurrentType);
+ } else {
+ ec.Report.SymbolRelatedToPreviousError (best_candidate.MetaInfo);
+ ErrorIsInaccesible (loc, GetSignatureForError (), ec.Report);
+ }
+ }
+
+ bool cand_params = candidate_to_form != null && candidate_to_form.ContainsKey (best_candidate);
+ if (!VerifyArgumentsCompat (ec, ref Arguments, arg_count, best_candidate, cand_params, false, loc))
+ return true;
+
+ if (has_inaccessible_candidates_only)
+ return true;
+ }
+
+ return false;
+ }
- public override void SetTypeArguments (TypeArguments ta)
+ public override void SetTypeArguments (ResolveContext ec, TypeArguments ta)
{
type_arguments = ta;
}
- public bool VerifyArgumentsCompat (EmitContext ec, ref Arguments arguments,
- int arg_count, MethodBase method,
+ public bool VerifyArgumentsCompat (ResolveContext ec, ref Arguments arguments,
+ int arg_count, MethodSpec method,
bool chose_params_expanded,
bool may_fail, Location loc)
{
- AParametersCollection pd = TypeManager.GetParameterData (method);
+ AParametersCollection pd = method.Parameters;
int param_count = GetApplicableParametersCount (method, pd);
- int errors = Report.Errors;
+ int errors = ec.Report.Errors;
Parameter.Modifier p_mod = 0;
Type pt = null;
int a_idx = 0, a_pos = 0;
Argument a = null;
- ArrayList params_initializers = null;
- bool has_unsafe_arg = false;
+ ArrayInitializer params_initializers = null;
+ bool has_unsafe_arg = method.ReturnType.IsPointer;
for (; a_idx < arg_count; a_idx++, ++a_pos) {
a = arguments [a_idx];
if (p_mod == Parameter.Modifier.PARAMS) {
if (chose_params_expanded) {
- params_initializers = new ArrayList (arg_count - a_idx);
+ params_initializers = new ArrayInitializer (arg_count - a_idx, a.Expr.Location);
pt = TypeManager.GetElementType (pt);
}
}
} else {
NamedArgument na = a as NamedArgument;
if (na != null) {
- int name_index = pd.GetParameterIndexByName (na.Name.Value);
+ int name_index = pd.GetParameterIndexByName (na.Name);
if (name_index < 0 || name_index >= param_count) {
if (DeclaringType != null && TypeManager.IsDelegateType (DeclaringType)) {
- Report.SymbolRelatedToPreviousError (DeclaringType);
- Report.Error (1746, na.Name.Location,
+ ec.Report.SymbolRelatedToPreviousError (DeclaringType);
+ ec.Report.Error (1746, na.Location,
"The delegate `{0}' does not contain a parameter named `{1}'",
- TypeManager.CSharpName (DeclaringType), na.Name.Value);
+ TypeManager.CSharpName (DeclaringType), na.Name);
} else {
- Report.SymbolRelatedToPreviousError (best_candidate);
- Report.Error (1739, na.Name.Location,
+ ec.Report.SymbolRelatedToPreviousError (best_candidate.MetaInfo);
+ ec.Report.Error (1739, na.Location,
"The best overloaded method match for `{0}' does not contain a parameter named `{1}'",
- TypeManager.CSharpSignature (method), na.Name.Value);
+ TypeManager.CSharpSignature (method.MetaInfo), na.Name);
}
} else if (arguments[name_index] != a) {
if (DeclaringType != null && TypeManager.IsDelegateType (DeclaringType))
- Report.SymbolRelatedToPreviousError (DeclaringType);
+ ec.Report.SymbolRelatedToPreviousError (DeclaringType);
else
- Report.SymbolRelatedToPreviousError (best_candidate);
+ ec.Report.SymbolRelatedToPreviousError (best_candidate.MetaInfo);
- Report.Error (1744, na.Name.Location,
+ ec.Report.Error (1744, na.Location,
"Named argument `{0}' cannot be used for a parameter which has positional argument specified",
- na.Name.Value);
+ na.Name);
}
}
}
+ if (TypeManager.IsDynamicType (a.Expr.Type))
+ continue;
+
if (delegate_type != null && !Delegate.IsTypeCovariant (a.Expr, pt))
break;
}
if (a_idx != arg_count) {
- if (!may_fail && Report.Errors == errors) {
+ if (!may_fail && ec.Report.Errors == errors) {
if (CustomErrorHandler != null)
CustomErrorHandler.NoExactMatch (ec, best_candidate);
else
pt = pd.Types [param_count - 1];
pt = TypeManager.GetElementType (pt);
has_unsafe_arg |= pt.IsPointer;
- params_initializers = new ArrayList (0);
+ params_initializers = new ArrayInitializer (0, loc);
}
//
//
if (params_initializers != null) {
arguments.Add (new Argument (
- new ArrayCreation (new TypeExpression (pt, loc), "[]",
- params_initializers, loc).Resolve (ec)));
+ new ArrayCreation (new TypeExpression (pt, loc), "[]", params_initializers, loc).Resolve (ec)));
arg_count++;
}
if (arg_count < param_count) {
if (!may_fail)
- Error_ArgumentCountWrong (arg_count);
+ Error_ArgumentCountWrong (ec, arg_count);
return false;
}
- if (has_unsafe_arg && !ec.InUnsafe) {
+ if (has_unsafe_arg && !ec.IsUnsafe) {
if (!may_fail)
- UnsafeError (loc);
+ UnsafeError (ec, loc);
return false;
}
public class ConstantExpr : MemberExpr
{
- FieldInfo constant;
+ ConstSpec constant;
- public ConstantExpr (FieldInfo constant, Location loc)
+ public ConstantExpr (ConstSpec constant, Location loc)
{
this.constant = constant;
this.loc = loc;
}
public override bool IsStatic {
- get { return constant.IsStatic; }
+ get { return true; }
}
public override Type DeclaringType {
get { return constant.DeclaringType; }
}
- public override MemberExpr ResolveMemberAccess (EmitContext ec, Expression left, Location loc, SimpleName original)
- {
- constant = TypeManager.GetGenericFieldDefinition (constant);
-
- 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);
- }
- TypeManager.RegisterConstant (constant, ic);
- }
-
- return base.ResolveMemberAccess (ec, left, loc, original);
- }
-
- public override Expression CreateExpressionTree (EmitContext ec)
+ public override Expression CreateExpressionTree (ResolveContext ec)
{
throw new NotSupportedException ("ET");
}
- public override Expression DoResolve (EmitContext ec)
+ protected override Expression DoResolve (ResolveContext rc)
{
- IConstant ic = TypeManager.GetConstant (constant);
- if (ic.ResolveValue ()) {
- if (!ec.IsInObsoleteScope)
- ic.CheckObsoleteness (loc);
+ constant.MemberDefinition.SetIsUsed ();
+
+ if (!rc.IsObsolete) {
+ var oa = constant.GetObsoleteAttribute ();
+ if (oa != null)
+ AttributeTester.Report_ObsoleteMessage (oa, TypeManager.GetFullNameSignature (constant.MetaInfo), loc, rc.Report);
}
- return ic.CreateConstantReference (loc);
+ // Constants are resolved on-demand
+ var c = constant.Value.Resolve (rc) as Constant;
+
+ // Creates reference expression to the constant value
+ return Constant.CreateConstant (rc, c.Type, c.GetValue (), loc);
}
public override void Emit (EmitContext ec)
public override string GetSignatureForError ()
{
- return TypeManager.GetFullNameSignature (constant);
+ return TypeManager.GetFullNameSignature (constant.MetaInfo);
}
}
/// <summary>
/// Fully resolved expression that evaluates to a Field
/// </summary>
- public class FieldExpr : MemberExpr, IAssignMethod, IMemoryLocation, IVariableReference {
- public FieldInfo FieldInfo;
+ public class FieldExpr : MemberExpr, IDynamicAssign, IMemoryLocation, IVariableReference {
+ protected FieldSpec spec;
readonly Type constructed_generic_type;
VariableInfo variable_info;
{
loc = l;
}
+
+ public FieldExpr (FieldSpec spec, Location loc)
+ {
+ this.spec = spec;
+ this.loc = loc;
+
+ type = TypeManager.TypeToCoreType (spec.FieldType);
+ }
- public FieldExpr (FieldInfo fi, Location l)
+ public FieldExpr (FieldBase fi, Location l)
+ : this (fi.Spec, l)
{
- FieldInfo = fi;
- type = TypeManager.TypeToCoreType (fi.FieldType);
loc = l;
}
- public FieldExpr (FieldInfo fi, Type genericType, Location l)
+ public FieldExpr (Field fi, Type genericType, Location l)
: this (fi, l)
{
if (TypeManager.IsGenericTypeDefinition (genericType))
public override string Name {
get {
- return FieldInfo.Name;
+ return spec.Name;
}
}
public override bool IsInstance {
get {
- return !FieldInfo.IsStatic;
+ return !spec.IsStatic;
}
}
public override bool IsStatic {
get {
- return FieldInfo.IsStatic;
+ return spec.IsStatic;
+ }
+ }
+
+ public FieldSpec Spec {
+ get {
+ return spec;
}
}
public override Type DeclaringType {
get {
- return FieldInfo.DeclaringType;
+ return spec.MetaInfo.DeclaringType;
}
}
public override string GetSignatureForError ()
{
- return TypeManager.GetFullNameSignature (FieldInfo);
+ return TypeManager.GetFullNameSignature (spec.MetaInfo);
}
public VariableInfo VariableInfo {
}
}
- public override MemberExpr ResolveMemberAccess (EmitContext ec, Expression left, Location loc,
+ public override MemberExpr ResolveMemberAccess (ResolveContext ec, Expression left, Location loc,
SimpleName original)
{
- FieldInfo fi = TypeManager.GetGenericFieldDefinition (FieldInfo);
+ FieldInfo fi = TypeManager.GetGenericFieldDefinition (spec.MetaInfo);
Type t = fi.FieldType;
- if (t.IsPointer && !ec.InUnsafe) {
- UnsafeError (loc);
+ if (t.IsPointer && !ec.IsUnsafe) {
+ UnsafeError (ec, loc);
}
return base.ResolveMemberAccess (ec, left, loc, original);
vr.SetHasAddressTaken ();
}
- public override Expression CreateExpressionTree (EmitContext ec)
+ public override Expression CreateExpressionTree (ResolveContext ec)
{
Expression instance;
if (InstanceExpression == null) {
instance,
CreateTypeOfExpression ());
- return CreateExpressionFactoryCall ("Field", args);
+ return CreateExpressionFactoryCall (ec, "Field", args);
}
public Expression CreateTypeOfExpression ()
{
- return new TypeOfField (GetConstructedFieldInfo (), loc);
+ return new TypeOfField (Import.CreateField (GetConstructedFieldInfo ()), loc);
}
- override public Expression DoResolve (EmitContext ec)
+ protected override Expression DoResolve (ResolveContext ec)
{
return DoResolve (ec, false, false);
}
- Expression DoResolve (EmitContext ec, bool lvalue_instance, bool out_access)
+ Expression DoResolve (ResolveContext ec, bool lvalue_instance, bool out_access)
{
- if (!FieldInfo.IsStatic){
+ if (!IsStatic){
if (InstanceExpression == null){
//
// This can happen when referencing an instance field using
// "a.b" is initialized, not whether the whole struct "a" is initialized.
if (lvalue_instance) {
- using (ec.With (EmitContext.Flags.DoFlowAnalysis, false)) {
+ using (ec.With (ResolveContext.Options.DoFlowAnalysis, false)) {
Expression right_side =
out_access ? EmptyExpression.LValueMemberOutAccess : EmptyExpression.LValueMemberAccess;
InstanceExpression = InstanceExpression.ResolveLValue (ec, right_side);
}
} else {
- ResolveFlags rf = ResolveFlags.VariableOrValue | ResolveFlags.DisableFlowAnalysis;
-
- if (InstanceExpression != EmptyExpression.Null)
- InstanceExpression = InstanceExpression.Resolve (ec, rf);
+ if (InstanceExpression != EmptyExpression.Null) {
+ using (ec.With (ResolveContext.Options.DoFlowAnalysis, false)) {
+ InstanceExpression = InstanceExpression.Resolve (ec, ResolveFlags.VariableOrValue);
+ }
+ }
}
if (InstanceExpression == null)
return null;
- using (ec.Set (EmitContext.Flags.OmitStructFlowAnalysis)) {
+ using (ec.Set (ResolveContext.Options.OmitStructFlowAnalysis)) {
InstanceExpression.CheckMarshalByRefAccess (ec);
}
}
- // TODO: the code above uses some non-standard multi-resolve rules
- if (eclass != ExprClass.Invalid)
- return this;
-
- if (!ec.IsInObsoleteScope) {
- FieldBase f = TypeManager.GetField (FieldInfo);
+ if (!ec.IsObsolete) {
+ FieldBase f = TypeManager.GetField (spec.MetaInfo);
if (f != null) {
f.CheckObsoleteness (loc);
} else {
- ObsoleteAttribute oa = AttributeTester.GetMemberObsoleteAttribute (FieldInfo);
+ ObsoleteAttribute oa = AttributeTester.GetMemberObsoleteAttribute (spec.MetaInfo);
if (oa != null)
- AttributeTester.Report_ObsoleteMessage (oa, TypeManager.GetFullNameSignature (FieldInfo), loc);
+ AttributeTester.Report_ObsoleteMessage (oa, TypeManager.GetFullNameSignature (spec.MetaInfo), loc, ec.Report);
}
}
- IFixedBuffer fb = AttributeTester.GetFixedBuffer (FieldInfo);
+ var fb = spec as FixedFieldSpec;
IVariableReference var = InstanceExpression as IVariableReference;
if (fb != null) {
IFixedExpression fe = InstanceExpression as IFixedExpression;
- if (!ec.InFixedInitializer && (fe == null || !fe.IsFixed)) {
- Report.Error (1666, loc, "You cannot use fixed size buffers contained in unfixed expressions. Try using the fixed statement");
+ if (!ec.HasSet (ResolveContext.Options.FixedInitializerScope) && (fe == null || !fe.IsFixed)) {
+ ec.Report.Error (1666, loc, "You cannot use fixed size buffers contained in unfixed expressions. Try using the fixed statement");
}
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));
+ ec.Report.SymbolRelatedToPreviousError (spec.MetaInfo);
+ ec.Report.Error (1708, loc, "`{0}': Fixed size buffers can only be accessed through locals or fields",
+ TypeManager.GetFullNameSignature (spec.MetaInfo));
} else if (var != null && var.IsHoisted) {
- AnonymousMethodExpression.Error_AddressOfCapturedVar (var, loc);
+ AnonymousMethodExpression.Error_AddressOfCapturedVar (ec, var, loc);
}
return new FixedBufferPtr (this, fb.ElementType, loc).Resolve (ec);
return this;
VariableInfo vi = var.VariableInfo;
- if (!vi.IsFieldAssigned (ec, FieldInfo.Name, loc))
+ if (!vi.IsFieldAssigned (ec, Name, loc))
return null;
- variable_info = vi.GetSubStruct (FieldInfo.Name);
- eclass = ExprClass.Variable;
+ variable_info = vi.GetSubStruct (Name);
return this;
}
};
// The return value is always null. Returning a value simplifies calling code.
- Expression Report_AssignToReadonly (Expression right_side)
+ Expression Report_AssignToReadonly (ResolveContext ec, Expression right_side)
{
int i = 0;
- if (right_side == EmptyExpression.OutAccess || right_side == EmptyExpression.LValueMemberOutAccess)
+ if (right_side == EmptyExpression.OutAccess.Instance || right_side == EmptyExpression.LValueMemberOutAccess)
i += 1;
if (IsStatic)
i += 2;
if (right_side == EmptyExpression.LValueMemberAccess || right_side == EmptyExpression.LValueMemberOutAccess)
i += 4;
- Report.Error (codes [i], loc, msgs [i], GetSignatureForError ());
+ ec.Report.Error (codes [i], loc, msgs [i], GetSignatureForError ());
return null;
}
- override public Expression DoResolveLValue (EmitContext ec, Expression right_side)
+ override public Expression DoResolveLValue (ResolveContext ec, Expression right_side)
{
IVariableReference var = InstanceExpression as IVariableReference;
if (var != null && var.VariableInfo != null)
- var.VariableInfo.SetFieldAssigned (ec, FieldInfo.Name);
+ var.VariableInfo.SetFieldAssigned (ec, Name);
- bool lvalue_instance = !FieldInfo.IsStatic && TypeManager.IsValueType (FieldInfo.DeclaringType);
- bool out_access = right_side == EmptyExpression.OutAccess || right_side == EmptyExpression.LValueMemberOutAccess;
+ bool lvalue_instance = !spec.IsStatic && TypeManager.IsValueType (spec.MetaInfo.DeclaringType);
+ bool out_access = right_side == EmptyExpression.OutAccess.Instance || right_side == EmptyExpression.LValueMemberOutAccess;
Expression e = DoResolve (ec, lvalue_instance, out_access);
if (e == null)
return null;
- FieldBase fb = TypeManager.GetField (FieldInfo);
- if (fb != null)
+ FieldBase fb = TypeManager.GetField (spec.MetaInfo);
+ if (fb != null) {
fb.SetAssigned ();
- if (FieldInfo.IsInitOnly) {
+ if ((right_side == EmptyExpression.UnaryAddress || right_side == EmptyExpression.OutAccess.Instance) &&
+ (fb.ModFlags & Modifiers.VOLATILE) != 0) {
+ ec.Report.Warning (420, 1, loc,
+ "`{0}': A volatile field references will not be treated as volatile",
+ fb.GetSignatureForError ());
+ }
+ }
+
+ if (spec.IsReadOnly) {
// InitOnly fields can only be assigned in constructors or initializers
- if (!ec.IsInFieldInitializer && !ec.IsConstructor)
- return Report_AssignToReadonly (right_side);
+ if (!ec.HasAny (ResolveContext.Options.FieldInitializerScope | ResolveContext.Options.ConstructorScope))
+ return Report_AssignToReadonly (ec, right_side);
- if (ec.IsConstructor) {
- Type ctype = ec.TypeContainer.CurrentType;
- if (ctype == null)
- ctype = ec.ContainerType;
+ if (ec.HasSet (ResolveContext.Options.ConstructorScope)) {
+ Type ctype = ec.CurrentType;
// InitOnly fields cannot be assigned-to in a different constructor from their declaring type
- if (!TypeManager.IsEqual (ctype, FieldInfo.DeclaringType))
- return Report_AssignToReadonly (right_side);
+ if (!TypeManager.IsEqual (ctype, DeclaringType))
+ return Report_AssignToReadonly (ec, right_side);
// static InitOnly fields cannot be assigned-to in an instance constructor
if (IsStatic && !ec.IsStatic)
- return Report_AssignToReadonly (right_side);
+ return Report_AssignToReadonly (ec, right_side);
// instance constructors can't modify InitOnly fields of other instances of the same type
if (!IsStatic && !(InstanceExpression is This))
- return Report_AssignToReadonly (right_side);
+ return Report_AssignToReadonly (ec, right_side);
}
}
- if (right_side == EmptyExpression.OutAccess &&
+ if (right_side == EmptyExpression.OutAccess.Instance &&
!IsStatic && !(InstanceExpression is This) && TypeManager.mbr_type != null && TypeManager.IsSubclassOf (DeclaringType, TypeManager.mbr_type)) {
- Report.SymbolRelatedToPreviousError (DeclaringType);
- Report.Warning (197, 1, loc,
+ ec.Report.SymbolRelatedToPreviousError (DeclaringType);
+ ec.Report.Warning (197, 1, loc,
"Passing `{0}' as ref or out or taking its address may cause a runtime exception because it is a field of a marshal-by-reference class",
GetSignatureForError ());
}
return !IsStatic && TypeManager.IsStruct (Type) && TypeManager.mbr_type != null && TypeManager.IsSubclassOf (DeclaringType, TypeManager.mbr_type);
}
- public override void CheckMarshalByRefAccess (EmitContext ec)
+ public override void CheckMarshalByRefAccess (ResolveContext ec)
{
if (is_marshal_by_ref () && !(InstanceExpression is This)) {
- 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",
+ ec.Report.SymbolRelatedToPreviousError (DeclaringType);
+ ec.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 ());
}
}
public override int GetHashCode ()
{
- return FieldInfo.GetHashCode ();
+ return spec.GetHashCode ();
}
public bool IsFixed {
if (fe == null)
return false;
- if (FieldInfo != fe.FieldInfo)
+ if (spec.MetaInfo != fe.spec.MetaInfo)
return false;
if (InstanceExpression == null || fe.InstanceExpression == null)
ILGenerator ig = ec.ig;
bool is_volatile = false;
- FieldBase f = TypeManager.GetField (FieldInfo);
+ var f = TypeManager.GetField (spec.MetaInfo);
if (f != null){
if ((f.ModFlags & Modifiers.VOLATILE) != 0)
is_volatile = true;
- f.SetMemberIsUsed ();
+ f.SetIsUsed ();
}
- if (FieldInfo.IsStatic){
+ if (IsStatic){
if (is_volatile)
ig.Emit (OpCodes.Volatile);
EmitInstance (ec, false);
// Optimization for build-in types
- // TODO: Iterators don't set current container
- if (TypeManager.IsStruct (type) && type == ec.DeclContainer.TypeBuilder && ec.CurrentIterator == null) {
+ if (TypeManager.IsStruct (type) && TypeManager.IsEqual (type, ec.MemberContext.CurrentType) && TypeManager.IsEqual (InstanceExpression.Type, type)) {
LoadFromPtr (ig, type);
} else {
- IFixedBuffer ff = AttributeTester.GetFixedBuffer (FieldInfo);
+ var ff = spec as FixedFieldSpec;
if (ff != null) {
ig.Emit (OpCodes.Ldflda, GetConstructedFieldInfo ());
ig.Emit (OpCodes.Ldflda, ff.Element);
if (leave_copy) {
ec.ig.Emit (OpCodes.Dup);
- if (!FieldInfo.IsStatic) {
+ if (!IsStatic) {
temp = new LocalTemporary (this.Type);
temp.Store (ec);
}
public void EmitAssign (EmitContext ec, Expression source, bool leave_copy, bool prepare_for_load)
{
- FieldAttributes fa = FieldInfo.Attributes;
- bool is_static = (fa & FieldAttributes.Static) != 0;
- bool is_readonly = (fa & FieldAttributes.InitOnly) != 0;
+ //FieldAttributes fa = FieldInfo.Attributes;
+ //bool is_static = (fa & FieldAttributes.Static) != 0;
ILGenerator ig = ec.ig;
- if (is_readonly && !ec.IsConstructor){
- Report_AssignToReadonly (source);
- return;
- }
-
prepared = prepare_for_load;
EmitInstance (ec, prepared);
source.Emit (ec);
if (leave_copy) {
ec.ig.Emit (OpCodes.Dup);
- if (!FieldInfo.IsStatic) {
+ if (!IsStatic) {
temp = new LocalTemporary (this.Type);
temp.Store (ec);
}
}
- FieldBase f = TypeManager.GetField (FieldInfo);
+ FieldBase f = TypeManager.GetField (spec.MetaInfo);
if (f != null){
if ((f.ModFlags & Modifiers.VOLATILE) != 0)
ig.Emit (OpCodes.Volatile);
f.SetAssigned ();
}
- if (is_static)
+ if (IsStatic)
ig.Emit (OpCodes.Stsfld, GetConstructedFieldInfo ());
else
ig.Emit (OpCodes.Stfld, GetConstructedFieldInfo ());
public override void EmitSideEffect (EmitContext ec)
{
- FieldBase f = TypeManager.GetField (FieldInfo);
+ FieldBase f = TypeManager.GetField (spec.MetaInfo);
bool is_volatile = f != null && (f.ModFlags & Modifiers.VOLATILE) != 0;
if (is_volatile || is_marshal_by_ref ())
base.EmitSideEffect (ec);
}
- public override void Error_VariableIsUsedBeforeItIsDeclared (string name)
+ public override void Error_VariableIsUsedBeforeItIsDeclared (Report r, string name)
{
- Report.Error (844, loc,
+ r.Error (844, loc,
"A local variable `{0}' cannot be used before it is declared. Consider renaming the local variable when it hides the field `{1}'",
name, GetSignatureForError ());
}
{
ILGenerator ig = ec.ig;
- FieldBase f = TypeManager.GetField (FieldInfo);
- if (f != null){
- if ((f.ModFlags & Modifiers.VOLATILE) != 0){
- Report.Warning (420, 1, loc, "`{0}': A volatile field references will not be treated as volatile",
- f.GetSignatureForError ());
- }
-
+ FieldBase f = TypeManager.GetField (spec.MetaInfo);
+ if (f != null){
if ((mode & AddressOp.Store) != 0)
f.SetAssigned ();
if ((mode & AddressOp.Load) != 0)
- f.SetMemberIsUsed ();
+ f.SetIsUsed ();
}
//
// get the address of the copy.
//
bool need_copy;
- if (FieldInfo.IsInitOnly){
+ if (spec.IsReadOnly){
need_copy = true;
- if (ec.IsConstructor){
- if (FieldInfo.IsStatic){
+ if (ec.HasSet (EmitContext.Options.ConstructorScope)){
+ if (IsStatic){
if (ec.IsStatic)
need_copy = false;
} else
}
- if (FieldInfo.IsStatic){
+ if (IsStatic){
ig.Emit (OpCodes.Ldsflda, GetConstructedFieldInfo ());
} else {
if (!prepared)
FieldInfo GetConstructedFieldInfo ()
{
if (constructed_generic_type == null)
- return FieldInfo;
-#if GMCS_SOURCE
- return TypeBuilder.GetField (constructed_generic_type, FieldInfo);
-#else
- throw new NotSupportedException ();
-#endif
+ return spec.MetaInfo;
+
+ return TypeBuilder.GetField (constructed_generic_type, spec.MetaInfo);
+ }
+
+ public SLE.Expression MakeAssignExpression (BuilderContext ctx)
+ {
+ return MakeExpression (ctx);
+ }
+
+ public override SLE.Expression MakeExpression (BuilderContext ctx)
+ {
+ return SLE.Expression.Field (InstanceExpression.MakeExpression (ctx), spec.MetaInfo);
}
public override void MutateHoistedGenericType (AnonymousMethodStorey storey)
{
- FieldInfo = storey.MutateField (FieldInfo);
+ storey.MutateField (spec);
base.MutateHoistedGenericType (storey);
}
}
/// This is not an LValue because we need to re-write the expression, we
/// can not take data from the stack and store it.
/// </summary>
- public class PropertyExpr : MemberExpr, IAssignMethod {
- public readonly PropertyInfo PropertyInfo;
- MethodInfo getter, setter;
+ public class PropertyExpr : MemberExpr, IDynamicAssign
+ {
+ PropertySpec spec;
+ MethodSpec getter, setter;
bool is_static;
- bool resolved;
+ TypeArguments targs;
LocalTemporary temp;
bool prepared;
- public PropertyExpr (Type container_type, PropertyInfo pi, Location l)
+ public PropertyExpr (Type container_type, PropertySpec spec, Location l)
{
- PropertyInfo = pi;
- eclass = ExprClass.PropertyAccess;
- is_static = false;
+ this.spec = spec;
loc = l;
- type = TypeManager.TypeToCoreType (pi.PropertyType);
+ type = TypeManager.TypeToCoreType (spec.PropertyType);
ResolveAccessors (container_type);
}
public override string Name {
get {
- return PropertyInfo.Name;
+ return spec.Name;
}
}
}
}
- public override Expression CreateExpressionTree (EmitContext ec)
+ public override Expression CreateExpressionTree (ResolveContext ec)
{
Arguments args;
if (IsSingleDimensionalArrayLength ()) {
args = new Arguments (1);
args.Add (new Argument (InstanceExpression.CreateExpressionTree (ec)));
- return CreateExpressionFactoryCall ("ArrayLength", args);
+ return CreateExpressionFactoryCall (ec, "ArrayLength", args);
}
if (is_base) {
- Error_BaseAccessInExpressionTree (loc);
+ Error_BaseAccessInExpressionTree (ec, loc);
return null;
}
args.Add (new Argument (new NullLiteral (loc)));
else
args.Add (new Argument (InstanceExpression.CreateExpressionTree (ec)));
- args.Add (new Argument (new TypeOfMethodInfo (getter, loc)));
- return CreateExpressionFactoryCall ("Property", args);
+ args.Add (new Argument (new TypeOfMethod (getter, loc)));
+ return CreateExpressionFactoryCall (ec, "Property", args);
}
public Expression CreateSetterTypeOfExpression ()
{
- return new TypeOfMethodInfo (setter, loc);
+ return new TypeOfMethod (setter, loc);
}
public override Type DeclaringType {
get {
- return PropertyInfo.DeclaringType;
+ return spec.DeclaringType;
}
}
public override string GetSignatureForError ()
{
- return TypeManager.GetFullNameSignature (PropertyInfo);
+ return TypeManager.GetFullNameSignature (spec.MetaInfo);
}
void FindAccessors (Type invocation_type)
BindingFlags.Static | BindingFlags.Instance |
BindingFlags.DeclaredOnly;
- Type current = PropertyInfo.DeclaringType;
+ Type current = spec.DeclaringType;
for (; current != null; current = current.BaseType) {
MemberInfo[] group = TypeManager.MemberLookup (
invocation_type, invocation_type, current,
- MemberTypes.Property, flags, PropertyInfo.Name, null);
+ MemberTypes.Property, flags, spec.Name, null);
if (group == null)
continue;
PropertyInfo pi = (PropertyInfo) group [0];
- if (getter == null)
- getter = pi.GetGetMethod (true);
+ if (getter == null) {
+ var m = pi.GetGetMethod (true);
+ if (m != null)
+ getter = Import.CreateMethod (m);
+ }
- if (setter == null)
- setter = pi.GetSetMethod (true);
+ if (setter == null) {
+ var m = pi.GetSetMethod (true);
+ if (m != null)
+ setter = Import.CreateMethod (m);
+ }
- MethodInfo accessor = getter != null ? getter : setter;
+ var accessor = getter != null ? getter : setter;
if (!accessor.IsVirtual)
return;
MethodBase the_getter = TypeManager.DropGenericMethodArguments (getter);
IMethodData md = TypeManager.GetMethod (the_getter);
if (md != null)
- md.SetMemberIsUsed ();
+ md.SetIsUsed ();
is_static = getter.IsStatic;
}
MethodBase the_setter = TypeManager.DropGenericMethodArguments (setter);
IMethodData md = TypeManager.GetMethod (the_setter);
if (md != null)
- md.SetMemberIsUsed ();
+ md.SetIsUsed ();
is_static = setter.IsStatic;
}
}
+ public SLE.Expression MakeAssignExpression (BuilderContext ctx)
+ {
+ return SLE.Expression.Property (InstanceExpression.MakeExpression (ctx), (MethodInfo) setter.MetaInfo);
+ }
+
+ public override SLE.Expression MakeExpression (BuilderContext ctx)
+ {
+ return SLE.Expression.Property (InstanceExpression.MakeExpression (ctx), (MethodInfo) getter.MetaInfo);
+ }
+
public override void MutateHoistedGenericType (AnonymousMethodStorey storey)
{
if (InstanceExpression != null)
type = storey.MutateType (type);
if (getter != null)
- getter = storey.MutateGenericMethod (getter);
+ storey.MutateGenericMethod (getter);
if (setter != null)
- setter = storey.MutateGenericMethod (setter);
+ storey.MutateGenericMethod (setter);
}
- bool InstanceResolve (EmitContext ec, bool lvalue_instance, bool must_do_cs1540_check)
+ public PropertyInfo PropertyInfo {
+ get {
+ return spec.MetaInfo;
+ }
+ }
+
+ bool InstanceResolve (ResolveContext ec, bool lvalue_instance, bool must_do_cs1540_check)
{
if (is_static) {
InstanceExpression = null;
return false;
}
- InstanceExpression = InstanceExpression.DoResolve (ec);
+ InstanceExpression = InstanceExpression.Resolve (ec);
if (lvalue_instance && InstanceExpression != null)
InstanceExpression = InstanceExpression.ResolveLValue (ec, EmptyExpression.LValueMemberAccess);
InstanceExpression.CheckMarshalByRefAccess (ec);
if (must_do_cs1540_check && (InstanceExpression != EmptyExpression.Null) &&
- !TypeManager.IsInstantiationOfSameGenericType (InstanceExpression.Type, ec.ContainerType) &&
- !TypeManager.IsNestedChildOf (ec.ContainerType, InstanceExpression.Type) &&
- !TypeManager.IsSubclassOf (InstanceExpression.Type, ec.ContainerType)) {
- Report.SymbolRelatedToPreviousError (PropertyInfo);
- Error_CannotAccessProtected (loc, PropertyInfo, InstanceExpression.Type, ec.ContainerType);
+ !TypeManager.IsInstantiationOfSameGenericType (InstanceExpression.Type, ec.CurrentType) &&
+ !TypeManager.IsNestedChildOf (ec.CurrentType, InstanceExpression.Type) &&
+ !TypeManager.IsSubclassOf (InstanceExpression.Type, ec.CurrentType)) {
+ ec.Report.SymbolRelatedToPreviousError (spec.MetaInfo);
+ Error_CannotAccessProtected (ec, loc, spec.MetaInfo, InstanceExpression.Type, ec.CurrentType);
return false;
}
return true;
}
- void Error_PropertyNotFound (MethodInfo mi, bool getter)
+ void Error_PropertyNotFound (ResolveContext ec, MethodSpec mi, bool getter)
{
// TODO: correctly we should compare arguments but it will lead to bigger changes
- if (mi is MethodBuilder) {
- Error_TypeDoesNotContainDefinition (loc, PropertyInfo.DeclaringType, Name);
+ if (mi.MetaInfo is MethodBuilder) {
+ Error_TypeDoesNotContainDefinition (ec, loc, spec.DeclaringType, Name);
return;
}
StringBuilder sig = new StringBuilder (TypeManager.CSharpName (mi.DeclaringType));
sig.Append ('.');
- AParametersCollection iparams = TypeManager.GetParameterData (mi);
+ AParametersCollection iparams = mi.Parameters;
sig.Append (getter ? "get_" : "set_");
sig.Append (Name);
sig.Append (iparams.GetSignatureForError ());
- Report.SymbolRelatedToPreviousError (mi);
- Report.Error (1546, loc, "Property `{0}' is not supported by the C# language. Try to call the accessor method `{1}' directly",
+ ec.Report.SymbolRelatedToPreviousError (mi.MetaInfo);
+ ec.Report.Error (1546, loc, "Property `{0}' is not supported by the C# language. Try to call the accessor method `{1}' directly",
Name, sig.ToString ());
}
public bool IsAccessibleFrom (Type invocation_type, bool lvalue)
{
bool dummy;
- MethodInfo accessor = lvalue ? setter : getter;
+ var accessor = lvalue ? setter : getter;
if (accessor == null && lvalue)
accessor = getter;
return accessor != null && IsAccessorAccessible (invocation_type, accessor, out dummy);
return t_name_len > 2 && t_name [t_name_len - 2] == '[';
}
- override public Expression DoResolve (EmitContext ec)
+ protected override Expression DoResolve (ResolveContext ec)
{
- if (resolved)
- return this;
-
- if (getter != null){
- if (TypeManager.GetParameterData (getter).Count != 0){
- Error_PropertyNotFound (getter, true);
- return null;
- }
- }
+ eclass = ExprClass.PropertyAccess;
- if (getter == null){
- //
- // The following condition happens if the PropertyExpr was
- // created, but is invalid (ie, the property is inaccessible),
- // and we did not want to embed the knowledge about this in
- // the caller routine. This only avoids double error reporting.
- //
- if (setter == null)
- return null;
+ bool must_do_cs1540_check = false;
+ ec.Report.DisableReporting ();
+ bool res = ResolveGetter (ec, ref must_do_cs1540_check);
+ ec.Report.EnableReporting ();
- if (InstanceExpression != EmptyExpression.Null) {
- Report.Error (154, loc, "The property or indexer `{0}' cannot be used in this context because it lacks the `get' accessor",
- TypeManager.GetFullNameSignature (PropertyInfo));
- return null;
+ if (!res) {
+ if (InstanceExpression != null) {
+ Type expr_type = InstanceExpression.Type;
+ ExtensionMethodGroupExpr ex_method_lookup = ec.LookupExtensionMethod (expr_type, Name, loc);
+ if (ex_method_lookup != null) {
+ ex_method_lookup.ExtensionExpression = InstanceExpression;
+ ex_method_lookup.SetTypeArguments (ec, targs);
+ return ex_method_lookup.Resolve (ec);
+ }
}
- }
- bool must_do_cs1540_check = false;
- if (getter != null &&
- !IsAccessorAccessible (ec.ContainerType, getter, out must_do_cs1540_check)) {
- PropertyBase.PropertyMethod pm = TypeManager.GetMethod (getter) as PropertyBase.PropertyMethod;
- if (pm != null && pm.HasCustomAccessModifier) {
- Report.SymbolRelatedToPreviousError (pm);
- Report.Error (271, loc, "The property or indexer `{0}' cannot be used in this context because the get accessor is inaccessible",
- TypeManager.CSharpSignature (getter));
- }
- else {
- Report.SymbolRelatedToPreviousError (getter);
- ErrorIsInaccesible (loc, TypeManager.CSharpSignature (getter));
- }
+ ResolveGetter (ec, ref must_do_cs1540_check);
return null;
}
-
+
if (!InstanceResolve (ec, false, must_do_cs1540_check))
return null;
// Only base will allow this invocation to happen.
//
if (IsBase && getter.IsAbstract) {
- Error_CannotCallAbstractBase (TypeManager.GetFullNameSignature (PropertyInfo));
+ Error_CannotCallAbstractBase (ec, TypeManager.GetFullNameSignature (spec.MetaInfo));
}
- if (PropertyInfo.PropertyType.IsPointer && !ec.InUnsafe){
- UnsafeError (loc);
+ if (spec.PropertyType.IsPointer && !ec.IsUnsafe){
+ UnsafeError (ec, loc);
}
- if (!ec.IsInObsoleteScope) {
- PropertyBase pb = TypeManager.GetProperty (PropertyInfo);
+ if (!ec.IsObsolete) {
+ PropertyBase pb = TypeManager.GetProperty (spec.MetaInfo);
if (pb != null) {
pb.CheckObsoleteness (loc);
} else {
- ObsoleteAttribute oa = AttributeTester.GetMemberObsoleteAttribute (PropertyInfo);
+ ObsoleteAttribute oa = AttributeTester.GetMemberObsoleteAttribute (spec.MetaInfo);
if (oa != null)
- AttributeTester.Report_ObsoleteMessage (oa, GetSignatureForError (), loc);
+ AttributeTester.Report_ObsoleteMessage (oa, GetSignatureForError (), loc, ec.Report);
}
}
- resolved = true;
-
return this;
}
- override public Expression DoResolveLValue (EmitContext ec, Expression right_side)
+ override public Expression DoResolveLValue (ResolveContext ec, Expression right_side)
{
- if (right_side == EmptyExpression.OutAccess) {
- if (ec.CurrentBlock.Toplevel.GetParameterReference (PropertyInfo.Name, loc) is MemberAccess) {
- Report.Error (1939, loc, "A range variable `{0}' may not be passes as `ref' or `out' parameter",
- PropertyInfo.Name);
+ eclass = ExprClass.PropertyAccess;
+
+ if (right_side == EmptyExpression.OutAccess.Instance) {
+ if (ec.CurrentBlock.Toplevel.GetParameterReference (spec.Name, loc) is MemberAccess) {
+ ec.Report.Error (1939, loc, "A range variable `{0}' may not be passes as `ref' or `out' parameter",
+ spec.Name);
} else {
- Report.Error (206, loc, "A property or indexer `{0}' may not be passed as `ref' or `out' parameter",
- GetSignatureForError ());
+ right_side.DoResolveLValue (ec, this);
}
return null;
}
if (getter == null)
return null;
- if (ec.CurrentBlock.Toplevel.GetParameterReference (PropertyInfo.Name, loc) is MemberAccess) {
- Report.Error (1947, loc, "A range variable `{0}' cannot be assigned to. Consider using `let' clause to store the value",
- PropertyInfo.Name);
+ if (ec.CurrentBlock.Toplevel.GetParameterReference (spec.Name, loc) is MemberAccess) {
+ ec.Report.Error (1947, loc, "A range variable `{0}' cannot be assigned to. Consider using `let' clause to store the value",
+ spec.Name);
} else {
- Report.Error (200, loc, "Property or indexer `{0}' cannot be assigned to (it is read only)",
+ ec.Report.Error (200, loc, "Property or indexer `{0}' cannot be assigned to (it is read only)",
GetSignatureForError ());
}
return null;
}
- if (TypeManager.GetParameterData (setter).Count != 1){
- Error_PropertyNotFound (setter, false);
+ if (targs != null) {
+ base.SetTypeArguments (ec, targs);
+ return null;
+ }
+
+ if (setter.Parameters.Count != 1){
+ Error_PropertyNotFound (ec, setter, false);
return null;
}
bool must_do_cs1540_check;
- if (!IsAccessorAccessible (ec.ContainerType, setter, out must_do_cs1540_check)) {
- PropertyBase.PropertyMethod pm = TypeManager.GetMethod (setter) as PropertyBase.PropertyMethod;
+ if (!IsAccessorAccessible (ec.CurrentType, setter, out must_do_cs1540_check)) {
+ PropertyBase.PropertyMethod pm = TypeManager.GetMethod (setter.MetaInfo) as PropertyBase.PropertyMethod;
if (pm != null && pm.HasCustomAccessModifier) {
- Report.SymbolRelatedToPreviousError (pm);
- Report.Error (272, loc, "The property or indexer `{0}' cannot be used in this context because the set accessor is inaccessible",
+ ec.Report.SymbolRelatedToPreviousError (pm);
+ ec.Report.Error (272, loc, "The property or indexer `{0}' cannot be used in this context because the set accessor is inaccessible",
TypeManager.CSharpSignature (setter));
}
else {
- Report.SymbolRelatedToPreviousError (setter);
- ErrorIsInaccesible (loc, TypeManager.CSharpSignature (setter));
+ ec.Report.SymbolRelatedToPreviousError (setter.MetaInfo);
+ ErrorIsInaccesible (loc, TypeManager.CSharpSignature (setter), ec.Report);
}
return null;
}
- if (!InstanceResolve (ec, TypeManager.IsStruct (PropertyInfo.DeclaringType), must_do_cs1540_check))
+ if (!InstanceResolve (ec, TypeManager.IsStruct (spec.DeclaringType), must_do_cs1540_check))
return null;
//
// Only base will allow this invocation to happen.
//
if (IsBase && setter.IsAbstract){
- Error_CannotCallAbstractBase (TypeManager.GetFullNameSignature (PropertyInfo));
+ Error_CannotCallAbstractBase (ec, TypeManager.GetFullNameSignature (spec.MetaInfo));
}
- if (PropertyInfo.PropertyType.IsPointer && !ec.InUnsafe) {
- UnsafeError (loc);
+ if (spec.PropertyType.IsPointer && !ec.IsUnsafe) {
+ UnsafeError (ec, loc);
}
- if (!ec.IsInObsoleteScope) {
- PropertyBase pb = TypeManager.GetProperty (PropertyInfo);
+ if (!ec.IsObsolete) {
+ PropertyBase pb = TypeManager.GetProperty (spec.MetaInfo);
if (pb != null) {
pb.CheckObsoleteness (loc);
} else {
- ObsoleteAttribute oa = AttributeTester.GetMemberObsoleteAttribute (PropertyInfo);
+ ObsoleteAttribute oa = AttributeTester.GetMemberObsoleteAttribute (spec.MetaInfo);
if (oa != null)
- AttributeTester.Report_ObsoleteMessage (oa, GetSignatureForError (), loc);
+ AttributeTester.Report_ObsoleteMessage (oa, GetSignatureForError (), loc, ec.Report);
}
}
temp.Release (ec);
}
}
+
+ bool ResolveGetter (ResolveContext ec, ref bool must_do_cs1540_check)
+ {
+ if (targs != null) {
+ base.SetTypeArguments (ec, targs);
+ return false;
+ }
+
+ if (getter != null) {
+ if (!getter.Parameters.IsEmpty) {
+ Error_PropertyNotFound (ec, getter, true);
+ return false;
+ }
+ }
+
+ if (getter == null) {
+ //
+ // The following condition happens if the PropertyExpr was
+ // created, but is invalid (ie, the property is inaccessible),
+ // and we did not want to embed the knowledge about this in
+ // the caller routine. This only avoids double error reporting.
+ //
+ if (setter == null)
+ return false;
+
+ if (InstanceExpression != EmptyExpression.Null) {
+ ec.Report.Error (154, loc, "The property or indexer `{0}' cannot be used in this context because it lacks the `get' accessor",
+ TypeManager.GetFullNameSignature (spec.MetaInfo));
+ return false;
+ }
+ }
+
+ if (getter != null &&
+ !IsAccessorAccessible (ec.CurrentType, getter, out must_do_cs1540_check)) {
+ PropertyBase.PropertyMethod pm = TypeManager.GetMethod (getter.MetaInfo) as PropertyBase.PropertyMethod;
+ if (pm != null && pm.HasCustomAccessModifier) {
+ ec.Report.SymbolRelatedToPreviousError (pm);
+ ec.Report.Error (271, loc, "The property or indexer `{0}' cannot be used in this context because the get accessor is inaccessible",
+ TypeManager.CSharpSignature (getter.MetaInfo));
+ } else {
+ ec.Report.SymbolRelatedToPreviousError (getter.MetaInfo);
+ ErrorIsInaccesible (loc, TypeManager.CSharpSignature (getter.MetaInfo), ec.Report);
+ }
+
+ return false;
+ }
+
+ return true;
+ }
+
+ public override void SetTypeArguments (ResolveContext ec, TypeArguments ta)
+ {
+ targs = ta;
+ }
}
/// <summary>
/// Fully resolved expression that evaluates to an Event
/// </summary>
- public class EventExpr : MemberExpr {
- public readonly EventInfo EventInfo;
-
- bool is_static;
- MethodInfo add_accessor, remove_accessor;
+ public class EventExpr : MemberExpr
+ {
+ readonly EventSpec spec;
- public EventExpr (EventInfo ei, Location loc)
+ public EventExpr (EventSpec spec, Location loc)
{
- EventInfo = ei;
+ this.spec = spec;
this.loc = loc;
- eclass = ExprClass.EventAccess;
-
- add_accessor = TypeManager.GetAddMethod (ei);
- remove_accessor = TypeManager.GetRemoveMethod (ei);
- if (add_accessor.IsStatic || remove_accessor.IsStatic)
- is_static = true;
-
- if (EventInfo is MyEventBuilder){
- MyEventBuilder eb = (MyEventBuilder) EventInfo;
- type = eb.EventType;
- eb.SetUsed ();
- } else
- type = EventInfo.EventHandlerType;
}
public override string Name {
get {
- return EventInfo.Name;
+ return spec.Name;
}
}
public override bool IsInstance {
get {
- return !is_static;
+ return !spec.IsStatic;
}
}
public override bool IsStatic {
get {
- return is_static;
+ return spec.IsStatic;
}
}
public override Type DeclaringType {
get {
- return EventInfo.DeclaringType;
+ return spec.DeclaringType;
}
}
- void Error_AssignmentEventOnly ()
+ public void Error_AssignmentEventOnly (ResolveContext ec)
{
- Report.Error (79, loc, "The event `{0}' can only appear on the left hand side of `+=' or `-=' operator",
+ ec.Report.Error (79, loc, "The event `{0}' can only appear on the left hand side of `+=' or `-=' operator",
GetSignatureForError ());
}
- public override MemberExpr ResolveMemberAccess (EmitContext ec, Expression left, Location loc,
+ public override MemberExpr ResolveMemberAccess (ResolveContext ec, Expression left, Location loc,
SimpleName original)
{
//
// If the event is local to this class, we transform ourselves into a FieldExpr
//
- if (EventInfo.DeclaringType == ec.ContainerType ||
- TypeManager.IsNestedChildOf(ec.ContainerType, EventInfo.DeclaringType)) {
- EventField mi = TypeManager.GetEventField (EventInfo);
+ if (spec.DeclaringType == ec.CurrentType ||
+ TypeManager.IsNestedChildOf(ec.CurrentType, spec.DeclaringType)) {
+
+ // TODO: Breaks dynamic binder as currect context fields are imported and not compiled
+ EventField mi = TypeManager.GetEventField (spec.MetaInfo).MemberDefinition as EventField;
- if (mi != null) {
- if (!ec.IsInObsoleteScope)
+ if (mi != null && mi.HasBackingField) {
+ mi.SetIsUsed ();
+ if (!ec.IsObsolete)
mi.CheckObsoleteness (loc);
- if ((mi.ModFlags & (Modifiers.ABSTRACT | Modifiers.EXTERN)) != 0 && !ec.IsInCompoundAssignment)
- Error_AssignmentEventOnly ();
+ if ((mi.ModFlags & (Modifiers.ABSTRACT | Modifiers.EXTERN)) != 0 && !ec.HasSet (ResolveContext.Options.CompoundAssignmentScope))
+ Error_AssignmentEventOnly (ec);
- FieldExpr ml = new FieldExpr (mi.BackingField.FieldBuilder, loc);
+ FieldExpr ml = new FieldExpr (mi.BackingField, loc);
InstanceExpression = null;
return ml.ResolveMemberAccess (ec, left, loc, original);
}
}
-
- if (left is This && !ec.IsInCompoundAssignment)
- Error_AssignmentEventOnly ();
+
+ if (left is This && !ec.HasSet (ResolveContext.Options.CompoundAssignmentScope))
+ Error_AssignmentEventOnly (ec);
return base.ResolveMemberAccess (ec, left, loc, original);
}
- bool InstanceResolve (EmitContext ec, bool must_do_cs1540_check)
+ bool InstanceResolve (ResolveContext ec, bool must_do_cs1540_check)
{
- if (is_static) {
+ if (IsStatic) {
InstanceExpression = null;
return true;
}
return false;
}
- InstanceExpression = InstanceExpression.DoResolve (ec);
+ InstanceExpression = InstanceExpression.Resolve (ec);
if (InstanceExpression == null)
return false;
- if (IsBase && add_accessor.IsAbstract) {
- Error_CannotCallAbstractBase(TypeManager.CSharpSignature(add_accessor));
+ if (IsBase && spec.IsAbstract) {
+ Error_CannotCallAbstractBase (ec, TypeManager.CSharpSignature(spec.MetaInfo));
return false;
}
// TODO: Exact copy from PropertyExpr
//
if (must_do_cs1540_check && InstanceExpression != EmptyExpression.Null &&
- !TypeManager.IsInstantiationOfSameGenericType (InstanceExpression.Type, ec.ContainerType) &&
- !TypeManager.IsNestedChildOf (ec.ContainerType, InstanceExpression.Type) &&
- !TypeManager.IsSubclassOf (InstanceExpression.Type, ec.ContainerType)) {
- Report.SymbolRelatedToPreviousError (EventInfo);
- ErrorIsInaccesible (loc, TypeManager.CSharpSignature (EventInfo));
+ !TypeManager.IsInstantiationOfSameGenericType (InstanceExpression.Type, ec.CurrentType) &&
+ !TypeManager.IsNestedChildOf (ec.CurrentType, InstanceExpression.Type) &&
+ !TypeManager.IsSubclassOf (InstanceExpression.Type, ec.CurrentType)) {
+ ec.Report.SymbolRelatedToPreviousError (spec.MetaInfo);
+ ErrorIsInaccesible (loc, TypeManager.CSharpSignature (spec.MetaInfo), ec.Report);
return false;
}
public bool IsAccessibleFrom (Type invocation_type)
{
bool dummy;
- return IsAccessorAccessible (invocation_type, add_accessor, out dummy) &&
- IsAccessorAccessible (invocation_type, remove_accessor, out dummy);
+ return IsAccessorAccessible (invocation_type, spec.AccessorAdd, out dummy) &&
+ IsAccessorAccessible (invocation_type, spec.AccessorRemove, out dummy);
}
- public override Expression CreateExpressionTree (EmitContext ec)
+ public override Expression CreateExpressionTree (ResolveContext ec)
{
throw new NotSupportedException ("ET");
}
- public override Expression DoResolveLValue (EmitContext ec, Expression right_side)
+ public override Expression DoResolveLValue (ResolveContext ec, Expression right_side)
{
// contexts where an LValue is valid have already devolved to FieldExprs
- Error_CannotAssign ();
+ Error_CannotAssign (ec);
return null;
}
- public override Expression DoResolve (EmitContext ec)
+ protected override Expression DoResolve (ResolveContext ec)
{
+ eclass = ExprClass.EventAccess;
+
bool must_do_cs1540_check;
- if (!(IsAccessorAccessible (ec.ContainerType, add_accessor, out must_do_cs1540_check) &&
- IsAccessorAccessible (ec.ContainerType, remove_accessor, out must_do_cs1540_check))) {
- Report.SymbolRelatedToPreviousError (EventInfo);
- ErrorIsInaccesible (loc, TypeManager.CSharpSignature (EventInfo));
+ if (!(IsAccessorAccessible (ec.CurrentType, spec.AccessorAdd, out must_do_cs1540_check) &&
+ IsAccessorAccessible (ec.CurrentType, spec.AccessorRemove, out must_do_cs1540_check))) {
+ ec.Report.SymbolRelatedToPreviousError (spec.MetaInfo);
+ ErrorIsInaccesible (loc, TypeManager.CSharpSignature (spec.MetaInfo), ec.Report);
return null;
}
if (!InstanceResolve (ec, must_do_cs1540_check))
return null;
- if (!ec.IsInCompoundAssignment) {
- Error_CannotAssign ();
+ if (!ec.HasSet (ResolveContext.Options.CompoundAssignmentScope)) {
+ Error_CannotAssign (ec);
return null;
}
- if (!ec.IsInObsoleteScope) {
- EventField ev = TypeManager.GetEventField (EventInfo);
- if (ev != null) {
- ev.CheckObsoleteness (loc);
- } else {
- ObsoleteAttribute oa = AttributeTester.GetMemberObsoleteAttribute (EventInfo);
- if (oa != null)
- AttributeTester.Report_ObsoleteMessage (oa, GetSignatureForError (), loc);
- }
+ if (!ec.IsObsolete) {
+ var oa = spec.GetObsoleteAttribute ();
+ if (oa != null)
+ AttributeTester.Report_ObsoleteMessage (oa, GetSignatureForError (), loc, ec.Report);
}
+
+ spec.MemberDefinition.SetIsUsed ();
+ type = spec.EventType;
return this;
}
public override void Emit (EmitContext ec)
{
- Error_CannotAssign ();
+ throw new NotSupportedException ();
+ //Error_CannotAssign ();
}
- public void Error_CannotAssign ()
+ public void Error_CannotAssign (ResolveContext ec)
{
- Report.Error (70, loc,
+ ec.Report.Error (70, loc,
"The event `{0}' can only appear on the left hand side of += or -= when used outside of the type `{1}'",
- GetSignatureForError (), TypeManager.CSharpName (EventInfo.DeclaringType));
+ GetSignatureForError (), TypeManager.CSharpName (spec.DeclaringType));
}
public override string GetSignatureForError ()
{
- return TypeManager.CSharpSignature (EventInfo);
+ return TypeManager.CSharpSignature (spec.MetaInfo);
}
public void EmitAddOrRemove (EmitContext ec, bool is_add, Expression source)
{
Arguments args = new Arguments (1);
args.Add (new Argument (source));
- Invocation.EmitCall (ec, IsBase, InstanceExpression, is_add ? add_accessor : remove_accessor, args, loc);
+ Invocation.EmitCall (ec, IsBase, InstanceExpression,
+ is_add ? spec.AccessorAdd : spec.AccessorRemove,
+ args, loc);
}
}
{
this.type = type;
this.loc = loc;
- eclass = ExprClass.Variable;
}
- public override Expression CreateExpressionTree (EmitContext ec)
+ public override Expression CreateExpressionTree (ResolveContext ec)
{
throw new NotSupportedException ("ET");
}
- public override Expression DoResolve (EmitContext ec)
+ protected override Expression DoResolve (ResolveContext ec)
{
- if (li != null)
- return this;
+ eclass = ExprClass.Variable;
TypeExpr te = new TypeExpression (type, loc);
li = ec.CurrentBlock.AddTemporaryVariable (te, loc);
return this;
}
- public override Expression DoResolveLValue (EmitContext ec, Expression right_side)
+ public override Expression DoResolveLValue (ResolveContext ec, Expression right_side)
{
- return DoResolve (ec);
+ return Resolve (ec);
}
public override void Emit (EmitContext ec)
EmitAssign (ec, source, false, false);
}
- public override HoistedVariable GetHoistedVariable (EmitContext ec)
+ public override HoistedVariable GetHoistedVariable (AnonymousExpression ae)
{
- return li.HoistedVariableReference;
+ return li.HoistedVariant;
}
public override bool IsFixed {
class VarExpr : SimpleName
{
// Used for error reporting only
- ArrayList initializer;
+ int initializers_count;
public VarExpr (Location loc)
: base ("var", loc)
{
+ initializers_count = 1;
}
- public ArrayList VariableInitializer {
+ public int VariableInitializersCount {
set {
- this.initializer = value;
+ this.initializers_count = value;
}
}
- public bool InferType (EmitContext ec, Expression right_side)
+ public bool InferType (ResolveContext ec, Expression right_side)
{
if (type != null)
throw new InternalErrorException ("An implicitly typed local variable could not be redefined");
type = right_side.Type;
- if (type == TypeManager.null_type || type == TypeManager.void_type || type == InternalType.AnonymousMethod) {
- Report.Error (815, loc, "An implicitly typed local variable declaration cannot be initialized with `{0}'",
+ if (type == TypeManager.null_type || type == TypeManager.void_type || type == InternalType.AnonymousMethod || type == InternalType.MethodGroup) {
+ ec.Report.Error (815, loc, "An implicitly typed local variable declaration cannot be initialized with `{0}'",
right_side.GetSignatureForError ());
return false;
}
return true;
}
- protected override void Error_TypeOrNamespaceNotFound (IResolveContext ec)
+ protected override void Error_TypeOrNamespaceNotFound (IMemberContext ec)
{
if (RootContext.Version < LanguageVersion.V_3)
base.Error_TypeOrNamespaceNotFound (ec);
else
- Report.Error (825, loc, "The contextual keyword `var' may only appear within a local variable declaration");
+ ec.Compiler.Report.Error (825, loc, "The contextual keyword `var' may only appear within a local variable declaration");
}
- public override TypeExpr ResolveAsContextualType (IResolveContext rc, bool silent)
+ public override TypeExpr ResolveAsContextualType (IMemberContext rc, bool silent)
{
TypeExpr te = base.ResolveAsContextualType (rc, true);
if (te != null)
return te;
if (RootContext.Version < LanguageVersion.V_3)
- Report.FeatureIsNotAvailable (loc, "implicitly typed local variable");
+ rc.Compiler.Report.FeatureIsNotAvailable (loc, "implicitly typed local variable");
- if (initializer == null)
+ if (initializers_count == 1)
return null;
- if (initializer.Count > 1) {
- Location loc_init = ((CSharpParser.VariableDeclaration) initializer[1]).Location;
- Report.Error (819, loc_init, "An implicitly typed local variable declaration cannot include multiple declarators");
- initializer = null;
+ if (initializers_count > 1) {
+ rc.Compiler.Report.Error (819, loc, "An implicitly typed local variable declaration cannot include multiple declarators");
+ initializers_count = 1;
return null;
}
- Expression variable_initializer = ((CSharpParser.VariableDeclaration) initializer[0]).expression_or_array_initializer;
- if (variable_initializer == null) {
- Report.Error (818, loc, "An implicitly typed local variable declarator must include an initializer");
+ if (initializers_count == 0) {
+ initializers_count = 1;
+ rc.Compiler.Report.Error (818, loc, "An implicitly typed local variable declarator must include an initializer");
return null;
}