X-Git-Url: http://wien.tomnetworks.com/gitweb/?a=blobdiff_plain;f=mcs%2Fgmcs%2Fgeneric.cs;h=5a94fa821e122ef8e194dc523a162a63d23438d8;hb=9076dfdec8582c59a2c683da9943496514f8d2dd;hp=15dd0cad6fdebec798fbd0475be0665fbd9a1ef6;hpb=6369966bdba0612c61c17b0db0e829ec923cd0d8;p=mono.git diff --git a/mcs/gmcs/generic.cs b/mcs/gmcs/generic.cs index 15dd0cad6fd..5a94fa821e1 100644 --- a/mcs/gmcs/generic.cs +++ b/mcs/gmcs/generic.cs @@ -15,43 +15,48 @@ using System.Text; namespace Mono.CSharp { + public enum SpecialConstraint + { + Constructor, + ReferenceType, + ValueType + } + // // Tracks the constraints for a type parameter // - public class Constraints { - string type_parameter; + public class Constraints : GenericConstraints { + string name; ArrayList constraints; Location loc; // - // type_parameter is the identifier, constraints is an arraylist of + // name is the identifier, constraints is an arraylist of // Expressions (with types) or `true' for the constructor constraint. // - public Constraints (string type_parameter, ArrayList constraints, + public Constraints (string name, ArrayList constraints, Location loc) { - this.type_parameter = type_parameter; + this.name = name; this.constraints = constraints; this.loc = loc; } public string TypeParameter { get { - return type_parameter; + return name; } } - protected void Error (string message) - { - Report.Error (-218, "Invalid constraints clause for type " + - "parameter `{0}': {1}", type_parameter, message); - } - bool has_ctor_constraint; + bool has_reference_type; + bool has_value_type; TypeExpr class_constraint; ArrayList iface_constraints; - TypeExpr[] constraint_types; - int num_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; } @@ -60,16 +65,43 @@ namespace Mono.CSharp { public bool Resolve (DeclSpace ds) { iface_constraints = new ArrayList (); + type_param_constraints = new ArrayList (); foreach (object obj in constraints) { if (has_ctor_constraint) { - Error ("can only use one constructor constraint and " + - "it must be the last constraint in the list."); + Report.Error (401, loc, + "The new() constraint must be last."); return false; } - if (obj is bool) { - has_ctor_constraint = true; + if (obj is SpecialConstraint) { + SpecialConstraint sc = (SpecialConstraint) obj; + + if (sc == SpecialConstraint.Constructor) { + if (!has_value_type) { + has_ctor_constraint = true; + continue; + } + + Report.Error ( + 451, loc, "The new () constraint " + + "cannot be used with the `struct' " + + "constraint."); + return false; + } + + if ((num_constraints > 0) || has_reference_type || + has_value_type) { + Report.Error (449, loc, + "The `class' or `struct' " + + "constraint must be first"); + return false; + } + + if (sc == SpecialConstraint.ReferenceType) + has_reference_type = true; + else + has_value_type = true; continue; } @@ -77,10 +109,21 @@ namespace Mono.CSharp { if (expr == null) 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) { - Error ("can have at most one class constraint."); + Report.Error (406, loc, + "`{0}': the class constraint for `{1}' " + + "must come before any other constraints.", + expr.Name, name); + return false; + } else if (has_reference_type || has_value_type) { + Report.Error (450, loc, "`{0}': cannot specify both " + + "a constraint class and the `class' " + + "or `struct' constraint.", expr.Name); return false; } else class_constraint = expr; @@ -88,34 +131,219 @@ namespace Mono.CSharp { num_constraints++; } - constraint_types = new TypeExpr [num_constraints]; - int pos = 0; - if (class_constraint != null) - constraint_types [pos++] = class_constraint; - iface_constraints.CopyTo (constraint_types, pos); + return true; + } + + bool CheckTypeParameterConstraints (TypeParameter tparam, Hashtable seen) + { + seen.Add (tparam, true); + + Constraints constraints = tparam.Constraints; + if (constraints == null) + return true; + + if (constraints.IsValueType) { + 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) + { + foreach (TypeParameterExpr expr in type_param_constraints) { + Hashtable seen = new Hashtable (); + if (!CheckTypeParameterConstraints (expr.TypeParameter, seen)) + return false; + } + + ArrayList list = new ArrayList (); + + foreach (TypeExpr iface_constraint in iface_constraints) { + Type resolved = iface_constraint.ResolveType (ec); + if (resolved == null) + return false; + + foreach (TypeExpr texpr in list) { + if (!texpr.Equals (resolved)) + continue; + + Report.Error (405, loc, + "Duplicate constraint `{0}' for type " + + "parameter `{1}'.", resolved, name); + return false; + } + + list.Add (resolved); + } + + foreach (TypeParameterExpr expr in type_param_constraints) { + Type resolved = expr.ResolveType (ec); + if (resolved == null) + return false; + + foreach (TypeExpr texpr in list) { + if (!texpr.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) + return false; + + if (class_constraint_type.IsSealed) { + Report.Error (701, loc, + "`{0}' is not a valid bound. Bounds " + + "must be interfaces or non sealed " + + "classes", class_constraint_type); + return false; + } + + 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)) { + Report.Error (702, loc, + "Bound cannot be special class `{0}'", + class_constraint_type); + return false; + } + } + + if (has_reference_type) + class_constraint_type = TypeManager.object_type; + else if (has_value_type) + class_constraint_type = TypeManager.value_type; + + return true; + } + + public bool CheckDependencies (EmitContext ec) + { + foreach (TypeParameterExpr expr in type_param_constraints) { + if (!CheckDependencies (expr.TypeParameter, ec)) + return false; + } + + return true; + } + + bool CheckDependencies (TypeParameter tparam, EmitContext ec) + { + Constraints constraints = tparam.Constraints; + if (constraints == null) + return true; + + if (IsValueType && 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 (e1, t2) && + !Convert.ImplicitReferenceConversionExists (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; } - public Type[] ResolveTypes (EmitContext ec) + public void Define (GenericTypeParameterBuilder type) { - Type [] types = new Type [constraint_types.Length]; + if (has_ctor_constraint) + type.Mono_SetConstructorConstraint (); + if (has_reference_type) + type.Mono_SetReferenceTypeConstraint (); + else if (has_value_type) + type.Mono_SetValueTypeConstraint (); + } - for (int i = 0; i < constraint_types.Length; i++) - types [i] = constraint_types [i].ResolveType (ec); + bool GenericConstraints.HasConstructor { + get { return has_ctor_constraint; } + } - return types; + bool GenericConstraints.IsReferenceType { + get { return has_reference_type; } + } + + public bool IsValueType { + get { return has_value_type; } + } + + public bool HasClassConstraint { + get { return class_constraint_type != null; } + } + + public Type ClassConstraint { + get { return class_constraint_type; } + } + + Type[] GenericConstraints.InterfaceConstraints { + get { return iface_constraint_types; } } } // // This type represents a generic type parameter // - public class TypeParameter { + public class TypeParameter : IMemberContainer { string name; Constraints constraints; Location loc; - Type type; + GenericTypeParameterBuilder type; public TypeParameter (string name, Constraints constraints, Location loc) { @@ -142,6 +370,15 @@ namespace Mono.CSharp { } } + public bool HasConstructorConstraint { + get { + if (constraints != null) + return constraints.HasConstructorConstraint; + + return false; + } + } + public Type Type { get { return type; @@ -156,34 +393,87 @@ namespace Mono.CSharp { return true; } - public Type Define (TypeBuilder tb) + public void Define (GenericTypeParameterBuilder type) { - type = tb.DefineGenericParameter (name); - return type; + this.type = type; + Type[] ifaces = null; + if (constraints != null) + constraints.Define (type); + TypeManager.AddTypeParameter (type, this); } - public Type DefineMethod (MethodBuilder mb) + public bool DefineType (EmitContext ec) { - type = mb.DefineGenericParameter (name); - return type; + if (constraints != null) { + if (!constraints.ResolveTypes (ec)) + return false; + + GenericConstraints gc = (GenericConstraints) constraints; + + if (gc.HasClassConstraint) + type.SetBaseTypeConstraint (gc.ClassConstraint); + + type.SetInterfaceConstraints (gc.InterfaceConstraints); + TypeManager.RegisterBuilder (type, gc.InterfaceConstraints); + } + + return true; } - public void DefineType (EmitContext ec, TypeBuilder tb) + public bool CheckDependencies (EmitContext ec) { - int index = type.GenericParameterPosition; - if (constraints == null) - tb.SetGenericParameterConstraints (index, new Type [0]); - else - tb.SetGenericParameterConstraints (index, constraints.ResolveTypes (ec)); + if (constraints != null) + return constraints.CheckDependencies (ec); + + return true; + } + + // + // IMemberContainer + // + + IMemberContainer IMemberContainer.ParentContainer { + get { return null; } } - public void DefineType (EmitContext ec, MethodBuilder mb) + bool IMemberContainer.IsInterface { + get { return true; } + } + + MemberList IMemberContainer.GetMembers (MemberTypes mt, BindingFlags bf) + { + return FindMembers (mt, bf, null, null); + } + + MemberCache IMemberContainer.MemberCache { + get { return null; } + } + + public MemberList FindMembers (MemberTypes mt, BindingFlags bf, + MemberFilter filter, object criteria) { - int index = type.GenericParameterPosition; if (constraints == null) - mb.SetGenericParameterConstraints (index, new Type [0]); - else - mb.SetGenericParameterConstraints (index, constraints.ResolveTypes (ec)); + return MemberList.Empty; + + ArrayList members = new ArrayList (); + + GenericConstraints gc = (GenericConstraints) constraints; + + if (gc.HasClassConstraint) { + MemberList list = TypeManager.FindMembers ( + gc.ClassConstraint, mt, bf, filter, criteria); + + members.AddRange (list); + } + + foreach (Type t in gc.InterfaceConstraints) { + MemberList list = TypeManager.FindMembers ( + t, mt, bf, filter, criteria); + + members.AddRange (list); + } + + return new MemberList (members); } public override string ToString () @@ -215,6 +505,7 @@ namespace Mono.CSharp { public TypeParameterExpr (TypeParameter type_parameter, Location loc) { this.type_parameter = type_parameter; + this.loc = loc; } public override TypeExpr DoResolveAsTypeStep (EmitContext ec) @@ -224,6 +515,10 @@ namespace Mono.CSharp { return this; } + public override bool IsInterface { + get { return false; } + } + public void Error_CannotUseAsUnmanagedType (Location loc) { Report.Error (-203, loc, "Can not use type parameter as unamanged type"); @@ -234,6 +529,7 @@ namespace Mono.CSharp { public readonly Location Location; ArrayList args; Type[] atypes; + int dimension; bool has_type_args; bool created; @@ -243,6 +539,12 @@ namespace Mono.CSharp { this.Location = loc; } + public TypeArguments (int dimension, Location loc) + { + this.dimension = dimension; + this.Location = loc; + } + public void Add (Expression type) { if (created) @@ -259,6 +561,23 @@ namespace Mono.CSharp { args.AddRange (new_args.args); } + public string[] GetDeclarations () + { + string[] ret = new string [args.Count]; + for (int i = 0; i < args.Count; i++) { + SimpleName sn = args [i] as SimpleName; + if (sn != null) { + ret [i] = sn.Name; + continue; + } + + Report.Error (81, Location, "Type parameter declaration " + + "must be an identifier not a type"); + return null; + } + return ret; + } + public Type[] Arguments { get { return atypes; @@ -273,7 +592,16 @@ namespace Mono.CSharp { public int Count { get { - return args.Count; + if (dimension > 0) + return dimension; + else + return args.Count; + } + } + + public bool IsUnbound { + get { + return dimension > 0; } } @@ -281,14 +609,15 @@ namespace Mono.CSharp { { 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 (", "); + s.Append (","); } return s.ToString (); } @@ -300,7 +629,7 @@ namespace Mono.CSharp { bool ok = true; atypes = new Type [count]; - + for (int i = 0; i < count; i++){ TypeExpr te = ds.ResolveTypeExpr ( (Expression) args [i], false, Location); @@ -331,7 +660,7 @@ namespace Mono.CSharp { public ConstructedType (string name, TypeArguments args, Location l) { loc = l; - this.name = name; + this.name = MemberName.MakeName (name, args.Count); this.args = args; eclass = ExprClass.Type; @@ -339,63 +668,183 @@ namespace Mono.CSharp { } public ConstructedType (string name, TypeParameter[] type_params, Location l) + : this (type_params, l) { loc = l; + this.name = name; + full_name = name + "<" + args.ToString () + ">"; + } + + protected ConstructedType (TypeArguments args, Location l) + { + loc = l; + this.args = args; + + eclass = ExprClass.Type; + } + + protected ConstructedType (TypeParameter[] type_params, Location l) + { + loc = l; args = new TypeArguments (l); foreach (TypeParameter type_param in type_params) args.Add (new TypeParameterExpr (type_param, l)); eclass = ExprClass.Type; - full_name = name + "<" + args.ToString () + ">"; } public ConstructedType (Type t, TypeParameter[] type_params, Location l) - : this (t.Name, type_params, l) + : this (type_params, l) { gt = t.GetGenericTypeDefinition (); + + this.name = gt.FullName; + full_name = gt.FullName + "<" + args.ToString () + ">"; } public ConstructedType (Type t, TypeArguments args, Location l) - : this (t.Name, args, l) + : this (args, l) { gt = t.GetGenericTypeDefinition (); + + this.name = gt.FullName; + full_name = gt.FullName + "<" + args.ToString () + ">"; } public TypeArguments TypeArguments { get { return args; } } - protected bool CheckConstraints (int index) + protected string DeclarationName { + get { + StringBuilder sb = new StringBuilder (); + sb.Append (gt.FullName); + sb.Append ("<"); + for (int i = 0; i < gen_params.Length; i++) { + if (i > 0) + sb.Append (","); + sb.Append (gen_params [i]); + } + sb.Append (">"); + return sb.ToString (); + } + } + + 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 (expr, ctype); + } + + protected bool CheckConstraints (EmitContext ec, int index) { Type atype = atypes [index]; Type ptype = gen_params [index]; - //// FIXME - return true; + if (atype == ptype) + return true; + + Expression aexpr = new EmptyExpression (atype); + + Type parent = ptype.BaseType; // - // First, check parent class. + // First, check the `class' and `struct' constraints. // - if ((ptype.BaseType != atype.BaseType) && - !atype.BaseType.IsSubclassOf (ptype.BaseType)) { - Report.Error (-219, loc, "Cannot create constructed type `{0}': " + - "type argument `{1}' must derive from `{2}'.", - full_name, atype, ptype.BaseType); - return false; + 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; + } } // - // Now, check the interfaces. + // The class constraint comes next. // - foreach (Type itype in ptype.GetInterfaces ()) { - if (TypeManager.ImplementsInterface (atype, itype)) - continue; + if ((parent != null) && (parent != TypeManager.object_type)) { + if (!CheckConstraint (ec, ptype, aexpr, parent)) { + 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); + return false; + } + } + + // + // Now, check the interface constraints. + // + foreach (Type it in TypeManager.GetInterfaces (ptype)) { + Type itype; + if (it.IsGenericParameter) + itype = atypes [it.GenericParameterPosition]; + else + itype = it; + + 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 " + + "generic type or method `{3}'", + atype, itype, ptype, DeclarationName); + return false; + } + } + + // + // Finally, check the constructor constraint. + // + + if (!TypeManager.HasConstructorConstraint (ptype)) + return true; - Report.Error (-219, loc, "Cannot create constructed type `{0}: " + - "type argument `{1}' must implement interface `{2}'.", - full_name, atype, itype); + MethodGroupExpr mg = Expression.MemberLookup ( + ec, atype, ".ctor", MemberTypes.Constructor, + BindingFlags.Public | BindingFlags.Instance | + BindingFlags.DeclaredOnly, loc) + as MethodGroupExpr; + + if (atype.IsAbstract || (mg == null) || !mg.IsInstance) { + 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}'", atype, ptype, DeclarationName); return false; } @@ -424,19 +873,35 @@ namespace Mono.CSharp { return this; } - SimpleName sn = new SimpleName (name, args.Count, loc); + Type t; + int num_args; + + SimpleName sn = new SimpleName (name, loc); TypeExpr resolved = sn.ResolveAsTypeTerminal (ec); - if (resolved == null) + if ((resolved == null) || (resolved.Type == null)) { + Report.Error (246, loc, + "The type or namespace name `{0}<...>' "+ + "could not be found", Basename); return null; + } + + t = resolved.Type; + if (t == null) { + Report.Error (246, loc, "Cannot find type `{0}'<...>", + Basename); + return null; + } - if (resolved.Type == null) { - Report.Error (-220, loc, - "Failed to resolve constructed type `{0}'", - full_name); + num_args = TypeManager.GetNumberOfTypeArguments (t); + if (num_args == 0) { + Report.Error (308, loc, + "The non-generic type `{0}' cannot " + + "be used with type arguments.", + TypeManager.CSharpName (t)); return null; } - gt = resolved.Type.GetGenericTypeDefinition (); + gt = t.GetGenericTypeDefinition (); return this; } @@ -457,14 +922,16 @@ namespace Mono.CSharp { atypes = args.Arguments; if (atypes.Length != gen_params.Length) { - Report.Error (-217, loc, "Generic type `{0}' takes {1} " + - "type parameters, but specified {2}.", gt.Name, - gen_params.Length, atypes.Length); + Report.Error (305, loc, + "Using the generic type `{0}' " + + "requires {1} type arguments", + TypeManager.GetFullName (gt), + gen_params.Length); return null; } for (int i = 0; i < gen_params.Length; i++) { - if (!CheckConstraints (i)) + if (!CheckConstraints (ec, i)) return null; } @@ -475,9 +942,9 @@ namespace Mono.CSharp { return type; } - public Expression GetMemberAccess (TypeExpr current_type) + public Expression GetSimpleName (EmitContext ec) { - return new GenericMemberAccess (current_type, name, args, loc); + return new SimpleName (Basename, args, loc); } public override bool CheckAccessLevel (DeclSpace ds) @@ -506,10 +973,30 @@ namespace Mono.CSharp { get { return gt.IsSealed; } } - public override TypeExpr[] GetInterfaces () + public override bool IsAttribute { + get { return false; } + } + + public override bool Equals (object obj) { - TypeExpr[] ifaces = TypeManager.GetInterfaces (gt); - return ifaces; + ConstructedType cobj = obj as ConstructedType; + if (cobj == null) + return false; + + if ((type == null) || (cobj.type == null)) + return false; + + return type == cobj.type; + } + + public string Basename { + get { + int pos = name.LastIndexOf ('`'); + if (pos >= 0) + return name.Substring (0, pos); + else + return name; + } } public override string Name { @@ -521,9 +1008,9 @@ namespace Mono.CSharp { public class GenericMethod : DeclSpace { - public GenericMethod (NamespaceEntry ns, TypeContainer parent, string name, - Attributes attrs, Location l) - : base (ns, parent, name, attrs, l) + public GenericMethod (NamespaceEntry ns, TypeContainer parent, + MemberName name, Location l) + : base (ns, parent, name, null, l) { } public override TypeBuilder DefineType () @@ -531,16 +1018,25 @@ namespace Mono.CSharp { 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)) + return false; + return true; } public bool Define (MethodBuilder mb) { - Type[] gen_params = new Type [TypeParameters.Length]; + if (!Define ()) + return false; + + GenericTypeParameterBuilder[] gen_params; + string[] names = MemberName.TypeArguments.GetDeclarations (); + gen_params = mb.DefineGenericParameters (names); for (int i = 0; i < TypeParameters.Length; i++) - gen_params [i] = TypeParameters [i].DefineMethod (mb); + TypeParameters [i].Define (gen_params [i]); return true; } @@ -548,7 +1044,8 @@ namespace Mono.CSharp { public bool DefineType (EmitContext ec, MethodBuilder mb) { for (int i = 0; i < TypeParameters.Length; i++) - TypeParameters [i].DefineType (ec, mb); + if (!TypeParameters [i].DefineType (ec)) + return false; return true; } @@ -569,84 +1066,21 @@ namespace Mono.CSharp { throw new Exception (); } } - } - public class GenericMemberAccess : MemberAccess - { - TypeArguments args; - - public GenericMemberAccess (Expression expr, string id, TypeArguments args, Location loc) - : base (expr, id, loc) + public override void ApplyAttributeBuilder (Attribute a, CustomAttributeBuilder cb) { - this.args = args; + // FIXME } - public override Expression DoResolve (EmitContext ec, Expression right_side, - ResolveFlags flags) + protected override void VerifyObsoleteAttribute() { - Expression expr = base.DoResolve (ec, right_side, flags); - if (expr == null) - return null; - - MethodGroupExpr mg = expr as MethodGroupExpr; - if (mg == null) { - Report.Error (-220, loc, "Member `{0}' has type arguments, but did " + - "not resolve as a method group.", Identifier); - return null; - } - - if (args.Resolve (ec) == false) - return null; - - Type[] atypes = args.Arguments; - - ArrayList list = new ArrayList (); - - foreach (MethodBase method in mg.Methods) { - MethodInfo mi = method as MethodInfo; - if (mi == null) - continue; - - Type[] gen_params = mi.GetGenericArguments (); - - if (atypes.Length != gen_params.Length) { - Report.Error (-217, loc, "Generic method `{0}' takes {1} " + - "type parameters, but specified {2}.", mi.Name, - gen_params.Length, atypes.Length); - continue; - } - - list.Add (mi.BindGenericParameters (args.Arguments)); - } - - MethodInfo[] methods = new MethodInfo [list.Count]; - list.CopyTo (methods, 0); - - MethodGroupExpr new_mg = new MethodGroupExpr (methods, mg.Location); - new_mg.InstanceExpression = mg.InstanceExpression; - return new_mg; + // FIXME } - public override Expression ResolveAsTypeStep (EmitContext ec) - { - ConstructedType cexpr = expr as ConstructedType; - if (cexpr == null) - throw new Exception (); - - expr = base.ResolveAsTypeStep (ec); - if (expr == null) - return null; - - Type t = ((TypeExpr) expr).ResolveType (ec); - if (t == null) - return null; - - TypeArguments new_args = new TypeArguments (loc); - new_args.Add (cexpr.TypeArguments); - new_args.Add (args); - - ConstructedType ctype = new ConstructedType (t, new_args, loc); - return ctype.ResolveAsTypeStep (ec); + public override AttributeTargets AttributeTargets { + get { + return AttributeTargets.Method | AttributeTargets.ReturnValue; + } } }