//
//
+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;
-
-#if NET_4_0
- using SLE = System.Linq.Expressions;
-#endif
/// <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,
-
}
//
/// </remarks>
public abstract class Expression {
public ExprClass eclass;
- protected Type type;
+ protected TypeSpec type;
protected Location loc;
- public Type Type {
+ public TypeSpec Type {
get { return type; }
set { type = value; }
}
{
}
- public virtual bool GetAttributableValue (ResolveContext ec, Type value_type, out object value)
- {
- Attribute.Error_AttributeArgumentNotValid (ec, loc);
- value = null;
- return false;
- }
-
public virtual string GetSignatureForError ()
{
- return TypeManager.CSharpName (type);
+ return type.GetDefinition ().GetSignatureForError ();
}
- public static bool IsAccessorAccessible (Type invocation_type, MethodInfo mi, out bool must_do_cs1540_check)
+ public static bool IsMemberAccessible (TypeSpec invocation_type, MemberSpec 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)
- return TypeManager.IsPrivateAccessible (invocation_type, mi.DeclaringType) ||
+ if (ma == Modifiers.PRIVATE)
+ return invocation_type.MemberDefinition == mi.DeclaringType.MemberDefinition ||
TypeManager.IsNestedChildOf (invocation_type, mi.DeclaringType);
- if (TypeManager.IsThisOrFriendAssembly (invocation_type.Assembly, 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 == InternalType.FakeInternalType ?
+ CodeGen.Assembly.Builder : 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 (ResolveContext ec);
+ protected abstract Expression DoResolve (ResolveContext rc);
- public virtual Expression DoResolveLValue (ResolveContext ec, Expression right_side)
+ public virtual Expression DoResolveLValue (ResolveContext rc, Expression right_side)
{
return null;
}
// value will be returned if the expression is not a type
// reference
//
- public virtual TypeExpr ResolveAsTypeTerminal (IMemberContext ec, bool silent)
- {
- TypeExpr te = ResolveAsBaseTerminal (ec, silent);
- if (te == null)
- return null;
-
- if (!silent) { // && !(te is TypeParameterExpr)) {
- ObsoleteAttribute obsolete_attr = AttributeTester.GetObsoleteAttribute (te.Type);
- 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) {
- //
- // 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;
- }
-
- // TODO: silent flag is ignored
- ct.CheckConstraints (ec);
- }
-
- return te;
- }
-
- public TypeExpr ResolveAsBaseTerminal (IMemberContext ec, bool silent)
+ public virtual TypeExpr ResolveAsTypeTerminal (IMemberContext ec , bool silent)
{
int errors = ec.Compiler.Report.Errors;
if (!te.CheckAccessLevel (ec)) {
ec.Compiler.Report.SymbolRelatedToPreviousError (te.Type);
ErrorIsInaccesible (loc, TypeManager.CSharpName (te.Type), ec.Compiler.Report);
- return null;
}
te.loc = loc;
+
+ //
+ // Obsolete checks cannot be done when resolving base context as they
+ // require type dependecies to be set but we are just resolving them
+ //
+ if (!silent && !(ec is TypeContainer.BaseContext)) {
+ ObsoleteAttribute obsolete_attr = te.Type.GetAttributeObsolete ();
+ if (obsolete_attr != null && !ec.IsObsolete) {
+ AttributeTester.Report_ObsoleteMessage (obsolete_attr, te.GetSignatureForError (), Location, ec.Compiler.Report);
+ }
+ }
+
return te;
}
-
+
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 (ResolveContext ec, Location loc, MemberInfo m, Type qualifier, Type container)
+ protected static void Error_CannotAccessProtected (ResolveContext ec, Location loc, MemberSpec m, TypeSpec qualifier, TypeSpec container)
{
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),
+ m.GetSignatureForError (),
TypeManager.CSharpName (qualifier),
TypeManager.CSharpName (container));
}
+ public void Error_ExpressionMustBeConstant (ResolveContext rc, Location loc, string e_name)
+ {
+ rc.Report.Error (133, loc, "The expression being assigned to `{0}' must be constant", e_name);
+ }
+
+ public void Error_ConstantCanBeInitializedWithNullOnly (ResolveContext rc, TypeSpec type, Location loc, string name)
+ {
+ rc.Report.Error (134, loc, "A constant `{0}' of reference type `{1}' can only be initialized with null",
+ name, TypeManager.CSharpName (type));
+ }
+
public static void Error_InvalidExpressionStatement (Report Report, Location loc)
{
Report.Error (201, loc, "Only assignment, call, increment, decrement, and new object " +
Report.Error (1547, loc, "Keyword `void' cannot be used in this context");
}
- public virtual void Error_ValueCannotBeConverted (ResolveContext ec, Location loc, Type target, bool expl)
+ public virtual void Error_ValueCannotBeConverted (ResolveContext ec, Location loc, TypeSpec target, bool expl)
{
Error_ValueCannotBeConvertedCore (ec, loc, target, expl);
}
- protected void Error_ValueCannotBeConvertedCore (ResolveContext ec, Location loc, Type target, bool expl)
+ protected void Error_ValueCannotBeConvertedCore (ResolveContext ec, Location loc, TypeSpec 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) {
string sig1 = type.DeclaringMethod == null ?
TypeManager.CSharpName (type.DeclaringType) :
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));
- } else if (Type.FullName == target.FullName){
+ } else if (Type.MetaInfo.FullName == target.MetaInfo.FullName) {
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));
+ Type.MetaInfo.FullName, Type.Assembly.FullName, target.Assembly.FullName));
}
-
+*/
if (expl) {
ec.Report.Error (30, loc, "Cannot convert type `{0}' to `{1}'",
TypeManager.CSharpName (type), TypeManager.CSharpName (target));
}
ec.Report.Error (29, loc, "Cannot implicitly convert type `{0}' to `{1}'",
- TypeManager.CSharpName (type),
- TypeManager.CSharpName (target));
+ type.GetSignatureForError (), target.GetSignatureForError ());
}
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);
}
- public void Error_TypeArgumentsCannotBeUsed (Report report, Location loc)
+ public void Error_TypeArgumentsCannotBeUsed (Report report, Location loc, MemberSpec member, int arity)
{
// Better message for possible generic expressions
- if (eclass == ExprClass.MethodGroup || eclass == ExprClass.Type) {
- if (this is TypeExpr)
- report.SymbolRelatedToPreviousError (type);
+ if (member != null && (member.Kind & MemberKind.GenericMask) != 0) {
+ report.SymbolRelatedToPreviousError (member);
+ if (member is TypeSpec)
+ member = ((TypeSpec) member).GetDefinition ();
+ else
+ member = ((MethodSpec) member).GetGenericMethodDefinition ();
- 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 ());
+ string name = member.Kind == MemberKind.Method ? "method" : "type";
+ if (member.IsGeneric) {
+ report.Error (305, loc, "Using the generic {0} `{1}' requires `{2}' type argument(s)",
+ name, member.GetSignatureForError (), member.Arity.ToString ());
+ } else {
+ report.Error (308, loc, "The non-generic {0} `{1}' cannot be used with the type arguments",
+ name, member.GetSignatureForError ());
+ }
} else {
report.Error (307, loc, "The {0} `{1}' cannot be used with type arguments",
ExprClassName, GetSignatureForError ());
}
}
- protected virtual void Error_TypeDoesNotContainDefinition (ResolveContext ec, Type type, string name)
+ protected virtual void Error_TypeDoesNotContainDefinition (ResolveContext ec, TypeSpec type, string name)
{
Error_TypeDoesNotContainDefinition (ec, loc, type, name);
}
- public static void Error_TypeDoesNotContainDefinition (ResolveContext ec, Location loc, Type type, string name)
+ public static void Error_TypeDoesNotContainDefinition (ResolveContext ec, Location loc, TypeSpec type, string name)
{
ec.Report.SymbolRelatedToPreviousError (type);
ec.Report.Error (117, loc, "`{0}' does not contain a definition for `{1}'",
ec.Report.Error (131, loc, "The left-hand side of an assignment must be a variable, a property or an indexer");
}
- ResolveFlags ExprClassToResolveFlags
- {
+ public ResolveFlags ExprClassToResolveFlags {
get {
switch (eclass) {
case ExprClass.Type:
/// </remarks>
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);
+ try {
+ e = DoResolve (ec);
+
+ if (e == null)
+ return null;
+
+ if ((flags & e.ExprClassToResolveFlags) == 0) {
+ e.Error_UnexpectedKind (ec, flags, loc);
+ return null;
}
- }
- if (e == null)
- return null;
+ if (e.type == null)
+ throw new InternalErrorException ("Expression `{0}' didn't set its type in DoResolve", e.GetType ());
- if ((flags & e.ExprClassToResolveFlags) == 0) {
- e.Error_UnexpectedKind (ec, flags, loc);
- return null;
- }
+ return e;
+ } catch (Exception ex) {
+ if (loc.IsNull || Report.DebugFlags > 0 || ex is CompletionResult || ec.Report.IsDisabled)
+ throw;
- 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 ());
+ ec.Report.Error (584, loc, "Internal compiler error: {0}", ex.Message);
+ return EmptyExpression.Null;
}
-
- return e;
}
/// <summary>
/// Resolves an expression and performs semantic analysis on it.
/// </summary>
- public Expression Resolve (ResolveContext ec)
- {
- Expression e = Resolve (ec, ResolveFlags.VariableOrValue | ResolveFlags.MethodGroup);
-
- if (e != null && e.eclass == ExprClass.MethodGroup && RootContext.Version == LanguageVersion.ISO_1) {
- ((MethodGroupExpr) e).ReportUsageError (ec);
- return null;
- }
- return e;
- }
-
- public Constant ResolveAsConstant (ResolveContext ec, MemberCore mc)
+ public Expression Resolve (ResolveContext rc)
{
- 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 (), ec.Report);
- else
- Const.Error_ExpressionMustBeConstant (loc, mc.GetSignatureForError (), ec.Report);
-
- return null;
+ return Resolve (rc, ResolveFlags.VariableOrValue | ResolveFlags.MethodGroup);
}
/// <summary>
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))
return e;
}
+ public virtual void EncodeAttributeValue (IMemberContext rc, AttributeEncoder enc, TypeSpec targetType)
+ {
+ Attribute.Error_AttributeArgumentNotValid (rc, loc);
+ }
+
/// <summary>
/// Emits the code for the expression
/// </summary>
/// </remarks>
public abstract void Emit (EmitContext ec);
+
// Emit code to branch to @target if this expression is equivalent to @on_true.
// The default implementation is to emit the value, and then emit a brtrue or brfalse.
// Subclasses can provide more efficient implementations, but those MUST be equivalent,
public virtual void EmitBranchable (EmitContext ec, Label target, bool on_true)
{
Emit (ec);
- ec.ig.Emit (on_true ? OpCodes.Brtrue : OpCodes.Brfalse, target);
+ ec.Emit (on_true ? OpCodes.Brtrue : OpCodes.Brfalse, target);
}
// Emit this expression for its side effects, not for its value.
public virtual void EmitSideEffect (EmitContext ec)
{
Emit (ec);
- ec.ig.Emit (OpCodes.Pop);
+ ec.Emit (OpCodes.Pop);
}
/// <summary>
protected Expression ()
{
- eclass = ExprClass.Invalid;
- type = null;
}
/// <summary>
/// Returns a fully formed expression after a MemberLookup
/// </summary>
///
- public static Expression ExprClassFromMemberInfo (Type container_type, MemberInfo mi, Location loc)
- {
- if (mi is EventInfo)
- return new EventExpr ((EventInfo) mi, loc);
- else if (mi is FieldInfo) {
- FieldInfo fi = (FieldInfo) mi;
- if (fi.IsLiteral || (fi.IsInitOnly && fi.FieldType == TypeManager.decimal_type))
- return new ConstantExpr (fi, loc);
- return new FieldExpr (fi, loc);
- } else if (mi is PropertyInfo)
- return new PropertyExpr (container_type, (PropertyInfo) mi, loc);
- else if (mi is Type) {
- return new TypeExpression ((System.Type) mi, loc);
- }
+ public static Expression ExprClassFromMemberInfo (TypeSpec container_type, MemberSpec spec, Location loc)
+ {
+ if (spec is EventSpec)
+ return new EventExpr ((EventSpec) spec, loc);
+ if (spec is ConstSpec)
+ return new ConstantExpr ((ConstSpec) spec, loc);
+ if (spec is FieldSpec)
+ return new FieldExpr ((FieldSpec) spec, loc);
+ if (spec is PropertySpec)
+ return new PropertyExpr ((PropertySpec) spec, loc);
+ if (spec is TypeSpec)
+ return new TypeExpression (((TypeSpec) spec), loc);
return null;
}
- // TODO: [Obsolete ("Can be removed")]
- protected static ArrayList almost_matched_members = new ArrayList (4);
-
//
// FIXME: Probably implement a cache for (t,name,current_access_set)?
//
// FIXME: Potential optimization, have a static ArrayList
//
- public static Expression MemberLookup (CompilerContext ctx, Type container_type, Type queried_type, string name,
- MemberTypes mt, BindingFlags bf, Location loc)
+ public static Expression MemberLookup (CompilerContext ctx, TypeSpec container_type, TypeSpec queried_type, string name, int arity,
+ MemberKind mt, BindingRestriction bf, Location loc)
{
- return MemberLookup (ctx, container_type, null, queried_type, name, mt, bf, loc);
+ return MemberLookup (ctx, container_type, null, queried_type, name, arity, mt, bf, loc);
}
//
// Lookup type `queried_type' for code in class `container_type' with a qualifier of
// `qualifier_type' or null to lookup members in the current class.
//
-
- public static Expression MemberLookup (CompilerContext ctx, Type container_type,
- Type qualifier_type, Type queried_type,
- string name, MemberTypes mt,
- BindingFlags bf, Location loc)
+ public static Expression MemberLookup (CompilerContext ctx, TypeSpec container_type,
+ TypeSpec qualifier_type, TypeSpec queried_type,
+ string name, int arity, MemberKind mt,
+ BindingRestriction binding, Location loc)
{
- almost_matched_members.Clear ();
-
- MemberInfo [] mi = TypeManager.MemberLookup (container_type, qualifier_type,
- queried_type, mt, bf, name, almost_matched_members);
-
+ var mi = TypeManager.MemberLookup (container_type, qualifier_type,
+ queried_type, mt, binding, name, arity, null);
if (mi == null)
return null;
- if (mi.Length > 1) {
- bool is_interface = qualifier_type != null && qualifier_type.IsInterface;
- ArrayList methods = new ArrayList (2);
- ArrayList non_methods = null;
-
- foreach (MemberInfo m in mi) {
- if (m is MethodBase) {
- methods.Add (m);
- continue;
- }
-
- if (non_methods == null)
- non_methods = new ArrayList (2);
-
- bool is_candidate = true;
- for (int i = 0; i < non_methods.Count; ++i) {
- MemberInfo n_m = (MemberInfo) 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;
- }
- }
-
- if (is_candidate) {
- non_methods.Add (m);
- }
- }
-
- if (methods.Count == 0 && non_methods != null && non_methods.Count > 1) {
- ctx.Report.SymbolRelatedToPreviousError ((MemberInfo)non_methods [1]);
- ctx.Report.SymbolRelatedToPreviousError ((MemberInfo)non_methods [0]);
- ctx.Report.Error (229, loc, "Ambiguity between `{0}' and `{1}'",
- TypeManager.GetFullNameSignature ((MemberInfo)non_methods [1]),
- TypeManager.GetFullNameSignature ((MemberInfo)non_methods [0]));
- return null;
- }
-
- if (methods.Count == 0)
- return ExprClassFromMemberInfo (container_type, (MemberInfo)non_methods [0], loc);
-
- if (non_methods != null && non_methods.Count > 0) {
- MethodBase method = (MethodBase) 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
- ctx.Report.SymbolRelatedToPreviousError (method);
- ctx.Report.SymbolRelatedToPreviousError (non_method);
- ctx.Report.Error (229, loc, "Ambiguity between `{0}' and `{1}'",
- TypeManager.GetFullNameSignature (non_method),
- TypeManager.CSharpSignature (method));
- return null;
- }
-
- if (is_interface) {
- ctx.Report.SymbolRelatedToPreviousError (method);
- 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), TypeManager.GetFullNameSignature (non_method));
- }
+ var first = mi [0];
+ if (mi.Count > 1) {
+ foreach (var mc in mi) {
+ if (mc is MethodSpec)
+ return new MethodGroupExpr (mi, queried_type, loc);
}
- return new MethodGroupExpr (methods, queried_type, loc);
+ ctx.Report.SymbolRelatedToPreviousError (mi [1]);
+ ctx.Report.SymbolRelatedToPreviousError (first);
+ ctx.Report.Error (229, loc, "Ambiguity between `{0}' and `{1}'",
+ first.GetSignatureForError (), mi [1].GetSignatureForError ());
}
- if (mi [0] is MethodBase)
+ if (first is MethodSpec)
return new MethodGroupExpr (mi, queried_type, loc);
- return ExprClassFromMemberInfo (container_type, mi [0], loc);
+ return ExprClassFromMemberInfo (container_type, first, loc);
}
- public const MemberTypes AllMemberTypes =
- MemberTypes.Constructor |
- MemberTypes.Event |
- MemberTypes.Field |
- MemberTypes.Method |
- MemberTypes.NestedType |
- MemberTypes.Property;
-
- public const BindingFlags AllBindingFlags =
- BindingFlags.Public |
- BindingFlags.Static |
- BindingFlags.Instance;
-
- public static Expression MemberLookup (CompilerContext ctx, Type container_type, Type queried_type,
- string name, Location loc)
+ public static Expression MemberLookup (CompilerContext ctx, TypeSpec container_type, TypeSpec queried_type,
+ string name, int arity, BindingRestriction binding, Location loc)
{
- return MemberLookup (ctx, container_type, null, queried_type, name,
- AllMemberTypes, AllBindingFlags, loc);
+ return MemberLookup (ctx, container_type, null, queried_type, name, arity,
+ MemberKind.All, binding | BindingRestriction.AccessibleOnly, loc);
}
- public static Expression MemberLookup (CompilerContext ctx, Type container_type, Type qualifier_type,
- Type queried_type, string name, Location loc)
+ public static Expression MemberLookup (CompilerContext ctx, TypeSpec container_type, TypeSpec qualifier_type,
+ TypeSpec queried_type, string name, int arity, BindingRestriction binding, Location loc)
{
return MemberLookup (ctx, container_type, qualifier_type, queried_type,
- name, AllMemberTypes, AllBindingFlags, loc);
- }
-
- public static MethodGroupExpr MethodLookup (CompilerContext ctx, Type container_type, Type queried_type,
- string name, Location loc)
- {
- return (MethodGroupExpr)MemberLookup (ctx, container_type, null, queried_type, name,
- MemberTypes.Method, AllBindingFlags, loc);
+ name, arity, MemberKind.All, binding | BindingRestriction.AccessibleOnly, loc);
}
/// <summary>
/// look for private members and display a useful debugging message if we
/// find it.
/// </summary>
- protected Expression MemberLookupFinal (ResolveContext ec, Type qualifier_type,
- Type queried_type, string name,
- MemberTypes mt, BindingFlags bf,
+ protected Expression MemberLookupFinal (ResolveContext ec, TypeSpec qualifier_type,
+ TypeSpec queried_type, string name, int arity,
+ MemberKind mt, BindingRestriction bf,
Location loc)
{
Expression e;
int errors = ec.Report.Errors;
- e = MemberLookup (ec.Compiler, ec.CurrentType, qualifier_type, queried_type, name, mt, bf, loc);
+ e = MemberLookup (ec.Compiler, ec.CurrentType, qualifier_type, queried_type, name, arity, mt, bf, loc);
if (e != null || errors != ec.Report.Errors)
return e;
// No errors were reported by MemberLookup, but there was an error.
return Error_MemberLookupFailed (ec, ec.CurrentType, qualifier_type, queried_type,
- name, null, mt, bf);
+ name, arity, null, mt, bf);
}
- 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)
+ protected virtual Expression Error_MemberLookupFailed (ResolveContext ec, TypeSpec container_type, TypeSpec qualifier_type,
+ TypeSpec queried_type, string name, int arity, string class_name,
+ MemberKind mt, BindingRestriction bf)
{
- MemberInfo[] lookup = null;
+ IList<MemberSpec> lookup = null;
if (queried_type == null) {
class_name = "global::";
} else {
+ BindingRestriction restriction = bf & BindingRestriction.DeclaredOnly;
+
lookup = TypeManager.MemberLookup (queried_type, null, queried_type,
- mt, (bf & ~BindingFlags.Public) | BindingFlags.NonPublic,
- name, null);
+ mt, restriction, name, arity, null);
if (lookup != null) {
Expression e = Error_MemberLookupFailed (ec, queried_type, lookup);
// OverloadResolve to do correct arguments matching.
// Requires MemberLookup accessiblity check removal
//
- if (e == null || (mt & (MemberTypes.Method | MemberTypes.Constructor)) == 0) {
- MemberInfo mi = lookup[0];
+ if (e == null || (mt & (MemberKind.Method | MemberKind.Constructor)) == 0) {
+ var mi = lookup.First ();
ec.Report.SymbolRelatedToPreviousError (mi);
- if (qualifier_type != null && container_type != null && qualifier_type != container_type &&
+ if ((mi.Modifiers & Modifiers.PROTECTED) != 0 && 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
}
lookup = TypeManager.MemberLookup (queried_type, null, queried_type,
- AllMemberTypes, AllBindingFlags | BindingFlags.NonPublic,
- name, null);
+ MemberKind.All, BindingRestriction.None, name, -System.Math.Max (1, arity), null);
}
if (lookup == null) {
return null;
}
- if (TypeManager.MemberLookup (queried_type, null, queried_type,
- AllMemberTypes, AllBindingFlags |
- BindingFlags.NonPublic, name, null) == null) {
- if ((lookup.Length == 1) && (lookup [0] is Type)) {
- Type t = (Type) lookup [0];
-
- ec.Report.Error (305, loc,
- "Using the generic type `{0}' " +
- "requires {1} type arguments",
- TypeManager.CSharpName (t),
- TypeManager.GetNumberOfTypeArguments (t).ToString ());
- return null;
- }
+ var mge = Error_MemberLookupFailed (ec, queried_type, lookup);
+ if (arity > 0 && mge != null) {
+ mge.SetTypeArguments (ec, new TypeArguments (new FullNamedExpression [arity]));
}
- return Error_MemberLookupFailed (ec, queried_type, lookup);
+ return mge.Resolve (ec);
}
- protected virtual Expression Error_MemberLookupFailed (ResolveContext ec, Type type, MemberInfo[] members)
+ protected virtual MemberExpr Error_MemberLookupFailed (ResolveContext ec, TypeSpec type, IList<MemberSpec> members)
{
- for (int i = 0; i < members.Length; ++i) {
- if (!(members [i] is MethodBase))
- return null;
- }
+ if (members.Any ((m) => !(m is MethodSpec)))
+ return (MemberExpr) ExprClassFromMemberInfo (type, members.First (), loc);
// By default propagate the closest candidates upwards
return new MethodGroupExpr (members, type, loc, true);
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.Compiler, ec.CurrentType, e.Type, mname, loc) as MethodGroupExpr;
- if (operator_group == null)
+ var op = is_true ? Operator.OpType.True : Operator.OpType.False;
+ var methods = MemberCache.GetUserOperator (e.type, op, false);
+ if (methods == null)
return null;
+ var mg = new MethodGroupExpr (methods, e.type, loc);
+
Arguments arguments = new Arguments (1);
arguments.Add (new Argument (e));
- operator_group = operator_group.OverloadResolve (
- ec, ref arguments, false, loc);
+ mg = mg.OverloadResolve (ec, ref arguments, false, loc);
- if (operator_group == null)
+ if (mg == null)
return null;
- return new UserOperatorCall (operator_group, arguments, null, loc);
+ return new UserOperatorCall (mg, arguments, null, loc);
}
-
+
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:
Report.Error (214, loc, "Pointers and fixed size buffers may only be used in an unsafe context");
}
- //
- // Load the object from the pointer.
- //
- public static void LoadFromPtr (ILGenerator ig, Type t)
- {
- if (t == TypeManager.int32_type)
- ig.Emit (OpCodes.Ldind_I4);
- else if (t == TypeManager.uint32_type)
- ig.Emit (OpCodes.Ldind_U4);
- else if (t == TypeManager.short_type)
- ig.Emit (OpCodes.Ldind_I2);
- else if (t == TypeManager.ushort_type)
- ig.Emit (OpCodes.Ldind_U2);
- else if (t == TypeManager.char_type)
- ig.Emit (OpCodes.Ldind_U2);
- else if (t == TypeManager.byte_type)
- ig.Emit (OpCodes.Ldind_U1);
- else if (t == TypeManager.sbyte_type)
- ig.Emit (OpCodes.Ldind_I1);
- else if (t == TypeManager.uint64_type)
- ig.Emit (OpCodes.Ldind_I8);
- else if (t == TypeManager.int64_type)
- ig.Emit (OpCodes.Ldind_I8);
- else if (t == TypeManager.float_type)
- ig.Emit (OpCodes.Ldind_R4);
- else if (t == TypeManager.double_type)
- ig.Emit (OpCodes.Ldind_R8);
- else if (t == TypeManager.bool_type)
- ig.Emit (OpCodes.Ldind_I1);
- else if (t == TypeManager.intptr_type)
- ig.Emit (OpCodes.Ldind_I);
- else if (TypeManager.IsEnumType (t)) {
- if (t == TypeManager.enum_type)
- ig.Emit (OpCodes.Ldind_Ref);
- else
- LoadFromPtr (ig, TypeManager.GetEnumUnderlyingType (t));
- } else if (TypeManager.IsStruct (t) || TypeManager.IsGenericParameter (t))
- ig.Emit (OpCodes.Ldobj, t);
- else if (t.IsPointer)
- ig.Emit (OpCodes.Ldind_I);
- else
- ig.Emit (OpCodes.Ldind_Ref);
- }
-
- //
- // The stack contains the pointer and the value of type `type'
- //
- public static void StoreFromPtr (ILGenerator ig, Type type)
- {
- if (TypeManager.IsEnumType (type))
- type = TypeManager.GetEnumUnderlyingType (type);
- if (type == TypeManager.int32_type || type == TypeManager.uint32_type)
- ig.Emit (OpCodes.Stind_I4);
- else if (type == TypeManager.int64_type || type == TypeManager.uint64_type)
- ig.Emit (OpCodes.Stind_I8);
- else if (type == TypeManager.char_type || type == TypeManager.short_type ||
- type == TypeManager.ushort_type)
- ig.Emit (OpCodes.Stind_I2);
- else if (type == TypeManager.float_type)
- ig.Emit (OpCodes.Stind_R4);
- else if (type == TypeManager.double_type)
- ig.Emit (OpCodes.Stind_R8);
- else if (type == TypeManager.byte_type || type == TypeManager.sbyte_type ||
- type == TypeManager.bool_type)
- ig.Emit (OpCodes.Stind_I1);
- else if (type == TypeManager.intptr_type)
- ig.Emit (OpCodes.Stind_I);
- else if (TypeManager.IsStruct (type) || TypeManager.IsGenericParameter (type))
- ig.Emit (OpCodes.Stobj, type);
- else
- ig.Emit (OpCodes.Stind_Ref);
- }
-
+
//
// Returns the size of type `t' if known, otherwise, 0
//
- public static int GetTypeSize (Type t)
+ public static int GetTypeSize (TypeSpec t)
{
- t = TypeManager.TypeToCoreType (t);
if (t == TypeManager.int32_type ||
t == TypeManager.uint32_type ||
t == TypeManager.float_type)
//
protected Expression ConvertExpressionToArrayIndex (ResolveContext ec, Expression source)
{
- if (TypeManager.IsDynamicType (source.type)) {
+ if (source.type == InternalType.Dynamic) {
Arguments args = new Arguments (1);
args.Add (new Argument (source));
return new DynamicConversion (TypeManager.int32_type, CSharpBinderFlags.ConvertArrayIndex, args, loc).Resolve (ec);
{
TypeExpr texpr = TypeManager.expression_type_expr;
if (texpr == null) {
- Type t = TypeManager.CoreLookupType (ec.Compiler, "System.Linq.Expressions", "Expression", Kind.Class, true);
+ TypeSpec t = TypeManager.CoreLookupType (ec.Compiler, "System.Linq.Expressions", "Expression", MemberKind.Class, true);
if (t == null)
return null;
return texpr;
}
-#if NET_4_0
//
// Implemented by all expressions which support conversion from
// compiler expression to invokable runtime expression. Used by
{
throw new NotImplementedException ("MakeExpression for " + GetType ());
}
-#endif
-
- public virtual void MutateHoistedGenericType (AnonymousMethodStorey storey)
- {
- // TODO: It should probably be type = storey.MutateType (type);
- }
}
/// <summary>
/// </summary>
public abstract class ExpressionStatement : Expression {
- public virtual ExpressionStatement ResolveStatement (BlockContext ec)
+ public ExpressionStatement ResolveStatement (BlockContext ec)
{
Expression e = Resolve (ec);
if (e == null)
{
protected readonly Expression child;
- protected TypeCast (Expression child, Type return_type)
+ protected TypeCast (Expression child, TypeSpec return_type)
{
eclass = child.eclass;
loc = child.Location;
this.child = child;
}
+ public Expression Child {
+ get {
+ return child;
+ }
+ }
+
public override Expression CreateExpressionTree (ResolveContext ec)
{
Arguments args = new Arguments (2);
return CreateExpressionFactoryCall (ec, ec.HasSet (ResolveContext.Options.CheckedScope) ? "ConvertChecked" : "Convert", args);
}
- public override Expression DoResolve (ResolveContext 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 (ResolveContext ec, Type value_type, out object value)
- {
- return child.GetAttributableValue (ec, value_type, out value);
- }
-
-#if NET_4_0
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);
- }
-#endif
-
- public override void MutateHoistedGenericType (AnonymousMethodStorey storey)
- {
- type = storey.MutateType (type);
- child.MutateHoistedGenericType (storey);
+ SLE.Expression.ConvertChecked (child.MakeExpression (ctx), type.GetMetaInfo ()) :
+ SLE.Expression.Convert (child.MakeExpression (ctx), type.GetMetaInfo ());
}
protected override void CloneTo (CloneContext clonectx, Expression t)
}
public class EmptyCast : TypeCast {
- EmptyCast (Expression child, Type target_type)
+ EmptyCast (Expression child, TypeSpec target_type)
: base (child, target_type)
{
}
- public static Expression Create (Expression child, Type type)
+ public static Expression Create (Expression child, TypeSpec type)
{
Constant c = child as Constant;
if (c != null)
// Used for predefined class library user casts (no obsolete check, etc.)
//
public class OperatorCast : TypeCast {
- MethodInfo conversion_operator;
+ MethodSpec conversion_operator;
- public OperatorCast (Expression child, Type target_type)
+ public OperatorCast (Expression child, TypeSpec target_type)
: this (child, target_type, false)
{
}
- public OperatorCast (Expression child, Type target_type, bool find_explicit)
+ public OperatorCast (Expression child, TypeSpec target_type, bool find_explicit)
: base (child, target_type)
{
conversion_operator = GetConversionOperator (find_explicit);
// Returns the implicit operator that converts from
// 'child.Type' to our target type (type)
- MethodInfo GetConversionOperator (bool find_explicit)
+ MethodSpec GetConversionOperator (bool find_explicit)
{
- string operator_name = find_explicit ? "op_Explicit" : "op_Implicit";
-
- MemberInfo [] mi;
-
- mi = TypeManager.MemberLookup (child.Type, child.Type, child.Type, MemberTypes.Method,
- BindingFlags.Static | BindingFlags.Public, operator_name, null);
+ var op = find_explicit ? Operator.OpType.Explicit : Operator.OpType.Implicit;
+ var mi = MemberCache.GetUserOperator (child.Type, op, true);
if (mi == null){
- mi = TypeManager.MemberLookup (type, type, type, MemberTypes.Method,
- BindingFlags.Static | BindingFlags.Public, operator_name, null);
+ mi = MemberCache.GetUserOperator (type, op, true);
}
- foreach (MethodInfo oper in mi) {
- AParametersCollection pd = TypeManager.GetParameterData (oper);
+ foreach (MethodSpec oper in mi) {
+ if (oper.ReturnType != type)
+ continue;
- if (pd.Types [0] == child.Type && TypeManager.TypeToCoreType (oper.ReturnType) == type)
+ if (oper.Parameters.Types [0] == child.Type)
return oper;
}
public override void Emit (EmitContext ec)
{
child.Emit (ec);
- ec.ig.Emit (OpCodes.Call, conversion_operator);
+ ec.Emit (OpCodes.Call, conversion_operator);
}
}
/// </summary>
public class CastFromDecimal : TypeCast
{
- static IDictionary operators;
+ static Dictionary<TypeSpec, MethodSpec> operators;
- public CastFromDecimal (Expression child, Type return_type)
+ public CastFromDecimal (Expression child, TypeSpec return_type)
: base (child, return_type)
{
if (child.Type != TypeManager.decimal_type)
- throw new InternalErrorException (
- "The expected type is Decimal, instead it is " + child.Type.FullName);
+ throw new ArgumentException ("Expected decimal child " + child.Type.GetSignatureForError ());
}
// Returns the explicit operator that converts from an
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);
+ var all_oper = MemberCache.GetUserOperator (TypeManager.decimal_type, Operator.OpType.Explicit, true);
- operators = new System.Collections.Specialized.HybridDictionary ();
- foreach (MethodInfo oper in all_oper) {
- AParametersCollection pd = TypeManager.GetParameterData (oper);
+ operators = new Dictionary<TypeSpec, MethodSpec> ();
+ foreach (MethodSpec oper in all_oper) {
+ AParametersCollection pd = oper.Parameters;
if (pd.Types [0] == TypeManager.decimal_type)
- operators.Add (TypeManager.TypeToCoreType (oper.ReturnType), oper);
+ operators.Add (oper.ReturnType, oper);
}
}
- 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]);
+ ec.Emit (OpCodes.Call, operators [type]);
+ }
+
+ public static void Reset ()
+ {
+ operators = null;
}
}
//
public class EmptyConstantCast : Constant
{
- public readonly Constant child;
+ public Constant child;
- public EmptyConstantCast(Constant child, Type type)
+ public EmptyConstantCast (Constant child, TypeSpec type)
: base (child.Location)
{
- eclass = child.eclass;
+ if (child == null)
+ throw new ArgumentNullException ("child");
+
this.child = child;
+ this.eclass = child.eclass;
this.type = type;
}
return child.GetValue ();
}
- public override Constant ConvertExplicitly (bool in_checked_context, Type target_type)
+ public override Constant ConvertExplicitly (bool in_checked_context, TypeSpec 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);
}
return CreateExpressionFactoryCall (ec, "Convert", args);
}
- public override Constant Increment ()
- {
- return child.Increment ();
- }
-
public override bool IsDefaultValue {
get { return child.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)
{
// Only to make verifier happy
if (TypeManager.IsGenericParameter (type) && child.IsNull)
- ec.ig.Emit (OpCodes.Unbox_Any, type);
+ ec.Emit (OpCodes.Unbox_Any, type);
}
public override void EmitSideEffect (EmitContext ec)
child.EmitSideEffect (ec);
}
- public override Constant ConvertImplicitly (Type target_type)
+ public override Constant ConvertImplicitly (ResolveContext rc, TypeSpec target_type)
{
// FIXME: Do we need to check user conversions?
if (!Convert.ImplicitStandardConversionExists (this, target_type))
return null;
- return child.ConvertImplicitly (target_type);
- }
-
- public override void MutateHoistedGenericType (AnonymousMethodStorey storey)
- {
- child.MutateHoistedGenericType (storey);
+ return child.ConvertImplicitly (rc, target_type);
}
}
-
/// <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, TypeSpec enum_type)
+ : base (child.Location)
{
- eclass = child.eclass;
this.Child = child;
- type = enum_type;
+ this.type = enum_type;
}
- protected EnumConstant ()
- : base (Location.Null)
+ protected EnumConstant (Location loc)
+ : base (loc)
{
}
-
- public override Expression DoResolve (ResolveContext ec)
- {
- // 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.Emit (ec);
}
+ public override void EncodeAttributeValue (IMemberContext rc, AttributeEncoder enc, TypeSpec targetType)
+ {
+ Child.EncodeAttributeValue (rc, enc, Child.Type);
+ }
+
public override void EmitBranchable (EmitContext ec, Label label, bool on_true)
{
Child.EmitBranchable (ec, label, on_true);
Child.EmitSideEffect (ec);
}
- public override bool GetAttributableValue (ResolveContext ec, Type value_type, out object value)
- {
- value = GetTypedValue ();
- return true;
- }
-
public override string GetSignatureForError()
{
return TypeManager.CSharpName (Type);
//
// This works only sometimes
//
- if (TypeManager.IsBeingCompiled (type))
+ if (type.MemberDefinition is TypeContainer)
return Child.GetValue ();
#endif
- return System.Enum.ToObject (type, Child.GetValue ());
+ return System.Enum.ToObject (type.GetMetaInfo (), Child.GetValue ());
}
public override string AsString ()
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 {
}
}
- public override Constant ConvertExplicitly(bool in_checked_context, Type target_type)
+ public override Constant ConvertExplicitly(bool in_checked_context, TypeSpec target_type)
{
if (Child.Type == target_type)
return Child;
return Child.ConvertExplicitly (in_checked_context, target_type);
}
- public override Constant ConvertImplicitly (Type type)
+ public override Constant ConvertImplicitly (ResolveContext rc, TypeSpec type)
{
- Type this_type = TypeManager.DropGenericTypeArguments (Type);
- type = TypeManager.DropGenericTypeArguments (type);
-
- if (this_type == type) {
- // This is workaround of mono bug. It can be removed when the latest corlib spreads enough
- if (TypeManager.IsEnumType (type.UnderlyingSystemType))
- return this;
-
- Type child_type = TypeManager.DropGenericTypeArguments (Child.Type);
- if (type.UnderlyingSystemType != child_type)
- Child = Child.ConvertImplicitly (type.UnderlyingSystemType);
+ if (this.type == type) {
return this;
}
return null;
}
- return Child.ConvertImplicitly(type);
+ return Child.ConvertImplicitly (rc, type);
}
-
}
/// <summary>
/// </summary>
public class BoxedCast : TypeCast {
- public BoxedCast (Expression expr, Type target_type)
+ public BoxedCast (Expression expr, TypeSpec target_type)
: base (expr, target_type)
{
eclass = ExprClass.Value;
}
- public override Expression DoResolve (ResolveContext ec)
+ protected override Expression DoResolve (ResolveContext ec)
{
// This should never be invoked, we are born in fully
// initialized state.
return this;
}
+ public override void EncodeAttributeValue (IMemberContext rc, AttributeEncoder enc, TypeSpec targetType)
+ {
+ enc.Encode (child.Type);
+ child.EncodeAttributeValue (rc, enc, child.Type);
+ }
+
public override void Emit (EmitContext ec)
{
base.Emit (ec);
- ec.ig.Emit (OpCodes.Box, child.Type);
+ ec.Emit (OpCodes.Box, child.Type);
}
public override void EmitSideEffect (EmitContext ec)
}
public class UnboxCast : TypeCast {
- public UnboxCast (Expression expr, Type return_type)
+ public UnboxCast (Expression expr, TypeSpec return_type)
: base (expr, return_type)
{
}
- public override Expression DoResolve (ResolveContext ec)
+ protected override Expression DoResolve (ResolveContext ec)
{
// This should never be invoked, we are born in fully
// initialized state.
{
base.Emit (ec);
- ILGenerator ig = ec.ig;
- ig.Emit (OpCodes.Unbox_Any, type);
- }
-
- public override void MutateHoistedGenericType (AnonymousMethodStorey storey)
- {
- type = storey.MutateType (type);
- base.MutateHoistedGenericType (storey);
+ ec.Emit (OpCodes.Unbox_Any, type);
}
}
Mode mode;
- public ConvCast (Expression child, Type return_type, Mode m)
+ public ConvCast (Expression child, TypeSpec return_type, Mode m)
: base (child, return_type)
{
mode = m;
}
- public override Expression DoResolve (ResolveContext ec)
+ protected override Expression DoResolve (ResolveContext ec)
{
// This should never be invoked, we are born in fully
// initialized state.
public override void Emit (EmitContext ec)
{
- ILGenerator ig = ec.ig;
-
base.Emit (ec);
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.I1_U4: ig.Emit (OpCodes.Conv_Ovf_U4); break;
- case Mode.I1_U8: ig.Emit (OpCodes.Conv_Ovf_U8); break;
- case Mode.I1_CH: ig.Emit (OpCodes.Conv_Ovf_U2); break;
+ case Mode.I1_U1: ec.Emit (OpCodes.Conv_Ovf_U1); break;
+ case Mode.I1_U2: ec.Emit (OpCodes.Conv_Ovf_U2); break;
+ case Mode.I1_U4: ec.Emit (OpCodes.Conv_Ovf_U4); break;
+ case Mode.I1_U8: ec.Emit (OpCodes.Conv_Ovf_U8); break;
+ case Mode.I1_CH: ec.Emit (OpCodes.Conv_Ovf_U2); break;
- case Mode.U1_I1: ig.Emit (OpCodes.Conv_Ovf_I1_Un); break;
+ case Mode.U1_I1: ec.Emit (OpCodes.Conv_Ovf_I1_Un); break;
case Mode.U1_CH: /* nothing */ break;
- case Mode.I2_I1: ig.Emit (OpCodes.Conv_Ovf_I1); break;
- case Mode.I2_U1: ig.Emit (OpCodes.Conv_Ovf_U1); break;
- case Mode.I2_U2: ig.Emit (OpCodes.Conv_Ovf_U2); break;
- case Mode.I2_U4: ig.Emit (OpCodes.Conv_Ovf_U4); break;
- case Mode.I2_U8: ig.Emit (OpCodes.Conv_Ovf_U8); break;
- case Mode.I2_CH: ig.Emit (OpCodes.Conv_Ovf_U2); break;
+ case Mode.I2_I1: ec.Emit (OpCodes.Conv_Ovf_I1); break;
+ case Mode.I2_U1: ec.Emit (OpCodes.Conv_Ovf_U1); break;
+ case Mode.I2_U2: ec.Emit (OpCodes.Conv_Ovf_U2); break;
+ case Mode.I2_U4: ec.Emit (OpCodes.Conv_Ovf_U4); break;
+ case Mode.I2_U8: ec.Emit (OpCodes.Conv_Ovf_U8); break;
+ case Mode.I2_CH: ec.Emit (OpCodes.Conv_Ovf_U2); break;
- case Mode.U2_I1: ig.Emit (OpCodes.Conv_Ovf_I1_Un); break;
- case Mode.U2_U1: ig.Emit (OpCodes.Conv_Ovf_U1_Un); break;
- case Mode.U2_I2: ig.Emit (OpCodes.Conv_Ovf_I2_Un); break;
+ case Mode.U2_I1: ec.Emit (OpCodes.Conv_Ovf_I1_Un); break;
+ case Mode.U2_U1: ec.Emit (OpCodes.Conv_Ovf_U1_Un); break;
+ case Mode.U2_I2: ec.Emit (OpCodes.Conv_Ovf_I2_Un); break;
case Mode.U2_CH: /* nothing */ break;
- case Mode.I4_I1: ig.Emit (OpCodes.Conv_Ovf_I1); break;
- case Mode.I4_U1: ig.Emit (OpCodes.Conv_Ovf_U1); break;
- case Mode.I4_I2: ig.Emit (OpCodes.Conv_Ovf_I2); break;
- case Mode.I4_U4: ig.Emit (OpCodes.Conv_Ovf_U4); break;
- case Mode.I4_U2: ig.Emit (OpCodes.Conv_Ovf_U2); break;
- case Mode.I4_U8: ig.Emit (OpCodes.Conv_Ovf_U8); break;
- case Mode.I4_CH: ig.Emit (OpCodes.Conv_Ovf_U2); break;
-
- case Mode.U4_I1: ig.Emit (OpCodes.Conv_Ovf_I1_Un); break;
- case Mode.U4_U1: ig.Emit (OpCodes.Conv_Ovf_U1_Un); break;
- case Mode.U4_I2: ig.Emit (OpCodes.Conv_Ovf_I2_Un); break;
- case Mode.U4_U2: ig.Emit (OpCodes.Conv_Ovf_U2_Un); break;
- case Mode.U4_I4: ig.Emit (OpCodes.Conv_Ovf_I4_Un); break;
- case Mode.U4_CH: ig.Emit (OpCodes.Conv_Ovf_U2_Un); break;
-
- case Mode.I8_I1: ig.Emit (OpCodes.Conv_Ovf_I1); break;
- case Mode.I8_U1: ig.Emit (OpCodes.Conv_Ovf_U1); break;
- case Mode.I8_I2: ig.Emit (OpCodes.Conv_Ovf_I2); break;
- case Mode.I8_U2: ig.Emit (OpCodes.Conv_Ovf_U2); break;
- case Mode.I8_I4: ig.Emit (OpCodes.Conv_Ovf_I4); 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_I2: ig.Emit (OpCodes.Conv_Ovf_I2_Un); break;
- case Mode.U8_U2: ig.Emit (OpCodes.Conv_Ovf_U2_Un); break;
- case Mode.U8_I4: ig.Emit (OpCodes.Conv_Ovf_I4_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.CH_I2: ig.Emit (OpCodes.Conv_Ovf_I2_Un); break;
-
- case Mode.R4_I1: ig.Emit (OpCodes.Conv_Ovf_I1); break;
- case Mode.R4_U1: ig.Emit (OpCodes.Conv_Ovf_U1); break;
- case Mode.R4_I2: ig.Emit (OpCodes.Conv_Ovf_I2); break;
- case Mode.R4_U2: ig.Emit (OpCodes.Conv_Ovf_U2); break;
- case Mode.R4_I4: ig.Emit (OpCodes.Conv_Ovf_I4); break;
- case Mode.R4_U4: ig.Emit (OpCodes.Conv_Ovf_U4); break;
- case Mode.R4_I8: ig.Emit (OpCodes.Conv_Ovf_I8); break;
- case Mode.R4_U8: ig.Emit (OpCodes.Conv_Ovf_U8); break;
- case Mode.R4_CH: ig.Emit (OpCodes.Conv_Ovf_U2); break;
-
- case Mode.R8_I1: ig.Emit (OpCodes.Conv_Ovf_I1); break;
- case Mode.R8_U1: ig.Emit (OpCodes.Conv_Ovf_U1); break;
- case Mode.R8_I2: ig.Emit (OpCodes.Conv_Ovf_I2); break;
- case Mode.R8_U2: ig.Emit (OpCodes.Conv_Ovf_U2); break;
- case Mode.R8_I4: ig.Emit (OpCodes.Conv_Ovf_I4); break;
- case Mode.R8_U4: ig.Emit (OpCodes.Conv_Ovf_U4); break;
- case Mode.R8_I8: ig.Emit (OpCodes.Conv_Ovf_I8); 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;
+ case Mode.I4_I1: ec.Emit (OpCodes.Conv_Ovf_I1); break;
+ case Mode.I4_U1: ec.Emit (OpCodes.Conv_Ovf_U1); break;
+ case Mode.I4_I2: ec.Emit (OpCodes.Conv_Ovf_I2); break;
+ case Mode.I4_U4: ec.Emit (OpCodes.Conv_Ovf_U4); break;
+ case Mode.I4_U2: ec.Emit (OpCodes.Conv_Ovf_U2); break;
+ case Mode.I4_U8: ec.Emit (OpCodes.Conv_Ovf_U8); break;
+ case Mode.I4_CH: ec.Emit (OpCodes.Conv_Ovf_U2); break;
+
+ case Mode.U4_I1: ec.Emit (OpCodes.Conv_Ovf_I1_Un); break;
+ case Mode.U4_U1: ec.Emit (OpCodes.Conv_Ovf_U1_Un); break;
+ case Mode.U4_I2: ec.Emit (OpCodes.Conv_Ovf_I2_Un); break;
+ case Mode.U4_U2: ec.Emit (OpCodes.Conv_Ovf_U2_Un); break;
+ case Mode.U4_I4: ec.Emit (OpCodes.Conv_Ovf_I4_Un); break;
+ case Mode.U4_CH: ec.Emit (OpCodes.Conv_Ovf_U2_Un); break;
+
+ case Mode.I8_I1: ec.Emit (OpCodes.Conv_Ovf_I1); break;
+ case Mode.I8_U1: ec.Emit (OpCodes.Conv_Ovf_U1); break;
+ case Mode.I8_I2: ec.Emit (OpCodes.Conv_Ovf_I2); break;
+ case Mode.I8_U2: ec.Emit (OpCodes.Conv_Ovf_U2); break;
+ case Mode.I8_I4: ec.Emit (OpCodes.Conv_Ovf_I4); break;
+ case Mode.I8_U4: ec.Emit (OpCodes.Conv_Ovf_U4); break;
+ case Mode.I8_U8: ec.Emit (OpCodes.Conv_Ovf_U8); break;
+ case Mode.I8_CH: ec.Emit (OpCodes.Conv_Ovf_U2); break;
+ case Mode.I8_I: ec.Emit (OpCodes.Conv_Ovf_U); break;
+
+ case Mode.U8_I1: ec.Emit (OpCodes.Conv_Ovf_I1_Un); break;
+ case Mode.U8_U1: ec.Emit (OpCodes.Conv_Ovf_U1_Un); break;
+ case Mode.U8_I2: ec.Emit (OpCodes.Conv_Ovf_I2_Un); break;
+ case Mode.U8_U2: ec.Emit (OpCodes.Conv_Ovf_U2_Un); break;
+ case Mode.U8_I4: ec.Emit (OpCodes.Conv_Ovf_I4_Un); break;
+ case Mode.U8_U4: ec.Emit (OpCodes.Conv_Ovf_U4_Un); break;
+ case Mode.U8_I8: ec.Emit (OpCodes.Conv_Ovf_I8_Un); break;
+ case Mode.U8_CH: ec.Emit (OpCodes.Conv_Ovf_U2_Un); break;
+ case Mode.U8_I: ec.Emit (OpCodes.Conv_Ovf_U_Un); break;
+
+ case Mode.CH_I1: ec.Emit (OpCodes.Conv_Ovf_I1_Un); break;
+ case Mode.CH_U1: ec.Emit (OpCodes.Conv_Ovf_U1_Un); break;
+ case Mode.CH_I2: ec.Emit (OpCodes.Conv_Ovf_I2_Un); break;
+
+ case Mode.R4_I1: ec.Emit (OpCodes.Conv_Ovf_I1); break;
+ case Mode.R4_U1: ec.Emit (OpCodes.Conv_Ovf_U1); break;
+ case Mode.R4_I2: ec.Emit (OpCodes.Conv_Ovf_I2); break;
+ case Mode.R4_U2: ec.Emit (OpCodes.Conv_Ovf_U2); break;
+ case Mode.R4_I4: ec.Emit (OpCodes.Conv_Ovf_I4); break;
+ case Mode.R4_U4: ec.Emit (OpCodes.Conv_Ovf_U4); break;
+ case Mode.R4_I8: ec.Emit (OpCodes.Conv_Ovf_I8); break;
+ case Mode.R4_U8: ec.Emit (OpCodes.Conv_Ovf_U8); break;
+ case Mode.R4_CH: ec.Emit (OpCodes.Conv_Ovf_U2); break;
+
+ case Mode.R8_I1: ec.Emit (OpCodes.Conv_Ovf_I1); break;
+ case Mode.R8_U1: ec.Emit (OpCodes.Conv_Ovf_U1); break;
+ case Mode.R8_I2: ec.Emit (OpCodes.Conv_Ovf_I2); break;
+ case Mode.R8_U2: ec.Emit (OpCodes.Conv_Ovf_U2); break;
+ case Mode.R8_I4: ec.Emit (OpCodes.Conv_Ovf_I4); break;
+ case Mode.R8_U4: ec.Emit (OpCodes.Conv_Ovf_U4); break;
+ case Mode.R8_I8: ec.Emit (OpCodes.Conv_Ovf_I8); break;
+ case Mode.R8_U8: ec.Emit (OpCodes.Conv_Ovf_U8); break;
+ case Mode.R8_CH: ec.Emit (OpCodes.Conv_Ovf_U2); break;
+ case Mode.R8_R4: ec.Emit (OpCodes.Conv_R4); break;
+
+ case Mode.I_I8: ec.Emit (OpCodes.Conv_Ovf_I8_Un); break;
}
} else {
switch (mode){
- case Mode.I1_U1: ig.Emit (OpCodes.Conv_U1); break;
- case Mode.I1_U2: ig.Emit (OpCodes.Conv_U2); break;
- case Mode.I1_U4: ig.Emit (OpCodes.Conv_U4); break;
- case Mode.I1_U8: ig.Emit (OpCodes.Conv_I8); break;
- case Mode.I1_CH: ig.Emit (OpCodes.Conv_U2); break;
-
- case Mode.U1_I1: ig.Emit (OpCodes.Conv_I1); break;
- case Mode.U1_CH: ig.Emit (OpCodes.Conv_U2); break;
-
- case Mode.I2_I1: ig.Emit (OpCodes.Conv_I1); break;
- case Mode.I2_U1: ig.Emit (OpCodes.Conv_U1); break;
- case Mode.I2_U2: ig.Emit (OpCodes.Conv_U2); break;
- case Mode.I2_U4: ig.Emit (OpCodes.Conv_U4); break;
- case Mode.I2_U8: ig.Emit (OpCodes.Conv_I8); break;
- case Mode.I2_CH: ig.Emit (OpCodes.Conv_U2); break;
-
- case Mode.U2_I1: ig.Emit (OpCodes.Conv_I1); break;
- case Mode.U2_U1: ig.Emit (OpCodes.Conv_U1); break;
- case Mode.U2_I2: ig.Emit (OpCodes.Conv_I2); break;
+ case Mode.I1_U1: ec.Emit (OpCodes.Conv_U1); break;
+ case Mode.I1_U2: ec.Emit (OpCodes.Conv_U2); break;
+ case Mode.I1_U4: ec.Emit (OpCodes.Conv_U4); break;
+ case Mode.I1_U8: ec.Emit (OpCodes.Conv_I8); break;
+ case Mode.I1_CH: ec.Emit (OpCodes.Conv_U2); break;
+
+ case Mode.U1_I1: ec.Emit (OpCodes.Conv_I1); break;
+ case Mode.U1_CH: ec.Emit (OpCodes.Conv_U2); break;
+
+ case Mode.I2_I1: ec.Emit (OpCodes.Conv_I1); break;
+ case Mode.I2_U1: ec.Emit (OpCodes.Conv_U1); break;
+ case Mode.I2_U2: ec.Emit (OpCodes.Conv_U2); break;
+ case Mode.I2_U4: ec.Emit (OpCodes.Conv_U4); break;
+ case Mode.I2_U8: ec.Emit (OpCodes.Conv_I8); break;
+ case Mode.I2_CH: ec.Emit (OpCodes.Conv_U2); break;
+
+ case Mode.U2_I1: ec.Emit (OpCodes.Conv_I1); break;
+ case Mode.U2_U1: ec.Emit (OpCodes.Conv_U1); break;
+ case Mode.U2_I2: ec.Emit (OpCodes.Conv_I2); break;
case Mode.U2_CH: /* nothing */ break;
- case Mode.I4_I1: ig.Emit (OpCodes.Conv_I1); break;
- case Mode.I4_U1: ig.Emit (OpCodes.Conv_U1); break;
- case Mode.I4_I2: ig.Emit (OpCodes.Conv_I2); break;
+ case Mode.I4_I1: ec.Emit (OpCodes.Conv_I1); break;
+ case Mode.I4_U1: ec.Emit (OpCodes.Conv_U1); break;
+ case Mode.I4_I2: ec.Emit (OpCodes.Conv_I2); break;
case Mode.I4_U4: /* nothing */ break;
- case Mode.I4_U2: ig.Emit (OpCodes.Conv_U2); break;
- case Mode.I4_U8: ig.Emit (OpCodes.Conv_I8); break;
- case Mode.I4_CH: ig.Emit (OpCodes.Conv_U2); break;
-
- case Mode.U4_I1: ig.Emit (OpCodes.Conv_I1); break;
- case Mode.U4_U1: ig.Emit (OpCodes.Conv_U1); break;
- case Mode.U4_I2: ig.Emit (OpCodes.Conv_I2); break;
- case Mode.U4_U2: ig.Emit (OpCodes.Conv_U2); break;
+ case Mode.I4_U2: ec.Emit (OpCodes.Conv_U2); break;
+ case Mode.I4_U8: ec.Emit (OpCodes.Conv_I8); break;
+ case Mode.I4_CH: ec.Emit (OpCodes.Conv_U2); break;
+
+ case Mode.U4_I1: ec.Emit (OpCodes.Conv_I1); break;
+ case Mode.U4_U1: ec.Emit (OpCodes.Conv_U1); break;
+ case Mode.U4_I2: ec.Emit (OpCodes.Conv_I2); break;
+ case Mode.U4_U2: ec.Emit (OpCodes.Conv_U2); break;
case Mode.U4_I4: /* nothing */ break;
- case Mode.U4_CH: ig.Emit (OpCodes.Conv_U2); break;
-
- case Mode.I8_I1: ig.Emit (OpCodes.Conv_I1); break;
- case Mode.I8_U1: ig.Emit (OpCodes.Conv_U1); break;
- case Mode.I8_I2: ig.Emit (OpCodes.Conv_I2); break;
- case Mode.I8_U2: ig.Emit (OpCodes.Conv_U2); break;
- case Mode.I8_I4: ig.Emit (OpCodes.Conv_I4); break;
- case Mode.I8_U4: ig.Emit (OpCodes.Conv_U4); break;
+ case Mode.U4_CH: ec.Emit (OpCodes.Conv_U2); break;
+
+ case Mode.I8_I1: ec.Emit (OpCodes.Conv_I1); break;
+ case Mode.I8_U1: ec.Emit (OpCodes.Conv_U1); break;
+ case Mode.I8_I2: ec.Emit (OpCodes.Conv_I2); break;
+ case Mode.I8_U2: ec.Emit (OpCodes.Conv_U2); break;
+ case Mode.I8_I4: ec.Emit (OpCodes.Conv_I4); break;
+ case Mode.I8_U4: ec.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_I2: ig.Emit (OpCodes.Conv_I2); break;
- case Mode.U8_U2: ig.Emit (OpCodes.Conv_U2); break;
- case Mode.U8_I4: ig.Emit (OpCodes.Conv_I4); break;
- case Mode.U8_U4: ig.Emit (OpCodes.Conv_U4); break;
+ case Mode.I8_CH: ec.Emit (OpCodes.Conv_U2); break;
+ case Mode.I8_I: ec.Emit (OpCodes.Conv_U); break;
+
+ case Mode.U8_I1: ec.Emit (OpCodes.Conv_I1); break;
+ case Mode.U8_U1: ec.Emit (OpCodes.Conv_U1); break;
+ case Mode.U8_I2: ec.Emit (OpCodes.Conv_I2); break;
+ case Mode.U8_U2: ec.Emit (OpCodes.Conv_U2); break;
+ case Mode.U8_I4: ec.Emit (OpCodes.Conv_I4); break;
+ case Mode.U8_U4: ec.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.CH_I2: ig.Emit (OpCodes.Conv_I2); break;
-
- case Mode.R4_I1: ig.Emit (OpCodes.Conv_I1); break;
- case Mode.R4_U1: ig.Emit (OpCodes.Conv_U1); break;
- case Mode.R4_I2: ig.Emit (OpCodes.Conv_I2); break;
- case Mode.R4_U2: ig.Emit (OpCodes.Conv_U2); break;
- case Mode.R4_I4: ig.Emit (OpCodes.Conv_I4); break;
- case Mode.R4_U4: ig.Emit (OpCodes.Conv_U4); break;
- case Mode.R4_I8: ig.Emit (OpCodes.Conv_I8); break;
- case Mode.R4_U8: ig.Emit (OpCodes.Conv_U8); break;
- case Mode.R4_CH: ig.Emit (OpCodes.Conv_U2); break;
-
- case Mode.R8_I1: ig.Emit (OpCodes.Conv_I1); break;
- case Mode.R8_U1: ig.Emit (OpCodes.Conv_U1); break;
- case Mode.R8_I2: ig.Emit (OpCodes.Conv_I2); break;
- case Mode.R8_U2: ig.Emit (OpCodes.Conv_U2); break;
- case Mode.R8_I4: ig.Emit (OpCodes.Conv_I4); break;
- case Mode.R8_U4: ig.Emit (OpCodes.Conv_U4); break;
- case Mode.R8_I8: ig.Emit (OpCodes.Conv_I8); 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;
+ case Mode.U8_CH: ec.Emit (OpCodes.Conv_U2); break;
+ case Mode.U8_I: ec.Emit (OpCodes.Conv_U); break;
+
+ case Mode.CH_I1: ec.Emit (OpCodes.Conv_I1); break;
+ case Mode.CH_U1: ec.Emit (OpCodes.Conv_U1); break;
+ case Mode.CH_I2: ec.Emit (OpCodes.Conv_I2); break;
+
+ case Mode.R4_I1: ec.Emit (OpCodes.Conv_I1); break;
+ case Mode.R4_U1: ec.Emit (OpCodes.Conv_U1); break;
+ case Mode.R4_I2: ec.Emit (OpCodes.Conv_I2); break;
+ case Mode.R4_U2: ec.Emit (OpCodes.Conv_U2); break;
+ case Mode.R4_I4: ec.Emit (OpCodes.Conv_I4); break;
+ case Mode.R4_U4: ec.Emit (OpCodes.Conv_U4); break;
+ case Mode.R4_I8: ec.Emit (OpCodes.Conv_I8); break;
+ case Mode.R4_U8: ec.Emit (OpCodes.Conv_U8); break;
+ case Mode.R4_CH: ec.Emit (OpCodes.Conv_U2); break;
+
+ case Mode.R8_I1: ec.Emit (OpCodes.Conv_I1); break;
+ case Mode.R8_U1: ec.Emit (OpCodes.Conv_U1); break;
+ case Mode.R8_I2: ec.Emit (OpCodes.Conv_I2); break;
+ case Mode.R8_U2: ec.Emit (OpCodes.Conv_U2); break;
+ case Mode.R8_I4: ec.Emit (OpCodes.Conv_I4); break;
+ case Mode.R8_U4: ec.Emit (OpCodes.Conv_U4); break;
+ case Mode.R8_I8: ec.Emit (OpCodes.Conv_I8); break;
+ case Mode.R8_U8: ec.Emit (OpCodes.Conv_U8); break;
+ case Mode.R8_CH: ec.Emit (OpCodes.Conv_U2); break;
+ case Mode.R8_R4: ec.Emit (OpCodes.Conv_R4); break;
+
+ case Mode.I_I8: ec.Emit (OpCodes.Conv_U8); break;
}
}
}
public class OpcodeCast : TypeCast {
readonly OpCode op;
- public OpcodeCast (Expression child, Type return_type, OpCode op)
+ public OpcodeCast (Expression child, TypeSpec return_type, OpCode op)
: base (child, return_type)
{
this.op = op;
}
- public override Expression DoResolve (ResolveContext ec)
+ protected override Expression DoResolve (ResolveContext ec)
{
// This should never be invoked, we are born in fully
// initialized state.
public override void Emit (EmitContext ec)
{
base.Emit (ec);
- ec.ig.Emit (op);
+ ec.Emit (op);
}
- public Type UnderlyingType {
+ public TypeSpec UnderlyingType {
get { return child.Type; }
}
}
public sealed class ClassCast : TypeCast {
readonly bool forced;
- public ClassCast (Expression child, Type return_type)
+ public ClassCast (Expression child, TypeSpec return_type)
: base (child, return_type)
{
}
- public ClassCast (Expression child, Type return_type, bool forced)
+ public ClassCast (Expression child, TypeSpec return_type, bool forced)
: base (child, return_type)
{
this.forced = forced;
bool gen = TypeManager.IsGenericParameter (child.Type);
if (gen)
- ec.ig.Emit (OpCodes.Box, child.Type);
+ ec.Emit (OpCodes.Box, child.Type);
if (type.IsGenericParameter) {
- ec.ig.Emit (OpCodes.Unbox_Any, type);
+ ec.Emit (OpCodes.Unbox_Any, type);
return;
}
if (gen && !forced)
return;
- ec.ig.Emit (OpCodes.Castclass, type);
+ ec.Emit (OpCodes.Castclass, type);
}
}
this.orig_expr = orig_expr;
}
- public override Constant ConvertImplicitly (Type target_type)
+ public override Constant ConvertImplicitly (ResolveContext rc, TypeSpec 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;
}
return orig_expr.CreateExpressionTree (ec);
}
- 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 (ec, orig_expr.Location);
- value = null;
- return false;
- }
-
- public override Constant ConvertExplicitly (bool in_checked_context, Type target_type)
+ public override Constant ConvertExplicitly (bool in_checked_context, TypeSpec target_type)
{
Constant c = base.ConvertExplicitly (in_checked_context, target_type);
if (c != null)
return orig_expr.CreateExpressionTree (ec);
}
- public override Expression DoResolve (ResolveContext ec)
+ protected override Expression DoResolve (ResolveContext ec)
{
eclass = stm.eclass;
type = stm.Type;
{
stm.EmitStatement (ec);
}
-
- public override void MutateHoistedGenericType (AnonymousMethodStorey storey)
- {
- stm.MutateHoistedGenericType (storey);
- }
}
readonly Expression expr, orig_expr;
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);
}
return orig_expr.CreateExpressionTree (ec);
}
- public override Expression DoResolve (ResolveContext ec)
+ protected override Expression DoResolve (ResolveContext ec)
{
- eclass = expr.eclass;
- type = expr.Type;
return this;
}
expr.EmitBranchable (ec, target, on_true);
}
-#if NET_4_0
public override SLE.Expression MakeExpression (BuilderContext ctx)
{
return orig_expr.MakeExpression (ctx);
}
-#endif
-
- public override void MutateHoistedGenericType (AnonymousMethodStorey storey)
- {
- expr.MutateHoistedGenericType (storey);
- }
}
//
get { return expr; }
}
- public override Expression DoResolve (ResolveContext ec)
+ protected override Expression DoResolve (ResolveContext ec)
{
expr = expr.Resolve (ec);
if (expr != null) {
public Expression Expr {
get { return expr; }
}
-
- public override void MutateHoistedGenericType (AnonymousMethodStorey storey)
- {
- throw new InternalErrorException ("Missing Resolve call");
- }
}
//
loc = l;
}
- public bool HasTypeArguments {
- get {
- return targs != null;
- }
- }
-
- public override bool Equals (object obj)
+ protected ATypeNameExpression (string name, int arity, Location l)
+ : this (name, new UnboundTypeArguments (arity), l)
{
- ATypeNameExpression atne = obj as ATypeNameExpression;
- return atne != null && atne.Name == Name &&
- (targs == null || targs.Equals (atne.targs));
}
- public override int GetHashCode ()
- {
- return Name.GetHashCode ();
- }
+ #region Properties
- public override string GetSignatureForError ()
- {
- if (targs != null) {
- return TypeManager.RemoveGenericArity (Name) + "<" +
- targs.GetSignatureForError () + ">";
+ protected int Arity {
+ get {
+ return targs == null ? 0 : targs.Count;
}
+ }
- return Name;
+ public bool HasTypeArguments {
+ get {
+ return targs != null && !targs.IsEmpty;
+ }
}
public string Name {
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 SimpleName (string name, Location l)
- : base (name, l)
- {
- }
+ #endregion
- public SimpleName (string name, TypeArguments args, Location l)
- : base (name, args, l)
+ public override bool Equals (object obj)
{
+ ATypeNameExpression atne = obj as ATypeNameExpression;
+ return atne != null && atne.Name == Name &&
+ (targs == null || targs.Equals (atne.targs));
}
- public SimpleName (string name, TypeParameter[] type_params, Location l)
- : base (name, l)
+ public override int GetHashCode ()
{
- targs = new TypeArguments ();
- foreach (TypeParameter type_param in type_params)
- targs.Add (new TypeParameterExpr (type_param, l));
+ return Name.GetHashCode ();
}
- public static string RemoveGenericArity (string name)
+ // TODO: Move it to MemberCore
+ public static string GetMemberType (MemberCore mc)
{
- int start = 0;
- StringBuilder sb = null;
- do {
- int pos = name.IndexOf ('`', start);
- if (pos < 0) {
- if (start == 0)
- return name;
-
- sb.Append (name.Substring (start));
- break;
- }
-
- if (sb == null)
- sb = new StringBuilder ();
- sb.Append (name.Substring (start, pos-start));
-
- pos++;
- while ((pos < name.Length) && Char.IsNumber (name [pos]))
- pos++;
-
- start = pos;
- } while (start < name.Length);
+ if (mc is Property)
+ return "property";
+ if (mc is Indexer)
+ return "indexer";
+ if (mc is FieldBase)
+ return "field";
+ if (mc is MethodCore)
+ return "method";
+ if (mc is EnumMember)
+ return "enum";
+ if (mc is Event)
+ return "event";
- return sb.ToString ();
+ return "type";
}
- public SimpleName GetMethodGroup ()
+ public override string GetSignatureForError ()
{
- return new SimpleName (RemoveGenericArity (Name), targs, loc);
- }
+ if (targs != null) {
+ return Name + "<" + targs.GetSignatureForError () + ">";
+ }
- public static void Error_ObjectRefRequired (ResolveContext ec, Location l, string name)
- {
- 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
- ec.Report.Error (120, l,
- "An object reference is required to access non-static member `{0}'",
- name);
+ return Name;
}
-
- public bool IdenticalNameAndTypeName (IMemberContext mc, Expression resolved_to, Location loc)
+ }
+
+ /// <summary>
+ /// SimpleName expressions are formed of a single word and only happen at the beginning
+ /// of a dotted-name.
+ /// </summary>
+ public class SimpleName : ATypeNameExpression
+ {
+ public SimpleName (string name, Location l)
+ : base (name, l)
{
- return resolved_to != null && resolved_to.Type != null &&
- resolved_to.Type.Name == Name &&
- (mc.LookupNamespaceOrType (Name, loc, /* ignore_cs0104 = */ true) != null);
}
- public override Expression DoResolve (ResolveContext ec)
+ public SimpleName (string name, TypeArguments args, Location l)
+ : base (name, args, l)
{
- return SimpleNameResolve (ec, null, false);
}
- public override Expression DoResolveLValue (ResolveContext ec, Expression right_side)
+ public SimpleName (string name, int arity, Location l)
+ : base (name, arity, l)
{
- return SimpleNameResolve (ec, right_side, false);
}
-
- public Expression DoResolve (ResolveContext ec, bool intermediate)
+ public SimpleName GetMethodGroup ()
{
- return SimpleNameResolve (ec, null, intermediate);
+ return new SimpleName (Name, targs, loc);
}
- static bool IsNestedChild (Type t, Type parent)
+ protected virtual void Error_TypeOrNamespaceNotFound (IMemberContext ec)
{
- while (parent != null) {
- if (TypeManager.IsNestedChildOf (t, TypeManager.DropGenericTypeArguments (parent)))
- return true;
+ if (ec.CurrentType != null) {
+ if (ec.CurrentMemberDefinition != null) {
+ MemberCore mc = ec.CurrentMemberDefinition.Parent.GetDefinition (Name);
+ if (mc != null) {
+ Error_UnexpectedKind (ec.Compiler.Report, mc, "type", GetMemberType (mc), loc);
+ return;
+ }
+ }
- parent = parent.BaseType;
+ /*
+ // TODO MemberCache: Implement
+
+ string ns = ec.CurrentType.Namespace;
+ string fullname = (ns.Length > 0) ? ns + "." + Name : Name;
+ foreach (Assembly a in GlobalRootNamespace.Instance.Assemblies) {
+ var type = a.GetType (fullname);
+ if (type != null) {
+ ec.Compiler.Report.SymbolRelatedToPreviousError (type);
+ Expression.ErrorIsInaccesible (loc, TypeManager.CSharpName (type), ec.Compiler.Report);
+ return;
+ }
+ }
+
+ if (ec.CurrentTypeDefinition != null) {
+ TypeSpec t = ec.CurrentTypeDefinition.LookupAnyGeneric (Name);
+ if (t != null) {
+ Namespace.Error_InvalidNumberOfTypeArguments (ec.Compiler.Report, t, loc);
+ return;
+ }
+ }
+ */
+ }
+
+ FullNamedExpression retval = ec.LookupNamespaceOrType (Name, -System.Math.Max (1, Arity), loc, true);
+ if (retval != null) {
+ Error_TypeArgumentsCannotBeUsed (ec.Compiler.Report, loc, retval.Type, Arity);
+/*
+ var te = retval as TypeExpr;
+ if (HasTypeArguments && te != null && !te.Type.IsGeneric)
+ retval.Error_TypeArgumentsCannotBeUsed (ec.Compiler.Report, loc);
+ else
+ Namespace.Error_InvalidNumberOfTypeArguments (ec.Compiler.Report, retval.Type, loc);
+*/
+ return;
}
- return false;
+ NamespaceEntry.Error_NamespaceNotFound (loc, Name, ec.Compiler.Report);
}
- FullNamedExpression ResolveNested (Type t)
+ protected override Expression DoResolve (ResolveContext ec)
{
- if (!TypeManager.IsGenericTypeDefinition (t) && !TypeManager.IsGenericType (t))
- return null;
-
- Type ds = t;
- while (ds != null && !IsNestedChild (t, ds))
- ds = ds.DeclaringType;
-
- if (ds == null)
- return null;
-
- Type[] gen_params = TypeManager.GetTypeArguments (t);
-
- int arg_count = targs != null ? targs.Count : 0;
-
- 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 (Type param in gargs)
- new_args.Add (new TypeExpression (param, loc));
-
- if (targs != null)
- new_args.Add (targs);
+ return SimpleNameResolve (ec, null, false);
+ }
- return new GenericTypeExpr (t, new_args, loc);
- }
- }
+ public override Expression DoResolveLValue (ResolveContext ec, Expression right_side)
+ {
+ return SimpleNameResolve (ec, right_side, false);
+ }
- return null;
+ public Expression DoResolve (ResolveContext ec, bool intermediate)
+ {
+ return SimpleNameResolve (ec, null, intermediate);
}
public override FullNamedExpression ResolveAsTypeStep (IMemberContext ec, bool silent)
{
int errors = ec.Compiler.Report.Errors;
- FullNamedExpression fne = ec.LookupNamespaceOrType (Name, loc, /*ignore_cs0104=*/ false);
+ FullNamedExpression fne = ec.LookupNamespaceOrType (Name, Arity, loc, /*ignore_cs0104=*/ false);
if (fne != null) {
- if (fne.Type == null)
- return fne;
-
- FullNamedExpression nested = ResolveNested (fne.Type);
- if (nested != null)
- return nested.ResolveAsTypeStep (ec, false);
-
- if (targs != null) {
- if (TypeManager.IsGenericType (fne.Type)) {
+ if (fne.Type != null && Arity > 0) {
+ if (HasTypeArguments) {
GenericTypeExpr ct = new GenericTypeExpr (fne.Type, targs, loc);
return ct.ResolveAsTypeStep (ec, false);
}
- fne.Error_TypeArgumentsCannotBeUsed (ec.Compiler.Report, loc);
+ return new GenericOpenTypeExpr (fne.Type, loc);
}
- return fne;
+ //
+ // dynamic namespace is ignored when dynamic is allowed (does not apply to types)
+ //
+ if (!(fne is Namespace))
+ return fne;
}
- if (!HasTypeArguments && Name == "dynamic" &&
- RootContext.Version > LanguageVersion.V_3 &&
- RootContext.MetadataCompatibilityVersion > MetadataVersion.v2) {
-
+ if (Arity == 0 && Name == "dynamic" && RootContext.Version > LanguageVersion.V_3) {
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?",
return new DynamicTypeExpr (loc);
}
+ if (fne != null)
+ return fne;
+
if (silent || errors != ec.Compiler.Report.Errors)
return null;
return null;
}
- protected virtual void Error_TypeOrNamespaceNotFound (IMemberContext ec)
- {
- 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.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;
- }
- }
-
- if (ec.CurrentTypeDefinition != null) {
- Type t = ec.CurrentTypeDefinition.LookupAnyGeneric (Name);
- if (t != null) {
- Namespace.Error_InvalidNumberOfTypeArguments (t, loc);
- return;
- }
- }
- }
-
- if (targs != null) {
- FullNamedExpression retval = ec.LookupNamespaceOrType (SimpleName.RemoveGenericArity (Name), loc, true);
- if (retval != null) {
- retval.Error_TypeArgumentsCannotBeUsed (ec.Compiler.Report, loc);
- return;
- }
- }
-
- NamespaceEntry.Error_NamespaceNotFound (loc, Name, ec.Compiler.Report);
- }
-
- // TODO: I am still not convinced about this. If someone else will need it
- // implement this as virtual property in MemberCore hierarchy
- public static string GetMemberType (MemberCore mc)
- {
- if (mc is Property)
- return "property";
- if (mc is Indexer)
- return "indexer";
- if (mc is FieldBase)
- return "field";
- if (mc is MethodCore)
- return "method";
- if (mc is EnumMember)
- return "enum";
- if (mc is Event)
- return "event";
-
- return "type";
- }
-
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;
if (right_side != null) {
e = e.ResolveLValue (ec, right_side);
} else {
- ResolveFlags rf = ResolveFlags.VariableOrValue;
- if (intermediate)
- rf |= ResolveFlags.DisableFlowAnalysis;
-
- e = e.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);
+ if (e != null && Arity > 0)
+ e.Error_TypeArgumentsCannotBeUsed (ec.Report, loc, null, 0);
return e;
}
else
e = e.Resolve (ec);
- if (targs != null && e != null)
- e.Error_TypeArgumentsCannotBeUsed (ec.Report, loc);
+ if (e != null && Arity > 0)
+ e.Error_TypeArgumentsCannotBeUsed (ec.Report, loc, null, 0);
return e;
}
//
// Stage 2: Lookup members
//
-
- Type almost_matched_type = null;
- ArrayList 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);
+ int arity = HasTypeArguments ? Arity : -1;
+// TypeSpec almost_matched_type = null;
+// IList<MemberSpec> almost_matched = null;
+ for (TypeSpec lookup_ds = ec.CurrentType; lookup_ds != null; lookup_ds = lookup_ds.DeclaringType) {
+ e = MemberLookup (ec.Compiler, ec.CurrentType, lookup_ds, Name, arity, BindingRestriction.DefaultMemberLookup, loc);
if (e != null) {
PropertyExpr pe = e as PropertyExpr;
if (pe != null) {
- AParametersCollection param = TypeManager.GetParameterData (pe.PropertyInfo);
-
// 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.CurrentType, right_side != null))
+ if (pe.PropertyInfo.Kind == MemberKind.Property && pe.IsAccessibleFrom (ec.CurrentType, right_side != null))
break;
} else if (e is EventExpr) {
if (((EventExpr) e).IsAccessibleFrom (ec.CurrentType))
break;
- } else if (targs != null && e is TypeExpression) {
+ } else if (HasTypeArguments && e is TypeExpression) {
e = new GenericTypeExpr (e.Type, targs, loc).ResolveAsTypeStep (ec, false);
break;
} else {
}
e = null;
}
-
+/*
if (almost_matched == null && almost_matched_members.Count > 0) {
almost_matched_type = lookup_ds;
- almost_matched = (ArrayList) almost_matched_members.Clone ();
+ almost_matched = new List<MemberSpec>(almost_matched_members);
}
+*/
}
if (e == null) {
+/*
if (almost_matched == null && almost_matched_members.Count > 0) {
almost_matched_type = ec.CurrentType;
- almost_matched = (ArrayList) almost_matched_members.Clone ();
+ almost_matched = new List<MemberSpec> (almost_matched_members);
}
+*/
e = ResolveAsTypeStep (ec, true);
}
}
if (RootContext.EvalMode){
- FieldInfo fi = Evaluator.LookupField (Name);
+ var fi = Evaluator.LookupField (Name);
if (fi != null)
- return new FieldExpr (fi, loc).Resolve (ec);
+ return new FieldExpr (fi.Item1, loc).Resolve (ec);
}
-
+/*
if (almost_matched != null)
almost_matched_members = almost_matched;
if (almost_matched_type == null)
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);
+ return Error_MemberLookupFailed (ec, ec.CurrentType, null, ec.CurrentType, Name, arity,
+ type_name, MemberKind.All, BindingRestriction.AccessibleOnly);
}
if (e is MemberExpr) {
MemberExpr me = (MemberExpr) e;
- Expression left;
- if (me.IsInstance) {
- 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
- // and each predicate is true if the MethodGroupExpr contains
- // at least one of that kind of method.
- //
-
- if (!me.IsStatic &&
- (!intermediate || !IdenticalNameAndTypeName (ec, me, loc))) {
- Error_ObjectRefRequired (ec, loc, me.GetSignatureForError ());
- return null;
- }
-
- //
- // Pass the buck to MemberAccess and Invocation.
- //
- left = EmptyExpression.Null;
- } else {
- left = ec.GetThis (loc);
- }
- } else {
- left = new TypeExpression (ec.CurrentType, loc);
- }
-
- me = me.ResolveMemberAccess (ec, left, loc, null);
- if (me == null)
- return null;
+ // TODO: It's used by EventExpr -> FieldExpr transformation only
+ me = me.ResolveMemberAccess (ec, null, null);
- if (targs != null) {
+ if (HasTypeArguments) {
if (!targs.Resolve (ec))
return null;
me.SetTypeArguments (ec, targs);
}
- if (!me.IsStatic && (me.InstanceExpression != null && me.InstanceExpression != EmptyExpression.Null) &&
- TypeManager.IsNestedFamilyAccessible (me.InstanceExpression.Type, me.DeclaringType) &&
- me.InstanceExpression.Type != me.DeclaringType &&
- !TypeManager.IsFamilyAccessible (me.InstanceExpression.Type, me.DeclaringType) &&
- (!intermediate || !IdenticalNameAndTypeName (ec, e, loc))) {
- 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;
- }
+ if (intermediate)
+ return me;
return (right_side != null)
? me.DoResolveLValue (ec, right_side)
- : me.DoResolve (ec);
+ : me.Resolve (ec);
}
return e;
throw new NotSupportedException ("ET");
}
- public override void MutateHoistedGenericType (AnonymousMethodStorey storey)
- {
- throw new NotSupportedException ();
- }
-
public override FullNamedExpression ResolveAsTypeStep (IMemberContext ec, bool silent)
{
return this;
return t;
}
- override public Expression DoResolve (ResolveContext ec)
+ protected override Expression DoResolve (ResolveContext ec)
{
return ResolveAsTypeTerminal (ec, false);
}
public virtual bool CheckAccessLevel (IMemberContext mc)
{
- return mc.CurrentTypeDefinition.CheckAccessLevel (Type);
- }
+ DeclSpace c = mc.CurrentMemberDefinition as DeclSpace;
+ if (c == null)
+ c = mc.CurrentMemberDefinition.Parent;
- public virtual bool IsClass {
- get { return Type.IsClass; }
- }
-
- public virtual bool IsValueType {
- get { return TypeManager.IsStruct (Type); }
- }
-
- public virtual bool IsInterface {
- get { return Type.IsInterface; }
- }
-
- public virtual bool IsSealed {
- get { return Type.IsSealed; }
- }
-
- public virtual bool CanInheritFrom ()
- {
- if (Type == TypeManager.enum_type ||
- (Type == TypeManager.value_type && RootContext.StdLib) ||
- Type == TypeManager.multicast_delegate_type ||
- Type == TypeManager.delegate_type ||
- Type == TypeManager.array_type)
- return false;
-
- return true;
+ return c.CheckAccessLevel (Type);
}
protected abstract TypeExpr DoResolveAsTypeStep (IMemberContext ec);
{
return Type.GetHashCode ();
}
-
- public override void MutateHoistedGenericType (AnonymousMethodStorey storey)
- {
- type = storey.MutateType (type);
- }
}
/// <summary>
/// Fully resolved Expression that already evaluated to a type
/// </summary>
public class TypeExpression : TypeExpr {
- public TypeExpression (Type t, Location l)
+ public TypeExpression (TypeSpec t, Location l)
{
Type = t;
eclass = ExprClass.Type;
}
}
- //
- // Used to create types from a fully qualified name. These are just used
- // by the parser to setup the core types.
- //
- public sealed class TypeLookupExpression : TypeExpr {
- readonly string ns_name;
- readonly string name;
-
- public TypeLookupExpression (string ns, string name)
- {
- this.name = name;
- this.ns_name = ns;
- eclass = ExprClass.Type;
- }
-
- public override TypeExpr ResolveAsTypeTerminal (IMemberContext ec, bool silent)
- {
- //
- // It's null only during mscorlib bootstrap when DefineType
- // nees to resolve base type of same type
- //
- // For instance struct Char : IComparable<char>
- //
- // TODO: it could be removed when Resolve starts to use
- // DeclSpace instead of Type
- //
- if (type == null) {
- Namespace ns = GlobalRootNamespace.Instance.GetNamespace (ns_name, false);
- FullNamedExpression fne = ns.Lookup (ec.Compiler, name, loc);
- if (fne != null)
- type = fne.Type;
- }
-
- return this;
- }
-
- protected override TypeExpr DoResolveAsTypeStep (IMemberContext ec)
- {
- return this;
- }
-
- public override string GetSignatureForError ()
- {
- if (type == null)
- return TypeManager.CSharpName (ns_name + "." + name, null);
-
- return base.GetSignatureForError ();
- }
- }
-
/// <summary>
/// This class denotes an expression which evaluates to a member
/// of a struct or a class.
/// </summary>
public abstract class MemberExpr : Expression
{
- protected bool is_base;
+ //
+ // An instance expression associated with this member, if it's a
+ // non-static member
+ //
+ public Expression InstanceExpression;
/// <summary>
/// The name of this member.
// When base.member is used
//
public bool IsBase {
- get { return is_base; }
- set { is_base = value; }
+ get { return InstanceExpression is BaseThis; }
}
/// <summary>
/// <summary>
/// The type which declares this member.
/// </summary>
- public abstract Type DeclaringType {
+ public abstract TypeSpec DeclaringType {
get;
}
- /// <summary>
- /// The instance expression associated with this member, if it's a
- /// non-static member.
- /// </summary>
- public Expression InstanceExpression;
-
- public static void error176 (ResolveContext ec, Location loc, string name)
+ //
+ // Converts best base candidate for virtual method starting from QueriedBaseType
+ //
+ protected MethodSpec CandidateToBaseOverride (ResolveContext rc, MethodSpec method)
{
- ec.Report.Error (176, loc, "Static member `{0}' cannot be accessed " +
- "with an instance reference, qualify it with a type name instead", name);
- }
+ //
+ // Only when base.member is used and method is virtual
+ //
+ if (!IsBase || method.DeclaringType == InstanceExpression.Type)
+ return method;
- public static void Error_BaseAccessInExpressionTree (ResolveContext ec, Location loc)
- {
- ec.Report.Error (831, loc, "An expression tree may not contain a base access");
+ //
+ // Overload resulution works on virtual or non-virtual members only (no overrides). That
+ // means for base.member access we have to find the closest match after we found best candidate
+ //
+ if ((method.Modifiers & (Modifiers.ABSTRACT | Modifiers.VIRTUAL | Modifiers.STATIC)) != Modifiers.STATIC) {
+ var base_override = MemberCache.FindMember (InstanceExpression.Type, new MemberFilter (method), BindingRestriction.InstanceOnly) as MethodSpec;
+ if (base_override != null && base_override.DeclaringType != method.DeclaringType) {
+ if (base_override.IsGeneric)
+ base_override = base_override.MakeGenericMethod (method.TypeArguments);
+
+ if (rc.CurrentAnonymousMethod != null)
+ throw new NotImplementedException ("base call hoisting");
+
+ return base_override;
+ }
+ }
+
+ return method;
}
- public override void MutateHoistedGenericType (AnonymousMethodStorey storey)
+ //
+ // Implements identicial simple name and type-name
+ //
+ public Expression ProbeIdenticalTypeName (ResolveContext rc, Expression left, SimpleName name)
{
- if (InstanceExpression != null)
- InstanceExpression.MutateHoistedGenericType (storey);
+ var t = left.Type;
+ if (t.Kind == MemberKind.InternalCompilerType || t is ElementTypeSpec || t.Arity > 0)
+ return left;
+
+ // In a member access of the form E.I, if E is a single identifier, and if the meaning of E as a simple-name is
+ // a constant, field, property, local variable, or parameter with the same type as the meaning of E as a type-name
+
+ if (left is MemberExpr || left is VariableReference) {
+ rc.Report.DisableReporting ();
+ Expression identical_type = rc.LookupNamespaceOrType (name.Name, 0, loc, true) as TypeExpr;
+ rc.Report.EnableReporting ();
+ if (identical_type != null && identical_type.Type == left.Type)
+ return identical_type;
+ }
+
+ return left;
}
- // TODO: possible optimalization
- // Cache resolved constant result in FieldBuilder <-> expression map
- public virtual MemberExpr ResolveMemberAccess (ResolveContext ec, Expression left, Location loc,
- SimpleName original)
+ protected bool ResolveInstanceExpression (ResolveContext rc)
{
- //
- // Precondition:
- // original == null || original.Resolve (...) ==> left
- //
-
- if (left is TypeExpr) {
- left = left.ResolveAsBaseTerminal (ec, false);
- if (left == null)
- return null;
+ if (IsStatic) {
+ if (InstanceExpression != null) {
+ if (InstanceExpression is TypeExpr) {
+ ObsoleteAttribute oa = InstanceExpression.Type.GetAttributeObsolete ();
+ if (oa != null && !rc.IsObsolete) {
+ AttributeTester.Report_ObsoleteMessage (oa, InstanceExpression.GetSignatureForError (), loc, rc.Report);
+ }
+ } else {
+ var runtime_expr = InstanceExpression as RuntimeValueExpression;
+ if (runtime_expr == null || !runtime_expr.IsSuggestionOnly) {
+ rc.Report.Error (176, loc,
+ "Static member `{0}' cannot be accessed with an instance reference, qualify it with a type name instead",
+ GetSignatureForError ());
+ }
+ }
- // 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.IsObsolete) {
- AttributeTester.Report_ObsoleteMessage (oa, left.GetSignatureForError (), loc, ec.Report);
+ InstanceExpression = null;
}
- GenericTypeExpr ct = left as GenericTypeExpr;
- if (ct != null && !ct.CheckConstraints (ec))
- return null;
- //
+ return false;
+ }
- if (!IsStatic) {
- SimpleName.Error_ObjectRefRequired (ec, loc, GetSignatureForError ());
- return null;
+ if (InstanceExpression == null || InstanceExpression is TypeExpr) {
+ if (InstanceExpression != null || !This.IsThisAvailable (rc, true)) {
+ if (rc.HasSet (ResolveContext.Options.FieldInitializerScope))
+ rc.Report.Error (236, loc,
+ "A field initializer cannot reference the nonstatic field, method, or property `{0}'",
+ GetSignatureForError ());
+ else
+ rc.Report.Error (120, loc,
+ "An object reference is required to access non-static member `{0}'",
+ GetSignatureForError ());
+
+ return false;
}
- return this;
- }
-
- if (!IsInstance) {
- if (original != null && original.IdenticalNameAndTypeName (ec, left, loc))
- return this;
+ if (!TypeManager.IsFamilyAccessible (rc.CurrentType, DeclaringType)) {
+ rc.Report.Error (38, loc,
+ "Cannot access a nonstatic member of outer type `{0}' via nested type `{1}'",
+ DeclaringType.GetSignatureForError (), rc.CurrentType.GetSignatureForError ());
+ }
- return ResolveExtensionMemberAccess (ec, left);
+ InstanceExpression = rc.GetThis (loc);
+ return false;
}
- InstanceExpression = left;
- return this;
+ var me = InstanceExpression as MemberExpr;
+ if (me != null)
+ me.ResolveInstanceExpression (rc);
+
+ return true;
}
- protected virtual MemberExpr ResolveExtensionMemberAccess (ResolveContext ec, Expression left)
+ public virtual MemberExpr ResolveMemberAccess (ResolveContext ec, Expression left, SimpleName original)
{
- error176 (ec, loc, GetSignatureForError ());
+ if (left != null && left.IsNull && TypeManager.IsReferenceType (left.Type)) {
+ ec.Report.Warning (1720, 1, left.Location,
+ "Expression will always cause a `{0}'", "System.NullReferenceException");
+ }
+
+ InstanceExpression = left;
return this;
}
protected void EmitInstance (EmitContext ec, bool prepare_for_load)
{
- if (IsStatic)
- return;
-
- if (InstanceExpression == EmptyExpression.Null) {
- // FIXME: This should not be here at all
- SimpleName.Error_ObjectRefRequired (new ResolveContext (ec.MemberContext), loc, GetSignatureForError ());
- return;
- }
-
if (TypeManager.IsValueType (InstanceExpression.Type)) {
if (InstanceExpression is IMemoryLocation) {
((IMemoryLocation) InstanceExpression).AddressOf (ec, AddressOp.LoadStore);
InstanceExpression.Emit (ec);
if (prepare_for_load)
- ec.ig.Emit (OpCodes.Dup);
+ ec.Emit (OpCodes.Dup);
}
public virtual void SetTypeArguments (ResolveContext ec, TypeArguments ta)
{
readonly NamespaceEntry namespace_entry;
public Expression ExtensionExpression;
- Argument extension_argument;
- public ExtensionMethodGroupExpr (ArrayList list, NamespaceEntry n, Type extensionType, Location l)
- : base (list, extensionType, l)
+ public ExtensionMethodGroupExpr (List<MethodSpec> list, NamespaceEntry n, TypeSpec extensionType, Location l)
+ : base (list.Cast<MemberSpec>().ToList (), extensionType, l)
{
this.namespace_entry = n;
}
get { return namespace_entry == null; }
}
- public override void MutateHoistedGenericType (AnonymousMethodStorey storey)
- {
- extension_argument.Expr.MutateHoistedGenericType (storey);
- base.MutateHoistedGenericType (storey);
- }
-
public override MethodGroupExpr OverloadResolve (ResolveContext ec, ref Arguments arguments, bool may_fail, Location loc)
{
if (arguments == null)
MethodGroupExpr mg = ResolveOverloadExtensions (ec, ref arguments, namespace_entry, loc);
// Store resolved argument and restore original arguments
- if (mg != null)
- ((ExtensionMethodGroupExpr)mg).extension_argument = arguments [0];
- else
+ if (mg == null)
arguments.RemoveAt (0); // Clean-up modified arguments for error reporting
return mg;
return null;
// Search continues
- ExtensionMethodGroupExpr e = ns.LookupExtensionMethod (type, Name, loc);
+ int arity = type_arguments == null ? -1 : type_arguments.Count;
+ ExtensionMethodGroupExpr e = ns.LookupExtensionMethod (type, Name, arity, loc);
if (e == null)
return base.OverloadResolve (ec, ref arguments, false, loc);
{
public interface IErrorHandler
{
- bool AmbiguousCall (ResolveContext ec, MethodBase ambiguous);
- bool NoExactMatch (ResolveContext ec, MethodBase method);
+ bool AmbiguousCall (ResolveContext ec, MethodGroupExpr mg, MethodSpec ambiguous);
+ bool NoExactMatch (ResolveContext ec, MethodSpec method);
}
- public IErrorHandler CustomErrorHandler;
- public MethodBase [] Methods;
- MethodBase best_candidate;
+ public IErrorHandler CustomErrorHandler;
+ protected IList<MemberSpec> Methods;
+ MethodSpec best_candidate;
// TODO: make private
public TypeArguments type_arguments;
- bool identical_type_name;
+ SimpleName simple_name;
bool has_inaccessible_candidates_only;
- Type delegate_type;
- Type queried_type;
-
- public MethodGroupExpr (MemberInfo [] mi, Type type, Location l)
+ TypeSpec delegate_type;
+ TypeSpec queried_type;
+
+ public MethodGroupExpr (IList<MemberSpec> mi, TypeSpec type, Location l)
: this (type, l)
{
- Methods = new MethodBase [mi.Length];
- mi.CopyTo (Methods, 0);
+ Methods = mi;
}
- public MethodGroupExpr (MemberInfo[] mi, Type type, Location l, bool inacessibleCandidatesOnly)
- : this (mi, type, l)
+ public MethodGroupExpr (MethodSpec m, TypeSpec type, Location l)
+ : this (type, l)
{
- has_inaccessible_candidates_only = inacessibleCandidatesOnly;
+ Methods = new List<MemberSpec> (1) { m };
}
- public MethodGroupExpr (ArrayList list, Type type, Location l)
- : this (type, l)
+ public MethodGroupExpr (IList<MemberSpec> mi, TypeSpec type, Location l, bool inacessibleCandidatesOnly)
+ : this (mi, type, l)
{
- try {
- Methods = (MethodBase[])list.ToArray (typeof (MethodBase));
- } catch {
- foreach (MemberInfo m in list){
- if (!(m is MethodBase)){
- Console.WriteLine ("Name " + m.Name);
- Console.WriteLine ("Found a: " + m.GetType ().FullName);
- }
- }
- throw;
- }
-
-
+ has_inaccessible_candidates_only = inacessibleCandidatesOnly;
}
-
- protected MethodGroupExpr (Type type, Location loc)
+
+ protected MethodGroupExpr (TypeSpec type, Location loc)
{
this.loc = loc;
eclass = ExprClass.MethodGroup;
queried_type = type;
}
- public override Type DeclaringType {
- get {
- return queried_type;
- }
- }
+ #region Properties
- public Type DelegateType {
- set {
- delegate_type = value;
+ public MethodSpec BestCandidate {
+ get {
+ return best_candidate;
}
}
- public bool IdenticalTypeName {
+ public override TypeSpec DeclaringType {
get {
- return identical_type_name;
+ return queried_type;
}
}
- public override string GetSignatureForError ()
- {
- if (best_candidate != null)
- return TypeManager.CSharpSignature (best_candidate);
-
- return TypeManager.CSharpSignature (Methods [0]);
- }
-
- public override string Name {
- get {
- return Methods [0].Name;
+ public TypeSpec DelegateType {
+ set {
+ delegate_type = value;
}
}
if (best_candidate != null)
return !best_candidate.IsStatic;
- foreach (MethodBase mb in Methods)
- if (!mb.IsStatic)
- return true;
-
return false;
}
}
if (best_candidate != null)
return best_candidate.IsStatic;
- foreach (MethodBase mb in Methods)
- if (mb.IsStatic)
- return true;
-
return false;
}
}
-
- public static explicit operator ConstructorInfo (MethodGroupExpr mg)
+
+ public override string Name {
+ get {
+ if (best_candidate != null)
+ return best_candidate.Name;
+
+ // TODO: throw ?
+ return Methods.First ().Name;
+ }
+ }
+
+ #endregion
+
+ //
+ // When best candidate is already know this factory can be used
+ // to avoid expensive overload resolution to be called
+ //
+ // NOTE: InstanceExpression has to be set manually
+ //
+ public static MethodGroupExpr CreatePredefined (MethodSpec best, TypeSpec queriedType, Location loc)
{
- return (ConstructorInfo)mg.best_candidate;
+ return new MethodGroupExpr (best, queriedType, loc) {
+ best_candidate = best
+ };
}
- public static explicit operator MethodInfo (MethodGroupExpr mg)
+ public override string GetSignatureForError ()
{
- return (MethodInfo)mg.best_candidate;
+ if (best_candidate != null)
+ return best_candidate.GetSignatureForError ();
+
+ return Methods.First ().GetSignatureForError ();
}
//
// 2 if a->q is better,
// 0 if neither is better
//
- static int BetterExpressionConversion (ResolveContext ec, Argument a, Type p, Type q)
+ static int BetterExpressionConversion (ResolveContext ec, Argument a, TypeSpec p, TypeSpec q)
{
- Type argument_type = TypeManager.TypeToCoreType (a.Type);
+ TypeSpec argument_type = a.Type;
if (argument_type == InternalType.AnonymousMethod && RootContext.Version > LanguageVersion.ISO_2) {
//
// Uwrap delegate from Expression<T>
//
- if (TypeManager.DropGenericTypeArguments (p) == TypeManager.expression_type) {
+ if (p.GetDefinition () == TypeManager.expression_type) {
p = TypeManager.GetTypeArguments (p) [0];
}
- if (TypeManager.DropGenericTypeArguments (q) == TypeManager.expression_type) {
+ if (q.GetDefinition () == TypeManager.expression_type) {
q = TypeManager.GetTypeArguments (q) [0];
}
- p = Delegate.GetInvokeMethod (ec.Compiler, null, p).ReturnType;
- q = Delegate.GetInvokeMethod (ec.Compiler, null, q).ReturnType;
+ p = Delegate.GetInvokeMethod (ec.Compiler, p).ReturnType;
+ q = Delegate.GetInvokeMethod (ec.Compiler, 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 (ResolveContext ec, Type p, Type q)
+ public static int BetterTypeConversion (ResolveContext ec, TypeSpec p, TypeSpec q)
{
if (p == null || q == null)
throw new InternalErrorException ("BetterTypeConversion got a null conversion");
/// true if candidate is better than the current best match
/// </remarks>
static bool BetterFunction (ResolveContext ec, Arguments args, int argument_count,
- MethodBase candidate, bool candidate_params,
- MethodBase best, bool best_params)
+ 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;
if (a.IsDefaultArgument && candidate_params == best_params)
return false;
- Type ct = candidate_pd.Types [c_idx];
- Type bt = best_pd.Types [b_idx];
+ TypeSpec ct = candidate_pd.Types [c_idx];
+ TypeSpec bt = best_pd.Types [b_idx];
if (candidate_params && candidate_pd.FixedParameters [c_idx].ModFlags == Parameter.Modifier.PARAMS)
{
bt = TypeManager.GetElementType (bt);
--b_idx;
}
-
- if (ct == 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.IsGeneric) {
+ if (!candidate.IsGeneric)
return true;
- } else if (TypeManager.IsGenericMethod (candidate)) {
+ } else if (candidate.IsGeneric) {
return false;
}
return candidate_param_count > best_param_count && best_pd.HasParams;
//
- // now, both methods have the same number of parameters, and the parameters have the same types
- // Pick the "more specific" signature
+ // Both methods have the same number of parameters, and the parameters have equal types
+ // Pick the "more specific" signature using rules over original (non-inflated) types
//
-
- MethodBase orig_candidate = TypeManager.DropGenericMethodArguments (candidate);
- MethodBase orig_best = TypeManager.DropGenericMethodArguments (best);
-
- AParametersCollection orig_candidate_pd = TypeManager.GetParameterData (orig_candidate);
- AParametersCollection orig_best_pd = TypeManager.GetParameterData (orig_best);
+ var candidate_def_pd = ((IParametersMember) candidate.MemberDefinition).Parameters;
+ var best_def_pd = ((IParametersMember) best.MemberDefinition).Parameters;
bool specific_at_least_once = false;
for (int j = 0; j < candidate_param_count; ++j)
{
- Type ct = orig_candidate_pd.Types [j];
- Type bt = orig_best_pd.Types [j];
- if (ct.Equals (bt))
+ var ct = candidate_def_pd.Types [j];
+ var bt = best_def_pd.Types [j];
+ if (ct == bt)
continue;
- Type specific = MoreSpecific (ct, bt);
+ TypeSpec specific = MoreSpecific (ct, bt);
if (specific == bt)
return false;
if (specific == ct)
return false;
}
- protected override MemberExpr ResolveExtensionMemberAccess (ResolveContext ec, Expression left)
+ public override MemberExpr ResolveMemberAccess (ResolveContext ec, Expression left, SimpleName original)
{
- if (!IsStatic)
- return base.ResolveExtensionMemberAccess (ec, left);
+ simple_name = original;
- //
- // When left side is an expression and at least one candidate method is
- // static, it can be extension method
- //
- InstanceExpression = left;
- return this;
- }
-
- public override MemberExpr ResolveMemberAccess (ResolveContext ec, Expression left, Location loc,
- SimpleName original)
- {
- if (!(left is TypeExpr) &&
- original != null && original.IdenticalNameAndTypeName (ec, left, loc))
- identical_type_name = true;
-
- return base.ResolveMemberAccess (ec, left, loc, original);
+ return base.ResolveMemberAccess (ec, left, original);
}
public override Expression CreateExpressionTree (ResolveContext ec)
return null;
}
- IMethodData md = TypeManager.GetMethod (best_candidate);
- if (md != null && md.IsExcluded ())
+ if (best_candidate.IsConditionallyExcluded (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 TypeOfMethod (best_candidate, loc);
}
- override public Expression DoResolve (ResolveContext 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;
}
override public void Emit (EmitContext ec)
{
throw new NotSupportedException ();
- // ReportUsageError ();
}
public void EmitCall (EmitContext ec, Arguments arguments)
{
- Invocation.EmitCall (ec, IsBase, InstanceExpression, best_candidate, arguments, loc);
+ Invocation.EmitCall (ec, InstanceExpression, best_candidate, arguments, loc);
}
- void Error_AmbiguousCall (ResolveContext ec, MethodBase ambiguous)
+ void Error_AmbiguousCall (ResolveContext ec, MethodSpec ambiguous)
{
- if (CustomErrorHandler != null && CustomErrorHandler.AmbiguousCall (ec, ambiguous))
+ if (CustomErrorHandler != null && CustomErrorHandler.AmbiguousCall (ec, this, ambiguous))
return;
ec.Report.SymbolRelatedToPreviousError (best_candidate);
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));
+ best_candidate.GetSignatureForError (), ambiguous.GetSignatureForError ());
}
- protected virtual void Error_InvalidArguments (ResolveContext ec, Location loc, int idx, MethodBase method,
- Argument a, AParametersCollection expected_par, Type paramType)
+ protected virtual void Error_InvalidArguments (ResolveContext ec, Location loc, int idx, MethodSpec method,
+ Argument a, AParametersCollection expected_par, TypeSpec paramType)
{
ExtensionMethodGroupExpr emg = this as ExtensionMethodGroupExpr;
}
}
- public override void Error_ValueCannotBeConverted (ResolveContext ec, Location loc, Type target, bool expl)
+ public override void Error_ValueCannotBeConverted (ResolveContext ec, Location loc, TypeSpec target, bool expl)
{
ec.Report.Error (428, loc, "Cannot convert method group `{0}' to non-delegate type `{1}'. Consider using parentheses to invoke the method",
Name, TypeManager.CSharpName (target));
Name, arg_count.ToString ());
}
- protected virtual int GetApplicableParametersCount (MethodBase method, AParametersCollection parameters)
+ protected virtual int GetApplicableParametersCount (MethodSpec method, AParametersCollection parameters)
{
return parameters.Count;
- }
+ }
+
+ protected virtual IList<MemberSpec> GetBaseTypeMethods (ResolveContext rc, TypeSpec type)
+ {
+ var arity = type_arguments == null ? -1 : type_arguments.Count;
- public static bool IsAncestralType (Type first_type, Type second_type)
+ return TypeManager.MemberLookup (rc.CurrentType, null, type,
+ MemberKind.Method, BindingRestriction.AccessibleOnly | BindingRestriction.DefaultMemberLookup,
+ Name, arity, null);
+ }
+
+ bool GetBaseTypeMethods (ResolveContext rc)
{
- return first_type != second_type &&
- (TypeManager.IsSubclassOf (second_type, first_type) ||
- TypeManager.ImplementsInterface (second_type, first_type));
+ var base_type = Methods [0].DeclaringType.BaseType;
+ if (base_type == null)
+ return false;
+
+ var methods = GetBaseTypeMethods (rc, base_type);
+ if (methods == null)
+ return false;
+
+ Methods = methods;
+ return true;
}
///
/// 0 = the best, int.MaxValue = the worst
///
public int IsApplicable (ResolveContext ec,
- ref Arguments arguments, int arg_count, ref MethodBase method, ref bool params_expanded_form)
+ 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;
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)
//
// 1. Handle generic method using type arguments when specified or type inference
//
- if (TypeManager.IsGenericMethod (candidate)) {
+ if (candidate.IsGeneric) {
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);
+ var g_args_count = candidate.Arity;
+ if (g_args_count != type_arguments.Count)
+ return int.MaxValue - 20000 + System.Math.Abs (type_arguments.Count - g_args_count);
- // TODO: Don't create new method, create Parameters only
- method = ((MethodInfo) candidate).MakeGenericMethod (type_arguments.Arguments);
+ method = candidate.MakeGenericMethod (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))
- throw new InternalErrorException ("A generic method `{0}' definition took part in overload resolution",
- TypeManager.CSharpSignature (candidate));
-
- pd = TypeManager.GetParameterData (candidate);
+ pd = candidate.Parameters;
}
} else {
if (type_arguments != null)
//
method = candidate;
Parameter.Modifier p_mod = 0;
- Type pt = null;
+ TypeSpec pt = null;
for (int i = 0; i < arg_count; i++) {
Argument a = arguments [i];
if (a == null) {
return 0;
}
- int IsArgumentCompatible (ResolveContext 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, TypeSpec parameter)
{
//
// Types have to be identical when ref or out modifer is used
//
if (arg_mod != 0 || param_mod != 0) {
- if (TypeManager.HasElementType (parameter))
- parameter = TypeManager.GetElementType (parameter);
-
- Type a_type = argument.Type;
- if (TypeManager.HasElementType (a_type))
- a_type = TypeManager.GetElementType (a_type);
-
- if (a_type != parameter) {
- if (TypeManager.IsDynamicType (a_type))
+ if (argument.Type != parameter) {
+ if (argument.Type == InternalType.Dynamic)
return 0;
return 2;
}
} else {
if (!Convert.ImplicitConversionExists (ec, argument.Expr, parameter)) {
- if (TypeManager.IsDynamicType (argument.Type))
+ if (argument.Type == InternalType.Dynamic)
return 0;
return 2;
return 0;
}
- public static bool IsOverride (MethodBase cand_method, MethodBase base_method)
- {
- if (!IsAncestralType (base_method.DeclaringType, cand_method.DeclaringType))
- return false;
-
- AParametersCollection cand_pd = TypeManager.GetParameterData (cand_method);
- AParametersCollection base_pd = TypeManager.GetParameterData (base_method);
-
- if (cand_pd.Count != base_pd.Count)
- return false;
-
- for (int j = 0; j < cand_pd.Count; ++j)
- {
- Parameter.Modifier cm = cand_pd.FixedParameters [j].ModFlags;
- Parameter.Modifier bm = base_pd.FixedParameters [j].ModFlags;
- Type ct = cand_pd.Types [j];
- Type bt = base_pd.Types [j];
-
- if (cm != bm || ct != bt)
- return false;
- }
-
- return true;
- }
-
- public static MethodGroupExpr MakeUnionSet (MethodGroupExpr mg1, MethodGroupExpr mg2, Location loc)
- {
- if (mg1 == null) {
- if (mg2 == null)
- return null;
- return mg2;
- }
-
- if (mg2 == null)
- return mg1;
-
- ArrayList all = new ArrayList (mg1.Methods);
- foreach (MethodBase m in mg2.Methods){
- if (!TypeManager.ArrayContainsMethod (mg1.Methods, m, false))
- all.Add (m);
- }
-
- return new MethodGroupExpr (all, null, loc);
- }
-
- static Type MoreSpecific (Type p, Type q)
+ static TypeSpec MoreSpecific (TypeSpec p, TypeSpec q)
{
if (TypeManager.IsGenericParameter (p) && !TypeManager.IsGenericParameter (q))
return q;
if (!TypeManager.IsGenericParameter (p) && TypeManager.IsGenericParameter (q))
return p;
- if (TypeManager.HasElementType (p))
- {
- Type pe = TypeManager.GetElementType (p);
- Type qe = TypeManager.GetElementType (q);
- Type specific = MoreSpecific (pe, qe);
- if (specific == pe)
+ var ac_p = p as ArrayContainer;
+ if (ac_p != null) {
+ var ac_q = ((ArrayContainer) q);
+ TypeSpec specific = MoreSpecific (ac_p.Element, (ac_q.Element));
+ if (specific == ac_p.Element)
return p;
- if (specific == qe)
+ if (specific == ac_q.Element)
return q;
- }
- else if (TypeManager.IsGenericType (p))
- {
- Type[] pargs = TypeManager.GetTypeArguments (p);
- Type[] qargs = TypeManager.GetTypeArguments (q);
+ } else if (TypeManager.IsGenericType (p)) {
+ var pargs = TypeManager.GetTypeArguments (p);
+ var qargs = TypeManager.GetTypeArguments (q);
bool p_specific_at_least_once = false;
bool q_specific_at_least_once = false;
- for (int i = 0; i < pargs.Length; i++)
- {
- Type specific = MoreSpecific (TypeManager.TypeToCoreType (pargs [i]), TypeManager.TypeToCoreType (qargs [i]));
- if (specific == pargs [i])
+ for (int i = 0; i < pargs.Length; i++) {
+ TypeSpec specific = MoreSpecific (pargs[i], qargs[i]);
+ if (specific == pargs[i])
p_specific_at_least_once = true;
- if (specific == qargs [i])
+ if (specific == qargs[i])
q_specific_at_least_once = true;
}
return null;
}
- public override void MutateHoistedGenericType (AnonymousMethodStorey storey)
- {
- base.MutateHoistedGenericType (storey);
-
- MethodInfo mi = best_candidate as MethodInfo;
- if (mi != null) {
- best_candidate = storey.MutateGenericMethod (mi);
- return;
- }
-
- best_candidate = storey.MutateConstructor ((ConstructorInfo) this);
- }
-
/// <summary>
/// Find the Applicable Function Members (7.4.2.1)
///
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;
+ // TODO: causes some issues with linq
+ //if (best_candidate != null)
+ // return this;
- //
- // Used to keep a map between the candidate
- // and whether it is being considered in its
- // normal or expanded form
- //
- // false is normal form, true is expanded form
- //
- Hashtable candidate_to_form = null;
- Hashtable candidates_expanded = null;
- Arguments candidate_args = Arguments;
+ var candidates = new List<MethodSpec> (2);
+ List<MethodSpec> params_candidates = null;
int arg_count = Arguments != null ? Arguments.Count : 0;
+ Dictionary<MethodSpec, Arguments> candidates_expanded = null;
+ Arguments candidate_args = Arguments;
if (RootContext.Version == LanguageVersion.ISO_1 && Name == "Invoke" && TypeManager.IsDelegateType (DeclaringType)) {
if (!may_fail)
return null;
}
- int nmethods = Methods.Length;
-
- if (!IsBase) {
- //
- // Methods marked 'override' don't take part in 'applicable_type'
- // computation, nor in the actual overload resolution.
- // However, they still need to be emitted instead of a base virtual method.
- // So, we salt them away into the 'candidate_overrides' array.
- //
- // In case of reflected methods, we replace each overriding method with
- // its corresponding base virtual method. This is to improve compatibility
- // with non-C# libraries which change the visibility of overrides (#75636)
- //
- int j = 0;
- for (int i = 0; i < Methods.Length; ++i) {
- MethodBase m = Methods [i];
- if (TypeManager.IsOverride (m)) {
- if (candidate_overrides == null)
- candidate_overrides = new ArrayList ();
- candidate_overrides.Add (m);
- m = TypeManager.TryGetBaseDefinition (m);
- }
- if (m != null)
- Methods [j++] = m;
- }
- nmethods = j;
- }
-
//
// Enable message recording, it's used mainly by lambda expressions
//
- SessionReportPrinter msg_recorder = new SessionReportPrinter ();
- ReportPrinter prev_recorder = ec.Report.SetPrinter (msg_recorder);
-
- //
- // First we construct the set of applicable methods
- //
- bool is_sorted = true;
- int best_candidate_rate = int.MaxValue;
- for (int i = 0; i < nmethods; i++) {
- Type decl_type = Methods [i].DeclaringType;
-
- //
- // If we have already found an applicable method
- // we eliminate all base types (Section 14.5.5.1)
- //
- if (applicable_type != null && IsAncestralType (decl_type, applicable_type))
- continue;
-
- //
- // Check if candidate is applicable (section 14.4.2.1)
- //
- bool params_expanded_form = false;
- int candidate_rate = IsApplicable (ec, ref candidate_args, arg_count, ref Methods [i], ref params_expanded_form);
+ var msg_recorder = new SessionReportPrinter ();
+ var prev_recorder = ec.Report.SetPrinter (msg_recorder);
+ try {
+ do {
+ //
+ // Methods in a base class are not candidates if any method in a derived
+ // class is applicable
+ //
+ int best_candidate_rate = int.MaxValue;
+
+ foreach (var member in Methods) {
+ var m = member as MethodSpec;
+ if (m == null) {
+ // TODO: It's wrong when non-member is before applicable method
+ // TODO: Should report only when at least 1 from the batch is applicable
+ if (candidates.Count != 0) {
+ ec.Report.SymbolRelatedToPreviousError (candidates[0]);
+ ec.Report.SymbolRelatedToPreviousError (member);
+ ec.Report.Warning (467, 2, loc, "Ambiguity between method `{0}' and non-method `{1}'. Using method `{0}'",
+ candidates[0].GetSignatureForError (), member.GetSignatureForError ());
+ }
+ continue;
+ }
- if (candidate_rate < best_candidate_rate) {
- best_candidate_rate = candidate_rate;
- best_candidate = Methods [i];
- }
-
- if (params_expanded_form) {
- if (candidate_to_form == null)
- candidate_to_form = new PtrHashtable ();
- MethodBase candidate = Methods [i];
- candidate_to_form [candidate] = candidate;
- }
-
- if (candidate_args != Arguments) {
- if (candidates_expanded == null)
- candidates_expanded = new Hashtable (2);
+ //
+ // Check if candidate is applicable (section 14.4.2.1)
+ //
+ bool params_expanded_form = false;
+ int candidate_rate = IsApplicable (ec, ref candidate_args, arg_count, ref m, ref params_expanded_form);
- candidates_expanded.Add (Methods [i], candidate_args);
- candidate_args = Arguments;
- }
+ if (candidate_rate < best_candidate_rate) {
+ best_candidate_rate = candidate_rate;
+ best_candidate = m;
+ }
- if (candidate_rate != 0 || has_inaccessible_candidates_only) {
- if (msg_recorder != null)
- msg_recorder.EndSession ();
- continue;
- }
+ if (params_expanded_form) {
+ if (params_candidates == null)
+ params_candidates = new List<MethodSpec> (2);
+ params_candidates.Add (m);
+ }
- msg_recorder = null;
- candidates.Add (Methods [i]);
+ if (candidate_args != Arguments) {
+ if (candidates_expanded == null)
+ candidates_expanded = new Dictionary<MethodSpec, Arguments> (2);
- if (applicable_type == null)
- applicable_type = decl_type;
- else if (applicable_type != decl_type) {
- is_sorted = false;
- if (IsAncestralType (applicable_type, decl_type))
- applicable_type = decl_type;
- }
- }
+ candidates_expanded.Add (m, candidate_args);
+ candidate_args = Arguments;
+ }
- ec.Report.SetPrinter (prev_recorder);
- if (msg_recorder != null && !msg_recorder.IsEmpty) {
- if (!may_fail)
- msg_recorder.Merge (prev_recorder);
+ if (candidate_rate != 0 || has_inaccessible_candidates_only) {
+ if (msg_recorder != null)
+ msg_recorder.EndSession ();
+ continue;
+ }
- return null;
+ msg_recorder = null;
+ candidates.Add (m);
+ }
+ } while (candidates.Count == 0 && GetBaseTypeMethods (ec));
+ } finally {
+ ec.Report.SetPrinter (prev_recorder);
}
-
- int candidate_top = candidates.Count;
- if (applicable_type == null) {
+ int candidate_top = candidates.Count;
+ if (candidate_top == 0) {
//
// When we found a top level method which does not match and it's
// not an extension method. We start extension methods lookup from here
//
if (InstanceExpression != null) {
- ExtensionMethodGroupExpr ex_method_lookup = ec.LookupExtensionMethod (type, Name, loc);
+ var first = Methods.First ();
+ var arity = type_arguments == null ? -1 : type_arguments.Count;
+ ExtensionMethodGroupExpr ex_method_lookup = ec.LookupExtensionMethod (type, first.Name, arity, loc);
if (ex_method_lookup != null) {
- ex_method_lookup.ExtensionExpression = InstanceExpression;
+ ex_method_lookup.ExtensionExpression = InstanceExpression.Resolve (ec);
ex_method_lookup.SetTypeArguments (ec, type_arguments);
- return ex_method_lookup.OverloadResolve (ec, ref Arguments, may_fail, loc);
+ var emg = ex_method_lookup.OverloadResolve (ec, ref Arguments, may_fail, loc);
+ if (emg != null)
+ return emg;
}
}
-
+
+ if (msg_recorder != null && !msg_recorder.IsEmpty) {
+ if (!may_fail)
+ msg_recorder.Merge (prev_recorder);
+
+ return null;
+ }
+
if (may_fail)
return null;
if (CustomErrorHandler != null && !has_inaccessible_candidates_only && CustomErrorHandler.NoExactMatch (ec, best_candidate))
return null;
- if (NoExactMatch (ec, ref Arguments, candidate_to_form))
+ bool params_expanded = params_candidates != null && params_candidates.Contains (best_candidate);
+ if (NoExactMatch (ec, ref Arguments, params_expanded))
return null;
}
//
// We failed to find any method with correct argument count
//
- if (Name == ConstructorInfo.ConstructorName) {
+ if (Methods.First ().Kind == MemberKind.Constructor) {
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);
+ TypeManager.CSharpName (queried_type), arg_count.ToString ());
} else {
Error_ArgumentCountWrong (ec, arg_count);
}
return this;
}
- if (!is_sorted) {
- //
- // At this point, applicable_type is _one_ of the most derived types
- // in the set of types containing the methods in this MethodGroup.
- // Filter the candidates so that they only contain methods from the
- // most derived types.
- //
-
- int finalized = 0; // Number of finalized candidates
-
- do {
- // Invariant: applicable_type is a most derived type
-
- // We'll try to complete Section 14.5.5.1 for 'applicable_type' by
- // eliminating all it's base types. At the same time, we'll also move
- // every unrelated type to the end of the array, and pick the next
- // 'applicable_type'.
-
- Type next_applicable_type = null;
- 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];
- Type decl_type = candidate.DeclaringType;
-
- if (decl_type == applicable_type) {
- candidates [k++] = candidates [j];
- candidates [j++] = candidates [i];
- continue;
- }
-
- if (IsAncestralType (decl_type, applicable_type))
- continue;
-
- if (next_applicable_type != null &&
- IsAncestralType (decl_type, next_applicable_type))
- continue;
-
- candidates [k++] = candidates [i];
-
- if (next_applicable_type == null ||
- IsAncestralType (next_applicable_type, decl_type))
- next_applicable_type = decl_type;
- }
-
- applicable_type = next_applicable_type;
- finalized = j;
- candidate_top = k;
- } while (applicable_type != null);
- }
-
//
// Now we actually find the best method
//
-
- best_candidate = (MethodBase) candidates [0];
- method_params = candidate_to_form != null && candidate_to_form.Contains (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];
- arg_count = candidate_args.Count;
- }
+ best_candidate = candidates [0];
+ bool method_params = params_candidates != null && params_candidates.Contains (best_candidate);
for (int ix = 1; ix < candidate_top; ix++) {
- MethodBase candidate = (MethodBase) candidates [ix];
+ var candidate = candidates [ix];
if (candidate == best_candidate)
continue;
- bool cand_params = candidate_to_form != null && candidate_to_form.Contains (candidate);
+ bool cand_params = params_candidates != null && params_candidates.Contains (candidate);
+
+ if (candidates_expanded != null && candidates_expanded.ContainsKey (candidate)) {
+ candidate_args = candidates_expanded[candidate];
+ arg_count = candidate_args.Count;
+ }
if (BetterFunction (ec, candidate_args, arg_count,
candidate, cand_params,
best_candidate = candidate;
method_params = cand_params;
}
+
+ if (candidate_args != Arguments) {
+ candidate_args = Arguments;
+ arg_count = candidate_args != null ? candidate_args.Count : 0;
+ }
+ }
+
+ if (candidates_expanded != null && candidates_expanded.ContainsKey (best_candidate)) {
+ candidate_args = candidates_expanded[best_candidate];
+ arg_count = candidate_args.Count;
}
+
//
// 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)
continue;
- bool cand_params = candidate_to_form != null && candidate_to_form.Contains (candidate);
+ bool cand_params = params_candidates != null && params_candidates.Contains (candidate);
if (!BetterFunction (ec, candidate_args, arg_count,
best_candidate, method_params,
candidate, cand_params))
return this;
}
- //
- // If the method is a virtual function, pick an override closer to the LHS type.
- //
- if (!IsBase && best_candidate.IsVirtual) {
- if (TypeManager.IsOverride (best_candidate))
- throw new InternalErrorException (
- "Should not happen. An 'override' method took part in overload resolution: " + best_candidate);
-
- if (candidate_overrides != null) {
- Type[] gen_args = null;
- bool gen_override = false;
- if (TypeManager.IsGenericMethod (best_candidate))
- gen_args = TypeManager.GetGenericArguments (best_candidate);
-
- foreach (MethodBase candidate in candidate_overrides) {
- if (TypeManager.IsGenericMethod (candidate)) {
- if (gen_args == null)
- continue;
-
- if (gen_args.Length != TypeManager.GetGenericArguments (candidate).Length)
- continue;
- } else {
- if (gen_args != null)
- continue;
- }
-
- if (IsOverride (candidate, best_candidate)) {
- gen_override = true;
- best_candidate = candidate;
- }
- }
-
- if (gen_override && gen_args != null) {
- best_candidate = ((MethodInfo) best_candidate).MakeGenericMethod (gen_args);
- }
- }
- }
+ best_candidate = CandidateToBaseOverride (ec, best_candidate);
//
// And now check if the arguments are all
if (best_candidate == null)
return null;
- MethodBase the_method = TypeManager.DropGenericMethodArguments (best_candidate);
- if (TypeManager.IsGenericMethodDefinition (the_method) &&
- !ConstraintChecker.CheckConstraints (ec, the_method, best_candidate, loc))
- return null;
+ if (best_candidate.Kind == MemberKind.Method) {
+ if (InstanceExpression != null) {
+ if (best_candidate.IsStatic && simple_name != null) {
+ InstanceExpression = ProbeIdenticalTypeName (ec, InstanceExpression, simple_name);
+ }
+
+ InstanceExpression.Resolve (ec);
+ }
+
+ ResolveInstanceExpression (ec);
+ }
+
+ if (best_candidate.IsGeneric) {
+ ConstraintChecker.CheckAll (best_candidate.GetGenericMethodDefinition (), best_candidate.TypeArguments,
+ best_candidate.Constraints, loc, ec.Report);
+ }
//
// Check ObsoleteAttribute on the best method
//
- ObsoleteAttribute oa = AttributeTester.GetMethodObsoleteAttribute (the_method);
+ ObsoleteAttribute oa = best_candidate.GetAttributeObsolete ();
if (oa != null && !ec.IsObsolete)
AttributeTester.Report_ObsoleteMessage (oa, GetSignatureForError (), loc, ec.Report);
- IMethodData data = TypeManager.GetMethod (the_method);
- if (data != null)
- data.SetMemberIsUsed ();
+ best_candidate.MemberDefinition.SetIsUsed ();
Arguments = candidate_args;
return this;
}
- bool NoExactMatch (ResolveContext ec, ref Arguments Arguments, Hashtable candidate_to_form)
+ bool NoExactMatch (ResolveContext ec, ref Arguments Arguments, bool params_expanded)
{
- AParametersCollection pd = TypeManager.GetParameterData (best_candidate);
+ 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)) {
+ if (best_candidate.IsGeneric) {
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));
+ "The type arguments for method `{0}' cannot be inferred from the usage. Try specifying the type arguments explicitly",
+ best_candidate.GetGenericMethodDefinition().GetSignatureForError ());
return true;
}
+ }
- Type[] g_args = TypeManager.GetGenericArguments (best_candidate);
- if (type_arguments.Count != g_args.Length) {
- ec.Report.SymbolRelatedToPreviousError (best_candidate);
- ec.Report.Error (305, loc, "Using the generic method `{0}' requires `{1}' type argument(s)",
- TypeManager.CSharpSignature (best_candidate),
- g_args.Length.ToString ());
- return true;
- }
- } else {
- if (type_arguments != null && !TypeManager.IsGenericMethod (best_candidate)) {
- Error_TypeArgumentsCannotBeUsed (ec.Report, loc);
- return true;
- }
+ var ta = type_arguments == null ? 0 : type_arguments.Count;
+ if (ta != best_candidate.Arity) {
+ Error_TypeArgumentsCannotBeUsed (ec.Report, loc, best_candidate, type_arguments.Count);
+ return true;
}
if (has_inaccessible_candidates_only) {
}
}
- bool cand_params = candidate_to_form != null && candidate_to_form.Contains (best_candidate);
- if (!VerifyArgumentsCompat (ec, ref Arguments, arg_count, best_candidate, cand_params, false, loc))
+ if (!VerifyArgumentsCompat (ec, ref Arguments, arg_count, best_candidate, params_expanded, false, loc))
return true;
if (has_inaccessible_candidates_only)
}
public bool VerifyArgumentsCompat (ResolveContext ec, ref Arguments arguments,
- int arg_count, MethodBase method,
+ 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 = ec.Report.Errors;
Parameter.Modifier p_mod = 0;
- Type pt = null;
+ TypeSpec pt = null;
int a_idx = 0, a_pos = 0;
Argument a = null;
- ArrayList params_initializers = null;
- bool has_unsafe_arg = method is MethodInfo ? ((MethodInfo) method).ReturnType.IsPointer : 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)) {
ec.Report.SymbolRelatedToPreviousError (DeclaringType);
- ec.Report.Error (1746, na.Name.Location,
+ 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 {
ec.Report.SymbolRelatedToPreviousError (best_candidate);
- ec.Report.Error (1739, na.Name.Location,
+ 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), na.Name);
}
} else if (arguments[name_index] != a) {
if (DeclaringType != null && TypeManager.IsDelegateType (DeclaringType))
else
ec.Report.SymbolRelatedToPreviousError (best_candidate);
- ec.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))
+ if (a.Expr.Type == InternalType.Dynamic)
continue;
if (delegate_type != null && !Delegate.IsTypeCovariant (a.Expr, pt))
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++;
}
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 {
+ public override TypeSpec DeclaringType {
get { return constant.DeclaringType; }
}
- public override MemberExpr ResolveMemberAccess (ResolveContext 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 (ResolveContext ec)
{
throw new NotSupportedException ("ET");
}
- public override Expression DoResolve (ResolveContext ec)
+ protected override Expression DoResolve (ResolveContext rc)
{
- IConstant ic = TypeManager.GetConstant (constant);
- if (ic.ResolveValue ()) {
- if (!ec.IsObsolete)
- ic.CheckObsoleteness (loc);
+ constant.MemberDefinition.SetIsUsed ();
+
+ ResolveInstanceExpression (rc);
+
+ if (!rc.IsObsolete) {
+ var oa = constant.GetAttributeObsolete ();
+ if (oa != null)
+ AttributeTester.Report_ObsoleteMessage (oa, constant.GetSignatureForError (), loc, rc.Report);
}
- return ic.CreateConstantReference (loc);
+ var c = constant.GetConstant (rc);
+
+ // Creates reference expression to the constant value
+ return Constant.CreateConstant (rc, constant.MemberType, c.GetValue (), loc);
}
public override void Emit (EmitContext ec)
public override string GetSignatureForError ()
{
- return TypeManager.GetFullNameSignature (constant);
+ return constant.GetSignatureForError ();
}
}
/// Fully resolved expression that evaluates to a Field
/// </summary>
public class FieldExpr : MemberExpr, IDynamicAssign, IMemoryLocation, IVariableReference {
- public FieldInfo FieldInfo;
- readonly Type constructed_generic_type;
+ protected FieldSpec spec;
VariableInfo variable_info;
LocalTemporary temp;
{
loc = l;
}
-
- public FieldExpr (FieldInfo fi, Location l)
+
+ public FieldExpr (FieldSpec spec, Location loc)
{
- FieldInfo = fi;
- type = TypeManager.TypeToCoreType (fi.FieldType);
- loc = l;
- }
+ this.spec = spec;
+ this.loc = loc;
- public FieldExpr (FieldInfo fi, Type genericType, Location l)
- : this (fi, l)
+ type = spec.MemberType;
+ }
+
+ public FieldExpr (FieldBase fi, Location l)
+ : this (fi.Spec, l)
{
- if (TypeManager.IsGenericTypeDefinition (genericType))
- return;
- this.constructed_generic_type = 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 {
+ public override TypeSpec DeclaringType {
get {
- return FieldInfo.DeclaringType;
+ return spec.DeclaringType;
}
}
public override string GetSignatureForError ()
{
- return TypeManager.GetFullNameSignature (FieldInfo);
+ return TypeManager.GetFullNameSignature (spec);
}
public VariableInfo VariableInfo {
}
}
- public override MemberExpr ResolveMemberAccess (ResolveContext ec, Expression left, Location loc,
- SimpleName original)
- {
- FieldInfo fi = TypeManager.GetGenericFieldDefinition (FieldInfo);
- Type t = fi.FieldType;
-
- if (t.IsPointer && !ec.IsUnsafe) {
- UnsafeError (ec, loc);
- }
-
- return base.ResolveMemberAccess (ec, left, loc, original);
- }
-
public void SetHasAddressTaken ()
{
IVariableReference vr = InstanceExpression as IVariableReference;
public Expression CreateTypeOfExpression ()
{
- return new TypeOfField (GetConstructedFieldInfo (), loc);
+ return new TypeOfField (spec, loc);
}
- override public Expression DoResolve (ResolveContext ec)
+ protected override Expression DoResolve (ResolveContext ec)
{
return DoResolve (ec, false, false);
}
Expression DoResolve (ResolveContext ec, bool lvalue_instance, bool out_access)
{
- if (!FieldInfo.IsStatic){
- if (InstanceExpression == null){
- //
- // This can happen when referencing an instance field using
- // a fully qualified type expression: TypeName.InstanceField = xxx
- //
- SimpleName.Error_ObjectRefRequired (ec, loc, GetSignatureForError ());
- return null;
- }
-
+ if (ResolveInstanceExpression (ec)) {
// Resolve the field's instance expression while flow analysis is turned
// off: when accessing a field "a.b", we must check whether the field
// "a.b" is initialized, not whether the whole struct "a" is initialized.
Expression right_side =
out_access ? EmptyExpression.LValueMemberOutAccess : EmptyExpression.LValueMemberAccess;
- if (InstanceExpression != EmptyExpression.Null)
- InstanceExpression = InstanceExpression.ResolveLValue (ec, right_side);
+ InstanceExpression = InstanceExpression.ResolveLValue (ec, right_side);
}
} else {
- ResolveFlags rf = ResolveFlags.VariableOrValue | ResolveFlags.DisableFlowAnalysis;
-
- if (InstanceExpression != EmptyExpression.Null)
- InstanceExpression = InstanceExpression.Resolve (ec, rf);
+ using (ec.With (ResolveContext.Options.DoFlowAnalysis, false)) {
+ InstanceExpression = InstanceExpression.Resolve (ec, ResolveFlags.VariableOrValue);
+ }
}
if (InstanceExpression == null)
}
}
- // TODO: the code above uses some non-standard multi-resolve rules
- if (eclass != ExprClass.Invalid)
- return this;
+ if (type.IsPointer && !ec.IsUnsafe) {
+ UnsafeError (ec, loc);
+ }
if (!ec.IsObsolete) {
- FieldBase f = TypeManager.GetField (FieldInfo);
- if (f != null) {
- f.CheckObsoleteness (loc);
- } else {
- ObsoleteAttribute oa = AttributeTester.GetMemberObsoleteAttribute (FieldInfo);
- if (oa != null)
- AttributeTester.Report_ObsoleteMessage (oa, TypeManager.GetFullNameSignature (FieldInfo), loc, ec.Report);
- }
+ ObsoleteAttribute oa = spec.GetAttributeObsolete ();
+ if (oa != null)
+ AttributeTester.Report_ObsoleteMessage (oa, TypeManager.GetFullNameSignature (spec), loc, ec.Report);
}
- IFixedBuffer fb = AttributeTester.GetFixedBuffer (FieldInfo);
+ var fb = spec as FixedFieldSpec;
IVariableReference var = InstanceExpression as IVariableReference;
+
+ if (lvalue_instance && var != null && var.VariableInfo != null) {
+ var.VariableInfo.SetFieldAssigned (ec, Name);
+ }
if (fb != null) {
IFixedExpression fe = InstanceExpression as IFixedExpression;
}
if (InstanceExpression.eclass != ExprClass.Variable) {
- ec.Report.SymbolRelatedToPreviousError (FieldInfo);
+ ec.Report.SymbolRelatedToPreviousError (spec);
ec.Report.Error (1708, loc, "`{0}': Fixed size buffers can only be accessed through locals or fields",
- TypeManager.GetFullNameSignature (FieldInfo));
+ TypeManager.GetFullNameSignature (spec));
} else if (var != null && var.IsHoisted) {
AnonymousMethodExpression.Error_AddressOfCapturedVar (ec, var, loc);
}
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;
}
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);
-
- bool lvalue_instance = !FieldInfo.IsStatic && TypeManager.IsValueType (FieldInfo.DeclaringType);
+ bool lvalue_instance = IsInstance && spec.DeclaringType.IsStruct;
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) {
- fb.SetAssigned ();
+ spec.MemberDefinition.SetIsAssigned ();
- 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 ((right_side == EmptyExpression.UnaryAddress || right_side == EmptyExpression.OutAccess.Instance) &&
+ (spec.Modifiers & Modifiers.VOLATILE) != 0) {
+ ec.Report.Warning (420, 1, loc,
+ "`{0}': A volatile field references will not be treated as volatile",
+ spec.GetSignatureForError ());
}
- if (FieldInfo.IsInitOnly) {
+ if (spec.IsReadOnly) {
// InitOnly fields can only be assigned in constructors or initializers
if (!ec.HasAny (ResolveContext.Options.FieldInitializerScope | ResolveContext.Options.ConstructorScope))
return Report_AssignToReadonly (ec, right_side);
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))
+ if (!TypeManager.IsEqual (ec.CurrentMemberDefinition.Parent.Definition, DeclaringType.GetDefinition ()))
return Report_AssignToReadonly (ec, right_side);
// static InitOnly fields cannot be assigned-to in an instance constructor
if (IsStatic && !ec.IsStatic)
public override int GetHashCode ()
{
- return FieldInfo.GetHashCode ();
+ return spec.GetHashCode ();
}
public bool IsFixed {
//
IVariableReference variable = InstanceExpression as IVariableReference;
if (variable != null)
- return TypeManager.IsStruct (InstanceExpression.Type) && variable.IsFixed;
+ return InstanceExpression.Type.IsStruct && variable.IsFixed;
IFixedExpression fe = InstanceExpression as IFixedExpression;
return fe != null && fe.IsFixed;
if (fe == null)
return false;
- if (FieldInfo != fe.FieldInfo)
+ if (spec != fe.spec)
return false;
if (InstanceExpression == null || fe.InstanceExpression == null)
public void Emit (EmitContext ec, bool leave_copy)
{
- ILGenerator ig = ec.ig;
bool is_volatile = false;
- FieldBase f = TypeManager.GetField (FieldInfo);
- if (f != null){
- if ((f.ModFlags & Modifiers.VOLATILE) != 0)
- is_volatile = true;
+ if ((spec.Modifiers & Modifiers.VOLATILE) != 0)
+ is_volatile = true;
- f.SetMemberIsUsed ();
- }
+ spec.MemberDefinition.SetIsUsed ();
- if (FieldInfo.IsStatic){
+ if (IsStatic){
if (is_volatile)
- ig.Emit (OpCodes.Volatile);
+ ec.Emit (OpCodes.Volatile);
- ig.Emit (OpCodes.Ldsfld, GetConstructedFieldInfo ());
+ ec.Emit (OpCodes.Ldsfld, spec);
} else {
if (!prepared)
EmitInstance (ec, false);
// Optimization for build-in types
- if (TypeManager.IsStruct (type) && TypeManager.IsEqual (type, ec.MemberContext.CurrentType)) {
- LoadFromPtr (ig, type);
+ if (TypeManager.IsStruct (type) && TypeManager.IsEqual (type, ec.MemberContext.CurrentType) && TypeManager.IsEqual (InstanceExpression.Type, type)) {
+ ec.EmitLoadFromPtr (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);
+ ec.Emit (OpCodes.Ldflda, spec);
+ ec.Emit (OpCodes.Ldflda, ff.Element);
} else {
if (is_volatile)
- ig.Emit (OpCodes.Volatile);
+ ec.Emit (OpCodes.Volatile);
- ig.Emit (OpCodes.Ldfld, GetConstructedFieldInfo ());
+ ec.Emit (OpCodes.Ldfld, spec);
}
}
}
if (leave_copy) {
- ec.ig.Emit (OpCodes.Dup);
- if (!FieldInfo.IsStatic) {
+ ec.Emit (OpCodes.Dup);
+ 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;
- ILGenerator ig = ec.ig;
-
prepared = prepare_for_load;
- EmitInstance (ec, prepared);
+ if (IsInstance)
+ EmitInstance (ec, prepared);
source.Emit (ec);
if (leave_copy) {
- ec.ig.Emit (OpCodes.Dup);
- if (!FieldInfo.IsStatic) {
+ ec.Emit (OpCodes.Dup);
+ if (!IsStatic) {
temp = new LocalTemporary (this.Type);
temp.Store (ec);
}
}
- FieldBase f = TypeManager.GetField (FieldInfo);
- if (f != null){
- if ((f.ModFlags & Modifiers.VOLATILE) != 0)
- ig.Emit (OpCodes.Volatile);
+ if ((spec.Modifiers & Modifiers.VOLATILE) != 0)
+ ec.Emit (OpCodes.Volatile);
- f.SetAssigned ();
- }
+ spec.MemberDefinition.SetIsAssigned ();
- if (is_static)
- ig.Emit (OpCodes.Stsfld, GetConstructedFieldInfo ());
+ if (IsStatic)
+ ec.Emit (OpCodes.Stsfld, spec);
else
- ig.Emit (OpCodes.Stfld, GetConstructedFieldInfo ());
+ ec.Emit (OpCodes.Stfld, spec);
if (temp != null) {
temp.Emit (ec);
public override void EmitSideEffect (EmitContext ec)
{
- FieldBase f = TypeManager.GetField (FieldInfo);
- bool is_volatile = f != null && (f.ModFlags & Modifiers.VOLATILE) != 0;
+ bool is_volatile = (spec.Modifiers & Modifiers.VOLATILE) != 0;
if (is_volatile || is_marshal_by_ref ())
base.EmitSideEffect (ec);
public void AddressOf (EmitContext ec, AddressOp mode)
{
- ILGenerator ig = ec.ig;
-
- FieldBase f = TypeManager.GetField (FieldInfo);
- if (f != null){
- if ((mode & AddressOp.Store) != 0)
- f.SetAssigned ();
- if ((mode & AddressOp.Load) != 0)
- f.SetMemberIsUsed ();
- }
+ if ((mode & AddressOp.Store) != 0)
+ spec.MemberDefinition.SetIsAssigned ();
+ if ((mode & AddressOp.Load) != 0)
+ spec.MemberDefinition.SetIsUsed ();
//
// Handle initonly fields specially: make a copy and then
// get the address of the copy.
//
bool need_copy;
- if (FieldInfo.IsInitOnly){
+ if (spec.IsReadOnly){
need_copy = true;
if (ec.HasSet (EmitContext.Options.ConstructorScope)){
- if (FieldInfo.IsStatic){
+ if (IsStatic){
if (ec.IsStatic)
need_copy = false;
} else
if (need_copy){
LocalBuilder local;
Emit (ec);
- local = ig.DeclareLocal (type);
- ig.Emit (OpCodes.Stloc, local);
- ig.Emit (OpCodes.Ldloca, local);
+ local = ec.DeclareLocal (type, false);
+ ec.Emit (OpCodes.Stloc, local);
+ ec.Emit (OpCodes.Ldloca, local);
return;
}
- if (FieldInfo.IsStatic){
- ig.Emit (OpCodes.Ldsflda, GetConstructedFieldInfo ());
+ if (IsStatic){
+ ec.Emit (OpCodes.Ldsflda, spec);
} else {
if (!prepared)
EmitInstance (ec, false);
- ig.Emit (OpCodes.Ldflda, GetConstructedFieldInfo ());
+ ec.Emit (OpCodes.Ldflda, spec);
}
}
- FieldInfo GetConstructedFieldInfo ()
- {
- if (constructed_generic_type == null)
- return FieldInfo;
-
- return TypeBuilder.GetField (constructed_generic_type, FieldInfo);
- }
-
-#if NET_4_0
public SLE.Expression MakeAssignExpression (BuilderContext ctx)
{
return MakeExpression (ctx);
public override SLE.Expression MakeExpression (BuilderContext ctx)
{
- return SLE.Expression.Field (InstanceExpression.MakeExpression (ctx), FieldInfo);
+ return SLE.Expression.Field (InstanceExpression.MakeExpression (ctx), spec.GetMetaInfo ());
}
-#endif
-
- public override void MutateHoistedGenericType (AnonymousMethodStorey storey)
- {
- FieldInfo = storey.MutateField (FieldInfo);
- base.MutateHoistedGenericType (storey);
- }
}
/// </summary>
public class PropertyExpr : MemberExpr, IDynamicAssign
{
- public readonly PropertyInfo PropertyInfo;
- MethodInfo getter, setter;
- bool is_static;
+ PropertySpec spec;
+
+ // getter and setter can be different for base calls
+ MethodSpec getter, setter;
- bool resolved;
TypeArguments targs;
-
LocalTemporary temp;
bool prepared;
- public PropertyExpr (Type container_type, PropertyInfo pi, Location l)
+ public PropertyExpr (PropertySpec spec, Location l)
{
- PropertyInfo = pi;
- eclass = ExprClass.PropertyAccess;
- is_static = false;
+ this.spec = spec;
loc = l;
- type = TypeManager.TypeToCoreType (pi.PropertyType);
-
- ResolveAccessors (container_type);
+ type = spec.MemberType;
}
+ #region Properties
+
public override string Name {
get {
- return PropertyInfo.Name;
+ return spec.Name;
}
}
public override bool IsInstance {
get {
- return !is_static;
+ return !IsStatic;
}
}
public override bool IsStatic {
get {
- return is_static;
+ return spec.IsStatic;
+ }
+ }
+
+ public PropertySpec PropertyInfo {
+ get {
+ return spec;
}
}
+ #endregion
+
public override Expression CreateExpressionTree (ResolveContext ec)
{
Arguments args;
return CreateExpressionFactoryCall (ec, "ArrayLength", args);
}
- if (is_base) {
- Error_BaseAccessInExpressionTree (ec, loc);
- return null;
- }
-
args = new Arguments (2);
if (InstanceExpression == null)
args.Add (new Argument (new NullLiteral (loc)));
return new TypeOfMethod (setter, loc);
}
- public override Type DeclaringType {
+ public override TypeSpec DeclaringType {
get {
- return PropertyInfo.DeclaringType;
+ return spec.DeclaringType;
}
}
public override string GetSignatureForError ()
{
- return TypeManager.GetFullNameSignature (PropertyInfo);
- }
-
- void FindAccessors (Type invocation_type)
- {
- const BindingFlags flags = BindingFlags.Public | BindingFlags.NonPublic |
- BindingFlags.Static | BindingFlags.Instance |
- BindingFlags.DeclaredOnly;
-
- Type current = PropertyInfo.DeclaringType;
- for (; current != null; current = current.BaseType) {
- MemberInfo[] group = TypeManager.MemberLookup (
- invocation_type, invocation_type, current,
- MemberTypes.Property, flags, PropertyInfo.Name, null);
-
- if (group == null)
- continue;
-
- if (group.Length != 1)
- // Oooops, can this ever happen ?
- return;
-
- PropertyInfo pi = (PropertyInfo) group [0];
-
- if (getter == null)
- getter = pi.GetGetMethod (true);
-
- if (setter == null)
- setter = pi.GetSetMethod (true);
-
- MethodInfo accessor = getter != null ? getter : setter;
-
- if (!accessor.IsVirtual)
- return;
- }
- }
-
- //
- // We also perform the permission checking here, as the PropertyInfo does not
- // hold the information for the accessibility of its setter/getter
- //
- // TODO: Refactor to use some kind of cache together with GetPropertyFromAccessor
- void ResolveAccessors (Type container_type)
- {
- FindAccessors (container_type);
-
- if (getter != null) {
- MethodBase the_getter = TypeManager.DropGenericMethodArguments (getter);
- IMethodData md = TypeManager.GetMethod (the_getter);
- if (md != null)
- md.SetMemberIsUsed ();
-
- is_static = getter.IsStatic;
- }
-
- if (setter != null) {
- MethodBase the_setter = TypeManager.DropGenericMethodArguments (setter);
- IMethodData md = TypeManager.GetMethod (the_setter);
- if (md != null)
- md.SetMemberIsUsed ();
-
- is_static = setter.IsStatic;
- }
+ return TypeManager.GetFullNameSignature (spec);
}
-#if NET_4_0
public SLE.Expression MakeAssignExpression (BuilderContext ctx)
{
- return SLE.Expression.Property (InstanceExpression.MakeExpression (ctx), setter);
+ return SLE.Expression.Property (InstanceExpression.MakeExpression (ctx), (MethodInfo) setter.GetMetaInfo ());
}
public override SLE.Expression MakeExpression (BuilderContext ctx)
{
- return SLE.Expression.Property (InstanceExpression.MakeExpression (ctx), getter);
- }
-#endif
-
- public override void MutateHoistedGenericType (AnonymousMethodStorey storey)
- {
- if (InstanceExpression != null)
- InstanceExpression.MutateHoistedGenericType (storey);
-
- type = storey.MutateType (type);
- if (getter != null)
- getter = storey.MutateGenericMethod (getter);
- if (setter != null)
- setter = storey.MutateGenericMethod (setter);
+ return SLE.Expression.Property (InstanceExpression.MakeExpression (ctx), (MethodInfo) getter.GetMetaInfo ());
}
bool InstanceResolve (ResolveContext ec, bool lvalue_instance, bool must_do_cs1540_check)
{
- if (is_static) {
- InstanceExpression = null;
+ if (!ResolveInstanceExpression (ec))
return true;
- }
-
- if (InstanceExpression == null) {
- SimpleName.Error_ObjectRefRequired (ec, loc, GetSignatureForError ());
- 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) &&
+ !(InstanceExpression is BaseThis) &&
!TypeManager.IsInstantiationOfSameGenericType (InstanceExpression.Type, ec.CurrentType) &&
!TypeManager.IsNestedChildOf (ec.CurrentType, InstanceExpression.Type) &&
!TypeManager.IsSubclassOf (InstanceExpression.Type, ec.CurrentType)) {
- ec.Report.SymbolRelatedToPreviousError (PropertyInfo);
- Error_CannotAccessProtected (ec, loc, PropertyInfo, InstanceExpression.Type, ec.CurrentType);
+ ec.Report.SymbolRelatedToPreviousError (spec);
+ Error_CannotAccessProtected (ec, loc, spec, InstanceExpression.Type, ec.CurrentType);
return false;
}
return true;
}
- void Error_PropertyNotFound (ResolveContext ec, MethodInfo mi, bool getter)
+ void Error_PropertyNotValid (ResolveContext ec)
{
- // TODO: correctly we should compare arguments but it will lead to bigger changes
- if (mi is MethodBuilder) {
- Error_TypeDoesNotContainDefinition (ec, loc, PropertyInfo.DeclaringType, Name);
- return;
- }
-
- StringBuilder sig = new StringBuilder (TypeManager.CSharpName (mi.DeclaringType));
- sig.Append ('.');
- AParametersCollection iparams = TypeManager.GetParameterData (mi);
- sig.Append (getter ? "get_" : "set_");
- sig.Append (Name);
- sig.Append (iparams.GetSignatureForError ());
-
- ec.Report.SymbolRelatedToPreviousError (mi);
- 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 ());
+ ec.Report.SymbolRelatedToPreviousError (spec);
+ ec.Report.Error (1546, loc, "Property or event `{0}' is not supported by the C# language",
+ GetSignatureForError ());
}
- public bool IsAccessibleFrom (Type invocation_type, bool lvalue)
+ public bool IsAccessibleFrom (TypeSpec invocation_type, bool lvalue)
{
bool dummy;
- MethodInfo accessor = lvalue ? setter : getter;
+ var accessor = lvalue ? spec.Set : spec.Get;
if (accessor == null && lvalue)
- accessor = getter;
- return accessor != null && IsAccessorAccessible (invocation_type, accessor, out dummy);
+ accessor = spec.Get;
+ return accessor != null && IsMemberAccessible (invocation_type, accessor, out dummy);
}
bool IsSingleDimensionalArrayLength ()
{
- if (DeclaringType != TypeManager.array_type || getter == null || Name != "Length")
+ if (DeclaringType != TypeManager.array_type || !spec.HasGet || Name != "Length")
return false;
- string t_name = InstanceExpression.Type.Name;
- int t_name_len = t_name.Length;
- return t_name_len > 2 && t_name [t_name_len - 2] == '[';
+ ArrayContainer ac = InstanceExpression.Type as ArrayContainer;
+ return ac != null && ac.Rank == 1;
}
- public override Expression DoResolve (ResolveContext ec)
+ protected override Expression DoResolve (ResolveContext ec)
{
- if (resolved)
- return this;
+ eclass = ExprClass.PropertyAccess;
bool must_do_cs1540_check = false;
ec.Report.DisableReporting ();
if (!res) {
if (InstanceExpression != null) {
- Type expr_type = InstanceExpression.Type;
- ExtensionMethodGroupExpr ex_method_lookup = ec.LookupExtensionMethod (expr_type, Name, loc);
+ TypeSpec expr_type = InstanceExpression.Type;
+ ExtensionMethodGroupExpr ex_method_lookup = ec.LookupExtensionMethod (expr_type, Name, 0, loc);
if (ex_method_lookup != null) {
ex_method_lookup.ExtensionExpression = InstanceExpression;
ex_method_lookup.SetTypeArguments (ec, targs);
- return ex_method_lookup.DoResolve (ec);
+ return ex_method_lookup.Resolve (ec);
}
}
if (!InstanceResolve (ec, false, must_do_cs1540_check))
return null;
+ if (type.IsPointer && !ec.IsUnsafe) {
+ UnsafeError (ec, loc);
+ }
+
+ getter = CandidateToBaseOverride (ec, spec.Get);
+
//
// Only base will allow this invocation to happen.
//
if (IsBase && getter.IsAbstract) {
- Error_CannotCallAbstractBase (ec, TypeManager.GetFullNameSignature (PropertyInfo));
- }
-
- if (PropertyInfo.PropertyType.IsPointer && !ec.IsUnsafe){
- UnsafeError (ec, loc);
+ Error_CannotCallAbstractBase (ec, spec.GetSignatureForError ());
}
if (!ec.IsObsolete) {
- PropertyBase pb = TypeManager.GetProperty (PropertyInfo);
- if (pb != null) {
- pb.CheckObsoleteness (loc);
- } else {
- ObsoleteAttribute oa = AttributeTester.GetMemberObsoleteAttribute (PropertyInfo);
- if (oa != null)
- AttributeTester.Report_ObsoleteMessage (oa, GetSignatureForError (), loc, ec.Report);
- }
+ ObsoleteAttribute oa = spec.GetAttributeObsolete ();
+ if (oa != null)
+ AttributeTester.Report_ObsoleteMessage (oa, GetSignatureForError (), loc, ec.Report);
}
- resolved = true;
-
return this;
}
override public Expression DoResolveLValue (ResolveContext ec, Expression right_side)
{
+ eclass = ExprClass.PropertyAccess;
+
if (right_side == EmptyExpression.OutAccess.Instance) {
- if (ec.CurrentBlock.Toplevel.GetParameterReference (PropertyInfo.Name, loc) is MemberAccess) {
+ 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",
- PropertyInfo.Name);
+ spec.Name);
} else {
right_side.DoResolveLValue (ec, this);
}
Error_CannotModifyIntermediateExpressionValue (ec);
}
- if (setter == 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 (getter == null)
- return null;
+ if (spec.IsNotRealProperty) {
+ Error_PropertyNotValid (ec);
+ return null;
+ }
- if (ec.CurrentBlock.Toplevel.GetParameterReference (PropertyInfo.Name, loc) is MemberAccess) {
+ if (!spec.HasSet){
+ 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",
- PropertyInfo.Name);
+ spec.Name);
} else {
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 (ec, setter, false);
- return null;
- }
-
bool must_do_cs1540_check;
- if (!IsAccessorAccessible (ec.CurrentType, setter, out must_do_cs1540_check)) {
- PropertyBase.PropertyMethod pm = TypeManager.GetMethod (setter) as PropertyBase.PropertyMethod;
- if (pm != null && pm.HasCustomAccessModifier) {
- ec.Report.SymbolRelatedToPreviousError (pm);
+ if (!IsMemberAccessible (ec.CurrentType, spec.Set, out must_do_cs1540_check)) {
+ if (spec.HasDifferentAccessibility) {
+ ec.Report.SymbolRelatedToPreviousError (spec.Set);
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 {
- ec.Report.SymbolRelatedToPreviousError (setter);
- ErrorIsInaccesible (loc, TypeManager.CSharpSignature (setter), ec.Report);
+ TypeManager.CSharpSignature (spec));
+ } else {
+ ec.Report.SymbolRelatedToPreviousError (spec.Set);
+ ErrorIsInaccesible (loc, TypeManager.CSharpSignature (spec.Set), 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;
+
+ setter = CandidateToBaseOverride (ec, spec.Set);
//
// Only base will allow this invocation to happen.
//
if (IsBase && setter.IsAbstract){
- Error_CannotCallAbstractBase (ec, TypeManager.GetFullNameSignature (PropertyInfo));
+ Error_CannotCallAbstractBase (ec, setter.GetSignatureForError ());
}
- if (PropertyInfo.PropertyType.IsPointer && !ec.IsUnsafe) {
+ if (spec.MemberType.IsPointer && !ec.IsUnsafe) {
UnsafeError (ec, loc);
}
if (!ec.IsObsolete) {
- PropertyBase pb = TypeManager.GetProperty (PropertyInfo);
- if (pb != null) {
- pb.CheckObsoleteness (loc);
- } else {
- ObsoleteAttribute oa = AttributeTester.GetMemberObsoleteAttribute (PropertyInfo);
- if (oa != null)
- AttributeTester.Report_ObsoleteMessage (oa, GetSignatureForError (), loc, ec.Report);
- }
+ ObsoleteAttribute oa = spec.GetAttributeObsolete ();
+ if (oa != null)
+ AttributeTester.Report_ObsoleteMessage (oa, GetSignatureForError (), loc, ec.Report);
}
return this;
if (IsSingleDimensionalArrayLength ()) {
if (!prepared)
EmitInstance (ec, false);
- ec.ig.Emit (OpCodes.Ldlen);
- ec.ig.Emit (OpCodes.Conv_I4);
+ ec.Emit (OpCodes.Ldlen);
+ ec.Emit (OpCodes.Conv_I4);
return;
}
- Invocation.EmitCall (ec, IsBase, InstanceExpression, getter, null, loc, prepared, false);
+ Invocation.EmitCall (ec, InstanceExpression, getter, null, loc, prepared, false);
if (leave_copy) {
- ec.ig.Emit (OpCodes.Dup);
- if (!is_static) {
+ ec.Emit (OpCodes.Dup);
+ if (!IsStatic) {
temp = new LocalTemporary (this.Type);
temp.Store (ec);
}
source.Emit (ec);
if (leave_copy) {
- ec.ig.Emit (OpCodes.Dup);
- if (!is_static) {
+ ec.Emit (OpCodes.Dup);
+ if (!IsStatic) {
temp = new LocalTemporary (this.Type);
temp.Store (ec);
}
Arguments args = new Arguments (1);
args.Add (new Argument (my_source));
- Invocation.EmitCall (ec, IsBase, InstanceExpression, setter, args, loc, false, prepared);
+ Invocation.EmitCall (ec, InstanceExpression, setter, args, loc, false, prepared);
if (temp != null) {
temp.Emit (ec);
return false;
}
- if (getter != null) {
- if (TypeManager.GetParameterData (getter).Count != 0) {
- Error_PropertyNotFound (ec, getter, true);
- return false;
- }
+ if (spec.IsNotRealProperty) {
+ Error_PropertyNotValid (ec);
+ 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 (!spec.HasGet) {
if (InstanceExpression != EmptyExpression.Null) {
+ ec.Report.SymbolRelatedToPreviousError (spec);
ec.Report.Error (154, loc, "The property or indexer `{0}' cannot be used in this context because it lacks the `get' accessor",
- TypeManager.GetFullNameSignature (PropertyInfo));
+ spec.GetSignatureForError ());
return false;
}
}
- if (getter != null &&
- !IsAccessorAccessible (ec.CurrentType, getter, out must_do_cs1540_check)) {
- PropertyBase.PropertyMethod pm = TypeManager.GetMethod (getter) as PropertyBase.PropertyMethod;
- if (pm != null && pm.HasCustomAccessModifier) {
- ec.Report.SymbolRelatedToPreviousError (pm);
+ if (spec.HasGet && !IsMemberAccessible (ec.CurrentType, spec.Get, out must_do_cs1540_check)) {
+ if (spec.HasDifferentAccessibility) {
+ ec.Report.SymbolRelatedToPreviousError (spec.Get);
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));
+ TypeManager.CSharpSignature (spec));
} else {
- ec.Report.SymbolRelatedToPreviousError (getter);
- ErrorIsInaccesible (loc, TypeManager.CSharpSignature (getter), ec.Report);
+ ec.Report.SymbolRelatedToPreviousError (spec.Get);
+ ErrorIsInaccesible (loc, TypeManager.CSharpSignature (spec.Get), ec.Report);
}
return false;
/// <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 {
+ public override TypeSpec DeclaringType {
get {
- return EventInfo.DeclaringType;
+ return spec.DeclaringType;
}
}
GetSignatureForError ());
}
- public override MemberExpr ResolveMemberAccess (ResolveContext ec, Expression left, Location loc,
- SimpleName original)
+ public override MemberExpr ResolveMemberAccess (ResolveContext ec, Expression left, SimpleName original)
{
//
// If the event is local to this class, we transform ourselves into a FieldExpr
//
- if (EventInfo.DeclaringType == ec.CurrentType ||
- TypeManager.IsNestedChildOf(ec.CurrentType, EventInfo.DeclaringType)) {
+ 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 (EventInfo);
+ // EventField mi = spec.MemberDefinition as EventField;
+
+ if (spec.BackingField != null) {
+ spec.MemberDefinition.SetIsUsed ();
- if (mi != null) {
- if (!ec.IsObsolete)
- mi.CheckObsoleteness (loc);
+ if (!ec.IsObsolete) {
+ ObsoleteAttribute oa = spec.GetAttributeObsolete ();
+ if (oa != null)
+ AttributeTester.Report_ObsoleteMessage (oa, spec.GetSignatureForError (), loc, ec.Report);
+ }
- if ((mi.ModFlags & (Modifiers.ABSTRACT | Modifiers.EXTERN)) != 0 && !ec.HasSet (ResolveContext.Options.CompoundAssignmentScope))
+ if ((spec.Modifiers & (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 (spec.BackingField, loc);
InstanceExpression = null;
- return ml.ResolveMemberAccess (ec, left, loc, original);
+ return ml.ResolveMemberAccess (ec, left, original);
}
}
- if (left is This && !ec.HasSet (ResolveContext.Options.CompoundAssignmentScope))
+ if (!ec.HasSet (ResolveContext.Options.CompoundAssignmentScope))
Error_AssignmentEventOnly (ec);
- return base.ResolveMemberAccess (ec, left, loc, original);
+ return base.ResolveMemberAccess (ec, left, original);
}
bool InstanceResolve (ResolveContext ec, bool must_do_cs1540_check)
{
- if (is_static) {
- InstanceExpression = null;
- return true;
- }
-
- if (InstanceExpression == null) {
- SimpleName.Error_ObjectRefRequired (ec, loc, GetSignatureForError ());
- return false;
+ if (IsBase && spec.IsAbstract) {
+ Error_CannotCallAbstractBase (ec, spec.GetSignatureForError ());
}
- InstanceExpression = InstanceExpression.DoResolve (ec);
- if (InstanceExpression == null)
- return false;
+ if (!ResolveInstanceExpression (ec))
+ return true;
- if (IsBase && add_accessor.IsAbstract) {
- Error_CannotCallAbstractBase (ec, TypeManager.CSharpSignature(add_accessor));
- return false;
- }
+ InstanceExpression.Resolve (ec);
//
// This is using the same mechanism as the CS1540 check in PropertyExpr.
!TypeManager.IsInstantiationOfSameGenericType (InstanceExpression.Type, ec.CurrentType) &&
!TypeManager.IsNestedChildOf (ec.CurrentType, InstanceExpression.Type) &&
!TypeManager.IsSubclassOf (InstanceExpression.Type, ec.CurrentType)) {
- ec.Report.SymbolRelatedToPreviousError (EventInfo);
- ErrorIsInaccesible (loc, TypeManager.CSharpSignature (EventInfo), ec.Report);
+ ec.Report.SymbolRelatedToPreviousError (spec);
+ ErrorIsInaccesible (loc, TypeManager.CSharpSignature (spec), ec.Report);
return false;
}
return true;
}
- public bool IsAccessibleFrom (Type invocation_type)
+ public bool IsAccessibleFrom (TypeSpec invocation_type)
{
bool dummy;
- return IsAccessorAccessible (invocation_type, add_accessor, out dummy) &&
- IsAccessorAccessible (invocation_type, remove_accessor, out dummy);
+ return IsMemberAccessible (invocation_type, spec.AccessorAdd, out dummy) &&
+ IsMemberAccessible (invocation_type, spec.AccessorRemove, out dummy);
}
public override Expression CreateExpressionTree (ResolveContext ec)
return null;
}
- public override Expression DoResolve (ResolveContext ec)
+ protected override Expression DoResolve (ResolveContext ec)
{
+ eclass = ExprClass.EventAccess;
+
bool must_do_cs1540_check;
- if (!(IsAccessorAccessible (ec.CurrentType, add_accessor, out must_do_cs1540_check) &&
- IsAccessorAccessible (ec.CurrentType, remove_accessor, out must_do_cs1540_check))) {
- ec.Report.SymbolRelatedToPreviousError (EventInfo);
- ErrorIsInaccesible (loc, TypeManager.CSharpSignature (EventInfo), ec.Report);
+ if (!(IsMemberAccessible (ec.CurrentType, spec.AccessorAdd, out must_do_cs1540_check) &&
+ IsMemberAccessible (ec.CurrentType, spec.AccessorRemove, out must_do_cs1540_check))) {
+ ec.Report.SymbolRelatedToPreviousError (spec);
+ ErrorIsInaccesible (loc, TypeManager.CSharpSignature (spec), ec.Report);
return null;
}
+ type = spec.MemberType;
+
if (!InstanceResolve (ec, must_do_cs1540_check))
return null;
}
if (!ec.IsObsolete) {
- 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, ec.Report);
- }
+ var oa = spec.GetAttributeObsolete ();
+ if (oa != null)
+ AttributeTester.Report_ObsoleteMessage (oa, GetSignatureForError (), loc, ec.Report);
}
+
+ spec.MemberDefinition.SetIsUsed ();
return this;
}
{
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);
}
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, InstanceExpression, is_add ? spec.AccessorAdd : spec.AccessorRemove, args, loc);
}
}
{
LocalInfo li;
- public TemporaryVariable (Type type, Location loc)
+ public TemporaryVariable (TypeSpec type, Location loc)
{
this.type = type;
this.loc = loc;
- eclass = ExprClass.Variable;
}
public override Expression CreateExpressionTree (ResolveContext ec)
throw new NotSupportedException ("ET");
}
- public override Expression DoResolve (ResolveContext 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);
public override Expression DoResolveLValue (ResolveContext ec, Expression right_side)
{
- return DoResolve (ec);
+ return Resolve (ec);
}
public override void Emit (EmitContext ec)
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;
}
}
if (RootContext.Version < LanguageVersion.V_3)
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;
- rc.Compiler.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) {
+ 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;
}