2010-05-25 Jb Evain <jbevain@novell.com>
[mcs.git] / mcs / typespec.cs
blobb328b3c3165c21a675993e921086bf4c2fd658e4
1 //
2 // typespec.cs: Type specification
3 //
4 // Authors: Marek Safar (marek.safar@gmail.com)
5 //
6 // Dual licensed under the terms of the MIT X11 or GNU GPL
7 //
8 // Copyright 2010 Novell, Inc
9 //
11 using System;
12 using System.Collections.Generic;
13 using System.Text;
14 using System.Linq;
16 namespace Mono.CSharp
18 public class TypeSpec : MemberSpec
20 protected Type info;
21 protected MemberCache cache;
22 protected IList<TypeSpec> ifaces;
23 TypeSpec base_type;
25 Dictionary<TypeSpec[], InflatedTypeSpec> inflated_instances;
27 public static readonly TypeSpec[] EmptyTypes = new TypeSpec[0];
29 // Reflection Emit hacking
30 static Type TypeBuilder;
31 static Type GenericTypeBuilder;
33 static TypeSpec ()
35 var assembly = typeof (object).Assembly;
36 TypeBuilder = assembly.GetType ("System.Reflection.Emit.TypeBuilder");
37 GenericTypeBuilder = assembly.GetType ("System.Reflection.MonoGenericClass");
38 if (GenericTypeBuilder == null)
39 GenericTypeBuilder = assembly.GetType ("System.Reflection.Emit.TypeBuilderInstantiation");
42 public TypeSpec (MemberKind kind, TypeSpec declaringType, ITypeDefinition definition, Type info, Modifiers modifiers)
43 : base (kind, declaringType, definition, modifiers)
45 this.declaringType = declaringType;
46 this.info = info;
48 if (definition != null && definition.TypeParametersCount > 0)
49 state |= StateFlags.IsGeneric;
52 #region Properties
54 public override int Arity {
55 get {
56 return MemberDefinition.TypeParametersCount;
60 public virtual TypeSpec BaseType {
61 get {
62 return base_type;
64 set {
65 base_type = value;
69 public virtual IList<TypeSpec> Interfaces {
70 get {
71 return ifaces;
73 set {
74 ifaces = value;
78 public bool IsArray {
79 get { return this is ArrayContainer; }
82 public bool IsAttribute {
83 get {
84 if (!IsClass)
85 return false;
87 var type = this;
88 do {
89 if (type.IsGeneric)
90 return false;
92 if (type == TypeManager.attribute_type)
93 return true;
95 type = type.base_type;
96 } while (type != null);
98 return false;
102 public bool IsInterface {
103 get {
104 return Kind == MemberKind.Interface;
108 public bool IsClass {
109 get {
110 return Kind == MemberKind.Class;
114 public bool IsConstantCompatible {
115 get {
116 if ((Kind & (MemberKind.Enum | MemberKind.Class | MemberKind.Interface | MemberKind.Delegate)) != 0)
117 return true;
119 return TypeManager.IsPrimitiveType (this) || this == TypeManager.decimal_type || this == InternalType.Dynamic;
123 public bool IsDelegate {
124 get {
125 return Kind == MemberKind.Delegate;
129 public bool IsEnum {
130 get { return Kind == MemberKind.Enum; }
133 // TODO: Should probably do
134 // IsGenericType -- recursive
135 // HasTypeParameter -- non-recursive
136 public bool IsGenericOrParentIsGeneric {
137 get {
138 var ts = this;
139 do {
140 if (ts.IsGeneric)
141 return true;
142 ts = ts.declaringType;
143 } while (ts != null);
145 return false;
149 public bool IsGenericParameter {
150 get { return Kind == MemberKind.TypeParameter; }
153 public bool IsNested {
154 get { return declaringType != null && Kind != MemberKind.TypeParameter; }
157 public bool IsPointer {
158 get {
159 return Kind == MemberKind.PointerType;
163 public bool IsSealed {
164 get { return (Modifiers & Modifiers.SEALED) != 0; }
167 public bool IsStruct {
168 get {
169 return Kind == MemberKind.Struct;
173 public bool IsTypeBuilder {
174 get {
175 var meta = GetMetaInfo().GetType ();
176 return meta == TypeBuilder || meta == GenericTypeBuilder;
180 public MemberCache MemberCache {
181 get {
182 if (cache == null || (state & StateFlags.PendingMemberCacheMembers) != 0)
183 InitializeMemberCache (false);
185 return cache;
187 set {
188 if (cache != null)
189 throw new InternalErrorException ("Membercache reset");
191 cache = value;
195 public virtual MemberCache MemberCacheTypes {
196 get {
197 return MemberCache;
201 public new ITypeDefinition MemberDefinition {
202 get {
203 return (ITypeDefinition) definition;
207 // TODO: Wouldn't be better to rely on cast to InflatedTypeSpec and
208 // remove the property, YES IT WOULD !!!
209 public virtual TypeSpec[] TypeArguments {
210 get { return TypeSpec.EmptyTypes; }
213 #endregion
215 public bool AddInterface (TypeSpec iface)
217 if ((state & StateFlags.InterfacesExpanded) != 0)
218 throw new InternalErrorException ("Modifying expanded interface list");
220 if (ifaces == null) {
221 ifaces = new List<TypeSpec> () { iface };
222 return true;
225 if (!ifaces.Contains (iface)) {
226 ifaces.Add (iface);
227 return true;
230 return false;
233 public AttributeUsageAttribute GetAttributeUsage (PredefinedAttribute pa)
235 if (Kind != MemberKind.Class)
236 throw new InternalErrorException ();
238 if (!pa.IsDefined)
239 return Attribute.DefaultUsageAttribute;
241 AttributeUsageAttribute aua = null;
242 var type = this;
243 while (type != null) {
244 aua = type.MemberDefinition.GetAttributeUsage (pa);
245 if (aua != null)
246 break;
248 type = type.BaseType;
251 return aua;
254 public virtual Type GetMetaInfo ()
256 return info;
259 public virtual TypeSpec GetDefinition ()
261 return this;
264 public override string GetSignatureForError ()
266 string s;
268 if (IsNested) {
269 s = DeclaringType.GetSignatureForError ();
270 } else {
271 s = MemberDefinition.Namespace;
274 if (!string.IsNullOrEmpty (s))
275 s += ".";
277 return s + Name + GetTypeNameSignature ();
280 protected virtual string GetTypeNameSignature ()
282 if (!IsGeneric)
283 return null;
285 return "<" + TypeManager.CSharpName (MemberDefinition.TypeParameters) + ">";
288 public bool ImplementsInterface (TypeSpec iface)
290 var t = this;
291 do {
292 if (t.Interfaces != null) { // TODO: Try t.iface
293 foreach (TypeSpec i in t.Interfaces) {
294 if (i == iface || TypeSpecComparer.Variant.IsEqual (i, iface))
295 return true;
299 t = t.BaseType;
300 } while (t != null);
302 return false;
305 protected virtual void InitializeMemberCache (bool onlyTypes)
308 // Not interested in members of nested private types
310 if (IsPrivate) {
311 cache = new MemberCache (0);
312 } else {
313 cache = MemberDefinition.LoadMembers (this);
317 public override MemberSpec InflateMember (TypeParameterInflator inflator)
319 var targs = IsGeneric ? MemberDefinition.TypeParameters : TypeSpec.EmptyTypes;
322 // When inflating nested type from inside the type instance will be same
323 // because type parameters are same for all nested types
325 if (DeclaringType == inflator.TypeInstance)
326 return MakeGenericType (targs);
328 return new InflatedTypeSpec (this, inflator.TypeInstance, targs);
331 public InflatedTypeSpec MakeGenericType (TypeSpec[] targs)
333 if (targs.Length == 0 && !IsNested)
334 throw new ArgumentException ("Empty type arguments");
336 InflatedTypeSpec instance;
338 if (inflated_instances == null)
339 inflated_instances = new Dictionary<TypeSpec[], InflatedTypeSpec> (TypeSpecComparer.Default);
341 if (!inflated_instances.TryGetValue (targs, out instance)) {
342 if (GetDefinition () != this && !IsNested)
343 throw new InternalErrorException ("Only type definition or nested non-inflated types can be used to call MakeGenericType");
345 instance = new InflatedTypeSpec (this, declaringType, targs);
346 inflated_instances.Add (targs, instance);
349 return instance;
352 public virtual TypeSpec Mutate (TypeParameterMutator mutator)
354 return this;
357 public void SetMetaInfo (Type info)
359 if (this.info != null)
360 throw new InternalErrorException ("MetaInfo reset");
362 this.info = info;
365 public void SetExtensionMethodContainer ()
367 modifiers |= Modifiers.METHOD_EXTENSION;
371 public class PredefinedTypeSpec : TypeSpec
373 string name;
374 string ns;
376 public PredefinedTypeSpec (MemberKind kind, string ns, string name)
377 : base (kind, null, null, null, Modifiers.PUBLIC)
379 this.name = name;
380 this.ns = ns;
383 public override int Arity {
384 get {
385 return 0;
389 public override string Name {
390 get {
391 return name;
395 public string Namespace {
396 get {
397 return ns;
401 public override string GetSignatureForError ()
403 switch (name) {
404 case "Int32": return "int";
405 case "Int64": return "long";
406 case "String": return "string";
407 case "Boolean": return "bool";
408 case "Void": return "void";
409 case "Object": return "object";
410 case "UInt32": return "uint";
411 case "Int16": return "short";
412 case "UInt16": return "ushort";
413 case "UInt64": return "ulong";
414 case "Single": return "float";
415 case "Double": return "double";
416 case "Decimal": return "decimal";
417 case "Char": return "char";
418 case "Byte": return "byte";
419 case "SByte": return "sbyte";
422 return ns + "." + name;
425 public void SetDefinition (ITypeDefinition td, Type type)
427 this.definition = td;
428 this.info = type;
431 public void SetDefinition (TypeSpec ts)
433 this.definition = ts.MemberDefinition;
434 this.info = ts.GetMetaInfo ();
435 this.BaseType = ts.BaseType;
436 this.Interfaces = ts.Interfaces;
440 static class TypeSpecComparer
443 // Default reference comparison
445 public static readonly DefaultImpl Default = new DefaultImpl ();
447 public class DefaultImpl : IEqualityComparer<TypeSpec[]>, IEqualityComparer<Tuple<TypeSpec, TypeSpec[]>>
449 #region IEqualityComparer<TypeSpec[]> Members
451 public bool Equals (TypeSpec[] x, TypeSpec[] y)
453 if (x.Length != y.Length)
454 return false;
456 if (x == y)
457 return true;
459 for (int i = 0; i < x.Length; ++i)
460 if (x[i] != y[i])
461 return false;
463 return true;
466 public int GetHashCode (TypeSpec[] obj)
468 int hash = 0;
469 for (int i = 0; i < obj.Length; ++i)
470 hash = (hash << 5) - hash + obj[i].GetHashCode ();
472 return hash;
475 #endregion
477 #region IEqualityComparer<Tuple<TypeSpec,TypeSpec[]>> Members
479 bool IEqualityComparer<Tuple<TypeSpec, TypeSpec[]>>.Equals (Tuple<TypeSpec, TypeSpec[]> x, Tuple<TypeSpec, TypeSpec[]> y)
481 return Equals (x.Item2, y.Item2) && x.Item1 == y.Item1;
484 int IEqualityComparer<Tuple<TypeSpec, TypeSpec[]>>.GetHashCode (Tuple<TypeSpec, TypeSpec[]> obj)
486 return GetHashCode (obj.Item2) ^ obj.Item1.GetHashCode ();
489 #endregion
493 // When comparing type signature of overrides or overloads
494 // this version tolerates different MVARs at same position
496 public static class Override
498 public static bool IsEqual (TypeSpec a, TypeSpec b)
500 if (a == b)
501 return true;
504 // Consider the following example:
506 // public abstract class A
507 // {
508 // public abstract T Foo<T>();
509 // }
511 // public class B : A
512 // {
513 // public override U Foo<T>() { return default (U); }
514 // }
516 // Here, `T' and `U' are method type parameters from different methods
517 // (A.Foo and B.Foo), so both `==' and Equals() will fail.
519 // However, since we're determining whether B.Foo() overrides A.Foo(),
520 // we need to do a signature based comparision and consider them equal.
523 var tp_a = a as TypeParameterSpec;
524 if (tp_a != null) {
525 var tp_b = b as TypeParameterSpec;
526 return tp_b != null && tp_a.IsMethodOwned == tp_b.IsMethodOwned && tp_a.DeclaredPosition == tp_b.DeclaredPosition;
529 if (a.TypeArguments.Length != b.TypeArguments.Length)
530 return false;
532 if (a.TypeArguments.Length != 0) {
533 if (a.MemberDefinition != b.MemberDefinition)
534 return false;
536 for (int i = 0; i < a.TypeArguments.Length; ++i) {
537 if (!IsEqual (a.TypeArguments[i], b.TypeArguments[i]))
538 return false;
541 return true;
544 var ac_a = a as ArrayContainer;
545 if (ac_a != null) {
546 var ac_b = b as ArrayContainer;
547 return ac_b != null && ac_a.Rank == ac_b.Rank && IsEqual (ac_a.Element, ac_b.Element);
550 if (a == InternalType.Dynamic || b == InternalType.Dynamic)
551 return b == TypeManager.object_type || a == TypeManager.object_type;
553 return false;
557 // Compares unordered arrays
559 public static bool IsSame (TypeSpec[] a, TypeSpec[] b)
561 if (a == b)
562 return true;
564 if (a == null || b == null || a.Length != b.Length)
565 return false;
567 for (int ai = 0; ai < a.Length; ++ai) {
568 bool found = false;
569 for (int bi = 0; bi < b.Length; ++bi) {
570 if (IsEqual (a[ai], b[bi])) {
571 found = true;
572 break;
576 if (!found)
577 return false;
580 return true;
583 public static bool IsEqual (AParametersCollection a, AParametersCollection b)
585 if (a == b)
586 return true;
588 if (a.Count != b.Count)
589 return false;
591 for (int i = 0; i < a.Count; ++i) {
592 if (!IsEqual (a.Types[i], b.Types[i]))
593 return false;
595 const Parameter.Modifier ref_out = Parameter.Modifier.REF | Parameter.Modifier.OUT;
596 if ((a.FixedParameters[i].ModFlags & ref_out) != (b.FixedParameters[i].ModFlags & ref_out))
597 return false;
600 return true;
605 // Type variance equality comparison
607 public static class Variant
609 public static bool IsEqual (TypeSpec type1, TypeSpec type2)
611 if (!type1.IsGeneric || !type2.IsGeneric)
612 return false;
614 var target_type_def = type2.MemberDefinition;
615 if (type1.MemberDefinition != target_type_def)
616 return false;
618 if (!type1.IsInterface && !type1.IsDelegate)
619 return false;
621 var t1_targs = type1.TypeArguments;
622 var t2_targs = type2.TypeArguments;
623 var targs_definition = target_type_def.TypeParameters;
624 for (int i = 0; i < targs_definition.Length; ++i) {
625 Variance v = targs_definition[i].Variance;
626 if (v == Variance.None) {
627 if (t1_targs[i] == t2_targs[i])
628 continue;
629 return false;
632 if (v == Variance.Covariant) {
633 if (!Convert.ImplicitReferenceConversionExists (new EmptyExpression (t1_targs[i]), t2_targs[i]))
634 return false;
635 } else if (!Convert.ImplicitReferenceConversionExists (new EmptyExpression (t2_targs[i]), t1_targs[i])) {
636 return false;
640 return true;
645 // Checks whether two generic instances may become equal for some
646 // particular instantiation (26.3.1).
648 public static class Unify
651 // Either @a or @b must be generic type
653 public static bool IsEqual (TypeSpec a, TypeSpec b)
655 if (a.MemberDefinition != b.MemberDefinition)
656 return false;
658 var ta = a.TypeArguments;
659 var tb = b.TypeArguments;
660 for (int i = 0; i < ta.Length; i++) {
661 if (!MayBecomeEqualGenericTypes (ta[i], tb[i]))
662 return false;
665 return true;
668 static bool ContainsTypeParameter (TypeSpec tparam, TypeSpec type)
670 TypeSpec[] targs = type.TypeArguments;
671 for (int i = 0; i < targs.Length; i++) {
672 if (tparam == targs[i])
673 return true;
675 if (ContainsTypeParameter (tparam, targs[i]))
676 return true;
679 return false;
682 /// <summary>
683 /// Check whether `a' and `b' may become equal generic types.
684 /// The algorithm to do that is a little bit complicated.
685 /// </summary>
686 static bool MayBecomeEqualGenericTypes (TypeSpec a, TypeSpec b)
688 if (a.IsGenericParameter) {
690 // If a is an array of a's type, they may never
691 // become equal.
693 if (b.IsArray)
694 return false;
697 // If b is a generic parameter or an actual type,
698 // they may become equal:
700 // class X<T,U> : I<T>, I<U>
701 // class X<T> : I<T>, I<float>
703 if (b.IsGenericParameter)
704 return a.DeclaringType == b.DeclaringType;
707 // We're now comparing a type parameter with a
708 // generic instance. They may become equal unless
709 // the type parameter appears anywhere in the
710 // generic instance:
712 // class X<T,U> : I<T>, I<X<U>>
713 // -> error because you could instanciate it as
714 // X<X<int>,int>
716 // class X<T> : I<T>, I<X<T>> -> ok
719 return !ContainsTypeParameter (a, b);
722 if (b.IsGenericParameter)
723 return MayBecomeEqualGenericTypes (b, a);
726 // At this point, neither a nor b are a type parameter.
728 // If one of them is a generic instance, compare them (if the
729 // other one is not a generic instance, they can never
730 // become equal).
732 if (TypeManager.IsGenericType (a) || TypeManager.IsGenericType (b))
733 return IsEqual (a, b);
736 // If both of them are arrays.
738 var a_ac = a as ArrayContainer;
739 if (a_ac != null) {
740 var b_ac = b as ArrayContainer;
741 if (b_ac == null || a_ac.Rank != b_ac.Rank)
742 return false;
744 return MayBecomeEqualGenericTypes (a_ac.Element, b_ac.Element);
748 // Ok, two ordinary types.
750 return false;
755 public interface ITypeDefinition : IMemberDefinition
757 string Namespace { get; }
758 int TypeParametersCount { get; }
759 TypeParameterSpec[] TypeParameters { get; }
761 TypeSpec GetAttributeCoClass ();
762 string GetAttributeDefaultMember ();
763 AttributeUsageAttribute GetAttributeUsage (PredefinedAttribute pa);
764 MemberCache LoadMembers (TypeSpec declaringType);
767 class InternalType : TypeSpec
769 private class DynamicType : InternalType
771 public DynamicType ()
772 : base ("dynamic")
776 public override Type GetMetaInfo ()
778 return typeof (object);
782 public static readonly TypeSpec AnonymousMethod = new InternalType ("anonymous method");
783 public static readonly TypeSpec Arglist = new InternalType ("__arglist");
784 public static readonly TypeSpec Dynamic = new DynamicType ();
785 public static readonly TypeSpec MethodGroup = new InternalType ("method group");
786 public static readonly TypeSpec Null = new InternalType ("null");
787 public static readonly TypeSpec FakeInternalType = new InternalType ("<fake$type>");
789 readonly string name;
791 protected InternalType (string name)
792 : base (MemberKind.InternalCompilerType, null, null, null, Modifiers.PUBLIC)
794 this.name = name;
795 cache = MemberCache.Empty;
797 // Make all internal types CLS-compliant, non-obsolete
798 state = (state & ~(StateFlags.CLSCompliant_Undetected | StateFlags.Obsolete_Undetected)) | StateFlags.CLSCompliant;
801 public override string Name {
802 get {
803 return name;
807 public override string GetSignatureForError ()
809 return name;
813 public abstract class ElementTypeSpec : TypeSpec
815 protected ElementTypeSpec (MemberKind kind, TypeSpec element, Type info)
816 : base (kind, element.DeclaringType, element.MemberDefinition, info, element.Modifiers)
818 this.Element = element;
819 cache = MemberCache.Empty;
822 #region Properties
824 public TypeSpec Element { get; private set; }
826 public override string Name {
827 get {
828 throw new NotSupportedException ();
832 #endregion
834 public override ObsoleteAttribute GetAttributeObsolete ()
836 return Element.GetAttributeObsolete ();
839 protected virtual string GetPostfixSignature ()
841 return null;
844 public override string GetSignatureForError ()
846 return Element.GetSignatureForError () + GetPostfixSignature ();
849 public override TypeSpec Mutate (TypeParameterMutator mutator)
851 var me = Element.Mutate (mutator);
852 if (me == Element)
853 return this;
855 var mutated = (ElementTypeSpec) MemberwiseClone ();
856 mutated.Element = me;
857 mutated.info = null;
858 return mutated;
862 public class ArrayContainer : ElementTypeSpec
864 readonly int rank;
865 static Dictionary<Tuple<TypeSpec, int>, ArrayContainer> instances = new Dictionary<Tuple<TypeSpec, int>, ArrayContainer> ();
867 private ArrayContainer (TypeSpec element, int rank)
868 : base (MemberKind.Class, element, null)
870 this.rank = rank;
873 public int Rank {
874 get {
875 return rank;
879 public System.Reflection.MethodInfo GetConstructor ()
881 var mb = RootContext.ToplevelTypes.Builder;
883 var arg_types = new Type[rank];
884 for (int i = 0; i < rank; i++)
885 arg_types[i] = TypeManager.int32_type.GetMetaInfo ();
887 var ctor = mb.GetArrayMethod (
888 GetMetaInfo (), ".ctor",
889 System.Reflection.CallingConventions.HasThis,
890 null, arg_types);
892 return ctor;
895 public System.Reflection.MethodInfo GetAddressMethod ()
897 var mb = RootContext.ToplevelTypes.Builder;
899 var arg_types = new Type[rank];
900 for (int i = 0; i < rank; i++)
901 arg_types[i] = TypeManager.int32_type.GetMetaInfo ();
903 var address = mb.GetArrayMethod (
904 GetMetaInfo (), "Address",
905 System.Reflection.CallingConventions.HasThis | System.Reflection.CallingConventions.Standard,
906 ReferenceContainer.MakeType (Element).GetMetaInfo (), arg_types);
908 return address;
911 public System.Reflection.MethodInfo GetGetMethod ()
913 var mb = RootContext.ToplevelTypes.Builder;
915 var arg_types = new Type[rank];
916 for (int i = 0; i < rank; i++)
917 arg_types[i] = TypeManager.int32_type.GetMetaInfo ();
919 var get = mb.GetArrayMethod (
920 GetMetaInfo (), "Get",
921 System.Reflection.CallingConventions.HasThis | System.Reflection.CallingConventions.Standard,
922 Element.GetMetaInfo (), arg_types);
924 return get;
927 public System.Reflection.MethodInfo GetSetMethod ()
929 var mb = RootContext.ToplevelTypes.Builder;
931 var arg_types = new Type[rank + 1];
932 for (int i = 0; i < rank; i++)
933 arg_types[i] = TypeManager.int32_type.GetMetaInfo ();
935 arg_types[rank] = Element.GetMetaInfo ();
937 var set = mb.GetArrayMethod (
938 GetMetaInfo (), "Set",
939 System.Reflection.CallingConventions.HasThis | System.Reflection.CallingConventions.Standard,
940 TypeManager.void_type.GetMetaInfo (), arg_types);
942 return set;
945 public override Type GetMetaInfo ()
947 if (info == null) {
948 if (rank == 1)
949 info = Element.GetMetaInfo ().MakeArrayType ();
950 else
951 info = Element.GetMetaInfo ().MakeArrayType (rank);
954 return info;
957 protected override string GetPostfixSignature()
959 StringBuilder sb = new StringBuilder ();
960 sb.Append ("[");
961 for (int i = 1; i < rank; i++) {
962 sb.Append (",");
964 sb.Append ("]");
966 return sb.ToString ();
969 public static ArrayContainer MakeType (TypeSpec element)
971 return MakeType (element, 1);
974 public static ArrayContainer MakeType (TypeSpec element, int rank)
976 ArrayContainer ac;
977 var key = Tuple.Create (element, rank);
978 if (!instances.TryGetValue (key, out ac)) {
979 ac = new ArrayContainer (element, rank) {
980 BaseType = TypeManager.array_type
983 instances.Add (key, ac);
986 return ac;
989 public static void Reset ()
991 instances = new Dictionary<Tuple<TypeSpec, int>, ArrayContainer> ();
995 class ReferenceContainer : ElementTypeSpec
997 static Dictionary<TypeSpec, ReferenceContainer> instances = new Dictionary<TypeSpec, ReferenceContainer> ();
999 private ReferenceContainer (TypeSpec element)
1000 : base (MemberKind.Class, element, null) // TODO: Kind.Class is most likely wrong
1004 public override Type GetMetaInfo ()
1006 if (info == null) {
1007 info = Element.GetMetaInfo ().MakeByRefType ();
1010 return info;
1013 public static ReferenceContainer MakeType (TypeSpec element)
1015 ReferenceContainer pc;
1016 if (!instances.TryGetValue (element, out pc)) {
1017 pc = new ReferenceContainer (element);
1018 instances.Add (element, pc);
1021 return pc;
1024 public static void Reset ()
1026 instances = new Dictionary<TypeSpec, ReferenceContainer> ();
1030 class PointerContainer : ElementTypeSpec
1032 static Dictionary<TypeSpec, PointerContainer> instances = new Dictionary<TypeSpec, PointerContainer> ();
1034 private PointerContainer (TypeSpec element)
1035 : base (MemberKind.PointerType, element, null)
1037 // It's never CLS-Compliant
1038 state &= ~StateFlags.CLSCompliant_Undetected;
1041 public override Type GetMetaInfo ()
1043 if (info == null) {
1044 info = Element.GetMetaInfo ().MakePointerType ();
1047 return info;
1050 protected override string GetPostfixSignature()
1052 return "*";
1055 public static PointerContainer MakeType (TypeSpec element)
1057 PointerContainer pc;
1058 if (!instances.TryGetValue (element, out pc)) {
1059 pc = new PointerContainer (element);
1060 instances.Add (element, pc);
1063 return pc;
1066 public static void Reset ()
1068 instances = new Dictionary<TypeSpec, PointerContainer> ();