2 // generic.cs: Support classes for generics
5 // Miguel de Icaza (miguel@ximian.com)
7 // (C) 2003 Ximian, Inc.
10 using System.Reflection;
11 using System.Reflection.Emit;
12 using System.Globalization;
13 using System.Collections;
16 namespace Mono.CSharp {
18 public abstract class GenericConstraints {
19 public abstract GenericParameterAttributes Attributes {
23 public bool HasConstructorConstraint {
24 get { return (Attributes & GenericParameterAttributes.DefaultConstructorConstraint) != 0; }
27 public bool HasReferenceTypeConstraint {
28 get { return (Attributes & GenericParameterAttributes.ReferenceTypeConstraint) != 0; }
31 public bool HasValueTypeConstraint {
32 get { return (Attributes & GenericParameterAttributes.ValueTypeConstraint) != 0; }
35 public virtual bool HasClassConstraint {
36 get { return ClassConstraint != null; }
39 public abstract Type ClassConstraint {
43 public abstract Type[] InterfaceConstraints {
47 public abstract Type EffectiveBaseClass {
52 // Returns whether the type parameter is "known to be a reference type".
54 public virtual bool IsReferenceType {
56 if (HasReferenceTypeConstraint)
58 if (HasValueTypeConstraint)
61 if (ClassConstraint != null) {
62 if (ClassConstraint.IsValueType)
65 if (ClassConstraint != TypeManager.object_type)
69 foreach (Type t in InterfaceConstraints) {
70 if (!t.IsGenericParameter)
73 GenericConstraints gc = TypeManager.GetTypeParameterConstraints (t);
74 if ((gc != null) && gc.IsReferenceType)
83 // Returns whether the type parameter is "known to be a value type".
85 public virtual bool IsValueType {
87 if (HasValueTypeConstraint)
89 if (HasReferenceTypeConstraint)
92 if (ClassConstraint != null) {
93 if (!ClassConstraint.IsValueType)
96 if (ClassConstraint != TypeManager.value_type)
100 foreach (Type t in InterfaceConstraints) {
101 if (!t.IsGenericParameter)
104 GenericConstraints gc = TypeManager.GetTypeParameterConstraints (t);
105 if ((gc != null) && gc.IsValueType)
114 public enum SpecialConstraint
122 // Tracks the constraints for a type parameter
124 public class Constraints : GenericConstraints {
126 ArrayList constraints;
130 // name is the identifier, constraints is an arraylist of
131 // Expressions (with types) or `true' for the constructor constraint.
133 public Constraints (string name, ArrayList constraints,
137 this.constraints = constraints;
141 public string TypeParameter {
147 GenericParameterAttributes attrs;
148 TypeExpr class_constraint;
149 ArrayList iface_constraints;
150 ArrayList type_param_constraints;
151 int num_constraints, first_constraint;
152 Type class_constraint_type;
153 Type[] iface_constraint_types;
154 Type effective_base_type;
156 public bool Resolve (DeclSpace ds)
158 iface_constraints = new ArrayList ();
159 type_param_constraints = new ArrayList ();
161 foreach (object obj in constraints) {
162 if (HasConstructorConstraint) {
163 Report.Error (401, loc,
164 "The new() constraint must be last.");
168 if (obj is SpecialConstraint) {
169 SpecialConstraint sc = (SpecialConstraint) obj;
171 if (sc == SpecialConstraint.Constructor) {
172 if (!HasValueTypeConstraint) {
173 attrs |= GenericParameterAttributes.DefaultConstructorConstraint;
178 451, loc, "The new () constraint " +
179 "cannot be used with the `struct' " +
184 if ((num_constraints > 0) || HasReferenceTypeConstraint || HasValueTypeConstraint) {
185 Report.Error (449, loc,
186 "The `class' or `struct' " +
187 "constraint must be first");
191 if (sc == SpecialConstraint.ReferenceType)
192 attrs |= GenericParameterAttributes.ReferenceTypeConstraint;
194 attrs |= GenericParameterAttributes.ValueTypeConstraint;
198 TypeExpr expr = ds.ResolveTypeExpr ((Expression) obj, false, loc);
202 TypeParameterExpr texpr = expr as TypeParameterExpr;
204 type_param_constraints.Add (expr);
205 else if (expr.IsInterface)
206 iface_constraints.Add (expr);
207 else if (class_constraint != null) {
208 Report.Error (406, loc,
209 "`{0}': the class constraint for `{1}' " +
210 "must come before any other constraints.",
213 } else if (HasReferenceTypeConstraint || HasValueTypeConstraint) {
214 Report.Error (450, loc, "`{0}': cannot specify both " +
215 "a constraint class and the `class' " +
216 "or `struct' constraint.", expr.Name);
219 class_constraint = expr;
227 bool CheckTypeParameterConstraints (TypeParameter tparam, Hashtable seen)
229 seen.Add (tparam, true);
231 Constraints constraints = tparam.Constraints;
232 if (constraints == null)
235 if (constraints.HasValueTypeConstraint) {
236 Report.Error (456, loc, "Type parameter `{0}' has " +
237 "the `struct' constraint, so it cannot " +
238 "be used as a constraint for `{1}'",
243 if (constraints.type_param_constraints == null)
246 foreach (TypeParameterExpr expr in constraints.type_param_constraints) {
247 if (seen.Contains (expr.TypeParameter)) {
248 Report.Error (454, loc, "Circular constraint " +
249 "dependency involving `{0}' and `{1}'",
250 tparam.Name, expr.Name);
254 if (!CheckTypeParameterConstraints (expr.TypeParameter, seen))
261 public bool ResolveTypes (EmitContext ec)
263 foreach (TypeParameterExpr expr in type_param_constraints) {
264 Hashtable seen = new Hashtable ();
265 if (!CheckTypeParameterConstraints (expr.TypeParameter, seen))
269 ArrayList list = new ArrayList ();
271 foreach (TypeExpr iface_constraint in iface_constraints) {
272 Type resolved = iface_constraint.ResolveType (ec);
273 if (resolved == null)
276 foreach (Type type in list) {
277 if (!type.Equals (resolved))
280 Report.Error (405, loc,
281 "Duplicate constraint `{0}' for type " +
282 "parameter `{1}'.", resolved, name);
289 foreach (TypeParameterExpr expr in type_param_constraints) {
290 Type resolved = expr.ResolveType (ec);
291 if (resolved == null)
294 foreach (Type type in list) {
295 if (!type.Equals (resolved))
298 Report.Error (405, loc,
299 "Duplicate constraint `{0}' for type " +
300 "parameter `{1}'.", resolved, name);
307 iface_constraint_types = new Type [list.Count];
308 list.CopyTo (iface_constraint_types, 0);
310 if (class_constraint != null) {
311 class_constraint_type = class_constraint.ResolveType (ec);
312 if (class_constraint_type == null)
315 if (class_constraint_type.IsSealed) {
316 Report.Error (701, loc,
317 "`{0}' is not a valid bound. Bounds " +
318 "must be interfaces or non sealed " +
319 "classes", class_constraint_type);
323 if ((class_constraint_type == TypeManager.array_type) ||
324 (class_constraint_type == TypeManager.delegate_type) ||
325 (class_constraint_type == TypeManager.enum_type) ||
326 (class_constraint_type == TypeManager.value_type) ||
327 (class_constraint_type == TypeManager.object_type)) {
328 Report.Error (702, loc,
329 "Bound cannot be special class `{0}'",
330 class_constraint_type);
335 if (class_constraint_type != null)
336 effective_base_type = class_constraint_type;
337 else if (HasValueTypeConstraint)
338 effective_base_type = TypeManager.value_type;
340 effective_base_type = TypeManager.object_type;
345 public bool CheckDependencies (EmitContext ec)
347 foreach (TypeParameterExpr expr in type_param_constraints) {
348 if (!CheckDependencies (expr.TypeParameter, ec))
355 bool CheckDependencies (TypeParameter tparam, EmitContext ec)
357 Constraints constraints = tparam.Constraints;
358 if (constraints == null)
361 if (HasValueTypeConstraint && constraints.HasClassConstraint) {
362 Report.Error (455, loc, "Type parameter `{0}' inherits " +
363 "conflicting constraints `{1}' and `{2}'",
364 name, constraints.ClassConstraint,
369 if (HasClassConstraint && constraints.HasClassConstraint) {
370 Type t1 = ClassConstraint;
371 TypeExpr e1 = class_constraint;
372 Type t2 = constraints.ClassConstraint;
373 TypeExpr e2 = constraints.class_constraint;
375 if (!Convert.ImplicitReferenceConversionExists (ec, e1, t2) &&
376 !Convert.ImplicitReferenceConversionExists (ec, e2, t1)) {
377 Report.Error (455, loc,
378 "Type parameter `{0}' inherits " +
379 "conflicting constraints `{1}' and `{2}'",
385 if (constraints.type_param_constraints == null)
388 foreach (TypeParameterExpr expr in constraints.type_param_constraints) {
389 if (!CheckDependencies (expr.TypeParameter, ec))
396 public void Define (GenericTypeParameterBuilder type)
398 type.SetGenericParameterAttributes (attrs);
401 public override GenericParameterAttributes Attributes {
402 get { return attrs; }
405 public override bool HasClassConstraint {
406 get { return class_constraint != null; }
409 public override Type ClassConstraint {
410 get { return class_constraint_type; }
413 public override Type[] InterfaceConstraints {
414 get { return iface_constraint_types; }
417 public override Type EffectiveBaseClass {
418 get { return effective_base_type; }
421 internal bool IsSubclassOf (Type t)
423 if ((class_constraint_type != null) &&
424 class_constraint_type.IsSubclassOf (t))
427 if (iface_constraint_types == null)
430 foreach (Type iface in iface_constraint_types) {
431 if (TypeManager.IsSubclassOf (iface, t))
438 public bool CheckInterfaceMethod (EmitContext ec, GenericConstraints gc)
440 if (!ResolveTypes (ec))
443 if (gc.Attributes != attrs)
446 if (HasClassConstraint != gc.HasClassConstraint)
448 if (HasClassConstraint && !TypeManager.IsEqual (gc.ClassConstraint, ClassConstraint))
451 int gc_icount = gc.InterfaceConstraints != null ?
452 gc.InterfaceConstraints.Length : 0;
453 int icount = InterfaceConstraints != null ?
454 InterfaceConstraints.Length : 0;
456 if (gc_icount != icount)
459 foreach (Type iface in gc.InterfaceConstraints) {
461 foreach (Type check in InterfaceConstraints) {
462 if (TypeManager.IsEqual (iface, check)) {
477 // This type represents a generic type parameter
479 public class TypeParameter : MemberCore, IMemberContainer {
481 GenericConstraints gc;
482 Constraints constraints;
484 GenericTypeParameterBuilder type;
486 public TypeParameter (TypeContainer parent, string name,
487 Constraints constraints, Location loc)
488 : base (parent, new MemberName (name), null, loc)
491 this.constraints = constraints;
495 public GenericConstraints GenericConstraints {
497 return gc != null ? gc : constraints;
501 public Constraints Constraints {
507 public bool HasConstructorConstraint {
509 if (constraints != null)
510 return constraints.HasConstructorConstraint;
522 public bool Resolve (DeclSpace ds)
524 if (constraints != null)
525 return constraints.Resolve (ds);
530 public void Define (GenericTypeParameterBuilder type)
532 if (this.type != null)
533 throw new InvalidOperationException ();
536 TypeManager.AddTypeParameter (type, this);
539 public void DefineConstraints ()
541 if (constraints != null)
542 constraints.Define (type);
545 public bool DefineType (EmitContext ec)
547 return DefineType (ec, null, null, false);
550 public bool DefineType (EmitContext ec, MethodBuilder builder,
551 MethodInfo implementing, bool is_override)
553 if (implementing != null) {
554 if (is_override && (constraints != null)) {
556 460, loc, "Constraints for override and " +
557 "explicit interface implementation methods " +
558 "are inherited from the base method so they " +
559 "cannot be specified directly");
563 MethodBase mb = implementing;
564 if (mb.Mono_IsInflatedMethod)
565 mb = mb.GetGenericMethodDefinition ();
567 int pos = type.GenericParameterPosition;
568 ParameterData pd = Invocation.GetParameterData (mb);
569 GenericConstraints temp_gc = pd.GenericConstraints (pos);
570 Type mparam = mb.GetGenericArguments () [pos];
573 gc = new InflatedConstraints (temp_gc, implementing.DeclaringType);
574 else if (constraints != null)
575 gc = new InflatedConstraints (constraints, implementing.DeclaringType);
578 if (constraints != null) {
581 else if (!constraints.CheckInterfaceMethod (ec, gc))
584 if (!is_override && (temp_gc != null))
589 Report.SymbolRelatedToPreviousError (implementing);
592 425, loc, "The constraints for type " +
593 "parameter `{0}' of method `{1}' must match " +
594 "the constraints for type parameter `{2}' " +
595 "of interface method `{3}'. Consider using " +
596 "an explicit interface implementation instead",
597 Name, TypeManager.CSharpSignature (builder),
598 mparam, TypeManager.CSharpSignature (mb));
602 if (constraints != null) {
603 if (!constraints.ResolveTypes (ec))
607 gc = (GenericConstraints) constraints;
613 if (gc.HasClassConstraint)
614 type.SetBaseTypeConstraint (gc.ClassConstraint);
616 type.SetInterfaceConstraints (gc.InterfaceConstraints);
617 TypeManager.RegisterBuilder (type, gc.InterfaceConstraints);
622 public bool CheckDependencies (EmitContext ec)
624 if (constraints != null)
625 return constraints.CheckDependencies (ec);
634 public override bool Define ()
639 protected override void VerifyObsoleteAttribute ()
642 public override void ApplyAttributeBuilder (Attribute a,
643 CustomAttributeBuilder cb)
646 public override AttributeTargets AttributeTargets {
648 return (AttributeTargets) 0;
652 public override string[] ValidAttributeTargets {
654 return new string [0];
662 string IMemberContainer.Name {
666 IMemberContainer IMemberContainer.ParentContainer {
670 bool IMemberContainer.IsInterface {
674 MemberList IMemberContainer.GetMembers (MemberTypes mt, BindingFlags bf)
676 return FindMembers (mt, bf, null, null);
679 MemberCache IMemberContainer.MemberCache {
683 public MemberList FindMembers (MemberTypes mt, BindingFlags bf,
684 MemberFilter filter, object criteria)
686 if (constraints == null)
687 return MemberList.Empty;
689 ArrayList members = new ArrayList ();
691 GenericConstraints gc = (GenericConstraints) constraints;
693 if (gc.HasClassConstraint) {
694 MemberList list = TypeManager.FindMembers (
695 gc.ClassConstraint, mt, bf, filter, criteria);
697 members.AddRange (list);
700 foreach (Type t in gc.InterfaceConstraints) {
701 MemberList list = TypeManager.FindMembers (
702 t, mt, bf, filter, criteria);
704 members.AddRange (list);
707 return new MemberList (members);
710 public bool IsSubclassOf (Type t)
715 if (constraints != null)
716 return constraints.IsSubclassOf (t);
721 public override string ToString ()
723 return "TypeParameter[" + name + "]";
726 protected class InflatedConstraints : GenericConstraints
728 GenericConstraints gc;
730 Type class_constraint;
731 Type[] iface_constraints;
735 public InflatedConstraints (GenericConstraints gc, Type declaring)
738 this.declaring = declaring;
740 dargs = TypeManager.GetTypeArguments (declaring);
742 ArrayList list = new ArrayList ();
743 if (gc.HasClassConstraint)
744 list.Add (inflate (gc.ClassConstraint));
745 foreach (Type iface in gc.InterfaceConstraints)
746 list.Add (inflate (iface));
748 bool has_class_constr = false;
749 if (list.Count > 0) {
750 Type first = (Type) list [0];
751 has_class_constr = !first.IsInterface && !first.IsGenericParameter;
754 if ((list.Count > 0) && has_class_constr) {
755 class_constraint = (Type) list [0];
756 iface_constraints = new Type [list.Count - 1];
757 list.CopyTo (1, iface_constraints, 0, list.Count - 1);
759 iface_constraints = new Type [list.Count];
760 list.CopyTo (iface_constraints, 0);
763 if (HasValueTypeConstraint)
764 base_type = TypeManager.value_type;
765 else if (class_constraint != null)
766 base_type = class_constraint;
768 base_type = TypeManager.object_type;
771 Type inflate (Type t)
775 if (t.IsGenericParameter)
776 return dargs [t.GenericParameterPosition];
777 if (t.IsGenericInstance) {
778 t = t.GetGenericTypeDefinition ();
779 t = t.BindGenericParameters (dargs);
785 public override GenericParameterAttributes Attributes {
786 get { return gc.Attributes; }
789 public override Type ClassConstraint {
790 get { return class_constraint; }
793 public override Type EffectiveBaseClass {
794 get { return base_type; }
797 public override Type[] InterfaceConstraints {
798 get { return iface_constraints; }
804 // This type represents a generic type parameter reference.
806 // These expressions are born in a fully resolved state.
808 public class TypeParameterExpr : TypeExpr {
809 TypeParameter type_parameter;
811 public override string Name {
813 return type_parameter.Name;
817 public TypeParameter TypeParameter {
819 return type_parameter;
823 public TypeParameterExpr (TypeParameter type_parameter, Location loc)
825 this.type_parameter = type_parameter;
829 public override TypeExpr DoResolveAsTypeStep (EmitContext ec)
831 type = type_parameter.Type;
836 public override bool IsInterface {
837 get { return false; }
840 public override bool CheckAccessLevel (DeclSpace ds)
845 public void Error_CannotUseAsUnmanagedType (Location loc)
847 Report.Error (-203, loc, "Can not use type parameter as unamanged type");
851 public class TypeArguments {
852 public readonly Location Location;
859 public TypeArguments (Location loc)
861 args = new ArrayList ();
865 public TypeArguments (int dimension, Location loc)
867 this.dimension = dimension;
871 public void Add (Expression type)
874 throw new InvalidOperationException ();
879 public void Add (TypeArguments new_args)
882 throw new InvalidOperationException ();
884 args.AddRange (new_args.args);
887 public string[] GetDeclarations ()
889 string[] ret = new string [args.Count];
890 for (int i = 0; i < args.Count; i++) {
891 SimpleName sn = args [i] as SimpleName;
897 Report.Error (81, Location, "Type parameter declaration " +
898 "must be an identifier not a type");
904 public Type[] Arguments {
910 public bool HasTypeArguments {
912 return has_type_args;
925 public bool IsUnbound {
927 return dimension > 0;
931 public override string ToString ()
933 StringBuilder s = new StringBuilder ();
936 for (int i = 0; i < count; i++){
938 // FIXME: Use TypeManager.CSharpname once we have the type
941 s.Append (args [i].ToString ());
945 return s.ToString ();
948 public bool Resolve (EmitContext ec)
950 DeclSpace ds = ec.DeclSpace;
951 int count = args.Count;
954 atypes = new Type [count];
956 for (int i = 0; i < count; i++){
957 TypeExpr te = ((Expression) args [i]).ResolveAsTypeTerminal (ec, false);
962 if (te is TypeParameterExpr)
963 has_type_args = true;
964 atypes [i] = te.ResolveType (ec);
966 if (atypes [i] == null) {
967 Report.Error (246, Location, "Cannot find type `{0}'",
976 public class ConstructedType : TypeExpr {
977 string name, full_name;
979 Type[] gen_params, atypes;
982 public ConstructedType (string name, TypeArguments args, Location l)
985 this.name = MemberName.MakeName (name, args.Count);
988 eclass = ExprClass.Type;
989 full_name = name + "<" + args.ToString () + ">";
992 public ConstructedType (string name, TypeParameter[] type_params, Location l)
993 : this (type_params, l)
998 full_name = name + "<" + args.ToString () + ">";
1001 protected ConstructedType (TypeArguments args, Location l)
1006 eclass = ExprClass.Type;
1009 protected ConstructedType (TypeParameter[] type_params, Location l)
1013 args = new TypeArguments (l);
1014 foreach (TypeParameter type_param in type_params)
1015 args.Add (new TypeParameterExpr (type_param, l));
1017 eclass = ExprClass.Type;
1020 public ConstructedType (Type t, TypeParameter[] type_params, Location l)
1021 : this (type_params, l)
1023 gt = t.GetGenericTypeDefinition ();
1025 this.name = gt.FullName;
1026 full_name = gt.FullName + "<" + args.ToString () + ">";
1029 public ConstructedType (Type t, TypeArguments args, Location l)
1032 gt = t.GetGenericTypeDefinition ();
1034 this.name = gt.FullName;
1035 full_name = gt.FullName + "<" + args.ToString () + ">";
1038 public TypeArguments TypeArguments {
1039 get { return args; }
1042 protected string DeclarationName {
1044 StringBuilder sb = new StringBuilder ();
1045 sb.Append (gt.FullName);
1047 for (int i = 0; i < gen_params.Length; i++) {
1050 sb.Append (gen_params [i]);
1053 return sb.ToString ();
1057 protected bool CheckConstraint (EmitContext ec, Type ptype, Expression expr,
1060 if (TypeManager.HasGenericArguments (ctype)) {
1061 Type[] types = TypeManager.GetTypeArguments (ctype);
1063 TypeArguments new_args = new TypeArguments (loc);
1065 for (int i = 0; i < types.Length; i++) {
1068 if (t.IsGenericParameter) {
1069 int pos = t.GenericParameterPosition;
1070 t = args.Arguments [pos];
1072 new_args.Add (new TypeExpression (t, loc));
1075 ctype = new ConstructedType (ctype, new_args, loc).ResolveType (ec);
1080 return Convert.ImplicitStandardConversionExists (ec, expr, ctype);
1083 protected bool CheckConstraints (EmitContext ec, int index)
1085 Type atype = atypes [index];
1086 Type ptype = gen_params [index];
1091 Expression aexpr = new EmptyExpression (atype);
1093 GenericConstraints gc = TypeManager.GetTypeParameterConstraints (ptype);
1098 // First, check the `class' and `struct' constraints.
1100 if (gc.HasReferenceTypeConstraint && !atype.IsClass) {
1101 Report.Error (452, loc, "The type `{0}' must be " +
1102 "a reference type in order to use it " +
1103 "as type parameter `{1}' in the " +
1104 "generic type or method `{2}'.",
1105 atype, ptype, DeclarationName);
1107 } else if (gc.HasValueTypeConstraint && !atype.IsValueType) {
1108 Report.Error (453, loc, "The type `{0}' must be " +
1109 "a value type in order to use it " +
1110 "as type parameter `{1}' in the " +
1111 "generic type or method `{2}'.",
1112 atype, ptype, DeclarationName);
1117 // The class constraint comes next.
1119 if (gc.HasClassConstraint) {
1120 if (!CheckConstraint (ec, ptype, aexpr, gc.ClassConstraint)) {
1121 Report.Error (309, loc, "The type `{0}' must be " +
1122 "convertible to `{1}' in order to " +
1123 "use it as parameter `{2}' in the " +
1124 "generic type or method `{3}'",
1125 atype, gc.ClassConstraint, ptype, DeclarationName);
1131 // Now, check the interface constraints.
1133 foreach (Type it in gc.InterfaceConstraints) {
1135 if (it.IsGenericParameter)
1136 itype = atypes [it.GenericParameterPosition];
1140 if (!CheckConstraint (ec, ptype, aexpr, itype)) {
1141 Report.Error (309, loc, "The type `{0}' must be " +
1142 "convertible to `{1}' in order to " +
1143 "use it as parameter `{2}' in the " +
1144 "generic type or method `{3}'",
1145 atype, itype, ptype, DeclarationName);
1151 // Finally, check the constructor constraint.
1154 if (!gc.HasConstructorConstraint)
1157 if (TypeManager.IsBuiltinType (atype))
1160 MethodGroupExpr mg = Expression.MemberLookup (
1161 ec, atype, ".ctor", MemberTypes.Constructor,
1162 BindingFlags.Public | BindingFlags.Instance |
1163 BindingFlags.DeclaredOnly, loc)
1166 if (atype.IsAbstract || (mg == null) || !mg.IsInstance) {
1167 Report.Error (310, loc, "The type `{0}' must have a public " +
1168 "parameterless constructor in order to use it " +
1169 "as parameter `{1}' in the generic type or " +
1170 "method `{2}'", atype, ptype, DeclarationName);
1177 public override TypeExpr DoResolveAsTypeStep (EmitContext ec)
1182 return DoResolveType (ec);
1185 // First, resolve the generic type.
1188 Type nested = ec.DeclSpace.FindNestedType (loc, name, out ds);
1189 if (nested != null) {
1190 gt = nested.GetGenericTypeDefinition ();
1192 TypeArguments new_args = new TypeArguments (loc);
1194 foreach (TypeParameter param in ds.TypeParameters)
1195 new_args.Add (new TypeParameterExpr (param, loc));
1197 new_args.Add (args);
1200 return DoResolveType (ec);
1206 SimpleName sn = new SimpleName (name, loc);
1207 TypeExpr resolved = sn.ResolveAsTypeTerminal (ec, true);
1208 if ((resolved == null) || (resolved.Type == null)) {
1209 Report.Error (246, loc,
1210 "The type or namespace name `{0}<...>' "+
1211 "could not be found", Basename);
1217 Report.Error (246, loc, "Cannot find type `{0}'<...>",
1222 num_args = TypeManager.GetNumberOfTypeArguments (t);
1223 if (num_args == 0) {
1224 Report.Error (308, loc,
1225 "The non-generic type `{0}' cannot " +
1226 "be used with type arguments.",
1227 TypeManager.CSharpName (t));
1231 gt = t.GetGenericTypeDefinition ();
1232 return DoResolveType (ec);
1235 TypeExpr DoResolveType (EmitContext ec)
1238 // Resolve the arguments.
1240 if (args.Resolve (ec) == false)
1243 gen_params = gt.GetGenericArguments ();
1244 atypes = args.Arguments;
1246 if (atypes.Length != gen_params.Length) {
1247 Report.Error (305, loc,
1248 "Using the generic type `{0}' " +
1249 "requires {1} type arguments",
1250 TypeManager.GetFullName (gt),
1255 for (int i = 0; i < gen_params.Length; i++) {
1256 if (!CheckConstraints (ec, i))
1261 // Now bind the parameters.
1263 type = gt.BindGenericParameters (atypes);
1267 public Expression GetSimpleName (EmitContext ec)
1269 return new SimpleName (Basename, args, loc);
1272 public override bool CheckAccessLevel (DeclSpace ds)
1274 return ds.CheckAccessLevel (gt);
1277 public override bool AsAccessible (DeclSpace ds, int flags)
1279 return ds.AsAccessible (gt, flags);
1282 public override bool IsClass {
1283 get { return gt.IsClass; }
1286 public override bool IsValueType {
1287 get { return gt.IsValueType; }
1290 public override bool IsInterface {
1291 get { return gt.IsInterface; }
1294 public override bool IsSealed {
1295 get { return gt.IsSealed; }
1298 public override bool IsAttribute {
1299 get { return false; }
1302 public override bool Equals (object obj)
1304 ConstructedType cobj = obj as ConstructedType;
1308 if ((type == null) || (cobj.type == null))
1311 return type == cobj.type;
1314 public string Basename {
1316 int pos = name.LastIndexOf ('`');
1318 return name.Substring (0, pos);
1324 public override string Name {
1331 public class GenericMethod : DeclSpace
1333 public GenericMethod (NamespaceEntry ns, TypeContainer parent,
1334 MemberName name, Location l)
1335 : base (ns, parent, name, null, l)
1338 public override TypeBuilder DefineType ()
1340 throw new Exception ();
1343 public override bool Define ()
1345 for (int i = 0; i < TypeParameters.Length; i++)
1346 if (!TypeParameters [i].Resolve (Parent))
1352 public bool Define (MethodBuilder mb, Type return_type)
1357 GenericTypeParameterBuilder[] gen_params;
1358 string[] names = MemberName.TypeArguments.GetDeclarations ();
1359 gen_params = mb.DefineGenericParameters (names);
1360 for (int i = 0; i < TypeParameters.Length; i++)
1361 TypeParameters [i].Define (gen_params [i]);
1363 ec = new EmitContext (
1364 this, this, Location, null, return_type, ModFlags, false);
1369 public bool DefineType (EmitContext ec, MethodBuilder mb,
1370 MethodInfo implementing, bool is_override)
1372 for (int i = 0; i < TypeParameters.Length; i++)
1373 if (!TypeParameters [i].DefineType (
1374 ec, mb, implementing, is_override))
1380 public override bool DefineMembers (TypeContainer parent)
1385 public override MemberList FindMembers (MemberTypes mt, BindingFlags bf,
1386 MemberFilter filter, object criteria)
1388 throw new Exception ();
1391 public override MemberCache MemberCache {
1393 throw new Exception ();
1397 public override void ApplyAttributeBuilder (Attribute a, CustomAttributeBuilder cb)
1402 protected override void VerifyObsoleteAttribute()
1407 public override AttributeTargets AttributeTargets {
1409 return AttributeTargets.Method | AttributeTargets.ReturnValue;
1414 public class DefaultValueExpression : Expression
1417 LocalTemporary temp_storage;
1419 public DefaultValueExpression (Expression expr, Location loc)
1425 public override Expression DoResolve (EmitContext ec)
1427 type = ec.DeclSpace.ResolveType (expr, false, loc);
1431 if (type.IsGenericParameter || TypeManager.IsValueType (type))
1432 temp_storage = new LocalTemporary (ec, type);
1434 eclass = ExprClass.Variable;
1438 public override void Emit (EmitContext ec)
1440 if (temp_storage != null) {
1441 temp_storage.AddressOf (ec, AddressOp.LoadStore);
1442 ec.ig.Emit (OpCodes.Initobj, type);
1443 temp_storage.Emit (ec);
1445 ec.ig.Emit (OpCodes.Ldnull);