namespace Mono.CSharp {
+ 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.ValueTypeConstraint) != 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 (!ClassConstraint.IsValueType)
+ 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 enum SpecialConstraint
{
Constructor,
}
}
- bool has_ctor_constraint;
- bool has_reference_type;
- bool has_value_type;
+ GenericParameterAttributes attrs;
TypeExpr class_constraint;
ArrayList iface_constraints;
+ ArrayList type_param_constraints;
int num_constraints, first_constraint;
Type class_constraint_type;
Type[] iface_constraint_types;
-
- public bool HasConstructorConstraint {
- get { return has_ctor_constraint; }
- }
+ Type effective_base_type;
public bool Resolve (DeclSpace ds)
{
iface_constraints = new ArrayList ();
+ type_param_constraints = new ArrayList ();
foreach (object obj in constraints) {
- if (has_ctor_constraint) {
+ if (HasConstructorConstraint) {
Report.Error (401, loc,
"The new() constraint must be last.");
return false;
SpecialConstraint sc = (SpecialConstraint) obj;
if (sc == SpecialConstraint.Constructor) {
- if (!has_value_type) {
- has_ctor_constraint = true;
+ if (!HasValueTypeConstraint) {
+ attrs |= GenericParameterAttributes.DefaultConstructorConstraint;
continue;
}
return false;
}
- if ((num_constraints > 0) || has_reference_type ||
- has_value_type) {
+ if ((num_constraints > 0) || HasReferenceTypeConstraint || HasValueTypeConstraint) {
Report.Error (449, loc,
"The `class' or `struct' " +
"constraint must be first");
}
if (sc == SpecialConstraint.ReferenceType)
- has_reference_type = true;
+ attrs |= GenericParameterAttributes.ReferenceTypeConstraint;
else
- has_value_type = true;
+ attrs |= GenericParameterAttributes.ValueTypeConstraint;
continue;
}
- TypeExpr expr = ds.ResolveTypeExpr ((Expression) obj, false, loc);
+ TypeExpr expr = ds.ResolveTypeExpr ((Expression) obj, loc);
if (expr == null)
return false;
- if (expr is TypeParameterExpr) {
- Report.Error (700, loc,
- "`{0}': naked type parameters cannot " +
- "be used as bounds", expr.Name);
- return false;
- }
-
- if (expr.IsInterface)
+ TypeParameterExpr texpr = expr as TypeParameterExpr;
+ if (texpr != null)
+ type_param_constraints.Add (expr);
+ else if (expr.IsInterface)
iface_constraints.Add (expr);
else if (class_constraint != null) {
Report.Error (406, loc,
"must come before any other constraints.",
expr.Name, name);
return false;
- } else if (has_reference_type || has_value_type) {
+ } else if (HasReferenceTypeConstraint || HasValueTypeConstraint) {
Report.Error (450, loc, "`{0}': cannot specify both " +
"a constraint class and the `class' " +
"or `struct' constraint.", expr.Name);
return true;
}
- public TypeExpr[] InterfaceConstraints {
- get {
- TypeExpr[] ifaces = new TypeExpr [iface_constraints.Count];
- iface_constraints.CopyTo (ifaces, 0);
- return ifaces;
+ bool CheckTypeParameterConstraints (TypeParameter tparam, Hashtable seen)
+ {
+ seen.Add (tparam, true);
+
+ Constraints constraints = 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, name);
+ return false;
+ }
+
+ if (constraints.type_param_constraints == null)
+ return true;
+
+ foreach (TypeParameterExpr expr in constraints.type_param_constraints) {
+ if (seen.Contains (expr.TypeParameter)) {
+ Report.Error (454, loc, "Circular constraint " +
+ "dependency involving `{0}' and `{1}'",
+ tparam.Name, expr.Name);
+ return false;
+ }
+
+ if (!CheckTypeParameterConstraints (expr.TypeParameter, seen))
+ return false;
}
+
+ return true;
}
public bool ResolveTypes (EmitContext ec)
{
- iface_constraint_types = new Type [iface_constraints.Count];
+ foreach (TypeParameterExpr expr in type_param_constraints) {
+ Hashtable seen = new Hashtable ();
+ if (!CheckTypeParameterConstraints (expr.TypeParameter, seen))
+ return false;
+ }
+
+ ArrayList list = new ArrayList ();
- for (int i = 0; i < iface_constraints.Count; i++) {
- TypeExpr iface_constraint = (TypeExpr) iface_constraints [i];
+ foreach (TypeExpr iface_constraint in iface_constraints) {
Type resolved = iface_constraint.ResolveType (ec);
if (resolved == null)
return false;
- for (int j = 0; j < i; j++) {
- if (!iface_constraint_types [j].Equals (resolved))
+ foreach (Type type in list) {
+ if (!type.Equals (resolved))
continue;
Report.Error (405, loc,
return false;
}
- iface_constraint_types [i] = resolved;
+ list.Add (resolved);
}
+ foreach (TypeParameterExpr expr in type_param_constraints) {
+ Type resolved = expr.ResolveType (ec);
+ if (resolved == null)
+ return false;
+
+ foreach (Type type in list) {
+ if (!type.Equals (resolved))
+ continue;
+
+ Report.Error (405, loc,
+ "Duplicate constraint `{0}' for type " +
+ "parameter `{1}'.", resolved, name);
+ return false;
+ }
+
+ list.Add (resolved);
+ }
+
+ iface_constraint_types = new Type [list.Count];
+ list.CopyTo (iface_constraint_types, 0);
+
if (class_constraint != null) {
class_constraint_type = class_constraint.ResolveType (ec);
if (class_constraint_type == null)
}
}
- if (has_reference_type)
- class_constraint_type = TypeManager.object_type;
- else if (has_value_type)
- class_constraint_type = TypeManager.value_type;
+ 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;
return true;
}
- public void Define (GenericTypeParameterBuilder type)
+ public bool CheckDependencies (EmitContext ec)
{
- if (has_ctor_constraint)
- type.Mono_SetConstructorConstraint ();
- if (has_reference_type)
- type.Mono_SetReferenceTypeConstraint ();
- else if (has_value_type)
- type.Mono_SetValueTypeConstraint ();
+ foreach (TypeParameterExpr expr in type_param_constraints) {
+ if (!CheckDependencies (expr.TypeParameter, ec))
+ return false;
+ }
+
+ return true;
}
- bool GenericConstraints.HasConstructor {
- get { return has_ctor_constraint; }
+ bool CheckDependencies (TypeParameter tparam, EmitContext ec)
+ {
+ Constraints constraints = tparam.Constraints;
+ if (constraints == null)
+ return true;
+
+ if (HasValueTypeConstraint && constraints.HasClassConstraint) {
+ Report.Error (455, loc, "Type parameter `{0}' inherits " +
+ "conflicting constraints `{1}' and `{2}'",
+ name, constraints.ClassConstraint,
+ "System.ValueType");
+ return false;
+ }
+
+ if (HasClassConstraint && constraints.HasClassConstraint) {
+ Type t1 = ClassConstraint;
+ TypeExpr e1 = class_constraint;
+ Type t2 = constraints.ClassConstraint;
+ TypeExpr e2 = constraints.class_constraint;
+
+ if (!Convert.ImplicitReferenceConversionExists (ec, e1, t2) &&
+ !Convert.ImplicitReferenceConversionExists (ec, e2, t1)) {
+ Report.Error (455, loc,
+ "Type parameter `{0}' inherits " +
+ "conflicting constraints `{1}' and `{2}'",
+ name, t1, t2);
+ return false;
+ }
+ }
+
+ if (constraints.type_param_constraints == null)
+ return true;
+
+ foreach (TypeParameterExpr expr in constraints.type_param_constraints) {
+ if (!CheckDependencies (expr.TypeParameter, ec))
+ return false;
+ }
+
+ return true;
}
- bool GenericConstraints.IsReferenceType {
- get { return has_reference_type; }
+ public void Define (GenericTypeParameterBuilder type)
+ {
+ type.SetGenericParameterAttributes (attrs);
}
- bool GenericConstraints.IsValueType {
- get { return has_value_type; }
+ public override GenericParameterAttributes Attributes {
+ get { return attrs; }
}
- bool GenericConstraints.HasClassConstraint {
- get { return class_constraint_type != null; }
+ public override bool HasClassConstraint {
+ get { return class_constraint != null; }
}
- Type GenericConstraints.ClassConstraint {
+ public override Type ClassConstraint {
get { return class_constraint_type; }
}
- Type[] GenericConstraints.InterfaceConstraints {
+ public override Type[] InterfaceConstraints {
get { return iface_constraint_types; }
}
+
+ public override Type EffectiveBaseClass {
+ get { return effective_base_type; }
+ }
+
+ internal bool IsSubclassOf (Type t)
+ {
+ if ((class_constraint_type != null) &&
+ class_constraint_type.IsSubclassOf (t))
+ return true;
+
+ if (iface_constraint_types == null)
+ return false;
+
+ foreach (Type iface in iface_constraint_types) {
+ if (TypeManager.IsSubclassOf (iface, t))
+ return true;
+ }
+
+ return false;
+ }
+
+ public bool CheckInterfaceMethod (EmitContext ec, GenericConstraints gc)
+ {
+ if (!ResolveTypes (ec))
+ return false;
+
+ 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;
+
+ foreach (Type iface in gc.InterfaceConstraints) {
+ bool ok = false;
+ foreach (Type check in InterfaceConstraints) {
+ if (TypeManager.IsEqual (iface, check)) {
+ ok = true;
+ break;
+ }
+ }
+
+ if (!ok)
+ return false;
+ }
+
+ return true;
+ }
}
//
// This type represents a generic type parameter
//
- public class TypeParameter : IMemberContainer {
+ public class TypeParameter : MemberCore, IMemberContainer {
string name;
+ GenericConstraints gc;
Constraints constraints;
Location loc;
GenericTypeParameterBuilder type;
- public TypeParameter (string name, Constraints constraints, Location loc)
+ public TypeParameter (TypeContainer parent, string name,
+ Constraints constraints, Location loc)
+ : base (parent, new MemberName (name), null, loc)
{
this.name = name;
this.constraints = constraints;
this.loc = loc;
}
- public string Name {
+ public GenericConstraints GenericConstraints {
get {
- return name;
- }
- }
-
- public Location Location {
- get {
- return loc;
+ return gc != null ? gc : constraints;
}
}
public void Define (GenericTypeParameterBuilder type)
{
+ if (this.type != null)
+ throw new InvalidOperationException ();
+
this.type = type;
- TypeExpr[] ifaces = null;
- if (constraints != null) {
- ifaces = constraints.InterfaceConstraints;
+ TypeManager.AddTypeParameter (type, this);
+ }
+
+ public void DefineConstraints ()
+ {
+ if (constraints != null)
constraints.Define (type);
- }
- TypeManager.AddTypeParameter (type, this, ifaces);
}
public bool DefineType (EmitContext ec)
{
- if (constraints != null) {
- if (!constraints.ResolveTypes (ec))
+ return DefineType (ec, null, null, false);
+ }
+
+ public bool DefineType (EmitContext ec, MethodBuilder builder,
+ MethodInfo implementing, bool is_override)
+ {
+ if (implementing != null) {
+ if (is_override && (constraints != null)) {
+ Report.Error (
+ 460, loc, "Constraints for override and " +
+ "explicit interface implementation methods " +
+ "are inherited from the base method so they " +
+ "cannot be specified directly");
return false;
+ }
- GenericConstraints gc = (GenericConstraints) constraints;
+ MethodBase mb = implementing;
+ if (mb.Mono_IsInflatedMethod)
+ mb = mb.GetGenericMethodDefinition ();
+
+ int pos = type.GenericParameterPosition;
+ ParameterData pd = Invocation.GetParameterData (mb);
+ GenericConstraints temp_gc = pd.GenericConstraints (pos);
+ Type mparam = mb.GetGenericArguments () [pos];
+
+ if (temp_gc != null)
+ gc = new InflatedConstraints (temp_gc, implementing.DeclaringType);
+ else if (constraints != null)
+ gc = new InflatedConstraints (constraints, implementing.DeclaringType);
+
+ bool ok = true;
+ if (constraints != null) {
+ if (temp_gc == null)
+ ok = false;
+ else if (!constraints.CheckInterfaceMethod (ec, gc))
+ ok = false;
+ } else {
+ if (!is_override && (temp_gc != null))
+ ok = false;
+ }
- if (gc.HasClassConstraint)
- type.SetBaseTypeConstraint (gc.ClassConstraint);
+ if (!ok) {
+ Report.SymbolRelatedToPreviousError (implementing);
+
+ Report.Error (
+ 425, loc, "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),
+ mparam, TypeManager.CSharpSignature (mb));
+ return false;
+ }
+ } else {
+ if (constraints != null) {
+ if (!constraints.ResolveTypes (ec))
+ return false;
+ }
- type.SetInterfaceConstraints (gc.InterfaceConstraints);
+ gc = (GenericConstraints) constraints;
}
+ if (gc == null)
+ return true;
+
+ if (gc.HasClassConstraint)
+ type.SetBaseTypeConstraint (gc.ClassConstraint);
+
+ type.SetInterfaceConstraints (gc.InterfaceConstraints);
+ TypeManager.RegisterBuilder (type, gc.InterfaceConstraints);
+
+ return true;
+ }
+
+ public bool CheckDependencies (EmitContext ec)
+ {
+ if (constraints != null)
+ return constraints.CheckDependencies (ec);
+
return true;
}
+ //
+ // MemberContainer
+ //
+
+ public override bool Define ()
+ {
+ return true;
+ }
+
+ protected override void VerifyObsoleteAttribute ()
+ { }
+
+ public override void ApplyAttributeBuilder (Attribute a,
+ CustomAttributeBuilder cb)
+ { }
+
+ public override AttributeTargets AttributeTargets {
+ get {
+ return (AttributeTargets) 0;
+ }
+ }
+
+ public override string[] ValidAttributeTargets {
+ get {
+ return new string [0];
+ }
+ }
+
//
// IMemberContainer
//
- IMemberContainer IMemberContainer.Parent {
+ string IMemberContainer.Name {
+ get { return Name; }
+ }
+
+ MemberCache IMemberContainer.ParentCache {
get { return null; }
}
return new MemberList (members);
}
+ public bool IsSubclassOf (Type t)
+ {
+ if (type.Equals (t))
+ return true;
+
+ if (constraints != null)
+ return constraints.IsSubclassOf (t);
+
+ return false;
+ }
+
public override string ToString ()
{
return "TypeParameter[" + name + "]";
}
+
+ protected class InflatedConstraints : GenericConstraints
+ {
+ GenericConstraints gc;
+ Type base_type;
+ Type class_constraint;
+ Type[] iface_constraints;
+ Type[] dargs;
+ Type declaring;
+
+ public InflatedConstraints (GenericConstraints gc, Type declaring)
+ {
+ this.gc = gc;
+ this.declaring = declaring;
+
+ dargs = TypeManager.GetTypeArguments (declaring);
+
+ ArrayList list = new ArrayList ();
+ 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.IsInterface && !first.IsGenericParameter;
+ }
+
+ 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);
+ } else {
+ iface_constraints = new Type [list.Count];
+ list.CopyTo (iface_constraints, 0);
+ }
+
+ if (HasValueTypeConstraint)
+ base_type = TypeManager.value_type;
+ else if (class_constraint != null)
+ base_type = class_constraint;
+ else
+ base_type = TypeManager.object_type;
+ }
+
+ Type inflate (Type t)
+ {
+ if (t == null)
+ return null;
+ if (t.IsGenericParameter)
+ return dargs [t.GenericParameterPosition];
+ if (t.IsGenericInstance) {
+ t = t.GetGenericTypeDefinition ();
+ t = t.BindGenericParameters (dargs);
+ }
+
+ return t;
+ }
+
+ public override GenericParameterAttributes Attributes {
+ get { return gc.Attributes; }
+ }
+
+ public override Type ClassConstraint {
+ get { return class_constraint; }
+ }
+
+ public override Type EffectiveBaseClass {
+ get { return base_type; }
+ }
+
+ public override Type[] InterfaceConstraints {
+ get { return iface_constraints; }
+ }
+ }
}
//
return this;
}
+ public override bool IsInterface {
+ get { return false; }
+ }
+
+ public override bool CheckAccessLevel (DeclSpace ds)
+ {
+ return true;
+ }
+
public void Error_CannotUseAsUnmanagedType (Location loc)
{
Report.Error (-203, loc, "Can not use type parameter as unamanged type");
public readonly Location Location;
ArrayList args;
Type[] atypes;
+ int dimension;
bool has_type_args;
bool created;
this.Location = loc;
}
+ public TypeArguments (int dimension, Location loc)
+ {
+ this.dimension = dimension;
+ this.Location = loc;
+ }
+
public void Add (Expression type)
{
if (created)
public int Count {
get {
- return args.Count;
+ if (dimension > 0)
+ return dimension;
+ else
+ return args.Count;
+ }
+ }
+
+ public bool IsUnbound {
+ get {
+ return dimension > 0;
}
}
{
StringBuilder s = new StringBuilder ();
- int count = args.Count;
+ int count = Count;
for (int i = 0; i < count; i++){
//
// FIXME: Use TypeManager.CSharpname once we have the type
//
- s.Append (args [i].ToString ());
+ if (args != null)
+ s.Append (args [i].ToString ());
if (i+1 < count)
s.Append (",");
}
bool ok = true;
atypes = new Type [count];
-
+
for (int i = 0; i < count; i++){
- TypeExpr te = ds.ResolveTypeExpr (
- (Expression) args [i], false, Location);
+ TypeExpr te = ((Expression) args [i]).ResolveAsTypeTerminal (ec);
if (te == null) {
ok = false;
continue;
public ConstructedType (string name, TypeArguments args, Location l)
{
loc = l;
- this.name = name + "!" + args.Count;
+ this.name = MemberName.MakeName (name, args.Count);
this.args = args;
eclass = ExprClass.Type;
}
}
+ protected bool CheckConstraint (EmitContext ec, Type ptype, Expression expr,
+ Type ctype)
+ {
+ if (TypeManager.HasGenericArguments (ctype)) {
+ Type[] types = TypeManager.GetTypeArguments (ctype);
+
+ TypeArguments new_args = new TypeArguments (loc);
+
+ for (int i = 0; i < types.Length; i++) {
+ Type t = types [i];
+
+ if (t.IsGenericParameter) {
+ int pos = t.GenericParameterPosition;
+ t = args.Arguments [pos];
+ }
+ new_args.Add (new TypeExpression (t, loc));
+ }
+
+ ctype = new ConstructedType (ctype, new_args, loc).ResolveType (ec);
+ if (ctype == null)
+ return false;
+ }
+
+ return Convert.ImplicitStandardConversionExists (ec, expr, ctype);
+ }
+
protected bool CheckConstraints (EmitContext ec, int index)
{
Type atype = atypes [index];
Expression aexpr = new EmptyExpression (atype);
- Type parent = ptype.BaseType;
+ GenericConstraints gc = TypeManager.GetTypeParameterConstraints (ptype);
+ if (gc == null)
+ return true;
//
// First, check the `class' and `struct' constraints.
//
- if (parent == TypeManager.object_type) {
- if (!atype.IsClass) {
- 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}'.",
- atype, ptype, DeclarationName);
- return false;
- }
- } else if (parent == TypeManager.value_type) {
- if (!atype.IsValueType) {
- Report.Error (453, loc, "The type `{0}' must be " +
- "a value type in order to use it " +
- "as type parameter `{1}' in the " +
- "generic type or method `{2}'.",
- atype, ptype, DeclarationName);
- return false;
- }
+ if (gc.HasReferenceTypeConstraint && !atype.IsClass) {
+ 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}'.",
+ atype, ptype, DeclarationName);
+ return false;
+ } else if (gc.HasValueTypeConstraint && !atype.IsValueType) {
+ Report.Error (453, loc, "The type `{0}' must be " +
+ "a value type in order to use it " +
+ "as type parameter `{1}' in the " +
+ "generic type or method `{2}'.",
+ atype, ptype, DeclarationName);
+ return false;
}
//
// The class constraint comes next.
//
- if ((parent != null) && (parent != TypeManager.object_type)) {
- if (!Convert.ImplicitStandardConversionExists (aexpr, parent)) {
+ if (gc.HasClassConstraint) {
+ if (!CheckConstraint (ec, ptype, aexpr, gc.ClassConstraint)) {
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}'",
- atype, parent, ptype, DeclarationName);
+ atype, gc.ClassConstraint, ptype, DeclarationName);
return false;
}
}
//
// Now, check the interface constraints.
//
- foreach (TypeExpr iface in TypeManager.GetInterfaces (ptype)) {
- Type itype = iface.ResolveType (ec);
- if (itype == null)
- return false;
+ foreach (Type it in gc.InterfaceConstraints) {
+ Type itype;
+ if (it.IsGenericParameter)
+ itype = atypes [it.GenericParameterPosition];
+ else
+ itype = it;
- if (!Convert.ImplicitStandardConversionExists (aexpr, itype)) {
+ if (!CheckConstraint (ec, ptype, aexpr, itype)) {
Report.Error (309, loc, "The type `{0}' must be " +
"convertible to `{1}' in order to " +
"use it as parameter `{2}' in the " +
// Finally, check the constructor constraint.
//
- if (!TypeManager.HasConstructorConstraint (ptype))
+ if (!gc.HasConstructorConstraint)
+ return true;
+
+ if (TypeManager.IsBuiltinType (atype))
return true;
MethodGroupExpr mg = Expression.MemberLookup (
public override TypeExpr DoResolveAsTypeStep (EmitContext ec)
{
- if (gt != null)
+ if (type != null)
return this;
+ if (gt != null)
+ return DoResolveType (ec);
//
// First, resolve the generic type.
gt = nested.GetGenericTypeDefinition ();
TypeArguments new_args = new TypeArguments (loc);
- foreach (TypeParameter param in ds.TypeParameters)
- new_args.Add (new TypeParameterExpr (param, loc));
+ if (ds.IsGeneric) {
+ foreach (TypeParameter param in ds.TypeParameters)
+ new_args.Add (new TypeParameterExpr (param, loc));
+ }
new_args.Add (args);
args = new_args;
- return this;
+ return DoResolveType (ec);
}
Type t;
SimpleName sn = new SimpleName (name, loc);
TypeExpr resolved = sn.ResolveAsTypeTerminal (ec);
- if ((resolved == null) || (resolved.Type == null)) {
- Report.Error (246, loc,
- "The type or namespace name `{0}<...>' "+
- "could not be found", Basename);
+ if (resolved == null)
return null;
- }
t = resolved.Type;
if (t == null) {
}
gt = t.GetGenericTypeDefinition ();
- return this;
+ return DoResolveType (ec);
}
- public override Type ResolveType (EmitContext ec)
+ TypeExpr DoResolveType (EmitContext ec)
{
- if (type != null)
- return type;
- if (DoResolveAsTypeStep (ec) == null)
- return null;
-
//
// Resolve the arguments.
//
// Now bind the parameters.
//
type = gt.BindGenericParameters (atypes);
- return type;
+ return this;
}
public Expression GetSimpleName (EmitContext ec)
get { return false; }
}
- public override TypeExpr[] GetInterfaces ()
- {
- TypeExpr[] ifaces = TypeManager.GetInterfaces (gt);
- return ifaces;
- }
-
public override bool Equals (object obj)
{
ConstructedType cobj = obj as ConstructedType;
public string Basename {
get {
- int pos = name.LastIndexOf ('!');
+ int pos = name.LastIndexOf ('`');
if (pos >= 0)
return name.Substring (0, pos);
else
throw new Exception ();
}
- public override bool Define (TypeContainer parent)
+ public override bool Define ()
{
for (int i = 0; i < TypeParameters.Length; i++)
- if (!TypeParameters [i].Resolve (parent))
+ if (!TypeParameters [i].Resolve (Parent))
return false;
return true;
}
- public bool Define (TypeContainer parent, MethodBuilder mb)
+ public bool Define (MethodBuilder mb, Type return_type)
{
- if (!Define (parent))
+ if (!Define ())
return false;
GenericTypeParameterBuilder[] gen_params;
for (int i = 0; i < TypeParameters.Length; i++)
TypeParameters [i].Define (gen_params [i]);
+ ec = new EmitContext (
+ this, this, Location, null, return_type, ModFlags, false);
+
return true;
}
- public bool DefineType (EmitContext ec, MethodBuilder mb)
+ public bool DefineType (EmitContext ec, MethodBuilder mb,
+ MethodInfo implementing, bool is_override)
{
for (int i = 0; i < TypeParameters.Length; i++)
- if (!TypeParameters [i].DefineType (ec))
+ if (!TypeParameters [i].DefineType (
+ ec, mb, implementing, is_override))
return false;
return true;
public override Expression DoResolve (EmitContext ec)
{
- type = ec.DeclSpace.ResolveType (expr, false, loc);
+ TypeExpr texpr = expr.ResolveAsTypeTerminal (ec);
+ if (texpr == null)
+ return null;
+
+ type = texpr.ResolveType (ec);
if (type == null)
return null;