{
}
- protected CompilerGeneratedClass (DeclSpace parent, GenericMethod generic, MemberName name, Modifiers mod)
- : this (parent, name, mod)
- {
- if (generic != null) {
- var list = new List<Constraints> ();
- foreach (TypeParameter tparam in generic.TypeParameters) {
- if (tparam.Constraints != null)
- list.Add (tparam.Constraints.Clone ());
- }
- SetParameterInfo (list);
- }
- }
-
protected void CheckMembersDefined ()
{
- if (members_defined)
+ if (HasMembersDefined)
throw new InternalErrorException ("Helper class already defined!");
}
}
return false;
AnonymousMethodStorey parent = ((AnonymousMethodStorey) Parent).GetGenericStorey ();
- if (parent != null)
- member_type = parent.MutateType (MemberType);
+ if (parent != null && parent.Mutator != null)
+ member_type = parent.Mutator.Mutate (MemberType);
return true;
}
{
// Nothing to clone
}
-
- public override void MutateHoistedGenericType (AnonymousMethodStorey storey)
- {
- // Nothing to mutate
- }
}
// Unique storey ID
// Local variable which holds this storey instance
public LocalTemporary Instance;
+ TypeParameterMutator mutator;
+
public AnonymousMethodStorey (Block block, TypeContainer parent, MemberBase host, GenericMethod generic, string name)
- : base (parent, generic, MakeMemberName (host, name, generic, block.StartLocation), Modifiers.PRIVATE | Modifiers.SEALED)
+ : base (parent, MakeMemberName (host, name, generic, block.StartLocation), Modifiers.PRIVATE | Modifiers.SEALED)
{
Parent = parent;
OriginalSourceBlock = block;
ID = unique_id++;
+
+ if (generic != null) {
+ var hoisted_tparams = generic.CurrentTypeParameters;
+ type_params = new TypeParameter [hoisted_tparams.Length];
+ for (int i = 0; i < type_params.Length; ++i) {
+ type_params[i] = hoisted_tparams[i].CreateHoistedCopy (spec);
+ }
+ }
}
static MemberName MakeMemberName (MemberBase host, string name, GenericMethod generic, Location loc)
Field f = AddCompilerGeneratedField ("<>f__this", type_expr);
f.Define ();
hoisted_this = new HoistedThis (this, f);
+
+ // Inflated type instance has to be updated manually
+ if (Instance.Type != f.Parent.CurrentType) {
+ var inflator = new TypeParameterInflator (Instance.Type, TypeParameterSpec.EmptyTypes, TypeSpec.EmptyTypes);
+ Instance.Type.MemberCache.AddMember (f.Spec.InflateMember (inflator));
+
+ inflator = new TypeParameterInflator (f.Parent.CurrentType, TypeParameterSpec.EmptyTypes, TypeSpec.EmptyTypes);
+ f.Parent.CurrentType.MemberCache.AddMember (f.Spec.InflateMember (inflator));
+ }
}
- public Field AddCapturedVariable (string name, Type type)
+ public Field AddCapturedVariable (string name, TypeSpec type)
{
CheckMembersDefined ();
children_references.Add (block);
}
- public void AddParentStoreyReference (AnonymousMethodStorey storey)
+ public void AddParentStoreyReference (EmitContext ec, AnonymousMethodStorey storey)
{
CheckMembersDefined ();
else if (used_parent_storeys.Exists (i => i.Storey == storey))
return;
- TypeExpr type_expr = new TypeExpression (storey.TypeBuilder, Location);
+ TypeExpr type_expr = storey.CreateStoreyTypeExpression (ec);
Field f = AddCompilerGeneratedField ("<>f__ref$" + storey.ID, type_expr);
used_parent_storeys.Add (new StoreyFieldPair (storey, f));
}
hoisted_params.Add (expr);
}
- public void ChangeParentStorey (AnonymousMethodStorey parentStorey)
+ TypeExpr CreateStoreyTypeExpression (EmitContext ec)
{
- Parent = parentStorey;
- type_params = null;
- }
-
- //
- // Initializes all hoisted variables
- //
- public void EmitStoreyInstantiation (EmitContext ec)
- {
- // There can be only one instance variable for each storey type
- if (Instance != null)
- throw new InternalErrorException ();
-
- SymbolWriter.OpenCompilerGeneratedBlock (ec.ig);
-
//
// Create an instance of storey type
//
- Expression storey_type_expr;
- if (is_generic) {
+ TypeExpr storey_type_expr;
+ if (CurrentTypeParameters != null) {
//
// Use current method type parameter (MVAR) for top level storey only. All
// nested storeys use class type parameter (VAR)
TypeArguments targs = new TypeArguments ();
- if (tparams.Length < CountTypeParameters) {
- TypeParameter[] parent_tparams = ec.MemberContext.CurrentTypeDefinition.TypeParameters;
- for (int i = 0; i < parent_tparams.Length; ++i)
- targs.Add (new TypeParameterExpr (parent_tparams[i], Location));
- }
-
+ //
+ // Use type parameter name instead of resolved type parameter
+ // specification to resolve to correctly nested type parameters
+ //
for (int i = 0; i < tparams.Length; ++i)
- targs.Add (new TypeParameterExpr (tparams[i], Location));
+ targs.Add (new SimpleName (tparams [i].Name, Location)); // new TypeParameterExpr (tparams[i], Location));
- storey_type_expr = new GenericTypeExpr (TypeBuilder, targs, Location);
+ storey_type_expr = new GenericTypeExpr (Definition, targs, Location);
} else {
- storey_type_expr = new TypeExpression (TypeBuilder, Location);
+ storey_type_expr = new TypeExpression (CurrentType, Location);
+ }
+
+ return storey_type_expr;
+ }
+
+ public void SetNestedStoryParent (AnonymousMethodStorey parentStorey)
+ {
+ Parent = parentStorey;
+ type_params = null;
+ spec.IsGeneric = false;
+ spec.DeclaringType = parentStorey.CurrentType;
+// MemberName.TypeArguments = null;
+ }
+
+ protected override bool DoResolveTypeParameters ()
+ {
+ // Although any storey can have type parameters they are all clones of method type
+ // parameters therefore have to mutate MVAR references in any of cloned constraints
+ if (type_params != null) {
+ for (int i = 0; i < type_params.Length; ++i) {
+ var spec = type_params[i].Type;
+ spec.BaseType = mutator.Mutate (spec.BaseType);
+ if (spec.Interfaces != null) {
+ var mutated = new TypeSpec[spec.Interfaces.Count];
+ for (int ii = 0; ii < mutated.Length; ++ii) {
+ mutated [ii] = mutator.Mutate (spec.Interfaces[ii]);
+ }
+
+ spec.Interfaces = mutated;
+ }
+
+ if (spec.TypeArguments != null) {
+ spec.TypeArguments = mutator.Mutate (spec.TypeArguments);
+ }
+ }
}
- ResolveContext rc = new ResolveContext (this);
+ return true;
+ }
+
+ //
+ // Initializes all hoisted variables
+ //
+ public void EmitStoreyInstantiation (EmitContext ec)
+ {
+ // There can be only one instance variable for each storey type
+ if (Instance != null)
+ throw new InternalErrorException ();
+
+ SymbolWriter.OpenCompilerGeneratedBlock (ec);
+
+ //
+ // Create an instance of a storey
+ //
+ Expression storey_type_expr = CreateStoreyTypeExpression (ec);
+
+ ResolveContext rc = new ResolveContext (ec.MemberContext);
Expression e = new New (storey_type_expr, null, Location).Resolve (rc);
e.Emit (ec);
EmitHoistedFieldsInitialization (ec);
SymbolWriter.DefineScopeVariable (ID, Instance.Builder);
- SymbolWriter.CloseCompilerGeneratedBlock (ec.ig);
+ SymbolWriter.CloseCompilerGeneratedBlock (ec);
}
void EmitHoistedFieldsInitialization (EmitContext ec)
// Initialize all storey reference fields by using local or hoisted variables
//
if (used_parent_storeys != null) {
+ var rc = new ResolveContext (ec.MemberContext);
+
foreach (StoreyFieldPair sf in used_parent_storeys) {
//
- // Setting local field
+ // Get instance expression of storey field
//
Expression instace_expr = GetStoreyInstanceExpression (ec);
- FieldExpr f_set_expr = TypeManager.IsGenericType (instace_expr.Type) ?
- new FieldExpr (sf.Field, instace_expr.Type, Location) :
- new FieldExpr (sf.Field, Location);
+ var fs = sf.Field.Spec;
+ if (TypeManager.IsGenericType (instace_expr.Type))
+ fs = MemberCache.GetMember (instace_expr.Type, fs);
+
+ FieldExpr f_set_expr = new FieldExpr (fs, Location);
f_set_expr.InstanceExpression = instace_expr;
SimpleAssign a = new SimpleAssign (f_set_expr, sf.Storey.GetStoreyInstanceExpression (ec));
- if (a.Resolve (new ResolveContext (ec.MemberContext)) != null)
+ if (a.Resolve (rc) != null)
a.EmitStatement (ec);
}
}
//
// Access inside of same storey (S -> S)
//
- return new CompilerGeneratedThis (TypeBuilder, Location);
+ return new CompilerGeneratedThis (CurrentType, Location);
}
//
// External field access
// Storey was cached to local field
//
FieldExpr f_ind = new FieldExpr (f, Location);
- f_ind.InstanceExpression = new CompilerGeneratedThis (TypeBuilder, Location);
+ f_ind.InstanceExpression = new CompilerGeneratedThis (CurrentType, Location);
return f_ind;
}
get { return hoisted_this; }
}
- //
- // Mutate type dispatcher
- //
- public Type MutateType (Type type)
- {
- if (TypeManager.IsGenericType (type))
- return MutateGenericType (type);
-
- if (TypeManager.IsGenericParameter (type))
- return MutateGenericArgument (type);
-
- if (type.IsArray)
- return MutateArrayType (type);
- return type;
- }
-
- //
- // Changes method type arguments (MVAR) to storey (VAR) type arguments
- //
- public void MutateGenericMethod (MethodSpec ms)
- {
- var method = (MethodInfo) ms.MetaInfo;
- Type [] t_args = TypeManager.GetGenericArguments (method);
- if (TypeManager.IsGenericType (method.DeclaringType)) {
- Type t = MutateGenericType (method.DeclaringType);
- if (t != method.DeclaringType) {
- method = (MethodInfo) TypeManager.DropGenericMethodArguments (method);
- if (TypeManager.IsBeingCompiled (method))
- ms.MetaInfo = TypeBuilder.GetMethod (t, method);
- else
- ms.MetaInfo = MethodInfo.GetMethodFromHandle (method.MethodHandle, t.TypeHandle);
- }
- }
-
- if (t_args == null || t_args.Length == 0)
- return;
-
- for (int i = 0; i < t_args.Length; ++i)
- t_args [i] = MutateType (t_args [i]);
-
- method = (MethodInfo) ms.MetaInfo;
- ms.MetaInfo = method.GetGenericMethodDefinition ().MakeGenericMethod (t_args);
- }
-
- public void MutateConstructor (MethodSpec ms)
- {
- var ctor = (ConstructorInfo) ms.MetaInfo;
- if (TypeManager.IsGenericType (ctor.DeclaringType)) {
- Type t = MutateGenericType (ctor.DeclaringType);
- if (t != ctor.DeclaringType) {
- ctor = (ConstructorInfo) TypeManager.DropGenericMethodArguments (ctor);
- if (TypeManager.IsBeingCompiled (ctor))
- ms.MetaInfo = TypeBuilder.GetConstructor (t, ctor);
- else
- ms.MetaInfo = ConstructorInfo.GetMethodFromHandle (ctor.MethodHandle, t.TypeHandle);
- }
- }
- }
-
- public void MutateField (FieldSpec fs)
- {
- var field = fs.MetaInfo;
- if (TypeManager.IsGenericType (field.DeclaringType)) {
- Type t = MutateGenericType (field.DeclaringType);
- if (t != field.DeclaringType) {
- field = TypeManager.DropGenericTypeArguments (field.DeclaringType).GetField (field.Name, TypeManager.AllMembers);
-
- // HACK: TypeBuilder has to be used when a type is of TypeBuilder* but there is no
- // way how to find out (use type comparison when this becomes an issue)
- if (t.GetType ().FullName == "System.Reflection.MonoGenericClass") {
- fs.MetaInfo = TypeBuilder.GetField (t, field);
- } else {
- fs.MetaInfo = FieldInfo.GetFieldFromHandle (field.FieldHandle, t.TypeHandle);
- }
- }
- }
- }
-
- protected Type MutateArrayType (Type array)
- {
- Type element = TypeManager.GetElementType (array);
- if (element.IsArray) {
- element = MutateArrayType (element);
- } else if (TypeManager.IsGenericParameter (element)) {
- element = MutateGenericArgument (element);
- } else if (TypeManager.IsGenericType (element)) {
- element = MutateGenericType (element);
- } else {
- return array;
+ public TypeParameterMutator Mutator {
+ get {
+ return mutator;
}
-
- int rank = array.GetArrayRank ();
- if (rank == 1)
- return element.MakeArrayType ();
-
- return element.MakeArrayType (rank);
- }
-
- protected Type MutateGenericType (Type type)
- {
- Type [] t_args = TypeManager.GetTypeArguments (type);
- if (t_args == null || t_args.Length == 0)
- return type;
-
- for (int i = 0; i < t_args.Length; ++i)
- t_args [i] = MutateType (t_args [i]);
-
- return TypeManager.DropGenericTypeArguments (type).MakeGenericType (t_args);
- }
-
- //
- // Changes method generic argument (MVAR) to type generic argument (VAR)
- //
- public Type MutateGenericArgument (Type type)
- {
- if (CurrentTypeParameters != null) {
- TypeParameter tp = TypeParameter.FindTypeParameter (CurrentTypeParameters, type.Name);
- if (tp != null)
- return tp.Type;
+ set {
+ mutator = value;
}
-
- return type;
}
public IList<ExplicitBlock> ReferencesFromChildrenBlock {
Dictionary<AnonymousExpression, FieldExpr> cached_inner_access; // TODO: Hashtable is too heavyweight
FieldExpr cached_outer_access;
- protected HoistedVariable (AnonymousMethodStorey storey, string name, Type type)
+ protected HoistedVariable (AnonymousMethodStorey storey, string name, TypeSpec type)
: this (storey, storey.AddCapturedVariable (name, type))
{
}
// When setting top-level hoisted variable in generic storey
// change storey generic types to method generic types (VAR -> MVAR)
//
- cached_outer_access = storey.MemberName.IsGeneric ?
- new FieldExpr (field, storey.Instance.Type, field.Location) :
- new FieldExpr (field, field.Location);
+ if (storey.MemberName.IsGeneric) {
+ var fs = MemberCache.GetMember (storey.Instance.Type, field.Spec);
+ cached_outer_access = new FieldExpr (fs, field.Location);
+ } else {
+ cached_outer_access = new FieldExpr (field, field.Location);
+ }
cached_outer_access.InstanceExpression = storey.GetStoreyInstanceExpression (ec);
return cached_outer_access;
}
if (inner_access == null) {
- inner_access = field.Parent.MemberName.IsGeneric ?
- new FieldExpr (field, field.Parent.CurrentType, field.Location) :
- new FieldExpr (field, field.Location);
-
+ if (field.Parent.MemberName.IsGeneric) {
+ var fs = MemberCache.GetMember (field.Parent.CurrentType, field.Spec);
+ inner_access = new FieldExpr (fs, field.Location);
+ } else {
+ inner_access = new FieldExpr (field, field.Location);
+ }
+
inner_access.InstanceExpression = storey.GetStoreyInstanceExpression (ec);
cached_inner_access.Add (ec.CurrentAnonymousMethod, inner_access);
}
}
}
- Dictionary<Type, Expression> compatibles;
+ Dictionary<TypeSpec, Expression> compatibles;
public ToplevelBlock Block;
public AnonymousMethodExpression (Location loc)
{
this.loc = loc;
- this.compatibles = new Dictionary<Type, Expression> ();
+ this.compatibles = new Dictionary<TypeSpec, Expression> ();
}
public override string ExprClassName {
// Returns true if the body of lambda expression can be implicitly
// converted to the delegate of type `delegate_type'
//
- public bool ImplicitStandardConversionExists (ResolveContext ec, Type delegate_type)
+ public bool ImplicitStandardConversionExists (ResolveContext ec, TypeSpec delegate_type)
{
using (ec.With (ResolveContext.Options.InferReturnType, false)) {
using (ec.Set (ResolveContext.Options.ProbingMode)) {
}
}
- protected Type CompatibleChecks (ResolveContext ec, Type delegate_type)
+ protected TypeSpec CompatibleChecks (ResolveContext ec, TypeSpec delegate_type)
{
- if (TypeManager.IsDelegateType (delegate_type))
+ if (delegate_type.IsDelegate)
return delegate_type;
- if (TypeManager.DropGenericTypeArguments (delegate_type) == TypeManager.expression_type) {
- delegate_type = TypeManager.GetTypeArguments (delegate_type) [0];
- if (TypeManager.IsDelegateType (delegate_type))
+ if (delegate_type.IsGeneric && delegate_type.GetDefinition () == TypeManager.expression_type) {
+ delegate_type = delegate_type.TypeArguments [0];
+ if (delegate_type.IsDelegate)
return delegate_type;
ec.Report.Error (835, loc, "Cannot convert `{0}' to an expression tree of non-delegate type `{1}'",
return null;
}
- protected bool VerifyExplicitParameters (ResolveContext ec, Type delegate_type, AParametersCollection parameters)
+ protected bool VerifyExplicitParameters (ResolveContext ec, TypeSpec delegate_type, AParametersCollection parameters)
{
if (VerifyParameterCompatibility (ec, delegate_type, parameters, ec.IsInProbingMode))
return true;
return false;
}
- protected bool VerifyParameterCompatibility (ResolveContext ec, Type delegate_type, AParametersCollection invoke_pd, bool ignore_errors)
+ protected bool VerifyParameterCompatibility (ResolveContext ec, TypeSpec delegate_type, AParametersCollection invoke_pd, bool ignore_errors)
{
if (Parameters.Count != invoke_pd.Count) {
if (ignore_errors)
if (has_implicit_parameters)
continue;
- Type type = invoke_pd.Types [i];
+ TypeSpec type = invoke_pd.Types [i];
// We assume that generic parameters are always inflated
if (TypeManager.IsGenericParameter (type))
//
// Infers type arguments based on explicit arguments
//
- public bool ExplicitTypeInference (ResolveContext ec, TypeInferenceContext type_inference, Type delegate_type)
+ public bool ExplicitTypeInference (ResolveContext ec, TypeInferenceContext type_inference, TypeSpec delegate_type)
{
if (!HasExplicitParameters)
return false;
- if (!TypeManager.IsDelegateType (delegate_type)) {
- if (TypeManager.DropGenericTypeArguments (delegate_type) != TypeManager.expression_type)
+ if (!delegate_type.IsDelegate) {
+ if (delegate_type.GetDefinition () != TypeManager.expression_type)
return false;
delegate_type = TypeManager.GetTypeArguments (delegate_type) [0];
- if (!TypeManager.IsDelegateType (delegate_type))
+ if (!delegate_type.IsDelegate)
return false;
}
- AParametersCollection d_params = TypeManager.GetDelegateParameters (ec, delegate_type);
+ AParametersCollection d_params = Delegate.GetParameters (ec.Compiler, delegate_type);
if (d_params.Count != Parameters.Count)
return false;
for (int i = 0; i < Parameters.Count; ++i) {
- Type itype = d_params.Types [i];
+ TypeSpec itype = d_params.Types [i];
if (!TypeManager.IsGenericParameter (itype)) {
if (!TypeManager.HasElementType (itype))
continue;
return true;
}
- public Type InferReturnType (ResolveContext ec, TypeInferenceContext tic, Type delegate_type)
+ public TypeSpec InferReturnType (ResolveContext ec, TypeInferenceContext tic, TypeSpec delegate_type)
{
AnonymousExpression am;
using (ec.Set (ResolveContext.Options.ProbingMode | ResolveContext.Options.InferReturnType)) {
// Returns AnonymousMethod container if this anonymous method
// expression can be implicitly converted to the delegate type `delegate_type'
//
- public Expression Compatible (ResolveContext ec, Type type)
+ public Expression Compatible (ResolveContext ec, TypeSpec type)
{
Expression am;
if (compatibles.TryGetValue (type, out am))
return am;
- Type delegate_type = CompatibleChecks (ec, type);
+ TypeSpec delegate_type = CompatibleChecks (ec, type);
if (delegate_type == null)
return null;
// needed for the anonymous method. We create the method here.
//
- var invoke_mb = Delegate.GetInvokeMethod (ec.Compiler,
- ec.CurrentType, delegate_type);
- Type return_type = TypeManager.TypeToCoreType (invoke_mb.ReturnType);
-
-#if MS_COMPATIBLE
- Type[] g_args = delegate_type.GetGenericArguments ();
- if (return_type.IsGenericParameter)
- return_type = g_args [return_type.GenericParameterPosition];
-#endif
+ var invoke_mb = Delegate.GetInvokeMethod (ec.Compiler, delegate_type);
+ TypeSpec return_type = invoke_mb.ReturnType;
//
// Second: the return type of the delegate must be compatible with
return am;
}
- protected virtual Expression CreateExpressionTree (ResolveContext ec, Type delegate_type)
+ protected virtual Expression CreateExpressionTree (ResolveContext ec, TypeSpec delegate_type)
{
return CreateExpressionTree (ec);
}
return null;
}
- protected virtual ParametersCompiled ResolveParameters (ResolveContext ec, TypeInferenceContext tic, Type delegate_type)
+ protected virtual ParametersCompiled ResolveParameters (ResolveContext ec, TypeInferenceContext tic, TypeSpec delegate_type)
{
- AParametersCollection delegate_parameters = TypeManager.GetDelegateParameters (ec, delegate_type);
+ var delegate_parameters = Delegate.GetParameters (ec.Compiler, delegate_type);
if (Parameters == ParametersCompiled.Undefined) {
//
return ExprClassName;
}
- AnonymousMethodBody CompatibleMethodBody (ResolveContext ec, TypeInferenceContext tic, Type return_type, Type delegate_type)
+ AnonymousMethodBody CompatibleMethodBody (ResolveContext ec, TypeInferenceContext tic, TypeSpec return_type, TypeSpec delegate_type)
{
ParametersCompiled p = ResolveParameters (ec, tic, delegate_type);
if (p == null)
}
- protected virtual AnonymousMethodBody CompatibleMethodFactory (Type return_type, Type delegate_type, ParametersCompiled p, ToplevelBlock b)
+ protected virtual AnonymousMethodBody CompatibleMethodFactory (TypeSpec return_type, TypeSpec delegate_type, ParametersCompiled p, ToplevelBlock b)
{
return new AnonymousMethodBody (p, b, return_type, delegate_type, loc);
}
return ec;
}
+ protected override void DefineTypeParameters ()
+ {
+ // Type parameters were cloned
+ }
+
protected override bool ResolveMemberType ()
{
if (!base.ResolveMemberType ())
return false;
- if (Storey != null && Storey.IsGeneric) {
- AnonymousMethodStorey gstorey = Storey.GetGenericStorey ();
- if (gstorey != null) {
- if (!Parameters.IsEmpty) {
- Type [] ptypes = Parameters.Types;
- for (int i = 0; i < ptypes.Length; ++i)
- ptypes [i] = gstorey.MutateType (ptypes [i]);
- }
-
- member_type = gstorey.MutateType (member_type);
+ if (Storey != null && Storey.Mutator != null) {
+ if (!parameters.IsEmpty) {
+ var mutated = Storey.Mutator.Mutate (parameters.Types);
+ if (mutated != parameters.Types)
+ parameters = ParametersCompiled.CreateFullyResolved ((Parameter[]) parameters.FixedParameters, mutated);
}
+
+ member_type = Storey.Mutator.Mutate (member_type);
}
return true;
public override void Emit ()
{
- //
- // Before emitting any code we have to change all MVAR references to VAR
- // when the method is of generic type and has hoisted variables
- //
- if (Storey == Parent && Storey.IsGeneric) {
- AnonymousMethodStorey gstorey = Storey.GetGenericStorey ();
- if (gstorey != null) {
- block.MutateHoistedGenericType (gstorey);
- }
- }
-
if (MethodBuilder == null) {
Define ();
}
readonly ToplevelBlock block;
- public Type ReturnType;
+ public TypeSpec ReturnType;
object return_label;
- protected AnonymousExpression (ToplevelBlock block, Type return_type, Location loc)
+ protected AnonymousExpression (ToplevelBlock block, TypeSpec return_type, Location loc)
{
this.ReturnType = return_type;
this.block = block;
static int unique_id;
public AnonymousMethodBody (ParametersCompiled parameters,
- ToplevelBlock block, Type return_type, Type delegate_type,
+ ToplevelBlock block, TypeSpec return_type, TypeSpec delegate_type,
Location loc)
: base (block, return_type, loc)
{
modifiers = Modifiers.STATIC | Modifiers.PRIVATE;
}
- TypeContainer parent = storey != null ? storey : ec.CurrentTypeDefinition;
+ TypeContainer parent = storey != null ? storey : ec.CurrentTypeDefinition.Parent.PartialContainer;
MemberCore mc = ec.MemberContext as MemberCore;
string name = CompilerGeneratedClass.MakeName (parent != storey ? block_name : null,
if (storey == null && mc.MemberName.TypeArguments != null) {
member_name = new MemberName (name, mc.MemberName.TypeArguments.Clone (), Location);
- generic_method = new GenericMethod (parent.NamespaceEntry, parent, member_name,
- new TypeExpression (ReturnType, Location), parameters);
-
- var list = new List<Constraints> ();
- foreach (TypeParameter tparam in ec.CurrentTypeParameters) {
- if (tparam.Constraints != null)
- list.Add (tparam.Constraints.Clone ());
+ var hoisted_tparams = ec.CurrentTypeParameters;
+ var type_params = new TypeParameter[hoisted_tparams.Length];
+ for (int i = 0; i < type_params.Length; ++i) {
+ type_params[i] = hoisted_tparams[i].CreateHoistedCopy (null);
}
- generic_method.SetParameterInfo (list);
+
+ generic_method = new GenericMethod (parent.NamespaceEntry, parent, member_name, type_params,
+ new TypeExpression (ReturnType, Location), parameters);
} else {
member_name = new MemberName (name, Location);
generic_method = null;
}
}
- ILGenerator ig = ec.ig;
- Label l_initialized = ig.DefineLabel ();
+ Label l_initialized = ec.DefineLabel ();
if (am_cache != null) {
- ig.Emit (OpCodes.Ldsfld, am_cache.Spec.MetaInfo);
- ig.Emit (OpCodes.Brtrue_S, l_initialized);
+ ec.Emit (OpCodes.Ldsfld, am_cache.Spec);
+ ec.Emit (OpCodes.Brtrue_S, l_initialized);
}
//
//
if (is_static) {
- ig.Emit (OpCodes.Ldnull);
+ ec.Emit (OpCodes.Ldnull);
} else if (storey != null) {
Expression e = storey.GetStoreyInstanceExpression (ec).Resolve (new ResolveContext (ec.MemberContext));
if (e != null)
e.Emit (ec);
} else {
- ig.Emit (OpCodes.Ldarg_0);
+ ec.Emit (OpCodes.Ldarg_0);
}
- MethodInfo delegate_method = method.MethodBuilder;
+ var delegate_method = method.Spec;
if (storey != null && storey.MemberName.IsGeneric) {
- Type t = storey.Instance.Type;
-
+ TypeSpec t = storey.Instance.Type;
+
//
// Mutate anonymous method instance type if we are in nested
// hoisted generic anonymous method storey
//
if (ec.CurrentAnonymousMethod != null &&
ec.CurrentAnonymousMethod.Storey != null &&
- ec.CurrentAnonymousMethod.Storey.IsGeneric) {
- t = storey.GetGenericStorey ().MutateType (t);
+ ec.CurrentAnonymousMethod.Storey.Mutator != null) {
+ t = storey.Mutator.Mutate (t);
}
- delegate_method = TypeBuilder.GetMethod (t, delegate_method);
+ ec.Emit (OpCodes.Ldftn, TypeBuilder.GetMethod (t.GetMetaInfo (), (MethodInfo) delegate_method.GetMetaInfo ()));
+ } else {
+ ec.Emit (OpCodes.Ldftn, delegate_method);
}
- ig.Emit (OpCodes.Ldftn, delegate_method);
-
var constructor_method = Delegate.GetConstructor (ec.MemberContext.Compiler, ec.CurrentType, type);
-#if MS_COMPATIBLE
-// if (type.IsGenericType && type is TypeBuilder)
-// constructor_method = TypeBuilder.GetConstructor (type, constructor_method);
-#endif
- ig.Emit (OpCodes.Newobj, (ConstructorInfo) constructor_method.MetaInfo);
+ ec.Emit (OpCodes.Newobj, constructor_method);
if (am_cache != null) {
- ig.Emit (OpCodes.Stsfld, am_cache.Spec.MetaInfo);
- ig.MarkLabel (l_initialized);
- ig.Emit (OpCodes.Ldsfld, am_cache.Spec.MetaInfo);
+ ec.Emit (OpCodes.Stsfld, am_cache.Spec);
+ ec.MarkLabel (l_initialized);
+ ec.Emit (OpCodes.Ldsfld, am_cache.Spec);
}
}
return TypeManager.CSharpName (type);
}
- public override void MutateHoistedGenericType (AnonymousMethodStorey storey)
- {
- type = storey.MutateType (type);
- }
-
public static void Reset ()
{
unique_id = 0;
Constructor c = new Constructor (a_type, name, Modifiers.PUBLIC | Modifiers.DEBUGGER_HIDDEN,
null, new AnonymousParameters (ctx, ctor_params), null, loc);
- c.Block = new ToplevelBlock (ctx, c.Parameters, loc);
+ c.Block = new ToplevelBlock (ctx, c.ParameterInfo, loc);
//
// Create fields and contructor body with field initialization
Modifiers.PUBLIC | Modifiers.OVERRIDE | Modifiers.DEBUGGER_HIDDEN, new MemberName ("ToString", loc),
Mono.CSharp.ParametersCompiled.EmptyReadOnlyParameters, null);
- ToplevelBlock equals_block = new ToplevelBlock (Compiler, equals.Parameters, loc);
+ ToplevelBlock equals_block = new ToplevelBlock (Compiler, equals.ParameterInfo, loc);
TypeExpr current_type;
- if (IsGeneric)
- current_type = new GenericTypeExpr (this, loc);
- else
- current_type = new TypeExpression (TypeBuilder, loc);
+ if (type_params != null) {
+ var targs = new TypeArguments ();
+ foreach (var type_param in type_params)
+ targs.Add (new TypeParameterExpr (type_param, type_param.Location));
+
+ current_type = new GenericTypeExpr (Definition, targs, loc);
+ } else {
+ current_type = new TypeExpression (Definition, loc);
+ }
equals_block.AddVariable (current_type, "other", loc);
LocalVariableReference other_variable = new LocalVariableReference (equals_block, "other", loc);
Expression string_concat = new StringConstant ("{", loc);
Expression rs_hashcode = new IntConstant (-2128831035, loc);
for (int i = 0; i < parameters.Count; ++i) {
- AnonymousTypeParameter p = (AnonymousTypeParameter) parameters [i];
- Field f = (Field) Fields [i];
+ var p = parameters [i];
+ var f = Fields [i];
MemberAccess equality_comparer = new MemberAccess (new MemberAccess (
system_collections_generic, "EqualityComparer",
- new TypeArguments (new SimpleName (TypeParameters [i].Name, loc)), loc),
+ new TypeArguments (new SimpleName (CurrentTypeParameters [i].Name, loc)), loc),
"Default", loc);
Arguments arguments_equal = new Arguments (2);
this.Expr = expr;
}
- public Type Type {
+ public TypeSpec Type {
get { return Expr.Type; }
}
if (IsByRef) {
var ml = (IMemoryLocation) Expr;
ml.AddressOf (ec, AddressOp.Load);
- type = TypeManager.GetReferenceType (type);
+ type = ReferenceContainer.MakeType (type);
} else {
Expr.Emit (ec);
}
var arg_type = a.Expr.Type;
- if (!TypeManager.IsDynamicType (arg_type)) {
+ if (arg_type != InternalType.Dynamic) {
MethodGroupExpr mg = a.Expr as MethodGroupExpr;
if (mg != null) {
rc.Report.Error (1976, a.Expr.Location,
foreach (Argument a in args) {
a.Emit (ec);
if (dup_args) {
- ec.ig.Emit (OpCodes.Dup);
+ ec.Emit (OpCodes.Dup);
(temps [i++] = new LocalTemporary (a.Type)).Store (ec);
}
}
public bool HasDynamic {
get {
foreach (Argument a in args) {
- if (TypeManager.IsDynamicType (a.Type))
+ if (a.Type == InternalType.Dynamic)
return true;
}
dynamic = false;
foreach (Argument a in args) {
a.Resolve (ec);
- dynamic |= TypeManager.IsDynamicType (a.Type);
+ dynamic |= a.Type == InternalType.Dynamic;
}
}
- public void MutateHoistedGenericType (AnonymousMethodStorey storey)
- {
- foreach (Argument a in args)
- a.Expr.MutateHoistedGenericType (storey);
- }
-
public void RemoveAt (int index)
{
args.RemoveAt (index);
public class LocalTemporary : Expression, IMemoryLocation, IAssignMethod {
LocalBuilder builder;
- public LocalTemporary (Type t)
+ public LocalTemporary (TypeSpec t)
{
type = t;
eclass = ExprClass.Value;
}
- public LocalTemporary (LocalBuilder b, Type t)
+ public LocalTemporary (LocalBuilder b, TypeSpec t)
: this (t)
{
builder = b;
public override void Emit (EmitContext ec)
{
- ILGenerator ig = ec.ig;
-
if (builder == null)
throw new InternalErrorException ("Emit without Store, or after Release");
- ig.Emit (OpCodes.Ldloc, builder);
+ ec.Emit (OpCodes.Ldloc, builder);
}
#region IAssignMethod Members
public void Store (EmitContext ec)
{
- ILGenerator ig = ec.ig;
if (builder == null)
builder = ec.GetTemporaryLocal (type);
- ig.Emit (OpCodes.Stloc, builder);
+ ec.Emit (OpCodes.Stloc, builder);
}
public void AddressOf (EmitContext ec, AddressOp mode)
if (builder == null)
builder = ec.GetTemporaryLocal (type);
- ILGenerator ig = ec.ig;
-
if (builder.LocalType.IsByRef) {
//
// if is_address, than this is just the address anyways,
// so we just return this.
//
- ig.Emit (OpCodes.Ldloc, builder);
+ ec.Emit (OpCodes.Ldloc, builder);
} else {
- ig.Emit (OpCodes.Ldloca, builder);
+ ec.Emit (OpCodes.Ldloca, builder);
}
}
-
- public override void MutateHoistedGenericType (AnonymousMethodStorey storey)
- {
- type = storey.MutateType (type);
- }
}
/// <summary>
if (target == null || !ok)
return null;
- Type target_type = target.Type;
- Type source_type = source.Type;
+ TypeSpec target_type = target.Type;
+ TypeSpec source_type = source.Type;
eclass = ExprClass.Value;
type = target_type;
return System.Linq.Expressions.Expression.Assign (target_object, source_object);
}
#endif
-
- public override void MutateHoistedGenericType (AnonymousMethodStorey storey)
- {
- source.MutateHoistedGenericType (storey);
- target.MutateHoistedGenericType (storey);
- type = storey.MutateType (type);
- }
-
protected virtual Expression ResolveConversions (ResolveContext ec)
{
source = Convert.ImplicitConversionRequired (ec, source, target.Type, loc);
protected override Expression ResolveConversions (ResolveContext ec)
{
- Type target_type = target.Type;
+ TypeSpec target_type = target.Type;
//
// 1. the return type is implicitly convertible to the type of target
}
}
- if (TypeManager.IsDynamicType (source.Type)) {
+ if (source.Type == InternalType.Dynamic) {
Arguments arg = new Arguments (1);
arg.Add (new Argument (source));
return new SimpleAssign (target, new DynamicConversion (target_type, CSharpBinderFlags.ConvertExplicit, arg, loc), loc).Resolve (ec);
/// <summary>
/// Use member-specific procedure to apply attribute @a in @cb to the entity being built in @builder
/// </summary>
- public abstract void ApplyAttributeBuilder (Attribute a, ConstructorInfo ctor, byte[] cdata, PredefinedAttributes pa);
+ public abstract void ApplyAttributeBuilder (Attribute a, MethodSpec ctor, byte[] cdata, PredefinedAttributes pa);
/// <summary>
/// Returns one AttributeTarget for this element.
//
IMemberContext context;
- static readonly AttributeUsageAttribute DefaultUsageAttribute = new AttributeUsageAttribute (AttributeTargets.All);
+ public static readonly AttributeUsageAttribute DefaultUsageAttribute = new AttributeUsageAttribute (AttributeTargets.All);
static Assembly orig_sec_assembly;
public static readonly object[] EmptyObject = new object [0];
IList<KeyValuePair<MemberExpr, NamedArgument>> named_values;
- static Dictionary<Type, AttributeUsageAttribute> usage_attr_cache;
// Cache for parameter-less attributes
- static Dictionary<Type, ConstructorInfo> att_cache;
+ static Dictionary<TypeSpec, MethodSpec> att_cache;
public Attribute (string target, ATypeNameExpression expr, Arguments[] args, Location loc, bool nameEscaped)
{
public static void Reset ()
{
- usage_attr_cache = new Dictionary<Type, AttributeUsageAttribute> (ReferenceEquality<Type>.Default);
- att_cache = new Dictionary<Type, ConstructorInfo> (ReferenceEquality<Type>.Default);
+ att_cache = new Dictionary<TypeSpec, MethodSpec> ();
}
//
return expr.ResolveAsTypeTerminal (ec, false);
}
- Type ResolvePossibleAttributeType (ATypeNameExpression expr, ref bool is_attr)
+ TypeSpec ResolvePossibleAttributeType (ATypeNameExpression expr, ref bool is_attr)
{
TypeExpr te = ResolveAsTypeTerminal (expr, context);
if (te == null)
return null;
- Type t = te.Type;
- if (TypeManager.IsSubclassOf (t, TypeManager.attribute_type)) {
+ TypeSpec t = te.Type;
+ if (t.IsAttribute) {
is_attr = true;
} else {
Report.SymbolRelatedToPreviousError (t);
bool t1_is_attr = false;
bool t2_is_attr = false;
- Type t1, t2;
+ TypeSpec t1, t2;
ATypeNameExpression expanded = null;
try {
resolve_error = true;
}
- public virtual Type ResolveType ()
+ public virtual TypeSpec ResolveType ()
{
if (Type == null && !resolve_error)
ResolveAttributeType ();
return HasSecurityAttribute && IsSecurityActionValid (false);
}
- static bool IsValidArgumentType (Type t)
+ static bool IsValidArgumentType (TypeSpec t)
{
if (t.IsArray)
t = TypeManager.GetElementType (t);
return;
}
}
-
+
+ var char_set = Import.ImportType (typeof (CharSet));
NamedArguments.Add (new NamedArgument (CharSetEnumMember, loc,
- Constant.CreateConstant (rc, typeof (CharSet), RootContext.ToplevelTypes.DefaultCharSet, Location)));
+ Constant.CreateConstant (rc, char_set, RootContext.ToplevelTypes.DefaultCharSet, Location)));
}
public Report Report {
get { return context.Compiler.Report; }
}
- public ConstructorInfo Resolve ()
+ public MethodSpec Resolve ()
{
if (resolve_error)
return null;
return null;
}
- ObsoleteAttribute obsolete_attr = AttributeTester.GetObsoleteAttribute (Type);
+ ObsoleteAttribute obsolete_attr = Type.GetAttributeObsolete ();
if (obsolete_attr != null) {
AttributeTester.Report_ObsoleteMessage (obsolete_attr, TypeManager.CSharpName (Type), Location, Report);
}
- ConstructorInfo ctor_meta;
-
+ MethodSpec ctor;
// Try if the attribute is simple has been resolved before
if (PosArguments == null && NamedArguments == null) {
- if (att_cache.TryGetValue (Type, out ctor_meta)) {
+ if (att_cache.TryGetValue (Type, out ctor)) {
resolve_error = false;
- return ctor_meta;
+ return ctor;
}
}
ResolveContext rc = new ResolveContext (context, ResolveContext.Options.ConstantScope);
- var ctor = ResolveConstructor (rc);
+ ctor = ResolveConstructor (rc);
if (ctor == null) {
- if (Type is TypeBuilder &&
- TypeManager.LookupDeclSpace (Type).MemberCache == null)
- // The attribute type has been DefineType'd, but not Defined. Let's not treat it as an error.
- // It'll be resolved again when the attached-to entity is emitted.
- resolve_error = false;
return null;
}
}
resolve_error = false;
- return (ConstructorInfo) ctor.MetaInfo;
+ return ctor;
}
protected virtual MethodSpec ResolveConstructor (ResolveContext ec)
}
MethodGroupExpr mg = MemberLookupFinal (ec, ec.CurrentType,
- Type, ConstructorInfo.ConstructorName, MemberTypes.Constructor,
- BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly,
+ Type, ConstructorInfo.ConstructorName, 0, MemberKind.Constructor,
+ BindingRestriction.AccessibleOnly | BindingRestriction.DeclaredOnly,
Location) as MethodGroupExpr;
if (mg == null)
a.Resolve (ec);
Expression member = Expression.MemberLookup (ec.Compiler,
- ec.CurrentType, Type, name,
- MemberTypes.All,
- BindingFlags.Public | BindingFlags.Instance | BindingFlags.Static,
+ ec.CurrentType, Type, name, 0,
+ MemberKind.All,
+ BindingRestriction.AccessibleOnly,
Location);
if (member == null) {
- member = Expression.MemberLookup (ec.Compiler, ec.CurrentType, Type, name,
- MemberTypes.All, BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.Static,
+ member = Expression.MemberLookup (ec.Compiler, ec.CurrentType, Type, name, 0,
+ MemberKind.All, BindingRestriction.None,
Location);
if (member != null) {
ObsoleteAttribute obsolete_attr;
if (member is PropertyExpr) {
- PropertyInfo pi = ((PropertyExpr) member).PropertyInfo;
+ var pi = ((PropertyExpr) member).PropertyInfo;
- if (!pi.CanWrite || !pi.CanRead || pi.GetGetMethod ().IsStatic) {
+ if (!pi.HasSet || !pi.HasGet || pi.IsStatic) {
ec.Report.SymbolRelatedToPreviousError (pi);
Error_InvalidNamedArgument (ec, a);
return false;
return false;
}
- PropertyBase pb = TypeManager.GetProperty (pi);
- if (pb != null)
- obsolete_attr = pb.GetObsoleteAttribute ();
- else
- obsolete_attr = AttributeTester.GetMemberObsoleteAttribute (pi);
-
+ obsolete_attr = pi.GetAttributeObsolete ();
} else {
var fi = ((FieldExpr) member).Spec;
}
if (!IsValidArgumentType (member.Type)) {
- ec.Report.SymbolRelatedToPreviousError (fi.MetaInfo);
+ ec.Report.SymbolRelatedToPreviousError (fi);
Error_InvalidNamedArgumentType (ec, a);
return false;
}
- FieldBase fb = TypeManager.GetField (fi.MetaInfo);
- if (fb != null)
- obsolete_attr = fb.GetObsoleteAttribute ();
- else
- obsolete_attr = AttributeTester.GetMemberObsoleteAttribute (fi.MetaInfo);
+ obsolete_attr = fi.GetAttributeObsolete ();
}
if (obsolete_attr != null && !context.IsObsolete)
public string GetValidTargets ()
{
StringBuilder sb = new StringBuilder ();
- AttributeTargets targets = GetAttributeUsage (Type).ValidOn;
+ AttributeTargets targets = Type.GetAttributeUsage (PredefinedAttributes.Get.AttributeUsage).ValidOn;
if ((targets & AttributeTargets.Assembly) != 0)
sb.Append ("assembly, ");
return sb.Remove (sb.Length - 2, 2).ToString ();
}
- /// <summary>
- /// Returns AttributeUsage attribute based on types hierarchy
- /// </summary>
- static AttributeUsageAttribute GetAttributeUsage (Type type)
- {
- AttributeUsageAttribute ua;
- if (usage_attr_cache.TryGetValue (type, out ua))
- return ua;
-
- Class attr_class = TypeManager.LookupClass (type);
- PredefinedAttribute pa = PredefinedAttributes.Get.AttributeUsage;
-
- if (attr_class == null) {
- if (!pa.IsDefined)
- return new AttributeUsageAttribute (0);
-
- object[] usage_attr = type.GetCustomAttributes (pa.Type, true);
- ua = (AttributeUsageAttribute)usage_attr [0];
- usage_attr_cache.Add (type, ua);
- return ua;
- }
-
- Attribute a = null;
- if (attr_class.OptAttributes != null)
- a = attr_class.OptAttributes.Search (pa);
-
- if (a == null) {
- if (attr_class.TypeBuilder.BaseType != TypeManager.attribute_type)
- ua = GetAttributeUsage (attr_class.TypeBuilder.BaseType);
- else
- ua = DefaultUsageAttribute;
- } else {
- ua = a.GetAttributeUsageAttribute ();
- }
-
- usage_attr_cache.Add (type, ua);
- return ua;
- }
-
- AttributeUsageAttribute GetAttributeUsageAttribute ()
+ public AttributeUsageAttribute GetAttributeUsageAttribute ()
{
if (!arg_resolved)
// TODO: It is not neccessary to call whole Resolve (ApplyAttribute does it now) we need only ctor args.
return ((BoolConstant) PosArguments[0].Expr).Value;
}
- public Type GetCoClassAttributeValue ()
+ public TypeSpec GetCoClassAttributeValue ()
{
if (!arg_resolved)
Resolve ();
{
Type orig_assembly_type = null;
- if (TypeManager.LookupDeclSpace (Type) != null) {
+ if (Type.MemberDefinition is TypeContainer) {
if (!RootContext.StdLib) {
- orig_assembly_type = Type.GetType (Type.FullName);
+ orig_assembly_type = System.Type.GetType (Type.GetMetaInfo ().FullName);
} else {
string orig_version_path = Environment.GetEnvironmentVariable ("__SECURITY_BOOTSTRAP_DB");
if (orig_version_path == null) {
orig_sec_assembly = Assembly.LoadFile (file);
}
- orig_assembly_type = orig_sec_assembly.GetType (Type.FullName, true);
+ orig_assembly_type = orig_sec_assembly.GetType (Type.GetMetaInfo ().FullName, true);
if (orig_assembly_type == null) {
Report.Warning (-112, 1, Location, "Self-referenced security attribute `{0}' " +
"was not found in previous version of assembly");
args[j] = ((Constant) PosArguments[j].Expr).GetTypedValue ();
}
- sa = (SecurityAttribute) Activator.CreateInstance (Type, args);
+ sa = (SecurityAttribute) Activator.CreateInstance (Type.GetMetaInfo (), args);
if (named_values != null) {
for (int i = 0; i < named_values.Count; ++i) {
- PropertyInfo pi = ((PropertyExpr) named_values[i].Key).PropertyInfo;
+ PropertyInfo pi = ((PropertyExpr) named_values[i].Key).PropertyInfo.MetaInfo;
pi.SetValue (sa, ((Constant) named_values [i].Value.Expr).GetTypedValue (), null);
}
}
// All types are from newly created assembly but for invocation with old one we need to convert them
if (named_values != null) {
for (int i = 0; i < named_values.Count; ++i) {
- PropertyInfo emited_pi = ((PropertyExpr) named_values[i].Key).PropertyInfo;
+ PropertyInfo emited_pi = ((PropertyExpr) named_values[i].Key).PropertyInfo.MetaInfo;
// FIXME: We are missing return type filter
// TODO: pi can be null
PropertyInfo pi = orig_assembly_type.GetProperty (emited_pi.Name);
return false;
MethodImplOptions options;
- if (PosArguments [0].Type != typeof (MethodImplOptions))
+ if (PosArguments[0].Type.GetMetaInfo () != typeof (MethodImplOptions))
options = (MethodImplOptions) System.Enum.ToObject (typeof (MethodImplOptions), ((Constant) PosArguments[0].Expr).GetValue ());
else
options = (MethodImplOptions) ((Constant) PosArguments [0].Expr).GetValue ();
public LayoutKind GetLayoutKindValue ()
{
- if (!RootContext.StdLib || PosArguments [0].Type != typeof (LayoutKind))
+ if (!RootContext.StdLib || PosArguments[0].Type.GetMetaInfo () != typeof (LayoutKind))
return (LayoutKind) System.Enum.ToObject (typeof (LayoutKind), ((Constant) PosArguments[0].Expr).GetValue ());
return (LayoutKind) ((Constant) PosArguments[0].Expr).GetValue ();
}
- public Constant GetParameterDefaultValue (out Type type)
+ public Constant GetParameterDefaultValue (out TypeSpec type)
{
var expr = PosArguments[0].Expr;
if (ctor == null)
return;
- AttributeUsageAttribute usage_attr = GetAttributeUsage (Type);
+ AttributeUsageAttribute usage_attr = Type.GetAttributeUsage (PredefinedAttributes.Get.AttributeUsage);
if ((usage_attr.ValidOn & Target) == 0) {
Report.Error (592, Location, "The attribute `{0}' is not valid on this declaration type. " +
"It is valid on `{1}' declarations only",
AttributeEncoder encoder = new AttributeEncoder (false);
if (PosArguments != null) {
- var param_types = TypeManager.GetParameterData (ctor).Types;
+ var param_types = ctor.Parameters.Types;
for (int j = 0; j < PosArguments.Count; ++j) {
var pt = param_types[j];
if (!IsValidArgumentType (pt)) {
return false;
}
- public Type GetArgumentType ()
+ public TypeSpec GetArgumentType ()
{
TypeOf e = GetValue () as TypeOf;
if (e == null)
Stream.Write (buf);
}
- public void Encode (Type type)
+ public void Encode (TypeSpec type)
{
if (type == TypeManager.bool_type) {
Stream.Write ((byte) 0x02);
}
}
- public bool EncodeTypeName (Type type)
+ public bool EncodeTypeName (TypeSpec type)
{
- if (TypeManager.ContainsGenericParameters (type) && !TypeManager.IsGenericTypeDefinition (type))
- return false;
+// if (TypeManager.ContainsGenericParameters (type) && !TypeManager.IsGenericTypeDefinition (type))
+// return false;
- Encode (CodeGen.Assembly.Builder == type.Assembly ? type.FullName : type.AssemblyQualifiedName);
+ var old_type = type.GetMetaInfo ();
+ Encode (type.MemberDefinition.IsImported ? old_type.AssemblyQualifiedName : old_type.FullName);
return true;
}
/// <summary>
/// Helper class for attribute verification routine.
/// </summary>
- sealed class AttributeTester
+ static class AttributeTester
{
- static Dictionary<Type, bool> analyzed_types;
- static Dictionary<Type, ObsoleteAttribute> analyzed_types_obsolete;
- static Dictionary<MemberInfo, ObsoleteAttribute> analyzed_member_obsolete;
- static Dictionary<MethodBase, bool> analyzed_method_excluded;
-// static Dictionary<FieldInfo, IFixedBuffer> fixed_buffer_cache;
-
- static AttributeTester ()
- {
- Reset ();
- }
-
- private AttributeTester ()
- {
- }
-
- public static void Reset ()
- {
- analyzed_types = new Dictionary<Type, bool> (ReferenceEquality<Type>.Default);
- analyzed_types_obsolete = new Dictionary<Type, ObsoleteAttribute> (ReferenceEquality<Type>.Default);
- analyzed_member_obsolete = new Dictionary<MemberInfo, ObsoleteAttribute> (ReferenceEquality<MemberInfo>.Default);
- analyzed_method_excluded = new Dictionary<MethodBase, bool> (ReferenceEquality<MethodBase>.Default);
-// fixed_buffer_cache = new Dictionary<FieldInfo, IFixedBuffer> (ReferenceEquality<FieldInfo>.Default);
- }
-
public enum Result {
Ok,
RefOutArrayError,
/// </summary>
public static Result AreOverloadedMethodParamsClsCompliant (AParametersCollection pa, AParametersCollection pb)
{
- Type [] types_a = pa.Types;
- Type [] types_b = pb.Types;
+ TypeSpec [] types_a = pa.Types;
+ TypeSpec [] types_b = pb.Types;
if (types_a == null || types_b == null)
return Result.Ok;
Result result = Result.Ok;
for (int i = 0; i < types_b.Length; ++i) {
- Type aType = types_a [i];
- Type bType = types_b [i];
+ TypeSpec aType = types_a [i];
+ TypeSpec bType = types_b [i];
+
+ var ac_a = aType as ArrayContainer;
+ var ac_b = aType as ArrayContainer;
- if (aType.IsArray && bType.IsArray) {
- Type a_el_type = TypeManager.GetElementType (aType);
- Type b_el_type = TypeManager.GetElementType (bType);
- if (aType.GetArrayRank () != bType.GetArrayRank () && a_el_type == b_el_type) {
+ if (ac_a != null && ac_b != null) {
+ if (ac_a.Rank != ac_b.Rank && ac_a.Element == ac_b.Element) {
result = Result.RefOutArrayError;
continue;
}
- if (a_el_type.IsArray || b_el_type.IsArray) {
+ if (ac_a.Element.IsArray || ac_b.Element.IsArray) {
result = Result.ArrayArrayError;
continue;
}
return result;
}
- /// <summary>
- /// This method tests the CLS compliance of external types. It doesn't test type visibility.
- /// </summary>
- public static bool IsClsCompliant (Type type)
- {
- if (type == null)
- return true;
-
- bool result;
- if (analyzed_types.TryGetValue (type, out result))
- return result;
-
- if (type.IsPointer) {
- analyzed_types.Add (type, false);
- return false;
- }
-
- if (type.IsArray) {
- result = IsClsCompliant (TypeManager.GetElementType (type));
- } else if (TypeManager.IsNullableType (type)) {
- result = IsClsCompliant (TypeManager.TypeToCoreType (TypeManager.GetTypeArguments (type) [0]));
- } else {
- result = AnalyzeTypeCompliance (type);
- }
- analyzed_types.Add (type, result);
- return result;
- }
-
public static void VerifyModulesClsCompliance (CompilerContext ctx)
{
Module[] modules = GlobalRootNamespace.Instance.Modules;
}
}
- public static Type GetImportedIgnoreCaseClsType (string name)
- {
- foreach (Assembly a in GlobalRootNamespace.Instance.Assemblies) {
- Type t = a.GetType (name, false, true);
- if (t == null)
- continue;
-
- if (IsClsCompliant (t))
- return t;
- }
- return null;
- }
-
static bool GetClsCompliantAttributeValue (ICustomAttributeProvider attribute_provider, Assembly a)
{
- PredefinedAttribute pa = PredefinedAttributes.Get.CLSCompliant;
- if (!pa.IsDefined)
- return false;
-
- object[] cls_attr = attribute_provider.GetCustomAttributes (pa.Type, false);
+ object[] cls_attr = attribute_provider.GetCustomAttributes (typeof (CLSCompliantAttribute), false);
if (cls_attr.Length == 0) {
if (a == null)
return false;
return ((CLSCompliantAttribute)cls_attr [0]).IsCompliant;
}
- static bool AnalyzeTypeCompliance (Type type)
- {
- type = TypeManager.DropGenericTypeArguments (type);
- DeclSpace ds = TypeManager.LookupDeclSpace (type);
- if (ds != null) {
- return ds.IsClsComplianceRequired ();
- }
-
- if (TypeManager.IsGenericParameter (type))
- return true;
-
- return GetClsCompliantAttributeValue (type, type.Assembly);
- }
-
- /// <summary>
- /// Returns instance of ObsoleteAttribute when type is obsolete
- /// </summary>
- public static ObsoleteAttribute GetObsoleteAttribute (Type type)
- {
- ObsoleteAttribute result;
- if (analyzed_types_obsolete.TryGetValue (type, out result))
- return result;
-
- if (TypeManager.HasElementType (type)) {
- result = GetObsoleteAttribute (TypeManager.GetElementType (type));
- } else if (TypeManager.IsGenericParameter (type))
- result = null; // TODO: throw new NotSupportedException ()
- else if (TypeManager.IsGenericType (type) && !TypeManager.IsGenericTypeDefinition (type)) {
- return GetObsoleteAttribute (TypeManager.DropGenericTypeArguments (type));
- } else {
- DeclSpace type_ds = TypeManager.LookupDeclSpace (type);
-
- // Type is external, we can get attribute directly
- if (type_ds == null) {
- PredefinedAttribute pa = PredefinedAttributes.Get.Obsolete;
- if (pa.IsDefined) {
- object[] attribute = type.GetCustomAttributes (pa.Type, false);
- if (attribute.Length == 1)
- result = (ObsoleteAttribute) attribute[0];
- }
- } else {
- result = type_ds.GetObsoleteAttribute ();
- }
- }
-
- // Cannot use .Add because of corlib bootstrap
- analyzed_types_obsolete [type] = result;
- return result;
- }
-
- /// <summary>
- /// Returns instance of ObsoleteAttribute when method is obsolete
- /// </summary>
- public static ObsoleteAttribute GetMethodObsoleteAttribute (MethodBase mb)
- {
- IMethodData mc = TypeManager.GetMethod (mb);
- if (mc != null)
- return mc.GetObsoleteAttribute ();
-
- // compiler generated methods are not registered by AddMethod
- if (mb.DeclaringType is TypeBuilder)
- return null;
-
- MemberInfo mi = TypeManager.GetPropertyFromAccessor (mb);
- if (mi != null)
- return GetMemberObsoleteAttribute (mi);
-
- mi = TypeManager.GetEventFromAccessor (mb);
- if (mi != null)
- return GetMemberObsoleteAttribute (mi);
-
- return GetMemberObsoleteAttribute (mb);
- }
-
- /// <summary>
- /// Returns instance of ObsoleteAttribute when member is obsolete
- /// </summary>
- public static ObsoleteAttribute GetMemberObsoleteAttribute (MemberInfo mi)
- {
- ObsoleteAttribute oa;
- if (analyzed_member_obsolete.TryGetValue (mi, out oa))
- return oa;
-
- if ((mi.DeclaringType is TypeBuilder) || TypeManager.IsGenericType (mi.DeclaringType))
- return null;
-
- PredefinedAttribute pa = PredefinedAttributes.Get.Obsolete;
- if (!pa.IsDefined)
- return null;
-
- oa = System.Attribute.GetCustomAttribute (mi, pa.Type, false) as ObsoleteAttribute;
- analyzed_member_obsolete.Add (mi, oa);
- return oa;
- }
-
/// <summary>
/// Common method for Obsolete error/warning reporting.
/// </summary>
}
Report.Warning (618, 2, loc, "`{0}' is obsolete: `{1}'", member, oa.Message);
}
-
- public static bool IsConditionalMethodExcluded (MethodBase mb, Location loc)
- {
- bool excluded;
- if (analyzed_method_excluded.TryGetValue (mb, out excluded))
- return excluded;
-
- PredefinedAttribute pa = PredefinedAttributes.Get.Conditional;
- if (!pa.IsDefined)
- return false;
-
- ConditionalAttribute[] attrs = mb.GetCustomAttributes (pa.Type, true)
- as ConditionalAttribute[];
- if (attrs.Length == 0) {
- analyzed_method_excluded.Add (mb, false);
- return false;
- }
-
- foreach (ConditionalAttribute a in attrs) {
- if (loc.CompilationUnit.IsConditionalDefined (a.ConditionString)) {
- analyzed_method_excluded.Add (mb, false);
- return false;
- }
- }
-
- analyzed_method_excluded.Add (mb, true);
- return true;
- }
-
- /// <summary>
- /// Analyzes class whether it has attribute which has ConditionalAttribute
- /// and its condition is not defined.
- /// </summary>
- public static bool IsAttributeExcluded (Type type, Location loc)
- {
- if (!type.IsClass)
- return false;
-
- Class class_decl = TypeManager.LookupDeclSpace (type) as Class;
-
- // TODO: add caching
- // TODO: merge all Type bases attribute caching to one cache to save memory
- PredefinedAttribute pa = PredefinedAttributes.Get.Conditional;
- if (class_decl == null && pa.IsDefined) {
- object[] attributes = type.GetCustomAttributes (pa.Type, false);
- foreach (ConditionalAttribute ca in attributes) {
- if (loc.CompilationUnit.IsConditionalDefined (ca.ConditionString))
- return false;
- }
- return attributes.Length > 0;
- }
-
- return class_decl.IsExcluded ();
- }
-
- public static Type GetCoClassAttribute (Type type)
- {
- TypeContainer tc = TypeManager.LookupInterface (type);
- PredefinedAttribute pa = PredefinedAttributes.Get.CoClass;
- if (tc == null) {
- if (!pa.IsDefined)
- return null;
-
- object[] o = type.GetCustomAttributes (pa.Type, false);
- if (o.Length < 1)
- return null;
- return ((System.Runtime.InteropServices.CoClassAttribute)o[0]).CoClass;
- }
-
- if (tc.OptAttributes == null)
- return null;
-
- Attribute a = tc.OptAttributes.Search (pa);
- if (a == null)
- return null;
-
- return a.GetCoClassAttributeValue ();
- }
}
public class PredefinedAttributes
public class PredefinedAttribute
{
- Type type;
+ TypeSpec type;
CustomAttributeBuilder cab;
- ConstructorInfo ctor;
+ MethodSpec ctor;
readonly string ns, name;
CompilerContext compiler;
- static readonly Type NotFound = typeof (PredefinedAttribute);
+ static readonly TypeSpec NotFound = InternalType.Null;
public PredefinedAttribute (string ns, string name)
{
this.name = name;
}
- public static bool operator == (Type type, PredefinedAttribute pa)
+ public static bool operator == (TypeSpec type, PredefinedAttribute pa)
{
return type == pa.type;
}
- public static bool operator != (Type type, PredefinedAttribute pa)
+ public static bool operator != (TypeSpec type, PredefinedAttribute pa)
{
return type != pa.type;
}
public ConstructorInfo Constructor {
- get { return ctor; }
+ get { return ctor == null ? null : (ConstructorInfo) ctor.GetMetaInfo (); }
}
public override int GetHashCode ()
if (!Resolve (true))
return false;
- ConstructorInfo ci = TypeManager.GetPredefinedConstructor (type, Location.Null, Type.EmptyTypes);
+ var ci = TypeManager.GetPredefinedConstructor (type, Location.Null, TypeSpec.EmptyTypes);
if (ci == null)
return false;
- cab = new CustomAttributeBuilder (ci, new object[0]);
+ cab = new CustomAttributeBuilder ((ConstructorInfo) ci.GetMetaInfo (), new object[0]);
return true;
}
- public bool ResolveConstructor (Location loc, params Type[] argType)
+ public bool ResolveConstructor (Location loc, params TypeSpec[] argType)
{
if (ctor != null)
throw new InternalErrorException ("Predefined ctor redefined");
return ctor != null;
}
- public Type Type {
+ public TypeSpec Type {
get { return type; }
}
}
public class ConstantFold {
- public static readonly Type[] binary_promotions = new Type[] {
- TypeManager.decimal_type, TypeManager.double_type, TypeManager.float_type,
- TypeManager.uint64_type, TypeManager.int64_type, TypeManager.uint32_type };
+ static TypeSpec[] binary_promotions;
+
+ public static TypeSpec[] BinaryPromotionsTypes {
+ get {
+ if (binary_promotions == null) {
+ binary_promotions = new TypeSpec[] {
+ TypeManager.decimal_type, TypeManager.double_type, TypeManager.float_type,
+ TypeManager.uint64_type, TypeManager.int64_type, TypeManager.uint32_type };
+ }
+
+ return binary_promotions;
+ }
+ }
+
+ public static void Reset ()
+ {
+ binary_promotions = null;
+ }
//
// Performs the numeric promotions on the left and right expresions
//
static bool DoBinaryNumericPromotions (ResolveContext rc, ref Constant left, ref Constant right)
{
- Type ltype = left.Type;
- Type rtype = right.Type;
+ TypeSpec ltype = left.Type;
+ TypeSpec rtype = right.Type;
- foreach (Type t in binary_promotions) {
+ foreach (TypeSpec t in BinaryPromotionsTypes) {
if (t == ltype)
return t == rtype || ConvertPromotion (rc, ref right, ref left, t);
return left != null && right != null;
}
- static bool ConvertPromotion (ResolveContext rc, ref Constant prim, ref Constant second, Type type)
+ static bool ConvertPromotion (ResolveContext rc, ref Constant prim, ref Constant second, TypeSpec type)
{
Constant c = prim.ConvertImplicitly (rc, type);
if (c != null) {
return new SideEffectConstant (result, right, loc);
}
- Type lt = left.Type;
- Type rt = right.Type;
+ TypeSpec lt = left.Type;
+ TypeSpec rt = right.Type;
bool bool_res;
if (lt == TypeManager.bool_type && lt == rt) {
using System.Security;
using System.Security.Permissions;
using System.Text;
+using System.Linq;
#if NET_2_1
using XmlElement = System.Object;
/// <summary>
/// This is the base class for structs and classes.
/// </summary>
- public abstract class TypeContainer : DeclSpace, IMemberContainer
+ public abstract class TypeContainer : DeclSpace, ITypeDefinition
{
//
// Different context is needed when resolving type container base
// types. Type names come from the parent scope but type parameter
// names from the container scope.
//
- struct BaseContext : IMemberContext
+ public struct BaseContext : IMemberContext
{
TypeContainer tc;
get { return tc.Compiler; }
}
- public Type CurrentType {
+ public TypeSpec CurrentType {
get { return tc.Parent.CurrentType; }
}
get { return tc.PartialContainer.CurrentTypeParameters; }
}
- public TypeContainer CurrentTypeDefinition {
- get { return tc.Parent.CurrentTypeDefinition; }
+ public MemberCore CurrentMemberDefinition {
+ get { return tc; }
+ }
+
+ public bool HasUnresolvedConstraints {
+ get { return true; }
}
public bool IsObsolete {
public string GetSignatureForError ()
{
- throw new NotImplementedException ();
+ return tc.GetSignatureForError ();
}
- public ExtensionMethodGroupExpr LookupExtensionMethod (Type extensionType, string name, Location loc)
+ public ExtensionMethodGroupExpr LookupExtensionMethod (TypeSpec extensionType, string name, int arity, Location loc)
{
return null;
}
return tc.Parent.LookupNamespaceAlias (name);
}
- public FullNamedExpression LookupNamespaceOrType (string name, Location loc, bool ignore_cs0104)
+ public FullNamedExpression LookupNamespaceOrType (string name, int arity, Location loc, bool ignore_cs0104)
{
- TypeParameter[] tp = CurrentTypeParameters;
- if (tp != null) {
- TypeParameter t = TypeParameter.FindTypeParameter (tp, name);
- if (t != null)
- return new TypeParameterExpr (t, loc);
+ if (arity == 0) {
+ TypeParameter[] tp = CurrentTypeParameters;
+ if (tp != null) {
+ TypeParameter t = TypeParameter.FindTypeParameter (tp, name);
+ if (t != null)
+ return new TypeParameterExpr (t, loc);
+ }
}
- return tc.Parent.LookupNamespaceOrType (name, loc, ignore_cs0104);
+ return tc.Parent.LookupNamespaceOrType (name, arity, loc, ignore_cs0104);
}
#endregion
// Holds the list of properties
List<MemberCore> properties;
- // Holds the list of delegates
- List<TypeContainer> delegates;
-
// Holds the list of constructors
- protected List<MemberCore> instance_constructors;
+ protected List<Constructor> instance_constructors;
// Holds the list of fields
- protected List<MemberCore> fields;
+ protected List<FieldBase> fields;
// Holds a list of fields that have initializers
protected List<FieldInitializer> initialized_fields;
// from classes from the arraylist `type_bases'
//
TypeExpr base_type;
- TypeExpr[] iface_exprs;
- Type GenericType;
- GenericTypeParameterBuilder[] nested_gen_params;
+ protected TypeExpr[] iface_exprs;
protected List<FullNamedExpression> type_bases;
- protected bool members_defined;
+ bool members_defined;
bool members_defined_ok;
+ bool type_defined;
- // The interfaces we implement.
- protected Type[] ifaces;
+ TypeContainer InTransit;
- // The base member cache and our member cache
- MemberCache base_cache;
- protected MemberCache member_cache;
+ GenericTypeParameterBuilder[] all_tp_builders;
public const string DefaultIndexerName = "Item";
private bool seen_normal_indexers = false;
private string indexer_name = DefaultIndexerName;
protected bool requires_delayed_unmanagedtype_check;
+ bool error;
private CachedMethods cached_method;
+ protected TypeSpec spec;
+ TypeSpec current_type;
+
List<TypeContainer> partial_parts;
/// <remarks>
this.PartialContainer = this;
}
+ #region Properties
+
+ public override TypeSpec CurrentType {
+ get {
+ if (current_type == null) {
+ if (IsGeneric) {
+ //
+ // Switch to inflated version as it's used by all expressions
+ //
+ var targs = CurrentTypeParameters == null ? TypeSpec.EmptyTypes : CurrentTypeParameters.Select (l => l.Type).ToArray ();
+ current_type = spec.MakeGenericType (targs);
+ } else {
+ current_type = spec;
+ }
+ }
+
+ return current_type;
+ }
+ }
+
+ public override TypeParameter[] CurrentTypeParameters {
+ get {
+ return PartialContainer.type_params;
+ }
+ }
+
+ int CurrentTypeParametersStartIndex {
+ get {
+ int total = all_tp_builders.Length;
+ if (CurrentTypeParameters != null) {
+ return total - CurrentTypeParameters.Length;
+ }
+ return total;
+ }
+ }
+
+ public TypeSpec Definition {
+ get {
+ return spec;
+ }
+ }
+
+ public bool HasMembersDefined {
+ get {
+ return members_defined;
+ }
+ }
+
+ #endregion
+
public bool AddMember (MemberCore symbol)
{
return AddToContainer (symbol, symbol.MemberName.Basename);
}
- protected virtual bool AddMemberType (DeclSpace ds)
+ protected virtual bool AddMemberType (TypeContainer ds)
{
return AddToContainer (ds, ds.Basename);
}
public void AddDelegate (Delegate d)
{
- if (!AddMemberType (d))
- return;
-
- if (delegates == null)
- delegates = new List<TypeContainer> ();
-
- delegates.Add (d);
+ AddTypeContainer (d);
}
private void AddMemberToList (MemberCore mc, List<MemberCore> alist, bool isexplicit)
ConstructorBuilder.ConstructorName : ConstructorBuilder.TypeConstructorName))
return;
- if (is_static && c.Parameters.IsEmpty){
+ if (is_static && c.ParameterInfo.IsEmpty){
if (default_static_constructor != null) {
Report.SymbolRelatedToPreviousError (default_static_constructor);
Report.Error (111, c.Location,
default_static_constructor = c;
} else {
- if (c.Parameters.IsEmpty)
+ if (c.ParameterInfo.IsEmpty)
default_constructor = c;
if (instance_constructors == null)
- instance_constructors = new List<MemberCore> ();
+ instance_constructors = new List<Constructor> ();
instance_constructors.Add (c);
}
return false;
if (fields == null)
- fields = new List<MemberCore> ();
+ fields = new List<FieldBase> ();
fields.Add (field);
compiler_generated.Add (c);
}
- public override void ApplyAttributeBuilder (Attribute a, ConstructorInfo ctor, byte[] cdata, PredefinedAttributes pa)
+ public override void ApplyAttributeBuilder (Attribute a, MethodSpec ctor, byte[] cdata, PredefinedAttributes pa)
{
if (a.Type == pa.DefaultMember) {
if (Indexers != null) {
return;
}
}
-
- base.ApplyAttributeBuilder (a, ctor, cdata, pa);
+
+ if (a.Type == pa.Required) {
+ Report.Error (1608, a.Location, "The RequiredAttribute attribute is not permitted on C# types");
+ return;
+ }
+
+ TypeBuilder.SetCustomAttribute ((ConstructorInfo) ctor.GetMetaInfo (), cdata);
}
public override AttributeTargets AttributeTargets {
}
}
- protected virtual Type BaseType {
+ public virtual TypeSpec BaseType {
get {
- return TypeBuilder.BaseType;
+ return spec.BaseType;
}
}
- public IList<MemberCore> Fields {
+ public IList<FieldBase> Fields {
get {
return fields;
}
}
- public IList<MemberCore> InstanceConstructors {
+ public IList<Constructor> InstanceConstructors {
get {
return instance_constructors;
}
}
}
- public IList<TypeContainer> Delegates {
- get {
- return delegates;
- }
- }
-
public IList<CompilerGeneratedClass> CompilerGeneratedClasses {
get {
return compiler_generated;
}
}
- public string IndexerName {
+ public int TypeParametersCount {
get {
- return indexers == null ? DefaultIndexerName : indexer_name;
+ return MemberName.Arity;
}
}
+ TypeParameterSpec[] ITypeDefinition.TypeParameters {
+ get {
+ // TODO MemberCache: this is going to hurt
+ return PartialContainer.type_params.Select (l => l.Type).ToArray ();
+ }
+ }
+
+ public string GetAttributeDefaultMember ()
+ {
+ return indexers == null ? DefaultIndexerName : indexer_name;
+ }
+
public bool IsComImport {
get {
if (OptAttributes == null)
}
}
+ string ITypeDefinition.Namespace {
+ get {
+ return NamespaceEntry.NS.MemberName.GetSignatureForError ();
+ }
+ }
+
public virtual void RegisterFieldForInitialization (MemberCore field, FieldInitializer expression)
{
if ((field.ModFlags & Modifiers.STATIC) != 0){
get { return pending; }
}
- public override bool GetClsCompliantAttributeValue ()
+ public TypeSpec GetAttributeCoClass ()
{
- if (PartialContainer != this)
- return PartialContainer.GetClsCompliantAttributeValue ();
+ if (OptAttributes == null)
+ return null;
+
+ Attribute a = OptAttributes.Search (PredefinedAttributes.Get.CoClass);
+ if (a == null)
+ return null;
+
+ return a.GetCoClassAttributeValue ();
+ }
+
+ public AttributeUsageAttribute GetAttributeUsage (PredefinedAttribute pa)
+ {
+ Attribute a = null;
+ if (OptAttributes != null) {
+ a = OptAttributes.Search (pa);
+ }
+
+ if (a == null) {
+ if (BaseType != TypeManager.attribute_type)
+ return BaseType.GetAttributeUsage (pa);
+
+ return null;
+ }
- return base.GetClsCompliantAttributeValue ();
+ return a.GetAttributeUsageAttribute ();
}
public virtual void AddBasesForPart (DeclSpace part, List<FullNamedExpression> bases)
int count = type_bases.Count;
TypeExpr [] ifaces = null;
- IMemberContext base_context = new BaseContext (this);
+ var base_context = new BaseContext (this);
for (int i = 0, j = 0; i < count; i++){
- FullNamedExpression fne = (FullNamedExpression) type_bases [i];
+ FullNamedExpression fne = type_bases [i];
- //
- // Standard ResolveAsTypeTerminal cannot be used in this case because
- // it does ObsoleteAttribute and constraint checks which require
- // base type to be set
- //
- TypeExpr fne_resolved = fne.ResolveAsBaseTerminal (base_context, false);
+ TypeExpr fne_resolved = fne.ResolveAsTypeTerminal (base_context, false);
if (fne_resolved == null)
continue;
if (i == 0 && Kind == MemberKind.Class && !fne_resolved.Type.IsInterface) {
- if (fne_resolved is DynamicTypeExpr)
+ if (fne_resolved.Type == InternalType.Dynamic)
Report.Error (1965, Location, "Class `{0}' cannot derive from the dynamic type",
GetSignatureForError ());
else
if (!TypeManager.IsEqual (o_a.ReturnType, o_b.ReturnType))
continue;
- if (!TypeManager.IsEqual (o_a.ParameterTypes, o_b.ParameterTypes))
+ if (!TypeSpecComparer.Default.Equals (o_a.ParameterTypes, o_b.ParameterTypes))
continue;
operators[i] = null;
GetSignatureForError ());
}
}
-
- bool CheckGenericInterfaces (Type[] ifaces)
+
+ bool CreateTypeBuilder ()
{
- var already_checked = new List<Type> ();
-
- for (int i = 0; i < ifaces.Length; i++) {
- Type iface = ifaces [i];
- foreach (Type t in already_checked) {
- if (iface == t)
- continue;
-
- Type[] inferred = new Type [CountTypeParameters];
- if (!TypeManager.MayBecomeEqualGenericInstances (iface, t, inferred, null))
- continue;
+ //
+ // Sets .size to 1 for structs with no instance fields
+ //
+ int type_size = Kind == MemberKind.Struct && first_nonstatic_field == null ? 1 : 0;
- Report.Error (695, Location,
- "`{0}' cannot implement both `{1}' and `{2}' " +
- "because they may unify for some type parameter substitutions",
- TypeManager.CSharpName (TypeBuilder), TypeManager.CSharpName (iface),
- TypeManager.CSharpName (t));
+ if (IsTopLevel) {
+ if (GlobalRootNamespace.Instance.IsNamespace (Name)) {
+ Report.Error (519, Location, "`{0}' clashes with a predefined namespace", Name);
return false;
}
- already_checked.Add (iface);
- }
-
- return true;
- }
-
- bool error = false;
-
- bool CreateTypeBuilder ()
- {
- try {
- Type default_parent = null;
- if (Kind == MemberKind.Struct)
- default_parent = TypeManager.value_type;
- else if (Kind == MemberKind.Enum)
- default_parent = TypeManager.enum_type;
- else if (Kind == MemberKind.Delegate)
- default_parent = TypeManager.multicast_delegate_type;
-
- //
- // Sets .size to 1 for structs with no instance fields
- //
- int type_size = Kind == MemberKind.Struct && first_nonstatic_field == null ? 1 : 0;
-
- if (IsTopLevel){
- if (GlobalRootNamespace.Instance.IsNamespace (Name)) {
- Report.Error (519, Location, "`{0}' clashes with a predefined namespace", Name);
- return false;
- }
-
- ModuleBuilder builder = Module.Compiled.Builder;
- TypeBuilder = builder.DefineType (
- Name, TypeAttr, default_parent, type_size);
- } else {
- TypeBuilder builder = Parent.TypeBuilder;
+ ModuleBuilder builder = Module.Compiled.Builder;
+ TypeBuilder = builder.DefineType (Name, TypeAttr, null, type_size);
+ } else {
+ TypeBuilder builder = Parent.TypeBuilder;
- TypeBuilder = builder.DefineNestedType (
- Basename, TypeAttr, default_parent, type_size);
- }
- } catch (ArgumentException) {
- Report.RuntimeMissingSupport (Location, "static classes");
- return false;
+ TypeBuilder = builder.DefineNestedType (Basename, TypeAttr, null, type_size);
}
- TypeManager.AddUserType (this);
+ spec.SetMetaInfo (TypeBuilder);
+ spec.MemberCache = new MemberCache (this);
+ spec.DeclaringType = Parent.CurrentType;
+
+ if (!IsTopLevel)
+ Parent.MemberCache.AddMember (spec);
if (IsGeneric) {
- string[] param_names = new string [TypeParameters.Length];
+ string[] param_names = new string[TypeParameters.Length];
for (int i = 0; i < TypeParameters.Length; i++)
- param_names [i] = TypeParameters [i].Name;
+ param_names [i] = TypeParameters[i].Name;
- GenericTypeParameterBuilder[] gen_params = TypeBuilder.DefineGenericParameters (param_names);
+ all_tp_builders = TypeBuilder.DefineGenericParameters (param_names);
- int offset = CountTypeParameters;
- if (CurrentTypeParameters != null)
- offset -= CurrentTypeParameters.Length;
-
- if (offset > 0) {
- nested_gen_params = new GenericTypeParameterBuilder [offset];
- Array.Copy (gen_params, nested_gen_params, offset);
+ int offset = CurrentTypeParametersStartIndex;
+ for (int i = offset; i < all_tp_builders.Length; i++) {
+ CurrentTypeParameters [i - offset].Define (all_tp_builders [i], spec);
}
-
- for (int i = offset; i < gen_params.Length; i++)
- CurrentTypeParameters [i - offset].Define (gen_params [i]);
}
return true;
iface_exprs = GetNormalPartialBases (ref base_type);
}
- //
- // GetClassBases calls ResolveBaseTypeExpr() on the various type expressions involved,
- // which in turn should have called DefineType()s on base types if necessary.
- //
- // None of the code below should trigger DefineType()s on classes that we depend on.
- // Thus, we are eligible to be on the topological sort `type_container_resolve_order'.
- //
- // Let's do it as soon as possible, since code below can call DefineType() on classes
- // that depend on us to be populated before they are.
- //
- if (!(this is CompilerGeneratedClass) && !(this is Delegate))
- RootContext.RegisterOrder (this);
-
- if (!CheckRecursiveDefinition (this))
- return false;
+ var cycle = CheckRecursiveDefinition (this);
+ if (cycle != null) {
+ Report.SymbolRelatedToPreviousError (cycle);
+ if (this is Interface) {
+ Report.Error (529, Location,
+ "Inherited interface `{0}' causes a cycle in the interface hierarchy of `{1}'",
+ GetSignatureForError (), cycle.GetSignatureForError ());
+ } else {
+ Report.Error (146, Location,
+ "Circular base class dependency involving `{0}' and `{1}'",
+ GetSignatureForError (), cycle.GetSignatureForError ());
+ }
- if (base_type != null && base_type.Type != null) {
- TypeBuilder.SetParent (base_type.Type);
+ base_type = null;
}
- // add interfaces that were not added at type creation
if (iface_exprs != null) {
- ifaces = TypeManager.ExpandInterfaces (iface_exprs);
- if (ifaces == null)
- return false;
+ foreach (TypeExpr iface in iface_exprs) {
+ var iface_type = iface.Type;
- foreach (Type itype in ifaces)
- TypeBuilder.AddInterfaceImplementation (itype);
+ if (!spec.AddInterface (iface_type))
+ continue;
- if (!CheckGenericInterfaces (ifaces))
- return false;
+ if (iface_type.IsGeneric && spec.Interfaces != null) {
+ foreach (var prev_iface in iface_exprs) {
+ if (prev_iface == iface)
+ break;
+
+ if (!TypeSpecComparer.Unify.IsEqual (iface_type, prev_iface.Type))
+ continue;
+
+ Report.Error (695, Location,
+ "`{0}' cannot implement both `{1}' and `{2}' because they may unify for some type parameter substitutions",
+ GetSignatureForError (), prev_iface.GetSignatureForError (), iface_type.GetSignatureForError ());
+ }
+ }
+
+ TypeBuilder.AddInterfaceImplementation (iface_type.GetMetaInfo ());
+
+ // Ensure the base is always setup
+ var compiled_iface = iface_type.MemberDefinition as Interface;
+ if (compiled_iface != null) {
+ // TODO: Need DefineBaseType only
+ compiled_iface.DefineType ();
+ }
+
+ if (iface_type.Interfaces != null) {
+ var base_ifaces = new List<TypeSpec> (iface_type.Interfaces);
+ for (int i = 0; i < base_ifaces.Count; ++i) {
+ var ii_iface_type = base_ifaces[i];
+ if (spec.AddInterface (ii_iface_type)) {
+ TypeBuilder.AddInterfaceImplementation (ii_iface_type.GetMetaInfo ());
+
+ if (ii_iface_type.Interfaces != null)
+ base_ifaces.AddRange (ii_iface_type.Interfaces);
+ }
+ }
+ }
+ }
+ }
- TypeManager.RegisterBuilder (TypeBuilder, ifaces);
+ if (Kind == MemberKind.Interface) {
+ spec.BaseType = TypeManager.object_type;
+ return true;
+ }
+
+ TypeSpec base_ts;
+ if (base_type != null)
+ base_ts = base_type.Type;
+ else if (spec.IsStruct)
+ base_ts = TypeManager.value_type;
+ else if (spec.IsEnum)
+ base_ts = TypeManager.enum_type;
+ else if (spec.IsDelegate)
+ base_ts = TypeManager.multicast_delegate_type;
+ else
+ base_ts = null;
+
+ if (base_ts != null) {
+ spec.BaseType = base_ts;
+
+ // Set base type after type creation
+ TypeBuilder.SetParent (base_ts.GetMetaInfo ());
}
return true;
}
+ public virtual void DefineConstants ()
+ {
+ if (constants != null) {
+ foreach (Const c in constants) {
+ c.DefineValue ();
+ }
+ }
+
+ if (instance_constructors != null) {
+ foreach (MethodCore m in instance_constructors) {
+ var p = m.ParameterInfo;
+ if (!p.IsEmpty && p[p.Count - 1].HasDefaultValue) {
+ var rc = new ResolveContext (m);
+ p.ResolveDefaultValues (rc);
+ }
+ }
+ }
+
+ if (methods != null) {
+ foreach (MethodCore m in methods) {
+ var p = m.ParameterInfo;
+ if (!p.IsEmpty && p[p.Count - 1].HasDefaultValue) {
+ var rc = new ResolveContext (m);
+ p.ResolveDefaultValues (rc);
+ }
+ }
+ }
+
+ if (indexers != null) {
+ foreach (Indexer i in indexers) {
+ var p = i.ParameterInfo;
+ if (p[p.Count - 1].HasDefaultValue) {
+ var rc = new ResolveContext (i);
+ p.ResolveDefaultValues (rc);
+ }
+ }
+ }
+
+ if (types != null) {
+ foreach (var t in types)
+ t.DefineConstants ();
+ }
+ }
+
//
// Defines the type in the appropriate ModuleBuilder or TypeBuilder.
//
}
if (partial_parts != null) {
- foreach (TypeContainer part in partial_parts)
+ foreach (TypeContainer part in partial_parts) {
+ part.spec = spec;
+ part.current_type = current_type;
part.TypeBuilder = TypeBuilder;
+ }
}
if (Types != null) {
return TypeBuilder;
}
- bool type_defined;
-
public override TypeBuilder DefineType ()
{
if (error)
type_defined = true;
- if (CreateType () == null) {
- error = true;
- return null;
- }
-
if (!DefineBaseTypes ()) {
error = true;
return null;
{
base.SetParameterInfo (constraints_list);
- if (!is_generic || PartialContainer == this)
+ if (PartialContainer.CurrentTypeParameters == null || PartialContainer == this)
return;
- TypeParameter[] tc_names = PartialContainer.TypeParameters;
+ TypeParameter[] tc_names = PartialContainer.CurrentTypeParameters;
for (int i = 0; i < tc_names.Length; ++i) {
if (tc_names [i].Name != type_params [i].Name) {
Report.SymbolRelatedToPreviousError (PartialContainer.Location, "");
}
}
+ //
+ // Replaces normal spec with predefined one when compiling corlib
+ // and this type container defines predefined type
+ //
+ public void SetPredefinedSpec (PredefinedTypeSpec spec)
+ {
+ this.spec = spec;
+ }
+
void UpdateTypeParameterConstraints (TypeContainer part)
{
TypeParameter[] current_params = type_params;
for (int i = 0; i < current_params.Length; i++) {
- Constraints c = part.type_params [i].Constraints;
- if (c == null)
- continue;
-
- if (current_params [i].UpdateConstraints (part, c))
+ if (current_params [i].AddPartialConstraints (part, part.type_params [i]))
continue;
Report.SymbolRelatedToPreviousError (Location, "");
}
}
- public bool ResolveType ()
+ public bool ResolveTypeParameters ()
{
- if (!DoResolveType ())
+ if (!DoResolveTypeParameters ())
return false;
+ if (types != null) {
+ foreach (var type in types)
+ if (!type.ResolveTypeParameters ())
+ return false;
+ }
+
if (compiler_generated != null) {
foreach (CompilerGeneratedClass c in compiler_generated)
- if (!c.ResolveType ())
+ if (!c.ResolveTypeParameters ())
return false;
}
return true;
}
- protected virtual bool DoResolveType ()
+ protected virtual bool DoResolveTypeParameters ()
{
- if (!IsGeneric)
+ if (CurrentTypeParameters == null)
return true;
if (PartialContainer != this)
throw new InternalErrorException ();
- TypeExpr current_type = null;
- if (CurrentTypeParameters != null) {
- foreach (TypeParameter type_param in CurrentTypeParameters) {
- if (!type_param.Resolve (this)) {
- error = true;
- return false;
- }
- }
-
- if (partial_parts != null) {
- foreach (TypeContainer part in partial_parts)
- UpdateTypeParameterConstraints (part);
- }
- }
-
- for (int i = 0; i < TypeParameters.Length; ++i) {
- //
- // FIXME: Same should be done for delegates
- // TODO: Quite ugly way how to propagate constraints to
- // nested types
- //
- if (nested_gen_params != null && i < nested_gen_params.Length) {
- TypeParameters [i].SetConstraints (nested_gen_params [i]);
- } else {
- if (!TypeParameters [i].DefineType (this)) {
- error = true;
- return false;
- }
+ var base_context = new BaseContext (this);
+ foreach (TypeParameter type_param in CurrentTypeParameters) {
+ if (!type_param.ResolveConstraints (base_context)) {
+ error = true;
+ return false;
}
}
- // TODO: Very strange, why not simple make generic type from
- // current type parameters
- current_type = new GenericTypeExpr (this, Location);
- current_type = current_type.ResolveAsTypeTerminal (this, false);
- if (current_type == null) {
- error = true;
- return false;
+ if (partial_parts != null) {
+ foreach (TypeContainer part in partial_parts)
+ UpdateTypeParameterConstraints (part);
}
- currentType = current_type.Type;
return true;
}
return false;
}
- if (Delegates != null) {
- foreach (Delegate d in Delegates)
- if (d.DefineType () == null)
- return false;
- }
-
return true;
}
- TypeContainer InTransit;
-
- protected bool CheckRecursiveDefinition (TypeContainer tc)
+ TypeSpec CheckRecursiveDefinition (TypeContainer tc)
{
- if (InTransit != null) {
- Report.SymbolRelatedToPreviousError (this);
- if (this is Interface)
- Report.Error (
- 529, tc.Location, "Inherited interface `{0}' causes a " +
- "cycle in the interface hierarchy of `{1}'",
- GetSignatureForError (), tc.GetSignatureForError ());
- else
- Report.Error (
- 146, tc.Location, "Circular base class dependency " +
- "involving `{0}' and `{1}'",
- tc.GetSignatureForError (), GetSignatureForError ());
- return false;
- }
+ if (InTransit != null)
+ return spec;
InTransit = tc;
if (base_type != null && base_type.Type != null) {
- Type t = TypeManager.DropGenericTypeArguments (base_type.Type);
- TypeContainer ptc = TypeManager.LookupTypeContainer (t);
- if ((ptc != null) && !ptc.CheckRecursiveDefinition (this))
- return false;
+ var ptc = base_type.Type.MemberDefinition as TypeContainer;
+ if (ptc != null && ptc.CheckRecursiveDefinition (this) != null)
+ return base_type.Type;
}
if (iface_exprs != null) {
foreach (TypeExpr iface in iface_exprs) {
- Type itype = TypeManager.DropGenericTypeArguments (iface.Type);
- TypeContainer ptc = TypeManager.LookupTypeContainer (itype);
- if ((ptc != null) && !ptc.CheckRecursiveDefinition (this))
- return false;
+ var ptc = iface.Type.MemberDefinition as Interface;
+ if (ptc != null && ptc.CheckRecursiveDefinition (this) != null)
+ return iface.Type;
}
}
- if (!IsTopLevel && !Parent.PartialContainer.CheckRecursiveDefinition (this))
- return false;
+ if (!IsTopLevel && Parent.PartialContainer.CheckRecursiveDefinition (this) != null)
+ return spec;
InTransit = null;
- return true;
- }
-
- public override TypeParameter[] CurrentTypeParameters {
- get {
- return PartialContainer.type_params;
- }
+ return null;
}
/// <summary>
members_defined_ok = DoDefineMembers ();
members_defined = true;
+ if (types != null) {
+ foreach (var nested in types)
+ nested.Define ();
+ }
+
return members_defined_ok;
}
{
if (iface_exprs != null) {
foreach (TypeExpr iface in iface_exprs) {
- ObsoleteAttribute oa = AttributeTester.GetObsoleteAttribute (iface.Type);
- if ((oa != null) && !IsObsolete)
- AttributeTester.Report_ObsoleteMessage (
- oa, iface.GetSignatureForError (), Location, Report);
+ var iface_type = iface.Type;
+
+ // Ensure the base is always setup
+ var compiled_iface = iface_type.MemberDefinition as Interface;
+ if (compiled_iface != null)
+ compiled_iface.Define ();
+
+ if (Kind == MemberKind.Interface)
+ MemberCache.AddInterface (iface_type);
+
+ ObsoleteAttribute oa = iface_type.GetAttributeObsolete ();
+ if (oa != null && !IsObsolete)
+ AttributeTester.Report_ObsoleteMessage (oa, iface.GetSignatureForError (), Location, Report);
GenericTypeExpr ct = iface as GenericTypeExpr;
if (ct != null) {
// TODO: passing `this' is wrong, should be base type iface instead
TypeManager.CheckTypeVariance (ct.Type, Variance.Covariant, this);
- if (!ct.CheckConstraints (this))
- return false;
+ ct.CheckConstraints (this);
if (ct.HasDynamicArguments ()) {
Report.Error (1966, iface.Location,
}
if (base_type != null) {
- ObsoleteAttribute obsolete_attr = AttributeTester.GetObsoleteAttribute (base_type.Type);
+ ObsoleteAttribute obsolete_attr = base_type.Type.GetAttributeObsolete ();
if (obsolete_attr != null && !IsObsolete)
AttributeTester.Report_ObsoleteMessage (obsolete_attr, base_type.GetSignatureForError (), Location, Report);
- GenericTypeExpr ct = base_type as GenericTypeExpr;
- if ((ct != null) && !ct.CheckConstraints (this))
- return false;
-
- TypeContainer baseContainer = TypeManager.LookupTypeContainer(base_type.Type);
+ var ct = base_type as GenericTypeExpr;
+ if (ct != null)
+ ct.CheckConstraints (this);
+
+ var baseContainer = base_type.Type.MemberDefinition as ClassOrStruct;
if (baseContainer != null)
- baseContainer.Define();
-
- member_cache = new MemberCache (base_type.Type, this);
- } else if (Kind == MemberKind.Interface) {
- member_cache = new MemberCache (null, this);
- Type [] ifaces = TypeManager.GetInterfaces (TypeBuilder);
- for (int i = 0; i < ifaces.Length; ++i)
- member_cache.AddInterface (TypeManager.LookupMemberCache (ifaces [i]));
- } else {
- member_cache = new MemberCache (null, this);
+ baseContainer.Define ();
}
- if (types != null)
- foreach (TypeContainer tc in types)
- member_cache.AddNestedType (tc);
-
- if (delegates != null)
- foreach (Delegate d in delegates)
- member_cache.AddNestedType (d);
-
- if (partial_parts != null) {
- foreach (TypeContainer part in partial_parts)
- part.member_cache = member_cache;
+ if (type_params != null) {
+ foreach (var tp in type_params) {
+ tp.CheckGenericConstraints ();
+ }
}
if (!IsTopLevel) {
- MemberInfo conflict_symbol = Parent.PartialContainer.FindBaseMemberWithSameName (Basename, false);
- if (conflict_symbol == null) {
+ MemberSpec candidate;
+ var conflict_symbol = MemberCache.FindBaseMember (this, out candidate);
+ if (conflict_symbol == null && candidate == null) {
if ((ModFlags & Modifiers.NEW) != 0)
- Report.Warning (109, 4, Location, "The member `{0}' does not hide an inherited member. The new keyword is not required", GetSignatureForError ());
+ Report.Warning (109, 4, Location, "The member `{0}' does not hide an inherited member. The new keyword is not required",
+ GetSignatureForError ());
} else {
if ((ModFlags & Modifiers.NEW) == 0) {
- Report.SymbolRelatedToPreviousError (conflict_symbol);
+ if (candidate == null)
+ candidate = conflict_symbol;
+
+ Report.SymbolRelatedToPreviousError (candidate);
Report.Warning (108, 2, Location, "`{0}' hides inherited member `{1}'. Use the new keyword if hiding was intended",
- GetSignatureForError (), TypeManager.GetFullNameSignature (conflict_symbol));
+ GetSignatureForError (), candidate.GetSignatureForError ());
}
}
}
CheckPairedOperators ();
}
- DefineContainerMembers (delegates);
-
ComputeIndexerName();
CheckEqualsAndGetHashCode();
- if (CurrentType != null) {
- GenericType = CurrentType;
- }
-
- //
- // FIXME: This hack is needed because member cache does not work
- // with generic types, we rely on runtime to inflate dynamic types.
- // TODO: This hack requires member cache refactoring to be removed
- //
- if (TypeManager.IsGenericType (TypeBuilder))
- member_cache = new MemberCache (this);
-
return true;
}
!pa.ResolveConstructor (Location, TypeManager.string_type))
return;
- CustomAttributeBuilder cb = new CustomAttributeBuilder (pa.Constructor, new string [] { IndexerName });
+ CustomAttributeBuilder cb = new CustomAttributeBuilder (pa.Constructor, new string [] { GetAttributeDefaultMember () });
TypeBuilder.SetCustomAttribute (cb);
}
}
}
- public MemberInfo FindBaseMemberWithSameName (string name, bool ignore_methods)
- {
- return BaseCache == null ? null : BaseCache.FindMemberWithSameName (name, ignore_methods, null);
- }
-
- /// <summary>
- /// This function is based by a delegate to the FindMembers routine
- /// </summary>
- static bool AlwaysAccept (MemberInfo m, object filterCriteria)
- {
- return true;
- }
-
- /// <summary>
- /// This filter is used by FindMembers, and we just keep
- /// a global for the filter to `AlwaysAccept'
- /// </summary>
- static MemberFilter accepting_filter;
-
-
- static TypeContainer ()
- {
- accepting_filter = new MemberFilter (AlwaysAccept);
- }
-
- public MethodInfo[] GetMethods ()
- {
- var members = new List<MethodInfo> ();
-
- Define ();
-
- if (methods != null) {
- int len = methods.Count;
- for (int i = 0; i < len; i++) {
- Method m = (Method) methods [i];
-
- members.Add (m.MethodBuilder);
- }
- }
-
- if (operators != null) {
- int len = operators.Count;
- for (int i = 0; i < len; i++) {
- Operator o = (Operator) operators [i];
-
- members.Add (o.MethodBuilder);
- }
- }
-
- if (properties != null) {
- int len = properties.Count;
- for (int i = 0; i < len; i++) {
- Property p = (Property) properties [i];
-
- if (p.GetBuilder != null)
- members.Add (p.GetBuilder);
- if (p.SetBuilder != null)
- members.Add (p.SetBuilder);
- }
- }
-
- if (indexers != null) {
- int len = indexers.Count;
- for (int i = 0; i < len; i++) {
- Indexer ix = (Indexer) indexers [i];
-
- if (ix.GetBuilder != null)
- members.Add (ix.GetBuilder);
- if (ix.SetBuilder != null)
- members.Add (ix.SetBuilder);
- }
- }
-
- if (events != null) {
- int len = events.Count;
- for (int i = 0; i < len; i++) {
- Event e = (Event) events [i];
-
- if (e.AddBuilder != null)
- members.Add (e.AddBuilder);
- if (e.RemoveBuilder != null)
- members.Add (e.RemoveBuilder);
- }
- }
-
- return members.ToArray ();
- }
-
// Indicated whether container has StructLayout attribute set Explicit
public bool HasExplicitLayout {
get { return (caching_flags & Flags.HasExplicitLayout) != 0; }
public bool HasStructLayout {
get { return (caching_flags & Flags.HasStructLayout) != 0; }
- set { caching_flags |= Flags.HasStructLayout; }
- }
-
- //
- // Return the nested type with name @name. Ensures that the nested type
- // is defined if necessary. Do _not_ use this when you have a MemberCache handy.
- //
- public Type FindNestedType (string name)
- {
- if (PartialContainer != this)
- throw new InternalErrorException ("should not happen");
-
- var lists = new[] { types, delegates };
-
- for (int j = 0; j < lists.Length; ++j) {
- var list = lists [j];
- if (list == null)
- continue;
-
- int len = list.Count;
- for (int i = 0; i < len; ++i) {
- var ds = list [i];
- if (ds.Basename == name) {
- return ds.DefineType ();
- }
- }
- }
-
- return null;
- }
-
- private void FindMembers_NestedTypes (Modifiers modflags,
- BindingFlags bf, MemberFilter filter, object criteria,
- ref List<MemberInfo> members)
- {
- var lists = new[] { types, delegates };
-
- for (int j = 0; j < lists.Length; ++j) {
- var list = lists [j];
- if (list == null)
- continue;
-
- int len = list.Count;
- for (int i = 0; i < len; i++) {
- var ds = list [i];
-
- if ((ds.ModFlags & modflags) == 0)
- continue;
-
- TypeBuilder tb = ds.TypeBuilder;
- if (tb == null) {
- if (!(criteria is string) || ds.Basename.Equals (criteria))
- tb = ds.DefineType ();
- }
-
- if (tb != null && (filter (tb, criteria) == true)) {
- if (members == null)
- members = new List<MemberInfo> ();
-
- members.Add (tb);
- }
- }
- }
- }
-
- /// <summary>
- /// This method returns the members of this type just like Type.FindMembers would
- /// Only, we need to use this for types which are _being_ defined because MS'
- /// implementation can't take care of that.
- /// </summary>
- //
- // FIXME: return an empty static array instead of null, that cleans up
- // some code and is consistent with some coding conventions I just found
- // out existed ;-)
- //
- //
- // Notice that in various cases we check if our field is non-null,
- // something that would normally mean that there was a bug elsewhere.
- //
- // The problem happens while we are defining p-invoke methods, as those
- // will trigger a FindMembers, but this happens before things are defined
- //
- // Since the whole process is a no-op, it is fine to check for null here.
- //
- // TODO: This approach will be one day completely removed, it's already
- // used at few places only
- //
- //
- public override MemberList FindMembers (MemberTypes mt, BindingFlags bf,
- MemberFilter filter, object criteria)
- {
- List<MemberInfo> members = null;
-
- Modifiers modflags = 0;
- if ((bf & BindingFlags.Public) != 0)
- modflags |= Modifiers.PUBLIC | Modifiers.PROTECTED |
- Modifiers.INTERNAL;
- if ((bf & BindingFlags.NonPublic) != 0)
- modflags |= Modifiers.PRIVATE;
-
- Modifiers static_mask = 0, static_flags = 0;
- switch (bf & (BindingFlags.Static | BindingFlags.Instance)) {
- case BindingFlags.Static:
- static_mask = static_flags = Modifiers.STATIC;
- break;
-
- case BindingFlags.Instance:
- static_mask = Modifiers.STATIC;
- static_flags = 0;
- break;
-
- default:
- static_mask = static_flags = 0;
- break;
- }
-
- Timer.StartTimer (TimerType.TcFindMembers);
-
- if (filter == null)
- filter = accepting_filter;
-
- if ((mt & MemberTypes.Field) != 0) {
- if (fields != null) {
- int len = fields.Count;
- for (int i = 0; i < len; i++) {
- FieldBase f = (FieldBase) fields [i];
-
- if ((f.ModFlags & modflags) == 0)
- continue;
- if ((f.ModFlags & static_mask) != static_flags)
- continue;
-
- FieldBuilder fb = f.FieldBuilder;
- if (fb != null && filter (fb, criteria) == true) {
- if (members == null)
- members = new List<MemberInfo> ();
-
- members.Add (fb);
- }
- }
- }
-
- if (constants != null) {
- int len = constants.Count;
- for (int i = 0; i < len; i++) {
- Const con = (Const) constants [i];
-
- if ((con.ModFlags & modflags) == 0)
- continue;
- if ((con.ModFlags & static_mask) != static_flags)
- continue;
-
- FieldBuilder fb = con.FieldBuilder;
- if (fb == null) {
- // Define parent and not member, otherwise membercache can be null
- if (con.Parent.Define ())
- fb = con.FieldBuilder;
- }
- if (fb != null && filter (fb, criteria) == true) {
- if (members == null)
- members = new List<MemberInfo> ();
-
- members.Add (fb);
- }
- }
- }
- }
-
- if ((mt & MemberTypes.Method) != 0) {
- if (methods != null) {
- int len = methods.Count;
- for (int i = 0; i < len; i++) {
- MethodOrOperator m = (MethodOrOperator) methods [i];
-
- if ((m.ModFlags & modflags) == 0)
- continue;
- if ((m.ModFlags & static_mask) != static_flags)
- continue;
-
- MethodBuilder mb = m.MethodBuilder;
-
- if (mb != null && filter (mb, criteria) == true) {
- if (members == null)
- members = new List<MemberInfo> ();
-
- members.Add (mb);
- }
- }
- }
-
- if (operators != null) {
- int len = operators.Count;
- for (int i = 0; i < len; i++) {
- Operator o = (Operator) operators [i];
-
- if ((o.ModFlags & modflags) == 0)
- continue;
- if ((o.ModFlags & static_mask) != static_flags)
- continue;
-
- MethodBuilder ob = o.MethodBuilder;
- if (ob != null && filter (ob, criteria) == true) {
- if (members == null)
- members = new List<MemberInfo> ();
-
- members.Add (ob);
- }
- }
- }
-
- if (events != null) {
- foreach (Event e in events) {
- if ((e.ModFlags & modflags) == 0)
- continue;
- if ((e.ModFlags & static_mask) != static_flags)
- continue;
-
- MethodBuilder b = e.AddBuilder;
- if (b != null && filter (b, criteria)) {
- if (members == null)
- members = new List<MemberInfo> ();
-
- members.Add (b);
- }
-
- b = e.RemoveBuilder;
- if (b != null && filter (b, criteria)) {
- if (members == null)
- members = new List<MemberInfo> ();
-
- members.Add (b);
- }
- }
- }
-
- if (properties != null) {
- int len = properties.Count;
- for (int i = 0; i < len; i++) {
- Property p = (Property) properties [i];
-
- if ((p.ModFlags & modflags) == 0)
- continue;
- if ((p.ModFlags & static_mask) != static_flags)
- continue;
-
- MethodBuilder b;
-
- b = p.GetBuilder;
- if (b != null && filter (b, criteria) == true) {
- if (members == null)
- members = new List<MemberInfo> ();
-
- members.Add (b);
- }
-
- b = p.SetBuilder;
- if (b != null && filter (b, criteria) == true) {
- if (members == null)
- members = new List<MemberInfo> ();
-
- members.Add (b);
- }
- }
- }
-
- if (indexers != null) {
- int len = indexers.Count;
- for (int i = 0; i < len; i++) {
- Indexer ix = (Indexer) indexers [i];
-
- if ((ix.ModFlags & modflags) == 0)
- continue;
- if ((ix.ModFlags & static_mask) != static_flags)
- continue;
-
- MethodBuilder b;
-
- b = ix.GetBuilder;
- if (b != null && filter (b, criteria) == true) {
- if (members == null)
- members = new List<MemberInfo> ();
-
- members.Add (b);
- }
-
- b = ix.SetBuilder;
- if (b != null && filter (b, criteria) == true) {
- if (members == null)
- members = new List<MemberInfo> ();
-
- members.Add (b);
- }
- }
- }
- }
-
- if ((mt & MemberTypes.Event) != 0) {
- if (events != null) {
- int len = events.Count;
- for (int i = 0; i < len; i++) {
- Event e = (Event) events [i];
-
- if ((e.ModFlags & modflags) == 0)
- continue;
- if ((e.ModFlags & static_mask) != static_flags)
- continue;
-
- MemberInfo eb = e.EventBuilder;
- if (eb != null && filter (eb, criteria) == true) {
- if (members == null)
- members = new List<MemberInfo> ();
-
- members.Add (e.EventBuilder);
- }
- }
- }
- }
-
- if ((mt & MemberTypes.Property) != 0){
- if (properties != null) {
- int len = properties.Count;
- for (int i = 0; i < len; i++) {
- Property p = (Property) properties [i];
-
- if ((p.ModFlags & modflags) == 0)
- continue;
- if ((p.ModFlags & static_mask) != static_flags)
- continue;
-
- MemberInfo pb = p.PropertyBuilder;
- if (pb != null && filter (pb, criteria) == true) {
- if (members == null)
- members = new List<MemberInfo> ();
-
- members.Add (p.PropertyBuilder);
- }
- }
- }
-
- if (indexers != null) {
- int len = indexers.Count;
- for (int i = 0; i < len; i++) {
- Indexer ix = (Indexer) indexers [i];
-
- if ((ix.ModFlags & modflags) == 0)
- continue;
- if ((ix.ModFlags & static_mask) != static_flags)
- continue;
-
- MemberInfo ib = ix.PropertyBuilder;
- if (ib != null && filter (ib, criteria) == true) {
- if (members == null)
- members = new List<MemberInfo> ();
-
- members.Add (ix.PropertyBuilder);
- }
- }
- }
- }
-
- if ((mt & MemberTypes.NestedType) != 0)
- FindMembers_NestedTypes (modflags, bf, filter, criteria, ref members);
-
- if ((mt & MemberTypes.Constructor) != 0){
- if (((bf & BindingFlags.Instance) != 0) && (instance_constructors != null)){
- int len = instance_constructors.Count;
- for (int i = 0; i < len; i++) {
- Constructor c = (Constructor) instance_constructors [i];
-
- ConstructorBuilder cb = c.ConstructorBuilder;
- if (cb != null && filter (cb, criteria) == true) {
- if (members == null)
- members = new List<MemberInfo> ();
-
- members.Add (cb);
- }
- }
- }
-
- if (((bf & BindingFlags.Static) != 0) && (default_static_constructor != null)){
- ConstructorBuilder cb =
- default_static_constructor.ConstructorBuilder;
-
- if (cb != null && filter (cb, criteria) == true) {
- if (members == null)
- members = new List<MemberInfo> ();
-
- members.Add (cb);
- }
- }
- }
-
- //
- // Lookup members in base if requested.
- //
- if ((bf & BindingFlags.DeclaredOnly) == 0) {
- if (TypeBuilder.BaseType != null) {
- MemberList list = FindMembers (TypeBuilder.BaseType, mt, bf, filter, criteria);
- if (list.Count > 0) {
- if (members == null)
- members = new List<MemberInfo> ();
-
- members.AddRange (list);
- }
- }
- }
-
- Timer.StopTimer (TimerType.TcFindMembers);
-
- if (members == null)
- return MemberList.Empty;
- else
- return new MemberList (members);
- }
-
- public override MemberCache MemberCache {
- get {
- return member_cache;
- }
- }
-
- public static MemberList FindMembers (Type t, MemberTypes mt, BindingFlags bf,
- MemberFilter filter, object criteria)
- {
- DeclSpace ds = TypeManager.LookupDeclSpace (t);
-
- if (ds != null)
- return ds.FindMembers (mt, bf, filter, criteria);
- else
- return new MemberList (t.FindMembers (mt, bf, filter, criteria));
- }
-
- /// <summary>
- /// Emits the values for the constants
- /// </summary>
- public void EmitConstants ()
- {
- if (constants != null)
- foreach (Const con in constants)
- con.Emit ();
- return;
+ set { caching_flags |= Flags.HasStructLayout; }
+ }
+
+ public MemberCache MemberCache {
+ get {
+ return spec.MemberCache;
+ }
}
void CheckMemberUsage (List<MemberCore> al, string member_type)
}
}
+ public override void Emit ()
+ {
+ if (all_tp_builders != null) {
+ int current_starts_index = CurrentTypeParametersStartIndex;
+ for (int i = 0; i < all_tp_builders.Length; i++) {
+ if (i < current_starts_index) {
+ TypeParameters[i].EmitConstraints (all_tp_builders [i]);
+ } else {
+ CurrentTypeParameters [i - current_starts_index].Emit ();
+ }
+ }
+ }
+
+ if ((ModFlags & Modifiers.COMPILER_GENERATED) != 0 && !Parent.IsCompilerGenerated)
+ PredefinedAttributes.Get.CompilerGenerated.EmitAttribute (TypeBuilder);
+
+ base.Emit ();
+ }
+
// TODO: move to ClassOrStruct
void EmitConstructors ()
{
if (instance_constructors == null)
return;
- if (TypeBuilder.IsSubclassOf (TypeManager.attribute_type) && RootContext.VerifyClsCompliance && IsClsComplianceRequired ()) {
+ if (spec.IsAttribute && IsExposedFromAssembly () && RootContext.VerifyClsCompliance && IsClsComplianceRequired ()) {
bool has_compliant_args = false;
foreach (Constructor c in instance_constructors) {
EmitConstructors ();
- // Can not continue if constants are broken
- EmitConstants ();
- if (Report.Errors > 0)
- return;
+ if (constants != null)
+ foreach (Const con in constants)
+ con.Emit ();
if (default_static_constructor != null)
default_static_constructor.Emit ();
foreach (FieldBase f in fields)
f.Emit ();
- if (delegates != null) {
- foreach (Delegate d in Delegates) {
- d.Emit ();
- }
+ if (types != null) {
+ foreach (TypeContainer t in types)
+ t.EmitType ();
}
if (pending != null)
if (compiler_generated != null) {
for (int i = 0; i < compiler_generated.Count; ++i)
- ((CompilerGeneratedClass) compiler_generated [i]).EmitType ();
+ compiler_generated [i].EmitType ();
}
}
-
- public override void CloseType ()
+
+ public void CloseType ()
{
if ((caching_flags & Flags.CloseTypeCreated) != 0)
return;
+ // Close base type container first to avoid TypeLoadException
+ if (spec.BaseType != null) {
+ var btype = spec.BaseType.MemberDefinition as TypeContainer;
+ if (btype != null)
+ btype.CloseType ();
+ }
+
try {
caching_flags |= Flags.CloseTypeCreated;
TypeBuilder.CreateType ();
if (Types != null){
foreach (TypeContainer tc in Types)
- if (tc.Kind == MemberKind.Struct)
- tc.CloseType ();
-
- foreach (TypeContainer tc in Types)
- if (tc.Kind != MemberKind.Struct)
- tc.CloseType ();
+ tc.CloseType ();
}
- if (Delegates != null)
- foreach (Delegate d in Delegates)
- d.CloseType ();
-
if (compiler_generated != null)
foreach (CompilerGeneratedClass c in compiler_generated)
c.CloseType ();
- PartialContainer = null;
types = null;
-// properties = null;
- delegates = null;
fields = null;
initialized_fields = null;
initialized_static_fields = null;
default_static_constructor = null;
type_bases = null;
OptAttributes = null;
- ifaces = null;
- base_cache = null;
- member_cache = null;
}
//
if (!base.VerifyClsCompliance ())
return false;
- VerifyClsName ();
-
- Type base_type = TypeBuilder.BaseType;
- if (base_type != null && !AttributeTester.IsClsCompliant (base_type)) {
- Report.Warning (3009, 1, Location, "`{0}': base type `{1}' is not CLS-compliant", GetSignatureForError (), TypeManager.CSharpName (base_type));
- }
- return true;
- }
-
-
- /// <summary>
- /// Checks whether container name is CLS Compliant
- /// </summary>
- void VerifyClsName ()
- {
- Dictionary<string, object> base_members = base_cache == null ?
- new Dictionary<string, object> () :
- base_cache.GetPublicMembers ();
- var this_members = new Dictionary<string, object> ();
-
- foreach (var entry in defined_names) {
- MemberCore mc = entry.Value;
- if (!mc.IsClsComplianceRequired ())
- continue;
-
- string name = entry.Key;
- string basename = name.Substring (name.LastIndexOf ('.') + 1);
-
- string lcase = basename.ToLower (System.Globalization.CultureInfo.InvariantCulture);
- object found;
- if (!base_members.TryGetValue (lcase, out found)) {
- if (!this_members.TryGetValue (lcase, out found)) {
- this_members.Add (lcase, mc);
- continue;
- }
- }
+ // Check this name against other containers
+ NamespaceEntry.NS.VerifyClsCompliance ();
- if ((mc.ModFlags & Modifiers.OVERRIDE) != 0)
- continue;
-
- if (found is MemberInfo) {
- if (basename == ((MemberInfo) found).Name)
- continue;
- Report.SymbolRelatedToPreviousError ((MemberInfo) found);
- } else {
- Report.SymbolRelatedToPreviousError ((MemberCore) found);
- }
+ // Check all container names for user classes
+ if (Kind != MemberKind.Delegate)
+ MemberCache.VerifyClsCompliance (Definition, Report);
- Report.Warning (3005, 1, mc.Location, "Identifier `{0}' differing only in case is not CLS-compliant", mc.GetSignatureForError ());
+ if (BaseType != null && !BaseType.IsCLSCompliant ()) {
+ Report.Warning (3009, 1, Location, "`{0}': base type `{1}' is not CLS-compliant",
+ GetSignatureForError (), BaseType.GetSignatureForError ());
}
+ return true;
}
-
/// <summary>
/// Performs checks for an explicit interface implementation. First it
/// checks whether the `interface_type' is a base inteface implementation.
/// </summary>
public bool VerifyImplements (InterfaceMemberBase mb)
{
+ var ifaces = spec.Interfaces;
if (ifaces != null) {
- foreach (Type t in ifaces){
+ foreach (TypeSpec t in ifaces){
if (TypeManager.IsEqual (t, mb.InterfaceType))
return true;
}
return false;
}
- public override Type LookupAnyGeneric (string typeName)
+ //
+ // Used for visiblity checks to tests whether this definition shares
+ // base type baseType, it does member-definition search
+ //
+ public bool IsBaseTypeDefinition (TypeSpec baseType)
{
- if (types != null) {
- foreach (TypeContainer tc in types) {
- if (!tc.IsGeneric)
- continue;
+ // RootContext check
+ if (TypeBuilder == null)
+ return false;
- int pos = tc.Basename.LastIndexOf ('`');
- if (pos == typeName.Length && String.Compare (typeName, 0, tc.Basename, 0, pos) == 0)
- return tc.TypeBuilder;
- }
- }
+ var type = spec;
+ do {
+ if (type.MemberDefinition == baseType.MemberDefinition)
+ return true;
+
+ type = type.BaseType;
+ } while (type != null);
+
+ return false;
+ }
- return base.LookupAnyGeneric (typeName);
+ public MemberCache LoadMembers (TypeSpec declaringType)
+ {
+ throw new NotSupportedException ("Not supported for compiled definition " + GetSignatureForError ());
}
public void Mark_HasEquals ()
}
}
- //
- // IMemberContainer
- //
-
- string IMemberContainer.Name {
- get {
- return Name;
- }
- }
-
- Type IMemberContainer.Type {
- get {
- return TypeBuilder;
- }
- }
-
- bool IMemberContainer.IsInterface {
- get {
- return Kind == MemberKind.Interface;
- }
- }
-
- MemberList IMemberContainer.GetMembers (MemberTypes mt, BindingFlags bf)
- {
- BindingFlags new_bf = bf | BindingFlags.DeclaredOnly;
-
- if (GenericType != null)
- return TypeManager.FindMembers (GenericType, mt, new_bf,
- null, null);
- else
- return FindMembers (mt, new_bf, null, null);
- }
-
//
// Generates xml doc comments (if any), and if required,
// handle warning report.
public override string DocCommentHeader {
get { return "T:"; }
}
-
- public MemberCache BaseCache {
- get {
- if (base_cache != null)
- return base_cache;
- if (TypeBuilder.BaseType != null)
- base_cache = TypeManager.LookupMemberCache (TypeBuilder.BaseType);
- if (TypeBuilder.IsInterface)
- base_cache = TypeManager.LookupBaseInterfacesCache (TypeBuilder);
- return base_cache;
- }
- }
}
public abstract class ClassOrStruct : TypeContainer
}
}
- public override void ApplyAttributeBuilder (Attribute a, ConstructorInfo ctor, byte[] cdata, PredefinedAttributes pa)
+ public override void ApplyAttributeBuilder (Attribute a, MethodSpec ctor, byte[] cdata, PredefinedAttributes pa)
{
if (a.IsValidSecurityAttribute ()) {
if (declarative_security == null)
}
}
- public override ExtensionMethodGroupExpr LookupExtensionMethod (Type extensionType, string name, Location loc)
+ public override ExtensionMethodGroupExpr LookupExtensionMethod (TypeSpec extensionType, string name, int arity, Location loc)
{
DeclSpace top_level = Parent;
if (top_level != null) {
while (top_level.Parent != null)
top_level = top_level.Parent;
- var candidates = NamespaceEntry.NS.LookupExtensionMethod (extensionType, this, name);
+ var candidates = NamespaceEntry.NS.LookupExtensionMethod (extensionType, this, name, arity);
if (candidates != null)
return new ExtensionMethodGroupExpr (candidates, NamespaceEntry, extensionType, loc);
}
- return NamespaceEntry.LookupExtensionMethod (extensionType, name, loc);
+ return NamespaceEntry.LookupExtensionMethod (extensionType, name, arity, loc);
}
protected override TypeAttributes TypeAttr {
Attributes attrs)
: base (ns, parent, name, attrs, MemberKind.Class)
{
- var accmods = Parent.Parent == null ? Modifiers.INTERNAL : Modifiers.PRIVATE;
+ var accmods = (Parent == null || Parent.Parent == null) ? Modifiers.INTERNAL : Modifiers.PRIVATE;
this.ModFlags = ModifiersExtensions.Check (AllowedModifiers, mod, accmods, Location, Report);
+ spec = new TypeSpec (Kind, null, this, null, ModFlags);
if (IsStatic && RootContext.Version == LanguageVersion.ISO_1) {
Report.FeatureIsNotAvailable (Location, "static classes");
base.AddBasesForPart (part, bases);
}
- public override void ApplyAttributeBuilder (Attribute a, ConstructorInfo ctor, byte[] cdata, PredefinedAttributes pa)
+ public override void ApplyAttributeBuilder (Attribute a, MethodSpec ctor, byte[] cdata, PredefinedAttributes pa)
{
if (a.Type == pa.AttributeUsage) {
- if (!TypeManager.IsAttributeType (BaseType) &&
- TypeBuilder.FullName != "System.Attribute") {
+ if (!BaseType.IsAttribute && spec != TypeManager.attribute_type) {
Report.Error (641, a.Location, "Attribute `{0}' is only valid on classes derived from System.Attribute", a.GetSignatureForError ());
}
}
- if (a.Type == pa.Conditional && !TypeManager.IsAttributeType (BaseType)) {
+ if (a.Type == pa.Conditional && !BaseType.IsAttribute) {
Report.Error (1689, a.Location, "Attribute `System.Diagnostics.ConditionalAttribute' is only valid on methods or attribute classes");
return;
}
return;
}
- if (AttributeTester.IsAttributeExcluded (a.Type, Location))
+ if (a.Type.IsConditionallyExcluded (Location))
return;
base.ApplyAttributeBuilder (a, ctor, cdata, pa);
}
Method method = m as Method;
- if (method != null && method.Parameters.HasExtensionMethodType) {
+ if (method != null && method.ParameterInfo.HasExtensionMethodType) {
Report.Error (1105, m.Location, "`{0}': Extension methods must be declared static", m.GetSignatureForError ());
continue;
}
TypeExpr[] ifaces = base.ResolveBaseTypes (out base_class);
if (base_class == null) {
- if (RootContext.StdLib)
- base_class = TypeManager.system_object_expr;
- else if (Name != "System.Object")
+ if (spec != TypeManager.object_type)
base_class = TypeManager.system_object_expr;
} else {
- if (Kind == MemberKind.Class && TypeManager.IsGenericParameter (base_class.Type)){
- Report.Error (
- 689, base_class.Location,
- "Cannot derive from `{0}' because it is a type parameter",
- base_class.GetSignatureForError ());
- return ifaces;
- }
+ var base_type = base_class.Type;
- if (IsGeneric && TypeManager.IsAttributeType (base_class.Type)) {
+ if (base_type.IsGenericParameter){
+ Report.Error (689, base_class.Location, "`{0}': Cannot derive from type parameter `{1}'",
+ GetSignatureForError (), base_type.GetSignatureForError ());
+ } else if (IsGeneric && base_type.IsAttribute) {
Report.Error (698, base_class.Location,
"A generic type cannot derive from `{0}' because it is an attribute class",
base_class.GetSignatureForError ());
- }
-
- if (base_class.IsSealed){
+ } else if (base_type.IsStatic) {
Report.SymbolRelatedToPreviousError (base_class.Type);
- if (base_class.Type.IsAbstract) {
- Report.Error (709, Location, "`{0}': Cannot derive from static class `{1}'",
- GetSignatureForError (), TypeManager.CSharpName (base_class.Type));
- } else {
- Report.Error (509, Location, "`{0}': cannot derive from sealed type `{1}'",
- GetSignatureForError (), TypeManager.CSharpName (base_class.Type));
- }
- return ifaces;
+ Report.Error (709, Location, "`{0}': Cannot derive from static class `{1}'",
+ GetSignatureForError (), base_type.GetSignatureForError ());
+ } else if (base_type.IsSealed){
+ Report.SymbolRelatedToPreviousError (base_class.Type);
+ Report.Error (509, Location, "`{0}': cannot derive from sealed type `{1}'",
+ GetSignatureForError (), base_type.GetSignatureForError ());
}
- if (!base_class.CanInheritFrom ()){
+ if (base_type is PredefinedTypeSpec && !(spec is PredefinedTypeSpec) &&
+ (base_type == TypeManager.enum_type || base_type == TypeManager.value_type || base_type == TypeManager.multicast_delegate_type ||
+ base_type == TypeManager.delegate_type || base_type == TypeManager.array_type)) {
Report.Error (644, Location, "`{0}' cannot derive from special class `{1}'",
- GetSignatureForError (), base_class.GetSignatureForError ());
- return ifaces;
+ GetSignatureForError (), base_type.GetSignatureForError ());
+ base_class = TypeManager.system_object_expr;
}
- if (!IsAccessibleAs (base_class.Type)) {
- Report.SymbolRelatedToPreviousError (base_class.Type);
- Report.Error (60, Location, "Inconsistent accessibility: base class `{0}' is less accessible than class `{1}'",
- TypeManager.CSharpName (base_class.Type), GetSignatureForError ());
+ if (!IsAccessibleAs (base_type)) {
+ Report.SymbolRelatedToPreviousError (base_type);
+ Report.Error (60, Location, "Inconsistent accessibility: base class `{0}' is less accessible than class `{1}'",
+ base_type.GetSignatureForError (), GetSignatureForError ());
}
}
- if (PartialContainer.IsStaticClass) {
+ if (PartialContainer.IsStatic) {
if (base_class.Type != TypeManager.object_type) {
Report.Error (713, Location, "Static class `{0}' cannot derive from type `{1}'. Static classes must derive from object",
GetSignatureForError (), base_class.GetSignatureForError ());
/// Search for at least one defined condition in ConditionalAttribute of attribute class
/// Valid only for attribute classes.
- public bool IsExcluded ()
+ public override string[] ConditionalConditions ()
{
- if ((caching_flags & Flags.Excluded_Undetected) == 0)
- return (caching_flags & Flags.Excluded) != 0;
+ if ((caching_flags & (Flags.Excluded_Undetected | Flags.Excluded)) == 0)
+ return null;
caching_flags &= ~Flags.Excluded_Undetected;
if (OptAttributes == null)
- return false;
+ return null;
Attribute[] attrs = OptAttributes.SearchMulti (PredefinedAttributes.Get.Conditional);
if (attrs == null)
- return false;
+ return null;
- foreach (Attribute a in attrs) {
- string condition = a.GetConditionalAttributeValue ();
- if (Location.CompilationUnit.IsConditionalDefined (condition))
- return false;
- }
+ string[] conditions = new string[attrs.Length];
+ for (int i = 0; i < conditions.Length; ++i)
+ conditions[i] = attrs[i].GetConditionalAttributeValue ();
caching_flags |= Flags.Excluded;
- return true;
+ return conditions;
}
//
public sealed class Struct : ClassOrStruct {
bool is_unmanaged, has_unmanaged_check_done;
+ bool InTransit;
// <summary>
// Modifiers allowed in a struct declaration
Modifiers mod, Attributes attrs)
: base (ns, parent, name, attrs, MemberKind.Struct)
{
- var accmods = parent.Parent == null ? Modifiers.INTERNAL : Modifiers.PRIVATE;
-
- this.ModFlags = ModifiersExtensions.Check (AllowedModifiers, mod, accmods, Location, Report);
+ var accmods = parent.Parent == null ? Modifiers.INTERNAL : Modifiers.PRIVATE;
+ this.ModFlags = ModifiersExtensions.Check (AllowedModifiers, mod, accmods, Location, Report) | Modifiers.SEALED ;
+ spec = new TypeSpec (Kind, null, this, null, ModFlags);
+ }
- this.ModFlags |= Modifiers.SEALED;
+ public override AttributeTargets AttributeTargets {
+ get {
+ return AttributeTargets.Struct;
+ }
}
- public override void ApplyAttributeBuilder (Attribute a, ConstructorInfo ctor, byte[] cdata, PredefinedAttributes pa)
+ public override void ApplyAttributeBuilder (Attribute a, MethodSpec ctor, byte[] cdata, PredefinedAttributes pa)
{
base.ApplyAttributeBuilder (a, ctor, cdata, pa);
}
}
- public override AttributeTargets AttributeTargets {
- get {
- return AttributeTargets.Struct;
+ bool CheckStructCycles (Struct s)
+ {
+ if (s.Fields == null)
+ return true;
+
+ if (s.InTransit)
+ return false;
+
+ s.InTransit = true;
+ foreach (FieldBase field in s.Fields) {
+ TypeSpec ftype = field.Spec.MemberType;
+ if (!ftype.IsStruct)
+ continue;
+
+ if (ftype is PredefinedTypeSpec)
+ continue;
+
+ foreach (var targ in ftype.TypeArguments) {
+ if (!CheckFieldTypeCycle (targ)) {
+ Report.Error (523, field.Location,
+ "Struct member `{0}' of type `{1}' causes a cycle in the struct layout",
+ field.GetSignatureForError (), ftype.GetSignatureForError ());
+ break;
+ }
+ }
+
+ if ((field.IsStatic && !ftype.IsGeneric))
+ continue;
+
+ if (!CheckFieldTypeCycle (ftype)) {
+ Report.Error (523, field.Location,
+ "Struct member `{0}' of type `{1}' causes a cycle in the struct layout",
+ field.GetSignatureForError (), ftype.GetSignatureForError ());
+ break;
+ }
}
+
+ s.InTransit = false;
+ return true;
+ }
+
+ bool CheckFieldTypeCycle (TypeSpec ts)
+ {
+ var fts = ts.MemberDefinition as Struct;
+ if (fts == null)
+ return true;
+
+ return CheckStructCycles (fts);
+ }
+
+ public override void Emit ()
+ {
+ CheckStructCycles (this);
+
+ base.Emit ();
}
public override bool IsUnmanagedType ()
has_unmanaged_check_done = true;
foreach (FieldBase f in fields) {
- if ((f.ModFlags & Modifiers.STATIC) != 0)
+ if (f.IsStatic)
continue;
// It can happen when recursive unmanaged types are defined
// struct S { S* s; }
- Type mt = f.MemberType;
+ TypeSpec mt = f.MemberType;
if (mt == null) {
has_unmanaged_check_done = false;
requires_delayed_unmanagedtype_check = true;
// TODO: Remove when pointer types are under mcs control
while (mt.IsPointer)
mt = TypeManager.GetElementType (mt);
- if (TypeManager.IsEqual (mt, TypeBuilder))
+
+ if (mt.MemberDefinition == this) {
+ for (var p = Parent; p != null; p = p.Parent) {
+ if (p.Kind == MemberKind.Class)
+ return false;
+ }
continue;
+ }
if (TypeManager.IsUnmanagedType (mt))
continue;
protected override TypeExpr[] ResolveBaseTypes (out TypeExpr base_class)
{
TypeExpr[] ifaces = base.ResolveBaseTypes (out base_class);
- //
- // If we are compiling our runtime,
- // and we are defining ValueType, then our
- // base is `System.Object'.
- //
- if (base_class == null) {
- if (!RootContext.StdLib && Name == "System.ValueType")
- base_class = TypeManager.system_object_expr;
- else
- base_class = TypeManager.system_valuetype_expr;
- }
-
+ base_class = TypeManager.system_valuetype_expr;
return ifaces;
}
- //
- // FIXME: Allow the user to specify a different set of attributes
- // in some cases (Sealed for example is mandatory for a class,
- // but what SequentialLayout can be changed
- //
protected override TypeAttributes TypeAttr {
get {
const TypeAttributes DefaultTypeAttributes =
/// <summary>
/// Interfaces
/// </summary>
- public sealed class Interface : TypeContainer, IMemberContainer {
+ public sealed class Interface : TypeContainer {
/// <summary>
/// Modifiers allowed in a class declaration
var accmods = parent.Parent == null ? Modifiers.INTERNAL : Modifiers.PRIVATE;
this.ModFlags = ModifiersExtensions.Check (AllowedModifiers, mod, accmods, name.Location, Report);
+ spec = new TypeSpec (Kind, null, this, null, ModFlags);
}
- public override void ApplyAttributeBuilder (Attribute a, ConstructorInfo ctor, byte[] cdata, PredefinedAttributes pa)
+ public override void ApplyAttributeBuilder (Attribute a, MethodSpec ctor, byte[] cdata, PredefinedAttributes pa)
{
if (a.Type == pa.ComImport && !attributes.Contains (pa.Guid)) {
a.Error_MissingGuidAttribute ();
if (!base.VerifyClsCompliance ())
return false;
- if (ifaces != null) {
- foreach (Type t in ifaces) {
- if (AttributeTester.IsClsCompliant (t))
+ if (iface_exprs != null) {
+ foreach (var iface in iface_exprs) {
+ if (iface.Type.IsCLSCompliant ())
continue;
- Report.SymbolRelatedToPreviousError (t);
+ Report.SymbolRelatedToPreviousError (iface.Type);
Report.Warning (3027, 1, Location, "`{0}' is not CLS-compliant because base interface `{1}' is not CLS-compliant",
- GetSignatureForError (), TypeManager.CSharpName (t));
+ GetSignatureForError (), TypeManager.CSharpName (iface.Type));
}
}
//
// The interface type we are explicitly implementing
//
- public Type InterfaceType;
+ public TypeSpec InterfaceType;
//
// The method we're overriding if this is an override method.
//
- protected MethodInfo base_method;
+ protected MethodSpec base_method;
readonly Modifiers explicit_mod_flags;
public MethodAttributes flags;
if ((caching_flags & Flags.MethodOverloadsExist) != 0)
CheckForDuplications ();
- if (IsExplicitImpl || this is Destructor)
+ if (IsExplicitImpl)
return true;
- // Is null for System.Object while compiling corlib and base interfaces
- if (Parent.PartialContainer.BaseCache == null) {
- if ((ModFlags & Modifiers.NEW) != 0) {
- Report.Warning (109, 4, Location, "The member `{0}' does not hide an inherited member. The new keyword is not required", GetSignatureForError ());
- }
+ // For System.Object only
+ if (Parent.BaseType == null)
return true;
- }
-
- Type base_ret_type = null;
- base_method = FindOutBaseMethod (ref base_ret_type);
- // method is override
- if (base_method != null) {
- if (!CheckMethodAgainstBase (base_ret_type))
- return false;
+ MemberSpec candidate;
+ var base_member = FindBaseMember (out candidate);
- if ((ModFlags & Modifiers.OVERRIDE) != 0) {
- ObsoleteAttribute oa = AttributeTester.GetMethodObsoleteAttribute (base_method);
- if (oa != null) {
- if (OptAttributes == null || !OptAttributes.Contains (PredefinedAttributes.Get.Obsolete)) {
- Report.SymbolRelatedToPreviousError (base_method);
- Report.Warning (672, 1, Location, "Member `{0}' overrides obsolete member `{1}'. Add the Obsolete attribute to `{0}'",
- GetSignatureForError (), TypeManager.CSharpSignature (base_method));
+ if ((ModFlags & Modifiers.OVERRIDE) != 0) {
+ if (base_member == null) {
+ if (candidate == null) {
+ if (this is Method && ((Method)this).ParameterInfo.IsEmpty && MemberName.Name == Destructor.MetadataName && MemberName.Arity == 0) {
+ Report.Error (249, Location, "Do not override `{0}'. Use destructor syntax instead",
+ "object.Finalize()");
+ } else {
+ Report.Error (115, Location, "`{0}' is marked as an override but no suitable {1} found to override",
+ GetSignatureForError (), SimpleName.GetMemberType (this));
}
} else {
- if (OptAttributes != null && OptAttributes.Contains (PredefinedAttributes.Get.Obsolete)) {
- Report.SymbolRelatedToPreviousError (base_method);
- Report.Warning (809, 1, Location, "Obsolete member `{0}' overrides non-obsolete member `{1}'",
- GetSignatureForError (), TypeManager.CSharpSignature (base_method));
- }
+ Report.SymbolRelatedToPreviousError (candidate);
+ if (this is Event)
+ Report.Error (72, Location, "`{0}': cannot override because `{1}' is not an event",
+ GetSignatureForError (), TypeManager.GetFullNameSignature (candidate));
+ else if (this is PropertyBase)
+ Report.Error (544, Location, "`{0}': cannot override because `{1}' is not a property",
+ GetSignatureForError (), TypeManager.GetFullNameSignature (candidate));
+ else
+ Report.Error (505, Location, "`{0}': cannot override because `{1}' is not a method",
+ GetSignatureForError (), TypeManager.GetFullNameSignature (candidate));
}
+
+ return false;
}
- return true;
- }
- MemberInfo conflict_symbol = Parent.PartialContainer.FindBaseMemberWithSameName (Name, !((this is Event) || (this is Property)));
- if ((ModFlags & Modifiers.OVERRIDE) != 0) {
- if (conflict_symbol != null) {
- Report.SymbolRelatedToPreviousError (conflict_symbol);
- if (this is Event)
- Report.Error (72, Location, "`{0}': cannot override because `{1}' is not an event", GetSignatureForError (), TypeManager.GetFullNameSignature (conflict_symbol));
- else if (this is PropertyBase)
- Report.Error (544, Location, "`{0}': cannot override because `{1}' is not a property", GetSignatureForError (), TypeManager.GetFullNameSignature (conflict_symbol));
- else
- Report.Error (505, Location, "`{0}': cannot override because `{1}' is not a method", GetSignatureForError (), TypeManager.GetFullNameSignature (conflict_symbol));
+ if (!CheckOverrideAgainstBase (base_member))
+ return false;
+
+ ObsoleteAttribute oa = base_member.GetAttributeObsolete ();
+ if (oa != null) {
+ if (OptAttributes == null || !OptAttributes.Contains (PredefinedAttributes.Get.Obsolete)) {
+ Report.SymbolRelatedToPreviousError (base_member);
+ Report.Warning (672, 1, Location, "Member `{0}' overrides obsolete member `{1}'. Add the Obsolete attribute to `{0}'",
+ GetSignatureForError (), TypeManager.GetFullNameSignature (base_member));
+ }
} else {
- Report.Error (115, Location, "`{0}' is marked as an override but no suitable {1} found to override",
- GetSignatureForError (), SimpleName.GetMemberType (this));
+ if (OptAttributes != null && OptAttributes.Contains (PredefinedAttributes.Get.Obsolete)) {
+ Report.SymbolRelatedToPreviousError (base_member);
+ Report.Warning (809, 1, Location, "Obsolete member `{0}' overrides non-obsolete member `{1}'",
+ GetSignatureForError (), TypeManager.GetFullNameSignature (base_member));
+ }
}
- return false;
- }
- if (conflict_symbol == null) {
- if ((ModFlags & Modifiers.NEW) != 0) {
- Report.Warning (109, 4, Location, "The member `{0}' does not hide an inherited member. The new keyword is not required", GetSignatureForError ());
- }
+ base_method = base_member as MethodSpec;
return true;
}
- if ((ModFlags & Modifiers.NEW) == 0) {
- if (this is MethodOrOperator && conflict_symbol.MemberType == MemberTypes.Method)
- return true;
+ if (base_member == null && candidate != null && (!(candidate is IParametersMember) || !(this is IParametersMember)))
+ base_member = candidate;
+
+ if (base_member == null) {
+ if ((ModFlags & Modifiers.NEW) != 0) {
+ if (base_member == null) {
+ Report.Warning (109, 4, Location, "The member `{0}' does not hide an inherited member. The new keyword is not required",
+ GetSignatureForError ());
+ }
+ }
+ } else {
+ if ((ModFlags & Modifiers.NEW) == 0) {
+ ModFlags |= Modifiers.NEW;
+ Report.SymbolRelatedToPreviousError (base_member);
+ if (!IsInterface && (base_member.Modifiers & (Modifiers.ABSTRACT | Modifiers.VIRTUAL | Modifiers.OVERRIDE)) != 0) {
+ Report.Warning (114, 2, Location, "`{0}' hides inherited member `{1}'. To make the current member override that implementation, add the override keyword. Otherwise add the new keyword",
+ GetSignatureForError (), base_member.GetSignatureForError ());
+ } else {
+ Report.Warning (108, 2, Location, "`{0}' hides inherited member `{1}'. Use the new keyword if hiding was intended",
+ GetSignatureForError (), base_member.GetSignatureForError ());
+ }
+ }
- Report.SymbolRelatedToPreviousError (conflict_symbol);
- Report.Warning (108, 2, Location, "`{0}' hides inherited member `{1}'. Use the new keyword if hiding was intended",
- GetSignatureForError (), TypeManager.GetFullNameSignature (conflict_symbol));
+ if (!IsInterface && base_member.IsAbstract) {
+ Report.SymbolRelatedToPreviousError (base_member);
+ Report.Error (533, Location, "`{0}' hides inherited abstract member `{1}'",
+ GetSignatureForError (), base_member.GetSignatureForError ());
+ }
}
return true;
protected virtual bool CheckForDuplications ()
{
- return Parent.MemberCache.CheckExistingMembersOverloads (
- this, GetFullName (MemberName), ParametersCompiled.EmptyReadOnlyParameters, Report);
+ return Parent.MemberCache.CheckExistingMembersOverloads (this, ParametersCompiled.EmptyReadOnlyParameters);
}
//
// Performs various checks on the MethodInfo `mb' regarding the modifier flags
// that have been defined.
//
- // `name' is the user visible name for reporting errors (this is used to
- // provide the right name regarding method names and properties)
- //
- bool CheckMethodAgainstBase (Type base_method_type)
+ protected virtual bool CheckOverrideAgainstBase (MemberSpec base_member)
{
bool ok = true;
- if ((ModFlags & Modifiers.OVERRIDE) != 0){
- if (!(base_method.IsAbstract || base_method.IsVirtual)){
- Report.SymbolRelatedToPreviousError (base_method);
- Report.Error (506, Location,
- "`{0}': cannot override inherited member `{1}' because it is not marked virtual, abstract or override",
- GetSignatureForError (), TypeManager.CSharpSignature (base_method));
- ok = false;
- }
-
- // Now we check that the overriden method is not final
-
- if (base_method.IsFinal) {
- Report.SymbolRelatedToPreviousError (base_method);
- Report.Error (239, Location, "`{0}': cannot override inherited member `{1}' because it is sealed",
- GetSignatureForError (), TypeManager.CSharpSignature (base_method));
- ok = false;
- }
- //
- // Check that the permissions are not being changed
- //
- MethodAttributes thisp = flags & MethodAttributes.MemberAccessMask;
- MethodAttributes base_classp = base_method.Attributes & MethodAttributes.MemberAccessMask;
-
- if (!CheckAccessModifiers (thisp, base_classp, base_method)) {
- Error_CannotChangeAccessModifiers (Location, base_method, base_classp, null);
- ok = false;
- }
+ if ((base_member.Modifiers & (Modifiers.ABSTRACT | Modifiers.VIRTUAL | Modifiers.OVERRIDE | Modifiers.OVERRIDE_UNCHECKED)) == 0) {
+ Report.SymbolRelatedToPreviousError (base_member);
+ Report.Error (506, Location,
+ "`{0}': cannot override inherited member `{1}' because it is not marked virtual, abstract or override",
+ GetSignatureForError (), TypeManager.CSharpSignature (base_member));
+ ok = false;
+ }
- if (!TypeManager.IsEqual (MemberType, TypeManager.TypeToCoreType (base_method_type))) {
- Report.SymbolRelatedToPreviousError (base_method);
- if (this is PropertyBasedMember) {
- Report.Error (1715, Location, "`{0}': type must be `{1}' to match overridden member `{2}'",
- GetSignatureForError (), TypeManager.CSharpName (base_method_type), TypeManager.CSharpSignature (base_method));
- }
- else {
- Report.Error (508, Location, "`{0}': return type must be `{1}' to match overridden member `{2}'",
- GetSignatureForError (), TypeManager.CSharpName (base_method_type), TypeManager.CSharpSignature (base_method));
- }
- ok = false;
- }
+ // Now we check that the overriden method is not final
+ if ((base_member.Modifiers & Modifiers.SEALED) != 0) {
+ Report.SymbolRelatedToPreviousError (base_member);
+ Report.Error (239, Location, "`{0}': cannot override inherited member `{1}' because it is sealed",
+ GetSignatureForError (), TypeManager.CSharpSignature (base_member));
+ ok = false;
}
- if ((ModFlags & Modifiers.NEW) == 0) {
- if ((ModFlags & Modifiers.OVERRIDE) == 0) {
- ModFlags |= Modifiers.NEW;
- Report.SymbolRelatedToPreviousError (base_method);
- if (!IsInterface && (base_method.IsVirtual || base_method.IsAbstract)) {
- Report.Warning (114, 2, Location, "`{0}' hides inherited member `{1}'. To make the current member override that implementation, add the override keyword. Otherwise add the new keyword",
- GetSignatureForError (), TypeManager.CSharpSignature (base_method));
- if (base_method.IsAbstract){
- Report.Error (533, Location, "`{0}' hides inherited abstract member `{1}'",
- GetSignatureForError (), TypeManager.CSharpSignature (base_method));
- ok = false;
- }
- } else {
- Report.Warning (108, 2, Location, "`{0}' hides inherited member `{1}'. Use the new keyword if hiding was intended",
- GetSignatureForError (), TypeManager.CSharpSignature (base_method));
- }
- }
- } else {
- if (base_method.IsAbstract && !IsInterface) {
- Report.SymbolRelatedToPreviousError (base_method);
- Report.Error (533, Location, "`{0}' hides inherited abstract member `{1}'",
- GetSignatureForError (), TypeManager.CSharpSignature (base_method));
- return ok = false;
+ var base_member_type = ((IInterfaceMemberSpec) base_member).MemberType;
+ if (!TypeSpecComparer.Override.IsEqual (MemberType, base_member_type)) {
+ Report.SymbolRelatedToPreviousError (base_member);
+ if (this is PropertyBasedMember) {
+ Report.Error (1715, Location, "`{0}': type must be `{1}' to match overridden member `{2}'",
+ GetSignatureForError (), TypeManager.CSharpName (base_member_type), TypeManager.CSharpSignature (base_member));
+ } else {
+ Report.Error (508, Location, "`{0}': return type must be `{1}' to match overridden member `{2}'",
+ GetSignatureForError (), TypeManager.CSharpName (base_member_type), TypeManager.CSharpSignature (base_member));
}
+ ok = false;
}
return ok;
}
-
- protected bool CheckAccessModifiers (MethodAttributes thisp, MethodAttributes base_classp, MethodInfo base_method)
+
+ protected static bool CheckAccessModifiers (MemberCore this_member, MemberSpec base_member)
{
- if ((base_classp & MethodAttributes.FamORAssem) == MethodAttributes.FamORAssem){
+ var thisp = this_member.ModFlags & Modifiers.AccessibilityMask;
+ var base_classp = base_member.Modifiers & Modifiers.AccessibilityMask;
+
+ if ((base_classp & (Modifiers.PROTECTED | Modifiers.INTERNAL)) == (Modifiers.PROTECTED | Modifiers.INTERNAL)) {
//
// when overriding protected internal, the method can be declared
// protected internal only within the same assembly or assembly
// which has InternalsVisibleTo
//
- if ((thisp & MethodAttributes.FamORAssem) == MethodAttributes.FamORAssem){
- return TypeManager.IsThisOrFriendAssembly (Parent.Module.Assembly, base_method.DeclaringType.Assembly);
- } else if ((thisp & MethodAttributes.Family) != MethodAttributes.Family) {
+ if ((thisp & (Modifiers.PROTECTED | Modifiers.INTERNAL)) == (Modifiers.PROTECTED | Modifiers.INTERNAL)) {
+ return TypeManager.IsThisOrFriendAssembly (this_member.Assembly, base_member.Assembly);
+ }
+ if ((thisp & Modifiers.PROTECTED) != Modifiers.PROTECTED) {
//
// if it's not "protected internal", it must be "protected"
//
return false;
- } else if (Parent.TypeBuilder.Assembly == base_method.DeclaringType.Assembly) {
+ }
+ if (this_member.Parent.PartialContainer.Module.Assembly == base_member.Assembly) {
//
// protected within the same assembly - an error
//
return false;
- } else if ((thisp & ~(MethodAttributes.Family | MethodAttributes.FamORAssem)) !=
- (base_classp & ~(MethodAttributes.Family | MethodAttributes.FamORAssem))) {
+ }
+ if ((thisp & ~(Modifiers.PROTECTED | Modifiers.INTERNAL)) !=
+ (base_classp & ~(Modifiers.PROTECTED | Modifiers.INTERNAL))) {
//
// protected ok, but other attributes differ - report an error
//
return false;
}
return true;
- } else {
- return (thisp == base_classp);
}
+
+ return thisp == base_classp;
}
public override bool Define ()
}
if (IsExplicitImpl) {
- TypeExpr iface_texpr = MemberName.Left.GetTypeExpression ().ResolveAsTypeTerminal (this, false);
+ TypeExpr iface_texpr = MemberName.Left.GetTypeExpression ().ResolveAsTypeTerminal (Parent, false);
if (iface_texpr == null)
return false;
if (p.CheckAccessibility (this))
continue;
- Type t = parameters.Types [i];
+ TypeSpec t = parameters.Types [i];
Report.SymbolRelatedToPreviousError (t);
if (this is Indexer)
Report.Error (55, Location,
return IsExplicitImpl;
}
- protected void Error_CannotChangeAccessModifiers (Location loc, MemberInfo base_method, MethodAttributes ma, string suffix)
+ protected void Error_CannotChangeAccessModifiers (MemberCore member, MemberSpec base_member)
{
- Report.SymbolRelatedToPreviousError (base_method);
- string base_name = TypeManager.GetFullNameSignature (base_method);
- string this_name = GetSignatureForError ();
- if (suffix != null) {
- base_name += suffix;
- this_name += suffix;
- }
-
- Report.Error (507, loc, "`{0}': cannot change access modifiers when overriding `{1}' inherited member `{2}'",
- this_name, ModifiersExtensions.GetDescription (ma), base_name);
+ Report.SymbolRelatedToPreviousError (base_member);
+ Report.Error (507, member.Location,
+ "`{0}': cannot change access modifiers when overriding `{1}' inherited member `{2}'",
+ member.GetSignatureForError (),
+ ModifiersExtensions.AccessibilityName (base_member.Modifiers),
+ base_member.GetSignatureForError ());
}
- protected static string Error722 {
- get {
- return "`{0}': static types cannot be used as return types";
- }
+ protected void Error_StaticReturnType ()
+ {
+ Report.Error (722, Location,
+ "`{0}': static types cannot be used as return types",
+ MemberType.GetSignatureForError ());
}
/// <summary>
/// Gets base method and its return type
/// </summary>
- protected abstract MethodInfo FindOutBaseMethod (ref Type base_ret_type);
+ protected virtual MemberSpec FindBaseMember (out MemberSpec bestCandidate)
+ {
+ return MemberCache.FindBaseMember (this, out bestCandidate);
+ }
//
// The "short" name of this property / indexer / event. This is the
// name without the explicit interface.
//
- public string ShortName
- {
+ public string ShortName {
get { return MemberName.Name; }
set { SetMemberName (new MemberName (MemberName.Left, value, Location)); }
}
// Returns full metadata method name
//
public string GetFullName (MemberName name)
+ {
+ return GetFullName (name.Name);
+ }
+
+ public string GetFullName (string name)
{
if (!IsExplicitImpl)
- return name.Name;
+ return name;
//
// When dealing with explicit members a full interface type
// replacing predefined names which saves some space and name
// is still unique
//
- return TypeManager.CSharpName (InterfaceType) + "." + name.Name;
+ return TypeManager.CSharpName (InterfaceType) + "." + name;
}
protected override bool VerifyClsCompliance ()
{
if (!base.VerifyClsCompliance ()) {
- if (IsInterface && HasClsCompliantAttribute && Parent.IsClsComplianceRequired ()) {
- Report.Warning (3010, 1, Location, "`{0}': CLS-compliant interfaces must have only CLS-compliant members", GetSignatureForError ());
- }
-
- if ((ModFlags & Modifiers.ABSTRACT) != 0 && Parent.TypeBuilder.IsClass && IsExposedFromAssembly () && Parent.IsClsComplianceRequired ()) {
- Report.Warning (3011, 1, Location, "`{0}': only CLS-compliant members can be abstract", GetSignatureForError ());
- }
return false;
}
public abstract class MemberBase : MemberCore
{
- protected FullNamedExpression type_name;
- protected Type member_type;
+ protected FullNamedExpression type_expr;
+ protected TypeSpec member_type;
public readonly DeclSpace ds;
public readonly GenericMethod GenericMethod;
: base (parent, name, attrs)
{
this.ds = generic != null ? generic : (DeclSpace) parent;
- this.type_name = type;
+ this.type_expr = type;
ModFlags = ModifiersExtensions.Check (allowed_mod, mod, def_mod, Location, Report);
GenericMethod = generic;
if (GenericMethod != null)
return true;
}
- public Type MemberType {
+ public TypeSpec MemberType {
get { return member_type; }
}
if (member_type != null)
throw new InternalErrorException ("Multi-resolve");
- TypeExpr te = type_name.ResolveAsTypeTerminal (this, false);
+ TypeExpr te = type_expr.ResolveAsTypeTerminal (this, false);
if (te == null)
return false;
//
// Replace original type name, error reporting can use fully resolved name
//
- type_name = te;
+ type_expr = te;
member_type = te.Type;
return true;
/// </summary>
public class EmitContext : BuilderContext
{
+ // TODO: Has to be private
public ILGenerator ig;
/// <summary>
/// The value that is allowed to be returned or NULL if there is no
/// return type.
/// </summary>
- Type return_type;
+ TypeSpec return_type;
/// <summary>
/// Keeps track of the Type to LocalBuilder temporary storage created
/// to store structures (used to compute the address of the structure
/// value on structure method invocations)
/// </summary>
- Dictionary<Type, object> temporary_storage;
+ Dictionary<TypeSpec, object> temporary_storage;
/// <summary>
/// The location where we store the return value.
/// </summary>
public bool HasReturnLabel;
+ /// <summary>
+ /// Current loop begin and end labels.
+ /// </summary>
+ public Label LoopBegin, LoopEnd;
+
+ /// <summary>
+ /// Default target in a switch statement. Only valid if
+ /// InSwitch is true
+ /// </summary>
+ public Label DefaultTarget;
+
+ /// <summary>
+ /// If this is non-null, points to the current switch statement
+ /// </summary>
+ public Switch Switch;
+
/// <summary>
/// Whether we are inside an anonymous method.
/// </summary>
public readonly IMemberContext MemberContext;
- public EmitContext (IMemberContext rc, ILGenerator ig, Type return_type)
+ public EmitContext (IMemberContext rc, ILGenerator ig, TypeSpec return_type)
{
this.MemberContext = rc;
this.ig = ig;
this.return_type = return_type;
}
- public Type CurrentType {
+#region Properties
+
+ public TypeSpec CurrentType {
get { return MemberContext.CurrentType; }
}
get { return MemberContext.CurrentTypeParameters; }
}
- public TypeContainer CurrentTypeDefinition {
- get { return MemberContext.CurrentTypeDefinition; }
+ public MemberCore CurrentTypeDefinition {
+ get { return MemberContext.CurrentMemberDefinition; }
}
public bool IsStatic {
get { return MemberContext.IsStatic; }
}
+ bool IsAnonymousStoreyMutateRequired {
+ get {
+ return CurrentAnonymousMethod != null &&
+ CurrentAnonymousMethod.Storey != null &&
+ CurrentAnonymousMethod.Storey.Mutator != null;
+ }
+ }
+
// Has to be used for emitter errors only
public Report Report {
get { return MemberContext.Compiler.Report; }
}
- public Type ReturnType {
+ public TypeSpec ReturnType {
get {
return return_type;
}
}
+#endregion
/// <summary>
/// This is called immediately before emitting an IL opcode to tell the symbol
SymbolWriter.DefineLocalVariable (name, builder);
}
+ public void BeginCatchBlock (TypeSpec type)
+ {
+ ig.BeginCatchBlock (type.GetMetaInfo ());
+ }
+
+ public void BeginExceptionBlock ()
+ {
+ ig.BeginExceptionBlock ();
+ }
+
+ public void BeginFinallyBlock ()
+ {
+ ig.BeginFinallyBlock ();
+ }
+
public void BeginScope ()
{
ig.BeginScope();
SymbolWriter.OpenScope(ig);
}
+ public void EndExceptionBlock ()
+ {
+ ig.EndExceptionBlock ();
+ }
+
public void EndScope ()
{
ig.EndScope();
SymbolWriter.CloseScope(ig);
}
+ public LocalBuilder DeclareLocal (TypeSpec type, bool pinned)
+ {
+ if (IsAnonymousStoreyMutateRequired)
+ type = CurrentAnonymousMethod.Storey.Mutator.Mutate (type);
+
+ return ig.DeclareLocal (type.GetMetaInfo (), pinned);
+ }
+
+ public Label DefineLabel ()
+ {
+ return ig.DefineLabel ();
+ }
+
+ public void MarkLabel (Label label)
+ {
+ ig.MarkLabel (label);
+ }
+
+ public void Emit (OpCode opcode)
+ {
+ ig.Emit (opcode);
+ }
+
+ public void Emit (OpCode opcode, LocalBuilder local)
+ {
+ ig.Emit (opcode, local);
+ }
+
+ public void Emit (OpCode opcode, string arg)
+ {
+ ig.Emit (opcode, arg);
+ }
+
+ public void Emit (OpCode opcode, double arg)
+ {
+ ig.Emit (opcode, arg);
+ }
+
+ public void Emit (OpCode opcode, float arg)
+ {
+ ig.Emit (opcode, arg);
+ }
+
+ public void Emit (OpCode opcode, int arg)
+ {
+ ig.Emit (opcode, arg);
+ }
+
+ public void Emit (OpCode opcode, byte arg)
+ {
+ ig.Emit (opcode, arg);
+ }
+
+ public void Emit (OpCode opcode, Label label)
+ {
+ ig.Emit (opcode, label);
+ }
+
+ public void Emit (OpCode opcode, Label[] labels)
+ {
+ ig.Emit (opcode, labels);
+ }
+
+ public void Emit (OpCode opcode, TypeSpec type)
+ {
+ if (IsAnonymousStoreyMutateRequired)
+ type = CurrentAnonymousMethod.Storey.Mutator.Mutate (type);
+
+ ig.Emit (opcode, type.GetMetaInfo ());
+ }
+
+ public void Emit (OpCode opcode, FieldSpec field)
+ {
+ if (IsAnonymousStoreyMutateRequired)
+ field = field.Mutate (CurrentAnonymousMethod.Storey.Mutator);
+
+ ig.Emit (opcode, field.GetMetaInfo ());
+ }
+
+ public void Emit (OpCode opcode, MethodSpec method)
+ {
+ if (IsAnonymousStoreyMutateRequired)
+ method = method.Mutate (CurrentAnonymousMethod.Storey.Mutator);
+
+ if (method.IsConstructor)
+ ig.Emit (opcode, (ConstructorInfo) method.GetMetaInfo ());
+ else
+ ig.Emit (opcode, (MethodInfo) method.GetMetaInfo ());
+ }
+
+ // TODO: REMOVE breaks mutator
+ public void Emit (OpCode opcode, MethodInfo method)
+ {
+ ig.Emit (opcode, method);
+ }
+
+ // TODO: REMOVE breaks mutator
+ public void Emit (OpCode opcode, FieldBuilder field)
+ {
+ ig.Emit (opcode, field);
+ }
+
+ public void Emit (OpCode opcode, MethodSpec method, Type[] vargs)
+ {
+ // TODO MemberCache: This should mutate too
+ ig.EmitCall (opcode, (MethodInfo) method.GetMetaInfo (), vargs);
+ }
+
+ public void EmitArrayNew (ArrayContainer ac)
+ {
+ if (ac.Rank == 1) {
+ Emit (OpCodes.Newarr, ac.Element);
+ } else {
+ if (IsAnonymousStoreyMutateRequired)
+ ac = (ArrayContainer) ac.Mutate (CurrentAnonymousMethod.Storey.Mutator);
+
+ ig.Emit (OpCodes.Newobj, ac.GetConstructor ());
+ }
+ }
+
+ //
+ // Emits the right opcode to load from an array
+ //
+ public void EmitArrayLoad (ArrayContainer ac)
+ {
+ if (ac.Rank > 1) {
+ if (IsAnonymousStoreyMutateRequired)
+ ac = (ArrayContainer) ac.Mutate (CurrentAnonymousMethod.Storey.Mutator);
+
+ ig.Emit (OpCodes.Call, ac.GetGetMethod ());
+ return;
+ }
+
+ var type = ac.Element;
+ if (TypeManager.IsEnumType (type))
+ type = EnumSpec.GetUnderlyingType (type);
+
+ if (type == TypeManager.byte_type || type == TypeManager.bool_type)
+ Emit (OpCodes.Ldelem_U1);
+ else if (type == TypeManager.sbyte_type)
+ Emit (OpCodes.Ldelem_I1);
+ else if (type == TypeManager.short_type)
+ Emit (OpCodes.Ldelem_I2);
+ else if (type == TypeManager.ushort_type || type == TypeManager.char_type)
+ Emit (OpCodes.Ldelem_U2);
+ else if (type == TypeManager.int32_type)
+ Emit (OpCodes.Ldelem_I4);
+ else if (type == TypeManager.uint32_type)
+ Emit (OpCodes.Ldelem_U4);
+ else if (type == TypeManager.uint64_type)
+ Emit (OpCodes.Ldelem_I8);
+ else if (type == TypeManager.int64_type)
+ Emit (OpCodes.Ldelem_I8);
+ else if (type == TypeManager.float_type)
+ Emit (OpCodes.Ldelem_R4);
+ else if (type == TypeManager.double_type)
+ Emit (OpCodes.Ldelem_R8);
+ else if (type == TypeManager.intptr_type)
+ Emit (OpCodes.Ldelem_I);
+ else if (TypeManager.IsStruct (type)) {
+ Emit (OpCodes.Ldelema, type);
+ Emit (OpCodes.Ldobj, type);
+ } else if (type.IsGenericParameter) {
+ Emit (OpCodes.Ldelem, type);
+ } else if (type.IsPointer)
+ Emit (OpCodes.Ldelem_I);
+ else
+ Emit (OpCodes.Ldelem_Ref);
+ }
+
+ //
+ // Emits the right opcode to store to an array
+ //
+ public void EmitArrayStore (ArrayContainer ac)
+ {
+ if (ac.Rank > 1) {
+ if (IsAnonymousStoreyMutateRequired)
+ ac = (ArrayContainer) ac.Mutate (CurrentAnonymousMethod.Storey.Mutator);
+
+ ig.Emit (OpCodes.Call, ac.GetSetMethod ());
+ return;
+ }
+
+ var type = ac.Element;
+
+ if (type.IsEnum)
+ type = EnumSpec.GetUnderlyingType (type);
+
+ if (type == TypeManager.byte_type || type == TypeManager.sbyte_type || type == TypeManager.bool_type)
+ Emit (OpCodes.Stelem_I1);
+ else if (type == TypeManager.short_type || type == TypeManager.ushort_type || type == TypeManager.char_type)
+ Emit (OpCodes.Stelem_I2);
+ else if (type == TypeManager.int32_type || type == TypeManager.uint32_type)
+ Emit (OpCodes.Stelem_I4);
+ else if (type == TypeManager.int64_type || type == TypeManager.uint64_type)
+ Emit (OpCodes.Stelem_I8);
+ else if (type == TypeManager.float_type)
+ Emit (OpCodes.Stelem_R4);
+ else if (type == TypeManager.double_type)
+ Emit (OpCodes.Stelem_R8);
+ else if (type == TypeManager.intptr_type)
+ Emit (OpCodes.Stobj, type);
+ else if (TypeManager.IsStruct (type))
+ Emit (OpCodes.Stobj, type);
+ else if (type.IsGenericParameter)
+ Emit (OpCodes.Stelem, type);
+ else if (type.IsPointer)
+ Emit (OpCodes.Stelem_I);
+ else
+ Emit (OpCodes.Stelem_Ref);
+ }
+
+ public void EmitInt (int i)
+ {
+ switch (i) {
+ case -1:
+ ig.Emit (OpCodes.Ldc_I4_M1);
+ break;
+
+ case 0:
+ ig.Emit (OpCodes.Ldc_I4_0);
+ break;
+
+ case 1:
+ ig.Emit (OpCodes.Ldc_I4_1);
+ break;
+
+ case 2:
+ ig.Emit (OpCodes.Ldc_I4_2);
+ break;
+
+ case 3:
+ ig.Emit (OpCodes.Ldc_I4_3);
+ break;
+
+ case 4:
+ ig.Emit (OpCodes.Ldc_I4_4);
+ break;
+
+ case 5:
+ ig.Emit (OpCodes.Ldc_I4_5);
+ break;
+
+ case 6:
+ ig.Emit (OpCodes.Ldc_I4_6);
+ break;
+
+ case 7:
+ ig.Emit (OpCodes.Ldc_I4_7);
+ break;
+
+ case 8:
+ ig.Emit (OpCodes.Ldc_I4_8);
+ break;
+
+ default:
+ if (i >= -128 && i <= 127) {
+ ig.Emit (OpCodes.Ldc_I4_S, (sbyte) i);
+ } else
+ ig.Emit (OpCodes.Ldc_I4, i);
+ break;
+ }
+ }
+
+ public void EmitLong (long l)
+ {
+ if (l >= int.MinValue && l <= int.MaxValue) {
+ EmitInt (unchecked ((int) l));
+ ig.Emit (OpCodes.Conv_I8);
+ return;
+ }
+
+ if (l >= 0 && l <= uint.MaxValue) {
+ EmitInt (unchecked ((int) l));
+ ig.Emit (OpCodes.Conv_U8);
+ return;
+ }
+
+ ig.Emit (OpCodes.Ldc_I8, l);
+ }
+
+ //
+ // Load the object from the pointer.
+ //
+ public void EmitLoadFromPtr (TypeSpec 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 (t.IsEnum) {
+ if (t == TypeManager.enum_type)
+ ig.Emit (OpCodes.Ldind_Ref);
+ else
+ EmitLoadFromPtr (EnumSpec.GetUnderlyingType (t));
+ } else if (TypeManager.IsStruct (t) || TypeManager.IsGenericParameter (t))
+ 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 void EmitStoreFromPtr (TypeSpec type)
+ {
+ if (type.IsEnum)
+ type = EnumSpec.GetUnderlyingType (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.GetMetaInfo ());
+ else
+ ig.Emit (OpCodes.Stind_Ref);
+ }
+
/// <summary>
/// Returns a temporary storage for a variable of type t as
/// a local variable in the current body.
/// </summary>
- public LocalBuilder GetTemporaryLocal (Type t)
+ public LocalBuilder GetTemporaryLocal (TypeSpec t)
{
if (temporary_storage != null) {
object o;
if (o != null)
return (LocalBuilder) o;
}
- return ig.DeclareLocal (TypeManager.TypeToReflectionType (t));
+ return DeclareLocal (t, false);
}
- public void FreeTemporaryLocal (LocalBuilder b, Type t)
+ public void FreeTemporaryLocal (LocalBuilder b, TypeSpec t)
{
if (temporary_storage == null) {
- temporary_storage = new Dictionary<Type, object> (ReferenceEquality<Type>.Default);
+ temporary_storage = new Dictionary<TypeSpec, object> (ReferenceEquality<TypeSpec>.Default);
temporary_storage.Add (t, b);
return;
}
s.Push (b);
}
- /// <summary>
- /// Current loop begin and end labels.
- /// </summary>
- public Label LoopBegin, LoopEnd;
-
- /// <summary>
- /// Default target in a switch statement. Only valid if
- /// InSwitch is true
- /// </summary>
- public Label DefaultTarget;
-
- /// <summary>
- /// If this is non-null, points to the current switch statement
- /// </summary>
- public Switch Switch;
-
/// <summary>
/// ReturnValue creates on demand the LocalBuilder for the
/// return value from the function. By default this is not
public LocalBuilder TemporaryReturn ()
{
if (return_value == null){
- return_value = ig.DeclareLocal (return_type);
+ return_value = DeclareLocal (return_type, false);
if (!HasReturnLabel){
- ReturnLabel = ig.DefineLabel ();
+ ReturnLabel = DefineLabel ();
HasReturnLabel = true;
}
}
get { return RootContext.ToplevelTypes.Compiler; }
}
- public Type CurrentType {
+ public TypeSpec CurrentType {
get { return null; }
}
get { return null; }
}
- public TypeContainer CurrentTypeDefinition {
+ public MemberCore CurrentMemberDefinition {
get { return RootContext.ToplevelTypes; }
}
return "<module>";
}
+ public bool HasUnresolvedConstraints {
+ get { return false; }
+ }
+
public bool IsObsolete {
get { return false; }
}
get { return false; }
}
- public ExtensionMethodGroupExpr LookupExtensionMethod (Type extensionType, string name, Location loc)
+ public ExtensionMethodGroupExpr LookupExtensionMethod (TypeSpec extensionType, string name, int arity, Location loc)
{
throw new NotImplementedException ();
}
- public FullNamedExpression LookupNamespaceOrType (string name, Location loc, bool ignore_cs0104)
+ public FullNamedExpression LookupNamespaceOrType (string name, int arity, Location loc, bool ignore_cs0104)
{
- return RootContext.ToplevelTypes.LookupNamespaceOrType (name, loc, ignore_cs0104);
+ return RootContext.ToplevelTypes.LookupNamespaceOrType (name, arity, loc, ignore_cs0104);
}
public FullNamedExpression LookupNamespaceAlias (string name)
bool has_extension_method;
public AssemblyName Name;
MethodInfo add_type_forwarder;
- Dictionary<Type, Attribute> emitted_forwarders;
+ Dictionary<ITypeDefinition, Attribute> emitted_forwarders;
// Module is here just because of error messages
static string[] attribute_targets = new string [] { "assembly", "module" };
return true;
}
- public override void ApplyAttributeBuilder (Attribute a, ConstructorInfo ctor, byte[] cdata, PredefinedAttributes pa)
+ public override void ApplyAttributeBuilder (Attribute a, MethodSpec ctor, byte[] cdata, PredefinedAttributes pa)
{
if (a.IsValidSecurityAttribute ()) {
if (declarative_security == null)
return;
if (a.Type == pa.TypeForwarder) {
- Type t = a.GetArgumentType ();
+ TypeSpec t = a.GetArgumentType ();
if (t == null || TypeManager.HasElementType (t)) {
Report.Error (735, a.Location, "Invalid type specified as an argument for TypeForwardedTo attribute");
return;
}
- t = TypeManager.DropGenericTypeArguments (t);
if (emitted_forwarders == null) {
- emitted_forwarders = new Dictionary<Type, Attribute> ();
- } else if (emitted_forwarders.ContainsKey (t)) {
- Report.SymbolRelatedToPreviousError(emitted_forwarders[t].Location, null);
+ emitted_forwarders = new Dictionary<ITypeDefinition, Attribute> ();
+ } else if (emitted_forwarders.ContainsKey (t.MemberDefinition)) {
+ Report.SymbolRelatedToPreviousError(emitted_forwarders[t.MemberDefinition].Location, null);
Report.Error(739, a.Location, "A duplicate type forward of type `{0}'",
TypeManager.CSharpName(t));
return;
}
- emitted_forwarders.Add(t, a);
+ emitted_forwarders.Add(t.MemberDefinition, a);
- if (TypeManager.LookupDeclSpace (t) != null) {
+ if (t.Assembly == Builder) {
Report.SymbolRelatedToPreviousError (t);
Report.Error (729, a.Location, "Cannot forward type `{0}' because it is defined in this assembly",
TypeManager.CSharpName (t));
return;
}
- if (t.DeclaringType != null) {
+ if (t.IsNested) {
Report.Error (730, a.Location, "Cannot forward type `{0}' because it is a nested type",
TypeManager.CSharpName (t));
return;
}
}
- add_type_forwarder.Invoke (Builder, new object[] { t });
+ add_type_forwarder.Invoke (Builder, new object[] { t.GetMetaInfo () });
return;
}
return;
}
- Builder.SetCustomAttribute (ctor, cdata);
+ Builder.SetCustomAttribute ((ConstructorInfo) ctor.GetMetaInfo (), cdata);
}
public override void Emit (TypeContainer tc)
// FIXME: Does this belong inside SRE.AssemblyBuilder instead?
PredefinedAttribute pa = PredefinedAttributes.Get.RuntimeCompatibility;
if (pa.IsDefined && (OptAttributes == null || !OptAttributes.Contains (pa))) {
- ConstructorInfo ci = TypeManager.GetPredefinedConstructor (
- pa.Type, Location.Null, Type.EmptyTypes);
+ var ci = TypeManager.GetPredefinedConstructor (pa.Type, Location.Null, TypeSpec.EmptyTypes);
PropertyInfo [] pis = new PropertyInfo [1];
pis [0] = TypeManager.GetPredefinedProperty (pa.Type,
"WrapNonExceptionThrows", Location.Null, TypeManager.bool_type).MetaInfo;
object [] pargs = new object [1];
pargs [0] = true;
- Builder.SetCustomAttribute (new CustomAttributeBuilder (ci, new object [0], pis, pargs));
+ Builder.SetCustomAttribute (new CustomAttributeBuilder ((ConstructorInfo) ci.GetMetaInfo (), new object[0], pis, pargs));
}
if (declarative_security != null) {
try {
// Microsoft runtime hacking
if (add_permission == null) {
- Type assembly_builder = typeof (AssemblyBuilder).Assembly.GetType ("System.Reflection.Emit.AssemblyBuilderData");
+ var assembly_builder = typeof (AssemblyBuilder).Assembly.GetType ("System.Reflection.Emit.AssemblyBuilderData");
add_permission = assembly_builder.GetMethod ("AddPermissionRequests", BindingFlags.Instance | BindingFlags.NonPublic);
FieldInfo fi = typeof (AssemblyBuilder).GetField ("m_assemblyData", BindingFlags.Instance | BindingFlags.NonPublic | BindingFlags.GetField);
using System.Reflection.Emit;
using System.Text;
using Mono.CSharp.Linq;
+using System.Linq;
namespace Mono.CSharp {
// A common base class for Completing expressions, it
// is just a very simple ExpressionStatement
//
- public abstract class CompletingExpression : ExpressionStatement {
+ public abstract class CompletingExpression : ExpressionStatement
+ {
+ public static void AppendResults (List<string> results, string prefix, IEnumerable<string> names)
+ {
+ foreach (string name in names) {
+ if (name == null || prefix == null)
+ continue;
+
+ if (!name.StartsWith (prefix))
+ continue;
+
+ if (results.Contains (name))
+ continue;
+
+ if (prefix != null)
+ results.Add (name.Substring (prefix.Length));
+ else
+ results.Add (name);
+ }
+ }
+
public override void EmitStatement (EmitContext ec)
{
// Do nothing
this.loc = l;
this.Prefix = prefix;
}
-
- public static void AppendResults (List<string> results, string prefix, IEnumerable<string> names)
- {
- foreach (string name in names){
- if (name == null || prefix == null)
- continue;
-
- if (!name.StartsWith (prefix))
- continue;
-
- if (results.Contains (name))
- continue;
-
- if (prefix != null)
- results.Add (name.Substring (prefix.Length));
- else
- results.Add (name);
- }
-
- }
protected override Expression DoResolve (ResolveContext ec)
{
var results = new List<string> ();
AppendResults (results, Prefix, Evaluator.GetVarNames ());
- AppendResults (results, Prefix, ec.CurrentTypeDefinition.NamespaceEntry.CompletionGetTypesStartingWith (Prefix));
+ AppendResults (results, Prefix, ec.CurrentMemberDefinition.Parent.NamespaceEntry.CompletionGetTypesStartingWith (Prefix));
AppendResults (results, Prefix, Evaluator.GetUsingList ());
throw new CompletionResult (Prefix, results.ToArray ());
Expression expr;
string partial_name;
TypeArguments targs;
-
- internal static MemberFilter CollectingFilter = new MemberFilter (Match);
-
- static bool Match (MemberInfo m, object filter_criteria)
- {
- if (m is FieldInfo){
- if (((FieldInfo) m).IsSpecialName)
- return false;
-
- }
- if (m is MethodInfo){
- if (((MethodInfo) m).IsSpecialName)
- return false;
- }
-
- if (filter_criteria == null)
- return true;
-
- string n = (string) filter_criteria;
- if (m.Name.StartsWith (n))
- return true;
-
- return false;
- }
public CompletionMemberAccess (Expression e, string partial_name, Location l)
{
if (expr_resolved == null)
return null;
- Type expr_type = expr_resolved.Type;
+ TypeSpec expr_type = expr_resolved.Type;
if (expr_type.IsPointer || expr_type == TypeManager.void_type || expr_type == TypeManager.null_type || expr_type == InternalType.AnonymousMethod) {
Unary.Error_OperatorCannotBeApplied (ec, loc, ".", expr_type);
return null;
CompletionSimpleName.AppendResults (
results,
partial_name,
- ec.CurrentTypeDefinition.NamespaceEntry.CompletionGetTypesStartingWith (namespaced_partial));
+ ec.CurrentMemberDefinition.Parent.NamespaceEntry.CompletionGetTypesStartingWith (namespaced_partial));
} else {
- MemberInfo [] result = expr_type.FindMembers (
- MemberTypes.All, BindingFlags.Instance | BindingFlags.Static | BindingFlags.Public,
- CollectingFilter, partial_name);
-
- foreach (MemberInfo r in result){
- string name;
-
- MethodBase rasb = r as MethodBase;
- if (rasb != null && rasb.IsSpecialName)
- continue;
-
- if (partial_name == null)
- name = r.Name;
- else
- name = r.Name.Substring (partial_name.Length);
-
- if (results.Contains (name))
- continue;
- results.Add (name);
- }
+ var r = MemberCache.GetCompletitionMembers (expr_type, partial_name).Select (l => l.Name);
+ AppendResults (results, partial_name, r);
}
throw new CompletionResult (partial_name == null ? "" : partial_name, results.ToArray ());
protected override Expression DoResolve (ResolveContext ec)
{
- MemberList members = TypeManager.FindMembers (
- ec.CurrentInitializerVariable.Type,
- MemberTypes.Field | MemberTypes.Property,
- BindingFlags.Instance | BindingFlags.Static | BindingFlags.Public,
- CompletionMemberAccess.CollectingFilter, partial_name);
+ var members = MemberCache.GetCompletitionMembers (ec.CurrentInitializerVariable.Type, partial_name);
- string [] result = new string [members.Count];
- int i = 0;
- foreach (MemberInfo mi in members){
- string name;
-
- if (partial_name == null)
- name = mi.Name;
- else
- name = mi.Name.Substring (partial_name.Length);
-
- result [i++] = name;
+// TODO: Does this mean exact match only ?
+// if (partial_name != null && results.Count > 0 && result [0] == "")
+// throw new CompletionResult ("", new string [] { "=" });
+
+ var results = members.Where (l => (l.Kind & (MemberKind.Field | MemberKind.Property)) != 0).Select (l => l.Name).ToList ();
+ if (partial_name != null) {
+ var temp = new List<string> ();
+ AppendResults (temp, partial_name, results);
+ results = temp;
}
- if (partial_name != null && i > 0 && result [0] == "")
- throw new CompletionResult ("", new string [] { "=" });
-
- throw new CompletionResult (partial_name == null ? "" : partial_name, result);
+ throw new CompletionResult (partial_name == null ? "" : partial_name, results.ToArray ());
}
protected override void CloneTo (CloneContext clonectx, Expression t)
public class Const : FieldBase
{
- bool define_called;
+ Constant value;
public const Modifiers AllowedModifiers =
Modifiers.NEW |
ModFlags |= Modifiers.STATIC;
}
- protected override bool CheckBase ()
- {
- // Constant.Define can be called when the parent type hasn't yet been populated
- // and it's base types need not have been populated. So, we defer this check
- // to the second time Define () is called on this member.
- if (Parent.PartialContainer.BaseCache == null)
- return true;
- return base.CheckBase ();
- }
-
/// <summary>
/// Defines the constant in the @parent
/// </summary>
public override bool Define ()
{
- // Because constant define can be called from other class
- if (define_called) {
- CheckBase ();
- return FieldBuilder != null;
- }
-
- define_called = true;
-
if (!base.Define ())
return false;
- Type ttype = MemberType;
- if (!IsConstantTypeValid (ttype)) {
+ TypeSpec ttype = MemberType;
+ if (!ttype.IsConstantCompatible) {
Error_InvalidConstantType (ttype, Location, Report);
}
field_attr |= FieldAttributes.Literal;
}
- FieldBuilder = Parent.TypeBuilder.DefineField (Name, MemberType, field_attr);
- spec = new ConstSpec (this, FieldBuilder, ModFlags, initializer);
+ FieldBuilder = Parent.TypeBuilder.DefineField (Name, MemberType.GetMetaInfo (), field_attr);
+ spec = new ConstSpec (Parent.Definition, this, MemberType, FieldBuilder, ModFlags, initializer);
- TypeManager.RegisterConstant (FieldBuilder, (ConstSpec) spec);
- Parent.MemberCache.AddMember (FieldBuilder, spec);
+ Parent.MemberCache.AddMember (spec);
if ((field_attr & FieldAttributes.InitOnly) != 0)
Parent.PartialContainer.RegisterFieldForInitialization (this,
return true;
}
- public static bool IsConstantTypeValid (Type t)
+ public Constant DefineValue ()
{
- if (TypeManager.IsBuiltinOrEnum (t))
- return true;
-
- if (TypeManager.IsGenericParameter (t) || t.IsPointer)
- return false;
+ if (value == null)
+ value = initializer.Resolve (new ResolveContext (this)) as Constant;
- return TypeManager.IsReferenceType (t);
+ return value;
}
/// <summary>
/// </summary>
public override void Emit ()
{
- var value = initializer.Resolve (new ResolveContext (this)) as Constant;
- if (value == null || FieldBuilder == null)
- return;
-
if (value.Type == TypeManager.decimal_type) {
FieldBuilder.SetCustomAttribute (CreateDecimalConstantAttribute (value));
} else{
return new CustomAttributeBuilder (pa.Constructor, args);
}
- public static void Error_InvalidConstantType (Type t, Location loc, Report Report)
+ public static void Error_InvalidConstantType (TypeSpec t, Location loc, Report Report)
{
- if (TypeManager.IsGenericParameter (t)) {
+ if (t.IsGenericParameter) {
Report.Error (1959, loc,
"Type parameter `{0}' cannot be declared const", TypeManager.CSharpName (t));
} else {
{
Expression value;
- public ConstSpec (IMemberDefinition definition, FieldInfo fi, Modifiers mod, Expression value)
- : base (definition, fi, mod)
+ public ConstSpec (TypeSpec declaringType, IMemberDefinition definition, TypeSpec memberType, FieldInfo fi, Modifiers mod, Expression value)
+ : base (declaringType, definition, memberType, fi, mod)
{
this.value = value;
}
get {
return value;
}
- set {
+ private set {
this.value = value;
}
}
expr = expr.Resolve (rc);
}
-
return expr;
}
}
return GetValue ();
}
- 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)
{
if (!expl && IsLiteral &&
(TypeManager.IsPrimitiveType (target) || type == TypeManager.decimal_type) &&
}
}
- public Constant ImplicitConversionRequired (ResolveContext ec, Type type, Location loc)
+ public Constant ImplicitConversionRequired (ResolveContext ec, TypeSpec type, Location loc)
{
Constant c = ConvertImplicitly (ec, type);
if (c == null)
return c;
}
- public virtual Constant ConvertImplicitly (ResolveContext rc, Type type)
+ public virtual Constant ConvertImplicitly (ResolveContext rc, TypeSpec type)
{
if (this.type == type)
return this;
//
// Returns a constant instance based on Type
//
- public static Constant CreateConstant (ResolveContext rc, Type t, object v, Location loc)
+ public static Constant CreateConstant (ResolveContext rc, TypeSpec t, object v, Location loc)
{
return CreateConstantFromValue (t, v, loc).Resolve (rc);
}
- public static Constant CreateConstantFromValue (Type t, object v, Location loc)
+ public static Constant CreateConstantFromValue (TypeSpec t, object v, Location loc)
{
if (t == TypeManager.int32_type)
return new IntConstant ((int) v, loc);
if (t == TypeManager.decimal_type)
return new DecimalConstant ((decimal) v, loc);
if (TypeManager.IsEnumType (t)) {
- Type real_type = TypeManager.GetEnumUnderlyingType (t);
+ var real_type = EnumSpec.GetUnderlyingType (t);
return new EnumConstant (CreateConstantFromValue (real_type, v, loc).Resolve (null), t);
}
if (v == null) {
/// It throws OverflowException
/// </summary>
// DON'T CALL THIS METHOD DIRECTLY AS IT DOES NOT HANDLE ENUMS
- public abstract Constant ConvertExplicitly (bool in_checked_context, Type target_type);
+ public abstract Constant ConvertExplicitly (bool in_checked_context, TypeSpec target_type);
/// <summary>
/// Attempts to do a compile-time folding of a constant cast.
/// </summary>
- public Constant TryReduce (ResolveContext ec, Type target_type, Location loc)
+ public Constant TryReduce (ResolveContext ec, TypeSpec target_type, Location loc)
{
try {
return TryReduce (ec, target_type);
}
}
- Constant TryReduce (ResolveContext ec, Type target_type)
+ Constant TryReduce (ResolveContext ec, TypeSpec target_type)
{
if (Type == target_type)
return this;
Constant c;
if (TypeManager.IsEnumType (target_type)) {
- c = TryReduce (ec, TypeManager.GetEnumUnderlyingType (target_type));
+ c = TryReduce (ec, EnumSpec.GetUnderlyingType (target_type));
if (c == null)
return null;
/// Need to pass type as the constant can require a boxing
/// and in such case no optimization is possible
/// </summary>
- public bool IsDefaultInitializer (Type type)
+ public bool IsDefaultInitializer (TypeSpec type)
{
if (type == Type)
return IsDefaultValue;
public override System.Linq.Expressions.Expression MakeExpression (BuilderContext ctx)
{
- return System.Linq.Expressions.Expression.Constant (GetTypedValue (), type);
- }
-
- public override void MutateHoistedGenericType (AnonymousMethodStorey storey)
- {
- // A constant cannot be of generic type
+ return System.Linq.Expressions.Expression.Constant (GetTypedValue (), type.GetMetaInfo ());
}
public new Constant Resolve (ResolveContext rc)
{
}
- 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)
{
try {
ConvertExplicitly (true, target);
return (object) Value;
}
- public override void EncodeAttributeValue (IMemberContext rc, AttributeEncoder enc, Type targetType)
+ public override void EncodeAttributeValue (IMemberContext rc, AttributeEncoder enc, TypeSpec targetType)
{
enc.Stream.Write (Value);
}
public override void Emit (EmitContext ec)
{
if (Value)
- ec.ig.Emit (OpCodes.Ldc_I4_1);
+ ec.Emit (OpCodes.Ldc_I4_1);
else
- ec.ig.Emit (OpCodes.Ldc_I4_0);
+ ec.Emit (OpCodes.Ldc_I4_0);
}
public override bool IsDefaultValue {
get { return Value == false; }
}
- public override Constant ConvertExplicitly (bool in_checked_context, Type target_type)
+ public override Constant ConvertExplicitly (bool in_checked_context, TypeSpec target_type)
{
return null;
}
Value = v;
}
- public override void EncodeAttributeValue (IMemberContext rc, AttributeEncoder enc, Type targetType)
+ public override void EncodeAttributeValue (IMemberContext rc, AttributeEncoder enc, TypeSpec targetType)
{
enc.Stream.Write (Value);
}
public override void Emit (EmitContext ec)
{
- IntLiteral.EmitInt (ec.ig, Value);
+ ec.EmitInt (Value);
}
public override string AsString ()
get { return Value == 0; }
}
- public override Constant ConvertExplicitly (bool in_checked_context, Type target_type)
+ public override Constant ConvertExplicitly (bool in_checked_context, TypeSpec target_type)
{
if (target_type == TypeManager.sbyte_type) {
if (in_checked_context){
return this;
}
- public override void EncodeAttributeValue (IMemberContext rc, AttributeEncoder enc, Type targetType)
+ public override void EncodeAttributeValue (IMemberContext rc, AttributeEncoder enc, TypeSpec targetType)
{
enc.Stream.Write ((ushort) Value);
}
public override void Emit (EmitContext ec)
{
- IntLiteral.EmitInt (ec.ig, Value);
+ ec.EmitInt (Value);
}
static string descape (char c)
get { return Value == '\0'; }
}
- public override Constant ConvertExplicitly (bool in_checked_context, Type target_type)
+ public override Constant ConvertExplicitly (bool in_checked_context, TypeSpec target_type)
{
if (target_type == TypeManager.byte_type) {
if (in_checked_context){
return this;
}
- public override void EncodeAttributeValue (IMemberContext rc, AttributeEncoder enc, Type targetType)
+ public override void EncodeAttributeValue (IMemberContext rc, AttributeEncoder enc, TypeSpec targetType)
{
enc.Stream.Write (Value);
}
public override void Emit (EmitContext ec)
{
- IntLiteral.EmitInt (ec.ig, Value);
+ ec.EmitInt (Value);
}
public override string AsString ()
get { return Value == 0; }
}
- public override Constant ConvertExplicitly (bool in_checked_context, Type target_type)
+ public override Constant ConvertExplicitly (bool in_checked_context, TypeSpec target_type)
{
if (target_type == TypeManager.byte_type) {
if (in_checked_context && Value < 0)
return this;
}
- public override void EncodeAttributeValue (IMemberContext rc, AttributeEncoder enc, Type targetType)
+ public override void EncodeAttributeValue (IMemberContext rc, AttributeEncoder enc, TypeSpec targetType)
{
enc.Stream.Write (Value);
}
public override void Emit (EmitContext ec)
{
- IntLiteral.EmitInt (ec.ig, Value);
+ ec.EmitInt (Value);
}
public override string AsString ()
}
}
- public override Constant ConvertExplicitly (bool in_checked_context, Type target_type)
+ public override Constant ConvertExplicitly (bool in_checked_context, TypeSpec target_type)
{
if (target_type == TypeManager.byte_type) {
if (in_checked_context){
return this;
}
- public override void EncodeAttributeValue (IMemberContext rc, AttributeEncoder enc, Type targetType)
+ public override void EncodeAttributeValue (IMemberContext rc, AttributeEncoder enc, TypeSpec targetType)
{
enc.Stream.Write (Value);
}
public override void Emit (EmitContext ec)
{
- IntLiteral.EmitInt (ec.ig, Value);
+ ec.EmitInt (Value);
}
public override string AsString ()
get { return Value == 0; }
}
- public override Constant ConvertExplicitly (bool in_checked_context, Type target_type)
+ public override Constant ConvertExplicitly (bool in_checked_context, TypeSpec target_type)
{
if (target_type == TypeManager.byte_type) {
if (in_checked_context){
return this;
}
- static public void EmitInt (ILGenerator ig, int i)
- {
- switch (i){
- case -1:
- ig.Emit (OpCodes.Ldc_I4_M1);
- break;
-
- case 0:
- ig.Emit (OpCodes.Ldc_I4_0);
- break;
-
- case 1:
- ig.Emit (OpCodes.Ldc_I4_1);
- break;
-
- case 2:
- ig.Emit (OpCodes.Ldc_I4_2);
- break;
-
- case 3:
- ig.Emit (OpCodes.Ldc_I4_3);
- break;
-
- case 4:
- ig.Emit (OpCodes.Ldc_I4_4);
- break;
-
- case 5:
- ig.Emit (OpCodes.Ldc_I4_5);
- break;
-
- case 6:
- ig.Emit (OpCodes.Ldc_I4_6);
- break;
-
- case 7:
- ig.Emit (OpCodes.Ldc_I4_7);
- break;
-
- case 8:
- ig.Emit (OpCodes.Ldc_I4_8);
- break;
-
- default:
- if (i >= -128 && i <= 127){
- ig.Emit (OpCodes.Ldc_I4_S, (sbyte) i);
- } else
- ig.Emit (OpCodes.Ldc_I4, i);
- break;
- }
- }
-
- public override void EncodeAttributeValue (IMemberContext rc, AttributeEncoder enc, Type targetType)
+ public override void EncodeAttributeValue (IMemberContext rc, AttributeEncoder enc, TypeSpec targetType)
{
enc.Stream.Write (Value);
}
public override void Emit (EmitContext ec)
{
- EmitInt (ec.ig, Value);
+ ec.EmitInt (Value);
}
public override string AsString ()
get { return Value == 0; }
}
- public override Constant ConvertExplicitly (bool in_checked_context, Type target_type)
+ public override Constant ConvertExplicitly (bool in_checked_context, TypeSpec target_type)
{
if (target_type == TypeManager.byte_type) {
if (in_checked_context){
return null;
}
- public override Constant ConvertImplicitly (ResolveContext rc, Type type)
+ public override Constant ConvertImplicitly (ResolveContext rc, TypeSpec type)
{
if (this.type == type)
return this;
/// into a different data type using casts (See Implicit Constant
/// Expression Conversions)
/// </summary>
- Constant TryImplicitIntConversion (Type target_type)
+ Constant TryImplicitIntConversion (TypeSpec target_type)
{
if (target_type == TypeManager.sbyte_type) {
if (Value >= SByte.MinValue && Value <= SByte.MaxValue)
return this;
}
- public override void EncodeAttributeValue (IMemberContext rc, AttributeEncoder enc, Type targetType)
+ public override void EncodeAttributeValue (IMemberContext rc, AttributeEncoder enc, TypeSpec targetType)
{
enc.Stream.Write (Value);
}
public override void Emit (EmitContext ec)
{
- IntLiteral.EmitInt (ec.ig, unchecked ((int) Value));
+ ec.EmitInt (unchecked ((int) Value));
}
public override string AsString ()
get { return Value == 0; }
}
- public override Constant ConvertExplicitly (bool in_checked_context, Type target_type)
+ public override Constant ConvertExplicitly (bool in_checked_context, TypeSpec target_type)
{
if (target_type == TypeManager.byte_type) {
if (in_checked_context){
return this;
}
- public override void EncodeAttributeValue (IMemberContext rc, AttributeEncoder enc, Type targetType)
+ public override void EncodeAttributeValue (IMemberContext rc, AttributeEncoder enc, TypeSpec targetType)
{
enc.Stream.Write (Value);
}
public override void Emit (EmitContext ec)
{
- EmitLong (ec.ig, Value);
- }
-
- static public void EmitLong (ILGenerator ig, long l)
- {
- if (l >= int.MinValue && l <= int.MaxValue) {
- IntLiteral.EmitInt (ig, unchecked ((int) l));
- ig.Emit (OpCodes.Conv_I8);
- return;
- }
-
- if (l >= 0 && l <= uint.MaxValue) {
- IntLiteral.EmitInt (ig, unchecked ((int) l));
- ig.Emit (OpCodes.Conv_U8);
- return;
- }
-
- ig.Emit (OpCodes.Ldc_I8, l);
+ ec.EmitLong (Value);
}
public override string AsString ()
get { return Value == 0; }
}
- public override Constant ConvertExplicitly (bool in_checked_context, Type target_type)
+ public override Constant ConvertExplicitly (bool in_checked_context, TypeSpec target_type)
{
if (target_type == TypeManager.byte_type) {
if (in_checked_context){
return null;
}
- public override Constant ConvertImplicitly (ResolveContext rc, Type type)
+ public override Constant ConvertImplicitly (ResolveContext rc, TypeSpec type)
{
if (Value >= 0 && type == TypeManager.uint64_type) {
return new ULongConstant ((ulong) Value, loc).Resolve (rc);
return this;
}
- public override void EncodeAttributeValue (IMemberContext rc, AttributeEncoder enc, Type targetType)
+ public override void EncodeAttributeValue (IMemberContext rc, AttributeEncoder enc, TypeSpec targetType)
{
enc.Stream.Write (Value);
}
public override void Emit (EmitContext ec)
{
- ILGenerator ig = ec.ig;
-
- LongLiteral.EmitLong (ig, unchecked ((long) Value));
+ ec.EmitLong (unchecked ((long) Value));
}
public override string AsString ()
get { return Value == 0; }
}
- public override Constant ConvertExplicitly (bool in_checked_context, Type target_type)
+ public override Constant ConvertExplicitly (bool in_checked_context, TypeSpec target_type)
{
if (target_type == TypeManager.byte_type) {
if (in_checked_context && Value > Byte.MaxValue)
return this;
}
- public override void EncodeAttributeValue (IMemberContext rc, AttributeEncoder enc, Type targetType)
+ public override void EncodeAttributeValue (IMemberContext rc, AttributeEncoder enc, TypeSpec targetType)
{
enc.Stream.Write (Value);
}
public override void Emit (EmitContext ec)
{
- ec.ig.Emit (OpCodes.Ldc_R4, Value);
+ ec.Emit (OpCodes.Ldc_R4, Value);
}
public override string AsString ()
}
}
- public override Constant ConvertExplicitly (bool in_checked_context, Type target_type)
+ public override Constant ConvertExplicitly (bool in_checked_context, TypeSpec target_type)
{
if (target_type == TypeManager.byte_type) {
if (in_checked_context){
return this;
}
- public override void EncodeAttributeValue (IMemberContext rc, AttributeEncoder enc, Type targetType)
+ public override void EncodeAttributeValue (IMemberContext rc, AttributeEncoder enc, TypeSpec targetType)
{
enc.Stream.Write (Value);
}
public override void Emit (EmitContext ec)
{
- ec.ig.Emit (OpCodes.Ldc_R8, Value);
+ ec.Emit (OpCodes.Ldc_R8, Value);
}
public override string AsString ()
}
}
- public override Constant ConvertExplicitly (bool in_checked_context, Type target_type)
+ public override Constant ConvertExplicitly (bool in_checked_context, TypeSpec target_type)
{
if (target_type == TypeManager.byte_type) {
if (in_checked_context){
public override void Emit (EmitContext ec)
{
- ILGenerator ig = ec.ig;
-
int [] words = decimal.GetBits (Value);
int power = (words [3] >> 16) & 0xff;
return;
}
- IntConstant.EmitInt (ig, (int) Value);
- ig.Emit (OpCodes.Newobj, TypeManager.void_decimal_ctor_int_arg);
+ ec.EmitInt ((int) Value);
+ ec.Emit (OpCodes.Newobj, TypeManager.void_decimal_ctor_int_arg);
return;
}
return;
}
- LongConstant.EmitLong (ig, (long) Value);
- ig.Emit (OpCodes.Newobj, TypeManager.void_decimal_ctor_long_arg);
+ ec.EmitLong ((long) Value);
+ ec.Emit (OpCodes.Newobj, TypeManager.void_decimal_ctor_long_arg);
return;
}
}
- IntConstant.EmitInt (ig, words [0]);
- IntConstant.EmitInt (ig, words [1]);
- IntConstant.EmitInt (ig, words [2]);
+ ec.EmitInt (words [0]);
+ ec.EmitInt (words [1]);
+ ec.EmitInt (words [2]);
// sign
- IntConstant.EmitInt (ig, words [3] >> 31);
+ ec.EmitInt (words [3] >> 31);
// power
- IntConstant.EmitInt (ig, power);
+ ec.EmitInt (power);
if (TypeManager.void_decimal_ctor_five_args == null) {
TypeManager.void_decimal_ctor_five_args = TypeManager.GetPredefinedConstructor (
return;
}
- ig.Emit (OpCodes.Newobj, TypeManager.void_decimal_ctor_five_args);
+ ec.Emit (OpCodes.Newobj, TypeManager.void_decimal_ctor_five_args);
}
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 (target_type == TypeManager.sbyte_type)
return new SByteConstant ((sbyte)Value, loc);
public override void Emit (EmitContext ec)
{
if (Value == null) {
- ec.ig.Emit (OpCodes.Ldnull);
+ ec.Emit (OpCodes.Ldnull);
return;
}
//
if (Value.Length == 0 && RootContext.Optimize && !TypeManager.IsEqual (ec.CurrentType, TypeManager.string_type)) {
if (TypeManager.string_empty == null)
- TypeManager.string_empty = TypeManager.GetPredefinedField (TypeManager.string_type, "Empty", loc);
+ TypeManager.string_empty = TypeManager.GetPredefinedField (TypeManager.string_type, "Empty", loc, TypeManager.string_type);
if (TypeManager.string_empty != null) {
- ec.ig.Emit (OpCodes.Ldsfld, TypeManager.string_empty);
+ ec.Emit (OpCodes.Ldsfld, TypeManager.string_empty);
return;
}
}
- ec.ig.Emit (OpCodes.Ldstr, Value);
+ ec.Emit (OpCodes.Ldstr, Value);
}
- public override void EncodeAttributeValue (IMemberContext rc, AttributeEncoder enc, Type targetType)
+ public override void EncodeAttributeValue (IMemberContext rc, AttributeEncoder enc, TypeSpec targetType)
{
// cast to object
if (type != targetType)
}
}
- public override Constant ConvertExplicitly (bool in_checked_context, Type target_type)
+ public override Constant ConvertExplicitly (bool in_checked_context, TypeSpec target_type)
{
return null;
}
//
public class NullConstant : Constant
{
- public NullConstant (Type type, Location loc)
+ public NullConstant (TypeSpec type, Location loc)
: base (loc)
{
eclass = ExprClass.Value;
return this;
}
- public override void EncodeAttributeValue (IMemberContext rc, AttributeEncoder enc, Type targetType)
+ public override void EncodeAttributeValue (IMemberContext rc, AttributeEncoder enc, TypeSpec targetType)
{
// Type it as string cast
if (targetType == TypeManager.object_type || targetType == TypeManager.null_type)
enc.Encode (TypeManager.string_type);
- if (targetType.IsArray) {
- if (targetType.GetArrayRank () != 1)
+ var ac = targetType as ArrayContainer;
+ if (ac != null) {
+ if (ac.Rank != 1)
base.EncodeAttributeValue (rc, enc, targetType);
else
enc.Stream.Write (uint.MaxValue);
public override void Emit (EmitContext ec)
{
- ec.ig.Emit (OpCodes.Ldnull);
+ ec.Emit (OpCodes.Ldnull);
// Only to make verifier happy
if (TypeManager.IsGenericParameter (type))
- ec.ig.Emit (OpCodes.Unbox_Any, type);
+ ec.Emit (OpCodes.Unbox_Any, type);
}
public override string ExprClassName {
return "null";
}
- public override Constant ConvertExplicitly (bool inCheckedContext, Type targetType)
+ public override Constant ConvertExplicitly (bool inCheckedContext, TypeSpec targetType)
{
if (targetType.IsPointer) {
if (IsLiteral || this is NullPointer)
return null;
}
- public override Constant ConvertImplicitly (ResolveContext rc, Type targetType)
+ public override Constant ConvertImplicitly (ResolveContext rc, TypeSpec targetType)
{
return ConvertExplicitly (false, targetType);
}
public override bool IsZeroInteger {
get { return true; }
}
-
- public override void MutateHoistedGenericType (AnonymousMethodStorey storey)
- {
- type = storey.MutateType (type);
- }
}
/// <summary>
get { return value.IsZeroInteger; }
}
- public override Constant ConvertExplicitly (bool in_checked_context, Type target_type)
+ public override Constant ConvertExplicitly (bool in_checked_context, TypeSpec target_type)
{
Constant new_value = value.ConvertExplicitly (in_checked_context, target_type);
return new_value == null ? null : new SideEffectConstant (new_value, side_effect, new_value.Location);
//
// A scope type context, it can be inflated for generic types
//
- Type CurrentType { get; }
+ TypeSpec CurrentType { get; }
//
// A scope type parameters either VAR or MVAR
TypeParameter[] CurrentTypeParameters { get; }
//
- // A type definition of the type context. For partial types definition use
+ // A member definition of the context. For partial types definition use
// CurrentTypeDefinition.PartialContainer otherwise the context is local
//
- // TODO: CurrentType.Definition
- //
- TypeContainer CurrentTypeDefinition { get; }
+ MemberCore CurrentMemberDefinition { get; }
bool IsObsolete { get; }
bool IsUnsafe { get; }
bool IsStatic { get; }
+ bool HasUnresolvedConstraints { get; }
string GetSignatureForError ();
- ExtensionMethodGroupExpr LookupExtensionMethod (Type extensionType, string name, Location loc);
- FullNamedExpression LookupNamespaceOrType (string name, Location loc, bool ignore_cs0104);
+ ExtensionMethodGroupExpr LookupExtensionMethod (TypeSpec extensionType, string name, int arity, Location loc);
+ FullNamedExpression LookupNamespaceOrType (string name, int arity, Location loc, bool ignore_cs0104);
FullNamedExpression LookupNamespaceAlias (string name);
CompilerContext Compiler { get; }
public TypeInferenceContext ReturnTypeInference;
- Type return_type;
+ TypeSpec return_type;
/// <summary>
/// The location where return has to jump to return the
/// </summary>
public bool HasReturnLabel;
- public BlockContext (IMemberContext mc, ExplicitBlock block, Type returnType)
+ public BlockContext (IMemberContext mc, ExplicitBlock block, TypeSpec returnType)
: base (mc)
{
if (returnType == null)
HasReturnLabel = true;
}
- public Type ReturnType {
+ public TypeSpec ReturnType {
get { return return_type; }
}
}
get { return CurrentAnonymousMethod as Iterator; }
}
- public Type CurrentType {
+ public TypeSpec CurrentType {
get { return MemberContext.CurrentType; }
}
get { return MemberContext.CurrentTypeParameters; }
}
- public TypeContainer CurrentTypeDefinition {
- get { return MemberContext.CurrentTypeDefinition; }
+ public MemberCore CurrentMemberDefinition {
+ get { return MemberContext.CurrentMemberDefinition; }
}
public bool ConstantCheckState {
get { return (flags & Options.DoFlowAnalysis) != 0; }
}
+ public bool HasUnresolvedConstraints {
+ get { return false; }
+ }
+
public bool IsInProbingMode {
get { return (flags & Options.ProbingMode) != 0; }
}
get { return HasSet (Options.UnsafeScope) || MemberContext.IsUnsafe; }
}
- public ExtensionMethodGroupExpr LookupExtensionMethod (Type extensionType, string name, Location loc)
+ public ExtensionMethodGroupExpr LookupExtensionMethod (TypeSpec extensionType, string name, int arity, Location loc)
{
- return MemberContext.LookupExtensionMethod (extensionType, name, loc);
+ return MemberContext.LookupExtensionMethod (extensionType, name, arity, loc);
}
- public FullNamedExpression LookupNamespaceOrType (string name, Location loc, bool ignore_cs0104)
+ public FullNamedExpression LookupNamespaceOrType (string name, int arity, Location loc, bool ignore_cs0104)
{
- return MemberContext.LookupNamespaceOrType (name, loc, ignore_cs0104);
+ return MemberContext.LookupNamespaceOrType (name, arity, loc, ignore_cs0104);
}
public FullNamedExpression LookupNamespaceAlias (string name)
implicit_conv = new DoubleHash (100);
}
- static Type TypeParam_EffectiveBaseType (GenericConstraints gc)
- {
- var list = new List<Type> ();
- list.Add (gc.EffectiveBaseClass);
- foreach (Type t in gc.InterfaceConstraints) {
- if (!TypeManager.IsGenericParameter (t))
- continue;
-
- GenericConstraints new_gc = TypeManager.GetTypeParameterConstraints (t);
- if (new_gc != null)
- list.Add (TypeParam_EffectiveBaseType (new_gc));
- }
- return FindMostEncompassedType (list);
- }
-
//
// From a one-dimensional array-type S[] to System.Collections.IList<T> and base
// interfaces of this interface, provided there is an implicit reference conversion
// from S to T.
//
- static bool Array_To_IList (Type array, Type list, bool isExplicit)
+ static bool ArrayToIList (ArrayContainer array, TypeSpec list, bool isExplicit)
{
- if ((array.GetArrayRank () != 1) || !TypeManager.IsGenericType (list))
+ if (array.Rank != 1 || !list.IsGeneric)
return false;
- Type gt = TypeManager.DropGenericTypeArguments (list);
- if ((gt != TypeManager.generic_ilist_type) &&
- (gt != TypeManager.generic_icollection_type) &&
- (gt != TypeManager.generic_ienumerable_type))
+ var open_version = list.GetDefinition ();
+ if ((open_version != TypeManager.generic_ilist_type) &&
+ (open_version != TypeManager.generic_icollection_type) &&
+ (open_version != TypeManager.generic_ienumerable_type))
return false;
- Type element_type = TypeManager.GetElementType (array);
- Type arg_type = TypeManager.TypeToCoreType (TypeManager.GetTypeArguments (list) [0]);
-
- if (element_type == arg_type)
+ var arg_type = list.TypeArguments[0];
+ if (array.Element == arg_type)
return true;
if (isExplicit)
- return ExplicitReferenceConversionExists (element_type, arg_type);
+ return ExplicitReferenceConversionExists (array.Element, arg_type);
- Type t = TypeManager.GetElementType (array);
if (MyEmptyExpr == null)
- MyEmptyExpr = new EmptyExpression (t);
+ MyEmptyExpr = new EmptyExpression (array.Element);
else
- MyEmptyExpr.SetType (t);
+ MyEmptyExpr.SetType (array.Element);
return ImplicitReferenceConversionExists (MyEmptyExpr, arg_type);
}
- static bool IList_To_Array(Type list, Type array)
+ static bool IList_To_Array(TypeSpec list, ArrayContainer array)
{
- if (!TypeManager.IsGenericType (list) || !array.IsArray || array.GetArrayRank() != 1)
+ if (array.Rank != 1 || !list.IsGeneric)
return false;
-
- Type gt = TypeManager.DropGenericTypeArguments (list);
- if (gt != TypeManager.generic_ilist_type &&
- gt != TypeManager.generic_icollection_type &&
- gt != TypeManager.generic_ienumerable_type)
+
+ var open_version = list.GetDefinition ();
+ if ((open_version != TypeManager.generic_ilist_type) &&
+ (open_version != TypeManager.generic_icollection_type) &&
+ (open_version != TypeManager.generic_ienumerable_type))
return false;
-
- Type arg_type = TypeManager.TypeToCoreType (TypeManager.GetTypeArguments(list)[0]);
- Type element_type = TypeManager.GetElementType(array);
-
- if (element_type == arg_type)
+
+ var arg_type = list.TypeArguments[0];
+ if (array.Element == arg_type)
return true;
if (MyEmptyExpr == null)
- MyEmptyExpr = new EmptyExpression(element_type);
+ MyEmptyExpr = new EmptyExpression (array.Element);
else
- MyEmptyExpr.SetType(element_type);
-
- return ImplicitReferenceConversionExists(MyEmptyExpr, arg_type) || ExplicitReferenceConversionExists(element_type, arg_type);
+ MyEmptyExpr.SetType (array.Element);
+
+ return ImplicitReferenceConversionExists (MyEmptyExpr, arg_type) || ExplicitReferenceConversionExists (array.Element, arg_type);
}
- static Expression ImplicitTypeParameterConversion (Expression expr,
- Type target_type)
+ static Expression ImplicitTypeParameterConversion (Expression expr, TypeSpec target_type)
{
- Type expr_type = expr.Type;
-
- GenericConstraints gc = TypeManager.GetTypeParameterConstraints (expr_type);
-
- if (gc == null) {
- if (target_type == TypeManager.object_type)
+ var expr_type = (TypeParameterSpec) expr.Type;
+ //
+ // From T to a type parameter U
+ //
+ var ttype = target_type as TypeParameterSpec;
+ if (ttype != null) {
+ if (expr_type.IsReferenceType && !ttype.IsReferenceType)
return new BoxedCast (expr, target_type);
- return null;
- }
-
- // We're converting from a type parameter which is known to be a reference type.
- Type base_type = TypeParam_EffectiveBaseType (gc);
-
- if (TypeManager.IsSubclassOf (base_type, target_type))
return new ClassCast (expr, target_type);
-
- if (target_type.IsInterface) {
- if (TypeManager.ImplementsInterface (base_type, target_type))
- return new ClassCast (expr, target_type);
-
- foreach (Type t in gc.InterfaceConstraints) {
- if (TypeManager.IsSubclassOf (t, target_type))
- return new ClassCast (expr, target_type);
- if (TypeManager.ImplementsInterface (t, target_type))
- return new ClassCast (expr, target_type);
- }
}
- foreach (Type t in gc.InterfaceConstraints) {
- if (!TypeManager.IsGenericParameter (t))
- continue;
- if (TypeManager.IsSubclassOf (t, target_type))
- return new ClassCast (expr, target_type);
- if (TypeManager.ImplementsInterface (t, target_type))
+ //
+ // From T to its effective base class C
+ // From T to any base class of C
+ // From T to any interface implemented by C
+ //
+ var base_type = expr_type.BaseType;
+ if (base_type == target_type || TypeManager.IsSubclassOf (base_type, target_type) || base_type.ImplementsInterface (target_type)) {
+ if (expr_type.IsReferenceType)
return new ClassCast (expr, target_type);
- }
-
- return null;
- }
-
- static bool ImplicitTypeParameterBoxingConversion (Type expr_type, Type target_type,
- out bool use_class_cast)
- {
- GenericConstraints gc = TypeManager.GetTypeParameterConstraints (expr_type);
- if (gc == null) {
- use_class_cast = false;
- return target_type == TypeManager.object_type;
+ return new BoxedCast (expr, target_type);
}
- use_class_cast = true;
-
- if (!gc.HasReferenceTypeConstraint)
- return false;
-
- // We're converting from a type parameter which is known to be a reference type.
- Type base_type = TypeParam_EffectiveBaseType (gc);
-
- if (TypeManager.IsSubclassOf (base_type, target_type))
- return true;
+ base_type = expr_type.GetEffectiveBase ();
- if (target_type.IsInterface) {
- if (TypeManager.ImplementsInterface (base_type, target_type))
- return true;
+ var effective_ifaces = expr_type.Interfaces;
+ if (effective_ifaces != null) {
+ foreach (var t in effective_ifaces) {
+ if (t == target_type || t.ImplementsInterface (target_type)) {
+ if (expr_type.IsReferenceType)
+ return new ClassCast (expr, target_type);
- foreach (Type t in gc.InterfaceConstraints) {
- if (TypeManager.IsSubclassOf (t, target_type))
- return true;
- if (TypeManager.ImplementsInterface (t, target_type))
- return true;
+ return new BoxedCast (expr, target_type);
+ }
}
}
- foreach (Type t in gc.InterfaceConstraints) {
- if (!TypeManager.IsGenericParameter (t))
- continue;
- if (TypeManager.IsSubclassOf (t, target_type))
- return true;
- if (TypeManager.ImplementsInterface (t, target_type))
- return true;
- }
-
- use_class_cast = false;
- return false;
+ return null;
}
- static Expression ExplicitTypeParameterConversion (Expression source, Type source_type, Type target_type)
+ static Expression ExplicitTypeParameterConversion (Expression source, TypeSpec source_type, TypeSpec target_type)
{
- if (TypeManager.IsGenericParameter (target_type)) {
- GenericConstraints gc = TypeManager.GetTypeParameterConstraints (target_type);
- if (gc == null)
- return null;
-
- foreach (Type iface in gc.InterfaceConstraints) {
- if (!TypeManager.IsGenericParameter (iface))
- continue;
+ var target_tp = target_type as TypeParameterSpec;
+ if (target_tp != null) {
+ if (target_tp.Interfaces != null) {
+ foreach (TypeSpec iface in target_tp.Interfaces) {
+ if (!TypeManager.IsGenericParameter (iface))
+ continue;
- if (TypeManager.IsSubclassOf (source_type, iface))
- return source == null ? EmptyExpression.Null : new ClassCast (source, target_type, true);
+ if (TypeManager.IsSubclassOf (source_type, iface))
+ return source == null ? EmptyExpression.Null : new ClassCast (source, target_type, true);
+ }
}
+
+ return null;
}
if (target_type.IsInterface)
return null;
}
- static Expression ImplicitReferenceConversion (Expression expr, Type target_type, bool explicit_cast)
+ static Expression ImplicitReferenceConversion (Expression expr, TypeSpec target_type, bool explicit_cast)
{
- Type expr_type = expr.Type;
+ TypeSpec expr_type = expr.Type;
if (expr_type == null && expr.eclass == ExprClass.MethodGroup){
// if we are a method group, emit a warning
if (expr_type == TypeManager.void_type)
return null;
- if (TypeManager.IsGenericParameter (expr_type))
+ if (expr_type.Kind == MemberKind.TypeParameter)
return ImplicitTypeParameterConversion (expr, target_type);
//
//
// 6.1.6 Implicit reference conversions
//
- public static bool ImplicitReferenceConversionExists (Expression expr, Type target_type)
+ public static bool ImplicitReferenceConversionExists (Expression expr, TypeSpec target_type)
{
if (TypeManager.IsStruct (target_type))
return false;
- Type expr_type = expr.Type;
+ TypeSpec expr_type = expr.Type;
// from the null type to any reference-type.
if (expr_type == TypeManager.null_type)
if (TypeManager.IsGenericParameter (expr_type))
return ImplicitTypeParameterConversion (expr, target_type) != null;
+ // This code is kind of mirrored inside ImplicitStandardConversionExists
+ // with the small distinction that we only probe there
+ //
+ // Always ensure that the code here and there is in sync
+
+ // from any class-type S to any interface-type T.
+ if (target_type.IsInterface) {
+ if (expr_type.ImplementsInterface (target_type)){
+ return !TypeManager.IsValueType (expr_type);
+ }
+ }
+
//
// notice that it is possible to write "ValueType v = 1", the ValueType here
// is an abstract class, and not really a value type, so we apply the same rules.
//
- if (target_type == TypeManager.object_type || TypeManager.IsDynamicType (target_type)) {
+ if (target_type == TypeManager.object_type || target_type == InternalType.Dynamic) {
//
// A pointer type cannot be converted to object
//
if (TypeManager.IsValueType (expr_type))
return false;
- if (expr_type.IsClass || expr_type.IsInterface || expr_type == TypeManager.enum_type){
+ if (expr_type.IsClass || expr_type.IsInterface || expr_type == TypeManager.enum_type || expr_type.IsDelegate) {
// No mcs internal types are convertible
- return expr_type.Module != typeof (Convert).Module;
+ return true; // expr_type.MetaInfo.Module != typeof (Convert).Module;
}
+ // From anything to dynamic
+ if (target_type == InternalType.Dynamic)
+ return true;
+
+ // From dynamic to object
+ if (expr_type == InternalType.Dynamic)
+ return true;
+
return false;
} else if (target_type == TypeManager.value_type) {
return expr_type == TypeManager.enum_type;
//
if (target_type == TypeManager.enum_type || TypeManager.IsGenericParameter (expr_type))
return false;
-
- return true;
- }
- // This code is kind of mirrored inside ImplicitStandardConversionExists
- // with the small distinction that we only probe there
- //
- // Always ensure that the code here and there is in sync
+ if (TypeManager.IsValueType (expr_type))
+ return false;
- // from any class-type S to any interface-type T.
- if (target_type.IsInterface) {
- if (TypeManager.ImplementsInterface (expr_type, target_type)){
- return !TypeManager.IsGenericParameter (expr_type) &&
- !TypeManager.IsValueType (expr_type);
- }
+ // Array type variance conversion
+ //if (target_type.IsArray != expr_type.IsArray)
+ // return false;
+
+ return true;
}
- if (expr_type.IsArray) {
+ var expr_type_array = expr_type as ArrayContainer;
+ if (expr_type_array != null) {
+ var target_type_array = target_type as ArrayContainer;
// from an array-type S to an array-type of type T
- if (target_type.IsArray && expr_type.GetArrayRank () == target_type.GetArrayRank ()) {
+ if (target_type_array != null && expr_type_array.Rank == target_type_array.Rank) {
//
// Both SE and TE are reference-types
//
- Type expr_element_type = TypeManager.GetElementType (expr_type);
+ TypeSpec expr_element_type = expr_type_array.Element;
if (!TypeManager.IsReferenceType (expr_element_type))
return false;
- Type target_element_type = TypeManager.GetElementType (target_type);
+ TypeSpec target_element_type = target_type_array.Element;
if (!TypeManager.IsReferenceType (target_element_type))
return false;
return true;
// from an array-type of type T to IList<T>
- if (Array_To_IList (expr_type, target_type, false))
+ if (ArrayToIList (expr_type_array, target_type, false))
return true;
return false;
}
- if (TypeManager.IsVariantOf (expr_type, target_type))
+ if (TypeSpecComparer.Variant.IsEqual (expr_type, target_type))
return true;
// from any interface type S to interface-type T.
if (expr_type.IsInterface && target_type.IsInterface) {
- return TypeManager.ImplementsInterface (expr_type, target_type);
+ return expr_type.ImplementsInterface (target_type);
}
// from any delegate type to System.Delegate
if (target_type == TypeManager.delegate_type &&
- (expr_type == TypeManager.delegate_type || TypeManager.IsDelegateType (expr_type)))
+ (expr_type == TypeManager.delegate_type || expr_type.IsDelegate))
return true;
if (TypeManager.IsEqual (expr_type, target_type))
return false;
}
- public static bool ImplicitBoxingConversionExists (Expression expr, Type target_type,
+ public static bool ImplicitBoxingConversionExists (Expression expr, TypeSpec target_type,
out bool use_class_cast)
{
- Type expr_type = expr.Type;
+ TypeSpec expr_type = expr.Type;
use_class_cast = false;
//
// From any value-type to the type object.
//
- if (target_type == TypeManager.object_type || TypeManager.IsDynamicType (target_type)) {
+ if (target_type == TypeManager.object_type || target_type == InternalType.Dynamic) {
//
// A pointer type cannot be converted to object
//
// From any nullable-type with an underlying enum-type to the type System.Enum
//
if (TypeManager.IsNullableType (expr_type))
- return TypeManager.IsEnumType (TypeManager.GetTypeArguments (expr_type) [0]);
+ return TypeManager.IsEnumType (Nullable.NullableInfo.GetUnderlyingType (expr_type));
}
if (TypeManager.IsSubclassOf (expr_type, target_type)) {
// from any class-type S to any interface-type T.
if (target_type.IsInterface) {
- if (TypeManager.ImplementsInterface (expr_type, target_type))
+ if (expr_type.ImplementsInterface (target_type))
return TypeManager.IsGenericParameter (expr_type) ||
TypeManager.IsValueType (expr_type);
}
- if (TypeManager.IsGenericParameter (expr_type))
- return ImplicitTypeParameterBoxingConversion (
- expr_type, target_type, out use_class_cast);
+ if (TypeManager.IsGenericParameter (expr_type)) {
+ return ImplicitTypeParameterConversion (expr, target_type) != null;
+// return ImplicitTypeParameterBoxingConversion (
+// expr_type, target_type, out use_class_cast);
+ }
return false;
}
- public static Expression ImplicitNulableConversion (ResolveContext ec, Expression expr, Type target_type)
+ public static Expression ImplicitNulableConversion (ResolveContext ec, Expression expr, TypeSpec target_type)
{
- Type expr_type = expr.Type;
+ TypeSpec expr_type = expr.Type;
//
// From null to any nullable type
return ec == null ? EmptyExpression.Null : Nullable.LiftedNull.Create (target_type, expr.Location);
// S -> T?
- Type t_el = TypeManager.TypeToCoreType (TypeManager.GetTypeArguments (target_type)[0]);
+ TypeSpec t_el = TypeManager.GetTypeArguments (target_type)[0];
// S? -> T?
if (TypeManager.IsNullableType (expr_type))
- expr_type = TypeManager.TypeToCoreType (TypeManager.GetTypeArguments (expr_type)[0]);
+ expr_type = TypeManager.GetTypeArguments (expr_type)[0];
//
// Predefined implicit identity or implicit numeric conversion
/// expr is the expression to convert, returns a new expression of type
/// target_type or null if an implicit conversion is not possible.
/// </summary>
- public static Expression ImplicitNumericConversion (Expression expr, Type target_type)
+ public static Expression ImplicitNumericConversion (Expression expr, TypeSpec target_type)
{
return ImplicitNumericConversion (expr, expr.Type, target_type);
}
- static Expression ImplicitNumericConversion (Expression expr, Type expr_type, Type target_type)
+ static Expression ImplicitNumericConversion (Expression expr, TypeSpec expr_type, TypeSpec target_type)
{
if (expr_type == TypeManager.sbyte_type){
//
/// Same as ImplicitStandardConversionExists except that it also looks at
/// implicit user defined conversions - needed for overload resolution
/// </summary>
- public static bool ImplicitConversionExists (ResolveContext ec, Expression expr, Type target_type)
+ public static bool ImplicitConversionExists (ResolveContext ec, Expression expr, TypeSpec target_type)
{
if (ImplicitStandardConversionExists (expr, target_type))
return true;
if (expr.Type == InternalType.AnonymousMethod) {
- if (!TypeManager.IsDelegateType (target_type) &&
- TypeManager.DropGenericTypeArguments (target_type) != TypeManager.expression_type)
+ if (!TypeManager.IsDelegateType (target_type) && target_type.GetDefinition () != TypeManager.expression_type)
return false;
AnonymousMethodExpression ame = (AnonymousMethodExpression) expr;
}
if (expr.eclass == ExprClass.MethodGroup) {
- if (TypeManager.IsDelegateType (target_type) && RootContext.Version != LanguageVersion.ISO_1) {
+ if (target_type.IsDelegate && RootContext.Version != LanguageVersion.ISO_1) {
MethodGroupExpr mg = expr as MethodGroupExpr;
if (mg != null)
return DelegateCreation.ImplicitStandardConversionExists (ec, mg, target_type);
///
/// ec should point to a real EmitContext if expr.Type is TypeManager.anonymous_method_type.
/// </summary>
- public static bool ImplicitStandardConversionExists (Expression expr, Type target_type)
+ public static bool ImplicitStandardConversionExists (Expression expr, TypeSpec target_type)
{
- Type expr_type = expr.Type;
+ TypeSpec expr_type = expr.Type;
if (expr_type == TypeManager.null_type) {
NullLiteral nl = expr as NullLiteral;
return true;
}
- if (value == 0 && TypeManager.IsEnumType (target_type))
+ if (value == 0 && target_type.IsEnum)
return true;
}
// If `expr_type' implements `target_type' (which is an iface)
// see TryImplicitIntConversion
//
- if (target_type.IsInterface && TypeManager.ImplementsInterface (expr_type, target_type))
+ if (target_type.IsInterface && expr_type.ImplementsInterface (target_type))
return true;
if (target_type == TypeManager.void_ptr_type && expr_type.IsPointer)
/// Finds "most encompassed type" according to the spec (13.4.2)
/// amongst the methods in the MethodGroupExpr
/// </summary>
- static Type FindMostEncompassedType (IList<Type> types)
+ public static TypeSpec FindMostEncompassedType (IEnumerable<TypeSpec> types)
{
- Type best = null;
-
- if (types.Count == 0)
- return null;
-
- if (types.Count == 1)
- return (Type) types [0];
-
+ TypeSpec best = null;
EmptyExpression expr = EmptyExpression.Grab ();
- foreach (Type t in types) {
+ foreach (TypeSpec t in types) {
if (best == null) {
best = t;
continue;
}
expr.SetType (best);
- foreach (Type t in types) {
+ foreach (TypeSpec t in types) {
if (best == t)
continue;
if (!ImplicitStandardConversionExists (expr, t)) {
/// Finds "most encompassing type" according to the spec (13.4.2)
/// amongst the types in the given set
/// </summary>
- static Type FindMostEncompassingType (IList<Type> types)
+ static TypeSpec FindMostEncompassingType (IList<TypeSpec> types)
{
- Type best = null;
+ TypeSpec best = null;
if (types.Count == 0)
return null;
EmptyExpression expr = EmptyExpression.Grab ();
- foreach (Type t in types) {
+ foreach (TypeSpec t in types) {
if (best == null) {
best = t;
continue;
best = t;
}
- foreach (Type t in types) {
+ foreach (TypeSpec t in types) {
if (best == t)
continue;
expr.SetType (t);
/// by making use of FindMostEncomp* methods. Applies the correct rules separately
/// for explicit and implicit conversion operators.
/// </summary>
- static public Type FindMostSpecificSource (IList<MethodSpec> list,
+ static public TypeSpec FindMostSpecificSource (IList<MethodSpec> list,
Expression source, bool apply_explicit_conv_rules)
{
- var src_types_set = new List<Type> ();
+ var src_types_set = new List<TypeSpec> ();
//
// If any operator converts from S then Sx = S
//
- Type source_type = source.Type;
+ TypeSpec source_type = source.Type;
foreach (var mb in list){
- Type param_type = mb.Parameters.Types [0];
+ TypeSpec param_type = mb.Parameters.Types [0];
if (param_type == source_type)
return param_type;
// Explicit Conv rules
//
if (apply_explicit_conv_rules) {
- var candidate_set = new List<Type> ();
+ var candidate_set = new List<TypeSpec> ();
- foreach (Type param_type in src_types_set){
+ foreach (TypeSpec param_type in src_types_set){
if (ImplicitStandardConversionExists (source, param_type))
candidate_set.Add (param_type);
}
/// <summary>
/// Finds the most specific target Tx according to section 13.4.4
/// </summary>
- static public Type FindMostSpecificTarget (IList<MethodSpec> list,
- Type target, bool apply_explicit_conv_rules)
+ static public TypeSpec FindMostSpecificTarget (IList<MethodSpec> list,
+ TypeSpec target, bool apply_explicit_conv_rules)
{
- var tgt_types_set = new List<Type> ();
+ var tgt_types_set = new List<TypeSpec> ();
//
// If any operator converts to T then Tx = T
//
foreach (var mi in list){
- Type ret_type = TypeManager.TypeToCoreType (mi.ReturnType);
+ TypeSpec ret_type = mi.ReturnType;
if (ret_type == target)
return ret_type;
// Explicit conv rules
//
if (apply_explicit_conv_rules) {
- var candidate_set = new List<Type> ();
+ var candidate_set = new List<TypeSpec> ();
EmptyExpression expr = EmptyExpression.Grab ();
- foreach (Type ret_type in tgt_types_set){
+ foreach (TypeSpec ret_type in tgt_types_set){
expr.SetType (ret_type);
if (ImplicitStandardConversionExists (expr, target))
/// User-defined Implicit conversions
/// </summary>
static public Expression ImplicitUserConversion (ResolveContext ec, Expression source,
- Type target, Location loc)
+ TypeSpec target, Location loc)
{
return UserDefinedConversion (ec, source, target, loc, false, true);
}
/// User-defined Explicit conversions
/// </summary>
static Expression ExplicitUserConversion (ResolveContext ec, Expression source,
- Type target, Location loc)
+ TypeSpec target, Location loc)
{
return UserDefinedConversion (ec, source, target, loc, true, true);
}
static void AddConversionOperators (List<MethodSpec> list,
- Expression source, Type target_type,
+ Expression source, TypeSpec target_type,
bool look_for_explicit,
MethodGroupExpr mg)
{
if (mg == null)
return;
- Type source_type = source.Type;
+ TypeSpec source_type = source.Type;
EmptyExpression expr = EmptyExpression.Grab ();
//
target_type = TypeManager.uint64_type;
}
- foreach (var m in mg.Methods) {
+ foreach (MethodSpec m in mg.Methods) {
AParametersCollection pd = m.Parameters;
- Type return_type = TypeManager.TypeToCoreType (m.ReturnType);
- Type arg_type = pd.Types [0];
+ TypeSpec return_type = m.ReturnType;
+ TypeSpec arg_type = pd.Types [0];
if (source_type != arg_type) {
if (!ImplicitStandardConversionExists (source, arg_type)) {
/// Compute the user-defined conversion operator from source_type to target_type.
/// `look_for_explicit' controls whether we should also include the list of explicit operators
/// </summary>
- static MethodSpec GetConversionOperator (CompilerContext ctx, Type container_type, Expression source, Type target_type, bool look_for_explicit)
+ static MethodSpec GetConversionOperator (CompilerContext ctx, TypeSpec container_type, Expression source, TypeSpec target_type, bool look_for_explicit)
{
var ops = new List<MethodSpec> (4);
- Type source_type = source.Type;
+ TypeSpec source_type = source.Type;
if (source_type != TypeManager.decimal_type) {
AddConversionOperators (ops, source, target_type, look_for_explicit,
- Expression.MethodLookup (ctx, container_type, source_type, "op_Implicit", Location.Null) as MethodGroupExpr);
+ Expression.MethodLookup (ctx, container_type, source_type, MemberKind.Operator, "op_Implicit", 0, Location.Null));
if (look_for_explicit) {
AddConversionOperators (ops, source, target_type, look_for_explicit,
Expression.MethodLookup (ctx,
- container_type, source_type, "op_Explicit", Location.Null) as MethodGroupExpr);
+ container_type, source_type, MemberKind.Operator, "op_Explicit", 0, Location.Null));
}
}
if (target_type != TypeManager.decimal_type) {
AddConversionOperators (ops, source, target_type, look_for_explicit,
- Expression.MethodLookup (ctx, container_type, target_type, "op_Implicit", Location.Null) as MethodGroupExpr);
+ Expression.MethodLookup (ctx, container_type, target_type, MemberKind.Operator, "op_Implicit", 0, Location.Null));
if (look_for_explicit) {
AddConversionOperators (ops, source, target_type, look_for_explicit,
Expression.MethodLookup (ctx,
- container_type, target_type, "op_Explicit", Location.Null) as MethodGroupExpr);
+ container_type, target_type, MemberKind.Operator, "op_Explicit", 0, Location.Null));
}
}
if (ops.Count == 0)
return null;
- Type most_specific_source = FindMostSpecificSource (ops, source, look_for_explicit);
+ TypeSpec most_specific_source = FindMostSpecificSource (ops, source, look_for_explicit);
if (most_specific_source == null)
return null;
- Type most_specific_target = FindMostSpecificTarget (ops, target_type, look_for_explicit);
+ TypeSpec most_specific_target = FindMostSpecificTarget (ops, target_type, look_for_explicit);
if (most_specific_target == null)
return null;
MethodSpec method = null;
foreach (var m in ops) {
- if (TypeManager.TypeToCoreType (m.ReturnType) != most_specific_target)
+ if (m.ReturnType != most_specific_target)
continue;
if (m.Parameters.Types [0] != most_specific_source)
continue;
/// User-defined conversions
/// </summary>
public static Expression UserDefinedConversion (ResolveContext ec, Expression source,
- Type target, Location loc,
+ TypeSpec target, Location loc,
bool look_for_explicit, bool return_convert)
{
- Type source_type = source.Type;
+ TypeSpec source_type = source.Type;
MethodSpec method = null;
Expression expr = null;
if (!(source is Constant) && hash.Lookup (source_type, target, out o)) {
method = (MethodSpec) o;
} else {
- if (TypeManager.IsDynamicType (source_type))
+ if (source_type == InternalType.Dynamic)
return null;
method = GetConversionOperator (ec.Compiler, null, source, target, look_for_explicit);
}
if (method != null) {
- Type most_specific_source = method.Parameters.Types[0];
+ TypeSpec most_specific_source = method.Parameters.Types[0];
//
// This will do the conversion to the best match that we
nullable = true;
}
- Type target_underlying;
+ TypeSpec target_underlying;
if (TypeManager.IsNullableType (target)) {
target_underlying = TypeManager.GetTypeArguments (target)[0];
nullable = true;
/// in a context that expects a `target_type'.
/// </summary>
static public Expression ImplicitConversion (ResolveContext ec, Expression expr,
- Type target_type, Location loc)
+ TypeSpec target_type, Location loc)
{
Expression e;
/// user defined implicit conversions are excluded.
/// </summary>
static public Expression ImplicitConversionStandard (ResolveContext ec, Expression expr,
- Type target_type, Location loc)
+ TypeSpec target_type, Location loc)
{
return ImplicitConversionStandard (ec, expr, target_type, loc, false);
}
- static Expression ImplicitConversionStandard (ResolveContext ec, Expression expr, Type target_type, Location loc, bool explicit_cast)
+ static Expression ImplicitConversionStandard (ResolveContext ec, Expression expr, TypeSpec target_type, Location loc, bool explicit_cast)
{
if (expr.eclass == ExprClass.MethodGroup){
if (!TypeManager.IsDelegateType (target_type)){
}
}
- Type expr_type = expr.Type;
+ TypeSpec expr_type = expr.Type;
Expression e;
if (expr_type.Equals (target_type)) {
return null;
}
- if (TypeManager.IsVariantOf (expr_type, target_type)) {
+ if (TypeSpecComparer.Variant.IsEqual (expr_type, target_type)) {
return expr;
}
/// an error is signaled
/// </summary>
static public Expression ImplicitConversionRequired (ResolveContext ec, Expression source,
- Type target_type, Location loc)
+ TypeSpec target_type, Location loc)
{
Expression e = ImplicitConversion (ec, source, target_type, loc);
if (e != null)
return e;
- if (TypeManager.IsDynamicType (source.Type)) {
+ if (source.Type == InternalType.Dynamic) {
Arguments args = new Arguments (1);
args.Add (new Argument (source));
return new DynamicConversion (target_type, 0, args, loc).Resolve (ec);
/// Int16->UIntPtr
///
/// </summary>
- public static Expression ExplicitNumericConversion (Expression expr, Type target_type)
+ public static Expression ExplicitNumericConversion (Expression expr, TypeSpec target_type)
{
- Type expr_type = expr.Type;
- Type real_target_type = target_type;
+ TypeSpec expr_type = expr.Type;
+ TypeSpec real_target_type = target_type;
if (expr_type == TypeManager.sbyte_type){
//
/// Returns whether an explicit reference conversion can be performed
/// from source_type to target_type
/// </summary>
- public static bool ExplicitReferenceConversionExists (Type source_type, Type target_type)
+ public static bool ExplicitReferenceConversionExists (TypeSpec source_type, TypeSpec target_type)
{
Expression e = ExplicitReferenceConversion (null, source_type, target_type);
if (e == null)
/// <summary>
/// Implements Explicit Reference conversions
/// </summary>
- static Expression ExplicitReferenceConversion (Expression source, Type source_type, Type target_type)
+ static Expression ExplicitReferenceConversion (Expression source, TypeSpec source_type, TypeSpec target_type)
{
bool target_is_value_type = TypeManager.IsStruct (target_type);
if (TypeManager.IsSubclassOf (target_type, source_type))
return source == null ? EmptyExpression.Null : new ClassCast (source, target_type);
- //
- // From any class type S to any interface T, provides S is not sealed
- // and provided S does not implement T.
- //
- if (target_type.IsInterface && !source_type.IsSealed &&
- !TypeManager.ImplementsInterface (source_type, target_type)) {
- return source == null ? EmptyExpression.Null : new ClassCast (source, target_type);
- }
-
//
// From any interface-type S to to any class type T, provided T is not
// sealed, or provided T implements S.
//
if (source_type.IsInterface) {
- if (!target_type.IsSealed || TypeManager.ImplementsInterface (target_type, source_type)) {
+ if (!target_type.IsSealed || target_type.ImplementsInterface (source_type)) {
if (target_type.IsClass)
return source == null ? EmptyExpression.Null : new ClassCast (source, target_type);
}
//
- // From System.Collecitons.Generic.IList<T> and its base interfaces to a one-dimensional
+ // From System.Collections.Generic.IList<T> and its base interfaces to a one-dimensional
// array type S[], provided there is an implicit or explicit reference conversion from S to T.
//
- if (IList_To_Array (source_type, target_type))
+ var target_array = target_type as ArrayContainer;
+ if (target_array != null && IList_To_Array (source_type, target_array))
return source == null ? EmptyExpression.Null : new ClassCast (source, target_type);
return null;
}
- if (source_type.IsArray) {
- if (target_type.IsArray) {
+ var source_array = source_type as ArrayContainer;
+ if (source_array != null) {
+ var target_array = target_type as ArrayContainer;
+ if (target_array != null) {
//
// From System.Array to any array-type
//
// * Both Se and Te are reference types
// * An explicit reference conversions exist from Se to Te
//
- if (source_type.GetArrayRank () == target_type.GetArrayRank ()) {
+ if (source_array.Rank == target_array.Rank) {
- source_type = TypeManager.GetElementType (source_type);
+ source_type = source_array.Element;
if (!TypeManager.IsReferenceType (source_type))
return null;
- Type target_type_element = TypeManager.GetElementType (target_type);
- if (!TypeManager.IsReferenceType (target_type_element))
+ var target_element = target_array.Element;
+ if (!TypeManager.IsReferenceType (target_element))
return null;
- if (ExplicitReferenceConversionExists (source_type, target_type_element))
+ if (ExplicitReferenceConversionExists (source_type, target_element))
return source == null ? EmptyExpression.Null : new ClassCast (source, target_type);
return null;
// From a single-dimensional array type S[] to System.Collections.Generic.IList<T> and its base interfaces,
// provided that there is an explicit reference conversion from S to T
//
- if (Array_To_IList (source_type, target_type, true))
+ if (ArrayToIList (source_array, target_type, true))
return source == null ? EmptyExpression.Null : new ClassCast (source, target_type);
return null;
}
+ //
+ // From any class type S to any interface T, provides S is not sealed
+ // and provided S does not implement T.
+ //
+ if (target_type.IsInterface && !source_type.IsSealed && !source_type.ImplementsInterface (target_type)) {
+ return source == null ? EmptyExpression.Null : new ClassCast (source, target_type);
+ }
+
//
// From System delegate to any delegate-type
//
/// type is expr.Type to `target_type'.
/// </summary>
static public Expression ExplicitConversionCore (ResolveContext ec, Expression expr,
- Type target_type, Location loc)
+ TypeSpec target_type, Location loc)
{
- Type expr_type = expr.Type;
+ TypeSpec expr_type = expr.Type;
// Explicit conversion includes implicit conversion and it used for enum underlying types too
Expression ne = ImplicitConversionStandard (ec, expr, target_type, loc, true);
return ne;
if (TypeManager.IsEnumType (expr_type)) {
- Expression underlying = EmptyCast.Create (expr, TypeManager.GetEnumUnderlyingType (expr_type));
+ Expression underlying = EmptyCast.Create (expr, EnumSpec.GetUnderlyingType (expr_type));
expr = ExplicitConversionCore (ec, underlying, target_type, loc);
if (expr != null)
return expr;
if (expr_type == TypeManager.enum_type)
return new UnboxCast (expr, target_type);
- Expression ce = ExplicitConversionCore (ec, expr, TypeManager.GetEnumUnderlyingType (target_type), loc);
+ Expression ce = ExplicitConversionCore (ec, expr, EnumSpec.GetUnderlyingType (target_type), loc);
if (ce != null)
return EmptyCast.Create (ce, target_type);
// LAMESPEC: IntPtr and UIntPtr conversion to any Enum is allowed
//
if (expr_type == TypeManager.intptr_type || expr_type == TypeManager.uintptr_type) {
- ne = ExplicitUserConversion (ec, expr, TypeManager.GetEnumUnderlyingType (target_type), loc);
+ ne = ExplicitUserConversion (ec, expr, EnumSpec.GetUnderlyingType (target_type), loc);
if (ne != null)
return ExplicitConversionCore (ec, ne, target_type, loc);
}
return null;
}
- public static Expression ExplicitUnsafe (Expression expr, Type target_type)
+ public static Expression ExplicitUnsafe (Expression expr, TypeSpec target_type)
{
- Type expr_type = expr.Type;
+ TypeSpec expr_type = expr.Type;
if (target_type.IsPointer){
if (expr_type.IsPointer)
/// Same as ExplicitConversion, only it doesn't include user defined conversions
/// </summary>
static public Expression ExplicitConversionStandard (ResolveContext ec, Expression expr,
- Type target_type, Location l)
+ TypeSpec target_type, Location l)
{
int errors = ec.Report.Errors;
Expression ne = ImplicitConversionStandard (ec, expr, target_type, l);
/// type is expr.Type to `target_type'.
/// </summary>
static public Expression ExplicitConversion (ResolveContext ec, Expression expr,
- Type target_type, Location loc)
+ TypeSpec target_type, Location loc)
{
Expression e = ExplicitConversionCore (ec, expr, target_type, loc);
if (e != null) {
return e;
}
- Type expr_type = expr.Type;
+ TypeSpec expr_type = expr.Type;
if (TypeManager.IsNullableType (target_type)) {
if (TypeManager.IsNullableType (expr_type)) {
- Type target = TypeManager.TypeToCoreType (TypeManager.GetTypeArguments (target_type)[0]);
+ TypeSpec target = TypeManager.GetTypeArguments (target_type)[0];
Expression unwrap = Nullable.Unwrap.Create (expr);
e = ExplicitConversion (ec, unwrap, target, expr.Location);
if (e == null)
} else if (expr_type == TypeManager.object_type) {
return new UnboxCast (expr, target_type);
} else {
- Type target = TypeManager.TypeToCoreType (TypeManager.GetTypeArguments (target_type) [0]);
+ TypeSpec target = TypeManager.GetTypeArguments (target_type) [0];
e = ExplicitConversionCore (ec, expr, target, loc);
if (e != null)
| IDENTIFIER opt_type_argument_list
{
var lt = (Tokenizer.LocatedToken) $1;
- $$ = new SimpleName (MemberName.MakeName (lt.Value, (TypeArguments)$2), (TypeArguments)$2, lt.Location);
+ $$ = new SimpleName (lt.Value, (TypeArguments)$2, lt.Location);
}
| IDENTIFIER GENERATE_COMPLETION {
var lt = (Tokenizer.LocatedToken) $1;
: rank_specifier
| rank_specifier rank_specifiers
{
- $$ = (string) $2 + (string) $1;
+ $$ = (string) $1 + (string) $2;
}
;
{
var lt = (Tokenizer.LocatedToken) $1;
- $$ = new SimpleName (MemberName.MakeName (lt.Value, (int)$2), lt.Location);
+ $$ = new SimpleName (lt.Value, (int) $2, lt.Location);
}
| qualified_alias_member IDENTIFIER generic_dimension
{
var lt1 = (Tokenizer.LocatedToken) $1;
var lt2 = (Tokenizer.LocatedToken) $2;
- $$ = new QualifiedAliasMember (lt1.Value, MemberName.MakeName (lt2.Value, (int) $3), lt1.Location);
+ $$ = new QualifiedAliasMember (lt1.Value, lt2.Value, (int) $3, lt1.Location);
}
| unbound_type_name DOT IDENTIFIER
{
{
var lt = (Tokenizer.LocatedToken) $3;
- $$ = new MemberAccess ((Expression) $1, MemberName.MakeName (lt.Value, (int) $4), lt.Location);
+ $$ = new MemberAccess ((Expression) $1, lt.Value, (int) $4, lt.Location);
}
| namespace_or_type_name DOT IDENTIFIER generic_dimension
{
var lt = (Tokenizer.LocatedToken) $3;
MemberName name = (MemberName) $1;
- $$ = new MemberAccess (name.GetTypeExpression (), MemberName.MakeName (lt.Value, (int) $4), lt.Location);
+ $$ = new MemberAccess (name.GetTypeExpression (), lt.Value, (int) $4, lt.Location);
}
;
return GetName (false);
}
+ public int Arity {
+ get {
+ return TypeArguments == null ? 0 : TypeArguments.Count;
+ }
+ }
+
public bool IsGeneric {
get {
if (TypeArguments != null)
{
if (Left == null) {
if (TypeArguments != null)
- return new SimpleName (Basename, TypeArguments, Location);
+ return new SimpleName (Name, TypeArguments, Location);
return new SimpleName (Name, Location);
}
/// Base representation for members. This is used to keep track
/// of Name, Location and Modifier flags, and handling Attributes.
/// </summary>
+ [System.Diagnostics.DebuggerDisplay ("{GetSignatureForError()}")]
public abstract class MemberCore : Attributable, IMemberContext, IMemberDefinition
{
/// <summary>
}
}
+ string IMemberDefinition.Name {
+ get {
+ return member_name.Name;
+ }
+ }
+
// Is not readonly because of IndexerName attribute
private MemberName member_name;
public MemberName MemberName {
}
}
- public /*readonly*/ DeclSpace Parent;
+ public /*readonly*/ TypeContainer Parent;
/// <summary>
/// Location where this declaration happens
CloseTypeCreated = 1 << 4, // Tracks whether we have Closed the type
HasCompliantAttribute_Undetected = 1 << 5, // Presence of CLSCompliantAttribute has not been detected
HasClsCompliantAttribute = 1 << 6, // Type has CLSCompliantAttribute
- ClsCompliantAttributeTrue = 1 << 7, // Type has CLSCompliant (true)
+ ClsCompliantAttributeFalse = 1 << 7, // Member has CLSCompliant(false)
Excluded_Undetected = 1 << 8, // Conditional attribute has not been detected yet
Excluded = 1 << 9, // Method is conditional
MethodOverloadsExist = 1 << 10, // Test for duplication must be performed
public MemberCore (DeclSpace parent, MemberName name, Attributes attrs)
{
- this.Parent = parent;
+ this.Parent = parent as TypeContainer;
member_name = name;
caching_flags = Flags.Obsolete_Undetected | Flags.ClsCompliance_Undetected | Flags.HasCompliantAttribute_Undetected | Flags.Excluded_Undetected;
AddAttributes (attrs, this);
}
+ public virtual Assembly Assembly {
+ get { return Parent.Module.Assembly; }
+ }
+
protected virtual void SetMemberName (MemberName new_name)
{
member_name = new_name;
if (!RootContext.VerifyClsCompliance)
return;
- if (Report.WarningLevel > 0)
- VerifyClsCompliance ();
+ VerifyClsCompliance ();
}
public bool IsCompilerGenerated {
}
}
+ public bool IsImported {
+ get {
+ return false;
+ }
+ }
+
public virtual bool IsUsed {
get { return (caching_flags & Flags.IsUsed) != 0; }
}
caching_flags |= Flags.IsUsed;
}
+ public void SetIsAssigned ()
+ {
+ caching_flags |= Flags.IsAssigned;
+ }
+
/// <summary>
/// Returns instance of ObsoleteAttribute for this MemberCore
/// </summary>
- public virtual ObsoleteAttribute GetObsoleteAttribute ()
+ public virtual ObsoleteAttribute GetAttributeObsolete ()
{
if ((caching_flags & (Flags.Obsolete_Undetected | Flags.Obsolete)) == 0)
return null;
/// </summary>
public virtual void CheckObsoleteness (Location loc)
{
- ObsoleteAttribute oa = GetObsoleteAttribute ();
+ ObsoleteAttribute oa = GetAttributeObsolete ();
if (oa != null)
AttributeTester.Report_ObsoleteMessage (oa, GetSignatureForError (), loc, Report);
}
- //
- // Returns the access level for type `t'
- //
- static Modifiers GetAccessLevelFromType (Type type)
- {
- var ma = type.Attributes;
- Modifiers mod;
- switch (ma & TypeAttributes.VisibilityMask) {
- case TypeAttributes.Public:
- case TypeAttributes.NestedPublic:
- mod = Modifiers.PUBLIC;
- break;
- case TypeAttributes.NestedPrivate:
- mod = Modifiers.PRIVATE;
- break;
- case TypeAttributes.NestedFamily:
- mod = Modifiers.PROTECTED;
- break;
- case TypeAttributes.NestedFamORAssem:
- mod = Modifiers.PROTECTED | Modifiers.INTERNAL;
- break;
- default:
- mod = Modifiers.INTERNAL;
- break;
- }
-
- return mod;
- }
-
//
// Checks whether the type P is as accessible as this member
//
- public bool IsAccessibleAs (Type p)
+ public bool IsAccessibleAs (TypeSpec p)
{
//
// if M is private, its accessibility is the same as this declspace.
while (TypeManager.HasElementType (p))
p = TypeManager.GetElementType (p);
- if (TypeManager.IsGenericParameter (p))
+ if (p.IsGenericParameter)
return true;
- if (TypeManager.IsGenericType (p)) {
- foreach (Type t in TypeManager.GetTypeArguments (p)) {
- if (!IsAccessibleAs (t))
- return false;
+ for (TypeSpec p_parent; p != null; p = p_parent) {
+ p_parent = p.DeclaringType;
+
+ if (p.IsGeneric) {
+ foreach (TypeSpec t in p.TypeArguments) {
+ if (!IsAccessibleAs (t))
+ return false;
+ }
}
- }
- for (Type p_parent = null; p != null; p = p_parent) {
- p_parent = p.DeclaringType;
- var pAccess = GetAccessLevelFromType (p);
+ var pAccess = p.Modifiers & Modifiers.AccessibilityMask;
if (pAccess == Modifiers.PUBLIC)
continue;
case Modifiers.PROTECTED:
if (al == Modifiers.PROTECTED) {
- same_access_restrictions = mc.Parent.IsBaseType (p_parent);
+ same_access_restrictions = mc.Parent.IsBaseTypeDefinition (p_parent);
break;
}
// protected type then the type is accessible
//
while (mc.Parent != null) {
- if (mc.Parent.IsBaseType (p_parent))
+ if (mc.Parent.IsBaseTypeDefinition (p_parent))
same_access_restrictions = true;
mc = mc.Parent;
}
if (al == Modifiers.INTERNAL)
same_access_restrictions = TypeManager.IsThisOrFriendAssembly (Parent.Module.Assembly, p.Assembly);
else if (al == Modifiers.PROTECTED)
- same_access_restrictions = mc.Parent.IsBaseType (p_parent);
+ same_access_restrictions = mc.Parent.IsBaseTypeDefinition (p_parent);
else if (al == (Modifiers.PROTECTED | Modifiers.INTERNAL))
- same_access_restrictions = mc.Parent.IsBaseType (p_parent) &&
+ same_access_restrictions = mc.Parent.IsBaseTypeDefinition (p_parent) &&
TypeManager.IsThisOrFriendAssembly (Parent.Module.Assembly, p.Assembly);
break;
if (al == Modifiers.PRIVATE) {
var decl = mc.Parent;
do {
- same_access_restrictions = TypeManager.IsEqual (decl.TypeBuilder, p_parent);
+ same_access_restrictions = decl.CurrentType == p_parent;
} while (!same_access_restrictions && !decl.IsTopLevel && (decl = decl.Parent) != null);
}
if ((caching_flags & Flags.ClsCompliance_Undetected) == 0)
return (caching_flags & Flags.ClsCompliant) != 0;
- if (GetClsCompliantAttributeValue () && IsExposedFromAssembly ()) {
- caching_flags &= ~Flags.ClsCompliance_Undetected;
+ caching_flags &= ~Flags.ClsCompliance_Undetected;
+
+ if (HasClsCompliantAttribute) {
+ if ((caching_flags & Flags.ClsCompliantAttributeFalse) != 0)
+ return false;
+
+ caching_flags |= Flags.ClsCompliant;
+ return true;
+ }
+
+ if (Parent.PartialContainer.IsClsComplianceRequired ()) {
caching_flags |= Flags.ClsCompliant;
return true;
}
- caching_flags &= ~Flags.ClsCompliance_Undetected;
return false;
}
+ public virtual string[] ConditionalConditions ()
+ {
+ return null;
+ }
+
/// <summary>
/// Returns true when MemberCore is exposed from assembly.
/// </summary>
return true;
}
- public virtual ExtensionMethodGroupExpr LookupExtensionMethod (Type extensionType, string name, Location loc)
+ public virtual ExtensionMethodGroupExpr LookupExtensionMethod (TypeSpec extensionType, string name, int arity, Location loc)
{
- return Parent.LookupExtensionMethod (extensionType, name, loc);
+ return Parent.LookupExtensionMethod (extensionType, name, arity, loc);
}
public virtual FullNamedExpression LookupNamespaceAlias (string name)
return Parent.NamespaceEntry.LookupNamespaceAlias (name);
}
- public virtual FullNamedExpression LookupNamespaceOrType (string name, Location loc, bool ignore_cs0104)
+ public virtual FullNamedExpression LookupNamespaceOrType (string name, int arity, Location loc, bool ignore_cs0104)
{
- return Parent.LookupNamespaceOrType (name, loc, ignore_cs0104);
+ return Parent.LookupNamespaceOrType (name, arity, loc, ignore_cs0104);
}
/// <summary>
/// Goes through class hierarchy and gets value of first found CLSCompliantAttribute.
/// If no is attribute exists then assembly CLSCompliantAttribute is returned.
/// </summary>
- public virtual bool GetClsCompliantAttributeValue ()
+ public bool IsNotCLSCompliant ()
{
if ((caching_flags & Flags.HasCompliantAttribute_Undetected) == 0)
- return (caching_flags & Flags.ClsCompliantAttributeTrue) != 0;
+ return (caching_flags & Flags.ClsCompliantAttributeFalse) != 0;
caching_flags &= ~Flags.HasCompliantAttribute_Undetected;
if (OptAttributes != null) {
- Attribute cls_attribute = OptAttributes.Search (
- PredefinedAttributes.Get.CLSCompliant);
+ Attribute cls_attribute = OptAttributes.Search (PredefinedAttributes.Get.CLSCompliant);
if (cls_attribute != null) {
caching_flags |= Flags.HasClsCompliantAttribute;
- bool value = cls_attribute.GetClsCompliantAttributeValue ();
- if (value)
- caching_flags |= Flags.ClsCompliantAttributeTrue;
- return value;
+ if (cls_attribute.GetClsCompliantAttributeValue ())
+ return false;
+
+ caching_flags |= Flags.ClsCompliantAttributeFalse;
+ return true;
}
}
-
- // It's null for TypeParameter
- if (Parent == null)
- return false;
- if (Parent.GetClsCompliantAttributeValue ()) {
- caching_flags |= Flags.ClsCompliantAttributeTrue;
- return true;
- }
return false;
}
protected bool HasClsCompliantAttribute {
get {
if ((caching_flags & Flags.HasCompliantAttribute_Undetected) != 0)
- GetClsCompliantAttributeValue ();
+ IsNotCLSCompliant ();
return (caching_flags & Flags.HasClsCompliantAttribute) != 0;
}
/// </summary>
protected virtual bool VerifyClsCompliance ()
{
- if (!IsClsComplianceRequired ()) {
- if (HasClsCompliantAttribute && Report.WarningLevel >= 2) {
- if (!IsExposedFromAssembly ()) {
- Attribute a = OptAttributes.Search (PredefinedAttributes.Get.CLSCompliant);
- Report.Warning (3019, 2, a.Location, "CLS compliance checking will not be performed on `{0}' because it is not visible from outside this assembly", GetSignatureForError ());
- }
-
- if (!CodeGen.Assembly.IsClsCompliant) {
- Attribute a = OptAttributes.Search (PredefinedAttributes.Get.CLSCompliant);
- Report.Warning (3021, 2, a.Location, "`{0}' does not need a CLSCompliant attribute because the assembly is not marked as CLS-compliant", GetSignatureForError ());
+ if (HasClsCompliantAttribute) {
+ if (CodeGen.Assembly.ClsCompliantAttribute == null) {
+ Attribute a = OptAttributes.Search (PredefinedAttributes.Get.CLSCompliant);
+ if ((caching_flags & Flags.ClsCompliantAttributeFalse) != 0) {
+ Report.Warning (3021, 2, a.Location,
+ "`{0}' does not need a CLSCompliant attribute because the assembly is not marked as CLS-compliant",
+ GetSignatureForError ());
+ } else {
+ Report.Warning (3014, 1, a.Location,
+ "`{0}' cannot be marked as CLS-compliant because the assembly is not marked as CLS-compliant",
+ GetSignatureForError ());
}
+ return false;
}
- return false;
- }
- if (HasClsCompliantAttribute) {
- if (CodeGen.Assembly.ClsCompliantAttribute == null && !CodeGen.Assembly.IsClsCompliant) {
+ if (!IsExposedFromAssembly ()) {
Attribute a = OptAttributes.Search (PredefinedAttributes.Get.CLSCompliant);
- Report.Warning (3014, 1, a.Location,
- "`{0}' cannot be marked as CLS-compliant because the assembly is not marked as CLS-compliant",
- GetSignatureForError ());
+ Report.Warning (3019, 2, a.Location, "CLS compliance checking will not be performed on `{0}' because it is not visible from outside this assembly", GetSignatureForError ());
+ return false;
+ }
+
+ if ((caching_flags & Flags.ClsCompliantAttributeFalse) != 0) {
+ if (Parent.Kind == MemberKind.Interface && Parent.IsClsComplianceRequired ()) {
+ Report.Warning (3010, 1, Location, "`{0}': CLS-compliant interfaces must have only CLS-compliant members", GetSignatureForError ());
+ } else if (Parent.Kind == MemberKind.Class && (ModFlags & Modifiers.ABSTRACT) != 0 && Parent.IsClsComplianceRequired ()) {
+ Report.Warning (3011, 1, Location, "`{0}': only CLS-compliant members can be abstract", GetSignatureForError ());
+ }
+
return false;
}
- if (!Parent.IsClsComplianceRequired ()) {
+ if (Parent.Parent != null && !Parent.IsClsComplianceRequired ()) {
Attribute a = OptAttributes.Search (PredefinedAttributes.Get.CLSCompliant);
- Report.Warning (3018, 1, a.Location, "`{0}' cannot be marked as CLS-compliant because it is a member of non CLS-compliant type `{1}'",
+ Report.Warning (3018, 1, a.Location, "`{0}' cannot be marked as CLS-compliant because it is a member of non CLS-compliant type `{1}'",
GetSignatureForError (), Parent.GetSignatureForError ());
return false;
}
+ } else {
+ if (!IsExposedFromAssembly ())
+ return false;
+
+ if (!Parent.PartialContainer.IsClsComplianceRequired ())
+ return false;
}
if (member_name.Name [0] == '_') {
Report.Warning (3008, 1, Location, "Identifier `{0}' is not CLS-compliant", GetSignatureForError () );
}
+
return true;
}
#region IMemberContext Members
public virtual CompilerContext Compiler {
- get { return Parent.Module.Compiler; }
+ get { return Parent.Compiler; }
}
- public virtual Type CurrentType {
+ public virtual TypeSpec CurrentType {
get { return Parent.CurrentType; }
}
- public virtual TypeContainer CurrentTypeDefinition {
- get { return Parent.CurrentTypeDefinition; }
+ public MemberCore CurrentMemberDefinition {
+ get { return this; }
}
public virtual TypeParameter[] CurrentTypeParameters {
get { return null; }
}
+ public virtual bool HasUnresolvedConstraints {
+ get { return false; }
+ }
+
public bool IsObsolete {
get {
- if (GetObsoleteAttribute () != null)
+ if (GetAttributeObsolete () != null)
return true;
return Parent == null ? false : Parent.IsObsolete;
}
public bool IsStatic {
- get { return (ModFlags & Modifiers.STATIC) != 0; }
+ get {
+ return (ModFlags & Modifiers.STATIC) != 0;
+ }
}
#endregion
protected enum StateFlags
{
Obsolete_Undetected = 1, // Obsolete attribute has not been detected yet
- Obsolete = 1 << 1 // Member has obsolete attribute
+ Obsolete = 1 << 1, // Member has obsolete attribute
+ CLSCompliant_Undetected = 1 << 3, // CLSCompliant attribute has not been detected yet
+ CLSCompliant = 1 << 4, // Member is CLS Compliant
+
+ IsAccessor = 1 << 9, // Method is an accessor
+ IsGeneric = 1 << 10, // Member contains type arguments
+
+ PendingMetaInflate = 1 << 12,
+ PendingMakeMethod = 1 << 13,
+ PendingMemberCacheMembers = 1 << 14,
+ PendingBaseTypeInflate = 1 << 15,
+ InterfacesExpanded = 1 << 16,
+ IsNotRealProperty = 1 << 17,
}
- readonly Modifiers modifiers;
- readonly string name;
+ protected Modifiers modifiers;
protected StateFlags state;
protected IMemberDefinition definition;
public readonly MemberKind Kind;
+ protected TypeSpec declaringType;
+
+#if DEBUG
+ static int counter;
+ public int ID = counter++;
+#endif
- protected MemberSpec (MemberKind kind, IMemberDefinition definition, string name, Modifiers modifiers)
+ protected MemberSpec (MemberKind kind, TypeSpec declaringType, IMemberDefinition definition, Modifiers modifiers)
{
+ this.Kind = kind;
+ this.declaringType = declaringType;
this.definition = definition;
- this.name = name;
this.modifiers = modifiers;
- state = StateFlags.Obsolete_Undetected;
+ state = StateFlags.Obsolete_Undetected | StateFlags.CLSCompliant_Undetected;
+ }
+
+ #region Properties
+
+ public Assembly Assembly {
+ get {
+ return definition.Assembly;
+ }
+ }
+
+ public virtual int Arity {
+ get {
+ return 0;
+ }
+ }
+
+ public TypeSpec DeclaringType {
+ get {
+ return declaringType;
+ }
+ set {
+ declaringType = value;
+ }
+ }
+
+ public IMemberDefinition MemberDefinition {
+ get {
+ return definition;
+ }
+ }
+
+ public Modifiers Modifiers {
+ get {
+ return modifiers;
+ }
+ set {
+ modifiers = value;
+ }
+ }
+
+ public virtual string Name {
+ get {
+ return definition.Name;
+ }
+ }
+
+ public bool IsAbstract {
+ get { return (modifiers & Modifiers.ABSTRACT) != 0; }
+ }
+
+ public bool IsAccessor {
+ get {
+ return (state & StateFlags.IsAccessor) != 0;
+ }
+ set {
+ state = value ? state | StateFlags.IsAccessor : state & ~StateFlags.IsAccessor;
+ }
+ }
+
+ //
+ // Return true when this member is a generic in C# terms
+ // therefore nested non-generic type of generic type will
+ // return false
+ //
+ public bool IsGeneric {
+ get {
+ return (state & StateFlags.IsGeneric) != 0;
+ }
+ set {
+ state = value ? state | StateFlags.IsGeneric : state & ~StateFlags.IsGeneric;
+ }
+ }
+
+ public bool IsPrivate {
+ get { return (modifiers & Modifiers.PRIVATE) != 0; }
+ }
+
+ public bool IsStatic {
+ get {
+ return (modifiers & Modifiers.STATIC) != 0;
+ }
}
- public abstract Type DeclaringType { get; }
+ #endregion
- public ObsoleteAttribute GetObsoleteAttribute ()
+ public virtual ObsoleteAttribute GetAttributeObsolete ()
{
if ((state & (StateFlags.Obsolete | StateFlags.Obsolete_Undetected)) == 0)
return null;
state &= ~StateFlags.Obsolete_Undetected;
- var oa = definition.GetObsoleteAttribute ();
+ var oa = definition.GetAttributeObsolete ();
if (oa != null)
state |= StateFlags.Obsolete;
return oa;
}
- public IMemberDefinition MemberDefinition {
- get { return definition; }
+ protected virtual bool IsNotCLSCompliant ()
+ {
+ return MemberDefinition.IsNotCLSCompliant ();
}
- public Modifiers Modifiers {
- get { return modifiers; }
+ public virtual string GetSignatureForError ()
+ {
+ var bf = MemberDefinition as Property.BackingField;
+ var name = bf == null ? Name : bf.OriginalName;
+ return DeclaringType.GetSignatureForError () + "." + name;
}
-
- public string Name {
- get { return name; }
+
+ public virtual MemberSpec InflateMember (TypeParameterInflator inflator)
+ {
+ var inflated = (MemberSpec) MemberwiseClone ();
+ inflated.declaringType = inflator.TypeInstance;
+ inflated.state |= StateFlags.PendingMetaInflate;
+ return inflated;
}
- public bool IsStatic {
- get { return (modifiers & Modifiers.STATIC) != 0; }
+ //
+ // Returns member CLS compliance based on full member hierarchy
+ //
+ public bool IsCLSCompliant ()
+ {
+ if ((state & StateFlags.CLSCompliant_Undetected) != 0) {
+ state &= ~StateFlags.CLSCompliant_Undetected;
+
+ if (IsNotCLSCompliant ())
+ return false;
+
+ bool compliant;
+ if (DeclaringType != null) {
+ compliant = DeclaringType.IsCLSCompliant ();
+ } else {
+ // TODO: NEED AssemblySpec
+ if (MemberDefinition.IsImported) {
+ var attr = MemberDefinition.Assembly.GetCustomAttributes (typeof (CLSCompliantAttribute), false);
+ compliant = attr.Length > 0 && ((CLSCompliantAttribute) attr[0]).IsCompliant;
+ } else {
+ compliant = CodeGen.Assembly.IsClsCompliant;
+ }
+ }
+
+ if (compliant)
+ state |= StateFlags.CLSCompliant;
+ }
+
+ return (state & StateFlags.CLSCompliant) != 0;
+ }
+
+ public bool IsConditionallyExcluded (Location loc)
+ {
+ if ((Kind & (MemberKind.Class | MemberKind.Method)) == 0)
+ return false;
+
+ var conditions = MemberDefinition.ConditionalConditions ();
+ if (conditions == null)
+ return false;
+
+ foreach (var condition in conditions) {
+ if (loc.CompilationUnit.IsConditionalDefined (condition))
+ return false;
+ }
+
+ return true;
+ }
+
+ public override string ToString ()
+ {
+ return GetSignatureForError ();
}
}
//
public interface IMemberDefinition
{
- ObsoleteAttribute GetObsoleteAttribute ();
+ Assembly Assembly { get; }
+ string Name { get; }
+ bool IsImported { get; }
+
+ string[] ConditionalConditions ();
+ ObsoleteAttribute GetAttributeObsolete ();
+ bool IsNotCLSCompliant ();
+ void SetIsAssigned ();
void SetIsUsed ();
}
- /// <summary>
- /// Base class for structs, classes, enumerations and interfaces.
- /// </summary>
- /// <remarks>
- /// They all create new declaration spaces. This
- /// provides the common foundation for managing those name
- /// spaces.
- /// </remarks>
+ public interface IParametersMember : IInterfaceMemberSpec
+ {
+ AParametersCollection Parameters { get; }
+ }
+
+ public interface IInterfaceMemberSpec
+ {
+ TypeSpec MemberType { get; }
+ }
+
+ //
+ // Base type container declaration. It exists to handle partial types
+ // which share same definition (PartialContainer) but have different
+ // resolve scopes
+ //
public abstract class DeclSpace : MemberCore {
/// <summary>
/// This points to the actual definition that is being
/// </summary>
public TypeBuilder TypeBuilder;
- /// <summary>
- /// If we are a generic type, this is the type we are
- /// currently defining. We need to lookup members on this
- /// instead of the TypeBuilder.
- /// </summary>
- protected Type currentType;
-
//
// This is the namespace in which this typecontainer
// was declared. We use this to resolve names.
defined_names.TryGetValue (name, out mc);
return mc;
}
-
- public bool IsStaticClass {
- get { return (ModFlags & Modifiers.STATIC) != 0; }
- }
-
+
//
// root_types contains all the types. All TopLevel types
// hence have a parent that points to `root_types', that is
return false;
}
- public virtual void CloseType ()
- {
- if ((caching_flags & Flags.CloseTypeCreated) == 0){
- try {
- TypeBuilder.CreateType ();
- } catch {
- //
- // The try/catch is needed because
- // nested enumerations fail to load when they
- // are defined.
- //
- // Even if this is the right order (enumerations
- // declared after types).
- //
- // Note that this still creates the type and
- // it is possible to save it
- }
- caching_flags |= Flags.CloseTypeCreated;
- }
- }
-
protected virtual TypeAttributes TypeAttr {
get { return Module.DefaultCharSetType; }
}
type.GetSignatureForError ());
}
- public override void Emit ()
- {
- if (type_params != null) {
- int offset = count_type_params - type_params.Length;
- for (int i = offset; i < type_params.Length; i++)
- CurrentTypeParameters [i - offset].Emit ();
- }
-
- if ((ModFlags & Modifiers.COMPILER_GENERATED) != 0 && !Parent.IsCompilerGenerated)
- PredefinedAttributes.Get.CompilerGenerated.EmitAttribute (TypeBuilder);
-
- base.Emit ();
- }
-
public override string GetSignatureForError ()
- {
+ {
return MemberName.GetSignatureForError ();
}
- public bool CheckAccessLevel (Type check_type)
+ public bool CheckAccessLevel (TypeSpec check_type)
{
- Type tb = TypeBuilder;
+ TypeSpec tb = PartialContainer.Definition;
+ check_type = check_type.GetDefinition ();
- if (this is GenericMethod) {
- tb = Parent.TypeBuilder;
-
- // FIXME: Generic container does not work with nested generic
- // anonymous method stories
- if (TypeBuilder == null)
- return true;
- }
-
- check_type = TypeManager.DropGenericTypeArguments (check_type);
- if (check_type == tb)
- return true;
-
- // TODO: When called from LocalUsingAliasEntry tb is null
- // because we are in RootDeclSpace
- if (tb == null)
- tb = typeof (RootDeclSpace);
-
- //
- // Broken Microsoft runtime, return public for arrays, no matter what
- // the accessibility is for their underlying class, and they return
- // NonPublic visibility for pointers
- //
- if (TypeManager.HasElementType (check_type))
- return CheckAccessLevel (TypeManager.GetElementType (check_type));
-
- if (TypeManager.IsGenericParameter (check_type))
- return true;
-
- TypeAttributes check_attr = check_type.Attributes & TypeAttributes.VisibilityMask;
+ var check_attr = check_type.Modifiers & Modifiers.AccessibilityMask;
switch (check_attr){
- case TypeAttributes.Public:
+ case Modifiers.PUBLIC:
return true;
- case TypeAttributes.NotPublic:
- return TypeManager.IsThisOrFriendAssembly (Module.Assembly, check_type.Assembly);
+ case Modifiers.INTERNAL:
+ return TypeManager.IsThisOrFriendAssembly (Assembly, check_type.Assembly);
- case TypeAttributes.NestedPublic:
- return CheckAccessLevel (check_type.DeclaringType);
+ case Modifiers.PRIVATE:
+ TypeSpec declaring = check_type.DeclaringType;
+ return tb == declaring.GetDefinition () || TypeManager.IsNestedChildOf (tb, declaring);
- case TypeAttributes.NestedPrivate:
- Type declaring = check_type.DeclaringType;
- return tb == declaring || TypeManager.IsNestedChildOf (tb, declaring);
-
- case TypeAttributes.NestedFamily:
+ case Modifiers.PROTECTED:
//
// Only accessible to methods in current type or any subtypes
//
- return FamilyAccessible (tb, check_type);
-
- case TypeAttributes.NestedFamANDAssem:
- return TypeManager.IsThisOrFriendAssembly (Module.Assembly, check_type.Assembly) &&
- FamilyAccessible (tb, check_type);
+ return TypeManager.IsNestedFamilyAccessible (tb, check_type.DeclaringType);
- case TypeAttributes.NestedFamORAssem:
- return FamilyAccessible (tb, check_type) ||
- TypeManager.IsThisOrFriendAssembly (Module.Assembly, check_type.Assembly);
+ case Modifiers.PROTECTED | Modifiers.INTERNAL:
+ if (TypeManager.IsThisOrFriendAssembly (Assembly, check_type.Assembly))
+ return true;
- case TypeAttributes.NestedAssembly:
- return TypeManager.IsThisOrFriendAssembly (Module.Assembly, check_type.Assembly);
+ goto case Modifiers.PROTECTED;
}
throw new NotImplementedException (check_attr.ToString ());
}
- static bool FamilyAccessible (Type tb, Type check_type)
- {
- Type declaring = check_type.DeclaringType;
- return TypeManager.IsNestedFamilyAccessible (tb, declaring);
- }
-
- public bool IsBaseType (Type baseType)
+ private TypeSpec LookupNestedTypeInHierarchy (string name, int arity)
{
- // We are called from RootDeclspace
- if (TypeBuilder == null)
- return false;
-
- return TypeManager.IsSubclassOf (TypeBuilder, baseType);
- }
-
- private Type LookupNestedTypeInHierarchy (string name)
- {
- Type t = null;
- // if the member cache has been created, lets use it.
- // the member cache is MUCH faster.
- if (MemberCache != null) {
- t = MemberCache.FindNestedType (name);
- if (t == null)
- return null;
- }
-
- //
- // FIXME: This hack is needed because member cache does not work
- // with nested base generic types, it does only type name copy and
- // not type construction
- //
+ // TODO: GenericMethod only
+ if (PartialContainer == null)
+ return null;
- // no member cache. Do it the hard way -- reflection
- for (Type current_type = TypeBuilder;
- current_type != null && current_type != TypeManager.object_type;
- current_type = current_type.BaseType) {
-
- Type ct = TypeManager.DropGenericTypeArguments (current_type);
- if (ct is TypeBuilder) {
- TypeContainer tc = ct == TypeBuilder
- ? PartialContainer : TypeManager.LookupTypeContainer (ct);
- if (tc != null)
- t = tc.FindNestedType (name);
- } else {
- t = TypeManager.GetNestedType (ct, name);
- }
+ // Has any nested type
+ // Does not work, because base type can have
+ //if (PartialContainer.Types == null)
+ // return null;
- if ((t == null) || !CheckAccessLevel (t))
- continue;
+ var container = PartialContainer.CurrentType;
- if (!TypeManager.IsGenericType (current_type))
- return t;
+ // Is not Root container
+ if (container == null)
+ return null;
- Type[] args = TypeManager.GetTypeArguments (current_type);
- Type[] targs = TypeManager.GetTypeArguments (t);
- for (int i = 0; i < args.Length; i++)
- targs [i] = TypeManager.TypeToCoreType (args [i]);
+ var t = MemberCache.FindNestedType (container, name, arity);
+ if (t == null)
+ return null;
- return t.MakeGenericType (targs);
- }
+ // FIXME: Breaks error reporting
+ if (!CheckAccessLevel (t))
+ return null;
- return null;
+ return t;
}
//
//
// Returns: Type or null if they type can not be found.
//
- public override FullNamedExpression LookupNamespaceOrType (string name, Location loc, bool ignore_cs0104)
+ public override FullNamedExpression LookupNamespaceOrType (string name, int arity, Location loc, bool ignore_cs0104)
{
FullNamedExpression e;
- if (Cache.TryGetValue (name, out e))
+ if (arity == 0 && Cache.TryGetValue (name, out e))
return e;
e = null;
int errors = Report.Errors;
- TypeParameter[] tp = CurrentTypeParameters;
- if (tp != null) {
- TypeParameter tparam = TypeParameter.FindTypeParameter (tp, name);
- if (tparam != null)
- e = new TypeParameterExpr (tparam, Location.Null);
+ if (arity == 0) {
+ TypeParameter[] tp = CurrentTypeParameters;
+ if (tp != null) {
+ TypeParameter tparam = TypeParameter.FindTypeParameter (tp, name);
+ if (tparam != null)
+ e = new TypeParameterExpr (tparam, Location.Null);
+ }
}
if (e == null) {
- Type t = LookupNestedTypeInHierarchy (name);
+ TypeSpec t = LookupNestedTypeInHierarchy (name, arity);
if (t != null)
e = new TypeExpression (t, Location.Null);
else if (Parent != null)
- e = Parent.LookupNamespaceOrType (name, loc, ignore_cs0104);
+ e = Parent.LookupNamespaceOrType (name, arity, loc, ignore_cs0104);
else
- e = NamespaceEntry.LookupNamespaceOrType (name, loc, ignore_cs0104);
+ e = NamespaceEntry.LookupNamespaceOrType (name, arity, loc, ignore_cs0104);
}
- if (errors == Report.Errors)
+ // TODO MemberCache: How to cache arity stuff ?
+ if (errors == Report.Errors && arity == 0)
Cache [name] = e;
return e;
}
- /// <remarks>
- /// This function is broken and not what you're looking for. It should only
- /// be used while the type is still being created since it doesn't use the cache
- /// and relies on the filter doing the member name check.
- /// </remarks>
- ///
- // [Obsolete ("Only MemberCache approach should be used")]
- public virtual MemberList FindMembers (MemberTypes mt, BindingFlags bf,
- MemberFilter filter, object criteria)
- {
- throw new NotSupportedException ();
- }
-
- /// <remarks>
- /// If we have a MemberCache, return it. This property may return null if the
- /// class doesn't have a member cache or while it's still being created.
- /// </remarks>
- public abstract MemberCache MemberCache {
- get;
+ public override Assembly Assembly {
+ get { return Module.Assembly; }
}
public virtual ModuleContainer Module {
get { return Parent.Module; }
}
- public override void ApplyAttributeBuilder (Attribute a, ConstructorInfo ctor, byte[] cdata, PredefinedAttributes pa)
- {
- if (a.Type == pa.Required) {
- Report.Error (1608, a.Location, "The RequiredAttribute attribute is not permitted on C# types");
- return;
- }
-
- TypeBuilder.SetCustomAttribute (ctor, cdata);
- }
-
TypeParameter[] initialize_type_params ()
{
if (type_param_list != null)
}
type_params [i] = new TypeParameter (
- Parent, this, name.Name, constraints, name.OptAttributes, variance, Location);
+ Parent, i, new MemberName (name.Name, Location), constraints, name.OptAttributes, variance);
AddToContainer (type_params [i], name.Name);
}
}
}
- public TypeParameter[] TypeParameters {
+ protected TypeParameter[] TypeParameters {
get {
if (!IsGeneric)
throw new InvalidOperationException ();
}
}
- public override Type CurrentType {
- get { return currentType != null ? currentType : TypeBuilder; }
- }
-
- public override TypeContainer CurrentTypeDefinition {
- get { return PartialContainer; }
- }
-
public int CountTypeParameters {
get {
return count_type_params;
}
}
- // Used for error reporting only
- public virtual Type LookupAnyGeneric (string typeName)
- {
- return NamespaceEntry.NS.LookForAnyGenericType (typeName);
- }
-
public override string[] ValidAttributeTargets {
get { return attribute_targets; }
}
if (type_params != null) {
foreach (TypeParameter tp in type_params) {
- if (tp.Constraints == null)
- continue;
-
- tp.Constraints.VerifyClsCompliance (Report);
+ tp.VerifyClsCompliance ();
}
}
- var cache = TypeManager.AllClsTopLevelTypes;
- if (cache == null)
- return true;
-
- string lcase = Name.ToLower (System.Globalization.CultureInfo.InvariantCulture);
- if (!cache.ContainsKey (lcase)) {
- cache.Add (lcase, this);
- return true;
- }
-
- object val = cache [lcase];
- if (val == null) {
- Type t = AttributeTester.GetImportedIgnoreCaseClsType (lcase);
- if (t == null)
- return true;
- Report.SymbolRelatedToPreviousError (t);
- }
- else {
- Report.SymbolRelatedToPreviousError ((DeclSpace)val);
- }
-
- Report.Warning (3005, 1, Location, "Identifier `{0}' differing only in case is not CLS-compliant", GetSignatureForError ());
return true;
}
}
using System;
using System.Reflection;
using System.Reflection.Emit;
+using System.Collections.Generic;
namespace Mono.CSharp {
public class Delegate : TypeContainer
{
FullNamedExpression ReturnType;
- public readonly AParametersCollection Parameters;
+ public readonly ParametersCompiled Parameters;
- // TODO: Maybe I can keep member cache only and not the builders
Constructor Constructor;
Method InvokeBuilder;
Method BeginInvokeBuilder;
IsTopLevel ? Modifiers.INTERNAL :
Modifiers.PRIVATE, name.Location, Report);
Parameters = param_list;
+ spec = new TypeSpec (Kind, null, this, null, ModFlags | Modifiers.SEALED);
}
- public override void ApplyAttributeBuilder (Attribute a, ConstructorInfo ctor, byte[] cdata, PredefinedAttributes pa)
+ public override void ApplyAttributeBuilder (Attribute a, MethodSpec ctor, byte[] cdata, PredefinedAttributes pa)
{
if (a.Target == AttributeTargets.ReturnValue) {
if (return_attributes == null)
}
}
- protected override Type BaseType {
+ public override TypeSpec BaseType {
get {
return TypeManager.multicast_delegate_type;
}
protected override bool DoDefineMembers ()
{
- if (IsGeneric) {
- foreach (TypeParameter type_param in TypeParameters) {
- if (!type_param.Resolve (this))
- return false;
- }
-
- foreach (TypeParameter type_param in TypeParameters) {
- if (!type_param.DefineType (this))
- return false;
- }
- }
-
- member_cache = new MemberCache (BaseType, this);
-
var ctor_parameters = ParametersCompiled.CreateFullyResolved (
new [] {
new Parameter (new TypeExpression (TypeManager.object_type, Location), "object", Parameter.Modifier.NONE, null, Location),
// First, call the `out of band' special method for
// defining recursively any types we need:
//
- var p = Parameters.AsCompiled;
+ var p = Parameters;
if (!p.Resolve (this))
return false;
}
if (out_params > 0) {
- var end_param_types = new Type [out_params];
+ var end_param_types = new TypeSpec [out_params];
Parameter[] end_params = new Parameter[out_params];
int param = 0;
for (int i = 0; i < Parameters.FixedParameters.Length; ++i) {
- Parameter p = Parameters.AsCompiled [i];
+ Parameter p = Parameters [i];
if ((p.ModFlags & Parameter.Modifier.ISBYREF) == 0)
continue;
EndInvokeBuilder.Define ();
}
- public override void Emit ()
+ public override void DefineConstants ()
+ {
+ if (!Parameters.IsEmpty && Parameters[Parameters.Count - 1].HasDefaultValue) {
+ var rc = new ResolveContext (this);
+ Parameters.ResolveDefaultValues (rc);
+ }
+ }
+
+ public override void EmitType ()
{
- if (TypeManager.IsDynamicType (ReturnType.Type)) {
+ if (ReturnType.Type == InternalType.Dynamic) {
return_attributes = new ReturnParameter (this, InvokeBuilder.MethodBuilder, Location);
PredefinedAttributes.Get.Dynamic.EmitAttribute (return_attributes.Builder);
} else {
var trans_flags = TypeManager.HasDynamicTypeUsed (ReturnType.Type);
if (trans_flags != null) {
var pa = PredefinedAttributes.Get.DynamicTransform;
- if (pa.Constructor != null || pa.ResolveConstructor (Location, TypeManager.bool_type.MakeArrayType ())) {
+ if (pa.Constructor != null || pa.ResolveConstructor (Location, ArrayContainer.MakeType (TypeManager.bool_type))) {
return_attributes = new ReturnParameter (this, InvokeBuilder.MethodBuilder, Location);
return_attributes.Builder.SetCustomAttribute (
new CustomAttributeBuilder (pa.Constructor, new object [] { trans_flags }));
}
}
- Parameters.AsCompiled.ApplyAttributes (InvokeBuilder.MethodBuilder);
+ Parameters.ApplyAttributes (InvokeBuilder.MethodBuilder);
Constructor.ConstructorBuilder.SetImplementationFlags (MethodImplAttributes.Runtime);
InvokeBuilder.MethodBuilder.SetImplementationFlags (MethodImplAttributes.Runtime);
if (BeginInvokeBuilder != null) {
- BeginInvokeBuilder.Parameters.ApplyAttributes (BeginInvokeBuilder.MethodBuilder);
+ BeginInvokeBuilder.ParameterInfo.ApplyAttributes (BeginInvokeBuilder.MethodBuilder);
BeginInvokeBuilder.MethodBuilder.SetImplementationFlags (MethodImplAttributes.Runtime);
EndInvokeBuilder.MethodBuilder.SetImplementationFlags (MethodImplAttributes.Runtime);
return false;
}
- Parameters.AsCompiled.VerifyClsCompliance (this);
+ Parameters.VerifyClsCompliance (this);
- if (!AttributeTester.IsClsCompliant (ReturnType.Type)) {
+ if (!ReturnType.Type.IsCLSCompliant ()) {
Report.Warning (3002, 1, Location, "Return type of `{0}' is not CLS-compliant",
GetSignatureForError ());
}
}
- public static MethodSpec GetConstructor (CompilerContext ctx, Type container_type, Type delegate_type)
+ public static MethodSpec GetConstructor (CompilerContext ctx, TypeSpec container_type, TypeSpec delType)
{
- Type dt = delegate_type;
- Type[] g_args = null;
- if (TypeManager.IsGenericType (delegate_type)) {
- g_args = TypeManager.GetTypeArguments (delegate_type);
- delegate_type = TypeManager.DropGenericTypeArguments (delegate_type);
- }
-
- Delegate d = TypeManager.LookupDelegate (delegate_type);
- if (d != null) {
- if (g_args != null)
- return Import.CreateMethod (TypeBuilder.GetConstructor (dt, d.Constructor.ConstructorBuilder));
-
- return d.Constructor.Spec;
- }
-
- Expression ml = Expression.MemberLookup (ctx, container_type,
- null, dt, ConstructorInfo.ConstructorName, MemberTypes.Constructor,
- BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly, Location.Null);
-
- MethodGroupExpr mg = ml as MethodGroupExpr;
- if (mg == null) {
- ctx.Report.Error (-100, Location.Null, "Internal error: could not find delegate constructor!");
- // FIXME: null will cause a crash later
- return null;
- }
-
- return mg.Methods[0];
+ var ctor = MemberCache.FindMember (delType, MemberFilter.Constructor (null), BindingRestriction.DeclaredOnly);
+ return (MethodSpec) ctor;
}
//
- // Returns the MethodBase for "Invoke" from a delegate type, this is used
- // to extract the signature of a delegate.
+ // Returns the "Invoke" from a delegate type
//
- public static MethodSpec GetInvokeMethod (CompilerContext ctx, Type container_type, Type delegate_type)
+ public static MethodSpec GetInvokeMethod (CompilerContext ctx, TypeSpec delType)
{
- Type dt = delegate_type;
-
- Type[] g_args = null;
- if (TypeManager.IsGenericType (delegate_type)) {
- g_args = TypeManager.GetTypeArguments (delegate_type);
- delegate_type = TypeManager.DropGenericTypeArguments (delegate_type);
- }
-
- Delegate d = TypeManager.LookupDelegate (delegate_type);
- MethodSpec invoke;
- if (d != null) {
- if (g_args != null) {
- invoke = Import.CreateMethod (TypeBuilder.GetMethod (dt, d.InvokeBuilder.MethodBuilder));
-#if MS_COMPATIBLE
-// ParametersCompiled p = (ParametersCompiled) d.Parameters.InflateTypes (g_args, g_args);
-// TypeManager.RegisterMethod (invoke, p);
-#endif
- return invoke;
- }
- return d.InvokeBuilder.Spec;
- }
-
- Expression ml = Expression.MemberLookup (ctx, container_type, null, dt,
- "Invoke", Location.Null);
-
- MethodGroupExpr mg = ml as MethodGroupExpr;
- if (mg == null) {
- ctx.Report.Error (-100, Location.Null, "Internal error: could not find Invoke method!");
- // FIXME: null will cause a crash later
- return null;
- }
+ var invoke = MemberCache.FindMember (delType,
+ MemberFilter.Method (InvokeMethodName, 0, null, null),
+ BindingRestriction.DeclaredOnly);
- invoke = mg.Methods[0];
-#if MS_COMPATIBLE
-// if (g_args != null) {
-// AParametersCollection p = TypeManager.GetParameterData (invoke);
-// p = p.InflateTypes (g_args, g_args);
-// TypeManager.RegisterMethod (invoke, p);
-// return invoke;
-// }
-#endif
+ return (MethodSpec) invoke;
+ }
- return invoke;
+ public static AParametersCollection GetParameters (CompilerContext ctx, TypeSpec delType)
+ {
+ var invoke_mb = GetInvokeMethod (ctx, delType);
+ return invoke_mb.Parameters;
}
//
// 15.2 Delegate compatibility
//
- public static bool IsTypeCovariant (Expression a, Type b)
+ public static bool IsTypeCovariant (Expression a, TypeSpec b)
{
//
// For each value parameter (a parameter with no ref or out modifier), an
public static string FullDelegateDesc (MethodSpec invoke_method)
{
- return TypeManager.GetFullNameSignature (invoke_method.MetaInfo).Replace (".Invoke", "");
+ return TypeManager.GetFullNameSignature (invoke_method).Replace (".Invoke", "");
}
public Expression InstanceExpression {
Arguments delegate_arguments = new Arguments (pd.Count);
for (int i = 0; i < pd.Count; ++i) {
Argument.AType atype_modifier;
- Type atype = pd.Types [i];
+ TypeSpec atype = pd.Types [i];
switch (pd.FixedParameters [i].ModFlags) {
case Parameter.Modifier.REF:
atype_modifier = Argument.AType.Ref;
{
constructor_method = Delegate.GetConstructor (ec.Compiler, ec.CurrentType, type);
- var invoke_method = Delegate.GetInvokeMethod (ec.Compiler, ec.CurrentType, type);
+ var invoke_method = Delegate.GetInvokeMethod (ec.Compiler, type);
method_group.DelegateType = type;
method_group.CustomErrorHandler = this;
if (TypeManager.IsNullableType (delegate_method.DeclaringType)) {
ec.Report.Error (1728, loc, "Cannot create delegate from method `{0}' because it is a member of System.Nullable<T> type",
- TypeManager.GetFullNameSignature (delegate_method.MetaInfo));
+ TypeManager.GetFullNameSignature (delegate_method));
return null;
}
ExtensionMethodGroupExpr emg = method_group as ExtensionMethodGroupExpr;
if (emg != null) {
delegate_instance_expression = emg.ExtensionExpression;
- Type e_type = delegate_instance_expression.Type;
+ TypeSpec e_type = delegate_instance_expression.Type;
if (TypeManager.IsValueType (e_type)) {
ec.Report.Error (1113, loc, "Extension method `{0}' of value type `{1}' cannot be used to create delegates",
- TypeManager.CSharpSignature (delegate_method.MetaInfo), TypeManager.CSharpName (e_type));
+ delegate_method.GetSignatureForError (), TypeManager.CSharpName (e_type));
}
}
- Type rt = TypeManager.TypeToCoreType (delegate_method.ReturnType);
+ TypeSpec rt = delegate_method.ReturnType;
Expression ret_expr = new TypeExpression (rt, loc);
- if (!Delegate.IsTypeCovariant (ret_expr, (TypeManager.TypeToCoreType (invoke_method.ReturnType)))) {
+ if (!Delegate.IsTypeCovariant (ret_expr, invoke_method.ReturnType)) {
Error_ConversionFailed (ec, delegate_method, ret_expr);
}
- if (Invocation.IsMethodExcluded (delegate_method, loc)) {
- ec.Report.SymbolRelatedToPreviousError (delegate_method.MetaInfo);
- MethodOrOperator m = TypeManager.GetMethod (delegate_method.MetaInfo) as MethodOrOperator;
+ if (delegate_method.IsConditionallyExcluded (loc)) {
+ ec.Report.SymbolRelatedToPreviousError (delegate_method);
+ MethodOrOperator m = delegate_method.MemberDefinition as MethodOrOperator;
if (m != null && m.IsPartialDefinition) {
ec.Report.Error (762, loc, "Cannot create delegate from partial method declaration `{0}'",
- TypeManager.CSharpSignature (delegate_method.MetaInfo));
+ delegate_method.GetSignatureForError ());
} else {
ec.Report.Error (1618, loc, "Cannot create delegate with `{0}' because it has a Conditional attribute",
- TypeManager.CSharpSignature (delegate_method.MetaInfo));
+ TypeManager.CSharpSignature (delegate_method));
}
}
Expression instance = method_group.InstanceExpression;
if (instance != null && instance != EmptyExpression.Null) {
delegate_instance_expression = instance;
- Type instance_type = delegate_instance_expression.Type;
+ TypeSpec instance_type = delegate_instance_expression.Type;
if (TypeManager.IsValueType (instance_type) || TypeManager.IsGenericParameter (instance_type)) {
delegate_instance_expression = new BoxedCast (
delegate_instance_expression, TypeManager.object_type);
public override void Emit (EmitContext ec)
{
if (delegate_instance_expression == null)
- ec.ig.Emit (OpCodes.Ldnull);
+ ec.Emit (OpCodes.Ldnull);
else
delegate_instance_expression.Emit (ec);
- if (!delegate_method.DeclaringType.IsSealed && delegate_method.IsVirtual && !method_group.IsBase) {
- ec.ig.Emit (OpCodes.Dup);
- ec.ig.Emit (OpCodes.Ldvirtftn, (MethodInfo) delegate_method.MetaInfo);
+ // Any delegate must be sealed
+ if (!delegate_method.DeclaringType.IsDelegate && delegate_method.IsVirtual && !method_group.IsBase) {
+ ec.Emit (OpCodes.Dup);
+ ec.Emit (OpCodes.Ldvirtftn, delegate_method);
} else {
- ec.ig.Emit (OpCodes.Ldftn, (MethodInfo) delegate_method.MetaInfo);
+ ec.Emit (OpCodes.Ldftn, delegate_method);
}
- ec.ig.Emit (OpCodes.Newobj, (ConstructorInfo) constructor_method.MetaInfo);
+ ec.Emit (OpCodes.Newobj, constructor_method);
}
void Error_ConversionFailed (ResolveContext ec, MethodSpec method, Expression return_type)
{
- var invoke_method = Delegate.GetInvokeMethod (ec.Compiler, ec.CurrentType, type);
+ var invoke_method = Delegate.GetInvokeMethod (ec.Compiler, type);
string member_name = delegate_instance_expression != null ?
Delegate.FullDelegateDesc (method) :
- TypeManager.GetFullNameSignature (method.MetaInfo);
+ TypeManager.GetFullNameSignature (method);
ec.Report.SymbolRelatedToPreviousError (type);
- ec.Report.SymbolRelatedToPreviousError (method.MetaInfo);
+ ec.Report.SymbolRelatedToPreviousError (method);
if (RootContext.Version == LanguageVersion.ISO_1) {
ec.Report.Error (410, loc, "A method or delegate `{0} {1}' parameters and return type must be same as delegate `{2} {3}' parameters and return type",
TypeManager.CSharpName (method.ReturnType), member_name,
TypeManager.CSharpName (invoke_method.ReturnType), Delegate.FullDelegateDesc (invoke_method));
}
- public static bool ImplicitStandardConversionExists (ResolveContext ec, MethodGroupExpr mg, Type target_type)
+ public static bool ImplicitStandardConversionExists (ResolveContext ec, MethodGroupExpr mg, TypeSpec target_type)
{
if (target_type == TypeManager.delegate_type || target_type == TypeManager.multicast_delegate_type)
return false;
mg.DelegateType = target_type;
- var invoke = Delegate.GetInvokeMethod (ec.Compiler, null, target_type);
+ var invoke = Delegate.GetInvokeMethod (ec.Compiler, target_type);
Arguments arguments = CreateDelegateMethodArguments (invoke.Parameters, mg.Location);
return mg.OverloadResolve (ec, ref arguments, true, mg.Location) != null;
}
- public override void MutateHoistedGenericType (AnonymousMethodStorey storey)
- {
- if (delegate_instance_expression != null)
- delegate_instance_expression.MutateHoistedGenericType (storey);
-
- storey.MutateGenericMethod (delegate_method);
- storey.MutateConstructor (constructor_method);
- }
-
#region IErrorHandler Members
public bool NoExactMatch (ResolveContext ec, MethodSpec method)
{
- if (method.IsGenericMethod)
+ if (method.IsGeneric)
return false;
Error_ConversionFailed (ec, method, null);
//
public class ImplicitDelegateCreation : DelegateCreation
{
- ImplicitDelegateCreation (Type t, MethodGroupExpr mg, Location l)
+ ImplicitDelegateCreation (TypeSpec t, MethodGroupExpr mg, Location l)
{
type = t;
this.method_group = mg;
}
static public Expression Create (ResolveContext ec, MethodGroupExpr mge,
- Type target_type, Location loc)
+ TypeSpec target_type, Location loc)
{
ImplicitDelegateCreation d = new ImplicitDelegateCreation (target_type, mge, loc);
return d.DoResolve (ec);
//
// This constructor is invoked from the `New' expression
//
- public NewDelegate (Type type, Arguments Arguments, Location loc)
+ public NewDelegate (TypeSpec type, Arguments Arguments, Location loc)
{
this.type = type;
this.Arguments = Arguments;
method_group = e as MethodGroupExpr;
if (method_group == null) {
- if (TypeManager.IsDynamicType (e.Type)) {
+ if (e.Type == InternalType.Dynamic) {
e = Convert.ImplicitConversionRequired (ec, e, type, loc);
- } else if (!TypeManager.IsDelegateType (e.Type)) {
+ } else if (!e.Type.IsDelegate) {
e.Error_UnexpectedKind (ec, ResolveFlags.MethodGroup | ResolveFlags.Type, loc);
return null;
}
// An argument is not a method but another delegate
//
delegate_instance_expression = e;
- method_group = new MethodGroupExpr (new [] {
- Delegate.GetInvokeMethod (ec.Compiler, ec.CurrentType, e.Type) }, e.Type, loc);
+ method_group = new MethodGroupExpr (Delegate.GetInvokeMethod (ec.Compiler, e.Type), e.Type, loc);
}
return base.DoResolve (ec);
return null;
}
- Type del_type = InstanceExpr.Type;
+ TypeSpec del_type = InstanceExpr.Type;
if (del_type == null)
return null;
- method = Delegate.GetInvokeMethod (ec.Compiler, ec.CurrentType, del_type);
+ method = Delegate.GetInvokeMethod (ec.Compiler, del_type);
var mb = method;
- var me = new MethodGroupExpr (new [] { mb }, del_type, loc);
+ var me = new MethodGroupExpr (mb, del_type, loc);
me.InstanceExpression = InstanceExpr;
AParametersCollection pd = mb.Parameters;
is_params_applicable || (!is_applicable && params_method), false, loc);
}
- type = TypeManager.TypeToCoreType (method.ReturnType);
+ type = method.ReturnType;
eclass = ExprClass.Value;
return this;
}
// Pop the return value if there is one
//
if (type != TypeManager.void_type)
- ec.ig.Emit (OpCodes.Pop);
+ ec.Emit (OpCodes.Pop);
}
public override System.Linq.Expressions.Expression MakeExpression (BuilderContext ctx)
{
return Invocation.MakeExpression (ctx, InstanceExpr, method, arguments);
}
-
- public override void MutateHoistedGenericType (AnonymousMethodStorey storey)
- {
- storey.MutateGenericMethod (method);
- type = storey.MutateType (type);
-
- if (arguments != null)
- arguments.MutateHoistedGenericType (storey);
-
- InstanceExpr.MutateHoistedGenericType (storey);
- }
}
}
using System.Security.Permissions;
using System.Text;
using System.Xml;
+using System.Linq;
using Mono.CompilerServices.SymbolWriter;
foreach (TypeContainer tc in t.Types)
tc.GenerateDocComment (t);
- if (t.Delegates != null)
- foreach (Delegate de in t.Delegates)
- de.GenerateDocComment (t);
-
if (t.Constants != null)
foreach (Const c in t.Constants)
c.GenerateDocComment (t);
// returns a full runtime type name from a name which might
// be C# specific type name.
//
- private static Type FindDocumentedType (MemberCore mc, string name, DeclSpace ds, string cref, Report r)
+ private static TypeSpec FindDocumentedType (MemberCore mc, string name, DeclSpace ds, string cref, Report r)
{
bool is_array = false;
string identifier = name;
is_array = true;
}
}
- Type t = FindDocumentedTypeNonArray (mc, identifier, ds, cref, r);
+ TypeSpec t = FindDocumentedTypeNonArray (mc, identifier, ds, cref, r);
if (t != null && is_array)
- t = Array.CreateInstance (t, 0).GetType ();
+ t = Import.ImportType (Array.CreateInstance (t.GetMetaInfo (), 0).GetType ());
return t;
}
- private static Type FindDocumentedTypeNonArray (MemberCore mc,
+ private static TypeSpec FindDocumentedTypeNonArray (MemberCore mc,
string identifier, DeclSpace ds, string cref, Report r)
{
switch (identifier) {
case "void":
return TypeManager.void_type;;
}
- FullNamedExpression e = ds.LookupNamespaceOrType (identifier, mc.Location, false);
+ FullNamedExpression e = ds.LookupNamespaceOrType (identifier, 0, mc.Location, false);
if (e != null) {
if (!(e is TypeExpr))
return null;
if (index < 0)
return null;
int warn;
- Type parent = FindDocumentedType (mc, identifier.Substring (0, index), ds, cref, r);
+ TypeSpec parent = FindDocumentedType (mc, identifier.Substring (0, index), ds, cref, r);
if (parent == null)
return null;
// no need to detect warning 419 here
- return FindDocumentedMember (mc, parent,
+ var ts = FindDocumentedMember (mc, parent,
identifier.Substring (index + 1),
- null, ds, out warn, cref, false, null, r).Member as Type;
- }
-
- private static MemberInfo [] empty_member_infos =
- new MemberInfo [0];
-
- private static MemberInfo [] FindMethodBase (Type type,
- BindingFlags binding_flags, MethodSignature signature)
- {
- MemberList ml = TypeManager.FindMembers (
- type,
- MemberTypes.Constructor | MemberTypes.Method | MemberTypes.Property | MemberTypes.Custom,
- binding_flags,
- MethodSignature.method_signature_filter,
- signature);
- if (ml == null)
- return empty_member_infos;
-
- return FilterOverridenMembersOut ((MemberInfo []) ml);
- }
-
- static bool IsOverride (PropertyInfo deriv_prop, PropertyInfo base_prop)
- {
- if (!MethodGroupExpr.IsAncestralType (base_prop.DeclaringType, deriv_prop.DeclaringType))
- return false;
-
- Type [] deriv_pd = TypeManager.GetParameterData (deriv_prop).Types;
- Type [] base_pd = TypeManager.GetParameterData (base_prop).Types;
-
- if (deriv_pd.Length != base_pd.Length)
- return false;
-
- for (int j = 0; j < deriv_pd.Length; ++j) {
- if (deriv_pd [j] != base_pd [j])
- return false;
- Type ct = TypeManager.TypeToCoreType (deriv_pd [j]);
- Type bt = TypeManager.TypeToCoreType (base_pd [j]);
-
- if (ct != bt)
- return false;
- }
-
- return true;
- }
-
- private static MemberInfo [] FilterOverridenMembersOut (
- MemberInfo [] ml)
- {
- if (ml == null)
- return empty_member_infos;
-
- var al = new List<MemberInfo> (ml.Length);
- for (int i = 0; i < ml.Length; i++) {
- MethodBase mx = ml [i] as MethodBase;
- PropertyInfo px = ml [i] as PropertyInfo;
- if (mx != null || px != null) {
- bool overriden = false;
- for (int j = 0; j < ml.Length; j++) {
- if (j == i)
- continue;
- MethodBase my = ml [j] as MethodBase;
- if (mx != null && my != null &&
- MethodGroupExpr.IsOverride (my, mx)) {
- overriden = true;
- break;
- }
- else if (mx != null)
- continue;
- PropertyInfo py = ml [j] as PropertyInfo;
- if (px != null && py != null &&
- IsOverride (py, px)) {
- overriden = true;
- break;
- }
- }
- if (overriden)
- continue;
- }
- al.Add (ml [i]);
- }
- return al.ToArray ();
- }
-
- struct FoundMember
- {
- public static FoundMember Empty = new FoundMember (true);
-
- public bool IsEmpty;
- public readonly MemberInfo Member;
- public readonly Type Type;
-
- public FoundMember (bool regardless_of_this_value_its_empty)
- {
- IsEmpty = true;
- Member = null;
- Type = null;
- }
-
- public FoundMember (Type found_type, MemberInfo member)
- {
- IsEmpty = false;
- Type = found_type;
- Member = member;
- }
+ null, ds, out warn, cref, false, null, r) as TypeSpec;
+ if (ts != null)
+ return ts;
+ return null;
}
//
// Returns a MemberInfo that is referenced in XML documentation
// (by "see" or "seealso" elements).
//
- private static FoundMember FindDocumentedMember (MemberCore mc,
- Type type, string member_name, Type [] param_list,
+ private static MemberSpec FindDocumentedMember (MemberCore mc,
+ TypeSpec type, string member_name, AParametersCollection param_list,
DeclSpace ds, out int warning_type, string cref,
bool warn419, string name_for_error, Report r)
{
- for (; type != null; type = type.DeclaringType) {
- MemberInfo mi = FindDocumentedMemberNoNest (
+// for (; type != null; type = type.DeclaringType) {
+ var mi = FindDocumentedMemberNoNest (
mc, type, member_name, param_list, ds,
out warning_type, cref, warn419,
name_for_error, r);
if (mi != null)
- return new FoundMember (type, mi);
- }
+ return mi; // new FoundMember (type, mi);
+// }
warning_type = 0;
- return FoundMember.Empty;
+ return null;
}
- private static MemberInfo FindDocumentedMemberNoNest (
- MemberCore mc, Type type, string member_name,
- Type [] param_list, DeclSpace ds, out int warning_type,
+ private static MemberSpec FindDocumentedMemberNoNest (
+ MemberCore mc, TypeSpec type, string member_name,
+ AParametersCollection param_list, DeclSpace ds, out int warning_type,
string cref, bool warn419, string name_for_error, Report Report)
{
warning_type = 0;
- MemberInfo [] mis;
+ var filter = new MemberFilter (member_name, 0, MemberKind.All, param_list, null);
+ IList<MemberSpec> found = null;
+ while (type != null && found == null) {
+ found = MemberCache.FindMembers (type, filter, BindingRestriction.None);
+ type = type.DeclaringType;
+ }
+
+ if (found == null)
+ return null;
+ if (warn419 && found.Count > 1) {
+ Report419 (mc, name_for_error, found.ToArray (), Report);
+ }
+
+ return found [0];
+
+/*
if (param_list == null) {
// search for fields/events etc.
mis = TypeManager.MemberLookup (type, null,
- type, MemberTypes.All,
- BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Static | BindingFlags.Instance,
+ type, MemberKind.All,
+ BindingRestriction.None,
member_name, null);
mis = FilterOverridenMembersOut (mis);
if (mis == null || mis.Length == 0)
msig);
if (mis.Length == 0)
return null; // CS1574
- MemberInfo mi = mis [0];
- Type expected = mi is MethodInfo ?
- ((MethodInfo) mi).ReturnType :
- mi is PropertyInfo ?
- ((PropertyInfo) mi).PropertyType :
+ var mi = mis [0];
+ TypeSpec expected = mi is MethodSpec ?
+ ((MethodSpec) mi).ReturnType :
+ mi is PropertySpec ?
+ ((PropertySpec) mi).PropertyType :
null;
if (return_type_name != null) {
- Type returnType = FindDocumentedType (mc, return_type_name, ds, cref, Report);
+ TypeSpec returnType = FindDocumentedType (mc, return_type_name, ds, cref, Report);
if (returnType == null || returnType != expected) {
warning_type = 1581;
Report.Warning (1581, 1, mc.Location, "Invalid return type in XML comment cref attribute `{0}'", cref);
}
}
return mis [0];
- }
-
- private static bool IsAmbiguous (MemberInfo [] members)
- {
- if (members.Length < 2)
- return false;
- if (members.Length > 2)
- return true;
- if (members [0] is EventInfo && members [1] is FieldInfo)
- return false;
- if (members [1] is EventInfo && members [0] is FieldInfo)
- return false;
- return true;
+*/
}
//
}
// check if parameters are valid
- Type [] parameter_types;
+ AParametersCollection parameter_types;
if (parameters == null)
parameter_types = null;
else if (parameters.Length == 0)
- parameter_types = Type.EmptyTypes;
+ parameter_types = ParametersCompiled.EmptyReadOnlyParameters;
else {
string [] param_list = parameters.Split (',');
- var plist = new List<Type> ();
+ var plist = new List<TypeSpec> ();
for (int i = 0; i < param_list.Length; i++) {
string param_type_name = param_list [i].Trim (wsChars);
Normalize (mc, ref param_type_name, Report);
- Type param_type = FindDocumentedType (mc, param_type_name, ds, cref, Report);
+ TypeSpec param_type = FindDocumentedType (mc, param_type_name, ds, cref, Report);
if (param_type == null) {
Report.Warning (1580, 1, mc.Location, "Invalid type for parameter `{0}' in XML comment cref attribute `{1}'",
(i + 1).ToString (), cref);
}
plist.Add (param_type);
}
- parameter_types = plist.ToArray ();
+
+ parameter_types = ParametersCompiled.CreateFullyResolved (plist.ToArray ());
}
- Type type = FindDocumentedType (mc, name, ds, cref, Report);
+ TypeSpec type = FindDocumentedType (mc, name, ds, cref, Report);
if (type != null
// delegate must not be referenced with args
- && (!TypeManager.IsDelegateType (type)
+ && (!type.IsDelegate
|| parameter_types == null)) {
string result = GetSignatureForDoc (type)
+ (brace_pos < 0 ? String.Empty : signature.Substring (brace_pos));
if (period > 0) {
string typeName = name.Substring (0, period);
string member_name = name.Substring (period + 1);
+ string lookup_name = member_name == "this" ? MemberCache.IndexerNameAlias : member_name;
+ Normalize (mc, ref lookup_name, Report);
Normalize (mc, ref member_name, Report);
type = FindDocumentedType (mc, typeName, ds, cref, Report);
int warn_result;
if (type != null) {
- FoundMember fm = FindDocumentedMember (mc, type, member_name, parameter_types, ds, out warn_result, cref, true, name, Report);
+ var mi = FindDocumentedMember (mc, type, lookup_name, parameter_types, ds, out warn_result, cref, true, name, Report);
if (warn_result > 0)
return;
- if (!fm.IsEmpty) {
- MemberInfo mi = fm.Member;
+ if (mi != null) {
// we cannot use 'type' directly
// to get its name, since mi
// could be from DeclaringType
// for nested types.
- xref.SetAttribute ("cref", GetMemberDocHead (mi.MemberType) + GetSignatureForDoc (fm.Type) + "." + member_name + GetParametersFormatted (mi));
+ xref.SetAttribute ("cref", GetMemberDocHead (mi) + GetSignatureForDoc (mi.DeclaringType) + "." + member_name + GetParametersFormatted (mi));
return; // a member of a type
}
}
- }
- else {
+ } else {
int warn_result;
- FoundMember fm = FindDocumentedMember (mc, ds.TypeBuilder, name, parameter_types, ds, out warn_result, cref, true, name, Report);
+ var mi = FindDocumentedMember (mc, ds.PartialContainer.Definition, name, parameter_types, ds, out warn_result, cref, true, name, Report);
+
if (warn_result > 0)
return;
- if (!fm.IsEmpty) {
- MemberInfo mi = fm.Member;
+ if (mi != null) {
// we cannot use 'type' directly
// to get its name, since mi
// could be from DeclaringType
// for nested types.
- xref.SetAttribute ("cref", GetMemberDocHead (mi.MemberType) + GetSignatureForDoc (fm.Type) + "." + name + GetParametersFormatted (mi));
+ xref.SetAttribute ("cref", GetMemberDocHead (mi) + GetSignatureForDoc (mi.DeclaringType) + "." + name + GetParametersFormatted (mi));
return; // local member name
}
}
xref.SetAttribute ("cref", "!:" + name);
}
- static string GetParametersFormatted (MemberInfo mi)
+ static string GetParametersFormatted (MemberSpec mi)
{
- MethodBase mb = mi as MethodBase;
- bool is_setter = false;
- PropertyInfo pi = mi as PropertyInfo;
- if (pi != null) {
- mb = pi.GetGetMethod ();
- if (mb == null) {
- is_setter = true;
- mb = pi.GetSetMethod ();
- }
- }
- if (mb == null)
- return String.Empty;
+ var pm = mi as IParametersMember;
+ if (pm == null || pm.Parameters.IsEmpty)
+ return string.Empty;
- AParametersCollection parameters = TypeManager.GetParameterData (mb);
+ AParametersCollection parameters = pm.Parameters;
+/*
if (parameters == null || parameters.Count == 0)
return String.Empty;
-
+*/
StringBuilder sb = new StringBuilder ();
sb.Append ('(');
for (int i = 0; i < parameters.Count; i++) {
- if (is_setter && i + 1 == parameters.Count)
- break; // skip "value".
+// if (is_setter && i + 1 == parameters.Count)
+// break; // skip "value".
if (i > 0)
sb.Append (',');
- Type t = parameters.Types [i];
+ TypeSpec t = parameters.Types [i];
sb.Append (GetSignatureForDoc (t));
}
sb.Append (')');
return identifier;
}
- static void Report419 (MemberCore mc, string member_name, MemberInfo [] mis, Report Report)
+ static void Report419 (MemberCore mc, string member_name, MemberSpec [] mis, Report Report)
{
Report.Warning (419, 3, mc.Location,
"Ambiguous reference in cref attribute `{0}'. Assuming `{1}' but other overloads including `{2}' have also matched",
// Get a prefix from member type for XML documentation (used
// to formalize cref target name).
//
- static string GetMemberDocHead (MemberTypes type)
+ static string GetMemberDocHead (MemberSpec type)
{
- switch (type) {
- case MemberTypes.Constructor:
- case MemberTypes.Method:
+ if (type is FieldSpec)
+ return "F:";
+ if (type is MethodSpec)
return "M:";
- case MemberTypes.Event:
+ if (type is EventSpec)
return "E:";
- case MemberTypes.Field:
- return "F:";
- case MemberTypes.NestedType:
- case MemberTypes.TypeInfo:
- return "T:";
- case MemberTypes.Property:
+ if (type is PropertySpec)
return "P:";
- }
+ if (type is TypeSpec)
+ return "T:";
+
return "!:";
}
switch (op.OperatorType) {
case Operator.OpType.Implicit:
case Operator.OpType.Explicit:
- suffix = "~" + GetSignatureForDoc (op.MethodBuilder.ReturnType);
+ suffix = "~" + GetSignatureForDoc (op.ReturnType);
break;
}
}
return String.Concat (mc.DocCommentHeader, ds.Name, ".", name, paramSpec, suffix);
}
- static string GetSignatureForDoc (Type type)
+ static string GetSignatureForDoc (TypeSpec type)
{
- if (TypeManager.IsGenericParameter (type))
- return (type.DeclaringMethod != null ? "``" : "`") + TypeManager.GenericParameterPosition (type);
+ var tp = type as TypeParameterSpec;
+ if (tp != null) {
+ var prefix = tp.IsMethodOwned ? "``" : "`";
+ return prefix + tp.DeclaredPosition;
+ }
if (TypeManager.IsGenericType (type)) {
- string g = type.Namespace;
+ string g = type.MemberDefinition.Namespace;
if (g != null && g.Length > 0)
g += '.';
int idx = type.Name.LastIndexOf ('`');
g += (idx < 0 ? type.Name : type.Name.Substring (0, idx)) + '{';
int argpos = 0;
- foreach (Type t in type.GetGenericArguments ())
+ foreach (TypeSpec t in TypeManager.GetTypeArguments (type))
g += (argpos++ > 0 ? "," : String.Empty) + GetSignatureForDoc (t);
g += '}';
return g;
}
- string name = type.FullName != null ? type.FullName : type.Name;
+ string name = type.GetMetaInfo ().FullName != null ? type.GetMetaInfo ().FullName : type.Name;
return name.Replace ("+", ".").Replace ('&', '@');
}
string xname = pelem.GetAttribute ("name");
if (xname.Length == 0)
continue; // really? but MS looks doing so
- if (xname != "" && mc.Parameters.GetParameterIndexByName (xname) < 0)
+ if (xname != "" && mc.ParameterInfo.GetParameterIndexByName (xname) < 0)
Report.Warning (1572, 2, mc.Location, "XML comment on `{0}' has a param tag for `{1}', but there is no parameter by that name",
mc.GetSignatureForError (), xname);
else if (paramTags.ContainsKey (xname))
mc.GetSignatureForError (), xname);
paramTags [xname] = xname;
}
- IParameterData [] plist = mc.Parameters.FixedParameters;
+ IParameterData [] plist = mc.ParameterInfo.FixedParameters;
foreach (Parameter p in plist) {
if (paramTags.Count > 0 && !paramTags.ContainsKey (p.Name))
Report.Warning (1573, 4, mc.Location, "Parameter `{0}' has no matching param tag in the XML comment for `{1}'",
if (root.Types != null)
foreach (TypeContainer tc in root.Types)
DocUtil.GenerateTypeDocComment (tc, null, r);
-
- if (root.Delegates != null)
- foreach (Delegate d in root.Delegates)
- DocUtil.GenerateDocComment (d, null, r);
}
}
}
{
// TODO: Should be passed to parser as an argument
RootContext.ToplevelTypes = new ModuleCompiled (ctx, RootContext.Unsafe);
+ var ctypes = TypeManager.InitCoreTypes ();
+ TypeManager.InitExpressionTypes ();
Parse ();
if (Report.Errors > 0)
if (timestamps)
ShowTime ("Loading references");
+ Import.Initialize ();
LoadReferences ();
if (modules.Count > 0) {
if (timestamps)
ShowTime ("References loaded");
- if (!TypeManager.InitCoreTypes (ctx) || Report.Errors > 0)
+ if (!TypeManager.InitCoreTypes (ctx, ctypes))
return false;
TypeManager.InitOptionalCoreTypes (ctx);
return false;
if (timestamps)
ShowTime ("Populate tree");
- if (!RootContext.StdLib)
- RootContext.BootCorlib_PopulateCoreTypes ();
+
RootContext.PopulateTypes ();
if (Report.Errors == 0 &&
if (RootContext.VerifyClsCompliance) {
if (CodeGen.Assembly.IsClsCompliant) {
AttributeTester.VerifyModulesClsCompliance (ctx);
- TypeManager.LoadAllImportedTypes ();
}
}
if (Report.Errors > 0)
{
Driver.Reset ();
CSharpParser.yacc_verbose_flag = 0;
- RootContext.Reset (full_flag);
Location.Reset ();
+
+ if (!full_flag)
+ return;
+
+ RootContext.Reset (full_flag);
TypeManager.Reset ();
PredefinedAttributes.Reset ();
- TypeHandle.Reset ();
-
- if (full_flag)
- GlobalRootNamespace.Reset ();
+ ArrayContainer.Reset ();
+ ReferenceContainer.Reset ();
+ PointerContainer.Reset ();
+ Parameter.Reset ();
+
+ GlobalRootNamespace.Reset ();
+ Unary.Reset ();
+ Binary.Reset ();
+ ConstantFold.Reset ();
+ CastFromDecimal.Reset ();
NamespaceEntry.Reset ();
CodeGen.Reset ();
Attribute.Reset ();
- AttributeTester.Reset ();
AnonymousTypeClass.Reset ();
AnonymousMethodBody.Reset ();
AnonymousMethodStorey.Reset ();
#if !NET_4_0
public class DynamicMetaObject
{
- public Type RuntimeType;
- public Type LimitType;
+ public TypeSpec RuntimeType;
+ public TypeSpec LimitType;
public SLE.Expression Expression;
}
#endif
readonly DynamicMetaObject obj;
- public RuntimeValueExpression (DynamicMetaObject obj, bool isCompileTimeType)
+ public RuntimeValueExpression (DynamicMetaObject obj, TypeSpec type)
{
this.obj = obj;
- this.type = isCompileTimeType ? obj.LimitType : obj.RuntimeType;
- this.type = obj.LimitType;
+ this.type = type;
this.eclass = ExprClass.Variable;
}
public override SLE.Expression MakeExpression (BuilderContext ctx)
{
- return SLE.Expression.Convert (obj.Expression, type);
+ return SLE.Expression.Convert (obj.Expression, type.GetMetaInfo ());
}
public DynamicMetaObject MetaObject {
//
public class DynamicResultCast : ShimExpression
{
- public DynamicResultCast (Type type, Expression expr)
+ public DynamicResultCast (TypeSpec type, Expression expr)
: base (expr)
{
this.type = type;
#if NET_4_0
public override SLE.Expression MakeExpression (BuilderContext ctx)
{
- return SLE.Expression.Block (expr.MakeExpression (ctx), SLE.Expression.Default (type));
+ return SLE.Expression.Block (expr.MakeExpression (ctx), SLE.Expression.Default (type.GetMetaInfo ()));
}
#endif
}
if (global_site_container == null) {
global_site_container = new StaticDataClass ();
RootContext.ToplevelTypes.AddCompilerGeneratedClass (global_site_container);
+ global_site_container.CreateType ();
global_site_container.DefineType ();
global_site_container.Define ();
}
if (TypeManager.generic_call_site_type == null)
TypeManager.generic_call_site_type = TypeManager.CoreLookupType (rc.Compiler,
- "System.Runtime.CompilerServices", "CallSite`1", MemberKind.Class, true);
+ "System.Runtime.CompilerServices", "CallSite", 1, MemberKind.Class, true);
if (TypeManager.binder_flags == null) {
TypeManager.binder_flags = TypeManager.CoreLookupType (rc.Compiler,
TypeExpr site_type = CreateSiteType (RootContext.ToplevelTypes.Compiler, arguments, dyn_args_count, isStatement);
FieldExpr site_field_expr = new FieldExpr (CreateSiteField (site_type), loc);
- SymbolWriter.OpenCompilerGeneratedBlock (ec.ig);
+ SymbolWriter.OpenCompilerGeneratedBlock (ec);
Arguments args = new Arguments (1);
args.Add (new Argument (binder));
if (target != null)
target.Emit (ec);
- SymbolWriter.CloseCompilerGeneratedBlock (ec.ig);
+ SymbolWriter.CloseCompilerGeneratedBlock (ec);
}
public static MemberAccess GetBinderNamespace (Location loc)
FullNamedExpression[] targs = new FullNamedExpression[dyn_args_count + default_args];
targs [0] = new TypeExpression (TypeManager.call_site_type, loc);
for (int i = 0; i < dyn_args_count; ++i) {
- Type arg_type;
+ TypeSpec arg_type;
Argument a = arguments [i];
if (a.Type == TypeManager.null_type)
arg_type = TypeManager.object_type;
TypeExpr del_type = null;
if (!has_ref_out_argument) {
- string d_name = is_statement ? "Action`" : "Func`";
+ string d_name = is_statement ? "Action" : "Func";
- Type t = TypeManager.CoreLookupType (ctx, "System", d_name + (dyn_args_count + default_args), MemberKind.Delegate, false);
+ TypeSpec t = TypeManager.CoreLookupType (ctx, "System", d_name, dyn_args_count + default_args, MemberKind.Delegate, false);
if (t != null) {
if (!is_statement)
targs [targs.Length - 1] = new TypeExpression (type, loc);
// Create custom delegate when no appropriate predefined one is found
//
if (del_type == null) {
- Type rt = is_statement ? TypeManager.void_type : type;
+ TypeSpec rt = is_statement ? TypeManager.void_type : type;
Parameter[] p = new Parameter [dyn_args_count + 1];
p[0] = new Parameter (targs [0], "p0", Parameter.Modifier.NONE, null, loc);
new MemberName ("Container" + container_counter++.ToString ("X")),
new ParametersCompiled (ctx, p), null);
+ d.CreateType ();
d.DefineType ();
d.Define ();
d.Emit ();
parent.AddDelegate (d);
- del_type = new TypeExpression (d.TypeBuilder, loc);
+ del_type = new TypeExpression (d.Definition, loc);
}
TypeExpr site_type = new GenericTypeExpr (TypeManager.generic_call_site_type, new TypeArguments (del_type), loc);
class DynamicConversion : DynamicExpressionStatement, IDynamicBinder
{
- public DynamicConversion (Type targetType, CSharpBinderFlags flags, Arguments args, Location loc)
+ public DynamicConversion (TypeSpec targetType, CSharpBinderFlags flags, Arguments args, Location loc)
: base (null, args, loc)
{
type = targetType;
class DynamicConstructorBinder : DynamicExpressionStatement, IDynamicBinder
{
- public DynamicConstructorBinder (Type type, Arguments args, Location loc)
+ public DynamicConstructorBinder (TypeSpec type, Arguments args, Location loc)
: base (null, args, loc)
{
this.type = type;
this.member = member;
}
- public DynamicInvocation (ATypeNameExpression member, Arguments args, Type type, Location loc)
+ public DynamicInvocation (ATypeNameExpression member, Arguments args, TypeSpec type, Location loc)
: this (member, args, loc)
{
// When a return type is known not to be dynamic
TypeArguments ta = member.TypeArguments;
if (ta.Resolve (ec)) {
var targs = new ArrayInitializer (ta.Count, loc);
- foreach (Type t in ta.Arguments)
+ foreach (TypeSpec t in ta.Arguments)
targs.Add (new TypeOf (new TypeExpression (t, loc), loc));
binder_args.Add (new Argument (new ImplicitlyTypedArrayCreation ("[]", targs, loc)));
/// </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 string GetSignatureForError ()
{
- return TypeManager.CSharpName (type);
+ return type.GetDefinition ().GetSignatureForError ();
}
- public static bool IsAccessorAccessible (Type invocation_type, MethodSpec mi, out bool must_do_cs1540_check)
+ public static bool IsMemberAccessible (TypeSpec invocation_type, MemberSpec mi, out bool must_do_cs1540_check)
{
var ma = mi.Modifiers & Modifiers.AccessibilityMask;
if (ma == Modifiers.PUBLIC)
return true;
-
+
//
// If only accessible to the current class or children
//
if (ma == Modifiers.PRIVATE)
- return TypeManager.IsPrivateAccessible (invocation_type, mi.DeclaringType) ||
+ return invocation_type.MemberDefinition == mi.DeclaringType.MemberDefinition ||
TypeManager.IsNestedChildOf (invocation_type, mi.DeclaringType);
if ((ma & Modifiers.INTERNAL) != 0) {
- var b = TypeManager.IsThisOrFriendAssembly (invocation_type.Assembly, mi.DeclaringType.Assembly);
+ var b = TypeManager.IsThisOrFriendAssembly (invocation_type == InternalType.FakeInternalType ?
+ CodeGen.Assembly.Builder : invocation_type.Assembly, mi.DeclaringType.Assembly);
if (b || ma == Modifiers.INTERNAL)
return b;
}
// 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));
rc.Report.Error (133, loc, "The expression being assigned to `{0}' must be constant", e_name);
}
- public void Error_ConstantCanBeInitializedWithNullOnly (ResolveContext rc, Type type, Location loc, string 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));
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}'",
return e;
}
- public virtual void EncodeAttributeValue (IMemberContext rc, AttributeEncoder enc, Type targetType)
+ public virtual void EncodeAttributeValue (IMemberContext rc, AttributeEncoder enc, TypeSpec targetType)
{
Attribute.Error_AttributeArgumentNotValid (rc, loc);
}
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>
/// 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 (Import.CreateEvent ((EventInfo) mi), loc);
- else if (mi is FieldInfo) {
- FieldInfo fi = (FieldInfo) mi;
- var spec = Import.CreateField (fi);
- if (spec is ConstSpec)
- return new ConstantExpr ((ConstSpec) spec, loc);
- return new FieldExpr (spec, loc);
- } else if (mi is PropertyInfo)
- return new PropertyExpr (container_type, Import.CreateProperty ((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 (container_type, (PropertySpec) spec, loc);
+ if (spec is TypeSpec)
+ return new TypeExpression (((TypeSpec) spec), loc);
return null;
}
- // TODO: [Obsolete ("Can be removed")]
- protected static IList<MemberInfo> almost_matched_members = new List<MemberInfo> (4);
-
//
// FIXME: Probably implement a cache for (t,name,current_access_set)?
//
// FIXME: Potential optimization, have a static ArrayList
//
- public static Expression MemberLookup (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;
- var methods = new List<MethodSpec> (2);
- List<MemberInfo> non_methods = null;
-
- foreach (var m in mi) {
- if (m is MethodBase) {
- methods.Add (Import.CreateMethod ((MethodBase) m));
- continue;
- }
-
- if (non_methods == null)
- non_methods = new List<MemberInfo> (2);
-
- bool is_candidate = true;
- for (int i = 0; i < non_methods.Count; ++i) {
- MemberInfo n_m = non_methods [i];
- if (n_m.DeclaringType.IsInterface && TypeManager.ImplementsInterface (m.DeclaringType, n_m.DeclaringType)) {
- non_methods.Remove (n_m);
- --i;
- } else if (m.DeclaringType.IsInterface && TypeManager.ImplementsInterface (n_m.DeclaringType, m.DeclaringType)) {
- is_candidate = false;
- break;
- }
- }
-
- if (is_candidate) {
- non_methods.Add (m);
- }
+ var first = mi [0];
+ if (mi.Count > 1) {
+ foreach (var mc in mi) {
+ if (mc is MethodSpec)
+ return new MethodGroupExpr (mi, queried_type, loc);
}
-
- if (methods.Count == 0 && non_methods != null && non_methods.Count > 1) {
- ctx.Report.SymbolRelatedToPreviousError (non_methods [1]);
- ctx.Report.SymbolRelatedToPreviousError (non_methods [0]);
- ctx.Report.Error (229, loc, "Ambiguity between `{0}' and `{1}'",
- TypeManager.GetFullNameSignature (non_methods [1]),
- TypeManager.GetFullNameSignature (non_methods [0]));
- return null;
- }
-
- if (methods.Count == 0)
- return ExprClassFromMemberInfo (container_type, (MemberInfo)non_methods [0], loc);
-
- if (non_methods != null && non_methods.Count > 0) {
- var method = methods [0];
- MemberInfo non_method = (MemberInfo) non_methods [0];
- if (method.DeclaringType == non_method.DeclaringType) {
- // Cannot happen with C# code, but is valid in IL
- ctx.Report.SymbolRelatedToPreviousError (method.MetaInfo);
- ctx.Report.SymbolRelatedToPreviousError (non_method);
- ctx.Report.Error (229, loc, "Ambiguity between `{0}' and `{1}'",
- TypeManager.GetFullNameSignature (non_method),
- TypeManager.CSharpSignature (method.MetaInfo));
- return null;
- }
- if (is_interface) {
- ctx.Report.SymbolRelatedToPreviousError (method.MetaInfo);
- ctx.Report.SymbolRelatedToPreviousError (non_method);
- ctx.Report.Warning (467, 2, loc, "Ambiguity between method `{0}' and non-method `{1}'. Using method `{0}'",
- TypeManager.CSharpSignature (method.MetaInfo), TypeManager.GetFullNameSignature (non_method));
- }
- }
-
- 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)
- return new MethodGroupExpr (mi.Select (l => Import.CreateMethod ((MethodBase) l)).ToArray (), queried_type, loc);
+ 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);
+ name, arity, MemberKind.All, binding | BindingRestriction.AccessibleOnly, loc);
}
- public static MethodGroupExpr MethodLookup (CompilerContext ctx, Type container_type, Type queried_type,
- string name, Location loc)
+ public static MethodGroupExpr MethodLookup (CompilerContext ctx, TypeSpec container_type, TypeSpec queried_type,
+ MemberKind kind, string name, int arity, Location loc)
{
- return (MethodGroupExpr)MemberLookup (ctx, container_type, null, queried_type, name,
- MemberTypes.Method, AllBindingFlags, loc);
+ return (MethodGroupExpr)MemberLookup (ctx, container_type, null, queried_type, name, arity,
+ kind, 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;
}
- protected virtual Expression Error_MemberLookupFailed (ResolveContext ec, Type type, MemberInfo[] members)
+ protected virtual MemberExpr Error_MemberLookupFailed (ResolveContext ec, TypeSpec type, IList<MemberSpec> members)
{
- List<MethodSpec> methods = new List<MethodSpec> ();
- for (int i = 0; i < members.Length; ++i) {
- if (!(members [i] is MethodBase))
- return null;
-
- methods.Add (Import.CreateMethod (members[i] as MethodBase));
- }
+ if (members.Any ((m) => !(m is MethodSpec)))
+ return (MemberExpr) ExprClassFromMemberInfo (type, members.First (), loc);
// By default propagate the closest candidates upwards
- return new MethodGroupExpr (methods.ToArray (), type, loc, true);
+ return new MethodGroupExpr (members, type, loc, true);
}
protected virtual void Error_NegativeArrayIndex (ResolveContext ec, 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;
+ operator_group = MethodLookup (ec.Compiler, ec.CurrentType, e.Type, MemberKind.Operator, mname, 0, loc) as MethodGroupExpr;
if (operator_group == null)
return null;
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", MemberKind.Class, true);
+ TypeSpec t = TypeManager.CoreLookupType (ec.Compiler, "System.Linq.Expressions", "Expression", MemberKind.Class, true);
if (t == null)
return null;
{
throw new NotImplementedException ("MakeExpression for " + GetType ());
}
-
- public virtual void MutateHoistedGenericType (AnonymousMethodStorey storey)
- {
- // TODO: It should probably be type = storey.MutateType (type);
- }
}
/// <summary>
{
protected readonly Expression child;
- protected TypeCast (Expression child, Type return_type)
+ protected TypeCast (Expression child, TypeSpec return_type)
{
eclass = child.eclass;
loc = child.Location;
public override SLE.Expression MakeExpression (BuilderContext ctx)
{
return ctx.HasSet (BuilderContext.Options.CheckedScope) ?
- SLE.Expression.ConvertChecked (child.MakeExpression (ctx), type) :
- SLE.Expression.Convert (child.MakeExpression (ctx), type);
- }
-
- public override void MutateHoistedGenericType (AnonymousMethodStorey storey)
- {
- type = storey.MutateType (type);
- 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);
+ // Operators are always public
+ var mi = TypeManager.MemberLookup (child.Type, child.Type, child.Type, MemberKind.Operator,
+ BindingRestriction.None, operator_name, 0, null);
if (mi == null){
- mi = TypeManager.MemberLookup (type, type, type, MemberTypes.Method,
- BindingFlags.Static | BindingFlags.Public, operator_name, null);
+ mi = TypeManager.MemberLookup (type, type, type, MemberKind.Operator,
+ BindingRestriction.None, operator_name, 0, null);
}
- foreach (MethodInfo oper in mi) {
- AParametersCollection pd = TypeManager.GetParameterData (oper);
+ foreach (MethodSpec oper in mi) {
+ AParametersCollection pd = oper.Parameters;
- if (pd.Types [0] == child.Type && TypeManager.TypeToCoreType (oper.ReturnType) == type)
+ if (pd.Types [0] == child.Type && oper.ReturnType == 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 Dictionary<Type, MethodInfo> 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 = TypeManager.MemberLookup (TypeManager.decimal_type,
+ TypeManager.decimal_type, TypeManager.decimal_type, MemberKind.Operator,
+ BindingRestriction.None, "op_Explicit", 0, null);
- operators = new Dictionary<Type, MethodInfo> (ReferenceEquality<Type>.Default);
- 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);
}
}
public override void Emit (EmitContext ec)
{
- ILGenerator ig = ec.ig;
child.Emit (ec);
- ig.Emit (OpCodes.Call, operators [type]);
+ ec.Emit (OpCodes.Call, operators [type]);
+ }
+
+ public static void Reset ()
+ {
+ operators = null;
}
}
{
public Constant child;
- public EmptyConstantCast (Constant child, Type type)
+ public EmptyConstantCast (Constant child, TypeSpec type)
: base (child.Location)
{
if (child == null)
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;
// 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 (ResolveContext rc, 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 (rc, target_type);
}
-
- public override void MutateHoistedGenericType (AnonymousMethodStorey storey)
- {
- child.MutateHoistedGenericType (storey);
- }
}
/// <summary>
{
public Constant Child;
- public EnumConstant (Constant child, Type enum_type)
+ public EnumConstant (Constant child, TypeSpec enum_type)
: base (child.Location)
{
this.Child = child;
Child.Emit (ec);
}
- public override void EncodeAttributeValue (IMemberContext rc, AttributeEncoder enc, Type targetType)
+ public override void EncodeAttributeValue (IMemberContext rc, AttributeEncoder enc, TypeSpec targetType)
{
Child.EncodeAttributeValue (rc, enc, Child.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 ()
}
}
- 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 (ResolveContext rc, 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 (rc, type.UnderlyingSystemType);
+ if (this.type == type) {
return this;
}
/// </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;
return this;
}
- public override void EncodeAttributeValue (IMemberContext rc, AttributeEncoder enc, Type targetType)
+ public override void EncodeAttributeValue (IMemberContext rc, AttributeEncoder enc, TypeSpec targetType)
{
enc.Encode (child.Type);
child.EncodeAttributeValue (rc, enc, child.Type);
{
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)
{
}
{
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 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 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 (ResolveContext rc, Type target_type)
+ public override Constant ConvertImplicitly (ResolveContext rc, TypeSpec target_type)
{
Constant c = base.ConvertImplicitly (rc, target_type);
if (c != null)
return orig_expr.CreateExpressionTree (ec);
}
- 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)
{
stm.EmitStatement (ec);
}
-
- public override void MutateHoistedGenericType (AnonymousMethodStorey storey)
- {
- stm.MutateHoistedGenericType (storey);
- }
}
readonly Expression expr, orig_expr;
{
return orig_expr.MakeExpression (ctx);
}
-
- public override void MutateHoistedGenericType (AnonymousMethodStorey storey)
- {
- expr.MutateHoistedGenericType (storey);
- }
}
//
public Expression Expr {
get { return expr; }
}
-
- public override void MutateHoistedGenericType (AnonymousMethodStorey storey)
- {
- throw new InternalErrorException ("Missing Resolve call");
- }
}
//
loc = l;
}
+ protected ATypeNameExpression (string name, int arity, Location l)
+ : this (name, new UnboundTypeArguments (arity), l)
+ {
+ }
+
+ #region Properties
+
+ protected int Arity {
+ get {
+ return targs == null ? 0 : targs.Count;
+ }
+ }
+
public bool HasTypeArguments {
get {
- return targs != null;
+ return targs != null && !targs.IsEmpty;
}
}
+ public string Name {
+ get {
+ return name;
+ }
+ set {
+ name = value;
+ }
+ }
+
+ public TypeArguments TypeArguments {
+ get {
+ return targs;
+ }
+ }
+
+ #endregion
+
public override bool Equals (object obj)
{
ATypeNameExpression atne = obj as ATypeNameExpression;
return Name.GetHashCode ();
}
- public override string GetSignatureForError ()
+ // TODO: Move it to MemberCore
+ public static string GetMemberType (MemberCore mc)
{
- if (targs != null) {
- return TypeManager.RemoveGenericArity (Name) + "<" +
- targs.GetSignatureForError () + ">";
- }
+ 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 Name;
+ return "type";
}
- public string Name {
- get {
- return name;
- }
- set {
- name = value;
+ public override string GetSignatureForError ()
+ {
+ if (targs != null) {
+ return Name + "<" + targs.GetSignatureForError () + ">";
}
- }
- public TypeArguments TypeArguments {
- get {
- return targs;
- }
+ return Name;
}
}
{
}
- public SimpleName (string name, TypeParameter[] type_params, Location l)
- : base (name, l)
+ public SimpleName (string name, int arity, Location l)
+ : base (name, arity, l)
{
- targs = new TypeArguments ();
- foreach (TypeParameter type_param in type_params)
- targs.Add (new TypeParameterExpr (type_param, l));
- }
-
- public static string RemoveGenericArity (string name)
- {
- 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);
-
- return sb.ToString ();
}
public SimpleName GetMethodGroup ()
{
- return new SimpleName (RemoveGenericArity (Name), targs, loc);
+ return new SimpleName (Name, targs, loc);
}
public static void Error_ObjectRefRequired (ResolveContext ec, Location l, string name)
name);
}
+ protected virtual void Error_TypeOrNamespaceNotFound (IMemberContext ec)
+ {
+ 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;
+ }
+ }
+
+ /*
+ // 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;
+ }
+
+ NamespaceEntry.Error_NamespaceNotFound (loc, Name, ec.Compiler.Report);
+ }
+
public bool IdenticalNameAndTypeName (IMemberContext mc, Expression resolved_to, Location loc)
{
- return resolved_to != null && resolved_to.Type != null &&
- resolved_to.Type.Name == Name &&
- (mc.LookupNamespaceOrType (Name, loc, /* ignore_cs0104 = */ true) != null);
+ if (resolved_to == null || resolved_to.Type == null)
+ return false;
+
+ if (resolved_to.Type is ElementTypeSpec || resolved_to.Type is InternalType)
+ return false;
+
+ return resolved_to.Type.Name == Name &&
+ (mc.LookupNamespaceOrType (Name, Arity, loc, /* ignore_cs0104 = */ true) != null);
}
protected override Expression DoResolve (ResolveContext ec)
return SimpleNameResolve (ec, null, intermediate);
}
- static bool IsNestedChild (Type t, Type parent)
+ static bool IsNestedChild (TypeSpec t, TypeSpec parent)
{
while (parent != null) {
- if (TypeManager.IsNestedChildOf (t, TypeManager.DropGenericTypeArguments (parent)))
+ if (TypeManager.IsNestedChildOf (t, parent))
return true;
parent = parent.BaseType;
return false;
}
- FullNamedExpression ResolveNested (Type t)
- {
- 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 new GenericTypeExpr (t, new_args, loc);
- }
- }
-
- return null;
- }
-
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)) {
- GenericTypeExpr ct = new GenericTypeExpr (fne.Type, targs, loc);
- return ct.ResolveAsTypeStep (ec, false);
- }
-
- fne.Error_TypeArgumentsCannotBeUsed (ec.Compiler.Report, loc);
+ if (HasTypeArguments && fne.Type != null && TypeManager.IsGenericType (fne.Type)) {
+ GenericTypeExpr ct = new GenericTypeExpr (fne.Type, targs, loc);
+ return ct.ResolveAsTypeStep (ec, false);
}
return fne;
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 (ec.Compiler.Report, 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)
{
Expression e = DoSimpleNameResolve (ec, right_side, intermediate);
}
}
- if (targs != null && e != null)
- e.Error_TypeArgumentsCannotBeUsed (ec.Report, loc);
+ if (HasTypeArguments && e != null)
+ 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 (HasTypeArguments && e != null)
+ e.Error_TypeArgumentsCannotBeUsed (ec.Report, loc, null, 0);
return e;
}
//
// Stage 2: Lookup members
//
-
- Type almost_matched_type = null;
- IList<MemberInfo> almost_matched = null;
- for (Type lookup_ds = ec.CurrentType; lookup_ds != null; lookup_ds = lookup_ds.DeclaringType) {
- e = MemberLookup (ec.Compiler, ec.CurrentType, lookup_ds, Name, loc);
+ 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.NoOverrides, 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 = new List<MemberInfo>(almost_matched_members);
+ 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 = new List<MemberInfo> (almost_matched_members);
+ almost_matched = new List<MemberSpec> (almost_matched_members);
}
+*/
e = ResolveAsTypeStep (ec, true);
}
if (RootContext.EvalMode){
FieldInfo fi = Evaluator.LookupField (Name);
if (fi != null)
- return new FieldExpr (Import.CreateField (fi), loc).Resolve (ec);
+ return new FieldExpr (Import.CreateField (fi, null), 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) {
// 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.
//
if (me == null)
return null;
- if (targs != null) {
+ if (HasTypeArguments) {
if (!targs.Resolve (ec))
return null;
throw new NotSupportedException ("ET");
}
- public override void MutateHoistedGenericType (AnonymousMethodStorey storey)
- {
- throw new NotSupportedException ();
- }
-
public override FullNamedExpression ResolveAsTypeStep (IMemberContext ec, bool silent)
{
return this;
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;
// 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)
+ public TypeLookupExpression (TypeSpec type)
{
- this.name = name;
- this.ns_name = ns;
eclass = ExprClass.Type;
+ this.type = 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 ()
+ protected override TypeExpr DoResolveAsTypeStep (IMemberContext ec)
{
- if (type == null)
- return TypeManager.CSharpName (ns_name + "." + name, null);
-
- return base.GetSignatureForError ();
+ return this;
}
}
/// <summary>
/// The type which declares this member.
/// </summary>
- public abstract Type DeclaringType {
+ public abstract TypeSpec DeclaringType {
get;
}
ec.Report.Error (831, loc, "An expression tree may not contain a base access");
}
- public override void MutateHoistedGenericType (AnonymousMethodStorey storey)
- {
- if (InstanceExpression != null)
- InstanceExpression.MutateHoistedGenericType (storey);
- }
-
- // TODO: possible optimalization
- // Cache resolved constant result in FieldBuilder <-> expression map
public virtual MemberExpr ResolveMemberAccess (ResolveContext ec, Expression left, Location loc,
SimpleName original)
{
//
if (left is TypeExpr) {
- left = left.ResolveAsBaseTerminal (ec, false);
+ left = ((TypeExpr) left).ResolveAsTypeTerminal (ec, false);
if (left == null)
return null;
// TODO: Same problem as in class.cs, TypeTerminal does not
// always do all necessary checks
- ObsoleteAttribute oa = AttributeTester.GetObsoleteAttribute (left.Type);
+ ObsoleteAttribute oa = left.Type.GetAttributeObsolete ();
if (oa != null && !ec.IsObsolete) {
AttributeTester.Report_ObsoleteMessage (oa, left.GetSignatureForError (), loc, ec.Report);
}
- GenericTypeExpr ct = left as GenericTypeExpr;
- if (ct != null && !ct.CheckConstraints (ec))
- return null;
+// GenericTypeExpr ct = left as GenericTypeExpr;
+// if (ct != null && !ct.CheckConstraints (ec))
+// return null;
//
if (!IsStatic) {
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 (List<MethodSpec> 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 IErrorHandler CustomErrorHandler;
- public MethodSpec [] Methods;
+ public IList<MemberSpec> Methods;
MethodSpec best_candidate;
// TODO: make private
public TypeArguments type_arguments;
bool identical_type_name;
bool has_inaccessible_candidates_only;
- Type delegate_type;
- Type queried_type;
-
- public MethodGroupExpr (MethodSpec [] 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 MethodSpec[mi.Length];
- mi.CopyTo (Methods, 0);
+ Methods = mi;
}
- public MethodGroupExpr (MethodSpec[] 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 (List<MethodSpec> 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 = list.ToArray ();
- } 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 {
+ public override TypeSpec DeclaringType {
get {
return queried_type;
}
}
}
- public Type DelegateType {
+ public TypeSpec DelegateType {
set {
delegate_type = value;
}
public override string GetSignatureForError ()
{
if (best_candidate != null)
- return TypeManager.CSharpSignature (best_candidate.MetaInfo);
-
- return TypeManager.CSharpSignature (Methods [0].MetaInfo);
+ return best_candidate.GetSignatureForError ();
+
+ return Methods.First ().GetSignatureForError ();
}
public override string Name {
get {
- return Methods [0].Name;
+ return Methods.First ().Name;
}
}
// 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");
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)
{
//
// The two methods have equal parameter types. Now apply tie-breaking rules
//
- if (best.IsGenericMethod) {
- if (!candidate.IsGenericMethod)
+ if (best.IsGeneric) {
+ if (!candidate.IsGeneric)
return true;
- } else if (candidate.IsGenericMethod) {
+ } 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 null;
}
- IMethodData md = TypeManager.GetMethod (best_candidate.MetaInfo);
- 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");
if (CustomErrorHandler != null && CustomErrorHandler.AmbiguousCall (ec, ambiguous))
return;
- ec.Report.SymbolRelatedToPreviousError (best_candidate.MetaInfo);
+ 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.MetaInfo));
+ best_candidate.GetSignatureForError (), ambiguous.GetSignatureForError ());
}
protected virtual void Error_InvalidArguments (ResolveContext ec, Location loc, int idx, MethodSpec method,
- Argument a, AParametersCollection expected_par, Type paramType)
+ Argument a, AParametersCollection expected_par, TypeSpec paramType)
{
ExtensionMethodGroupExpr emg = this as ExtensionMethodGroupExpr;
if (a is CollectionElementInitializer.ElementInitializerArgument) {
- ec.Report.SymbolRelatedToPreviousError (method.MetaInfo);
+ ec.Report.SymbolRelatedToPreviousError (method);
if ((expected_par.FixedParameters [idx].ModFlags & Parameter.Modifier.ISBYREF) != 0) {
ec.Report.Error (1954, loc, "The best overloaded collection initalizer method `{0}' cannot have 'ref', or `out' modifier",
TypeManager.CSharpSignature (method));
ec.Report.Error (1594, loc, "Delegate `{0}' has some invalid arguments",
TypeManager.CSharpName (method.DeclaringType));
} else {
- ec.Report.SymbolRelatedToPreviousError (method.MetaInfo);
+ ec.Report.SymbolRelatedToPreviousError (method);
if (emg != null) {
ec.Report.Error (1928, loc,
"Type `{0}' does not contain a member `{1}' and the best extension method overload `{2}' has some invalid arguments",
}
}
- 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));
protected virtual int GetApplicableParametersCount (MethodSpec method, AParametersCollection parameters)
{
return parameters.Count;
- }
+ }
- public static bool IsAncestralType (Type first_type, Type second_type)
+ protected virtual IList<MemberSpec> GetBaseTypeMethods (ResolveContext rc, TypeSpec type)
{
- return first_type != second_type &&
- (TypeManager.IsSubclassOf (second_type, first_type) ||
- TypeManager.ImplementsInterface (second_type, first_type));
+ return TypeManager.MemberLookup (rc.CurrentType, null, type,
+ MemberKind.Method, BindingRestriction.AccessibleOnly | BindingRestriction.NoOverrides,
+ Name, 0, null); // TODO MemberCache: Arity !
+ }
+
+ bool GetBaseTypeMethods (ResolveContext rc)
+ {
+ var base_type = Methods.First ().DeclaringType.BaseType;
+ if (base_type == null)
+ return false;
+
+ var methods = GetBaseTypeMethods (rc, base_type);
+ if (methods == null)
+ return false;
+
+ Methods = methods;
+ return true;
}
///
//
// 1. Handle generic method using type arguments when specified or type inference
//
- if (candidate.IsGenericMethod) {
+ if (candidate.IsGeneric) {
if (type_arguments != null) {
- Type [] g_args = candidate.GetGenericArguments ();
- if (g_args.Length != type_arguments.Count)
- return int.MaxValue - 20000 + System.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);
- method = candidate.Inflate (type_arguments.Arguments);
+ method = candidate.MakeGenericMethod (type_arguments.Arguments);
candidate = method;
pd = candidate.Parameters;
} else {
if (score != 0)
return score - 20000;
- if (TypeManager.IsGenericMethodDefinition (candidate.MetaInfo))
- throw new InternalErrorException ("A generic method `{0}' definition took part in overload resolution",
- TypeManager.CSharpSignature (candidate.MetaInfo));
-
pd = candidate.Parameters;
}
} else {
//
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 (TypeManager.HasElementType (parameter))
parameter = TypeManager.GetElementType (parameter);
- Type a_type = argument.Type;
+ TypeSpec 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 (a_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 mg1;
- var all = new List<MethodSpec> (mg1.Methods);
- foreach (var m in mg2.Methods){
- if (!TypeManager.ArrayContainsMethod (mg1.Methods.Select (l => l.MetaInfo).ToArray (), m.MetaInfo, false))
+ var all = new List<MemberSpec> (mg1.Methods);
+ foreach (MethodSpec m in mg2.Methods){
+ if (!TypeManager.ArrayContainsMethod (all, 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);
-
- if (best_candidate.IsConstructor) {
- storey.MutateConstructor (best_candidate);
- } else {
- storey.MutateGenericMethod (best_candidate);
- }
- }
-
/// <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;
var candidates = new List<MethodSpec> (2);
- List<MethodSpec> candidate_overrides = null;
+ List<MethodSpec> params_candidates = null;
- //
- // 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
- //
- Dictionary<MethodSpec, MethodSpec> candidate_to_form = null;
+ int arg_count = Arguments != null ? Arguments.Count : 0;
Dictionary<MethodSpec, Arguments> candidates_expanded = null;
Arguments candidate_args = Arguments;
- int arg_count = Arguments != null ? Arguments.Count : 0;
-
if (RootContext.Version == LanguageVersion.ISO_1 && Name == "Invoke" && TypeManager.IsDelegateType (DeclaringType)) {
if (!may_fail)
ec.Report.Error (1533, loc, "Invoke cannot be called directly on a delegate");
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;
- MethodBase mb = null;
- for (int i = 0; i < Methods.Length; ++i) {
- var m = Methods [i];
- mb = m.MetaInfo;
- if (TypeManager.IsOverride (m)) {
- if (candidate_overrides == null)
- candidate_overrides = new List<MethodSpec> ();
- candidate_overrides.Add (m);
- mb = TypeManager.TryGetBaseDefinition (mb);
- if (mb != null && Array.Exists (Methods, l => l.MetaInfo == mb))
- continue;
- }
- if (mb != null)
- Methods [j++] = Import.CreateMethod (mb);
- }
- 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;
+ var msg_recorder = new SessionReportPrinter ();
+ var prev_recorder = ec.Report.SetPrinter (msg_recorder);
+ do {
//
- // If we have already found an applicable method
- // we eliminate all base types (Section 14.5.5.1)
+ // Methods in a base class are not candidates if any method in a derived
+ // class is applicable
//
- if (applicable_type != null && IsAncestralType (decl_type, applicable_type))
- continue;
+ 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;
+ }
- //
- // 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);
+ //
+ // 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);
- 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 Dictionary<MethodSpec, MethodSpec> (4, ReferenceEquality<MethodSpec>.Default);
- var candidate = Methods [i];
- candidate_to_form [candidate] = candidate;
- }
-
- if (candidate_args != Arguments) {
- if (candidates_expanded == null)
- candidates_expanded = new Dictionary<MethodSpec, Arguments> (4, ReferenceEquality<MethodSpec>.Default);
+ if (candidate_rate < best_candidate_rate) {
+ best_candidate_rate = candidate_rate;
+ best_candidate = m;
+ }
- candidates_expanded.Add (Methods [i], candidate_args);
- candidate_args = Arguments;
- }
+ if (params_expanded_form) {
+ if (params_candidates == null)
+ params_candidates = new List<MethodSpec> (2);
+ params_candidates.Add (m);
+ }
- if (candidate_rate != 0 || has_inaccessible_candidates_only) {
- if (msg_recorder != null)
- msg_recorder.EndSession ();
- continue;
- }
+ if (candidate_args != Arguments) {
+ if (candidates_expanded == null)
+ candidates_expanded = new Dictionary<MethodSpec, Arguments> (2);
+
+ candidates_expanded.Add (m, candidate_args);
+ candidate_args = Arguments;
+ }
- msg_recorder = null;
- candidates.Add (Methods [i]);
+ if (candidate_rate != 0 || has_inaccessible_candidates_only) {
+ if (msg_recorder != null)
+ msg_recorder.EndSession ();
+ continue;
+ }
- 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;
+ msg_recorder = null;
+ candidates.Add (m);
}
- }
+ } while (candidates.Count == 0 && GetBaseTypeMethods (ec));
ec.Report.SetPrinter (prev_recorder);
if (msg_recorder != null && !msg_recorder.IsEmpty) {
return null;
}
-
- 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.SetTypeArguments (ec, type_arguments);
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) {
- var candidate = 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 = candidates [0];
- method_params = candidate_to_form != null && candidate_to_form.ContainsKey (best_candidate);
-
- //
- // TODO: Broken inverse order of candidates logic does not work with optional
- // parameters used for method overrides and I am not going to fix it for SRE
- //
- if (candidates_expanded != null && candidates_expanded.ContainsKey (best_candidate)) {
- candidate_args = candidates_expanded [best_candidate];
- arg_count = candidate_args.Count;
- }
+ bool method_params = params_candidates != null && params_candidates.Contains (best_candidate);
for (int ix = 1; ix < candidate_top; ix++) {
var candidate = candidates [ix];
- if (candidate.MetaInfo == best_candidate.MetaInfo)
+ if (candidate == best_candidate)
continue;
- bool cand_params = candidate_to_form != null && candidate_to_form.ContainsKey (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
for (int ix = 1; ix < candidate_top; ix++) {
var candidate = candidates [ix];
- if (candidate.MetaInfo == best_candidate.MetaInfo)
+ if (candidate == best_candidate)
continue;
- bool cand_params = candidate_to_form != null && candidate_to_form.ContainsKey (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))
{
if (!may_fail)
- ec.Report.SymbolRelatedToPreviousError (candidate.MetaInfo);
+ ec.Report.SymbolRelatedToPreviousError (candidate);
ambiguous = candidate;
}
}
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 (best_candidate.IsGenericMethod)
- gen_args = TypeManager.GetGenericArguments (best_candidate.MetaInfo);
-
- foreach (var candidate in candidate_overrides) {
- if (candidate.IsGenericMethod) {
- if (gen_args == null)
- continue;
-
- if (gen_args.Length != TypeManager.GetGenericArguments (candidate.MetaInfo).Length)
- continue;
- } else {
- if (gen_args != null)
- continue;
- }
-
- if (IsOverride (candidate.MetaInfo, best_candidate.MetaInfo)) {
- gen_override = true;
- best_candidate = candidate;
- }
- }
-
- if (gen_override && gen_args != null) {
- best_candidate = best_candidate.Inflate (gen_args);
- }
- }
- }
-
//
// And now check if the arguments are all
// compatible, perform conversions if
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.MetaInfo, loc))
- return null;
+ 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.SetIsUsed ();
+ best_candidate.MemberDefinition.SetIsUsed ();
Arguments = candidate_args;
return this;
}
- bool NoExactMatch (ResolveContext ec, ref Arguments Arguments, IDictionary<MethodSpec, MethodSpec> candidate_to_form)
+ bool NoExactMatch (ResolveContext ec, ref Arguments Arguments, bool params_expanded)
{
AParametersCollection pd = best_candidate.Parameters;
int arg_count = Arguments == null ? 0 : Arguments.Count;
if (arg_count == pd.Count || pd.HasParams) {
- if (TypeManager.IsGenericMethodDefinition (best_candidate.MetaInfo)) {
+ if (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.MetaInfo));
+ "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.MetaInfo);
- if (type_arguments.Count != g_args.Length) {
- ec.Report.SymbolRelatedToPreviousError (best_candidate.MetaInfo);
- ec.Report.Error (305, loc, "Using the generic method `{0}' requires `{1}' type argument(s)",
- TypeManager.CSharpSignature (best_candidate.MetaInfo),
- g_args.Length.ToString ());
- return true;
- }
- } else {
- if (type_arguments != null && !best_candidate.IsGenericMethod) {
- Error_TypeArgumentsCannotBeUsed (ec.Report, loc);
- return true;
- }
+ 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) {
// base class (CS1540). If the qualifier_type is a base of the
// ec.CurrentType and the lookup succeeds with the latter one,
// then we are in this situation.
- Error_CannotAccessProtected (ec, loc, best_candidate.MetaInfo, queried_type, ec.CurrentType);
+ Error_CannotAccessProtected (ec, loc, best_candidate, queried_type, ec.CurrentType);
} else {
- ec.Report.SymbolRelatedToPreviousError (best_candidate.MetaInfo);
+ ec.Report.SymbolRelatedToPreviousError (best_candidate);
ErrorIsInaccesible (loc, GetSignatureForError (), ec.Report);
}
}
- bool cand_params = candidate_to_form != null && candidate_to_form.ContainsKey (best_candidate);
- if (!VerifyArgumentsCompat (ec, ref Arguments, arg_count, best_candidate, cand_params, false, loc))
+ if (!VerifyArgumentsCompat (ec, ref Arguments, arg_count, best_candidate, params_expanded, false, loc))
return true;
if (has_inaccessible_candidates_only)
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;
ArrayInitializer params_initializers = null;
"The delegate `{0}' does not contain a parameter named `{1}'",
TypeManager.CSharpName (DeclaringType), na.Name);
} else {
- ec.Report.SymbolRelatedToPreviousError (best_candidate.MetaInfo);
+ ec.Report.SymbolRelatedToPreviousError (best_candidate);
ec.Report.Error (1739, na.Location,
"The best overloaded method match for `{0}' does not contain a parameter named `{1}'",
- TypeManager.CSharpSignature (method.MetaInfo), na.Name);
+ TypeManager.CSharpSignature (method), na.Name);
}
} else if (arguments[name_index] != a) {
if (DeclaringType != null && TypeManager.IsDelegateType (DeclaringType))
ec.Report.SymbolRelatedToPreviousError (DeclaringType);
else
- ec.Report.SymbolRelatedToPreviousError (best_candidate.MetaInfo);
+ ec.Report.SymbolRelatedToPreviousError (best_candidate);
ec.Report.Error (1744, na.Location,
"Named argument `{0}' cannot be used for a parameter which has positional argument specified",
}
}
- if (TypeManager.IsDynamicType (a.Expr.Type))
+ if (a.Expr.Type == InternalType.Dynamic)
continue;
if (delegate_type != null && !Delegate.IsTypeCovariant (a.Expr, pt))
get { return true; }
}
- public override Type DeclaringType {
+ public override TypeSpec DeclaringType {
get { return constant.DeclaringType; }
}
constant.MemberDefinition.SetIsUsed ();
if (!rc.IsObsolete) {
- var oa = constant.GetObsoleteAttribute ();
+ var oa = constant.GetAttributeObsolete ();
if (oa != null)
- AttributeTester.Report_ObsoleteMessage (oa, TypeManager.GetFullNameSignature (constant.MetaInfo), loc, rc.Report);
+ AttributeTester.Report_ObsoleteMessage (oa, TypeManager.GetFullNameSignature (constant), loc, rc.Report);
}
// Constants are resolved on-demand
var c = constant.Value.Resolve (rc) as Constant;
// Creates reference expression to the constant value
- return Constant.CreateConstant (rc, c.Type, c.GetValue (), loc);
+ return Constant.CreateConstant (rc, constant.MemberType, c.GetValue (), loc);
}
public override void Emit (EmitContext ec)
public override string GetSignatureForError ()
{
- return TypeManager.GetFullNameSignature (constant.MetaInfo);
+ return TypeManager.GetFullNameSignature (constant);
}
}
/// </summary>
public class FieldExpr : MemberExpr, IDynamicAssign, IMemoryLocation, IVariableReference {
protected FieldSpec spec;
- readonly Type constructed_generic_type;
VariableInfo variable_info;
LocalTemporary temp;
this.spec = spec;
this.loc = loc;
- type = TypeManager.TypeToCoreType (spec.FieldType);
+ type = spec.MemberType;
}
public FieldExpr (FieldBase fi, Location l)
loc = l;
}
- public FieldExpr (Field fi, Type genericType, Location l)
- : this (fi, l)
- {
- if (TypeManager.IsGenericTypeDefinition (genericType))
- return;
- this.constructed_generic_type = genericType;
- }
-
public override string Name {
get {
return spec.Name;
}
}
- public override Type DeclaringType {
+ public override TypeSpec DeclaringType {
get {
- return spec.MetaInfo.DeclaringType;
+ return spec.DeclaringType;
}
}
public override string GetSignatureForError ()
{
- return TypeManager.GetFullNameSignature (spec.MetaInfo);
+ return TypeManager.GetFullNameSignature (spec);
}
public VariableInfo VariableInfo {
public override MemberExpr ResolveMemberAccess (ResolveContext ec, Expression left, Location loc,
SimpleName original)
{
- FieldInfo fi = TypeManager.GetGenericFieldDefinition (spec.MetaInfo);
- Type t = fi.FieldType;
-
- if (t.IsPointer && !ec.IsUnsafe) {
+ if (spec.MemberType.IsPointer && !ec.IsUnsafe) {
UnsafeError (ec, loc);
}
public Expression CreateTypeOfExpression ()
{
- return new TypeOfField (Import.CreateField (GetConstructedFieldInfo ()), loc);
+ return new TypeOfField (spec, loc);
}
protected override Expression DoResolve (ResolveContext ec)
}
if (!ec.IsObsolete) {
- FieldBase f = TypeManager.GetField (spec.MetaInfo);
- if (f != null) {
- f.CheckObsoleteness (loc);
- } else {
- ObsoleteAttribute oa = AttributeTester.GetMemberObsoleteAttribute (spec.MetaInfo);
- if (oa != null)
- AttributeTester.Report_ObsoleteMessage (oa, TypeManager.GetFullNameSignature (spec.MetaInfo), loc, ec.Report);
- }
+ ObsoleteAttribute oa = spec.GetAttributeObsolete ();
+ if (oa != null)
+ AttributeTester.Report_ObsoleteMessage (oa, TypeManager.GetFullNameSignature (spec), loc, ec.Report);
}
var fb = spec as FixedFieldSpec;
}
if (InstanceExpression.eclass != ExprClass.Variable) {
- ec.Report.SymbolRelatedToPreviousError (spec.MetaInfo);
+ ec.Report.SymbolRelatedToPreviousError (spec);
ec.Report.Error (1708, loc, "`{0}': Fixed size buffers can only be accessed through locals or fields",
- TypeManager.GetFullNameSignature (spec.MetaInfo));
+ TypeManager.GetFullNameSignature (spec));
} else if (var != null && var.IsHoisted) {
AnonymousMethodExpression.Error_AddressOfCapturedVar (ec, var, loc);
}
if (var != null && var.VariableInfo != null)
var.VariableInfo.SetFieldAssigned (ec, Name);
- bool lvalue_instance = !spec.IsStatic && TypeManager.IsValueType (spec.MetaInfo.DeclaringType);
+ bool lvalue_instance = !spec.IsStatic && TypeManager.IsValueType (spec.DeclaringType);
bool out_access = right_side == EmptyExpression.OutAccess.Instance || right_side == EmptyExpression.LValueMemberOutAccess;
Expression e = DoResolve (ec, lvalue_instance, out_access);
if (e == null)
return null;
- FieldBase fb = TypeManager.GetField (spec.MetaInfo);
- 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 (spec.IsReadOnly) {
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, 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)
//
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 (spec.MetaInfo != fe.spec.MetaInfo)
+ 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;
- var f = TypeManager.GetField (spec.MetaInfo);
- if (f != null){
- if ((f.ModFlags & Modifiers.VOLATILE) != 0)
- is_volatile = true;
+ if ((spec.Modifiers & Modifiers.VOLATILE) != 0)
+ is_volatile = true;
- f.SetIsUsed ();
- }
+ spec.MemberDefinition.SetIsUsed ();
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) && TypeManager.IsEqual (InstanceExpression.Type, type)) {
- LoadFromPtr (ig, type);
+ ec.EmitLoadFromPtr (type);
} else {
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);
+ 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);
source.Emit (ec);
if (leave_copy) {
- ec.ig.Emit (OpCodes.Dup);
+ ec.Emit (OpCodes.Dup);
if (!IsStatic) {
temp = new LocalTemporary (this.Type);
temp.Store (ec);
}
}
- FieldBase f = TypeManager.GetField (spec.MetaInfo);
- 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 (IsStatic)
- ig.Emit (OpCodes.Stsfld, GetConstructedFieldInfo ());
+ 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 (spec.MetaInfo);
- 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 (spec.MetaInfo);
- if (f != null){
- if ((mode & AddressOp.Store) != 0)
- f.SetAssigned ();
- if ((mode & AddressOp.Load) != 0)
- f.SetIsUsed ();
- }
+ 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
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 (IsStatic){
- ig.Emit (OpCodes.Ldsflda, GetConstructedFieldInfo ());
+ 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 spec.MetaInfo;
-
- return TypeBuilder.GetField (constructed_generic_type, spec.MetaInfo);
- }
-
public SLE.Expression MakeAssignExpression (BuilderContext ctx)
{
return MakeExpression (ctx);
public override SLE.Expression MakeExpression (BuilderContext ctx)
{
- return SLE.Expression.Field (InstanceExpression.MakeExpression (ctx), spec.MetaInfo);
+ return SLE.Expression.Field (InstanceExpression.MakeExpression (ctx), spec.GetMetaInfo ());
}
-
- public override void MutateHoistedGenericType (AnonymousMethodStorey storey)
- {
- storey.MutateField (spec);
- base.MutateHoistedGenericType (storey);
- }
}
public class PropertyExpr : MemberExpr, IDynamicAssign
{
PropertySpec spec;
- MethodSpec getter, setter;
- bool is_static;
-
TypeArguments targs;
LocalTemporary temp;
bool prepared;
- public PropertyExpr (Type container_type, PropertySpec spec, Location l)
+ public PropertyExpr (TypeSpec container_type, PropertySpec spec, Location l)
{
this.spec = spec;
loc = l;
- type = TypeManager.TypeToCoreType (spec.PropertyType);
-
- ResolveAccessors (container_type);
+ type = spec.MemberType;
}
+ #region Properties
+
public override string Name {
get {
return spec.Name;
public override bool IsInstance {
get {
- return !is_static;
+ return !IsStatic;
}
}
public override bool IsStatic {
get {
- return is_static;
+ return spec.IsStatic;
}
}
+ #endregion
+
public override Expression CreateExpressionTree (ResolveContext ec)
{
Arguments args;
args.Add (new Argument (new NullLiteral (loc)));
else
args.Add (new Argument (InstanceExpression.CreateExpressionTree (ec)));
- args.Add (new Argument (new TypeOfMethod (getter, loc)));
+ args.Add (new Argument (new TypeOfMethod (spec.Get, loc)));
return CreateExpressionFactoryCall (ec, "Property", args);
}
public Expression CreateSetterTypeOfExpression ()
{
- return new TypeOfMethod (setter, loc);
+ return new TypeOfMethod (spec.Set, loc);
}
- public override Type DeclaringType {
+ public override TypeSpec DeclaringType {
get {
return spec.DeclaringType;
}
public override string GetSignatureForError ()
{
- return TypeManager.GetFullNameSignature (spec.MetaInfo);
- }
-
- void FindAccessors (Type invocation_type)
- {
- const BindingFlags flags = BindingFlags.Public | BindingFlags.NonPublic |
- BindingFlags.Static | BindingFlags.Instance |
- BindingFlags.DeclaredOnly;
-
- Type current = spec.DeclaringType;
- for (; current != null; current = current.BaseType) {
- MemberInfo[] group = TypeManager.MemberLookup (
- invocation_type, invocation_type, current,
- MemberTypes.Property, flags, spec.Name, null);
-
- if (group == null)
- continue;
-
- if (group.Length != 1)
- // Oooops, can this ever happen ?
- return;
-
- PropertyInfo pi = (PropertyInfo) group [0];
-
- if (getter == null) {
- var m = pi.GetGetMethod (true);
- if (m != null)
- getter = Import.CreateMethod (m);
- }
-
- if (setter == null) {
- var m = pi.GetSetMethod (true);
- if (m != null)
- setter = Import.CreateMethod (m);
- }
-
- var 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.SetIsUsed ();
-
- is_static = getter.IsStatic;
- }
-
- if (setter != null) {
- MethodBase the_setter = TypeManager.DropGenericMethodArguments (setter);
- IMethodData md = TypeManager.GetMethod (the_setter);
- if (md != null)
- md.SetIsUsed ();
-
- is_static = setter.IsStatic;
- }
+ return TypeManager.GetFullNameSignature (spec);
}
public SLE.Expression MakeAssignExpression (BuilderContext ctx)
{
- return SLE.Expression.Property (InstanceExpression.MakeExpression (ctx), (MethodInfo) setter.MetaInfo);
+ return SLE.Expression.Property (InstanceExpression.MakeExpression (ctx), (MethodInfo) spec.Set.GetMetaInfo ());
}
public override SLE.Expression MakeExpression (BuilderContext ctx)
{
- return SLE.Expression.Property (InstanceExpression.MakeExpression (ctx), (MethodInfo) getter.MetaInfo);
- }
-
- public override void MutateHoistedGenericType (AnonymousMethodStorey storey)
- {
- if (InstanceExpression != null)
- InstanceExpression.MutateHoistedGenericType (storey);
-
- type = storey.MutateType (type);
- if (getter != null)
- storey.MutateGenericMethod (getter);
- if (setter != null)
- storey.MutateGenericMethod (setter);
+ return SLE.Expression.Property (InstanceExpression.MakeExpression (ctx), (MethodInfo) spec.Get.GetMetaInfo ());
}
- public PropertyInfo PropertyInfo {
+ public PropertySpec PropertyInfo {
get {
- return spec.MetaInfo;
+ return spec;
}
}
bool InstanceResolve (ResolveContext ec, bool lvalue_instance, bool must_do_cs1540_check)
{
- if (is_static) {
+ if (IsStatic) {
InstanceExpression = null;
return true;
}
!TypeManager.IsInstantiationOfSameGenericType (InstanceExpression.Type, ec.CurrentType) &&
!TypeManager.IsNestedChildOf (ec.CurrentType, InstanceExpression.Type) &&
!TypeManager.IsSubclassOf (InstanceExpression.Type, ec.CurrentType)) {
- ec.Report.SymbolRelatedToPreviousError (spec.MetaInfo);
- Error_CannotAccessProtected (ec, loc, spec.MetaInfo, InstanceExpression.Type, ec.CurrentType);
+ ec.Report.SymbolRelatedToPreviousError (spec);
+ Error_CannotAccessProtected (ec, loc, spec, InstanceExpression.Type, ec.CurrentType);
return false;
}
return true;
}
- void Error_PropertyNotFound (ResolveContext ec, MethodSpec mi, bool getter)
+ void Error_PropertyNotValid (ResolveContext ec)
{
- // TODO: correctly we should compare arguments but it will lead to bigger changes
- if (mi.MetaInfo is MethodBuilder) {
- Error_TypeDoesNotContainDefinition (ec, loc, spec.DeclaringType, Name);
- return;
- }
-
- StringBuilder sig = new StringBuilder (TypeManager.CSharpName (mi.DeclaringType));
- sig.Append ('.');
- AParametersCollection iparams = mi.Parameters;
- sig.Append (getter ? "get_" : "set_");
- sig.Append (Name);
- sig.Append (iparams.GetSignatureForError ());
-
- ec.Report.SymbolRelatedToPreviousError (mi.MetaInfo);
- ec.Report.Error (1546, loc, "Property `{0}' is not supported by the C# language. Try to call the accessor method `{1}' directly",
- Name, sig.ToString ());
+ 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;
- var 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;
}
protected override Expression DoResolve (ResolveContext ec)
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);
//
// Only base will allow this invocation to happen.
//
- if (IsBase && getter.IsAbstract) {
- Error_CannotCallAbstractBase (ec, TypeManager.GetFullNameSignature (spec.MetaInfo));
+ if (IsBase && spec.IsAbstract) {
+ Error_CannotCallAbstractBase (ec, TypeManager.GetFullNameSignature (spec));
}
- if (spec.PropertyType.IsPointer && !ec.IsUnsafe){
+ if (spec.MemberType.IsPointer && !ec.IsUnsafe){
UnsafeError (ec, loc);
}
if (!ec.IsObsolete) {
- PropertyBase pb = TypeManager.GetProperty (spec.MetaInfo);
- if (pb != null) {
- pb.CheckObsoleteness (loc);
- } else {
- ObsoleteAttribute oa = AttributeTester.GetMemberObsoleteAttribute (spec.MetaInfo);
- 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;
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 (!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",
spec.Name);
return null;
}
- if (setter.Parameters.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.MetaInfo) 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.MetaInfo);
- 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;
}
//
// Only base will allow this invocation to happen.
//
- if (IsBase && setter.IsAbstract){
- Error_CannotCallAbstractBase (ec, TypeManager.GetFullNameSignature (spec.MetaInfo));
+ if (IsBase && spec.IsAbstract){
+ Error_CannotCallAbstractBase (ec, TypeManager.GetFullNameSignature (spec));
}
- if (spec.PropertyType.IsPointer && !ec.IsUnsafe) {
+ if (spec.MemberType.IsPointer && !ec.IsUnsafe) {
UnsafeError (ec, loc);
}
if (!ec.IsObsolete) {
- PropertyBase pb = TypeManager.GetProperty (spec.MetaInfo);
- if (pb != null) {
- pb.CheckObsoleteness (loc);
- } else {
- ObsoleteAttribute oa = AttributeTester.GetMemberObsoleteAttribute (spec.MetaInfo);
- 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, IsBase, InstanceExpression, spec.Get, 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, IsBase, InstanceExpression, spec.Set, args, loc, false, prepared);
if (temp != null) {
temp.Emit (ec);
return false;
}
- if (getter != null) {
- if (!getter.Parameters.IsEmpty) {
- 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 (spec.MetaInfo));
+ spec.GetSignatureForError ());
return false;
}
}
- if (getter != null &&
- !IsAccessorAccessible (ec.CurrentType, getter, out must_do_cs1540_check)) {
- PropertyBase.PropertyMethod pm = TypeManager.GetMethod (getter.MetaInfo) as PropertyBase.PropertyMethod;
- if (pm != null && pm.HasCustomAccessModifier) {
- ec.Report.SymbolRelatedToPreviousError (pm);
+ 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.MetaInfo));
+ TypeManager.CSharpSignature (spec));
} else {
- ec.Report.SymbolRelatedToPreviousError (getter.MetaInfo);
- ErrorIsInaccesible (loc, TypeManager.CSharpSignature (getter.MetaInfo), ec.Report);
+ ec.Report.SymbolRelatedToPreviousError (spec.Get);
+ ErrorIsInaccesible (loc, TypeManager.CSharpSignature (spec.Get), ec.Report);
}
return false;
}
}
- public override Type DeclaringType {
+ public override TypeSpec DeclaringType {
get {
return spec.DeclaringType;
}
TypeManager.IsNestedChildOf(ec.CurrentType, spec.DeclaringType)) {
// TODO: Breaks dynamic binder as currect context fields are imported and not compiled
- EventField mi = TypeManager.GetEventField (spec.MetaInfo).MemberDefinition as EventField;
+ EventField mi = spec.MemberDefinition as EventField;
if (mi != null && mi.HasBackingField) {
mi.SetIsUsed ();
return false;
if (IsBase && spec.IsAbstract) {
- Error_CannotCallAbstractBase (ec, TypeManager.CSharpSignature(spec.MetaInfo));
+ Error_CannotCallAbstractBase (ec, TypeManager.CSharpSignature(spec));
return false;
}
!TypeManager.IsInstantiationOfSameGenericType (InstanceExpression.Type, ec.CurrentType) &&
!TypeManager.IsNestedChildOf (ec.CurrentType, InstanceExpression.Type) &&
!TypeManager.IsSubclassOf (InstanceExpression.Type, ec.CurrentType)) {
- ec.Report.SymbolRelatedToPreviousError (spec.MetaInfo);
- ErrorIsInaccesible (loc, TypeManager.CSharpSignature (spec.MetaInfo), ec.Report);
+ 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, spec.AccessorAdd, out dummy) &&
- IsAccessorAccessible (invocation_type, spec.AccessorRemove, out dummy);
+ return IsMemberAccessible (invocation_type, spec.AccessorAdd, out dummy) &&
+ IsMemberAccessible (invocation_type, spec.AccessorRemove, out dummy);
}
public override Expression CreateExpressionTree (ResolveContext ec)
eclass = ExprClass.EventAccess;
bool must_do_cs1540_check;
- if (!(IsAccessorAccessible (ec.CurrentType, spec.AccessorAdd, out must_do_cs1540_check) &&
- IsAccessorAccessible (ec.CurrentType, spec.AccessorRemove, out must_do_cs1540_check))) {
- ec.Report.SymbolRelatedToPreviousError (spec.MetaInfo);
- ErrorIsInaccesible (loc, TypeManager.CSharpSignature (spec.MetaInfo), ec.Report);
+ 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;
}
}
if (!ec.IsObsolete) {
- var oa = spec.GetObsoleteAttribute ();
+ var oa = spec.GetAttributeObsolete ();
if (oa != null)
AttributeTester.Report_ObsoleteMessage (oa, GetSignatureForError (), loc, ec.Report);
}
spec.MemberDefinition.SetIsUsed ();
- type = spec.EventType;
+ type = spec.MemberType;
return this;
}
public override string GetSignatureForError ()
{
- return TypeManager.CSharpSignature (spec.MetaInfo);
+ return TypeManager.CSharpSignature (spec);
}
public void EmitAddOrRemove (EmitContext ec, bool is_add, Expression source)
{
LocalInfo li;
- public TemporaryVariable (Type type, Location loc)
+ public TemporaryVariable (TypeSpec type, Location loc)
{
this.type = type;
this.loc = loc;
{
class EnumTypeExpr : TypeExpr
{
- public readonly Enum Enum;
-
- public EnumTypeExpr (Enum e)
- {
- this.Enum = e;
- }
-
protected override TypeExpr DoResolveAsTypeStep (IMemberContext ec)
{
- type = Enum.CurrentType != null ? Enum.CurrentType : Enum.TypeBuilder;
+ type = ec.CurrentType;
return this;
}
public EnumMember (Enum parent, EnumMember prev_member, string name, Expression expr,
Attributes attrs, Location loc)
- : base (parent, new EnumTypeExpr (parent), name, null, Modifiers.PUBLIC,
+ : base (parent, new EnumTypeExpr (), name, null, Modifiers.PUBLIC,
attrs, loc)
{
initializer = new EnumInitializer (this, expr, prev_member);
}
- static bool IsValidEnumType (Type t)
+ static bool IsValidEnumType (TypeSpec t)
{
return (t == TypeManager.int32_type || t == TypeManager.uint32_type || t == TypeManager.int64_type ||
t == TypeManager.byte_type || t == TypeManager.sbyte_type || t == TypeManager.short_type ||
return false;
const FieldAttributes attr = FieldAttributes.Public | FieldAttributes.Static | FieldAttributes.Literal;
- FieldBuilder = Parent.TypeBuilder.DefineField (Name, MemberType, attr);
- spec = new ConstSpec (this, FieldBuilder, ModFlags, initializer);
-
- Parent.MemberCache.AddMember (FieldBuilder, spec);
- TypeManager.RegisterConstant (FieldBuilder, (ConstSpec) spec);
+ FieldBuilder = Parent.TypeBuilder.DefineField (Name, MemberType.GetMetaInfo (), attr);
+ spec = new ConstSpec (Parent.Definition, this, MemberType, FieldBuilder, ModFlags, initializer);
+ Parent.MemberCache.AddMember (spec);
return true;
}
}
return field.ConvertInitializer (rc, null);
try {
- var ec = prev.Initializer.Resolve (rc) as EnumConstant;
+ var ec = prev.DefineValue () as EnumConstant;
expr = ec.Increment ().Resolve (rc);
} catch (OverflowException) {
rc.Report.Error (543, field.Location,
this.base_type = type;
var accmods = IsTopLevel ? Modifiers.INTERNAL : Modifiers.PRIVATE;
ModFlags = ModifiersExtensions.Check (AllowedModifiers, mod_flags, accmods, Location, Report);
+ spec = new EnumSpec (null, this, null, null, ModFlags);
}
public void AddEnumMember (EnumMember em)
if (!base.DefineNestedTypes ())
return false;
- //
- // Call MapToInternalType for corlib
- //
- TypeBuilder.DefineField (UnderlyingValueField, UnderlyingType,
- FieldAttributes.Public | FieldAttributes.SpecialName
- | FieldAttributes.RTSpecialName);
+ ((EnumSpec) spec).UnderlyingType = UnderlyingType;
+
+ TypeBuilder.DefineField (UnderlyingValueField, UnderlyingType.GetMetaInfo (),
+ FieldAttributes.Public | FieldAttributes.SpecialName | FieldAttributes.RTSpecialName);
+
+ if (!RootContext.StdLib)
+ RootContext.hack_corlib_enums.Add (this);
return true;
}
protected override bool DoDefineMembers ()
{
- member_cache = new MemberCache (TypeManager.enum_type, this);
DefineContainerMembers (constants);
return true;
}
return true;
}
- public Type UnderlyingType {
+ public TypeSpec UnderlyingType {
get {
return base_type.Type;
}
}
}
- public class EnumSpec : TypeSpec
+ class EnumSpec : TypeSpec
{
- public EnumSpec (MemberKind kind, ITypeDefinition definition, TypeSpec underlyingType, Type info, string name, Modifiers modifiers)
- : base (kind, definition, info, name, modifiers)
+ TypeSpec underlying;
+
+ public EnumSpec (TypeSpec declaringType, ITypeDefinition definition, TypeSpec underlyingType, Type info, Modifiers modifiers)
+ : base (MemberKind.Enum, declaringType, definition, info, modifiers | Modifiers.SEALED)
{
- this.UnderlyingType = underlyingType;
+ this.underlying = underlyingType;
}
- public TypeSpec UnderlyingType { get; private set; }
+ public TypeSpec UnderlyingType {
+ get {
+ return underlying;
+ }
+ set {
+ if (underlying != null)
+ throw new InternalErrorException ("UnderlyingType reset");
+
+ underlying = value;
+ }
+ }
+
+ public static TypeSpec GetUnderlyingType (TypeSpec t)
+ {
+ return ((EnumSpec) t.GetDefinition ()).UnderlyingType;
+ }
}
}
internal static List<NamespaceEntry.UsingEntry> using_list = new List<NamespaceEntry.UsingEntry> ();
static Dictionary<string, FieldInfo> fields = new Dictionary<string, FieldInfo> ();
- static Type interactive_base_class = typeof (InteractiveBase);
+ static TypeSpec interactive_base_class;
static Driver driver;
static bool inited;
CompilerCallableEntryPoint.Reset ();
RootContext.ToplevelTypes = new ModuleCompiled (ctx, true);
+ /*var ctypes = */TypeManager.InitCoreTypes ();
+ TypeManager.InitExpressionTypes ();
+ Import.Initialize ();
driver.LoadReferences ();
RootContext.EvalMode = true;
inited = true;
static void Reset ()
{
CompilerCallableEntryPoint.PartialReset ();
+ RootContext.PartialReset ();
// Workaround for API limitation where full message printer cannot be passed
ReportPrinter printer;
//
// PartialReset should not reset the core types, this is very redundant.
//
- if (!TypeManager.InitCoreTypes (ctx))
- throw new Exception ("Failed to InitCoreTypes");
+// if (!TypeManager.InitCoreTypes (ctx, null))
+// throw new Exception ("Failed to InitCoreTypes");
TypeManager.InitOptionalCoreTypes (ctx);
Location.AddFile (null, "{interactive}");
/// base class and the static members that are
/// available to your evaluated code.
/// </remarks>
- static public Type InteractiveBaseClass {
+ static public TypeSpec InteractiveBaseClass {
get {
- return interactive_base_class;
+ if (interactive_base_class != null)
+ return interactive_base_class;
+
+ return interactive_base_class = Import.ImportType (typeof (InteractiveBase));
}
set {
// Unlike Mono, .NET requires that the MethodInfo is fetched, it cant
// work from MethodBuilders. Retarded, I know.
//
- Type tt = CodeGen.Assembly.Builder.GetType (tb.Name);
+ var tt = CodeGen.Assembly.Builder.GetType (tb.Name);
MethodInfo mi = tt.GetMethod (mb.Name);
// Pull the FieldInfos from the type, and keep track of them
// If a previous value was set, nullify it, so that we do
// not leak memory
if (fields.TryGetValue (field.Name, out old)){
- if (TypeManager.IsStruct (old.FieldType)){
+ if (old.FieldType.IsValueType){
//
// TODO: Clear fields for structs
//
foreach (var de in fields){
FieldInfo fi = LookupField (de.Key);
object value = null;
- bool error = false;
+ //bool error = false;
try {
if (value == null)
if (value is string)
value = Quote ((string)value);
} catch {
- error = true;
+ //error = true;
}
-
- if (error)
- sb.Append (String.Format ("{0} {1} <error reading value>", TypeManager.CSharpName(fi.FieldType), de.Key));
- else
- sb.Append (String.Format ("{0} {1} = {2}", TypeManager.CSharpName(fi.FieldType), de.Key, value));
+
+ throw new NotImplementedException ("net");
+ //if (error)
+ // sb.Append (String.Format ("{0} {1} <error reading value>", TypeManager.CSharpName(fi.FieldType), de.Key));
+ //else
+ // sb.Append (String.Format ("{0} {1} = {2}", TypeManager.CSharpName(fi.FieldType), de.Key, value));
}
return sb.ToString ();
static public void ReferenceAssembly (Assembly a)
{
lock (evaluator_lock){
- GlobalRootNamespace.Instance.AddAssemblyReference (a);
- GlobalRootNamespace.Instance.ComputeNamespaces (ctx);
+// GlobalRootNamespace.Instance.AddAssemblyReference (a);
+// GlobalRootNamespace.Instance.ComputeNamespaces (ctx);
+ GlobalRootNamespace.Instance.ImportAssembly (a);
}
}
if (x == null)
return "";
- Type t = x as Type;
- if (t == null)
- t = x.GetType ();
+ TypeSpec t = x as TypeSpec;
+// if (t == null)
+// t = x.GetType ();
StringWriter sw = new StringWriter ();
- new Outline (t, sw, true, false, false).OutlineType ();
+ new Outline (t.GetMetaInfo (), sw, true, false, false).OutlineType ();
return sw.ToString ();
}
#endif
this.arguments = args;
this.expr_tree = expr_tree;
- type = TypeManager.TypeToCoreType (((MethodSpec) mg).ReturnType);
+ type = mg.BestCandidate.ReturnType;
eclass = ExprClass.Value;
this.loc = loc;
}
public override SLE.Expression MakeExpression (BuilderContext ctx)
{
- var method = ((MethodSpec) mg).MetaInfo as MethodInfo;
+ var method = mg.BestCandidate.GetMetaInfo () as MethodInfo;
return SLE.Expression.Call (method, Arguments.MakeExpression (arguments, ctx));
}
public MethodGroupExpr Method {
get { return mg; }
}
-
- public override void MutateHoistedGenericType (AnonymousMethodStorey storey)
- {
- arguments.MutateHoistedGenericType (storey);
- mg.MutateHoistedGenericType (storey);
- }
}
public class ParenthesizedExpression : ShimExpression
AddressOf, TOP
}
- static Type [] [] predefined_operators;
+ static TypeSpec[][] predefined_operators;
public readonly Operator Oper;
public Expression Expr;
return r == null ? null : new SideEffectConstant (r, e, r.Location);
}
- Type expr_type = e.Type;
+ TypeSpec expr_type = e.Type;
switch (Oper){
case Operator.UnaryPlus:
if (predefined_operators == null)
CreatePredefinedOperatorsTable ();
- Type expr_type = expr.Type;
+ TypeSpec expr_type = expr.Type;
Expression best_expr;
//
protected virtual Expression ResolveEnumOperator (ResolveContext ec, Expression expr)
{
- Type underlying_type = TypeManager.GetEnumUnderlyingType (expr.Type);
+ TypeSpec underlying_type = EnumSpec.GetUnderlyingType (expr.Type);
Expression best_expr = ResolvePrimitivePredefinedType (EmptyCast.Create (expr, underlying_type));
if (best_expr == null)
return null;
static void CreatePredefinedOperatorsTable ()
{
- predefined_operators = new Type [(int) Operator.TOP] [];
+ predefined_operators = new TypeSpec [(int) Operator.TOP] [];
//
// 7.6.1 Unary plus operator
//
- predefined_operators [(int) Operator.UnaryPlus] = new Type [] {
+ predefined_operators [(int) Operator.UnaryPlus] = new TypeSpec [] {
TypeManager.int32_type, TypeManager.uint32_type,
TypeManager.int64_type, TypeManager.uint64_type,
TypeManager.float_type, TypeManager.double_type,
//
// 7.6.2 Unary minus operator
//
- predefined_operators [(int) Operator.UnaryNegation] = new Type [] {
+ predefined_operators [(int) Operator.UnaryNegation] = new TypeSpec [] {
TypeManager.int32_type,
TypeManager.int64_type,
TypeManager.float_type, TypeManager.double_type,
//
// 7.6.3 Logical negation operator
//
- predefined_operators [(int) Operator.LogicalNot] = new Type [] {
+ predefined_operators [(int) Operator.LogicalNot] = new TypeSpec [] {
TypeManager.bool_type
};
//
// 7.6.4 Bitwise complement operator
//
- predefined_operators [(int) Operator.OnesComplement] = new Type [] {
+ predefined_operators [(int) Operator.OnesComplement] = new TypeSpec [] {
TypeManager.int32_type, TypeManager.uint32_type,
TypeManager.int64_type, TypeManager.uint64_type
};
//
static Expression DoNumericPromotion (Operator op, Expression expr)
{
- Type expr_type = expr.Type;
+ TypeSpec expr_type = expr.Type;
if ((op == Operator.UnaryPlus || op == Operator.UnaryNegation || op == Operator.OnesComplement) &&
expr_type == TypeManager.byte_type || expr_type == TypeManager.sbyte_type ||
expr_type == TypeManager.short_type || expr_type == TypeManager.ushort_type ||
if (Expr == null)
return null;
- if (TypeManager.IsDynamicType (Expr.Type)) {
+ if (Expr.Type == InternalType.Dynamic) {
Arguments args = new Arguments (1);
args.Add (new Argument (Expr));
return new DynamicUnaryConversion (GetOperatorExpressionTypeName (), args, loc).Resolve (ec);
EmitOperator (ec, type);
}
- protected void EmitOperator (EmitContext ec, Type type)
+ protected void EmitOperator (EmitContext ec, TypeSpec type)
{
- ILGenerator ig = ec.ig;
-
switch (Oper) {
case Operator.UnaryPlus:
Expr.Emit (ec);
case Operator.UnaryNegation:
if (ec.HasSet (EmitContext.Options.CheckedScope) && !IsFloat (type)) {
- ig.Emit (OpCodes.Ldc_I4_0);
+ ec.Emit (OpCodes.Ldc_I4_0);
if (type == TypeManager.int64_type)
- ig.Emit (OpCodes.Conv_U8);
+ ec.Emit (OpCodes.Conv_U8);
Expr.Emit (ec);
- ig.Emit (OpCodes.Sub_Ovf);
+ ec.Emit (OpCodes.Sub_Ovf);
} else {
Expr.Emit (ec);
- ig.Emit (OpCodes.Neg);
+ ec.Emit (OpCodes.Neg);
}
break;
case Operator.LogicalNot:
Expr.Emit (ec);
- ig.Emit (OpCodes.Ldc_I4_0);
- ig.Emit (OpCodes.Ceq);
+ ec.Emit (OpCodes.Ldc_I4_0);
+ ec.Emit (OpCodes.Ceq);
break;
case Operator.OnesComplement:
Expr.Emit (ec);
- ig.Emit (OpCodes.Not);
+ ec.Emit (OpCodes.Not);
break;
case Operator.AddressOf:
Expr.EmitSideEffect (ec);
}
- public static void Error_OperatorCannotBeApplied (ResolveContext ec, Location loc, string oper, Type t)
+ public static void Error_OperatorCannotBeApplied (ResolveContext ec, Location loc, string oper, TypeSpec t)
{
ec.Report.Error (23, loc, "The `{0}' operator cannot be applied to operand of type `{1}'",
oper, TypeManager.CSharpName (t));
}
}
- static bool IsFloat (Type t)
+ static bool IsFloat (TypeSpec t)
{
return t == TypeManager.float_type || t == TypeManager.double_type;
}
}
}
- public override void MutateHoistedGenericType (AnonymousMethodStorey storey)
+ public static void Reset ()
{
- type = storey.MutateType (type);
- Expr.MutateHoistedGenericType (storey);
+ predefined_operators = null;
}
Expression ResolveAddressOf (ResolveContext ec)
ec.Report.Error (212, loc, "You can only take the address of unfixed expression inside of a fixed statement initializer");
}
- type = TypeManager.GetPointerType (Expr.Type);
+ type = PointerContainer.MakeType (Expr.Type);
eclass = ExprClass.Value;
return this;
}
Expression ResolvePrimitivePredefinedType (Expression expr)
{
expr = DoNumericPromotion (Oper, expr);
- Type expr_type = expr.Type;
- Type[] predefined = predefined_operators [(int) Oper];
- foreach (Type t in predefined) {
+ TypeSpec expr_type = expr.Type;
+ TypeSpec[] predefined = predefined_operators [(int) Oper];
+ foreach (TypeSpec t in predefined) {
if (t == expr_type)
return expr;
}
}
string op_name = CSharp.Operator.GetMetadataName (op_type);
- MethodGroupExpr user_op = MemberLookup (ec.Compiler, ec.CurrentType, expr.Type, op_name, MemberTypes.Method, AllBindingFlags, expr.Location) as MethodGroupExpr;
+ MethodGroupExpr user_op = MethodLookup (ec.Compiler, ec.CurrentType, expr.Type, MemberKind.Operator, op_name, 0, expr.Location);
if (user_op == null)
return null;
if (best_expr != null)
return best_expr;
- Type[] predefined = predefined_operators [(int) Oper];
- foreach (Type t in predefined) {
+ TypeSpec[] predefined = predefined_operators [(int) Oper];
+ foreach (TypeSpec t in predefined) {
Expression oper_expr = Convert.UserDefinedConversion (ec, expr, t, expr.Location, false, false);
if (oper_expr == null)
continue;
if (!prepared)
expr.Emit (ec);
- LoadFromPtr (ec.ig, Type);
+ ec.EmitLoadFromPtr (Type);
}
public void Emit (EmitContext ec, bool leave_copy)
{
Emit (ec);
if (leave_copy) {
- ec.ig.Emit (OpCodes.Dup);
+ ec.Emit (OpCodes.Dup);
temporary = new LocalTemporary (expr.Type);
temporary.Store (ec);
}
expr.Emit (ec);
if (prepare_for_load)
- ec.ig.Emit (OpCodes.Dup);
+ ec.Emit (OpCodes.Dup);
source.Emit (ec);
if (leave_copy) {
- ec.ig.Emit (OpCodes.Dup);
+ ec.Emit (OpCodes.Dup);
temporary = new LocalTemporary (expr.Type);
temporary.Store (ec);
}
- StoreFromPtr (ec.ig, type);
+ ec.EmitStoreFromPtr (type);
if (temporary != null) {
temporary.Emit (ec);
if (expr == null)
return null;
- if (TypeManager.IsDynamicType (expr.Type)) {
+ if (expr.Type == InternalType.Dynamic) {
//
// Handle postfix unary operators using local
// temporary variable
// use pre-post incr-decr operations on it, but it is not a
// System.Decimal, which we require operator overloading to catch)
//
- static bool IsPredefinedOperator (Type t)
+ static bool IsPredefinedOperator (TypeSpec t)
{
return (TypeManager.IsPrimitiveType (t) && t != TypeManager.bool_type) ||
TypeManager.IsEnumType (t) ||
//
// Step 2: Perform Operator Overload location
//
- MethodGroupExpr mg;
string op_name;
if (IsDecrement)
else
op_name = Operator.GetMetadataName (Operator.OpType.Increment);
- mg = MemberLookup (ec.Compiler, ec.CurrentType, type, op_name, MemberTypes.Method, AllBindingFlags, loc) as MethodGroupExpr;
+ var mg = MethodLookup (ec.Compiler, ec.CurrentType, type, MemberKind.Operator, op_name, 0, loc);
if (mg != null) {
Arguments args = new Arguments (1);
if (expr == null)
return null;
- if ((probe_type_expr.Type.Attributes & Class.StaticClassAttribute) == Class.StaticClassAttribute) {
+ if (probe_type_expr.Type.IsStatic) {
ec.Report.Error (-244, loc, "The `{0}' operator cannot be applied to an operand of a static type",
OperatorName);
}
return this;
}
- public override void MutateHoistedGenericType (AnonymousMethodStorey storey)
- {
- expr.MutateHoistedGenericType (storey);
- probe_type_expr.MutateHoistedGenericType (storey);
- }
-
protected abstract string OperatorName { get; }
protected override void CloneTo (CloneContext clonectx, Expression t)
public override void Emit (EmitContext ec)
{
- ILGenerator ig = ec.ig;
if (expr_unwrap != null) {
expr_unwrap.EmitCheck (ec);
return;
}
expr.Emit (ec);
- ig.Emit (OpCodes.Isinst, probe_type_expr.Type);
- ig.Emit (OpCodes.Ldnull);
- ig.Emit (OpCodes.Cgt_Un);
+ ec.Emit (OpCodes.Isinst, probe_type_expr.Type);
+ ec.Emit (OpCodes.Ldnull);
+ ec.Emit (OpCodes.Cgt_Un);
}
public override void EmitBranchable (EmitContext ec, Label target, bool on_true)
{
- ILGenerator ig = ec.ig;
if (expr_unwrap != null) {
expr_unwrap.EmitCheck (ec);
} else {
expr.Emit (ec);
- ig.Emit (OpCodes.Isinst, probe_type_expr.Type);
+ ec.Emit (OpCodes.Isinst, probe_type_expr.Type);
}
- ig.Emit (on_true ? OpCodes.Brtrue : OpCodes.Brfalse, target);
+ ec.Emit (on_true ? OpCodes.Brtrue : OpCodes.Brfalse, target);
}
Expression CreateConstantResult (ResolveContext ec, bool result)
if (base.DoResolve (ec) == null)
return null;
- Type d = expr.Type;
+ TypeSpec d = expr.Type;
bool d_is_nullable = false;
//
if (expr.IsNull || expr.eclass == ExprClass.MethodGroup)
return CreateConstantResult (ec, false);
- if (TypeManager.IsNullableType (d) && !TypeManager.ContainsGenericParameters (d)) {
- d = TypeManager.TypeToCoreType (TypeManager.GetTypeArguments (d) [0]);
- d_is_nullable = true;
+ if (TypeManager.IsNullableType (d)) {
+ var ut = Nullable.NullableInfo.GetUnderlyingType (d);
+ if (!ut.IsGenericParameter) {
+ d = ut;
+ d_is_nullable = true;
+ }
}
type = TypeManager.bool_type;
eclass = ExprClass.Value;
- Type t = probe_type_expr.Type;
+ TypeSpec t = probe_type_expr.Type;
bool t_is_nullable = false;
- if (TypeManager.IsNullableType (t) && !TypeManager.ContainsGenericParameters (t)) {
- t = TypeManager.TypeToCoreType (TypeManager.GetTypeArguments (t) [0]);
- t_is_nullable = true;
+ if (TypeManager.IsNullableType (t)) {
+ var ut = Nullable.NullableInfo.GetUnderlyingType (t);
+ if (!ut.IsGenericParameter) {
+ t = ut;
+ t_is_nullable = true;
+ }
}
if (TypeManager.IsStruct (t)) {
return CreateConstantResult (ec, true);
}
- if (TypeManager.IsGenericParameter (d))
- return ResolveGenericParameter (ec, t, d);
+ var tp = d as TypeParameterSpec;
+ if (tp != null)
+ return ResolveGenericParameter (ec, t, tp);
//
// An unboxing conversion exists
return this;
} else {
if (TypeManager.IsGenericParameter (t))
- return ResolveGenericParameter (ec, d, t);
+ return ResolveGenericParameter (ec, d, (TypeParameterSpec) t);
if (TypeManager.IsStruct (d)) {
bool temp;
return CreateConstantResult (ec, true);
} else {
if (TypeManager.IsGenericParameter (d))
- return ResolveGenericParameter (ec, t, d);
+ return ResolveGenericParameter (ec, t, (TypeParameterSpec) d);
if (TypeManager.ContainsGenericParameters (d))
return this;
return CreateConstantResult (ec, false);
}
- Expression ResolveGenericParameter (ResolveContext ec, Type d, Type t)
+ Expression ResolveGenericParameter (ResolveContext ec, TypeSpec d, TypeParameterSpec t)
{
- GenericConstraints constraints = TypeManager.GetTypeParameterConstraints (t);
- if (constraints != null) {
- if (constraints.IsReferenceType && TypeManager.IsStruct (d))
+ if (t.IsReferenceType) {
+ if (TypeManager.IsStruct (d))
return CreateConstantResult (ec, false);
}
if (TypeManager.IsGenericParameter (expr.Type)) {
- if (constraints != null && constraints.IsValueType && expr.Type == t)
+ if (t.IsValueType && expr.Type == t)
return CreateConstantResult (ec, true);
expr = new BoxedCast (expr, d);
public override void Emit (EmitContext ec)
{
- ILGenerator ig = ec.ig;
-
expr.Emit (ec);
if (do_isinst)
- ig.Emit (OpCodes.Isinst, type);
+ ec.Emit (OpCodes.Isinst, type);
if (TypeManager.IsGenericParameter (type) || TypeManager.IsNullableType (type))
- ig.Emit (OpCodes.Unbox_Any, type);
+ ec.Emit (OpCodes.Unbox_Any, type);
}
protected override Expression DoResolve (ResolveContext ec)
type = probe_type_expr.Type;
eclass = ExprClass.Value;
- Type etype = expr.Type;
+ TypeSpec etype = expr.Type;
if (!TypeManager.IsReferenceType (type) && !TypeManager.IsNullableType (type)) {
if (TypeManager.IsGenericParameter (type)) {
protected override string OperatorName {
get { return "as"; }
}
-
- public override void MutateHoistedGenericType (AnonymousMethodStorey storey)
- {
- type = storey.MutateType (type);
- base.MutateHoistedGenericType (storey);
- }
}
/// <summary>
type = target.Type;
- if (type.IsAbstract && type.IsSealed) {
+ if (type.IsStatic) {
ec.Report.Error (716, loc, "Cannot convert to static type `{0}'", TypeManager.CSharpName (type));
return null;
}
if (type.IsPointer && !ec.IsUnsafe) {
UnsafeError (ec, loc);
- } else if (TypeManager.IsDynamicType (expr.Type)) {
+ } else if (expr.Type == InternalType.Dynamic) {
Arguments arg = new Arguments (1);
arg.Add (new Argument (expr));
return new DynamicConversion (type, CSharpBinderFlags.ConvertExplicit, arg, loc).Resolve (ec);
{
bool arrayAccess;
- public ImplicitCast (Expression expr, Type target, bool arrayAccess)
+ public ImplicitCast (Expression expr, TypeSpec target, bool arrayAccess)
: base (expr)
{
this.loc = expr.Location;
type = texpr.Type;
- if ((type.Attributes & Class.StaticClassAttribute) == Class.StaticClassAttribute) {
+ if (type.IsStatic) {
ec.Report.Error (-244, loc, "The `default value' operator cannot be applied to an operand of a static type");
}
LocalTemporary temp_storage = new LocalTemporary(type);
temp_storage.AddressOf(ec, AddressOp.LoadStore);
- ec.ig.Emit(OpCodes.Initobj, type);
+ ec.Emit(OpCodes.Initobj, type);
temp_storage.Emit(ec);
}
- public override void MutateHoistedGenericType (AnonymousMethodStorey storey)
- {
- type = storey.MutateType (type);
- }
-
protected override void CloneTo (CloneContext clonectx, Expression t)
{
DefaultValueExpression target = (DefaultValueExpression) t;
public class Binary : Expression, IDynamicBinder
{
protected class PredefinedOperator {
- protected readonly Type left;
- protected readonly Type right;
+ protected readonly TypeSpec left;
+ protected readonly TypeSpec right;
public readonly Operator OperatorsMask;
- public Type ReturnType;
+ public TypeSpec ReturnType;
- public PredefinedOperator (Type ltype, Type rtype, Operator op_mask)
+ public PredefinedOperator (TypeSpec ltype, TypeSpec rtype, Operator op_mask)
: this (ltype, rtype, op_mask, ltype)
{
}
- public PredefinedOperator (Type type, Operator op_mask, Type return_type)
+ public PredefinedOperator (TypeSpec type, Operator op_mask, TypeSpec return_type)
: this (type, type, op_mask, return_type)
{
}
- public PredefinedOperator (Type type, Operator op_mask)
+ public PredefinedOperator (TypeSpec type, Operator op_mask)
: this (type, type, op_mask, type)
{
}
- public PredefinedOperator (Type ltype, Type rtype, Operator op_mask, Type return_type)
+ public PredefinedOperator (TypeSpec ltype, TypeSpec rtype, Operator op_mask, TypeSpec return_type)
{
if ((op_mask & Operator.ValuesOnlyMask) != 0)
throw new InternalErrorException ("Only masked values can be used");
return b;
}
- public bool IsPrimitiveApplicable (Type ltype, Type rtype)
+ public bool IsPrimitiveApplicable (TypeSpec ltype, TypeSpec rtype)
{
//
// We are dealing with primitive types only
}
class PredefinedStringOperator : PredefinedOperator {
- public PredefinedStringOperator (Type type, Operator op_mask)
+ public PredefinedStringOperator (TypeSpec type, Operator op_mask)
: base (type, op_mask, type)
{
ReturnType = TypeManager.string_type;
}
- public PredefinedStringOperator (Type ltype, Type rtype, Operator op_mask)
+ public PredefinedStringOperator (TypeSpec ltype, TypeSpec rtype, Operator op_mask)
: base (ltype, rtype, op_mask)
{
ReturnType = TypeManager.string_type;
}
class PredefinedShiftOperator : PredefinedOperator {
- public PredefinedShiftOperator (Type ltype, Operator op_mask) :
+ public PredefinedShiftOperator (TypeSpec ltype, Operator op_mask) :
base (ltype, TypeManager.int32_type, op_mask)
{
}
}
class PredefinedPointerOperator : PredefinedOperator {
- public PredefinedPointerOperator (Type ltype, Type rtype, Operator op_mask)
+ public PredefinedPointerOperator (TypeSpec ltype, TypeSpec rtype, Operator op_mask)
: base (ltype, rtype, op_mask)
{
}
- public PredefinedPointerOperator (Type ltype, Type rtype, Operator op_mask, Type retType)
+ public PredefinedPointerOperator (TypeSpec ltype, TypeSpec rtype, Operator op_mask, TypeSpec retType)
: base (ltype, rtype, op_mask, retType)
{
}
- public PredefinedPointerOperator (Type type, Operator op_mask, Type return_type)
+ public PredefinedPointerOperator (TypeSpec type, Operator op_mask, TypeSpec return_type)
: base (type, op_mask, return_type)
{
}
b.right = EmptyCast.Create (b.right, right);
}
- Type r_type = ReturnType;
+ TypeSpec r_type = ReturnType;
Expression left_arg, right_arg;
if (r_type == null) {
if (left == null) {
readonly bool is_compound;
Expression enum_conversion;
- static PredefinedOperator [] standard_operators;
- static PredefinedOperator [] pointer_operators;
+ static PredefinedOperator[] standard_operators;
+ static PredefinedOperator[] pointer_operators;
public Binary (Operator oper, Expression left, Expression right, bool isCompound, Location loc)
: this (oper, left, right, loc)
return CSharp.Operator.GetMetadataName (op_type);
}
- public static void EmitOperatorOpcode (EmitContext ec, Operator oper, Type l)
+ public static void EmitOperatorOpcode (EmitContext ec, Operator oper, TypeSpec l)
{
OpCode opcode;
- ILGenerator ig = ec.ig;
switch (oper){
case Operator.Multiply:
break;
case Operator.Inequality:
- ig.Emit (OpCodes.Ceq);
- ig.Emit (OpCodes.Ldc_I4_0);
+ ec.Emit (OpCodes.Ceq);
+ ec.Emit (OpCodes.Ldc_I4_0);
opcode = OpCodes.Ceq;
break;
case Operator.LessThanOrEqual:
if (IsUnsigned (l) || IsFloat (l))
- ig.Emit (OpCodes.Cgt_Un);
+ ec.Emit (OpCodes.Cgt_Un);
else
- ig.Emit (OpCodes.Cgt);
- ig.Emit (OpCodes.Ldc_I4_0);
+ ec.Emit (OpCodes.Cgt);
+ ec.Emit (OpCodes.Ldc_I4_0);
opcode = OpCodes.Ceq;
break;
case Operator.GreaterThanOrEqual:
if (IsUnsigned (l) || IsFloat (l))
- ig.Emit (OpCodes.Clt_Un);
+ ec.Emit (OpCodes.Clt_Un);
else
- ig.Emit (OpCodes.Clt);
+ ec.Emit (OpCodes.Clt);
- ig.Emit (OpCodes.Ldc_I4_0);
+ ec.Emit (OpCodes.Ldc_I4_0);
opcode = OpCodes.Ceq;
break;
throw new InternalErrorException (oper.ToString ());
}
- ig.Emit (opcode);
+ ec.Emit (opcode);
}
- static bool IsUnsigned (Type t)
+ static bool IsUnsigned (TypeSpec t)
{
if (t.IsPointer)
return true;
t == TypeManager.ushort_type || t == TypeManager.byte_type);
}
- static bool IsFloat (Type t)
+ static bool IsFloat (TypeSpec t)
{
return t == TypeManager.float_type || t == TypeManager.double_type;
}
+ public static void Reset ()
+ {
+ pointer_operators = standard_operators = null;
+ }
+
Expression ResolveOperator (ResolveContext ec)
{
- Type l = left.Type;
- Type r = right.Type;
+ TypeSpec l = left.Type;
+ TypeSpec r = right.Type;
Expression expr;
bool primitives_only = false;
static void CreateStandardOperatorsTable ()
{
var temp = new List<PredefinedOperator> ();
- Type bool_type = TypeManager.bool_type;
+ TypeSpec bool_type = TypeManager.bool_type;
temp.Add (new PredefinedOperator (TypeManager.int32_type, Operator.ArithmeticMask | Operator.BitwiseMask));
temp.Add (new PredefinedOperator (TypeManager.uint32_type, Operator.ArithmeticMask | Operator.BitwiseMask));
//
// Rules used during binary numeric promotion
//
- static bool DoNumericPromotion (ResolveContext rc, ref Expression prim_expr, ref Expression second_expr, Type type)
+ static bool DoNumericPromotion (ResolveContext rc, ref Expression prim_expr, ref Expression second_expr, TypeSpec type)
{
Expression temp;
- Type etype;
+ TypeSpec etype;
Constant c = prim_expr as Constant;
if (c != null) {
//
public bool DoBinaryOperatorPromotion (ResolveContext ec)
{
- Type ltype = left.Type;
- Type rtype = right.Type;
+ TypeSpec ltype = left.Type;
+ TypeSpec rtype = right.Type;
Expression temp;
- foreach (Type t in ConstantFold.binary_promotions) {
+ foreach (TypeSpec t in ConstantFold.BinaryPromotionsTypes) {
if (t == ltype)
return t == rtype || DoNumericPromotion (ec, ref right, ref left, t);
return t == ltype || DoNumericPromotion (ec, ref left, ref right, t);
}
- Type int32 = TypeManager.int32_type;
+ TypeSpec int32 = TypeManager.int32_type;
if (ltype != int32) {
Constant c = left as Constant;
if (c != null)
CheckUselessComparison (ec, rc, left.Type);
}
- if (TypeManager.IsDynamicType (left.Type) || TypeManager.IsDynamicType (right.Type)) {
+ if (left.Type == InternalType.Dynamic || right.Type == InternalType.Dynamic) {
Arguments args = new Arguments (2);
args.Add (new Argument (left));
args.Add (new Argument (right));
}
}
- public override void MutateHoistedGenericType (AnonymousMethodStorey storey)
- {
- left.MutateHoistedGenericType (storey);
- right.MutateHoistedGenericType (storey);
- }
-
//
// D operator + (D x, D y)
// D operator - (D x, D y)
// bool operator == (D x, D y)
// bool operator != (D x, D y)
//
- Expression ResolveOperatorDelegate (ResolveContext ec, Type l, Type r)
+ Expression ResolveOperatorDelegate (ResolveContext ec, TypeSpec l, TypeSpec r)
{
bool is_equality = (oper & Operator.EqualityMask) != 0;
- if (!TypeManager.IsEqual (l, r) && !TypeManager.IsVariantOf (r, l)) {
+ if (!TypeManager.IsEqual (l, r) && !TypeSpecComparer.Variant.IsEqual (r, l)) {
Expression tmp;
if (right.eclass == ExprClass.MethodGroup || (r == InternalType.AnonymousMethod && !is_equality)) {
tmp = Convert.ImplicitConversionRequired (ec, right, l, loc);
method = TypeManager.delegate_remove_delegate_delegate;
}
- MethodGroupExpr mg = new MethodGroupExpr (new [] { method }, TypeManager.delegate_type, loc);
+ if (method == null)
+ return new EmptyExpression (TypeManager.decimal_type);
+
+ MethodGroupExpr mg = new MethodGroupExpr (method, TypeManager.delegate_type, loc);
mg = mg.OverloadResolve (ec, ref args, false, loc);
return new ClassCast (new UserOperatorCall (mg, args, CreateExpressionTree, loc), l);
//
// Enumeration operators
//
- Expression ResolveOperatorEnum (ResolveContext ec, bool lenum, bool renum, Type ltype, Type rtype)
+ Expression ResolveOperatorEnum (ResolveContext ec, bool lenum, bool renum, TypeSpec ltype, TypeSpec rtype)
{
//
// bool operator == (E x, E y);
Expression ltemp = left;
Expression rtemp = right;
- Type underlying_type;
+ TypeSpec underlying_type;
Expression expr;
if ((oper & (Operator.ComparisonMask | Operator.BitwiseMask)) != 0) {
}
if (TypeManager.IsEqual (ltype, rtype)) {
- underlying_type = TypeManager.GetEnumUnderlyingType (ltype);
+ underlying_type = EnumSpec.GetUnderlyingType (ltype);
if (left is Constant)
left = ((Constant) left).ConvertExplicitly (false, underlying_type).Resolve (ec);
else
right = EmptyCast.Create (right, underlying_type);
} else if (lenum) {
- underlying_type = TypeManager.GetEnumUnderlyingType (ltype);
+ underlying_type = EnumSpec.GetUnderlyingType (ltype);
if (oper != Operator.Subtraction && oper != Operator.Addition) {
Constant c = right as Constant;
left = EmptyCast.Create (left, underlying_type);
} else if (renum) {
- underlying_type = TypeManager.GetEnumUnderlyingType (rtype);
+ underlying_type = EnumSpec.GetUnderlyingType (rtype);
if (oper != Operator.Addition) {
Constant c = left as Constant;
return null;
}
- Type res_type = null;
+ TypeSpec res_type = null;
if ((oper & Operator.BitwiseMask) != 0 || oper == Operator.Subtraction || oper == Operator.Addition) {
- Type promoted_type = lenum ? left.Type : right.Type;
+ TypeSpec promoted_type = lenum ? left.Type : right.Type;
enum_conversion = Convert.ExplicitNumericConversion (
new EmptyExpression (promoted_type), underlying_type);
//
// 7.9.6 Reference type equality operators
//
- Binary ResolveOperatorEqualityRerefence (ResolveContext ec, Type l, Type r)
+ Binary ResolveOperatorEqualityRerefence (ResolveContext ec, TypeSpec l, TypeSpec r)
{
//
// operator != (object a, object b)
return null;
type = TypeManager.bool_type;
- GenericConstraints constraints;
- bool lgen = TypeManager.IsGenericParameter (l);
+ var lgen = l as TypeParameterSpec;
+
+ if (l == r) {
+ if (l is InternalType)
+ return null;
- if (TypeManager.IsEqual (l, r)) {
- if (lgen) {
+ if (lgen != null) {
//
// Only allow to compare same reference type parameter
//
return null;
}
- if (l == InternalType.AnonymousMethod)
- return null;
-
if (TypeManager.IsValueType (l))
return null;
return this;
}
- bool rgen = TypeManager.IsGenericParameter (r);
+ var rgen = r as TypeParameterSpec;
//
// a, Both operands are reference-type values or the value null
// value type constrain
//
if (left is NullLiteral || right is NullLiteral) {
- if (lgen) {
- constraints = TypeManager.GetTypeParameterConstraints (l);
- if (constraints != null && constraints.HasValueTypeConstraint)
+ if (lgen != null) {
+ if (lgen.HasSpecialStruct)
return null;
left = new BoxedCast (left, TypeManager.object_type);
return this;
}
- if (rgen) {
- constraints = TypeManager.GetTypeParameterConstraints (r);
- if (constraints != null && constraints.HasValueTypeConstraint)
+ if (rgen != null) {
+ if (rgen.HasSpecialStruct)
return null;
right = new BoxedCast (right, TypeManager.object_type);
// standard conversion is applied. It's not clear from the
// standard but it looks like it works like that.
//
- if (lgen) {
+ if (lgen != null) {
if (!TypeManager.IsReferenceType (l))
return null;
return null;
}
- if (rgen) {
+ if (rgen != null) {
if (!TypeManager.IsReferenceType (r))
return null;
}
- Expression ResolveOperatorPointer (ResolveContext ec, Type l, Type r)
+ Expression ResolveOperatorPointer (ResolveContext ec, TypeSpec l, TypeSpec r)
{
//
// bool operator == (void* x, void* y);
//
// Build-in operators method overloading
//
- protected virtual Expression ResolveOperatorPredefined (ResolveContext ec, PredefinedOperator [] operators, bool primitives_only, Type enum_type)
+ protected virtual Expression ResolveOperatorPredefined (ResolveContext ec, PredefinedOperator [] operators, bool primitives_only, TypeSpec enum_type)
{
PredefinedOperator best_operator = null;
- Type l = left.Type;
- Type r = right.Type;
+ TypeSpec l = left.Type;
+ TypeSpec r = right.Type;
Operator oper_mask = oper & ~Operator.ValuesOnlyMask;
foreach (PredefinedOperator po in operators) {
//
// Performs user-operator overloading
//
- protected virtual Expression ResolveUserOperator (ResolveContext ec, Type l, Type r)
+ protected virtual Expression ResolveUserOperator (ResolveContext ec, TypeSpec l, TypeSpec r)
{
Operator user_oper;
if (oper == Operator.LogicalAnd)
string op = GetOperatorMetadataName (user_oper);
- MethodGroupExpr left_operators = MemberLookup (ec.Compiler, ec.CurrentType, l, op, MemberTypes.Method, AllBindingFlags, loc) as MethodGroupExpr;
+ MethodGroupExpr left_operators = MethodLookup (ec.Compiler, ec.CurrentType, l, MemberKind.Operator, op, 0, loc);
MethodGroupExpr right_operators = null;
if (!TypeManager.IsEqual (r, l)) {
- right_operators = MemberLookup (ec.Compiler, ec.CurrentType, r, op, MemberTypes.Method, AllBindingFlags, loc) as MethodGroupExpr;
+ right_operators = MethodLookup (ec.Compiler, ec.CurrentType, r, MemberKind.Operator, op, 0, loc);
if (right_operators == null && left_operators == null)
return null;
} else if (left_operators == null) {
return null;
}
- private void CheckUselessComparison (ResolveContext ec, Constant c, Type type)
+ private void CheckUselessComparison (ResolveContext ec, Constant c, TypeSpec type)
{
if (c == null || !IsTypeIntegral (type)
|| c is StringConstant
WarnUselessComparison (ec, type);
}
- static bool IsValueOutOfRange (long value, Type type)
+ static bool IsValueOutOfRange (long value, TypeSpec type)
{
if (IsTypeUnsigned (type) && value < 0)
return true;
type == TypeManager.uint32_type && value >= 0x100000000;
}
- static bool IsBuildInEqualityOperator (Type t)
+ static bool IsBuildInEqualityOperator (TypeSpec t)
{
return t == TypeManager.object_type || t == TypeManager.string_type ||
t == TypeManager.delegate_type || TypeManager.IsDelegateType (t);
}
- static bool IsPredefinedUserOperator (Type t, Operator op)
+ static bool IsPredefinedUserOperator (TypeSpec t, Operator op)
{
//
// Some predefined types have user operators
return (op & Operator.EqualityMask) != 0 && (t == TypeManager.string_type || t == TypeManager.decimal_type);
}
- private static bool IsTypeIntegral (Type type)
+ private static bool IsTypeIntegral (TypeSpec type)
{
return type == TypeManager.uint64_type ||
type == TypeManager.int64_type ||
type == TypeManager.char_type;
}
- private static bool IsTypeUnsigned (Type type)
+ private static bool IsTypeUnsigned (TypeSpec type)
{
return type == TypeManager.uint64_type ||
type == TypeManager.uint32_type ||
type == TypeManager.char_type;
}
- private void WarnUselessComparison (ResolveContext ec, Type type)
+ private void WarnUselessComparison (ResolveContext ec, TypeSpec type)
{
ec.Report.Warning (652, 2, loc, "A comparison between a constant and a variable is useless. The constant is out of the range of the variable type `{0}'",
TypeManager.CSharpName (type));
/// </remarks>
public override void EmitBranchable (EmitContext ec, Label target, bool on_true)
{
- ILGenerator ig = ec.ig;
-
//
// This is more complicated than it looks, but its just to avoid
// duplicated tests: basically, we allow ==, !=, >, <, >= and <=
} else if (oper == Operator.LogicalAnd) {
if (on_true) {
- Label tests_end = ig.DefineLabel ();
+ Label tests_end = ec.DefineLabel ();
left.EmitBranchable (ec, tests_end, false);
right.EmitBranchable (ec, target, true);
- ig.MarkLabel (tests_end);
+ ec.MarkLabel (tests_end);
} else {
//
// This optimizes code like this
right.EmitBranchable (ec, target, true);
} else {
- Label tests_end = ig.DefineLabel ();
+ Label tests_end = ec.DefineLabel ();
left.EmitBranchable (ec, tests_end, true);
right.EmitBranchable (ec, target, false);
- ig.MarkLabel (tests_end);
+ ec.MarkLabel (tests_end);
}
return;
left.Emit (ec);
right.Emit (ec);
- Type t = left.Type;
+ TypeSpec t = left.Type;
bool is_float = IsFloat (t);
bool is_unsigned = is_float || IsUnsigned (t);
switch (oper){
case Operator.Equality:
if (on_true)
- ig.Emit (OpCodes.Beq, target);
+ ec.Emit (OpCodes.Beq, target);
else
- ig.Emit (OpCodes.Bne_Un, target);
+ ec.Emit (OpCodes.Bne_Un, target);
break;
case Operator.Inequality:
if (on_true)
- ig.Emit (OpCodes.Bne_Un, target);
+ ec.Emit (OpCodes.Bne_Un, target);
else
- ig.Emit (OpCodes.Beq, target);
+ ec.Emit (OpCodes.Beq, target);
break;
case Operator.LessThan:
if (on_true)
if (is_unsigned && !is_float)
- ig.Emit (OpCodes.Blt_Un, target);
+ ec.Emit (OpCodes.Blt_Un, target);
else
- ig.Emit (OpCodes.Blt, target);
+ ec.Emit (OpCodes.Blt, target);
else
if (is_unsigned)
- ig.Emit (OpCodes.Bge_Un, target);
+ ec.Emit (OpCodes.Bge_Un, target);
else
- ig.Emit (OpCodes.Bge, target);
+ ec.Emit (OpCodes.Bge, target);
break;
case Operator.GreaterThan:
if (on_true)
if (is_unsigned && !is_float)
- ig.Emit (OpCodes.Bgt_Un, target);
+ ec.Emit (OpCodes.Bgt_Un, target);
else
- ig.Emit (OpCodes.Bgt, target);
+ ec.Emit (OpCodes.Bgt, target);
else
if (is_unsigned)
- ig.Emit (OpCodes.Ble_Un, target);
+ ec.Emit (OpCodes.Ble_Un, target);
else
- ig.Emit (OpCodes.Ble, target);
+ ec.Emit (OpCodes.Ble, target);
break;
case Operator.LessThanOrEqual:
if (on_true)
if (is_unsigned && !is_float)
- ig.Emit (OpCodes.Ble_Un, target);
+ ec.Emit (OpCodes.Ble_Un, target);
else
- ig.Emit (OpCodes.Ble, target);
+ ec.Emit (OpCodes.Ble, target);
else
if (is_unsigned)
- ig.Emit (OpCodes.Bgt_Un, target);
+ ec.Emit (OpCodes.Bgt_Un, target);
else
- ig.Emit (OpCodes.Bgt, target);
+ ec.Emit (OpCodes.Bgt, target);
break;
case Operator.GreaterThanOrEqual:
if (on_true)
if (is_unsigned && !is_float)
- ig.Emit (OpCodes.Bge_Un, target);
+ ec.Emit (OpCodes.Bge_Un, target);
else
- ig.Emit (OpCodes.Bge, target);
+ ec.Emit (OpCodes.Bge, target);
else
if (is_unsigned)
- ig.Emit (OpCodes.Blt_Un, target);
+ ec.Emit (OpCodes.Blt_Un, target);
else
- ig.Emit (OpCodes.Blt, target);
+ ec.Emit (OpCodes.Blt, target);
break;
default:
throw new InternalErrorException (oper.ToString ());
EmitOperator (ec, left.Type);
}
- protected virtual void EmitOperator (EmitContext ec, Type l)
+ protected virtual void EmitOperator (EmitContext ec, TypeSpec l)
{
- ILGenerator ig = ec.ig;
-
//
// Handle short-circuit operators differently
// than the rest
//
if ((oper & Operator.LogicalMask) != 0) {
- Label load_result = ig.DefineLabel ();
- Label end = ig.DefineLabel ();
+ Label load_result = ec.DefineLabel ();
+ Label end = ec.DefineLabel ();
bool is_or = oper == Operator.LogicalOr;
left.EmitBranchable (ec, load_result, is_or);
right.Emit (ec);
- ig.Emit (OpCodes.Br_S, end);
+ ec.Emit (OpCodes.Br_S, end);
- ig.MarkLabel (load_result);
- ig.Emit (is_or ? OpCodes.Ldc_I4_1 : OpCodes.Ldc_I4_0);
- ig.MarkLabel (end);
+ ec.MarkLabel (load_result);
+ ec.Emit (is_or ? OpCodes.Ldc_I4_1 : OpCodes.Ldc_I4_0);
+ ec.MarkLabel (end);
return;
}
var lc = left as IntegralConstant;
if (lc != null && lc.IsDefaultValue) {
right.Emit (ec);
- ig.Emit (OpCodes.Neg);
+ ec.Emit (OpCodes.Neg);
return;
}
}
if (arguments.Count != 2)
throw new NotImplementedException ("arguments.Count != 2");
- var concat = TypeManager.string_type.GetMethod ("Concat", new[] { typeof (object), typeof (object) });
+ var concat = typeof (string).GetMethod ("Concat", new[] { typeof (object), typeof (object) });
return SLE.Expression.Add (arguments[0].Expr.MakeExpression (ctx), arguments[1].Expr.MakeExpression (ctx), concat);
}
-
- public override void MutateHoistedGenericType (AnonymousMethodStorey storey)
- {
- arguments.MutateHoistedGenericType (storey);
- }
}
//
protected override Expression DoResolve (ResolveContext ec)
{
var method = mg.BestCandidate;
- type = TypeManager.TypeToCoreType (method.ReturnType);
+ type = method.ReturnType;
AParametersCollection pd = method.Parameters;
if (!TypeManager.IsEqual (type, type) || !TypeManager.IsEqual (type, pd.Types [0]) || !TypeManager.IsEqual (type, pd.Types [1])) {
ec.Report.Error (217, loc,
"A user-defined operator `{0}' must have parameters and return values of the same type in order to be applicable as a short circuit operator",
- TypeManager.CSharpSignature (method.MetaInfo));
+ TypeManager.CSharpSignature (method));
return null;
}
if (op_true == null || op_false == null) {
ec.Report.Error (218, loc,
"The type `{0}' must have operator `true' and operator `false' defined when `{1}' is used as a short circuit operator",
- TypeManager.CSharpName (type), TypeManager.CSharpSignature (method.MetaInfo));
+ TypeManager.CSharpName (type), TypeManager.CSharpSignature (method));
return null;
}
public override void Emit (EmitContext ec)
{
- ILGenerator ig = ec.ig;
- Label end_target = ig.DefineLabel ();
+ Label end_target = ec.DefineLabel ();
//
// Emit and duplicate left argument
//
arguments [0].Expr.Emit (ec);
- ig.Emit (OpCodes.Dup);
+ ec.Emit (OpCodes.Dup);
arguments.RemoveAt (0);
oper.EmitBranchable (ec, end_target, true);
base.Emit (ec);
- ig.MarkLabel (end_target);
+ ec.MarkLabel (end_target);
}
}
//
// We assume that `l' is always a pointer
//
- public PointerArithmetic (Binary.Operator op, Expression l, Expression r, Type t, Location loc)
+ public PointerArithmetic (Binary.Operator op, Expression l, Expression r, TypeSpec t, Location loc)
{
type = t;
this.loc = loc;
public override void Emit (EmitContext ec)
{
- Type op_type = left.Type;
- ILGenerator ig = ec.ig;
+ TypeSpec op_type = left.Type;
// It must be either array or fixed buffer
- Type element;
+ TypeSpec element;
if (TypeManager.HasElementType (op_type)) {
element = TypeManager.GetElementType (op_type);
} else {
}
int size = GetTypeSize (element);
- Type rtype = right.Type;
+ TypeSpec rtype = right.Type;
if ((op & Binary.Operator.SubtractionMask) != 0 && rtype.IsPointer){
//
//
left.Emit (ec);
right.Emit (ec);
- ig.Emit (OpCodes.Sub);
+ ec.Emit (OpCodes.Sub);
if (size != 1){
if (size == 0)
- ig.Emit (OpCodes.Sizeof, element);
+ ec.Emit (OpCodes.Sizeof, element);
else
- IntLiteral.EmitInt (ig, size);
- ig.Emit (OpCodes.Div);
+ ec.EmitInt (size);
+ ec.Emit (OpCodes.Div);
}
- ig.Emit (OpCodes.Conv_I8);
+ ec.Emit (OpCodes.Conv_I8);
} else {
//
// handle + and - on (pointer op int)
right.Emit (ec);
if (rtype == TypeManager.sbyte_type || rtype == TypeManager.byte_type ||
rtype == TypeManager.short_type || rtype == TypeManager.ushort_type) {
- ig.Emit (OpCodes.Conv_I);
+ ec.Emit (OpCodes.Conv_I);
} else if (rtype == TypeManager.uint32_type) {
- ig.Emit (OpCodes.Conv_U);
+ ec.Emit (OpCodes.Conv_U);
}
if (right_const == null && size != 1){
if (size == 0)
- ig.Emit (OpCodes.Sizeof, element);
+ ec.Emit (OpCodes.Sizeof, element);
else
- IntLiteral.EmitInt (ig, size);
+ ec.EmitInt (size);
if (rtype == TypeManager.int64_type || rtype == TypeManager.uint64_type)
- ig.Emit (OpCodes.Conv_I8);
+ ec.Emit (OpCodes.Conv_I8);
Binary.EmitOperatorOpcode (ec, Binary.Operator.Multiply, rtype);
}
if (left_const == null) {
if (rtype == TypeManager.int64_type)
- ig.Emit (OpCodes.Conv_I);
+ ec.Emit (OpCodes.Conv_I);
else if (rtype == TypeManager.uint64_type)
- ig.Emit (OpCodes.Conv_U);
+ ec.Emit (OpCodes.Conv_U);
Binary.EmitOperatorOpcode (ec, op, op_type);
}
if (expr.Type == TypeManager.bool_type)
return expr;
- if (TypeManager.IsDynamicType (expr.Type)) {
+ if (expr.Type == InternalType.Dynamic) {
Arguments args = new Arguments (1);
args.Add (new Argument (expr));
return new DynamicUnaryConversion ("IsTrue", args, loc).Resolve (ec);
return null;
eclass = ExprClass.Value;
- Type true_type = true_expr.Type;
- Type false_type = false_expr.Type;
+ TypeSpec true_type = true_expr.Type;
+ TypeSpec false_type = false_expr.Type;
type = true_type;
//
return this;
}
- public override void MutateHoistedGenericType (AnonymousMethodStorey storey)
- {
- expr.MutateHoistedGenericType (storey);
- true_expr.MutateHoistedGenericType (storey);
- false_expr.MutateHoistedGenericType (storey);
- type = storey.MutateType (type);
- }
-
public override TypeExpr ResolveAsTypeTerminal (IMemberContext ec, bool silent)
{
return null;
public override void Emit (EmitContext ec)
{
- ILGenerator ig = ec.ig;
- Label false_target = ig.DefineLabel ();
- Label end_target = ig.DefineLabel ();
+ Label false_target = ec.DefineLabel ();
+ Label end_target = ec.DefineLabel ();
expr.EmitBranchable (ec, false_target, false);
true_expr.Emit (ec);
if (type.IsInterface) {
LocalBuilder temp = ec.GetTemporaryLocal (type);
- ig.Emit (OpCodes.Stloc, temp);
- ig.Emit (OpCodes.Ldloc, temp);
+ ec.Emit (OpCodes.Stloc, temp);
+ ec.Emit (OpCodes.Ldloc, temp);
ec.FreeTemporaryLocal (temp, type);
}
- ig.Emit (OpCodes.Br, end_target);
- ig.MarkLabel (false_target);
+ ec.Emit (OpCodes.Br, end_target);
+ ec.MarkLabel (false_target);
false_expr.Emit (ec);
- ig.MarkLabel (end_target);
+ ec.MarkLabel (end_target);
}
protected override void CloneTo (CloneContext clonectx, Expression t)
// If we are a reference, we loaded on the stack a pointer
// Now lets load the real value
//
- LoadFromPtr (ec.ig, type);
+ ec.EmitLoadFromPtr (type);
}
if (leave_copy) {
- ec.ig.Emit (OpCodes.Dup);
+ ec.Emit (OpCodes.Dup);
if (IsRef) {
temp = new LocalTemporary (Type);
}
if (leave_copy) {
- ec.ig.Emit (OpCodes.Dup);
+ ec.Emit (OpCodes.Dup);
if (IsRef) {
temp = new LocalTemporary (Type);
temp.Store (ec);
}
if (IsRef)
- StoreFromPtr (ec.ig, type);
+ ec.EmitStoreFromPtr (type);
else
Variable.EmitAssign (ec);
public bool IsHoisted {
get { return GetHoistedVariable ((AnonymousExpression) null) != null; }
}
-
- public override void MutateHoistedGenericType (AnonymousMethodStorey storey)
- {
- type = storey.MutateType (type);
- }
}
/// <summary>
return this;
}
- static public void EmitLdArg (ILGenerator ig, int x)
+ static public void EmitLdArg (EmitContext ec, int x)
{
switch (x) {
- case 0: ig.Emit (OpCodes.Ldarg_0); break;
- case 1: ig.Emit (OpCodes.Ldarg_1); break;
- case 2: ig.Emit (OpCodes.Ldarg_2); break;
- case 3: ig.Emit (OpCodes.Ldarg_3); break;
+ case 0: ec.Emit (OpCodes.Ldarg_0); break;
+ case 1: ec.Emit (OpCodes.Ldarg_1); break;
+ case 2: ec.Emit (OpCodes.Ldarg_2); break;
+ case 3: ec.Emit (OpCodes.Ldarg_3); break;
default:
if (x > byte.MaxValue)
- ig.Emit (OpCodes.Ldarg, x);
+ ec.Emit (OpCodes.Ldarg, x);
else
- ig.Emit (OpCodes.Ldarg_S, (byte) x);
+ ec.Emit (OpCodes.Ldarg_S, (byte) x);
break;
}
}
if (arguments != null && !arguments_resolved)
arguments.Resolve (ec, out dynamic_arg);
- Type expr_type = member_expr.Type;
+ TypeSpec expr_type = member_expr.Type;
mg = member_expr as MethodGroupExpr;
- bool dynamic_member = TypeManager.IsDynamicType (expr_type);
+ bool dynamic_member = expr_type == InternalType.Dynamic;
if (!dynamic_member) {
Expression invoke = null;
return null;
}
- mg = ec.LookupExtensionMethod (me.Type, me.Name, loc);
+ mg = ec.LookupExtensionMethod (me.Type, me.Name, -1, loc);
if (mg == null) {
ec.Report.Error (1955, loc, "The member `{0}' cannot be used as method or delegate",
member_expr.GetSignatureForError ());
var method = mg.BestCandidate;
if (method != null) {
- type = TypeManager.TypeToCoreType (method.ReturnType);
+ type = method.ReturnType;
// TODO: this is a copy of mg.ResolveMemberAccess method
Expression iexpr = mg.InstanceExpression;
public static bool IsSpecialMethodInvocation (ResolveContext ec, MethodSpec method, Location loc)
{
- if (!TypeManager.IsSpecialMethod (method.MetaInfo))
+ if (!method.IsReservedMethod)
return false;
if (ec.HasSet (ResolveContext.Options.InvokeSpecialName))
return false;
- ec.Report.SymbolRelatedToPreviousError (method.MetaInfo);
+ ec.Report.SymbolRelatedToPreviousError (method);
ec.Report.Error (571, loc, "`{0}': cannot explicitly call operator or accessor",
- TypeManager.CSharpSignature (method.MetaInfo, true));
+ method.GetSignatureForError ());
return true;
}
return list.ArgumentTypes;
}
- /// <summary>
- /// This checks the ConditionalAttribute on the method
- /// </summary>
- public static bool IsMethodExcluded (MethodSpec method, Location loc)
- {
- if (method.IsConstructor)
- return false;
-
- var mb = TypeManager.DropGenericMethodArguments (method.MetaInfo);
- if (TypeManager.IsBeingCompiled (mb)) {
- IMethodData md = TypeManager.GetMethod (mb);
- if (md != null)
- return md.IsExcluded ();
-
- // For some methods (generated by delegate class) GetMethod returns null
- // because they are not included in builder_to_method table
- return false;
- }
-
- return AttributeTester.IsConditionalMethodExcluded (mb, loc);
- }
-
/// <remarks>
/// is_base tells whether we want to force the use of the `call'
/// opcode instead of using callvirt. Call is required to call
MethodSpec method, Arguments Arguments, Location loc,
bool dup_args, bool omit_args)
{
- ILGenerator ig = ec.ig;
bool struct_call = false;
bool this_call = false;
LocalTemporary this_arg = null;
- Type decl_type = method.DeclaringType;
+ TypeSpec decl_type = method.DeclaringType;
- if (IsMethodExcluded (method, loc))
+ // Speed up the check by not doing it on not allowed targets
+ if (method.ReturnType == TypeManager.void_type && method.IsConditionallyExcluded (loc))
return;
bool is_static = method.IsStatic;
// If this is ourselves, push "this"
//
if (!omit_args) {
- Type t = null;
- Type iexpr_type = instance_expr.Type;
+ TypeSpec t = null;
+ TypeSpec iexpr_type = instance_expr.Type;
//
// Push the instance expression
// avoid the overhead of doing this all the time.
if (dup_args)
- t = TypeManager.GetReferenceType (iexpr_type);
+ t = ReferenceContainer.MakeType (iexpr_type);
} else {
instance_expr.Emit (ec);
// FIXME: should use instance_expr is IMemoryLocation + constraint.
// to help JIT to produce better code
- ig.Emit (OpCodes.Box, instance_expr.Type);
+ ec.Emit (OpCodes.Box, instance_expr.Type);
t = TypeManager.object_type;
}
} else {
}
if (dup_args) {
- ig.Emit (OpCodes.Dup);
+ ec.Emit (OpCodes.Dup);
if (Arguments != null && Arguments.Count != 0) {
this_arg = new LocalTemporary (t);
this_arg.Store (ec);
call_op = OpCodes.Callvirt;
if ((instance_expr != null) && (instance_expr.Type.IsGenericParameter))
- ig.Emit (OpCodes.Constrained, instance_expr.Type);
+ ec.Emit (OpCodes.Constrained, instance_expr.Type);
}
- if ((method.MetaInfo.CallingConvention & CallingConventions.VarArgs) != 0) {
+ if (method.Parameters.HasArglist) {
Type[] varargs_types = GetVarargsTypes (method, Arguments);
- ig.EmitCall (call_op, (MethodInfo) method.MetaInfo, varargs_types);
+ ec.Emit (call_op, method, varargs_types);
return;
}
// and DoFoo is not virtual, you can omit the callvirt,
// because you don't need the null checking behavior.
//
- if (method.IsConstructor)
- ig.Emit (call_op, (ConstructorInfo) method.MetaInfo);
- else
- ig.Emit (call_op, (MethodInfo) method.MetaInfo);
+ ec.Emit (call_op, method);
}
public override void Emit (EmitContext ec)
//
// Pop the return value if there is one
//
- if (TypeManager.TypeToCoreType (type) != TypeManager.void_type)
- ec.ig.Emit (OpCodes.Pop);
+ if (type != TypeManager.void_type)
+ ec.Emit (OpCodes.Pop);
}
protected override void CloneTo (CloneContext clonectx, Expression t)
public static SLE.Expression MakeExpression (BuilderContext ctx, Expression instance, MethodSpec mi, Arguments args)
{
var instance_expr = instance == null ? null : instance.MakeExpression (ctx);
- return SLE.Expression.Call (instance_expr, (MethodInfo) mi.MetaInfo, Arguments.MakeExpression (args, ctx));
- }
-
- public override void MutateHoistedGenericType (AnonymousMethodStorey storey)
- {
- mg.MutateHoistedGenericType (storey);
- type = storey.MutateType (type);
- if (arguments != null) {
- arguments.MutateHoistedGenericType (storey);
- }
+ return SLE.Expression.Call (instance_expr, (MethodInfo) mi.GetMetaInfo (), Arguments.MakeExpression (args, ctx));
}
}
protected MethodGroupExpr method;
- bool is_type_parameter;
-
public New (Expression requested_type, Arguments arguments, Location l)
{
RequestedType = requested_type;
/// <summary>
/// Converts complex core type syntax like 'new int ()' to simple constant
/// </summary>
- public static Constant Constantify (Type t)
+ public static Constant Constantify (TypeSpec t)
{
if (t == TypeManager.int32_type)
return new IntConstant (0, Location.Null);
if (t == TypeManager.decimal_type)
return new DecimalConstant (0, Location.Null);
if (TypeManager.IsEnumType (t))
- return new EnumConstant (Constantify (TypeManager.GetEnumUnderlyingType (t)), t);
+ return new EnumConstant (Constantify (EnumSpec.GetUnderlyingType (t)), t);
if (TypeManager.IsNullableType (t))
return Nullable.LiftedNull.Create (t, Location.Null);
// Turn the call into:
// (the-interface-stated) (new class-referenced-in-coclassattribute ())
//
- Type real_class = AttributeTester.GetCoClassAttribute (type);
+ var real_class = type.MemberDefinition.GetAttributeCoClass ();
if (real_class == null)
return null;
return (new NewDelegate (type, Arguments, loc)).Resolve (ec);
}
- if (TypeManager.IsGenericParameter (type)) {
- GenericConstraints gc = TypeManager.GetTypeParameterConstraints (type);
-
- if ((gc == null) || (!gc.HasConstructorConstraint && !gc.IsValueType)) {
+ var tparam = type as TypeParameterSpec;
+ if (tparam != null) {
+ if (!tparam.HasSpecialConstructor && !tparam.HasSpecialStruct) {
ec.Report.Error (304, loc,
- "Cannot create an instance of the variable type '{0}' because it doesn't have the new() constraint",
+ "Cannot create an instance of the variable type `{0}' because it does not have the new() constraint",
TypeManager.CSharpName (type));
- return null;
}
if ((Arguments != null) && (Arguments.Count != 0)) {
ec.Report.Error (417, loc,
"`{0}': cannot provide arguments when creating an instance of a variable type",
TypeManager.CSharpName (type));
- return null;
}
if (TypeManager.activator_create_instance == null) {
- Type activator_type = TypeManager.CoreLookupType (ec.Compiler, "System", "Activator", MemberKind.Class, true);
+ TypeSpec activator_type = TypeManager.CoreLookupType (ec.Compiler, "System", "Activator", MemberKind.Class, true);
if (activator_type != null) {
TypeManager.activator_create_instance = TypeManager.GetPredefinedMethod (
- activator_type, "CreateInstance", loc, Type.EmptyTypes);
+ activator_type, MemberFilter.Method ("CreateInstance", 1, ParametersCompiled.EmptyReadOnlyParameters, null), loc);
}
}
- is_type_parameter = true;
eclass = ExprClass.Value;
return this;
}
- if (type.IsAbstract && type.IsSealed) {
+ if (type.IsStatic) {
ec.Report.SymbolRelatedToPreviousError (type);
ec.Report.Error (712, loc, "Cannot create an instance of the static class `{0}'", TypeManager.CSharpName (type));
return null;
return this;
// For member-lookup, treat 'new Foo (bar)' as call to 'foo.ctor (bar)', where 'foo' is of type 'Foo'.
- Expression ml = MemberLookupFinal (ec, type, type, ConstructorInfo.ConstructorName,
- MemberTypes.Constructor, AllBindingFlags | BindingFlags.DeclaredOnly, loc);
+ Expression ml = MemberLookupFinal (ec, type, type, ConstructorInfo.ConstructorName, 0,
+ MemberKind.Constructor, BindingRestriction.AccessibleOnly | BindingRestriction.DeclaredOnly, loc);
bool dynamic;
if (Arguments != null) {
bool DoEmitTypeParameter (EmitContext ec)
{
- ILGenerator ig = ec.ig;
+ var ctor_factory = TypeManager.activator_create_instance.MakeGenericMethod (type);
+ var tparam = (TypeParameterSpec) type;
- MethodInfo ci = (MethodInfo) TypeManager.activator_create_instance.MetaInfo;
- ci = ci.MakeGenericMethod (new Type [] { type });
-
- GenericConstraints gc = TypeManager.GetTypeParameterConstraints (type);
- if (gc.HasReferenceTypeConstraint || gc.HasClassConstraint) {
- ig.Emit (OpCodes.Call, ci);
+ if (tparam.IsReferenceType) {
+ ec.Emit (OpCodes.Call, ctor_factory);
return true;
}
// you can't share LocalBuilders among ILGeneators.
LocalTemporary temp = new LocalTemporary (type);
- Label label_activator = ig.DefineLabel ();
- Label label_end = ig.DefineLabel ();
+ Label label_activator = ec.DefineLabel ();
+ Label label_end = ec.DefineLabel ();
temp.AddressOf (ec, AddressOp.Store);
- ig.Emit (OpCodes.Initobj, type);
+ ec.Emit (OpCodes.Initobj, type);
temp.Emit (ec);
- ig.Emit (OpCodes.Box, type);
- ig.Emit (OpCodes.Brfalse, label_activator);
+ ec.Emit (OpCodes.Box, type);
+ ec.Emit (OpCodes.Brfalse, label_activator);
temp.AddressOf (ec, AddressOp.Store);
- ig.Emit (OpCodes.Initobj, type);
+ ec.Emit (OpCodes.Initobj, type);
temp.Emit (ec);
- ig.Emit (OpCodes.Br_S, label_end);
+ ec.Emit (OpCodes.Br_S, label_end);
- ig.MarkLabel (label_activator);
+ ec.MarkLabel (label_activator);
- ig.Emit (OpCodes.Call, ci);
- ig.MarkLabel (label_end);
+ ec.Emit (OpCodes.Call, ctor_factory);
+ ec.MarkLabel (label_end);
return true;
}
public virtual bool Emit (EmitContext ec, IMemoryLocation target)
{
bool is_value_type = TypeManager.IsValueType (type);
- ILGenerator ig = ec.ig;
VariableReference vr = target as VariableReference;
if (target != null && is_value_type && (vr != null || method == null)) {
if (is_value_type) {
if (method == null) {
- ig.Emit (OpCodes.Initobj, type);
+ ec.Emit (OpCodes.Initobj, type);
return false;
}
if (vr != null) {
- ig.Emit (OpCodes.Call, (ConstructorInfo) method.BestCandidate.MetaInfo);
+ ec.Emit (OpCodes.Call, method.BestCandidate);
return false;
}
}
- if (is_type_parameter)
+ if (type is TypeParameterSpec)
return DoEmitTypeParameter (ec);
- ConstructorInfo ci = (ConstructorInfo) method.BestCandidate.MetaInfo;
-#if MS_COMPATIBLE
- if (TypeManager.IsGenericType (type) && type.IsGenericTypeDefinition)
- ci = TypeBuilder.GetConstructor (type, ci);
-#endif
-
- ig.Emit (OpCodes.Newobj, ci);
+ ec.Emit (OpCodes.Newobj, method.BestCandidate);
return true;
}
}
if (Emit (ec, v))
- ec.ig.Emit (OpCodes.Pop);
+ ec.Emit (OpCodes.Pop);
}
public virtual bool HasInitializer {
{
LocalTemporary value_target = new LocalTemporary (type);
- if (is_type_parameter) {
+ if (type is TypeParameterSpec) {
DoEmitTypeParameter (ec);
value_target.Store (ec);
value_target.AddressOf (ec, mode);
value_target.AddressOf (ec, AddressOp.Store);
if (method == null) {
- ec.ig.Emit (OpCodes.Initobj, type);
+ ec.Emit (OpCodes.Initobj, type);
} else {
if (Arguments != null)
Arguments.Emit (ec);
- ec.ig.Emit (OpCodes.Call, (ConstructorInfo) method.BestCandidate.MetaInfo);
+ ec.Emit (OpCodes.Call, method.BestCandidate);
}
value_target.AddressOf (ec, mode);
public override SLE.Expression MakeExpression (BuilderContext ctx)
{
- return SLE.Expression.New ((ConstructorInfo) method.BestCandidate.MetaInfo, Arguments.MakeExpression (Arguments, ctx));
- }
-
- public override void MutateHoistedGenericType (AnonymousMethodStorey storey)
- {
- if (method != null) {
- method.MutateHoistedGenericType (storey);
- if (Arguments != null) {
- Arguments.MutateHoistedGenericType (storey);
- }
- }
-
- type = storey.MutateType (type);
+ return SLE.Expression.New ((ConstructorInfo) method.BestCandidate.GetMetaInfo (), Arguments.MakeExpression (Arguments, ctx));
}
}
//
protected List<Expression> arguments;
- protected Type array_element_type;
+ protected TypeSpec array_element_type;
bool expect_initializers = false;
int num_arguments = 0;
protected int dimensions;
int value = (int) c.GetValue ();
if (value != probe.Count) {
- ec.Report.Error (847, loc, "An array initializer of length `{0}' was expected", value);
+ ec.Report.Error (847, loc, "An array initializer of length `{0}' was expected", value.ToString ());
return false;
}
return false;
}
- StringBuilder array_qualifier = new StringBuilder (rank);
+ StringBuilder array_qualifier = new StringBuilder ();
//
// `In the first form allocates an array instace of the type that results
array_qualifier.Append ("]");
}
+ array_qualifier.Append (rank);
+
//
// Lookup the type
//
return false;
type = array_type_expr.Type;
- if (!type.IsArray) {
+ var ac = type as ArrayContainer;
+ if (ac == null) {
ec.Report.Error (622, loc, "Can only use array initializer expressions to assign to array types. Try using a new expression instead");
return false;
}
- array_element_type = TypeManager.GetElementType (type);
- dimensions = type.GetArrayRank ();
+ array_element_type = ac.Element;
+ dimensions = ac.Rank;
return true;
}
return this;
}
- MethodInfo GetArrayMethod (EmitContext ec, int arguments)
- {
- ModuleBuilder mb = RootContext.ToplevelTypes.Builder;
-
- Type[] arg_types = new Type[arguments];
- for (int i = 0; i < arguments; i++)
- arg_types[i] = TypeManager.int32_type;
-
- MethodInfo mi = mb.GetArrayMethod (type, ".ctor", CallingConventions.HasThis, null,
- arg_types);
-
- if (mi == null) {
- ec.Report.Error (-6, "New invocation: Can not find a constructor for " +
- "this argument list");
- return null;
- }
-
- return mi;
- }
-
byte [] MakeByteBlob ()
{
int factor;
byte [] element;
int count = array_data.Count;
- Type element_type = array_element_type;
+ TypeSpec element_type = array_element_type;
if (TypeManager.IsEnumType (element_type))
- element_type = TypeManager.GetEnumUnderlyingType (element_type);
+ element_type = EnumSpec.GetUnderlyingType (element_type);
factor = GetTypeSize (element_type);
if (factor == 0)
var initializers = new SLE.Expression [array_data.Count];
for (var i = 0; i < initializers.Length; i++) {
if (array_data [i] == null)
- initializers [i] = SLE.Expression.Default (array_element_type);
+ initializers [i] = SLE.Expression.Default (array_element_type.GetMetaInfo ());
else
initializers [i] = array_data [i].MakeExpression (ctx);
}
- return SLE.Expression.NewArrayInit (array_element_type, initializers);
+ return SLE.Expression.NewArrayInit (array_element_type.GetMetaInfo (), initializers);
}
#endif
-
- public override void MutateHoistedGenericType (AnonymousMethodStorey storey)
- {
- array_element_type = storey.MutateType (array_element_type);
- type = storey.MutateType (type);
- if (arguments != null) {
- foreach (Expression e in arguments)
- e.MutateHoistedGenericType (storey);
- }
-
- if (array_data != null) {
- foreach (Expression e in array_data) {
- // Don't mutate values optimized away
- if (e == null)
- continue;
-
- e.MutateHoistedGenericType (storey);
- }
- }
- }
-
//
// Emits the initializers for the array
//
// First, the static data
//
FieldBuilder fb;
- ILGenerator ig = ec.ig;
byte [] data = MakeByteBlob ();
fb = RootContext.MakeStaticData (data);
- ig.Emit (OpCodes.Dup);
- ig.Emit (OpCodes.Ldtoken, fb);
- ig.Emit (OpCodes.Call, (MethodInfo) TypeManager.void_initializearray_array_fieldhandle.MetaInfo);
+ ec.Emit (OpCodes.Dup);
+ ec.Emit (OpCodes.Ldtoken, fb);
+ ec.Emit (OpCodes.Call, TypeManager.void_initializearray_array_fieldhandle);
}
//
//
void EmitDynamicInitializers (EmitContext ec, bool emitConstants)
{
- ILGenerator ig = ec.ig;
int dims = bounds.Count;
int [] current_pos = new int [dims];
- MethodInfo set = null;
-
- if (dims != 1){
- Type [] args = new Type [dims + 1];
-
- for (int j = 0; j < dims; j++)
- args [j] = TypeManager.int32_type;
- args [dims] = array_element_type;
-
- set = RootContext.ToplevelTypes.Builder.GetArrayMethod (
- type, "Set",
- CallingConventions.HasThis | CallingConventions.Standard,
- TypeManager.void_type, args);
- }
-
for (int i = 0; i < array_data.Count; i++){
Expression e = array_data [i];
// Constant can be initialized via StaticInitializer
if (c == null || (c != null && emitConstants && !c.IsDefaultInitializer (array_element_type))) {
- Type etype = e.Type;
+ TypeSpec etype = e.Type;
- ig.Emit (OpCodes.Dup);
+ ec.Emit (OpCodes.Dup);
for (int idx = 0; idx < dims; idx++)
- IntConstant.EmitInt (ig, current_pos [idx]);
+ ec.EmitInt (current_pos [idx]);
//
// If we are dealing with a struct, get the
(!TypeManager.IsBuiltinOrEnum (etype) ||
etype == TypeManager.decimal_type)) {
- ig.Emit (OpCodes.Ldelema, etype);
+ ec.Emit (OpCodes.Ldelema, etype);
}
e.Emit (ec);
- if (dims == 1) {
- bool is_stobj, has_type_arg;
- OpCode op = ArrayAccess.GetStoreOpcode (etype, out is_stobj, out has_type_arg);
- if (is_stobj)
- ig.Emit (OpCodes.Stobj, etype);
- else if (has_type_arg)
- ig.Emit (op, etype);
- else
- ig.Emit (op);
- } else
- ig.Emit (OpCodes.Call, set);
-
+ ec.EmitArrayStore ((ArrayContainer) type);
}
//
public override void Emit (EmitContext ec)
{
- ILGenerator ig = ec.ig;
-
if (first_emit != null) {
first_emit.Emit (ec);
first_emit_temp.Store (ec);
foreach (Expression e in arguments)
e.Emit (ec);
- if (arguments.Count == 1)
- ig.Emit (OpCodes.Newarr, TypeManager.TypeToReflectionType (array_element_type));
- else {
- ig.Emit (OpCodes.Newobj, GetArrayMethod (ec, arguments.Count));
- }
+ ec.EmitArrayNew ((ArrayContainer) type);
if (initializers == null)
return;
first_emit_temp.Release (ec);
}
- public override void EncodeAttributeValue (IMemberContext rc, AttributeEncoder enc, Type targetType)
+ public override void EncodeAttributeValue (IMemberContext rc, AttributeEncoder enc, TypeSpec targetType)
{
// no multi dimensional or jagged arrays
if (arguments.Count != 1 || array_element_type.IsArray) {
{
}
- public CompilerGeneratedThis (Type type, Location loc)
+ public CompilerGeneratedThis (TypeSpec type, Location loc)
: base (loc)
{
this.type = type;
if (type == null)
type = ec.CurrentType;
- is_struct = type.IsValueType;
+ is_struct = TypeManager.IsStruct (type);
return this;
}
public void Emit (EmitContext ec)
{
- ec.ig.Emit (OpCodes.Ldarg_0);
+ ec.Emit (OpCodes.Ldarg_0);
}
public void EmitAssign (EmitContext ec)
public void EmitAddressOf (EmitContext ec)
{
- ec.ig.Emit (OpCodes.Ldarg_0);
+ ec.Emit (OpCodes.Ldarg_0);
}
}
if (ec.CurrentAnonymousMethod == null)
return true;
- if (ec.CurrentType.IsValueType && ec.CurrentIterator == null)
+ if (TypeManager.IsStruct (ec.CurrentType) && ec.CurrentIterator == null)
return false;
return true;
}
}
- is_struct = type.IsValueType;
+ is_struct = TypeManager.IsStruct (type);
if (block != null) {
if (block.Toplevel.ThisVariable != null)
public override void Emit (EmitContext ec)
{
- ec.ig.Emit (OpCodes.Arglist);
+ ec.Emit (OpCodes.Arglist);
}
protected override void CloneTo (CloneContext clonectx, Expression target)
public Type[] ArgumentTypes {
get {
if (Arguments == null)
- return Type.EmptyTypes;
+ return System.Type.EmptyTypes;
- Type[] retval = new Type [Arguments.Count];
+ var retval = new Type [Arguments.Count];
for (int i = 0; i < retval.Length; i++)
- retval [i] = Arguments [i].Expr.Type;
+ retval[i] = Arguments[i].Expr.Type.GetMetaInfo ();
return retval;
}
Arguments.Emit (ec);
}
- public override void MutateHoistedGenericType (AnonymousMethodStorey storey)
- {
- if (Arguments != null)
- Arguments.MutateHoistedGenericType (storey);
- }
-
protected override void CloneTo (CloneContext clonectx, Expression t)
{
Arglist target = (Arglist) t;
/// </summary>
public class TypeOf : Expression {
Expression QueriedType;
- protected Type typearg;
+ protected TypeSpec typearg;
public TypeOf (Expression queried_type, Location l)
{
return this;
}
- public override void EncodeAttributeValue (IMemberContext rc, AttributeEncoder enc, Type targetType)
+ public override void EncodeAttributeValue (IMemberContext rc, AttributeEncoder enc, TypeSpec targetType)
{
// Target type is not System.Type therefore must be object
// and we need to use different encoding sequence
if (targetType != type)
enc.Encode (type);
+/*
+ var gi = typearg as InflatedTypeSpec;
+ if (gi != null) {
+ // TODO: This has to be recursive, handle arrays, etc.
+ // I could probably do it after CustomAttribute encoder rewrite
+ foreach (var ta in gi.TypeArguments) {
+ if (ta.IsGenericParameter) {
+ ec.Report.SymbolRelatedToPreviousError (typearg);
+ ec.Report.Error (416, loc, "`{0}': an attribute argument cannot use type parameters",
+ TypeManager.CSharpName (typearg));
+ value = null;
+ return false;
+ }
+ }
+ }
+ */
+
if (!enc.EncodeTypeName (typearg)) {
rc.Compiler.Report.SymbolRelatedToPreviousError (typearg);
rc.Compiler.Report.Error (416, loc, "`{0}': an attribute argument cannot use type parameters",
public override void Emit (EmitContext ec)
{
- ec.ig.Emit (OpCodes.Ldtoken, TypeManager.TypeToReflectionType (typearg));
- ec.ig.Emit (OpCodes.Call, (MethodInfo) TypeManager.system_type_get_type_from_handle.MetaInfo);
+ ec.Emit (OpCodes.Ldtoken, typearg);
+ ec.Emit (OpCodes.Call, TypeManager.system_type_get_type_from_handle);
}
- public override void MutateHoistedGenericType (AnonymousMethodStorey storey)
- {
- if (!TypeManager.IsGenericTypeDefinition (typearg))
- typearg = storey.MutateType (typearg);
- }
-
- public Type TypeArgument {
+ public TypeSpec TypeArgument {
get {
return typearg;
}
public override void Emit (EmitContext ec)
{
- if (member.IsConstructor)
- ec.ig.Emit (OpCodes.Ldtoken, (ConstructorInfo) member.MetaInfo);
- else
- ec.ig.Emit (OpCodes.Ldtoken, (MethodInfo) member.MetaInfo);
+ ec.Emit (OpCodes.Ldtoken, member);
base.Emit (ec);
- ec.ig.Emit (OpCodes.Castclass, type);
+ ec.Emit (OpCodes.Castclass, type);
}
protected override string GetMethodName {
protected override Expression DoResolve (ResolveContext ec)
{
- bool is_generic = TypeManager.IsGenericType (member.DeclaringType);
+ bool is_generic = member.DeclaringType.IsGenericOrParentIsGeneric;
var mi = is_generic ? TypeFromHandleGeneric : TypeFromHandle;
if (mi == null) {
- Type t = TypeManager.CoreLookupType (ec.Compiler, "System.Reflection", TypeName, MemberKind.Class, true);
- Type handle_type = TypeManager.CoreLookupType (ec.Compiler, "System", RuntimeHandleName, MemberKind.Class, true);
+ TypeSpec t = TypeManager.CoreLookupType (ec.Compiler, "System.Reflection", TypeName, MemberKind.Class, true);
+ TypeSpec handle_type = TypeManager.CoreLookupType (ec.Compiler, "System", RuntimeHandleName, MemberKind.Struct, true);
if (t == null || handle_type == null)
return null;
mi = TypeManager.GetPredefinedMethod (t, GetMethodName, loc,
is_generic ?
- new Type[] { handle_type, TypeManager.runtime_handle_type } :
- new Type[] { handle_type } );
+ new TypeSpec[] { handle_type, TypeManager.runtime_handle_type } :
+ new TypeSpec[] { handle_type } );
if (is_generic)
TypeFromHandleGeneric = mi;
public override void Emit (EmitContext ec)
{
- bool is_generic = TypeManager.IsGenericType (member.DeclaringType);
+ bool is_generic = member.DeclaringType.IsGenericOrParentIsGeneric;
MethodSpec mi;
if (is_generic) {
mi = TypeFromHandleGeneric;
- ec.ig.Emit (OpCodes.Ldtoken, member.DeclaringType);
+ ec.Emit (OpCodes.Ldtoken, member.DeclaringType);
} else {
mi = TypeFromHandle;
}
- ec.ig.Emit (OpCodes.Call, (MethodInfo) mi.MetaInfo);
+ ec.Emit (OpCodes.Call, mi);
}
protected abstract string GetMethodName { get; }
public override void Emit (EmitContext ec)
{
- ec.ig.Emit (OpCodes.Ldtoken, member.MetaInfo);
+ ec.Emit (OpCodes.Ldtoken, member);
base.Emit (ec);
}
/// </summary>
public class SizeOf : Expression {
readonly Expression QueriedType;
- Type type_queried;
+ TypeSpec type_queried;
public SizeOf (Expression queried_type, Location l)
{
type_queried = texpr.Type;
if (TypeManager.IsEnumType (type_queried))
- type_queried = TypeManager.GetEnumUnderlyingType (type_queried);
+ type_queried = EnumSpec.GetUnderlyingType (type_queried);
int size_of = GetTypeSize (type_queried);
if (size_of > 0) {
public override void Emit (EmitContext ec)
{
- ec.ig.Emit (OpCodes.Sizeof, type_queried);
+ ec.Emit (OpCodes.Sizeof, type_queried);
}
protected override void CloneTo (CloneContext clonectx, Expression t)
readonly string alias;
public static readonly string GlobalAlias = "global";
+ public QualifiedAliasMember (string alias, string identifier, Location l)
+ : base (null, identifier, l)
+ {
+ this.alias = alias;
+ }
+
public QualifiedAliasMember (string alias, string identifier, TypeArguments targs, Location l)
: base (null, identifier, targs, l)
{
this.alias = alias;
}
- public QualifiedAliasMember (string alias, string identifier, Location l)
- : base (null, identifier, l)
+ public QualifiedAliasMember (string alias, string identifier, int arity, Location l)
+ : base (null, identifier, arity, l)
{
this.alias = alias;
}
return ResolveAsTypeStep (ec, false);
}
- protected override void Error_IdentifierNotFound (IMemberContext rc, FullNamedExpression expr_type, string identifier)
+ protected override void Error_IdentifierNotFound (IMemberContext rc, TypeSpec expr_type, string identifier)
{
rc.Compiler.Report.Error (687, loc,
"A namespace alias qualifier `{0}' did not resolve to a namespace or a type",
{
string name = Name;
if (targs != null) {
- name = TypeManager.RemoveGenericArity (Name) + "<" +
- targs.GetSignatureForError () + ">";
+ name = Name + "<" + targs.GetSignatureForError () + ">";
}
return alias + "::" + name;
this.expr = expr;
}
+ public MemberAccess (Expression expr, string identifier, int arity, Location loc)
+ : base (identifier, arity, loc)
+ {
+ this.expr = expr;
+ }
+
Expression DoResolve (ResolveContext ec, Expression right_side)
{
if (type != null)
if (expr_resolved == null)
return null;
- string LookupIdentifier = MemberName.MakeName (Name, targs);
-
Namespace ns = expr_resolved as Namespace;
if (ns != null) {
- FullNamedExpression retval = ns.Lookup (ec.Compiler, LookupIdentifier, loc);
+ FullNamedExpression retval = ns.Lookup (ec.Compiler, Name, Arity, loc);
if (retval == null)
- ns.Error_NamespaceDoesNotExist (loc, LookupIdentifier, ec);
- else if (targs != null)
+ ns.Error_NamespaceDoesNotExist (loc, Name, Arity, ec);
+ else if (HasTypeArguments)
retval = new GenericTypeExpr (retval.Type, targs, loc).ResolveAsTypeStep (ec, false);
return retval;
}
- Type expr_type = expr_resolved.Type;
- if (TypeManager.IsDynamicType (expr_type)) {
+ TypeSpec expr_type = expr_resolved.Type;
+ if (expr_type == InternalType.Dynamic) {
Arguments args = new Arguments (1);
args.Add (new Argument (expr_resolved.Resolve (ec)));
expr = new DynamicMemberBinder (Name, args, loc);
"System.NullReferenceException");
}
- if (targs != null) {
- if (!targs.Resolve (ec))
- return null;
- }
+ var arity = HasTypeArguments ? targs.Count : -1;
- Expression member_lookup;
- member_lookup = MemberLookup (ec.Compiler,
- ec.CurrentType, expr_type, expr_type, Name, loc);
-
- if (member_lookup == null && targs != null) {
- member_lookup = MemberLookup (ec.Compiler,
- ec.CurrentType, expr_type, expr_type, LookupIdentifier, loc);
- }
+ var member_lookup = MemberLookup (ec.Compiler,
+ ec.CurrentType, expr_type, expr_type, Name, arity, BindingRestriction.NoOverrides, loc);
if (member_lookup == null) {
ExprClass expr_eclass = expr_resolved.eclass;
if (expr_eclass == ExprClass.Value || expr_eclass == ExprClass.Variable ||
expr_eclass == ExprClass.IndexerAccess || expr_eclass == ExprClass.PropertyAccess ||
expr_eclass == ExprClass.EventAccess) {
- ExtensionMethodGroupExpr ex_method_lookup = ec.LookupExtensionMethod (expr_type, Name, loc);
+ ExtensionMethodGroupExpr ex_method_lookup = ec.LookupExtensionMethod (expr_type, Name, arity, loc);
if (ex_method_lookup != null) {
ex_method_lookup.ExtensionExpression = expr_resolved;
- if (targs != null) {
+ if (HasTypeArguments) {
+ if (!targs.Resolve (ec))
+ return null;
+
ex_method_lookup.SetTypeArguments (ec, targs);
}
expr = expr_resolved;
member_lookup = Error_MemberLookupFailed (ec,
- ec.CurrentType, expr_type, expr_type, Name, null,
- AllMemberTypes, AllBindingFlags);
+ ec.CurrentType, expr_type, expr_type, Name, arity, null,
+ MemberKind.All, BindingRestriction.AccessibleOnly);
if (member_lookup == null)
return null;
}
}
GenericTypeExpr ct = expr_resolved as GenericTypeExpr;
- if (ct != null) {
- //
- // When looking up a nested type in a generic instance
- // via reflection, we always get a generic type definition
- // and not a generic instance - so we have to do this here.
- //
- // See gtest-172-lib.cs and gtest-172.cs for an example.
- //
-
- TypeArguments nested_targs;
- if (HasTypeArguments) {
- nested_targs = ct.TypeArguments.Clone ();
- nested_targs.Add (targs);
- } else {
- nested_targs = ct.TypeArguments;
- }
-
- ct = new GenericTypeExpr (member_lookup.Type, nested_targs, loc);
-
+ if (ct != null && Arity > 0) {
+ ct = new GenericTypeExpr (member_lookup.Type, targs, loc);
return ct.ResolveAsTypeStep (ec, false);
}
if (me == null)
return null;
- if (targs != null) {
+ if (HasTypeArguments) {
+ if (!targs.Resolve (ec))
+ return null;
+
me.SetTypeArguments (ec, targs);
}
if (expr_resolved == null)
return null;
- string LookupIdentifier = MemberName.MakeName (Name, targs);
-
Namespace ns = expr_resolved as Namespace;
if (ns != null) {
- FullNamedExpression retval = ns.Lookup (rc.Compiler, LookupIdentifier, loc);
+ FullNamedExpression retval = ns.Lookup (rc.Compiler, Name, Arity, loc);
- if (retval == null && !silent)
- ns.Error_NamespaceDoesNotExist (loc, LookupIdentifier, rc);
- else if (targs != null)
+ if (retval == null) {
+ if (!silent)
+ ns.Error_NamespaceDoesNotExist (loc, Name, Arity, rc);
+ } else if (HasTypeArguments) {
retval = new GenericTypeExpr (retval.Type, targs, loc).ResolveAsTypeStep (rc, silent);
+ }
return retval;
}
if (tnew_expr == null)
return null;
- Type expr_type = tnew_expr.Type;
+ TypeSpec expr_type = tnew_expr.Type;
if (TypeManager.IsGenericParameter (expr_type)) {
rc.Compiler.Report.Error (704, loc, "A nested type cannot be specified through a type parameter `{0}'",
tnew_expr.GetSignatureForError ());
return null;
}
- Expression member_lookup = MemberLookup (rc.Compiler,
- rc.CurrentType, expr_type, expr_type, LookupIdentifier,
- MemberTypes.NestedType, BindingFlags.Public | BindingFlags.NonPublic, loc);
- if (member_lookup == null) {
+ var nested = MemberCache.FindNestedType (expr_type, Name, Arity);
+ if (nested == null) {
if (silent)
return null;
- Error_IdentifierNotFound (rc, expr_resolved, LookupIdentifier);
+ Error_IdentifierNotFound (rc, expr_type, Name);
return null;
}
- TypeExpr texpr = member_lookup.ResolveAsTypeTerminal (rc, false);
- if (texpr == null)
- return null;
-
- TypeArguments the_args = targs;
- Type declaring_type = texpr.Type.DeclaringType;
- if (TypeManager.HasGenericArguments (declaring_type) && !TypeManager.IsGenericTypeDefinition (expr_type)) {
- while (!TypeManager.IsEqual (TypeManager.DropGenericTypeArguments (expr_type), declaring_type)) {
- expr_type = expr_type.BaseType;
- }
-
- TypeArguments new_args = new TypeArguments ();
- foreach (Type decl in TypeManager.GetTypeArguments (expr_type))
- new_args.Add (new TypeExpression (TypeManager.TypeToCoreType (decl), loc));
-
- if (targs != null)
- new_args.Add (targs);
-
- the_args = new_args;
+ bool extra_check;
+ if (!IsMemberAccessible (rc.CurrentType ?? InternalType.FakeInternalType, nested, out extra_check)) {
+ ErrorIsInaccesible (loc, nested.GetSignatureForError (), rc.Compiler.Report);
}
-
- if (the_args != null) {
- GenericTypeExpr ctype = new GenericTypeExpr (texpr.Type, the_args, loc);
- return ctype.ResolveAsTypeStep (rc, false);
+
+ TypeExpr texpr;
+ if (HasTypeArguments) {
+ texpr = new GenericTypeExpr (nested, targs, loc);
+ } else {
+ texpr = new TypeExpression (nested, loc);
}
- return texpr;
+ return texpr.ResolveAsTypeStep (rc, false);
}
- protected virtual void Error_IdentifierNotFound (IMemberContext rc, FullNamedExpression expr_type, string identifier)
+ protected virtual void Error_IdentifierNotFound (IMemberContext rc, TypeSpec expr_type, string identifier)
{
- Expression member_lookup = MemberLookup (rc.Compiler,
- rc.CurrentType, expr_type.Type, expr_type.Type, SimpleName.RemoveGenericArity (identifier),
- MemberTypes.NestedType, BindingFlags.Public | BindingFlags.NonPublic, loc);
-
- if (member_lookup != null) {
- expr_type = member_lookup.ResolveAsTypeTerminal (rc, false);
- if (expr_type == null)
- return;
+ var nested = MemberCache.FindNestedType (expr_type, Name, -System.Math.Max (1, Arity));
- expr_type.Error_TypeArgumentsCannotBeUsed (rc.Compiler.Report, loc);
+ if (nested != null) {
+ Error_TypeArgumentsCannotBeUsed (rc.Compiler.Report, expr.Location, nested, Arity);
return;
}
- member_lookup = MemberLookup (rc.Compiler,
- rc.CurrentType, expr_type.Type, expr_type.Type, identifier,
- MemberTypes.All, BindingFlags.Public | BindingFlags.NonPublic, loc);
+ var member_lookup = MemberLookup (rc.Compiler,
+ rc.CurrentType, expr_type, expr_type, identifier, -1,
+ MemberKind.All, BindingRestriction.None, loc);
if (member_lookup == null) {
rc.Compiler.Report.Error (426, loc, "The nested type `{0}' does not exist in the type `{1}'",
}
}
- protected override void Error_TypeDoesNotContainDefinition (ResolveContext ec, Type type, string name)
+ protected override void Error_TypeDoesNotContainDefinition (ResolveContext ec, TypeSpec type, string name)
{
if (RootContext.Version > LanguageVersion.ISO_2 && !ec.Compiler.IsRuntimeBinder &&
((expr.eclass & (ExprClass.Value | ExprClass.Variable)) != 0)) {
}
}
- public override void MutateHoistedGenericType (AnonymousMethodStorey storey)
- {
- Expr.MutateHoistedGenericType (storey);
- }
-
protected override void CloneTo (CloneContext clonectx, Expression t)
{
CheckedExpr target = (CheckedExpr) t;
Expr.EmitBranchable (ec, target, on_true);
}
- public override void MutateHoistedGenericType (AnonymousMethodStorey storey)
- {
- Expr.MutateHoistedGenericType (storey);
- }
-
protected override void CloneTo (CloneContext clonectx, Expression t)
{
UnCheckedExpr target = (UnCheckedExpr) t;
return CreateExpressionFactoryCall (ec, "ArrayIndex", args);
}
- Expression MakePointerAccess (ResolveContext ec, Type t)
+ Expression MakePointerAccess (ResolveContext ec, TypeSpec t)
{
if (Arguments.Count != 1){
ec.Report.Error (196, loc, "A pointer must be indexed by only one value");
//
// I am experimenting with this pattern.
//
- Type t = Expr.Type;
+ TypeSpec t = Expr.Type;
if (t == TypeManager.array_type){
ec.Report.Error (21, loc, "Cannot apply indexing with [] to an expression of type `System.Array'");
bool dynamic;
ea.Arguments.Resolve (ec, out dynamic);
- Type t = ea.Expr.Type;
+ TypeSpec t = ea.Expr.Type;
int rank = ea.Arguments.Count;
- if (t.GetArrayRank () != rank) {
+ if (t.GetMetaInfo ().GetArrayRank () != rank) {
ec.Report.Error (22, ea.Location, "Wrong number of indexes `{0}' inside [], expected `{1}'",
- ea.Arguments.Count.ToString (), t.GetArrayRank ().ToString ());
+ ea.Arguments.Count.ToString (), t.GetMetaInfo ().GetArrayRank ().ToString ());
return null;
}
return this;
}
- /// <summary>
- /// Emits the right opcode to load an object of Type `t'
- /// from an array of T
- /// </summary>
- void EmitLoadOpcode (ILGenerator ig, Type type, int rank)
- {
- if (rank > 1) {
- MethodInfo get = FetchGetMethod ();
- ig.Emit (OpCodes.Call, get);
- return;
- }
-
- if (type == TypeManager.byte_type || type == TypeManager.bool_type)
- ig.Emit (OpCodes.Ldelem_U1);
- else if (type == TypeManager.sbyte_type)
- ig.Emit (OpCodes.Ldelem_I1);
- else if (type == TypeManager.short_type)
- ig.Emit (OpCodes.Ldelem_I2);
- else if (type == TypeManager.ushort_type || type == TypeManager.char_type)
- ig.Emit (OpCodes.Ldelem_U2);
- else if (type == TypeManager.int32_type)
- ig.Emit (OpCodes.Ldelem_I4);
- else if (type == TypeManager.uint32_type)
- ig.Emit (OpCodes.Ldelem_U4);
- else if (type == TypeManager.uint64_type)
- ig.Emit (OpCodes.Ldelem_I8);
- else if (type == TypeManager.int64_type)
- ig.Emit (OpCodes.Ldelem_I8);
- else if (type == TypeManager.float_type)
- ig.Emit (OpCodes.Ldelem_R4);
- else if (type == TypeManager.double_type)
- ig.Emit (OpCodes.Ldelem_R8);
- else if (type == TypeManager.intptr_type)
- ig.Emit (OpCodes.Ldelem_I);
- else if (TypeManager.IsEnumType (type)){
- EmitLoadOpcode (ig, TypeManager.GetEnumUnderlyingType (type), rank);
- } else if (TypeManager.IsStruct (type)){
- ig.Emit (OpCodes.Ldelema, type);
- ig.Emit (OpCodes.Ldobj, type);
- } else if (type.IsGenericParameter) {
- ig.Emit (OpCodes.Ldelem, type);
- } else if (type.IsPointer)
- ig.Emit (OpCodes.Ldelem_I);
- else
- ig.Emit (OpCodes.Ldelem_Ref);
- }
-
protected override void Error_NegativeArrayIndex (ResolveContext ec, Location loc)
{
ec.Report.Warning (251, 2, loc, "Indexing an array with a negative index (array indices always start at zero)");
}
- /// <summary>
- /// Returns the right opcode to store an object of Type `t'
- /// from an array of T.
- /// </summary>
- static public OpCode GetStoreOpcode (Type t, out bool is_stobj, out bool has_type_arg)
- {
- has_type_arg = false; is_stobj = false;
- t = TypeManager.TypeToCoreType (t);
- if (TypeManager.IsEnumType (t))
- t = TypeManager.GetEnumUnderlyingType (t);
- if (t == TypeManager.byte_type || t == TypeManager.sbyte_type ||
- t == TypeManager.bool_type)
- return OpCodes.Stelem_I1;
- else if (t == TypeManager.short_type || t == TypeManager.ushort_type ||
- t == TypeManager.char_type)
- return OpCodes.Stelem_I2;
- else if (t == TypeManager.int32_type || t == TypeManager.uint32_type)
- return OpCodes.Stelem_I4;
- else if (t == TypeManager.int64_type || t == TypeManager.uint64_type)
- return OpCodes.Stelem_I8;
- else if (t == TypeManager.float_type)
- return OpCodes.Stelem_R4;
- else if (t == TypeManager.double_type)
- return OpCodes.Stelem_R8;
- else if (t == TypeManager.intptr_type) {
- has_type_arg = true;
- is_stobj = true;
- return OpCodes.Stobj;
- } else if (TypeManager.IsStruct (t)) {
- has_type_arg = true;
- is_stobj = true;
- return OpCodes.Stobj;
- } else if (t.IsGenericParameter) {
- has_type_arg = true;
- return OpCodes.Stelem;
- } else if (t.IsPointer)
- return OpCodes.Stelem_I;
- else
- return OpCodes.Stelem_Ref;
- }
-
- MethodInfo FetchGetMethod ()
- {
- ModuleBuilder mb = RootContext.ToplevelTypes.Builder;
- int arg_count = ea.Arguments.Count;
- Type [] args = new Type [arg_count];
- MethodInfo get;
-
- for (int i = 0; i < arg_count; i++){
- //args [i++] = a.Type;
- args [i] = TypeManager.int32_type;
- }
-
- get = mb.GetArrayMethod (
- ea.Expr.Type, "Get",
- CallingConventions.HasThis |
- CallingConventions.Standard,
- type, args);
- return get;
- }
-
-
MethodInfo FetchAddressMethod ()
{
ModuleBuilder mb = RootContext.ToplevelTypes.Builder;
int arg_count = ea.Arguments.Count;
- Type [] args = new Type [arg_count];
+ var args = new Type [arg_count];
MethodInfo address;
- Type ret_type;
- ret_type = TypeManager.GetReferenceType (type);
+ var ret_type = TypeManager.GetReferenceType (type);
for (int i = 0; i < arg_count; i++){
//args [i++] = a.Type;
- args [i] = TypeManager.int32_type;
+ args[i] = TypeManager.int32_type.GetMetaInfo ();
}
address = mb.GetArrayMethod (
- ea.Expr.Type, "Address",
+ ea.Expr.Type.GetMetaInfo (), "Address",
CallingConventions.HasThis |
CallingConventions.Standard,
ret_type, args);
public void Emit (EmitContext ec, bool leave_copy)
{
- int rank = ea.Expr.Type.GetArrayRank ();
- ILGenerator ig = ec.ig;
+ var ac = ea.Expr.Type as ArrayContainer;
if (prepared) {
- LoadFromPtr (ig, this.type);
+ ec.EmitLoadFromPtr (type);
} else {
LoadArrayAndArguments (ec);
- EmitLoadOpcode (ig, type, rank);
+ ec.EmitArrayLoad (ac);
}
if (leave_copy) {
- ig.Emit (OpCodes.Dup);
+ ec.Emit (OpCodes.Dup);
temp = new LocalTemporary (this.type);
temp.Store (ec);
}
public void EmitAssign (EmitContext ec, Expression source, bool leave_copy, bool prepare_for_load)
{
- int rank = ea.Expr.Type.GetArrayRank ();
- ILGenerator ig = ec.ig;
- Type t = source.Type;
+ var ac = (ArrayContainer) ea.Expr.Type;
+ TypeSpec t = source.Type;
prepared = prepare_for_load;
if (prepared) {
AddressOf (ec, AddressOp.LoadStore);
- ec.ig.Emit (OpCodes.Dup);
+ ec.Emit (OpCodes.Dup);
} else {
LoadArrayAndArguments (ec);
- }
- if (rank == 1) {
- bool is_stobj, has_type_arg;
- OpCode op = GetStoreOpcode (t, out is_stobj, out has_type_arg);
+ //
+ // If we are dealing with a struct, get the
+ // address of it, so we can store it.
+ //
+ // The stobj opcode used by value types will need
+ // an address on the stack, not really an array/array
+ // pair
+ //
+ if (ac.Rank == 1 && TypeManager.IsStruct (t) &&
+ (!TypeManager.IsBuiltinOrEnum (t) ||
+ t == TypeManager.decimal_type)) {
- if (!prepared) {
- //
- // The stobj opcode used by value types will need
- // an address on the stack, not really an array/array
- // pair
- //
- if (is_stobj)
- ig.Emit (OpCodes.Ldelema, t);
+ ec.Emit (OpCodes.Ldelema, t);
}
-
- source.Emit (ec);
- if (leave_copy) {
- ec.ig.Emit (OpCodes.Dup);
- temp = new LocalTemporary (this.type);
- temp.Store (ec);
- }
-
- if (prepared)
- StoreFromPtr (ig, t);
- else if (is_stobj)
- ig.Emit (OpCodes.Stobj, t);
- else if (has_type_arg)
- ig.Emit (op, t);
- else
- ig.Emit (op);
- } else {
- source.Emit (ec);
- if (leave_copy) {
- ec.ig.Emit (OpCodes.Dup);
- temp = new LocalTemporary (this.type);
- temp.Store (ec);
- }
-
- if (prepared) {
- StoreFromPtr (ig, t);
- } else {
- int arg_count = ea.Arguments.Count;
- Type [] args = new Type [arg_count + 1];
- for (int i = 0; i < arg_count; i++) {
- //args [i++] = a.Type;
- args [i] = TypeManager.int32_type;
- }
- args [arg_count] = type;
+ }
- MethodInfo set = RootContext.ToplevelTypes.Builder.GetArrayMethod (
- ea.Expr.Type, "Set",
- CallingConventions.HasThis |
- CallingConventions.Standard,
- TypeManager.void_type, args);
+ source.Emit (ec);
+ if (leave_copy) {
+ ec.Emit (OpCodes.Dup);
+ temp = new LocalTemporary (this.type);
+ temp.Store (ec);
+ }
- ig.Emit (OpCodes.Call, set);
- }
+ if (prepared) {
+ ec.EmitStoreFromPtr (t);
+ } else {
+ ec.EmitArrayStore (ac);
}
if (temp != null) {
public void AddressOf (EmitContext ec, AddressOp mode)
{
- int rank = ea.Expr.Type.GetArrayRank ();
- ILGenerator ig = ec.ig;
+ int rank = ea.Expr.Type.GetMetaInfo ().GetArrayRank ();
LoadArrayAndArguments (ec);
if (rank == 1){
- ig.Emit (OpCodes.Ldelema, type);
+ ec.Emit (OpCodes.Ldelema, type);
} else {
MethodInfo address = FetchAddressMethod ();
- ig.Emit (OpCodes.Call, address);
+ ec.Emit (OpCodes.Call, address);
}
}
ea.Expr.MakeExpression (ctx),
Arguments.MakeExpression (ea.Arguments, ctx));
}
-
- public override void MutateHoistedGenericType (AnonymousMethodStorey storey)
- {
- type = storey.MutateType (type);
- ea.Expr.Type = storey.MutateType (ea.Expr.Type);
- }
}
/// <summary>
{
class IndexerMethodGroupExpr : MethodGroupExpr
{
- public IndexerMethodGroupExpr (Indexers indexers, Location loc)
- : base (null, loc)
+ IEnumerable<IndexerSpec> candidates;
+
+ public IndexerMethodGroupExpr (IEnumerable<IndexerSpec> indexers, Location loc)
+ : base (FilterAccessors (indexers).ToList (), null, loc)
{
- Methods = indexers.Methods.ToArray ();
+ candidates = indexers;
+ }
+
+ public IndexerSpec BestIndexer ()
+ {
+ return candidates.Where (l => l.Get == BestCandidate || l.Set == BestCandidate).First ();
+ }
+
+ static IEnumerable<MemberSpec> FilterAccessors (IEnumerable<IndexerSpec> indexers)
+ {
+ foreach (IndexerSpec i in indexers) {
+ if (i.HasGet)
+ yield return i.Get;
+ else
+ yield return i.Set;
+ }
+ }
+
+ protected override IList<MemberSpec> GetBaseTypeMethods (ResolveContext rc, TypeSpec type)
+ {
+ candidates = GetIndexersForType (type);
+ if (candidates == null)
+ return null;
+
+ return FilterAccessors (candidates).ToList ();
}
public override string Name {
}
}
- class Indexers
- {
- // Contains either property getter or setter
- public List<MethodSpec> Methods;
- public List<PropertyInfo> Properties;
-
- Indexers ()
- {
- }
-
- void Append (Type caller_type, MemberInfo [] mi)
- {
- if (mi == null)
- return;
-
- foreach (PropertyInfo property in mi) {
- MethodInfo accessor = property.GetGetMethod (true);
- if (accessor == null)
- accessor = property.GetSetMethod (true);
-
- if (Methods == null) {
- Methods = new List<MethodSpec> ();
- Properties = new List<PropertyInfo> ();
- }
-
- Methods.Add (Import.CreateMethod (accessor));
- Properties.Add (property);
- }
- }
-
- static MemberInfo [] GetIndexersForTypeOrInterface (Type caller_type, Type lookup_type)
- {
- string p_name = TypeManager.IndexerPropertyName (lookup_type);
-
- return TypeManager.MemberLookup (
- caller_type, caller_type, lookup_type, MemberTypes.Property,
- BindingFlags.Public | BindingFlags.Instance |
- BindingFlags.DeclaredOnly, p_name, null);
- }
-
- public static Indexers GetIndexersForType (Type caller_type, Type lookup_type)
- {
- Indexers ix = new Indexers ();
-
- if (TypeManager.IsGenericParameter (lookup_type)) {
- GenericConstraints gc = TypeManager.GetTypeParameterConstraints (lookup_type);
- if (gc == null)
- return ix;
-
- if (gc.HasClassConstraint) {
- Type class_contraint = gc.ClassConstraint;
- while (class_contraint != TypeManager.object_type && class_contraint != null) {
- ix.Append (caller_type, GetIndexersForTypeOrInterface (caller_type, class_contraint));
- class_contraint = class_contraint.BaseType;
- }
- }
-
- Type[] ifaces = gc.InterfaceConstraints;
- foreach (Type itype in ifaces)
- ix.Append (caller_type, GetIndexersForTypeOrInterface (caller_type, itype));
-
- return ix;
- }
-
- Type copy = lookup_type;
- while (copy != TypeManager.object_type && copy != null){
- ix.Append (caller_type, GetIndexersForTypeOrInterface (caller_type, copy));
- copy = copy.BaseType;
- }
-
- if (lookup_type.IsInterface) {
- Type [] ifaces = TypeManager.GetInterfaces (lookup_type);
- if (ifaces != null) {
- foreach (Type itype in ifaces)
- ix.Append (caller_type, GetIndexersForTypeOrInterface (caller_type, itype));
- }
- }
-
- return ix;
- }
- }
-
//
// Points to our "data" repository
//
- MethodSpec get, set;
+ IndexerSpec spec;
bool is_base_indexer;
bool prepared;
LocalTemporary temp;
LocalTemporary prepared_value;
Expression set_expr;
- protected Type indexer_type;
- protected Type current_type;
+ protected TypeSpec indexer_type;
+ protected TypeSpec current_type;
protected Expression instance_expr;
protected Arguments arguments;
{
Arguments args = Arguments.CreateForExpressionTree (ec, arguments,
instance_expr.CreateExpressionTree (ec),
- new TypeOfMethod (get, loc));
+ new TypeOfMethod (spec.Get, loc));
return CreateExpressionFactoryCall (ec, "Call", args);
}
+ static IEnumerable<IndexerSpec> GetIndexersForType (TypeSpec lookup_type)
+ {
+ return MemberCache.FindIndexers (lookup_type, BindingRestriction.AccessibleOnly | BindingRestriction.NoOverrides);
+ }
+
protected virtual void CommonResolve (ResolveContext ec)
{
indexer_type = instance_expr.Type;
{
CommonResolve (ec);
- MethodGroupExpr mg;
- Indexers ilist;
bool dynamic;
arguments.Resolve (ec, out dynamic);
- if (TypeManager.IsDynamicType (indexer_type)) {
+ if (indexer_type == InternalType.Dynamic) {
dynamic = true;
- mg = null;
- ilist = null;
} else {
- ilist = Indexers.GetIndexersForType (current_type, indexer_type);
- if (ilist.Methods == null) {
+ var ilist = GetIndexersForType (/*current_type,*/ indexer_type);
+ if (ilist == null) {
ec.Report.Error (21, loc, "Cannot apply indexing with [] to an expression of type `{0}'",
TypeManager.CSharpName (indexer_type));
return null;
}
- mg = new IndexerMethodGroupExpr (ilist, loc);
- mg = mg.OverloadResolve (ec, ref arguments, false, loc);
+ var mg = new IndexerMethodGroupExpr (ilist, loc);
+ mg = mg.OverloadResolve (ec, ref arguments, false, loc) as IndexerMethodGroupExpr;
if (mg == null)
return null;
+
+ if (!dynamic)
+ spec = mg.BestIndexer ();
}
if (dynamic) {
return expr.Resolve (ec);
}
- var mi = (MethodSpec) mg;
- PropertyInfo pi = null;
- for (int i = 0; i < ilist.Methods.Count; ++i) {
- if (ilist.Methods [i].MetaInfo == mi.MetaInfo) {
- pi = (PropertyInfo) ilist.Properties [i];
- break;
- }
- }
-
- type = TypeManager.TypeToCoreType (pi.PropertyType);
+ type = spec.MemberType;
if (type.IsPointer && !ec.IsUnsafe)
UnsafeError (ec, loc);
- MethodSpec accessor = null;
+ MethodSpec accessor;
if (right_side == null) {
- var m = pi.GetGetMethod (true);
- if (m != null)
- accessor = get = Import.CreateMethod (m);
+ accessor = spec.Get;
} else {
- var m = pi.GetSetMethod (true);
- if (m != null)
- accessor = set = Import.CreateMethod (m);
- if (accessor == null && pi.GetGetMethod (true) != null) {
- ec.Report.SymbolRelatedToPreviousError (pi);
+ accessor = spec.Set;
+ if (!spec.HasSet && spec.HasGet) {
+ ec.Report.SymbolRelatedToPreviousError (spec);
ec.Report.Error (200, loc, "The read only property or indexer `{0}' cannot be assigned to",
- TypeManager.GetFullNameSignature (pi));
+ spec.GetSignatureForError ());
return null;
}
set_expr = Convert.ImplicitConversion (ec, right_side, type, loc);
}
- if (accessor == null) {
- ec.Report.SymbolRelatedToPreviousError (pi);
+ if (accessor == null || accessor.Kind == MemberKind.FakeMethod) {
+ ec.Report.SymbolRelatedToPreviousError (spec);
ec.Report.Error (154, loc, "The property or indexer `{0}' cannot be used in this context because it lacks a `{1}' accessor",
- TypeManager.GetFullNameSignature (pi), GetAccessorName (right_side != null));
+ spec.GetSignatureForError (), GetAccessorName (right_side != null));
return null;
}
//
// Only base will allow this invocation to happen.
//
- if (accessor.IsAbstract && this is BaseIndexerAccess) {
- Error_CannotCallAbstractBase (ec, TypeManager.GetFullNameSignature (pi));
+ if (spec.IsAbstract && this is BaseIndexerAccess) {
+ Error_CannotCallAbstractBase (ec, spec.GetSignatureForError ());
}
bool must_do_cs1540_check;
- if (!IsAccessorAccessible (ec.CurrentType, accessor, out must_do_cs1540_check)) {
- if (set == null) {
- var m = pi.GetSetMethod (true);
- if (m != null)
- set = Import.CreateMethod (m);
- } else {
- var m = pi.GetGetMethod (true);
- if (m != null)
- get = Import.CreateMethod (m);
- }
-
- if (set != null && get != null &&
- (set.MetaInfo.Attributes & MethodAttributes.MemberAccessMask) != (get.MetaInfo.Attributes & MethodAttributes.MemberAccessMask)) {
- ec.Report.SymbolRelatedToPreviousError (accessor.MetaInfo);
+ if (!IsMemberAccessible (ec.CurrentType, accessor, out must_do_cs1540_check)) {
+ if (spec.HasDifferentAccessibility) {
+ ec.Report.SymbolRelatedToPreviousError (accessor);
ec.Report.Error (271, loc, "The property or indexer `{0}' cannot be used in this context because a `{1}' accessor is inaccessible",
- TypeManager.GetFullNameSignature (pi), GetAccessorName (right_side != null));
+ TypeManager.GetFullNameSignature (spec), GetAccessorName (right_side != null));
} else {
- ec.Report.SymbolRelatedToPreviousError (pi);
- ErrorIsInaccesible (loc, TypeManager.GetFullNameSignature (pi), ec.Report);
+ ec.Report.SymbolRelatedToPreviousError (spec);
+ ErrorIsInaccesible (loc, TypeManager.GetFullNameSignature (spec), ec.Report);
}
}
!TypeManager.IsInstantiationOfSameGenericType (instance_expr.Type, ec.CurrentType) &&
!TypeManager.IsNestedChildOf (ec.CurrentType, instance_expr.Type) &&
!TypeManager.IsSubclassOf (instance_expr.Type, ec.CurrentType)) {
- ec.Report.SymbolRelatedToPreviousError (accessor.MetaInfo);
- Error_CannotAccessProtected (ec, loc, accessor.MetaInfo, instance_expr.Type, ec.CurrentType);
+ ec.Report.SymbolRelatedToPreviousError (accessor);
+ Error_CannotAccessProtected (ec, loc, spec, instance_expr.Type, ec.CurrentType);
return null;
}
if (prepared) {
prepared_value.Emit (ec);
} else {
- Invocation.EmitCall (ec, is_base_indexer, instance_expr, get,
+ Invocation.EmitCall (ec, is_base_indexer, instance_expr, spec.Get,
arguments, loc, false, false);
}
if (leave_copy) {
- ec.ig.Emit (OpCodes.Dup);
+ ec.Emit (OpCodes.Dup);
temp = new LocalTemporary (Type);
temp.Store (ec);
}
Expression value = set_expr;
if (prepared) {
- Invocation.EmitCall (ec, is_base_indexer, instance_expr, get,
+ Invocation.EmitCall (ec, is_base_indexer, instance_expr, spec.Get,
arguments, loc, true, false);
prepared_value = new LocalTemporary (type);
prepared_value.Release (ec);
if (leave_copy) {
- ec.ig.Emit (OpCodes.Dup);
+ ec.Emit (OpCodes.Dup);
temp = new LocalTemporary (Type);
temp.Store (ec);
}
if (!prepared)
arguments.Add (new Argument (value));
- Invocation.EmitCall (ec, is_base_indexer, instance_expr, set, arguments, loc, false, prepared);
+ Invocation.EmitCall (ec, is_base_indexer, instance_expr, spec.Set, arguments, loc, false, prepared);
if (temp != null) {
temp.Emit (ec);
public override string GetSignatureForError ()
{
- return TypeManager.CSharpSignature (get != null ? get.MetaInfo : set.MetaInfo, false);
+ return spec.GetSignatureForError ();
}
#if NET_4_0
var args = Arguments.MakeExpression (arguments, ctx).Concat (value);
return SLE.Expression.Block (
- SLE.Expression.Call (instance_expr.MakeExpression (ctx), (MethodInfo) set.MetaInfo, args),
+ SLE.Expression.Call (instance_expr.MakeExpression (ctx), (MethodInfo) spec.Set.GetMetaInfo (), args),
value [0]);
}
#endif
public override SLE.Expression MakeExpression (BuilderContext ctx)
{
var args = Arguments.MakeExpression (arguments, ctx);
- return SLE.Expression.Call (instance_expr.MakeExpression (ctx), (MethodInfo) get.MetaInfo, args);
- }
-
- public override void MutateHoistedGenericType (AnonymousMethodStorey storey)
- {
- if (get != null)
- storey.MutateGenericMethod (get);
- if (set != null)
- storey.MutateGenericMethod (set);
-
- instance_expr.MutateHoistedGenericType (storey);
- if (arguments != null)
- arguments.MutateHoistedGenericType (storey);
-
- type = storey.MutateType (type);
+ return SLE.Expression.Call (instance_expr.MakeExpression (ctx), (MethodInfo) spec.Get.GetMetaInfo (), args);
}
protected override void CloneTo (CloneContext clonectx, Expression t)
Expression CommonResolve (ResolveContext ec)
{
Expression member_lookup;
- Type current_type = ec.CurrentType;
- Type base_type = current_type.BaseType;
+ TypeSpec current_type = ec.CurrentType;
+ TypeSpec base_type = current_type.BaseType;
if (!This.IsThisAvailable (ec)) {
if (ec.IsStatic) {
}
return null;
}
-
- member_lookup = MemberLookup (ec.Compiler, ec.CurrentType, null, base_type, Identifier,
- AllMemberTypes, AllBindingFlags, loc);
+
+ var arity = args == null ? -1 : args.Count;
+ member_lookup = MemberLookup (ec.Compiler, ec.CurrentType, null, base_type, Identifier, arity,
+ MemberKind.All, BindingRestriction.AccessibleOnly, loc);
if (member_lookup == null) {
- Error_MemberLookupFailed (ec, ec.CurrentType, base_type, base_type, Identifier,
- null, AllMemberTypes, AllBindingFlags);
+ Error_MemberLookupFailed (ec, ec.CurrentType, base_type, base_type, Identifier, arity,
+ null, MemberKind.All, BindingRestriction.AccessibleOnly);
return null;
}
loc = Location.Null;
}
- public EmptyExpression (Type t)
+ public EmptyExpression (TypeSpec t)
{
type = t;
eclass = ExprClass.Value;
// instead of creating gazillions of EmptyExpressions.
// (CanImplicitConversion uses it)
//
- public void SetType (Type t)
+ public void SetType (TypeSpec t)
{
type = t;
}
{
this.method = method;
this.source = source;
- type = TypeManager.TypeToCoreType (method.ReturnType);
+ type = method.ReturnType;
loc = l;
}
protected override Expression DoResolve (ResolveContext ec)
{
- ObsoleteAttribute oa = AttributeTester.GetMethodObsoleteAttribute (method.MetaInfo);
+ ObsoleteAttribute oa = method.GetAttributeObsolete ();
if (oa != null)
AttributeTester.Report_ObsoleteMessage (oa, GetSignatureForError (), loc, ec.Report);
public override void Emit (EmitContext ec)
{
source.Emit (ec);
- ec.ig.Emit (OpCodes.Call, (MethodInfo) method.MetaInfo);
+ ec.Emit (OpCodes.Call, method);
}
public override string GetSignatureForError ()
{
- return TypeManager.CSharpSignature (method.MetaInfo);
+ return TypeManager.CSharpSignature (method);
}
public override SLE.Expression MakeExpression (BuilderContext ctx)
{
- return SLE.Expression.Convert (source.MakeExpression (ctx), type, (MethodInfo) method.MetaInfo);
- }
-
- public override void MutateHoistedGenericType (AnonymousMethodStorey storey)
- {
- source.MutateHoistedGenericType (storey);
- storey.MutateGenericMethod (method);
+ return SLE.Expression.Convert (source.MakeExpression (ctx), type.GetMetaInfo (), (MethodInfo) method.GetMetaInfo ());
}
}
if (lexpr == null)
return null;
- Type ltype = lexpr.Type;
+ TypeSpec ltype = lexpr.Type;
if ((dim.Length > 0) && (dim [0] == '?')) {
TypeExpr nullable = new Nullable.NullableType (lexpr, loc);
if (dim.Length > 1)
return null;
}
- if ((ltype.Attributes & Class.StaticClassAttribute) == Class.StaticClassAttribute) {
+ if (ltype.IsStatic) {
ec.Compiler.Report.SymbolRelatedToPreviousError (ltype);
ec.Compiler.Report.Error (719, loc, "Array elements cannot be of static type `{0}'",
TypeManager.CSharpName (ltype));
{
return left.GetSignatureForError () + dim;
}
-
- public override TypeExpr ResolveAsTypeTerminal (IMemberContext ec, bool silent)
- {
- return ResolveAsBaseTerminal (ec, silent);
- }
}
public class FixedBufferPtr : Expression {
Expression array;
- public FixedBufferPtr (Expression array, Type array_type, Location l)
+ public FixedBufferPtr (Expression array, TypeSpec array_type, Location l)
{
this.array = array;
this.loc = l;
- type = TypeManager.GetPointerType (array_type);
+ type = PointerContainer.MakeType (array_type);
eclass = ExprClass.Value;
}
// for fixed (char *pa = a)
//
public class ArrayPtr : FixedBufferPtr {
- Type array_type;
+ TypeSpec array_type;
- public ArrayPtr (Expression array, Type array_type, Location l):
+ public ArrayPtr (Expression array, TypeSpec array_type, Location l):
base (array, array_type, l)
{
this.array_type = array_type;
{
base.Emit (ec);
- ILGenerator ig = ec.ig;
- IntLiteral.EmitInt (ig, 0);
- ig.Emit (OpCodes.Ldelema, array_type);
+ ec.EmitInt (0);
+ ec.Emit (OpCodes.Ldelema, array_type);
}
}
var expr_type = child.Type;
if (expr_type == TypeManager.uint32_type)
- ec.ig.Emit (OpCodes.Conv_U);
+ ec.Emit (OpCodes.Conv_U);
else if (expr_type == TypeManager.int64_type)
- ec.ig.Emit (OpCodes.Conv_Ovf_I);
+ ec.Emit (OpCodes.Conv_Ovf_I);
else if (expr_type == TypeManager.uint64_type)
- ec.ig.Emit (OpCodes.Conv_Ovf_I_Un);
+ ec.Emit (OpCodes.Conv_Ovf_I_Un);
else
throw new InternalErrorException ("Cannot emit cast to unknown array element type", type);
}
// Implements the `stackalloc' keyword
//
public class StackAlloc : Expression {
- Type otype;
+ TypeSpec otype;
Expression t;
Expression count;
if (!TypeManager.VerifyUnmanaged (ec.Compiler, otype, loc))
return null;
- type = TypeManager.GetPointerType (otype);
+ type = PointerContainer.MakeType (otype);
eclass = ExprClass.Value;
return this;
public override void Emit (EmitContext ec)
{
int size = GetTypeSize (otype);
- ILGenerator ig = ec.ig;
count.Emit (ec);
if (size == 0)
- ig.Emit (OpCodes.Sizeof, otype);
+ ec.Emit (OpCodes.Sizeof, otype);
else
- IntConstant.EmitInt (ig, size);
+ ec.EmitInt (size);
- ig.Emit (OpCodes.Mul_Ovf_Un);
- ig.Emit (OpCodes.Localloc);
+ ec.Emit (OpCodes.Mul_Ovf_Un);
+ ec.Emit (OpCodes.Localloc);
}
protected override void CloneTo (CloneContext clonectx, Expression t)
return EmptyExpressionStatement.Instance;
MemberExpr me = MemberLookupFinal (ec, ec.CurrentInitializerVariable.Type, ec.CurrentInitializerVariable.Type,
- Name, MemberTypes.Field | MemberTypes.Property, BindingFlags.Public | BindingFlags.Instance, loc) as MemberExpr;
+ Name, 0, MemberKind.Field | MemberKind.Property, BindingRestriction.AccessibleOnly | BindingRestriction.InstanceOnly, loc) as MemberExpr;
if (me == null)
return null;
return expr;
}
- protected override Expression Error_MemberLookupFailed (ResolveContext ec, Type type, MemberInfo[] members)
+ protected override MemberExpr Error_MemberLookupFailed (ResolveContext ec, TypeSpec type, IList<MemberSpec> members)
{
- MemberInfo member = members [0];
- if (member.MemberType != MemberTypes.Property && member.MemberType != MemberTypes.Field)
+ var member = members.First ();
+ if (member.Kind != MemberKind.Property && member.Kind != MemberKind.Field)
ec.Report.Error (1913, loc, "Member `{0}' cannot be initialized. An object " +
"initializer may only be used for fields, or properties", TypeManager.GetFullNameSignature (member));
else
{
}
- protected override void Error_TypeDoesNotContainDefinition (ResolveContext ec, Type type, string name)
+ protected override void Error_TypeDoesNotContainDefinition (ResolveContext ec, TypeSpec type, string name)
{
if (TypeManager.HasElementType (type))
return;
initializer.Resolve (ec);
throw new InternalErrorException ("This line should never be reached");
} else {
- if (!TypeManager.ImplementsInterface (ec.CurrentInitializerVariable.Type, TypeManager.ienumerable_type)) {
+ if (!ec.CurrentInitializerVariable.Type.ImplementsInterface (TypeManager.ienumerable_type)) {
ec.Report.Error (1922, loc, "A field or property `{0}' cannot be initialized with a collection " +
"object initializer because type `{1}' does not implement `{2}' interface",
ec.CurrentInitializerVariable.GetSignatureForError (),
foreach (ExpressionStatement e in initializers)
e.EmitStatement (ec);
}
-
- public override void MutateHoistedGenericType (AnonymousMethodStorey storey)
- {
- foreach (Expression e in initializers)
- e.MutateHoistedGenericType (storey);
- }
}
//
return !initializers.IsEmpty;
}
}
-
- public override void MutateHoistedGenericType (AnonymousMethodStorey storey)
- {
- base.MutateHoistedGenericType (storey);
- initializers.MutateHoistedGenericType (storey);
- }
}
public class NewAnonymousType : New
{
- static readonly IList<AnonymousTypeParameter> EmptyParameters = Array.AsReadOnly (new AnonymousTypeParameter[0]);
+ static readonly AnonymousTypeParameter[] EmptyParameters = new AnonymousTypeParameter[0];
List<AnonymousTypeParameter> parameters;
readonly TypeContainer parent;
if (type == null)
return null;
+ type.CreateType ();
type.DefineType ();
+ type.ResolveTypeParameters ();
type.Define ();
type.EmitType ();
if (ec.Report.Errors == 0)
var init = new ArrayInitializer (parameters.Count, loc);
foreach (Property p in anonymous_type.Properties)
- init.Add (new TypeOfMethod (Import.CreateMethod (TypeBuilder.GetMethod (type, p.GetBuilder)), loc));
+ init.Add (new TypeOfMethod (MemberCache.GetMember (type, p.Get.Spec), loc));
var ctor_args = new ArrayInitializer (Arguments.Count, loc);
foreach (Argument a in Arguments)
if (parameters == null) {
anonymous_type = CreateAnonymousType (ec, EmptyParameters);
- RequestedType = new TypeExpression (anonymous_type.TypeBuilder, loc);
+ RequestedType = new TypeExpression (anonymous_type.Definition, loc);
return base.DoResolve (ec);
}
if (anonymous_type == null)
return null;
- RequestedType = new GenericTypeExpr (anonymous_type.TypeBuilder, new TypeArguments (t_args), loc);
+ RequestedType = new GenericTypeExpr (anonymous_type.Definition, new TypeArguments (t_args), loc);
return base.DoResolve (ec);
}
}
}
}
- public override void ApplyAttributeBuilder (Attribute a, ConstructorInfo ctor, byte[] cdata, PredefinedAttributes pa)
+ public override void ApplyAttributeBuilder (Attribute a, MethodSpec ctor, byte[] cdata, PredefinedAttributes pa)
{
if (a.Type == pa.FieldOffset) {
status |= Status.HAS_OFFSET;
return;
}
- FieldBuilder.SetCustomAttribute (ctor, cdata);
+ FieldBuilder.SetCustomAttribute ((ConstructorInfo) ctor.GetMetaInfo (), cdata);
}
protected override bool CheckBase ()
{
if (!base.CheckBase ())
return false;
-
- MemberInfo conflict_symbol = Parent.PartialContainer.FindBaseMemberWithSameName (Name, false);
+
+ MemberSpec candidate;
+ var conflict_symbol = MemberCache.FindBaseMember (this, out candidate);
+ if (conflict_symbol == null)
+ conflict_symbol = candidate;
+
if (conflict_symbol == null) {
if ((ModFlags & Modifiers.NEW) != 0) {
- Report.Warning (109, 4, Location, "The member `{0}' does not hide an inherited member. The new keyword is not required", GetSignatureForError ());
+ Report.Warning (109, 4, Location, "The member `{0}' does not hide an inherited member. The new keyword is not required",
+ GetSignatureForError ());
}
- return true;
- }
-
- if ((ModFlags & (Modifiers.NEW | Modifiers.OVERRIDE | Modifiers.BACKING_FIELD)) == 0) {
- Report.SymbolRelatedToPreviousError (conflict_symbol);
- Report.Warning (108, 2, Location, "`{0}' hides inherited member `{1}'. Use the new keyword if hiding was intended",
- GetSignatureForError (), TypeManager.GetFullNameSignature (conflict_symbol));
+ } else {
+ if ((ModFlags & (Modifiers.NEW | Modifiers.OVERRIDE | Modifiers.BACKING_FIELD)) == 0) {
+ Report.SymbolRelatedToPreviousError (conflict_symbol);
+ Report.Warning (108, 2, Location, "`{0}' hides inherited member `{1}'. Use the new keyword if hiding was intended",
+ GetSignatureForError (), conflict_symbol.GetSignatureForError ());
+ }
+
+ if (conflict_symbol.IsAbstract) {
+ Report.SymbolRelatedToPreviousError (conflict_symbol);
+ Report.Error (533, Location, "`{0}' hides inherited abstract member `{1}'",
+ GetSignatureForError (), conflict_symbol.GetSignatureForError ());
+ }
}
return true;
{
base.DoMemberTypeDependentChecks ();
- if (TypeManager.IsGenericParameter (MemberType))
+ if (MemberType.IsGenericParameter)
return;
- if (MemberType.IsSealed && MemberType.IsAbstract) {
+ if (MemberType.IsStatic)
Error_VariableOfStaticClass (Location, GetSignatureForError (), MemberType, Report);
- }
CheckBase ();
IsTypePermitted ();
public override void Emit ()
{
- if (TypeManager.IsDynamicType (member_type)) {
+ if (member_type == InternalType.Dynamic) {
PredefinedAttributes.Get.Dynamic.EmitAttribute (FieldBuilder);
} else {
var trans_flags = TypeManager.HasDynamicTypeUsed (member_type);
if (trans_flags != null) {
var pa = PredefinedAttributes.Get.DynamicTransform;
- if (pa.Constructor != null || pa.ResolveConstructor (Location, TypeManager.bool_type.MakeArrayType ())) {
+ if (pa.Constructor != null || pa.ResolveConstructor (Location, ArrayContainer.MakeType (TypeManager.bool_type, 1))) {
FieldBuilder.SetCustomAttribute (new CustomAttributeBuilder (pa.Constructor, new object[] { trans_flags }));
}
}
base.Emit ();
}
- public static void Error_VariableOfStaticClass (Location loc, string variable_name, Type static_class, Report Report)
+ public static void Error_VariableOfStaticClass (Location loc, string variable_name, TypeSpec static_class, Report Report)
{
Report.SymbolRelatedToPreviousError (static_class);
Report.Error (723, loc, "`{0}': cannot declare variables of static types",
}
}
- protected virtual bool IsFieldClsCompliant {
- get {
- if (FieldBuilder == null)
- return true;
-
- return AttributeTester.IsClsCompliant (FieldBuilder.FieldType);
- }
- }
-
public FieldSpec Spec {
get { return spec; }
}
if (!base.VerifyClsCompliance ())
return false;
- if (!IsFieldClsCompliant) {
+ if (!MemberType.IsCLSCompliant () || this is FixedField) {
Report.Warning (3003, 1, Location, "Type of `{0}' is not CLS-compliant",
GetSignatureForError ());
}
return true;
}
-
- public void SetAssigned ()
- {
- caching_flags |= Flags.IsAssigned;
- }
}
//
// Field specification
//
- public class FieldSpec : MemberSpec
+ public class FieldSpec : MemberSpec, IInterfaceMemberSpec
{
- FieldInfo info;
+ FieldInfo metaInfo;
+ TypeSpec memberType;
- public FieldSpec (IMemberDefinition definition, FieldInfo info, Modifiers modifiers)
- : base (MemberKind.Field, definition, info.Name, modifiers)
+ public FieldSpec (TypeSpec declaringType, IMemberDefinition definition, TypeSpec memberType, FieldInfo info, Modifiers modifiers)
+ : base (MemberKind.Field, declaringType, definition, modifiers)
{
- this.info = info;
+ this.metaInfo = info;
+ this.memberType = memberType;
}
- public bool IsReadOnly {
- get { return (Modifiers & Modifiers.READONLY) != 0; }
- }
+#region Properties
- public FieldInfo MetaInfo {
+ public bool IsReadOnly {
get {
- return info;
- }
- set {
- info = value;
+ return (Modifiers & Modifiers.READONLY) != 0;
}
}
- public override Type DeclaringType {
+ public TypeSpec MemberType {
get {
- return MetaInfo.DeclaringType;
+ return memberType;
}
}
- // Obsolete
- public Type FieldType {
- get {
- return MetaInfo.FieldType;
+#endregion
+
+ public FieldInfo GetMetaInfo ()
+ {
+ if ((state & StateFlags.PendingMetaInflate) != 0) {
+ var decl_meta = DeclaringType.GetMetaInfo ();
+ if (DeclaringType.IsTypeBuilder) {
+ metaInfo = TypeBuilder.GetField (decl_meta, metaInfo);
+ } else {
+ var orig_token = metaInfo.MetadataToken;
+ metaInfo = decl_meta.GetField (Name);
+ if (metaInfo.MetadataToken != orig_token)
+ throw new NotImplementedException ("Resolved to wrong meta token");
+
+ // What a stupid API, does not work because field handle is imported
+ // metaInfo = FieldInfo.GetFieldFromHandle (metaInfo.FieldHandle, DeclaringType.MetaInfo.TypeHandle);
+ }
+
+ state &= ~StateFlags.PendingMetaInflate;
}
+
+ return metaInfo;
+ }
+
+ public override MemberSpec InflateMember (TypeParameterInflator inflator)
+ {
+ var fs = (FieldSpec) base.InflateMember (inflator);
+ fs.memberType = inflator.Inflate (memberType);
+ return fs;
+ }
+
+ public FieldSpec Mutate (TypeParameterMutator mutator)
+ {
+ var decl = DeclaringType;
+ if (DeclaringType.IsGenericOrParentIsGeneric)
+ decl = mutator.Mutate (decl);
+
+ if (decl == DeclaringType)
+ return this;
+
+ var fs = (FieldSpec) MemberwiseClone ();
+ fs.declaringType = decl;
+ fs.state |= StateFlags.PendingMetaInflate;
+
+ // Gets back FieldInfo in case of metaInfo was inflated
+ fs.metaInfo = MemberCache.GetMember (DeclaringType.GetDefinition (), this).metaInfo;
+ return fs;
}
}
// Create nested fixed buffer container
string name = String.Format ("<{0}>__FixedBuffer{1}", Name, GlobalCounter++);
fixed_buffer_type = Parent.TypeBuilder.DefineNestedType (name, Parent.Module.DefaultCharSetType |
- TypeAttributes.NestedPublic | TypeAttributes.Sealed | TypeAttributes.BeforeFieldInit, TypeManager.value_type);
-
- var element = fixed_buffer_type.DefineField (FixedElementName, MemberType, FieldAttributes.Public);
+ TypeAttributes.NestedPublic | TypeAttributes.Sealed | TypeAttributes.BeforeFieldInit, TypeManager.value_type.GetMetaInfo ());
+
+ fixed_buffer_type.DefineField (FixedElementName, MemberType.GetMetaInfo (), FieldAttributes.Public);
RootContext.RegisterCompilerGeneratedType (fixed_buffer_type);
FieldBuilder = Parent.TypeBuilder.DefineField (Name, fixed_buffer_type, ModifiersExtensions.FieldAttr (ModFlags));
- spec = new FixedFieldSpec (this, FieldBuilder, element, ModFlags);
-
- Parent.MemberCache.AddMember (FieldBuilder, spec);
- TypeManager.RegisterFieldBase (FieldBuilder, this);
+ var element_spec = new FieldSpec (null, this, MemberType, FieldBuilder, ModFlags);
+ spec = new FixedFieldSpec (Parent.Definition, this, FieldBuilder, element_spec, ModFlags);
+ Parent.MemberCache.AddMember (spec);
return true;
}
return;
// TODO: It's not cleared
- if (fi == null)
- fi = new FieldInfo[] { pa.Type.GetField ("Size") };
+ if (fi == null) {
+ var field = (FieldSpec) MemberCache.FindMember (pa.Type, MemberFilter.Field ("Size", null), BindingRestriction.DeclaredOnly);
+ fi = new FieldInfo[] { field.GetMetaInfo () };
+ }
object[] fi_val = new object[] { buffer_size };
cab = new CustomAttributeBuilder (pa.Constructor,
!pa.ResolveConstructor (Location, TypeManager.type_type, TypeManager.int32_type))
return;
- cab = new CustomAttributeBuilder (pa.Constructor, new object[] { MemberType, buffer_size });
+ cab = new CustomAttributeBuilder (pa.Constructor, new object[] { MemberType.GetMetaInfo (), buffer_size });
FieldBuilder.SetCustomAttribute (cab);
}
- protected override bool IsFieldClsCompliant {
- get {
- return false;
- }
- }
-
public void SetCharSet (TypeAttributes ta)
{
TypeAttributes cta = fixed_buffer_type.Attributes;
class FixedFieldSpec : FieldSpec
{
- readonly FieldInfo element;
+ readonly FieldSpec element;
- public FixedFieldSpec (IMemberDefinition definition, FieldInfo info, FieldInfo element, Modifiers modifiers)
- : base (definition, info, modifiers)
+ public FixedFieldSpec (TypeSpec declaringType, IMemberDefinition definition, FieldInfo info, FieldSpec element, Modifiers modifiers)
+ : base (declaringType, definition, element.MemberType, info, modifiers)
{
this.element = element;
+
+ // It's never CLS-Compliant
+ state &= ~StateFlags.CLSCompliant_Undetected;
}
- public FieldInfo Element {
+ public FieldSpec Element {
get {
return element;
}
}
- public Type ElementType {
+ public TypeSpec ElementType {
get {
- return element.FieldType;
+ return MemberType;
}
}
}
MemberType == TypeManager.intptr_type || MemberType == TypeManager.uintptr_type)
return true;
- if (TypeManager.IsEnumType (MemberType))
- return true;
-
- return false;
- }
-
- bool CheckStructLayout (Type type, bool isStatic)
- {
- if (TypeManager.IsBuiltinType (type))
+ if (MemberType.IsEnum)
return true;
- if (isStatic) {
- if (!TypeManager.IsValueType (type) || TypeManager.IsEqual (type, Parent.TypeBuilder))
- return true;
- }
-
- if (!TypeManager.IsEqual (TypeManager.DropGenericTypeArguments (type), Parent.TypeBuilder)) {
- if (!TypeManager.IsGenericType (type))
- return true;
-
- foreach (Type t in TypeManager.GetTypeArguments (type)) {
- if (!CheckStructLayout (t, false))
- return false;
- }
- return true;
- }
-
- Report.Error (523, Location,
- "Struct member `{0}' of type `{1}' causes a cycle in the struct layout",
- GetSignatureForError (), TypeManager.CSharpName (MemberType));
return false;
}
"System.Runtime.CompilerServices", "IsVolatile", MemberKind.Class, true);
if (TypeManager.isvolatile_type != null)
- required_modifier = new Type [] { TypeManager.isvolatile_type };
+ required_modifier = new Type[] { TypeManager.isvolatile_type.GetMetaInfo () };
}
FieldBuilder = Parent.TypeBuilder.DefineField (
- Name, MemberType, required_modifier, null, ModifiersExtensions.FieldAttr (ModFlags));
+ Name, member_type.GetMetaInfo (), required_modifier, null, ModifiersExtensions.FieldAttr (ModFlags));
- spec = new FieldSpec (this, FieldBuilder, ModFlags);
+ spec = new FieldSpec (Parent.Definition, this, MemberType, FieldBuilder, ModFlags);
// Don't cache inaccessible fields
if ((ModFlags & Modifiers.BACKING_FIELD) == 0) {
- Parent.MemberCache.AddMember (FieldBuilder, spec);
+ Parent.MemberCache.AddMember (spec);
}
-
- TypeManager.RegisterFieldBase (FieldBuilder, this);
}
catch (ArgumentException) {
Report.RuntimeMissingSupport (Location, "`void' or `void*' field type");
if (initializer != null) {
((TypeContainer) Parent).RegisterFieldForInitialization (this,
new FieldInitializer (this, initializer, this));
- } else {
- if (Parent.PartialContainer.Kind == MemberKind.Struct)
- CheckStructLayout (member_type, (ModFlags & Modifiers.STATIC) != 0);
}
return true;
protected override void DoMemberTypeDependentChecks ()
{
+ if ((ModFlags & Modifiers.BACKING_FIELD) != 0)
+ return;
+
base.DoMemberTypeDependentChecks ();
if ((ModFlags & Modifiers.VOLATILE) != 0) {
// </summary>
public class TypeInfo
{
- public readonly Type Type;
+ public readonly TypeSpec Type;
// <summary>
// Total number of bits a variable of this type consumes in the flow vector.
public TypeInfo[] SubStructInfo;
readonly StructInfo struct_info;
- private static Dictionary<Type, TypeInfo> type_hash;
+ private static Dictionary<TypeSpec, TypeInfo> type_hash;
static TypeInfo ()
{
public static void Reset ()
{
- type_hash = new Dictionary<Type, TypeInfo> ();
- StructInfo.field_type_hash = new Dictionary<Type, StructInfo> ();
+ type_hash = new Dictionary<TypeSpec, TypeInfo> ();
+ StructInfo.field_type_hash = new Dictionary<TypeSpec, StructInfo> ();
}
- public static TypeInfo GetTypeInfo (Type type)
+ public static TypeInfo GetTypeInfo (TypeSpec type)
{
TypeInfo info;
if (type_hash.TryGetValue (type, out info))
public static TypeInfo GetTypeInfo (TypeContainer tc)
{
TypeInfo info;
- if (type_hash.TryGetValue (tc.TypeBuilder, out info))
+ if (type_hash.TryGetValue (tc.Definition, out info))
return info;
info = new TypeInfo (tc);
- type_hash.Add (tc.TypeBuilder, info);
+ type_hash.Add (tc.Definition, info);
return info;
}
- private TypeInfo (Type type)
+ private TypeInfo (TypeSpec type)
{
this.Type = type;
private TypeInfo (TypeContainer tc)
{
- this.Type = tc.TypeBuilder;
+ this.Type = tc.Definition;
struct_info = StructInfo.GetStructInfo (tc);
if (struct_info != null) {
var field = struct_info.Fields [i];
if (!branching.IsFieldAssigned (vi, field.Name)) {
- FieldBase fb = TypeManager.GetField (field.MetaInfo);
- if (fb is Property.BackingField) {
+ if (field.MemberDefinition is Property.BackingField) {
ec.Report.Error (843, loc,
"An automatically implemented property `{0}' must be fully assigned before control leaves the constructor. Consider calling default contructor",
- fb.GetSignatureForError ());
+ field.GetSignatureForError ());
} else {
ec.Report.Error (171, loc,
"Field `{0}' must be fully assigned before control leaves the constructor",
- TypeManager.GetFullNameSignature (field.MetaInfo));
+ field.GetSignatureForError ());
}
ok = false;
}
}
class StructInfo {
- public readonly Type Type;
+ public readonly TypeSpec Type;
public readonly FieldSpec[] Fields;
public readonly TypeInfo[] StructFields;
public readonly int Count;
public readonly int TotalLength;
public readonly bool HasStructFields;
- public static Dictionary<Type, StructInfo> field_type_hash;
+ public static Dictionary<TypeSpec, StructInfo> field_type_hash;
private Dictionary<string, TypeInfo> struct_field_hash;
private Dictionary<string, int> field_hash;
// Private constructor. To save memory usage, we only need to create one instance
// of this class per struct type.
- private StructInfo (Type type)
+ private StructInfo (TypeSpec type)
{
this.Type = type;
field_type_hash.Add (type, this);
- if (TypeManager.IsBeingCompiled (type)) {
- TypeContainer tc = TypeManager.LookupTypeContainer (TypeManager.DropGenericTypeArguments (type));
-
- var public_fields = new List<FieldSpec> ();
- var non_public_fields = new List<FieldSpec> ();
-
- //
- // TODO: tc != null is needed because FixedBuffers are not cached
- //
- if (tc != null) {
- var fields = tc.Fields;
-
- if (fields != null) {
- foreach (FieldBase field in fields) {
- if ((field.ModFlags & Modifiers.STATIC) != 0)
- continue;
- if ((field.ModFlags & Modifiers.PUBLIC) != 0)
- public_fields.Add (field.Spec);
- else
- non_public_fields.Add (field.Spec);
- }
- }
- }
+ TypeContainer tc = type.MemberDefinition as TypeContainer;
- CountPublic = public_fields.Count;
- CountNonPublic = non_public_fields.Count;
- Count = CountPublic + CountNonPublic;
+ var public_fields = new List<FieldSpec> ();
+ var non_public_fields = new List<FieldSpec> ();
- Fields = new FieldSpec [Count];
- public_fields.CopyTo (Fields, 0);
- non_public_fields.CopyTo (Fields, CountPublic);
- } else if (type is GenericTypeParameterBuilder) {
- CountPublic = CountNonPublic = Count = 0;
-
- Fields = new FieldSpec [0];
- } else {
- FieldInfo[] public_fields = type.GetFields (
- BindingFlags.Instance|BindingFlags.Public);
- FieldInfo[] non_public_fields = type.GetFields (
- BindingFlags.Instance|BindingFlags.NonPublic);
+ if (tc != null) {
+ var fields = tc.Fields;
- CountPublic = public_fields.Length;
- CountNonPublic = non_public_fields.Length;
- Count = CountPublic + CountNonPublic;
+ if (fields != null) {
+ foreach (FieldBase field in fields) {
+ if ((field.ModFlags & Modifiers.STATIC) != 0)
+ continue;
+ if ((field.ModFlags & Modifiers.PUBLIC) != 0)
+ public_fields.Add (field.Spec);
+ else
+ non_public_fields.Add (field.Spec);
+ }
+ }
+ }
- Fields = new FieldSpec [Count];
- for (int i = 0; i < CountPublic; ++i)
- Fields [i] = Import.CreateField (public_fields[i]);
+ CountPublic = public_fields.Count;
+ CountNonPublic = non_public_fields.Count;
+ Count = CountPublic + CountNonPublic;
- for (int i = 0; i < CountNonPublic; ++i)
- Fields [i + CountPublic] = Import.CreateField (non_public_fields[i]);
- }
+ Fields = new FieldSpec[Count];
+ public_fields.CopyTo (Fields, 0);
+ non_public_fields.CopyTo (Fields, CountPublic);
struct_field_hash = new Dictionary<string, TypeInfo> ();
field_hash = new Dictionary<string, int> ();
for (int i = 0; i < Count; i++) {
var field = Fields [i];
- sinfo [i] = GetStructInfo (field.FieldType);
+ sinfo [i] = GetStructInfo (field.MemberType);
if (sinfo [i] == null)
field_hash.Add (field.Name, ++Length);
else if (sinfo [i].InTransit) {
- RootContext.ToplevelTypes.Compiler.Report.Error (523, String.Format (
- "Struct member `{0}.{1}' of type `{2}' causes " +
- "a cycle in the structure layout",
- type, field.Name, sinfo [i].Type));
sinfo [i] = null;
return;
}
return null;
}
- public static StructInfo GetStructInfo (Type type)
+ public static StructInfo GetStructInfo (TypeSpec type)
{
if (!TypeManager.IsValueType (type) || TypeManager.IsEnumType (type) ||
TypeManager.IsBuiltinType (type))
public static StructInfo GetStructInfo (TypeContainer tc)
{
StructInfo info;
- if (field_type_hash.TryGetValue (tc.TypeBuilder, out info))
+ if (field_type_hash.TryGetValue (tc.Definition, out info))
return info;
- return new StructInfo (tc.TypeBuilder);
+ return new StructInfo (tc.Definition);
}
}
}
get { return is_ever_assigned; }
}
- protected VariableInfo (string name, Type type, int offset)
+ protected VariableInfo (string name, TypeSpec type, int offset)
{
this.Name = name;
this.Offset = offset;
using System.Globalization;
using System.Collections.Generic;
using System.Text;
+using System.Linq;
namespace Mono.CSharp {
-
- /// <summary>
- /// Abstract base class for type parameter constraints.
- /// The type parameter can come from a generic type definition or from reflection.
- /// </summary>
- public abstract class GenericConstraints {
- public abstract GenericParameterAttributes Attributes {
- get;
- }
-
- public bool HasConstructorConstraint {
- get { return (Attributes & GenericParameterAttributes.DefaultConstructorConstraint) != 0; }
- }
-
- public bool HasReferenceTypeConstraint {
- get { return (Attributes & GenericParameterAttributes.ReferenceTypeConstraint) != 0; }
- }
-
- public bool HasValueTypeConstraint {
- get { return (Attributes & GenericParameterAttributes.NotNullableValueTypeConstraint) != 0; }
- }
-
- public virtual bool HasClassConstraint {
- get { return ClassConstraint != null; }
- }
-
- public abstract Type ClassConstraint {
- get;
- }
-
- public abstract Type[] InterfaceConstraints {
- get;
- }
-
- public abstract Type EffectiveBaseClass {
- get;
- }
-
- // <summary>
- // Returns whether the type parameter is "known to be a reference type".
- // </summary>
- public virtual bool IsReferenceType {
- get {
- if (HasReferenceTypeConstraint)
- return true;
- if (HasValueTypeConstraint)
- return false;
-
- if (ClassConstraint != null) {
- if (ClassConstraint.IsValueType)
- return false;
-
- if (ClassConstraint != TypeManager.object_type)
- return true;
- }
-
- foreach (Type t in InterfaceConstraints) {
- if (!t.IsGenericParameter)
- continue;
-
- GenericConstraints gc = TypeManager.GetTypeParameterConstraints (t);
- if ((gc != null) && gc.IsReferenceType)
- return true;
- }
-
- return false;
- }
- }
-
- // <summary>
- // Returns whether the type parameter is "known to be a value type".
- // </summary>
- public virtual bool IsValueType {
- get {
- if (HasValueTypeConstraint)
- return true;
- if (HasReferenceTypeConstraint)
- return false;
-
- if (ClassConstraint != null) {
- if (!TypeManager.IsValueType (ClassConstraint))
- return false;
-
- if (ClassConstraint != TypeManager.value_type)
- return true;
- }
-
- foreach (Type t in InterfaceConstraints) {
- if (!t.IsGenericParameter)
- continue;
-
- GenericConstraints gc = TypeManager.GetTypeParameterConstraints (t);
- if ((gc != null) && gc.IsValueType)
- return true;
- }
-
- return false;
- }
- }
- }
-
- public class ReflectionConstraints : GenericConstraints
- {
- GenericParameterAttributes attrs;
- Type base_type;
- Type class_constraint;
- Type[] iface_constraints;
-
- public static GenericConstraints GetConstraints (Type t)
- {
- Type[] constraints = t.GetGenericParameterConstraints ();
- GenericParameterAttributes attrs = t.GenericParameterAttributes;
- if (constraints.Length == 0 && attrs == GenericParameterAttributes.None)
- return null;
- return new ReflectionConstraints (t.Name, constraints, attrs);
- }
-
- private ReflectionConstraints (string name, Type[] constraints, GenericParameterAttributes attrs)
- {
- this.attrs = attrs;
-
- int interface_constraints_pos = 0;
- if ((attrs & GenericParameterAttributes.NotNullableValueTypeConstraint) != 0) {
- base_type = TypeManager.value_type;
- interface_constraints_pos = 1;
- } else if ((attrs & GenericParameterAttributes.ReferenceTypeConstraint) != 0) {
- if (constraints.Length > 0 && constraints[0].IsClass) {
- class_constraint = base_type = constraints[0];
- interface_constraints_pos = 1;
- } else {
- base_type = TypeManager.object_type;
- }
- } else {
- base_type = TypeManager.object_type;
- }
-
- if (constraints.Length > interface_constraints_pos) {
- if (interface_constraints_pos == 0) {
- iface_constraints = constraints;
- } else {
- iface_constraints = new Type[constraints.Length - interface_constraints_pos];
- Array.Copy (constraints, interface_constraints_pos, iface_constraints, 0, iface_constraints.Length);
- }
- } else {
- iface_constraints = Type.EmptyTypes;
- }
- }
-
- public override GenericParameterAttributes Attributes
- {
- get { return attrs; }
- }
-
- public override Type ClassConstraint
- {
- get { return class_constraint; }
- }
-
- public override Type EffectiveBaseClass
- {
- get { return base_type; }
- }
-
- public override Type[] InterfaceConstraints
- {
- get { return iface_constraints; }
- }
- }
-
public enum Variance
{
//
//
// A set of parsed constraints for a type parameter
//
- public class Constraints : GenericConstraints
+ public class Constraints
{
SimpleMemberName tparam;
List<FullNamedExpression> constraints;
Location loc;
- GenericParameterAttributes attrs;
- TypeExpr class_constraint;
- List<TypeExpr> iface_constraints;
- List<TypeExpr> type_param_constraints;
- int num_constraints;
- Type class_constraint_type;
- Type[] iface_constraint_types;
- Type effective_base_type;
bool resolved;
- bool resolved_types;
+ bool resolving;
- //
- // name is the identifier, constraints is an arraylist of
- // Expressions (with types) or `true' for the constructor constraint.
- //
public Constraints (SimpleMemberName tparam, List<FullNamedExpression> constraints, Location loc)
{
this.tparam = tparam;
#region Properties
+ public Location Location {
+ get {
+ return loc;
+ }
+ }
+
public SimpleMemberName TypeParameter {
get {
return tparam;
#endregion
- public Constraints Clone ()
+ bool CheckConflictingInheritedConstraint (TypeSpec ba, TypeSpec bb, IMemberContext context, Location loc)
{
- return new Constraints (tparam, constraints, loc);
+ if (!TypeManager.IsSubclassOf (ba, bb) && !TypeManager.IsSubclassOf (bb, ba)) {
+ context.Compiler.Report.Error (455, loc,
+ "Type parameter `{0}' inherits conflicting constraints `{1}' and `{2}'",
+ tparam.Value,
+ ba.GetSignatureForError (), bb.GetSignatureForError ());
+ return false;
+ }
+
+ return true;
}
- /// <summary>
- /// Resolve the constraints - but only resolve things into Expression's, not
- /// into actual types.
- /// </summary>
- public bool Resolve (MemberCore ec, TypeParameter tp, Report Report)
+ public void CheckGenericConstraints (IMemberContext context)
+ {
+ foreach (var c in constraints) {
+ var ge = c as GenericTypeExpr;
+ if (ge != null)
+ ge.CheckConstraints (context);
+ }
+ }
+
+ //
+ // Resolve the constraints types with only possible early checks, return
+ // value `false' is reserved for recursive failure
+ //
+ public bool Resolve (IMemberContext context, TypeParameter tp)
{
if (resolved)
return true;
- if (ec == null)
+ if (resolving)
return false;
- iface_constraints = new List<TypeExpr> (2); // TODO: Too expensive allocation
- type_param_constraints = new List<TypeExpr> ();
+ resolving = true;
+ var spec = tp.Type;
+ List<TypeParameterSpec> tparam_types = null;
+ bool iface_found = false;
- foreach (var obj in constraints) {
+ spec.BaseType = TypeManager.object_type;
- if (obj is SpecialContraintExpr) {
- SpecialConstraint sc = ((SpecialContraintExpr) obj).Constraint;
+ for (int i = 0; i < constraints.Count; ++i) {
+ var constraint = constraints[i];
- if (sc == SpecialConstraint.Constructor) {
- if (!HasValueTypeConstraint) {
- attrs |= GenericParameterAttributes.DefaultConstructorConstraint;
- continue;
- }
- }
+ if (constraint is SpecialContraintExpr) {
+ spec.SpecialConstraint |= ((SpecialContraintExpr) constraint).Constraint;
+ if (spec.HasSpecialStruct)
+ spec.BaseType = TypeManager.value_type;
- if (sc == SpecialConstraint.Class)
- attrs |= GenericParameterAttributes.ReferenceTypeConstraint;
- else
- attrs |= GenericParameterAttributes.NotNullableValueTypeConstraint;
+ // Set to null as it does not have a type
+ constraints[i] = null;
continue;
}
- int errors = Report.Errors;
- FullNamedExpression fn = obj.ResolveAsTypeStep (ec, false);
-
- if (fn == null) {
- if (errors != Report.Errors)
- return false;
+ var type_expr = constraints[i] = constraint.ResolveAsTypeTerminal (context, false);
+ if (type_expr == null)
+ continue;
- NamespaceEntry.Error_NamespaceNotFound (loc, obj.GetSignatureForError (), Report);
- return false;
+ var gexpr = type_expr as GenericTypeExpr;
+ if (gexpr != null && gexpr.HasDynamicArguments ()) {
+ context.Compiler.Report.Error (1968, constraint.Location,
+ "A constraint cannot be the dynamic type `{0}'", gexpr.GetSignatureForError ());
+ continue;
}
- TypeExpr expr;
- GenericTypeExpr cexpr = fn as GenericTypeExpr;
- if (cexpr != null) {
- expr = cexpr.ResolveAsBaseTerminal (ec, false);
- if (expr != null && cexpr.HasDynamicArguments ()) {
- Report.Error (1968, cexpr.Location,
- "A constraint cannot be the dynamic type `{0}'",
- cexpr.GetSignatureForError ());
- expr = null;
- }
- } else
- expr = ((Expression) obj).ResolveAsTypeTerminal (ec, false);
-
- if ((expr == null) || (expr.Type == null))
- return false;
+ var type = type_expr.Type;
- if (TypeManager.IsGenericParameter (expr.Type))
- type_param_constraints.Add (expr);
- else if (expr.IsInterface)
- iface_constraints.Add (expr);
- else if (class_constraint != null || iface_constraints.Count != 0) {
- Report.Error (406, loc,
- "The class type constraint `{0}' must be listed before any other constraints. Consider moving type constraint to the beginning of the constraint list",
- expr.GetSignatureForError ());
- return false;
- } else if (HasReferenceTypeConstraint || HasValueTypeConstraint) {
- Report.Error (450, loc, "`{0}': cannot specify both " +
- "a constraint class and the `class' " +
- "or `struct' constraint", expr.GetSignatureForError ());
- return false;
- } else
- class_constraint = expr;
+ if (!context.CurrentMemberDefinition.IsAccessibleAs (type)) {
+ context.Compiler.Report.SymbolRelatedToPreviousError (type);
+ context.Compiler.Report.Error (703, loc,
+ "Inconsistent accessibility: constraint type `{0}' is less accessible than `{1}'",
+ type.GetSignatureForError (), context.GetSignatureForError ());
+ }
+ if (type.IsInterface) {
+ if (!spec.AddInterface (type)) {
+ context.Compiler.Report.Error (405, constraint.Location,
+ "Duplicate constraint `{0}' for type parameter `{1}'", type.GetSignatureForError (), tparam.Value);
+ }
- //
- // Checks whether each generic method parameter constraint type
- // is valid with respect to T
- //
- if (tp != null && tp.Type.DeclaringMethod != null) {
- TypeManager.CheckTypeVariance (expr.Type, Variance.Contravariant, ec as MemberCore);
+ iface_found = true;
+ continue;
}
- if (!ec.IsAccessibleAs (fn.Type)) {
- Report.SymbolRelatedToPreviousError (fn.Type);
- Report.Error (703, loc,
- "Inconsistent accessibility: constraint type `{0}' is less accessible than `{1}'",
- fn.GetSignatureForError (), ec.GetSignatureForError ());
- }
- num_constraints++;
- }
+ var constraint_tp = type as TypeParameterSpec;
+ if (constraint_tp != null) {
+ if (tparam_types == null) {
+ tparam_types = new List<TypeParameterSpec> (2);
+ } else if (tparam_types.Contains (constraint_tp)) {
+ context.Compiler.Report.Error (405, constraint.Location,
+ "Duplicate constraint `{0}' for type parameter `{1}'", type.GetSignatureForError (), tparam.Value);
+ continue;
+ }
+
+ //
+ // Checks whether each generic method parameter constraint type
+ // is valid with respect to T
+ //
+ if (tp.IsMethodTypeParameter) {
+ TypeManager.CheckTypeVariance (type, Variance.Contravariant, context);
+ }
- var list = new List<Type> ();
- foreach (TypeExpr iface_constraint in iface_constraints) {
- foreach (Type type in list) {
- if (!type.Equals (iface_constraint.Type))
+ var tp_def = constraint_tp.MemberDefinition as TypeParameter;
+ if (tp_def != null && !tp_def.ResolveConstraints (context)) {
+ context.Compiler.Report.Error (454, constraint.Location,
+ "Circular constraint dependency involving `{0}' and `{1}'",
+ constraint_tp.GetSignatureForError (), tp.GetSignatureForError ());
continue;
+ }
- Report.Error (405, loc,
- "Duplicate constraint `{0}' for type " +
- "parameter `{1}'.", iface_constraint.GetSignatureForError (),
- tparam.Value);
- return false;
- }
+ //
+ // Checks whether there are no conflicts between type parameter constraints
+ //
+ // class Foo<T, U>
+ // where T : A
+ // where U : B, T
+ //
+ // A and B are not convertible and only 1 class constraint is allowed
+ //
+ if (constraint_tp.HasTypeConstraint) {
+ if (spec.HasTypeConstraint || spec.HasSpecialStruct) {
+ if (!CheckConflictingInheritedConstraint (spec.BaseType, constraint_tp.BaseType, context, constraint.Location))
+ continue;
+ } else {
+ for (int ii = 0; ii < tparam_types.Count; ++ii) {
+ if (!tparam_types[ii].HasTypeConstraint)
+ continue;
- list.Add (iface_constraint.Type);
- }
+ if (!CheckConflictingInheritedConstraint (tparam_types[ii].BaseType, constraint_tp.BaseType, context, constraint.Location))
+ break;
+ }
+ }
+ }
- foreach (TypeExpr expr in type_param_constraints) {
- foreach (Type type in list) {
- if (!type.Equals (expr.Type))
+ if (constraint_tp.HasSpecialStruct) {
+ context.Compiler.Report.Error (456, constraint.Location,
+ "Type parameter `{0}' has the `struct' constraint, so it cannot be used as a constraint for `{1}'",
+ constraint_tp.GetSignatureForError (), tp.GetSignatureForError ());
continue;
+ }
- Report.Error (405, loc,
- "Duplicate constraint `{0}' for type " +
- "parameter `{1}'.", expr.GetSignatureForError (), tparam.Value);
- return false;
+ tparam_types.Add (constraint_tp);
+ continue;
}
- list.Add (expr.Type);
- }
-
- iface_constraint_types = new Type [list.Count];
- list.CopyTo (iface_constraint_types, 0);
+ if (iface_found || spec.HasTypeConstraint) {
+ context.Compiler.Report.Error (406, constraint.Location,
+ "The class type constraint `{0}' must be listed before any other constraints. Consider moving type constraint to the beginning of the constraint list",
+ type.GetSignatureForError ());
+ }
- if (class_constraint != null) {
- class_constraint_type = class_constraint.Type;
- if (class_constraint_type == null)
- return false;
+ if (spec.HasSpecialStruct || spec.HasSpecialClass) {
+ context.Compiler.Report.Error (450, type_expr.Location,
+ "`{0}': cannot specify both a constraint class and the `class' or `struct' constraint",
+ type.GetSignatureForError ());
+ }
- if (class_constraint_type.IsSealed) {
- if (class_constraint_type.IsAbstract)
- {
- Report.Error (717, loc, "`{0}' is not a valid constraint. Static classes cannot be used as constraints",
- TypeManager.CSharpName (class_constraint_type));
- }
- else
- {
- Report.Error (701, loc, "`{0}' is not a valid constraint. A constraint must be an interface, " +
- "a non-sealed class or a type parameter", TypeManager.CSharpName(class_constraint_type));
- }
- return false;
+ if (type == InternalType.Dynamic) {
+ context.Compiler.Report.Error (1967, constraint.Location, "A constraint cannot be the dynamic type");
+ continue;
}
- if ((class_constraint_type == TypeManager.array_type) ||
- (class_constraint_type == TypeManager.delegate_type) ||
- (class_constraint_type == TypeManager.enum_type) ||
- (class_constraint_type == TypeManager.value_type) ||
- (class_constraint_type == TypeManager.object_type) ||
- class_constraint_type == TypeManager.multicast_delegate_type) {
- Report.Error (702, loc,
- "A constraint cannot be special class `{0}'",
- TypeManager.CSharpName (class_constraint_type));
- return false;
+ if (type.IsSealed || !type.IsClass) {
+ context.Compiler.Report.Error (701, loc,
+ "`{0}' is not a valid constraint. A constraint must be an interface, a non-sealed class or a type parameter",
+ TypeManager.CSharpName (type));
+ continue;
}
- if (TypeManager.IsDynamicType (class_constraint_type)) {
- Report.Error (1967, loc, "A constraint cannot be the dynamic type");
- return false;
+ if (type.IsStatic) {
+ context.Compiler.Report.Error (717, constraint.Location,
+ "`{0}' is not a valid constraint. Static classes cannot be used as constraints",
+ type.GetSignatureForError ());
+ } else if (type == TypeManager.array_type || type == TypeManager.delegate_type ||
+ type == TypeManager.enum_type || type == TypeManager.value_type ||
+ type == TypeManager.object_type || type == TypeManager.multicast_delegate_type) {
+ context.Compiler.Report.Error (702, constraint.Location,
+ "A constraint cannot be special class `{0}'", type.GetSignatureForError ());
+ continue;
}
- }
- if (class_constraint_type != null)
- effective_base_type = class_constraint_type;
- else if (HasValueTypeConstraint)
- effective_base_type = TypeManager.value_type;
- else
- effective_base_type = TypeManager.object_type;
+ spec.BaseType = type;
+ }
- if ((attrs & GenericParameterAttributes.NotNullableValueTypeConstraint) != 0)
- attrs |= GenericParameterAttributes.DefaultConstructorConstraint;
+ if (tparam_types != null)
+ spec.TypeArguments = tparam_types.ToArray ();
+ resolving = false;
resolved = true;
return true;
}
- bool CheckTypeParameterConstraints (Type tparam, ref TypeExpr prevConstraint, List<Type> seen, Report Report)
+ public void VerifyClsCompliance (Report report)
{
- seen.Add (tparam);
-
- Constraints constraints = TypeManager.LookupTypeParameter (tparam).Constraints;
- if (constraints == null)
- return true;
-
- if (constraints.HasValueTypeConstraint) {
- Report.Error (456, loc,
- "Type parameter `{0}' has the `struct' constraint, so it cannot be used as a constraint for `{1}'",
- tparam.Name, this.tparam.Value);
- return false;
- }
-
- //
- // Checks whether there are no conflicts between type parameter constraints
- //
- // class Foo<T, U>
- // where T : A
- // where U : A, B // A and B are not convertible
- //
- if (constraints.HasClassConstraint) {
- if (prevConstraint != null) {
- Type t2 = constraints.ClassConstraint;
- TypeExpr e2 = constraints.class_constraint;
-
- if (!Convert.ImplicitReferenceConversionExists (prevConstraint, t2) &&
- !Convert.ImplicitReferenceConversionExists (e2, prevConstraint.Type)) {
- Report.Error (455, loc,
- "Type parameter `{0}' inherits conflicting constraints `{1}' and `{2}'",
- this.tparam.Value, TypeManager.CSharpName (prevConstraint.Type), TypeManager.CSharpName (t2));
- return false;
- }
- }
-
- prevConstraint = constraints.class_constraint;
- }
-
- if (constraints.type_param_constraints == null)
- return true;
+ foreach (var c in constraints)
+ {
+ if (c == null)
+ continue;
- foreach (TypeExpr expr in constraints.type_param_constraints) {
- if (seen.Contains (expr.Type)) {
- Report.Error (454, loc, "Circular constraint " +
- "dependency involving `{0}' and `{1}'",
- tparam.Name, expr.GetSignatureForError ());
- return false;
+ if (!c.Type.IsCLSCompliant ()) {
+ report.SymbolRelatedToPreviousError (c.Type);
+ report.Warning (3024, 1, loc, "Constraint type `{0}' is not CLS-compliant",
+ c.Type.GetSignatureForError ());
}
-
- if (!CheckTypeParameterConstraints (expr.Type, ref prevConstraint, seen, Report))
- return false;
}
-
- return true;
}
+ }
- /// <summary>
- /// Resolve the constraints into actual types.
- /// </summary>
- public bool ResolveTypes (IMemberContext ec, Report r)
- {
- if (resolved_types)
- return true;
+ //
+ // A type parameter for a generic type or generic method definition
+ //
+ public class TypeParameter : MemberCore, ITypeDefinition
+ {
+ static readonly string[] attribute_target = new string [] { "type parameter" };
+
+ Constraints constraints;
+ GenericTypeParameterBuilder builder;
+// Variance variance;
+ TypeParameterSpec spec;
- resolved_types = true;
+ public TypeParameter (DeclSpace parent, int index, MemberName name, Constraints constraints, Attributes attrs, Variance variance)
+ : base (parent, name, attrs)
+ {
+ this.constraints = constraints;
+// this.variance = variance;
+ this.spec = new TypeParameterSpec (null, index, this, SpecialConstraint.None, variance, null);
+ }
- foreach (object obj in constraints) {
- GenericTypeExpr cexpr = obj as GenericTypeExpr;
- if (cexpr == null)
- continue;
+ #region Properties
- if (!cexpr.CheckConstraints (ec))
- return false;
+ public override AttributeTargets AttributeTargets {
+ get {
+ return AttributeTargets.GenericParameter;
}
+ }
- if (type_param_constraints.Count != 0) {
- var seen = new List<Type> ();
- TypeExpr prev_constraint = class_constraint;
- foreach (TypeExpr expr in type_param_constraints) {
- if (!CheckTypeParameterConstraints (expr.Type, ref prev_constraint, seen, r))
- return false;
- seen.Clear ();
- }
+ public override string DocCommentHeader {
+ get {
+ throw new InvalidOperationException (
+ "Unexpected attempt to get doc comment from " + this.GetType ());
}
+ }
- for (int i = 0; i < iface_constraints.Count; ++i) {
- TypeExpr iface_constraint = (TypeExpr) iface_constraints [i];
- iface_constraint = iface_constraint.ResolveAsTypeTerminal (ec, false);
- if (iface_constraint == null)
- return false;
- iface_constraints [i] = iface_constraint;
+ public bool IsMethodTypeParameter {
+ get {
+ return spec.IsMethodOwned;
}
+ }
- if (class_constraint != null) {
- class_constraint = class_constraint.ResolveAsTypeTerminal (ec, false);
- if (class_constraint == null)
- return false;
+ public string Namespace {
+ get {
+ return null;
}
-
- return true;
}
- public override GenericParameterAttributes Attributes {
- get { return attrs; }
+ public TypeParameterSpec Type {
+ get {
+ return spec;
+ }
}
- public override bool HasClassConstraint {
- get { return class_constraint != null; }
+ public int TypeParametersCount {
+ get {
+ return 0;
+ }
}
- public override Type ClassConstraint {
- get { return class_constraint_type; }
+ public TypeParameterSpec[] TypeParameters {
+ get {
+ return null;
+ }
}
- public override Type[] InterfaceConstraints {
- get { return iface_constraint_types; }
+ public override string[] ValidAttributeTargets {
+ get {
+ return attribute_target;
+ }
}
- public override Type EffectiveBaseClass {
- get { return effective_base_type; }
+ public Variance Variance {
+ get {
+ return spec.Variance;
+ }
}
- public bool IsSubclassOf (Type t)
+ #endregion
+
+ //
+ // This is called for each part of a partial generic type definition.
+ //
+ // If partial type parameters constraints are not null and we don't
+ // already have constraints they become our constraints. If we already
+ // have constraints, we must check that they're the same.
+ //
+ public bool AddPartialConstraints (TypeContainer part, TypeParameter tp)
{
- if ((class_constraint_type != null) &&
- class_constraint_type.IsSubclassOf (t))
+ if (builder == null)
+ throw new InvalidOperationException ();
+
+ var new_constraints = tp.constraints;
+ if (new_constraints == null)
return true;
- if (iface_constraint_types == null)
+ // TODO: could create spec only
+ //tp.Define (null, -1, part.Definition);
+ tp.spec.DeclaringType = part.Definition;
+ if (!tp.ResolveConstraints (part))
return false;
- foreach (Type iface in iface_constraint_types) {
- if (TypeManager.IsSubclassOf (iface, t))
- return true;
- }
+ if (constraints != null)
+ return spec.HasSameConstraintsDefinition (tp.Type);
- return false;
+ constraints = new_constraints;
+ return true;
}
- public Location Location {
- get {
- return loc;
- }
+ public override void ApplyAttributeBuilder (Attribute a, MethodSpec ctor, byte[] cdata, PredefinedAttributes pa)
+ {
+ builder.SetCustomAttribute ((ConstructorInfo) ctor.GetMetaInfo (), cdata);
}
- /// <summary>
- /// This is used when we're implementing a generic interface method.
- /// Each method type parameter in implementing method must have the same
- /// constraints than the corresponding type parameter in the interface
- /// method. To do that, we're called on each of the implementing method's
- /// type parameters.
- /// </summary>
- public bool AreEqual (GenericConstraints gc)
+ public void CheckGenericConstraints ()
{
- if (gc.Attributes != attrs)
- return false;
-
- if (HasClassConstraint != gc.HasClassConstraint)
- return false;
- if (HasClassConstraint && !TypeManager.IsEqual (gc.ClassConstraint, ClassConstraint))
- return false;
-
- int gc_icount = gc.InterfaceConstraints != null ?
- gc.InterfaceConstraints.Length : 0;
- int icount = InterfaceConstraints != null ?
- InterfaceConstraints.Length : 0;
-
- if (gc_icount != icount)
- return false;
+ if (constraints != null)
+ constraints.CheckGenericConstraints (this);
+ }
- for (int i = 0; i < gc.InterfaceConstraints.Length; ++i) {
- Type iface = gc.InterfaceConstraints [i];
- if (iface.IsGenericType)
- iface = iface.GetGenericTypeDefinition ();
-
- bool ok = false;
- for (int ii = 0; ii < InterfaceConstraints.Length; ii++) {
- Type check = InterfaceConstraints [ii];
- if (check.IsGenericType)
- check = check.GetGenericTypeDefinition ();
-
- if (TypeManager.IsEqual (iface, check)) {
- ok = true;
- break;
- }
+ public TypeParameter CreateHoistedCopy (TypeSpec declaringType)
+ {
+ return new TypeParameter (Parent, spec.DeclaredPosition, MemberName, constraints, null, spec.Variance) {
+ spec = new TypeParameterSpec (declaringType, spec.DeclaredPosition, spec.MemberDefinition, spec.SpecialConstraint, spec.Variance, null) {
+ BaseType = spec.BaseType,
+ InterfacesDefined = spec.InterfacesDefined,
+ TypeArguments = spec.TypeArguments
}
+ };
+ }
- if (!ok)
- return false;
- }
-
+ public override bool Define ()
+ {
return true;
}
- public void VerifyClsCompliance (Report r)
+ //
+ // This is the first method which is called during the resolving
+ // process; we're called immediately after creating the type parameters
+ // with SRE (by calling `DefineGenericParameters()' on the TypeBuilder /
+ // MethodBuilder).
+ //
+ public void Define (GenericTypeParameterBuilder type, TypeSpec declaringType)
{
- if (class_constraint_type != null && !AttributeTester.IsClsCompliant (class_constraint_type))
- Warning_ConstrainIsNotClsCompliant (class_constraint_type, class_constraint.Location, r);
+ if (builder != null)
+ throw new InternalErrorException ();
- if (iface_constraint_types != null) {
- for (int i = 0; i < iface_constraint_types.Length; ++i) {
- if (!AttributeTester.IsClsCompliant (iface_constraint_types [i]))
- Warning_ConstrainIsNotClsCompliant (iface_constraint_types [i],
- ((TypeExpr)iface_constraints [i]).Location, r);
- }
- }
+ this.builder = type;
+ spec.DeclaringType = declaringType;
+ spec.SetMetaInfo (type);
}
- void Warning_ConstrainIsNotClsCompliant (Type t, Location loc, Report Report)
+ public void EmitConstraints (GenericTypeParameterBuilder builder)
{
- Report.SymbolRelatedToPreviousError (t);
- Report.Warning (3024, 1, loc, "Constraint type `{0}' is not CLS-compliant",
- TypeManager.CSharpName (t));
- }
- }
-
- /// <summary>
- /// A type parameter from a generic type definition.
- /// </summary>
- public class TypeParameter : MemberCore, IMemberContainer
- {
- static readonly string[] attribute_target = new string [] { "type parameter" };
-
- DeclSpace decl;
- GenericConstraints gc;
- Constraints constraints;
- GenericTypeParameterBuilder type;
- MemberCache member_cache;
- Variance variance;
+ var attr = GenericParameterAttributes.None;
+ if (spec.Variance == Variance.Contravariant)
+ attr |= GenericParameterAttributes.Contravariant;
+ else if (spec.Variance == Variance.Covariant)
+ attr |= GenericParameterAttributes.Covariant;
- public TypeParameter (DeclSpace parent, DeclSpace decl, string name,
- Constraints constraints, Attributes attrs, Variance variance, Location loc)
- : base (parent, new MemberName (name, loc), attrs)
- {
- this.decl = decl;
- this.constraints = constraints;
- this.variance = variance;
- }
+ if (spec.HasSpecialClass)
+ attr |= GenericParameterAttributes.ReferenceTypeConstraint;
+ else if (spec.HasSpecialStruct)
+ attr |= GenericParameterAttributes.NotNullableValueTypeConstraint | GenericParameterAttributes.DefaultConstructorConstraint;
- public GenericConstraints GenericConstraints {
- get { return gc != null ? gc : constraints; }
- }
+ if (spec.HasSpecialConstructor)
+ attr |= GenericParameterAttributes.DefaultConstructorConstraint;
- public Constraints Constraints {
- get { return constraints; }
- }
+ if (spec.BaseType != TypeManager.object_type)
+ builder.SetBaseTypeConstraint (spec.BaseType.GetMetaInfo ());
- public DeclSpace DeclSpace {
- get { return decl; }
- }
+ if (spec.InterfacesDefined != null)
+ builder.SetInterfaceConstraints (spec.InterfacesDefined.Select (l => l.GetMetaInfo ()).ToArray ());
- public Variance Variance {
- get { return variance; }
- }
+ if (spec.TypeArguments != null)
+ builder.SetInterfaceConstraints (spec.TypeArguments.Select (l => l.GetMetaInfo ()).ToArray ());
- public Type Type {
- get { return type; }
+ builder.SetGenericParameterAttributes (attr);
}
- /// <summary>
- /// This is the first method which is called during the resolving
- /// process; we're called immediately after creating the type parameters
- /// with SRE (by calling `DefineGenericParameters()' on the TypeBuilder /
- /// MethodBuilder).
- ///
- /// We're either called from TypeContainer.DefineType() or from
- /// GenericMethod.Define() (called from Method.Define()).
- /// </summary>
- public void Define (GenericTypeParameterBuilder type)
+ public override void Emit ()
{
- if (this.type != null)
- throw new InvalidOperationException ();
+ EmitConstraints (builder);
- this.type = type;
- TypeManager.AddTypeParameter (type, this);
+ if (OptAttributes != null)
+ OptAttributes.Emit ();
+
+ base.Emit ();
}
public void ErrorInvalidVariance (IMemberContext mc, Variance expected)
{
-// TODO: Report.SymbolRelatedToPreviousError (mc);
+ Report.SymbolRelatedToPreviousError (mc.CurrentMemberDefinition);
string input_variance = Variance == Variance.Contravariant ? "contravariant" : "covariant";
string gtype_variance;
switch (expected) {
GetSignatureForError (), mc.GetSignatureForError (), input_variance, gtype_variance, parameters);
}
- /// <summary>
- /// This is the second method which is called during the resolving
- /// process - in case of class type parameters, we're called from
- /// TypeContainer.ResolveType() - after it resolved the class'es
- /// base class and interfaces. For method type parameters, we're
- /// called immediately after Define().
- ///
- /// We're just resolving the constraints into expressions here, we
- /// don't resolve them into actual types.
- ///
- /// Note that in the special case of partial generic classes, we may be
- /// called _before_ Define() and we may also be called multiple types.
- /// </summary>
- public bool Resolve (DeclSpace ds)
+ public TypeSpec GetAttributeCoClass ()
{
- if (constraints != null) {
- if (!constraints.Resolve (ds, this, Report)) {
- constraints = null;
- return false;
- }
- }
+ return null;
+ }
+
+ public string GetAttributeDefaultMember ()
+ {
+ throw new NotSupportedException ();
+ }
+
+ public AttributeUsageAttribute GetAttributeUsage (PredefinedAttribute pa)
+ {
+ throw new NotSupportedException ();
+ }
+
+ public override string GetSignatureForError ()
+ {
+ return MemberName.Name;
+ }
+
+ public MemberCache LoadMembers (TypeSpec declaringType)
+ {
+ throw new NotSupportedException ("Not supported for compiled definition");
+ }
+ //
+ // Resolves all type parameter constraints
+ //
+ public bool ResolveConstraints (IMemberContext context)
+ {
+ if (constraints != null)
+ return constraints.Resolve (context, this);
+
+ spec.BaseType = TypeManager.object_type;
return true;
}
- /// <summary>
- /// This is the third method which is called during the resolving
- /// process. We're called immediately after calling DefineConstraints()
- /// on all of the current class'es type parameters.
- ///
- /// Our job is to resolve the constraints to actual types.
- ///
- /// Note that we may have circular dependencies on type parameters - this
- /// is why Resolve() and ResolveType() are separate.
- /// </summary>
- public bool ResolveType (IMemberContext ec)
+ public static TypeParameter FindTypeParameter (TypeParameter[] tparams, string name)
{
- if (constraints != null) {
- if (!constraints.ResolveTypes (ec, Report)) {
- constraints = null;
- return false;
+ foreach (var tp in tparams) {
+ if (tp.Name == name)
+ return tp;
+ }
+
+ return null;
+ }
+
+ public override bool IsClsComplianceRequired ()
+ {
+ return false;
+ }
+
+ public new void VerifyClsCompliance ()
+ {
+ if (constraints != null)
+ constraints.VerifyClsCompliance (Report);
+ }
+ }
+
+ [System.Diagnostics.DebuggerDisplay ("{DisplayDebugInfo()}")]
+ public class TypeParameterSpec : TypeSpec
+ {
+ public static readonly new TypeParameterSpec[] EmptyTypes = new TypeParameterSpec[0];
+
+ Variance variance;
+ SpecialConstraint spec;
+ readonly int tp_pos;
+ TypeSpec[] targs;
+ TypeSpec[] ifaces_defined;
+
+ //
+ // Creates type owned type parameter
+ //
+ public TypeParameterSpec (TypeSpec declaringType, int index, ITypeDefinition definition, SpecialConstraint spec, Variance variance, Type info)
+ : base (MemberKind.TypeParameter, declaringType, definition, info, Modifiers.PUBLIC)
+ {
+ this.variance = variance;
+ this.spec = spec;
+ state &= ~StateFlags.Obsolete_Undetected;
+ tp_pos = index;
+ }
+
+ //
+ // Creates method owned type parameter
+ //
+ public TypeParameterSpec (int index, ITypeDefinition definition, SpecialConstraint spec, Variance variance, Type info)
+ : this (null, index, definition, spec, variance, info)
+ {
+ }
+
+ #region Properties
+
+ public int DeclaredPosition {
+ get {
+ return tp_pos;
+ }
+ }
+
+ public bool HasSpecialConstructor {
+ get {
+ return (spec & SpecialConstraint.Constructor) != 0;
+ }
+ }
+
+ public bool HasSpecialClass {
+ get {
+ return (spec & SpecialConstraint.Class) != 0;
+ }
+ }
+
+ public bool HasSpecialStruct {
+ get {
+ return (spec & SpecialConstraint.Struct) != 0;
+ }
+ }
+
+ public bool HasTypeConstraint {
+ get {
+ return BaseType != TypeManager.object_type && BaseType != TypeManager.value_type;
+ }
+ }
+
+ public override IList<TypeSpec> Interfaces {
+ get {
+ if ((state & StateFlags.InterfacesExpanded) == 0) {
+ if (ifaces != null) {
+ for (int i = 0; i < ifaces.Count; ++i ) {
+ var iface_type = ifaces[i];
+ if (iface_type.Interfaces != null) {
+ if (ifaces_defined == null)
+ ifaces_defined = ifaces.ToArray ();
+
+ for (int ii = 0; ii < iface_type.Interfaces.Count; ++ii) {
+ var ii_iface_type = iface_type.Interfaces [ii];
+
+ AddInterface (ii_iface_type);
+ }
+ }
+ }
+ }
+
+ if (ifaces_defined == null && ifaces != null)
+ ifaces_defined = ifaces.ToArray ();
+
+ state |= StateFlags.InterfacesExpanded;
}
+
+ return ifaces;
}
+ }
- return true;
+ //
+ // Unexpanded interfaces list
+ //
+ public TypeSpec[] InterfacesDefined {
+ get {
+ if (ifaces_defined == null && ifaces != null)
+ ifaces_defined = ifaces.ToArray ();
+
+ return ifaces_defined;
+ }
+ set {
+ ifaces_defined = value;
+ }
}
- /// <summary>
- /// This is the fourth and last method which is called during the resolving
- /// process. We're called after everything is fully resolved and actually
- /// register the constraints with SRE and the TypeManager.
- /// </summary>
- public bool DefineType (IMemberContext ec)
+ public bool IsConstrained {
+ get {
+ return spec != SpecialConstraint.None || ifaces != null || targs != null || HasTypeConstraint;
+ }
+ }
+
+ //
+ // Returns whether the type parameter is "known to be a reference type"
+ //
+ public bool IsReferenceType {
+ get {
+ return (spec & SpecialConstraint.Class) != 0 || HasTypeConstraint;
+ }
+ }
+
+ public bool IsValueType { // TODO: Do I need this ?
+ get {
+ // TODO MemberCache: probably wrong
+ return HasSpecialStruct;
+ }
+ }
+
+ public override string Name {
+ get {
+ return definition.Name;
+ }
+ }
+
+ public bool IsMethodOwned {
+ get {
+ return DeclaringType == null;
+ }
+ }
+
+ public SpecialConstraint SpecialConstraint {
+ get {
+ return spec;
+ }
+ set {
+ spec = value;
+ }
+ }
+
+ //
+ // Types used to inflate the generic type
+ //
+ public new TypeSpec[] TypeArguments {
+ get {
+ return targs;
+ }
+ set {
+ targs = value;
+ }
+ }
+
+ public Variance Variance {
+ get {
+ return variance;
+ }
+ }
+
+ #endregion
+
+ public string DisplayDebugInfo ()
{
- return DefineType (ec, null, null, false);
+ var s = GetSignatureForError ();
+ return IsMethodOwned ? s + "!!" : s + "!";
}
- /// <summary>
- /// This is the fith and last method which is called during the resolving
- /// process. We're called after everything is fully resolved and actually
- /// register the constraints with SRE and the TypeManager.
- ///
- /// The `builder', `implementing' and `is_override' arguments are only
- /// applicable to method type parameters.
- /// </summary>
- public bool DefineType (IMemberContext ec, MethodBuilder builder,
- MethodInfo implementing, bool is_override)
+ //
+ // Finds effective base class
+ //
+ public TypeSpec GetEffectiveBase ()
+ {
+ if (HasSpecialStruct) {
+ return TypeManager.value_type;
+ }
+
+ if (BaseType != null && targs == null)
+ return BaseType;
+
+ var types = targs;
+ if (HasTypeConstraint) {
+ Array.Resize (ref types, types.Length + 1);
+ types[types.Length - 1] = BaseType;
+ }
+
+ if (types != null)
+ return Convert.FindMostEncompassedType (types.Select (l => l.BaseType));
+
+ return TypeManager.object_type;
+ }
+
+ public override string GetSignatureForError ()
{
- if (!ResolveType (ec))
+ return Name;
+ }
+
+ //
+ // Constraints have to match by definition but not position, used by
+ // partial classes or methods
+ //
+ public bool HasSameConstraintsDefinition (TypeParameterSpec other)
+ {
+ if (spec != other.spec)
return false;
- if (implementing != null) {
- MethodBase mb = TypeManager.DropGenericMethodArguments (implementing);
+ if (BaseType != other.BaseType)
+ return false;
- int pos = type.GenericParameterPosition;
- Type mparam = mb.GetGenericArguments () [pos];
- GenericConstraints temp_gc = ReflectionConstraints.GetConstraints (mparam);
+ if (!TypeSpecComparer.Override.IsSame (InterfacesDefined, other.InterfacesDefined))
+ return false;
- if (temp_gc != null)
- gc = new InflatedConstraints (temp_gc, implementing.DeclaringType);
- else if (constraints != null)
- gc = new InflatedConstraints (constraints, implementing.DeclaringType);
+ if (!TypeSpecComparer.Override.IsSame (targs, other.targs))
+ return false;
- bool ok = true;
- if (constraints != null) {
- if (temp_gc == null)
- ok = false;
- else if (!constraints.AreEqual (gc))
- ok = false;
- } else {
- if (!is_override && (temp_gc != null))
- ok = false;
+ return true;
+ }
+
+ //
+ // Constraints have to match by using same set of types, used by
+ // implicit interface implementation
+ //
+ public bool HasSameConstraintsImplementation (TypeParameterSpec other)
+ {
+ if (spec != other.spec)
+ return false;
+
+ //
+ // It can be same base type or inflated type parameter
+ //
+ // interface I<T> { void Foo<U> where U : T; }
+ // class A : I<int> { void Foo<X> where X : int {} }
+ //
+ bool found;
+ if (BaseType != other.BaseType) {
+ if (other.targs == null)
+ return false;
+
+ found = false;
+ foreach (var otarg in other.targs) {
+ if (TypeSpecComparer.Override.IsEqual (BaseType, otarg)) {
+ found = true;
+ break;
+ }
}
- if (!ok) {
- Report.SymbolRelatedToPreviousError (implementing);
-
- Report.Error (
- 425, Location, "The constraints for type " +
- "parameter `{0}' of method `{1}' must match " +
- "the constraints for type parameter `{2}' " +
- "of interface method `{3}'. Consider using " +
- "an explicit interface implementation instead",
- Name, TypeManager.CSharpSignature (builder),
- TypeManager.CSharpName (mparam), TypeManager.CSharpSignature (mb));
+ if (!found)
return false;
+ }
+
+ // Check interfaces implementation -> definition
+ if (InterfacesDefined != null) {
+ foreach (var iface in InterfacesDefined) {
+ found = false;
+ if (other.InterfacesDefined != null) {
+ foreach (var oiface in other.InterfacesDefined) {
+ if (TypeSpecComparer.Override.IsEqual (iface, oiface)) {
+ found = true;
+ break;
+ }
+ }
+ }
+
+ if (found)
+ continue;
+
+ if (other.targs != null) {
+ foreach (var otarg in other.targs) {
+ if (TypeSpecComparer.Override.IsEqual (BaseType, otarg)) {
+ found = true;
+ break;
+ }
+ }
+ }
+
+ if (!found)
+ return false;
+ }
+ }
+
+ // Check interfaces implementation <- definition
+ if (other.InterfacesDefined != null) {
+ if (InterfacesDefined == null)
+ return false;
+
+ foreach (var oiface in other.InterfacesDefined) {
+ found = false;
+ foreach (var iface in InterfacesDefined) {
+ if (TypeSpecComparer.Override.IsEqual (iface, oiface)) {
+ found = true;
+ break;
+ }
+ }
+
+ if (!found)
+ return false;
}
- } else if (DeclSpace is CompilerGeneratedClass) {
- TypeParameter[] tparams = DeclSpace.TypeParameters;
- Type[] types = new Type [tparams.Length];
- for (int i = 0; i < tparams.Length; i++)
- types [i] = tparams [i].Type;
-
- if (constraints != null)
- gc = new InflatedConstraints (constraints, types);
- } else {
- gc = (GenericConstraints) constraints;
}
- SetConstraints (type);
+ // Check type parameters implementation -> definition
+ if (targs != null) {
+ if (other.targs == null)
+ return false;
+
+ foreach (var targ in targs) {
+ found = false;
+ foreach (var otarg in other.targs) {
+ if (TypeSpecComparer.Override.IsEqual (targ, otarg)) {
+ found = true;
+ break;
+ }
+ }
+
+ if (!found)
+ return false;
+ }
+ }
+
+ // Check type parameters implementation <- definition
+ if (other.targs != null) {
+ foreach (var otarg in other.targs) {
+ // Ignore inflated type arguments, were checked above
+ if (!otarg.IsGenericParameter)
+ continue;
+
+ if (targs == null)
+ return false;
+
+ found = false;
+ foreach (var targ in targs) {
+ if (TypeSpecComparer.Override.IsEqual (targ, otarg)) {
+ found = true;
+ break;
+ }
+ }
+
+ if (!found)
+ return false;
+ }
+ }
+
return true;
}
- public static TypeParameter FindTypeParameter (TypeParameter[] tparams, string name)
+ public static TypeParameterSpec[] InflateConstraints (TypeParameterInflator inflator, TypeParameterSpec[] tparams)
{
- foreach (var tp in tparams) {
- if (tp.Name == name)
- return tp;
+ TypeParameterSpec[] constraints = null;
+
+ for (int i = 0; i < tparams.Length; ++i) {
+ var tp = tparams[i];
+ if (tp.HasTypeConstraint || tp.Interfaces != null || tp.TypeArguments != null) {
+ if (constraints == null) {
+ constraints = new TypeParameterSpec[tparams.Length];
+ Array.Copy (tparams, constraints, constraints.Length);
+ }
+
+ constraints[i] = (TypeParameterSpec) constraints[i].InflateMember (inflator);
+ }
}
- return null;
+ if (constraints == null)
+ constraints = tparams;
+
+ return constraints;
}
- public void SetConstraints (GenericTypeParameterBuilder type)
+ public override MemberSpec InflateMember (TypeParameterInflator inflator)
{
- GenericParameterAttributes attr = GenericParameterAttributes.None;
- if (variance == Variance.Contravariant)
- attr |= GenericParameterAttributes.Contravariant;
- else if (variance == Variance.Covariant)
- attr |= GenericParameterAttributes.Covariant;
+ var tps = (TypeParameterSpec) MemberwiseClone ();
+ tps.BaseType = inflator.Inflate (BaseType);
+ if (ifaces != null) {
+ tps.ifaces = new TypeSpec[ifaces.Count];
+ for (int i = 0; i < ifaces.Count; ++i)
+ tps.ifaces[i] = inflator.Inflate (ifaces[i]);
+ }
+ if (targs != null) {
+ tps.targs = new TypeSpec[targs.Length];
+ for (int i = 0; i < targs.Length; ++i)
+ tps.targs[i] = inflator.Inflate (targs[i]);
+ }
- if (gc != null) {
- if (gc.HasClassConstraint || gc.HasValueTypeConstraint)
- type.SetBaseTypeConstraint (gc.EffectiveBaseClass);
+ return tps;
+ }
- attr |= gc.Attributes;
- type.SetInterfaceConstraints (gc.InterfaceConstraints);
- TypeManager.RegisterBuilder (type, gc.InterfaceConstraints);
+ //
+ // Populates type parameter members using type parameter constraints
+ // The trick here is to be called late enough but not too late to
+ // populate member cache with all members from other types
+ //
+ protected override void InitializeMemberCache (bool onlyTypes)
+ {
+ cache = new MemberCache ();
+ if (ifaces != null) {
+ foreach (var iface_type in Interfaces) {
+ cache.AddInterface (iface_type);
+ }
}
-
- type.SetGenericParameterAttributes (attr);
}
- /// <summary>
- /// This is called for each part of a partial generic type definition.
- ///
- /// If `new_constraints' is not null and we don't already have constraints,
- /// they become our constraints. If we already have constraints, we must
- /// check that they're the same.
- /// con
- /// </summary>
- public bool UpdateConstraints (MemberCore ec, Constraints new_constraints)
+ public override TypeSpec Mutate (TypeParameterMutator mutator)
{
- if (type == null)
- throw new InvalidOperationException ();
-
- if (new_constraints == null)
- return true;
-
- if (!new_constraints.Resolve (ec, this, Report))
- return false;
- if (!new_constraints.ResolveTypes (ec, Report))
- return false;
+ return mutator.Mutate (this);
+ }
+ }
- if (constraints != null)
- return constraints.AreEqual (new_constraints);
+ public struct TypeParameterInflator
+ {
+ readonly TypeSpec type;
+ readonly TypeParameterSpec[] tparams;
+ readonly TypeSpec[] targs;
- constraints = new_constraints;
- return true;
+ public TypeParameterInflator (TypeParameterInflator nested, TypeSpec type)
+ : this (type, nested.tparams, nested.targs)
+ {
}
- public override void Emit ()
+ public TypeParameterInflator (TypeSpec type, TypeParameterSpec[] tparams, TypeSpec[] targs)
{
- if (OptAttributes != null)
- OptAttributes.Emit ();
+ if (tparams.Length != targs.Length)
+ throw new ArgumentException ("Invalid arguments");
- base.Emit ();
+ this.tparams = tparams;
+ this.targs = targs;
+ this.type = type;
}
- public override string DocCommentHeader {
+ //
+ // Type parameters to inflate
+ //
+ public TypeParameterSpec[] TypeParameters {
get {
- throw new InvalidOperationException (
- "Unexpected attempt to get doc comment from " + this.GetType () + ".");
+ return tparams;
+ }
+ }
+
+ public TypeSpec Inflate (TypeSpec ts)
+ {
+ var tp = ts as TypeParameterSpec;
+ if (tp != null)
+ return Inflate (tp);
+
+ var ac = ts as ArrayContainer;
+ if (ac != null) {
+ var et = Inflate (ac.Element);
+ if (et != ac.Element)
+ return ArrayContainer.MakeType (et, ac.Rank);
+
+ return ac;
+ }
+
+ //
+ // When inflating a nested type, inflate its parent first
+ // in case it's using same type parameters (was inflated within the type)
+ //
+ if (ts.IsNested) {
+ var parent = Inflate (ts.DeclaringType);
+ if (ts.DeclaringType != parent) {
+ //
+ // Keep the inflated type arguments
+ //
+ var targs = ts.TypeArguments;
+
+ //
+ // Parent was inflated, find the same type on inflated type
+ // to use same cache for nested types on same generic parent
+ //
+ // TODO: Should use BindingRestriction.DeclaredOnly or GetMember
+ ts = MemberCache.FindNestedType (parent, ts.Name, targs.Length);
+
+ //
+ // Handle the tricky case where parent shares local type arguments
+ // which means inflating inflated type
+ //
+ // class Test<T> {
+ // public static Nested<T> Foo () { return null; }
+ //
+ // public class Nested<U> {}
+ // }
+ //
+ // return type of Test<string>.Foo() has to be Test<string>.Nested<string>
+ //
+ if (targs.Length > 0) {
+ var inflated_targs = new TypeSpec [targs.Length];
+ for (var i = 0; i < targs.Length; ++i)
+ inflated_targs[i] = Inflate (targs[i]);
+
+ ts = ts.MakeGenericType (inflated_targs);
+ }
+
+ return ts;
+ }
}
+
+ // Inflate generic type
+ if (ts.IsGeneric)
+ return InflateTypeParameters (ts);
+
+ return ts;
+ }
+
+ public TypeSpec Inflate (TypeParameterSpec tp)
+ {
+ for (int i = 0; i < tparams.Length; ++i)
+ if (tparams [i] == tp)
+ return targs[i];
+
+ // CECIL: This can happen when inflating nested types
+ // without type arguments specified
+ return tp;
}
//
- // MemberContainer
+ // Inflates generic types
//
+ TypeSpec InflateTypeParameters (TypeSpec type)
+ {
+ var targs = new TypeSpec[type.Arity];
+ var i = 0;
- public override bool Define ()
+ var gti = type as InflatedTypeSpec;
+
+ //
+ // Inflating using outside type arguments, var v = new Foo<int> (), class Foo<T> {}
+ //
+ if (gti != null) {
+ for (; i < targs.Length; ++i)
+ targs[i] = Inflate (gti.TypeArguments[i]);
+
+ return gti.GetDefinition ().MakeGenericType (targs);
+ }
+
+ //
+ // Inflating parent using inside type arguments, class Foo<T> { ITest<T> foo; }
+ //
+ var args = type.MemberDefinition.TypeParameters;
+ foreach (var ds_tp in args)
+ targs[i++] = Inflate (ds_tp);
+
+ return type.MakeGenericType (targs);
+ }
+
+ public TypeSpec TypeInstance {
+ get { return type; }
+ }
+ }
+
+ //
+ // Before emitting any code we have to change all MVAR references to VAR
+ // when the method is of generic type and has hoisted variables
+ //
+ public class TypeParameterMutator
+ {
+ TypeParameter[] mvar;
+ TypeParameter[] var;
+ Dictionary<TypeSpec, TypeSpec> mutated_typespec = new Dictionary<TypeSpec, TypeSpec> ();
+
+ public TypeParameterMutator (TypeParameter[] mvar, TypeParameter[] var)
{
- return true;
+ if (mvar.Length != var.Length)
+ throw new ArgumentException ();
+
+ this.mvar = mvar;
+ this.var = var;
}
- public override void ApplyAttributeBuilder (Attribute a, ConstructorInfo ctor, byte[] cdata, PredefinedAttributes pa)
+ public TypeSpec Mutate (TypeSpec ts)
{
- type.SetCustomAttribute (ctor, cdata);
+ TypeSpec value;
+ if (mutated_typespec.TryGetValue (ts, out value))
+ return value;
+
+ value = ts.Mutate (this);
+ mutated_typespec.Add (ts, value);
+ return value;
}
- public override AttributeTargets AttributeTargets {
- get {
- return AttributeTargets.GenericParameter;
+ public FieldInfo Mutate (FieldSpec fs)
+ {
+ // TODO:
+ return fs.GetMetaInfo ();
+ }
+
+ public TypeParameterSpec Mutate (TypeParameterSpec tp)
+ {
+ for (int i = 0; i < mvar.Length; ++i) {
+ if (mvar[i].Type == tp)
+ return var[i].Type;
+ }
+
+ return tp;
+ }
+
+ public TypeSpec[] Mutate (TypeSpec[] targs)
+ {
+ TypeSpec[] mutated = new TypeSpec[targs.Length];
+ bool changed = false;
+ for (int i = 0; i < targs.Length; ++i) {
+ mutated[i] = Mutate (targs[i]);
+ changed |= targs[i] != mutated[i];
}
+
+ return changed ? mutated : targs;
}
+ }
- public override string[] ValidAttributeTargets {
+ /// <summary>
+ /// A TypeExpr which already resolved to a type parameter.
+ /// </summary>
+ public class TypeParameterExpr : TypeExpr {
+
+ public TypeParameterExpr (TypeParameter type_parameter, Location loc)
+ {
+ this.type = type_parameter.Type;
+ this.eclass = ExprClass.TypeParameter;
+ this.loc = loc;
+ }
+
+ protected override TypeExpr DoResolveAsTypeStep (IMemberContext ec)
+ {
+ throw new NotSupportedException ();
+ }
+
+ public override FullNamedExpression ResolveAsTypeStep (IMemberContext ec, bool silent)
+ {
+ return this;
+ }
+
+ public override bool CheckAccessLevel (IMemberContext ds)
+ {
+ return true;
+ }
+ }
+
+ public class InflatedTypeSpec : TypeSpec
+ {
+ TypeSpec[] targs;
+ TypeParameterSpec[] constraints;
+ readonly TypeSpec open_type;
+
+ public InflatedTypeSpec (TypeSpec openType, TypeSpec declaringType, TypeSpec[] targs)
+ : base (openType.Kind, declaringType, openType.MemberDefinition, null, openType.Modifiers)
+ {
+ if (targs == null)
+ throw new ArgumentNullException ("targs");
+
+#if DEBUG
+ if (ID == 4937)
+ Console.WriteLine ("HIT");
+#endif
+
+// this.state = openType.state;
+ this.open_type = openType;
+ this.targs = targs;
+ }
+
+ #region Properties
+
+ public override TypeSpec BaseType {
get {
- return attribute_target;
+ if (cache == null || (state & StateFlags.PendingBaseTypeInflate) != 0)
+ InitializeMemberCache (true);
+
+ return base.BaseType;
}
}
//
- // IMemberContainer
+ // Inflated type parameters with constraints array, mapping with type arguments is based on index
//
+ public TypeParameterSpec[] Constraints {
+ get {
+ if (constraints == null) {
+ var inflator = new TypeParameterInflator (this, MemberDefinition.TypeParameters, targs);
+ constraints = TypeParameterSpec.InflateConstraints (inflator, MemberDefinition.TypeParameters);
+ }
- string IMemberContainer.Name {
- get { return Name; }
+ return constraints;
+ }
}
- MemberCache IMemberContainer.BaseCache {
+ public override IList<TypeSpec> Interfaces {
get {
- if (gc == null)
- return null;
-
- if (gc.EffectiveBaseClass.BaseType == null)
- return null;
+ if (cache == null)
+ InitializeMemberCache (true);
- return TypeManager.LookupMemberCache (gc.EffectiveBaseClass.BaseType);
+ return base.Interfaces;
}
}
- bool IMemberContainer.IsInterface {
- get { return false; }
- }
+ public override MemberCache MemberCacheTypes {
+ get {
+ if (cache == null)
+ InitializeMemberCache (true);
- MemberList IMemberContainer.GetMembers (MemberTypes mt, BindingFlags bf)
- {
- throw new NotSupportedException ();
+ return cache;
+ }
}
- public MemberCache MemberCache {
+ //
+ // Types used to inflate the generic type
+ //
+ public override TypeSpec[] TypeArguments {
get {
- if (member_cache != null)
- return member_cache;
-
- if (gc == null)
- return null;
-
- Type[] ifaces = TypeManager.ExpandInterfaces (gc.InterfaceConstraints);
- member_cache = new MemberCache (this, gc.EffectiveBaseClass, ifaces);
-
- return member_cache;
+ return targs;
}
}
- public MemberList FindMembers (MemberTypes mt, BindingFlags bf,
- MemberFilter filter, object criteria)
- {
- if (gc == null)
- return MemberList.Empty;
-
- var members = new List<MemberInfo> ();
-
- if (gc.HasClassConstraint) {
- MemberList list = TypeManager.FindMembers (
- gc.ClassConstraint, mt, bf, filter, criteria);
+ #endregion
- members.AddRange (list);
- }
+ Type CreateMetaInfo (TypeParameterMutator mutator)
+ {
+ //
+ // Converts nested type arguments into right order
+ // Foo<string, bool>.Bar<int> => string, bool, int
+ //
+ var all = new List<Type> ();
+ TypeSpec type = this;
+ TypeSpec definition = type;
+ do {
+ if (type.GetDefinition().IsGeneric) {
+ all.InsertRange (0,
+ type.TypeArguments != TypeSpec.EmptyTypes ?
+ type.TypeArguments.Select (l => l.GetMetaInfo ()) :
+ type.MemberDefinition.TypeParameters.Select (l => l.GetMetaInfo ()));
+ }
- Type[] ifaces = TypeManager.ExpandInterfaces (gc.InterfaceConstraints);
- foreach (Type t in ifaces) {
- MemberList list = TypeManager.FindMembers (
- t, mt, bf, filter, criteria);
+ definition = definition.GetDefinition ();
+ type = type.DeclaringType;
+ } while (type != null);
- members.AddRange (list);
- }
+ return definition.GetMetaInfo ().MakeGenericType (all.ToArray ());
+ }
- return new MemberList (members);
+ public override ObsoleteAttribute GetAttributeObsolete ()
+ {
+ return open_type.GetAttributeObsolete ();
}
- public bool IsSubclassOf (Type t)
+ protected override bool IsNotCLSCompliant ()
{
- if (type.Equals (t))
+ if (base.IsNotCLSCompliant ())
return true;
- if (constraints != null)
- return constraints.IsSubclassOf (t);
+ foreach (var ta in TypeArguments) {
+ if (ta.MemberDefinition.IsNotCLSCompliant ())
+ return true;
+ }
return false;
}
- public void InflateConstraints (Type declaring)
+ public override TypeSpec GetDefinition ()
{
- if (constraints != null)
- gc = new InflatedConstraints (constraints, declaring);
+ return open_type;
}
-
- public override bool IsClsComplianceRequired ()
+
+ public override Type GetMetaInfo ()
{
- return false;
+ if (info == null)
+ info = CreateMetaInfo (null);
+
+ return info;
}
- protected class InflatedConstraints : GenericConstraints
+ public override string GetSignatureForError ()
{
- GenericConstraints gc;
- Type base_type;
- Type class_constraint;
- Type[] iface_constraints;
- Type[] dargs;
+ if (TypeManager.IsNullableType (open_type))
+ return targs[0].GetSignatureForError () + "?";
- public InflatedConstraints (GenericConstraints gc, Type declaring)
- : this (gc, TypeManager.GetTypeArguments (declaring))
- { }
+ if (MemberDefinition is AnonymousTypeClass)
+ return ((AnonymousTypeClass) MemberDefinition).GetSignatureForError ();
- public InflatedConstraints (GenericConstraints gc, Type[] dargs)
- {
- this.gc = gc;
- this.dargs = dargs;
-
- var list = new List<Type> ();
- if (gc.HasClassConstraint)
- list.Add (inflate (gc.ClassConstraint));
- foreach (Type iface in gc.InterfaceConstraints)
- list.Add (inflate (iface));
-
- bool has_class_constr = false;
- if (list.Count > 0) {
- Type first = (Type) list [0];
- has_class_constr = !first.IsGenericParameter && !first.IsInterface;
- }
+ return base.GetSignatureForError ();
+ }
+
+ protected override string GetTypeNameSignature ()
+ {
+ if (targs.Length == 0 || MemberDefinition is AnonymousTypeClass)
+ return null;
- if ((list.Count > 0) && has_class_constr) {
- class_constraint = (Type) list [0];
- iface_constraints = new Type [list.Count - 1];
- list.CopyTo (1, iface_constraints, 0, list.Count - 1);
+ return "<" + TypeManager.CSharpName (targs) + ">";
+ }
+
+ protected override void InitializeMemberCache (bool onlyTypes)
+ {
+ if (cache == null)
+ cache = new MemberCache (open_type.MemberCache);
+
+ TypeParameterSpec[] tparams_full;
+ TypeSpec[] targs_full = targs;
+ if (IsNested) {
+ //
+ // Special case is needed when we are inflating an open type (nested type definition)
+ // on inflated parent. Consider following case
+ //
+ // Foo<T>.Bar<U> => Foo<string>.Bar<U>
+ //
+ // Any later inflation of Foo<string>.Bar<U> has to also inflate T if used inside Bar<U>
+ //
+ List<TypeSpec> merged_targs = null;
+ List<TypeParameterSpec> merged_tparams = null;
+
+ var type = DeclaringType;
+
+ do {
+ if (type.TypeArguments.Length > 0) {
+ if (merged_targs == null) {
+ merged_targs = new List<TypeSpec> ();
+ merged_tparams = new List<TypeParameterSpec> ();
+ if (targs.Length > 0) {
+ merged_targs.AddRange (targs);
+ merged_tparams.AddRange (open_type.MemberDefinition.TypeParameters);
+ }
+ }
+ merged_tparams.AddRange (type.MemberDefinition.TypeParameters);
+ merged_targs.AddRange (type.TypeArguments);
+ }
+ type = type.DeclaringType;
+ } while (type != null);
+
+ if (merged_targs != null) {
+ // Type arguments are not in the right order but it should not matter in this case
+ targs_full = merged_targs.ToArray ();
+ tparams_full = merged_tparams.ToArray ();
+ } else if (targs.Length == 0) {
+ tparams_full = TypeParameterSpec.EmptyTypes;
} else {
- iface_constraints = new Type [list.Count];
- list.CopyTo (iface_constraints, 0);
+ tparams_full = open_type.MemberDefinition.TypeParameters;
}
-
- if (HasValueTypeConstraint)
- base_type = TypeManager.value_type;
- else if (class_constraint != null)
- base_type = class_constraint;
- else
- base_type = TypeManager.object_type;
+ } else if (targs.Length == 0) {
+ tparams_full = TypeParameterSpec.EmptyTypes;
+ } else {
+ tparams_full = open_type.MemberDefinition.TypeParameters;
}
- Type inflate (Type t)
- {
- if (t == null)
- return null;
- if (t.IsGenericParameter)
- return t.GenericParameterPosition < dargs.Length ? dargs [t.GenericParameterPosition] : t;
- if (t.IsGenericType) {
- Type[] args = t.GetGenericArguments ();
- Type[] inflated = new Type [args.Length];
+ var inflator = new TypeParameterInflator (this, tparams_full, targs_full);
- for (int i = 0; i < args.Length; i++)
- inflated [i] = inflate (args [i]);
+ //
+ // Two stage inflate due to possible nested types recursive
+ // references
+ //
+ // class A<T> {
+ // B b;
+ // class B {
+ // T Value;
+ // }
+ // }
+ //
+ // When resolving type of `b' members of `B' cannot be
+ // inflated because are not yet available in membercache
+ //
+ if ((state & StateFlags.PendingMemberCacheMembers) == 0) {
+ open_type.MemberCache.InflateTypes (cache, inflator);
- t = t.GetGenericTypeDefinition ();
- t = t.MakeGenericType (inflated);
+ //
+ // Inflate any implemented interfaces
+ //
+ if (open_type.Interfaces != null) {
+ ifaces = new List<TypeSpec> (open_type.Interfaces.Count);
+ foreach (var iface in open_type.Interfaces) {
+ var iface_inflated = inflator.Inflate (iface);
+ AddInterface (iface_inflated);
+ }
}
- return t;
+ //
+ // Handles the tricky case of recursive nested base generic type
+ //
+ // class A<T> : Base<A<T>.Nested> {
+ // class Nested {}
+ // }
+ //
+ // When inflating A<T>. base type is not yet known, secondary
+ // inflation is required (not common case) once base scope
+ // is known
+ //
+ if (open_type.BaseType == null) {
+ if (IsClass)
+ state |= StateFlags.PendingBaseTypeInflate;
+ } else {
+ BaseType = inflator.Inflate (open_type.BaseType);
+ }
+ } else if ((state & StateFlags.PendingBaseTypeInflate) != 0) {
+ BaseType = inflator.Inflate (open_type.BaseType);
+ state &= ~StateFlags.PendingBaseTypeInflate;
}
- public override GenericParameterAttributes Attributes {
- get { return gc.Attributes; }
+ if (onlyTypes) {
+ state |= StateFlags.PendingMemberCacheMembers;
+ return;
}
- public override Type ClassConstraint {
- get { return class_constraint; }
- }
+ var tc = open_type.MemberDefinition as TypeContainer;
+ if (tc != null && !tc.HasMembersDefined)
+ throw new InternalErrorException ("Inflating MemberCache with undefined members");
- public override Type EffectiveBaseClass {
- get { return base_type; }
+ if ((state & StateFlags.PendingBaseTypeInflate) != 0) {
+ BaseType = inflator.Inflate (open_type.BaseType);
+ state &= ~StateFlags.PendingBaseTypeInflate;
}
- public override Type[] InterfaceConstraints {
- get { return iface_constraints; }
- }
+ state &= ~StateFlags.PendingMemberCacheMembers;
+ open_type.MemberCache.InflateMembers (cache, open_type, inflator);
}
- }
- /// <summary>
- /// A TypeExpr which already resolved to a type parameter.
- /// </summary>
- public class TypeParameterExpr : TypeExpr {
-
- public TypeParameterExpr (TypeParameter type_parameter, Location loc)
+ public override TypeSpec Mutate (TypeParameterMutator mutator)
{
- this.type = type_parameter.Type;
- this.eclass = ExprClass.TypeParameter;
- this.loc = loc;
- }
+ var targs = TypeArguments;
+ if (targs != null)
+ targs = mutator.Mutate (targs);
- protected override TypeExpr DoResolveAsTypeStep (IMemberContext ec)
- {
- throw new NotSupportedException ();
- }
+ var decl = DeclaringType;
+ if (IsNested && DeclaringType.IsGenericOrParentIsGeneric)
+ decl = mutator.Mutate (decl);
- public override FullNamedExpression ResolveAsTypeStep (IMemberContext ec, bool silent)
- {
- return this;
- }
+ if (targs == TypeArguments && decl == DeclaringType)
+ return this;
- public override bool IsInterface {
- get { return false; }
- }
+ var mutated = (InflatedTypeSpec) MemberwiseClone ();
+ if (decl != DeclaringType) {
+ // Gets back MethodInfo in case of metaInfo was inflated
+ //mutated.info = MemberCache.GetMember<TypeSpec> (DeclaringType.GetDefinition (), this).info;
- public override bool CheckAccessLevel (IMemberContext ds)
- {
- return true;
+ mutated.declaringType = decl;
+ mutated.state |= StateFlags.PendingMetaInflate;
+ }
+
+ if (targs != null) {
+ mutated.targs = targs;
+ mutated.info = null;
+ }
+
+ return mutated;
}
}
+
//
// Tracks the type arguments when instantiating a generic type. It's used
// by both type arguments and type parameters
//
- public class TypeArguments {
+ public class TypeArguments
+ {
List<FullNamedExpression> args;
- Type[] atypes;
-
- public TypeArguments ()
- {
- args = new List<FullNamedExpression> ();
- }
+ TypeSpec[] atypes;
public TypeArguments (params FullNamedExpression[] types)
{
args.Add (type);
}
- public void Add (TypeArguments new_args)
- {
- args.AddRange (new_args.args);
- }
-
// TODO: Kill this monster
public TypeParameterName[] GetDeclarations ()
{
/// We may only be used after Resolve() is called and return the fully
/// resolved types.
/// </summary>
- public Type[] Arguments {
+ // TODO: Not needed, just return type from resolve
+ public TypeSpec[] Arguments {
get {
return atypes;
}
}
}
+ public virtual bool IsEmpty {
+ get {
+ return false;
+ }
+ }
+
public string GetSignatureForError()
{
- StringBuilder sb = new StringBuilder();
- for (int i = 0; i < Count; ++i)
- {
- Expression expr = (Expression)args [i];
- sb.Append(expr.GetSignatureForError());
+ StringBuilder sb = new StringBuilder ();
+ for (int i = 0; i < Count; ++i) {
+ var expr = args[i];
+ if (expr != null)
+ sb.Append (expr.GetSignatureForError ());
+
if (i + 1 < Count)
- sb.Append(',');
+ sb.Append (',');
}
- return sb.ToString();
+
+ return sb.ToString ();
}
/// <summary>
/// Resolve the type arguments.
/// </summary>
- public bool Resolve (IMemberContext ec)
+ public virtual bool Resolve (IMemberContext ec)
{
if (atypes != null)
- return atypes.Length != 0;
+ return atypes.Length != 0;
int count = args.Count;
bool ok = true;
- atypes = new Type [count];
+ atypes = new TypeSpec [count];
for (int i = 0; i < count; i++){
- TypeExpr te = ((FullNamedExpression) args[i]).ResolveAsTypeTerminal (ec, false);
+ TypeExpr te = args[i].ResolveAsTypeTerminal (ec, false);
if (te == null) {
ok = false;
continue;
atypes[i] = te.Type;
- if (te.Type.IsSealed && te.Type.IsAbstract) {
+ if (te.Type.IsStatic) {
ec.Compiler.Report.Error (718, te.Location, "`{0}': static classes cannot be used as generic arguments",
te.GetSignatureForError ());
ok = false;
}
if (!ok)
- atypes = Type.EmptyTypes;
+ atypes = TypeSpec.EmptyTypes;
return ok;
}
}
}
+ public class UnboundTypeArguments : TypeArguments
+ {
+ public UnboundTypeArguments (int arity)
+ : base (new FullNamedExpression[arity])
+ {
+ }
+
+ public override bool IsEmpty {
+ get {
+ return true;
+ }
+ }
+
+ public override bool Resolve (IMemberContext ec)
+ {
+ // should not be called
+ throw new NotSupportedException ();
+ }
+ }
+
public class TypeParameterName : SimpleName
{
Attributes attributes;
}
}
- /// <summary>
- /// A reference expression to generic type
- /// </summary>
+ //
+ // A type expression of generic type with type arguments
+ //
class GenericTypeExpr : TypeExpr
{
TypeArguments args;
- Type[] gen_params; // TODO: Waiting for constrains check cleanup
- Type open_type;
-
- //
- // Should be carefully used only with defined generic containers. Type parameters
- // can be used as type arguments in this case.
- //
- // TODO: This could be GenericTypeExpr specialization
- //
- public GenericTypeExpr (DeclSpace gType, Location l)
- {
- open_type = gType.TypeBuilder.GetGenericTypeDefinition ();
-
- args = new TypeArguments ();
- foreach (TypeParameter type_param in gType.TypeParameters)
- args.Add (new TypeParameterExpr (type_param, l));
-
- this.loc = l;
- }
+ TypeSpec open_type;
+ bool constraints_checked;
/// <summary>
/// Instantiate the generic type `t' with the type arguments `args'.
/// Use this constructor if you already know the fully resolved
/// generic type.
/// </summary>
- public GenericTypeExpr (Type t, TypeArguments args, Location l)
+ public GenericTypeExpr (TypeSpec open_type, TypeArguments args, Location l)
{
- open_type = t.GetGenericTypeDefinition ();
-
+ this.open_type = open_type;
loc = l;
this.args = args;
}
protected override TypeExpr DoResolveAsTypeStep (IMemberContext ec)
{
- eclass = ExprClass.Type;
-
if (!args.Resolve (ec))
return null;
- gen_params = open_type.GetGenericArguments ();
- Type[] atypes = args.Arguments;
-
- if (atypes.Length != gen_params.Length) {
- Namespace.Error_InvalidNumberOfTypeArguments (ec.Compiler.Report, open_type, loc);
- return null;
- }
+ TypeSpec[] atypes = args.Arguments;
//
// Now bind the parameters
//
type = open_type.MakeGenericType (atypes);
+
+ //
+ // Check constraints when context is not method/base type
+ //
+ if (!ec.HasUnresolvedConstraints)
+ CheckConstraints (ec);
+
return this;
}
- /// <summary>
- /// Check the constraints; we're called from ResolveAsTypeTerminal()
- /// after fully resolving the constructed type.
- /// </summary>
+ //
+ // Checks the constraints of open generic type against type
+ // arguments. Has to be called onafter all members are defined
+ //
public bool CheckConstraints (IMemberContext ec)
{
- return ConstraintChecker.CheckConstraints (ec, open_type, gen_params, args.Arguments, loc);
+ if (constraints_checked)
+ return true;
+
+ constraints_checked = true;
+
+ var gtype = (InflatedTypeSpec) type;
+ var constraints = gtype.Constraints;
+ if (constraints == null)
+ return true;
+
+ return ConstraintChecker.CheckAll (open_type, args.Arguments, constraints, loc, ec.Compiler.Report);
}
public override bool CheckAccessLevel (IMemberContext mc)
{
- return mc.CurrentTypeDefinition.CheckAccessLevel (open_type);
+ DeclSpace c = mc.CurrentMemberDefinition as DeclSpace;
+ if (c == null)
+ c = mc.CurrentMemberDefinition.Parent;
+
+ return c.CheckAccessLevel (open_type);
}
public bool HasDynamicArguments ()
return HasDynamicArguments (args.Arguments);
}
- static bool HasDynamicArguments (Type[] args)
+ static bool HasDynamicArguments (TypeSpec[] args)
{
- foreach (var item in args)
- {
+ foreach (var item in args) {
+ if (item == InternalType.Dynamic)
+ return true;
+
if (TypeManager.IsGenericType (item))
return HasDynamicArguments (TypeManager.GetTypeArguments (item));
-
- if (TypeManager.IsDynamicType (item))
- return true;
}
return false;
}
- public override bool IsClass {
- get { return open_type.IsClass; }
- }
-
- public override bool IsValueType {
- get { return TypeManager.IsStruct (open_type); }
- }
-
- public override bool IsInterface {
- get { return open_type.IsInterface; }
- }
-
- public override bool IsSealed {
- get { return open_type.IsSealed; }
- }
-
public override bool Equals (object obj)
{
GenericTypeExpr cobj = obj as GenericTypeExpr;
{
return base.GetHashCode ();
}
- }
-
- public abstract class ConstraintChecker
- {
- protected readonly Type[] gen_params;
- protected readonly Type[] atypes;
- protected readonly Location loc;
- protected Report Report;
-
- protected ConstraintChecker (Type[] gen_params, Type[] atypes, Location loc, Report r)
- {
- this.gen_params = gen_params;
- this.atypes = atypes;
- this.loc = loc;
- this.Report = r;
- }
-
- /// <summary>
- /// Check the constraints; we're called from ResolveAsTypeTerminal()
- /// after fully resolving the constructed type.
- /// </summary>
- public bool CheckConstraints (IMemberContext ec)
- {
- for (int i = 0; i < gen_params.Length; i++) {
- if (!CheckConstraints (ec, i))
- return false;
- }
-
- return true;
- }
-
- protected bool CheckConstraints (IMemberContext ec, int index)
- {
- Type atype = TypeManager.TypeToCoreType (atypes [index]);
- Type ptype = gen_params [index];
-
- if (atype == ptype)
- return true;
-
- Expression aexpr = new EmptyExpression (atype);
-
- GenericConstraints gc = TypeManager.GetTypeParameterConstraints (ptype);
- if (gc == null)
- return true;
-
- bool is_class, is_struct;
- if (atype.IsGenericParameter) {
- GenericConstraints agc = TypeManager.GetTypeParameterConstraints (atype);
- if (agc != null) {
- if (agc is Constraints) {
- // FIXME: No constraints can be resolved here, we are in
- // completely wrong/different context. This path is hit
- // when resolving base type of unresolved generic type
- // with constraints. We are waiting with CheckConsttraints
- // after type-definition but not in this case
- if (!((Constraints) agc).Resolve (null, null, Report))
- return true;
- }
- is_class = agc.IsReferenceType;
- is_struct = agc.IsValueType;
- } else {
- is_class = is_struct = false;
- }
- } else {
- is_class = TypeManager.IsReferenceType (atype);
- is_struct = TypeManager.IsValueType (atype) && !TypeManager.IsNullableType (atype);
- }
-
- //
- // First, check the `class' and `struct' constraints.
- //
- if (gc.HasReferenceTypeConstraint && !is_class) {
- Report.Error (452, loc, "The type `{0}' must be " +
- "a reference type in order to use it " +
- "as type parameter `{1}' in the " +
- "generic type or method `{2}'.",
- TypeManager.CSharpName (atype),
- TypeManager.CSharpName (ptype),
- GetSignatureForError ());
- return false;
- } else if (gc.HasValueTypeConstraint && !is_struct) {
- Report.Error (453, loc, "The type `{0}' must be a " +
- "non-nullable value type in order to use it " +
- "as type parameter `{1}' in the " +
- "generic type or method `{2}'.",
- TypeManager.CSharpName (atype),
- TypeManager.CSharpName (ptype),
- GetSignatureForError ());
- return false;
- }
-
- //
- // The class constraint comes next.
- //
- if (gc.HasClassConstraint) {
- if (!CheckConstraint (ec, ptype, aexpr, gc.ClassConstraint))
- return false;
- }
-
- //
- // Now, check the interface constraints.
- //
- if (gc.InterfaceConstraints != null) {
- foreach (Type it in gc.InterfaceConstraints) {
- if (!CheckConstraint (ec, ptype, aexpr, it))
- return false;
- }
- }
-
- //
- // Finally, check the constructor constraint.
- //
-
- if (!gc.HasConstructorConstraint)
- return true;
-
- if (TypeManager.IsValueType (atype))
- return true;
-
- if (HasDefaultConstructor (atype))
- return true;
-
- Report_SymbolRelatedToPreviousError ();
- Report.SymbolRelatedToPreviousError (atype);
- Report.Error (310, loc, "The type `{0}' must have a public " +
- "parameterless constructor in order to use it " +
- "as parameter `{1}' in the generic type or " +
- "method `{2}'",
- TypeManager.CSharpName (atype),
- TypeManager.CSharpName (ptype),
- GetSignatureForError ());
- return false;
- }
-
- Type InflateType(IMemberContext ec, Type ctype)
- {
- Type[] types = TypeManager.GetTypeArguments (ctype);
-
- TypeArguments new_args = new TypeArguments ();
-
- for (int i = 0; i < types.Length; i++) {
- Type t = TypeManager.TypeToCoreType (types [i]);
-
- if (t.IsGenericParameter) {
- int pos = t.GenericParameterPosition;
- if (t.DeclaringMethod == null && this is MethodConstraintChecker) {
- Type parent = ((MethodConstraintChecker) this).declaring_type;
- t = parent.GetGenericArguments ()[pos];
- } else {
- t = atypes [pos];
- }
- } else if(TypeManager.HasGenericArguments(t)) {
- t = InflateType (ec, t);
- if (t == null) {
- return null;
- }
- }
- new_args.Add (new TypeExpression (t, loc));
- }
-
- TypeExpr ct = new GenericTypeExpr (ctype, new_args, loc);
- if (ct.ResolveAsTypeStep (ec, false) == null)
- return null;
-
- return ct.Type;
- }
+ }
- protected bool CheckConstraint (IMemberContext ec, Type ptype, Expression expr,
- Type ctype)
+ static class ConstraintChecker
+ {
+ /// <summary>
+ /// Check the constraints; we're called from ResolveAsTypeTerminal()
+ /// after fully resolving the constructed type.
+ /// </summary>
+ public static bool CheckAll (MemberSpec context, TypeSpec[] targs, TypeParameterSpec[] tparams, Location loc, Report report)
{
- //
- // All this is needed because we don't have
- // real inflated type hierarchy
- //
- if (TypeManager.HasGenericArguments (ctype)) {
- ctype = InflateType (ec, ctype);
- if(ctype == null) {
+ for (int i = 0; i < tparams.Length; i++) {
+ if (!CheckConstraint (context, targs [i], tparams [i], loc, report))
return false;
- }
- } else if (ctype.IsGenericParameter) {
- int pos = ctype.GenericParameterPosition;
- if (ctype.DeclaringMethod == null) {
- // FIXME: Implement
- return true;
- } else {
- ctype = atypes [pos];
- }
}
- if (Convert.ImplicitStandardConversionExists (expr, ctype))
- return true;
-
- Report_SymbolRelatedToPreviousError ();
- Report.SymbolRelatedToPreviousError (expr.Type);
-
- if (TypeManager.IsNullableType (expr.Type) && ctype.IsInterface) {
- Report.Error (313, loc,
- "The type `{0}' cannot be used as type parameter `{1}' in the generic type or method `{2}'. " +
- "The nullable type `{0}' never satisfies interface constraint of type `{3}'",
- TypeManager.CSharpName (expr.Type), TypeManager.CSharpName (ptype),
- GetSignatureForError (), TypeManager.CSharpName (ctype));
- } else {
- Report.Error (309, loc,
- "The type `{0}' must be convertible to `{1}' in order to " +
- "use it as parameter `{2}' in the generic type or method `{3}'",
- TypeManager.CSharpName (expr.Type), TypeManager.CSharpName (ctype),
- TypeManager.CSharpName (ptype), GetSignatureForError ());
- }
- return false;
+ return true;
}
- static bool HasDefaultConstructor (Type atype)
+ static bool CheckConstraint (MemberSpec context, TypeSpec atype, TypeParameterSpec tparam, Location loc, Report report)
{
- TypeParameter tparam = TypeManager.LookupTypeParameter (atype);
- if (tparam != null) {
- if (tparam.GenericConstraints == null)
- return false;
-
- return tparam.GenericConstraints.HasConstructorConstraint ||
- tparam.GenericConstraints.HasValueTypeConstraint;
- }
-
- if (atype.IsAbstract)
+ //
+ // First, check the `class' and `struct' constraints.
+ //
+ if (tparam.HasSpecialClass && !TypeManager.IsReferenceType (atype)) {
+ report.Error (452, loc,
+ "The type `{0}' must be a reference type in order to use it as type parameter `{1}' in the generic type or method `{2}'",
+ TypeManager.CSharpName (atype), tparam.GetSignatureForError (), context.GetSignatureForError ());
return false;
+ }
- again:
- atype = TypeManager.DropGenericTypeArguments (atype);
- if (atype is TypeBuilder) {
- TypeContainer tc = TypeManager.LookupTypeContainer (atype);
- if (tc.InstanceConstructors == null) {
- atype = atype.BaseType;
- goto again;
- }
+ if (tparam.HasSpecialStruct && (!TypeManager.IsValueType (atype) || TypeManager.IsNullableType (atype))) {
+ report.Error (453, loc,
+ "The type `{0}' must be a non-nullable value type in order to use it as type parameter `{1}' in the generic type or method `{2}'",
+ TypeManager.CSharpName (atype), tparam.GetSignatureForError (), context.GetSignatureForError ());
+ return false;
+ }
- foreach (Constructor c in tc.InstanceConstructors) {
- if ((c.ModFlags & Modifiers.PUBLIC) == 0)
- continue;
- if ((c.Parameters.FixedParameters != null) &&
- (c.Parameters.FixedParameters.Length != 0))
- continue;
- if (c.Parameters.HasArglist || c.Parameters.HasParams)
- continue;
+ //
+ // The class constraint comes next.
+ //
+ if (tparam.HasTypeConstraint) {
+ CheckConversion (context, atype, tparam, tparam.BaseType, loc, report);
+ }
- return true;
+ //
+ // Now, check the interfaces and type parameters constraints
+ //
+ if (tparam.Interfaces != null) {
+ if (TypeManager.IsNullableType (atype)) {
+ report.Error (313, loc,
+ "The type `{0}' cannot be used as type parameter `{1}' in the generic type or method `{2}'. The nullable type `{0}' never satisfies interface constraint",
+ atype.GetSignatureForError (), tparam.GetSignatureForError (), context.GetSignatureForError ());
+ } else {
+ foreach (TypeSpec iface in tparam.Interfaces) {
+ CheckConversion (context, atype, tparam, iface, loc, report);
+ }
}
}
- MemberInfo [] list = TypeManager.MemberLookup (null, null, atype, MemberTypes.Constructor,
- BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly,
- ConstructorInfo.ConstructorName, null);
+ //
+ // Finally, check the constructor constraint.
+ //
+ if (!tparam.HasSpecialConstructor)
+ return true;
- if (list == null)
+ if (!HasDefaultConstructor (atype)) {
+ report.SymbolRelatedToPreviousError (atype);
+ report.Error (310, loc,
+ "The type `{0}' must have a public parameterless constructor in order to use it as parameter `{1}' in the generic type or method `{2}'",
+ TypeManager.CSharpName (atype), tparam.GetSignatureForError (), context.GetSignatureForError ());
return false;
-
- foreach (MethodBase mb in list) {
- AParametersCollection pd = TypeManager.GetParameterData (mb);
- if (pd.Count == 0)
- return true;
}
- return false;
+ return true;
}
- protected abstract string GetSignatureForError ();
- protected abstract void Report_SymbolRelatedToPreviousError ();
-
- public static bool CheckConstraints (IMemberContext ec, MethodBase definition,
- MethodBase instantiated, Location loc)
+ static void CheckConversion (MemberSpec context, TypeSpec atype, TypeParameterSpec tparam, TypeSpec ttype, Location loc, Report report)
{
- MethodConstraintChecker checker = new MethodConstraintChecker (
- definition, instantiated.DeclaringType, definition.GetGenericArguments (),
- instantiated.GetGenericArguments (), loc, ec.Compiler.Report);
-
- return checker.CheckConstraints (ec);
+ var expr = new EmptyExpression (atype);
+ if (!Convert.ImplicitStandardConversionExists (expr, ttype)) {
+ report.SymbolRelatedToPreviousError (tparam);
+ if (TypeManager.IsValueType (atype)) {
+ report.Error (315, loc, "The type `{0}' cannot be used as type parameter `{1}' in the generic type or method `{2}'. There is no boxing conversion from `{0}' to `{3}'",
+ atype.GetSignatureForError (), tparam.GetSignatureForError (), context.GetSignatureForError (), ttype.GetSignatureForError ());
+ } else if (atype.IsGenericParameter) {
+ report.Error (314, loc, "The type `{0}' cannot be used as type parameter `{1}' in the generic type or method `{2}'. There is no boxing or type parameter conversion from `{0}' to `{3}'",
+ atype.GetSignatureForError (), tparam.GetSignatureForError (), context.GetSignatureForError (), ttype.GetSignatureForError ());
+ } else {
+ report.Error (311, loc, "The type `{0}' cannot be used as type parameter `{1}' in the generic type or method `{2}'. There is no implicit reference conversion from `{0}' to `{3}'",
+ atype.GetSignatureForError (), tparam.GetSignatureForError (), context.GetSignatureForError (), ttype.GetSignatureForError ());
+ }
+ }
}
- public static bool CheckConstraints (IMemberContext ec, Type gt, Type[] gen_params,
- Type[] atypes, Location loc)
+ static bool HasDefaultConstructor (TypeSpec atype)
{
- TypeConstraintChecker checker = new TypeConstraintChecker (
- gt, gen_params, atypes, loc, ec.Compiler.Report);
-
- return checker.CheckConstraints (ec);
- }
+ var tp = atype as TypeParameterSpec;
+ if (tp != null) {
+ return tp.HasSpecialConstructor || tp.HasSpecialStruct;
+ }
- protected class MethodConstraintChecker : ConstraintChecker
- {
- MethodBase definition;
- public Type declaring_type;
+ if (atype.IsStruct || atype.IsEnum)
+ return true;
- public MethodConstraintChecker (MethodBase definition, Type declaringType, Type[] gen_params,
- Type[] atypes, Location loc, Report r)
- : base (gen_params, atypes, loc, r)
- {
- this.declaring_type = declaringType;
- this.definition = definition;
- }
+ if (atype.IsAbstract)
+ return false;
- protected override string GetSignatureForError ()
- {
- return TypeManager.CSharpSignature (definition);
- }
+ var tdef = atype.GetDefinition ();
- protected override void Report_SymbolRelatedToPreviousError ()
- {
- Report.SymbolRelatedToPreviousError (definition);
- }
- }
+ //
+ // In some circumstances MemberCache is not yet populated and members
+ // cannot be defined yet (recursive type new constraints)
+ //
+ // class A<T> where T : B<T>, new () {}
+ // class B<T> where T : A<T>, new () {}
+ //
+ var tc = tdef.MemberDefinition as Class;
+ if (tc != null) {
+ if (tc.InstanceConstructors == null) {
+ // Default ctor will be generated later
+ return true;
+ }
- protected class TypeConstraintChecker : ConstraintChecker
- {
- Type gt;
+ foreach (var c in tc.InstanceConstructors) {
+ if (c.ParameterInfo.IsEmpty) {
+ if ((c.ModFlags & Modifiers.PUBLIC) != 0)
+ return true;
+ }
+ }
- public TypeConstraintChecker (Type gt, Type[] gen_params, Type[] atypes,
- Location loc, Report r)
- : base (gen_params, atypes, loc, r)
- {
- this.gt = gt;
+ return false;
}
- protected override string GetSignatureForError ()
- {
- return TypeManager.CSharpName (gt);
- }
+ var found = MemberCache.FindMember (tdef,
+ MemberFilter.Constructor (ParametersCompiled.EmptyReadOnlyParameters),
+ BindingRestriction.DeclaredOnly | BindingRestriction.InstanceOnly);
- protected override void Report_SymbolRelatedToPreviousError ()
- {
- Report.SymbolRelatedToPreviousError (gt);
- }
+ return found != null && (found.Modifiers & Modifiers.PUBLIC) != 0;
}
}
/// </summary>
public class GenericMethod : DeclSpace
{
- FullNamedExpression return_type;
ParametersCompiled parameters;
public GenericMethod (NamespaceEntry ns, DeclSpace parent, MemberName name,
FullNamedExpression return_type, ParametersCompiled parameters)
: base (ns, parent, name, null)
{
- this.return_type = return_type;
this.parameters = parameters;
}
- public override TypeContainer CurrentTypeDefinition {
- get {
- return Parent.CurrentTypeDefinition;
- }
+ public GenericMethod (NamespaceEntry ns, DeclSpace parent, MemberName name, TypeParameter[] tparams,
+ FullNamedExpression return_type, ParametersCompiled parameters)
+ : this (ns, parent, name, return_type, parameters)
+ {
+ this.type_params = tparams;
}
public override TypeParameter[] CurrentTypeParameters {
throw new Exception ();
}
- public override bool Define ()
+ public override void ApplyAttributeBuilder (Attribute a, MethodSpec ctor, byte[] cdata, PredefinedAttributes pa)
{
- for (int i = 0; i < TypeParameters.Length; i++)
- if (!TypeParameters [i].Resolve (this))
- return false;
+ throw new NotSupportedException ();
+ }
- return true;
+ public override bool Define ()
+ {
+ throw new NotSupportedException ();
}
/// <summary>
GenericTypeParameterBuilder[] gen_params = m.MethodBuilder.DefineGenericParameters (snames);
for (int i = 0; i < TypeParameters.Length; i++)
- TypeParameters [i].Define (gen_params [i]);
-
- if (!Define ())
- return false;
-
- for (int i = 0; i < TypeParameters.Length; i++) {
- if (!TypeParameters [i].ResolveType (this))
- return false;
- }
+ TypeParameters [i].Define (gen_params [i], null);
return true;
}
- /// <summary>
- /// We're called from MethodData.Define() after creating the MethodBuilder.
- /// </summary>
- public bool DefineType (IMemberContext ec, MethodBuilder mb,
- MethodInfo implementing, bool is_override)
- {
- for (int i = 0; i < TypeParameters.Length; i++)
- if (!TypeParameters [i].DefineType (
- ec, mb, implementing, is_override))
- return false;
-
- bool ok = parameters.Resolve (ec);
-
- if ((return_type != null) && (return_type.ResolveAsTypeTerminal (ec, false) == null))
- ok = false;
-
- return ok;
- }
-
public void EmitAttributes ()
{
- for (int i = 0; i < TypeParameters.Length; i++)
- TypeParameters [i].Emit ();
-
if (OptAttributes != null)
OptAttributes.Emit ();
}
- public override MemberList FindMembers (MemberTypes mt, BindingFlags bf,
- MemberFilter filter, object criteria)
- {
- throw new Exception ();
- }
-
public override string GetSignatureForError ()
{
return base.GetSignatureForError () + parameters.GetSignatureForError ();
}
- public override MemberCache MemberCache {
- get {
- return null;
- }
- }
-
public override AttributeTargets AttributeTargets {
get {
return AttributeTargets.Method | AttributeTargets.ReturnValue;
public new void VerifyClsCompliance ()
{
foreach (TypeParameter tp in TypeParameters) {
- if (tp.Constraints == null)
- continue;
-
- tp.Constraints.VerifyClsCompliance (Report);
+ tp.VerifyClsCompliance ();
}
}
}
- partial class TypeManager
+ public partial class TypeManager
{
- public static TypeContainer LookupGenericTypeContainer (Type t)
+ public static Variance CheckTypeVariance (TypeSpec t, Variance expected, IMemberContext member)
{
- t = DropGenericTypeArguments (t);
- return LookupTypeContainer (t);
- }
-
- public static Variance GetTypeParameterVariance (Type type)
- {
- TypeParameter tparam = LookupTypeParameter (type);
- if (tparam != null)
- return tparam.Variance;
-
- switch (type.GenericParameterAttributes & GenericParameterAttributes.VarianceMask) {
- case GenericParameterAttributes.Covariant:
- return Variance.Covariant;
- case GenericParameterAttributes.Contravariant:
- return Variance.Contravariant;
- default:
- return Variance.None;
- }
- }
-
- public static Variance CheckTypeVariance (Type t, Variance expected, IMemberContext member)
- {
- TypeParameter tp = LookupTypeParameter (t);
+ var tp = t as TypeParameterSpec;
if (tp != null) {
Variance v = tp.Variance;
if (expected == Variance.None && v != expected ||
expected == Variance.Covariant && v == Variance.Contravariant ||
- expected == Variance.Contravariant && v == Variance.Covariant)
- tp.ErrorInvalidVariance (member, expected);
+ expected == Variance.Contravariant && v == Variance.Covariant) {
+ ((TypeParameter)tp.MemberDefinition).ErrorInvalidVariance (member, expected);
+ }
return expected;
}
- if (t.IsGenericType) {
- Type[] targs_definition = GetTypeArguments (DropGenericTypeArguments (t));
- Type[] targs = GetTypeArguments (t);
- for (int i = 0; i < targs_definition.Length; ++i) {
- Variance v = GetTypeParameterVariance (targs_definition[i]);
+ if (t.TypeArguments.Length > 0) {
+ var targs_definition = t.MemberDefinition.TypeParameters;
+ TypeSpec[] targs = GetTypeArguments (t);
+ for (int i = 0; i < targs.Length; ++i) {
+ Variance v = targs_definition[i].Variance;
CheckTypeVariance (targs[i], (Variance) ((int)v * (int)expected), member);
}
return Variance.None;
}
- public static bool IsVariantOf (Type type1, Type type2)
- {
- if (!type1.IsGenericType || !type2.IsGenericType)
- return false;
-
- Type generic_target_type = DropGenericTypeArguments (type2);
- if (DropGenericTypeArguments (type1) != generic_target_type)
- return false;
-
- Type[] t1 = GetTypeArguments (type1);
- Type[] t2 = GetTypeArguments (type2);
- Type[] targs_definition = GetTypeArguments (generic_target_type);
- for (int i = 0; i < targs_definition.Length; ++i) {
- Variance v = GetTypeParameterVariance (targs_definition [i]);
- if (v == Variance.None) {
- if (t1[i] == t2[i])
- continue;
- return false;
- }
-
- if (v == Variance.Covariant) {
- if (!Convert.ImplicitReferenceConversionExists (new EmptyExpression (t1 [i]), t2 [i]))
- return false;
- } else if (!Convert.ImplicitReferenceConversionExists (new EmptyExpression (t2[i]), t1[i])) {
- return false;
- }
- }
-
- return true;
- }
-
- /// <summary>
- /// Check whether `a' and `b' may become equal generic types.
- /// The algorithm to do that is a little bit complicated.
- /// </summary>
- public static bool MayBecomeEqualGenericTypes (Type a, Type b, Type[] class_inferred,
- Type[] method_inferred)
- {
- if (a.IsGenericParameter) {
- //
- // If a is an array of a's type, they may never
- // become equal.
- //
- while (b.IsArray) {
- b = GetElementType (b);
- if (a.Equals (b))
- return false;
- }
-
- //
- // If b is a generic parameter or an actual type,
- // they may become equal:
- //
- // class X<T,U> : I<T>, I<U>
- // class X<T> : I<T>, I<float>
- //
- if (b.IsGenericParameter || !b.IsGenericType) {
- int pos = a.GenericParameterPosition;
- Type[] args = a.DeclaringMethod != null ? method_inferred : class_inferred;
- if (args [pos] == null) {
- args [pos] = b;
- return true;
- }
-
- return args [pos] == a;
- }
-
- //
- // We're now comparing a type parameter with a
- // generic instance. They may become equal unless
- // the type parameter appears anywhere in the
- // generic instance:
- //
- // class X<T,U> : I<T>, I<X<U>>
- // -> error because you could instanciate it as
- // X<X<int>,int>
- //
- // class X<T> : I<T>, I<X<T>> -> ok
- //
-
- Type[] bargs = GetTypeArguments (b);
- for (int i = 0; i < bargs.Length; i++) {
- if (a.Equals (bargs [i]))
- return false;
- }
-
- return true;
- }
-
- if (b.IsGenericParameter)
- return MayBecomeEqualGenericTypes (b, a, class_inferred, method_inferred);
-
- //
- // At this point, neither a nor b are a type parameter.
- //
- // If one of them is a generic instance, let
- // MayBecomeEqualGenericInstances() compare them (if the
- // other one is not a generic instance, they can never
- // become equal).
- //
-
- if (a.IsGenericType || b.IsGenericType)
- return MayBecomeEqualGenericInstances (a, b, class_inferred, method_inferred);
-
- //
- // If both of them are arrays.
- //
-
- if (a.IsArray && b.IsArray) {
- if (a.GetArrayRank () != b.GetArrayRank ())
- return false;
-
- a = GetElementType (a);
- b = GetElementType (b);
-
- return MayBecomeEqualGenericTypes (a, b, class_inferred, method_inferred);
- }
-
- //
- // Ok, two ordinary types.
- //
-
- return a.Equals (b);
- }
-
- //
- // Checks whether two generic instances may become equal for some
- // particular instantiation (26.3.1).
- //
- public static bool MayBecomeEqualGenericInstances (Type a, Type b,
- Type[] class_inferred,
- Type[] method_inferred)
- {
- if (!a.IsGenericType || !b.IsGenericType)
- return false;
- if (a.GetGenericTypeDefinition () != b.GetGenericTypeDefinition ())
- return false;
-
- return MayBecomeEqualGenericInstances (
- GetTypeArguments (a), GetTypeArguments (b), class_inferred, method_inferred);
- }
-
- public static bool MayBecomeEqualGenericInstances (Type[] aargs, Type[] bargs,
- Type[] class_inferred,
- Type[] method_inferred)
- {
- if (aargs.Length != bargs.Length)
- return false;
-
- for (int i = 0; i < aargs.Length; i++) {
- if (!MayBecomeEqualGenericTypes (aargs [i], bargs [i], class_inferred, method_inferred))
- return false;
- }
-
- return true;
- }
-
/// <summary>
/// Type inference. Try to infer the type arguments from `method',
/// which is invoked with the arguments `arguments'. This is used
public static int InferTypeArguments (ResolveContext ec, Arguments arguments, ref MethodSpec method)
{
ATypeInference ti = ATypeInference.CreateInstance (arguments);
- Type[] i_args = ti.InferMethodArguments (ec, method);
+ TypeSpec[] i_args = ti.InferMethodArguments (ec, method);
if (i_args == null)
return ti.InferenceScore;
if (i_args.Length == 0)
return 0;
- method = method.Inflate (i_args);
+ method = method.MakeGenericMethod (i_args);
return 0;
}
-
-/*
- public static bool InferTypeArguments (ResolveContext ec, AParametersCollection param, ref MethodBase method)
- {
- if (!TypeManager.IsGenericMethod (method))
- return true;
-
- ATypeInference ti = ATypeInference.CreateInstance (DelegateCreation.CreateDelegateMethodArguments (param, Location.Null));
- Type[] i_args = ti.InferDelegateArguments (ec, method);
- if (i_args == null)
- return false;
-
- method = ((MethodInfo) method).MakeGenericMethod (i_args);
- return true;
- }
-*/
}
abstract class ATypeInference
}
}
- public abstract Type[] InferMethodArguments (ResolveContext ec, MethodSpec method);
-// public abstract Type[] InferDelegateArguments (ResolveContext ec, MethodBase method);
+ public abstract TypeSpec[] InferMethodArguments (ResolveContext ec, MethodSpec method);
}
//
}
}
-/*
- public override Type[] InferDelegateArguments (ResolveContext ec, MethodBase method)
- {
- AParametersCollection pd = TypeManager.GetParameterData (method);
- if (arg_count != pd.Count)
- return null;
-
- Type[] d_gargs = method.GetGenericArguments ();
- TypeInferenceContext context = new TypeInferenceContext (d_gargs);
-
- // A lower-bound inference is made from each argument type Uj of D
- // to the corresponding parameter type Tj of M
- for (int i = 0; i < arg_count; ++i) {
- Type t = pd.Types [i];
- if (!t.IsGenericParameter)
- continue;
-
- context.LowerBoundInference (arguments [i].Expr.Type, t);
- }
-
- if (!context.FixAllTypes (ec))
- return null;
-
- return context.InferredTypeArguments;
- }
-*/
- public override Type[] InferMethodArguments (ResolveContext ec, MethodSpec method)
+ public override TypeSpec[] InferMethodArguments (ResolveContext ec, MethodSpec method)
{
- var method_generic_args = method.GetGenericArguments ();
+ var method_generic_args = method.GenericDefinition.TypeParameters;
TypeInferenceContext context = new TypeInferenceContext (method_generic_args);
if (!context.UnfixedVariableExists)
- return Type.EmptyTypes;
+ return TypeSpec.EmptyTypes;
AParametersCollection pd = method.Parameters;
if (!InferInPhases (ec, context, pd))
params_arguments_start = arg_count;
}
- Type [] ptypes = methodParameters.Types;
+ TypeSpec [] ptypes = methodParameters.Types;
//
// The first inference phase
//
- Type method_parameter = null;
+ TypeSpec method_parameter = null;
for (int i = 0; i < arg_count; i++) {
Argument a = arguments [i];
if (a == null)
else
method_parameter = TypeManager.GetElementType (methodParameters.Types [params_arguments_start]);
- ptypes = (Type[]) ptypes.Clone ();
+ ptypes = (TypeSpec[]) ptypes.Clone ();
ptypes [i] = method_parameter;
}
continue;
}
- if (a.Expr.Type == TypeManager.null_type)
+ if (a.Expr.Type == InternalType.Null)
continue;
if (TypeManager.IsValueType (method_parameter)) {
return DoSecondPhase (ec, tic, ptypes, !fixed_any);
}
- bool DoSecondPhase (ResolveContext ec, TypeInferenceContext tic, Type[] methodParameters, bool fixDependent)
+ bool DoSecondPhase (ResolveContext ec, TypeInferenceContext tic, TypeSpec[] methodParameters, bool fixDependent)
{
bool fixed_any = false;
if (fixDependent && !tic.FixDependentTypes (ec, ref fixed_any))
for (int i = 0; i < arg_count; i++) {
// Align params arguments
- Type t_i = methodParameters [i >= methodParameters.Length ? methodParameters.Length - 1: i];
+ TypeSpec t_i = methodParameters [i >= methodParameters.Length ? methodParameters.Length - 1: i];
if (!TypeManager.IsDelegateType (t_i)) {
- if (TypeManager.DropGenericTypeArguments (t_i) != TypeManager.expression_type)
+ if (t_i.GetDefinition () != TypeManager.expression_type)
continue;
- t_i = t_i.GetGenericArguments () [0];
+ t_i = TypeManager.GetTypeArguments (t_i) [0];
}
- var mi = Delegate.GetInvokeMethod (ec.Compiler, t_i, t_i);
- Type rtype = mi.ReturnType;
-
-#if MS_COMPATIBLE
- // Blablabla, because reflection does not work with dynamic types
-// Type[] g_args = t_i.GetGenericArguments ();
-// rtype = g_args[rtype.GenericParameterPosition];
-#endif
+ var mi = Delegate.GetInvokeMethod (ec.Compiler, t_i);
+ TypeSpec rtype = mi.ReturnType;
if (tic.IsReturnTypeNonDependent (ec, mi, rtype))
score -= tic.OutputTypeInference (ec, arguments [i].Expr, t_i);
class BoundInfo
{
- public readonly Type Type;
+ public readonly TypeSpec Type;
public readonly BoundKind Kind;
- public BoundInfo (Type type, BoundKind kind)
+ public BoundInfo (TypeSpec type, BoundKind kind)
{
this.Type = type;
this.Kind = kind;
}
}
- readonly Type[] unfixed_types;
- readonly Type[] fixed_types;
+ readonly TypeSpec[] unfixed_types;
+ readonly TypeSpec[] fixed_types;
readonly List<BoundInfo>[] bounds;
bool failed;
-
- public TypeInferenceContext (Type[] typeArguments)
+
+ // TODO MemberCache: Could it be TypeParameterSpec[] ??
+ public TypeInferenceContext (TypeSpec[] typeArguments)
{
if (typeArguments.Length == 0)
throw new ArgumentException ("Empty generic arguments");
- fixed_types = new Type [typeArguments.Length];
+ fixed_types = new TypeSpec [typeArguments.Length];
for (int i = 0; i < typeArguments.Length; ++i) {
if (typeArguments [i].IsGenericParameter) {
if (bounds == null) {
bounds = new List<BoundInfo> [typeArguments.Length];
- unfixed_types = new Type [typeArguments.Length];
+ unfixed_types = new TypeSpec [typeArguments.Length];
}
unfixed_types [i] = typeArguments [i];
} else {
//
public TypeInferenceContext ()
{
- fixed_types = new Type [1];
- unfixed_types = new Type [1];
+ fixed_types = new TypeSpec [1];
+ unfixed_types = new TypeSpec [1];
unfixed_types[0] = InternalType.Arglist; // it can be any internal type
bounds = new List<BoundInfo> [1];
}
- public Type[] InferredTypeArguments {
+ public TypeSpec[] InferredTypeArguments {
get {
return fixed_types;
}
}
- public void AddCommonTypeBound (Type type)
+ public void AddCommonTypeBound (TypeSpec type)
{
AddToBounds (new BoundInfo (type, BoundKind.Lower), 0);
}
a.Add (bound);
}
- bool AllTypesAreFixed (Type[] types)
+ bool AllTypesAreFixed (TypeSpec[] types)
{
- foreach (Type t in types) {
+ foreach (TypeSpec t in types) {
if (t.IsGenericParameter) {
if (!IsFixed (t))
return false;
continue;
}
- if (t.IsGenericType)
- return AllTypesAreFixed (t.GetGenericArguments ());
+ if (TypeManager.IsGenericType (t))
+ return AllTypesAreFixed (TypeManager.GetTypeArguments (t));
}
return true;
//
// 26.3.3.8 Exact Inference
//
- public int ExactInference (Type u, Type v)
+ public int ExactInference (TypeSpec u, TypeSpec v)
{
// If V is an array type
if (v.IsArray) {
if (!u.IsArray)
return 0;
- if (u.GetArrayRank () != v.GetArrayRank ())
+ // TODO MemberCache: GetMetaInfo ()
+ if (u.GetMetaInfo ().GetArrayRank () != v.GetMetaInfo ().GetArrayRank ())
return 0;
return ExactInference (TypeManager.GetElementType (u), TypeManager.GetElementType (v));
}
// If V is constructed type and U is constructed type
- if (v.IsGenericType && !v.IsGenericTypeDefinition) {
- if (!u.IsGenericType)
+ if (TypeManager.IsGenericType (v)) {
+ if (!TypeManager.IsGenericType (u))
return 0;
- Type [] ga_u = u.GetGenericArguments ();
- Type [] ga_v = v.GetGenericArguments ();
+ TypeSpec [] ga_u = TypeManager.GetTypeArguments (u);
+ TypeSpec [] ga_v = TypeManager.GetTypeArguments (v);
if (ga_u.Length != ga_v.Length)
return 0;
//
// All unfixed type variables Xi which depend on no Xj are fixed
//
- public bool FixIndependentTypeArguments (ResolveContext ec, Type[] methodParameters, ref bool fixed_any)
+ public bool FixIndependentTypeArguments (ResolveContext ec, TypeSpec[] methodParameters, ref bool fixed_any)
{
- var types_to_fix = new List<Type> (unfixed_types);
+ var types_to_fix = new List<TypeSpec> (unfixed_types);
for (int i = 0; i < methodParameters.Length; ++i) {
- Type t = methodParameters[i];
+ TypeSpec t = methodParameters[i];
if (!TypeManager.IsDelegateType (t)) {
- if (TypeManager.DropGenericTypeArguments (t) != TypeManager.expression_type)
+ if (TypeManager.expression_type == null || t.MemberDefinition != TypeManager.expression_type.MemberDefinition)
continue;
- t = t.GetGenericArguments () [0];
+ t = TypeManager.GetTypeArguments (t) [0];
}
if (t.IsGenericParameter)
continue;
- var invoke = Delegate.GetInvokeMethod (ec.Compiler, t, t);
- Type rtype = invoke.ReturnType;
- if (!rtype.IsGenericParameter && !rtype.IsGenericType)
+ var invoke = Delegate.GetInvokeMethod (ec.Compiler, t);
+ TypeSpec rtype = invoke.ReturnType;
+ if (!rtype.IsGenericParameter && !TypeManager.IsGenericType (rtype))
continue;
-#if MS_COMPATIBLE
- // Blablabla, because reflection does not work with dynamic types
-// if (rtype.IsGenericParameter) {
-// Type [] g_args = t.GetGenericArguments ();
-// rtype = g_args [rtype.GenericParameterPosition];
-// }
-#endif
// Remove dependent types, they cannot be fixed yet
RemoveDependentTypes (types_to_fix, rtype);
}
- foreach (Type t in types_to_fix) {
+ foreach (TypeSpec t in types_to_fix) {
if (t == null)
continue;
if (candidates.Count == 1) {
unfixed_types[i] = null;
- Type t = candidates[0].Type;
- if (t == TypeManager.null_type)
+ TypeSpec t = candidates[0].Type;
+ if (t == InternalType.Null)
return false;
fixed_types [i] = t;
// a standard implicit conversion to all the other
// candidate types.
//
- Type best_candidate = null;
+ TypeSpec best_candidate = null;
int cii;
int candidates_count = candidates.Count;
for (int ci = 0; ci < candidates_count; ++ci) {
- BoundInfo bound = (BoundInfo)candidates [ci];
+ BoundInfo bound = candidates [ci];
for (cii = 0; cii < candidates_count; ++cii) {
if (cii == ci)
continue;
- BoundInfo cbound = (BoundInfo) candidates[cii];
+ BoundInfo cbound = candidates[cii];
// Same type parameters with different bounds
if (cbound.Type == bound.Type) {
//
// Uses inferred types to inflate delegate type argument
//
- public Type InflateGenericArgument (Type parameter)
+ public TypeSpec InflateGenericArgument (TypeSpec parameter)
{
- if (parameter.IsGenericParameter) {
+ var tp = parameter as TypeParameterSpec;
+ if (tp != null) {
//
// Inflate method generic argument (MVAR) only
//
- if (parameter.DeclaringMethod == null)
+ if (!tp.IsMethodOwned)
return parameter;
- return fixed_types [parameter.GenericParameterPosition];
+ return fixed_types [tp.DeclaredPosition];
}
- if (parameter.IsGenericType) {
- Type [] parameter_targs = parameter.GetGenericArguments ();
- for (int ii = 0; ii < parameter_targs.Length; ++ii) {
- parameter_targs [ii] = InflateGenericArgument (parameter_targs [ii]);
+ var gt = parameter as InflatedTypeSpec;
+ if (gt != null) {
+ var inflated_targs = new TypeSpec [gt.TypeArguments.Length];
+ for (int ii = 0; ii < inflated_targs.Length; ++ii) {
+ inflated_targs[ii] = InflateGenericArgument (gt.TypeArguments [ii]);
}
- return parameter.GetGenericTypeDefinition ().MakeGenericType (parameter_targs);
+
+ return gt.GetDefinition ().MakeGenericType (inflated_targs);
}
return parameter;
// Tests whether all delegate input arguments are fixed and generic output type
// requires output type inference
//
- public bool IsReturnTypeNonDependent (ResolveContext ec, MethodSpec invoke, Type returnType)
+ public bool IsReturnTypeNonDependent (ResolveContext ec, MethodSpec invoke, TypeSpec returnType)
{
if (returnType.IsGenericParameter) {
if (IsFixed (returnType))
return false;
- } else if (returnType.IsGenericType) {
+ } else if (TypeManager.IsGenericType (returnType)) {
if (TypeManager.IsDelegateType (returnType)) {
- invoke = Delegate.GetInvokeMethod (ec.Compiler, returnType, returnType);
+ invoke = Delegate.GetInvokeMethod (ec.Compiler, returnType);
return IsReturnTypeNonDependent (ec, invoke, invoke.ReturnType);
}
- Type[] g_args = returnType.GetGenericArguments ();
+ TypeSpec[] g_args = TypeManager.GetTypeArguments (returnType);
// At least one unfixed return type has to exist
if (AllTypesAreFixed (g_args))
return AllTypesAreFixed (d_parameters.Types);
}
- bool IsFixed (Type type)
+ bool IsFixed (TypeSpec type)
{
return IsUnfixed (type) == -1;
}
- int IsUnfixed (Type type)
+ int IsUnfixed (TypeSpec type)
{
if (!type.IsGenericParameter)
return -1;
//
// 26.3.3.9 Lower-bound Inference
//
- public int LowerBoundInference (Type u, Type v)
+ public int LowerBoundInference (TypeSpec u, TypeSpec v)
{
return LowerBoundInference (u, v, false);
}
//
// Lower-bound (false) or Upper-bound (true) inference based on inversed argument
//
- int LowerBoundInference (Type u, Type v, bool inversed)
+ int LowerBoundInference (TypeSpec u, TypeSpec v, bool inversed)
{
// If V is one of the unfixed type arguments
int pos = IsUnfixed (v);
}
// If U is an array type
- if (u.IsArray) {
- int u_dim = u.GetArrayRank ();
- Type v_i;
- Type u_i = TypeManager.GetElementType (u);
-
- if (v.IsArray) {
- if (u_dim != v.GetArrayRank ())
+ var u_ac = u as ArrayContainer;
+ if (u_ac != null) {
+ var v_ac = v as ArrayContainer;
+ if (v_ac != null) {
+ if (u_ac.Rank != v_ac.Rank)
return 0;
- v_i = TypeManager.GetElementType (v);
-
- if (TypeManager.IsValueType (u_i))
- return ExactInference (u_i, v_i);
+ if (TypeManager.IsValueType (u_ac.Element))
+ return ExactInference (u_ac.Element, v_ac.Element);
- return LowerBoundInference (u_i, v_i, inversed);
+ return LowerBoundInference (u_ac.Element, v_ac.Element, inversed);
}
- if (u_dim != 1)
+ if (u_ac.Rank != 1)
return 0;
- if (v.IsGenericType) {
- Type g_v = v.GetGenericTypeDefinition ();
- if ((g_v != TypeManager.generic_ilist_type) && (g_v != TypeManager.generic_icollection_type) &&
- (g_v != TypeManager.generic_ienumerable_type))
+ if (TypeManager.IsGenericType (v)) {
+ TypeSpec g_v = v.GetDefinition ();
+ if (g_v != TypeManager.generic_ilist_type &&
+ g_v != TypeManager.generic_icollection_type &&
+ g_v != TypeManager.generic_ienumerable_type)
return 0;
- v_i = TypeManager.TypeToCoreType (TypeManager.GetTypeArguments (v) [0]);
- if (TypeManager.IsValueType (u_i))
- return ExactInference (u_i, v_i);
+ var v_i = TypeManager.GetTypeArguments (v) [0];
+ if (TypeManager.IsValueType (u_ac.Element))
+ return ExactInference (u_ac.Element, v_i);
- return LowerBoundInference (u_i, v_i);
+ return LowerBoundInference (u_ac.Element, v_i);
}
- } else if (v.IsGenericType && !v.IsGenericTypeDefinition) {
+ } else if (TypeManager.IsGenericType (v)) {
//
// if V is a constructed type C<V1..Vk> and there is a unique type C<U1..Uk>
// such that U is identical to, inherits from (directly or indirectly),
// or implements (directly or indirectly) C<U1..Uk>
//
- var u_candidates = new List<Type> ();
- if (u.IsGenericType)
- u_candidates.Add (u);
+ var u_candidates = new List<TypeSpec> ();
+ var open_v = v.MemberDefinition;
- for (Type t = u.BaseType; t != null; t = t.BaseType) {
- if (t.IsGenericType && !t.IsGenericTypeDefinition)
+ for (TypeSpec t = u; t != null; t = t.BaseType) {
+ if (open_v == t.MemberDefinition)
u_candidates.Add (t);
- }
-
- // TODO: Implement GetGenericInterfaces only and remove
- // the if from foreach
- u_candidates.AddRange (TypeManager.GetInterfaces (u));
- Type open_v = v.GetGenericTypeDefinition ();
- Type [] unique_candidate_targs = null;
- Type [] ga_v = v.GetGenericArguments ();
- foreach (Type u_candidate in u_candidates) {
- if (!u_candidate.IsGenericType || u_candidate.IsGenericTypeDefinition)
- continue;
-
- if (TypeManager.DropGenericTypeArguments (u_candidate) != open_v)
- continue;
+ if (t.Interfaces != null) {
+ foreach (var iface in t.Interfaces) {
+ if (open_v == iface.MemberDefinition)
+ u_candidates.Add (iface);
+ }
+ }
+ }
+ TypeSpec [] unique_candidate_targs = null;
+ TypeSpec[] ga_v = TypeManager.GetTypeArguments (v);
+ foreach (TypeSpec u_candidate in u_candidates) {
//
// The unique set of types U1..Uk means that if we have an interface I<T>,
// class U : I<int>, I<long> then no type inference is made when inferring
// type I<T> by applying type U because T could be int or long
//
if (unique_candidate_targs != null) {
- Type[] second_unique_candidate_targs = u_candidate.GetGenericArguments ();
- if (TypeManager.IsEqual (unique_candidate_targs, second_unique_candidate_targs)) {
+ TypeSpec[] second_unique_candidate_targs = TypeManager.GetTypeArguments (u_candidate);
+ if (TypeSpecComparer.Default.Equals (unique_candidate_targs, second_unique_candidate_targs)) {
unique_candidate_targs = second_unique_candidate_targs;
continue;
}
return 1;
}
- unique_candidate_targs = u_candidate.GetGenericArguments ();
+ unique_candidate_targs = TypeManager.GetTypeArguments (u_candidate);
}
if (unique_candidate_targs != null) {
- Type[] ga_open_v = open_v.GetGenericArguments ();
+ var ga_open_v = open_v.TypeParameters;
int score = 0;
for (int i = 0; i < unique_candidate_targs.Length; ++i) {
- Variance variance = TypeManager.GetTypeParameterVariance (ga_open_v [i]);
+ Variance variance = ga_open_v [i].Variance;
- Type u_i = unique_candidate_targs [i];
+ TypeSpec u_i = unique_candidate_targs [i];
if (variance == Variance.None || TypeManager.IsValueType (u_i)) {
if (ExactInference (u_i, ga_v [i]) == 0)
++score;
//
// 26.3.3.6 Output Type Inference
//
- public int OutputTypeInference (ResolveContext ec, Expression e, Type t)
+ public int OutputTypeInference (ResolveContext ec, Expression e, TypeSpec t)
{
// If e is a lambda or anonymous method with inferred return type
AnonymousMethodExpression ame = e as AnonymousMethodExpression;
if (ame != null) {
- Type rt = ame.InferReturnType (ec, this, t);
- var invoke = Delegate.GetInvokeMethod (ec.Compiler, t, t);
+ TypeSpec rt = ame.InferReturnType (ec, this, t);
+ var invoke = Delegate.GetInvokeMethod (ec.Compiler, t);
if (rt == null) {
AParametersCollection pd = invoke.Parameters;
return ame.Parameters.Count == pd.Count ? 1 : 0;
}
- Type rtype = invoke.ReturnType;
-#if MS_COMPATIBLE
- // Blablabla, because reflection does not work with dynamic types
-// Type [] g_args = t.GetGenericArguments ();
-// rtype = g_args [rtype.GenericParameterPosition];
-#endif
+ TypeSpec rtype = invoke.ReturnType;
return LowerBoundInference (rt, rtype) + 1;
}
if (!TypeManager.IsDelegateType (t))
return 0;
- var invoke = Delegate.GetInvokeMethod (ec.Compiler, t, t);
- Type rtype = invoke.ReturnType;
-#if MS_COMPATIBLE
- // Blablabla, because reflection does not work with dynamic types
-// Type [] g_args = t.GetGenericArguments ();
-// rtype = g_args [rtype.GenericParameterPosition];
-#endif
+ var invoke = Delegate.GetInvokeMethod (ec.Compiler, t);
+ TypeSpec rtype = invoke.ReturnType;
if (!TypeManager.IsGenericType (rtype))
return 0;
return LowerBoundInference (e.Type, t) * 2;
}
- void RemoveDependentTypes (List<Type> types, Type returnType)
+ void RemoveDependentTypes (List<TypeSpec> types, TypeSpec returnType)
{
int idx = IsUnfixed (returnType);
if (idx >= 0) {
return;
}
- if (returnType.IsGenericType) {
- foreach (Type t in returnType.GetGenericArguments ()) {
+ if (TypeManager.IsGenericType (returnType)) {
+ foreach (TypeSpec t in TypeManager.GetTypeArguments (returnType)) {
RemoveDependentTypes (types, t);
}
}
if (unfixed_types == null)
return false;
- foreach (Type ut in unfixed_types)
+ foreach (TypeSpec ut in unfixed_types)
if (ut != null)
return true;
return false;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Linq;
+using System.Collections.Generic;
+using System.Diagnostics;
+using System.Runtime.InteropServices;
namespace Mono.CSharp
{
- static class Import
+ public static class Import
{
- public static FieldSpec CreateField (FieldInfo fi)
+ static Dictionary<Type, TypeSpec> import_cache;
+ static Dictionary<Type, PredefinedTypeSpec> type_2_predefined;
+
+ public static void Initialize ()
{
- // TODO MemberCache: remove
- var cs = TypeManager.GetConstant (fi);
- if (cs != null)
- return cs;
- var fb = TypeManager.GetFieldCore (fi);
- if (fb != null)
- return fb.Spec;
- // End
+ import_cache = new Dictionary<Type, TypeSpec> (1024, ReferenceEquality<Type>.Default);
+
+ // Setup mapping for predefined types
+ type_2_predefined = new Dictionary<Type, PredefinedTypeSpec> () {
+ { typeof (object), TypeManager.object_type },
+ { typeof (System.ValueType), TypeManager.value_type },
+ { typeof (System.Attribute), TypeManager.attribute_type },
+
+ { typeof (int), TypeManager.int32_type },
+ { typeof (long), TypeManager.int64_type },
+ { typeof (uint), TypeManager.uint32_type },
+ { typeof (ulong), TypeManager.uint64_type },
+ { typeof (byte), TypeManager.byte_type },
+ { typeof (sbyte), TypeManager.sbyte_type },
+ { typeof (short), TypeManager.short_type },
+ { typeof (ushort), TypeManager.ushort_type },
+
+ { typeof (System.Collections.IEnumerator), TypeManager.ienumerator_type },
+ { typeof (System.Collections.IEnumerable), TypeManager.ienumerable_type },
+ { typeof (System.IDisposable), TypeManager.idisposable_type },
+
+ { typeof (char), TypeManager.char_type },
+ { typeof (string), TypeManager.string_type },
+ { typeof (float), TypeManager.float_type },
+ { typeof (double), TypeManager.double_type },
+ { typeof (decimal), TypeManager.decimal_type },
+ { typeof (bool), TypeManager.bool_type },
+ { typeof (System.IntPtr), TypeManager.intptr_type },
+ { typeof (System.UIntPtr), TypeManager.uintptr_type },
+
+ { typeof (System.MulticastDelegate), TypeManager.multicast_delegate_type },
+ { typeof (System.Delegate), TypeManager.delegate_type },
+ { typeof (System.Enum), TypeManager.enum_type },
+ { typeof (System.Array), TypeManager.array_type },
+ { typeof (void), TypeManager.void_type },
+ { typeof (System.Type), TypeManager.type_type },
+ { typeof (System.Exception), TypeManager.exception_type },
+ { typeof (System.RuntimeFieldHandle), TypeManager.runtime_field_handle_type },
+ { typeof (System.RuntimeTypeHandle), TypeManager.runtime_handle_type }
+ };
+ }
+ public static FieldSpec CreateField (FieldInfo fi, TypeSpec declaringType)
+ {
Modifiers mod = 0;
var fa = fi.Attributes;
switch (fa & FieldAttributes.FieldAccessMask) {
break;
}
- // TODO MemberCache: Remove completely and use only Imported
- IMemberDefinition definition;
- var gfd = TypeManager.GetGenericFieldDefinition (fi);
- fb = TypeManager.GetFieldCore (gfd);
- if (fb != null) {
- definition = fb;
- } else {
- cs = TypeManager.GetConstant (gfd);
- if (cs != null)
- definition = cs.MemberDefinition;
- else
- definition = new ImportedMemberDefinition (fi);
- }
+ var definition = new ImportedMemberDefinition (fi);
if ((fa & FieldAttributes.Literal) != 0) {
- Expression c;
- if (gfd is System.Reflection.Emit.FieldBuilder) {
- // TODO: Remove after MemberCache
- c = TypeManager.GetConstant (gfd).Value;
- } else {
- c = Constant.CreateConstantFromValue (fi.FieldType, gfd.GetValue (gfd), Location.Null);
- }
-
- return new ConstSpec (definition, fi, mod, c);
+ var c = Constant.CreateConstantFromValue (ImportType (fi.FieldType), fi.GetValue (fi), Location.Null);
+ return new ConstSpec (declaringType, definition, ImportType (fi.FieldType), fi, mod, c);
}
if ((fa & FieldAttributes.InitOnly) != 0) {
- if (fi.FieldType == TypeManager.decimal_type) {
- var dc = ReadDecimalConstant (gfd);
+ if (fi.FieldType == typeof (decimal)) {
+ var dc = ReadDecimalConstant (fi);
if (dc != null)
- return new ConstSpec (definition, fi, mod, dc);
+ return new ConstSpec (declaringType, definition, ImportType (fi.FieldType), fi, mod, dc);
}
mod |= Modifiers.READONLY;
if ((fa & FieldAttributes.Static) != 0)
mod |= Modifiers.STATIC;
- if (!TypeManager.IsReferenceType (fi.FieldType)) {
- PredefinedAttribute pa = PredefinedAttributes.Get.FixedBuffer;
- if (pa.IsDefined) {
- if (gfd is System.Reflection.Emit.FieldBuilder) {
- // TODO: Remove this after MemberCache fix
- } else if (gfd.IsDefined (pa.Type, false)) {
- var element_field = fi.FieldType.GetField (FixedField.FixedElementName);
- return new FixedFieldSpec (definition, fi, element_field, mod);
- }
+ if (fi.FieldType.IsValueType) {
+ if (fi.IsDefined (typeof (FixedBufferAttribute), false)) {
+ var element_field = CreateField (fi.FieldType.GetField (FixedField.FixedElementName), declaringType);
+ return new FixedFieldSpec (declaringType, definition, fi, element_field, mod);
}
}
- // TODO: volatile
+ // TODO: import volatile
- return new FieldSpec (definition, fi, mod);
+ return new FieldSpec (declaringType, definition, ImportType (fi.FieldType), fi, mod);
}
- public static EventSpec CreateEvent (EventInfo ei)
+ public static EventSpec CreateEvent (EventInfo ei, TypeSpec declaringType, MethodSpec add, MethodSpec remove)
{
- // TODO MemberCache: Remove
- var ef = TypeManager.GetEventField (ei);
- if (ef != null)
- return ef;
+ add.IsAccessor = true;
+ remove.IsAccessor = true;
- var add_accessor = CreateMethod (TypeManager.GetAddMethod (ei));
- var remove_accessor = CreateMethod (TypeManager.GetRemoveMethod (ei));
-
- if (add_accessor.Modifiers != remove_accessor.Modifiers)
+ if (add.Modifiers != remove.Modifiers)
throw new NotImplementedException ("Different accessor modifiers " + ei.Name);
var definition = new ImportedMemberDefinition (ei);
- return new EventSpec (definition, ei, add_accessor.Modifiers, add_accessor, remove_accessor) {
- EventType = ei.EventHandlerType
- };
+ return new EventSpec (declaringType, definition, ImportType (ei.EventHandlerType), add.Modifiers, add, remove);
}
- public static MethodSpec CreateMethod (MethodBase mb)
+ static T[] CreateGenericParameters<T> (Type type, TypeSpec declaringType) where T : TypeSpec
{
- // TODO MemberCache: Remove
- MethodCore mc = TypeManager.GetMethod (mb) as MethodCore;
- if (mc != null)
- return mc.Spec;
+ Type[] tparams = type.GetGenericArguments ();
- Modifiers mod = 0;
- var ma = mb.Attributes;
- switch (ma & MethodAttributes.MemberAccessMask) {
- case MethodAttributes.Public:
- mod = Modifiers.PUBLIC;
- break;
- case MethodAttributes.Assembly:
- mod = Modifiers.INTERNAL;
- break;
- case MethodAttributes.Family:
- mod = Modifiers.PROTECTED;
- break;
- case MethodAttributes.FamORAssem:
- mod = Modifiers.PROTECTED | Modifiers.INTERNAL;
- break;
- default:
- mod = Modifiers.PRIVATE;
- break;
- }
+ int parent_owned_count;
+ if (type.IsNested) {
+ parent_owned_count = type.DeclaringType.GetGenericArguments ().Length;
- if ((ma & MethodAttributes.Static) != 0)
- mod |= Modifiers.STATIC;
- if ((ma & MethodAttributes.Virtual) != 0)
- mod |= Modifiers.VIRTUAL;
- if ((ma & MethodAttributes.Abstract) != 0)
- mod |= Modifiers.ABSTRACT;
- if ((ma & MethodAttributes.Final) != 0)
- mod |= Modifiers.SEALED;
+ //
+ // System.Reflection duplicates parent type parameters for each
+ // nested type with slightly modified properties (eg. different owner)
+ // This just makes things more complicated (think of cloned constraints)
+ // therefore we remap any nested type owned by parent using `type_cache'
+ // to the single TypeParameterSpec
+ //
+ if (declaringType != null && parent_owned_count > 0) {
+ int read_count = 0;
+ while (read_count != parent_owned_count) {
+ var tparams_count = declaringType.Arity;
+ if (tparams_count != 0) {
+ var parent_tp = declaringType.MemberDefinition.TypeParameters;
+ read_count += tparams_count;
+ for (int i = 0; i < tparams_count; i++) {
+ import_cache.Add (tparams[parent_owned_count - read_count + i], parent_tp[i]);
+ }
+ }
- IMemberDefinition definition;
- var gmd = mb as MethodInfo;
- if (gmd != null && gmd.IsGenericMethodDefinition) {
- definition = new ImportedGenericMethodDefinition (gmd);
- } else if (mb.IsGenericMethod) { // TODO MemberCache: Remove me
- definition = new ImportedGenericMethodDefinition ((MethodInfo) TypeManager.DropGenericMethodArguments (mb));
+ declaringType = declaringType.DeclaringType;
+ }
+ }
} else {
- definition = new ImportedMemberDefinition (mb);
+ parent_owned_count = 0;
}
- // TODO MemberCache: Use AParametersCollection p = ParametersImported.Create (mb);
- AParametersCollection p = TypeManager.GetParameterData (mb);
+ if (tparams.Length - parent_owned_count == 0)
+ return null;
+
+ return CreateGenericParameters<T> (parent_owned_count, tparams);
+ }
+
+ static T[] CreateGenericParameters<T> (int first, Type[] tparams) where T : TypeSpec
+ {
+ var tspec = new T [tparams.Length - first];
+ for (int pos = first; pos < tparams.Length; ++pos) {
+ tspec [pos - first] = (T) CreateType (tparams [pos]);
+ }
+
+ return tspec;
+ }
+
+ public static MethodSpec CreateMethod (MethodBase mb, TypeSpec declaringType)
+ {
+ Modifiers mod = ReadMethodModifiers (mb, declaringType);
+ //if (declaringType.IsInterface) {
+ // mod = (mod & ~Modifiers.ABSTRACT) | Modifiers.VIRTUAL;
+ //}
+
+ bool is_generic;
+ ImportedMethodDefinition definition;
+
+ var parameters = ParametersImported.Create (declaringType, mb);
+
+ if (mb.IsGenericMethod) {
+ if (!mb.IsGenericMethodDefinition)
+ throw new NotSupportedException ("assert");
+
+ var tparams = CreateGenericParameters<TypeParameterSpec>(0, mb.GetGenericArguments ());
+ definition = new ImportedGenericMethodDefinition ((MethodInfo) mb, parameters, tparams);
+ is_generic = true;
+ } else {
+ definition = new ImportedMethodDefinition (mb, parameters);
+ is_generic = false;
+ }
MemberKind kind;
- if (mb.IsConstructor) {
+ TypeSpec returnType;
+ if (mb.MemberType == MemberTypes.Constructor) {
kind = MemberKind.Constructor;
+ returnType = TypeManager.void_type;
} else {
//
// Detect operators and destructors
string name = mb.Name;
kind = MemberKind.Method;
if (!mb.DeclaringType.IsInterface && name.Length > 6) {
- if ((mod & Modifiers.STATIC) != 0 && name[2] == '_' && name[1] == 'p' && name[0] == 'o') {
- var op_type = Operator.GetType (name);
- if (op_type.HasValue) {
- kind = MemberKind.Operator;
+ if ((mod & (Modifiers.STATIC | Modifiers.PUBLIC)) == (Modifiers.STATIC | Modifiers.PUBLIC)) {
+ if (name[2] == '_' && name[1] == 'p' && name[0] == 'o') {
+ var op_type = Operator.GetType (name);
+ if (op_type.HasValue) {
+ kind = MemberKind.Operator;
+ }
}
- } else if (p.IsEmpty && (mod & Modifiers.STATIC) == 0 && name == Destructor.MetadataName) {
+ } else if (parameters.IsEmpty && name == Destructor.MetadataName) {
kind = MemberKind.Destructor;
}
}
+
+ returnType = ImportType (((MethodInfo)mb).ReturnType);
}
-
- MethodSpec ms = new MethodSpec (kind, definition, mb, p, mod);
+
+ MethodSpec ms = new MethodSpec (kind, declaringType, definition, returnType, mb, parameters, mod);
+ if (is_generic)
+ ms.IsGeneric = true;
+
return ms;
}
- public static PropertySpec CreateProperty (PropertyInfo pi)
+ //
+ // Returns null when the property is not valid C# property
+ //
+ public static PropertySpec CreateProperty (PropertyInfo pi, TypeSpec declaringType, MethodSpec get, MethodSpec set)
{
var definition = new ImportedMemberDefinition (pi);
- var mod = Modifiers.PRIVATE; // TODO: modifiers
- return new PropertySpec (MemberKind.Property | MemberKind.Indexer, definition, pi, mod);
+
+ Modifiers mod = 0;
+ AParametersCollection param = null;
+ TypeSpec type = null;
+ if (get != null) {
+ mod = get.Modifiers;
+ param = get.Parameters;
+ type = get.ReturnType;
+ }
+
+ bool is_valid_property = true;
+ if (set != null) {
+ if (set.ReturnType != TypeManager.void_type)
+ is_valid_property = false;
+
+ var set_param_count = set.Parameters.Count - 1;
+ if (set_param_count < 0)
+ is_valid_property = false;
+
+ var data = new IParameterData [set_param_count];
+ var types = new TypeSpec[set_param_count];
+ for (int i = 0; i < set_param_count; ++i ) {
+ data[i] = set.Parameters.FixedParameters[i];
+ types[i] = set.Parameters.Types[i];
+ }
+
+ var set_param = new ParametersImported (data, types);
+ var set_type = set.Parameters.Types[set_param_count];
+
+ if (mod == 0) {
+ mod = set.Modifiers;
+ param = set_param;
+ type = set_type;
+ } else {
+ if (set_param_count != get.Parameters.Count)
+ is_valid_property = false;
+
+ if (get.ReturnType != set_type)
+ is_valid_property = false;
+
+ // Possible custom accessor modifiers
+ if ((mod & ~Modifiers.AccessibilityMask) != (set.Modifiers & ~Modifiers.AccessibilityMask)) {
+ var get_acc = mod & Modifiers.AccessibilityMask;
+ if (get_acc != Modifiers.PUBLIC) {
+ var set_acc = set.Modifiers & Modifiers.AccessibilityMask;
+ // If the accessor modifiers are not same, do extra restriction checks
+ if (get_acc != set_acc) {
+ var get_restr = ModifiersExtensions.IsRestrictedModifier (get_acc, set_acc);
+ var set_restr = ModifiersExtensions.IsRestrictedModifier (set_acc, get_acc);
+ if (get_restr && set_restr) {
+ is_valid_property = false; // Neither is more restrictive
+ }
+
+ if (set_restr) {
+ mod &= ~Modifiers.AccessibilityMask;
+ mod |= set_acc;
+ }
+ }
+ }
+ }
+ }
+ }
+
+ PropertySpec spec = null;
+ if (!param.IsEmpty) {
+ var index_name = declaringType.MemberDefinition.GetAttributeDefaultMember ();
+ if (index_name == null) {
+ is_valid_property = false;
+ } else {
+ if (get != null) {
+ if (get.IsStatic)
+ is_valid_property = false;
+ if (get.Name.IndexOf (index_name, StringComparison.Ordinal) != 4)
+ is_valid_property = false;
+ }
+ if (set != null) {
+ if (set.IsStatic)
+ is_valid_property = false;
+ if (set.Name.IndexOf (index_name, StringComparison.Ordinal) != 4)
+ is_valid_property = false;
+ }
+ }
+
+ if (is_valid_property)
+ spec = new IndexerSpec (declaringType, definition, type, param, pi, mod);
+ }
+
+ if (spec == null)
+ spec = new PropertySpec (MemberKind.Property, declaringType, definition, type, pi, mod);
+
+ if (!is_valid_property) {
+ spec.IsNotRealProperty = true;
+ return spec;
+ }
+
+ if (set != null)
+ spec.Set = set;
+ if (get != null)
+ spec.Get = get;
+
+ return spec;
}
- static TypeSpec CreateType (Type type)
+ public static TypeSpec CreateType (Type type)
{
- Modifiers mod = 0;
+ return CreateType (type, null);
+ }
+
+ public static TypeSpec CreateType (Type type, TypeSpec declaringType)
+ {
+ TypeSpec spec;
+ if (import_cache.TryGetValue (type, out spec))
+ return spec;
+
+ if (type.IsGenericType && !type.IsGenericTypeDefinition) {
+ var type_def = type.GetGenericTypeDefinition ();
+ spec = CreateType (type_def, declaringType);
+
+ var targs = CreateGenericParameters<TypeSpec> (type, null);
+
+ InflatedTypeSpec inflated;
+ if (targs == null) {
+ // Inflating nested non-generic type, same in TypeSpec::InflateMember
+ inflated = new InflatedTypeSpec (spec, declaringType, TypeSpec.EmptyTypes);
+ } else {
+ // CreateGenericParameters constraint could inflate type
+ if (import_cache.ContainsKey (type))
+ return import_cache[type];
+
+ inflated = spec.MakeGenericType (targs);
+
+ // Use of reading cache to speed up reading only
+ import_cache.Add (type, inflated);
+ }
+
+ return inflated;
+ }
+
+ Modifiers mod;
+ MemberKind kind;
+
var ma = type.Attributes;
switch (ma & TypeAttributes.VisibilityMask) {
- case TypeAttributes.Public:
- case TypeAttributes.NestedPublic:
- mod = Modifiers.PUBLIC;
- break;
- case TypeAttributes.NestedPrivate:
- mod = Modifiers.PRIVATE;
- break;
- case TypeAttributes.NestedFamily:
- mod = Modifiers.PROTECTED;
- break;
- case TypeAttributes.NestedFamORAssem:
- mod = Modifiers.PROTECTED | Modifiers.INTERNAL;
- break;
- default:
- mod = Modifiers.INTERNAL;
- break;
+ case TypeAttributes.Public:
+ case TypeAttributes.NestedPublic:
+ mod = Modifiers.PUBLIC;
+ break;
+ case TypeAttributes.NestedPrivate:
+ mod = Modifiers.PRIVATE;
+ break;
+ case TypeAttributes.NestedFamily:
+ mod = Modifiers.PROTECTED;
+ break;
+ case TypeAttributes.NestedFamORAssem:
+ mod = Modifiers.PROTECTED | Modifiers.INTERNAL;
+ break;
+ default:
+ mod = Modifiers.INTERNAL;
+ break;
}
- var type_def = TypeManager.DropGenericTypeArguments (type);
-
- MemberKind kind;
- if (type_def.IsInterface)
+ if ((ma & TypeAttributes.Interface) != 0) {
kind = MemberKind.Interface;
- else if (type_def.IsEnum)
- kind = MemberKind.Enum;
- else if (type_def.IsClass) {
- if (type_def.BaseType == TypeManager.multicast_delegate_type)
+ } else if (type.IsGenericParameter) {
+ kind = MemberKind.TypeParameter;
+ } else if (type.IsClass || type.IsAbstract) { // SRE: System.Enum returns false for IsClass
+ if ((ma & TypeAttributes.Sealed) != 0 && type.IsSubclassOf (typeof (MulticastDelegate))) {
kind = MemberKind.Delegate;
- else
+ } else {
kind = MemberKind.Class;
+
+ if (type == typeof (object)) {
+#if NET_4_0
+ var pa = PredefinedAttributes.Get.Dynamic.Type;
+ if (pa != null && type.IsDefined (typeof (DynamicAttribute), false))
+ return InternalType.Dynamic;
+#endif
+ }
+
+ if ((ma & TypeAttributes.Sealed) != 0) {
+ mod |= Modifiers.SEALED;
+ if ((ma & TypeAttributes.Abstract) != 0)
+ mod |= Modifiers.STATIC;
+ } else if ((ma & TypeAttributes.Abstract) != 0) {
+ mod |= Modifiers.ABSTRACT;
+ }
+ }
+ } else if (type.IsEnum) {
+ kind = MemberKind.Enum;
} else {
kind = MemberKind.Struct;
+ mod |= Modifiers.SEALED;
}
- if (type.IsGenericType) {
- throw new NotImplementedException ();
+ var definition = new ImportedTypeDefinition (type);
+ PredefinedTypeSpec pt;
+
+ if (kind == MemberKind.Enum) {
+ const BindingFlags any_member = BindingFlags.DeclaredOnly |
+ BindingFlags.Static | BindingFlags.Instance |
+ BindingFlags.Public | BindingFlags.NonPublic;
+
+ var u_type = type.GetField (Enum.UnderlyingValueField, any_member);
+ if (u_type != null) {
+ spec = new EnumSpec (declaringType, definition, Import.CreateType (u_type.FieldType), type, mod);
+ }
+ } else if (kind == MemberKind.TypeParameter) {
+ // Return as type_cache was updated
+ return CreateTypeParameter (type, declaringType);
+ } else if (type.IsGenericTypeDefinition) {
+ definition.TypeParameters = CreateGenericParameters<TypeParameterSpec>(type, declaringType);
+
+ // Constraints are not loaded on demand and can reference this type
+ if (import_cache.TryGetValue (type, out spec))
+ return spec;
+
+ } else if (type_2_predefined.TryGetValue (type, out pt)) {
+ spec = pt;
+ pt.SetDefinition (definition, type);
}
- var definition = new ImportedTypeDefinition (type_def);
- var spec = new TypeSpec (kind, definition, type, type.Name, mod);
+ if (spec == null)
+ spec = new TypeSpec (kind, declaringType, definition, type, mod);
+
+ import_cache.Add (type, spec);
- // TODO: BaseType for class only?
+ if (kind == MemberKind.Interface)
+ spec.BaseType = TypeManager.object_type;
+ else if (type.BaseType != null)
+ spec.BaseType = CreateType (type.BaseType);
+
+ var ifaces = type.GetInterfaces ();
+ if (ifaces.Length > 0) {
+ foreach (Type iface in ifaces) {
+ spec.AddInterface (Import.CreateType (iface));
+ }
+ }
+
+ return spec;
+ }
+
+ static TypeParameterSpec CreateTypeParameter (Type type, TypeSpec declaringType)
+ {
+ Variance variance;
+ switch (type.GenericParameterAttributes & GenericParameterAttributes.VarianceMask) {
+ case GenericParameterAttributes.Covariant:
+ variance = Variance.Covariant;
+ break;
+ case GenericParameterAttributes.Contravariant:
+ variance = Variance.Contravariant;
+ break;
+ default:
+ variance = Variance.None;
+ break;
+ }
+
+ SpecialConstraint special = SpecialConstraint.None;
+ var import_special = type.GenericParameterAttributes & GenericParameterAttributes.SpecialConstraintMask;
+
+ if ((import_special & GenericParameterAttributes.NotNullableValueTypeConstraint) != 0) {
+ special |= SpecialConstraint.Struct;
+ } else if ((import_special & GenericParameterAttributes.DefaultConstructorConstraint) != 0) {
+ special = SpecialConstraint.Constructor;
+ }
+
+ if ((import_special & GenericParameterAttributes.ReferenceTypeConstraint) != 0) {
+ special |= SpecialConstraint.Class;
+ }
+
+ TypeParameterSpec spec;
+ var def = new ImportedTypeParameterDefinition (type);
+ if (type.DeclaringMethod != null)
+ spec = new TypeParameterSpec (type.GenericParameterPosition, def, special, variance, type);
+ else
+ spec = new TypeParameterSpec (declaringType, type.GenericParameterPosition, def, special, variance, type);
+
+ // Add it now, so any constraint can reference it and get same instance
+ import_cache.Add (type, spec);
+
+ var constraints = type.GetGenericParameterConstraints ();
+ foreach (var ct in constraints) {
+ // TODO MemberCache: What to do ??
+ if (ct.IsGenericParameter) {
+ continue;
+ }
+
+ if (ct.IsClass) {
+ if (ct == typeof (ValueType)) {
+ spec.BaseType = TypeManager.value_type;
+ } else {
+ spec.BaseType = CreateType (ct);
+ }
+
+ continue;
+ }
+
+ spec.AddInterface (CreateType (ct));
+ }
+
+ if (spec.BaseType == null)
+ spec.BaseType = TypeManager.object_type;
return spec;
}
public static TypeSpec ImportType (Type type)
{
- if (type.IsDefined (typeof (CompilerGeneratedAttribute), false))
- return null;
+ if (type.HasElementType) {
+ var element = type.GetElementType ();
+ var spec = ImportType (element);
+
+ if (type.IsArray)
+ return ArrayContainer.MakeType (spec, type.GetArrayRank ());
+ if (type.IsByRef)
+ return ReferenceContainer.MakeType (spec);
+ if (type.IsPointer)
+ return PointerContainer.MakeType (spec);
+
+ throw new NotImplementedException ("Unknown element type " + type.ToString ());
+ }
+
+ TypeSpec dtype;
+ if (type.IsNested)
+ dtype = ImportType (type.DeclaringType);
+ else
+ dtype = null;
- return CreateType (type);
+ return CreateType (type, dtype);
}
//
//
static Constant ReadDecimalConstant (FieldInfo fi)
{
- PredefinedAttribute pa = PredefinedAttributes.Get.DecimalConstant;
- if (!pa.IsDefined)
- return null;
-
- object[] attrs = fi.GetCustomAttributes (pa.Type, false);
+ object[] attrs = fi.GetCustomAttributes (typeof (DecimalConstantAttribute), false);
if (attrs.Length != 1)
return null;
return new DecimalConstant (((DecimalConstantAttribute) attrs [0]).Value, Location.Null);
}
+
+ static Modifiers ReadMethodModifiers (MethodBase mb, TypeSpec declaringType)
+ {
+ Modifiers mod;
+ var ma = mb.Attributes;
+ switch (ma & MethodAttributes.MemberAccessMask) {
+ case MethodAttributes.Public:
+ mod = Modifiers.PUBLIC;
+ break;
+ case MethodAttributes.Assembly:
+ mod = Modifiers.INTERNAL;
+ break;
+ case MethodAttributes.Family:
+ mod = Modifiers.PROTECTED;
+ break;
+ case MethodAttributes.FamORAssem:
+ mod = Modifiers.PROTECTED | Modifiers.INTERNAL;
+ break;
+ default:
+ mod = Modifiers.PRIVATE;
+ break;
+ }
+
+ if ((ma & MethodAttributes.Static) != 0) {
+ mod |= Modifiers.STATIC;
+ } else if ((ma & MethodAttributes.Final) != 0) {
+ mod |= Modifiers.SEALED;
+ } else if ((ma & MethodAttributes.Abstract) != 0 && declaringType.IsClass) {
+ mod |= Modifiers.ABSTRACT;
+ }
+
+ // It can be sealed and override
+ if ((ma & MethodAttributes.Virtual) != 0) {
+ if ((ma & MethodAttributes.NewSlot) != 0 || !declaringType.IsClass || mod == Modifiers.PRIVATE) {
+ mod |= Modifiers.VIRTUAL;
+ } else {
+ // Cannot set to OVERRIDE without full hierarchy checks
+ // this flag indicates that the method could be override
+ // but further validation is needed
+ mod |= Modifiers.OVERRIDE_UNCHECKED;
+ }
+ }
+
+ return mod;
+ }
}
class ImportedMemberDefinition : IMemberDefinition
{
- protected readonly ICustomAttributeProvider provider;
+ protected class AttributesBag
+ {
+ public static readonly AttributesBag Default = new AttributesBag ();
+
+ public AttributeUsageAttribute AttributeUsage;
+ public ObsoleteAttribute Obsolete;
+ public string[] Conditionals;
+ public string DefaultIndexerName;
+ public bool IsNotCLSCompliant;
+
+ public static AttributesBag Read (MemberInfo mi)
+ {
+ AttributesBag bag = null;
+ List<string> conditionals = null;
+
+ var attrs = CustomAttributeData.GetCustomAttributes (mi);
+ foreach (var a in attrs) {
+ var type = a.Constructor.DeclaringType;
+ if (type == typeof (ObsoleteAttribute)) {
+ if (bag == null)
+ bag = new AttributesBag ();
+
+ var args = a.ConstructorArguments;
+
+ if (args.Count == 1) {
+ bag.Obsolete = new ObsoleteAttribute ((string) args[0].Value);
+ } else if (args.Count == 2) {
+ bag.Obsolete = new ObsoleteAttribute ((string) args[0].Value, (bool) args[1].Value);
+ } else {
+ bag.Obsolete = new ObsoleteAttribute ();
+ }
+
+ continue;
+ }
+
+ if (type == typeof (ConditionalAttribute)) {
+ if (bag == null)
+ bag = new AttributesBag ();
+
+ if (conditionals == null)
+ conditionals = new List<string> (2);
+
+ conditionals.Add ((string) a.ConstructorArguments[0].Value);
+ continue;
+ }
+
+ if (type == typeof (CLSCompliantAttribute)) {
+ if (bag == null)
+ bag = new AttributesBag ();
+
+ bag.IsNotCLSCompliant = !(bool) a.ConstructorArguments[0].Value;
+ continue;
+ }
+
+ // Type only attributes
+ if (type == typeof (DefaultMemberAttribute)) {
+ if (bag == null)
+ bag = new AttributesBag ();
+
+ bag.DefaultIndexerName = (string) a.ConstructorArguments[0].Value;
+ continue;
+ }
+
+ if (type == typeof (AttributeUsageAttribute)) {
+ if (bag == null)
+ bag = new AttributesBag ();
+
+ bag.AttributeUsage = new AttributeUsageAttribute ((AttributeTargets) a.ConstructorArguments[0].Value);
+ foreach (var named in a.NamedArguments) {
+ if (named.MemberInfo.Name == "AllowMultiple")
+ bag.AttributeUsage.AllowMultiple = (bool) named.TypedValue.Value;
+ else if (named.MemberInfo.Name == "Inherited")
+ bag.AttributeUsage.Inherited = (bool) named.TypedValue.Value;
+ }
+ continue;
+ }
+ }
+
+ if (bag == null)
+ return Default;
+
+ if (conditionals != null)
+ bag.Conditionals = conditionals.ToArray ();
+
+ return bag;
+ }
+ }
+
+ protected readonly MemberInfo provider;
+ protected AttributesBag cattrs;
- public ImportedMemberDefinition (ICustomAttributeProvider provider)
+ public ImportedMemberDefinition (MemberInfo provider)
{
this.provider = provider;
}
- public ObsoleteAttribute GetObsoleteAttribute ()
+ #region Properties
+
+ public Assembly Assembly {
+ get {
+ return provider.Module.Assembly;
+ }
+ }
+
+ public bool IsImported {
+ get {
+ return true;
+ }
+ }
+
+ public virtual string Name {
+ get {
+ return provider.Name;
+ }
+ }
+
+ #endregion
+
+ public string[] ConditionalConditions ()
{
- var res = provider.GetCustomAttributes (typeof (ObsoleteAttribute), false);
- if (res == null || res.Length < 1)
- return null;
+ if (cattrs == null)
+ ReadAttributes ();
- return res [0] as ObsoleteAttribute;
+ return cattrs.Conditionals;
+ }
+
+ public ObsoleteAttribute GetAttributeObsolete ()
+ {
+ if (cattrs == null)
+ ReadAttributes ();
+
+ return cattrs.Obsolete;
+ }
+
+ public bool IsNotCLSCompliant ()
+ {
+ if (cattrs == null)
+ ReadAttributes ();
+
+ return cattrs.IsNotCLSCompliant;
+ }
+
+ protected void ReadAttributes ()
+ {
+ cattrs = AttributesBag.Read (provider);
+ }
+
+ public void SetIsAssigned ()
+ {
+ // Unused for imported members
}
public void SetIsUsed ()
}
}
- class ImportedGenericMethodDefinition : ImportedMemberDefinition, IGenericMethodDefinition
+ class ImportedMethodDefinition : ImportedMemberDefinition, IParametersMember
{
- public ImportedGenericMethodDefinition (MethodInfo provider)
+ readonly AParametersCollection parameters;
+
+ public ImportedMethodDefinition (MethodBase provider, AParametersCollection parameters)
: base (provider)
{
+ this.parameters = parameters;
+ }
+
+ #region Properties
+
+ public AParametersCollection Parameters {
+ get {
+ return parameters;
+ }
}
- public MethodInfo MakeGenericMethod (Type[] targs)
+ public TypeSpec MemberType {
+ get {
+ throw new NotImplementedException ();
+ }
+ }
+
+ #endregion
+ }
+
+ class ImportedGenericMethodDefinition : ImportedMethodDefinition, IGenericMethodDefinition
+ {
+ TypeParameterSpec[] tparams;
+
+ public ImportedGenericMethodDefinition (MethodInfo provider, AParametersCollection parameters, TypeParameterSpec[] tparams)
+ : base (provider, parameters)
{
- return ((MethodInfo) provider).MakeGenericMethod (targs);
+ this.tparams = tparams;
+ }
+
+ #region Properties
+
+ public TypeParameterSpec[] TypeParameters {
+ get {
+ return tparams;
+ }
}
+
+ public int TypeParametersCount {
+ get {
+ return tparams.Length;
+ }
+ }
+
+ #endregion
}
class ImportedTypeDefinition : ImportedMemberDefinition, ITypeDefinition
{
+ TypeParameterSpec[] tparams;
+ string name;
+
public ImportedTypeDefinition (Type type)
: base (type)
{
}
- public void LoadMembers (MemberCache cache)
+ #region Properties
+
+ public override string Name {
+ get {
+ if (name == null) {
+ name = base.Name;
+ if (tparams != null)
+ name = name.Substring (0, name.IndexOf ('`'));
+ }
+
+ return name;
+ }
+ }
+
+ public string Namespace {
+ get {
+ return ((Type) provider).Namespace;
+ }
+ }
+
+ public int TypeParametersCount {
+ get {
+ return tparams == null ? 0 : tparams.Length;
+ }
+ }
+
+ public TypeParameterSpec[] TypeParameters {
+ get {
+ return tparams;
+ }
+ set {
+ tparams = value;
+ }
+ }
+
+ #endregion
+
+ public TypeSpec GetAttributeCoClass ()
+ {
+ // TODO: Use ReadAttributes
+ var attr = provider.GetCustomAttributes (typeof (CoClassAttribute), false);
+ if (attr.Length < 1)
+ return null;
+
+ return Import.CreateType (((CoClassAttribute) attr[0]).CoClass);
+ }
+
+ public string GetAttributeDefaultMember ()
+ {
+ if (cattrs == null)
+ ReadAttributes ();
+
+ return cattrs.DefaultIndexerName;
+ }
+
+ public AttributeUsageAttribute GetAttributeUsage (PredefinedAttribute pa)
+ {
+ if (cattrs == null)
+ ReadAttributes ();
+
+ return cattrs.AttributeUsage;
+ }
+
+ public MemberCache LoadMembers (TypeSpec declaringType)
+ {
+ var loading_type = (Type) provider;
+ const BindingFlags all_members = BindingFlags.DeclaredOnly |
+ BindingFlags.Static | BindingFlags.Instance |
+ BindingFlags.Public | BindingFlags.NonPublic;
+
+ const MethodAttributes explicit_impl = MethodAttributes.NewSlot |
+ MethodAttributes.Virtual | MethodAttributes.HideBySig |
+ MethodAttributes.Final | MethodAttributes.Private;
+
+ Dictionary<MethodBase, MethodSpec> possible_accessors = null;
+ MemberSpec imported;
+ MethodInfo m;
+ List<string> fields_to_ignore = null;
+
+ //
+ // This requires methods to be returned first which seems to work for both Mono and .NET
+ //
+ var all = loading_type.GetMembers (all_members);
+
+ var cache = new MemberCache (all.Length);
+ foreach (var member in all) {
+ switch (member.MemberType) {
+ case MemberTypes.Constructor:
+ case MemberTypes.Method:
+ MethodBase mb = (MethodBase) member;
+
+ // Ignore explicitly implemented members
+ if ((mb.Attributes & explicit_impl) == explicit_impl)
+ continue;
+
+ // Ignore compiler generated methods
+ if (mb.IsPrivate && mb.IsDefined (typeof (CompilerGeneratedAttribute), false))
+ continue;
+
+ imported = Import.CreateMethod (mb, declaringType);
+ var name = imported.Name;
+ if (imported.Kind == MemberKind.Method && name.Length > 4) {
+ if ((name[3] == '_' && (name.StartsWith ("get", StringComparison.Ordinal) ||
+ name.StartsWith ("set", StringComparison.Ordinal) ||
+ name.StartsWith ("add", StringComparison.Ordinal))) ||
+ name.Length > 7 && name[6] == '_' && name.StartsWith ("remove", StringComparison.Ordinal)) {
+
+ if (possible_accessors == null)
+ possible_accessors = new Dictionary<MethodBase, MethodSpec> ();
+
+ possible_accessors.Add (mb, (MethodSpec) imported);
+ }
+ }
+
+ break;
+ case MemberTypes.Property:
+ if (possible_accessors == null)
+ continue;
+
+ var p = (PropertyInfo) member;
+ //
+ // Links possible accessors with property
+ //
+ MethodSpec get, set;
+ m = p.GetGetMethod (true);
+ if (m == null || !possible_accessors.TryGetValue (m, out get))
+ get = null;
+
+ m = p.GetSetMethod (true);
+ if (m == null || !possible_accessors.TryGetValue (m, out set))
+ set = null;
+
+ // No accessors registered (e.g. explicit implementation)
+ if (get == null && set == null)
+ continue;
+
+ imported = Import.CreateProperty (p, declaringType, get, set);
+ if (imported == null)
+ continue;
+
+ break;
+ case MemberTypes.Event:
+ if (possible_accessors == null)
+ continue;
+
+ var e = (EventInfo) member;
+ //
+ // Links accessors with event
+ //
+ MethodSpec add, remove;
+ m = e.GetAddMethod (true);
+ if (m == null || !possible_accessors.TryGetValue (m, out add))
+ add = null;
+
+ m = e.GetRemoveMethod (true);
+ if (m == null || !possible_accessors.TryGetValue (m, out remove))
+ remove = null;
+
+ // Both accessors are required
+ if (add == null || remove == null)
+ continue;
+
+ if (fields_to_ignore == null)
+ fields_to_ignore = new List<string> ();
+
+ fields_to_ignore.Add (e.Name);
+
+ imported = Import.CreateEvent (e, declaringType, add, remove);
+ break;
+ case MemberTypes.Field:
+ var fi = (FieldInfo) member;
+
+ // Ignore compiler generated fields
+ if (fi.IsPrivate && fi.IsDefined (typeof (CompilerGeneratedAttribute), false))
+ continue;
+
+ if (fields_to_ignore != null && fields_to_ignore.Contains (fi.Name))
+ continue;
+
+ imported = Import.CreateField (fi, declaringType);
+ break;
+ case MemberTypes.NestedType:
+ Type t = (Type) member;
+
+ // Ignore compiler generated types, mostly lambda containers
+ if (t.IsNotPublic && t.IsDefined (typeof (CompilerGeneratedAttribute), false))
+ continue;
+
+ imported = Import.CreateType (t, declaringType);
+ break;
+ default:
+ throw new NotImplementedException (member.ToString ());
+ }
+
+ cache.AddMember (imported);
+ }
+
+ if (declaringType.IsInterface && declaringType.Interfaces != null) {
+ foreach (var iface in declaringType.Interfaces) {
+ cache.AddInterface (iface);
+ }
+ }
+
+ return cache;
+ }
+ }
+
+ class ImportedTypeParameterDefinition : ImportedMemberDefinition, ITypeDefinition
+ {
+ public ImportedTypeParameterDefinition (Type type)
+ : base (type)
+ {
+ }
+
+ #region Properties
+
+ public string Namespace {
+ get {
+ return null;
+ }
+ }
+
+ public int TypeParametersCount {
+ get {
+ return 0;
+ }
+ }
+
+ public TypeParameterSpec[] TypeParameters {
+ get {
+ return null;
+ }
+ }
+
+ #endregion
+
+ public TypeSpec GetAttributeCoClass ()
+ {
+ return null;
+ }
+
+ public string GetAttributeDefaultMember ()
+ {
+ throw new NotSupportedException ();
+ }
+
+ public AttributeUsageAttribute GetAttributeUsage (PredefinedAttribute pa)
+ {
+ throw new NotSupportedException ();
+ }
+
+ public MemberCache LoadMembers (TypeSpec declaringType)
{
throw new NotImplementedException ();
}
return true;
}
- public override void MutateHoistedGenericType (AnonymousMethodStorey storey)
- {
- expr.MutateHoistedGenericType (storey);
- }
-
public override bool Resolve (BlockContext ec)
{
expr = expr.Resolve (ec);
protected override void DoEmit (EmitContext ec)
{
- iterator.EmitYieldBreak (ec.ig, unwind_protect);
- }
-
- public override void MutateHoistedGenericType (AnonymousMethodStorey storey)
- {
- // nothing to do
+ iterator.EmitYieldBreak (ec, unwind_protect);
}
}
{
iterator.EmitMoveNext (ec, original_block);
}
-
- public override void MutateHoistedGenericType (AnonymousMethodStorey storey)
- {
- original_block.MutateHoistedGenericType (storey);
- iterator.MutateHoistedGenericType (storey);
- }
}
public class IteratorStorey : AnonymousMethodStorey
public override bool Resolve (BlockContext ec)
{
- TypeExpression storey_type_expr = new TypeExpression (host.TypeBuilder, loc);
+ TypeExpression storey_type_expr = new TypeExpression (host.Definition, loc);
List<Expression> init = null;
if (host.hoisted_this != null) {
init = new List<Expression> (host.hoisted_params == null ? 1 : host.HoistedParameters.Count + 1);
new_storey = Convert.ImplicitConversionRequired (ec, new_storey, host_method.MemberType, loc);
if (TypeManager.int_interlocked_compare_exchange == null) {
- Type t = TypeManager.CoreLookupType (ec.Compiler, "System.Threading", "Interlocked", MemberKind.Class, true);
+ TypeSpec t = TypeManager.CoreLookupType (ec.Compiler, "System.Threading", "Interlocked", MemberKind.Class, true);
if (t != null) {
- TypeManager.int_interlocked_compare_exchange = TypeManager.GetPredefinedMethod (
- t, "CompareExchange", loc, TypeManager.int32_type,
- TypeManager.int32_type, TypeManager.int32_type);
+ var p = ParametersCompiled.CreateFullyResolved (
+ new[] {
+ new ParameterData (null, Parameter.Modifier.REF),
+ new ParameterData (null, Parameter.Modifier.NONE),
+ new ParameterData (null, Parameter.Modifier.NONE)
+ },
+ new[] {
+ TypeManager.int32_type, TypeManager.int32_type, TypeManager.int32_type
+ }
+ );
+ var f = new MemberFilter ("CompareExchange", 0, MemberKind.Method, p, TypeManager.int32_type);
+ TypeManager.int_interlocked_compare_exchange = TypeManager.GetPredefinedMethod (t, f, loc);
}
}
protected override void DoEmit (EmitContext ec)
{
- ILGenerator ig = ec.ig;
- Label label_init = ig.DefineLabel ();
+ Label label_init = ec.DefineLabel ();
- ig.Emit (OpCodes.Ldarg_0);
- ig.Emit (OpCodes.Ldflda, host.PC.Spec.MetaInfo);
- IntConstant.EmitInt (ig, (int) Iterator.State.Start);
- IntConstant.EmitInt (ig, (int) Iterator.State.Uninitialized);
- ig.Emit (OpCodes.Call, (MethodInfo) TypeManager.int_interlocked_compare_exchange.MetaInfo);
+ ec.Emit (OpCodes.Ldarg_0);
+ ec.Emit (OpCodes.Ldflda, host.PC.Spec);
+ ec.EmitInt ((int) Iterator.State.Start);
+ ec.EmitInt ((int) Iterator.State.Uninitialized);
+ ec.Emit (OpCodes.Call, TypeManager.int_interlocked_compare_exchange);
- IntConstant.EmitInt (ig, (int) Iterator.State.Uninitialized);
- ig.Emit (OpCodes.Bne_Un_S, label_init);
+ ec.EmitInt ((int) Iterator.State.Uninitialized);
+ ec.Emit (OpCodes.Bne_Un_S, label_init);
- ig.Emit (OpCodes.Ldarg_0);
- ig.Emit (OpCodes.Ret);
+ ec.Emit (OpCodes.Ldarg_0);
+ ec.Emit (OpCodes.Ret);
- ig.MarkLabel (label_init);
+ ec.MarkLabel (label_init);
new_storey.Emit (ec);
- ig.Emit (OpCodes.Ret);
- }
-
- public override void MutateHoistedGenericType (AnonymousMethodStorey storey)
- {
- throw new NotSupportedException ();
+ ec.Emit (OpCodes.Ret);
}
}
{
iterator.EmitDispose (ec);
}
-
- public override void MutateHoistedGenericType (AnonymousMethodStorey storey)
- {
- throw new NotSupportedException ();
- }
}
public DisposeMethod (IteratorStorey host)
protected override Expression DoResolve (ResolveContext ec)
{
- Methods = new [] { method.Spec };
- type = method.Parent.TypeBuilder;
+ Methods = new List<MemberSpec> (1) { method.Spec };
+ type = method.Parent.Definition;
InstanceExpression = new CompilerGeneratedThis (type, Location);
return base.DoResolve (ec);
}
protected override Expression DoResolve (ResolveContext ec)
{
spec = field.Spec;
- type = TypeManager.TypeToCoreType (spec.FieldType);
+ type = spec.MemberType;
InstanceExpression = new CompilerGeneratedThis (type, Location);
return base.DoResolve (ec);
}
protected override TypeExpr [] ResolveBaseTypes (out TypeExpr base_class)
{
- iterator_type_expr = new TypeExpression (MutateType (Iterator.OriginalIteratorType), Location);
+ var mtype = Iterator.OriginalIteratorType;
+ if (Mutator != null)
+ mtype = Mutator.Mutate (mtype);
+
+ iterator_type_expr = new TypeExpression (mtype, Location);
generic_args = new TypeArguments (iterator_type_expr);
var list = new List<FullNamedExpression> ();
return "<" + local_info.Name + ">__" + local_name_idx++.ToString ();
}
- public void DefineIteratorMembers ()
+ protected override bool DoDefineMembers ()
+ {
+ DefineIteratorMembers ();
+ return base.DoDefineMembers ();
+ }
+
+ void DefineIteratorMembers ()
{
pc_field = AddCompilerGeneratedField ("$PC", TypeManager.system_int32_expr);
current_field = AddCompilerGeneratedField ("$current", iterator_type_expr);
reset.Block = new ToplevelBlock (Compiler, Location);
- Type ex_type = TypeManager.CoreLookupType (Compiler, "System", "NotSupportedException", MemberKind.Class, true);
+ TypeSpec ex_type = TypeManager.CoreLookupType (Compiler, "System", "NotSupportedException", MemberKind.Class, true);
if (ex_type == null)
return;
get { return OriginalMethod.GenericMethod; }
}
- public readonly Type OriginalIteratorType;
+ public readonly TypeSpec OriginalIteratorType;
readonly IteratorStorey IteratorHost;
Start = 0
}
- public void EmitYieldBreak (ILGenerator ig, bool unwind_protect)
+ public void EmitYieldBreak (EmitContext ec, bool unwind_protect)
{
- ig.Emit (unwind_protect ? OpCodes.Leave : OpCodes.Br, move_next_error);
+ ec.Emit (unwind_protect ? OpCodes.Leave : OpCodes.Br, move_next_error);
}
void EmitMoveNext_NoResumePoints (EmitContext ec, Block original_block)
{
- ILGenerator ig = ec.ig;
-
- ig.Emit (OpCodes.Ldarg_0);
- ig.Emit (OpCodes.Ldfld, IteratorHost.PC.Spec.MetaInfo);
+ ec.Emit (OpCodes.Ldarg_0);
+ ec.Emit (OpCodes.Ldfld, IteratorHost.PC.Spec);
- ig.Emit (OpCodes.Ldarg_0);
- IntConstant.EmitInt (ig, (int) State.After);
- ig.Emit (OpCodes.Stfld, IteratorHost.PC.Spec.MetaInfo);
+ ec.Emit (OpCodes.Ldarg_0);
+ ec.EmitInt ((int) State.After);
+ ec.Emit (OpCodes.Stfld, IteratorHost.PC.Spec);
// We only care if the PC is zero (start executing) or non-zero (don't do anything)
- ig.Emit (OpCodes.Brtrue, move_next_error);
+ ec.Emit (OpCodes.Brtrue, move_next_error);
- SymbolWriter.StartIteratorBody (ec.ig);
+ SymbolWriter.StartIteratorBody (ec);
original_block.Emit (ec);
- SymbolWriter.EndIteratorBody (ec.ig);
+ SymbolWriter.EndIteratorBody (ec);
- ig.MarkLabel (move_next_error);
- ig.Emit (OpCodes.Ldc_I4_0);
- ig.Emit (OpCodes.Ret);
+ ec.MarkLabel (move_next_error);
+ ec.Emit (OpCodes.Ldc_I4_0);
+ ec.Emit (OpCodes.Ret);
}
internal void EmitMoveNext (EmitContext ec, Block original_block)
{
- ILGenerator ig = ec.ig;
-
- move_next_ok = ig.DefineLabel ();
- move_next_error = ig.DefineLabel ();
+ move_next_ok = ec.DefineLabel ();
+ move_next_error = ec.DefineLabel ();
if (resume_points == null) {
EmitMoveNext_NoResumePoints (ec, original_block);
}
current_pc = ec.GetTemporaryLocal (TypeManager.uint32_type);
- ig.Emit (OpCodes.Ldarg_0);
- ig.Emit (OpCodes.Ldfld, IteratorHost.PC.Spec.MetaInfo);
- ig.Emit (OpCodes.Stloc, current_pc);
+ ec.Emit (OpCodes.Ldarg_0);
+ ec.Emit (OpCodes.Ldfld, IteratorHost.PC.Spec);
+ ec.Emit (OpCodes.Stloc, current_pc);
// We're actually in state 'running', but this is as good a PC value as any if there's an abnormal exit
- ig.Emit (OpCodes.Ldarg_0);
- IntConstant.EmitInt (ig, (int) State.After);
- ig.Emit (OpCodes.Stfld, IteratorHost.PC.Spec.MetaInfo);
+ ec.Emit (OpCodes.Ldarg_0);
+ ec.EmitInt ((int) State.After);
+ ec.Emit (OpCodes.Stfld, IteratorHost.PC.Spec);
Label [] labels = new Label [1 + resume_points.Count];
- labels [0] = ig.DefineLabel ();
+ labels [0] = ec.DefineLabel ();
bool need_skip_finally = false;
for (int i = 0; i < resume_points.Count; ++i) {
if (need_skip_finally) {
skip_finally = ec.GetTemporaryLocal (TypeManager.bool_type);
- ig.Emit (OpCodes.Ldc_I4_0);
- ig.Emit (OpCodes.Stloc, skip_finally);
+ ec.Emit (OpCodes.Ldc_I4_0);
+ ec.Emit (OpCodes.Stloc, skip_finally);
}
- SymbolWriter.StartIteratorDispatcher (ec.ig);
- ig.Emit (OpCodes.Ldloc, current_pc);
- ig.Emit (OpCodes.Switch, labels);
+ SymbolWriter.StartIteratorDispatcher (ec);
+ ec.Emit (OpCodes.Ldloc, current_pc);
+ ec.Emit (OpCodes.Switch, labels);
- ig.Emit (OpCodes.Br, move_next_error);
- SymbolWriter.EndIteratorDispatcher (ec.ig);
+ ec.Emit (OpCodes.Br, move_next_error);
+ SymbolWriter.EndIteratorDispatcher (ec);
- ig.MarkLabel (labels [0]);
+ ec.MarkLabel (labels [0]);
- SymbolWriter.StartIteratorBody (ec.ig);
+ SymbolWriter.StartIteratorBody (ec);
original_block.Emit (ec);
- SymbolWriter.EndIteratorBody (ec.ig);
+ SymbolWriter.EndIteratorBody (ec);
- SymbolWriter.StartIteratorDispatcher (ec.ig);
+ SymbolWriter.StartIteratorDispatcher (ec);
- ig.Emit (OpCodes.Ldarg_0);
- IntConstant.EmitInt (ig, (int) State.After);
- ig.Emit (OpCodes.Stfld, IteratorHost.PC.Spec.MetaInfo);
+ ec.Emit (OpCodes.Ldarg_0);
+ ec.EmitInt ((int) State.After);
+ ec.Emit (OpCodes.Stfld, IteratorHost.PC.Spec);
- ig.MarkLabel (move_next_error);
- ig.Emit (OpCodes.Ldc_I4_0);
- ig.Emit (OpCodes.Ret);
+ ec.MarkLabel (move_next_error);
+ ec.EmitInt (0);
+ ec.Emit (OpCodes.Ret);
- ig.MarkLabel (move_next_ok);
- ig.Emit (OpCodes.Ldc_I4_1);
- ig.Emit (OpCodes.Ret);
+ ec.MarkLabel (move_next_ok);
+ ec.Emit (OpCodes.Ldc_I4_1);
+ ec.Emit (OpCodes.Ret);
- SymbolWriter.EndIteratorDispatcher (ec.ig);
+ SymbolWriter.EndIteratorDispatcher (ec);
}
public void EmitDispose (EmitContext ec)
{
- ILGenerator ig = ec.ig;
-
- Label end = ig.DefineLabel ();
+ Label end = ec.DefineLabel ();
Label [] labels = null;
int n_resume_points = resume_points == null ? 0 : resume_points.Count;
if (labels != null) {
current_pc = ec.GetTemporaryLocal (TypeManager.uint32_type);
- ig.Emit (OpCodes.Ldarg_0);
- ig.Emit (OpCodes.Ldfld, IteratorHost.PC.Spec.MetaInfo);
- ig.Emit (OpCodes.Stloc, current_pc);
+ ec.Emit (OpCodes.Ldarg_0);
+ ec.Emit (OpCodes.Ldfld, IteratorHost.PC.Spec);
+ ec.Emit (OpCodes.Stloc, current_pc);
}
- ig.Emit (OpCodes.Ldarg_0);
- IntConstant.EmitInt (ig, (int) State.After);
- ig.Emit (OpCodes.Stfld, IteratorHost.PC.Spec.MetaInfo);
+ ec.Emit (OpCodes.Ldarg_0);
+ ec.EmitInt ((int) State.After);
+ ec.Emit (OpCodes.Stfld, IteratorHost.PC.Spec);
if (labels != null) {
//SymbolWriter.StartIteratorDispatcher (ec.ig);
- ig.Emit (OpCodes.Ldloc, current_pc);
- ig.Emit (OpCodes.Switch, labels);
+ ec.Emit (OpCodes.Ldloc, current_pc);
+ ec.Emit (OpCodes.Switch, labels);
//SymbolWriter.EndIteratorDispatcher (ec.ig);
foreach (ResumableStatement s in resume_points)
s.EmitForDispose (ec, this, end, true);
}
- ig.MarkLabel (end);
+ ec.MarkLabel (end);
}
public int AddResumePoint (ResumableStatement stmt)
//
public void MarkYield (EmitContext ec, Expression expr, int resume_pc, bool unwind_protect, Label resume_point)
{
- ILGenerator ig = ec.ig;
-
// Store the new current
- ig.Emit (OpCodes.Ldarg_0);
+ ec.Emit (OpCodes.Ldarg_0);
expr.Emit (ec);
- ig.Emit (OpCodes.Stfld, IteratorHost.CurrentField.Spec.MetaInfo);
+ ec.Emit (OpCodes.Stfld, IteratorHost.CurrentField.Spec);
// store resume program-counter
- ig.Emit (OpCodes.Ldarg_0);
- IntConstant.EmitInt (ig, resume_pc);
- ig.Emit (OpCodes.Stfld, IteratorHost.PC.Spec.MetaInfo);
+ ec.Emit (OpCodes.Ldarg_0);
+ ec.EmitInt (resume_pc);
+ ec.Emit (OpCodes.Stfld, IteratorHost.PC.Spec);
// mark finally blocks as disabled
if (unwind_protect && skip_finally != null) {
- ig.Emit (OpCodes.Ldc_I4_1);
- ig.Emit (OpCodes.Stloc, skip_finally);
+ ec.EmitInt (1);
+ ec.Emit (OpCodes.Stloc, skip_finally);
}
// Return ok
- ig.Emit (unwind_protect ? OpCodes.Leave : OpCodes.Br, move_next_ok);
+ ec.Emit (unwind_protect ? OpCodes.Leave : OpCodes.Br, move_next_ok);
- ig.MarkLabel (resume_point);
+ ec.MarkLabel (resume_point);
}
public override string ContainerType {
//
// Our constructor
//
- private Iterator (CompilerContext ctx, IMethodData method, TypeContainer host, Type iterator_type, bool is_enumerable)
+ private Iterator (CompilerContext ctx, IMethodData method, TypeContainer host, TypeSpec iterator_type, bool is_enumerable)
: base (
new ToplevelBlock (ctx, method.Block, ParametersCompiled.EmptyReadOnlyParameters, method.Block.StartLocation),
TypeManager.bool_type,
if (Compatible (ec) == null)
return null;
- IteratorHost.DefineIteratorMembers ();
-
eclass = ExprClass.Value;
return this;
}
// Initialize iterator PC when it's unitialized
//
if (IsEnumerable) {
- ILGenerator ig = ec.ig;
- ig.Emit (OpCodes.Dup);
- IntConstant.EmitInt (ig, (int)State.Uninitialized);
+ ec.Emit (OpCodes.Dup);
+ ec.EmitInt ((int)State.Uninitialized);
- FieldInfo field = IteratorHost.PC.Spec.MetaInfo;
- if (Storey.MemberName.IsGeneric)
- field = TypeBuilder.GetField (Storey.Instance.Type, field);
+ var field = IteratorHost.PC.Spec;
+ if (Storey.MemberName.IsGeneric) {
+ field = MemberCache.GetMember (Storey.Instance.Type, field);
+ }
- ig.Emit (OpCodes.Stfld, field);
+ ec.Emit (OpCodes.Stfld, field);
}
}
public static void CreateIterator (IMethodData method, TypeContainer parent, Modifiers modifiers, CompilerContext ctx)
{
bool is_enumerable;
- Type iterator_type;
+ TypeSpec iterator_type;
- Type ret = method.ReturnType;
+ TypeSpec ret = method.ReturnType;
if (ret == null)
return;
return;
}
- Iterator iter = new Iterator (ctx, method, parent, iterator_type, is_enumerable);
- iter.Storey.DefineType ();
+ // TODO: Ugly leftover
+ new Iterator (ctx, method, parent, iterator_type, is_enumerable);
}
- static bool CheckType (Type ret, out Type original_iterator_type, out bool is_enumerable)
+ static bool CheckType (TypeSpec ret, out TypeSpec original_iterator_type, out bool is_enumerable)
{
original_iterator_type = null;
is_enumerable = false;
return true;
}
- if (!TypeManager.IsGenericType (ret))
- return false;
-
- Type[] args = TypeManager.GetTypeArguments (ret);
- if (args.Length != 1)
+ InflatedTypeSpec inflated = ret as InflatedTypeSpec;
+ if (inflated == null)
return false;
- Type gt = TypeManager.DropGenericTypeArguments (ret);
- if (gt == TypeManager.generic_ienumerable_type) {
- original_iterator_type = TypeManager.TypeToCoreType (args [0]);
+ ret = inflated.GetDefinition ();
+ if (ret == TypeManager.generic_ienumerable_type) {
+ original_iterator_type = inflated.TypeArguments[0];
is_enumerable = true;
return true;
}
- if (gt == TypeManager.generic_ienumerator_type) {
- original_iterator_type = TypeManager.TypeToCoreType (args [0]);
+ if (ret == TypeManager.generic_ienumerator_type) {
+ original_iterator_type = inflated.TypeArguments[0];
is_enumerable = false;
return true;
}
{
}
- protected override Expression CreateExpressionTree (ResolveContext ec, Type delegate_type)
+ protected override Expression CreateExpressionTree (ResolveContext ec, TypeSpec delegate_type)
{
if (ec.IsInProbingMode)
return this;
}
}
- protected override ParametersCompiled ResolveParameters (ResolveContext ec, TypeInferenceContext tic, Type delegateType)
+ protected override ParametersCompiled ResolveParameters (ResolveContext ec, TypeInferenceContext tic, TypeSpec delegateType)
{
- if (!TypeManager.IsDelegateType (delegateType))
+ if (!delegateType.IsDelegate)
return null;
- AParametersCollection d_params = TypeManager.GetDelegateParameters (ec, delegateType);
+ AParametersCollection d_params = Delegate.GetParameters (ec.Compiler, delegateType);
if (HasExplicitParameters) {
if (!VerifyExplicitParameters (ec, delegateType, d_params))
if (!VerifyParameterCompatibility (ec, delegateType, d_params, ec.IsInProbingMode))
return null;
- Type [] ptypes = new Type [Parameters.Count];
+ TypeSpec [] ptypes = new TypeSpec [Parameters.Count];
for (int i = 0; i < d_params.Count; i++) {
// D has no ref or out parameters
if ((d_params.FixedParameters [i].ModFlags & Parameter.Modifier.ISBYREF) != 0)
return null;
- Type d_param = d_params.Types [i];
+ TypeSpec d_param = d_params.Types [i];
-#if MS_COMPATIBLE
- // Blablabla, because reflection does not work with dynamic types
- if (d_param.IsGenericParameter)
- d_param = delegateType.GetGenericArguments () [d_param.GenericParameterPosition];
-#endif
//
// When type inference context exists try to apply inferred type arguments
//
}
ptypes [i] = d_param;
- ((ImplicitLambdaParameter) Parameters.FixedParameters [i]).Type = d_param;
+ ImplicitLambdaParameter ilp = (ImplicitLambdaParameter) Parameters.FixedParameters [i];
+ ilp.Type = d_param;
+ ilp.Resolve (null, i);
}
Parameters.Types = ptypes;
return this;
}
- protected override AnonymousMethodBody CompatibleMethodFactory (Type returnType, Type delegateType, ParametersCompiled p, ToplevelBlock b)
+ protected override AnonymousMethodBody CompatibleMethodFactory (TypeSpec returnType, TypeSpec delegateType, ParametersCompiled p, ToplevelBlock b)
{
return new LambdaMethod (p, b, returnType, delegateType, loc);
}
public class LambdaMethod : AnonymousMethodBody
{
public LambdaMethod (ParametersCompiled parameters,
- ToplevelBlock block, Type return_type, Type delegate_type,
+ ToplevelBlock block, TypeSpec return_type, TypeSpec delegate_type,
Location loc)
: base (parameters, block, return_type, delegate_type, loc)
{
{
if (statement != null) {
statement.EmitStatement (ec);
- ec.ig.Emit (OpCodes.Ret);
+ ec.Emit (OpCodes.Ret);
return;
}
{
}
- protected override Expression Error_MemberLookupFailed (ResolveContext ec, Type container_type, Type qualifier_type,
- Type queried_type, string name, string class_name, MemberTypes mt, BindingFlags bf)
+ protected override 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)
{
ec.Report.Error (1935, loc, "An implementation of `{0}' query expression pattern could not be found. " +
"Are you missing `System.Linq' using directive or `System.Core.dll' assembly reference?",
public bool AmbiguousCall (ResolveContext ec, MethodSpec ambiguous)
{
- ec.Report.SymbolRelatedToPreviousError (mg.BestCandidate.MetaInfo);
- ec.Report.SymbolRelatedToPreviousError (ambiguous.MetaInfo);
+ ec.Report.SymbolRelatedToPreviousError (mg.BestCandidate);
+ ec.Report.SymbolRelatedToPreviousError (ambiguous);
ec.Report.Error (1940, loc, "Ambiguous implementation of the query pattern `{0}' for source type `{1}'",
mg.Name, mg.InstanceExpression.GetSignatureForError ());
return true;
public bool NoExactMatch (ResolveContext ec, MethodSpec method)
{
var pd = method.Parameters;
- Type source_type = pd.ExtensionMethodType;
+ TypeSpec source_type = pd.ExtensionMethodType;
if (source_type != null) {
Argument a = arguments [0];
if (TypeManager.IsGenericType (source_type) && TypeManager.ContainsGenericParameters (source_type)) {
- TypeInferenceContext tic = new TypeInferenceContext (TypeManager.GetTypeArguments (source_type));
+ TypeInferenceContext tic = new TypeInferenceContext (source_type.TypeArguments);
tic.OutputTypeInference (ec, a.Expr, source_type);
if (tic.FixAllTypes (ec)) {
- source_type = TypeManager.DropGenericTypeArguments (source_type).MakeGenericType (tic.InferredTypeArguments);
+ source_type = source_type.GetDefinition ().MakeGenericType (tic.InferredTypeArguments);
}
}
}
}
- if (!method.IsGenericMethod)
+ if (!method.IsGeneric)
return false;
if (mg.Name == "SelectMany") {
{
}
- protected static Expression CreateRangeVariableType (ToplevelBlock block, IMemberContext context, SimpleMemberName name, Expression init)
+ protected static Expression CreateRangeVariableType (ToplevelBlock block, TypeContainer container, SimpleMemberName name, Expression init)
{
var args = new List<AnonymousTypeParameter> (2);
args.Add (new AnonymousTypeParameter (block.Parameters [0]));
args.Add (new RangeAnonymousTypeParameter (init, name));
- return new NewAnonymousType (args, context.CurrentTypeDefinition, name.Location);
+ return new NewAnonymousType (args, container, name.Location);
}
}
if (expr == null)
return null;
- if (TypeManager.IsDynamicType (expr.Type) || expr.Type == TypeManager.void_type) {
+ if (expr.Type == InternalType.Dynamic || expr.Type == TypeManager.void_type) {
ec.Report.Error (1979, expr.Location,
"Query expression with a source or join sequence of type `{0}' is not allowed",
TypeManager.CSharpName (expr.Type));
result_selector_expr = next.Expr;
next = next.next;
} else {
- result_selector_expr = CreateRangeVariableType (block, ec.MemberContext, into_variable,
+ result_selector_expr = CreateRangeVariableType (block, ec.MemberContext.CurrentMemberDefinition.Parent, into_variable,
new SimpleName (into_variable.Value, into_variable.Location));
}
result_selector_expr = next.Expr;
next = next.next;
} else {
- result_selector_expr = CreateRangeVariableType (block, ec.MemberContext, lt, new SimpleName (lt.Value, lt.Location));
+ result_selector_expr = CreateRangeVariableType (block, ec.MemberContext.CurrentMemberDefinition.Parent, lt, new SimpleName (lt.Value, lt.Location));
}
LambdaExpression result_selector = new LambdaExpression (lt.Location);
Identifier = identifier.Value;
}
- public static void Reset ()
+ public new static void Reset ()
{
Counter = 0;
}
// Default type of null is an object
//
public NullLiteral (Location loc)
- : base (typeof (NullLiteral), loc)
+ : base (InternalType.Null, loc)
{
}
return CreateExpressionFactoryCall (ec, "Constant", args);
}
- public override void Error_ValueCannotBeConverted (ResolveContext ec, Location loc, Type t, bool expl)
+ public override void Error_ValueCannotBeConverted (ResolveContext ec, Location loc, TypeSpec t, bool expl)
{
- if (TypeManager.IsGenericParameter (t)) {
+ if (t.IsGenericParameter) {
ec.Report.Error(403, loc,
"Cannot convert null to the type parameter `{0}' because it could be a value " +
"type. Consider using `default ({0})' instead", t.Name);
base.Error_ValueCannotBeConverted (ec, loc, t, expl);
}
- public override Constant ConvertImplicitly (ResolveContext rc, Type targetType)
+ public override Constant ConvertImplicitly (ResolveContext rc, TypeSpec targetType)
{
//
// Null literal is of object type
public override void Emit (EmitContext ec)
{
- ILGenerator ig = ec.ig;
-
//
// Emits null pointer
//
- ig.Emit (OpCodes.Ldc_I4_0);
- ig.Emit (OpCodes.Conv_U);
+ ec.Emit (OpCodes.Ldc_I4_0);
+ ec.Emit (OpCodes.Conv_U);
}
}
{
}
- public override Constant ConvertImplicitly (ResolveContext rc, Type type)
+ public override Constant ConvertImplicitly (ResolveContext rc, TypeSpec type)
{
//
// The 0 literal can be converted to an enum value
//
if (Value == 0 && TypeManager.IsEnumType (type)) {
- Constant c = ConvertImplicitly (rc, TypeManager.GetEnumUnderlyingType (type));
+ Constant c = ConvertImplicitly (rc, EnumSpec.GetUnderlyingType (type));
if (c == null)
return null;
{
}
- 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)
{
if (target == TypeManager.float_type) {
Error_664 (ec, loc, "float", "f");
using System.Globalization;
using System.Reflection.Emit;
using System.Reflection;
+using System.Linq;
namespace Mono.CSharp {
Indexer = 1 << 5,
Operator = 1 << 6,
Destructor = 1 << 7,
- //Constant = 1 << 8,
-
- NestedType = 1 << 10,
Class = 1 << 11,
Struct = 1 << 12,
Delegate = 1 << 13,
Enum = 1 << 14,
Interface = 1 << 15,
+ TypeParameter = 1 << 16,
+
+ PointerType = 1 << 20,
+ InternalCompilerType = 1 << 21,
+ FakeMethod = 1 << 22,
- MaskType = Constructor | Event | Field | Method | Property | NestedType | Indexer | Operator | Destructor,
+ NestedMask = Class | Struct | Delegate | Enum | Interface,
+ GenericMask = Method | Class | Struct | Delegate | Interface,
+ MaskType = Constructor | Event | Field | Method | Property | Indexer | Operator | Destructor | NestedMask,
All = MaskType
}
// Inspect only queried type members
DeclaredOnly = 1 << 1,
- // Excluded static
+ // Exclude static
InstanceOnly = 1 << 2,
- //
- NoOverloadableOverrides = 1 << 3
+ // Ignore member overrides
+ NoOverrides = 1 << 3
}
-/*
- public struct MemberFilter : IEquatable<MemberCore>
+
+ public struct MemberFilter : IEquatable<MemberSpec>
{
public readonly string Name;
public readonly MemberKind Kind;
- public readonly TypeSpec[] Parameters;
+ public readonly AParametersCollection Parameters;
public readonly TypeSpec MemberType;
- public MemberFilter (IMethod m)
- {
- Name = m.MethodBuilder.Name;
- Kind = MemberKind.Method;
- Parameters = m.Parameters.Types;
- MemberType = m.ReturnType;
- }
+ int arity; // -1 to ignore the check
+ TypeSpec invocation_type;
- public MemberFilter (string name, MemberKind kind)
+ private MemberFilter (string name, MemberKind kind)
{
Name = name;
Kind = kind;
Parameters = null;
MemberType = null;
+ arity = -1;
+ invocation_type = null;
+ }
+
+ public MemberFilter (MethodSpec m)
+ {
+ Name = m.Name;
+ Kind = MemberKind.Method;
+ Parameters = m.Parameters;
+ MemberType = m.ReturnType;
+ arity = m.Arity;
+ invocation_type = null;
}
- public MemberFilter (string name, MemberKind kind, TypeSpec[] param, TypeSpec type)
- : this (name, kind)
+ public MemberFilter (string name, int arity, MemberKind kind, AParametersCollection param, TypeSpec type)
{
Name = name;
Kind = kind;
Parameters = param;
MemberType = type;
+ this.arity = arity;
+ invocation_type = null;
}
- public static MemberFilter Constuctor (TypeSpec[] param)
+ public TypeSpec InvocationType {
+ get {
+ return invocation_type;
+ }
+ set {
+ invocation_type = value;
+ }
+ }
+
+ public static MemberFilter Constructor (AParametersCollection param)
{
- return new MemberFilter (System.Reflection.ConstructorInfo.ConstructorName, MemberKind.Constructor, param, null);
+ return new MemberFilter (System.Reflection.ConstructorInfo.ConstructorName, 0, MemberKind.Constructor, param, null);
}
public static MemberFilter Property (string name, TypeSpec type)
{
- return new MemberFilter (name, MemberKind.Property, null, type);
+ return new MemberFilter (name, 0, MemberKind.Property, null, type);
}
public static MemberFilter Field (string name, TypeSpec type)
{
- return new MemberFilter (name, MemberKind.Field, null, type);
+ return new MemberFilter (name, 0, MemberKind.Field, null, type);
}
- public static MemberFilter Method (string name, TypeSpec[] param, TypeSpec type)
+ public static MemberFilter Method (string name, int arity, AParametersCollection param, TypeSpec type)
{
- return new MemberFilter (name, MemberKind.Method, param, type);
+ return new MemberFilter (name, arity, MemberKind.Method, param, type);
}
- #region IEquatable<MemberCore> Members
+ #region IEquatable<MemberSpec> Members
- public bool Equals (MemberCore other)
+ public bool Equals (MemberSpec other)
{
// Is the member of the correct type ?
- if ((other.MemberKind & Kind & MemberKind.MaskType) == 0)
+ // TODO: Isn't this redundant ?
+ if ((other.Kind & Kind & MemberKind.MaskType) == 0)
+ return false;
+
+ // Check arity when not disabled
+ if (arity >= 0 && arity != other.Arity)
return false;
if (Parameters != null) {
if (other is IParametersMember) {
- AParametersCollection other_param = ((IParametersMember) other).Parameters;
- if (TypeSpecArrayComparer.Default.Equals (Parameters, other_param.Types))
- return true;
+ var other_param = ((IParametersMember) other).Parameters;
+ if (!TypeSpecComparer.Override.IsEqual (Parameters, other_param))
+ return false;
+ } else {
+ return false;
}
-
- return false;
}
if (MemberType != null) {
- //throw new NotImplementedException ();
+ if (other is IInterfaceMemberSpec) {
+ var other_type = ((IInterfaceMemberSpec) other).MemberType;
+ if (!TypeSpecComparer.Override.IsEqual (other_type, MemberType))
+ return false;
+ } else {
+ return false;
+ }
}
+ if (invocation_type != null && !IsAccessible (other))
+ return false;
+
return true;
}
+ bool IsAccessible (MemberSpec other)
+ {
+ bool extra;
+ return Expression.IsMemberAccessible (invocation_type, other, out extra);
+ }
+
#endregion
}
-*/
+
/// <summary>
- /// This is a readonly list of MemberInfo's.
+ /// The MemberCache is used by dynamic and non-dynamic types to speed up
+ /// member lookups. It has a member name based hash table; it maps each member
+ /// name to a list of CacheEntry objects. Each CacheEntry contains a MemberInfo
+ /// and the BindingFlags that were initially used to get it. The cache contains
+ /// all members of the current class and all inherited members. If this cache is
+ /// for an interface types, it also contains all inherited members.
+ ///
+ /// There are two ways to get a MemberCache:
+ /// * if this is a dynamic type, lookup the corresponding DeclSpace and then
+ /// use the DeclSpace.MemberCache property.
+ /// * if this not a dynamic type, call TypeHandle.GetTypeHandle() to get a
+ /// TypeHandle instance for the type and then use TypeHandle.MemberCache.
/// </summary>
- public class MemberList : IList<MemberInfo> {
- public readonly IList<MemberInfo> List;
- int count;
-
- /// <summary>
- /// Create a new MemberList from the given IList.
- /// </summary>
- public MemberList (IList<MemberInfo> list)
- {
- if (list != null)
- this.List = list;
- else
- this.List = new List<MemberInfo> ();
- count = List.Count;
- }
+ public class MemberCache
+ {
+ readonly Dictionary<string, IList<MemberSpec>> member_hash;
+ Dictionary<string, MemberSpec[]> locase_members;
+ IList<MethodSpec> missing_abstract;
- /// <summary>
- /// Concatenate the ILists `first' and `second' to a new MemberList.
- /// </summary>
- public MemberList (IList<MemberInfo> first, IList<MemberInfo> second)
- {
- var list = new List<MemberInfo> ();
- list.AddRange (first);
- list.AddRange (second);
- count = list.Count;
- List = list;
- }
+ public static readonly string IndexerNameAlias = "<this>";
- public static readonly MemberList Empty = new MemberList (Array.AsReadOnly (new MemberInfo[0]));
+ public static readonly MemberCache Empty = new MemberCache (0);
- /// <summary>
- /// Cast the MemberList into a MemberInfo[] array.
- /// </summary>
- /// <remarks>
- /// This is an expensive operation, only use it if it's really necessary.
- /// </remarks>
- public static explicit operator MemberInfo [] (MemberList list)
+ public MemberCache ()
+ : this (16)
{
- Timer.StartTimer (TimerType.MiscTimer);
- MemberInfo [] result = new MemberInfo [list.Count];
- list.CopyTo (result, 0);
- Timer.StopTimer (TimerType.MiscTimer);
- return result;
}
- // ICollection
-
- public int Count {
- get {
- return count;
- }
- }
-
- public void CopyTo (MemberInfo[] array, int index)
+ public MemberCache (int capacity)
{
- List.CopyTo (array, index);
+ member_hash = new Dictionary<string, IList<MemberSpec>> (capacity);
}
- // IEnumerable
-
- public IEnumerator<MemberInfo> GetEnumerator ()
+ public MemberCache (MemberCache cache)
+ : this (cache.member_hash.Count)
{
- return List.GetEnumerator ();
}
- System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator ()
+ //
+ // Creates a new MemberCache for the given `container'.
+ //
+ public MemberCache (TypeContainer container)
+ : this () // TODO: Optimize the size
{
- return List.GetEnumerator ();
}
- // IList
+ //
+ // Member-cache does not contain base members but it does
+ // contain all base interface members, so the Lookup code
+ // can use simple inheritance rules.
+ //
+ public void AddInterface (TypeSpec iface)
+ {
+ var cache = iface.MemberCache;
- public bool IsFixedSize {
- get {
- return true;
- }
- }
+ IList<MemberSpec> list;
+ foreach (var entry in cache.member_hash) {
+ if (!member_hash.TryGetValue (entry.Key, out list)) {
+ if (entry.Value.Count == 1) {
+ list = entry.Value;
+ } else {
+ list = new List<MemberSpec> (entry.Value);
+ }
- public bool IsReadOnly {
- get {
- return true;
- }
- }
+ member_hash.Add (entry.Key, list);
+ continue;
+ }
- MemberInfo IList<MemberInfo>.this [int index] {
- get {
- return List [index];
- }
+ foreach (var ce in entry.Value) {
+ if (ce.DeclaringType != iface)
+ break;
- set {
- throw new NotSupportedException ();
- }
- }
+ if (list.Contains (ce))
+ continue;
- // FIXME: try to find out whether we can avoid the cast in this indexer.
- public MemberInfo this [int index] {
- get {
- return (MemberInfo) List [index];
+ if (AddInterfaceMember (ce, ref list))
+ member_hash[entry.Key] = list;
+ }
}
}
- public void Add (MemberInfo value)
+ public void AddMember (InterfaceMemberBase imb, string exlicitName, MemberSpec ms)
{
- throw new NotSupportedException ();
+ // Explicit names cannot be looked-up but can be used for
+ // collision checking (no name mangling needed)
+ if (imb.IsExplicitImpl)
+ AddMember (exlicitName, ms);
+ else
+ AddMember (ms);
}
- public void Clear ()
+ //
+ // Add non-explicit member to member cache
+ //
+ public void AddMember (MemberSpec ms)
{
- throw new NotSupportedException ();
+ AddMember (GetLookupName (ms), ms);
}
- public bool Contains (MemberInfo value)
+ void AddMember (string name, MemberSpec member)
{
- return List.Contains (value);
- }
+ IList<MemberSpec> list;
+ if (!member_hash.TryGetValue (name, out list)) {
+ member_hash.Add (name, new MemberSpec[] { member });
+ return;
+ }
- public int IndexOf (MemberInfo value)
- {
- return List.IndexOf (value);
- }
+ if (member.DeclaringType.IsInterface) {
+ if (AddInterfaceMember (member, ref list))
+ member_hash[name] = list;
+ } else {
+ if (list is MemberSpec[]) {
+ list = new List<MemberSpec> () { list[0] };
+ member_hash[name] = list;
+ }
- public void Insert (int index, MemberInfo value)
- {
- throw new NotSupportedException ();
+ list.Add (member);
+ }
}
- public bool Remove (MemberInfo value)
+ //
+ // Ignores any base interface member which can be hidden
+ // by this interface
+ //
+ static bool AddInterfaceMember (MemberSpec member, ref IList<MemberSpec> existing)
{
- throw new NotSupportedException ();
- }
+ var member_param = member is IParametersMember ? ((IParametersMember) member).Parameters : ParametersCompiled.EmptyReadOnlyParameters;
- public void RemoveAt (int index)
- {
- throw new NotSupportedException ();
- }
- }
+ //
+ // interface IA : IB { int Prop { set; } }
+ // interface IB { bool Prop { get; } }
+ //
+ // IB.Prop is never accessible from IA interface
+ //
+ for (int i = 0; i < existing.Count; ++i) {
+ var entry = existing[i];
- /// <summary>
- /// This interface is used to get all members of a class when creating the
- /// member cache. It must be implemented by all DeclSpace derivatives which
- /// want to support the member cache and by TypeHandle to get caching of
- /// non-dynamic types.
- /// </summary>
- public interface IMemberContainer {
- /// <summary>
- /// The name of the IMemberContainer. This is only used for
- /// debugging purposes.
- /// </summary>
- string Name {
- get;
- }
+ if (entry.Arity != member.Arity)
+ continue;
- /// <summary>
- /// The type of this IMemberContainer.
- /// </summary>
- Type Type {
- get;
- }
+ if (entry is IParametersMember) {
+ var entry_param = ((IParametersMember) entry).Parameters;
+ if (!TypeSpecComparer.Override.IsEqual (entry_param, member_param))
+ continue;
+ }
- /// <summary>
- /// Returns the IMemberContainer of the base class or null if this
- /// is an interface or TypeManger.object_type.
- /// This is used when creating the member cache for a class to get all
- /// members from the base class.
- /// </summary>
- MemberCache BaseCache {
- get;
- }
+ if (member.DeclaringType.ImplementsInterface (entry.DeclaringType)) {
+ if (existing is MemberSpec[]) {
+ existing = new MemberSpec[] { member };
+ return true;
+ }
- /// <summary>
- /// Whether this is an interface.
- /// </summary>
- bool IsInterface {
- get;
- }
+ existing.RemoveAt (i--);
+ continue;
+ }
- /// <summary>
- /// Returns all members of this class with the corresponding MemberTypes
- /// and BindingFlags.
- /// </summary>
- /// <remarks>
- /// When implementing this method, make sure not to return any inherited
- /// members and check the MemberTypes and BindingFlags properly.
- /// Unfortunately, System.Reflection is lame and doesn't provide a way to
- /// get the BindingFlags (static/non-static,public/non-public) in the
- /// MemberInfo class, but the cache needs this information. That's why
- /// this method is called multiple times with different BindingFlags.
- /// </remarks>
- MemberList GetMembers (MemberTypes mt, BindingFlags bf);
- }
+ if (entry.DeclaringType == member.DeclaringType || entry.DeclaringType.ImplementsInterface (member.DeclaringType))
+ return false;
+ }
- /// <summary>
- /// The MemberCache is used by dynamic and non-dynamic types to speed up
- /// member lookups. It has a member name based hash table; it maps each member
- /// name to a list of CacheEntry objects. Each CacheEntry contains a MemberInfo
- /// and the BindingFlags that were initially used to get it. The cache contains
- /// all members of the current class and all inherited members. If this cache is
- /// for an interface types, it also contains all inherited members.
- ///
- /// There are two ways to get a MemberCache:
- /// * if this is a dynamic type, lookup the corresponding DeclSpace and then
- /// use the DeclSpace.MemberCache property.
- /// * if this not a dynamic type, call TypeHandle.GetTypeHandle() to get a
- /// TypeHandle instance for the type and then use TypeHandle.MemberCache.
- /// </summary>
- public class MemberCache {
- public readonly IMemberContainer Container;
- protected Dictionary<string, List<CacheEntry>> member_hash;
- protected Dictionary<string, List<CacheEntry>> method_hash;
+ if (existing is MemberSpec[]) {
+ existing = new List<MemberSpec> () { existing[0], member };
+ return true;
+ }
- Dictionary<string, object> locase_table;
+ existing.Add (member);
+ return false;
+ }
- static List<MethodInfo> overrides = new List<MethodInfo> ();
+ public static IEnumerable<IndexerSpec> FindIndexers (TypeSpec container, BindingRestriction restrictions)
+ {
+ var filter = new MemberFilter (IndexerNameAlias, 0, MemberKind.Indexer, null, null);
+ var found = FindMembers (container, filter, restrictions);
+ return found == null ? null : found.Cast<IndexerSpec> ();
+ }
- /// <summary>
- /// Create a new MemberCache for the given IMemberContainer `container'.
- /// </summary>
- public MemberCache (IMemberContainer container)
+ public static MemberSpec FindMember (TypeSpec container, MemberFilter filter, BindingRestriction restrictions)
{
- this.Container = container;
+ do {
+ IList<MemberSpec> applicable;
+ if (container.MemberCache.member_hash.TryGetValue (filter.Name, out applicable)) {
+ // Start from the end because interface members are in reverse order
+ for (int i = applicable.Count - 1; i >= 0; i--) {
+ var entry = applicable [i];
+
+ if ((restrictions & BindingRestriction.InstanceOnly) != 0 && entry.IsStatic)
+ continue;
- Timer.IncrementCounter (CounterType.MemberCache);
- Timer.StartTimer (TimerType.CacheInit);
+ if (filter.Equals (entry))
+ return entry;
- // If we have a base class (we have a base class unless we're
- // TypeManager.object_type), we deep-copy its MemberCache here.
- if (Container.BaseCache != null)
- member_hash = SetupCache (Container.BaseCache);
- else
- member_hash = new Dictionary<string, List<CacheEntry>> ();
-
- // If this is neither a dynamic type nor an interface, create a special
- // method cache with all declared and inherited methods.
- Type type = container.Type;
- if (!(type is TypeBuilder) && !type.IsInterface &&
- // !(type.IsGenericType && (type.GetGenericTypeDefinition () is TypeBuilder)) &&
- !TypeManager.IsGenericType (type) && !TypeManager.IsGenericParameter (type) &&
- (Container.BaseCache == null || Container.BaseCache.method_hash != null)) {
- method_hash = new Dictionary<string, List<CacheEntry>> ();
- AddMethods (type);
- }
+ // TODO MemberCache:
+ //if ((restrictions & BindingRestriction.AccessibleOnly) != 0)
+ // throw new NotImplementedException ("net");
+ }
+ }
- // Add all members from the current class.
- AddMembers (Container);
+ container = container.BaseType;
+ } while (container != null && (restrictions & BindingRestriction.DeclaredOnly) == 0);
- Timer.StopTimer (TimerType.CacheInit);
+ return null;
}
- public MemberCache (Type baseType, IMemberContainer container)
+ //
+ // Returns the first set of members starting from container
+ //
+ public static IList<MemberSpec> FindMembers (TypeSpec container, MemberFilter filter, BindingRestriction restrictions)
{
- this.Container = container;
- if (baseType == null)
- this.member_hash = new Dictionary<string, List<CacheEntry>> ();
- else
- this.member_hash = SetupCache (TypeManager.LookupMemberCache (baseType));
- }
+ IList<MemberSpec> applicable;
+ IList<MemberSpec> found = null;
- public MemberCache (Type[] ifaces)
- {
- //
- // The members of this cache all belong to other caches.
- // So, 'Container' will not be used.
- //
- this.Container = null;
+ do {
+ if (container.MemberCache.member_hash.TryGetValue (filter.Name, out applicable)) {
+ for (int i = 0; i < applicable.Count; ++i) {
+ var entry = applicable [i];
- member_hash = new Dictionary<string, List<CacheEntry>> ();
- if (ifaces == null)
- return;
+ // Is the member of the correct type
+ if ((entry.Kind & filter.Kind & MemberKind.MaskType) == 0)
+ continue;
- foreach (Type itype in ifaces)
- AddCacheContents (TypeManager.LookupMemberCache (itype));
- }
+ //
+ // When using overloadable overrides filter ignore members which
+ // are not base members. Including properties because overrides can
+ // implement get or set only and we are looking for complete base member
+ //
+ const MemberKind overloadable = MemberKind.Indexer | MemberKind.Method | MemberKind.Property;
+ if ((restrictions & BindingRestriction.NoOverrides) != 0 && (entry.Kind & overloadable) != 0) {
+ if ((entry.Modifiers & Modifiers.OVERRIDE) != 0)
+ continue;
- public MemberCache (IMemberContainer container, Type base_class, Type[] ifaces)
- {
- this.Container = container;
+ if ((entry.Modifiers & Modifiers.OVERRIDE_UNCHECKED) != 0) {
+ // TODO: Implement this correctly for accessors
+ var ms = entry as MethodSpec;
+ if (ms == null || IsRealMethodOverride (ms)) {
+ entry.Modifiers = (entry.Modifiers & ~Modifiers.OVERRIDE_UNCHECKED) | Modifiers.OVERRIDE;
+ continue;
+ }
+ }
+ }
- // If we have a base class (we have a base class unless we're
- // TypeManager.object_type), we deep-copy its MemberCache here.
- if (Container.BaseCache != null)
- member_hash = SetupCache (Container.BaseCache);
- else
- member_hash = new Dictionary<string, List<CacheEntry>> ();
-
- if (base_class != null)
- AddCacheContents (TypeManager.LookupMemberCache (base_class));
- if (ifaces != null) {
- foreach (Type itype in ifaces) {
- MemberCache cache = TypeManager.LookupMemberCache (itype);
- if (cache != null)
- AddCacheContents (cache);
+ if ((restrictions & BindingRestriction.InstanceOnly) != 0 && entry.IsStatic)
+ continue;
+
+ // Apply the filter to it.
+ if (!filter.Equals (entry))
+ continue;
+
+ if (found == null) {
+ if (i == 0) {
+ found = applicable;
+ } else {
+ found = new List<MemberSpec> ();
+ found.Add (entry);
+ }
+ } else if (found == applicable) {
+ found = new List<MemberSpec> ();
+ found.Add (applicable[0]);
+ found.Add (entry);
+ } else {
+ found.Add (entry);
+ }
+ }
+
+ if (found != null) {
+ if (found == applicable && applicable.Count != 1)
+ return new MemberSpec[] { found[0] };
+
+ return found;
+ }
}
- }
- }
- /// <summary>
- /// Bootstrap this member cache by doing a deep-copy of our base.
- /// </summary>
- static Dictionary<string, List<CacheEntry>> SetupCache (MemberCache base_class)
- {
- if (base_class == null)
- return new Dictionary<string, List<CacheEntry>> ();
+ container = container.BaseType;
+ } while (container != null && (restrictions & BindingRestriction.DeclaredOnly) == 0);
- var hash = new Dictionary<string, List<CacheEntry>> (base_class.member_hash.Count);
- var it = base_class.member_hash.GetEnumerator ();
- while (it.MoveNext ()) {
- hash.Add (it.Current.Key, new List<CacheEntry> (it.Current.Value));
- }
-
- return hash;
+ return found;
}
-
+
//
- // Converts ModFlags to BindingFlags
+ // Finds the nested type in container
//
- static BindingFlags GetBindingFlags (Modifiers modifiers)
+ public static TypeSpec FindNestedType (TypeSpec container, string name, int arity)
{
- BindingFlags bf;
- if ((modifiers & Modifiers.STATIC) != 0)
- bf = BindingFlags.Static;
- else
- bf = BindingFlags.Instance;
-
- if ((modifiers & Modifiers.PRIVATE) != 0)
- bf |= BindingFlags.NonPublic;
- else
- bf |= BindingFlags.Public;
-
- return bf;
- }
-
- /// <summary>
- /// Add the contents of `cache' to the member_hash.
- /// </summary>
- void AddCacheContents (MemberCache cache)
- {
- var it = cache.member_hash.GetEnumerator ();
- while (it.MoveNext ()) {
- List<CacheEntry> list;
- if (!member_hash.TryGetValue (it.Current.Key, out list))
- member_hash [it.Current.Key] = list = new List<CacheEntry> ();
+ IList<MemberSpec> applicable;
+ TypeSpec best_match = null;
+ do {
+ // TODO: Don't know how to handle this yet
+ // When resolving base type of nested type, parent type must have
+ // base type resolved to scan full hierarchy correctly
+ // Similarly MemberCacheTypes will inflate BaseType and Interfaces
+ // based on type definition
+ var tc = container.MemberDefinition as TypeContainer;
+ if (tc != null)
+ tc.DefineType ();
+
+ if (container.MemberCacheTypes.member_hash.TryGetValue (name, out applicable)) {
+ for (int i = applicable.Count - 1; i >= 0; i--) {
+ var entry = applicable[i];
+ if ((entry.Kind & MemberKind.NestedMask) == 0)
+ continue;
- var entries = it.Current.Value;
- for (int i = entries.Count-1; i >= 0; i--) {
- var entry = entries [i];
+ var ts = (TypeSpec) entry;
+ if (arity == ts.Arity)
+ return ts;
- if (entry.Container != cache.Container)
- break;
- list.Add (entry);
+ if (arity < 0) {
+ if (best_match == null) {
+ best_match = ts;
+ } else if (System.Math.Abs (ts.Arity + arity) < System.Math.Abs (ts.Arity + arity)) {
+ best_match = ts;
+ }
+ }
+ }
}
- }
- }
- /// <summary>
- /// Add all members from class `container' to the cache.
- /// </summary>
- void AddMembers (IMemberContainer container)
- {
- // We need to call AddMembers() with a single member type at a time
- // to get the member type part of CacheEntry.EntryType right.
- if (!container.IsInterface) {
- AddMembers (MemberTypes.Constructor, container);
- AddMembers (MemberTypes.Field, container);
- }
- AddMembers (MemberTypes.Method, container);
- AddMembers (MemberTypes.Property, container);
- AddMembers (MemberTypes.Event, container);
- // Nested types are returned by both Static and Instance searches.
- AddMembers (MemberTypes.NestedType,
- BindingFlags.Static | BindingFlags.Public, container);
- AddMembers (MemberTypes.NestedType,
- BindingFlags.Static | BindingFlags.NonPublic, container);
- }
+ container = container.BaseType;
+ } while (container != null);
- void AddMembers (MemberTypes mt, IMemberContainer container)
- {
- AddMembers (mt, BindingFlags.Static | BindingFlags.Public, container);
- AddMembers (mt, BindingFlags.Static | BindingFlags.NonPublic, container);
- AddMembers (mt, BindingFlags.Instance | BindingFlags.Public, container);
- AddMembers (mt, BindingFlags.Instance | BindingFlags.NonPublic, container);
+ return best_match;
}
- public void AddMember (MemberInfo mi, MemberSpec mc)
+ //
+ // Looks for extension methods with defined name and extension type
+ //
+ public List<MethodSpec> FindExtensionMethods (TypeSpec invocationType, TypeSpec extensionType, string name, int arity)
{
- AddMember (mi.MemberType, GetBindingFlags (mc.Modifiers), Container, mi.Name, mi);
- }
+ IList<MemberSpec> entries;
+ if (!member_hash.TryGetValue (name, out entries))
+ return null;
- public void AddGenericMember (MemberInfo mi, InterfaceMemberBase mc)
- {
- AddMember (mi.MemberType, GetBindingFlags (mc.ModFlags), Container,
- MemberName.MakeName (mc.GetFullName (mc.MemberName), mc.MemberName.TypeArguments), mi);
- }
+ List<MethodSpec> candidates = null;
+ foreach (var entry in entries) {
+ if (entry.Kind != MemberKind.Method || (arity >= 0 && entry.Arity != arity))
+ continue;
- public void AddNestedType (DeclSpace type)
- {
- AddMember (MemberTypes.NestedType, GetBindingFlags (type.ModFlags), (IMemberContainer) type.Parent,
- type.TypeBuilder.Name, type.TypeBuilder);
- }
+ var ms = (MethodSpec) entry;
+ if (!ms.IsExtensionMethod)
+ continue;
- public void AddInterface (MemberCache baseCache)
- {
- if (baseCache.member_hash.Count > 0)
- AddCacheContents (baseCache);
- }
+ bool extra;
+ if (!Expression.IsMemberAccessible (invocationType, ms, out extra))
+ continue;
- void AddMember (MemberTypes mt, BindingFlags bf, IMemberContainer container,
- string name, MemberInfo member)
- {
- // We use a name-based hash table of ArrayList's.
- List<CacheEntry> list;
- if (!member_hash.TryGetValue (name, out list)) {
- list = new List<CacheEntry> (1);
- member_hash.Add (name, list);
+ // TODO: CodeGen.Assembly.Builder
+ if ((ms.DeclaringType.Modifiers & Modifiers.INTERNAL) != 0 &&
+ !TypeManager.IsThisOrFriendAssembly (CodeGen.Assembly.Builder, ms.Assembly))
+ continue;
+
+ if (candidates == null)
+ candidates = new List<MethodSpec> ();
+ candidates.Add (ms);
}
- // When this method is called for the current class, the list will
- // already contain all inherited members from our base classes.
- // We cannot add new members in front of the list since this'd be an
- // expensive operation, that's why the list is sorted in reverse order
- // (ie. members from the current class are coming last).
- list.Add (new CacheEntry (container, member, mt, bf));
+ return candidates;
}
- /// <summary>
- /// Add all members from class `container' with the requested MemberTypes and
- /// BindingFlags to the cache. This method is called multiple times with different
- /// MemberTypes and BindingFlags.
- /// </summary>
- void AddMembers (MemberTypes mt, BindingFlags bf, IMemberContainer container)
+ //
+ // Returns base members of @member member if no exact match is found @bestCandidate returns
+ // the best match
+ //
+ public static MemberSpec FindBaseMember (MemberCore member, out MemberSpec bestCandidate)
{
- MemberList members = container.GetMembers (mt, bf);
+ bestCandidate = null;
+ var container = member.Parent.PartialContainer.Definition;
+ if (!container.IsInterface)
+ container = container.BaseType;
- foreach (MemberInfo member in members) {
- string name = member.Name;
+ string name = GetLookupName (member);
+ IList<MemberSpec> applicable;
+ var member_param = member is IParametersMember ? ((IParametersMember) member).Parameters : null;
- AddMember (mt, bf, container, name, member);
+ var mkind = GetMemberCoreKind (member);
- if (member is MethodInfo) {
- string gname = TypeManager.GetMethodName ((MethodInfo) member);
- if (gname != name)
- AddMember (mt, bf, container, gname, member);
- }
- }
- }
+ do {
+ if (container.MemberCache.member_hash.TryGetValue (name, out applicable)) {
+ for (int i = 0; i < applicable.Count; ++i) {
+ var entry = applicable [i];
- /// <summary>
- /// Add all declared and inherited methods from class `type' to the method cache.
- /// </summary>
- void AddMethods (Type type)
- {
- AddMethods (BindingFlags.Static | BindingFlags.Public |
- BindingFlags.FlattenHierarchy, type);
- AddMethods (BindingFlags.Static | BindingFlags.NonPublic |
- BindingFlags.FlattenHierarchy, type);
- AddMethods (BindingFlags.Instance | BindingFlags.Public, type);
- AddMethods (BindingFlags.Instance | BindingFlags.NonPublic, type);
- }
+ if ((entry.Modifiers & Modifiers.PRIVATE) != 0)
+ continue;
- void AddMethods (BindingFlags bf, Type type)
- {
- MethodBase [] members = type.GetMethods (bf);
+ if ((entry.Modifiers & Modifiers.AccessibilityMask) == Modifiers.INTERNAL) {
+ if (!TypeManager.IsThisOrFriendAssembly (member.Assembly, entry.Assembly))
+ continue;
+ }
+
+ // Is the member of the correct type ?
+ if ((entry.Kind & mkind & MemberKind.MaskType) == 0) {
+ if (member_param == null || !(entry is IParametersMember)) {
+ bestCandidate = entry;
+ return null;
+ }
- Array.Reverse (members);
+ continue;
+ }
- foreach (MethodBase member in members) {
- string name = member.Name;
+ if (member_param == null)
+ return entry;
- // We use a name-based hash table of ArrayList's.
- List<CacheEntry> list;
- if (!method_hash.TryGetValue (name, out list)) {
- list = new List<CacheEntry> (1);
- method_hash.Add (name, list);
- }
+ // Check arity match
+ int arity = member.MemberName.Arity;
+ if (arity != entry.Arity)
+ continue;
- MethodInfo curr = (MethodInfo) member;
- while (curr.IsVirtual && (curr.Attributes & MethodAttributes.NewSlot) == 0) {
- MethodInfo base_method = curr.GetBaseDefinition ();
+ if (entry is IParametersMember) {
+ if (entry.IsAccessor != member is AbstractPropertyEventMethod)
+ continue;
- if (base_method == curr)
- // Not every virtual function needs to have a NewSlot flag.
- break;
+ var entry_param = ((IParametersMember) entry).Parameters;
+ if (TypeSpecComparer.Override.IsEqual (entry_param, member_param))
+ return entry;
- overrides.Add (curr);
- list.Add (new CacheEntry (null, base_method, MemberTypes.Method, bf));
- curr = base_method;
- }
+ continue;
+ }
+
+ if (bestCandidate == null)
+ bestCandidate = entry;
+ }
- if (overrides.Count > 0) {
- for (int i = 0; i < overrides.Count; ++i)
- TypeManager.RegisterOverride ((MethodBase) overrides [i], curr);
- overrides.Clear ();
+ if (member_param == null)
+ return null;
}
- // Unfortunately, the elements returned by Type.GetMethods() aren't
- // sorted so we need to do this check for every member.
- BindingFlags new_bf = bf;
- if (member.DeclaringType == type)
- new_bf |= BindingFlags.DeclaredOnly;
+ if (container.IsInterface)
+ break;
- list.Add (new CacheEntry (Container, member, MemberTypes.Method, new_bf));
- }
- }
+ container = container.BaseType;
+ } while (container != null);
- /// <summary>
- /// Compute and return a appropriate `EntryType' magic number for the given
- /// MemberTypes and BindingFlags.
- /// </summary>
- protected static EntryType GetEntryType (MemberTypes mt, BindingFlags bf)
- {
- EntryType type = EntryType.None;
-
- if ((mt & MemberTypes.Constructor) != 0)
- type |= EntryType.Constructor;
- if ((mt & MemberTypes.Event) != 0)
- type |= EntryType.Event;
- if ((mt & MemberTypes.Field) != 0)
- type |= EntryType.Field;
- if ((mt & MemberTypes.Method) != 0)
- type |= EntryType.Method;
- if ((mt & MemberTypes.Property) != 0)
- type |= EntryType.Property;
- // Nested types are returned by static and instance searches.
- if ((mt & MemberTypes.NestedType) != 0)
- type |= EntryType.NestedType | EntryType.Static | EntryType.Instance;
-
- if ((bf & BindingFlags.Instance) != 0)
- type |= EntryType.Instance;
- if ((bf & BindingFlags.Static) != 0)
- type |= EntryType.Static;
- if ((bf & BindingFlags.Public) != 0)
- type |= EntryType.Public;
- if ((bf & BindingFlags.NonPublic) != 0)
- type |= EntryType.NonPublic;
- if ((bf & BindingFlags.DeclaredOnly) != 0)
- type |= EntryType.Declared;
-
- return type;
+ return null;
}
- /// <summary>
- /// The `MemberTypes' enumeration type is a [Flags] type which means that it may
- /// denote multiple member types. Returns true if the given flags value denotes a
- /// single member types.
- /// </summary>
- public static bool IsSingleMemberType (MemberTypes mt)
+ //
+ // Returns inflated version of MemberSpec, it works similarly to
+ // SRE TypeBuilder.GetMethod
+ //
+ public static T GetMember<T> (TypeSpec container, T spec) where T : MemberSpec
{
- switch (mt) {
- case MemberTypes.Constructor:
- case MemberTypes.Event:
- case MemberTypes.Field:
- case MemberTypes.Method:
- case MemberTypes.Property:
- case MemberTypes.NestedType:
- return true;
-
- default:
- return false;
+ IList<MemberSpec> applicable;
+ if (container.MemberCache.member_hash.TryGetValue (GetLookupName (spec), out applicable)) {
+ for (int i = applicable.Count - 1; i >= 0; i--) {
+ var entry = applicable[i];
+ if (entry.MemberDefinition == spec.MemberDefinition)
+ return (T) entry;
+ }
}
- }
- /// <summary>
- /// We encode the MemberTypes and BindingFlags of each members in a "magic"
- /// number to speed up the searching process.
- /// </summary>
- [Flags]
- public enum EntryType {
- None = 0x000,
-
- Instance = 0x001,
- Static = 0x002,
- MaskStatic = Instance|Static,
-
- Public = 0x004,
- NonPublic = 0x008,
- MaskProtection = Public|NonPublic,
+ throw new InternalErrorException ("Missing member `{0}' on inflated type `{1}'",
+ spec.GetSignatureForError (), container.GetSignatureForError ());
+ }
- Declared = 0x010,
+ static MemberKind GetMemberCoreKind (MemberCore member)
+ {
+ if (member is FieldBase)
+ return MemberKind.Field;
+ if (member is Indexer)
+ return MemberKind.Indexer;
+ if (member is Class)
+ return MemberKind.Class;
+ if (member is Struct)
+ return MemberKind.Struct;
+ if (member is Destructor)
+ return MemberKind.Destructor;
+ if (member is Method)
+ return MemberKind.Method;
+ if (member is Property)
+ return MemberKind.Property;
+ if (member is EventField)
+ return MemberKind.Event;
+ if (member is Interface)
+ return MemberKind.Interface;
+ if (member is EventProperty)
+ return MemberKind.Event;
+
+ throw new NotImplementedException (member.GetType ().ToString ());
+ }
- Constructor = 0x020,
- Event = 0x040,
- Field = 0x080,
- Method = 0x100,
- Property = 0x200,
- NestedType = 0x400,
+ public static IList<MemberSpec> GetCompletitionMembers (TypeSpec container, string name)
+ {
+ var matches = new List<MemberSpec> ();
+ foreach (var entry in container.MemberCache.member_hash) {
+ foreach (var name_entry in entry.Value) {
+ if (name_entry.IsAccessor)
+ continue;
- NotExtensionMethod = 0x800,
+ if ((name_entry.Kind & (MemberKind.Constructor | MemberKind.FakeMethod | MemberKind.Destructor)) != 0)
+ continue;
- MaskType = Constructor|Event|Field|Method|Property|NestedType
- }
+ bool extra;
+ if (!Expression.IsMemberAccessible (InternalType.FakeInternalType, name_entry, out extra))
+ continue;
- public class CacheEntry {
- public readonly IMemberContainer Container;
- public EntryType EntryType;
- public readonly MemberInfo Member;
-
- public CacheEntry (IMemberContainer container, MemberInfo member,
- MemberTypes mt, BindingFlags bf)
- {
- this.Container = container;
- this.Member = member;
- this.EntryType = GetEntryType (mt, bf);
+ if (name == null || name_entry.Name.StartsWith (name)) {
+ matches.Add (name_entry);
+ }
+ }
}
- public override string ToString ()
- {
- return String.Format ("CacheEntry ({0}:{1}:{2})", Container.Name,
- EntryType, Member);
- }
+ return matches;
}
- /// <summary>
- /// This is called each time we're walking up one level in the class hierarchy
- /// and checks whether we can abort the search since we've already found what
- /// we were looking for.
- /// </summary>
- protected bool DoneSearching (IList<MemberInfo> list)
+ //
+ // Returns members of @iface only, base members are ignored
+ //
+ public static IList<MethodSpec> GetInterfaceMembers (TypeSpec iface)
{
//
- // We've found exactly one member in the current class and it's not
- // a method or constructor.
+ // MemberCache flatten interfaces, therefore in cases like this one
+ //
+ // interface IA : IB {}
+ // interface IB { void Foo () }
//
- if (list.Count == 1 && !(list [0] is MethodBase))
- return true;
-
- //
- // Multiple properties: we query those just to find out the indexer
- // name
+ // we would return Foo inside IA which is not expected in this case
//
- if ((list.Count > 0) && (list [0] is PropertyInfo))
- return true;
+ var methods = new List<MethodSpec> ();
+ foreach (var entry in iface.MemberCache.member_hash.Values) {
+ foreach (var name_entry in entry) {
+ if (iface == name_entry.DeclaringType) {
+ if (name_entry.Kind == MemberKind.Method) {
+ methods.Add ((MethodSpec) name_entry);
+ }
+ }
+ }
+ }
- return false;
+ return methods;
}
- /// <summary>
- /// Looks up members with name `name'. If you provide an optional
- /// filter function, it'll only be called with members matching the
- /// requested member name.
- ///
- /// This method will try to use the cache to do the lookup if possible.
- ///
- /// Unlike other FindMembers implementations, this method will always
- /// check all inherited members - even when called on an interface type.
- ///
- /// If you know that you're only looking for methods, you should use
- /// MemberTypes.Method alone since this speeds up the lookup a bit.
- /// When doing a method-only search, it'll try to use a special method
- /// cache (unless it's a dynamic type or an interface) and the returned
- /// MemberInfo's will have the correct ReflectedType for inherited methods.
- /// The lookup process will automatically restart itself in method-only
- /// search mode if it discovers that it's about to return methods.
- /// </summary>
- List<MemberInfo> global = new List<MemberInfo> ();
- bool using_global;
-
- static MemberInfo [] emptyMemberInfo = new MemberInfo [0];
-
- public MemberInfo [] FindMembers (MemberTypes mt, BindingFlags bf, string name,
- MemberFilter filter, object criteria)
+ public static IList<MethodSpec> GetNotImplementedAbstractMethods (TypeSpec type)
{
- if (using_global)
- throw new Exception ();
-
- bool declared_only = (bf & BindingFlags.DeclaredOnly) != 0;
- bool method_search = mt == MemberTypes.Method;
- // If we have a method cache and we aren't already doing a method-only search,
- // then we restart a method search if the first match is a method.
- bool do_method_search = !method_search && (method_hash != null);
-
- List<CacheEntry> applicable;
-
- // If this is a method-only search, we try to use the method cache if
- // possible; a lookup in the method cache will return a MemberInfo with
- // the correct ReflectedType for inherited methods.
-
- if (method_search && (method_hash != null))
- method_hash.TryGetValue (name, out applicable);
- else
- member_hash.TryGetValue (name, out applicable);
-
- if (applicable == null)
- return emptyMemberInfo;
+ if (type.MemberCache.missing_abstract != null)
+ return type.MemberCache.missing_abstract;
+
+ var abstract_methods = new List<MethodSpec> ();
+ List<TypeSpec> hierarchy = null;
//
- // 32 slots gives 53 rss/54 size
- // 2/4 slots gives 55 rss
+ // Stage 1: top-to-bottom scan for abstract members
//
- // Strange: from 25,000 calls, only 1,800
- // are above 2. Why does this impact it?
- //
- global.Clear ();
- using_global = true;
-
- Timer.StartTimer (TimerType.CachedLookup);
-
- EntryType type = GetEntryType (mt, bf);
-
- IMemberContainer current = Container;
+ var abstract_type = type;
+ while (true) {
+ foreach (var entry in abstract_type.MemberCache.member_hash) {
+ foreach (var name_entry in entry.Value) {
+ if ((name_entry.Modifiers & Modifiers.ABSTRACT) == 0)
+ continue;
- bool do_interface_search = current.IsInterface;
+ if (name_entry.Kind != MemberKind.Method)
+ continue;
- // `applicable' is a list of all members with the given member name `name'
- // in the current class and all its base classes. The list is sorted in
- // reverse order due to the way how the cache is initialy created (to speed
- // things up, we're doing a deep-copy of our base).
+ abstract_methods.Add ((MethodSpec) name_entry);
+ }
+ }
- for (int i = applicable.Count-1; i >= 0; i--) {
- CacheEntry entry = (CacheEntry) applicable [i];
+ var base_type = abstract_type.BaseType;
+ if (!base_type.IsAbstract)
+ break;
- // This happens each time we're walking one level up in the class
- // hierarchy. If we're doing a DeclaredOnly search, we must abort
- // the first time this happens (this may already happen in the first
- // iteration of this loop if there are no members with the name we're
- // looking for in the current class).
- if (entry.Container != current) {
- if (declared_only)
- break;
+ if (hierarchy == null)
+ hierarchy = new List<TypeSpec> ();
- if (!do_interface_search && DoneSearching (global))
- break;
+ hierarchy.Add (abstract_type);
+ abstract_type = base_type;
+ }
- current = entry.Container;
- }
+ int not_implemented_count = abstract_methods.Count;
+ if (not_implemented_count == 0 || hierarchy == null) {
+ type.MemberCache.missing_abstract = abstract_methods;
+ return type.MemberCache.missing_abstract;
+ }
- // Is the member of the correct type ?
- if ((entry.EntryType & type & EntryType.MaskType) == 0)
+ //
+ // Stage 2: Remove already implemented methods
+ //
+ foreach (var type_up in hierarchy) {
+ var members = type_up.MemberCache.member_hash;
+ if (members.Count == 0)
continue;
- // Is the member static/non-static ?
- if ((entry.EntryType & type & EntryType.MaskStatic) == 0)
- continue;
+ for (int i = 0; i < abstract_methods.Count; ++i) {
+ var candidate = abstract_methods [i];
+ if (candidate == null)
+ continue;
- // Apply the filter to it.
- if (filter (entry.Member, criteria)) {
- if ((entry.EntryType & EntryType.MaskType) != EntryType.Method) {
- do_method_search = false;
- }
-
- // Because interfaces support multiple inheritance we have to be sure that
- // base member is from same interface, so only top level member will be returned
- if (do_interface_search && global.Count > 0) {
- bool member_already_exists = false;
-
- foreach (MemberInfo mi in global) {
- if (mi is MethodBase)
- continue;
+ IList<MemberSpec> applicable;
+ if (!members.TryGetValue (candidate.Name, out applicable))
+ continue;
- if (IsInterfaceBaseInterface (TypeManager.GetInterfaces (mi.DeclaringType), entry.Member.DeclaringType)) {
- member_already_exists = true;
- break;
- }
- }
- if (member_already_exists)
+ var filter = new MemberFilter (candidate);
+ foreach (var item in applicable) {
+ // TODO: Need to test what should happen for OVERRIDE_UNCHECKED
+ if ((item.Modifiers & (Modifiers.OVERRIDE | Modifiers.OVERRIDE_UNCHECKED | Modifiers.VIRTUAL)) == 0)
continue;
- }
- global.Add (entry.Member);
+ if (filter.Equals (item)) {
+ --not_implemented_count;
+ abstract_methods [i] = null;
+ break;
+ }
+ }
}
}
- Timer.StopTimer (TimerType.CachedLookup);
+ if (not_implemented_count == abstract_methods.Count) {
+ type.MemberCache.missing_abstract = abstract_methods;
+ return type.MemberCache.missing_abstract;
+ }
- // If we have a method cache and we aren't already doing a method-only
- // search, we restart in method-only search mode if the first match is
- // a method. This ensures that we return a MemberInfo with the correct
- // ReflectedType for inherited methods.
- if (do_method_search && (global.Count > 0)){
- using_global = false;
+ var not_implemented = new MethodSpec[not_implemented_count];
+ int counter = 0;
+ foreach (var m in abstract_methods) {
+ if (m == null)
+ continue;
- return FindMembers (MemberTypes.Method, bf, name, filter, criteria);
+ not_implemented[counter++] = m;
}
- using_global = false;
- MemberInfo [] copy = new MemberInfo [global.Count];
- global.CopyTo (copy);
- return copy;
+ type.MemberCache.missing_abstract = not_implemented;
+ return type.MemberCache.missing_abstract;
}
- /// <summary>
- /// Returns true if iterface exists in any base interfaces (ifaces)
- /// </summary>
- static bool IsInterfaceBaseInterface (Type[] ifaces, Type ifaceToFind)
+ static string GetLookupName (MemberSpec ms)
{
- foreach (Type iface in ifaces) {
- if (iface == ifaceToFind)
- return true;
+ if (ms.Kind == MemberKind.Indexer)
+ return IndexerNameAlias;
- Type[] base_ifaces = TypeManager.GetInterfaces (iface);
- if (base_ifaces.Length > 0 && IsInterfaceBaseInterface (base_ifaces, ifaceToFind))
- return true;
- }
- return false;
- }
-
- // find the nested type @name in @this.
- public Type FindNestedType (string name)
- {
- List<CacheEntry> applicable;
- if (!member_hash.TryGetValue (name, out applicable))
- return null;
-
- for (int i = applicable.Count-1; i >= 0; i--) {
- CacheEntry entry = applicable [i];
- if ((entry.EntryType & EntryType.NestedType & EntryType.MaskType) != 0)
- return (Type) entry.Member;
+ if (ms.Kind == MemberKind.Constructor) {
+ if (ms.IsStatic)
+ return ConstructorInfo.TypeConstructorName;
+
+ return ConstructorInfo.ConstructorName;
}
-
- return null;
+
+ return ms.Name;
}
- public MemberInfo FindBaseEvent (Type invocation_type, string name)
+ static string GetLookupName (MemberCore mc)
{
- List<CacheEntry> applicable;
- if (!member_hash.TryGetValue (name, out applicable))
- return null;
+ if (mc is Indexer)
+ return IndexerNameAlias;
- //
- // Walk the chain of events, starting from the top.
- //
- for (int i = applicable.Count - 1; i >= 0; i--)
- {
- CacheEntry entry = applicable [i];
- if ((entry.EntryType & EntryType.Event) == 0)
- continue;
-
- EventInfo ei = (EventInfo)entry.Member;
- return ei.GetAddMethod (true);
- }
+ if (mc is Constructor)
+ return ConstructorInfo.ConstructorName;
- return null;
+ return mc.MemberName.Name;
}
//
- // Looks for extension methods with defined name and extension type
+ // Inflates all member cache nested types
//
- public List<MethodSpec> FindExtensionMethods (Assembly thisAssembly, Type extensionType, string name, bool publicOnly)
+ public void InflateTypes (MemberCache inflated_cache, TypeParameterInflator inflator)
{
- List<CacheEntry> entries;
- if (method_hash != null)
- method_hash.TryGetValue (name, out entries);
- else {
- member_hash.TryGetValue (name, out entries);
- }
-
- if (entries == null)
- return null;
-
- EntryType entry_type = EntryType.Static | EntryType.Method | EntryType.NotExtensionMethod;
- EntryType found_entry_type = entry_type & ~EntryType.NotExtensionMethod;
+ foreach (var item in member_hash) {
+ IList<MemberSpec> inflated_members = null;
+ for (int i = 0; i < item.Value.Count; ++i ) {
+ var member = item.Value[i];
- List<MethodSpec> candidates = null;
- foreach (CacheEntry entry in entries) {
- if ((entry.EntryType & entry_type) == found_entry_type) {
- MethodBase mb = (MethodBase)entry.Member;
-
- // Simple accessibility check
- if ((entry.EntryType & EntryType.Public) == 0 && publicOnly) {
- MethodAttributes ma = mb.Attributes & MethodAttributes.MemberAccessMask;
- if (ma != MethodAttributes.Assembly && ma != MethodAttributes.FamORAssem)
- continue;
-
- if (!TypeManager.IsThisOrFriendAssembly (thisAssembly, mb.DeclaringType.Assembly))
- continue;
- }
+ // FIXME: When inflating members refering nested types before they are inflated
+ if (member == null)
+ continue;
- IMethodData md = TypeManager.GetMethod (mb);
- AParametersCollection pd = md == null ?
- TypeManager.GetParameterData (mb) : md.ParameterInfo;
+ if ((member.Kind & MemberKind.NestedMask) != 0 &&
+ (member.Modifiers & Modifiers.COMPILER_GENERATED) == 0) {
+ if (inflated_members == null) {
+ inflated_members = new MemberSpec[item.Value.Count];
+ inflated_cache.member_hash.Add (item.Key, inflated_members);
+ }
- Type ex_type = pd.ExtensionMethodType;
- if (ex_type == null) {
- entry.EntryType |= EntryType.NotExtensionMethod;
- continue;
+ inflated_members [i] = member.InflateMember (inflator);
}
-
- if (candidates == null)
- candidates = new List<MethodSpec> (2);
- candidates.Add (Import.CreateMethod (mb));
}
}
-
- return candidates;
}
-
- //
- // This finds the method or property for us to override. invocation_type is the type where
- // the override is going to be declared, name is the name of the method/property, and
- // param_types is the parameters, if any to the method or property
+
//
- // Because the MemberCache holds members from this class and all the base classes,
- // we can avoid tons of reflection stuff.
+ // Inflates all open type members, requires InflateTypes to be called before
//
- public MemberInfo FindMemberToOverride (Type invocation_type, string name, AParametersCollection parameters, GenericMethod generic_method, bool is_property)
+ public void InflateMembers (MemberCache cacheToInflate, TypeSpec inflatedType, TypeParameterInflator inflator)
{
- List<CacheEntry> applicable;
- if (method_hash != null && !is_property)
- method_hash.TryGetValue (name, out applicable);
- else
- member_hash.TryGetValue (name, out applicable);
-
- if (applicable == null)
- return null;
- //
- // Walk the chain of methods, starting from the top.
- //
- for (int i = applicable.Count - 1; i >= 0; i--) {
- CacheEntry entry = applicable [i];
-
- if ((entry.EntryType & (is_property ? (EntryType.Property | EntryType.Field) : EntryType.Method)) == 0)
- continue;
+ var inflated_member_hash = cacheToInflate.member_hash;
+ Dictionary<MethodSpec, MethodSpec> accessor_relation = null;
+ List<MemberSpec> accessor_members = null;
- PropertyInfo pi = null;
- MethodInfo mi = null;
- FieldInfo fi = null;
- AParametersCollection cmp_attrs;
-
- if (is_property) {
- if ((entry.EntryType & EntryType.Field) != 0) {
- fi = (FieldInfo)entry.Member;
- cmp_attrs = ParametersCompiled.EmptyReadOnlyParameters;
- } else {
- pi = (PropertyInfo) entry.Member;
- cmp_attrs = TypeManager.GetParameterData (pi);
- }
- } else {
- mi = (MethodInfo) entry.Member;
- cmp_attrs = TypeManager.GetParameterData (mi);
- }
+ foreach (var item in member_hash) {
+ var members = item.Value;
+ IList<MemberSpec> inflated_members = null;
+ for (int i = 0; i < members.Count; ++i ) {
+ var member = members[i];
+
+ //
+ // All nested types have been inflated earlier except for
+ // compiler types which are created later and could miss InflateTypes
+ //
+ if ((member.Kind & MemberKind.NestedMask) != 0 &&
+ (member.Modifiers & Modifiers.COMPILER_GENERATED) == 0) {
+ if (inflated_members == null)
+ inflated_members = inflated_member_hash[item.Key];
- if (fi != null) {
- // TODO: Almost duplicate !
- // Check visibility
- switch (fi.Attributes & FieldAttributes.FieldAccessMask) {
- case FieldAttributes.PrivateScope:
continue;
- case FieldAttributes.Private:
+ }
+
+ //
+ // Clone the container first
+ //
+ if (inflated_members == null) {
+ inflated_members = new MemberSpec [item.Value.Count];
+ inflated_member_hash.Add (item.Key, inflated_members);
+ }
+
+ var local_inflator = inflator;
+
+ if (member.DeclaringType != inflatedType) {
//
- // A private method is Ok if we are a nested subtype.
- // The spec actually is not very clear about this, see bug 52458.
+ // Don't inflate non generic interface members
+ // merged into generic interface
//
- if (!invocation_type.Equals (entry.Container.Type) &&
- !TypeManager.IsNestedChildOf (invocation_type, entry.Container.Type))
+ if (!member.DeclaringType.IsGeneric) {
+ inflated_members [i] = member;
continue;
- break;
- case FieldAttributes.FamANDAssem:
- case FieldAttributes.Assembly:
+ }
+
//
- // Check for assembly methods
+ // Needed when inflating flatten interfaces. It inflates
+ // container type only, type parameters are already done
//
- if (fi.DeclaringType.Assembly != CodeGen.Assembly.Builder)
- continue;
- break;
+ // Handles cases like:
+ //
+ // interface I<T> {}
+ // interface I<U, V> : I<U> {}
+ //
+ // class C: I<int, bool> {}
+ //
+ var inflated_parent = inflator.Inflate (member.DeclaringType);
+ if (inflated_parent != inflator.TypeInstance)
+ local_inflator = new TypeParameterInflator (inflator, inflated_parent);
}
- return entry.Member;
- }
- //
- // Check the arguments
- //
- if (cmp_attrs.Count != parameters.Count)
- continue;
-
- int j;
- for (j = 0; j < cmp_attrs.Count; ++j) {
//
- // LAMESPEC: No idea why `params' modifier is ignored
+ // Inflate every member, its parent is now different
//
- if ((parameters.FixedParameters [j].ModFlags & ~Parameter.Modifier.PARAMS) !=
- (cmp_attrs.FixedParameters [j].ModFlags & ~Parameter.Modifier.PARAMS))
- break;
-
- if (!TypeManager.IsEqual (parameters.Types [j], cmp_attrs.Types [j]))
- break;
- }
+ var inflated = member.InflateMember (local_inflator);
+ inflated_members [i] = inflated;
- if (j < cmp_attrs.Count)
- continue;
+ if (member is PropertySpec || member is EventSpec) {
+ if (accessor_members == null)
+ accessor_members = new List<MemberSpec> ();
- //
- // check generic arguments for methods
- //
- if (mi != null) {
- Type [] cmpGenArgs = TypeManager.GetGenericArguments (mi);
- if (generic_method == null && cmpGenArgs != null && cmpGenArgs.Length != 0)
- continue;
- if (generic_method != null && cmpGenArgs != null && cmpGenArgs.Length != generic_method.TypeParameters.Length)
+ accessor_members.Add (inflated);
continue;
- }
+ }
- //
- // get one of the methods because this has the visibility info.
- //
- if (is_property) {
- mi = pi.GetGetMethod (true);
- if (mi == null)
- mi = pi.GetSetMethod (true);
+ if (member.IsAccessor) {
+ if (accessor_relation == null)
+ accessor_relation = new Dictionary<MethodSpec, MethodSpec> ();
+ accessor_relation.Add ((MethodSpec) member, (MethodSpec) inflated);
+ }
}
-
- //
- // Check visibility
- //
- switch (mi.Attributes & MethodAttributes.MemberAccessMask) {
- case MethodAttributes.PrivateScope:
- continue;
- case MethodAttributes.Private:
- //
- // A private method is Ok if we are a nested subtype.
- // The spec actually is not very clear about this, see bug 52458.
- //
- if (!invocation_type.Equals (entry.Container.Type) &&
- !TypeManager.IsNestedChildOf (invocation_type, entry.Container.Type))
- continue;
- break;
- case MethodAttributes.FamANDAssem:
- case MethodAttributes.Assembly:
- //
- // Check for assembly methods
- //
- if (!TypeManager.IsThisOrFriendAssembly (invocation_type.Assembly, mi.DeclaringType.Assembly))
+ }
+
+ if (accessor_members != null) {
+ foreach (var member in accessor_members) {
+ var prop = member as PropertySpec;
+ if (prop != null) {
+ if (prop.Get != null)
+ prop.Get = accessor_relation[prop.Get];
+ if (prop.Set != null)
+ prop.Set = accessor_relation[prop.Set];
+
continue;
- break;
+ }
+
+ var ev = (EventSpec) member;
+ ev.AccessorAdd = accessor_relation[ev.AccessorAdd];
+ ev.AccessorRemove = accessor_relation[ev.AccessorRemove];
}
- return entry.Member;
}
-
- return null;
}
- /// <summary>
- /// The method is looking for conflict with inherited symbols (errors CS0108, CS0109).
- /// We handle two cases. The first is for types without parameters (events, field, properties).
- /// The second are methods, indexers and this is why ignore_complex_types is here.
- /// The latest param is temporary hack. See DoDefineMembers method for more info.
- /// </summary>
- public MemberInfo FindMemberWithSameName (string name, bool ignore_complex_types, MemberInfo ignore_member)
- {
- List<CacheEntry> applicable = null;
-
- if (method_hash != null)
- method_hash.TryGetValue (name, out applicable);
-
- if (applicable != null) {
- for (int i = applicable.Count - 1; i >= 0; i--) {
- CacheEntry entry = (CacheEntry) applicable [i];
- if ((entry.EntryType & EntryType.Public) != 0)
- return entry.Member;
- }
- }
-
- if (member_hash == null)
- return null;
-
- if (member_hash.TryGetValue (name, out applicable)) {
- for (int i = applicable.Count - 1; i >= 0; i--) {
- CacheEntry entry = (CacheEntry) applicable [i];
- if ((entry.EntryType & EntryType.Public) != 0 & entry.Member != ignore_member) {
- if (ignore_complex_types) {
- if ((entry.EntryType & EntryType.Method) != 0)
- continue;
-
- // Does exist easier way how to detect indexer ?
- if ((entry.EntryType & EntryType.Property) != 0) {
- AParametersCollection arg_types = TypeManager.GetParameterData ((PropertyInfo)entry.Member);
- if (arg_types.Count > 0)
- continue;
- }
- }
- return entry.Member;
- }
- }
- }
- return null;
- }
-
-
- /// <summary>
- /// Builds low-case table for CLS Compliance test
- /// </summary>
- public Dictionary<string, object> GetPublicMembers ()
- {
- if (locase_table != null)
- return locase_table;
-
- locase_table = new Dictionary<string, object> ();
- foreach (var entry in member_hash) {
- var members = entry.Value;
- for (int ii = 0; ii < members.Count; ++ii) {
- CacheEntry member_entry = members [ii];
-
- if ((member_entry.EntryType & EntryType.Public) == 0)
- continue;
-
- // TODO: Does anyone know easier way how to detect that member is internal ?
- switch (member_entry.EntryType & EntryType.MaskType) {
- case EntryType.Constructor:
- continue;
-
- case EntryType.Field:
- if ((((FieldInfo)member_entry.Member).Attributes & (FieldAttributes.Assembly | FieldAttributes.Public)) == FieldAttributes.Assembly)
- continue;
- break;
-
- case EntryType.Method:
- if ((((MethodInfo)member_entry.Member).Attributes & (MethodAttributes.Assembly | MethodAttributes.Public)) == MethodAttributes.Assembly)
+ //
+ // For imported class method do additional validation to be sure that metadata
+ // override flag was correct
+ //
+ static bool IsRealMethodOverride (MethodSpec ms)
+ {
+ IList<MemberSpec> candidates;
+ var dt = ms.DeclaringType;
+ while (dt.BaseType != null) {
+ var base_cache = dt.BaseType.MemberCache;
+ if (base_cache.member_hash.TryGetValue (ms.Name, out candidates)) {
+ foreach (var candidate in candidates) {
+ if (candidate.Kind != ms.Kind)
continue;
- break;
-
- case EntryType.Property:
- PropertyInfo pi = (PropertyInfo)member_entry.Member;
- if (pi.GetSetMethod () == null && pi.GetGetMethod () == null)
+
+ if (candidate.Arity != ms.Arity)
continue;
- break;
-
- case EntryType.Event:
- EventInfo ei = (EventInfo)member_entry.Member;
- MethodInfo mi = ei.GetAddMethod ();
- if ((mi.Attributes & (MethodAttributes.Assembly | MethodAttributes.Public)) == MethodAttributes.Assembly)
+
+ if (!TypeSpecComparer.Override.IsEqual (((MethodSpec) candidate).Parameters, ms.Parameters))
continue;
- break;
- }
- string lcase = ((string)entry.Key).ToLower (System.Globalization.CultureInfo.InvariantCulture);
- locase_table [lcase] = member_entry.Member;
- break;
- }
- }
- return locase_table;
- }
-
- public IDictionary<string, List<CacheEntry>> Members {
- get {
- return member_hash;
- }
- }
-
- /// <summary>
- /// Cls compliance check whether methods or constructors parameters differing only in ref or out, or in array rank
- /// </summary>
- ///
- // TODO: refactor as method is always 'this'
- public static void VerifyClsParameterConflict (IList<CacheEntry> al, MethodCore method, MemberInfo this_builder, Report Report)
- {
- EntryType tested_type = (method is Constructor ? EntryType.Constructor : EntryType.Method) | EntryType.Public;
-
- for (int i = 0; i < al.Count; ++i) {
- var entry = al [i];
-
- // skip itself
- if (entry.Member == this_builder)
- continue;
-
- if ((entry.EntryType & tested_type) != tested_type)
- continue;
-
- MethodBase method_to_compare = (MethodBase)entry.Member;
- AttributeTester.Result result = AttributeTester.AreOverloadedMethodParamsClsCompliant (
- method.Parameters, TypeManager.GetParameterData (method_to_compare));
-
- if (result == AttributeTester.Result.Ok)
- continue;
-
- IMethodData md = TypeManager.GetMethod (method_to_compare);
-
- // TODO: now we are ignoring CLSCompliance(false) on method from other assembly which is buggy.
- // However it is exactly what csc does.
- if (md != null && !md.IsClsComplianceRequired ())
- continue;
-
- Report.SymbolRelatedToPreviousError (entry.Member);
- switch (result) {
- case AttributeTester.Result.RefOutArrayError:
- Report.Warning (3006, 1, method.Location,
- "Overloaded method `{0}' differing only in ref or out, or in array rank, is not CLS-compliant",
- method.GetSignatureForError ());
- continue;
- case AttributeTester.Result.ArrayArrayError:
- Report.Warning (3007, 1, method.Location,
- "Overloaded method `{0}' differing only by unnamed array types is not CLS-compliant",
- method.GetSignatureForError ());
- continue;
+
+ // Everything matches except modifiers, it's not correct soverride
+ if ((candidate.Modifiers & Modifiers.AccessibilityMask) != (ms.Modifiers & Modifiers.AccessibilityMask))
+ return false;
+
+ return true;
+ }
}
- throw new NotImplementedException (result.ToString ());
- }
- }
+ dt = dt.BaseType;
+ }
- public bool CheckExistingMembersOverloads (MemberCore member, string name, ParametersCompiled parameters, Report Report)
+ return false;
+ }
+
+ //
+ // Checks all appropriate container members for CLS compliance
+ //
+ public void VerifyClsCompliance (TypeSpec container, Report report)
{
- List<CacheEntry> entries;
- if (!member_hash.TryGetValue (name, out entries))
- return true;
+ if (locase_members != null)
+ return;
- int method_param_count = parameters.Count;
- for (int i = entries.Count - 1; i >= 0; --i) {
- CacheEntry ce = (CacheEntry) entries [i];
+ if (container.BaseType == null) {
+ locase_members = new Dictionary<string, MemberSpec[]> (member_hash.Count); // StringComparer.OrdinalIgnoreCase);
+ } else {
+ container.BaseType.MemberCache.VerifyClsCompliance (container.BaseType, report);
+ locase_members = new Dictionary<string, MemberSpec[]> (container.BaseType.MemberCache.locase_members); //, StringComparer.OrdinalIgnoreCase);
+ }
- if (ce.Container != member.Parent.PartialContainer)
- return true;
+ var is_imported_type = container.MemberDefinition.IsImported;
+ foreach (var entry in container.MemberCache.member_hash) {
+ for (int i = 0; i < entry.Value.Count; ++i ) {
+ var name_entry = entry.Value[i];
+ if ((name_entry.Modifiers & (Modifiers.PUBLIC | Modifiers.PROTECTED)) == 0)
+ continue;
- Type [] p_types;
- AParametersCollection pd;
- if ((ce.EntryType & EntryType.Property) != 0) {
- pd = TypeManager.GetParameterData ((PropertyInfo) ce.Member);
- p_types = pd.Types;
- } else {
- MethodBase mb = (MethodBase) ce.Member;
-
- // TODO: This is more like a hack, because we are adding generic methods
- // twice with and without arity name
- if (TypeManager.IsGenericMethod (mb) && !member.MemberName.IsGeneric)
+ if ((name_entry.Modifiers & (Modifiers.OVERRIDE | Modifiers.COMPILER_GENERATED)) != 0)
continue;
- pd = TypeManager.GetParameterData (mb);
- p_types = pd.Types;
+ if ((name_entry.Kind & MemberKind.MaskType) == 0)
+ continue;
+
+ if (name_entry.MemberDefinition.IsNotCLSCompliant ())
+ continue;
+
+ IParametersMember p_a = name_entry as IParametersMember;
+ if (p_a != null && !name_entry.IsAccessor) {
+ if (!is_imported_type) {
+ var p_a_pd = p_a.Parameters;
+ for (int ii = i + 1; ii < entry.Value.Count; ++ii) {
+ var checked_entry = entry.Value[ii];
+ IParametersMember p_b = checked_entry as IParametersMember;
+ if (p_b == null)
+ continue;
+
+ if (p_a_pd.Count != p_b.Parameters.Count)
+ continue;
+
+ if (checked_entry.IsAccessor)
+ continue;
+
+ var res = ParametersCompiled.IsSameClsSignature (p_a.Parameters, p_b.Parameters);
+ if (res != 0) {
+ var last = GetLaterDefinedMember (checked_entry, name_entry);
+ if (last == checked_entry.MemberDefinition) {
+ report.SymbolRelatedToPreviousError (name_entry);
+ } else {
+ report.SymbolRelatedToPreviousError (checked_entry);
+ }
+
+ if ((res & 1) != 0) {
+ report.Warning (3006, 1, last.Location,
+ "Overloaded method `{0}' differing only in ref or out, or in array rank, is not CLS-compliant",
+ name_entry.GetSignatureForError ());
+ }
+
+ if ((res & 2) != 0) {
+ report.Warning (3007, 1, last.Location,
+ "Overloaded method `{0}' differing only by unnamed array types is not CLS-compliant",
+ name_entry.GetSignatureForError ());
+ }
+ }
+ }
+ }
+ }
+
+ if (i > 0 || name_entry.Kind == MemberKind.Constructor || name_entry.Kind == MemberKind.Indexer)
+ continue;
+
+ var name_entry_locase = name_entry.Name.ToLowerInvariant ();
+
+ MemberSpec[] found;
+ if (!locase_members.TryGetValue (name_entry_locase, out found)) {
+ found = new MemberSpec[] { name_entry };
+ locase_members.Add (name_entry_locase, found);
+ } else {
+ bool same_names_only = true;
+ foreach (var f in found) {
+ if (f.Name == name_entry.Name)
+ continue;
+
+// if (f.IsAccessor && name_entry.IsAccessor)
+// continue;
+
+ same_names_only = false;
+ if (!is_imported_type) {
+ var last = GetLaterDefinedMember (f, name_entry);
+ if (last == f.MemberDefinition) {
+ report.SymbolRelatedToPreviousError (name_entry);
+ } else {
+ report.SymbolRelatedToPreviousError (f);
+ }
+
+ report.Warning (3005, 1, last.Location,
+ "Identifier `{0}' differing only in case is not CLS-compliant", last.GetSignatureForError ());
+ }
+ }
+
+ if (!same_names_only) {
+ Array.Resize (ref found, found.Length + 1);
+ found[found.Length - 1] = name_entry;
+ locase_members[name_entry_locase] = found;
+ }
+ }
}
+ }
+ }
- if (p_types.Length != method_param_count)
+ //
+ // Local report helper to issue correctly ordered members stored in hashtable
+ //
+ static MemberCore GetLaterDefinedMember (MemberSpec a, MemberSpec b)
+ {
+ var mc_a = a.MemberDefinition as MemberCore;
+ var mc_b = b.MemberDefinition as MemberCore;
+ if (mc_a == null)
+ return mc_b;
+
+ if (mc_b == null)
+ return mc_a;
+
+ if (mc_a.Location.File != mc_a.Location.File)
+ return mc_b;
+
+ return mc_b.Location.Row > mc_a.Location.Row ? mc_b : mc_a;
+ }
+
+ public bool CheckExistingMembersOverloads (MemberCore member, AParametersCollection parameters)
+ {
+ var name = GetLookupName (member);
+ var imb = member as InterfaceMemberBase;
+ if (imb != null && imb.IsExplicitImpl) {
+ name = imb.GetFullName (name);
+ }
+
+ return CheckExistingMembersOverloads (member, name, parameters);
+ }
+
+ public bool CheckExistingMembersOverloads (MemberCore member, string name, AParametersCollection parameters)
+ {
+ IList<MemberSpec> entries;
+ if (!member_hash.TryGetValue (name, out entries))
+ return false;
+
+ var Report = member.Compiler.Report;
+
+ int method_param_count = parameters.Count;
+ for (int i = entries.Count - 1; i >= 0; --i) {
+ var ce = entries[i];
+ var pm = ce as IParametersMember;
+ var pd = pm == null ? ParametersCompiled.EmptyReadOnlyParameters : pm.Parameters;
+ if (pd.Count != method_param_count)
+ continue;
+
+ if (ce.Arity != member.MemberName.Arity)
continue;
+ // Ignore merged interface members
+ if (member.Parent.PartialContainer != ce.DeclaringType.MemberDefinition)
+ continue;
+
+ var p_types = pd.Types;
if (method_param_count > 0) {
int ii = method_param_count - 1;
- Type type_a, type_b;
+ TypeSpec type_a, type_b;
do {
type_a = parameters.Types [ii];
type_b = p_types [ii];
- if (TypeManager.IsGenericParameter (type_a) && type_a.DeclaringMethod != null)
- type_a = typeof (TypeParameter);
-
- if (TypeManager.IsGenericParameter (type_b) && type_b.DeclaringMethod != null)
- type_b = typeof (TypeParameter);
-
if ((pd.FixedParameters [ii].ModFlags & Parameter.Modifier.ISBYREF) !=
(parameters.FixedParameters [ii].ModFlags & Parameter.Modifier.ISBYREF))
break;
- } while (TypeManager.IsEqual (type_a, type_b) && ii-- != 0);
+ } while (TypeSpecComparer.Override.IsEqual (type_a, type_b) && ii-- != 0);
if (ii >= 0)
continue;
//
// Operators can differ in return type only
//
- if (member is Operator) {
- Operator op = TypeManager.GetMethod ((MethodBase) ce.Member) as Operator;
- if (op != null && op.ReturnType != ((Operator) member).ReturnType)
- continue;
- }
+ if (member is Operator && ce.Kind == MemberKind.Operator && ((MethodSpec) ce).ReturnType != ((Operator) member).ReturnType)
+ continue;
//
// Report difference in parameter modifiers only
//
if (pd != null && member is MethodCore) {
ii = method_param_count;
- while (ii-- != 0 && parameters.FixedParameters [ii].ModFlags == pd.FixedParameters [ii].ModFlags &&
- parameters.ExtensionMethodType == pd.ExtensionMethodType);
+ while (ii-- != 0 && parameters.FixedParameters[ii].ModFlags == pd.FixedParameters[ii].ModFlags &&
+ parameters.ExtensionMethodType == pd.ExtensionMethodType) ;
if (ii >= 0) {
- MethodCore mc = TypeManager.GetMethod ((MethodBase) ce.Member) as MethodCore;
- Report.SymbolRelatedToPreviousError (ce.Member);
- if ((member.ModFlags & Modifiers.PARTIAL) != 0 && (mc.ModFlags & Modifiers.PARTIAL) != 0) {
+ var mc = ce as MethodSpec;
+ member.Compiler.Report.SymbolRelatedToPreviousError (ce);
+ if ((member.ModFlags & Modifiers.PARTIAL) != 0 && (mc.Modifiers & Modifiers.PARTIAL) != 0) {
if (parameters.HasParams || pd.HasParams) {
Report.Error (758, member.Location,
"A partial method declaration and partial method implementation cannot differ on use of `params' modifier");
Report.Error (755, member.Location,
"A partial method declaration and partial method implementation must be both an extension method or neither");
}
+ } else if (member is Constructor) {
+ Report.Error (851, member.Location,
+ "Overloaded contructor `{0}' cannot differ on use of parameter modifiers only",
+ member.GetSignatureForError ());
} else {
- if (member is Constructor) {
- Report.Error (851, member.Location,
- "Overloaded contructor `{0}' cannot differ on use of parameter modifiers only",
- member.GetSignatureForError ());
- } else {
- Report.Error (663, member.Location,
- "Overloaded method `{0}' cannot differ on use of parameter modifiers only",
- member.GetSignatureForError ());
- }
+ Report.Error (663, member.Location,
+ "Overloaded method `{0}' cannot differ on use of parameter modifiers only",
+ member.GetSignatureForError ());
}
return false;
}
}
}
- if ((ce.EntryType & EntryType.Method) != 0) {
+ if ((ce.Kind & (MemberKind.Method | MemberKind.FakeMethod)) != 0) {
Method method_a = member as Method;
- Method method_b = TypeManager.GetMethod ((MethodBase) ce.Member) as Method;
+ Method method_b = ce.MemberDefinition as Method;
if (method_a != null && method_b != null && (method_a.ModFlags & method_b.ModFlags & Modifiers.PARTIAL) != 0) {
const Modifiers partial_modifiers = Modifiers.STATIC | Modifiers.UNSAFE;
if (method_a.IsPartialDefinition == method_b.IsPartialImplementation) {
method_a.Parent.IsUnsafe && method_b.Parent.IsUnsafe) {
if (method_a.IsPartialImplementation) {
method_a.SetPartialDefinition (method_b);
- entries.RemoveAt (i);
+ if (entries.Count == 1)
+ member_hash.Remove (name);
+ else
+ entries.RemoveAt (i);
} else {
method_b.SetPartialDefinition (method_a);
method_a.caching_flags |= MemberCore.Flags.PartialDefinitionExists;
continue;
}
- if ((method_a.ModFlags & Modifiers.STATIC) != (method_b.ModFlags & Modifiers.STATIC)) {
- Report.SymbolRelatedToPreviousError (ce.Member);
+ if (method_a.IsStatic != method_b.IsStatic) {
+ Report.SymbolRelatedToPreviousError (ce);
Report.Error (763, member.Location,
"A partial method declaration and partial method implementation must be both `static' or neither");
}
- Report.SymbolRelatedToPreviousError (ce.Member);
+ Report.SymbolRelatedToPreviousError (ce);
Report.Error (764, member.Location,
"A partial method declaration and partial method implementation must be both `unsafe' or neither");
return false;
}
- Report.SymbolRelatedToPreviousError (ce.Member);
+ Report.SymbolRelatedToPreviousError (ce);
if (method_a.IsPartialDefinition) {
Report.Error (756, member.Location, "A partial method `{0}' declaration is already defined",
member.GetSignatureForError ());
- } else {
- Report.Error (757, member.Location, "A partial method `{0}' implementation is already defined",
- member.GetSignatureForError ());
}
+ Report.Error (757, member.Location, "A partial method `{0}' implementation is already defined",
+ member.GetSignatureForError ());
return false;
}
- Report.SymbolRelatedToPreviousError (ce.Member);
- IMethodData duplicate_member = TypeManager.GetMethod ((MethodBase) ce.Member);
- if (member is Operator && duplicate_member is Operator) {
- Report.Error (557, member.Location, "Duplicate user-defined conversion in type `{0}'",
- member.Parent.GetSignatureForError ());
- return false;
- }
+ Report.SymbolRelatedToPreviousError (ce);
bool is_reserved_a = member is AbstractPropertyEventMethod || member is Operator;
- bool is_reserved_b = duplicate_member is AbstractPropertyEventMethod || duplicate_member is Operator;
+ bool is_reserved_b = ((MethodSpec) ce).IsReservedMethod;
if (is_reserved_a || is_reserved_b) {
Report.Error (82, member.Location, "A member `{0}' is already reserved",
is_reserved_a ?
- TypeManager.GetFullNameSignature (ce.Member) :
+ ce.GetSignatureForError () :
member.GetSignatureForError ());
return false;
}
} else {
- Report.SymbolRelatedToPreviousError (ce.Member);
+ Report.SymbolRelatedToPreviousError (ce);
}
-
+
+ if (member is Operator && ce.Kind == MemberKind.Operator) {
+ Report.Error (557, member.Location, "Duplicate user-defined conversion in type `{0}'",
+ member.Parent.GetSignatureForError ());
+ return false;
+ }
+
Report.Error (111, member.Location,
"A member `{0}' is already defined. Rename this member or use different parameter types",
member.GetSignatureForError ());
using System.Security;
using System.Security.Permissions;
using System.Text;
+using System.Linq;
#if NET_2_1
using XmlElement = System.Object;
namespace Mono.CSharp {
- public abstract class MethodCore : InterfaceMemberBase
+ public abstract class MethodCore : InterfaceMemberBase, IParametersMember
{
- public readonly ParametersCompiled Parameters;
+ protected ParametersCompiled parameters;
protected ToplevelBlock block;
protected MethodSpec spec;
MemberName name, Attributes attrs, ParametersCompiled parameters)
: base (parent, generic, type, mod, allowed_mod, name, attrs)
{
- Parameters = parameters;
+ this.parameters = parameters;
}
//
// Returns the System.Type array for the parameters of this method
//
- public Type [] ParameterTypes {
+ public TypeSpec [] ParameterTypes {
get {
- return Parameters.Types;
+ return parameters.Types;
}
}
public ParametersCompiled ParameterInfo {
get {
- return Parameters;
+ return parameters;
}
}
+
+ AParametersCollection IParametersMember.Parameters {
+ get { return parameters; }
+ }
public ToplevelBlock Block {
get {
public CallingConventions CallingConventions {
get {
- CallingConventions cc = Parameters.CallingConvention;
+ CallingConventions cc = parameters.CallingConvention;
if (!IsInterface)
if ((ModFlags & Modifiers.STATIC) == 0)
cc |= CallingConventions.HasThis;
}
}
+ protected override bool CheckOverrideAgainstBase (MemberSpec base_member)
+ {
+ bool res = base.CheckOverrideAgainstBase (base_member);
+
+ //
+ // Check that the permissions are not being changed
+ //
+ if (!CheckAccessModifiers (this, base_member)) {
+ Error_CannotChangeAccessModifiers (this, base_member);
+ res = false;
+ }
+
+ return res;
+ }
+
protected override bool CheckBase ()
{
// Check whether arguments were correct.
- if (!DefineParameters (Parameters))
+ if (!DefineParameters (parameters))
return false;
return base.CheckBase ();
//
public override string GetDocCommentName (DeclSpace ds)
{
- return DocUtil.GetMethodDocCommentName (this, Parameters, ds);
+ return DocUtil.GetMethodDocCommentName (this, parameters, ds);
}
//
if (!base.VerifyClsCompliance ())
return false;
- if (Parameters.HasArglist) {
+ if (parameters.HasArglist) {
Report.Warning (3000, 1, Location, "Methods with variable arguments are not CLS-compliant");
}
- if (!AttributeTester.IsClsCompliant (MemberType)) {
+ if (member_type != null && !member_type.IsCLSCompliant ()) {
Report.Warning (3002, 1, Location, "Return type of `{0}' is not CLS-compliant",
GetSignatureForError ());
}
- Parameters.VerifyClsCompliance (this);
+ parameters.VerifyClsCompliance (this);
return true;
}
}
- interface IGenericMethodDefinition : IMemberDefinition
+ public interface IGenericMethodDefinition : IMemberDefinition
{
- MethodInfo MakeGenericMethod (Type[] targs);
+ TypeParameterSpec[] TypeParameters { get; }
+ int TypeParametersCount { get; }
+
+// MethodInfo MakeGenericMethod (TypeSpec[] targs);
}
- public class MethodSpec : MemberSpec
+ public class MethodSpec : MemberSpec, IParametersMember
{
MethodBase metaInfo;
- readonly AParametersCollection parameters;
+ AParametersCollection parameters;
+ TypeSpec returnType;
+
+ TypeSpec[] targs;
+ TypeParameterSpec[] constraints;
- public MethodSpec (MemberKind kind, IMemberDefinition details, MethodBase info, AParametersCollection parameters, Modifiers modifiers)
- : base (kind, details, info.Name, modifiers)
+ public MethodSpec (MemberKind kind, TypeSpec declaringType, IMemberDefinition details, TypeSpec returnType,
+ MethodBase info, AParametersCollection parameters, Modifiers modifiers)
+ : base (kind, declaringType, details, modifiers)
{
- this.MetaInfo = info;
+ this.metaInfo = info;
this.parameters = parameters;
+ this.returnType = returnType;
}
- public override Type DeclaringType {
+ #region Properties
+
+ public override int Arity {
get {
- return MetaInfo.DeclaringType;
+ return IsGeneric ? GenericDefinition.TypeParametersCount : 0;
}
}
- public Type[] GetGenericArguments ()
- {
- return MetaInfo.GetGenericArguments ();
- }
-
- public MethodSpec Inflate (Type[] targs)
- {
- // TODO: Only create MethodSpec and inflate parameters, defer the call for later
- var mb = ((IGenericMethodDefinition) definition).MakeGenericMethod (targs);
+ public TypeParameterSpec[] Constraints {
+ get {
+ if (constraints == null && IsGeneric)
+ constraints = GenericDefinition.TypeParameters;
- // TODO: Does not work on .NET
- var par = TypeManager.GetParameterData (mb);
+ return constraints;
+ }
+ }
- return new MethodSpec (Kind, definition, mb, par, Modifiers);
+ public bool IsConstructor {
+ get {
+ return Kind == MemberKind.Constructor;
+ }
}
- public bool IsAbstract {
+ public IGenericMethodDefinition GenericDefinition {
get {
- return (Modifiers & Modifiers.ABSTRACT) != 0;
+ return (IGenericMethodDefinition) definition;
}
}
- public bool IsConstructor {
+ public bool IsExtensionMethod {
get {
- return MetaInfo.IsConstructor;
+ return IsStatic && parameters.HasExtensionMethodType;
}
}
- public bool IsGenericMethod {
+ public bool IsSealed {
get {
- return MetaInfo.IsGenericMethod;
+ return (Modifiers & Modifiers.SEALED) != 0;
}
}
}
}
- public MethodBase MetaInfo {
+ public bool IsReservedMethod {
get {
- return metaInfo;
+ return Kind == MemberKind.Operator || IsAccessor;
}
- set {
- metaInfo = value;
+ }
+
+ TypeSpec IInterfaceMemberSpec.MemberType {
+ get {
+ return returnType;
}
}
public AParametersCollection Parameters {
- get { return parameters; }
+ get {
+ return parameters;
+ }
}
- public Type ReturnType {
+ public TypeSpec ReturnType {
get {
- return IsConstructor ?
- TypeManager.void_type : ((MethodInfo) MetaInfo).ReturnType;
+ return returnType;
+ }
+ }
+
+ public TypeSpec[] TypeArguments {
+ get {
+ return targs;
+ }
+ }
+
+ #endregion
+
+ public MethodSpec GetGenericMethodDefinition ()
+ {
+ if (!IsGeneric && !DeclaringType.IsGeneric)
+ return this;
+
+ return MemberCache.GetMember (declaringType, this);
+ }
+
+ public MethodBase GetMetaInfo ()
+ {
+ if ((state & StateFlags.PendingMetaInflate) != 0) {
+ if (DeclaringType.IsTypeBuilder) {
+ if (IsConstructor)
+ metaInfo = TypeBuilder.GetConstructor (DeclaringType.GetMetaInfo (), (ConstructorInfo) metaInfo);
+ else
+ metaInfo = TypeBuilder.GetMethod (DeclaringType.GetMetaInfo (), (MethodInfo) metaInfo);
+ } else {
+ metaInfo = MethodInfo.GetMethodFromHandle (metaInfo.MethodHandle, DeclaringType.GetMetaInfo ().TypeHandle);
+ }
+
+ state &= ~StateFlags.PendingMetaInflate;
+ }
+
+ if ((state & StateFlags.PendingMakeMethod) != 0) {
+ metaInfo = ((MethodInfo) metaInfo).MakeGenericMethod (targs.Select (l => l.GetMetaInfo ()).ToArray ());
+ state &= ~StateFlags.PendingMakeMethod;
}
+
+ if (Kind == MemberKind.FakeMethod)
+ throw new InternalErrorException ("Emitting fake method");
+
+ return metaInfo;
+ }
+
+ public override string GetSignatureForError ()
+ {
+ string name;
+ if (IsConstructor) {
+ name = DeclaringType.GetSignatureForError () + "." + DeclaringType.Name;
+ } else if (Kind == MemberKind.Operator) {
+ var op = Operator.GetType (Name).Value;
+ if (op == Operator.OpType.Implicit || op == Operator.OpType.Explicit) {
+ name = DeclaringType.GetSignatureForError () + "." + Operator.GetName (op) + " operator " + returnType.GetSignatureForError ();
+ } else {
+ name = DeclaringType.GetSignatureForError () + ".operator " + Operator.GetName (op);
+ }
+ } else if (IsAccessor) {
+ int split = Name.IndexOf ('_');
+ name = Name.Substring (split + 1);
+ var postfix = Name.Substring (0, split);
+ if (split == 3) {
+ var pc = parameters.Count;
+ if (pc > 0 && postfix == "get") {
+ name = "this" + parameters.GetSignatureForError ("[", "]", pc);
+ } else if (pc > 1 && postfix == "set") {
+ name = "this" + parameters.GetSignatureForError ("[", "]", pc - 1);
+ }
+ }
+
+ return DeclaringType.GetSignatureForError () + "." + name + "." + postfix;
+ } else {
+ name = base.GetSignatureForError ();
+ if (targs != null)
+ name += "<" + TypeManager.CSharpName (targs) + ">";
+ else if (IsGeneric)
+ name += "<" + TypeManager.CSharpName (GenericDefinition.TypeParameters) + ">";
+ }
+
+ return name + parameters.GetSignatureForError ();
+ }
+
+ public override MemberSpec InflateMember (TypeParameterInflator inflator)
+ {
+ var ms = (MethodSpec) base.InflateMember (inflator);
+ ms.returnType = inflator.Inflate (returnType);
+ ms.parameters = parameters.Inflate (inflator);
+ if (IsGeneric)
+ ms.constraints = TypeParameterSpec.InflateConstraints (inflator, GenericDefinition.TypeParameters);
+
+ return ms;
+ }
+
+ public MethodSpec MakeGenericMethod (params TypeSpec[] targs)
+ {
+ if (targs == null)
+ throw new ArgumentNullException ();
+// TODO MemberCache
+// if (generic_intances != null && generic_intances.TryGetValue (targs, out ginstance))
+// return ginstance;
+
+ //if (generic_intances == null)
+ // generic_intances = new Dictionary<TypeSpec[], Method> (TypeSpecArrayComparer.Default);
+
+ var inflator = new TypeParameterInflator (DeclaringType, GenericDefinition.TypeParameters, targs);
+
+ var inflated = (MethodSpec) MemberwiseClone ();
+ inflated.declaringType = inflator.TypeInstance;
+ inflated.returnType = inflator.Inflate (returnType);
+ inflated.parameters = parameters.Inflate (inflator);
+ inflated.targs = targs;
+ inflated.constraints = TypeParameterSpec.InflateConstraints (inflator, constraints ?? GenericDefinition.TypeParameters);
+ inflated.state |= StateFlags.PendingMakeMethod;
+
+ // if (inflated.parent == null)
+ // inflated.parent = parent;
+
+ //generic_intances.Add (targs, inflated);
+ return inflated;
+ }
+
+ public MethodSpec Mutate (TypeParameterMutator mutator)
+ {
+ var targs = TypeArguments;
+ if (targs != null)
+ targs = mutator.Mutate (targs);
+
+ var decl = DeclaringType;
+ if (DeclaringType.IsGenericOrParentIsGeneric) {
+ decl = mutator.Mutate (decl);
+ }
+
+ if (targs == TypeArguments && decl == DeclaringType)
+ return this;
+
+ var ms = (MethodSpec) MemberwiseClone ();
+ if (decl != DeclaringType) {
+ // Gets back MethodInfo in case of metaInfo was inflated
+ ms.metaInfo = MemberCache.GetMember (DeclaringType.GetDefinition (), this).metaInfo;
+
+ ms.declaringType = decl;
+ ms.state |= StateFlags.PendingMetaInflate;
+ }
+
+ if (targs != null) {
+ ms.targs = targs;
+ ms.state |= StateFlags.PendingMakeMethod;
+ }
+
+ return ms;
+ }
+
+ public void SetMetaInfo (MethodInfo info)
+ {
+ if (this.metaInfo != null)
+ throw new InternalErrorException ("MetaInfo reset");
+
+ this.metaInfo = info;
}
}
{
}
- public override void ApplyAttributeBuilder (Attribute a, ConstructorInfo ctor, byte[] cdata, PredefinedAttributes pa)
+ public override void ApplyAttributeBuilder (Attribute a, MethodSpec ctor, byte[] cdata, PredefinedAttributes pa)
{
if (a.Target == AttributeTargets.ReturnValue) {
if (return_attributes == null)
}
if (MethodBuilder != null)
- MethodBuilder.SetCustomAttribute (ctor, cdata);
+ MethodBuilder.SetCustomAttribute ((ConstructorInfo) ctor.GetMetaInfo (), cdata);
}
public override AttributeTargets AttributeTargets {
protected override bool CheckForDuplications ()
{
- string name = GetFullName (MemberName);
- if (MemberName.IsGeneric)
- name = MemberName.MakeName (name, MemberName.TypeArguments);
-
- return Parent.MemberCache.CheckExistingMembersOverloads (this, name, Parameters, Report);
+ return Parent.MemberCache.CheckExistingMembersOverloads (this, parameters);
}
public virtual EmitContext CreateEmitContext (ILGenerator ig)
{
- return new EmitContext (
- this, ig, MemberType);
- }
-
- protected override bool ResolveMemberType ()
- {
- if (GenericMethod != null) {
- MethodBuilder = Parent.TypeBuilder.DefineMethod (GetFullName (MemberName), flags);
- if (!GenericMethod.Define (this))
- return false;
- }
-
- return base.ResolveMemberType ();
+ return new EmitContext (this, ig, MemberType);
}
public override bool Define ()
if (!CheckBase ())
return false;
- if (block != null && block.IsIterator && !(Parent is IteratorStorey)) {
- //
- // Current method is turned into automatically generated
- // wrapper which creates an instance of iterator
- //
- Iterator.CreateIterator (this, Parent.PartialContainer, ModFlags, Compiler);
- ModFlags |= Modifiers.DEBUGGER_HIDDEN;
- }
-
MemberKind kind;
if (this is Operator)
kind = MemberKind.Operator;
// Add to member cache only when a partial method implementation has not been found yet
if ((caching_flags & Flags.PartialDefinitionExists) == 0) {
- MethodBase mb = new PartialMethodDefinitionInfo (this);
+// MethodBase mb = new PartialMethodDefinitionInfo (this);
- spec = new MethodSpec (kind, this, mb, Parameters, ModFlags);
- Parent.MemberCache.AddMember (mb, spec);
- TypeManager.AddMethod (mb, this);
+ spec = new MethodSpec (kind, Parent.Definition, this, ReturnType, null, parameters, ModFlags);
+ Parent.MemberCache.AddMember (spec);
}
return true;
MethodBuilder = MethodData.MethodBuilder;
- spec = new MethodSpec (kind, this, MethodBuilder, Parameters, ModFlags);
-
- if (TypeManager.IsGenericMethod (MethodBuilder))
- Parent.MemberCache.AddGenericMember (MethodBuilder, this);
+ spec = new MethodSpec (kind, Parent.Definition, this, ReturnType, MethodBuilder, parameters, ModFlags);
+ if (MemberName.Arity > 0)
+ spec.IsGeneric = true;
- Parent.MemberCache.AddMember (MethodBuilder, spec);
+ Parent.MemberCache.AddMember (this, MethodBuilder.Name, spec);
return true;
}
CheckAbstractAndExtern (block != null);
if ((ModFlags & Modifiers.PARTIAL) != 0) {
- for (int i = 0; i < Parameters.Count; ++i) {
- IParameterData p = Parameters.FixedParameters [i];
+ for (int i = 0; i < parameters.Count; ++i) {
+ IParameterData p = parameters.FixedParameters [i];
if (p.ModFlags == Parameter.Modifier.OUT) {
Report.Error (752, Location, "`{0}': A partial method parameters cannot use `out' modifier",
GetSignatureForError ());
{
base.DoMemberTypeDependentChecks ();
- if (!TypeManager.IsGenericParameter (MemberType)) {
- if (MemberType.IsAbstract && MemberType.IsSealed) {
- Report.Error (722, Location, Error722, TypeManager.CSharpName (MemberType));
- }
+ if (MemberType.IsStatic) {
+ Error_StaticReturnType ();
}
}
if ((ModFlags & Modifiers.DEBUGGER_HIDDEN) != 0)
PredefinedAttributes.Get.DebuggerHidden.EmitAttribute (MethodBuilder);
- if (TypeManager.IsDynamicType (ReturnType)) {
+ if (ReturnType == InternalType.Dynamic) {
return_attributes = new ReturnParameter (this, MethodBuilder, Location);
PredefinedAttributes.Get.Dynamic.EmitAttribute (return_attributes.Builder);
} else {
var trans_flags = TypeManager.HasDynamicTypeUsed (ReturnType);
if (trans_flags != null) {
var pa = PredefinedAttributes.Get.DynamicTransform;
- if (pa.Constructor != null || pa.ResolveConstructor (Location, TypeManager.bool_type.MakeArrayType ())) {
+ if (pa.Constructor != null || pa.ResolveConstructor (Location, ArrayContainer.MakeType (TypeManager.bool_type))) {
return_attributes = new ReturnParameter (this, MethodBuilder, Location);
return_attributes.Builder.SetCustomAttribute (
new CustomAttributeBuilder (pa.Constructor, new object [] { trans_flags }));
#region IMethodData Members
- public Type ReturnType {
+ public TypeSpec ReturnType {
get {
return MemberType;
}
/// <summary>
/// Returns true if method has conditional attribute and the conditions is not defined (method is excluded).
/// </summary>
- public bool IsExcluded () {
- if ((caching_flags & Flags.Excluded_Undetected) == 0)
- return (caching_flags & Flags.Excluded) != 0;
+ public override string[] ConditionalConditions ()
+ {
+ if ((caching_flags & (Flags.Excluded_Undetected | Flags.Excluded)) == 0)
+ return null;
+
+ if ((ModFlags & Modifiers.PARTIAL) != 0 && (caching_flags & Flags.Excluded) != 0)
+ return new string [0];
caching_flags &= ~Flags.Excluded_Undetected;
+ string[] conditions;
if (base_method == null) {
if (OptAttributes == null)
- return false;
+ return null;
Attribute[] attrs = OptAttributes.SearchMulti (PredefinedAttributes.Get.Conditional);
-
if (attrs == null)
- return false;
-
- foreach (Attribute a in attrs) {
- string condition = a.GetConditionalAttributeValue ();
- if (condition == null)
- return false;
-
- if (Location.CompilationUnit.IsConditionalDefined (condition))
- return false;
- }
-
- caching_flags |= Flags.Excluded;
- return true;
- }
+ return null;
- IMethodData md = TypeManager.GetMethod (TypeManager.DropGenericMethodArguments (base_method));
- if (md == null) {
- if (AttributeTester.IsConditionalMethodExcluded (base_method, Location)) {
- caching_flags |= Flags.Excluded;
- return true;
- }
- return false;
+ conditions = new string[attrs.Length];
+ for (int i = 0; i < conditions.Length; ++i)
+ conditions[i] = attrs[i].GetConditionalAttributeValue ();
+ } else {
+ conditions = base_method.MemberDefinition.ConditionalConditions();
}
- if (md.IsExcluded ()) {
+ if (conditions != null)
caching_flags |= Flags.Excluded;
- return true;
- }
- return false;
+
+ return conditions;
}
GenericMethod IMethodData.GenericMethod {
: base (parent, null, return_type, mod, amod, name, attrs, parameters)
{
}
-
+
+#region Properties
+
+ public override TypeParameter[] CurrentTypeParameters {
+ get {
+ if (GenericMethod != null)
+ return GenericMethod.CurrentTypeParameters;
+
+ return null;
+ }
+ }
+
+ public override bool HasUnresolvedConstraints {
+ get {
+ if (CurrentTypeParameters == null)
+ return false;
+
+ // When overriding base method constraints are fetched from
+ // base method but to find it we have to resolve parameters
+ // to find exact base method match
+ if (IsExplicitImpl || (ModFlags & Modifiers.OVERRIDE) != 0)
+ return base_method == null;
+
+ // Even for non-override generic method constraints check has to be
+ // delayed after all constraints are resolved
+ return true;
+ }
+ }
+
+ public TypeParameterSpec[] TypeParameters {
+ get {
+ return CurrentTypeParameters.Select (l => l.Type).ToArray ();
+ }
+ }
+
+ public int TypeParametersCount {
+ get {
+ return CurrentTypeParameters == null ? 0 : CurrentTypeParameters.Length;
+ }
+ }
+
+#endregion
+
public override string GetSignatureForError()
{
- return base.GetSignatureForError () + Parameters.GetSignatureForError ();
+ return base.GetSignatureForError () + parameters.GetSignatureForError ();
}
void Error_DuplicateEntryPoint (Method b)
ReturnType != TypeManager.int32_type)
return false;
- if (Parameters.Count == 0)
+ if (parameters.IsEmpty)
return true;
- if (Parameters.Count > 1)
+ if (parameters.Count > 1)
return false;
- Type t = Parameters.Types [0];
- return t.IsArray && t.GetArrayRank () == 1 &&
- TypeManager.GetElementType (t) == TypeManager.string_type &&
- (Parameters[0].ModFlags & ~Parameter.Modifier.PARAMS) == Parameter.Modifier.NONE;
+ var ac = parameters.Types [0] as ArrayContainer;
+ return ac != null && ac.Rank == 1 && ac.Element == TypeManager.string_type &&
+ (parameters[0].ModFlags & ~Parameter.Modifier.PARAMS) == Parameter.Modifier.NONE;
}
- public override FullNamedExpression LookupNamespaceOrType (string name, Location loc, bool ignore_cs0104)
+ public override FullNamedExpression LookupNamespaceOrType (string name, int arity, Location loc, bool ignore_cs0104)
{
- TypeParameter[] tp = CurrentTypeParameters;
- if (tp != null) {
- TypeParameter t = TypeParameter.FindTypeParameter (tp, name);
- if (t != null)
- return new TypeParameterExpr (t, loc);
+ if (arity == 0) {
+ TypeParameter[] tp = CurrentTypeParameters;
+ if (tp != null) {
+ TypeParameter t = TypeParameter.FindTypeParameter (tp, name);
+ if (t != null)
+ return new TypeParameterExpr (t, loc);
+ }
}
- return base.LookupNamespaceOrType (name, loc, ignore_cs0104);
+ return base.LookupNamespaceOrType (name, arity, loc, ignore_cs0104);
}
- public override void ApplyAttributeBuilder (Attribute a, ConstructorInfo ctor, byte[] cdata, PredefinedAttributes pa)
+ public override void ApplyAttributeBuilder (Attribute a, MethodSpec ctor, byte[] cdata, PredefinedAttributes pa)
{
if (a.Type == pa.Conditional) {
if (IsExplicitImpl) {
return;
}
- for (int i = 0; i < Parameters.Count; ++i) {
- if (Parameters.FixedParameters [i].ModFlags == Parameter.Modifier.OUT) {
+ for (int i = 0; i < parameters.Count; ++i) {
+ if (parameters.FixedParameters [i].ModFlags == Parameter.Modifier.OUT) {
Report.Error (685, Location, "Conditional method `{0}' cannot have an out parameter", GetSignatureForError ());
return;
}
return true;
}
- protected override bool CheckBase ()
+ protected virtual void DefineTypeParameters ()
{
- if (!base.CheckBase ())
- return false;
+ var tparams = CurrentTypeParameters;
- if (base_method != null && (ModFlags & Modifiers.OVERRIDE) != 0 && Name == Destructor.MetadataName) {
- Report.Error (249, Location, "Do not override `{0}'. Use destructor syntax instead",
- TypeManager.CSharpSignature (base_method));
+ TypeParameterSpec[] base_tparams = null;
+ if (((ModFlags & Modifiers.OVERRIDE) != 0 || IsExplicitImpl)) {
+ if (base_method != null)
+ base_tparams = base_method.GenericDefinition.TypeParameters;
+ else if (MethodData.implementing != null)
+ base_tparams = MethodData.implementing.GenericDefinition.TypeParameters;
}
- return true;
- }
+ for (int i = 0; i < tparams.Length; ++i) {
+ var tp = tparams[i];
- public override TypeParameter[] CurrentTypeParameters {
- get {
- if (GenericMethod != null)
- return GenericMethod.CurrentTypeParameters;
+ if (!tp.ResolveConstraints (this))
+ continue;
- return null;
+ //
+ // Copy base constraints for override/explicit methods
+ //
+ if (base_tparams != null) {
+ var base_tparam = base_tparams[i];
+ tp.Type.SpecialConstraint = base_tparam.SpecialConstraint;
+ tp.Type.TypeArguments = base_tparam.TypeArguments;
+
+ // TODO MemberCache: Inflate with different MVAR ?
+ tp.Type.Interfaces = base_tparam.Interfaces;
+ tp.Type.BaseType = base_tparam.BaseType;
+ } else if (MethodData.implementing != null) {
+ var base_tp = MethodData.implementing.Constraints[i];
+ if (!tp.Type.HasSameConstraintsImplementation (base_tp)) {
+ Report.SymbolRelatedToPreviousError (MethodData.implementing);
+ Report.Error (425, Location,
+ "The constraints for type parameter `{0}' of method `{1}' must match the constraints for type parameter `{2}' of interface method `{3}'. Consider using an explicit interface implementation instead",
+ tp.GetSignatureForError (), GetSignatureForError (), base_tp.GetSignatureForError (), MethodData.implementing.GetSignatureForError ());
+ }
+ }
}
}
//
public override bool Define ()
{
- if (type_name == TypeManager.system_void_expr && Parameters.IsEmpty && Name == Destructor.MetadataName) {
+ if (type_expr == TypeManager.system_void_expr && parameters.IsEmpty && Name == Destructor.MetadataName) {
Report.Warning (465, 1, Location, "Introducing `Finalize' method can interfere with destructor invocation. Did you intend to declare a destructor?");
}
return false;
}
- if (base_method != null && (ModFlags & Modifiers.NEW) == 0) {
- if (Parameters.Count == 1 && ParameterTypes [0] == TypeManager.object_type && Name == "Equals")
- Parent.PartialContainer.Mark_HasEquals ();
- else if (Parameters.IsEmpty && Name == "GetHashCode")
- Parent.PartialContainer.Mark_HasGetHashCode ();
+ if (CurrentTypeParameters == null) {
+ if (base_method != null) {
+ if (parameters.Count == 1 && ParameterTypes[0] == TypeManager.object_type && Name == "Equals")
+ Parent.PartialContainer.Mark_HasEquals ();
+ else if (parameters.IsEmpty && Name == "GetHashCode")
+ Parent.PartialContainer.Mark_HasGetHashCode ();
+ }
+
+ } else {
+ DefineTypeParameters ();
+ }
+
+ if (block != null && block.IsIterator && !(Parent is IteratorStorey)) {
+ //
+ // Current method is turned into automatically generated
+ // wrapper which creates an instance of iterator
+ //
+ Iterator.CreateIterator (this, Parent.PartialContainer, ModFlags, Compiler);
+ ModFlags |= Modifiers.DEBUGGER_HIDDEN;
}
if ((ModFlags & Modifiers.STATIC) == 0)
return true;
- if (Parameters.HasExtensionMethodType) {
- if (Parent.PartialContainer.IsStaticClass && !Parent.IsGeneric) {
+ if (parameters.HasExtensionMethodType) {
+ if (Parent.PartialContainer.IsStatic && !Parent.IsGeneric) {
if (!Parent.IsTopLevel)
Report.Error (1109, Location, "`{0}': Extension methods cannot be defined in a nested class",
GetSignatureForError ());
ModFlags |= Modifiers.METHOD_EXTENSION;
Parent.PartialContainer.ModFlags |= Modifiers.METHOD_EXTENSION;
+ Spec.DeclaringType.SetExtensionMethodContainer ();
CodeGen.Assembly.HasExtensionMethods = true;
} else {
Report.Error (1106, Location, "`{0}': Extension methods must be defined in a non-generic static class",
GetSignatureForError ());
}
+ if (CurrentTypeParameters != null) {
+ var ge = type_expr as GenericTypeExpr;
+ if (ge != null)
+ ge.CheckConstraints (this);
+
+ foreach (Parameter p in parameters.FixedParameters) {
+ ge = p.TypeExpression as GenericTypeExpr;
+ if (ge != null)
+ ge.CheckConstraints (this);
+ }
+
+ for (int i = 0; i < CurrentTypeParameters.Length; ++i) {
+ var tp = CurrentTypeParameters [i];
+ tp.CheckGenericConstraints ();
+ tp.Emit ();
+ }
+ }
+
base.Emit ();
if ((ModFlags & Modifiers.METHOD_EXTENSION) != 0)
return base.EnableOverloadChecks (overload);
}
- public static void Error1599 (Location loc, Type t, Report Report)
+ public static void Error1599 (Location loc, TypeSpec t, Report Report)
{
Report.Error (1599, loc, "Method or delegate cannot return type `{0}'", TypeManager.CSharpName (t));
}
- protected override MethodInfo FindOutBaseMethod (ref Type base_ret_type)
+ protected override bool ResolveMemberType ()
{
- MethodInfo mi = (MethodInfo) Parent.PartialContainer.BaseCache.FindMemberToOverride (
- Parent.TypeBuilder, Name, Parameters, GenericMethod, false);
-
- if (mi == null)
- return null;
-
- if (mi.IsSpecialName)
- return null;
-
- base_ret_type = TypeManager.TypeToCoreType (mi.ReturnType);
- return mi;
- }
+ if (GenericMethod != null) {
+ MethodBuilder = Parent.TypeBuilder.DefineMethod (GetFullName (MemberName), flags);
+ if (!GenericMethod.Define (this))
+ return false;
+ }
- public MethodInfo MakeGenericMethod (Type[] targs)
- {
- return MethodBuilder.MakeGenericMethod (targs);
+ return base.ResolveMemberType ();
}
public void SetPartialDefinition (Method methodDefinition)
methodDefinition.partialMethodImplementation = this;
// Ensure we are always using method declaration parameters
- for (int i = 0; i < methodDefinition.Parameters.Count; ++i ) {
- Parameters [i].Name = methodDefinition.Parameters [i].Name;
- Parameters [i].DefaultValue = methodDefinition.Parameters [i].DefaultValue;
+ for (int i = 0; i < methodDefinition.parameters.Count; ++i ) {
+ parameters [i].Name = methodDefinition.parameters [i].Name;
+ parameters [i].DefaultValue = methodDefinition.parameters [i].DefaultValue;
}
if (methodDefinition.attributes == null)
attributes.Attrs.AddRange (methodDefinition.attributes.Attrs);
}
}
-
- protected override bool VerifyClsCompliance ()
- {
- if (!base.VerifyClsCompliance ())
- return false;
-
- if (!Parameters.IsEmpty) {
- var al = Parent.PartialContainer.MemberCache.Members [Name];
- if (al.Count > 1)
- MemberCache.VerifyClsParameterConflict (al, this, MethodBuilder, Report);
- }
-
- return true;
- }
}
public abstract class ConstructorInitializer : ExpressionStatement
{
eclass = ExprClass.Value;
- // TODO: ec.GetSignatureForError ()
- ConstructorBuilder caller_builder = ((Constructor) ec.MemberContext).ConstructorBuilder;
+ // FIXME: Hack
+ var caller_builder = (Constructor) ec.MemberContext;
if (argument_list != null) {
bool dynamic;
return this;
type = ec.CurrentType.BaseType;
- if (TypeManager.IsStruct (ec.CurrentType)) {
+ if (ec.CurrentType.IsStruct) {
ec.Report.Error (522, loc,
- "`{0}': Struct constructors cannot call base constructors", TypeManager.CSharpSignature (caller_builder));
+ "`{0}': Struct constructors cannot call base constructors", caller_builder.GetSignatureForError ());
return this;
}
} else {
}
base_constructor_group = MemberLookupFinal (
- ec, null, type, ConstructorBuilder.ConstructorName, MemberTypes.Constructor,
- BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly,
+ ec, null, type, ConstructorBuilder.ConstructorName, 0, MemberKind.Constructor,
+ BindingRestriction.AccessibleOnly | BindingRestriction.DeclaredOnly,
loc) as MethodGroupExpr;
if (base_constructor_group == null)
var base_ctor = base_constructor_group.BestCandidate;
- if (base_ctor.MetaInfo == caller_builder){
- ec.Report.Error (516, loc, "Constructor `{0}' cannot call itself", TypeManager.CSharpSignature (caller_builder));
+ // TODO MemberCache: Does it work for inflated types ?
+ if (base_ctor == caller_builder.Spec){
+ ec.Report.Error (516, loc, "Constructor `{0}' cannot call itself",
+ caller_builder.GetSignatureForError ());
}
return this;
public bool IsDefault ()
{
if ((ModFlags & Modifiers.STATIC) != 0)
- return Parameters.IsEmpty;
-
- return Parameters.IsEmpty &&
+ return parameters.IsEmpty;
+
+ return parameters.IsEmpty &&
(Initializer is ConstructorBaseInitializer) &&
(Initializer.Arguments == null);
}
- public override void ApplyAttributeBuilder (Attribute a, ConstructorInfo ctor, byte[] cdata, PredefinedAttributes pa)
+ public override void ApplyAttributeBuilder (Attribute a, MethodSpec ctor, byte[] cdata, PredefinedAttributes pa)
{
if (a.IsValidSecurityAttribute ()) {
if (declarative_security == null) {
is_external_implementation = true;
}
- ConstructorBuilder.SetCustomAttribute (ctor, cdata);
+ ConstructorBuilder.SetCustomAttribute ((ConstructorInfo) ctor.GetMetaInfo (), cdata);
}
protected override bool CheckBase ()
{
if ((ModFlags & Modifiers.STATIC) != 0) {
- if (!Parameters.IsEmpty) {
+ if (!parameters.IsEmpty) {
Report.Error (132, Location, "`{0}': The static constructor must be parameterless",
GetSignatureForError ());
return false;
}
// Check whether arguments were correct.
- if (!DefineParameters (Parameters))
+ if (!DefineParameters (parameters))
return false;
if ((caching_flags & Flags.MethodOverloadsExist) != 0)
- Parent.MemberCache.CheckExistingMembersOverloads (this, ConstructorInfo.ConstructorName,
- Parameters, Report);
+ Parent.MemberCache.CheckExistingMembersOverloads (this, parameters);
- if (Parent.PartialContainer.Kind == MemberKind.Struct) {
- if (Parameters.Count == 0) {
- Report.Error (568, Location,
- "Structs cannot contain explicit parameterless constructors");
- return false;
- }
+ if (Parent.PartialContainer.Kind == MemberKind.Struct && parameters.IsEmpty) {
+ Report.Error (568, Location,
+ "Structs cannot contain explicit parameterless constructors");
+ return false;
}
CheckProtectedModifier ();
if (ConstructorBuilder != null)
return true;
- MethodAttributes ca = (MethodAttributes.RTSpecialName |
- MethodAttributes.SpecialName);
+ var ca = MethodAttributes.RTSpecialName | MethodAttributes.SpecialName;
if ((ModFlags & Modifiers.STATIC) != 0) {
ca |= MethodAttributes.Static | MethodAttributes.Private;
} else {
- ca |= MethodAttributes.HideBySig;
-
- if ((ModFlags & Modifiers.PUBLIC) != 0)
- ca |= MethodAttributes.Public;
- else if ((ModFlags & Modifiers.PROTECTED) != 0){
- if ((ModFlags & Modifiers.INTERNAL) != 0)
- ca |= MethodAttributes.FamORAssem;
- else
- ca |= MethodAttributes.Family;
- } else if ((ModFlags & Modifiers.INTERNAL) != 0)
- ca |= MethodAttributes.Assembly;
- else
- ca |= MethodAttributes.Private;
+ ca |= ModifiersExtensions.MethodAttr (ModFlags);
}
if (!CheckAbstractAndExtern (block != null))
ConstructorBuilder = Parent.TypeBuilder.DefineConstructor (
ca, CallingConventions,
- Parameters.GetEmitTypes ());
+ parameters.GetMetaInfo ());
- spec = new MethodSpec (MemberKind.Constructor, this, ConstructorBuilder, Parameters, ModFlags);
-
- if (Parent.PartialContainer.IsComImport) {
- if (!IsDefault ()) {
- Report.Error (669, Location, "`{0}': A class with the ComImport attribute cannot have a user-defined constructor",
- Parent.GetSignatureForError ());
- }
- ConstructorBuilder.SetImplementationFlags (MethodImplAttributes.InternalCall);
- }
+ spec = new MethodSpec (MemberKind.Constructor, Parent.Definition, this, TypeManager.void_type, ConstructorBuilder, parameters, ModFlags);
- Parent.MemberCache.AddMember (ConstructorBuilder, spec);
- TypeManager.AddMethod (ConstructorBuilder, this);
+ Parent.MemberCache.AddMember (spec);
// It's here only to report an error
if (block != null && block.IsIterator) {
//
public override void Emit ()
{
+ if (Parent.PartialContainer.IsComImport) {
+ if (!IsDefault ()) {
+ Report.Error (669, Location, "`{0}': A class with the ComImport attribute cannot have a user-defined constructor",
+ Parent.GetSignatureForError ());
+ }
+ ConstructorBuilder.SetImplementationFlags (MethodImplAttributes.InternalCall);
+ }
+
if ((ModFlags & Modifiers.DEBUGGER_HIDDEN) != 0)
PredefinedAttributes.Get.DebuggerHidden.EmitAttribute (ConstructorBuilder);
}
}
- Parameters.ApplyAttributes (ConstructorBuilder);
+ parameters.ApplyAttributes (ConstructorBuilder);
SourceMethod source = SourceMethod.Create (Parent, ConstructorBuilder, block);
if (block != null) {
- if (block.Resolve (null, bc, Parameters, this)) {
+ if (block.Resolve (null, bc, parameters, this)) {
EmitContext ec = new EmitContext (this, ConstructorBuilder.GetILGenerator (), bc.ReturnType);
ec.With (EmitContext.Options.ConstructorScope, true);
block = null;
}
- // Is never override
- protected override MethodInfo FindOutBaseMethod (ref Type base_ret_type)
+ protected override MemberSpec FindBaseMember (out MemberSpec bestCandidate)
{
+ // Is never override
+ bestCandidate = null;
return null;
}
public override string GetSignatureForError()
{
- return base.GetSignatureForError () + Parameters.GetSignatureForError ();
+ return base.GetSignatureForError () + parameters.GetSignatureForError ();
}
public override string[] ValidAttributeTargets {
if (!base.VerifyClsCompliance () || !IsExposedFromAssembly ()) {
return false;
}
-
- if (!Parameters.IsEmpty) {
- var al = Parent.MemberCache.Members [ConstructorInfo.ConstructorName];
- if (al.Count > 2)
- MemberCache.VerifyClsParameterConflict (al, this, ConstructorBuilder, Report);
-
- if (TypeManager.IsSubclassOf (Parent.TypeBuilder, TypeManager.attribute_type)) {
- foreach (Type param in Parameters.Types) {
- if (param.IsArray) {
- return true;
- }
+
+ if (!parameters.IsEmpty && Parent.Definition.IsAttribute) {
+ foreach (TypeSpec param in parameters.Types) {
+ if (param.IsArray) {
+ return true;
}
}
}
+
has_compliant_args = true;
return true;
}
}
}
- public Type ReturnType {
+ public TypeSpec ReturnType {
get {
return MemberType;
}
CallingConventions CallingConventions { get; }
Location Location { get; }
MemberName MethodName { get; }
- Type ReturnType { get; }
+ TypeSpec ReturnType { get; }
GenericMethod GenericMethod { get; }
ParametersCompiled ParameterInfo { get; }
+ MethodSpec Spec { get; }
Attributes OptAttributes { get; }
ToplevelBlock Block { get; set; }
EmitContext CreateEmitContext (ILGenerator ig);
- ObsoleteAttribute GetObsoleteAttribute ();
string GetSignatureForError ();
- bool IsExcluded ();
- bool IsClsComplianceRequired ();
- void SetIsUsed ();
void EmitExtraSymbolInfo (SourceMethod source);
}
//
// Are we implementing an interface ?
//
- public MethodInfo implementing;
+ public MethodSpec implementing;
//
// Protected data.
protected InterfaceMemberBase member;
protected Modifiers modifiers;
protected MethodAttributes flags;
- protected Type declaring_type;
- protected MethodInfo parent_method;
+ protected TypeSpec declaring_type;
+ protected MethodSpec parent_method;
- MethodBuilder builder = null;
+ MethodBuilder builder;
public MethodBuilder MethodBuilder {
get {
return builder;
}
}
- public Type DeclaringType {
+ public TypeSpec DeclaringType {
get {
return declaring_type;
}
public MethodData (InterfaceMemberBase member,
Modifiers modifiers, MethodAttributes flags,
IMethodData method, MethodBuilder builder,
- GenericMethod generic, MethodInfo parent_method)
+ GenericMethod generic, MethodSpec parent_method)
: this (member, modifiers, flags, method)
{
this.builder = builder;
public bool Define (DeclSpace parent, string method_full_name, Report Report)
{
- string name = method.MethodName.Basename;
-
TypeContainer container = parent.PartialContainer;
PendingImplementation pending = container.PendingImplementations;
if (pending != null){
- implementing = pending.IsInterfaceMethod (name, member.InterfaceType, this);
+ implementing = pending.IsInterfaceMethod (method.MethodName, member.InterfaceType, this);
if (member.InterfaceType != null){
if (implementing == null){
}
return false;
}
- if (implementing.IsSpecialName && !(method is AbstractPropertyEventMethod)) {
+ if (implementing.IsAccessor && !(method is AbstractPropertyEventMethod)) {
Report.SymbolRelatedToPreviousError (implementing);
Report.Error (683, method.Location, "`{0}' explicit method implementation cannot implement `{1}' because it is an accessor",
member.GetSignatureForError (), TypeManager.CSharpSignature (implementing));
if (implementing != null) {
AbstractPropertyEventMethod prop_method = method as AbstractPropertyEventMethod;
if (prop_method == null) {
- if (TypeManager.IsSpecialMethod (implementing)) {
+ if (implementing.IsAccessor) {
Report.SymbolRelatedToPreviousError (implementing);
- Report.Error (470, method.Location, "Method `{0}' cannot implement interface accessor `{1}.{2}'",
- method.GetSignatureForError (), TypeManager.CSharpSignature (implementing),
- implementing.Name.StartsWith ("get_") ? "get" : "set");
+ Report.Error (470, method.Location, "Method `{0}' cannot implement interface accessor `{1}'",
+ method.GetSignatureForError (), TypeManager.CSharpSignature (implementing));
}
} else if (implementing.DeclaringType.IsInterface) {
- if (!implementing.IsSpecialName) {
+ if (!implementing.IsAccessor) {
Report.SymbolRelatedToPreviousError (implementing);
Report.Error (686, method.Location, "Accessor `{0}' cannot implement interface member `{1}' for type `{2}'. Use an explicit interface implementation",
method.GetSignatureForError (), TypeManager.CSharpSignature (implementing), container.GetSignatureForError ());
if (pm != null && pm.HasCustomAccessModifier && (pm.ModFlags & Modifiers.PUBLIC) == 0) {
Report.SymbolRelatedToPreviousError (implementing);
Report.Error (277, method.Location, "Accessor `{0}' must be declared public to implement interface member `{1}'",
- method.GetSignatureForError (), TypeManager.CSharpSignature (implementing, true));
+ method.GetSignatureForError (), implementing.GetSignatureForError ());
return false;
}
}
// but it wont get cleared
//
if (member.IsExplicitImpl){
- if (method.ParameterInfo.HasParams && !TypeManager.GetParameterData (implementing).HasParams) {
+ if (method.ParameterInfo.HasParams && !implementing.Parameters.HasParams) {
Report.SymbolRelatedToPreviousError (implementing);
Report.Error (466, method.Location, "`{0}': the explicit interface implementation cannot introduce the params modifier",
method.GetSignatureForError ());
if (builder == null)
return false;
- if (container.CurrentType != null)
- declaring_type = container.CurrentType;
- else
- declaring_type = container.TypeBuilder;
+// if (container.CurrentType != null)
+// declaring_type = container.CurrentType;
+// else
+ declaring_type = container.Definition;
if (implementing != null && member.IsExplicitImpl) {
- container.TypeBuilder.DefineMethodOverride (builder, implementing);
- }
-
- TypeManager.AddMethod (builder, method);
-
- if (GenericMethod != null) {
- bool is_override = member.IsExplicitImpl |
- ((modifiers & Modifiers.OVERRIDE) != 0);
-
- if (implementing != null)
- parent_method = implementing;
-
- if (!GenericMethod.DefineType (GenericMethod, builder, parent_method, is_override))
- return false;
+ container.TypeBuilder.DefineMethodOverride (builder, (MethodInfo) implementing.GetMetaInfo ());
}
return true;
/// </summary>
void DefineMethodBuilder (TypeContainer container, string method_name, ParametersCompiled param)
{
+ var return_type = method.ReturnType.GetMetaInfo ();
+ var p_types = param.GetMetaInfo ();
+
if (builder == null) {
builder = container.TypeBuilder.DefineMethod (
method_name, flags, method.CallingConventions,
- method.ReturnType,
- param.GetEmitTypes ());
+ return_type, p_types);
return;
}
// Generic method has been already defined to resolve method parameters
// correctly when they use type parameters
//
- builder.SetParameters (param.GetEmitTypes ());
- builder.SetReturnType (method.ReturnType);
+ builder.SetParameters (p_types);
+ builder.SetReturnType (return_type);
if (builder.Attributes != flags) {
try {
if (methodbuilder_attrs_field == null)
//
public void Emit (DeclSpace parent)
{
- method.ParameterInfo.ApplyAttributes (MethodBuilder);
-
if (GenericMethod != null)
GenericMethod.EmitAttributes ();
+ method.ParameterInfo.ApplyAttributes (MethodBuilder);
+
//
// clear the pending implementation flag
//
if (implementing != null)
- parent.PartialContainer.PendingImplementations.ImplementMethod (method.MethodName.Basename,
+ parent.PartialContainer.PendingImplementations.ImplementMethod (method.MethodName,
member.InterfaceType, this, member.IsExplicitImpl);
SourceMethod source = SourceMethod.Create (parent, MethodBuilder, method.Block);
ModFlags |= Modifiers.PROTECTED | Modifiers.OVERRIDE;
}
- public override void ApplyAttributeBuilder (Attribute a, ConstructorInfo ctor, byte[] cdata, PredefinedAttributes pa)
+ public override void ApplyAttributeBuilder (Attribute a, MethodSpec ctor, byte[] cdata, PredefinedAttributes pa)
{
if (a.Type == pa.Conditional) {
Error_ConditionalAttributeIsNotValid ();
if (!base.CheckBase ())
return false;
- if (Parent.PartialContainer.BaseCache == null)
+ var base_type = Parent.PartialContainer.BaseType;
+ if (base_type == null)
return true;
- Type base_type = Parent.PartialContainer.BaseCache.Container.Type;
- if (base_type != null && Block != null) {
- MethodGroupExpr method_expr = Expression.MethodLookup (Parent.Module.Compiler, Parent.TypeBuilder, base_type, MetadataName, Location);
+ if (Block != null) {
+ MethodGroupExpr method_expr = Expression.MethodLookup (Parent.Module.Compiler, Parent.Definition, base_type, MemberKind.Destructor, MetadataName, 0, Location);
if (method_expr == null)
throw new NotImplementedException ();
method_expr.IsBase = true;
- method_expr.InstanceExpression = new CompilerGeneratedThis (Parent.TypeBuilder, Location);
+ method_expr.InstanceExpression = new CompilerGeneratedThis (Parent.Definition, Location);
ToplevelBlock new_block = new ToplevelBlock (Compiler, Block.StartLocation);
new_block.EndLocation = Block.EndLocation;
return Parent.GetSignatureForError () + ".~" + Parent.MemberName.Name + "()";
}
- protected override MethodInfo FindOutBaseMethod (ref Type base_ret_type)
- {
- return null;
- }
-
public override string[] ValidAttributeTargets {
get {
return attribute_targets;
}
}
- public Type[] ParameterTypes {
+ public TypeSpec[] ParameterTypes {
get {
return ParameterInfo.Types;
}
}
public abstract ParametersCompiled ParameterInfo { get ; }
- public abstract Type ReturnType { get; }
+ public abstract TypeSpec ReturnType { get; }
#endregion
- public override void ApplyAttributeBuilder (Attribute a, ConstructorInfo ctor, byte[] cdata, PredefinedAttributes pa)
+ public override void ApplyAttributeBuilder (Attribute a, MethodSpec ctor, byte[] cdata, PredefinedAttributes pa)
{
if (a.Type == pa.CLSCompliant || a.Type == pa.Obsolete || a.Type == pa.Conditional) {
Report.Error (1667, a.Location,
}
if (a.Target == AttributeTargets.Method) {
- method_data.MethodBuilder.SetCustomAttribute (ctor, cdata);
+ method_data.MethodBuilder.SetCustomAttribute ((ConstructorInfo) ctor.GetMetaInfo (), cdata);
return;
}
ApplyToExtraTarget (a, ctor, cdata, pa);
}
- protected virtual void ApplyToExtraTarget (Attribute a, ConstructorInfo ctor, byte[] cdata, PredefinedAttributes pa)
+ protected virtual void ApplyToExtraTarget (Attribute a, MethodSpec ctor, byte[] cdata, PredefinedAttributes pa)
{
throw new NotSupportedException ("You forgot to define special attribute target handling");
}
if (((ModFlags & Modifiers.DEBUGGER_HIDDEN) != 0))
PredefinedAttributes.Get.DebuggerHidden.EmitAttribute (method_data.MethodBuilder);
- if (TypeManager.IsDynamicType (ReturnType)) {
+ if (ReturnType == InternalType.Dynamic) {
return_attributes = new ReturnParameter (this, method_data.MethodBuilder, Location);
PredefinedAttributes.Get.Dynamic.EmitAttribute (return_attributes.Builder);
} else {
var trans_flags = TypeManager.HasDynamicTypeUsed (ReturnType);
if (trans_flags != null) {
var pa = PredefinedAttributes.Get.DynamicTransform;
- if (pa.Constructor != null || pa.ResolveConstructor (Location, TypeManager.bool_type.MakeArrayType ())) {
+ if (pa.Constructor != null || pa.ResolveConstructor (Location, ArrayContainer.MakeType (TypeManager.bool_type))) {
return_attributes = new ReturnParameter (this, method_data.MethodBuilder, Location);
return_attributes.Builder.SetCustomAttribute (
new CustomAttributeBuilder (pa.Constructor, new object [] { trans_flags }));
if (!MemberName.Equals (method.MemberName))
return false;
- Type[] param_types = method.ParameterTypes;
+ TypeSpec[] param_types = method.ParameterTypes;
if (param_types == null || param_types.Length != ParameterTypes.Length)
return false;
Block = block;
}
- public override void ApplyAttributeBuilder (Attribute a, ConstructorInfo ctor, byte[] cdata, PredefinedAttributes pa)
+ public override void ApplyAttributeBuilder (Attribute a, MethodSpec ctor, byte[] cdata, PredefinedAttributes pa)
{
if (a.Type == pa.Conditional) {
Error_ConditionalAttributeIsNotValid ();
if (!base.Define ())
return false;
+ if (block != null && block.IsIterator && !(Parent is IteratorStorey)) {
+ //
+ // Current method is turned into automatically generated
+ // wrapper which creates an instance of iterator
+ //
+ Iterator.CreateIterator (this, Parent.PartialContainer, ModFlags, Compiler);
+ ModFlags |= Modifiers.DEBUGGER_HIDDEN;
+ }
+
// imlicit and explicit operator of same types are not allowed
if (OperatorType == OpType.Explicit)
- Parent.MemberCache.CheckExistingMembersOverloads (this, GetMetadataName (OpType.Implicit), Parameters, Report);
+ Parent.MemberCache.CheckExistingMembersOverloads (this, GetMetadataName (OpType.Implicit), parameters);
else if (OperatorType == OpType.Implicit)
- Parent.MemberCache.CheckExistingMembersOverloads (this, GetMetadataName (OpType.Explicit), Parameters, Report);
+ Parent.MemberCache.CheckExistingMembersOverloads (this, GetMetadataName (OpType.Explicit), parameters);
- Type declaring_type = MethodData.DeclaringType;
- Type return_type = MemberType;
- Type first_arg_type = ParameterTypes [0];
+ TypeSpec declaring_type = Parent.CurrentType;
+ TypeSpec return_type = MemberType;
+ TypeSpec first_arg_type = ParameterTypes [0];
- Type first_arg_type_unwrap = first_arg_type;
+ TypeSpec first_arg_type_unwrap = first_arg_type;
if (TypeManager.IsNullableType (first_arg_type))
- first_arg_type_unwrap = TypeManager.TypeToCoreType (TypeManager.GetTypeArguments (first_arg_type) [0]);
+ first_arg_type_unwrap = TypeManager.GetTypeArguments (first_arg_type) [0];
- Type return_type_unwrap = return_type;
+ TypeSpec return_type_unwrap = return_type;
if (TypeManager.IsNullableType (return_type))
- return_type_unwrap = TypeManager.TypeToCoreType (TypeManager.GetTypeArguments (return_type) [0]);
+ return_type_unwrap = TypeManager.GetTypeArguments (return_type) [0];
- if (TypeManager.IsDynamicType (return_type) || TypeManager.IsDynamicType (first_arg_type)) {
+ if (return_type == InternalType.Dynamic || first_arg_type == InternalType.Dynamic) {
Report.Error (1964, Location,
"User-defined operator `{0}' cannot convert to or from the dynamic type",
GetSignatureForError ());
return false;
}
- Type conv_type;
+ TypeSpec conv_type;
if (TypeManager.IsEqual (declaring_type, return_type) || declaring_type == return_type_unwrap) {
conv_type = first_arg_type;
} else if (TypeManager.IsEqual (declaring_type, first_arg_type) || declaring_type == first_arg_type_unwrap) {
}
}
} else if (OperatorType == OpType.LeftShift || OperatorType == OpType.RightShift) {
- if (first_arg_type != declaring_type || Parameters.Types [1] != TypeManager.int32_type) {
+ if (first_arg_type != declaring_type || parameters.Types[1] != TypeManager.int32_type) {
Report.Error (564, Location, "Overloaded shift operator must have the type of the first operand be the containing type, and the type of the second operand must be int");
return false;
}
- } else if (Parameters.Count == 1) {
+ } else if (parameters.Count == 1) {
// Checks for Unary operators
if (OperatorType == OpType.Increment || OperatorType == OpType.Decrement) {
var second_arg_type = ParameterTypes [1];
if (TypeManager.IsNullableType (second_arg_type))
- second_arg_type = TypeManager.TypeToCoreType (TypeManager.GetTypeArguments (second_arg_type) [0]);
+ second_arg_type = TypeManager.GetTypeArguments (second_arg_type) [0];
if (!TypeManager.IsEqual (second_arg_type, declaring_type)) {
Report.Error (563, Location,
return true;
}
- // Operator cannot be override
- protected override MethodInfo FindOutBaseMethod (ref Type base_ret_type)
+ protected override MemberSpec FindBaseMember (out MemberSpec bestCandidate)
{
+ // Operator cannot be override
+ bestCandidate = null;
return null;
}
StringBuilder sb = new StringBuilder ();
if (OperatorType == OpType.Implicit || OperatorType == OpType.Explicit) {
sb.AppendFormat ("{0}.{1} operator {2}",
- Parent.GetSignatureForError (), GetName (OperatorType), type_name.GetSignatureForError ());
+ Parent.GetSignatureForError (), GetName (OperatorType), type_expr.GetSignatureForError ());
}
else {
sb.AppendFormat ("{0}.operator {1}", Parent.GetSignatureForError (), GetName (OperatorType));
}
- sb.Append (Parameters.GetSignatureForError ());
+ sb.Append (parameters.GetSignatureForError ());
return sb.ToString ();
}
}
-
- //
- // This is used to compare method signatures
- //
- struct MethodSignature {
- public string Name;
- public Type RetType;
- public Type [] Parameters;
-
- /// <summary>
- /// This delegate is used to extract methods which have the
- /// same signature as the argument
- /// </summary>
- public static MemberFilter method_signature_filter = new MemberFilter (MemberSignatureCompare);
-
- public MethodSignature (string name, Type ret_type, Type [] parameters)
- {
- Name = name;
- RetType = ret_type;
-
- if (parameters == null)
- Parameters = Type.EmptyTypes;
- else
- Parameters = parameters;
- }
-
- public override string ToString ()
- {
- string pars = "";
- if (Parameters.Length != 0){
- System.Text.StringBuilder sb = new System.Text.StringBuilder ();
- for (int i = 0; i < Parameters.Length; i++){
- sb.Append (Parameters [i]);
- if (i+1 < Parameters.Length)
- sb.Append (", ");
- }
- pars = sb.ToString ();
- }
-
- return String.Format ("{0} {1} ({2})", RetType, Name, pars);
- }
-
- public override int GetHashCode ()
- {
- return Name.GetHashCode ();
- }
-
- public override bool Equals (Object o)
- {
- MethodSignature other = (MethodSignature) o;
-
- if (other.Name != Name)
- return false;
-
- if (other.RetType != RetType)
- return false;
-
- if (Parameters == null){
- if (other.Parameters == null)
- return true;
- return false;
- }
-
- if (other.Parameters == null)
- return false;
-
- int c = Parameters.Length;
- if (other.Parameters.Length != c)
- return false;
-
- for (int i = 0; i < c; i++)
- if (other.Parameters [i] != Parameters [i])
- return false;
-
- return true;
- }
-
- static bool MemberSignatureCompare (MemberInfo m, object filter_criteria)
- {
- MethodSignature sig = (MethodSignature) filter_criteria;
-
- if (m.Name != sig.Name)
- return false;
-
- Type ReturnType;
- MethodInfo mi = m as MethodInfo;
- PropertyInfo pi = m as PropertyInfo;
-
- if (mi != null)
- ReturnType = mi.ReturnType;
- else if (pi != null)
- ReturnType = pi.PropertyType;
- else
- return false;
-
- //
- // we use sig.RetType == null to mean `do not check the
- // method return value.
- //
- if (sig.RetType != null) {
- if (!TypeManager.IsEqual (ReturnType, sig.RetType))
- return false;
- }
-
- Type [] args;
- if (mi != null)
- args = TypeManager.GetParameterData (mi).Types;
- else
- args = TypeManager.GetParameterData (pi).Types;
- Type [] sigp = sig.Parameters;
-
- if (args.Length != sigp.Length)
- return false;
-
- for (int i = args.Length - 1; i >= 0; i--)
- if (!TypeManager.IsEqual (args [i], sigp [i]))
- return false;
-
- return true;
- }
- }
}
// Compiler specific flags
//
PROPERTY_CUSTOM = 0x4000,
+ OVERRIDE_UNCHECKED = 0x8000,
PARTIAL = 0x20000,
DEFAULT_ACCESS_MODIFER = 0x40000,
METHOD_EXTENSION = 0x80000,
static class ModifiersExtensions
{
+ public static string AccessibilityName (Modifiers mod)
+ {
+ switch (mod & Modifiers.AccessibilityMask) {
+ case Modifiers.PUBLIC:
+ return "public";
+ case Modifiers.PROTECTED:
+ return "protected";
+ case Modifiers.PROTECTED | Modifiers.INTERNAL:
+ return "protected internal";
+ case Modifiers.INTERNAL:
+ return "internal";
+ case Modifiers.PRIVATE:
+ return "private";
+ default:
+ throw new NotImplementedException (mod.ToString ());
+ }
+ }
+
static public string Name (Modifiers i)
{
string s = "";
return s;
}
- public static string GetDescription (MethodAttributes ma)
+ //
+ // Used by custom property accessors to check whether @modA is more restrictive than @modB
+ //
+ public static bool IsRestrictedModifier (Modifiers modA, Modifiers modB)
{
- ma &= MethodAttributes.MemberAccessMask;
+ Modifiers flags = 0;
- if (ma == MethodAttributes.Assembly)
- return "internal";
+ if ((modB & Modifiers.PUBLIC) != 0) {
+ flags = Modifiers.PROTECTED | Modifiers.INTERNAL | Modifiers.PRIVATE;
+ } else if ((modB & Modifiers.PROTECTED) != 0) {
+ if ((modB & Modifiers.INTERNAL) != 0)
+ flags = Modifiers.PROTECTED | Modifiers.INTERNAL;
- if (ma == MethodAttributes.Family)
- return "protected";
+ flags |= Modifiers.PRIVATE;
+ } else if ((modB & Modifiers.INTERNAL) != 0)
+ flags = Modifiers.PRIVATE;
- if (ma == MethodAttributes.Public)
- return "public";
-
- if (ma == MethodAttributes.FamORAssem)
- return "protected internal";
-
- if (ma == MethodAttributes.Private)
- return "private";
-
- throw new NotImplementedException (ma.ToString ());
+ return modB != modA && (modA & (~flags)) == 0;
}
public static TypeAttributes TypeAttr (Modifiers mod_flags, bool is_toplevel)
{
MethodAttributes ma = MethodAttributes.HideBySig;
- if ((mod_flags & Modifiers.PUBLIC) != 0)
+ switch (mod_flags & Modifiers.AccessibilityMask) {
+ case Modifiers.PUBLIC:
ma |= MethodAttributes.Public;
- else if ((mod_flags & Modifiers.PRIVATE) != 0)
+ break;
+ case Modifiers.PRIVATE:
ma |= MethodAttributes.Private;
- else if ((mod_flags & Modifiers.PROTECTED) != 0) {
- if ((mod_flags & Modifiers.INTERNAL) != 0)
- ma |= MethodAttributes.FamORAssem;
- else
- ma |= MethodAttributes.Family;
- } else {
- if ((mod_flags & Modifiers.INTERNAL) != 0)
- ma |= MethodAttributes.Assembly;
+ break;
+ case Modifiers.PROTECTED | Modifiers.INTERNAL:
+ ma |= MethodAttributes.FamORAssem;
+ break;
+ case Modifiers.PROTECTED:
+ ma |= MethodAttributes.Family;
+ break;
+ case Modifiers.INTERNAL:
+ ma |= MethodAttributes.Assembly;
+ break;
+ default:
+ throw new NotImplementedException (mod_flags.ToString ());
}
if ((mod_flags & Modifiers.STATIC) != 0)
if ((mod_flags & Modifiers.VIRTUAL) != 0)
ma |= MethodAttributes.Virtual;
- if ((mod_flags & Modifiers.OVERRIDE) != 0)
+ if ((mod_flags & Modifiers.OVERRIDE) != 0) {
ma |= MethodAttributes.Virtual;
- else {
+ } else {
if ((ma & MethodAttributes.Virtual) != 0)
ma |= MethodAttributes.NewSlot;
}
a = ((a & 2) >> 1) + (a & 5);
a = ((a & 4) >> 2) + (a & 3);
if (a > 1)
- Report.Error (107, l, "More than one protection modifier specified", Report);
+ Report.Error (107, l, "More than one protection modifier specified");
return mod;
}
public static void Error_InvalidModifier (Location l, string name, Report Report)
{
- Report.Error (106, l, "The modifier `" + name + "' is not valid for this item", Report);
+ Report.Error (106, l, "The modifier `{0}' is not valid for this item", name);
}
}
}
using System;
using System.Collections.Generic;
using System.Reflection;
+using System.Linq;
namespace Mono.CSharp {
public class RootNamespace : Namespace {
- //
- // Points to Mono's GetNamespaces method, an
- // optimization when running on Mono to fetch all the
- // namespaces in an assembly
- //
- static MethodInfo get_namespaces_method;
protected readonly string alias_name;
protected Assembly [] referenced_assemblies;
Dictionary<string, Namespace> all_namespaces;
- static RootNamespace ()
- {
- get_namespaces_method = typeof (Assembly).GetMethod ("GetNamespaces", BindingFlags.Instance | BindingFlags.NonPublic);
- }
-
public RootNamespace (string alias_name)
: base (null, String.Empty)
{
referenced_assemblies = n;
}
- public void ComputeNamespace (CompilerContext ctx, Type extensionType)
+ public void ImportTypes (CompilerContext ctx)
{
foreach (Assembly a in referenced_assemblies) {
try {
- ComputeNamespaces (a, extensionType);
+ ImportAssembly (a);
} catch (TypeLoadException e) {
ctx.Report.Error (11, Location.Null, e.Message);
} catch (System.IO.FileNotFoundException) {
}
}
- public virtual Type LookupTypeReflection (CompilerContext ctx, string name, Location loc, bool must_be_unique)
- {
- // FIXME: Breaks dynamic
- Assembly invocation_assembly = CodeGen.Assembly.Builder;
-
- Type found_type = null;
- foreach (Assembly a in referenced_assemblies) {
- Type t = GetTypeInAssembly (invocation_assembly, a, name);
- if (t == null)
- continue;
-
- if (!must_be_unique)
- return t;
-
- if (found_type == null) {
- found_type = t;
- continue;
- }
-
- // When type is forwarded
- if (t.Assembly == found_type.Assembly)
- continue;
-
- ctx.Report.SymbolRelatedToPreviousError (found_type);
- ctx.Report.SymbolRelatedToPreviousError (t);
- if (loc.IsNull) {
- Error_AmbiguousPredefinedType (ctx, loc, name, found_type);
- } else {
- ctx.Report.Error (433, loc, "The imported type `{0}' is defined multiple times", name);
- }
-
- return found_type;
- }
-
- return found_type;
- }
-
- //
- // Returns the types starting with the given prefix
- //
- public ICollection<string> CompletionGetTypesStartingWith (string prefix)
- {
- Dictionary<string, string> result = null;
-
- foreach (Assembly a in referenced_assemblies){
- Type [] mtypes = a.GetTypes ();
-
- foreach (Type t in mtypes){
- if (t.IsNotPublic)
- continue;
-
- string f = t.FullName;
-
- if (f.StartsWith (prefix) && (result == null || !result.ContainsKey (f))){
- if (result == null)
- result = new Dictionary<string, string> ();
-
- result [f] = f;
- }
- }
- }
- return result == null ? null : result.Keys;
- }
-
- protected static void Error_AmbiguousPredefinedType (CompilerContext ctx, Location loc, string name, Type type)
- {
- ctx.Report.Warning (1685, 1, loc,
- "The predefined type `{0}' is ambiguous. Using definition from `{1}'",
- name, type.Assembly.FullName);
- }
-
public void RegisterNamespace (Namespace child)
{
if (child != this)
GetNamespace (dotted_name, true);
}
- void RegisterExtensionMethodClass (Type t)
- {
- string n = t.Namespace;
- Namespace ns = null;
- if (n == null)
- ns = GlobalRootNamespace.Instance;
- else
- all_namespaces.TryGetValue (n, out ns);
-
- if (ns == null)
- ns = GetNamespace (n, true);
-
- ns.RegisterExternalExtensionMethodClass (t);
- }
-
- void ComputeNamespaces (Assembly assembly, Type extensionType)
+ public void ImportAssembly (Assembly assembly)
{
- bool contains_extension_methods = extensionType != null && assembly.IsDefined (extensionType, false);
-
- if (get_namespaces_method != null) {
- string [] namespaces = (string []) get_namespaces_method.Invoke (assembly, null);
- foreach (string ns in namespaces)
- RegisterNamespace (ns);
-
- if (!contains_extension_methods)
- return;
- }
-
- foreach (Type t in assembly.GetTypes ()) {
- if ((t.Attributes & Class.StaticClassAttribute) == Class.StaticClassAttribute &&
- contains_extension_methods && t.IsDefined (extensionType, false))
- RegisterExtensionMethodClass (t);
-
- if (get_namespaces_method == null)
- RegisterNamespace (t.Namespace);
- }
- }
+ Type extension_type = null;
+ var all_attributes = CustomAttributeData.GetCustomAttributes (assembly);
+ foreach (var attr in all_attributes) {
+ var dt = attr.Constructor.DeclaringType;
+ if (dt.Name == "ExtensionAttribute" && dt.Namespace == "System.Runtime.CompilerServices") {
+ extension_type = dt;
+ break;
+ }
+ }
- protected static Type GetTypeInAssembly (Assembly invocation, Assembly assembly, string name)
- {
- if (assembly == null)
- throw new ArgumentNullException ("assembly");
- if (name == null)
- throw new ArgumentNullException ("name");
- Type t = assembly.GetType (name);
- if (t == null)
- return null;
+ Namespace ns = this;
+ string prev_namespace = null;
+ foreach (var t in assembly.GetTypes ()) {
+ if (t.IsNested)
+ continue;
- if (t.IsPointer)
- throw new InternalErrorException ("Use GetPointerType() to get a pointer");
+ if (t.Name[0] == '<')
+ continue;
- TypeAttributes ta = t.Attributes & TypeAttributes.VisibilityMask;
- if (ta == TypeAttributes.NestedPrivate)
- return null;
+ var it = Import.CreateType (t);
+ if (it == null)
+ continue;
- if ((ta == TypeAttributes.NotPublic ||
- ta == TypeAttributes.NestedAssembly ||
- ta == TypeAttributes.NestedFamANDAssem) &&
- !TypeManager.IsThisOrFriendAssembly (invocation, t.Assembly))
- return null;
+ if (prev_namespace != t.Namespace) {
+ ns = t.Namespace == null ? this : GetNamespace (t.Namespace, true);
+ prev_namespace = t.Namespace;
+ }
- return t;
- }
+ ns.AddType (it);
- public override string ToString ()
- {
- return String.Format ("RootNamespace ({0}::)", alias_name);
- }
+ if (it.IsStatic && extension_type != null && t.IsDefined (extension_type, false)) {
+ it.SetExtensionMethodContainer ();
+ }
+ }
+ }
public override string GetSignatureForError ()
{
if (m == RootContext.ToplevelTypes.Builder)
return;
- foreach (Type t in m.GetTypes ())
+ foreach (var t in m.GetTypes ())
RegisterNamespace (t.Namespace);
}
public void ComputeNamespaces (CompilerContext ctx)
{
- //
- // Do very early lookup because type is required when we cache
- // imported extension types in ComputeNamespaces
- //
- Type extension_attribute_type = TypeManager.CoreLookupType (ctx, "System.Runtime.CompilerServices", "ExtensionAttribute", MemberKind.Class, false);
-
foreach (RootNamespace rn in root_namespaces.Values) {
- rn.ComputeNamespace (ctx, extension_attribute_type);
+ rn.ImportTypes (ctx);
}
}
retval.AddAssemblyReference (assembly);
}
- public override void Error_NamespaceDoesNotExist (Location loc, string name, IMemberContext ctx)
+ public override void Error_NamespaceDoesNotExist (Location loc, string name, int arity, IMemberContext ctx)
{
ctx.Compiler.Report.Error (400, loc,
"The type or namespace name `{0}' could not be found in the global namespace (are you missing an assembly reference?)",
return rn;
}
-
- public override Type LookupTypeReflection (CompilerContext ctx, string name, Location loc, bool must_be_unique)
- {
- Type found_type = base.LookupTypeReflection (ctx, name, loc, must_be_unique);
-
- if (modules != null) {
- foreach (Module module in modules) {
- Type t = module.GetType (name);
- if (t == null)
- continue;
-
- if (found_type == null) {
- found_type = t;
- continue;
- }
-
- ctx.Report.SymbolRelatedToPreviousError (found_type);
- if (loc.IsNull) {
- DeclSpace ds = TypeManager.LookupDeclSpace (t);
- Error_AmbiguousPredefinedType (ctx, ds.Location, name, found_type);
- return found_type;
- }
- ctx.Report.SymbolRelatedToPreviousError (t);
- ctx.Report.Warning (436, 2, loc, "The type `{0}' conflicts with the imported type `{1}'. Ignoring the imported type definition",
- TypeManager.CSharpName (t), TypeManager.CSharpName (found_type));
- return t;
- }
- }
-
- return found_type;
- }
}
/// <summary>
Namespace parent;
string fullname;
- Dictionary<string, Namespace> namespaces;
- Dictionary<string, DeclSpace> declspaces;
+ protected Dictionary<string, Namespace> namespaces;
+ protected Dictionary<string, IList<TypeSpec>> types;
Dictionary<string, TypeExpr> cached_types;
RootNamespace root;
- List<Type> external_exmethod_classes;
+ bool cls_checked;
public readonly MemberName MemberName;
{
// Expression members.
this.eclass = ExprClass.Namespace;
- this.Type = typeof (Namespace);
+ this.Type = InternalType.FakeInternalType;
this.loc = Location.Null;
this.parent = parent;
root.RegisterNamespace (this);
}
+ #region Properties
+
+ /// <summary>
+ /// The qualified name of the current namespace
+ /// </summary>
+ public string Name {
+ get { return fullname; }
+ }
+
+ /// <summary>
+ /// The parent of this namespace, used by the parser to "Pop"
+ /// the current namespace declaration
+ /// </summary>
+ public Namespace Parent {
+ get { return parent; }
+ }
+
+ #endregion
+
protected override Expression DoResolve (ResolveContext ec)
{
return this;
}
- public virtual void Error_NamespaceDoesNotExist (Location loc, string name, IMemberContext ctx)
+ public virtual void Error_NamespaceDoesNotExist (Location loc, string name, int arity, IMemberContext ctx)
{
- if (name.IndexOf ('`') > 0) {
- FullNamedExpression retval = Lookup (ctx.Compiler, SimpleName.RemoveGenericArity (name), loc);
- if (retval != null) {
- retval.Error_TypeArgumentsCannotBeUsed (ctx.Compiler.Report, loc);
- return;
- }
- } else {
- Type t = LookForAnyGenericType (name);
- if (t != null) {
- Error_InvalidNumberOfTypeArguments (ctx.Compiler.Report, t, loc);
- return;
- }
+ FullNamedExpression retval = Lookup (ctx.Compiler, name, -System.Math.Max (1, arity), loc);
+ if (retval != null) {
+ Error_TypeArgumentsCannotBeUsed (ctx.Compiler.Report, loc, retval.Type, arity);
+ return;
+ }
+
+ Namespace ns;
+ if (arity > 0 && namespaces.TryGetValue (name, out ns)) {
+ ns.Error_TypeArgumentsCannotBeUsed (ctx.Compiler.Report, loc, null, arity);
+ return;
}
ctx.Compiler.Report.Error (234, loc,
name, GetSignatureForError ());
}
- public static void Error_InvalidNumberOfTypeArguments (Report report, Type t, Location loc)
- {
- report.SymbolRelatedToPreviousError (t);
- report.Error (305, loc, "Using the generic type `{0}' requires `{1}' type argument(s)",
- TypeManager.CSharpName(t), TypeManager.GetNumberOfTypeArguments(t).ToString());
- }
-
public override string GetSignatureForError ()
{
return fullname;
return ns;
}
- public bool HasDefinition (string name)
+ TypeExpr LookupType (CompilerContext ctx, string name, int arity, Location loc)
{
- return declspaces != null && declspaces.ContainsKey (name);
- }
+ if (types == null)
+ return null;
- TypeExpr LookupType (CompilerContext ctx, string name, Location loc)
- {
TypeExpr te;
- if (cached_types.TryGetValue (name, out te))
+ if (arity == 0 && cached_types.TryGetValue (name, out te))
return te;
- Type t = null;
- if (declspaces != null) {
- DeclSpace tdecl;
- if (declspaces.TryGetValue (name, out tdecl)) {
- //
- // Note that this is not:
- //
- // t = tdecl.DefineType ()
- //
- // This is to make it somewhat more useful when a DefineType
- // fails due to problems in nested types (more useful in the sense
- // of fewer misleading error messages)
- //
- tdecl.DefineType ();
- t = tdecl.TypeBuilder;
-
- if (RootContext.EvalMode){
- // Replace the TypeBuilder with a System.Type, as
- // Reflection.Emit fails otherwise (we end up pretty
- // much with Random type definitions later on).
- Type tt = t.Assembly.GetType (t.Name);
- if (tt != null)
- t = tt;
+ IList<TypeSpec> found;
+ if (!types.TryGetValue (name, out found))
+ return null;
+
+ TypeSpec best = null;
+ foreach (var ts in found) {
+ if (ts.Arity == arity) {
+ if (best == null) {
+ best = ts;
+ continue;
+ }
+
+ if (best.MemberDefinition.IsImported && ts.MemberDefinition.IsImported) {
+ ctx.Report.SymbolRelatedToPreviousError (best);
+ ctx.Report.SymbolRelatedToPreviousError (ts);
+ ctx.Report.Error (433, loc, "The imported type `{0}' is defined multiple times", ts.GetSignatureForError ());
+ break;
+ }
+
+ var pts = best as PredefinedTypeSpec;
+ if (pts == null)
+ pts = ts as PredefinedTypeSpec;
+
+ if (pts != null) {
+ ctx.Report.SymbolRelatedToPreviousError (best);
+ ctx.Report.SymbolRelatedToPreviousError (ts);
+ ctx.Report.Warning (1685, 1, loc,
+ "The predefined type `{0}.{1}' is redefined in the source code. Ignoring the local type definition",
+ pts.Namespace, pts.Name);
+ best = pts;
+ continue;
+ }
+
+ if (best.MemberDefinition.IsImported)
+ best = ts;
+
+ if ((best.Modifiers & Modifiers.INTERNAL) != 0 && !TypeManager.IsThisOrFriendAssembly (CodeGen.Assembly.Builder, best.MemberDefinition.Assembly))
+ continue;
+
+ if (ts.MemberDefinition.IsImported)
+ ctx.Report.SymbolRelatedToPreviousError (ts);
+
+ ctx.Report.Warning (436, 2, loc,
+ "The type `{0}' conflicts with the imported type of same name'. Ignoring the imported type definition",
+ best.GetSignatureForError ());
+ }
+
+ //
+ // Lookup for the best candidate with closest arity match
+ //
+ if (arity < 0) {
+ if (best == null) {
+ best = ts;
+ } else if (System.Math.Abs (ts.Arity + arity) < System.Math.Abs (best.Arity + arity)) {
+ best = ts;
}
}
}
- string lookup = t != null ? t.FullName : (fullname.Length == 0 ? name : fullname + "." + name);
- Type rt = root.LookupTypeReflection (ctx, lookup, loc, t == null);
- // HACK: loc.IsNull when the type is core type
- if (t == null || (rt != null && loc.IsNull))
- t = rt;
+ if (best == null)
+ return null;
+
+ te = new TypeExpression (best, Location.Null);
+
+ // TODO MemberCache: Cache more
+ if (arity == 0)
+ cached_types.Add (name, te);
- te = t == null ? null : new TypeExpression (t, Location.Null);
- cached_types [name] = te;
return te;
}
- ///
- /// Used for better error reporting only
- ///
- public Type LookForAnyGenericType (string typeName)
+ TypeSpec LookupType (string name, int arity)
{
- if (declspaces == null)
+ if (types == null)
return null;
- typeName = SimpleName.RemoveGenericArity (typeName);
+ IList<TypeSpec> found;
+ if (types.TryGetValue (name, out found)) {
+ TypeSpec best = null;
+
+ foreach (var ts in found) {
+ if (ts.Arity == arity)
+ return ts;
- foreach (var de in declspaces) {
- string type_item = de.Key;
- int pos = type_item.LastIndexOf ('`');
- if (pos == typeName.Length && String.Compare (typeName, 0, type_item, 0, pos) == 0)
- return de.Value.TypeBuilder;
+ //
+ // Lookup for the best candidate with closest arity match
+ //
+ if (arity < 0) {
+ if (best == null) {
+ best = ts;
+ } else if (System.Math.Abs (ts.Arity + arity) < System.Math.Abs (best.Arity + arity)) {
+ best = ts;
+ }
+ }
+ }
+
+ return best;
}
+
return null;
}
- public FullNamedExpression Lookup (CompilerContext ctx, string name, Location loc)
+ public FullNamedExpression Lookup (CompilerContext ctx, string name, int arity, Location loc)
{
- if (namespaces.ContainsKey (name))
+ if (arity == 0 && namespaces.ContainsKey (name))
return namespaces [name];
- return LookupType (ctx, name, loc);
+ return LookupType (ctx, name, arity, loc);
}
//
- // Completes types with the given `prefix' and stores the results in `result'
+ // Completes types with the given `prefix'
//
- public void CompletionGetTypesStartingWith (string prefix, Dictionary<string, string> result)
+ public IEnumerable<string> CompletionGetTypesStartingWith (string prefix)
{
- int l = fullname.Length + 1;
- var res = root.CompletionGetTypesStartingWith (fullname + "." + prefix);
-
- if (res == null)
- return;
-
- foreach (string match in res){
- string x = match.Substring (l);
+ if (types == null)
+ return Enumerable.Empty<string> ();
- // Turn reflection nested classes foo+bar into foo.bar
- x = x.Replace ('+', '.');
+ var res = from item in types
+ where item.Key.StartsWith (prefix) && item.Value.Any (l => (l.Modifiers & Modifiers.PUBLIC) != 0)
+ select item.Key;
- // Only get the first name element, no point in adding anything beyond the first dot.
- int p = x.IndexOf ('.');
- if (p != -1)
- x = x.Substring (0, p);
+ if (namespaces != null)
+ res = res.Concat (from item in namespaces where item.Key.StartsWith (prefix) select item.Key);
- // Turn Foo`N into Foo<
- p = x.IndexOf ('`');
- if (p != -1)
- x = x.Substring (0, p) + "<";
-
- if (!result.ContainsKey (x))
- result [x] = x;
- }
- }
-
- public void RegisterExternalExtensionMethodClass (Type type)
- {
- // Ignore, extension methods cannot be nested
- if (type.DeclaringType != null)
- return;
-
- // TODO: CodeGen.Assembly.Builder is global
- if (type.IsNotPublic && !TypeManager.IsThisOrFriendAssembly (CodeGen.Assembly.Builder, type.Assembly))
- return;
-
- if (external_exmethod_classes == null)
- external_exmethod_classes = new List<Type> ();
-
- external_exmethod_classes.Add (type);
+ return res;
}
///
/// Looks for extension method in this namespace
///
- public List<MethodSpec> LookupExtensionMethod (Type extensionType, ClassOrStruct currentClass, string name)
+ public List<MethodSpec> LookupExtensionMethod (TypeSpec extensionType, ClassOrStruct currentClass, string name, int arity)
{
+ if (types == null)
+ return null;
+
List<MethodSpec> found = null;
- // TODO: problematic
- var invocation_assembly = CodeGen.Assembly.Builder;
+ var invocation_type = currentClass == null ? InternalType.FakeInternalType : currentClass.CurrentType;
- if (declspaces != null) {
- var e = declspaces.Values.GetEnumerator ();
- while (e.MoveNext ()) {
- Class c = e.Current as Class;
- if (c == null)
- continue;
+ // TODO: Add per namespace flag when at least 1 type has extension
- if ((c.ModFlags & Modifiers.METHOD_EXTENSION) == 0)
+ foreach (var tgroup in types.Values) {
+ foreach (var ts in tgroup) {
+ if ((ts.Modifiers & Modifiers.METHOD_EXTENSION) == 0)
continue;
- var res = c.MemberCache.FindExtensionMethods (invocation_assembly, extensionType, name, c != currentClass);
+ var res = ts.MemberCache.FindExtensionMethods (invocation_type, extensionType, name, arity);
if (res == null)
continue;
- if (found == null)
+ if (found == null) {
found = res;
- else
+ } else {
found.AddRange (res);
+ }
}
}
- if (external_exmethod_classes == null)
- return found;
-
- foreach (Type t in external_exmethod_classes) {
- MemberCache m = TypeHandle.GetMemberCache (t);
- var res = m.FindExtensionMethods (invocation_assembly, extensionType, name, true);
- if (res == null)
- continue;
+ return found;
+ }
- if (found == null)
- found = res;
- else
- found.AddRange (res);
+ public void AddType (TypeSpec ts)
+ {
+ if (types == null) {
+ types = new Dictionary<string, IList<TypeSpec>> (64);
}
- return found;
+ var name = ts.Name;
+ IList<TypeSpec> existing;
+ if (types.TryGetValue (name, out existing)) {
+ TypeSpec better_type;
+ TypeSpec found;
+ if (existing.Count == 1) {
+ found = existing[0];
+ if (ts.Arity == found.Arity) {
+ better_type = IsImportedTypeOverride (ts, found);
+ if (better_type == found)
+ return;
+
+ if (better_type != null) {
+ existing [0] = better_type;
+ return;
+ }
+ }
+
+ existing = new List<TypeSpec> ();
+ existing.Add (found);
+ types[name] = existing;
+ } else {
+ for (int i = 0; i < existing.Count; ++i) {
+ found = existing[i];
+ if (ts.Arity != found.Arity)
+ continue;
+
+ better_type = IsImportedTypeOverride (ts, found);
+ if (better_type == found)
+ return;
+
+ if (better_type != null) {
+ existing.RemoveAt (i);
+ --i;
+ continue;
+ }
+ }
+ }
+
+ existing.Add (ts);
+ } else {
+ types.Add (name, new TypeSpec[] { ts });
+ }
}
- public void AddDeclSpace (string name, DeclSpace ds)
+ //
+ // We import any types but in the situation there are same types
+ // but one has better visibility (either public or internal with friend)
+ // the less visible type is removed from the namespace cache
+ //
+ public static TypeSpec IsImportedTypeOverride (TypeSpec ts, TypeSpec found)
{
- if (declspaces == null)
- declspaces = new Dictionary<string, DeclSpace> ();
- declspaces.Add (name, ds);
+ var ts_accessible = (ts.Modifiers & Modifiers.PUBLIC) != 0 || TypeManager.IsThisOrFriendAssembly (CodeGen.Assembly.Builder, ts.MemberDefinition.Assembly);
+ var found_accessible = (found.Modifiers & Modifiers.PUBLIC) != 0 || TypeManager.IsThisOrFriendAssembly (CodeGen.Assembly.Builder, found.MemberDefinition.Assembly);
+
+ if (ts_accessible && !found_accessible)
+ return ts;
+
+ // found is better always better for accessible or inaccessible ts
+ if (!ts_accessible)
+ return found;
+
+ return null;
}
public void RemoveDeclSpace (string name)
{
- declspaces.Remove (name);
+ types.Remove (name);
}
-
- /// <summary>
- /// The qualified name of the current namespace
- /// </summary>
- public string Name {
- get { return fullname; }
+
+ public void ReplaceTypeWithPredefined (TypeSpec ts, PredefinedTypeSpec pts)
+ {
+ var found = types [ts.Name];
+ cached_types.Remove (ts.Name);
+ if (found.Count == 1) {
+ types[ts.Name][0] = pts;
+ } else {
+ throw new NotImplementedException ();
+ }
}
- /// <summary>
- /// The parent of this namespace, used by the parser to "Pop"
- /// the current namespace declaration
- /// </summary>
- public Namespace Parent {
- get { return parent; }
+ public void VerifyClsCompliance ()
+ {
+ if (types == null || cls_checked)
+ return;
+
+ cls_checked = true;
+
+ // TODO: This is quite ugly way to check for CLS compliance at namespace level
+
+ var locase_types = new Dictionary<string, List<TypeSpec>> (StringComparer.OrdinalIgnoreCase);
+ foreach (var tgroup in types.Values) {
+ foreach (var tm in tgroup) {
+ if ((tm.Modifiers & Modifiers.PUBLIC) == 0 || !tm.IsCLSCompliant ())
+ continue;
+
+ List<TypeSpec> found;
+ if (!locase_types.TryGetValue (tm.Name, out found)) {
+ found = new List<TypeSpec> ();
+ locase_types.Add (tm.Name, found);
+ }
+
+ found.Add (tm);
+ }
+ }
+
+ foreach (var locase in locase_types.Values) {
+ if (locase.Count < 2)
+ continue;
+
+ bool all_same = true;
+ foreach (var notcompliant in locase) {
+ all_same = notcompliant.Name == locase[0].Name;
+ if (!all_same)
+ break;
+ }
+
+ if (all_same)
+ continue;
+
+ TypeContainer compiled = null;
+ foreach (var notcompliant in locase) {
+ if (!notcompliant.MemberDefinition.IsImported) {
+ if (compiled != null)
+ compiled.Compiler.Report.SymbolRelatedToPreviousError (compiled);
+
+ compiled = notcompliant.MemberDefinition as TypeContainer;
+ } else {
+ compiled.Compiler.Report.SymbolRelatedToPreviousError (notcompliant);
+ }
+ }
+
+ compiled.Compiler.Report.Warning (3005, 1, compiled.Location,
+ "Identifier `{0}' differing only in case is not CLS-compliant", compiled.GetSignatureForError ());
+ }
}
}
}
if (resolved is TypeExpr)
- resolved = resolved.ResolveAsBaseTerminal (rc, false);
+ resolved = resolved.ResolveAsTypeTerminal (rc, false);
return resolved;
}
/// Does extension methods look up to find a method which matches name and extensionType.
/// Search starts from this namespace and continues hierarchically up to top level.
///
- public ExtensionMethodGroupExpr LookupExtensionMethod (Type extensionType, string name, Location loc)
+ public ExtensionMethodGroupExpr LookupExtensionMethod (TypeSpec extensionType, string name, int arity, Location loc)
{
List<MethodSpec> candidates = null;
foreach (Namespace n in GetUsingTable ()) {
- var a = n.LookupExtensionMethod (extensionType, null, name);
+ var a = n.LookupExtensionMethod (extensionType, null, name, arity);
if (a == null)
continue;
//
Namespace parent_ns = ns.Parent;
do {
- candidates = parent_ns.LookupExtensionMethod (extensionType, null, name);
+ candidates = parent_ns.LookupExtensionMethod (extensionType, null, name, arity);
if (candidates != null)
return new ExtensionMethodGroupExpr (candidates, parent, extensionType, loc);
//
// Continue in parent scope
//
- return parent.LookupExtensionMethod (extensionType, name, loc);
+ return parent.LookupExtensionMethod (extensionType, name, arity, loc);
}
- public FullNamedExpression LookupNamespaceOrType (string name, Location loc, bool ignore_cs0104)
+ public FullNamedExpression LookupNamespaceOrType (string name, int arity, Location loc, bool ignore_cs0104)
{
// Precondition: Only simple names (no dots) will be looked up with this function.
FullNamedExpression resolved = null;
for (NamespaceEntry curr_ns = this; curr_ns != null; curr_ns = curr_ns.ImplicitParent) {
- if ((resolved = curr_ns.Lookup (name, loc, ignore_cs0104)) != null)
+ if ((resolved = curr_ns.Lookup (name, arity, loc, ignore_cs0104)) != null)
break;
}
+
return resolved;
}
- public ICollection<string> CompletionGetTypesStartingWith (string prefix)
+ public IList<string> CompletionGetTypesStartingWith (string prefix)
{
- var result = new Dictionary<string, string> ();
+ IEnumerable<string> all = Enumerable.Empty<string> ();
for (NamespaceEntry curr_ns = this; curr_ns != null; curr_ns = curr_ns.ImplicitParent){
foreach (Namespace using_ns in GetUsingTable ()){
if (ld != -1){
string rest = prefix.Substring (ld+1);
- using_ns.CompletionGetTypesStartingWith (rest, result);
+ all = all.Concat (using_ns.CompletionGetTypesStartingWith (rest));
}
}
- using_ns.CompletionGetTypesStartingWith (prefix, result);
+ all = all.Concat (using_ns.CompletionGetTypesStartingWith (prefix));
}
}
- return result.Keys;
+ return all.Distinct ().ToList ();
}
- void Error_AmbiguousTypeReference (Location loc, string name, FullNamedExpression t1, FullNamedExpression t2)
- {
- Compiler.Report.SymbolRelatedToPreviousError (t1.Type);
- Compiler.Report.SymbolRelatedToPreviousError (t2.Type);
- Compiler.Report.Error (104, loc, "`{0}' is an ambiguous reference between `{1}' and `{2}'",
- name, t1.GetSignatureForError (), t2.GetSignatureForError ());
- }
-
// Looks-up a alias named @name in this and surrounding namespace declarations
public FullNamedExpression LookupNamespaceAlias (string name)
{
return null;
}
- private FullNamedExpression Lookup (string name, Location loc, bool ignore_cs0104)
+ private FullNamedExpression Lookup (string name, int arity, Location loc, bool ignore_cs0104)
{
//
// Check whether it's in the namespace.
//
- FullNamedExpression fne = ns.Lookup (Compiler, name, loc);
+ FullNamedExpression fne = ns.Lookup (Compiler, name, arity, loc);
//
// Check aliases.
//
- if (using_aliases != null) {
+ if (using_aliases != null && arity == 0) {
foreach (UsingAliasEntry ue in using_aliases) {
if (ue.Alias == name) {
if (fne != null) {
}
}
- if (fne != null)
- return fne;
+ if (fne != null) {
+ if (!((fne.Type.Modifiers & Modifiers.INTERNAL) != 0 && !TypeManager.IsThisOrFriendAssembly (CodeGen.Assembly.Builder, fne.Type.Assembly)))
+ return fne;
+ }
if (IsImplicit)
return null;
//
FullNamedExpression match = null;
foreach (Namespace using_ns in GetUsingTable ()) {
- match = using_ns.Lookup (Compiler, name, loc);
- if (match == null || !(match is TypeExpr))
+ fne = using_ns.Lookup (Compiler, name, arity, loc);
+ if (fne == null)
+ continue;
+
+ if (match == null) {
+ match = fne;
continue;
- if (fne != null) {
- if (!ignore_cs0104)
- Error_AmbiguousTypeReference (loc, name, fne, match);
- return null;
}
- fne = match;
+
+ // Prefer types over namespaces
+ var texpr_fne = fne as TypeExpr;
+ var texpr_match = match as TypeExpr;
+ if (texpr_fne != null && texpr_match == null) {
+ match = fne;
+ continue;
+ } else if (texpr_fne == null && texpr_match != null) {
+ continue;
+ }
+
+ if (ignore_cs0104)
+ return match;
+
+ // It can be top level accessibility only
+ var better = Namespace.IsImportedTypeOverride (texpr_match.Type, texpr_fne.Type);
+ if (better == null) {
+ Compiler.Report.SymbolRelatedToPreviousError (texpr_match.Type);
+ Compiler.Report.SymbolRelatedToPreviousError (texpr_fne.Type);
+ Compiler.Report.Error (104, loc, "`{0}' is an ambiguous reference between `{1}' and `{2}'",
+ name, texpr_match.GetSignatureForError (), texpr_fne.GetSignatureForError ());
+ return match;
+ }
+
+ if (better == texpr_fne.Type)
+ match = texpr_fne;
}
- return fne;
+ return match;
}
Namespace [] GetUsingTable ()
get { return RootContext.ToplevelTypes.Compiler; }
}
- public Type CurrentType {
+ public TypeSpec CurrentType {
get { return SlaveDeclSpace.CurrentType; }
}
- public TypeContainer CurrentTypeDefinition {
- get { return SlaveDeclSpace.CurrentTypeDefinition; }
+ public MemberCore CurrentMemberDefinition {
+ get { return SlaveDeclSpace.CurrentMemberDefinition; }
}
public TypeParameter[] CurrentTypeParameters {
get { return SlaveDeclSpace.CurrentTypeParameters; }
}
+ public bool HasUnresolvedConstraints {
+ get { return false; }
+ }
+
public bool IsObsolete {
get { return SlaveDeclSpace.IsObsolete; }
}
eclass = ExprClass.Type;
}
- public NullableType (Type type, Location loc)
+ public NullableType (TypeSpec type, Location loc)
: this (new TypeExpression (type, loc), loc)
{ }
{
if (TypeManager.generic_nullable_type == null) {
TypeManager.generic_nullable_type = TypeManager.CoreLookupType (ec.Compiler,
- "System", "Nullable`1", MemberKind.Struct, true);
+ "System", "Nullable", 1, MemberKind.Struct, true);
}
TypeArguments args = new TypeArguments (underlying);
GenericTypeExpr ctype = new GenericTypeExpr (TypeManager.generic_nullable_type, args, loc);
return ctype.ResolveAsTypeTerminal (ec, false);
}
-
- public override TypeExpr ResolveAsTypeTerminal (IMemberContext ec, bool silent)
- {
- return ResolveAsBaseTerminal (ec, silent);
- }
}
- public sealed class NullableInfo
+ static class NullableInfo
{
- public readonly Type Type;
- public readonly Type UnderlyingType;
- public MethodSpec HasValue;
- public MethodSpec Value;
- public MethodSpec GetValueOrDefault;
- public MethodSpec Constructor;
-
- public NullableInfo (Type type)
+ public static MethodSpec GetConstructor (TypeSpec nullableType)
{
- Type = type;
- UnderlyingType = TypeManager.TypeToCoreType (TypeManager.GetTypeArguments (type) [0]);
-
- var has_value_pi = TypeManager.GetPredefinedProperty (type, "HasValue", Location.Null, Type.EmptyTypes);
- var value_pi = TypeManager.GetPredefinedProperty (type, "Value", Location.Null, Type.EmptyTypes);
- GetValueOrDefault = TypeManager.GetPredefinedMethod (type, "GetValueOrDefault", Location.Null, Type.EmptyTypes);
+ return TypeManager.GetPredefinedConstructor (nullableType, Location.Null, GetUnderlyingType (nullableType));
+ }
- HasValue = Import.CreateMethod (has_value_pi.MetaInfo.GetGetMethod (false));
- Value = Import.CreateMethod (value_pi.MetaInfo.GetGetMethod (false));
+ public static MethodSpec GetHasValue (TypeSpec nullableType)
+ {
+ return (MethodSpec) MemberCache.FindMember (nullableType,
+ MemberFilter.Method ("get_HasValue", 0, ParametersCompiled.EmptyReadOnlyParameters, null), BindingRestriction.None);
+ }
- // When compiling corlib
- if (TypeManager.IsBeingCompiled (type)) {
- TypeContainer tc = TypeManager.LookupGenericTypeContainer (type);
-
- // TODO: check for correct overload
- Constructor c = ((Constructor) tc.InstanceConstructors [0]);
+ public static MethodSpec GetGetValueOrDefault (TypeSpec nullableType)
+ {
+ return (MethodSpec) MemberCache.FindMember (nullableType,
+ MemberFilter.Method ("GetValueOrDefault", 0, ParametersCompiled.EmptyReadOnlyParameters, null), BindingRestriction.None);
+ }
- Constructor = Import.CreateMethod (TypeBuilder.GetConstructor (type, c.ConstructorBuilder));
- return;
- }
+ public static MethodSpec GetValue (TypeSpec nullableType)
+ {
+ return (MethodSpec) MemberCache.FindMember (nullableType,
+ MemberFilter.Method ("get_Value", 0, ParametersCompiled.EmptyReadOnlyParameters, null), BindingRestriction.None);
+ }
-#if MS_COMPATIBLE
-// if (TypeManager.IsBeingCompiled (UnderlyingType)) {
-// ConstructorInfo cinfo = TypeManager.DropGenericTypeArguments (type).GetConstructors ()[0];
-// Constructor = TypeBuilder.GetConstructor (type, cinfo);
-// return;
-// }
-#endif
+ public static TypeSpec GetUnderlyingType (TypeSpec nullableType)
+ {
+ return ((InflatedTypeSpec) nullableType).TypeArguments[0];
+ }
- Constructor = Import.CreateMethod (type.GetConstructor (new Type[] { UnderlyingType }));
+ public static bool IsNullableType (TypeSpec type)
+ {
+ throw new NotImplementedException ("net");
}
}
public class Unwrap : Expression, IMemoryLocation, IAssignMethod
{
Expression expr;
- NullableInfo info;
LocalTemporary temp;
readonly bool useDefaultValue;
this.loc = expr.Location;
this.useDefaultValue = useDefaultValue;
- info = new NullableInfo (expr.Type);
- type = info.UnderlyingType;
+ type = NullableInfo.GetUnderlyingType (expr.Type);
eclass = expr.eclass;
}
{
Store (ec);
if (useDefaultValue)
- Invocation.EmitCall (ec, false, this, info.GetValueOrDefault, null, loc);
+ Invocation.EmitCall (ec, false, this, NullableInfo.GetGetValueOrDefault (expr.Type), null, loc);
else
- Invocation.EmitCall (ec, false, this, info.Value, null, loc);
+ Invocation.EmitCall (ec, false, this, NullableInfo.GetValue (expr.Type), null, loc);
}
public void EmitCheck (EmitContext ec)
{
Store (ec);
- Invocation.EmitCall (ec, false, this, info.HasValue, null, loc);
+ Invocation.EmitCall (ec, false, this, NullableInfo.GetHasValue (expr.Type), null, loc);
}
public override bool Equals (object obj)
return expr.MakeExpression (ctx);
}
- public override void MutateHoistedGenericType (AnonymousMethodStorey storey)
- {
- type = storey.MutateType (type);
- storey.MutateConstructor (info.Constructor);
- storey.MutateGenericMethod (info.HasValue);
- storey.MutateGenericMethod (info.GetValueOrDefault);
- storey.MutateGenericMethod (info.Value);
- }
-
public void AddressOf (EmitContext ec, AddressOp mode)
{
IMemoryLocation ml = expr as VariableReference;
LocalTemporary LocalVariable {
get {
if (temp == null)
- temp = new LocalTemporary (info.Type);
+ temp = new LocalTemporary (expr.Type);
return temp;
}
}
public void EmitAssign (EmitContext ec, Expression source,
bool leave_copy, bool prepare_for_load)
{
- InternalWrap wrap = new InternalWrap (source, info, loc);
+ InternalWrap wrap = new InternalWrap (source, expr.Type, loc);
((IAssignMethod) expr).EmitAssign (ec, wrap, leave_copy, false);
}
- protected class InternalWrap : Expression
+ class InternalWrap : Expression
{
public Expression expr;
- public NullableInfo info;
- public InternalWrap (Expression expr, NullableInfo info, Location loc)
+ public InternalWrap (Expression expr, TypeSpec type, Location loc)
{
this.expr = expr;
- this.info = info;
this.loc = loc;
+ this.type = type;
- type = info.Type;
eclass = ExprClass.Value;
}
public override void Emit (EmitContext ec)
{
expr.Emit (ec);
- ec.ig.Emit (OpCodes.Newobj, (ConstructorInfo) info.Constructor.MetaInfo);
+ ec.Emit (OpCodes.Newobj, NullableInfo.GetConstructor (type));
}
}
}
public class Wrap : TypeCast
{
- readonly NullableInfo info;
-
- protected Wrap (Expression expr, Type type)
+ private Wrap (Expression expr, TypeSpec type)
: base (expr, type)
{
- info = new NullableInfo (type);
eclass = ExprClass.Value;
}
return base.CreateExpressionTree (ec);
}
- public static Expression Create (Expression expr, Type type)
+ public static Expression Create (Expression expr, TypeSpec type)
{
//
// Avoid unwraping and wraping of the same type
//
Unwrap unwrap = expr as Unwrap;
- if (unwrap != null && TypeManager.IsEqual (expr.Type, TypeManager.TypeToCoreType (TypeManager.GetTypeArguments (type) [0])))
+ if (unwrap != null && TypeManager.IsEqual (expr.Type, NullableInfo.GetUnderlyingType (type)))
return unwrap.Original;
return new Wrap (expr, type);
public override void Emit (EmitContext ec)
{
child.Emit (ec);
- ec.ig.Emit (OpCodes.Newobj, (ConstructorInfo) info.Constructor.MetaInfo);
+ ec.Emit (OpCodes.Newobj, NullableInfo.GetConstructor (type));
}
}
//
public class LiftedNull : NullConstant, IMemoryLocation
{
- private LiftedNull (Type nullable_type, Location loc)
+ private LiftedNull (TypeSpec nullable_type, Location loc)
: base (nullable_type, loc)
{
eclass = ExprClass.Value;
}
- public static Constant Create (Type nullable, Location loc)
+ public static Constant Create (TypeSpec nullable, Location loc)
{
return new LiftedNull (nullable, loc);
}
LocalTemporary value_target = new LocalTemporary (type);
value_target.AddressOf (ec, AddressOp.Store);
- ec.ig.Emit (OpCodes.Initobj, type);
+ ec.Emit (OpCodes.Initobj, type);
value_target.Emit (ec);
}
LocalTemporary value_target = new LocalTemporary (type);
value_target.AddressOf (ec, AddressOp.Store);
- ec.ig.Emit (OpCodes.Initobj, type);
+ ec.Emit (OpCodes.Initobj, type);
((IMemoryLocation) value_target).AddressOf (ec, Mode);
}
}
Expression expr, null_value;
Unwrap unwrap;
- public Lifted (Expression expr, Unwrap unwrap, Type type)
+ public Lifted (Expression expr, Unwrap unwrap, TypeSpec type)
{
this.expr = expr;
this.unwrap = unwrap;
this.type = type;
}
- public Lifted (Expression expr, Expression unwrap, Type type)
+ public Lifted (Expression expr, Expression unwrap, TypeSpec type)
: this (expr, unwrap as Unwrap, type)
{
}
public override void Emit (EmitContext ec)
{
- ILGenerator ig = ec.ig;
- Label is_null_label = ig.DefineLabel ();
- Label end_label = ig.DefineLabel ();
+ Label is_null_label = ec.DefineLabel ();
+ Label end_label = ec.DefineLabel ();
unwrap.EmitCheck (ec);
- ig.Emit (OpCodes.Brfalse, is_null_label);
+ ec.Emit (OpCodes.Brfalse, is_null_label);
expr.Emit (ec);
- ig.Emit (OpCodes.Br, end_label);
- ig.MarkLabel (is_null_label);
+ ec.Emit (OpCodes.Br, end_label);
+ ec.MarkLabel (is_null_label);
null_value.Emit (ec);
- ig.MarkLabel (end_label);
+ ec.MarkLabel (end_label);
}
public void AddressOf (EmitContext ec, AddressOp mode)
public override void Emit (EmitContext ec)
{
- ILGenerator ig = ec.ig;
- Label is_null_label = ig.DefineLabel ();
- Label end_label = ig.DefineLabel ();
+ Label is_null_label = ec.DefineLabel ();
+ Label end_label = ec.DefineLabel ();
unwrap.EmitCheck (ec);
- ig.Emit (OpCodes.Brfalse, is_null_label);
-
- NullableInfo ni = new NullableInfo (type);
+ ec.Emit (OpCodes.Brfalse, is_null_label);
if (user_operator != null) {
user_operator.Emit (ec);
} else {
- EmitOperator (ec, ni.UnderlyingType);
+ EmitOperator (ec, NullableInfo.GetUnderlyingType (type));
}
- ig.Emit (OpCodes.Newobj, (ConstructorInfo) ni.Constructor.MetaInfo);
- ig.Emit (OpCodes.Br_S, end_label);
+ ec.Emit (OpCodes.Newobj, NullableInfo.GetConstructor (type));
+ ec.Emit (OpCodes.Br_S, end_label);
- ig.MarkLabel (is_null_label);
+ ec.MarkLabel (is_null_label);
LiftedNull.Create (type, loc).Emit (ec);
- ig.MarkLabel (end_label);
+ ec.MarkLabel (end_label);
}
Expression LiftExpression (ResolveContext ec, Expression expr)
void EmitBitwiseBoolean (EmitContext ec)
{
- ILGenerator ig = ec.ig;
-
- Label load_left = ig.DefineLabel ();
- Label load_right = ig.DefineLabel ();
- Label end_label = ig.DefineLabel ();
+ Label load_left = ec.DefineLabel ();
+ Label load_right = ec.DefineLabel ();
+ Label end_label = ec.DefineLabel ();
left_unwrap.Emit (ec);
- ig.Emit (OpCodes.Brtrue_S, load_right);
+ ec.Emit (OpCodes.Brtrue_S, load_right);
right_unwrap.Emit (ec);
- ig.Emit (OpCodes.Brtrue_S, load_left);
+ ec.Emit (OpCodes.Brtrue_S, load_left);
left_unwrap.EmitCheck (ec);
- ig.Emit (OpCodes.Brfalse_S, load_right);
+ ec.Emit (OpCodes.Brfalse_S, load_right);
// load left
- ig.MarkLabel (load_left);
+ ec.MarkLabel (load_left);
if (Oper == Operator.BitwiseAnd) {
left_unwrap.Load (ec);
right_unwrap.Load (ec);
right_unwrap = left_unwrap;
}
- ig.Emit (OpCodes.Br_S, end_label);
+ ec.Emit (OpCodes.Br_S, end_label);
// load right
- ig.MarkLabel (load_right);
+ ec.MarkLabel (load_right);
right_unwrap.Load (ec);
- ig.MarkLabel (end_label);
+ ec.MarkLabel (end_label);
}
//
//
void EmitEquality (EmitContext ec)
{
- ILGenerator ig = ec.ig;
-
//
// Either left or right is null
//
if (left_unwrap != null && (right_null_lifted || right.IsNull)) {
left_unwrap.EmitCheck (ec);
if (Oper == Binary.Operator.Equality) {
- ig.Emit (OpCodes.Ldc_I4_0);
- ig.Emit (OpCodes.Ceq);
+ ec.Emit (OpCodes.Ldc_I4_0);
+ ec.Emit (OpCodes.Ceq);
}
return;
}
if (right_unwrap != null && (left_null_lifted || left.IsNull)) {
right_unwrap.EmitCheck (ec);
if (Oper == Binary.Operator.Equality) {
- ig.Emit (OpCodes.Ldc_I4_0);
- ig.Emit (OpCodes.Ceq);
+ ec.Emit (OpCodes.Ldc_I4_0);
+ ec.Emit (OpCodes.Ceq);
}
return;
}
- Label dissimilar_label = ig.DefineLabel ();
- Label end_label = ig.DefineLabel ();
+ Label dissimilar_label = ec.DefineLabel ();
+ Label end_label = ec.DefineLabel ();
if (user_operator != null) {
user_operator.Emit (ec);
- ig.Emit (Oper == Operator.Equality ? OpCodes.Brfalse_S : OpCodes.Brtrue_S, dissimilar_label);
+ ec.Emit (Oper == Operator.Equality ? OpCodes.Brfalse_S : OpCodes.Brtrue_S, dissimilar_label);
} else {
left.Emit (ec);
right.Emit (ec);
- ig.Emit (OpCodes.Bne_Un_S, dissimilar_label);
+ ec.Emit (OpCodes.Bne_Un_S, dissimilar_label);
}
if (left_unwrap != null)
if (left_unwrap != null && right_unwrap != null) {
if (Oper == Operator.Inequality)
- ig.Emit (OpCodes.Xor);
+ ec.Emit (OpCodes.Xor);
else
- ig.Emit (OpCodes.Ceq);
+ ec.Emit (OpCodes.Ceq);
} else {
if (Oper == Operator.Inequality) {
- ig.Emit (OpCodes.Ldc_I4_0);
- ig.Emit (OpCodes.Ceq);
+ ec.Emit (OpCodes.Ldc_I4_0);
+ ec.Emit (OpCodes.Ceq);
}
}
- ig.Emit (OpCodes.Br_S, end_label);
+ ec.Emit (OpCodes.Br_S, end_label);
- ig.MarkLabel (dissimilar_label);
+ ec.MarkLabel (dissimilar_label);
if (Oper == Operator.Inequality)
- ig.Emit (OpCodes.Ldc_I4_1);
+ ec.Emit (OpCodes.Ldc_I4_1);
else
- ig.Emit (OpCodes.Ldc_I4_0);
+ ec.Emit (OpCodes.Ldc_I4_0);
- ig.MarkLabel (end_label);
+ ec.MarkLabel (end_label);
}
public override void EmitBranchable (EmitContext ec, Label target, bool onTrue)
{
Emit (ec);
- ec.ig.Emit (onTrue ? OpCodes.Brtrue : OpCodes.Brfalse, target);
+ ec.Emit (onTrue ? OpCodes.Brtrue : OpCodes.Brfalse, target);
}
public override void Emit (EmitContext ec)
return;
}
- ILGenerator ig = ec.ig;
-
- Label is_null_label = ig.DefineLabel ();
- Label end_label = ig.DefineLabel ();
+ Label is_null_label = ec.DefineLabel ();
+ Label end_label = ec.DefineLabel ();
if (left_unwrap != null) {
left_unwrap.EmitCheck (ec);
- ig.Emit (OpCodes.Brfalse, is_null_label);
+ ec.Emit (OpCodes.Brfalse, is_null_label);
}
//
//
if (right_unwrap != null && !left.Equals (right)) {
right_unwrap.EmitCheck (ec);
- ig.Emit (OpCodes.Brfalse, is_null_label);
+ ec.Emit (OpCodes.Brfalse, is_null_label);
}
EmitOperator (ec, left.Type);
if (wrap_ctor != null)
- ig.Emit (OpCodes.Newobj, (ConstructorInfo) wrap_ctor.MetaInfo);
+ ec.Emit (OpCodes.Newobj, wrap_ctor);
- ig.Emit (OpCodes.Br_S, end_label);
- ig.MarkLabel (is_null_label);
+ ec.Emit (OpCodes.Br_S, end_label);
+ ec.MarkLabel (is_null_label);
if ((Oper & Operator.ComparisonMask) != 0) {
- ig.Emit (OpCodes.Ldc_I4_0);
+ ec.Emit (OpCodes.Ldc_I4_0);
} else {
LiftedNull.Create (type, loc).Emit (ec);
}
- ig.MarkLabel (end_label);
+ ec.MarkLabel (end_label);
}
- protected override void EmitOperator (EmitContext ec, Type l)
+ protected override void EmitOperator (EmitContext ec, TypeSpec l)
{
if (user_operator != null) {
user_operator.Emit (ec);
}
if (TypeManager.IsNullableType (l))
- l = TypeManager.TypeToCoreType (TypeManager.GetTypeArguments (l) [0]);
+ l = TypeManager.GetTypeArguments (l) [0];
base.EmitOperator (ec, l);
}
if (lifted_type == null)
return null;
- wrap_ctor = new NullableInfo (lifted_type.Type).Constructor;
+ wrap_ctor = NullableInfo.GetConstructor (lifted_type.Type);
type = res_expr.Type = lifted_type.Type;
}
return res_expr;
}
- protected override Expression ResolveOperatorPredefined (ResolveContext ec, Binary.PredefinedOperator [] operators, bool primitives_only, Type enum_type)
+ protected override Expression ResolveOperatorPredefined (ResolveContext ec, Binary.PredefinedOperator [] operators, bool primitives_only, TypeSpec enum_type)
{
Expression e = base.ResolveOperatorPredefined (ec, operators, primitives_only, enum_type);
return e;
}
- protected override Expression ResolveUserOperator (ResolveContext ec, Type l, Type r)
+ protected override Expression ResolveUserOperator (ResolveContext ec, TypeSpec l, TypeSpec r)
{
Expression expr = base.ResolveUserOperator (ec, l, r);
if (expr == null)
if (left.eclass == ExprClass.MethodGroup)
return null;
- Type ltype = left.Type;
+ TypeSpec ltype = left.Type;
//
// If left is a nullable type and an implicit conversion exists from right to underlying type of left,
return null;
}
- Type rtype = right.Type;
+ TypeSpec rtype = right.Type;
if (!Convert.ImplicitConversionExists (ec, unwrap != null ? unwrap : left, rtype) || right.eclass == ExprClass.MethodGroup)
return null;
public override void Emit (EmitContext ec)
{
- ILGenerator ig = ec.ig;
-
- Label end_label = ig.DefineLabel ();
+ Label end_label = ec.DefineLabel ();
if (unwrap != null) {
- Label is_null_label = ig.DefineLabel ();
+ Label is_null_label = ec.DefineLabel ();
unwrap.EmitCheck (ec);
- ig.Emit (OpCodes.Brfalse, is_null_label);
+ ec.Emit (OpCodes.Brfalse, is_null_label);
left.Emit (ec);
- ig.Emit (OpCodes.Br, end_label);
+ ec.Emit (OpCodes.Br, end_label);
- ig.MarkLabel (is_null_label);
+ ec.MarkLabel (is_null_label);
right.Emit (ec);
- ig.MarkLabel (end_label);
+ ec.MarkLabel (end_label);
return;
}
left.Emit (ec);
- ig.Emit (OpCodes.Dup);
- ig.Emit (OpCodes.Brtrue, end_label);
+ ec.Emit (OpCodes.Dup);
+ ec.Emit (OpCodes.Brtrue, end_label);
- ig.Emit (OpCodes.Pop);
+ ec.Emit (OpCodes.Pop);
right.Emit (ec);
- ig.MarkLabel (end_label);
- }
-
- public override void MutateHoistedGenericType (AnonymousMethodStorey storey)
- {
- left.MutateHoistedGenericType (storey);
- right.MutateHoistedGenericType (storey);
- type = storey.MutateType (type);
+ ec.MarkLabel (end_label);
}
protected override void CloneTo (CloneContext clonectx, Expression t)
void DoEmit (EmitContext ec, bool is_expr)
{
- ILGenerator ig = ec.ig;
- Label is_null_label = ig.DefineLabel ();
- Label end_label = ig.DefineLabel ();
+ Label is_null_label = ec.DefineLabel ();
+ Label end_label = ec.DefineLabel ();
unwrap.EmitCheck (ec);
- ig.Emit (OpCodes.Brfalse, is_null_label);
+ ec.Emit (OpCodes.Brfalse, is_null_label);
if (is_expr) {
underlying.Emit (ec);
- ig.Emit (OpCodes.Br_S, end_label);
+ ec.Emit (OpCodes.Br_S, end_label);
} else {
underlying.EmitStatement (ec);
}
- ig.MarkLabel (is_null_label);
+ ec.MarkLabel (is_null_label);
if (is_expr)
LiftedNull.Create (type, loc).Emit (ec);
- ig.MarkLabel (end_label);
+ ec.MarkLabel (end_label);
}
public override void Emit (EmitContext ec)
using System.Reflection;
using System.Reflection.Emit;
using System.Text;
+using System.Linq;
namespace Mono.CSharp {
{
protected ParameterBuilder builder;
- public override void ApplyAttributeBuilder (Attribute a, ConstructorInfo ctor, byte[] cdata, PredefinedAttributes pa)
+ public override void ApplyAttributeBuilder (Attribute a, MethodSpec ctor, byte[] cdata, PredefinedAttributes pa)
{
#if false
if (a.Type == pa.MarshalAs) {
return;
}
- builder.SetCustomAttribute (ctor, cdata);
+ builder.SetCustomAttribute ((ConstructorInfo) ctor.GetMetaInfo (), cdata);
}
public ParameterBuilder Builder {
}
}
- public override void ApplyAttributeBuilder (Attribute a, ConstructorInfo ctor, byte[] cdata, PredefinedAttributes pa)
+ public override void ApplyAttributeBuilder (Attribute a, MethodSpec ctor, byte[] cdata, PredefinedAttributes pa)
{
if (a.Type == pa.CLSCompliant) {
method.Compiler.Report.Warning (3023, 1, a.Location,
{
}
- public override Type Resolve (IMemberContext ec)
+ public override TypeSpec Resolve (IMemberContext ec, int index)
{
if (parameter_type == null)
throw new InternalErrorException ("A type of implicit lambda parameter `{0}' is not set",
Name);
+ base.idx = index;
return parameter_type;
}
- public Type Type {
+ public TypeSpec Type {
set { parameter_type = value; }
}
}
{
}
- public override Type Resolve (IMemberContext ec)
+ public override TypeSpec Resolve (IMemberContext ec, int index)
{
- if (base.Resolve (ec) == null)
+ if (base.Resolve (ec, index) == null)
return null;
- if (!parameter_type.IsArray || parameter_type.GetArrayRank () != 1) {
+ var ac = parameter_type as ArrayContainer;
+ if (ac == null || ac.Rank != 1) {
ec.Compiler.Report.Error (225, Location, "The params parameter must be a single dimensional array");
return null;
}
public ArglistParameter (Location loc) :
base (null, String.Empty, Parameter.Modifier.NONE, null, loc)
{
+ parameter_type = InternalType.Arglist;
}
public override void ApplyAttributes (MethodBuilder mb, ConstructorBuilder cb, int index)
return true;
}
- public override Type Resolve (IMemberContext ec)
+ public override TypeSpec Resolve (IMemberContext ec, int index)
{
- return InternalType.Arglist;
- }
-
- public override string GetSignatureForError ()
- {
- return "__arglist";
+ return parameter_type;
}
}
static string[] attribute_targets = new string [] { "param" };
- protected FullNamedExpression TypeName;
+ FullNamedExpression texpr;
readonly Modifier modFlags;
string name;
Expression default_expr;
- protected Type parameter_type;
+ protected TypeSpec parameter_type;
public readonly Location Location;
- int idx;
+ protected int idx;
public bool HasAddressTaken;
Expression expr_tree_variable;
this.name = name;
modFlags = mod;
Location = loc;
- TypeName = type;
+ texpr = type;
// Only assign, attributes will be attached during resolve
base.attributes = attrs;
}
- public override void ApplyAttributeBuilder (Attribute a, ConstructorInfo ctor, byte[] cdata, PredefinedAttributes pa)
+#region Properties
+ public FullNamedExpression TypeExpression {
+ get {
+ return texpr;
+ }
+ }
+#endregion
+
+ public override void ApplyAttributeBuilder (Attribute a, MethodSpec ctor, byte[] cdata, PredefinedAttributes pa)
{
if (a.Type == pa.In && ModFlags == Modifier.OUT) {
a.Report.Error (36, a.Location, "An out parameter cannot have the `In' attribute");
}
if (a.Type == pa.DefaultParameterValue) {
- Type arg_type;
+ TypeSpec arg_type;
var c = a.GetParameterDefaultValue (out arg_type);
if (c == null) {
if (parameter_type == TypeManager.object_type) {
a.Report.Error (1910, a.Location, "Argument of type `{0}' is not applicable for the DefaultParameterValue attribute",
- TypeManager.CSharpName (arg_type));
+ arg_type.GetSignatureForError ());
} else {
a.Report.Error (1909, a.Location, "The DefaultParameterValue attribute is not applicable on parameters of type `{0}'",
- TypeManager.CSharpName (parameter_type)); ;
+ parameter_type.GetSignatureForError ()); ;
}
return;
return member.IsAccessibleAs (parameter_type);
}
+ public static void Reset ()
+ {
+ parameter_expr_tree_type = null;
+ }
+
// <summary>
// Resolve is used in method definitions
// </summary>
- public virtual Type Resolve (IMemberContext rc)
+ public virtual TypeSpec Resolve (IMemberContext rc, int index)
{
if (parameter_type != null)
return parameter_type;
if (attributes != null)
attributes.AttachTo (this, rc);
- TypeExpr texpr = TypeName.ResolveAsTypeTerminal (rc, false);
- if (texpr == null)
+ var expr = texpr.ResolveAsTypeTerminal (rc, false);
+ if (expr == null)
return null;
+ this.idx = index;
+ texpr = expr;
parameter_type = texpr.Type;
// Ignore all checks for dummy members
AbstractPropertyEventMethod pem = rc as AbstractPropertyEventMethod;
if (pem != null && pem.IsDummy)
return parameter_type;
-
- if (default_expr != null)
- default_expr = ResolveDefaultValue (new ResolveContext (rc));
-
+
if ((modFlags & Parameter.Modifier.ISBYREF) != 0 &&
TypeManager.IsSpecialType (parameter_type)) {
rc.Compiler.Report.Error (1601, Location, "Method or delegate parameter cannot be of type `{0}'",
(modFlags & Parameter.Modifier.ISBYREF) != 0 ? Variance.None : Variance.Contravariant,
rc);
- if (TypeManager.IsGenericParameter (parameter_type))
- return parameter_type;
-
- if ((parameter_type.Attributes & Class.StaticClassAttribute) == Class.StaticClassAttribute) {
+ if (parameter_type.IsStatic) {
rc.Compiler.Report.Error (721, Location, "`{0}': static types cannot be used as parameters",
texpr.GetSignatureForError ());
return parameter_type;
}
- if ((modFlags & Modifier.This) != 0 && (parameter_type.IsPointer || TypeManager.IsDynamicType (parameter_type))) {
+ if ((modFlags & Modifier.This) != 0 && (parameter_type.IsPointer || parameter_type == InternalType.Dynamic)) {
rc.Compiler.Report.Error (1103, Location, "The extension method cannot be of type `{0}'",
TypeManager.CSharpName (parameter_type));
}
return parameter_type;
}
- Expression ResolveDefaultValue (ResolveContext rc)
+ public void ResolveDefaultValue (ResolveContext rc)
+ {
+ if (default_expr != null)
+ default_expr = ResolveDefaultExpression (rc);
+ }
+
+ Expression ResolveDefaultExpression (ResolveContext rc)
{
default_expr = default_expr.Resolve (rc);
if (default_expr == null)
return null;
}
- public void ResolveVariable (int idx)
- {
- this.idx = idx;
- }
-
public bool HasDefaultValue {
get { return default_expr != null; }
}
if (parameter_type != null)
type_name = TypeManager.CSharpName (parameter_type);
else
- type_name = TypeName.GetSignatureForError ();
+ type_name = texpr.GetSignatureForError ();
string mod = GetModifierSignature (modFlags);
if (mod.Length > 0)
public void IsClsCompliant (IMemberContext ctx)
{
- if (AttributeTester.IsClsCompliant (parameter_type))
+ if (parameter_type.IsCLSCompliant ())
return;
ctx.Compiler.Report.Warning (3001, 1, Location,
}
}
- if (TypeManager.IsDynamicType (parameter_type)) {
+ if (parameter_type == InternalType.Dynamic) {
PredefinedAttributes.Get.Dynamic.EmitAttribute (builder);
} else {
var trans_flags = TypeManager.HasDynamicTypeUsed (parameter_type);
if (trans_flags != null) {
var pa = PredefinedAttributes.Get.DynamicTransform;
- if (pa.Constructor != null || pa.ResolveConstructor (Location, TypeManager.bool_type.MakeArrayType ())) {
+ if (pa.Constructor != null || pa.ResolveConstructor (Location, ArrayContainer.MakeType (TypeManager.bool_type))) {
builder.SetCustomAttribute (
new CustomAttributeBuilder (pa.Constructor, new object [] { trans_flags }));
}
if (!ec.IsStatic)
arg_idx++;
- ParameterReference.EmitLdArg (ec.ig, arg_idx);
+ ParameterReference.EmitLdArg (ec, arg_idx);
}
public void EmitAssign (EmitContext ec)
arg_idx++;
if (arg_idx <= 255)
- ec.ig.Emit (OpCodes.Starg_S, (byte) arg_idx);
+ ec.Emit (OpCodes.Starg_S, (byte) arg_idx);
else
- ec.ig.Emit (OpCodes.Starg, arg_idx);
+ ec.Emit (OpCodes.Starg, arg_idx);
}
public void EmitAddressOf (EmitContext ec)
bool is_ref = (ModFlags & Modifier.ISBYREF) != 0;
if (is_ref) {
- ParameterReference.EmitLdArg (ec.ig, arg_idx);
+ ParameterReference.EmitLdArg (ec, arg_idx);
} else {
if (arg_idx <= 255)
- ec.ig.Emit (OpCodes.Ldarga_S, (byte) arg_idx);
+ ec.Emit (OpCodes.Ldarga_S, (byte) arg_idx);
else
- ec.ig.Emit (OpCodes.Ldarga, arg_idx);
+ ec.Emit (OpCodes.Ldarga, arg_idx);
}
}
if (parameter_expr_tree_type != null)
return parameter_expr_tree_type;
- Type p_type = TypeManager.parameter_expression_type;
+ TypeSpec p_type = TypeManager.parameter_expression_type;
if (p_type == null) {
p_type = TypeManager.CoreLookupType (ec.Compiler, "System.Linq.Expressions", "ParameterExpression", MemberKind.Class, true);
TypeManager.parameter_expression_type = p_type;
// Null object pattern
protected IParameterData [] parameters;
- protected Type [] types;
-
- public ParametersCompiled AsCompiled {
- get { return (ParametersCompiled) this; }
- }
+ protected TypeSpec [] types;
public CallingConventions CallingConvention {
get {
get { return parameters.Length; }
}
- public Type ExtensionMethodType {
+ public TypeSpec ExtensionMethodType {
get {
if (Count == 0)
return null;
ParameterAttributes.Out : ParameterAttributes.None;
}
- public Type [] GetEmitTypes ()
+ // Very expensive operation
+ public Type[] GetMetaInfo ()
{
- Type [] types = null;
+ Type[] types;
if (has_arglist) {
if (Count == 1)
return Type.EmptyTypes;
types = new Type [Count - 1];
- Array.Copy (Types, types, types.Length);
+ } else {
+ if (Count == 0)
+ return Type.EmptyTypes;
+
+ types = new Type [Count];
}
- for (int i = 0; i < Count; ++i) {
+ for (int i = 0; i < types.Length; ++i) {
+ types[i] = Types[i].GetMetaInfo ();
+
if ((FixedParameters [i].ModFlags & Parameter.Modifier.ISBYREF) == 0)
continue;
- if (types == null)
- types = (Type []) Types.Clone ();
-
- types [i] = TypeManager.GetReferenceType (types [i]);
+ // TODO MemberCache: Should go to MetaInfo getter
+ types [i] = types [i].MakeByRefType ();
}
- if (types == null)
- types = Types;
-
return types;
}
public string GetSignatureForError ()
{
- StringBuilder sb = new StringBuilder ("(");
- for (int i = 0; i < Count; ++i) {
+ return GetSignatureForError ("(", ")", Count);
+ }
+
+ public string GetSignatureForError (string start, string end, int count)
+ {
+ StringBuilder sb = new StringBuilder (start);
+ for (int i = 0; i < count; ++i) {
if (i != 0)
sb.Append (", ");
sb.Append (ParameterDesc (i));
}
- sb.Append (')');
+ sb.Append (end);
return sb.ToString ();
}
get { return parameters.Length == 0; }
}
+ public AParametersCollection Inflate (TypeParameterInflator inflator)
+ {
+ TypeSpec[] inflated_types = null;
+ bool default_value = false;
+
+ for (int i = 0; i < Count; ++i) {
+ var inflated_param = inflator.Inflate (types[i]);
+ if (inflated_types == null) {
+ if (inflated_param == types[i])
+ continue;
+
+ default_value |= FixedParameters[i] is DefaultValueExpression;
+ inflated_types = new TypeSpec[types.Length];
+ Array.Copy (types, inflated_types, types.Length);
+ }
+
+ inflated_types[i] = inflated_param;
+ }
+
+ if (inflated_types == null)
+ return this;
+
+ var clone = (AParametersCollection) MemberwiseClone ();
+ clone.types = inflated_types;
+ if (default_value) {
+ for (int i = 0; i < Count; ++i) {
+ var dve = clone.FixedParameters[i] as DefaultValueExpression;
+ if (dve != null) {
+ throw new NotImplementedException ("net");
+ // clone.FixedParameters [i].DefaultValue = new DefaultValueExpression ();
+ }
+ }
+ }
+
+ return clone;
+ }
+
public string ParameterDesc (int pos)
{
if (types == null || types [pos] == null)
return Parameter.GetModifierSignature (mod) + " " + type;
}
- public Type[] Types {
+ public TypeSpec[] Types {
get { return types; }
set { types = value; }
}
-
-#if MS_COMPATIBLE
- public AParametersCollection InflateTypes (Type[] genArguments, Type[] argTypes)
- {
- AParametersCollection p = (AParametersCollection) MemberwiseClone (); // Clone ();
-
- for (int i = 0; i < Count; ++i) {
- if (types[i].IsGenericType) {
- Type[] gen_arguments_open = new Type[types[i].GetGenericTypeDefinition ().GetGenericArguments ().Length];
- Type[] gen_arguments = types[i].GetGenericArguments ();
- for (int ii = 0; ii < gen_arguments_open.Length; ++ii) {
- if (gen_arguments[ii].IsGenericParameter) {
- Type t = argTypes[gen_arguments[ii].GenericParameterPosition];
- gen_arguments_open[ii] = t;
- } else
- gen_arguments_open[ii] = gen_arguments[ii];
- }
-
- p.types[i] = types[i].GetGenericTypeDefinition ().MakeGenericType (gen_arguments_open);
- continue;
- }
-
- if (types[i].IsGenericParameter) {
- Type gen_argument = argTypes[types[i].GenericParameterPosition];
- p.types[i] = gen_argument;
- continue;
- }
- }
-
- return p;
- }
-#endif
}
//
//
public class ParametersImported : AParametersCollection
{
- ParametersImported (AParametersCollection param, Type[] types)
+ ParametersImported (AParametersCollection param, TypeSpec[] types)
{
this.parameters = param.FixedParameters;
this.types = types;
has_params = param.HasParams;
}
- ParametersImported (IParameterData [] parameters, Type [] types, bool hasArglist, bool hasParams)
+ ParametersImported (IParameterData [] parameters, TypeSpec [] types, bool hasArglist, bool hasParams)
{
this.parameters = parameters;
this.types = types;
this.has_params = hasParams;
}
- public ParametersImported (IParameterData [] param, Type[] types)
+ public ParametersImported (IParameterData [] param, TypeSpec[] types)
{
this.parameters = param;
this.types = types;
}
- public static AParametersCollection Create (MethodBase method)
+ public static AParametersCollection Create (TypeSpec parent, MethodBase method)
{
- return Create (method.GetParameters (), method);
- }
-
- //
- // Generic method parameters importer, param is shared between all instances
- //
- public static AParametersCollection Create (AParametersCollection param, MethodBase method)
- {
- if (param.IsEmpty)
- return param;
-
- ParameterInfo [] pi = method.GetParameters ();
- Type [] types = new Type [pi.Length];
- for (int i = 0; i < types.Length; i++) {
- Type t = pi [i].ParameterType;
- if (t.IsByRef)
- t = TypeManager.GetElementType (t);
-
- types [i] = TypeManager.TypeToCoreType (t);
- }
-
- return new ParametersImported (param, types);
+ return Create (parent, method.GetParameters (), method);
}
//
// Imports SRE parameters
//
- public static AParametersCollection Create (ParameterInfo [] pi, MethodBase method)
+ public static AParametersCollection Create (TypeSpec parent, ParameterInfo [] pi, MethodBase method)
{
int varargs = method != null && (method.CallingConvention & CallingConventions.VarArgs) != 0 ? 1 : 0;
if (pi.Length == 0 && varargs == 0)
return ParametersCompiled.EmptyReadOnlyParameters;
- Type [] types = new Type [pi.Length + varargs];
+ TypeSpec [] types = new TypeSpec [pi.Length + varargs];
IParameterData [] par = new IParameterData [pi.Length + varargs];
bool is_params = false;
PredefinedAttribute extension_attr = PredefinedAttributes.Get.Extension;
- PredefinedAttribute param_attr = PredefinedAttributes.Get.ParamArray;
for (int i = 0; i < pi.Length; i++) {
- types [i] = TypeManager.TypeToCoreType (pi [i].ParameterType);
-
ParameterInfo p = pi [i];
Parameter.Modifier mod = 0;
Expression default_value = null;
- if (types [i].IsByRef) {
+ if (p.ParameterType.IsByRef) {
if ((p.Attributes & (ParameterAttributes.Out | ParameterAttributes.In)) == ParameterAttributes.Out)
mod = Parameter.Modifier.OUT;
else
//
// Strip reference wrapping
//
- types [i] = TypeManager.GetElementType (types [i]);
- } else if (i == 0 && extension_attr.IsDefined && method != null && method.IsStatic &&
- (method.DeclaringType.Attributes & Class.StaticClassAttribute) == Class.StaticClassAttribute &&
- method.IsDefined (extension_attr.Type, false)) {
+ types [i] = Import.ImportType (p.ParameterType.GetElementType ());
+ } else if (i == 0 && method.IsStatic && parent.IsStatic &&
+ extension_attr.IsDefined && extension_attr.IsDefined && method.IsDefined (extension_attr.Type.GetMetaInfo (), false)) {
mod = Parameter.Modifier.This;
+ types[i] = Import.ImportType (p.ParameterType);
} else {
- if (i >= pi.Length - 2 && types[i].IsArray) {
- if (p.IsDefined (param_attr.Type, false)) {
+ types[i] = Import.ImportType (p.ParameterType);
+
+ if (i >= pi.Length - 2 && types[i] is ArrayContainer) {
+ var cattrs = CustomAttributeData.GetCustomAttributes (p);
+ if (cattrs != null && cattrs.Any (l => l.Constructor.DeclaringType == typeof (ParamArrayAttribute))) {
mod = Parameter.Modifier.PARAMS;
is_params = true;
}
} else if (value == null) {
default_value = new NullLiteral (Location.Null);
} else {
- default_value = Constant.CreateConstant (null, value.GetType (), value, Location.Null);
+ default_value = Constant.CreateConstant (null, Import.ImportType (value.GetType ()), value, Location.Null);
}
}
}
private ParametersCompiled ()
{
parameters = new Parameter [0];
- types = Type.EmptyTypes;
+ types = TypeSpec.EmptyTypes;
}
- private ParametersCompiled (Parameter [] parameters, Type [] types)
+ private ParametersCompiled (IParameterData [] parameters, TypeSpec [] types)
{
this.parameters = parameters;
this.types = types;
this.has_arglist = has_arglist;
}
- public static ParametersCompiled CreateFullyResolved (Parameter p, Type type)
+ public static ParametersCompiled CreateFullyResolved (Parameter p, TypeSpec type)
{
- return new ParametersCompiled (new Parameter [] { p }, new Type [] { type });
+ return new ParametersCompiled (new Parameter [] { p }, new TypeSpec [] { type });
}
- public static ParametersCompiled CreateFullyResolved (Parameter[] parameters, Type[] types)
+ public static ParametersCompiled CreateFullyResolved (IParameterData[] parameters, TypeSpec[] types)
{
return new ParametersCompiled (parameters, types);
}
- public static ParametersCompiled MergeGenerated (CompilerContext ctx, ParametersCompiled userParams, bool checkConflicts, Parameter compilerParams, Type compilerTypes)
+ public static AParametersCollection CreateFullyResolved (TypeSpec[] types)
+ {
+ var pd = new ParameterData [types.Length];
+ for (int i = 0; i < pd.Length; ++i)
+ pd[i] = new ParameterData (null, Parameter.Modifier.NONE, null);
+
+ return new ParametersCompiled (pd, types);
+ }
+
+ //
+ // Returns non-zero value for equal CLS parameter signatures
+ //
+ public static int IsSameClsSignature (AParametersCollection a, AParametersCollection b)
+ {
+ int res = 0;
+
+ for (int i = 0; i < a.Count; ++i) {
+ var a_type = a.Types[i];
+ var b_type = b.Types[i];
+ if (TypeSpecComparer.Override.IsEqual (a_type, b_type)) {
+ const Parameter.Modifier ref_out = Parameter.Modifier.REF | Parameter.Modifier.OUT;
+ if ((a.FixedParameters[i].ModFlags & ref_out) != (b.FixedParameters[i].ModFlags & ref_out))
+ res |= 1;
+
+ continue;
+ }
+
+ var ac_a = a_type as ArrayContainer;
+ if (ac_a == null)
+ return 0;
+
+ var ac_b = b_type as ArrayContainer;
+ if (ac_b == null)
+ return 0;
+
+ if (ac_a.Element is ArrayContainer || ac_b.Element is ArrayContainer) {
+ res |= 2;
+ continue;
+ }
+
+ if (ac_a.Rank != ac_b.Rank && TypeSpecComparer.Override.IsEqual (ac_a.Element, ac_b.Element)) {
+ res |= 1;
+ continue;
+ }
+
+ return 0;
+ }
+
+ return res;
+ }
+
+ public static ParametersCompiled MergeGenerated (CompilerContext ctx, ParametersCompiled userParams, bool checkConflicts, Parameter compilerParams, TypeSpec compilerTypes)
{
return MergeGenerated (ctx, userParams, checkConflicts,
new Parameter [] { compilerParams },
- new Type [] { compilerTypes });
+ new TypeSpec [] { compilerTypes });
}
//
// Use this method when you merge compiler generated parameters with user parameters
//
- public static ParametersCompiled MergeGenerated (CompilerContext ctx, ParametersCompiled userParams, bool checkConflicts, Parameter[] compilerParams, Type[] compilerTypes)
+ public static ParametersCompiled MergeGenerated (CompilerContext ctx, ParametersCompiled userParams, bool checkConflicts, Parameter[] compilerParams, TypeSpec[] compilerTypes)
{
Parameter[] all_params = new Parameter [userParams.Count + compilerParams.Length];
userParams.FixedParameters.CopyTo(all_params, 0);
- Type [] all_types;
+ TypeSpec [] all_types;
if (userParams.types != null) {
- all_types = new Type [all_params.Length];
+ all_types = new TypeSpec [all_params.Length];
userParams.Types.CopyTo (all_types, 0);
} else {
all_types = null;
if (types != null)
return true;
- types = new Type [Count];
+ types = new TypeSpec [Count];
bool ok = true;
Parameter p;
for (int i = 0; i < FixedParameters.Length; ++i) {
p = this [i];
- Type t = p.Resolve (ec);
+ TypeSpec t = p.Resolve (ec, i);
if (t == null) {
ok = false;
continue;
return ok;
}
- public void ResolveVariable ()
+ public void ResolveDefaultValues (ResolveContext rc)
{
for (int i = 0; i < FixedParameters.Length; ++i) {
- this [i].ResolveVariable (i);
+ this [i].ResolveDefaultValue (rc);
}
}
//
// pending.cs: Pending method implementation
//
-// Author:
+// Authors:
// Miguel de Icaza (miguel@gnu.org)
+// Marek Safar (marek.safar@gmail.com)
//
// Dual licensed under the terms of the MIT X11 or GNU GPL
//
using System.Collections.Generic;
using System.Reflection;
using System.Reflection.Emit;
+using System.Linq;
namespace Mono.CSharp {
struct TypeAndMethods {
- public Type type;
- public MethodInfo [] methods;
+ public TypeSpec type;
+ public IList<MethodSpec> methods;
//
// Whether it is optional, this is used to allow the explicit/implicit
// class X : IA { } class Y : X, IA { IA.Explicit (); }
//
public bool optional;
-
- // Far from ideal, but we want to avoid creating a copy
- // of methods above.
- public Type [][] args;
-
- //This is used to store the modifiers of arguments
- public Parameter.Modifier [][] mods;
-
+
//
// This flag on the method says `We found a match, but
// because it was private, we could not use the match
// If a method is defined here, then we always need to
// create a proxy for it. This is used when implementing
// an interface's indexer with a different IndexerName.
- public MethodInfo [] need_proxy;
+ public MethodSpec [] need_proxy;
}
- public class PendingImplementation {
+ public class PendingImplementation
+ {
/// <summary>
/// The container for this PendingImplementation
/// </summary>
TypeContainer container;
- /// <summary>
- /// This filter is used by FindMembers, and it is used to
- /// extract only virtual/abstract fields
- /// </summary>
- static MemberFilter virtual_method_filter;
-
/// <summary>
/// This is the array of TypeAndMethods that describes the pending implementations
/// (both interfaces and abstract methods in base class)
/// </summary>
TypeAndMethods [] pending_implementations;
- static bool IsVirtualFilter (MemberInfo m, object filterCriteria)
- {
- MethodInfo mi = m as MethodInfo;
- return (mi == null) ? false : mi.IsVirtual;
- }
-
- /// <summary>
- /// Inits the virtual_method_filter
- /// </summary>
- static PendingImplementation ()
- {
- virtual_method_filter = new MemberFilter (IsVirtualFilter);
- }
-
- // <remarks>
- // Returns a list of the abstract methods that are exposed by all of our
- // bases that we must implement. Notice that this `flattens' the
- // method search space, and takes into account overrides.
- // </remarks>
- static IList<MethodBase> GetAbstractMethods (Type t)
- {
- List<MethodBase> list = null;
- bool searching = true;
- Type current_type = t;
-
- do {
- MemberList mi;
-
- mi = TypeContainer.FindMembers (
- current_type, MemberTypes.Method,
- BindingFlags.Public | BindingFlags.NonPublic |
- BindingFlags.Instance | BindingFlags.DeclaredOnly,
- virtual_method_filter, null);
-
- if (current_type == TypeManager.object_type)
- searching = false;
- else {
- current_type = current_type.BaseType;
- if (!current_type.IsAbstract)
- searching = false;
- }
-
- if (mi.Count == 0)
- continue;
-
- if (mi.Count == 1 && !(mi [0] is MethodBase))
- searching = false;
- else
- list = TypeManager.CopyNewMethods (list, mi);
- } while (searching);
-
- if (list == null)
- return null;
-
- for (int i = 0; i < list.Count; i++){
- while (list.Count > i && !((MethodInfo) list [i]).IsAbstract)
- list.RemoveAt (i);
- }
-
- if (list.Count == 0)
- return null;
-
- return list;
- }
-
- PendingImplementation (TypeContainer container, MissingInterfacesInfo[] missing_ifaces, IList<MethodBase> abstract_methods, int total)
+ PendingImplementation (TypeContainer container, MissingInterfacesInfo[] missing_ifaces, IList<MethodSpec> abstract_methods, int total)
{
- TypeBuilder type_builder = container.TypeBuilder;
+ var type_builder = container.Definition;
this.container = container;
pending_implementations = new TypeAndMethods [total];
int i = 0;
if (abstract_methods != null) {
int count = abstract_methods.Count;
- pending_implementations [i].methods = new MethodInfo [count];
- pending_implementations [i].need_proxy = new MethodInfo [count];
-
- abstract_methods.CopyTo (pending_implementations [i].methods, 0);
+ pending_implementations [i].methods = new MethodSpec [count];
+ pending_implementations [i].need_proxy = new MethodSpec [count];
+
+ pending_implementations [i].methods = abstract_methods;
pending_implementations [i].found = new MethodData [count];
- pending_implementations [i].args = new Type [count][];
- pending_implementations [i].mods = new Parameter.Modifier [count][];
pending_implementations [i].type = type_builder;
-
- int j = 0;
- foreach (MemberInfo m in abstract_methods) {
- MethodInfo mi = (MethodInfo) m;
-
- AParametersCollection pd = TypeManager.GetParameterData (mi);
- Type [] types = pd.Types;
-
- pending_implementations [i].args [j] = types;
- pending_implementations [i].mods [j] = null;
- if (pd.Count > 0) {
- Parameter.Modifier [] pm = new Parameter.Modifier [pd.Count];
- for (int k = 0; k < pd.Count; k++)
- pm [k] = pd.FixedParameters[k].ModFlags;
- pending_implementations [i].mods [j] = pm;
- }
-
- j++;
- }
++i;
}
foreach (MissingInterfacesInfo missing in missing_ifaces) {
- MethodInfo [] mi;
- Type t = missing.Type;
-
- if (!t.IsInterface)
- continue;
-
- if (t is TypeBuilder){
- TypeContainer iface;
+ var iface = missing.Type;
+ var mi = MemberCache.GetInterfaceMembers (iface);
- iface = TypeManager.LookupInterface (t);
-
- mi = iface.GetMethods ();
- } else
- mi = t.GetMethods ();
-
- int count = mi.Length;
- pending_implementations [i].type = t;
+ int count = mi.Count;
+ pending_implementations [i].type = iface;
pending_implementations [i].optional = missing.Optional;
pending_implementations [i].methods = mi;
- pending_implementations [i].args = new Type [count][];
- pending_implementations [i].mods = new Parameter.Modifier [count][];
pending_implementations [i].found = new MethodData [count];
- pending_implementations [i].need_proxy = new MethodInfo [count];
-
- int j = 0;
- foreach (MethodInfo m in mi){
- pending_implementations [i].args [j] = Type.EmptyTypes;
- pending_implementations [i].mods [j] = null;
-
- // If there is a previous error, just ignore
- if (m == null)
- continue;
-
- AParametersCollection pd = TypeManager.GetParameterData (m);
- pending_implementations [i].args [j] = pd.Types;
-
- if (pd.Count > 0){
- Parameter.Modifier [] pm = new Parameter.Modifier [pd.Count];
- for (int k = 0; k < pd.Count; k++)
- pm [k] = pd.FixedParameters [k].ModFlags;
- pending_implementations [i].mods [j] = pm;
- }
-
- j++;
- }
+ pending_implementations [i].need_proxy = new MethodSpec [count];
i++;
}
}
struct MissingInterfacesInfo {
- public Type Type;
+ public TypeSpec Type;
public bool Optional;
- public MissingInterfacesInfo (Type t)
+ public MissingInterfacesInfo (TypeSpec t)
{
Type = t;
Optional = false;
static MissingInterfacesInfo [] EmptyMissingInterfacesInfo = new MissingInterfacesInfo [0];
- static MissingInterfacesInfo [] GetMissingInterfaces (TypeBuilder type_builder)
+ static MissingInterfacesInfo [] GetMissingInterfaces (TypeContainer container)
{
//
- // Notice that TypeBuilders will only return the interfaces that the Type
+ // Notice that Interfaces will only return the interfaces that the Type
// is supposed to implement, not all the interfaces that the type implements.
//
- // Even better -- on MS it returns an empty array, no matter what.
- //
- // Completely broken. So we do it ourselves!
- //
- Type [] impl = TypeManager.GetExplicitInterfaces (type_builder);
+ var impl = container.Definition.Interfaces;
- if (impl == null || impl.Length == 0)
+ if (impl == null || impl.Count == 0)
return EmptyMissingInterfacesInfo;
- MissingInterfacesInfo [] ret = new MissingInterfacesInfo [impl.Length];
+ MissingInterfacesInfo[] ret = new MissingInterfacesInfo[impl.Count];
- for (int i = 0; i < impl.Length; i++)
+ for (int i = 0; i < impl.Count; i++)
ret [i] = new MissingInterfacesInfo (impl [i]);
// we really should not get here because Object doesnt implement any
// interfaces. But it could implement something internal, so we have
// to handle that case.
- if (type_builder.BaseType == null)
+ if (container.BaseType == null)
return ret;
- Type [] base_impls = TypeManager.GetInterfaces (type_builder.BaseType);
-
- foreach (Type t in base_impls) {
- for (int i = 0; i < ret.Length; i ++) {
- if (t == ret [i].Type) {
- ret [i].Optional = true;
- break;
+ var base_impls = container.BaseType.Interfaces;
+ if (base_impls != null) {
+ foreach (TypeSpec t in base_impls) {
+ for (int i = 0; i < ret.Length; i++) {
+ if (t == ret[i].Type) {
+ ret[i].Optional = true;
+ break;
+ }
}
}
}
+
return ret;
}
//
static public PendingImplementation GetPendingImplementations (TypeContainer container)
{
- TypeBuilder type_builder = container.TypeBuilder;
- MissingInterfacesInfo [] missing_interfaces;
- Type b = type_builder.BaseType;
+ TypeSpec b = container.BaseType;
- missing_interfaces = GetMissingInterfaces (type_builder);
+ var missing_interfaces = GetMissingInterfaces (container);
//
// If we are implementing an abstract class, and we are not
//
// We also pre-compute the methods.
//
- bool implementing_abstract = ((b != null) && b.IsAbstract && !type_builder.IsAbstract);
- IList<MethodBase> abstract_methods = null;
+ bool implementing_abstract = ((b != null) && b.IsAbstract && (container.ModFlags & Modifiers.ABSTRACT) == 0);
+ IList<MethodSpec> abstract_methods = null;
if (implementing_abstract){
- abstract_methods = GetAbstractMethods (b);
+ abstract_methods = MemberCache.GetNotImplementedAbstractMethods (b);
if (abstract_methods == null)
implementing_abstract = false;
/// <summary>
/// Whether the specified method is an interface method implementation
/// </summary>
- public MethodInfo IsInterfaceMethod (string name, Type ifaceType, MethodData method)
+ public MethodSpec IsInterfaceMethod (MemberName name, TypeSpec ifaceType, MethodData method)
{
return InterfaceMethod (name, ifaceType, method, Operation.Lookup);
}
- public void ImplementMethod (string name, Type ifaceType, MethodData method, bool clear_one)
+ public void ImplementMethod (MemberName name, TypeSpec ifaceType, MethodData method, bool clear_one)
{
InterfaceMethod (name, ifaceType, method, clear_one ? Operation.ClearOne : Operation.ClearAll);
}
/// that was used in the interface, then we always need to create a proxy for it.
///
/// </remarks>
- public MethodInfo InterfaceMethod (string name, Type iType, MethodData method, Operation op)
+ public MethodSpec InterfaceMethod (MemberName name, TypeSpec iType, MethodData method, Operation op)
{
if (pending_implementations == null)
return null;
- Type ret_type = method.method.ReturnType;
+ TypeSpec ret_type = method.method.ReturnType;
ParametersCompiled args = method.method.ParameterInfo;
- int arg_len = args.Count;
bool is_indexer = method.method is Indexer.SetIndexerMethod || method.method is Indexer.GetIndexerMethod;
foreach (TypeAndMethods tm in pending_implementations){
if (!(iType == null || tm.type == iType))
continue;
- int method_count = tm.methods.Length;
- MethodInfo m;
+ int method_count = tm.methods.Count;
+ MethodSpec m;
for (int i = 0; i < method_count; i++){
m = tm.methods [i];
if (m == null)
continue;
- //
- // Check if we have the same parameters
- //
+ if (is_indexer) {
+ if (!m.IsAccessor || m.Parameters.IsEmpty)
+ continue;
+ } else {
+ if (name.Name != m.Name)
+ continue;
- if (tm.args [i] == null && arg_len != 0)
- continue;
- if (tm.args [i] != null && tm.args [i].Length != arg_len)
+ if (m.Arity != name.Arity)
+ continue;
+ }
+
+ if (!TypeSpecComparer.Override.IsEqual (m.Parameters, args))
continue;
- string mname = TypeManager.GetMethodName (m);
+ if (!TypeSpecComparer.Override.IsEqual (m.ReturnType, ret_type)) {
+ tm.found[i] = method;
+ continue;
+ }
//
// `need_proxy' is not null when we're implementing an
// signature and not on the name (this is done in the Lookup
// for an interface indexer).
//
-
- if (is_indexer) {
- IMethodData md = TypeManager.GetMethod (m);
- if (md != null) {
- if (!(md is Indexer.SetIndexerMethod || md is Indexer.GetIndexerMethod))
- continue;
- } else {
- if (TypeManager.GetPropertyFromAccessor (m) == null)
- continue;
- }
- } else if (name != mname) {
- continue;
- }
-
- int j;
-
- for (j = 0; j < arg_len; j++) {
- if (!TypeManager.IsEqual (tm.args [i][j], args.Types [j]))
- break;
- if (tm.mods [i][j] == args.FixedParameters [j].ModFlags)
- continue;
- // The modifiers are different, but if one of them
- // is a PARAMS modifier, and the other isn't, ignore
- // the difference.
- if (tm.mods [i][j] != Parameter.Modifier.PARAMS &&
- args.FixedParameters [j].ModFlags != Parameter.Modifier.PARAMS)
- break;
- }
- if (j != arg_len)
- continue;
-
- Type rt = TypeManager.TypeToCoreType (m.ReturnType);
- if (!TypeManager.IsEqual (ret_type, rt) &&
- !(ret_type == null && rt == TypeManager.void_type) &&
- !(rt == null && ret_type == TypeManager.void_type)) {
- tm.found [i] = method;
- continue;
- }
-
if (op != Operation.Lookup) {
// If `t != null', then this is an explicitly interface
// implementation and we can always clear the method.
// interface indexer. In this case, we need to create
// a proxy if the implementation's IndexerName doesn't
// match the IndexerName in the interface.
- if (iType == null && name != mname)
- tm.need_proxy [i] = method.MethodBuilder;
- else
- tm.methods [i] = null;
+ if (iType == null && name.Name != m.Name) { // TODO: This is very expensive comparison
+ tm.need_proxy[i] = method.method.Spec;
+ } else
+ tm.methods[i] = null;
} else {
tm.found [i] = method;
}
/// For that case, we create an explicit implementation function
/// I.M in Y.
/// </summary>
- void DefineProxy (Type iface, MethodInfo base_method, MethodInfo iface_method,
- AParametersCollection param)
+ void DefineProxy (TypeSpec iface, MethodSpec base_method, MethodSpec iface_method)
{
// TODO: Handle nested iface names
- string proxy_name = SimpleName.RemoveGenericArity (iface.FullName) + "." + iface_method.Name;
+ string proxy_name;
+ var ns = iface.MemberDefinition.Namespace;
+ if (string.IsNullOrEmpty (ns))
+ proxy_name = iface.MemberDefinition.Name + "." + iface_method.Name;
+ else
+ proxy_name = ns + "." + iface.MemberDefinition.Name + "." + iface_method.Name;
+
+ var param = iface_method.Parameters;
MethodBuilder proxy = container.TypeBuilder.DefineMethod (
proxy_name,
MethodAttributes.CheckAccessOnOverride |
MethodAttributes.Virtual,
CallingConventions.Standard | CallingConventions.HasThis,
- base_method.ReturnType, param.GetEmitTypes ());
-
- Type[] gargs = TypeManager.GetGenericArguments (iface_method);
- if (gargs.Length > 0) {
- string[] gnames = new string[gargs.Length];
- for (int i = 0; i < gargs.Length; ++i)
- gnames[i] = gargs[i].Name;
+ base_method.ReturnType.GetMetaInfo (), param.GetMetaInfo ());
+ if (iface_method.IsGeneric) {
+ var gnames = iface_method.GenericDefinition.TypeParameters.Select (l => l.Name).ToArray ();
proxy.DefineGenericParameters (gnames);
}
}
int top = param.Count;
- ILGenerator ig = proxy.GetILGenerator ();
+ var ec = new EmitContext (null, proxy.GetILGenerator (), null);
for (int i = 0; i <= top; i++)
- ParameterReference.EmitLdArg (ig, i);
+ ParameterReference.EmitLdArg (ec, i);
- ig.Emit (OpCodes.Call, base_method);
- ig.Emit (OpCodes.Ret);
+ ec.Emit (OpCodes.Call, base_method);
+ ec.Emit (OpCodes.Ret);
- container.TypeBuilder.DefineMethodOverride (proxy, iface_method);
+ container.TypeBuilder.DefineMethodOverride (proxy, (MethodInfo) iface_method.GetMetaInfo ());
}
/// <summary>
/// the given method (which turns out, it is valid to have an interface
/// implementation in a base
/// </summary>
- bool BaseImplements (Type iface_type, MethodInfo mi, out MethodInfo base_method)
+ bool BaseImplements (TypeSpec iface_type, MethodSpec mi, out MethodSpec base_method)
{
- MethodSignature ms;
-
- AParametersCollection param = TypeManager.GetParameterData (mi);
- ms = new MethodSignature (mi.Name, TypeManager.TypeToCoreType (mi.ReturnType), param.Types);
- MemberList list = TypeContainer.FindMembers (
- container.TypeBuilder.BaseType, MemberTypes.Method | MemberTypes.Property,
- BindingFlags.Public | BindingFlags.Instance,
- MethodSignature.method_signature_filter, ms);
-
- if (list.Count == 0) {
- base_method = null;
- return false;
- }
-
- if (TypeManager.ImplementsInterface (container.TypeBuilder.BaseType, iface_type)) {
- base_method = null;
- return true;
- }
+ var base_type = container.BaseType;
+ base_method = (MethodSpec) MemberCache.FindMember (base_type, new MemberFilter (mi), BindingRestriction.None);
- base_method = (MethodInfo) list [0];
+ if (base_method == null || (base_method.Modifiers & Modifiers.PUBLIC) == 0)
+ return false;
if (base_method.DeclaringType.IsInterface)
return false;
- if (!base_method.IsPublic)
- return false;
+ // Why was it here ????
+ //if (TypeManager.ImplementsInterface (base_type, iface_type)) {
+ // return true;
+ //}
if (!base_method.IsAbstract && !base_method.IsVirtual)
// FIXME: We can avoid creating a proxy if base_method can be marked 'final virtual' instead.
// However, it's too late now, the MethodBuilder has already been created (see bug 377519)
- DefineProxy (iface_type, base_method, mi, param);
+ DefineProxy (iface_type, base_method, mi);
return true;
}
int i;
for (i = 0; i < top; i++){
- Type type = pending_implementations [i].type;
+ TypeSpec type = pending_implementations [i].type;
int j = 0;
bool base_implements_type = type.IsInterface &&
- container.TypeBuilder.BaseType != null &&
- TypeManager.ImplementsInterface (container.TypeBuilder.BaseType, type);
+ container.BaseType != null &&
+ container.BaseType.ImplementsInterface (type);
- foreach (MethodInfo mi in pending_implementations [i].methods){
+ foreach (var mi in pending_implementations [i].methods){
if (mi == null)
continue;
if (type.IsInterface){
- MethodInfo need_proxy =
+ var need_proxy =
pending_implementations [i].need_proxy [j];
if (need_proxy != null) {
- DefineProxy (type, need_proxy, mi, TypeManager.GetParameterData (mi));
+ DefineProxy (type, need_proxy, mi);
continue;
}
if (pending_implementations [i].optional)
continue;
- MethodInfo candidate = null;
+ MethodSpec candidate = null;
if (base_implements_type || BaseImplements (type, mi, out candidate))
continue;
if (candidate == null) {
MethodData md = pending_implementations [i].found [j];
if (md != null)
- candidate = md.MethodBuilder;
+ candidate = md.method.Spec;
}
-
+
Report.SymbolRelatedToPreviousError (mi);
if (candidate != null) {
Report.SymbolRelatedToPreviousError (candidate);
if (candidate.IsStatic) {
Report.Error (736, container.Location,
"`{0}' does not implement interface member `{1}' and the best implementing candidate `{2}' is static",
- container.GetSignatureForError (), TypeManager.CSharpSignature (mi, true), TypeManager.CSharpSignature (candidate));
- } else if (!candidate.IsPublic) {
+ container.GetSignatureForError (), mi.GetSignatureForError (), TypeManager.CSharpSignature (candidate));
+ } else if ((candidate.Modifiers & Modifiers.PUBLIC) == 0) {
Report.Error (737, container.Location,
"`{0}' does not implement interface member `{1}' and the best implementing candidate `{2}' in not public",
- container.GetSignatureForError (), TypeManager.CSharpSignature (mi, true), TypeManager.CSharpSignature (candidate, true));
+ container.GetSignatureForError (), mi.GetSignatureForError (), candidate.GetSignatureForError ());
} else {
Report.Error (738, container.Location,
"`{0}' does not implement interface member `{1}' and the best implementing candidate `{2}' return type `{3}' does not match interface member return type `{4}'",
- container.GetSignatureForError (), TypeManager.CSharpSignature (mi, true), TypeManager.CSharpSignature (candidate),
+ container.GetSignatureForError (), mi.GetSignatureForError (), TypeManager.CSharpSignature (candidate),
TypeManager.CSharpName (candidate.ReturnType), TypeManager.CSharpName (mi.ReturnType));
}
} else {
Report.Error (535, container.Location, "`{0}' does not implement interface member `{1}'",
- container.GetSignatureForError (), TypeManager.CSharpSignature (mi, true));
+ container.GetSignatureForError (), mi.GetSignatureForError ());
}
} else {
+ Report.SymbolRelatedToPreviousError (mi);
Report.Error (534, container.Location, "`{0}' does not implement inherited abstract member `{1}'",
- container.GetSignatureForError (), TypeManager.CSharpSignature (mi, true));
+ container.GetSignatureForError (), mi.GetSignatureForError ());
}
errors = true;
j++;
}
return errors;
}
- } /* end of class */
+ }
}
if (!base.VerifyClsCompliance ())
return false;
- if (!AttributeTester.IsClsCompliant (MemberType)) {
+ if (!MemberType.IsCLSCompliant ()) {
Report.Warning (3003, 1, Location, "Type of `{0}' is not CLS-compliant",
GetSignatureForError ());
}
}
}
- public class PropertySpec : MemberSpec
+ public class PropertySpec : MemberSpec, IInterfaceMemberSpec
{
PropertyInfo info;
+ TypeSpec memberType;
+ MethodSpec set, get;
- public PropertySpec (MemberKind kind, IMemberDefinition definition, PropertyInfo info, Modifiers modifiers)
- : base (kind, definition, info.Name, modifiers)
+ public PropertySpec (MemberKind kind, TypeSpec declaringType, IMemberDefinition definition, TypeSpec memberType, PropertyInfo info, Modifiers modifiers)
+ : base (kind, declaringType, definition, modifiers)
{
this.info = info;
+ this.memberType = memberType;
}
- public override Type DeclaringType {
- get { return info.DeclaringType; }
+ #region Properties
+
+ public MethodSpec Get {
+ get {
+ return get;
+ }
+ set {
+ get = value;
+ get.IsAccessor = true;
+ }
+ }
+
+ public MethodSpec Set {
+ get {
+ return set;
+ }
+ set {
+ set = value;
+ set.IsAccessor = true;
+ }
+ }
+
+ public bool IsNotRealProperty {
+ get {
+ return (state & StateFlags.IsNotRealProperty) != 0;
+ }
+ set {
+ state |= StateFlags.IsNotRealProperty;
+ }
+ }
+
+ public bool HasDifferentAccessibility {
+ get {
+ return HasGet && HasSet &&
+ (Get.Modifiers & Modifiers.AccessibilityMask) != (Set.Modifiers & Modifiers.AccessibilityMask);
+ }
+ }
+
+ public bool HasGet {
+ get {
+ return Get != null && Get.Kind != MemberKind.FakeMethod;
+ }
+ }
+
+ public bool HasSet {
+ get {
+ return Set != null && Set.Kind != MemberKind.FakeMethod;
+ }
}
public PropertyInfo MetaInfo {
- get { return info; }
+ get {
+ if ((state & StateFlags.PendingMetaInflate) != 0)
+ throw new NotSupportedException ();
+
+ return info;
+ }
}
- public Type PropertyType {
- get { return info.PropertyType; }
+ public TypeSpec MemberType {
+ get {
+ return memberType;
+ }
+ }
+
+ #endregion
+
+ public override MemberSpec InflateMember (TypeParameterInflator inflator)
+ {
+ var ps = (PropertySpec) base.InflateMember (inflator);
+ ps.memberType = inflator.Inflate (memberType);
+ return ps;
}
}
{
base.Define (parent);
+ Spec = new MethodSpec (IsDummy ? MemberKind.FakeMethod : MemberKind.Method, parent.PartialContainer.Definition, this, ReturnType, null, ParameterInfo, ModFlags);
+
if (IsDummy)
return null;
if (!method_data.Define (parent, method.GetFullName (MemberName), Report))
return null;
- Spec = new MethodSpec (MemberKind.Method, this, method_data.MethodBuilder, ParameterInfo, ModFlags);
+ Spec.SetMetaInfo (method_data.MethodBuilder);
return method_data.MethodBuilder;
}
- public override Type ReturnType {
+ public override TypeSpec ReturnType {
get {
return method.MemberType;
}
base (method, "set_")
{
parameters = new ParametersCompiled (Compiler,
- new Parameter (method.type_name, "value", Parameter.Modifier.NONE, null, Location));
+ new Parameter (method.type_expr, "value", Parameter.Modifier.NONE, null, Location));
}
public SetMethod (PropertyBase method, Accessor accessor):
this.parameters = accessor.Parameters;
}
- protected override void ApplyToExtraTarget (Attribute a, ConstructorInfo ctor, byte[] cdata, PredefinedAttributes pa)
+ protected override void ApplyToExtraTarget (Attribute a, MethodSpec ctor, byte[] cdata, PredefinedAttributes pa)
{
if (a.Target == AttributeTargets.Parameter) {
if (param_attr == null)
base.Define (parent);
+ Spec = new MethodSpec (IsDummy ? MemberKind.FakeMethod : MemberKind.Method, parent.PartialContainer.Definition, this, ReturnType, null, ParameterInfo, ModFlags);
+
if (IsDummy)
return null;
if (!method_data.Define (parent, method.GetFullName (MemberName), Report))
return null;
- Spec = new MethodSpec (MemberKind.Method, this, method_data.MethodBuilder, ParameterInfo, ModFlags);
+ Spec.SetMetaInfo (method_data.MethodBuilder);
return method_data.MethodBuilder;
}
- public override Type ReturnType {
+ public override TypeSpec ReturnType {
get {
return TypeManager.void_type;
}
}
}
- public override void ApplyAttributeBuilder (Attribute a, ConstructorInfo ctor, byte[] cdata, PredefinedAttributes pa)
+ public override void ApplyAttributeBuilder (Attribute a, MethodSpec ctor, byte[] cdata, PredefinedAttributes pa)
{
if (a.IsInternalMethodImplAttribute) {
method.is_external_implementation = true;
if (IsDummy) {
if (method.InterfaceType != null && parent.PartialContainer.PendingImplementations != null) {
- MethodInfo mi = parent.PartialContainer.PendingImplementations.IsInterfaceMethod (
- MethodName.Name, method.InterfaceType, new MethodData (method, ModFlags, flags, this));
+ var mi = parent.PartialContainer.PendingImplementations.IsInterfaceMethod (
+ MethodName, method.InterfaceType, new MethodData (method, ModFlags, flags, this));
if (mi != null) {
Report.SymbolRelatedToPreviousError (mi);
Report.Error (551, Location, "Explicit interface implementation `{0}' is missing accessor `{1}'",
- method.GetSignatureForError (), TypeManager.CSharpSignature (mi, true));
+ method.GetSignatureForError (), mi.GetSignatureForError ());
}
}
return null;
}
}
- public override ObsoleteAttribute GetObsoleteAttribute ()
+ public override ObsoleteAttribute GetAttributeObsolete ()
{
- return method.GetObsoleteAttribute ();
+ return method.GetAttributeObsolete ();
}
public override string GetSignatureForError()
{
- return method.GetSignatureForError () + '.' + prefix.Substring (0, 3);
+ return method.GetSignatureForError () + "." + prefix.Substring (0, 3);
}
void CheckModifiers (Modifiers modflags)
{
- modflags &= Modifiers.AccessibilityMask;
- Modifiers flags = 0;
- Modifiers mflags = method.ModFlags & Modifiers.AccessibilityMask;
-
- if ((mflags & Modifiers.PUBLIC) != 0) {
- flags |= Modifiers.PROTECTED | Modifiers.INTERNAL | Modifiers.PRIVATE;
- }
- else if ((mflags & Modifiers.PROTECTED) != 0) {
- if ((mflags & Modifiers.INTERNAL) != 0)
- flags |= Modifiers.PROTECTED | Modifiers.INTERNAL;
-
- flags |= Modifiers.PRIVATE;
- } else if ((mflags & Modifiers.INTERNAL) != 0)
- flags |= Modifiers.PRIVATE;
-
- if ((mflags == modflags) || (modflags & (~flags)) != 0) {
+ if (!ModifiersExtensions.IsRestrictedModifier (modflags & Modifiers.AccessibilityMask, method.ModFlags & Modifiers.AccessibilityMask)) {
Report.Error (273, Location,
"The accessibility modifier of the `{0}' accessor must be more restrictive than the modifier of the property or indexer `{1}'",
GetSignatureForError (), method.GetSignatureForError ());
if ((caching_flags & Flags.MethodOverloadsExist) == 0)
return true;
- return Parent.MemberCache.CheckExistingMembersOverloads (this, Name, ParameterInfo, Report);
+ return Parent.MemberCache.CheckExistingMembersOverloads (this, ParameterInfo);
}
}
this.define_set_first = define_set_first;
}
- public override void ApplyAttributeBuilder (Attribute a, ConstructorInfo ctor, byte[] cdata, PredefinedAttributes pa)
+ public override void ApplyAttributeBuilder (Attribute a, MethodSpec ctor, byte[] cdata, PredefinedAttributes pa)
{
if (a.HasSecurityAttribute) {
a.Error_InvalidSecurityParent ();
return;
}
- PropertyBuilder.SetCustomAttribute (ctor, cdata);
+ PropertyBuilder.SetCustomAttribute ((ConstructorInfo) ctor.GetMetaInfo (), cdata);
}
public override AttributeTargets AttributeTargets {
}
}
+ protected override bool CheckOverrideAgainstBase (MemberSpec base_member)
+ {
+ var ok = base.CheckOverrideAgainstBase (base_member);
+
+ //
+ // Check base property accessors conflict
+ //
+ var base_prop = (PropertySpec) base_member;
+ if (!Get.IsDummy) {
+ if (!base_prop.HasGet) {
+ Report.SymbolRelatedToPreviousError (base_prop);
+ Report.Error (545, Get.Location,
+ "`{0}': cannot override because `{1}' does not have an overridable get accessor",
+ Get.GetSignatureForError (), base_prop.GetSignatureForError ());
+ ok = false;
+ } else if (Get.HasCustomAccessModifier || base_prop.HasDifferentAccessibility) {
+ if (!CheckAccessModifiers (Get, base_prop.Get)) {
+ Error_CannotChangeAccessModifiers (Get, base_prop.Get);
+ ok = false;
+ }
+ }
+ }
+
+ if (!Set.IsDummy) {
+ if (!base_prop.HasSet) {
+ Report.SymbolRelatedToPreviousError (base_prop);
+ Report.Error (546, Set.Location,
+ "`{0}': cannot override because `{1}' does not have an overridable set accessor",
+ Set.GetSignatureForError (), base_prop.GetSignatureForError ());
+ ok = false;
+ } else if (Set.HasCustomAccessModifier || base_prop.HasDifferentAccessibility) {
+ if (!CheckAccessModifiers (Set, base_prop.Set)) {
+ Error_CannotChangeAccessModifiers (Set, base_prop.Set);
+ ok = false;
+ }
+ }
+ }
+
+ if (!Set.HasCustomAccessModifier && !Get.HasCustomAccessModifier) {
+ if (!CheckAccessModifiers (this, base_prop)) {
+ Error_CannotChangeAccessModifiers (this, base_prop);
+ ok = false;
+ }
+ }
+
+ return ok;
+ }
+
protected override void DoMemberTypeDependentChecks ()
{
base.DoMemberTypeDependentChecks ();
IsTypePermitted ();
-#if MS_COMPATIBLE
- if (MemberType.IsGenericParameter)
- return;
-#endif
- if ((MemberType.Attributes & Class.StaticClassAttribute) == Class.StaticClassAttribute) {
- Report.Error (722, Location, Error722, TypeManager.CSharpName (MemberType));
- }
+ if (MemberType.IsStatic)
+ Error_StaticReturnType ();
}
protected override void DoMemberTypeIndependentChecks ()
DefineSet (!define_set_first);
}
- protected void DefineBuilders (MemberKind kind, Type[] parameterTypes)
+ protected void DefineBuilders (MemberKind kind, ParametersCompiled parameters)
{
// FIXME - PropertyAttributes.HasDefault ?
PropertyBuilder = Parent.TypeBuilder.DefineProperty (
- GetFullName (MemberName), PropertyAttributes.None, MemberType, parameterTypes);
+ GetFullName (MemberName), PropertyAttributes.None, MemberType.GetMetaInfo (), parameters.GetMetaInfo ());
+
+ PropertySpec spec;
+ if (kind == MemberKind.Indexer)
+ spec = new IndexerSpec (Parent.Definition, this, MemberType, parameters, PropertyBuilder, ModFlags);
+ else
+ spec = new PropertySpec (kind, Parent.Definition, this, MemberType, PropertyBuilder, ModFlags);
+
+ spec.Get = Get.Spec;
+ spec.Set = Set.Spec;
if (!Get.IsDummy) {
PropertyBuilder.SetGetMethod (GetBuilder);
- Parent.MemberCache.AddMember (GetBuilder, Get.Spec);
}
if (!Set.IsDummy) {
PropertyBuilder.SetSetMethod (SetBuilder);
- Parent.MemberCache.AddMember (SetBuilder, Set.Spec);
}
- var spec = new PropertySpec (kind, this, PropertyBuilder, ModFlags);
- Parent.MemberCache.AddMember (PropertyBuilder, spec);
- }
-
- protected abstract PropertyInfo ResolveBaseProperty ();
-
- // TODO: rename to Resolve......
- protected override MethodInfo FindOutBaseMethod (ref Type base_ret_type)
- {
- PropertyInfo base_property = ResolveBaseProperty ();
- if (base_property == null)
- return null;
-
- base_ret_type = base_property.PropertyType;
- MethodInfo get_accessor = base_property.GetGetMethod (true);
- MethodInfo set_accessor = base_property.GetSetMethod (true);
- MethodAttributes get_accessor_access = 0, set_accessor_access = 0;
-
- //
- // Check base property accessors conflict
- //
- if ((ModFlags & (Modifiers.OVERRIDE | Modifiers.NEW)) == Modifiers.OVERRIDE) {
- if (get_accessor == null) {
- if (Get != null && !Get.IsDummy) {
- Report.SymbolRelatedToPreviousError (base_property);
- Report.Error (545, Location,
- "`{0}.get': cannot override because `{1}' does not have an overridable get accessor",
- GetSignatureForError (), TypeManager.GetFullNameSignature (base_property));
- }
- } else {
- get_accessor_access = get_accessor.Attributes & MethodAttributes.MemberAccessMask;
-
- if (!Get.IsDummy && !CheckAccessModifiers (
- ModifiersExtensions.MethodAttr (Get.ModFlags) & MethodAttributes.MemberAccessMask, get_accessor_access, get_accessor))
- Error_CannotChangeAccessModifiers (Get.Location, get_accessor, get_accessor_access, ".get");
- }
-
- if (set_accessor == null) {
- if (Set != null && !Set.IsDummy) {
- Report.SymbolRelatedToPreviousError (base_property);
- Report.Error (546, Location,
- "`{0}.set': cannot override because `{1}' does not have an overridable set accessor",
- GetSignatureForError (), TypeManager.GetFullNameSignature (base_property));
- }
- } else {
- set_accessor_access = set_accessor.Attributes & MethodAttributes.MemberAccessMask;
-
- if (!Set.IsDummy && !CheckAccessModifiers (
- ModifiersExtensions.MethodAttr (Set.ModFlags) & MethodAttributes.MemberAccessMask, set_accessor_access, set_accessor))
- Error_CannotChangeAccessModifiers (Set.Location, set_accessor, set_accessor_access, ".set");
- }
- }
-
- // When one accessor does not exist and property hides base one
- // we need to propagate this upwards
- if (set_accessor == null)
- set_accessor = get_accessor;
-
- //
- // Get the less restrictive access
- //
- return get_accessor_access > set_accessor_access ? get_accessor : set_accessor;
+ Parent.MemberCache.AddMember (this, Get.IsDummy ? Get.Name : GetBuilder.Name, Get.Spec);
+ Parent.MemberCache.AddMember (this, Set.IsDummy ? Set.Name : SetBuilder.Name, Set.Spec);
+ Parent.MemberCache.AddMember (this, PropertyBuilder.Name, spec);
}
public override void Emit ()
if (OptAttributes != null)
OptAttributes.Emit ();
- if (TypeManager.IsDynamicType (member_type)) {
+ if (member_type == InternalType.Dynamic) {
PredefinedAttributes.Get.Dynamic.EmitAttribute (PropertyBuilder);
} else {
var trans_flags = TypeManager.HasDynamicTypeUsed (member_type);
if (trans_flags != null) {
var pa = PredefinedAttributes.Get.DynamicTransform;
- if (pa.Constructor != null || pa.ResolveConstructor (Location, TypeManager.bool_type.MakeArrayType ())) {
+ if (pa.Constructor != null || pa.ResolveConstructor (Location, ArrayContainer.MakeType (TypeManager.bool_type))) {
PropertyBuilder.SetCustomAttribute (
new CustomAttributeBuilder (pa.Constructor, new object [] { trans_flags }));
}
return Get.IsDuplicateImplementation (mc) || Set.IsDuplicateImplementation (mc);
}
- public override bool IsUsed
- {
+ public override bool IsUsed {
get {
if (IsExplicitImpl)
return true;
readonly Property property;
public BackingField (Property p)
- : base (p.Parent, p.type_name,
+ : base (p.Parent, p.type_expr,
Modifiers.BACKING_FIELD | Modifiers.COMPILER_GENERATED | Modifiers.PRIVATE | (p.ModFlags & (Modifiers.STATIC | Modifiers.UNSAFE)),
new MemberName ("<" + p.GetFullName (p.MemberName) + ">k__BackingField", p.Location), null)
{
this.property = p;
}
+ public string OriginalName {
+ get {
+ return property.Name;
+ }
+ }
+
public override string GetSignatureForError ()
{
return property.GetSignatureForError ();
if (!CheckBase ())
return false;
- DefineBuilders (MemberKind.Property, null);
- TypeManager.RegisterProperty (PropertyBuilder, this);
+ DefineBuilders (MemberKind.Property, ParametersCompiled.EmptyReadOnlyParameters);
return true;
}
base.Emit ();
}
-
- protected override PropertyInfo ResolveBaseProperty ()
- {
- return Parent.PartialContainer.BaseCache.FindMemberToOverride (
- Parent.TypeBuilder, Name, ParametersCompiled.EmptyReadOnlyParameters, null, true) as PropertyInfo;
- }
}
- /// </summary>
- /// Gigantic workaround for lameness in SRE follows :
- /// This class derives from EventInfo and attempts to basically
- /// wrap around the EventBuilder so that FindMembers can quickly
- /// return this in it search for members
- /// </summary>
- public class MyEventBuilder : EventInfo {
-
- //
- // We use this to "point" to our Builder which is
- // not really a MemberInfo
- //
- EventBuilder MyBuilder;
-
- //
- // We "catch" and wrap these methods
- //
- MethodInfo raise, remove, add;
-
- EventAttributes attributes;
- Type declaring_type, reflected_type, event_type;
- string name;
-
- Event my_event;
-
- public MyEventBuilder (Event ev, TypeBuilder type_builder, string name, EventAttributes event_attr, Type event_type)
- {
- MyBuilder = type_builder.DefineEvent (name, event_attr, event_type);
-
- // And now store the values in our own fields.
-
- declaring_type = type_builder;
-
- reflected_type = type_builder;
-
- attributes = event_attr;
- this.name = name;
- my_event = ev;
- this.event_type = event_type;
- }
-
- //
- // Methods that you have to override. Note that you only need
- // to "implement" the variants that take the argument (those are
- // the "abstract" methods, the others (GetAddMethod()) are
- // regular.
- //
- public override MethodInfo GetAddMethod (bool nonPublic)
- {
- return add;
- }
-
- public override MethodInfo GetRemoveMethod (bool nonPublic)
- {
- return remove;
- }
-
- public override MethodInfo GetRaiseMethod (bool nonPublic)
- {
- return raise;
- }
-
- //
- // These methods make "MyEventInfo" look like a Builder
- //
- public void SetRaiseMethod (MethodBuilder raiseMethod)
- {
- raise = raiseMethod;
- MyBuilder.SetRaiseMethod (raiseMethod);
- }
-
- public void SetRemoveOnMethod (MethodBuilder removeMethod)
- {
- remove = removeMethod;
- MyBuilder.SetRemoveOnMethod (removeMethod);
- }
-
- public void SetAddOnMethod (MethodBuilder addMethod)
- {
- add = addMethod;
- MyBuilder.SetAddOnMethod (addMethod);
- }
-
- public void SetCustomAttribute (ConstructorInfo ctor, byte[] cdata)
- {
- MyBuilder.SetCustomAttribute (ctor, cdata);
- }
-
- public override object [] GetCustomAttributes (bool inherit)
- {
- // FIXME : There's nothing which can be seemingly done here because
- // we have no way of getting at the custom attribute objects of the
- // EventBuilder !
- return null;
- }
-
- public override object [] GetCustomAttributes (Type t, bool inherit)
- {
- // FIXME : Same here !
- return null;
- }
-
- public override bool IsDefined (Type t, bool b)
- {
- return true;
- }
-
- public override EventAttributes Attributes {
- get {
- return attributes;
- }
- }
-
- public override string Name {
- get {
- return name;
- }
- }
-
- public override Type DeclaringType {
- get {
- return declaring_type;
- }
- }
-
- public override Type ReflectedType {
- get {
- return reflected_type;
- }
- }
-
- public Type EventType {
- get {
- return event_type;
- }
- }
-
- public void SetUsed ()
- {
- if (my_event != null) {
-// my_event.SetAssigned ();
- my_event.SetIsUsed ();
- }
- }
- }
-
/// <summary>
/// For case when event is declared like property (with add and remove accessors).
/// </summary>
}
- static readonly string[] attribute_targets = new string [] { "event" }; // "property" target was disabled for 2.0 version
+ static readonly string[] attribute_targets = new string [] { "event" };
public EventProperty (DeclSpace parent, FullNamedExpression type, Modifiers mod_flags,
MemberName name,
var field_info = ((EventField) method).BackingField;
FieldExpr f_expr = new FieldExpr (field_info, Location);
if ((method.ModFlags & Modifiers.STATIC) == 0)
- f_expr.InstanceExpression = new CompilerGeneratedThis (field_info.Spec.FieldType, Location);
+ f_expr.InstanceExpression = new CompilerGeneratedThis (field_info.Spec.MemberType, Location);
block = new ToplevelBlock (Compiler, ParameterInfo, Location);
block.AddStatement (new StatementExpression (
Remove = new RemoveDelegateMethod (this);
}
- public override void ApplyAttributeBuilder (Attribute a, ConstructorInfo ctor, byte[] cdata, PredefinedAttributes pa)
+ public override void ApplyAttributeBuilder (Attribute a, MethodSpec ctor, byte[] cdata, PredefinedAttributes pa)
{
if (a.Target == AttributeTargets.Field) {
BackingField.ApplyAttributeBuilder (a, ctor, cdata, pa);
get { return method_data.implementing != null; }
}
- public override void ApplyAttributeBuilder (Attribute a, ConstructorInfo ctor, byte[] cdata, PredefinedAttributes pa)
+ public override void ApplyAttributeBuilder (Attribute a, MethodSpec ctor, byte[] cdata, PredefinedAttributes pa)
{
if (a.IsInternalMethodImplAttribute) {
method.is_external_implementation = true;
base.ApplyAttributeBuilder (a, ctor, cdata, pa);
}
- protected override void ApplyToExtraTarget (Attribute a, ConstructorInfo ctor, byte[] cdata, PredefinedAttributes pa)
+ protected override void ApplyToExtraTarget (Attribute a, MethodSpec ctor, byte[] cdata, PredefinedAttributes pa)
{
if (a.Target == AttributeTargets.Parameter) {
if (param_attr == null)
MethodBuilder mb = method_data.MethodBuilder;
ParameterInfo.ApplyAttributes (mb);
- Spec = new MethodSpec (MemberKind.Method, this, mb, ParameterInfo, method.ModFlags);
+ Spec = new MethodSpec (MemberKind.Method, parent.PartialContainer.Definition, this, ReturnType, mb, ParameterInfo, method.ModFlags);
+ Spec.IsAccessor = true;
return mb;
}
- public override Type ReturnType {
+ public override TypeSpec ReturnType {
get {
return TypeManager.void_type;
}
}
- public override ObsoleteAttribute GetObsoleteAttribute ()
+ public override ObsoleteAttribute GetAttributeObsolete ()
{
- return method.GetObsoleteAttribute ();
+ return method.GetAttributeObsolete ();
}
public override string[] ValidAttributeTargets {
Modifiers.NEW;
public AEventAccessor Add, Remove;
- public MyEventBuilder EventBuilder;
+ public EventBuilder EventBuilder;
public MethodBuilder AddBuilder, RemoveBuilder;
ParametersCompiled parameters;
{
}
- public override void ApplyAttributeBuilder (Attribute a, ConstructorInfo ctor, byte[] cdata, PredefinedAttributes pa)
+ public override void ApplyAttributeBuilder (Attribute a, MethodSpec ctor, byte[] cdata, PredefinedAttributes pa)
{
if ((a.HasSecurityAttribute)) {
a.Error_InvalidSecurityParent ();
return;
}
-
- EventBuilder.SetCustomAttribute (ctor, cdata);
+
+ EventBuilder.SetCustomAttribute ((ConstructorInfo) ctor.GetMetaInfo (), cdata);
}
public bool AreAccessorsDuplicateImplementation (MethodCore mc)
}
}
+ protected override bool CheckOverrideAgainstBase (MemberSpec base_member)
+ {
+ var ok = base.CheckOverrideAgainstBase (base_member);
+
+ if (!CheckAccessModifiers (this, base_member)) {
+ Error_CannotChangeAccessModifiers (this, base_member);
+ ok = false;
+ }
+
+ return ok;
+ }
+
public override bool Define ()
{
if (!base.Define ())
if (!CheckBase ())
return false;
- if (TypeManager.delegate_combine_delegate_delegate == null) {
- TypeManager.delegate_combine_delegate_delegate = TypeManager.GetPredefinedMethod (
- TypeManager.delegate_type, "Combine", Location,
- TypeManager.delegate_type, TypeManager.delegate_type);
- }
- if (TypeManager.delegate_remove_delegate_delegate == null) {
- TypeManager.delegate_remove_delegate_delegate = TypeManager.GetPredefinedMethod (
- TypeManager.delegate_type, "Remove", Location,
- TypeManager.delegate_type, TypeManager.delegate_type);
- }
-
//
// Now define the accessors
//
-
AddBuilder = Add.Define (Parent);
if (AddBuilder == null)
return false;
if (RemoveBuilder == null)
return false;
- EventBuilder = new MyEventBuilder (this, Parent.TypeBuilder, Name, EventAttributes.None, MemberType);
+ EventBuilder = Parent.TypeBuilder.DefineEvent (Name, EventAttributes.None, MemberType.GetMetaInfo ());
EventBuilder.SetAddOnMethod (AddBuilder);
EventBuilder.SetRemoveOnMethod (RemoveBuilder);
- var spec = new EventSpec (this, EventBuilder, ModFlags, Add.Spec, Remove.Spec) {
- EventType = MemberType
- };
+ var spec = new EventSpec (Parent.Definition, this, MemberType, ModFlags, Add.Spec, Remove.Spec);
- TypeManager.RegisterEventField (EventBuilder, spec);
+ Parent.MemberCache.AddMember (this, Name, spec);
+ Parent.MemberCache.AddMember (this, AddBuilder.Name, Add.Spec);
+ Parent.MemberCache.AddMember (this, RemoveBuilder.Name, Remove.Spec);
- Parent.MemberCache.AddMember (EventBuilder, spec);
- Parent.MemberCache.AddMember (AddBuilder, Add.Spec);
- Parent.MemberCache.AddMember (RemoveBuilder, Remove.Spec);
-
return true;
}
base.Emit ();
}
- protected override MethodInfo FindOutBaseMethod (ref Type base_ret_type)
- {
- MethodInfo mi = (MethodInfo) Parent.PartialContainer.BaseCache.FindBaseEvent (
- Parent.TypeBuilder, Name);
-
- if (mi == null)
- return null;
-
- AParametersCollection pd = TypeManager.GetParameterData (mi);
- base_ret_type = pd.Types [0];
- return mi;
- }
-
//
// Represents header string for documentation comment.
//
}
}
- public class EventSpec : MemberSpec
+ public class EventSpec : MemberSpec, IInterfaceMemberSpec
{
- EventInfo info;
+ MethodSpec add, remove;
- public EventSpec (IMemberDefinition definition, EventInfo info, Modifiers modifiers, MethodSpec add, MethodSpec remove)
- : base (MemberKind.Event, definition, info.Name, modifiers)
+ public EventSpec (TypeSpec declaringType, IMemberDefinition definition, TypeSpec eventType, Modifiers modifiers, MethodSpec add, MethodSpec remove)
+ : base (MemberKind.Event, declaringType, definition, modifiers)
{
- this.info = info;
this.AccessorAdd = add;
this.AccessorRemove = remove;
-
- // TODO MemberCache: Remove
- if (TypeManager.IsBeingCompiled (info))
- state &= ~MemberSpec.StateFlags.Obsolete_Undetected;
+ this.MemberType = eventType;
}
- public MethodSpec AccessorAdd { get; private set; }
- public MethodSpec AccessorRemove { get; private set; }
+ #region Properties
- public override Type DeclaringType {
- get { return info.DeclaringType; }
+ public MethodSpec AccessorAdd {
+ get {
+ return add;
+ }
+ set {
+ add = value;
+ }
}
- public Type EventType { get; set; }
-
- public bool IsAbstract {
- get { return (Modifiers & Modifiers.ABSTRACT) != 0; }
+ public MethodSpec AccessorRemove {
+ get {
+ return remove;
+ }
+ set {
+ remove = value;
+ }
}
- public EventInfo MetaInfo {
- get { return info; }
+ public TypeSpec MemberType { get; private set; }
+
+ #endregion
+
+ public override MemberSpec InflateMember (TypeParameterInflator inflator)
+ {
+ var es = (EventSpec) base.InflateMember (inflator);
+ es.MemberType = inflator.Inflate (MemberType);
+ return es;
}
}
- public class Indexer : PropertyBase
+ public class Indexer : PropertyBase, IParametersMember
{
public class GetIndexerMethod : GetMethod
{
const Modifiers AllowedInterfaceModifiers =
Modifiers.NEW;
- public readonly ParametersCompiled parameters;
+ readonly ParametersCompiled parameters;
public Indexer (DeclSpace parent, FullNamedExpression type, MemberName name, Modifiers mod,
ParametersCompiled parameters, Attributes attrs,
Set = new SetIndexerMethod (this, set_block);
}
- public override void ApplyAttributeBuilder (Attribute a, ConstructorInfo ctor, byte[] cdata, PredefinedAttributes pa)
+ public override void ApplyAttributeBuilder (Attribute a, MethodSpec ctor, byte[] cdata, PredefinedAttributes pa)
{
if (a.Type == pa.IndexerName) {
if (IsExplicitImpl) {
protected override bool CheckForDuplications ()
{
- return Parent.MemberCache.CheckExistingMembersOverloads (this, GetFullName (MemberName), parameters, Report);
+ return Parent.MemberCache.CheckExistingMembersOverloads (this, parameters);
}
public override bool Define ()
if (OptAttributes != null) {
Attribute indexer_attr = OptAttributes.Search (PredefinedAttributes.Get.IndexerName);
if (indexer_attr != null) {
+ var compiling = indexer_attr.Type.MemberDefinition as TypeContainer;
+ if (compiling != null)
+ compiling.Define ();
+
string name = indexer_attr.GetIndexerAttributeValue ();
if ((ModFlags & Modifiers.OVERRIDE) != 0) {
Report.Error (609, indexer_attr.Location,
}
if (InterfaceType != null) {
- string base_IndexerName = TypeManager.IndexerPropertyName (InterfaceType);
+ string base_IndexerName = InterfaceType.MemberDefinition.GetAttributeDefaultMember ();
if (base_IndexerName != Name)
ShortName = base_IndexerName;
}
if (!CheckBase ())
return false;
- DefineBuilders (MemberKind.Indexer, parameters.GetEmitTypes ());
- TypeManager.RegisterIndexer (PropertyBuilder, parameters);
+ DefineBuilders (MemberKind.Indexer, parameters);
return true;
}
return sb.ToString ();
}
- protected override PropertyInfo ResolveBaseProperty ()
- {
- return Parent.PartialContainer.BaseCache.FindMemberToOverride (
- Parent.TypeBuilder, Name, parameters, null, true) as PropertyInfo;
+ public AParametersCollection Parameters {
+ get {
+ return parameters;
+ }
+ }
+
+ public ParametersCompiled ParameterInfo {
+ get {
+ return parameters;
+ }
}
protected override bool VerifyClsCompliance ()
return true;
}
}
+
+ public class IndexerSpec : PropertySpec, IParametersMember
+ {
+ AParametersCollection parameters;
+
+ public IndexerSpec (TypeSpec declaringType, IMemberDefinition definition, TypeSpec memberType, AParametersCollection parameters, PropertyInfo info, Modifiers modifiers)
+ : base (MemberKind.Indexer, declaringType, definition, memberType, info, modifiers)
+ {
+ this.parameters = parameters;
+ }
+
+ public override string GetSignatureForError ()
+ {
+ return DeclaringType.GetSignatureForError () + ".this" + parameters.GetSignatureForError ("[", "]", parameters.Count);
+ }
+
+ public AParametersCollection Parameters {
+ get {
+ return parameters;
+ }
+ }
+ }
}
SymbolRelatedToPreviousError (loc.ToString (), symbol);
}
- public void SymbolRelatedToPreviousError (MemberInfo mi)
+ public void SymbolRelatedToPreviousError (MemberSpec ms)
{
if (reporting_disabled > 0 || !printer.HasRelatedSymbolSupport)
return;
- Type dt = TypeManager.DropGenericTypeArguments (mi.DeclaringType);
- if (TypeManager.IsDelegateType (dt)) {
- SymbolRelatedToPreviousError (dt);
- return;
- }
-
- DeclSpace temp_ds = TypeManager.LookupDeclSpace (dt);
- if (temp_ds == null) {
- SymbolRelatedToPreviousError (dt.Assembly.Location, TypeManager.GetFullNameSignature (mi));
+ var mc = ms.MemberDefinition as MemberCore;
+ if (mc != null) {
+ SymbolRelatedToPreviousError (mc);
} else {
- MethodBase mb = mi as MethodBase;
- if (mb != null) {
- mb = TypeManager.DropGenericMethodArguments (mb);
- IMethodData md = TypeManager.GetMethod (mb);
- if (md != null)
- SymbolRelatedToPreviousError (md.Location, md.GetSignatureForError ());
-
- return;
- }
-
- // FIXME: Completely wrong, it has to use FindMembers
- MemberCore mc = temp_ds.GetDefinition (mi.Name);
- if (mc != null)
- SymbolRelatedToPreviousError (mc);
+ var im = ms.MemberDefinition as ImportedMemberDefinition;
+ SymbolRelatedToPreviousError (im.Assembly.Location, "");
}
}
SymbolRelatedToPreviousError (mc.Location, mc.GetSignatureForError ());
}
- public void SymbolRelatedToPreviousError (Type type)
- {
- if (reporting_disabled > 0 || !printer.HasRelatedSymbolSupport)
- return;
-
- type = TypeManager.DropGenericTypeArguments (type);
-
- if (TypeManager.IsGenericParameter (type)) {
- TypeParameter tp = TypeManager.LookupTypeParameter (type);
- if (tp != null) {
- SymbolRelatedToPreviousError (tp.Location, "");
- return;
- }
- }
-
- if (type is TypeBuilder) {
- DeclSpace temp_ds = TypeManager.LookupDeclSpace (type);
- SymbolRelatedToPreviousError (temp_ds.Location, TypeManager.CSharpName (type));
- } else if (TypeManager.HasElementType (type)) {
- SymbolRelatedToPreviousError (TypeManager.GetElementType (type));
- } else {
- SymbolRelatedToPreviousError (type.Assembly.Location, TypeManager.CSharpName (type));
- }
- }
-
void SymbolRelatedToPreviousError (string loc, string symbol)
{
string msg = String.Format ("{0} (Location of the symbol related to previous ", loc);
Error (code, loc, String.Format (format, arg1, arg2));
}
- public void Error (int code, Location loc, string format, params object[] args)
+ public void Error (int code, Location loc, string format, params string[] args)
{
Error (code, loc, String.Format (format, args));
}
if (!first)
sb.Append (", ");
first = false;
-
- sb.Append (TypeManager.CSharpName (pi.ParameterType));
+
+ sb.Append (pi.ParameterType.FullName);
}
sb.Append (")\n");
}
//
static List<string> AllDefines;
- //
- // This keeps track of the order in which classes were defined
- // so that we can poulate them in that order.
- //
- // Order is important, because we need to be able to tell, by
- // examining the list of methods of the base class, which ones are virtual
- // or abstract as well as the parent names (to implement new,
- // override).
- //
- static List<TypeContainer> type_container_resolve_order;
-
//
// Holds a reference to the Private Implementation Details
// class.
static TypeBuilder impl_details_class;
+ public static List<Enum> hack_corlib_enums = new List<Enum> ();
+
//
// Constructor
//
public static void Reset (bool full)
{
- if (full)
- root = null;
+ impl_details_class = null;
+ helper_classes = null;
+
+ if (!full)
+ return;
- type_container_resolve_order = new List<TypeContainer> ();
EntryPoint = null;
Checked = false;
Unsafe = false;
set { root = value; }
}
- public static void RegisterOrder (TypeContainer tc)
- {
- type_container_resolve_order.Add (tc);
- }
-
// <remarks>
// This function is used to resolve the hierarchy tree.
// It processes interfaces, structs and classes in that order.
foreach (TypeContainer tc in root.Types)
tc.DefineType ();
+ }
+
+ static void HackCorlib ()
+ {
+ if (StdLib)
+ return;
+
+ //
+ // HACK: When building corlib mcs uses loaded mscorlib which
+ // has different predefined types and this method sets mscorlib types
+ // to be same to avoid type check errors in CreateType.
+ //
+ var type = typeof (Type);
+ var system_4_type_arg = new[] { type, type, type, type };
+
+ MethodInfo set_corlib_type_builders =
+ typeof (System.Reflection.Emit.AssemblyBuilder).GetMethod (
+ "SetCorlibTypeBuilders", BindingFlags.NonPublic | BindingFlags.Instance, null,
+ system_4_type_arg, null);
+
+ if (set_corlib_type_builders == null) {
+ root.Compiler.Report.Warning (-26, 3, "The compilation may fail due to missing `{0}.SetCorlibTypeBuilders(...)' method",
+ typeof (System.Reflection.Emit.AssemblyBuilder).FullName);
+ return;
+ }
- if (root.Delegates != null)
- foreach (Delegate d in root.Delegates)
- d.DefineType ();
+ object[] args = new object[4];
+ args[0] = TypeManager.object_type.GetMetaInfo ();
+ args[1] = TypeManager.value_type.GetMetaInfo ();
+ args[2] = TypeManager.enum_type.GetMetaInfo ();
+ args[3] = TypeManager.void_type.GetMetaInfo ();
+ set_corlib_type_builders.Invoke (CodeGen.Assembly.Builder, args);
+
+ // Another Mono corlib HACK
+ // mono_class_layout_fields requires to have enums created
+ // before creating a class which used the enum for any of its fields
+ foreach (var e in hack_corlib_enums)
+ e.CloseType ();
}
// <summary>
// </remarks>
static public void CloseTypes ()
{
- //
- // We do this in two passes, first we close the structs,
- // then the classes, because it seems the code needs it this
- // way. If this is really what is going on, we should probably
- // make sure that we define the structs in order as well.
- //
- foreach (TypeContainer tc in type_container_resolve_order){
- if (tc.Kind == MemberKind.Struct && tc.Parent == root){
- tc.CloseType ();
- }
- }
+ HackCorlib ();
- foreach (TypeContainer tc in type_container_resolve_order){
- if (!(tc.Kind == MemberKind.Struct && tc.Parent == root))
- tc.CloseType ();
+ foreach (TypeContainer tc in root.Types){
+ tc.CloseType ();
}
-
- if (root.Delegates != null)
- foreach (Delegate d in root.Delegates)
- d.CloseType ();
if (root.CompilerGeneratedClasses != null)
foreach (CompilerGeneratedClass c in root.CompilerGeneratedClasses)
}
}
- type_container_resolve_order = null;
helper_classes = null;
- //root = null;
- TypeManager.CleanUp ();
}
/// <summary>
helper_classes.Add (helper_class);
}
- static public DeclSpace PopulateCoreType (TypeContainer root, string name)
- {
- DeclSpace ds = (DeclSpace) root.GetDefinition (name);
- // Core type was imported
- if (ds == null)
- return null;
-
- ds.Define ();
- return ds;
- }
-
- static public void BootCorlib_PopulateCoreTypes ()
- {
- // Clear -nostdlib flag when object type is imported
- if (PopulateCoreType (root, "System.Object") == null)
- RootContext.StdLib = true;
-
- PopulateCoreType (root, "System.ValueType");
- PopulateCoreType (root, "System.Attribute");
- PopulateCoreType (root, "System.Runtime.CompilerServices.IndexerNameAttribute");
- }
-
// <summary>
// Populates the structs and classes with fields and methods
// </summary>
// have been defined through `ResolveTree'
static public void PopulateTypes ()
{
-
- if (type_container_resolve_order != null){
- foreach (TypeContainer tc in type_container_resolve_order)
- tc.ResolveType ();
- foreach (TypeContainer tc in type_container_resolve_order) {
- try {
- tc.Define ();
- } catch (Exception e) {
- throw new InternalErrorException (tc, e);
- }
+ foreach (TypeContainer tc in ToplevelTypes.Types)
+ tc.ResolveTypeParameters ();
+
+ foreach (TypeContainer tc in ToplevelTypes.Types) {
+ try {
+ tc.Define ();
+ } catch (Exception e) {
+ throw new InternalErrorException (tc, e);
}
}
-
- var delegates = root.Delegates;
- if (delegates != null){
- foreach (Delegate d in delegates)
- d.Define ();
- }
-
- //
- // Check for cycles in the struct layout
- //
- if (type_container_resolve_order != null){
- var seen = new Dictionary<TypeContainer, object> ();
- foreach (TypeContainer tc in type_container_resolve_order)
- TypeManager.CheckStructCycles (tc, seen);
- }
}
static public void EmitCode ()
{
- if (type_container_resolve_order != null) {
- foreach (TypeContainer tc in type_container_resolve_order)
- tc.EmitType ();
+ foreach (var tc in ToplevelTypes.Types)
+ tc.DefineConstants ();
- if (ToplevelTypes.Compiler.Report.Errors > 0)
- return;
+ foreach (TypeContainer tc in ToplevelTypes.Types)
+ tc.EmitType ();
- foreach (TypeContainer tc in type_container_resolve_order)
- tc.VerifyMembers ();
- }
-
- if (root.Delegates != null) {
- foreach (Delegate d in root.Delegates)
- d.Emit ();
- }
+ if (ToplevelTypes.Compiler.Report.Errors > 0)
+ return;
+
+ foreach (TypeContainer tc in ToplevelTypes.Types)
+ tc.VerifyMembers ();
if (root.CompilerGeneratedClasses != null)
foreach (CompilerGeneratedClass c in root.CompilerGeneratedClasses)
impl_details_class = ToplevelTypes.Builder.DefineType (
"<PrivateImplementationDetails>",
TypeAttributes.NotPublic,
- TypeManager.object_type);
+ TypeManager.object_type.GetMetaInfo ());
RegisterCompilerGeneratedType (impl_details_class);
}
this.assembly = assembly;
}
- public Assembly Assembly {
+ public override Assembly Assembly {
get { return assembly; }
}
return AddPartial (nextPart, nextPart.Name);
}
- public override void ApplyAttributeBuilder (Attribute a, ConstructorInfo ctor, byte[] cdata, PredefinedAttributes pa)
+ public override void ApplyAttributeBuilder (Attribute a, MethodSpec ctor, byte[] cdata, PredefinedAttributes pa)
{
if (a.Type == pa.CLSCompliant) {
if (CodeGen.Assembly.ClsCompliantAttribute == null) {
}
}
- builder.SetCustomAttribute (ctor, cdata);
+ builder.SetCustomAttribute ((ConstructorInfo) ctor.GetMetaInfo (), cdata);
}
public ModuleBuilder Builder {
OptAttributes.Emit ();
if (is_unsafe) {
- Type t = TypeManager.CoreLookupType (context, "System.Security", "UnverifiableCodeAttribute", MemberKind.Class, true);
+ TypeSpec t = TypeManager.CoreLookupType (context, "System.Security", "UnverifiableCodeAttribute", MemberKind.Class, true);
if (t != null) {
- ConstructorInfo unverifiable_code_ctor = TypeManager.GetPredefinedConstructor (t, Location.Null, Type.EmptyTypes);
+ var unverifiable_code_ctor = TypeManager.GetPredefinedConstructor (t, Location.Null, TypeSpec.EmptyTypes);
if (unverifiable_code_ctor != null)
- builder.SetCustomAttribute (new CustomAttributeBuilder (unverifiable_code_ctor, new object [0]));
+ builder.SetCustomAttribute (new CustomAttributeBuilder ((ConstructorInfo) unverifiable_code_ctor.GetMetaInfo (), new object[0]));
}
}
}
return null;
}
- public override bool GetClsCompliantAttributeValue ()
- {
- return CodeGen.Assembly.IsClsCompliant;
- }
-
public bool HasDefaultCharSet {
get {
return has_default_charset;
public override bool IsClsComplianceRequired ()
{
- return true;
+ return CodeGen.Assembly.IsClsCompliant;
}
- protected override bool AddMemberType (DeclSpace ds)
+ protected override bool AddMemberType (TypeContainer ds)
{
if (!AddToContainer (ds, ds.Name))
return false;
- ds.NamespaceEntry.NS.AddDeclSpace (ds.Basename, ds);
+ ds.NamespaceEntry.NS.AddType (ds.Definition);
return true;
}
}
}
- class RootDeclSpace : DeclSpace {
+ class RootDeclSpace : TypeContainer {
public RootDeclSpace (NamespaceEntry ns)
- : base (ns, null, MemberName.Null, null)
+ : base (ns, null, MemberName.Null, null, 0)
{
PartialContainer = RootContext.ToplevelTypes;
}
get { throw new InternalErrorException ("should not be called"); }
}
- public override bool Define ()
- {
- throw new InternalErrorException ("should not be called");
- }
+ //public override bool Define ()
+ //{
+ // throw new InternalErrorException ("should not be called");
+ //}
public override TypeBuilder DefineType ()
{
throw new InternalErrorException ("should not be called");
}
- public override MemberCache MemberCache {
- get { return PartialContainer.MemberCache; }
- }
-
public override ModuleContainer Module {
get {
return PartialContainer.Module;
}
}
- public override bool GetClsCompliantAttributeValue ()
- {
- return PartialContainer.GetClsCompliantAttributeValue ();
- }
-
public override bool IsClsComplianceRequired ()
{
return PartialContainer.IsClsComplianceRequired ();
return Clone (clonectx);
}
-
- public abstract void MutateHoistedGenericType (AnonymousMethodStorey storey);
}
public sealed class EmptyStatement : Statement
throw new NotSupportedException ();
}
- public override void MutateHoistedGenericType (AnonymousMethodStorey storey)
- {
- }
-
protected override void CloneTo (CloneContext clonectx, Statement target)
{
// nothing needed.
loc = l;
}
- public override void MutateHoistedGenericType (AnonymousMethodStorey storey)
- {
- expr.MutateHoistedGenericType (storey);
- TrueStatement.MutateHoistedGenericType (storey);
- if (FalseStatement != null)
- FalseStatement.MutateHoistedGenericType (storey);
- }
-
public override bool Resolve (BlockContext ec)
{
bool ok = true;
protected override void DoEmit (EmitContext ec)
{
- ILGenerator ig = ec.ig;
- Label false_target = ig.DefineLabel ();
+ Label false_target = ec.DefineLabel ();
Label end;
//
if (FalseStatement != null){
bool branch_emitted = false;
- end = ig.DefineLabel ();
+ end = ec.DefineLabel ();
if (!is_true_ret){
- ig.Emit (OpCodes.Br, end);
+ ec.Emit (OpCodes.Br, end);
branch_emitted = true;
}
- ig.MarkLabel (false_target);
+ ec.MarkLabel (false_target);
FalseStatement.Emit (ec);
if (branch_emitted)
- ig.MarkLabel (end);
+ ec.MarkLabel (end);
} else {
- ig.MarkLabel (false_target);
+ ec.MarkLabel (false_target);
}
}
protected override void DoEmit (EmitContext ec)
{
- ILGenerator ig = ec.ig;
- Label loop = ig.DefineLabel ();
+ Label loop = ec.DefineLabel ();
Label old_begin = ec.LoopBegin;
Label old_end = ec.LoopEnd;
- ec.LoopBegin = ig.DefineLabel ();
- ec.LoopEnd = ig.DefineLabel ();
+ ec.LoopBegin = ec.DefineLabel ();
+ ec.LoopEnd = ec.DefineLabel ();
- ig.MarkLabel (loop);
+ ec.MarkLabel (loop);
EmbeddedStatement.Emit (ec);
- ig.MarkLabel (ec.LoopBegin);
+ ec.MarkLabel (ec.LoopBegin);
//
// Dead code elimination
expr.EmitSideEffect (ec);
if (res)
- ec.ig.Emit (OpCodes.Br, loop);
+ ec.Emit (OpCodes.Br, loop);
} else
expr.EmitBranchable (ec, loop, true);
- ig.MarkLabel (ec.LoopEnd);
+ ec.MarkLabel (ec.LoopEnd);
ec.LoopBegin = old_begin;
ec.LoopEnd = old_end;
}
- public override void MutateHoistedGenericType (AnonymousMethodStorey storey)
- {
- expr.MutateHoistedGenericType (storey);
- EmbeddedStatement.MutateHoistedGenericType (storey);
- }
-
protected override void CloneTo (CloneContext clonectx, Statement t)
{
Do target = (Do) t;
return;
}
- ILGenerator ig = ec.ig;
Label old_begin = ec.LoopBegin;
Label old_end = ec.LoopEnd;
- ec.LoopBegin = ig.DefineLabel ();
- ec.LoopEnd = ig.DefineLabel ();
+ ec.LoopBegin = ec.DefineLabel ();
+ ec.LoopEnd = ec.DefineLabel ();
//
// Inform whether we are infinite or not
//
if (expr is Constant){
// expr is 'true', since the 'empty' case above handles the 'false' case
- ig.MarkLabel (ec.LoopBegin);
+ ec.MarkLabel (ec.LoopBegin);
expr.EmitSideEffect (ec);
Statement.Emit (ec);
- ig.Emit (OpCodes.Br, ec.LoopBegin);
+ ec.Emit (OpCodes.Br, ec.LoopBegin);
//
// Inform that we are infinite (ie, `we return'), only
// if we do not `break' inside the code.
//
- ig.MarkLabel (ec.LoopEnd);
+ ec.MarkLabel (ec.LoopEnd);
} else {
- Label while_loop = ig.DefineLabel ();
+ Label while_loop = ec.DefineLabel ();
- ig.Emit (OpCodes.Br, ec.LoopBegin);
- ig.MarkLabel (while_loop);
+ ec.Emit (OpCodes.Br, ec.LoopBegin);
+ ec.MarkLabel (while_loop);
Statement.Emit (ec);
- ig.MarkLabel (ec.LoopBegin);
+ ec.MarkLabel (ec.LoopBegin);
ec.Mark (loc);
expr.EmitBranchable (ec, while_loop, true);
- ig.MarkLabel (ec.LoopEnd);
+ ec.MarkLabel (ec.LoopEnd);
}
ec.LoopBegin = old_begin;
target.expr = expr.Clone (clonectx);
target.Statement = Statement.Clone (clonectx);
}
-
- public override void MutateHoistedGenericType (AnonymousMethodStorey storey)
- {
- expr.MutateHoistedGenericType (storey);
- Statement.MutateHoistedGenericType (storey);
- }
}
public class For : Statement {
return;
}
- ILGenerator ig = ec.ig;
Label old_begin = ec.LoopBegin;
Label old_end = ec.LoopEnd;
- Label loop = ig.DefineLabel ();
- Label test = ig.DefineLabel ();
+ Label loop = ec.DefineLabel ();
+ Label test = ec.DefineLabel ();
- ec.LoopBegin = ig.DefineLabel ();
- ec.LoopEnd = ig.DefineLabel ();
+ ec.LoopBegin = ec.DefineLabel ();
+ ec.LoopEnd = ec.DefineLabel ();
- ig.Emit (OpCodes.Br, test);
- ig.MarkLabel (loop);
+ ec.Emit (OpCodes.Br, test);
+ ec.MarkLabel (loop);
Statement.Emit (ec);
- ig.MarkLabel (ec.LoopBegin);
+ ec.MarkLabel (ec.LoopBegin);
Increment.Emit (ec);
- ig.MarkLabel (test);
+ ec.MarkLabel (test);
//
// If test is null, there is no test, and we are just
// an infinite loop
//
if (Test is Constant) {
Test.EmitSideEffect (ec);
- ig.Emit (OpCodes.Br, loop);
+ ec.Emit (OpCodes.Br, loop);
} else {
Test.EmitBranchable (ec, loop, true);
}
} else
- ig.Emit (OpCodes.Br, loop);
- ig.MarkLabel (ec.LoopEnd);
+ ec.Emit (OpCodes.Br, loop);
+ ec.MarkLabel (ec.LoopEnd);
ec.LoopBegin = old_begin;
ec.LoopEnd = old_end;
}
- public override void MutateHoistedGenericType (AnonymousMethodStorey storey)
- {
- if (InitStatement != null)
- InitStatement.MutateHoistedGenericType (storey);
- if (Test != null)
- Test.MutateHoistedGenericType (storey);
- if (Increment != null)
- Increment.MutateHoistedGenericType (storey);
-
- Statement.MutateHoistedGenericType (storey);
- }
-
protected override void CloneTo (CloneContext clonectx, Statement t)
{
For target = (For) t;
expr.EmitStatement (ec);
}
- public override void MutateHoistedGenericType (AnonymousMethodStorey storey)
- {
- expr.MutateHoistedGenericType (storey);
- }
-
public override string ToString ()
{
return "StatementExpression (" + expr + ")";
Expr.Emit (ec);
if (unwind_protect)
- ec.ig.Emit (OpCodes.Stloc, ec.TemporaryReturn ());
+ ec.Emit (OpCodes.Stloc, ec.TemporaryReturn ());
}
if (unwind_protect)
- ec.ig.Emit (OpCodes.Leave, ec.ReturnLabel);
+ ec.Emit (OpCodes.Leave, ec.ReturnLabel);
else
- ec.ig.Emit (OpCodes.Ret);
- }
-
- public override void MutateHoistedGenericType (AnonymousMethodStorey storey)
- {
- if (Expr != null)
- Expr.MutateHoistedGenericType (storey);
+ ec.Emit (OpCodes.Ret);
}
protected override void CloneTo (CloneContext clonectx, Statement t)
if (label == null)
throw new InternalErrorException ("goto emitted before target resolved");
Label l = label.LabelTarget (ec);
- ec.ig.Emit (unwind_protect ? OpCodes.Leave : OpCodes.Br, l);
- }
-
- public override void MutateHoistedGenericType (AnonymousMethodStorey storey)
- {
+ ec.Emit (unwind_protect ? OpCodes.Leave : OpCodes.Br, l);
}
}
bool defined;
bool referenced;
Label label;
- ILGenerator ig;
FlowBranching.UsageVector vectors;
{
if (defined)
return label;
- ig = ec.ig;
- label = ec.ig.DefineLabel ();
- defined = true;
+ label = ec.DefineLabel ();
+ defined = true;
return label;
}
protected override void DoEmit (EmitContext ec)
{
- if (ig != null && ig != ec.ig)
- throw new InternalErrorException ("cannot happen");
LabelTarget (ec);
- ec.ig.MarkLabel (label);
- }
-
- public override void MutateHoistedGenericType (AnonymousMethodStorey storey)
- {
+ ec.MarkLabel (label);
}
public void AddReference ()
protected override void DoEmit (EmitContext ec)
{
- ec.ig.Emit (OpCodes.Br, ec.Switch.DefaultTarget);
- }
-
- public override void MutateHoistedGenericType (AnonymousMethodStorey storey)
- {
+ ec.Emit (OpCodes.Br, ec.Switch.DefaultTarget);
}
}
return false;
}
- Type type = ec.Switch.SwitchType;
+ TypeSpec type = ec.Switch.SwitchType;
Constant res = c.TryReduce (ec, type, c.Location);
if (res == null) {
c.Error_ValueCannotBeConverted (ec, loc, type, true);
protected override void DoEmit (EmitContext ec)
{
- ec.ig.Emit (OpCodes.Br, sl.GetILLabelCode (ec));
- }
-
- public override void MutateHoistedGenericType (AnonymousMethodStorey storey)
- {
- expr.MutateHoistedGenericType (storey);
+ ec.Emit (OpCodes.Br, sl.GetILLabelCode (ec));
}
protected override void CloneTo (CloneContext clonectx, Statement t)
protected override void DoEmit (EmitContext ec)
{
if (expr == null)
- ec.ig.Emit (OpCodes.Rethrow);
+ ec.Emit (OpCodes.Rethrow);
else {
expr.Emit (ec);
- ec.ig.Emit (OpCodes.Throw);
+ ec.Emit (OpCodes.Throw);
}
}
- public override void MutateHoistedGenericType (AnonymousMethodStorey storey)
- {
- if (expr != null)
- expr.MutateHoistedGenericType (storey);
- }
-
protected override void CloneTo (CloneContext clonectx, Statement t)
{
Throw target = (Throw) t;
protected override void DoEmit (EmitContext ec)
{
- ec.ig.Emit (unwind_protect ? OpCodes.Leave : OpCodes.Br, ec.LoopEnd);
+ ec.Emit (unwind_protect ? OpCodes.Leave : OpCodes.Br, ec.LoopEnd);
}
- public override void MutateHoistedGenericType (AnonymousMethodStorey storey)
- {
- }
-
protected override void CloneTo (CloneContext clonectx, Statement t)
{
// nothing needed
protected override void DoEmit (EmitContext ec)
{
- ec.ig.Emit (unwind_protect ? OpCodes.Leave : OpCodes.Br, ec.LoopBegin);
- }
-
- public override void MutateHoistedGenericType (AnonymousMethodStorey storey)
- {
+ ec.Emit (unwind_protect ? OpCodes.Leave : OpCodes.Br, ec.LoopBegin);
}
protected override void CloneTo (CloneContext clonectx, Statement t)
public class LocalInfo : IKnownVariable, ILocalVariable {
public readonly FullNamedExpression Type;
- public Type VariableType;
+ public TypeSpec VariableType;
public readonly string Name;
public readonly Location Location;
public readonly Block Block;
Location = l;
}
- public LocalInfo (DeclSpace ds, Block block, Location l)
+ public LocalInfo (TypeContainer ds, Block block, Location l)
{
- VariableType = ds.IsGeneric ? ds.CurrentType : ds.TypeBuilder;
+ VariableType = ds.IsGeneric ? ds.CurrentType : ds.Definition;
Block = block;
Location = l;
}
return;
if (builder == null) {
- builder = ec.ig.DeclareLocal (TypeManager.TypeToReflectionType (VariableType), Pinned);
+ builder = ec.DeclareLocal (VariableType, Pinned);
}
}
public void Emit (EmitContext ec)
{
- ec.ig.Emit (OpCodes.Ldloc, builder);
+ ec.Emit (OpCodes.Ldloc, builder);
}
public void EmitAssign (EmitContext ec)
{
- ec.ig.Emit (OpCodes.Stloc, builder);
+ ec.Emit (OpCodes.Stloc, builder);
}
public void EmitAddressOf (EmitContext ec)
{
- ec.ig.Emit (OpCodes.Ldloca, builder);
+ ec.Emit (OpCodes.Ldloca, builder);
}
public void EmitSymbolInfo (EmitContext ec)
VariableType = texpr.Type;
- if (TypeManager.IsGenericParameter (VariableType))
- return true;
-
- if (VariableType.IsAbstract && VariableType.IsSealed) {
+ if (VariableType.IsStatic) {
FieldBase.Error_VariableOfStaticClass (Location, Name, VariableType, ec.Report);
return false;
}
foreach (var de in variables) {
string name = de.Key;
LocalInfo vi = de.Value;
- Type variable_type = vi.VariableType;
+ TypeSpec variable_type = vi.VariableType;
if (variable_type == null) {
if (vi.Type is VarExpr)
// which in turn causes the 'must be constant' error to be triggered.
constants.Remove (name);
- if (!Const.IsConstantTypeValid (variable_type)) {
+ if (!variable_type.IsConstantCompatible) {
Const.Error_InvalidConstantType (variable_type, loc, ec.Report);
continue;
}
protected void EmitScopeInitializers (EmitContext ec)
{
- SymbolWriter.OpenCompilerGeneratedBlock (ec.ig);
+ SymbolWriter.OpenCompilerGeneratedBlock (ec);
using (ec.With (EmitContext.Options.OmitDebugInfo, true)) {
foreach (Statement s in scope_initializers)
s.Emit (ec);
}
- SymbolWriter.CloseCompilerGeneratedBlock (ec.ig);
+ SymbolWriter.CloseCompilerGeneratedBlock (ec);
}
protected virtual void EmitSymbolInfo (EmitContext ec)
}
}
- public override void MutateHoistedGenericType (AnonymousMethodStorey storey)
- {
- MutateVariables (storey);
-
- if (scope_initializers != null) {
- foreach (Statement s in scope_initializers)
- s.MutateHoistedGenericType (storey);
- }
-
- foreach (Statement s in statements)
- s.MutateHoistedGenericType (storey);
- }
-
- void MutateVariables (AnonymousMethodStorey storey)
- {
- if (variables != null) {
- foreach (LocalInfo vi in variables.Values) {
- vi.VariableType = storey.MutateType (vi.VariableType);
- }
- }
-
- if (temporary_variables != null) {
- foreach (LocalInfo vi in temporary_variables)
- vi.VariableType = storey.MutateType (vi.VariableType);
- }
- }
-
public override string ToString ()
{
return String.Format ("{0} ({1}:{2})", GetType (),ID, StartLocation);
//
// Creates anonymous method storey for this block
//
- am_storey = new AnonymousMethodStorey (this, ec.CurrentTypeDefinition, mc, gm, "AnonStorey");
+ am_storey = new AnonymousMethodStorey (this, ec.CurrentMemberDefinition.Parent.PartialContainer, mc, gm, "AnonStorey");
}
return am_storey;
while (parent.am_storey == null || parent.am_storey.Parent is AnonymousMethodStorey)
parent = parent.Parent.Explicit;
- am_storey.AddParentStoreyReference (parent.am_storey);
+ am_storey.AddParentStoreyReference (ec, parent.am_storey);
}
- am_storey.ChangeParentStorey (ec.CurrentAnonymousMethod.Storey);
+ am_storey.SetNestedStoryParent (ec.CurrentAnonymousMethod.Storey);
+
+ // TODO MemberCache: Review
+ am_storey.Mutator = ec.CurrentAnonymousMethod.Storey.Mutator;
}
+ am_storey.CreateType ();
+ if (am_storey.Mutator == null && ec.CurrentTypeParameters != null)
+ am_storey.Mutator = new TypeParameterMutator (ec.CurrentTypeParameters, am_storey.CurrentTypeParameters);
+
am_storey.DefineType ();
- am_storey.ResolveType ();
+ am_storey.ResolveTypeParameters ();
am_storey.Define ();
am_storey.Parent.PartialContainer.AddCompilerGeneratedClass (am_storey);
foreach (ExplicitBlock ref_block in ref_blocks) {
for (ExplicitBlock b = ref_block.Explicit; b != this; b = b.Parent.Explicit) {
if (b.am_storey != null) {
- b.am_storey.AddParentStoreyReference (am_storey);
+ b.am_storey.AddParentStoreyReference (ec, am_storey);
// Stop propagation inside same top block
if (b.Toplevel == Toplevel)
get { return Block.Parameters [Index]; }
}
- public Type ParameterType {
+ public TypeSpec ParameterType {
get { return Block.Parameters.Types [Index]; }
}
block.EmitScopeInitializers (ec);
child.Emit (ec);
}
-
- public override void MutateHoistedGenericType (AnonymousMethodStorey storey)
- {
- type = storey.MutateType (type);
- child.MutateHoistedGenericType (storey);
- block.MutateHoistedGenericType (storey);
- }
}
GenericMethod generic;
// analysis code to ensure that it's been fully initialized before control
// leaves the constructor.
// </summary>
- public LocalInfo AddThisVariable (DeclSpace ds, Location l)
+ public LocalInfo AddThisVariable (TypeContainer ds, Location l)
{
if (this_variable == null) {
this_variable = new LocalInfo (ds, this, l);
EmitMeta (ec);
if (ec.HasReturnLabel)
- ec.ReturnLabel = ec.ig.DefineLabel ();
+ ec.ReturnLabel = ec.DefineLabel ();
base.Emit (ec);
ec.Mark (EndLocation);
if (ec.HasReturnLabel)
- ec.ig.MarkLabel (ec.ReturnLabel);
+ ec.MarkLabel (ec.ReturnLabel);
if (ec.return_value != null) {
- ec.ig.Emit (OpCodes.Ldloc, ec.return_value);
- ec.ig.Emit (OpCodes.Ret);
+ ec.Emit (OpCodes.Ldloc, ec.return_value);
+ ec.Emit (OpCodes.Ret);
} else {
//
// If `HasReturnLabel' is set, then we already emitted a
if (ec.HasReturnLabel || !unreachable) {
if (ec.ReturnType != TypeManager.void_type)
- ec.ig.Emit (OpCodes.Ldloc, ec.TemporaryReturn ());
- ec.ig.Emit (OpCodes.Ret);
+ ec.Emit (OpCodes.Ldloc, ec.TemporaryReturn ());
+ ec.Emit (OpCodes.Ret);
}
}
public override void EmitMeta (EmitContext ec)
{
- parameters.ResolveVariable ();
-
// Avoid declaring an IL variable for this_variable since it is not accessed
// from the generated IL
if (this_variable != null)
public Label GetILLabel (EmitContext ec)
{
if (!il_label_set){
- il_label = ec.ig.DefineLabel ();
+ il_label = ec.DefineLabel ();
il_label_set = true;
}
return il_label;
public Label GetILLabelCode (EmitContext ec)
{
if (!il_label_code_set){
- il_label_code = ec.ig.DefineLabel ();
+ il_label_code = ec.DefineLabel ();
il_label_code_set = true;
}
return il_label_code;
// Resolves the expression, reduces it to a literal if possible
// and then converts it to the requested type.
//
- public bool ResolveAndReduce (ResolveContext ec, Type required_type, bool allow_nullable)
+ public bool ResolveAndReduce (ResolveContext ec, TypeSpec required_type, bool allow_nullable)
{
Expression e = label.Resolve (ec);
return true;
}
- public void Error_AlreadyOccurs (ResolveContext ec, Type switch_type, SwitchLabel collision_with)
+ public void Error_AlreadyOccurs (ResolveContext ec, TypeSpec switch_type, SwitchLabel collision_with)
{
string label;
if (converted == null)
/// <summary>
/// The governing switch type
/// </summary>
- public Type SwitchType;
+ public TypeSpec SwitchType;
//
// Computed
// The types allowed to be implicitly cast from
// on the governing type
//
- static Type [] allowed_types;
+ static TypeSpec [] allowed_types;
public Switch (Expression e, List<SwitchSection> sects, Location l)
{
//
Expression SwitchGoverningType (ResolveContext ec, Expression expr)
{
- Type t = expr.Type;
+ TypeSpec t = expr.Type;
if (t == TypeManager.byte_type ||
t == TypeManager.sbyte_type ||
return expr;
if (allowed_types == null){
- allowed_types = new Type [] {
+ allowed_types = new TypeSpec [] {
TypeManager.sbyte_type,
TypeManager.byte_type,
TypeManager.short_type,
// conversions, we have to report an error
//
Expression converted = null;
- foreach (Type tt in allowed_types){
+ foreach (TypeSpec tt in allowed_types){
Expression e;
e = Convert.ImplicitUserConversion (ec, expr, tt, loc);
return !error;
}
- void EmitObjectInteger (ILGenerator ig, object k)
+ void EmitObjectInteger (EmitContext ec, object k)
{
if (k is int)
- IntConstant.EmitInt (ig, (int) k);
+ ec.EmitInt ((int) k);
else if (k is Constant) {
- EmitObjectInteger (ig, ((Constant) k).GetValue ());
+ EmitObjectInteger (ec, ((Constant) k).GetValue ());
}
else if (k is uint)
- IntConstant.EmitInt (ig, unchecked ((int) (uint) k));
+ ec.EmitInt (unchecked ((int) (uint) k));
else if (k is long)
{
if ((long) k >= int.MinValue && (long) k <= int.MaxValue)
{
- IntConstant.EmitInt (ig, (int) (long) k);
- ig.Emit (OpCodes.Conv_I8);
+ ec.EmitInt ((int) (long) k);
+ ec.Emit (OpCodes.Conv_I8);
}
else
- LongConstant.EmitLong (ig, (long) k);
+ ec.EmitLong ((long) k);
}
else if (k is ulong)
{
ulong ul = (ulong) k;
if (ul < (1L<<32))
{
- IntConstant.EmitInt (ig, unchecked ((int) ul));
- ig.Emit (OpCodes.Conv_U8);
+ ec.EmitInt (unchecked ((int) ul));
+ ec.Emit (OpCodes.Conv_U8);
}
else
{
- LongConstant.EmitLong (ig, unchecked ((long) ul));
+ ec.EmitLong (unchecked ((long) ul));
}
}
else if (k is char)
- IntConstant.EmitInt (ig, (int) ((char) k));
+ ec.EmitInt ((int) ((char) k));
else if (k is sbyte)
- IntConstant.EmitInt (ig, (int) ((sbyte) k));
+ ec.EmitInt ((int) ((sbyte) k));
else if (k is byte)
- IntConstant.EmitInt (ig, (int) ((byte) k));
+ ec.EmitInt ((int) ((byte) k));
else if (k is short)
- IntConstant.EmitInt (ig, (int) ((short) k));
+ ec.EmitInt ((int) ((short) k));
else if (k is ushort)
- IntConstant.EmitInt (ig, (int) ((ushort) k));
+ ec.EmitInt ((int) ((ushort) k));
else if (k is bool)
- IntConstant.EmitInt (ig, ((bool) k) ? 1 : 0);
+ ec.EmitInt (((bool) k) ? 1 : 0);
else
throw new Exception ("Unhandled case");
}
key_blocks.Sort ();
// okay now we can start...
- ILGenerator ig = ec.ig;
- Label lbl_end = ig.DefineLabel (); // at the end ;-)
+ Label lbl_end = ec.DefineLabel (); // at the end ;-)
Label lbl_default = default_target;
Type type_keys = null;
if (element_keys.Length > 0)
type_keys = element_keys [0].GetType (); // used for conversions
- Type compare_type;
+ TypeSpec compare_type;
if (TypeManager.IsEnumType (SwitchType))
- compare_type = TypeManager.GetEnumUnderlyingType (SwitchType);
+ compare_type = EnumSpec.GetUnderlyingType (SwitchType);
else
compare_type = SwitchType;
for (int iBlock = key_blocks.Count - 1; iBlock >= 0; --iBlock)
{
KeyBlock kb = ((KeyBlock) key_blocks [iBlock]);
- lbl_default = (iBlock == 0) ? default_target : ig.DefineLabel ();
+ lbl_default = (iBlock == 0) ? default_target : ec.DefineLabel ();
if (kb.Length <= 2)
{
foreach (object key in kb.element_keys) {
val.EmitBranchable (ec, sl.GetILLabel (ec), false);
} else {
val.Emit (ec);
- EmitObjectInteger (ig, key);
- ig.Emit (OpCodes.Beq, sl.GetILLabel (ec));
+ EmitObjectInteger (ec, key);
+ ec.Emit (OpCodes.Beq, sl.GetILLabel (ec));
}
}
}
// check block range (could be > 2^31)
val.Emit (ec);
- EmitObjectInteger (ig, System.Convert.ChangeType (kb.first, type_keys));
- ig.Emit (OpCodes.Blt, lbl_default);
+ EmitObjectInteger (ec, System.Convert.ChangeType (kb.first, type_keys));
+ ec.Emit (OpCodes.Blt, lbl_default);
val.Emit (ec);
- EmitObjectInteger (ig, System.Convert.ChangeType (kb.last, type_keys));
- ig.Emit (OpCodes.Bgt, lbl_default);
+ EmitObjectInteger (ec, System.Convert.ChangeType (kb.last, type_keys));
+ ec.Emit (OpCodes.Bgt, lbl_default);
// normalize range
val.Emit (ec);
if (kb.first != 0)
{
- EmitObjectInteger (ig, System.Convert.ChangeType (kb.first, type_keys));
- ig.Emit (OpCodes.Sub);
+ EmitObjectInteger (ec, System.Convert.ChangeType (kb.first, type_keys));
+ ec.Emit (OpCodes.Sub);
}
- ig.Emit (OpCodes.Conv_I4); // assumes < 2^31 labels!
+ ec.Emit (OpCodes.Conv_I4); // assumes < 2^31 labels!
}
else
{
int first = (int) kb.first;
if (first > 0)
{
- IntConstant.EmitInt (ig, first);
- ig.Emit (OpCodes.Sub);
+ ec.EmitInt (first);
+ ec.Emit (OpCodes.Sub);
}
else if (first < 0)
{
- IntConstant.EmitInt (ig, -first);
- ig.Emit (OpCodes.Add);
+ ec.EmitInt (-first);
+ ec.Emit (OpCodes.Add);
}
}
switch_labels [iJump] = lbl_default;
}
// emit the switch opcode
- ig.Emit (OpCodes.Switch, switch_labels);
+ ec.Emit (OpCodes.Switch, switch_labels);
}
// mark the default for this block
if (iBlock != 0)
- ig.MarkLabel (lbl_default);
+ ec.MarkLabel (lbl_default);
}
// TODO: find the default case and emit it here,
// the last default just goes to the end
if (element_keys.Length > 0)
- ig.Emit (OpCodes.Br, lbl_default);
+ ec.Emit (OpCodes.Br, lbl_default);
// now emit the code for the sections
bool found_default = false;
foreach (SwitchSection ss in Sections) {
foreach (SwitchLabel sl in ss.Labels) {
if (sl.Converted == SwitchLabel.NullStringCase) {
- ig.MarkLabel (null_target);
+ ec.MarkLabel (null_target);
} else if (sl.Label == null) {
- ig.MarkLabel (lbl_default);
+ ec.MarkLabel (lbl_default);
found_default = true;
if (!has_null_case)
- ig.MarkLabel (null_target);
+ ec.MarkLabel (null_target);
}
- ig.MarkLabel (sl.GetILLabel (ec));
- ig.MarkLabel (sl.GetILLabelCode (ec));
+ ec.MarkLabel (sl.GetILLabel (ec));
+ ec.MarkLabel (sl.GetILLabelCode (ec));
}
ss.Block.Emit (ec);
}
if (!found_default) {
- ig.MarkLabel (lbl_default);
+ ec.MarkLabel (lbl_default);
if (!has_null_case) {
- ig.MarkLabel (null_target);
+ ec.MarkLabel (null_target);
}
}
- ig.MarkLabel (lbl_end);
+ ec.MarkLabel (lbl_end);
}
SwitchSection FindSection (SwitchLabel label)
return null;
}
- public override void MutateHoistedGenericType (AnonymousMethodStorey storey)
- {
- foreach (SwitchSection ss in Sections)
- ss.Block.MutateHoistedGenericType (storey);
- }
-
public static void Reset ()
{
unique_counter = 0;
string_dictionary_type = new MemberAccess (system_collections_generic, "Hashtable", loc);
}
- Field field = new Field (ec.CurrentTypeDefinition, string_dictionary_type,
+ var ctype = ec.CurrentMemberDefinition.Parent.PartialContainer;
+ Field field = new Field (ctype, string_dictionary_type,
Modifiers.STATIC | Modifiers.PRIVATE | Modifiers.COMPILER_GENERATED,
new MemberName (CompilerGeneratedClass.MakeName (null, "f", "switch$map", unique_counter++), loc), null);
if (!field.Define ())
return;
- ec.CurrentTypeDefinition.PartialContainer.AddField (field);
+ ctype.AddField (field);
var init = new List<Expression> ();
int counter = 0;
void DoEmitStringSwitch (LocalTemporary value, EmitContext ec)
{
- ILGenerator ig = ec.ig;
- Label l_initialized = ig.DefineLabel ();
+ Label l_initialized = ec.DefineLabel ();
//
// Skip initialization when value is null
//
switch_cache_field.EmitBranchable (ec, l_initialized, true);
string_dictionary.EmitStatement (ec);
- ig.MarkLabel (l_initialized);
+ ec.MarkLabel (l_initialized);
LocalTemporary string_switch_variable = new LocalTemporary (TypeManager.int32_type);
LocalTemporary get_item_object = new LocalTemporary (TypeManager.object_type);
get_item_object.EmitAssign (ec, get_item, true, false);
- ec.ig.Emit (OpCodes.Brfalse, default_target);
+ ec.Emit (OpCodes.Brfalse, default_target);
ExpressionStatement get_item_int = (ExpressionStatement) new SimpleAssign (string_switch_variable,
new Cast (new TypeExpression (TypeManager.int32_type, loc), get_item_object, loc)).Resolve (rc);
protected override void DoEmit (EmitContext ec)
{
- ILGenerator ig = ec.ig;
-
- default_target = ig.DefineLabel ();
- null_target = ig.DefineLabel ();
+ default_target = ec.DefineLabel ();
+ null_target = ec.DefineLabel ();
// Store variable for comparission purposes
// TODO: Don't duplicate non-captured VariableReference
if (HaveUnwrap) {
value = new LocalTemporary (SwitchType);
unwrap.EmitCheck (ec);
- ig.Emit (OpCodes.Brfalse, null_target);
+ ec.Emit (OpCodes.Brfalse, null_target);
new_expr.Emit (ec);
value.Store (ec);
} else if (!is_constant) {
Label old_end = ec.LoopEnd;
Switch old_switch = ec.Switch;
- ec.LoopEnd = ig.DefineLabel ();
+ ec.LoopEnd = ec.DefineLabel ();
ec.Switch = this;
// Emit Code.
value.Release (ec);
// Restore context state.
- ig.MarkLabel (ec.LoopEnd);
+ ec.MarkLabel (ec.LoopEnd);
//
// Restore the previous context
{
if (!prepared) {
prepared = true;
- resume_point = ec.ig.DefineLabel ();
+ resume_point = ec.DefineLabel ();
}
return resume_point;
}
protected sealed override void DoEmit (EmitContext ec)
{
- ILGenerator ig = ec.ig;
-
EmitPreTryBody (ec);
if (resume_points != null) {
- IntConstant.EmitInt (ig, (int) Iterator.State.Running);
- ig.Emit (OpCodes.Stloc, iter.CurrentPC);
+ ec.EmitInt ((int) Iterator.State.Running);
+ ec.Emit (OpCodes.Stloc, iter.CurrentPC);
}
- ig.BeginExceptionBlock ();
+ ec.BeginExceptionBlock ();
if (resume_points != null) {
- ig.MarkLabel (resume_point);
+ ec.MarkLabel (resume_point);
// For normal control flow, we want to fall-through the Switch
// So, we use CurrentPC rather than the $PC field, and initialize it to an outside value above
- ig.Emit (OpCodes.Ldloc, iter.CurrentPC);
- IntConstant.EmitInt (ig, first_resume_pc);
- ig.Emit (OpCodes.Sub);
+ ec.Emit (OpCodes.Ldloc, iter.CurrentPC);
+ ec.EmitInt (first_resume_pc);
+ ec.Emit (OpCodes.Sub);
Label [] labels = new Label [resume_points.Count];
for (int i = 0; i < resume_points.Count; ++i)
labels [i] = ((ResumableStatement) resume_points [i]).PrepareForEmit (ec);
- ig.Emit (OpCodes.Switch, labels);
+ ec.Emit (OpCodes.Switch, labels);
}
EmitTryBody (ec);
- ig.BeginFinallyBlock ();
+ ec.BeginFinallyBlock ();
- Label start_finally = ec.ig.DefineLabel ();
+ Label start_finally = ec.DefineLabel ();
if (resume_points != null) {
- ig.Emit (OpCodes.Ldloc, iter.SkipFinally);
- ig.Emit (OpCodes.Brfalse_S, start_finally);
- ig.Emit (OpCodes.Endfinally);
+ ec.Emit (OpCodes.Ldloc, iter.SkipFinally);
+ ec.Emit (OpCodes.Brfalse_S, start_finally);
+ ec.Emit (OpCodes.Endfinally);
}
- ig.MarkLabel (start_finally);
+ ec.MarkLabel (start_finally);
EmitFinallyBody (ec);
- ig.EndExceptionBlock ();
+ ec.EndExceptionBlock ();
}
public void SomeCodeFollows ()
{
if (!prepared_for_dispose) {
prepared_for_dispose = true;
- dispose_try_block = ec.ig.DefineLabel ();
+ dispose_try_block = ec.DefineLabel ();
}
return dispose_try_block;
}
emitted_dispose = true;
- ILGenerator ig = ec.ig;
-
- Label end_of_try = ig.DefineLabel ();
+ Label end_of_try = ec.DefineLabel ();
// Ensure that the only way we can get into this code is through a dispatcher
if (have_dispatcher)
- ig.Emit (OpCodes.Br, end);
+ ec.Emit (OpCodes.Br, end);
- ig.BeginExceptionBlock ();
+ ec.BeginExceptionBlock ();
- ig.MarkLabel (dispose_try_block);
+ ec.MarkLabel (dispose_try_block);
Label [] labels = null;
for (int i = 0; i < resume_points.Count; ++i) {
if (emit_dispatcher) {
//SymbolWriter.StartIteratorDispatcher (ec.ig);
- ig.Emit (OpCodes.Ldloc, iterator.CurrentPC);
- IntConstant.EmitInt (ig, first_resume_pc);
- ig.Emit (OpCodes.Sub);
- ig.Emit (OpCodes.Switch, labels);
+ ec.Emit (OpCodes.Ldloc, iterator.CurrentPC);
+ ec.EmitInt (first_resume_pc);
+ ec.Emit (OpCodes.Sub);
+ ec.Emit (OpCodes.Switch, labels);
//SymbolWriter.EndIteratorDispatcher (ec.ig);
}
s.EmitForDispose (ec, iterator, end_of_try, emit_dispatcher);
}
- ig.MarkLabel (end_of_try);
+ ec.MarkLabel (end_of_try);
- ig.BeginFinallyBlock ();
+ ec.BeginFinallyBlock ();
EmitFinallyBody (ec);
- ig.EndExceptionBlock ();
+ ec.EndExceptionBlock ();
}
}
// Avoid creating libraries that reference the internal
// mcs NullType:
- Type t = expr.Type;
+ TypeSpec t = expr.Type;
if (t == TypeManager.null_type)
t = TypeManager.object_type;
temp.Resolve (ec);
if (TypeManager.void_monitor_enter_object == null || TypeManager.void_monitor_exit_object == null) {
- Type monitor_type = TypeManager.CoreLookupType (ec.Compiler, "System.Threading", "Monitor", MemberKind.Class, true);
+ TypeSpec monitor_type = TypeManager.CoreLookupType (ec.Compiler, "System.Threading", "Monitor", MemberKind.Class, true);
TypeManager.void_monitor_enter_object = TypeManager.GetPredefinedMethod (
monitor_type, "Enter", loc, TypeManager.object_type);
TypeManager.void_monitor_exit_object = TypeManager.GetPredefinedMethod (
protected override void EmitPreTryBody (EmitContext ec)
{
- ILGenerator ig = ec.ig;
-
temp.EmitAssign (ec, expr);
temp.Emit (ec);
- ig.Emit (OpCodes.Call, (MethodInfo) TypeManager.void_monitor_enter_object.MetaInfo);
+ ec.Emit (OpCodes.Call, TypeManager.void_monitor_enter_object);
}
protected override void EmitTryBody (EmitContext ec)
protected override void EmitFinallyBody (EmitContext ec)
{
temp.Emit (ec);
- ec.ig.Emit (OpCodes.Call, (MethodInfo) TypeManager.void_monitor_exit_object.MetaInfo);
+ ec.Emit (OpCodes.Call, TypeManager.void_monitor_exit_object);
}
- public override void MutateHoistedGenericType (AnonymousMethodStorey storey)
- {
- expr.MutateHoistedGenericType (storey);
- temp.MutateHoistedGenericType (storey);
- Statement.MutateHoistedGenericType (storey);
- }
-
protected override void CloneTo (CloneContext clonectx, Statement t)
{
Lock target = (Lock) t;
Block.Emit (ec);
}
- public override void MutateHoistedGenericType (AnonymousMethodStorey storey)
- {
- Block.MutateHoistedGenericType (storey);
- }
-
protected override void CloneTo (CloneContext clonectx, Statement t)
{
Unchecked target = (Unchecked) t;
Block.Emit (ec);
}
- public override void MutateHoistedGenericType (AnonymousMethodStorey storey)
- {
- Block.MutateHoistedGenericType (storey);
- }
-
protected override void CloneTo (CloneContext clonectx, Statement t)
{
Checked target = (Checked) t;
Block.Emit (ec);
}
- public override void MutateHoistedGenericType (AnonymousMethodStorey storey)
- {
- Block.MutateHoistedGenericType (storey);
- }
-
protected override void CloneTo (CloneContext clonectx, Statement t)
{
Unsafe target = (Unsafe) t;
Expression type;
List<KeyValuePair<LocalInfo, Expression>> declarators;
Statement statement;
- Type expr_type;
+ TypeSpec expr_type;
Emitter[] data;
bool has_ret;
public override void EmitExit (EmitContext ec)
{
- ec.ig.Emit (OpCodes.Ldc_I4_0);
- ec.ig.Emit (OpCodes.Conv_U);
+ ec.Emit (OpCodes.Ldc_I4_0);
+ ec.Emit (OpCodes.Conv_U);
vi.EmitAssign (ec);
}
}
// TODO: Should use Binary::Add
pinned_string.Emit (ec);
- ec.ig.Emit (OpCodes.Conv_I);
+ ec.Emit (OpCodes.Conv_I);
PropertyExpr pe = new PropertyExpr (pinned_string.VariableType, TypeManager.int_get_offset_to_string_data, pinned_string.Location);
//pe.InstanceExpression = pinned_string;
pe.Resolve (new ResolveContext (ec.MemberContext)).Emit (ec);
- ec.ig.Emit (OpCodes.Add);
+ ec.Emit (OpCodes.Add);
vi.EmitAssign (ec);
}
public override void EmitExit (EmitContext ec)
{
- ec.ig.Emit (OpCodes.Ldnull);
+ ec.Emit (OpCodes.Ldnull);
pinned_string.EmitAssign (ec);
}
}
// Case 2: Array
//
if (e.Type.IsArray){
- Type array_type = TypeManager.GetElementType (e.Type);
+ TypeSpec array_type = TypeManager.GetElementType (e.Type);
//
// Provided that array_type is unmanaged,
}
}
- public override void MutateHoistedGenericType (AnonymousMethodStorey storey)
- {
- // Fixed statement cannot be used inside anonymous methods or lambdas
- throw new NotSupportedException ();
- }
-
protected override void CloneTo (CloneContext clonectx, Statement t)
{
Fixed target = (Fixed) t;
public Block VarBlock;
Expression type_expr;
- Type type;
+ TypeSpec type;
public Catch (Expression type, string name, Block block, Block var_block, Location l)
{
loc = l;
}
- public Type CatchType {
+ public TypeSpec CatchType {
get {
return type;
}
protected override void DoEmit (EmitContext ec)
{
- ILGenerator ig = ec.ig;
-
if (CatchType != null)
- ig.BeginCatchBlock (CatchType);
+ ec.BeginCatchBlock (CatchType);
else
- ig.BeginCatchBlock (TypeManager.object_type);
+ ec.BeginCatchBlock (TypeManager.object_type);
if (VarBlock != null)
VarBlock.Emit (ec);
// Only to make verifier happy
if (TypeManager.IsGenericParameter (lvr.Type))
- ig.Emit (OpCodes.Unbox_Any, lvr.Type);
+ ec.Emit (OpCodes.Unbox_Any, lvr.Type);
Expression source;
if (lvr.IsHoisted) {
lvr.EmitAssign (ec, source, false, false);
} else
- ig.Emit (OpCodes.Pop);
+ ec.Emit (OpCodes.Pop);
Block.Emit (ec);
}
}
}
- public override void MutateHoistedGenericType (AnonymousMethodStorey storey)
- {
- if (type != null)
- type = storey.MutateType (type);
- if (VarBlock != null)
- VarBlock.MutateHoistedGenericType (storey);
- Block.MutateHoistedGenericType (storey);
- }
-
protected override void CloneTo (CloneContext clonectx, Statement t)
{
Catch target = (Catch) t;
fini.Emit (ec);
}
- public override void MutateHoistedGenericType (AnonymousMethodStorey storey)
- {
- stmt.MutateHoistedGenericType (storey);
- fini.MutateHoistedGenericType (storey);
- }
-
protected override void CloneTo (CloneContext clonectx, Statement t)
{
TryFinally target = (TryFinally) t;
if (!Block.Resolve (ec))
ok = false;
- Type[] prev_catches = new Type [Specific.Count];
+ TypeSpec[] prev_catches = new TypeSpec [Specific.Count];
int last_index = 0;
foreach (Catch c in Specific){
ec.CurrentBranching.CreateSibling (c.Block, FlowBranching.SiblingType.Catch);
continue;
}
- Type resolved_type = c.CatchType;
+ TypeSpec resolved_type = c.CatchType;
for (int ii = 0; ii < last_index; ++ii) {
if (resolved_type == prev_catches [ii] || TypeManager.IsSubclassOf (resolved_type, prev_catches [ii])) {
ec.Report.Error (160, c.loc,
protected override void DoEmit (EmitContext ec)
{
- ILGenerator ig = ec.ig;
-
if (!inside_try_finally)
- ig.BeginExceptionBlock ();
+ ec.BeginExceptionBlock ();
Block.Emit (ec);
General.Emit (ec);
if (!inside_try_finally)
- ig.EndExceptionBlock ();
- }
-
- public override void MutateHoistedGenericType (AnonymousMethodStorey storey)
- {
- Block.MutateHoistedGenericType (storey);
-
- if (General != null)
- General.MutateHoistedGenericType (storey);
- if (Specific != null) {
- foreach (Catch c in Specific)
- c.MutateHoistedGenericType (storey);
- }
+ ec.EndExceptionBlock ();
}
protected override void CloneTo (CloneContext clonectx, Statement t)
TemporaryVariable local_copy;
public Statement Statement;
Expression expr;
- Type expr_type;
+ TypeSpec expr_type;
public UsingTemporary (Expression expr, Statement stmt, Location l)
{
expr_type = expr.Type;
- if (!TypeManager.ImplementsInterface (expr_type, TypeManager.idisposable_type) &&
+ if (!expr_type.ImplementsInterface (TypeManager.idisposable_type) &&
Convert.ImplicitConversion (ec, expr, TypeManager.idisposable_type, loc) == null) {
- if (!TypeManager.IsDynamicType (expr_type)) {
+ if (expr_type != InternalType.Dynamic) {
Using.Error_IsNotConvertibleToIDisposable (ec, expr);
return false;
}
if (TypeManager.void_dispose_void == null) {
TypeManager.void_dispose_void = TypeManager.GetPredefinedMethod (
- TypeManager.idisposable_type, "Dispose", loc, Type.EmptyTypes);
+ TypeManager.idisposable_type, "Dispose", loc, TypeSpec.EmptyTypes);
}
return ok;
protected override void EmitFinallyBody (EmitContext ec)
{
- ILGenerator ig = ec.ig;
if (!TypeManager.IsStruct (expr_type)) {
- Label skip = ig.DefineLabel ();
+ Label skip = ec.DefineLabel ();
local_copy.Emit (ec);
- ig.Emit (OpCodes.Brfalse, skip);
+ ec.Emit (OpCodes.Brfalse, skip);
local_copy.Emit (ec);
- ig.Emit (OpCodes.Callvirt, (MethodInfo) TypeManager.void_dispose_void.MetaInfo);
- ig.MarkLabel (skip);
+ ec.Emit (OpCodes.Callvirt, TypeManager.void_dispose_void);
+ ec.MarkLabel (skip);
return;
}
- Expression ml = Expression.MemberLookup (RootContext.ToplevelTypes.Compiler,
- ec.CurrentType, TypeManager.idisposable_type, expr_type,
- "Dispose", Location.Null);
+ MethodSpec ms = MemberCache.FindMember (expr_type,
+ MemberFilter.Method ("Dispose", 0, ParametersCompiled.EmptyReadOnlyParameters, TypeManager.void_type),
+ BindingRestriction.InstanceOnly) as MethodSpec;
- if (!(ml is MethodGroupExpr)) {
+ if (ms == null) {
local_copy.Emit (ec);
- ig.Emit (OpCodes.Box, expr_type);
- ig.Emit (OpCodes.Callvirt, (MethodInfo) TypeManager.void_dispose_void.MetaInfo);
- return;
- }
-
- MethodSpec mi = null;
-
- foreach (var mk in ((MethodGroupExpr) ml).Methods) {
- if (mk.Parameters.IsEmpty) {
- mi = mk;
- break;
- }
- }
-
- if (mi == null) {
- ec.Report.Error(-100, Mono.CSharp.Location.Null, "Internal error: No Dispose method which takes 0 parameters.");
+ ec.Emit (OpCodes.Box, expr_type);
+ ec.Emit (OpCodes.Callvirt, TypeManager.void_dispose_void);
return;
}
local_copy.AddressOf (ec, AddressOp.Load);
- ig.Emit (OpCodes.Call, (MethodInfo) mi.MetaInfo);
- }
-
- public override void MutateHoistedGenericType (AnonymousMethodStorey storey)
- {
- expr_type = storey.MutateType (expr_type);
- local_copy.MutateHoistedGenericType (storey);
- Statement.MutateHoistedGenericType (storey);
+ ec.Emit (OpCodes.Call, ms);
}
protected override void CloneTo (CloneContext clonectx, Statement t)
protected override void EmitFinallyBody (EmitContext ec)
{
- ILGenerator ig = ec.ig;
- Label skip = ig.DefineLabel ();
+ Label skip = ec.DefineLabel ();
bool emit_null_check = !TypeManager.IsValueType (var.Type);
if (emit_null_check) {
var.Emit (ec);
- ig.Emit (OpCodes.Brfalse, skip);
+ ec.Emit (OpCodes.Brfalse, skip);
}
Invocation.EmitCall (ec, false, var, TypeManager.void_dispose_void, null, loc);
if (emit_null_check)
- ig.MarkLabel (skip);
- }
-
- public override void MutateHoistedGenericType (AnonymousMethodStorey storey)
- {
- assign.MutateHoistedGenericType (storey);
- var.MutateHoistedGenericType (storey);
- stmt.MutateHoistedGenericType (storey);
+ ec.MarkLabel (skip);
}
public override bool Resolve (BlockContext ec)
if (TypeManager.void_dispose_void == null) {
TypeManager.void_dispose_void = TypeManager.GetPredefinedMethod (
- TypeManager.idisposable_type, "Dispose", loc, Type.EmptyTypes);
+ TypeManager.idisposable_type, "Dispose", loc, TypeSpec.EmptyTypes);
}
return ok;
if (assign == null)
return false;
- if (assign.Type == TypeManager.idisposable_type ||
- TypeManager.ImplementsInterface (assign.Type, TypeManager.idisposable_type)) {
+ if (assign.Type == TypeManager.idisposable_type || assign.Type.ImplementsInterface (TypeManager.idisposable_type)) {
return true;
}
Expression e = Convert.ImplicitConversionStandard (ec, assign, TypeManager.idisposable_type, var.Location);
if (e == null) {
- if (TypeManager.IsDynamicType (assign.Type)) {
+ if (assign.Type == InternalType.Dynamic) {
e = Convert.ImplicitConversionRequired (ec, assign, TypeManager.idisposable_type, loc);
var = new TemporaryVariable (e.Type, loc);
assign = new SimpleAssign (var, e, loc).ResolveStatement (ec);
protected override void DoEmit (EmitContext ec)
{
- ILGenerator ig = ec.ig;
-
copy.EmitAssign (ec, for_each.expr);
int rank = length_exprs.Length;
Label[] loop = new Label [rank];
for (int i = 0; i < rank; i++) {
- test [i] = ig.DefineLabel ();
- loop [i] = ig.DefineLabel ();
+ test [i] = ec.DefineLabel ();
+ loop [i] = ec.DefineLabel ();
if (lengths != null)
lengths [i].EmitAssign (ec, length_exprs [i]);
for (int i = 0; i < rank; i++) {
counter [i].EmitAssign (ec, zero);
- ig.Emit (OpCodes.Br, test [i]);
- ig.MarkLabel (loop [i]);
+ ec.Emit (OpCodes.Br, test [i]);
+ ec.MarkLabel (loop [i]);
}
((IAssignMethod) for_each.variable).EmitAssign (ec, conv, false, false);
statement.Emit (ec);
- ig.MarkLabel (ec.LoopBegin);
+ ec.MarkLabel (ec.LoopBegin);
for (int i = rank - 1; i >= 0; i--){
counter [i].EmitIncrement (ec);
- ig.MarkLabel (test [i]);
+ ec.MarkLabel (test [i]);
counter [i].Emit (ec);
if (lengths != null)
else
length_exprs [i].Emit (ec);
- ig.Emit (OpCodes.Blt, loop [i]);
+ ec.Emit (OpCodes.Blt, loop [i]);
}
- ig.MarkLabel (ec.LoopEnd);
- }
-
- public override void MutateHoistedGenericType (AnonymousMethodStorey storey)
- {
- for_each.expr.MutateHoistedGenericType (storey);
-
- copy.MutateHoistedGenericType (storey);
- conv.MutateHoistedGenericType (storey);
- statement.MutateHoistedGenericType (storey);
-
- for (int i = 0; i < counter.Length; i++) {
- counter [i].MutateHoistedGenericType (storey);
- if (lengths != null)
- lengths [i].MutateHoistedGenericType (storey);
- }
+ ec.MarkLabel (ec.LoopEnd);
}
}
{
class CollectionForeachStatement : Statement
{
- Type type;
+ TypeSpec type;
Expression variable, current, conv;
Statement statement;
Assign assign;
- public CollectionForeachStatement (Type type, Expression variable,
+ public CollectionForeachStatement (TypeSpec type, Expression variable,
Expression current, Statement statement,
Location loc)
{
assign.EmitStatement (ec);
statement.Emit (ec);
}
-
- public override void MutateHoistedGenericType (AnonymousMethodStorey storey)
- {
- assign.MutateHoistedGenericType (storey);
- statement.MutateHoistedGenericType (storey);
- }
}
Expression variable, expr;
PropertyExpr get_current;
MethodSpec move_next;
Expression var_type;
- Type enumerator_type;
+ TypeSpec enumerator_type;
bool enumerator_found;
public CollectionForeach (Expression var_type, Expression var,
bool GetEnumeratorFilter (ResolveContext ec, MethodSpec mi)
{
- Type return_type = mi.ReturnType;
+ TypeSpec return_type = mi.ReturnType;
//
// Ok, we can access it, now make sure that we can do something
//
if (return_type == TypeManager.ienumerator_type ||
- TypeManager.ImplementsInterface (return_type, TypeManager.ienumerator_type)) {
+ return_type.ImplementsInterface (TypeManager.ienumerator_type)) {
//
// If it is not an interface, lets try to find the methods ourselves.
// For example, if we have:
if (TypeManager.bool_movenext_void == null) {
TypeManager.bool_movenext_void = TypeManager.GetPredefinedMethod (
- TypeManager.ienumerator_type, "MoveNext", loc, Type.EmptyTypes);
+ TypeManager.ienumerator_type, "MoveNext", loc, TypeSpec.EmptyTypes);
}
if (TypeManager.ienumerator_getcurrent == null) {
//
// Retrieves a `public bool MoveNext ()' method from the Type `t'
//
- bool FetchMoveNext (Type t)
+ bool FetchMoveNext (TypeSpec t)
{
- MemberInfo[] move_next_list = TypeManager.MemberLookup (null, null, t,
- MemberTypes.Method,
- BindingFlags.Public | BindingFlags.Instance,
- "MoveNext", null);
-
- if (move_next_list == null)
- return false;
+ move_next = MemberCache.FindMember (t,
+ MemberFilter.Method ("MoveNext", 0, ParametersCompiled.EmptyReadOnlyParameters, TypeManager.bool_type),
+ BindingRestriction.InstanceOnly) as MethodSpec;
- foreach (MemberInfo m in move_next_list){
- MethodInfo mi = (MethodInfo) m;
-
- if ((TypeManager.GetParameterData (mi).Count == 0) &&
- TypeManager.TypeToCoreType (mi.ReturnType) == TypeManager.bool_type) {
- move_next = Import.CreateMethod (mi);
- return true;
- }
- }
-
- return false;
+ return move_next != null && (move_next.Modifiers & Modifiers.PUBLIC) != 0;
}
//
// Retrieves a `public T get_Current ()' method from the Type `t'
//
- bool FetchGetCurrent (ResolveContext ec, Type t)
+ bool FetchGetCurrent (ResolveContext ec, TypeSpec t)
{
PropertyExpr pe = Expression.MemberLookup (ec.Compiler,
- ec.CurrentType, t, "Current", MemberTypes.Property,
- Expression.AllBindingFlags, loc) as PropertyExpr;
+ ec.CurrentType, t, "Current", 0, MemberKind.Property,
+ BindingRestriction.AccessibleOnly, loc) as PropertyExpr;
if (pe == null)
return false;
TypeManager.CSharpName (expr.Type));
}
- bool IsOverride (MethodSpec ms)
+ bool TryType (ResolveContext ec, TypeSpec t)
{
- MethodInfo m = (MethodInfo) ms.MetaInfo;
- m = (MethodInfo) TypeManager.DropGenericMethodArguments (m);
-
- if (!m.IsVirtual || ((m.Attributes & MethodAttributes.NewSlot) != 0))
- return false;
- if (m is MethodBuilder)
- return true;
-
- MethodInfo base_method = m.GetBaseDefinition ();
- return base_method != m;
- }
+ var mg = Expression.MemberLookup (ec.Compiler, ec.CurrentType, null, t, "GetEnumerator", 0,
+ MemberKind.Method, BindingRestriction.NoOverrides | BindingRestriction.InstanceOnly, loc) as MethodGroupExpr;
- bool TryType (ResolveContext ec, Type t)
- {
- MethodGroupExpr mg = Expression.MemberLookup (ec.Compiler,
- ec.CurrentType, t, "GetEnumerator", MemberTypes.Method,
- Expression.AllBindingFlags, loc) as MethodGroupExpr;
if (mg == null)
return false;
MethodSpec result = null;
MethodSpec tmp_move_next = null;
PropertyExpr tmp_get_cur = null;
- Type tmp_enumerator_type = enumerator_type;
- foreach (var mi in mg.Methods) {
+ TypeSpec tmp_enumerator_type = enumerator_type;
+ foreach (MethodSpec mi in mg.Methods) {
if (!mi.Parameters.IsEmpty)
continue;
// Check whether GetEnumerator is public
- if ((mi.MetaInfo.Attributes & MethodAttributes.Public) != MethodAttributes.Public)
- continue;
-
- if (IsOverride (mi))
+ if ((mi.Modifiers & Modifiers.AccessibilityMask) != Modifiers.PUBLIC)
continue;
enumerator_found = true;
if (!TypeManager.IsGenericType (mi.ReturnType))
continue;
- MethodBase mb = TypeManager.DropGenericMethodArguments (mi);
ec.Report.SymbolRelatedToPreviousError (t);
ec.Report.Error(1640, loc, "foreach statement cannot operate on variables of type `{0}' " +
- "because it contains multiple implementation of `{1}'. Try casting to a specific implementation",
- TypeManager.CSharpName (t), TypeManager.CSharpSignature (mb));
+ "because it contains multiple implementation of `{1}'. Try casting to a specific implementation",
+ TypeManager.CSharpName (t), TypeManager.generic_ienumerable_type.GetSignatureForError ());
return false;
}
// Always prefer generics enumerators
if (!TypeManager.IsGenericType (mi.ReturnType)) {
- if (TypeManager.ImplementsInterface (mi.DeclaringType, result.DeclaringType) ||
- TypeManager.ImplementsInterface (result.DeclaringType, mi.DeclaringType))
+ if (mi.DeclaringType.ImplementsInterface (result.DeclaringType) ||
+ result.DeclaringType.ImplementsInterface (mi.DeclaringType))
continue;
- ec.Report.SymbolRelatedToPreviousError (result.MetaInfo);
- ec.Report.SymbolRelatedToPreviousError (mi.MetaInfo);
+ ec.Report.SymbolRelatedToPreviousError (result);
+ ec.Report.SymbolRelatedToPreviousError (mi);
ec.Report.Warning (278, 2, loc, "`{0}' contains ambiguous implementation of `{1}' pattern. Method `{2}' is ambiguous with method `{3}'",
- TypeManager.CSharpName (t), "enumerable", TypeManager.CSharpSignature (result.MetaInfo), TypeManager.CSharpSignature (mi.MetaInfo));
+ TypeManager.CSharpName (t), "enumerable", result.GetSignatureForError (), mi.GetSignatureForError ());
return false;
}
}
move_next = tmp_move_next;
get_current = tmp_get_cur;
enumerator_type = tmp_enumerator_type;
- var mi = new [] { result };
- get_enumerator = new MethodGroupExpr (mi, enumerator_type, loc);
+ get_enumerator = new MethodGroupExpr (result, enumerator_type, loc);
if (t != expr.Type) {
expr = Convert.ExplicitConversion (
return false;
}
- bool ProbeCollectionType (ResolveContext ec, Type t)
+ bool ProbeCollectionType (ResolveContext ec, TypeSpec t)
{
int errors = ec.Report.Errors;
- for (Type tt = t; tt != null && tt != TypeManager.object_type;){
+ for (TypeSpec tt = t; tt != null && tt != TypeManager.object_type;){
if (TryType (ec, tt))
return true;
tt = tt.BaseType;
//
// Now try to find the method in the interfaces
//
- Type [] ifaces = TypeManager.GetInterfaces (t);
- foreach (Type i in ifaces){
- if (TryType (ec, i))
- return true;
+ for (TypeSpec tt = t; tt != null && tt != TypeManager.object_type; ) {
+ if (tt.Interfaces != null) {
+ foreach (TypeSpec i in tt.Interfaces) {
+ if (TryType (ec, i))
+ return true;
+ }
+ }
+ tt = tt.BaseType;
}
return false;
{
enumerator_type = TypeManager.ienumerator_type;
- bool is_dynamic = TypeManager.IsDynamicType (expr.Type);
+ bool is_dynamic = expr.Type == InternalType.Dynamic;
if (is_dynamic)
expr = Convert.ImplicitConversionRequired (ec, expr, TypeManager.ienumerable_type, loc);
if (ve != null) {
// Infer implicitly typed local variable from foreach enumerable type
var_type = new TypeExpression (
- is_dynamic ? InternalType.Dynamic : get_current.PropertyInfo.PropertyType,
+ is_dynamic ? InternalType.Dynamic : get_current.Type,
var_type.Location);
}
Expression move_next_expr;
{
- var mi = new [] { move_next };
+ var mi = new List<MemberSpec> (1) { move_next };
MethodGroupExpr mg = new MethodGroupExpr (mi, var_type.Type, loc);
mg.InstanceExpression = enumerator;
loop = new While (new BooleanExpression (move_next_expr), block, loc);
- bool implements_idisposable = TypeManager.ImplementsInterface (enumerator_type, TypeManager.idisposable_type);
+ bool implements_idisposable = enumerator_type.ImplementsInterface (TypeManager.idisposable_type);
if (implements_idisposable || !enumerator_type.IsSealed) {
wrapper = new DisposableWrapper (this, implements_idisposable);
} else {
parent.EmitLoopInit (ec);
parent.EmitLoopBody (ec);
}
-
- public override void MutateHoistedGenericType (AnonymousMethodStorey storey)
- {
- throw new NotSupportedException ();
- }
}
sealed class DisposableWrapper : ExceptionStatement
if (TypeManager.void_dispose_void == null) {
TypeManager.void_dispose_void = TypeManager.GetPredefinedMethod (
- TypeManager.idisposable_type, "Dispose", loc, Type.EmptyTypes);
+ TypeManager.idisposable_type, "Dispose", loc, TypeSpec.EmptyTypes);
}
return ok;
}
{
Expression instance = parent.enumerator;
if (!TypeManager.IsValueType (parent.enumerator_type)) {
- ILGenerator ig = ec.ig;
parent.enumerator.Emit (ec);
- Label call_dispose = ig.DefineLabel ();
+ Label call_dispose = ec.DefineLabel ();
if (!implements_idisposable) {
- ec.ig.Emit (OpCodes.Isinst, TypeManager.idisposable_type);
+ ec.Emit (OpCodes.Isinst, TypeManager.idisposable_type);
LocalTemporary temp = new LocalTemporary (TypeManager.idisposable_type);
temp.Store (ec);
temp.Emit (ec);
instance = temp;
}
- ig.Emit (OpCodes.Brtrue_S, call_dispose);
+ ec.Emit (OpCodes.Brtrue_S, call_dispose);
// using 'endfinally' to empty the evaluation stack
- ig.Emit (OpCodes.Endfinally);
- ig.MarkLabel (call_dispose);
+ ec.Emit (OpCodes.Endfinally);
+ ec.MarkLabel (call_dispose);
}
Invocation.EmitCall (ec, false, instance, TypeManager.void_dispose_void, null, loc);
}
-
- public override void MutateHoistedGenericType (AnonymousMethodStorey storey)
- {
- throw new NotSupportedException ();
- }
}
bool ResolveLoop (BlockContext ec)
{
loop.Emit (ec);
}
-
- public override void MutateHoistedGenericType (AnonymousMethodStorey storey)
- {
- enumerator_type = storey.MutateType (enumerator_type);
- init.MutateHoistedGenericType (storey);
- loop.MutateHoistedGenericType (storey);
- }
}
Expression type;
if (expr.Type == TypeManager.string_type) {
statement = new ArrayForeach (this, 1);
- } else if (expr.Type.IsArray) {
- statement = new ArrayForeach (this, expr.Type.GetArrayRank ());
+ } else if (expr.Type is ArrayContainer) {
+ statement = new ArrayForeach (this, ((ArrayContainer) expr.Type).Rank);
} else {
if (expr.eclass == ExprClass.MethodGroup || expr is AnonymousMethodExpression) {
ec.Report.Error (446, expr.Location, "Foreach statement cannot operate on a `{0}'",
protected override void DoEmit (EmitContext ec)
{
- ILGenerator ig = ec.ig;
-
Label old_begin = ec.LoopBegin, old_end = ec.LoopEnd;
- ec.LoopBegin = ig.DefineLabel ();
- ec.LoopEnd = ig.DefineLabel ();
+ ec.LoopBegin = ec.DefineLabel ();
+ ec.LoopEnd = ec.DefineLabel ();
statement.Emit (ec);
target.expr = expr.Clone (clonectx);
target.statement = statement.Clone (clonectx);
}
-
- public override void MutateHoistedGenericType (AnonymousMethodStorey storey)
- {
- statement.MutateHoistedGenericType (storey);
- }
}
}
namespace Mono.CSharp {
- class ReferenceEquality<T> : IEqualityComparer<T> where T : class
+ sealed class ReferenceEquality<T> : IEqualityComparer<T> where T : class
{
public static readonly IEqualityComparer<T> Default = new ReferenceEquality<T> ();
}
}
- class Tuple<T1, T2>
+ class Tuple<T1, T2> : IEquatable<Tuple<T1, T2>>
{
public Tuple (T1 item1, T2 item2)
{
public T1 Item1 { get; private set; }
public T2 Item2 { get; private set; }
+
+ public override int GetHashCode ()
+ {
+ return Item1.GetHashCode () ^ Item2.GetHashCode ();
+ }
+
+ #region IEquatable<Tuple<T1,T2>> Members
+
+ public bool Equals (Tuple<T1, T2> other)
+ {
+ return EqualityComparer<T1>.Default.Equals (Item1, other.Item1) &&
+ EqualityComparer<T2>.Default.Equals (Item2, other.Item2);
+ }
+
+ #endregion
+ }
+
+ static class Tuple
+ {
+ public static Tuple<T1, T2> Create<T1, T2> (T1 item1, T2 item2)
+ {
+ return new Tuple<T1, T2> (item1, item2);
+ }
}
public class Accessors {
}
}
- class PartialMethodDefinitionInfo : MethodInfo
- {
- MethodOrOperator mc;
- MethodAttributes attrs;
-
- public PartialMethodDefinitionInfo (MethodOrOperator mc)
- {
- this.mc = mc;
- if ((mc.ModFlags & Modifiers.STATIC) != 0)
- attrs = MethodAttributes.Static;
- }
-
- public override MethodInfo GetBaseDefinition ()
- {
- throw new NotImplementedException ();
- }
-
- public override ICustomAttributeProvider ReturnTypeCustomAttributes
- {
- get { throw new NotImplementedException (); }
- }
-
- public override MethodAttributes Attributes
- {
- get { return attrs; }
- }
-
- public override MethodImplAttributes GetMethodImplementationFlags ()
- {
- throw new NotImplementedException ();
- }
-
- public override ParameterInfo [] GetParameters ()
- {
- throw new NotImplementedException ();
- }
-
- public override object Invoke (object obj, BindingFlags invokeAttr, Binder binder, object [] parameters, CultureInfo culture)
- {
- throw new NotImplementedException ();
- }
-
- public override RuntimeMethodHandle MethodHandle
- {
- get { throw new NotImplementedException (); }
- }
-
- public override Type DeclaringType
- {
- get { return mc.Parent.TypeBuilder; }
- }
-
- public override object [] GetCustomAttributes (Type attributeType, bool inherit)
- {
- throw new NotImplementedException ();
- }
-
- public override object [] GetCustomAttributes (bool inherit)
- {
- throw new NotImplementedException ();
- }
-
- public override Type ReturnType {
- get {
- return mc.MemberType;
- }
- }
-
- public override bool IsDefined (Type attributeType, bool inherit)
- {
- throw new NotImplementedException ();
- }
-
- public override string Name
- {
- get { return mc.Name; }
- }
-
- public override Type ReflectedType
- {
- get { throw new NotImplementedException (); }
- }
- }
-
-#if NET_4_0 || MS_COMPATIBLE
- [System.Diagnostics.DebuggerDisplay ("Dynamic type")]
-#endif
- class DynamicType : Type
- {
- public override Assembly Assembly {
- get { return CodeGen.Assembly.Builder; }
- }
-
- public override string AssemblyQualifiedName {
- get { throw new NotImplementedException (); }
- }
-
- public override Type BaseType {
- get { return null; }
- }
-
- public override string FullName {
- get { return UnderlyingSystemType.FullName; }
- }
-
- public override Guid GUID {
- get { throw new NotImplementedException (); }
- }
-
- protected override TypeAttributes GetAttributeFlagsImpl ()
- {
- return UnderlyingSystemType.Attributes;
- }
-
- protected override ConstructorInfo GetConstructorImpl (BindingFlags bindingAttr, Binder binder, CallingConventions callConvention, Type[] types, ParameterModifier[] modifiers)
- {
- throw new NotImplementedException ();
- }
-
- public override ConstructorInfo[] GetConstructors (BindingFlags bindingAttr)
- {
- throw new NotImplementedException ();
- }
-
- public override Type GetElementType ()
- {
- throw new NotImplementedException ();
- }
-
- public override EventInfo GetEvent (string name, BindingFlags bindingAttr)
- {
- throw new NotImplementedException ();
- }
-
- public override EventInfo[] GetEvents (BindingFlags bindingAttr)
- {
- throw new NotImplementedException ();
- }
-
- public override FieldInfo GetField (string name, BindingFlags bindingAttr)
- {
- throw new NotImplementedException ();
- }
-
- public override FieldInfo[] GetFields (BindingFlags bindingAttr)
- {
- throw new NotImplementedException ();
- }
-
- public override Type GetInterface (string name, bool ignoreCase)
- {
- throw new NotImplementedException ();
- }
-
- public override Type[] GetInterfaces ()
- {
- return Type.EmptyTypes;
- }
-
- public override MemberInfo[] GetMembers (BindingFlags bindingAttr)
- {
- throw new NotImplementedException ();
- }
-
- protected override MethodInfo GetMethodImpl (string name, BindingFlags bindingAttr, Binder binder, CallingConventions callConvention, Type[] types, ParameterModifier[] modifiers)
- {
- throw new NotImplementedException ();
- }
-
- public override MethodInfo[] GetMethods (BindingFlags bindingAttr)
- {
- throw new NotImplementedException ();
- }
-
- public override Type GetNestedType (string name, BindingFlags bindingAttr)
- {
- throw new NotImplementedException ();
- }
-
- public override Type[] GetNestedTypes (BindingFlags bindingAttr)
- {
- throw new NotImplementedException ();
- }
-
- public override PropertyInfo[] GetProperties (BindingFlags bindingAttr)
- {
- throw new NotImplementedException ();
- }
-
- protected override PropertyInfo GetPropertyImpl (string name, BindingFlags bindingAttr, Binder binder, Type returnType, Type[] types, ParameterModifier[] modifiers)
- {
- throw new NotImplementedException ();
- }
-
- protected override bool HasElementTypeImpl ()
- {
- return false;
- }
-
- public override object InvokeMember (string name, BindingFlags invokeAttr, Binder binder, object target, object[] args, ParameterModifier[] modifiers, System.Globalization.CultureInfo culture, string[] namedParameters)
- {
- throw new NotImplementedException ();
- }
-
- protected override bool IsArrayImpl ()
- {
- return false;
- }
-
- protected override bool IsByRefImpl ()
- {
- return false;
- }
-
- protected override bool IsCOMObjectImpl ()
- {
- return false;
- }
-
- protected override bool IsPointerImpl ()
- {
- return false;
- }
-
- protected override bool IsPrimitiveImpl ()
- {
- return false;
- }
-
- public override Module Module {
- get { return UnderlyingSystemType.Module; }
- }
-
- public override string Namespace {
- get { return UnderlyingSystemType.Namespace; }
- }
-
- public override Type UnderlyingSystemType {
- get { return TypeManager.object_type; }
- }
-
- public override object[] GetCustomAttributes (Type attributeType, bool inherit)
- {
- return new object [0];
- }
-
- public override object[] GetCustomAttributes (bool inherit)
- {
- return new object [0];
- }
-
- public override bool IsDefined (Type attributeType, bool inherit)
- {
- throw new NotImplementedException ();
- }
-
- public override string Name {
- get { return UnderlyingSystemType.Name; }
- }
-
- public override string ToString ()
- {
- return UnderlyingSystemType.ToString ();
- }
-
- public override RuntimeTypeHandle TypeHandle {
- get { return UnderlyingSystemType.TypeHandle; }
- }
-
- public override Type MakeByRefType ()
- {
- // TODO: Wrong, hides dynamic type
- return UnderlyingSystemType.MakeByRefType ();
- }
- }
-
-#if NET_4_0 || MS_COMPATIBLE
- [System.Diagnostics.DebuggerDisplay ("Dynamic array type")]
-#endif
- class DynamicArrayType : Type
- {
- readonly int rank;
- Type reflection_type;
-
- public DynamicArrayType (int rank)
- {
- this.rank = rank;
- }
-
- public override Assembly Assembly {
- get { return UnderlyingSystemType.Assembly; }
- }
-
- public override string AssemblyQualifiedName {
- get { throw new NotImplementedException (); }
- }
-
- public override Type BaseType {
- get { return TypeManager.array_type; }
- }
-
- public override string FullName {
- get { return UnderlyingSystemType.FullName; }
- }
-
- public override Guid GUID {
- get { throw new NotImplementedException (); }
- }
-
- protected override TypeAttributes GetAttributeFlagsImpl ()
- {
- return UnderlyingSystemType.Attributes;
- }
-
- public override int GetArrayRank ()
- {
- return rank;
- }
-
- protected override ConstructorInfo GetConstructorImpl (BindingFlags bindingAttr, Binder binder, CallingConventions callConvention, Type[] types, ParameterModifier[] modifiers)
- {
- throw new NotImplementedException ();
- }
-
- public override ConstructorInfo[] GetConstructors (BindingFlags bindingAttr)
- {
- throw new NotImplementedException ();
- }
-
- public override Type GetElementType ()
- {
- return InternalType.Dynamic;
- }
-
- public override EventInfo GetEvent (string name, BindingFlags bindingAttr)
- {
- throw new NotImplementedException ();
- }
-
- public override EventInfo[] GetEvents (BindingFlags bindingAttr)
- {
- throw new NotImplementedException ();
- }
-
- public override FieldInfo GetField (string name, BindingFlags bindingAttr)
- {
- throw new NotImplementedException ();
- }
-
- public override FieldInfo[] GetFields (BindingFlags bindingAttr)
- {
- throw new NotImplementedException ();
- }
-
- public override Type GetInterface (string name, bool ignoreCase)
- {
- throw new NotImplementedException ();
- }
-
- public override Type[] GetInterfaces ()
- {
- return Type.EmptyTypes;
- }
-
- public override MemberInfo[] GetMembers (BindingFlags bindingAttr)
- {
- throw new NotImplementedException ();
- }
-
- protected override MethodInfo GetMethodImpl (string name, BindingFlags bindingAttr, Binder binder, CallingConventions callConvention, Type[] types, ParameterModifier[] modifiers)
- {
- throw new NotImplementedException ();
- }
-
- public override MethodInfo[] GetMethods (BindingFlags bindingAttr)
- {
- throw new NotImplementedException ();
- }
-
- public override Type GetNestedType (string name, BindingFlags bindingAttr)
- {
- throw new NotImplementedException ();
- }
-
- public override Type[] GetNestedTypes (BindingFlags bindingAttr)
- {
- throw new NotImplementedException ();
- }
-
- public override PropertyInfo[] GetProperties (BindingFlags bindingAttr)
- {
- throw new NotImplementedException ();
- }
-
- protected override PropertyInfo GetPropertyImpl (string name, BindingFlags bindingAttr, Binder binder, Type returnType, Type[] types, ParameterModifier[] modifiers)
- {
- throw new NotImplementedException ();
- }
-
- protected override bool HasElementTypeImpl ()
- {
- return true;
- }
-
- public override object InvokeMember (string name, BindingFlags invokeAttr, Binder binder, object target, object[] args, ParameterModifier[] modifiers, System.Globalization.CultureInfo culture, string[] namedParameters)
- {
- throw new NotImplementedException ();
- }
-
- protected override bool IsArrayImpl ()
- {
- return true;
- }
-
- protected override bool IsByRefImpl ()
- {
- return false;
- }
-
- protected override bool IsCOMObjectImpl ()
- {
- return false;
- }
-
- protected override bool IsPointerImpl ()
- {
- return false;
- }
-
- protected override bool IsPrimitiveImpl ()
- {
- return false;
- }
-
- public override Module Module {
- get { return UnderlyingSystemType.Module; }
- }
-
- public override string Namespace {
- get { return UnderlyingSystemType.Namespace; }
- }
-
- public override Type UnderlyingSystemType {
- get {
- if (reflection_type == null) {
- reflection_type = rank == 1 ?
- TypeManager.object_type.MakeArrayType () :
- TypeManager.object_type.MakeArrayType (rank);
- }
-
- return reflection_type;
- }
- }
-
- public override object[] GetCustomAttributes (Type attributeType, bool inherit)
- {
- return new object [0];
- }
-
- public override object[] GetCustomAttributes (bool inherit)
- {
- return new object [0];
- }
-
- public override bool IsDefined (Type attributeType, bool inherit)
- {
- throw new NotImplementedException ();
- }
-
- public override string Name {
- get { return UnderlyingSystemType.Name; }
- }
-
- public override string ToString ()
- {
- return UnderlyingSystemType.ToString ();
- }
-
- public override RuntimeTypeHandle TypeHandle {
- get { return UnderlyingSystemType.TypeHandle; }
- }
- }
-
public class UnixUtils {
[System.Runtime.InteropServices.DllImport ("libc", EntryPoint="isatty")]
extern static int _isatty (int fd);
symwriter.DefineCapturedScope (scope_id, id, captured_name);
}
- public static void OpenCompilerGeneratedBlock (ILGenerator ig)
+ public static void OpenCompilerGeneratedBlock (EmitContext ec)
{
if (symwriter != null) {
- int offset = symwriter.GetILOffset (ig);
+ int offset = symwriter.GetILOffset (ec.ig);
symwriter.OpenCompilerGeneratedBlock (offset);
}
}
- public static void CloseCompilerGeneratedBlock (ILGenerator ig)
+ public static void CloseCompilerGeneratedBlock (EmitContext ec)
{
if (symwriter != null) {
- int offset = symwriter.GetILOffset (ig);
+ int offset = symwriter.GetILOffset (ec.ig);
symwriter.CloseCompilerGeneratedBlock (offset);
}
}
- public static void StartIteratorBody (ILGenerator ig)
+ public static void StartIteratorBody (EmitContext ec)
{
if (symwriter != null) {
- int offset = symwriter.GetILOffset (ig);
+ int offset = symwriter.GetILOffset (ec.ig);
symwriter.StartIteratorBody (offset);
}
}
- public static void EndIteratorBody (ILGenerator ig)
+ public static void EndIteratorBody (EmitContext ec)
{
if (symwriter != null) {
- int offset = symwriter.GetILOffset (ig);
+ int offset = symwriter.GetILOffset (ec.ig);
symwriter.EndIteratorBody (offset);
}
}
- public static void StartIteratorDispatcher (ILGenerator ig)
+ public static void StartIteratorDispatcher (EmitContext ec)
{
if (symwriter != null) {
- int offset = symwriter.GetILOffset (ig);
+ int offset = symwriter.GetILOffset (ec.ig);
symwriter.StartIteratorDispatcher (offset);
}
}
- public static void EndIteratorDispatcher (ILGenerator ig)
+ public static void EndIteratorDispatcher (EmitContext ec)
{
if (symwriter != null) {
- int offset = symwriter.GetILOffset (ig);
+ int offset = symwriter.GetILOffset (ec.ig);
symwriter.EndIteratorDispatcher (offset);
}
}
// Copyright 2003-2008 Novell, Inc.
//
-//
-// We will eventually remove the SIMPLE_SPEEDUP, and should never change
-// the behavior of the compilation. This can be removed if we rework
-// the code to get a list of namespaces available.
-//
-#define SIMPLE_SPEEDUP
-
using System;
using System.IO;
using System.Globalization;
using System.Text;
using System.Runtime.CompilerServices;
using System.Diagnostics;
+using System.Linq;
namespace Mono.CSharp {
//
// A list of core types that the compiler requires or uses
//
- static public Type object_type;
- static public Type value_type;
- static public Type string_type;
- static public Type int32_type;
- static public Type uint32_type;
- static public Type int64_type;
- static public Type uint64_type;
- static public Type float_type;
- static public Type double_type;
- static public Type char_type;
- static public Type short_type;
- static public Type decimal_type;
- static public Type bool_type;
- static public Type sbyte_type;
- static public Type byte_type;
- static public Type ushort_type;
- static public Type enum_type;
- static public Type delegate_type;
- static public Type multicast_delegate_type;
- static public Type void_type;
- static public Type null_type;
- static public Type array_type;
- static public Type runtime_handle_type;
- static public Type type_type;
- static public Type ienumerator_type;
- static public Type ienumerable_type;
- static public Type idisposable_type;
- static public Type iasyncresult_type;
- static public Type asynccallback_type;
- static public Type intptr_type;
- static public Type uintptr_type;
- static public Type runtime_field_handle_type;
- static public Type runtime_argument_handle_type;
- static public Type attribute_type;
- static public Type void_ptr_type;
- static public Type exception_type;
-
- static public Type typed_reference_type;
- static public Type arg_iterator_type;
- static public Type mbr_type;
- public static Type runtime_helpers_type;
+ static public PredefinedTypeSpec object_type;
+ static public PredefinedTypeSpec value_type;
+ static public PredefinedTypeSpec string_type;
+ static public PredefinedTypeSpec int32_type;
+ static public PredefinedTypeSpec uint32_type;
+ static public PredefinedTypeSpec int64_type;
+ static public PredefinedTypeSpec uint64_type;
+ static public PredefinedTypeSpec float_type;
+ static public PredefinedTypeSpec double_type;
+ static public PredefinedTypeSpec char_type;
+ static public PredefinedTypeSpec short_type;
+ static public PredefinedTypeSpec decimal_type;
+ static public PredefinedTypeSpec bool_type;
+ static public PredefinedTypeSpec sbyte_type;
+ static public PredefinedTypeSpec byte_type;
+ static public PredefinedTypeSpec ushort_type;
+ static public PredefinedTypeSpec enum_type;
+ static public PredefinedTypeSpec delegate_type;
+ static public PredefinedTypeSpec multicast_delegate_type;
+ static public PredefinedTypeSpec void_type;
+ static public PredefinedTypeSpec array_type;
+ static public PredefinedTypeSpec runtime_handle_type;
+ static public PredefinedTypeSpec type_type;
+ static public PredefinedTypeSpec ienumerator_type;
+ static public PredefinedTypeSpec ienumerable_type;
+ static public PredefinedTypeSpec idisposable_type;
+ static public PredefinedTypeSpec intptr_type;
+ static public PredefinedTypeSpec uintptr_type;
+ static public PredefinedTypeSpec runtime_field_handle_type;
+ static public PredefinedTypeSpec attribute_type;
+ static public PredefinedTypeSpec exception_type;
+
+
+ static public TypeSpec null_type;
+ static public TypeSpec typed_reference_type;
+ static public TypeSpec arg_iterator_type;
+ static public TypeSpec mbr_type;
+ public static TypeSpec runtime_helpers_type;
+ static public TypeSpec iasyncresult_type;
+ static public TypeSpec asynccallback_type;
+ static public TypeSpec runtime_argument_handle_type;
+ static public TypeSpec void_ptr_type;
//
// C# 2.0
//
- static internal Type isvolatile_type;
- static public Type generic_ilist_type;
- static public Type generic_icollection_type;
- static public Type generic_ienumerator_type;
- static public Type generic_ienumerable_type;
- static public Type generic_nullable_type;
+ static internal TypeSpec isvolatile_type;
+ static public TypeSpec generic_ilist_type;
+ static public TypeSpec generic_icollection_type;
+ static public TypeSpec generic_ienumerator_type;
+ static public TypeSpec generic_ienumerable_type;
+ static public TypeSpec generic_nullable_type;
//
// C# 3.0
//
- static internal Type expression_type;
- public static Type parameter_expression_type;
- public static Type fieldinfo_type;
- public static Type methodinfo_type;
- public static Type ctorinfo_type;
+ static internal TypeSpec expression_type;
+ public static TypeSpec parameter_expression_type;
+ public static TypeSpec fieldinfo_type;
+ public static TypeSpec methodinfo_type;
+ public static TypeSpec ctorinfo_type;
//
// C# 4.0
//
- public static Type call_site_type;
- public static Type generic_call_site_type;
+ public static TypeSpec call_site_type;
+ public static TypeSpec generic_call_site_type;
public static TypeExpr binder_type;
- public static Type binder_flags;
+ public static TypeSpec binder_flags;
//
// Expressions representing the internal types. Used during declaration
static public TypeExpr system_int64_expr, system_uint64_expr;
static public TypeExpr system_char_expr, system_void_expr;
static public TypeExpr system_valuetype_expr;
- static public TypeExpr system_intptr_expr;
public static TypeExpr expression_type_expr;
//
// These methods are called by code generated by the compiler
//
- static public FieldInfo string_empty;
+ static public FieldSpec string_empty;
static public MethodSpec system_type_get_type_from_handle;
static public MethodSpec bool_movenext_void;
static public MethodSpec void_dispose_void;
//
// The constructors.
//
- static public ConstructorInfo void_decimal_ctor_five_args;
- static public ConstructorInfo void_decimal_ctor_int_arg;
- public static ConstructorInfo void_decimal_ctor_long_arg;
-
- static Dictionary<TypeBuilder, DeclSpace> builder_to_declspace;
-
- static Dictionary<Type, MemberCache> builder_to_member_cache;
-
- // <remarks>
- // Tracks the interfaces implemented by typebuilders. We only
- // enter those who do implement or or more interfaces
- // </remarks>
- static Dictionary<Type, Type[]> builder_to_ifaces;
-
- // <remarks>
- // Maps a MethodBase to its ParameterData (either InternalParameters or ReflectionParameters)
- // <remarks>
- static Dictionary<MemberInfo, AParametersCollection> method_params;
-
- // <remarks>
- // A hash table from override methods to their base virtual method.
- // <remarks>
- static Dictionary<MethodBase, MethodBase> method_overrides;
-
- // <remarks>
- // Keeps track of methods
- // </remarks>
-
- static Dictionary<MethodBase, IMethodData> builder_to_method;
-
- // <remarks>
- // Contains all public types from referenced assemblies.
- // This member is used only if CLS Compliance verification is required.
- // </remarks>
- public static Dictionary<string, object> AllClsTopLevelTypes;
-
- static Dictionary<FieldInfo, FieldBase> fieldbuilders_to_fields;
- static Dictionary<PropertyInfo, PropertyBase> propertybuilder_to_property;
- static Dictionary<FieldInfo, ConstSpec> fields;
- static Dictionary<EventInfo, EventSpec> events;
- static Dictionary<Assembly, bool> assembly_internals_vis_attrs;
- static Dictionary<GenericTypeParameterBuilder, TypeParameter> builder_to_type_param;
- static Dictionary<Type, Type[]> iface_cache;
+ static public MethodSpec void_decimal_ctor_five_args;
+ static public MethodSpec void_decimal_ctor_int_arg;
+ public static MethodSpec void_decimal_ctor_long_arg;
- public static void CleanUp ()
- {
- // Lets get everything clean so that we can collect before generating code
- builder_to_declspace = null;
- builder_to_member_cache = null;
- builder_to_ifaces = null;
- builder_to_type_param = null;
- method_params = null;
- builder_to_method = null;
- iface_cache = null;
-
- fields = null;
- events = null;
- type_hash = null;
- propertybuilder_to_property = null;
-
- TypeHandle.CleanUp ();
- }
+ static Dictionary<Assembly, bool> assembly_internals_vis_attrs;
//
// These are expressions that represent some of the internal data types, used
// elsewhere
//
- static void InitExpressionTypes ()
- {
- system_object_expr = new TypeLookupExpression ("System", "Object");
- system_string_expr = new TypeLookupExpression ("System", "String");
- system_boolean_expr = new TypeLookupExpression ("System", "Boolean");
- system_decimal_expr = new TypeLookupExpression ("System", "Decimal");
- system_single_expr = new TypeLookupExpression ("System", "Single");
- system_double_expr = new TypeLookupExpression ("System", "Double");
- system_sbyte_expr = new TypeLookupExpression ("System", "SByte");
- system_byte_expr = new TypeLookupExpression ("System", "Byte");
- system_int16_expr = new TypeLookupExpression ("System", "Int16");
- system_uint16_expr = new TypeLookupExpression ("System", "UInt16");
- system_int32_expr = new TypeLookupExpression ("System", "Int32");
- system_uint32_expr = new TypeLookupExpression ("System", "UInt32");
- system_int64_expr = new TypeLookupExpression ("System", "Int64");
- system_uint64_expr = new TypeLookupExpression ("System", "UInt64");
- system_char_expr = new TypeLookupExpression ("System", "Char");
- system_void_expr = new TypeLookupExpression ("System", "Void");
- system_valuetype_expr = new TypeLookupExpression ("System", "ValueType");
- system_intptr_expr = new TypeLookupExpression ("System", "IntPtr");
+ public static void InitExpressionTypes ()
+ {
+ system_object_expr = new TypeLookupExpression (object_type);
+ system_string_expr = new TypeLookupExpression (string_type);
+ system_boolean_expr = new TypeLookupExpression (bool_type);
+ system_decimal_expr = new TypeLookupExpression (decimal_type);
+ system_single_expr = new TypeLookupExpression (float_type);
+ system_double_expr = new TypeLookupExpression (double_type);
+ system_sbyte_expr = new TypeLookupExpression (sbyte_type);
+ system_byte_expr = new TypeLookupExpression (byte_type);
+ system_int16_expr = new TypeLookupExpression (short_type);
+ system_uint16_expr = new TypeLookupExpression (ushort_type);
+ system_int32_expr = new TypeLookupExpression (int32_type);
+ system_uint32_expr = new TypeLookupExpression (uint32_type);
+ system_int64_expr = new TypeLookupExpression (int64_type);
+ system_uint64_expr = new TypeLookupExpression (uint64_type);
+ system_char_expr = new TypeLookupExpression (char_type);
+ system_void_expr = new TypeLookupExpression (void_type);
+ system_valuetype_expr = new TypeLookupExpression (value_type);
}
static TypeManager ()
static public void Reset ()
{
- object_type = null;
-
- InitExpressionTypes ();
-
- builder_to_declspace = new Dictionary<TypeBuilder, DeclSpace> (ReferenceEquality<TypeBuilder>.Default);
- builder_to_member_cache = new Dictionary<Type, MemberCache> (ReferenceEquality<Type>.Default);
- builder_to_method = new Dictionary<MethodBase, IMethodData> (ReferenceEquality<MethodBase>.Default);
- builder_to_type_param = new Dictionary<GenericTypeParameterBuilder, TypeParameter> (ReferenceEquality<GenericTypeParameterBuilder>.Default);
- method_params = new Dictionary<MemberInfo, AParametersCollection> (ReferenceEquality<MemberInfo>.Default);
- method_overrides = new Dictionary<MethodBase, MethodBase> (ReferenceEquality<MethodBase>.Default);
- builder_to_ifaces = new Dictionary<Type, Type[]> (ReferenceEquality<Type>.Default);
-
- fieldbuilders_to_fields = new Dictionary<FieldInfo, FieldBase> (ReferenceEquality<FieldInfo>.Default);
- propertybuilder_to_property = new Dictionary<PropertyInfo, PropertyBase> (ReferenceEquality<PropertyInfo>.Default);
- fields = new Dictionary<FieldInfo, ConstSpec> (ReferenceEquality<FieldInfo>.Default);
+// object_type = null;
+
type_hash = new DoubleHash ();
assembly_internals_vis_attrs = new Dictionary<Assembly, bool> ();
- iface_cache = new Dictionary<Type, Type[]> (ReferenceEquality<Type>.Default);
- closure = new Closure ();
- FilterWithClosure_delegate = new MemberFilter (closure.Filter);
-
// TODO: I am really bored by all this static stuff
system_type_get_type_from_handle =
bool_movenext_void =
void_decimal_ctor_int_arg =
void_decimal_ctor_long_arg = null;
- isvolatile_type = null;
+ string_empty = null;
call_site_type =
generic_call_site_type =
binder_type = null;
- // to uncover regressions
- AllClsTopLevelTypes = null;
- }
-
- public static void AddUserType (DeclSpace ds)
- {
- builder_to_declspace.Add (ds.TypeBuilder, ds);
- }
-
- //
- // This entry point is used by types that we define under the covers
- //
- public static void RegisterBuilder (Type tb, Type [] ifaces)
- {
- if (ifaces != null)
- builder_to_ifaces [tb] = ifaces;
- }
-
- public static void AddMethod (MethodBase builder, IMethodData method)
- {
- builder_to_method.Add (builder, method);
- method_params.Add (builder, method.ParameterInfo);
- }
-
- public static IMethodData GetMethod (MethodBase builder)
- {
- IMethodData md;
- if (builder_to_method.TryGetValue (builder, out md))
- return md;
- return null;
- }
-
- /// <summary>
- /// Returns the DeclSpace whose Type is `t' or null if there is no
- /// DeclSpace for `t' (ie, the Type comes from a library)
- /// </summary>
- public static DeclSpace LookupDeclSpace (Type t)
- {
- DeclSpace ds;
- var tb = t as TypeBuilder;
- if (tb != null && builder_to_declspace.TryGetValue (tb, out ds))
- return ds;
-
- return null;
- }
-
- /// <summary>
- /// Returns the TypeContainer whose Type is `t' or null if there is no
- /// TypeContainer for `t' (ie, the Type comes from a library)
- /// </summary>
- public static TypeContainer LookupTypeContainer (Type t)
- {
- return LookupDeclSpace (t) as TypeContainer;
- }
-
- public static MemberCache LookupMemberCache (Type t)
- {
- if (IsBeingCompiled (t)) {
- DeclSpace container = LookupDeclSpace (t);
- if (container != null)
- return container.MemberCache;
- }
-
- if (t is GenericTypeParameterBuilder) {
- TypeParameter container;
- if (builder_to_type_param.TryGetValue ((GenericTypeParameterBuilder) t, out container))
- return container.MemberCache;
- }
-
- return TypeHandle.GetMemberCache (t);
- }
-
- public static MemberCache LookupBaseInterfacesCache (Type t)
- {
- Type [] ifaces = GetInterfaces (t);
-
- if (ifaces != null && ifaces.Length == 1)
- return LookupMemberCache (ifaces [0]);
-
- // TODO: the builder_to_member_cache should be indexed by 'ifaces', not 't'
- MemberCache cache;
- if (builder_to_member_cache.TryGetValue (t, out cache))
- return cache;
-
- cache = new MemberCache (ifaces);
- builder_to_member_cache.Add (t, cache);
- return cache;
- }
-
- public static TypeContainer LookupInterface (Type t)
- {
- TypeContainer tc = LookupTypeContainer (t);
- if ((tc == null) || (tc.Kind != MemberKind.Interface))
- return null;
-
- return tc;
- }
+ typed_reference_type = arg_iterator_type = mbr_type =
+ runtime_helpers_type = iasyncresult_type = asynccallback_type =
+ runtime_argument_handle_type = void_ptr_type = isvolatile_type =
+ generic_ilist_type = generic_icollection_type = generic_ienumerator_type =
+ generic_ienumerable_type = generic_nullable_type = expression_type =
+ parameter_expression_type = fieldinfo_type = methodinfo_type = ctorinfo_type = null;
- public static Delegate LookupDelegate (Type t)
- {
- return LookupDeclSpace (t) as Delegate;
- }
-
- public static Class LookupClass (Type t)
- {
- return LookupDeclSpace (t) as Class;
+ expression_type_expr = null;
}
//
//
// Gets the reference to T version of the Type (T&)
//
- public static Type GetReferenceType (Type t)
+ public static Type GetReferenceType (TypeSpec t)
{
- return t.MakeByRefType ();
+ return t.GetMetaInfo ().MakeByRefType ();
}
- //
- // Gets the pointer to T version of the Type (T*)
- //
- public static Type GetPointerType (Type t)
- {
- return GetConstructedType (t, "*");
- }
-
- public static Type GetConstructedType (Type t, string dim)
+ public static TypeSpec GetConstructedType (TypeSpec t, string dim)
{
object ret = null;
if (type_hash.Lookup (t, dim, out ret))
- return (Type) ret;
-
- if (IsDynamicType (t)) {
- ret = new DynamicArrayType (dim.Length - 1);
- type_hash.Insert (t, dim, ret);
- return (Type) ret;
- }
-
- ret = t.Module.GetType (t.ToString () + dim);
- if (ret != null) {
- type_hash.Insert (t, dim, ret);
- return (Type) ret;
- }
-
- if (dim == "&") {
- ret = GetReferenceType (t);
- type_hash.Insert (t, dim, ret);
- return (Type) ret;
- }
-
- if (t.IsGenericParameter || t.IsGenericType) {
- int pos = 0;
- Type result = t;
- while ((pos < dim.Length) && (dim [pos] == '[')) {
- pos++;
-
- if (dim [pos] == ']') {
- result = result.MakeArrayType ();
- pos++;
-
- if (pos < dim.Length)
- continue;
-
- type_hash.Insert (t, dim, result);
- return result;
- }
-
- int rank = 0;
- while (dim [pos] == ',') {
- pos++; rank++;
- }
-
- if ((dim [pos] != ']') || (pos != dim.Length-1))
- break;
-
- result = result.MakeArrayType (rank + 1);
- type_hash.Insert (t, dim, result);
- return result;
+ return (TypeSpec) ret;
+
+ TypeSpec ds;
+ if (dim.Length == 1) {
+ if (dim[0] == '*') {
+ ds = PointerContainer.MakeType (t);
+ } else if (dim[0] == '&') {
+ ds = ReferenceContainer.MakeType (t);
+ } else {
+ throw new NotImplementedException ("net");
}
- }
-
- type_hash.Insert (t, dim, null);
- return null;
- }
+ } else if (dim.Length == 2) { // optimizes common "[]"
+ ds = ArrayContainer.MakeType (t);
+ } else {
+ int rank = dim.IndexOf (']');
+ if (rank + 1 != dim.Length)
+ t = GetConstructedType (t, dim.Substring (rank + 1));
- public static Type GetNestedType (Type t, string name)
- {
- object ret = null;
- if (!type_hash.Lookup (t, name, out ret)) {
- ret = t.GetNestedType (name,
- BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.DeclaredOnly);
- type_hash.Insert (t, name, ret);
+ ds = ArrayContainer.MakeType (t, rank);
}
- return (Type) ret;
- }
- /// <summary>
- /// Fills static table with exported types from all referenced assemblies.
- /// This information is required for CLS Compliance tests.
- /// </summary>
- public static void LoadAllImportedTypes ()
- {
- AllClsTopLevelTypes = new Dictionary<string, object> (1500);
- foreach (Assembly a in GlobalRootNamespace.Instance.Assemblies) {
- foreach (Type t in a.GetExportedTypes ()) {
- AllClsTopLevelTypes [t.FullName.ToLower (System.Globalization.CultureInfo.InvariantCulture)] = null;
- }
- }
+ type_hash.Insert (t, dim, ds);
+ return ds;
}
/// <summary>
/// Returns the C# name of a type if possible, or the full type name otherwise
/// </summary>
- static public string CSharpName (Type t)
- {
- if (t == null_type)
- return "null";
-
- if (t == typeof (ArglistAccess))
- return "__arglist";
-
- if (t == typeof (AnonymousMethodBody))
- return "anonymous method";
-
- if (t == typeof (MethodGroupExpr))
- return "method group";
-
- if (IsDynamicType (t))
- return "dynamic";
-
- if (t == null)
- return "internal error";
-
- return CSharpName (GetFullName (t), t);
- }
-
- static readonly char [] elements = new char [] { '*', '[' };
-
- public static string CSharpName (string name, Type type)
+ static public string CSharpName (TypeSpec t)
{
- if (name.Length > 10) {
- string s;
- switch (name) {
- case "System.Int32": s = "int"; break;
- case "System.Int64": s = "long"; break;
- case "System.String": s = "string"; break;
- case "System.Boolean": s = "bool"; break;
- case "System.Void": s = "void"; break;
- case "System.Object": s = "object"; break;
- case "System.UInt32": s = "uint"; break;
- case "System.Int16": s = "short"; break;
- case "System.UInt16": s = "ushort"; break;
- case "System.UInt64": s = "ulong"; break;
- case "System.Single": s = "float"; break;
- case "System.Double": s = "double"; break;
- case "System.Decimal": s = "decimal"; break;
- case "System.Char": s = "char"; break;
- case "System.Byte": s = "byte"; break;
- case "System.SByte": s = "sbyte"; break;
- default: s = null; break;
- }
-
- if (s != null) {
- //
- // Predefined names can come from mscorlib only
- //
- if (type == null || type.Module.Name == "mscorlib.dll" || !RootContext.StdLib)
- return s;
-
- return name;
- }
-
- if (name [0] == AnonymousTypeClass.ClassNamePrefix [0] && name.StartsWith (AnonymousTypeClass.ClassNamePrefix))
- return AnonymousTypeClass.SignatureForError;
-
- int idx = name.IndexOfAny (elements, 10);
- if (idx > 0)
- return CSharpName (name.Substring (0, idx), type) + name.Substring (idx);
- }
-
- return name.Replace ('+', '.');
+ return t.GetSignatureForError ();
}
- static public string CSharpName (Type[] types)
+ static public string CSharpName (IList<TypeSpec> types)
{
- if (types.Length == 0)
+ if (types.Count == 0)
return string.Empty;
StringBuilder sb = new StringBuilder ();
- for (int i = 0; i < types.Length; ++i) {
+ for (int i = 0; i < types.Count; ++i) {
if (i > 0)
- sb.Append (", ");
+ sb.Append (",");
sb.Append (CSharpName (types [i]));
}
return sb.ToString ();
}
- /// <summary>
- /// Returns the signature of the method with full namespace classification
- /// </summary>
- static public string GetFullNameSignature (MemberInfo mi)
- {
- PropertyInfo pi = mi as PropertyInfo;
- if (pi != null) {
- MethodBase pmi = pi.GetGetMethod (true);
- if (pmi == null)
- pmi = pi.GetSetMethod (true);
- if (GetParameterData (pmi).Count > 0)
- mi = pmi;
- }
- return (mi is MethodBase)
- ? CSharpSignature (mi as MethodBase)
- : CSharpName (mi.DeclaringType) + '.' + mi.Name;
- }
-
- private static int GetFullName (Type t, StringBuilder sb)
- {
- int pos = 0;
-
- if (!t.IsGenericType) {
- sb.Append (t.FullName);
- return 0;
- }
-
- if (t.DeclaringType != null) {
- pos = GetFullName (t.DeclaringType, sb);
- sb.Append ('.');
- } else if (t.Namespace != null && t.Namespace.Length != 0) {
- sb.Append (t.Namespace);
- sb.Append ('.');
- }
- sb.Append (RemoveGenericArity (t.Name));
-
- Type[] this_args = GetTypeArguments (t);
-
- if (this_args.Length < pos)
- throw new InternalErrorException (
- "Enclosing class " + t.DeclaringType + " has more type arguments than " + t);
- if (this_args.Length == pos)
- return pos;
-
- sb.Append ('<');
- for (;;) {
- sb.Append (CSharpName (this_args [pos++]));
- if (pos == this_args.Length)
- break;
- sb.Append (',');
- }
- sb.Append ('>');
- return pos;
- }
-
- static string GetFullName (Type t)
- {
- if (t.IsArray) {
- string dimension = t.Name.Substring (t.Name.LastIndexOf ('['));
- return GetFullName (GetElementType (t)) + dimension;
- }
-
- if (IsNullableType (t) && !t.IsGenericTypeDefinition) {
- t = TypeToCoreType (GetTypeArguments (t)[0]);
- return CSharpName (t) + "?";
- }
-
- if (t.IsGenericParameter)
- return t.Name;
- if (!t.IsGenericType)
- return t.FullName;
-
- StringBuilder sb = new StringBuilder ();
- int pos = GetFullName (t, sb);
- if (pos <= 0)
- throw new InternalErrorException ("Generic Type " + t + " doesn't have type arguments");
- return sb.ToString ();
- }
-
- public static string RemoveGenericArity (string from)
- {
- int i = from.IndexOf ('`');
- if (i > 0)
- return from.Substring (0, i);
- return from;
- }
-
- /// <summary>
- /// When we need to report accessors as well
- /// </summary>
- static public string CSharpSignature (MethodBase mb)
- {
- return CSharpSignature (mb, false);
- }
-
- static public string CSharpSignature (MethodSpec ms)
- {
- return CSharpSignature (ms.MetaInfo);
- }
-
- /// <summary>
- /// Returns the signature of the method
- /// </summary>
- static public string CSharpSignature (MethodBase mb, bool show_accessor)
- {
- StringBuilder sig = new StringBuilder (CSharpName (mb.DeclaringType));
- sig.Append ('.');
-
- AParametersCollection iparams = GetParameterData (mb);
- string parameters = iparams.GetSignatureForError ();
- int accessor_end = 0;
-
- if (!mb.IsConstructor && TypeManager.IsSpecialMethod (mb)) {
- string op_name = Operator.GetName (mb.Name);
- if (op_name != null) {
- if (op_name == "explicit" || op_name == "implicit") {
- sig.Append (op_name);
- sig.Append (" operator ");
- sig.Append (CSharpName (((MethodInfo)mb).ReturnType));
- } else {
- sig.Append ("operator ");
- sig.Append (op_name);
- }
- sig.Append (parameters);
- return sig.ToString ();
- }
-
- bool is_getter = mb.Name.StartsWith ("get_");
- bool is_setter = mb.Name.StartsWith ("set_");
- if (is_getter || is_setter || mb.Name.StartsWith ("add_")) {
- accessor_end = 3;
- } else if (mb.Name.StartsWith ("remove_")) {
- accessor_end = 6;
- }
-
- // Is indexer
- if (iparams.Count > (is_getter ? 0 : 1)) {
- sig.Append ("this[");
- if (is_getter)
- sig.Append (parameters.Substring (1, parameters.Length - 2));
- else
- sig.Append (parameters.Substring (1, parameters.LastIndexOf (',') - 1));
- sig.Append (']');
- } else {
- sig.Append (mb.Name.Substring (accessor_end + 1));
- }
- } else {
- if (mb.Name == ".ctor")
- sig.Append (RemoveGenericArity (mb.DeclaringType.Name));
- else {
- sig.Append (mb.Name);
-
- if (IsGenericMethod (mb)) {
- Type[] args = GetGenericArguments (mb);
- sig.Append ('<');
- for (int i = 0; i < args.Length; i++) {
- if (i > 0)
- sig.Append (',');
- sig.Append (CSharpName (args [i]));
- }
- sig.Append ('>');
- }
- }
-
- sig.Append (parameters);
- }
-
- if (show_accessor && accessor_end > 0) {
- sig.Append ('.');
- sig.Append (mb.Name.Substring (0, accessor_end));
- }
-
- return sig.ToString ();
- }
-
- public static string GetMethodName (MethodInfo m)
+ static public string GetFullNameSignature (MemberSpec mi)
{
- if (!IsGenericMethodDefinition (m) && !IsGenericMethod (m))
- return m.Name;
-
- return MemberName.MakeName (m.Name, TypeManager.GetGenericArguments (m).Length);
+ return mi.GetSignatureForError ();
}
- static public string CSharpSignature (EventInfo ei)
+ static public string CSharpSignature (MemberSpec mb)
{
- return CSharpName (ei.DeclaringType) + "." + ei.Name;
+ return mb.GetSignatureForError ();
}
//
// Looks up a type, and aborts if it is not found. This is used
// by predefined types required by the compiler
//
- public static Type CoreLookupType (CompilerContext ctx, string ns_name, string name, MemberKind type_kind, bool required)
+ public static TypeSpec CoreLookupType (CompilerContext ctx, string ns_name, string name, MemberKind kind, bool required)
+ {
+ return CoreLookupType (ctx, ns_name, name, 0, kind, required);
+ }
+
+ public static TypeSpec CoreLookupType (CompilerContext ctx, string ns_name, string name, int arity, MemberKind kind, bool required)
{
Namespace ns = GlobalRootNamespace.Instance.GetNamespace (ns_name, true);
- Expression expr = ns.Lookup (ctx, name, Location.Null);
+ var te = ns.Lookup (ctx, name, arity, Location.Null);
+ var ts = te == null ? null : te.Type;
- if (expr == null) {
- if (required) {
- ctx.Report.Error (518, "The predefined type `{0}.{1}' is not defined or imported",
- ns_name, name);
- }
+ if (!required)
+ return ts;
+
+ if (ts == null) {
+ ctx.Report.Error (518, "The predefined type `{0}.{1}' is not defined or imported",
+ ns_name, name);
return null;
}
- Type t = expr.Type;
- if (RootContext.StdLib || t == null || !required)
- return t;
-
- // TODO: All predefined imported types have to have correct signature
- if (!IsBeingCompiled (t))
- return t;
-
- DeclSpace ds = (DeclSpace)RootContext.ToplevelTypes.GetDefinition (t.FullName);
- if (ds is Delegate) {
- if (type_kind == MemberKind.Delegate)
- return t;
- } else {
- TypeContainer tc = (TypeContainer)ds;
- if (tc.Kind == type_kind)
- return t;
+ if (ts.Kind != kind) {
+ ctx.Report.Error (520, "The predefined type `{0}.{1}' is not declared correctly",
+ ns_name, name);
+ return null;
}
- ctx.Report.Error (520, ds.Location, "The predefined type `{0}.{1}' is not declared correctly",
- ns_name, name);
- return null;
+ return ts;
}
- static MemberInfo GetPredefinedMember (Type t, string name, MemberTypes mt, Location loc, params Type [] args)
+ static MemberSpec GetPredefinedMember (TypeSpec t, MemberFilter filter, Location loc)
{
- const BindingFlags flags = instance_and_static | BindingFlags.Public | BindingFlags.DeclaredOnly;
-
- MemberInfo [] members = MemberLookup (null, null, t, mt, flags, name, null);
- if (members != null) {
- for (int i = 0; i < members.Length; ++i) {
- MemberInfo member = members [i];
- if (mt == MemberTypes.Method || mt == MemberTypes.Constructor) {
- MethodBase mb = member as MethodBase;
- if (mb == null)
- continue;
-
- AParametersCollection pd = TypeManager.GetParameterData (mb);
- if (IsEqual (pd.Types, args))
- return member;
- }
- if (mt == MemberTypes.Field) {
- FieldInfo fi = member as FieldInfo;
- if (fi == null)
- continue;
-
- if (args.Length >= 1 && !IsEqual (TypeToCoreType (fi.FieldType), args [0]))
- continue;
-
- return member;
- }
-
- if (mt == MemberTypes.Property) {
- PropertyInfo pi = member as PropertyInfo;
- if (pi == null)
- continue;
+ const BindingRestriction restrictions = BindingRestriction.AccessibleOnly | BindingRestriction.DeclaredOnly;
+ var member = MemberCache.FindMember (t, filter, restrictions);
- if (args.Length >= 1 && !IsEqual (TypeToCoreType (pi.PropertyType), args [0]))
- continue;
-
- return member;
- }
- }
- }
+ if (member != null)
+ return member;
string method_args = null;
- if (mt == MemberTypes.Method || mt == MemberTypes.Constructor)
- method_args = "(" + TypeManager.CSharpName (args) + ")";
+ if (filter.Parameters != null)
+ method_args = filter.Parameters.GetSignatureForError ();
RootContext.ToplevelTypes.Compiler.Report.Error (656, loc, "The compiler required member `{0}.{1}{2}' could not be found or is inaccessible",
- TypeManager.CSharpName (t), name, method_args);
+ TypeManager.CSharpName (t), filter.Name, method_args);
return null;
}
//
// Returns the ConstructorInfo for "args"
//
- public static ConstructorInfo GetPredefinedConstructor (Type t, Location loc, params Type [] args)
+ public static MethodSpec GetPredefinedConstructor (TypeSpec t, Location loc, params TypeSpec [] args)
{
- return (ConstructorInfo) GetPredefinedMember (t, ConstructorInfo.ConstructorName, MemberTypes.Constructor, loc, args);
+ var pc = ParametersCompiled.CreateFullyResolved (args);
+ return GetPredefinedMember (t, MemberFilter.Constructor (pc), loc) as MethodSpec;
}
//
- // Returns the MethodInfo for a method named `name' defined
+ // Returns the method specification for a method named `name' defined
// in type `t' which takes arguments of types `args'
//
- public static MethodSpec GetPredefinedMethod (Type t, string name, Location loc, params Type [] args)
+ public static MethodSpec GetPredefinedMethod (TypeSpec t, string name, Location loc, params TypeSpec [] args)
{
- var m = GetPredefinedMember (t, name, MemberTypes.Method, loc, args) as MethodBase;
- if (m == null)
- return null;
+ var pc = ParametersCompiled.CreateFullyResolved (args);
+ return GetPredefinedMethod (t, MemberFilter.Method (name, 0, pc, null), loc);
+ }
- return Import.CreateMethod (m);
+ public static MethodSpec GetPredefinedMethod (TypeSpec t, MemberFilter filter, Location loc)
+ {
+ return GetPredefinedMember (t, filter, loc) as MethodSpec;
}
- public static FieldInfo GetPredefinedField (Type t, string name, Location loc, params Type [] args)
+ public static FieldSpec GetPredefinedField (TypeSpec t, string name, Location loc, TypeSpec type)
{
- return (FieldInfo) GetPredefinedMember (t, name, MemberTypes.Field, loc, args);
+ return GetPredefinedMember (t, MemberFilter.Field (name, type), loc) as FieldSpec;
}
- public static PropertySpec GetPredefinedProperty (Type t, string name, Location loc, params Type [] args)
+ public static PropertySpec GetPredefinedProperty (TypeSpec t, string name, Location loc, TypeSpec type)
{
- var p = GetPredefinedMember (t, name, MemberTypes.Property, loc, args) as PropertyInfo;
- if (p == null)
- return null;
- return Import.CreateProperty (p);
+ return GetPredefinedMember (t, MemberFilter.Property (name, type), loc) as PropertySpec;
+ }
+
+ public static IList<PredefinedTypeSpec> InitCoreTypes ()
+ {
+ var core_types = new PredefinedTypeSpec[] {
+ object_type = new PredefinedTypeSpec (MemberKind.Class, "System", "Object"),
+ value_type = new PredefinedTypeSpec (MemberKind.Class, "System", "ValueType"),
+ attribute_type = new PredefinedTypeSpec (MemberKind.Class, "System", "Attribute"),
+
+ int32_type = new PredefinedTypeSpec (MemberKind.Struct, "System", "Int32"),
+ int64_type = new PredefinedTypeSpec (MemberKind.Struct, "System", "Int64"),
+ uint32_type = new PredefinedTypeSpec (MemberKind.Struct, "System", "UInt32"),
+ uint64_type = new PredefinedTypeSpec (MemberKind.Struct, "System", "UInt64"),
+ byte_type = new PredefinedTypeSpec (MemberKind.Struct, "System", "Byte"),
+ sbyte_type = new PredefinedTypeSpec (MemberKind.Struct, "System", "SByte"),
+ short_type = new PredefinedTypeSpec (MemberKind.Struct, "System", "Int16"),
+ ushort_type = new PredefinedTypeSpec (MemberKind.Struct, "System", "UInt16"),
+
+ ienumerator_type = new PredefinedTypeSpec (MemberKind.Interface, "System.Collections", "IEnumerator"),
+ ienumerable_type = new PredefinedTypeSpec (MemberKind.Interface, "System.Collections", "IEnumerable"),
+ idisposable_type = new PredefinedTypeSpec (MemberKind.Interface, "System", "IDisposable"),
+
+ char_type = new PredefinedTypeSpec (MemberKind.Struct, "System", "Char"),
+ string_type = new PredefinedTypeSpec (MemberKind.Class, "System", "String"),
+ float_type = new PredefinedTypeSpec (MemberKind.Struct, "System", "Single"),
+ double_type = new PredefinedTypeSpec (MemberKind.Struct, "System", "Double"),
+ decimal_type = new PredefinedTypeSpec (MemberKind.Struct, "System", "Decimal"),
+ bool_type = new PredefinedTypeSpec (MemberKind.Struct, "System", "Boolean"),
+ intptr_type = new PredefinedTypeSpec (MemberKind.Struct, "System", "IntPtr"),
+ uintptr_type = new PredefinedTypeSpec (MemberKind.Struct, "System", "UIntPtr"),
+
+ multicast_delegate_type = new PredefinedTypeSpec (MemberKind.Class, "System", "MulticastDelegate"),
+ delegate_type = new PredefinedTypeSpec (MemberKind.Class, "System", "Delegate"),
+ enum_type = new PredefinedTypeSpec (MemberKind.Class, "System", "Enum"),
+ array_type = new PredefinedTypeSpec (MemberKind.Class, "System", "Array"),
+ void_type = new PredefinedTypeSpec (MemberKind.Struct, "System", "Void"),
+ type_type = new PredefinedTypeSpec (MemberKind.Class, "System", "Type"),
+ exception_type = new PredefinedTypeSpec (MemberKind.Class, "System", "Exception"),
+ runtime_field_handle_type = new PredefinedTypeSpec (MemberKind.Struct, "System", "RuntimeFieldHandle"),
+ runtime_handle_type = new PredefinedTypeSpec (MemberKind.Struct, "System", "RuntimeTypeHandle"),
+ };
+
+ return core_types;
}
/// <remarks>
/// population of the type has happened (for example, to
/// bootstrap the corlib.dll
/// </remarks>
- public static bool InitCoreTypes (CompilerContext ctx)
+ public static bool InitCoreTypes (CompilerContext ctx, IList<PredefinedTypeSpec> predefined)
{
- object_type = CoreLookupType (ctx, "System", "Object", MemberKind.Class, true);
- system_object_expr.Type = object_type;
- value_type = CoreLookupType (ctx, "System", "ValueType", MemberKind.Class, true);
- system_valuetype_expr.Type = value_type;
- attribute_type = CoreLookupType (ctx, "System", "Attribute", MemberKind.Class, true);
-
- int32_type = CoreLookupType (ctx, "System", "Int32", MemberKind.Struct, true);
- system_int32_expr.Type = int32_type;
- int64_type = CoreLookupType (ctx, "System", "Int64", MemberKind.Struct, true);
- system_int64_expr.Type = int64_type;
- uint32_type = CoreLookupType (ctx, "System", "UInt32", MemberKind.Struct, true);
- system_uint32_expr.Type = uint32_type;
- uint64_type = CoreLookupType (ctx, "System", "UInt64", MemberKind.Struct, true);
- system_uint64_expr.Type = uint64_type;
- byte_type = CoreLookupType (ctx, "System", "Byte", MemberKind.Struct, true);
- system_byte_expr.Type = byte_type;
- sbyte_type = CoreLookupType (ctx, "System", "SByte", MemberKind.Struct, true);
- system_sbyte_expr.Type = sbyte_type;
- short_type = CoreLookupType (ctx, "System", "Int16", MemberKind.Struct, true);
- system_int16_expr.Type = short_type;
- ushort_type = CoreLookupType (ctx, "System", "UInt16", MemberKind.Struct, true);
- system_uint16_expr.Type = ushort_type;
-
- ienumerator_type = CoreLookupType (ctx, "System.Collections", "IEnumerator", MemberKind.Interface, true);
- ienumerable_type = CoreLookupType (ctx, "System.Collections", "IEnumerable", MemberKind.Interface, true);
- idisposable_type = CoreLookupType (ctx, "System", "IDisposable", MemberKind.Interface, true);
-
- // HACK: DefineType immediately resolves iterators (very wrong)
- generic_ienumerator_type = CoreLookupType (ctx, "System.Collections.Generic", "IEnumerator`1", MemberKind.Interface, false);
-
- char_type = CoreLookupType (ctx, "System", "Char", MemberKind.Struct, true);
- system_char_expr.Type = char_type;
- string_type = CoreLookupType (ctx, "System", "String", MemberKind.Class, true);
- system_string_expr.Type = string_type;
- float_type = CoreLookupType (ctx, "System", "Single", MemberKind.Struct, true);
- system_single_expr.Type = float_type;
- double_type = CoreLookupType (ctx, "System", "Double", MemberKind.Struct, true);
- system_double_expr.Type = double_type;
- decimal_type = CoreLookupType (ctx, "System", "Decimal", MemberKind.Struct, true);
- system_decimal_expr.Type = decimal_type;
- bool_type = CoreLookupType (ctx, "System", "Boolean", MemberKind.Struct, true);
- system_boolean_expr.Type = bool_type;
- intptr_type = CoreLookupType (ctx, "System", "IntPtr", MemberKind.Struct, true);
- system_intptr_expr.Type = intptr_type;
- uintptr_type = CoreLookupType (ctx, "System", "UIntPtr", MemberKind.Struct, true);
-
- multicast_delegate_type = CoreLookupType (ctx, "System", "MulticastDelegate", MemberKind.Class, true);
- delegate_type = CoreLookupType (ctx, "System", "Delegate", MemberKind.Class, true);
-
- enum_type = CoreLookupType (ctx, "System", "Enum", MemberKind.Class, true);
- array_type = CoreLookupType (ctx, "System", "Array", MemberKind.Class, true);
- void_type = CoreLookupType (ctx, "System", "Void", MemberKind.Struct, true);
- system_void_expr.Type = void_type;
- type_type = CoreLookupType (ctx, "System", "Type", MemberKind.Class, true);
- exception_type = CoreLookupType (ctx, "System", "Exception", MemberKind.Class, true);
-
- runtime_field_handle_type = CoreLookupType (ctx, "System", "RuntimeFieldHandle", MemberKind.Struct, true);
- runtime_handle_type = CoreLookupType (ctx, "System", "RuntimeTypeHandle", MemberKind.Struct, true);
+ foreach (var p in predefined) {
+ var found = CoreLookupType (ctx, p.Namespace, p.Name, p.Kind, true);
+ if (found == null || found == p)
+ continue;
+
+ if (!RootContext.StdLib) {
+ var ns = GlobalRootNamespace.Instance.GetNamespace (p.Namespace, false);
+ ns.ReplaceTypeWithPredefined (found, p);
+
+ var tc = found.MemberDefinition as TypeContainer;
+ tc.SetPredefinedSpec (p);
+ p.SetDefinition (found);
+ }
+ }
PredefinedAttributes.Get.ParamArray.Initialize (ctx, false);
PredefinedAttributes.Get.Out.Initialize (ctx, false);
//
// These are only used for compare purposes
//
- null_type = typeof (NullLiteral);
-
- void_ptr_type = GetPointerType (void_type);
+ null_type = InternalType.Null;
+
+ void_ptr_type = PointerContainer.MakeType (void_type);
//
// Initialize InternalsVisibleTo as the very first optional type. Otherwise we would populate
arg_iterator_type = CoreLookupType (ctx, "System", "ArgIterator", MemberKind.Struct, false);
mbr_type = CoreLookupType (ctx, "System", "MarshalByRefObject", MemberKind.Class, false);
- //
- // Optional attributes, used for error reporting only
- //
- //if (PredefinedAttributes.Get.Obsolete.IsDefined) {
- // Class c = TypeManager.LookupClass (PredefinedAttributes.Get.Obsolete.Type);
- // if (c != null)
- // c.Define ();
- //}
-
- generic_ilist_type = CoreLookupType (ctx, "System.Collections.Generic", "IList`1", MemberKind.Interface, false);
- generic_icollection_type = CoreLookupType (ctx, "System.Collections.Generic", "ICollection`1", MemberKind.Interface, false);
- generic_ienumerable_type = CoreLookupType (ctx, "System.Collections.Generic", "IEnumerable`1", MemberKind.Interface, false);
- generic_nullable_type = CoreLookupType (ctx, "System", "Nullable`1", MemberKind.Struct, false);
+ generic_ienumerator_type = CoreLookupType (ctx, "System.Collections.Generic", "IEnumerator", 1, MemberKind.Interface, false);
+ generic_ilist_type = CoreLookupType (ctx, "System.Collections.Generic", "IList", 1, MemberKind.Interface, false);
+ generic_icollection_type = CoreLookupType (ctx, "System.Collections.Generic", "ICollection", 1, MemberKind.Interface, false);
+ generic_ienumerable_type = CoreLookupType (ctx, "System.Collections.Generic", "IEnumerable", 1, MemberKind.Interface, false);
+ generic_nullable_type = CoreLookupType (ctx, "System", "Nullable", 1, MemberKind.Struct, false);
//
// Optional types which are used as types and for member lookup
// New in .NET 3.5
// Note: extension_attribute_type is already loaded
- expression_type = CoreLookupType (ctx, "System.Linq.Expressions", "Expression`1", MemberKind.Class, false);
+ expression_type = CoreLookupType (ctx, "System.Linq.Expressions", "Expression", 1, MemberKind.Class, false);
+ }
- if (!RootContext.StdLib) {
- //
- // HACK: When building Mono corlib mcs uses loaded mscorlib which
- // has different predefined types and this method sets mscorlib types
- // to be same to avoid any type check errors.
- //
+ public static bool IsBuiltinType (TypeSpec t)
+ {
+ if (t == object_type || t == string_type || t == int32_type || t == uint32_type ||
+ t == int64_type || t == uint64_type || t == float_type || t == double_type ||
+ t == char_type || t == short_type || t == decimal_type || t == bool_type ||
+ t == sbyte_type || t == byte_type || t == ushort_type || t == void_type)
+ return true;
+ else
+ return false;
+ }
- Type type = typeof (Type);
- Type [] system_4_type_arg = { type, type, type, type };
-
- MethodInfo set_corlib_type_builders =
- typeof (System.Reflection.Emit.AssemblyBuilder).GetMethod (
- "SetCorlibTypeBuilders", BindingFlags.NonPublic | BindingFlags.Instance, null,
- system_4_type_arg, null);
-
- if (set_corlib_type_builders != null) {
- object[] args = new object [4];
- args [0] = object_type;
- args [1] = value_type;
- args [2] = enum_type;
- args [3] = void_type;
-
- set_corlib_type_builders.Invoke (CodeGen.Assembly.Builder, args);
- } else {
- ctx.Report.Warning (-26, 3, "The compilation may fail due to missing `{0}.SetCorlibTypeBuilders({1})' method",
- TypeManager.CSharpName (typeof (System.Reflection.Emit.AssemblyBuilder)),
- TypeManager.CSharpName (system_4_type_arg));
- }
- }
+ //
+ // This is like IsBuiltinType, but lacks decimal_type, we should also clean up
+ // the pieces in the code where we use IsBuiltinType and special case decimal_type.
+ //
+ public static bool IsPrimitiveType (TypeSpec t)
+ {
+ return (t == int32_type || t == uint32_type ||
+ t == int64_type || t == uint64_type || t == float_type || t == double_type ||
+ t == char_type || t == short_type || t == bool_type ||
+ t == sbyte_type || t == byte_type || t == ushort_type);
}
- const BindingFlags instance_and_static = BindingFlags.Static | BindingFlags.Instance;
+ // Obsolete
+ public static bool IsDelegateType (TypeSpec t)
+ {
+ return t.IsDelegate;
+ }
- /// <remarks>
- /// This is the "old", non-cache based FindMembers() function. We cannot use
- /// the cache here because there is no member name argument.
- /// </remarks>
- public static MemberList FindMembers (Type t, MemberTypes mt, BindingFlags bf,
- MemberFilter filter, object criteria)
+ //
+ // When any element of the type is a dynamic type
+ //
+ // This method builds a transformation array for dynamic types
+ // used in places where DynamicAttribute cannot be applied to.
+ // It uses bool flag when type is of dynamic type and each
+ // section always starts with "false" for some reason.
+ //
+ // LAMESPEC: This should be part of C# specification !
+ //
+ // Example: Func<dynamic, int, dynamic[]>
+ // Transformation: { false, true, false, false, true }
+ //
+ public static bool[] HasDynamicTypeUsed (TypeSpec t)
{
-#if MS_COMPATIBLE
- if (t.IsGenericType)
- t = t.GetGenericTypeDefinition ();
-#endif
+ var ac = t as ArrayContainer;
+ if (ac != null) {
+ if (HasDynamicTypeUsed (ac.Element) != null)
+ return new bool[] { false, true };
- DeclSpace decl = LookupDeclSpace (t);
-
- //
- // `builder_to_declspace' contains all dynamic types.
- //
- if (decl != null) {
- MemberList list;
- Timer.StartTimer (TimerType.FindMembers);
- list = decl.FindMembers (mt, bf, filter, criteria);
- Timer.StopTimer (TimerType.FindMembers);
- return list;
- }
-
- //
- // We have to take care of arrays specially, because GetType on
- // a TypeBuilder array will return a Type, not a TypeBuilder,
- // and we can not call FindMembers on this type.
- //
- if (
-#if MS_COMPATIBLE
- !t.IsGenericType &&
-#endif
- t.IsSubclassOf (TypeManager.array_type))
- return new MemberList (TypeManager.array_type.FindMembers (mt, bf, filter, criteria));
-
- if (t is GenericTypeParameterBuilder) {
- TypeParameter tparam = builder_to_type_param [(GenericTypeParameterBuilder) t];
-
- Timer.StartTimer (TimerType.FindMembers);
- MemberList list = tparam.FindMembers (
- mt, bf | BindingFlags.DeclaredOnly, filter, criteria);
- Timer.StopTimer (TimerType.FindMembers);
- return list;
- }
-
- //
- // Since FindMembers will not lookup both static and instance
- // members, we emulate this behaviour here.
- //
- if ((bf & instance_and_static) == instance_and_static){
- MemberInfo [] i_members = t.FindMembers (
- mt, bf & ~BindingFlags.Static, filter, criteria);
-
- int i_len = i_members.Length;
- if (i_len == 1){
- MemberInfo one = i_members [0];
-
- //
- // If any of these are present, we are done!
- //
- if ((one is Type) || (one is EventInfo) || (one is FieldInfo))
- return new MemberList (i_members);
- }
-
- MemberInfo [] s_members = t.FindMembers (
- mt, bf & ~BindingFlags.Instance, filter, criteria);
-
- int s_len = s_members.Length;
- if (i_len > 0 || s_len > 0)
- return new MemberList (i_members, s_members);
- else {
- if (i_len > 0)
- return new MemberList (i_members);
- else
- return new MemberList (s_members);
- }
- }
-
- return new MemberList (t.FindMembers (mt, bf, filter, criteria));
- }
-
-
- /// <summary>
- /// This method is only called from within MemberLookup. It tries to use the member
- /// cache if possible and falls back to the normal FindMembers if not. The `used_cache'
- /// flag tells the caller whether we used the cache or not. If we used the cache, then
- /// our return value will already contain all inherited members and the caller don't need
- /// to check base classes and interfaces anymore.
- /// </summary>
- private static MemberInfo [] MemberLookup_FindMembers (Type t, MemberTypes mt, BindingFlags bf,
- string name, out bool used_cache)
- {
- MemberCache cache;
-
- //
- // If this is a dynamic type, it's always in the `builder_to_declspace' hash table
- // and we can ask the DeclSpace for the MemberCache.
- //
-#if MS_COMPATIBLE
- if (t.Assembly == CodeGen.Assembly.Builder) {
- if (t.IsGenericParameter) {
- TypeParameter tparam = builder_to_type_param [(GenericTypeParameterBuilder) t];
-
- used_cache = true;
- if (tparam.MemberCache == null)
- return new MemberInfo[0];
-
- return tparam.MemberCache.FindMembers (
- mt, bf, name, FilterWithClosure_delegate, null);
- }
-
- //
- // We have to take care of arrays specially, because GetType on
- // a TypeBuilder array will return a Type, not a TypeBuilder,
- // and we can not call FindMembers on this type.
- //
- if (t.IsArray) {
- used_cache = true;
- return TypeHandle.ArrayType.MemberCache.FindMembers (
- mt, bf, name, FilterWithClosure_delegate, null);
- }
-
- if (t.IsGenericType && !t.IsGenericTypeDefinition)
- t = t.GetGenericTypeDefinition ();
-#else
- if (t is TypeBuilder) {
-#endif
- DeclSpace decl = LookupDeclSpace (t);
- cache = decl.MemberCache;
-
- //
- // If this DeclSpace has a MemberCache, use it.
- //
-
- if (cache != null) {
- used_cache = true;
- return cache.FindMembers (
- mt, bf, name, FilterWithClosure_delegate, null);
- }
-
- // If there is no MemberCache, we need to use the "normal" FindMembers.
- // Note, this is a VERY uncommon route!
-
- MemberList list;
- Timer.StartTimer (TimerType.FindMembers);
- list = decl.FindMembers (mt, bf | BindingFlags.DeclaredOnly,
- FilterWithClosure_delegate, name);
- Timer.StopTimer (TimerType.FindMembers);
- used_cache = false;
- return (MemberInfo []) list;
- }
-
- //
- // We have to take care of arrays specially, because GetType on
- // a TypeBuilder array will return a Type, not a TypeBuilder,
- // and we can not call FindMembers on this type.
- //
- if (t.IsArray) {
- used_cache = true;
- return TypeHandle.ArrayType.MemberCache.FindMembers (
- mt, bf, name, FilterWithClosure_delegate, null);
- }
-
- if (t is GenericTypeParameterBuilder) {
- TypeParameter tparam = builder_to_type_param [(GenericTypeParameterBuilder) t];
-
- used_cache = true;
- if (tparam.MemberCache == null)
- return new MemberInfo [0];
-
- return tparam.MemberCache.FindMembers (
- mt, bf, name, FilterWithClosure_delegate, null);
- }
-
- if (IsGenericType (t) && (mt == MemberTypes.NestedType)) {
- //
- // This happens if we're resolving a class'es base class and interfaces
- // in TypeContainer.DefineType(). At this time, the types aren't
- // populated yet, so we can't use the cache.
- //
- MemberInfo[] info = t.FindMembers (mt, bf | BindingFlags.DeclaredOnly,
- FilterWithClosure_delegate, name);
- used_cache = false;
- return info;
+ return null;
}
- //
- // This call will always succeed. There is exactly one TypeHandle instance per
- // type, TypeHandle.GetMemberCache() will, if necessary, create a new one, and return
- // the corresponding MemberCache.
- //
- cache = TypeHandle.GetMemberCache (t);
-
- used_cache = true;
- return cache.FindMembers (mt, bf, name, FilterWithClosure_delegate, null);
- }
-
- //
- // Return true for SRE dynamic/unclosed members
- //
- public static bool IsBeingCompiled (MemberInfo mi)
- {
- return mi.Module.Assembly == CodeGen.Assembly.Builder;
- }
-
- public static bool IsBuiltinType (Type t)
- {
- t = TypeToCoreType (t);
- if (t == object_type || t == string_type || t == int32_type || t == uint32_type ||
- t == int64_type || t == uint64_type || t == float_type || t == double_type ||
- t == char_type || t == short_type || t == decimal_type || t == bool_type ||
- t == sbyte_type || t == byte_type || t == ushort_type || t == void_type)
- return true;
- else
- return false;
- }
-
- //
- // This is like IsBuiltinType, but lacks decimal_type, we should also clean up
- // the pieces in the code where we use IsBuiltinType and special case decimal_type.
- //
- public static bool IsPrimitiveType (Type t)
- {
- return (t == int32_type || t == uint32_type ||
- t == int64_type || t == uint64_type || t == float_type || t == double_type ||
- t == char_type || t == short_type || t == bool_type ||
- t == sbyte_type || t == byte_type || t == ushort_type);
- }
-
- public static bool IsDelegateType (Type t)
- {
- if (TypeManager.IsGenericParameter (t))
- return false;
-
- if (t == TypeManager.delegate_type || t == TypeManager.multicast_delegate_type)
- return false;
-
- t = DropGenericTypeArguments (t);
- return IsSubclassOf (t, TypeManager.delegate_type);
- }
-
- //
- // Is a type of dynamic type
- //
- public static bool IsDynamicType (Type t)
- {
- if (object.ReferenceEquals (InternalType.Dynamic, t))
- return true;
-
- if (t != object_type)
- return false;
-
- if (IsBeingCompiled (t))
- return false;
-
- PredefinedAttribute pa = PredefinedAttributes.Get.Dynamic;
- if (pa == null || IsBeingCompiled (pa.Type))
- return false;
-
- object[] res = t.GetCustomAttributes (pa.Type, false);
- return res != null && res.Length != 0;
- }
-
- //
- // When any element of the type is a dynamic type
- //
- // This method builds a transformation array for dynamic types
- // used in places where DynamicAttribute cannnot be applied to.
- // It uses bool flag when type is of dynamic type and each
- // section always starts with "false" for some reason.
- //
- // LAMESPEC: This should be part of C# specification !
- //
- // Example: Func<dynamic, int, dynamic[]>
- // Transformation: { false, true, false, false, true }
- //
- public static bool[] HasDynamicTypeUsed (Type t)
- {
- if (t is DynamicArrayType)
- return new bool[] { false, true };
-
if (t == null)
return null;
return null;
}
- public static bool IsEnumType (Type t)
+ // Obsolete
+ public static bool IsEnumType (TypeSpec t)
{
- t = DropGenericTypeArguments (t);
- return t.BaseType == TypeManager.enum_type;
+ return t.IsEnum;
}
- public static bool IsBuiltinOrEnum (Type t)
+ public static bool IsBuiltinOrEnum (TypeSpec t)
{
if (IsBuiltinType (t))
return true;
return false;
}
- public static bool IsAttributeType (Type t)
- {
- return t == attribute_type && t.BaseType != null || IsSubclassOf (t, attribute_type);
- }
-
//
// Whether a type is unmanaged. This is used by the unsafe code (25.2)
//
- // mcs4: delete, DeclSpace.IsUnmanagedType is replacement
- public static bool IsUnmanagedType (Type t)
+ public static bool IsUnmanagedType (TypeSpec t)
{
- DeclSpace ds = TypeManager.LookupDeclSpace (t);
+ var ds = t.MemberDefinition as DeclSpace;
if (ds != null)
return ds.IsUnmanagedType ();
- // builtins that are not unmanaged types
+ // some builtins that are not unmanaged types
if (t == TypeManager.object_type || t == TypeManager.string_type)
return false;
- if (IsGenericType (t) || IsGenericParameter (t))
- return false;
-
if (IsBuiltinOrEnum (t))
return true;
if (t.IsPointer)
return IsUnmanagedType (GetElementType (t));
- // Arrays are disallowed, even if we mark them with [MarshalAs(UnmanagedType.ByValArray, ...)]
- if (t.IsArray)
- return false;
-
if (!IsValueType (t))
return false;
- for (Type p = t.DeclaringType; p != null; p = p.DeclaringType) {
- if (IsGenericTypeDefinition (p))
- return false;
- }
-
- bool retval = true;
- {
- FieldInfo [] fields = t.GetFields (BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance);
-
- foreach (FieldInfo f in fields){
- if (!IsUnmanagedType (f.FieldType)){
- retval = false;
- }
- }
- }
+ if (t.IsNested && t.DeclaringType.IsGenericOrParentIsGeneric)
+ return false;
- return retval;
+ return true;
}
//
// Null is considered to be a reference type
//
- public static bool IsReferenceType (Type t)
+ public static bool IsReferenceType (TypeSpec t)
{
- if (TypeManager.IsGenericParameter (t)) {
- GenericConstraints constraints = TypeManager.GetTypeParameterConstraints (t);
- if (constraints == null)
- return false;
-
- return constraints.IsReferenceType;
- }
+ if (t.IsGenericParameter)
+ return ((TypeParameterSpec) t).IsReferenceType;
- return !IsStruct (t) && !IsEnumType (t);
+ return !t.IsStruct && !IsEnumType (t);
}
- public static bool IsValueType (Type t)
+ public static bool IsValueType (TypeSpec t)
{
- if (TypeManager.IsGenericParameter (t)) {
- GenericConstraints constraints = TypeManager.GetTypeParameterConstraints (t);
- if (constraints == null)
- return false;
-
- return constraints.IsValueType;
- }
+ if (t.IsGenericParameter)
+ return ((TypeParameterSpec) t).IsValueType;
- return IsStruct (t) || IsEnumType (t);
+ return t.IsStruct || IsEnumType (t);
}
- public static bool IsStruct (Type t)
+ public static bool IsStruct (TypeSpec t)
{
- return t.BaseType == value_type && t != enum_type && t.IsSealed;
- }
-
- public static bool IsInterfaceType (Type t)
- {
- TypeContainer tc = LookupTypeContainer (t);
- if (tc == null)
- return false;
-
- return tc.Kind == MemberKind.Interface;
+ return t.IsStruct;
}
- public static bool IsSubclassOf (Type type, Type base_type)
+ public static bool IsSubclassOf (TypeSpec type, TypeSpec base_type)
{
- TypeParameter tparam = LookupTypeParameter (type);
- TypeParameter pparam = LookupTypeParameter (base_type);
-
- if ((tparam != null) && (pparam != null)) {
- if (tparam == pparam)
- return true;
-
- return tparam.IsSubclassOf (base_type);
- }
-
-#if MS_COMPATIBLE
- if (tparam != pparam)
- return false;
-
- if (type.IsGenericType)
- type = type.GetGenericTypeDefinition ();
-#endif
-
- if (type.IsSubclassOf (base_type))
- return true;
-
do {
- if (IsEqual (type, base_type))
+ if (type == base_type)
return true;
type = type.BaseType;
return false;
}
- public static bool IsPrivateAccessible (Type type, Type parent)
- {
- if (type == null)
- return false;
-
- if (type.Equals (parent))
- return true;
-
- return DropGenericTypeArguments (type) == DropGenericTypeArguments (parent);
- }
-
- public static bool IsFamilyAccessible (Type type, Type parent)
+ public static bool IsFamilyAccessible (TypeSpec type, TypeSpec parent)
{
- TypeParameter tparam = LookupTypeParameter (type);
- TypeParameter pparam = LookupTypeParameter (parent);
+// TypeParameter tparam = LookupTypeParameter (type);
+// TypeParameter pparam = LookupTypeParameter (parent);
- if ((tparam != null) && (pparam != null)) {
- if (tparam == pparam)
+ if (type.Kind == MemberKind.TypeParameter && parent.Kind == MemberKind.TypeParameter) { // (tparam != null) && (pparam != null)) {
+ if (type == parent)
return true;
- return tparam.IsSubclassOf (parent);
+ throw new NotImplementedException ("net");
+// return tparam.IsSubclassOf (parent);
}
do {
//
// Checks whether `type' is a subclass or nested child of `base_type'.
//
- public static bool IsNestedFamilyAccessible (Type type, Type base_type)
+ public static bool IsNestedFamilyAccessible (TypeSpec type, TypeSpec base_type)
{
do {
if (IsFamilyAccessible (type, base_type))
//
// Checks whether `type' is a nested child of `parent'.
//
- public static bool IsNestedChildOf (Type type, Type parent)
+ public static bool IsNestedChildOf (TypeSpec type, TypeSpec parent)
{
if (type == null)
return false;
- type = DropGenericTypeArguments (type);
- parent = DropGenericTypeArguments (parent);
+ type = type.GetDefinition (); // DropGenericTypeArguments (type);
+ parent = parent.GetDefinition (); // DropGenericTypeArguments (parent);
if (IsEqual (type, parent))
return false;
type = type.DeclaringType;
while (type != null) {
- if (IsEqual (type, parent))
+ if (IsEqual (type.GetDefinition (), parent))
return true;
type = type.DeclaringType;
return false;
}
- public static bool IsSpecialType (Type t)
+ public static bool IsSpecialType (TypeSpec t)
{
return t == arg_iterator_type || t == typed_reference_type;
}
if (assembly_internals_vis_attrs.TryGetValue (assembly, out value))
return value;
- PredefinedAttribute pa = PredefinedAttributes.Get.InternalsVisibleTo;
- // HACK: Do very early resolve of SRE type checking
- if (pa.Type == null)
- pa.Resolve (true);
-
- if (!pa.IsDefined)
- return false;
-
- object [] attrs = assembly.GetCustomAttributes (pa.Type, false);
+ object[] attrs = assembly.GetCustomAttributes (typeof (InternalsVisibleToAttribute), false);
if (attrs.Length == 0) {
assembly_internals_vis_attrs.Add (assembly, false);
return false;
bool is_friend = false;
AssemblyName this_name = CodeGen.Assembly.Name;
+ if (this_name == null)
+ return false;
+
byte [] this_token = this_name.GetPublicKeyToken ();
foreach (InternalsVisibleToAttribute attr in attrs) {
if (attr.AssemblyName == null || attr.AssemblyName.Length == 0)
other_name, CodeGen.Assembly.Name.FullName);
}
- //
- // Do the right thing when returning the element type of an
- // array type based on whether we are compiling corlib or not
- //
- public static Type GetElementType (Type t)
- {
- if (RootContext.StdLib)
- return t.GetElementType ();
- else
- return TypeToCoreType (t.GetElementType ());
- }
+ public static TypeSpec GetElementType (TypeSpec t)
+ {
+ return ((ElementTypeSpec)t).Element;
+ }
/// <summary>
/// This method is not implemented by MS runtime for dynamic types
/// </summary>
- public static bool HasElementType (Type t)
+ public static bool HasElementType (TypeSpec t)
{
- return t.IsArray || t.IsPointer || t.IsByRef;
+ return t is ElementTypeSpec;
}
- public static Type GetEnumUnderlyingType (Type t)
+ static NumberFormatInfo nf_provider = CultureInfo.CurrentCulture.NumberFormat;
+
+ // This is a custom version of Convert.ChangeType() which works
+ // with the TypeBuilder defined types when compiling corlib.
+ public static object ChangeType (object value, TypeSpec targetType, out bool error)
{
- t = DropGenericTypeArguments (t);
- Enum e = LookupTypeContainer (t) as Enum;
- if (e != null)
- return e.UnderlyingType;
+ IConvertible convert_value = value as IConvertible;
+
+ if (convert_value == null){
+ error = true;
+ return null;
+ }
+
+ //
+ // We cannot rely on build-in type conversions as they are
+ // more limited than what C# supports.
+ // See char -> float/decimal/double conversion
+ //
+ error = false;
+ try {
+ if (targetType == TypeManager.bool_type)
+ return convert_value.ToBoolean (nf_provider);
+ if (targetType == TypeManager.byte_type)
+ return convert_value.ToByte (nf_provider);
+ if (targetType == TypeManager.char_type)
+ return convert_value.ToChar (nf_provider);
+ if (targetType == TypeManager.short_type)
+ return convert_value.ToInt16 (nf_provider);
+ if (targetType == TypeManager.int32_type)
+ return convert_value.ToInt32 (nf_provider);
+ if (targetType == TypeManager.int64_type)
+ return convert_value.ToInt64 (nf_provider);
+ if (targetType == TypeManager.sbyte_type)
+ return convert_value.ToSByte (nf_provider);
+
+ if (targetType == TypeManager.decimal_type) {
+ if (convert_value.GetType () == typeof (char))
+ return (decimal) convert_value.ToInt32 (nf_provider);
+ return convert_value.ToDecimal (nf_provider);
+ }
+
+ if (targetType == TypeManager.double_type) {
+ if (convert_value.GetType () == typeof (char))
+ return (double) convert_value.ToInt32 (nf_provider);
+ return convert_value.ToDouble (nf_provider);
+ }
+
+ if (targetType == TypeManager.float_type) {
+ if (convert_value.GetType () == typeof (char))
+ return (float)convert_value.ToInt32 (nf_provider);
+ return convert_value.ToSingle (nf_provider);
+ }
- // TODO: cache it ?
- FieldInfo fi = GetPredefinedField (t, Enum.UnderlyingValueField, Location.Null, Type.EmptyTypes);
- if (fi == null)
- return TypeManager.int32_type;
+ if (targetType == TypeManager.string_type)
+ return convert_value.ToString (nf_provider);
+ if (targetType == TypeManager.ushort_type)
+ return convert_value.ToUInt16 (nf_provider);
+ if (targetType == TypeManager.uint32_type)
+ return convert_value.ToUInt32 (nf_provider);
+ if (targetType == TypeManager.uint64_type)
+ return convert_value.ToUInt64 (nf_provider);
+ if (targetType == TypeManager.object_type)
+ return value;
- return TypeToCoreType (fi.FieldType);
+ error = true;
+ } catch {
+ error = true;
+ }
+ return null;
}
-
+
/// <summary>
- /// Gigantic work around for missing features in System.Reflection.Emit follows.
+ /// Utility function that can be used to probe whether a type
+ /// is managed or not.
/// </summary>
- ///
- /// <remarks>
- /// Since System.Reflection.Emit can not return MethodBase.GetParameters
- /// for anything which is dynamic, and we need this in a number of places,
- /// we register this information here, and use it afterwards.
- /// </remarks>
- static public void RegisterMethod (MethodBase mb, AParametersCollection ip)
+ public static bool VerifyUnmanaged (CompilerContext ctx, TypeSpec t, Location loc)
{
- method_params.Add (mb, ip);
- }
+ while (t.IsPointer)
+ t = GetElementType (t);
- static public void RegisterIndexer (PropertyBuilder pb, AParametersCollection p)
- {
- method_params.Add (pb, p);
+ if (IsUnmanagedType (t))
+ return true;
+
+ ctx.Report.SymbolRelatedToPreviousError (t);
+ ctx.Report.Error (208, loc,
+ "Cannot take the address of, get the size of, or declare a pointer to a managed type `{0}'",
+ CSharpName (t));
+
+ return false;
}
- static public AParametersCollection GetParameterData (MethodBase mb)
+ //
+ // Returns whether the array of memberinfos contains the given method
+ //
+ public static bool ArrayContainsMethod (List<MemberSpec> array, MethodSpec new_method, bool ignoreDeclType)
{
- AParametersCollection pd;
- if (!method_params.TryGetValue (mb, out pd)) {
-#if MS_COMPATIBLE
- if (mb.IsGenericMethod && !mb.IsGenericMethodDefinition) {
- MethodInfo mi = ((MethodInfo) mb).GetGenericMethodDefinition ();
- pd = GetParameterData (mi);
- /*
- if (mi.IsGenericMethod)
- pd = pd.InflateTypes (mi.GetGenericArguments (), mb.GetGenericArguments ());
- else
- pd = pd.InflateTypes (mi.DeclaringType.GetGenericArguments (), mb.GetGenericArguments ());
- */
- method_params.Add (mb, pd);
- return pd;
- }
+ AParametersCollection new_args = new_method.Parameters;
- if (mb.DeclaringType.Assembly == CodeGen.Assembly.Builder) {
- throw new InternalErrorException ("Parameters are not registered for method `{0}'",
- TypeManager.CSharpName (mb.DeclaringType) + "." + mb.Name);
- }
+ foreach (MethodSpec method in array) {
+ if (!ignoreDeclType && method.DeclaringType != new_method.DeclaringType)
+ continue;
- pd = ParametersImported.Create (mb);
-#else
- MethodBase generic = TypeManager.DropGenericMethodArguments (mb);
- if (generic != mb) {
- pd = TypeManager.GetParameterData (generic);
- pd = ParametersImported.Create (pd, mb);
- } else {
- pd = ParametersImported.Create (mb);
- }
-#endif
- method_params.Add (mb, pd);
- }
- return pd;
- }
+ if (method.Name != new_method.Name)
+ continue;
- public static AParametersCollection GetParameterData (PropertyInfo pi)
- {
- AParametersCollection pd;
- if (!method_params.TryGetValue (pi, out pd)) {
- if (pi is PropertyBuilder)
- return ParametersCompiled.EmptyReadOnlyParameters;
+ if (!TypeSpecComparer.Override.IsEqual (method.ReturnType, new_method.ReturnType))
+ continue;
- ParameterInfo [] p = pi.GetIndexParameters ();
- if (p == null)
- return ParametersCompiled.EmptyReadOnlyParameters;
+ AParametersCollection old_args = method.Parameters;
+ int old_count = old_args.Count;
+ int i;
+
+ if (new_args.Count != old_count)
+ continue;
+
+ for (i = 0; i < old_count; i++) {
+ if (!TypeSpecComparer.Override.IsEqual (old_args.Types[i], new_args.Types[i]))
+ break;
+ }
+ if (i != old_count)
+ continue;
- pd = ParametersImported.Create (p, null);
- method_params.Add (pi, pd);
+ return true;
}
- return pd;
+ return false;
}
-
- public static AParametersCollection GetDelegateParameters (ResolveContext ec, Type t)
+#region Generics
+ // This method always return false for non-generic compiler,
+ // while Type.IsGenericParameter is returned if it is supported.
+ public static bool IsGenericParameter (TypeSpec type)
{
- Delegate d = LookupDelegate (t);
- if (d != null)
- return d.Parameters;
-
- var invoke_mb = Delegate.GetInvokeMethod (ec.Compiler, t, t);
- return invoke_mb.Parameters;
+ return type.IsGenericParameter;
}
- static public void RegisterOverride (MethodBase override_method, MethodBase base_method)
+ public static bool IsGenericType (TypeSpec type)
{
- if (!method_overrides.ContainsKey (override_method))
- method_overrides [override_method] = base_method;
- if (method_overrides [override_method] != base_method)
- throw new InternalErrorException ("Override mismatch: " + override_method);
+ return type.IsGeneric;
}
- static public bool IsOverride (MethodSpec ms)
+ // TODO: Implement correctly
+ public static bool ContainsGenericParameters (TypeSpec type)
{
- MethodBase m = ms.MetaInfo;
- m = DropGenericMethodArguments (m);
-
- return m.IsVirtual &&
- (m.Attributes & MethodAttributes.NewSlot) == 0 &&
- (m is MethodBuilder || method_overrides.ContainsKey (m));
+ return type.GetMetaInfo ().ContainsGenericParameters;
}
- static public MethodBase TryGetBaseDefinition (MethodBase m)
+ public static bool IsEqual (TypeSpec a, TypeSpec b)
{
- m = DropGenericMethodArguments (m);
- MethodBase mb;
- if (method_overrides.TryGetValue (m, out mb))
- return mb;
+ return a == b && !(a is InternalType);
+ }
- return null;
+ public static TypeSpec[] GetTypeArguments (TypeSpec t)
+ {
+ // TODO: return empty array !!
+ return t.TypeArguments;
}
- public static void RegisterConstant (FieldInfo fb, ConstSpec ic)
+ /// <summary>
+ /// Check whether `type' and `parent' are both instantiations of the same
+ /// generic type. Note that we do not check the type parameters here.
+ /// </summary>
+ public static bool IsInstantiationOfSameGenericType (TypeSpec type, TypeSpec parent)
{
- fields.Add (fb, ic);
+ return type == parent || type.MemberDefinition == parent.MemberDefinition;
}
- public static ConstSpec GetConstant (FieldInfo fb)
+ public static bool IsNullableType (TypeSpec t)
{
- if (fb == null)
- return null;
-
- ConstSpec ic;
- if (fields.TryGetValue (fb, out ic))
- return ic;
-
- return null;
- }
-
- public static void RegisterProperty (PropertyInfo pi, PropertyBase pb)
- {
- propertybuilder_to_property.Add (pi, pb);
- }
-
- public static PropertyBase GetProperty (PropertyInfo pi)
- {
- PropertyBase pb;
- if (propertybuilder_to_property.TryGetValue (pi, out pb))
- return pb;
-
- return null;
- }
-
- static public void RegisterFieldBase (FieldBuilder fb, FieldBase f)
- {
- fieldbuilders_to_fields.Add (fb, f);
- }
-
- //
- // The return value can be null; This will be the case for
- // auxiliary FieldBuilders created by the compiler that have no
- // real field being declared on the source code
- //
- static public FieldBase GetField (FieldInfo fb)
- {
- return GetFieldCore (GetGenericFieldDefinition (fb));
- }
-
- static public FieldBase GetFieldCore (FieldInfo fb)
- {
- FieldBase f;
- if (fieldbuilders_to_fields.TryGetValue (fb, out f))
- return f;
-
- return null;
- }
-
- static public MethodInfo GetAddMethod (EventInfo ei)
- {
- if (ei is MyEventBuilder) {
- return ((MyEventBuilder)ei).GetAddMethod (true);
- }
- return ei.GetAddMethod (true);
- }
-
- static public MethodInfo GetRemoveMethod (EventInfo ei)
- {
- if (ei is MyEventBuilder) {
- return ((MyEventBuilder)ei).GetRemoveMethod (true);
- }
- return ei.GetRemoveMethod (true);
- }
-
- static public void RegisterEventField (EventInfo einfo, EventSpec e)
- {
- if (events == null)
- events = new Dictionary<EventInfo, EventSpec> (ReferenceEquality<EventInfo>.Default);
-
- events.Add (einfo, e);
- }
-
- static public EventSpec GetEventField (EventInfo ei)
- {
- if (events == null)
- return null;
-
- EventSpec value;
- if (events.TryGetValue (ei, out value))
- return value;
-
- return null;
- }
-
- public static bool CheckStructCycles (TypeContainer tc, Dictionary<TypeContainer, object> seen)
- {
- var hash = new Dictionary<TypeContainer, object> ();
- return CheckStructCycles (tc, seen, hash);
- }
-
- public static bool CheckStructCycles (TypeContainer tc, Dictionary<TypeContainer, object> seen,
- Dictionary<TypeContainer, object> hash)
- {
- if ((tc.Kind != MemberKind.Struct) || IsBuiltinType (tc.TypeBuilder))
- return true;
-
- //
- // `seen' contains all types we've already visited.
- //
- if (seen.ContainsKey (tc))
- return true;
- seen.Add (tc, null);
-
- if (tc.Fields == null)
- return true;
-
- foreach (FieldBase field in tc.Fields) {
- if (field.Spec == null || field.Spec.IsStatic)
- continue;
-
- Type ftype = field.Spec.FieldType;
- TypeContainer ftc = LookupTypeContainer (ftype);
- if (ftc == null)
- continue;
-
- if (hash.ContainsKey (ftc)) {
- tc.Compiler.Report.Error (523, tc.Location,
- "Struct member `{0}.{1}' of type `{2}' " +
- "causes a cycle in the struct layout",
- tc.Name, field.Name, ftc.Name);
- return false;
- }
-
- //
- // `hash' contains all types in the current path.
- //
- hash.Add (tc, null);
-
- bool ok = CheckStructCycles (ftc, seen, hash);
-
- hash.Remove (tc);
-
- if (!ok)
- return false;
-
- if (!seen.ContainsKey (ftc))
- seen.Add (ftc, null);
- }
-
- return true;
- }
-
- /// <summary>
- /// Given an array of interface types, expand and eliminate repeated ocurrences
- /// of an interface.
- /// </summary>
- ///
- /// <remarks>
- /// This expands in context like: IA; IB : IA; IC : IA, IB; the interface "IC" to
- /// be IA, IB, IC.
- /// </remarks>
- public static Type[] ExpandInterfaces (TypeExpr [] base_interfaces)
- {
- var new_ifaces = new List<Type> ();
-
- foreach (TypeExpr iface in base_interfaces){
- Type itype = iface.Type;
-
- if (new_ifaces.Contains (itype))
- continue;
-
- new_ifaces.Add (itype);
-
- Type [] implementing = GetInterfaces (itype);
-
- foreach (Type imp in implementing){
- if (!new_ifaces.Contains (imp))
- new_ifaces.Add (imp);
- }
- }
-
- return new_ifaces.ToArray ();
- }
-
- public static Type[] ExpandInterfaces (Type [] base_interfaces)
- {
- var new_ifaces = new List<Type> ();
-
- foreach (Type itype in base_interfaces){
- if (new_ifaces.Contains (itype))
- continue;
-
- new_ifaces.Add (itype);
-
- Type [] implementing = GetInterfaces (itype);
-
- foreach (Type imp in implementing){
- if (!new_ifaces.Contains (imp))
- new_ifaces.Add (imp);
- }
- }
-
- return new_ifaces.ToArray ();
- }
-
- /// <summary>
- /// This function returns the interfaces in the type `t'. Works with
- /// both types and TypeBuilders.
- /// </summary>
- public static Type [] GetInterfaces (Type t)
- {
- Type [] cached;
- if (iface_cache.TryGetValue (t, out cached))
- if (cached != null)
- return cached;
-
- //
- // The reason for catching the Array case is that Reflection.Emit
- // will not return a TypeBuilder for Array types of TypeBuilder types,
- // but will still throw an exception if we try to call GetInterfaces
- // on the type.
- //
- // Since the array interfaces are always constant, we return those for
- // the System.Array
- //
-
- if (t.IsArray)
- t = TypeManager.array_type;
-
- if ((t is TypeBuilder) || IsGenericType (t)) {
- Type [] base_ifaces;
-
- if (t.BaseType == null)
- base_ifaces = Type.EmptyTypes;
- else
- base_ifaces = GetInterfaces (t.BaseType);
- Type[] type_ifaces;
- if (IsGenericType (t))
-#if MS_COMPATIBLE
- type_ifaces = t.GetGenericTypeDefinition().GetInterfaces ();
-#else
- type_ifaces = t.GetInterfaces ();
-#endif
- else
- type_ifaces = GetExplicitInterfaces (t);
- if (type_ifaces == null || type_ifaces.Length == 0)
- type_ifaces = Type.EmptyTypes;
-
- int base_count = base_ifaces.Length;
- Type [] result = new Type [base_count + type_ifaces.Length];
- base_ifaces.CopyTo (result, 0);
- type_ifaces.CopyTo (result, base_count);
-
- iface_cache [t] = result;
- return result;
- } else if (t is GenericTypeParameterBuilder){
- Type[] type_ifaces = GetExplicitInterfaces (t);
- if (type_ifaces == null || type_ifaces.Length == 0)
- type_ifaces = Type.EmptyTypes;
-
- iface_cache [t] = type_ifaces;
- return type_ifaces;
- } else {
- Type[] ifaces = t.GetInterfaces ();
- iface_cache [t] = ifaces;
- return ifaces;
- }
- }
-
- //
- // gets the interfaces that are declared explicitly on t
- //
- public static Type[] GetExplicitInterfaces (Type t)
- {
- Type[] ifaces;
- if (builder_to_ifaces.TryGetValue (t, out ifaces))
- return ifaces;
-
- return null;
- }
-
- /// <remarks>
- /// The following is used to check if a given type implements an interface.
- /// The cache helps us reduce the expense of hitting Type.GetInterfaces everytime.
- /// </remarks>
- public static bool ImplementsInterface (Type t, Type iface)
- {
- Type [] interfaces;
-
- //
- // FIXME OPTIMIZATION:
- // as soon as we hit a non-TypeBuiler in the interface
- // chain, we could return, as the `Type.GetInterfaces'
- // will return all the interfaces implement by the type
- // or its bases.
- //
- do {
- interfaces = GetInterfaces (t);
-
- if (interfaces != null){
- foreach (Type i in interfaces){
- if (i == iface || IsVariantOf (i, iface))
- return true;
- }
- }
-
- t = t.BaseType;
- } while (t != null);
-
- return false;
- }
-
- static NumberFormatInfo nf_provider = CultureInfo.CurrentCulture.NumberFormat;
-
- // This is a custom version of Convert.ChangeType() which works
- // with the TypeBuilder defined types when compiling corlib.
- public static object ChangeType (object value, Type conversionType, out bool error)
- {
- IConvertible convert_value = value as IConvertible;
-
- if (convert_value == null){
- error = true;
- return null;
- }
-
- //
- // NOTE 1:
- // We must use Type.Equals() here since `conversionType' is
- // the TypeBuilder created version of a system type and not
- // the system type itself. You cannot use Type.GetTypeCode()
- // on such a type - it'd always return TypeCode.Object.
- //
- // NOTE 2:
- // We cannot rely on build-in type conversions as they are
- // more limited than what C# supports.
- // See char -> float/decimal/double conversion
- //
-
- error = false;
- try {
- if (conversionType.Equals (typeof (Boolean)))
- return (object)(convert_value.ToBoolean (nf_provider));
- if (conversionType.Equals (typeof (Byte)))
- return (object)(convert_value.ToByte (nf_provider));
- if (conversionType.Equals (typeof (Char)))
- return (object)(convert_value.ToChar (nf_provider));
- if (conversionType.Equals (typeof (DateTime)))
- return (object)(convert_value.ToDateTime (nf_provider));
-
- if (conversionType.Equals (decimal_type)) {
- if (convert_value.GetType () == TypeManager.char_type)
- return (decimal)convert_value.ToInt32 (nf_provider);
- return convert_value.ToDecimal (nf_provider);
- }
-
- if (conversionType.Equals (typeof (Double))) {
- if (convert_value.GetType () == TypeManager.char_type)
- return (double)convert_value.ToInt32 (nf_provider);
- return convert_value.ToDouble (nf_provider);
- }
-
- if (conversionType.Equals (typeof (Int16)))
- return (object)(convert_value.ToInt16 (nf_provider));
- if (conversionType.Equals (int32_type))
- return (object)(convert_value.ToInt32 (nf_provider));
- if (conversionType.Equals (int64_type))
- return (object)(convert_value.ToInt64 (nf_provider));
- if (conversionType.Equals (typeof (SByte)))
- return (object)(convert_value.ToSByte (nf_provider));
-
- if (conversionType.Equals (typeof (Single))) {
- if (convert_value.GetType () == TypeManager.char_type)
- return (float)convert_value.ToInt32 (nf_provider);
- return convert_value.ToSingle (nf_provider);
- }
-
- if (conversionType.Equals (typeof (String)))
- return (object)(convert_value.ToString (nf_provider));
- if (conversionType.Equals (typeof (UInt16)))
- return (object)(convert_value.ToUInt16 (nf_provider));
- if (conversionType.Equals (typeof (UInt32)))
- return (object)(convert_value.ToUInt32 (nf_provider));
- if (conversionType.Equals (typeof (UInt64)))
- return (object)(convert_value.ToUInt64 (nf_provider));
- if (conversionType.Equals (typeof (Object)))
- return (object)(value);
- else
- error = true;
- } catch {
- error = true;
- }
- return null;
- }
-
- //
- // When compiling with -nostdlib and the type is imported from an external assembly
- // SRE uses "wrong" type and we have to convert it to the right compiler instance.
- //
- public static Type TypeToCoreType (Type t)
- {
- if (RootContext.StdLib || t.Module != typeof (object).Module)
- return t;
-
- // TODO: GetTypeCode returns underlying type for enums !!
- TypeCode tc = Type.GetTypeCode (t);
-
- switch (tc){
- case TypeCode.Boolean:
- return TypeManager.bool_type;
- case TypeCode.Byte:
- return TypeManager.byte_type;
- case TypeCode.SByte:
- return TypeManager.sbyte_type;
- case TypeCode.Char:
- return TypeManager.char_type;
- case TypeCode.Int16:
- return TypeManager.short_type;
- case TypeCode.UInt16:
- return TypeManager.ushort_type;
- case TypeCode.Int32:
- return TypeManager.int32_type;
- case TypeCode.UInt32:
- return TypeManager.uint32_type;
- case TypeCode.Int64:
- return TypeManager.int64_type;
- case TypeCode.UInt64:
- return TypeManager.uint64_type;
- case TypeCode.Single:
- return TypeManager.float_type;
- case TypeCode.Double:
- return TypeManager.double_type;
- case TypeCode.String:
- return TypeManager.string_type;
- case TypeCode.Decimal:
- return TypeManager.decimal_type;
- }
-
- if (t == typeof (void))
- return TypeManager.void_type;
- if (t == typeof (object))
- return TypeManager.object_type;
- if (t == typeof (System.Type))
- return TypeManager.type_type;
- if (t == typeof (System.IntPtr))
- return TypeManager.intptr_type;
- if (t == typeof (System.UIntPtr))
- return TypeManager.uintptr_type;
-
- if (t.IsArray) {
- int dim = t.GetArrayRank ();
- t = GetElementType (t);
- return t.MakeArrayType (dim);
- }
- if (t.IsByRef) {
- t = GetElementType (t);
- return t.MakeByRefType ();
- }
- if (t.IsPointer) {
- t = GetElementType (t);
- return t.MakePointerType ();
- }
-
- return t;
- }
-
- //
- // Converts any type to reflection supported type
- //
- public static Type TypeToReflectionType (Type type)
- {
- // TODO: Very lame and painful, GetReference () is enough for mcs-cecil
- if (IsDynamicType (type))
- return object_type;
-
- if (type is DynamicArrayType)
- return type.UnderlyingSystemType;
-
- return type;
- }
-
- /// <summary>
- /// Utility function that can be used to probe whether a type
- /// is managed or not.
- /// </summary>
- public static bool VerifyUnmanaged (CompilerContext ctx, Type t, Location loc)
- {
- if (IsUnmanagedType (t))
- return true;
-
- while (t.IsPointer)
- t = GetElementType (t);
-
- ctx.Report.SymbolRelatedToPreviousError (t);
- ctx.Report.Error (208, loc,
- "Cannot take the address of, get the size of, or declare a pointer to a managed type `{0}'",
- CSharpName (t));
-
- return false;
- }
-
- /// <summary>
- /// Returns the name of the indexer in a given type.
- /// </summary>
- /// <remarks>
- /// The default is not always `Item'. The user can change this behaviour by
- /// using the IndexerNameAttribute in the container.
- /// For example, the String class indexer is named `Chars' not `Item'
- /// </remarks>
- public static string IndexerPropertyName (Type t)
- {
- t = DropGenericTypeArguments (t);
- if (t is TypeBuilder) {
- TypeContainer tc = t.IsInterface ? LookupInterface (t) : LookupTypeContainer (t);
- return tc == null ? TypeContainer.DefaultIndexerName : tc.IndexerName;
- }
-
- PredefinedAttribute pa = PredefinedAttributes.Get.DefaultMember;
- if (pa.IsDefined) {
- System.Attribute attr = System.Attribute.GetCustomAttribute (
- t, pa.Type);
- if (attr != null) {
- DefaultMemberAttribute dma = (DefaultMemberAttribute) attr;
- return dma.MemberName;
- }
- }
-
- return TypeContainer.DefaultIndexerName;
- }
-
- private static bool IsSignatureEqual (Type a, Type b)
- {
- ///
- /// Consider the following example (bug #77674):
- ///
- /// public abstract class A
- /// {
- /// public abstract T Foo<T> ();
- /// }
- ///
- /// public abstract class B : A
- /// {
- /// public override U Foo<T> ()
- /// { return default (U); }
- /// }
- ///
- /// Here, `T' and `U' are method type parameters from different methods
- /// (A.Foo and B.Foo), so both `==' and Equals() will fail.
- ///
- /// However, since we're determining whether B.Foo() overrides A.Foo(),
- /// we need to do a signature based comparision and consider them equal.
-
- if (a == b)
- return true;
-
- if (a.IsGenericParameter && b.IsGenericParameter &&
- (a.DeclaringMethod != null) && (b.DeclaringMethod != null)) {
- return a.GenericParameterPosition == b.GenericParameterPosition;
- }
-
- if (a.IsArray && b.IsArray) {
- if (a.GetArrayRank () != b.GetArrayRank ())
- return false;
-
- return IsSignatureEqual (GetElementType (a), GetElementType (b));
- }
-
- if (a.IsByRef && b.IsByRef)
- return IsSignatureEqual (GetElementType (a), GetElementType (b));
-
- if (IsGenericType (a) && IsGenericType (b)) {
- if (DropGenericTypeArguments (a) != DropGenericTypeArguments (b))
- return false;
-
- Type[] aargs = GetTypeArguments (a);
- Type[] bargs = GetTypeArguments (b);
-
- if (aargs.Length != bargs.Length)
- return false;
-
- for (int i = 0; i < aargs.Length; i++) {
- if (!IsSignatureEqual (aargs [i], bargs [i]))
- return false;
- }
-
- return true;
- }
-
- return false;
- }
-
- //
- // Returns whether the array of memberinfos contains the given method
- //
- public static bool ArrayContainsMethod (MethodBase [] array, MethodBase new_method, bool ignoreDeclType)
- {
- Type [] new_args = TypeManager.GetParameterData (new_method).Types;
-
- foreach (MethodBase method in array) {
- if (!ignoreDeclType && method.DeclaringType != new_method.DeclaringType)
- continue;
-
- if (method.Name != new_method.Name)
- continue;
-
- if (method is MethodInfo && new_method is MethodInfo &&
- !IsSignatureEqual (
- TypeToCoreType (((MethodInfo) method).ReturnType),
- TypeToCoreType (((MethodInfo) new_method).ReturnType)))
- continue;
-
- Type [] old_args = TypeManager.GetParameterData (method).Types;
- int old_count = old_args.Length;
- int i;
-
- if (new_args.Length != old_count)
- continue;
-
- for (i = 0; i < old_count; i++){
- if (!IsSignatureEqual (old_args [i], new_args [i]))
- break;
- }
- if (i != old_count)
- continue;
-
- return true;
- }
-
- return false;
- }
-
- //
- // We copy methods from `new_members' into `target_list' if the signature
- // for the method from in the new list does not exist in the target_list
- //
- // The name is assumed to be the same.
- //
- public static List<MethodBase> CopyNewMethods (List<MethodBase> target_list, IList<MemberInfo> new_members)
- {
- if (target_list == null){
- target_list = new List<MethodBase> ();
-
- foreach (MemberInfo mi in new_members){
- if (mi is MethodBase)
- target_list.Add ((MethodBase) mi);
- }
- return target_list;
- }
-
- MethodBase[] target_array = new MethodBase[target_list.Count];
- target_list.CopyTo (target_array, 0);
-
- foreach (MemberInfo mi in new_members){
- MethodBase new_method = (MethodBase) mi;
-
- if (!ArrayContainsMethod (target_array, new_method, true))
- target_list.Add (new_method);
- }
- return target_list;
- }
-
-#region Generics
- // <remarks>
- // Tracks the generic parameters.
- // </remarks>
-
- public static void AddTypeParameter (GenericTypeParameterBuilder t, TypeParameter tparam)
- {
- builder_to_type_param [t] = tparam;
- }
-
- public static TypeParameter LookupTypeParameter (Type t)
- {
- TypeParameter tp;
- var gtp = t as GenericTypeParameterBuilder;
- if (gtp != null && builder_to_type_param.TryGetValue (gtp, out tp))
- return tp;
-
- return null;
- }
-
- // This method always return false for non-generic compiler,
- // while Type.IsGenericParameter is returned if it is supported.
- public static bool IsGenericParameter (Type type)
- {
- return type.IsGenericParameter;
- }
-
- public static int GenericParameterPosition (Type type)
- {
- return type.GenericParameterPosition;
- }
-
- public static bool IsGenericType (Type type)
- {
- return type.IsGenericType;
- }
-
- public static bool IsGenericTypeDefinition (Type type)
- {
- return type.IsGenericTypeDefinition;
- }
-
- public static bool ContainsGenericParameters (Type type)
- {
- return type.ContainsGenericParameters;
- }
-
- public static FieldInfo GetGenericFieldDefinition (FieldInfo fi)
- {
- if (fi.DeclaringType.IsGenericTypeDefinition ||
- !fi.DeclaringType.IsGenericType)
- return fi;
-
- Type t = fi.DeclaringType.GetGenericTypeDefinition ();
- BindingFlags bf = BindingFlags.Public | BindingFlags.NonPublic |
- BindingFlags.Static | BindingFlags.Instance | BindingFlags.DeclaredOnly;
-
- // TODO: use CodeGen.Module.Builder.ResolveField (fi.MetadataToken);
- foreach (FieldInfo f in t.GetFields (bf))
- if (f.MetadataToken == fi.MetadataToken)
- return f;
-
- return fi;
- }
-
- public static bool IsEqual (Type a, Type b)
- {
- if (a.Equals (b)) {
- // MS BCL returns true even if enum types are different
- if (a.BaseType == TypeManager.enum_type || b.BaseType == TypeManager.enum_type)
- return a.FullName == b.FullName;
-
- // Some types are never equal
- if (a == TypeManager.null_type || a == InternalType.AnonymousMethod)
- return false;
-
- return true;
- }
-
- if (IsGenericParameter (a) && IsGenericParameter (b)) {
- // TODO: needs more testing before cleaning up
- //if (a.DeclaringMethod != b.DeclaringMethod &&
- // (a.DeclaringMethod == null || b.DeclaringMethod == null))
- // return false;
- return a.GenericParameterPosition == b.GenericParameterPosition;
- }
-
- if (a.IsArray && b.IsArray) {
- if (a.GetArrayRank () != b.GetArrayRank ())
- return false;
- return IsEqual (GetElementType (a), GetElementType (b));
- }
-
- if (a.IsByRef && b.IsByRef)
- return IsEqual (a.GetElementType (), b.GetElementType ());
-
- if (IsGenericType (a) && IsGenericType (b)) {
- Type adef = DropGenericTypeArguments (a);
- Type bdef = DropGenericTypeArguments (b);
-
- if (adef != bdef)
- return false;
-
- if (adef.IsEnum && bdef.IsEnum)
- return true;
-
- Type[] aargs = GetTypeArguments (a);
- Type[] bargs = GetTypeArguments (b);
-
- if (aargs.Length != bargs.Length)
- return false;
-
- for (int i = 0; i < aargs.Length; i++) {
- if (!IsEqual (aargs [i], bargs [i]))
- return false;
- }
-
- return true;
- }
-
- return false;
- }
-
- public static bool IsEqual (Type[] a, Type[] b)
- {
- if (a == null || b == null || a.Length != b.Length)
- return false;
-
- for (int i = 0; i < a.Length; ++i) {
- if (a [i] == null || b [i] == null) {
- if (a [i] == b [i])
- continue;
-
- return false;
- }
-
- if (!IsEqual (a [i], b [i]))
- return false;
- }
-
- return true;
- }
-
- public static Type DropGenericTypeArguments (Type t)
- {
- if (!t.IsGenericType)
- return t;
- // Micro-optimization: a generic typebuilder is always a generic type definition
- if (t is TypeBuilder)
- return t;
- return t.GetGenericTypeDefinition ();
- }
-
- public static MethodBase DropGenericMethodArguments (MethodSpec m)
- {
- return DropGenericMethodArguments (m.MetaInfo);
- }
-
- public static MethodBase DropGenericMethodArguments (MethodBase m)
- {
- if (m.IsGenericMethod)
- m = ((MethodInfo) m).GetGenericMethodDefinition ();
-
- Type t = m.DeclaringType;
- if (!t.IsGenericType || t.IsGenericTypeDefinition)
- return m;
-
- t = t.GetGenericTypeDefinition ();
- BindingFlags bf = BindingFlags.Public | BindingFlags.NonPublic |
- BindingFlags.Static | BindingFlags.Instance | BindingFlags.DeclaredOnly;
-
-#if MS_COMPATIBLE
- // TODO: use CodeGen.Module.Builder.ResolveMethod ()
- return m;
-#endif
-
- if (m is ConstructorInfo) {
- foreach (ConstructorInfo c in t.GetConstructors (bf))
- if (c.MetadataToken == m.MetadataToken)
- return c;
- } else {
- foreach (MethodBase mb in t.GetMethods (bf))
- if (mb.MetadataToken == m.MetadataToken)
- return mb;
- }
-
- return m;
- }
-
- public static Type[] GetGenericArguments (MethodBase mi)
- {
- return mi.GetGenericArguments () ?? Type.EmptyTypes;
- }
-
- public static Type[] GetTypeArguments (Type t)
- {
- DeclSpace tc = LookupDeclSpace (t);
- if (tc != null) {
- if (!tc.IsGeneric)
- return Type.EmptyTypes;
-
- TypeParameter[] tparam = tc.TypeParameters;
- Type[] ret = new Type [tparam.Length];
- for (int i = 0; i < tparam.Length; i++) {
- ret [i] = tparam [i].Type;
- if (ret [i] == null)
- throw new InternalErrorException ();
- }
-
- return ret;
- } else
- return t.GetGenericArguments ();
- }
-
- public static GenericConstraints GetTypeParameterConstraints (Type t)
- {
- if (!t.IsGenericParameter)
- throw new InvalidOperationException ();
-
- TypeParameter tparam = LookupTypeParameter (t);
- if (tparam != null)
- return tparam.GenericConstraints;
-
- return ReflectionConstraints.GetConstraints (t);
- }
-
- public static bool HasGenericArguments (Type t)
- {
- return GetNumberOfTypeArguments (t) > 0;
- }
-
- public static int GetNumberOfTypeArguments (Type t)
- {
- if (t.IsGenericParameter)
- return 0;
- DeclSpace tc = LookupDeclSpace (t);
- if (tc != null)
- return tc.IsGeneric ? tc.CountTypeParameters : 0;
- else
- return t.IsGenericType ? t.GetGenericArguments ().Length : 0;
- }
-
- /// <summary>
- /// Check whether `type' and `parent' are both instantiations of the same
- /// generic type. Note that we do not check the type parameters here.
- /// </summary>
- public static bool IsInstantiationOfSameGenericType (Type type, Type parent)
- {
- int tcount = GetNumberOfTypeArguments (type);
- int pcount = GetNumberOfTypeArguments (parent);
-
- if (tcount != pcount)
- return false;
-
- type = DropGenericTypeArguments (type);
- parent = DropGenericTypeArguments (parent);
-
- return type.Equals (parent);
- }
-
- /// <summary>
- /// Whether `mb' is a generic method definition.
- /// </summary>
- public static bool IsGenericMethodDefinition (MethodBase mb)
- {
- if (mb.DeclaringType is TypeBuilder) {
- IMethodData method = GetMethod (mb);
- if (method == null)
- return false;
-
- return method.GenericMethod != null;
- }
-
- return mb.IsGenericMethodDefinition;
- }
-
- /// <summary>
- /// Whether `mb' is a generic method.
- /// </summary>
- public static bool IsGenericMethod (MethodBase mb)
- {
- return mb.IsGenericMethod;
- }
-
- public static bool IsNullableType (Type t)
- {
- return generic_nullable_type == DropGenericTypeArguments (t);
- }
-
- public static MethodInfo MakeGenericMethod (MethodInfo gmd, Type[] methodArguments)
- {
- if (!gmd.IsGenericMethodDefinition)
- gmd = gmd.GetGenericMethodDefinition ();
- return gmd.MakeGenericMethod (methodArguments);
+ return generic_nullable_type == t.GetDefinition ();
}
#endregion
-#region MemberLookup implementation
-
- //
- // Whether we allow private members in the result (since FindMembers
- // uses NonPublic for both protected and private), we need to distinguish.
- //
-
- internal class Closure {
- internal bool private_ok;
-
- // Who is invoking us and which type is being queried currently.
- internal Type invocation_type;
- internal Type qualifier_type;
-
- // The assembly that defines the type is that is calling us
- internal Assembly invocation_assembly;
- internal IList<MemberInfo> almost_match;
-
- private bool CheckValidFamilyAccess (bool is_static, MemberInfo m)
- {
- if (invocation_type == null)
- return false;
-
- if (is_static && qualifier_type == null)
- // It resolved from a simple name, so it should be visible.
- return true;
-
- if (IsNestedChildOf (invocation_type, m.DeclaringType))
- return true;
-
- for (Type t = invocation_type; t != null; t = t.DeclaringType) {
- if (!IsFamilyAccessible (t, m.DeclaringType))
- continue;
-
- // Although a derived class can access protected members of its base class
- // it cannot do so through an instance of the base class (CS1540).
- // => Ancestry should be: declaring_type ->* invocation_type ->* qualified_type
- if (is_static || qualifier_type == null ||
- IsInstantiationOfSameGenericType (t, qualifier_type) ||
- IsFamilyAccessible (qualifier_type, t))
- return true;
- }
-
- if (almost_match != null)
- almost_match.Add (m);
-
- return false;
- }
-
- //
- // This filter filters by name + whether it is ok to include private
- // members in the search
- //
- internal bool Filter (MemberInfo m, object filter_criteria)
- {
- //
- // Hack: we know that the filter criteria will always be in the
- // `closure' // fields.
- //
-
- if ((filter_criteria != null) && (m.Name != (string) filter_criteria))
- return false;
-
- if (((qualifier_type == null) || (qualifier_type == invocation_type)) &&
- (invocation_type != null) &&
- IsPrivateAccessible (m.DeclaringType, invocation_type))
- return true;
-
- //
- // Ugly: we need to find out the type of `m', and depending
- // on this, tell whether we accept or not
- //
- if (m is MethodBase){
- MethodBase mb = (MethodBase) m;
- MethodAttributes ma = mb.Attributes & MethodAttributes.MemberAccessMask;
-
- if (ma == MethodAttributes.Public)
- return true;
-
- if (ma == MethodAttributes.PrivateScope)
- return false;
-
- if (ma == MethodAttributes.Private)
- return private_ok ||
- IsPrivateAccessible (invocation_type, m.DeclaringType) ||
- IsNestedChildOf (invocation_type, m.DeclaringType);
-
- if (TypeManager.IsThisOrFriendAssembly (invocation_assembly, mb.DeclaringType.Assembly)) {
- if (ma == MethodAttributes.Assembly || ma == MethodAttributes.FamORAssem)
- return true;
- } else {
- if (ma == MethodAttributes.Assembly || ma == MethodAttributes.FamANDAssem)
- return false;
- }
-
- // Family, FamORAssem or FamANDAssem
- return CheckValidFamilyAccess (mb.IsStatic, m);
- }
-
- if (m is FieldInfo){
- FieldInfo fi = (FieldInfo) m;
- FieldAttributes fa = fi.Attributes & FieldAttributes.FieldAccessMask;
-
- if (fa == FieldAttributes.Public)
- return true;
-
- if (fa == FieldAttributes.PrivateScope)
- return false;
-
- if (fa == FieldAttributes.Private)
- return private_ok ||
- IsPrivateAccessible (invocation_type, m.DeclaringType) ||
- IsNestedChildOf (invocation_type, m.DeclaringType);
-
- if (TypeManager.IsThisOrFriendAssembly (invocation_assembly, fi.DeclaringType.Assembly)) {
- if ((fa == FieldAttributes.Assembly) ||
- (fa == FieldAttributes.FamORAssem))
- return true;
- } else {
- if ((fa == FieldAttributes.Assembly) ||
- (fa == FieldAttributes.FamANDAssem))
- return false;
- }
-
- // Family, FamORAssem or FamANDAssem
- return CheckValidFamilyAccess (fi.IsStatic, m);
- }
-
- //
- // EventInfos and PropertyInfos, return true because they lack
- // permission information, so we need to check later on the methods.
- //
- return true;
- }
- }
-
- static Closure closure;
- static MemberFilter FilterWithClosure_delegate;
-
//
// Looks up a member called `name' in the `queried_type'. This lookup
// is done by code that is contained in the definition for `invocation_type'
// Returns an array of a single element for everything but Methods/Constructors
// that might return multiple matches.
//
- public static MemberInfo [] MemberLookup (Type invocation_type, Type qualifier_type,
- Type queried_type, MemberTypes mt,
- BindingFlags original_bf, string name, IList<MemberInfo> almost_match)
+ public static IList<MemberSpec> MemberLookup (TypeSpec invocation_type, TypeSpec qualifier_type,
+ TypeSpec queried_type, MemberKind mt,
+ BindingRestriction opt, string name, int arity, IList<MemberSpec> almost_match)
{
Timer.StartTimer (TimerType.MemberLookup);
- MemberInfo[] retval = RealMemberLookup (invocation_type, qualifier_type,
- queried_type, mt, original_bf, name, almost_match);
+ var retval = RealMemberLookup (invocation_type, qualifier_type,
+ queried_type, mt, opt, name, arity, almost_match);
Timer.StopTimer (TimerType.MemberLookup);
return retval;
}
- static MemberInfo [] RealMemberLookup (Type invocation_type, Type qualifier_type,
- Type queried_type, MemberTypes mt,
- BindingFlags original_bf, string name, IList<MemberInfo> almost_match)
- {
- BindingFlags bf = original_bf;
-
- List<MethodBase> method_list = null;
- Type current_type = queried_type;
- bool searching = (original_bf & BindingFlags.DeclaredOnly) == 0;
- bool skip_iface_check = true, used_cache = false;
- bool always_ok_flag = invocation_type != null && IsNestedChildOf (invocation_type, queried_type);
-
- closure.invocation_type = invocation_type;
- closure.invocation_assembly = invocation_type != null ? invocation_type.Assembly : null;
- closure.qualifier_type = qualifier_type;
- closure.almost_match = almost_match;
-
- // This is from the first time we find a method
- // in most cases, we do not actually find a method in the base class
- // so we can just ignore it, and save the arraylist allocation
- MemberInfo [] first_members_list = null;
- bool use_first_members_list = false;
-
- do {
- MemberInfo [] list;
-
- //
- // `NonPublic' is lame, because it includes both protected and
- // private methods, so we need to control this behavior by
- // explicitly tracking if a private method is ok or not.
- //
- // The possible cases are:
- // public, private and protected (internal does not come into the
- // equation)
- //
- if ((invocation_type != null) &&
- ((invocation_type == current_type) ||
- IsNestedChildOf (invocation_type, current_type)) ||
- always_ok_flag)
- bf = original_bf | BindingFlags.NonPublic;
- else
- bf = original_bf;
-
- closure.private_ok = (original_bf & BindingFlags.NonPublic) != 0;
-
- Timer.StopTimer (TimerType.MemberLookup);
-
- list = MemberLookup_FindMembers (current_type, mt, bf, name, out used_cache);
-
- Timer.StartTimer (TimerType.MemberLookup);
-
- //
- // When queried for an interface type, the cache will automatically check all
- // inherited members, so we don't need to do this here. However, this only
- // works if we already used the cache in the first iteration of this loop.
- //
- // If we used the cache in any further iteration, we can still terminate the
- // loop since the cache always looks in all base classes.
- //
-
- if (used_cache)
- searching = false;
- else
- skip_iface_check = false;
-
- if (current_type == TypeManager.object_type)
- searching = false;
- else {
- current_type = current_type.BaseType;
-
- //
- // This happens with interfaces, they have a null
- // basetype. Look members up in the Object class.
- //
- if (current_type == null) {
- current_type = TypeManager.object_type;
- searching = true;
- }
- }
-
- if (list.Length == 0)
- continue;
-
- //
- // Events and types are returned by both `static' and `instance'
- // searches, which means that our above FindMembers will
- // return two copies of the same.
- //
- if (list.Length == 1 && !(list [0] is MethodBase)){
- return list;
- }
-
- //
- // Multiple properties: we query those just to find out the indexer
- // name
- //
- if (list [0] is PropertyInfo)
- return list;
-
- //
- // We found an event: the cache lookup returns both the event and
- // its private field.
- //
- if (list [0] is EventInfo) {
- if ((list.Length == 2) && (list [1] is FieldInfo))
- return new MemberInfo [] { list [0] };
-
- return list;
- }
-
- //
- // We found methods, turn the search into "method scan"
- // mode.
- //
-
- if (first_members_list != null) {
- if (use_first_members_list) {
- method_list = CopyNewMethods (method_list, first_members_list);
- use_first_members_list = false;
- }
-
- method_list = CopyNewMethods (method_list, list);
- } else {
- first_members_list = list;
- use_first_members_list = true;
- mt &= (MemberTypes.Method | MemberTypes.Constructor);
- }
- } while (searching);
-
- if (use_first_members_list)
- return first_members_list;
-
- if (method_list != null && method_list.Count > 0) {
- return method_list.ToArray ();
- }
- //
- // This happens if we already used the cache in the first iteration, in this case
- // the cache already looked in all interfaces.
- //
- if (skip_iface_check)
- return null;
-
- //
- // Interfaces do not list members they inherit, so we have to
- // scan those.
- //
- if (!queried_type.IsInterface)
- return null;
-
- if (queried_type.IsArray)
- queried_type = TypeManager.array_type;
-
- Type [] ifaces = GetInterfaces (queried_type);
- if (ifaces == null)
- return null;
-
- foreach (Type itype in ifaces){
- MemberInfo [] x;
-
- x = MemberLookup (null, null, itype, mt, bf, name, null);
- if (x != null)
- return x;
- }
-
- return null;
- }
-
- public const BindingFlags AllMembers = BindingFlags.Public | BindingFlags.NonPublic |
- BindingFlags.Static | BindingFlags.Instance |
- BindingFlags.DeclaredOnly;
-
- // Currently is designed to work with external types only
- public static PropertyInfo GetPropertyFromAccessor (MethodBase mb)
- {
- if (!mb.IsSpecialName)
- return null;
-
- string name = mb.Name;
- if (name.Length < 5)
- return null;
-
- if (name [3] != '_')
- return null;
-
- if (name.StartsWith ("get") || name.StartsWith ("set")) {
- MemberInfo[] pi = mb.DeclaringType.FindMembers (MemberTypes.Property, AllMembers,
- Type.FilterName, name.Substring (4));
-
- if (pi == null)
- return null;
-
- // This can happen when property is indexer (it can have same name but different parameters)
- foreach (PropertyInfo p in pi) {
- foreach (MethodInfo p_mi in p.GetAccessors (true)) {
- if (p_mi == mb || TypeManager.GetParameterData (p_mi).Equals (TypeManager.GetParameterData (mb)))
- return p;
- }
- }
- }
-
- return null;
- }
-
- // Currently is designed to work with external types only
- public static MemberInfo GetEventFromAccessor (MethodBase mb)
- {
- if (!mb.IsSpecialName)
- return null;
-
- string name = mb.Name;
- if (name.Length < 5)
- return null;
-
- if (name.StartsWith ("add_"))
- return mb.DeclaringType.GetEvent (name.Substring (4), AllMembers);
-
- if (name.StartsWith ("remove_"))
- return mb.DeclaringType.GetEvent (name.Substring (7), AllMembers);
-
- return null;
- }
-
- // Tests whether external method is really special
- public static bool IsSpecialMethod (MethodBase mb)
- {
- if (!mb.IsSpecialName)
- return false;
-
- IMethodData md = TypeManager.GetMethod (mb);
- if (md != null)
- return (md is AbstractPropertyEventMethod || md is Operator);
-
- PropertyInfo pi = GetPropertyFromAccessor (mb);
- if (pi != null)
- return IsValidProperty (pi);
-
- if (GetEventFromAccessor (mb) != null)
- return true;
-
- string name = mb.Name;
- if (name.StartsWith ("op_"))
- return Operator.GetName (name) != null;
-
- return false;
- }
-
- // Tests whether imported property is valid C# property.
- // TODO: It seems to me that we should do a lot of sanity tests before
- // we accept property as C# property
- static bool IsValidProperty (PropertyInfo pi)
+ static IList<MemberSpec> RealMemberLookup (TypeSpec invocation_type, TypeSpec qualifier_type,
+ TypeSpec queried_type, MemberKind mt,
+ BindingRestriction bf, string name, int arity, IList<MemberSpec> almost_match)
{
- MethodInfo get_method = pi.GetGetMethod (true);
- MethodInfo set_method = pi.GetSetMethod (true);
- int g_count = 0;
- int s_count = 0;
- if (get_method != null && set_method != null) {
- g_count = get_method.GetParameters ().Length;
- s_count = set_method.GetParameters ().Length;
- if (g_count + 1 != s_count)
- return false;
- } else if (get_method != null) {
- g_count = get_method.GetParameters ().Length;
- } else if (set_method != null) {
- s_count = set_method.GetParameters ().Length;
- }
-
- //
- // DefaultMemberName and indexer name has to match to identify valid C# indexer
- //
- PredefinedAttribute pa = PredefinedAttributes.Get.DefaultMember;
- if ((s_count > 1 || g_count > 0) && pa.IsDefined) {
- object[] o = pi.DeclaringType.GetCustomAttributes (pa.Type, false);
- if (o.Length == 0)
- return false;
-
- DefaultMemberAttribute dma = (DefaultMemberAttribute) o [0];
- if (dma.MemberName != pi.Name)
- return false;
- if (get_method != null && "get_" + dma.MemberName != get_method.Name)
- return false;
- if (set_method != null && "set_" + dma.MemberName != set_method.Name)
- return false;
+ MemberFilter filter = new MemberFilter (name, arity, mt, null, null);
+ if ((bf & BindingRestriction.AccessibleOnly) != 0) {
+ filter.InvocationType = invocation_type ?? InternalType.FakeInternalType;
}
- return true;
- }
-
-#endregion
-
+ return MemberCache.FindMembers (queried_type, filter, bf);
+ }
}
- class InternalType
- {
- public static readonly Type AnonymousMethod = typeof (AnonymousMethodBody);
- public static readonly Type Arglist = typeof (ArglistAccess);
- public static readonly Type Dynamic = new DynamicType ();
- public static readonly Type MethodGroup = typeof (MethodGroupExpr);
- }
-
-/// <summary>
-/// There is exactly one instance of this class per type.
-/// </summary>
-sealed class TypeHandle : IMemberContainer {
- public readonly IMemberContainer BaseType;
-
- readonly int id = ++next_id;
- static int next_id = 0;
-
- static TypeHandle ()
- {
- Reset ();
- }
-
- /// <summary>
- /// Lookup a TypeHandle instance for the given type. If the type doesn't have
- /// a TypeHandle yet, a new instance of it is created. This static method
- /// ensures that we'll only have one TypeHandle instance per type.
- /// </summary>
- private static TypeHandle GetTypeHandle (Type t)
- {
- TypeHandle handle;
- if (type_hash.TryGetValue (t, out handle))
- return handle;
-
- handle = new TypeHandle (t);
- type_hash.Add (t, handle);
- return handle;
- }
-
- public static MemberCache GetMemberCache (Type t)
- {
- return GetTypeHandle (t).MemberCache;
- }
-
- public static void CleanUp ()
- {
- type_hash = null;
- }
-
- public static void Reset ()
- {
- type_hash = new Dictionary<Type, TypeHandle> (ReferenceEquality<Type>.Default);
- }
-
- /// <summary>
- /// Returns the TypeHandle for TypeManager.object_type.
- /// </summary>
- public static IMemberContainer ObjectType {
- get {
- if (object_type != null)
- return object_type;
-
- object_type = GetTypeHandle (TypeManager.object_type);
-
- return object_type;
- }
- }
-
- /// <summary>
- /// Returns the TypeHandle for TypeManager.array_type.
- /// </summary>
- public static TypeHandle ArrayType {
- get {
- if (array_type != null)
- return array_type;
-
- array_type = GetTypeHandle (TypeManager.array_type);
-
- return array_type;
- }
- }
-
- static Dictionary<Type, TypeHandle> type_hash;
-
- private static TypeHandle object_type;
- private static TypeHandle array_type;
-
- private Type type;
- private string full_name;
- private bool is_interface;
- private MemberCache member_cache;
- private MemberCache base_cache;
-
- private TypeHandle (Type type)
- {
- this.type = type;
- full_name = type.FullName != null ? type.FullName : type.Name;
- if (type.BaseType != null) {
- base_cache = TypeManager.LookupMemberCache (type.BaseType);
- BaseType = base_cache.Container;
- } else if (type.IsInterface)
- base_cache = TypeManager.LookupBaseInterfacesCache (type);
- this.is_interface = type.IsInterface || TypeManager.IsGenericParameter (type);
- this.member_cache = new MemberCache (this);
- }
-
- // IMemberContainer methods
-
- public string Name {
- get {
- return full_name;
- }
- }
-
- public Type Type {
- get {
- return type;
- }
- }
-
- public MemberCache BaseCache {
- get {
- return base_cache;
- }
- }
-
- public bool IsInterface {
- get {
- return is_interface;
- }
- }
-
- public MemberList GetMembers (MemberTypes mt, BindingFlags bf)
- {
- MemberInfo [] members;
-
- if (type is GenericTypeParameterBuilder)
- return MemberList.Empty;
-
-#if MS_COMPATIBLE
- type = TypeManager.DropGenericTypeArguments (type);
-#endif
- if (mt == MemberTypes.Event)
- members = type.GetEvents (bf | BindingFlags.DeclaredOnly);
- else
- members = type.FindMembers (mt, bf | BindingFlags.DeclaredOnly,
- null, null);
-
- if (members.Length == 0)
- return MemberList.Empty;
-
- Array.Reverse (members);
- return new MemberList (members);
- }
-
- // IMemberFinder methods
-
- public MemberList FindMembers (MemberTypes mt, BindingFlags bf, string name,
- MemberFilter filter, object criteria)
- {
- return new MemberList (member_cache.FindMembers (mt, bf, name, filter, criteria));
- }
-
- public MemberCache MemberCache {
- get {
- return member_cache;
- }
- }
-
- public override string ToString ()
- {
- if (BaseType != null)
- return "TypeHandle (" + id + "," + Name + " : " + BaseType + ")";
- else
- return "TypeHandle (" + id + "," + Name + ")";
- }
-}
}
using System;
using System.Collections.Generic;
+using System.Text;
+using System.Linq;
namespace Mono.CSharp
{
public class TypeSpec : MemberSpec
{
- Type info;
+ protected Type info;
protected MemberCache cache;
+ protected IList<TypeSpec> ifaces;
+ TypeSpec base_type;
- public TypeSpec (MemberKind kind, ITypeDefinition definition, Type info, string name, Modifiers modifiers)
- : base (kind, definition, name, modifiers)
+ Dictionary<TypeSpec[], InflatedTypeSpec> inflated_instances;
+
+ public static readonly TypeSpec[] EmptyTypes = new TypeSpec[0];
+
+ // Reflection Emit hacking
+ static Type TypeBuilder;
+ static Type GenericTypeBuilder;
+
+ static TypeSpec ()
+ {
+ var assembly = typeof (object).Assembly;
+ TypeBuilder = assembly.GetType ("System.Reflection.Emit.TypeBuilder");
+ GenericTypeBuilder = assembly.GetType ("System.Reflection.MonoGenericClass");
+ if (GenericTypeBuilder == null)
+ GenericTypeBuilder = assembly.GetType ("System.Reflection.Emit.TypeBuilderInstantiation");
+ }
+
+ public TypeSpec (MemberKind kind, TypeSpec declaringType, ITypeDefinition definition, Type info, Modifiers modifiers)
+ : base (kind, declaringType, definition, modifiers)
{
+ this.declaringType = declaringType;
this.info = info;
+
+ if (definition != null && definition.TypeParametersCount > 0)
+ state |= StateFlags.IsGeneric;
+ }
+
+ #region Properties
+
+ public override int Arity {
+ get {
+ return MemberDefinition.TypeParametersCount;
+ }
+ }
+
+ public virtual TypeSpec BaseType {
+ get {
+ return base_type;
+ }
+ set {
+ base_type = value;
+ }
+ }
+
+ public virtual IList<TypeSpec> Interfaces {
+ get {
+ return ifaces;
+ }
+ set {
+ ifaces = value;
+ }
+ }
+
+ public bool IsArray {
+ get { return this is ArrayContainer; }
+ }
+
+ public bool IsAttribute {
+ get {
+ if (!IsClass)
+ return false;
+
+ var type = this;
+ do {
+ if (type.IsGeneric)
+ return false;
+
+ if (type == TypeManager.attribute_type)
+ return true;
+
+ type = type.base_type;
+ } while (type != null);
+
+ return false;
+ }
+ }
+
+ public bool IsInterface {
+ get {
+ return Kind == MemberKind.Interface;
+ }
+ }
+
+ public bool IsClass {
+ get {
+ return Kind == MemberKind.Class;
+ }
+ }
+
+ public bool IsConstantCompatible {
+ get {
+ if ((Kind & (MemberKind.Enum | MemberKind.Class | MemberKind.Interface | MemberKind.Delegate)) != 0)
+ return true;
+
+ return TypeManager.IsPrimitiveType (this) || this == TypeManager.decimal_type || this == InternalType.Dynamic;
+ }
+ }
+
+ public bool IsDelegate {
+ get {
+ return Kind == MemberKind.Delegate;
+ }
}
- public TypeSpec BaseType { get; set; }
+ public bool IsEnum {
+ get { return Kind == MemberKind.Enum; }
+ }
+
+ // TODO: Should probably do
+ // IsGenericType -- recursive
+ // HasTypeParameter -- non-recursive
+ public bool IsGenericOrParentIsGeneric {
+ get {
+ var ts = this;
+ do {
+ if (ts.IsGeneric)
+ return true;
+ ts = ts.declaringType;
+ } while (ts != null);
+
+ return false;
+ }
+ }
+
+ public bool IsGenericParameter {
+ get { return Kind == MemberKind.TypeParameter; }
+ }
+
+ public bool IsNested {
+ get { return declaringType != null && Kind != MemberKind.TypeParameter; }
+ }
+
+ public bool IsPointer {
+ get {
+ return Kind == MemberKind.PointerType;
+ }
+ }
+
+ public bool IsSealed {
+ get { return (Modifiers & Modifiers.SEALED) != 0; }
+ }
- public override Type DeclaringType {
- get { return info.DeclaringType; }
+ public bool IsStruct {
+ get {
+ return Kind == MemberKind.Struct;
+ }
}
- public Type MetaInfo {
- get { return info; }
+ public bool IsTypeBuilder {
+ get {
+ var meta = GetMetaInfo().GetType ();
+ return meta == TypeBuilder || meta == GenericTypeBuilder;
+ }
}
public MemberCache MemberCache {
get {
- if (cache == null) {
-// cache = new MemberCache (BaseType);
+ if (cache == null || (state & StateFlags.PendingMemberCacheMembers) != 0)
+ InitializeMemberCache (false);
+
+ return cache;
+ }
+ set {
+ if (cache != null)
+ throw new InternalErrorException ("Membercache reset");
+
+ cache = value;
+ }
+ }
+
+ public virtual MemberCache MemberCacheTypes {
+ get {
+ return MemberCache;
+ }
+ }
+
+ public new ITypeDefinition MemberDefinition {
+ get {
+ return (ITypeDefinition) definition;
+ }
+ }
+
+ // TODO: Wouldn't be better to rely on cast to InflatedTypeSpec and
+ // remove the property, YES IT WOULD !!!
+ public virtual TypeSpec[] TypeArguments {
+ get { return TypeSpec.EmptyTypes; }
+ }
+
+ #endregion
+
+ public bool AddInterface (TypeSpec iface)
+ {
+ if ((state & StateFlags.InterfacesExpanded) != 0)
+ throw new InternalErrorException ("Modifying expanded interface list");
+
+ if (ifaces == null) {
+ ifaces = new List<TypeSpec> () { iface };
+ return true;
+ }
+
+ if (!ifaces.Contains (iface)) {
+ ifaces.Add (iface);
+ return true;
+ }
+
+ return false;
+ }
+
+ public AttributeUsageAttribute GetAttributeUsage (PredefinedAttribute pa)
+ {
+ if (Kind != MemberKind.Class)
+ throw new InternalErrorException ();
+
+ if (!pa.IsDefined)
+ return Attribute.DefaultUsageAttribute;
+
+ var aua = MemberDefinition.GetAttributeUsage (pa);
+ return aua ?? Attribute.DefaultUsageAttribute;
+ }
-// ((ITypeDefinition) definition).LoadMembers (cache);
+ public virtual Type GetMetaInfo ()
+ {
+ return info;
+ }
+
+ public virtual TypeSpec GetDefinition ()
+ {
+ return this;
+ }
+
+ public override string GetSignatureForError ()
+ {
+ string s;
+
+ if (IsNested) {
+ s = DeclaringType.GetSignatureForError ();
+ } else {
+ s = MemberDefinition.Namespace;
+ }
+
+ if (!string.IsNullOrEmpty (s))
+ s += ".";
+
+ return s + Name + GetTypeNameSignature ();
+ }
+
+ protected virtual string GetTypeNameSignature ()
+ {
+ if (!IsGeneric)
+ return null;
+
+ return "<" + TypeManager.CSharpName (MemberDefinition.TypeParameters) + ">";
+ }
+
+ public bool ImplementsInterface (TypeSpec iface)
+ {
+ var t = this;
+ do {
+ if (t.Interfaces != null) { // TODO: Try t.iface
+ foreach (TypeSpec i in t.Interfaces) {
+ if (i == iface || TypeSpecComparer.Variant.IsEqual (i, iface))
+ return true;
+ }
}
- return cache;
+ t = t.BaseType;
+ } while (t != null);
+
+ return false;
+ }
+
+ protected virtual void InitializeMemberCache (bool onlyTypes)
+ {
+ //
+ // Not interested in members of nested private types
+ //
+ if (IsPrivate) {
+ cache = new MemberCache (0);
+ } else {
+ cache = MemberDefinition.LoadMembers (this);
+ }
+ }
+
+ public override MemberSpec InflateMember (TypeParameterInflator inflator)
+ {
+ var targs = IsGeneric ? MemberDefinition.TypeParameters : TypeSpec.EmptyTypes;
+
+ //
+ // When inflating nested type from inside the type instance will be same
+ // because type parameters are same for all nested types
+ //
+ if (DeclaringType == inflator.TypeInstance)
+ return MakeGenericType (targs);
+
+ return new InflatedTypeSpec (this, inflator.TypeInstance, targs);
+ }
+
+ public InflatedTypeSpec MakeGenericType (TypeSpec[] targs)
+ {
+ if (targs.Length == 0 && !IsNested)
+ throw new ArgumentException ("Empty type arguments");
+
+ InflatedTypeSpec instance;
+
+ if (inflated_instances == null)
+ inflated_instances = new Dictionary<TypeSpec[], InflatedTypeSpec> (TypeSpecComparer.Default);
+
+ if (!inflated_instances.TryGetValue (targs, out instance)) {
+ if (GetDefinition () != this && !IsNested)
+ throw new InternalErrorException ("Only type definition or nested non-inflated types can be used to call MakeGenericType");
+
+ instance = new InflatedTypeSpec (this, declaringType, targs);
+ inflated_instances.Add (targs, instance);
+ }
+
+ return instance;
+ }
+
+ public virtual TypeSpec Mutate (TypeParameterMutator mutator)
+ {
+ return this;
+ }
+
+ public void SetMetaInfo (Type info)
+ {
+ if (this.info != null)
+ throw new InternalErrorException ("MetaInfo reset");
+
+ this.info = info;
+ }
+
+ public void SetExtensionMethodContainer ()
+ {
+ modifiers |= Modifiers.METHOD_EXTENSION;
+ }
+ }
+
+ public class PredefinedTypeSpec : TypeSpec
+ {
+ string name;
+ string ns;
+
+ public PredefinedTypeSpec (MemberKind kind, string ns, string name)
+ : base (kind, null, null, null, Modifiers.PUBLIC)
+ {
+ this.name = name;
+ this.ns = ns;
+ }
+
+ public override int Arity {
+ get {
+ return 0;
+ }
+ }
+
+ public override string Name {
+ get {
+ return name;
+ }
+ }
+
+ public string Namespace {
+ get {
+ return ns;
+ }
+ }
+
+ public override string GetSignatureForError ()
+ {
+ switch (name) {
+ case "Int32": return "int";
+ case "Int64": return "long";
+ case "String": return "string";
+ case "Boolean": return "bool";
+ case "Void": return "void";
+ case "Object": return "object";
+ case "UInt32": return "uint";
+ case "Int16": return "short";
+ case "UInt16": return "ushort";
+ case "UInt64": return "ulong";
+ case "Single": return "float";
+ case "Double": return "double";
+ case "Decimal": return "decimal";
+ case "Char": return "char";
+ case "Byte": return "byte";
+ case "SByte": return "sbyte";
+ }
+
+ return ns + "." + name;
+ }
+
+ public void SetDefinition (ITypeDefinition td, Type type)
+ {
+ this.definition = td;
+ this.info = type;
+ }
+
+ public void SetDefinition (TypeSpec ts)
+ {
+ this.definition = ts.MemberDefinition;
+ this.info = ts.GetMetaInfo ();
+ this.BaseType = ts.BaseType;
+ this.Interfaces = ts.Interfaces;
+ }
+ }
+
+ static class TypeSpecComparer
+ {
+ //
+ // Default reference comparison
+ //
+ public static readonly DefaultImpl Default = new DefaultImpl ();
+
+ public class DefaultImpl : IEqualityComparer<TypeSpec[]>, IEqualityComparer<Tuple<TypeSpec, TypeSpec[]>>
+ {
+ #region IEqualityComparer<TypeSpec[]> Members
+
+ public bool Equals (TypeSpec[] x, TypeSpec[] y)
+ {
+ if (x.Length != y.Length)
+ return false;
+
+ if (x == y)
+ return true;
+
+ for (int i = 0; i < x.Length; ++i)
+ if (x[i] != y[i])
+ return false;
+
+ return true;
+ }
+
+ public int GetHashCode (TypeSpec[] obj)
+ {
+ int hash = 0;
+ for (int i = 0; i < obj.Length; ++i)
+ hash = (hash << 5) - hash + obj[i].GetHashCode ();
+
+ return hash;
+ }
+
+ #endregion
+
+ #region IEqualityComparer<Tuple<TypeSpec,TypeSpec[]>> Members
+
+ bool IEqualityComparer<Tuple<TypeSpec, TypeSpec[]>>.Equals (Tuple<TypeSpec, TypeSpec[]> x, Tuple<TypeSpec, TypeSpec[]> y)
+ {
+ return Equals (x.Item2, y.Item2) && x.Item1 == y.Item1;
+ }
+
+ int IEqualityComparer<Tuple<TypeSpec, TypeSpec[]>>.GetHashCode (Tuple<TypeSpec, TypeSpec[]> obj)
+ {
+ return GetHashCode (obj.Item2) ^ obj.Item1.GetHashCode ();
+ }
+
+ #endregion
+ }
+
+ //
+ // When comparing type signature of overrides or overloads
+ // this version tolerates different MVARs at same position
+ //
+ public static class Override
+ {
+ public static bool IsEqual (TypeSpec a, TypeSpec b)
+ {
+ if (a == b)
+ return true;
+
+ //
+ // Consider the following example:
+ //
+ // public abstract class A
+ // {
+ // public abstract T Foo<T>();
+ // }
+ //
+ // public class B : A
+ // {
+ // public override U Foo<T>() { return default (U); }
+ // }
+ //
+ // Here, `T' and `U' are method type parameters from different methods
+ // (A.Foo and B.Foo), so both `==' and Equals() will fail.
+ //
+ // However, since we're determining whether B.Foo() overrides A.Foo(),
+ // we need to do a signature based comparision and consider them equal.
+ //
+
+ var tp_a = a as TypeParameterSpec;
+ if (tp_a != null) {
+ var tp_b = b as TypeParameterSpec;
+ return tp_b != null && tp_a.IsMethodOwned == tp_b.IsMethodOwned && tp_a.DeclaredPosition == tp_b.DeclaredPosition;
+ }
+
+ if (a.TypeArguments.Length != b.TypeArguments.Length)
+ return false;
+
+ if (a.TypeArguments.Length != 0) {
+ if (a.MemberDefinition != b.MemberDefinition)
+ return false;
+
+ for (int i = 0; i < a.TypeArguments.Length; ++i) {
+ if (!IsEqual (a.TypeArguments[i], b.TypeArguments[i]))
+ return false;
+ }
+
+ return true;
+ }
+
+ var ac_a = a as ArrayContainer;
+ if (ac_a != null) {
+ var ac_b = b as ArrayContainer;
+ return ac_b != null && ac_a.Rank == ac_b.Rank && IsEqual (ac_a.Element, ac_b.Element);
+ }
+
+ if (a == InternalType.Dynamic || b == InternalType.Dynamic)
+ return b == TypeManager.object_type || a == TypeManager.object_type;
+
+ return false;
+ }
+
+ //
+ // Compares unordered arrays
+ //
+ public static bool IsSame (TypeSpec[] a, TypeSpec[] b)
+ {
+ if (a == b)
+ return true;
+
+ if (a == null || b == null || a.Length != b.Length)
+ return false;
+
+ for (int ai = 0; ai < a.Length; ++ai) {
+ bool found = false;
+ for (int bi = 0; bi < b.Length; ++bi) {
+ if (IsEqual (a[ai], b[bi])) {
+ found = true;
+ break;
+ }
+ }
+
+ if (!found)
+ return false;
+ }
+
+ return true;
+ }
+
+ public static bool IsEqual (AParametersCollection a, AParametersCollection b)
+ {
+ if (a == b)
+ return true;
+
+ if (a.Count != b.Count)
+ return false;
+
+ for (int i = 0; i < a.Count; ++i) {
+ if (!IsEqual (a.Types[i], b.Types[i]))
+ return false;
+
+ const Parameter.Modifier ref_out = Parameter.Modifier.REF | Parameter.Modifier.OUT;
+ if ((a.FixedParameters[i].ModFlags & ref_out) != (b.FixedParameters[i].ModFlags & ref_out))
+ return false;
+ }
+
+ return true;
+ }
+ }
+
+ //
+ // Type variance equality comparison
+ //
+ public static class Variant
+ {
+ public static bool IsEqual (TypeSpec type1, TypeSpec type2)
+ {
+ if (!type1.IsGeneric || !type2.IsGeneric)
+ return false;
+
+ var target_type_def = type2.MemberDefinition;
+ if (type1.MemberDefinition != target_type_def)
+ return false;
+
+ if (!type1.IsInterface && !type1.IsDelegate)
+ return false;
+
+ var t1_targs = type1.TypeArguments;
+ var t2_targs = type2.TypeArguments;
+ var targs_definition = target_type_def.TypeParameters;
+ for (int i = 0; i < targs_definition.Length; ++i) {
+ Variance v = targs_definition[i].Variance;
+ if (v == Variance.None) {
+ if (t1_targs[i] == t2_targs[i])
+ continue;
+ return false;
+ }
+
+ if (v == Variance.Covariant) {
+ if (!Convert.ImplicitReferenceConversionExists (new EmptyExpression (t1_targs[i]), t2_targs[i]))
+ return false;
+ } else if (!Convert.ImplicitReferenceConversionExists (new EmptyExpression (t2_targs[i]), t1_targs[i])) {
+ return false;
+ }
+ }
+
+ return true;
+ }
+ }
+
+ //
+ // Checks whether two generic instances may become equal for some
+ // particular instantiation (26.3.1).
+ //
+ public static class Unify
+ {
+ //
+ // Either @a or @b must be generic type
+ //
+ public static bool IsEqual (TypeSpec a, TypeSpec b)
+ {
+ if (a.MemberDefinition != b.MemberDefinition)
+ return false;
+
+ var ta = a.TypeArguments;
+ var tb = b.TypeArguments;
+ for (int i = 0; i < ta.Length; i++) {
+ if (!MayBecomeEqualGenericTypes (ta[i], tb[i]))
+ return false;
+ }
+
+ return true;
+ }
+
+ /// <summary>
+ /// Check whether `a' and `b' may become equal generic types.
+ /// The algorithm to do that is a little bit complicated.
+ /// </summary>
+ static bool MayBecomeEqualGenericTypes (TypeSpec a, TypeSpec b)
+ {
+ if (a.IsGenericParameter) {
+ //
+ // If a is an array of a's type, they may never
+ // become equal.
+ //
+ if (b.IsArray)
+ return false;
+
+ //
+ // If b is a generic parameter or an actual type,
+ // they may become equal:
+ //
+ // class X<T,U> : I<T>, I<U>
+ // class X<T> : I<T>, I<float>
+ //
+ if (b.IsGenericParameter)
+ return a.DeclaringType == b.DeclaringType;
+
+ //
+ // We're now comparing a type parameter with a
+ // generic instance. They may become equal unless
+ // the type parameter appears anywhere in the
+ // generic instance:
+ //
+ // class X<T,U> : I<T>, I<X<U>>
+ // -> error because you could instanciate it as
+ // X<X<int>,int>
+ //
+ // class X<T> : I<T>, I<X<T>> -> ok
+ //
+
+ TypeSpec[] bargs = b.TypeArguments;
+ for (int i = 0; i < bargs.Length; i++) {
+ if (a.Equals (bargs[i]))
+ return false;
+ }
+
+ return true;
+ }
+
+ if (b.IsGenericParameter)
+ return MayBecomeEqualGenericTypes (b, a);
+
+ //
+ // At this point, neither a nor b are a type parameter.
+ //
+ // If one of them is a generic instance, compare them (if the
+ // other one is not a generic instance, they can never
+ // become equal).
+ //
+ if (TypeManager.IsGenericType (a) || TypeManager.IsGenericType (b))
+ return IsEqual (a, b);
+
+ //
+ // If both of them are arrays.
+ //
+ var a_ac = a as ArrayContainer;
+ if (a_ac != null) {
+ var b_ac = b as ArrayContainer;
+ if (b_ac == null || a_ac.Rank != b_ac.Rank)
+ return false;
+
+ return MayBecomeEqualGenericTypes (a_ac.Element, b_ac.Element);
+ }
+
+ //
+ // Ok, two ordinary types.
+ //
+ return false;
}
}
}
public interface ITypeDefinition : IMemberDefinition
{
- void LoadMembers (MemberCache cache);
+ string Namespace { get; }
+ int TypeParametersCount { get; }
+ TypeParameterSpec[] TypeParameters { get; }
+
+ TypeSpec GetAttributeCoClass ();
+ string GetAttributeDefaultMember ();
+ AttributeUsageAttribute GetAttributeUsage (PredefinedAttribute pa);
+ MemberCache LoadMembers (TypeSpec declaringType);
}
-/*
+
class InternalType : TypeSpec
{
+ private class DynamicType : InternalType
+ {
+ public DynamicType ()
+ : base ("dynamic")
+ {
+ }
+
+ public override Type GetMetaInfo ()
+ {
+ return typeof (object);
+ }
+ }
+
public static readonly TypeSpec AnonymousMethod = new InternalType ("anonymous method");
public static readonly TypeSpec Arglist = new InternalType ("__arglist");
-// public static readonly TypeSpec Dynamic = new DynamicType ();
+ public static readonly TypeSpec Dynamic = new DynamicType ();
public static readonly TypeSpec MethodGroup = new InternalType ("method group");
+ public static readonly TypeSpec Null = new InternalType ("null");
+ public static readonly TypeSpec FakeInternalType = new InternalType ("<fake$type>");
+
+ readonly string name;
protected InternalType (string name)
- : base (null, null, name, Modifiers.PUBLIC)
+ : base (MemberKind.InternalCompilerType, null, null, null, Modifiers.PUBLIC)
+ {
+ this.name = name;
+ cache = MemberCache.Empty;
+
+ // Make all internal types CLS-compliant, non-obsolete
+ state = (state & ~(StateFlags.CLSCompliant_Undetected | StateFlags.Obsolete_Undetected)) | StateFlags.CLSCompliant;
+ }
+
+ public override string GetSignatureForError ()
+ {
+ return name;
+ }
+ }
+
+ public abstract class ElementTypeSpec : TypeSpec
+ {
+ protected ElementTypeSpec (MemberKind kind, TypeSpec element, Type info)
+ : base (kind, element.DeclaringType, element.MemberDefinition, info, element.Modifiers)
+ {
+ this.Element = element;
+ cache = MemberCache.Empty;
+ }
+
+ #region Properties
+
+ public TypeSpec Element { get; private set; }
+
+ public override string Name {
+ get {
+ throw new NotSupportedException ();
+ }
+ }
+
+ #endregion
+
+ public override ObsoleteAttribute GetAttributeObsolete ()
+ {
+ return Element.GetAttributeObsolete ();
+ }
+
+ protected virtual string GetPostfixSignature ()
+ {
+ return null;
+ }
+
+ public override string GetSignatureForError ()
+ {
+ return Element.GetSignatureForError () + GetPostfixSignature ();
+ }
+
+ public override TypeSpec Mutate (TypeParameterMutator mutator)
+ {
+ var me = Element.Mutate (mutator);
+ if (me == Element)
+ return this;
+
+ var mutated = (ElementTypeSpec) MemberwiseClone ();
+ mutated.Element = me;
+ mutated.info = null;
+ return mutated;
+ }
+ }
+
+ public class ArrayContainer : ElementTypeSpec
+ {
+ readonly int rank;
+ static Dictionary<Tuple<TypeSpec, int>, ArrayContainer> instances = new Dictionary<Tuple<TypeSpec, int>, ArrayContainer> ();
+
+ private ArrayContainer (TypeSpec element, int rank)
+ : base (MemberKind.Class, element, null)
+ {
+ this.rank = rank;
+ }
+
+ public int Rank {
+ get {
+ return rank;
+ }
+ }
+
+ public System.Reflection.MethodInfo GetConstructor ()
+ {
+ var mb = RootContext.ToplevelTypes.Builder;
+
+ var arg_types = new Type[rank];
+ for (int i = 0; i < rank; i++)
+ arg_types[i] = TypeManager.int32_type.GetMetaInfo ();
+
+ var ctor = mb.GetArrayMethod (
+ GetMetaInfo (), ".ctor",
+ System.Reflection.CallingConventions.HasThis,
+ null, arg_types);
+
+ return ctor;
+ }
+
+ public System.Reflection.MethodInfo GetGetMethod ()
+ {
+ var mb = RootContext.ToplevelTypes.Builder;
+
+ var arg_types = new Type[rank];
+ for (int i = 0; i < rank; i++)
+ arg_types[i] = TypeManager.int32_type.GetMetaInfo ();
+
+ var get = mb.GetArrayMethod (
+ GetMetaInfo (), "Get",
+ System.Reflection.CallingConventions.HasThis | System.Reflection.CallingConventions.Standard,
+ Element.GetMetaInfo (), arg_types);
+
+ return get;
+ }
+
+ public System.Reflection.MethodInfo GetSetMethod ()
+ {
+ var mb = RootContext.ToplevelTypes.Builder;
+
+ var arg_types = new Type[rank + 1];
+ for (int i = 0; i < rank; i++)
+ arg_types[i] = TypeManager.int32_type.GetMetaInfo ();
+
+ arg_types[rank] = Element.GetMetaInfo ();
+
+ var set = mb.GetArrayMethod (
+ GetMetaInfo (), "Set",
+ System.Reflection.CallingConventions.HasThis | System.Reflection.CallingConventions.Standard,
+ TypeManager.void_type.GetMetaInfo (), arg_types);
+
+ return set;
+ }
+
+ public override Type GetMetaInfo ()
+ {
+ if (info == null) {
+ if (rank == 1)
+ info = Element.GetMetaInfo ().MakeArrayType ();
+ else
+ info = Element.GetMetaInfo ().MakeArrayType (rank);
+ }
+
+ return info;
+ }
+
+ protected override string GetPostfixSignature()
+ {
+ StringBuilder sb = new StringBuilder ();
+ sb.Append ("[");
+ for (int i = 1; i < rank; i++) {
+ sb.Append (",");
+ }
+ sb.Append ("]");
+
+ return sb.ToString ();
+ }
+
+ public static ArrayContainer MakeType (TypeSpec element)
+ {
+ return MakeType (element, 1);
+ }
+
+ public static ArrayContainer MakeType (TypeSpec element, int rank)
+ {
+ ArrayContainer ac;
+ var key = Tuple.Create (element, rank);
+ if (!instances.TryGetValue (key, out ac)) {
+ ac = new ArrayContainer (element, rank) {
+ BaseType = TypeManager.array_type
+ };
+
+ instances.Add (key, ac);
+ }
+
+ return ac;
+ }
+
+ public static void Reset ()
+ {
+ instances = new Dictionary<Tuple<TypeSpec, int>, ArrayContainer> ();
+ }
+ }
+
+ class ReferenceContainer : ElementTypeSpec
+ {
+ static Dictionary<TypeSpec, ReferenceContainer> instances = new Dictionary<TypeSpec, ReferenceContainer> ();
+
+ private ReferenceContainer (TypeSpec element)
+ : base (MemberKind.Class, element, null) // TODO: Kind.Class is most likely wrong
+ {
+ }
+
+ public override Type GetMetaInfo ()
+ {
+ if (info == null) {
+ info = Element.GetMetaInfo ().MakeByRefType ();
+ }
+
+ return info;
+ }
+
+ public static ReferenceContainer MakeType (TypeSpec element)
+ {
+ ReferenceContainer pc;
+ if (!instances.TryGetValue (element, out pc)) {
+ pc = new ReferenceContainer (element);
+ instances.Add (element, pc);
+ }
+
+ return pc;
+ }
+
+ public static void Reset ()
+ {
+ instances = new Dictionary<TypeSpec, ReferenceContainer> ();
+ }
+ }
+
+ class PointerContainer : ElementTypeSpec
+ {
+ static Dictionary<TypeSpec, PointerContainer> instances = new Dictionary<TypeSpec, PointerContainer> ();
+
+ private PointerContainer (TypeSpec element)
+ : base (MemberKind.PointerType, element, null)
+ {
+ // It's never CLS-Compliant
+ state &= ~StateFlags.CLSCompliant_Undetected;
+ }
+
+ public override Type GetMetaInfo ()
+ {
+ if (info == null) {
+ info = Element.GetMetaInfo ().MakePointerType ();
+ }
+
+ return info;
+ }
+
+ protected override string GetPostfixSignature()
+ {
+ return "*";
+ }
+
+ public static PointerContainer MakeType (TypeSpec element)
+ {
+ PointerContainer pc;
+ if (!instances.TryGetValue (element, out pc)) {
+ pc = new PointerContainer (element);
+ instances.Add (element, pc);
+ }
+
+ return pc;
+ }
+
+ public static void Reset ()
{
-// cache = MemberCache.Empty;
+ instances = new Dictionary<TypeSpec, PointerContainer> ();
}
}
-*/
}