2 // typespec.cs: Type specification
4 // Authors: Marek Safar (marek.safar@gmail.com)
6 // Dual licensed under the terms of the MIT X11 or GNU GPL
8 // Copyright 2010 Novell, Inc
12 using System
.Collections
.Generic
;
18 public class TypeSpec
: MemberSpec
21 protected MemberCache cache
;
22 protected IList
<TypeSpec
> ifaces
;
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
;
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
;
48 if (definition
!= null && definition
.TypeParametersCount
> 0)
49 state
|= StateFlags
.IsGeneric
;
54 public override int Arity
{
56 return MemberDefinition
.TypeParametersCount
;
60 public virtual TypeSpec BaseType
{
69 public virtual IList
<TypeSpec
> Interfaces
{
80 return Kind
== MemberKind
.ArrayType
;
84 public bool IsAttribute
{
94 if (type
== TypeManager
.attribute_type
)
97 type
= type
.base_type
;
98 } while (type
!= null);
104 public bool IsInterface
{
106 return Kind
== MemberKind
.Interface
;
110 public bool IsClass
{
112 return Kind
== MemberKind
.Class
;
116 public bool IsConstantCompatible
{
118 if ((Kind
& (MemberKind
.Enum
| MemberKind
.Class
| MemberKind
.Interface
| MemberKind
.Delegate
| MemberKind
.ArrayType
)) != 0)
121 return TypeManager
.IsPrimitiveType (this) || this == TypeManager
.decimal_type
|| this == InternalType
.Dynamic
;
125 public bool IsDelegate
{
127 return Kind
== MemberKind
.Delegate
;
132 get { return Kind == MemberKind.Enum; }
135 // TODO: Should probably do
136 // IsGenericType -- recursive
137 // HasTypeParameter -- non-recursive
138 public bool IsGenericOrParentIsGeneric
{
144 ts
= ts
.declaringType
;
145 } while (ts
!= null);
151 public bool IsGenericParameter
{
152 get { return Kind == MemberKind.TypeParameter; }
155 public bool IsNested
{
156 get { return declaringType != null && Kind != MemberKind.TypeParameter; }
159 public bool IsPointer
{
161 return Kind
== MemberKind
.PointerType
;
165 public bool IsSealed
{
166 get { return (Modifiers & Modifiers.SEALED) != 0; }
169 public bool IsStruct
{
171 return Kind
== MemberKind
.Struct
;
175 public bool IsTypeBuilder
{
177 var meta
= GetMetaInfo().GetType ();
178 return meta
== TypeBuilder
|| meta
== GenericTypeBuilder
;
182 public MemberCache MemberCache
{
184 if (cache
== null || (state
& StateFlags
.PendingMemberCacheMembers
) != 0)
185 InitializeMemberCache (false);
191 throw new InternalErrorException ("Membercache reset");
197 public virtual MemberCache MemberCacheTypes
{
203 public new ITypeDefinition MemberDefinition
{
205 return (ITypeDefinition
) definition
;
209 // TODO: Wouldn't be better to rely on cast to InflatedTypeSpec and
210 // remove the property, YES IT WOULD !!!
211 public virtual TypeSpec
[] TypeArguments
{
212 get { return TypeSpec.EmptyTypes; }
217 public bool AddInterface (TypeSpec iface
)
219 if ((state
& StateFlags
.InterfacesExpanded
) != 0)
220 throw new InternalErrorException ("Modifying expanded interface list");
222 if (ifaces
== null) {
223 ifaces
= new List
<TypeSpec
> () { iface }
;
227 if (!ifaces
.Contains (iface
)) {
235 public AttributeUsageAttribute
GetAttributeUsage (PredefinedAttribute pa
)
237 if (Kind
!= MemberKind
.Class
)
238 throw new InternalErrorException ();
241 return Attribute
.DefaultUsageAttribute
;
243 AttributeUsageAttribute aua
= null;
245 while (type
!= null) {
246 aua
= type
.MemberDefinition
.GetAttributeUsage (pa
);
250 type
= type
.BaseType
;
256 public virtual Type
GetMetaInfo ()
261 public virtual TypeSpec
GetDefinition ()
266 public override string GetSignatureForError ()
271 s
= DeclaringType
.GetSignatureForError ();
273 s
= MemberDefinition
.Namespace
;
276 if (!string.IsNullOrEmpty (s
))
279 return s
+ Name
+ GetTypeNameSignature ();
282 protected virtual string GetTypeNameSignature ()
287 return "<" + TypeManager
.CSharpName (MemberDefinition
.TypeParameters
) + ">";
290 public bool ImplementsInterface (TypeSpec iface
)
294 if (t
.Interfaces
!= null) { // TODO: Try t.iface
295 foreach (TypeSpec i
in t
.Interfaces
) {
296 if (i
== iface
|| TypeSpecComparer
.Variant
.IsEqual (i
, iface
))
307 protected virtual void InitializeMemberCache (bool onlyTypes
)
310 // Not interested in members of nested private types
313 cache
= new MemberCache (0);
315 cache
= MemberDefinition
.LoadMembers (this);
319 public override MemberSpec
InflateMember (TypeParameterInflator inflator
)
321 var targs
= IsGeneric
? MemberDefinition
.TypeParameters
: TypeSpec
.EmptyTypes
;
324 // When inflating nested type from inside the type instance will be same
325 // because type parameters are same for all nested types
327 if (DeclaringType
== inflator
.TypeInstance
)
328 return MakeGenericType (targs
);
330 return new InflatedTypeSpec (this, inflator
.TypeInstance
, targs
);
333 public InflatedTypeSpec
MakeGenericType (TypeSpec
[] targs
)
335 if (targs
.Length
== 0 && !IsNested
)
336 throw new ArgumentException ("Empty type arguments");
338 InflatedTypeSpec instance
;
340 if (inflated_instances
== null)
341 inflated_instances
= new Dictionary
<TypeSpec
[], InflatedTypeSpec
> (TypeSpecComparer
.Default
);
343 if (!inflated_instances
.TryGetValue (targs
, out instance
)) {
344 if (GetDefinition () != this && !IsNested
)
345 throw new InternalErrorException ("Only type definition or nested non-inflated types can be used to call MakeGenericType");
347 instance
= new InflatedTypeSpec (this, declaringType
, targs
);
348 inflated_instances
.Add (targs
, instance
);
354 public virtual TypeSpec
Mutate (TypeParameterMutator mutator
)
359 public void SetMetaInfo (Type info
)
361 if (this.info
!= null)
362 throw new InternalErrorException ("MetaInfo reset");
367 public void SetExtensionMethodContainer ()
369 modifiers
|= Modifiers
.METHOD_EXTENSION
;
373 public class PredefinedTypeSpec
: TypeSpec
378 public PredefinedTypeSpec (MemberKind kind
, string ns
, string name
)
379 : base (kind
, null, null, null, Modifiers
.PUBLIC
)
385 public override int Arity
{
391 public override string Name
{
397 public string Namespace
{
403 public override string GetSignatureForError ()
406 case "Int32": return "int";
407 case "Int64": return "long";
408 case "String": return "string";
409 case "Boolean": return "bool";
410 case "Void": return "void";
411 case "Object": return "object";
412 case "UInt32": return "uint";
413 case "Int16": return "short";
414 case "UInt16": return "ushort";
415 case "UInt64": return "ulong";
416 case "Single": return "float";
417 case "Double": return "double";
418 case "Decimal": return "decimal";
419 case "Char": return "char";
420 case "Byte": return "byte";
421 case "SByte": return "sbyte";
424 return ns
+ "." + name
;
427 public void SetDefinition (ITypeDefinition td
, Type type
)
429 this.definition
= td
;
433 public void SetDefinition (TypeSpec ts
)
435 this.definition
= ts
.MemberDefinition
;
436 this.info
= ts
.GetMetaInfo ();
437 this.BaseType
= ts
.BaseType
;
438 this.Interfaces
= ts
.Interfaces
;
442 static class TypeSpecComparer
445 // Default reference comparison
447 public static readonly DefaultImpl Default
= new DefaultImpl ();
449 public class DefaultImpl
: IEqualityComparer
<TypeSpec
[]>, IEqualityComparer
<Tuple
<TypeSpec
, TypeSpec
[]>>
451 #region IEqualityComparer<TypeSpec[]> Members
453 public bool Equals (TypeSpec
[] x
, TypeSpec
[] y
)
455 if (x
.Length
!= y
.Length
)
461 for (int i
= 0; i
< x
.Length
; ++i
)
468 public int GetHashCode (TypeSpec
[] obj
)
471 for (int i
= 0; i
< obj
.Length
; ++i
)
472 hash
= (hash
<< 5) - hash
+ obj
[i
].GetHashCode ();
479 #region IEqualityComparer<Tuple<TypeSpec,TypeSpec[]>> Members
481 bool IEqualityComparer
<Tuple
<TypeSpec
, TypeSpec
[]>>.Equals (Tuple
<TypeSpec
, TypeSpec
[]> x
, Tuple
<TypeSpec
, TypeSpec
[]> y
)
483 return Equals (x
.Item2
, y
.Item2
) && x
.Item1
== y
.Item1
;
486 int IEqualityComparer
<Tuple
<TypeSpec
, TypeSpec
[]>>.GetHashCode (Tuple
<TypeSpec
, TypeSpec
[]> obj
)
488 return GetHashCode (obj
.Item2
) ^ obj
.Item1
.GetHashCode ();
495 // When comparing type signature of overrides or overloads
496 // this version tolerates different MVARs at same position
498 public static class Override
500 public static bool IsEqual (TypeSpec a
, TypeSpec b
)
506 // Consider the following example:
508 // public abstract class A
510 // public abstract T Foo<T>();
513 // public class B : A
515 // public override U Foo<T>() { return default (U); }
518 // Here, `T' and `U' are method type parameters from different methods
519 // (A.Foo and B.Foo), so both `==' and Equals() will fail.
521 // However, since we're determining whether B.Foo() overrides A.Foo(),
522 // we need to do a signature based comparision and consider them equal.
525 var tp_a
= a
as TypeParameterSpec
;
527 var tp_b
= b
as TypeParameterSpec
;
528 return tp_b
!= null && tp_a
.IsMethodOwned
== tp_b
.IsMethodOwned
&& tp_a
.DeclaredPosition
== tp_b
.DeclaredPosition
;
531 if (a
.TypeArguments
.Length
!= b
.TypeArguments
.Length
)
534 if (a
.TypeArguments
.Length
!= 0) {
535 if (a
.MemberDefinition
!= b
.MemberDefinition
)
538 for (int i
= 0; i
< a
.TypeArguments
.Length
; ++i
) {
539 if (!IsEqual (a
.TypeArguments
[i
], b
.TypeArguments
[i
]))
546 var ac_a
= a
as ArrayContainer
;
548 var ac_b
= b
as ArrayContainer
;
549 return ac_b
!= null && ac_a
.Rank
== ac_b
.Rank
&& IsEqual (ac_a
.Element
, ac_b
.Element
);
552 if (a
== InternalType
.Dynamic
|| b
== InternalType
.Dynamic
)
553 return b
== TypeManager
.object_type
|| a
== TypeManager
.object_type
;
559 // Compares unordered arrays
561 public static bool IsSame (TypeSpec
[] a
, TypeSpec
[] b
)
566 if (a
== null || b
== null || a
.Length
!= b
.Length
)
569 for (int ai
= 0; ai
< a
.Length
; ++ai
) {
571 for (int bi
= 0; bi
< b
.Length
; ++bi
) {
572 if (IsEqual (a
[ai
], b
[bi
])) {
585 public static bool IsEqual (AParametersCollection a
, AParametersCollection b
)
590 if (a
.Count
!= b
.Count
)
593 for (int i
= 0; i
< a
.Count
; ++i
) {
594 if (!IsEqual (a
.Types
[i
], b
.Types
[i
]))
597 const Parameter
.Modifier ref_out
= Parameter
.Modifier
.REF
| Parameter
.Modifier
.OUT
;
598 if ((a
.FixedParameters
[i
].ModFlags
& ref_out
) != (b
.FixedParameters
[i
].ModFlags
& ref_out
))
607 // Type variance equality comparison
609 public static class Variant
611 public static bool IsEqual (TypeSpec type1
, TypeSpec type2
)
613 if (!type1
.IsGeneric
|| !type2
.IsGeneric
)
616 var target_type_def
= type2
.MemberDefinition
;
617 if (type1
.MemberDefinition
!= target_type_def
)
620 var t1_targs
= type1
.TypeArguments
;
621 var t2_targs
= type2
.TypeArguments
;
622 var targs_definition
= target_type_def
.TypeParameters
;
624 if (!type1
.IsInterface
&& !type1
.IsDelegate
) {
626 // Internal compiler variance between G<object> and G<dynamic>
628 for (int i
= 0; i
< targs_definition
.Length
; ++i
) {
629 if ((t1_targs
[i
] != TypeManager
.object_type
&& t1_targs
[i
] != InternalType
.Dynamic
) ||
630 (t2_targs
[i
] != TypeManager
.object_type
&& t2_targs
[i
] != InternalType
.Dynamic
))
637 for (int i
= 0; i
< targs_definition
.Length
; ++i
) {
638 Variance v
= targs_definition
[i
].Variance
;
639 if (v
== Variance
.None
) {
640 if (t1_targs
[i
] == t2_targs
[i
])
645 if (v
== Variance
.Covariant
) {
646 if (!Convert
.ImplicitReferenceConversionExists (new EmptyExpression (t1_targs
[i
]), t2_targs
[i
]))
648 } else if (!Convert
.ImplicitReferenceConversionExists (new EmptyExpression (t2_targs
[i
]), t1_targs
[i
])) {
658 // Checks whether two generic instances may become equal for some
659 // particular instantiation (26.3.1).
661 public static class Unify
664 // Either @a or @b must be generic type
666 public static bool IsEqual (TypeSpec a
, TypeSpec b
)
668 if (a
.MemberDefinition
!= b
.MemberDefinition
)
671 var ta
= a
.TypeArguments
;
672 var tb
= b
.TypeArguments
;
673 for (int i
= 0; i
< ta
.Length
; i
++) {
674 if (!MayBecomeEqualGenericTypes (ta
[i
], tb
[i
]))
681 static bool ContainsTypeParameter (TypeSpec tparam
, TypeSpec type
)
683 TypeSpec
[] targs
= type
.TypeArguments
;
684 for (int i
= 0; i
< targs
.Length
; i
++) {
685 if (tparam
== targs
[i
])
688 if (ContainsTypeParameter (tparam
, targs
[i
]))
696 /// Check whether `a' and `b' may become equal generic types.
697 /// The algorithm to do that is a little bit complicated.
699 static bool MayBecomeEqualGenericTypes (TypeSpec a
, TypeSpec b
)
701 if (a
.IsGenericParameter
) {
703 // If a is an array of a's type, they may never
710 // If b is a generic parameter or an actual type,
711 // they may become equal:
713 // class X<T,U> : I<T>, I<U>
714 // class X<T> : I<T>, I<float>
716 if (b
.IsGenericParameter
)
717 return a
.DeclaringType
== b
.DeclaringType
;
720 // We're now comparing a type parameter with a
721 // generic instance. They may become equal unless
722 // the type parameter appears anywhere in the
725 // class X<T,U> : I<T>, I<X<U>>
726 // -> error because you could instanciate it as
729 // class X<T> : I<T>, I<X<T>> -> ok
732 return !ContainsTypeParameter (a
, b
);
735 if (b
.IsGenericParameter
)
736 return MayBecomeEqualGenericTypes (b
, a
);
739 // At this point, neither a nor b are a type parameter.
741 // If one of them is a generic instance, compare them (if the
742 // other one is not a generic instance, they can never
745 if (TypeManager
.IsGenericType (a
) || TypeManager
.IsGenericType (b
))
746 return IsEqual (a
, b
);
749 // If both of them are arrays.
751 var a_ac
= a
as ArrayContainer
;
753 var b_ac
= b
as ArrayContainer
;
754 if (b_ac
== null || a_ac
.Rank
!= b_ac
.Rank
)
757 return MayBecomeEqualGenericTypes (a_ac
.Element
, b_ac
.Element
);
761 // Ok, two ordinary types.
768 public interface ITypeDefinition
: IMemberDefinition
770 string Namespace { get; }
771 int TypeParametersCount { get; }
772 TypeParameterSpec
[] TypeParameters { get; }
774 TypeSpec
GetAttributeCoClass ();
775 string GetAttributeDefaultMember ();
776 AttributeUsageAttribute
GetAttributeUsage (PredefinedAttribute pa
);
777 MemberCache
LoadMembers (TypeSpec declaringType
);
780 class InternalType
: TypeSpec
782 private class DynamicType
: InternalType
784 public DynamicType ()
789 public override Type
GetMetaInfo ()
791 return typeof (object);
795 public static readonly TypeSpec AnonymousMethod
= new InternalType ("anonymous method");
796 public static readonly TypeSpec Arglist
= new InternalType ("__arglist");
797 public static readonly TypeSpec Dynamic
= new DynamicType ();
798 public static readonly TypeSpec MethodGroup
= new InternalType ("method group");
799 public static readonly TypeSpec Null
= new InternalType ("null");
800 public static readonly TypeSpec FakeInternalType
= new InternalType ("<fake$type>");
802 readonly string name
;
804 protected InternalType (string name
)
805 : base (MemberKind
.InternalCompilerType
, null, null, null, Modifiers
.PUBLIC
)
808 cache
= MemberCache
.Empty
;
810 // Make all internal types CLS-compliant, non-obsolete
811 state
= (state
& ~
(StateFlags
.CLSCompliant_Undetected
| StateFlags
.Obsolete_Undetected
)) | StateFlags
.CLSCompliant
;
814 public override int Arity
{
820 public override string Name
{
826 public override string GetSignatureForError ()
832 public abstract class ElementTypeSpec
: TypeSpec
, ITypeDefinition
834 protected ElementTypeSpec (MemberKind kind
, TypeSpec element
, Type info
)
835 : base (kind
, element
.DeclaringType
, null, info
, element
.Modifiers
)
837 this.Element
= element
;
839 // Has to use its own type definition instead of just element definition to
840 // correctly identify itself for cases like x.MemberDefininition == predefined.MemberDefinition
841 this.definition
= this;
843 cache
= MemberCache
.Empty
;
848 public TypeSpec Element { get; private set; }
850 public override string Name
{
852 throw new NotSupportedException ();
858 public override ObsoleteAttribute
GetAttributeObsolete ()
860 return Element
.GetAttributeObsolete ();
863 protected virtual string GetPostfixSignature ()
868 public override string GetSignatureForError ()
870 return Element
.GetSignatureForError () + GetPostfixSignature ();
873 public override TypeSpec
Mutate (TypeParameterMutator mutator
)
875 var me
= Element
.Mutate (mutator
);
879 var mutated
= (ElementTypeSpec
) MemberwiseClone ();
880 mutated
.Element
= me
;
885 #region ITypeDefinition Members
887 System
.Reflection
.Assembly IMemberDefinition
.Assembly
{
889 return Element
.Assembly
;
893 public string Namespace
{
894 get { throw new NotImplementedException (); }
897 public int TypeParametersCount
{
903 public TypeParameterSpec
[] TypeParameters
{
905 throw new NotSupportedException ();
909 public TypeSpec
GetAttributeCoClass ()
911 return Element
.MemberDefinition
.GetAttributeCoClass ();
914 public string GetAttributeDefaultMember ()
916 return Element
.MemberDefinition
.GetAttributeDefaultMember ();
919 public MemberCache
LoadMembers (TypeSpec declaringType
)
921 return Element
.MemberDefinition
.LoadMembers (declaringType
);
924 public bool IsImported
{
926 return Element
.MemberDefinition
.IsImported
;
930 public string[] ConditionalConditions ()
932 return Element
.MemberDefinition
.ConditionalConditions ();
935 bool IMemberDefinition
.IsNotCLSCompliant ()
937 return Element
.MemberDefinition
.IsNotCLSCompliant ();
940 public void SetIsAssigned ()
942 Element
.MemberDefinition
.SetIsAssigned ();
945 public void SetIsUsed ()
947 Element
.MemberDefinition
.SetIsUsed ();
953 public class ArrayContainer
: ElementTypeSpec
955 struct TypeRankPair
: IEquatable
<TypeRankPair
>
960 public TypeRankPair (TypeSpec ts
, int rank
)
966 public override int GetHashCode ()
968 return ts
.GetHashCode () ^ rank
.GetHashCode ();
971 #region IEquatable<Tuple<T1,T2>> Members
973 public bool Equals (TypeRankPair other
)
975 return other
.ts
== ts
&& other
.rank
== rank
;
982 static Dictionary
<TypeRankPair
, ArrayContainer
> instances
= new Dictionary
<TypeRankPair
, ArrayContainer
> ();
984 private ArrayContainer (TypeSpec element
, int rank
)
985 : base (MemberKind
.ArrayType
, element
, null)
996 public System
.Reflection
.MethodInfo
GetConstructor ()
998 var mb
= RootContext
.ToplevelTypes
.Builder
;
1000 var arg_types
= new Type
[rank
];
1001 for (int i
= 0; i
< rank
; i
++)
1002 arg_types
[i
] = TypeManager
.int32_type
.GetMetaInfo ();
1004 var ctor
= mb
.GetArrayMethod (
1005 GetMetaInfo (), ".ctor",
1006 System
.Reflection
.CallingConventions
.HasThis
,
1012 public System
.Reflection
.MethodInfo
GetAddressMethod ()
1014 var mb
= RootContext
.ToplevelTypes
.Builder
;
1016 var arg_types
= new Type
[rank
];
1017 for (int i
= 0; i
< rank
; i
++)
1018 arg_types
[i
] = TypeManager
.int32_type
.GetMetaInfo ();
1020 var address
= mb
.GetArrayMethod (
1021 GetMetaInfo (), "Address",
1022 System
.Reflection
.CallingConventions
.HasThis
| System
.Reflection
.CallingConventions
.Standard
,
1023 ReferenceContainer
.MakeType (Element
).GetMetaInfo (), arg_types
);
1028 public System
.Reflection
.MethodInfo
GetGetMethod ()
1030 var mb
= RootContext
.ToplevelTypes
.Builder
;
1032 var arg_types
= new Type
[rank
];
1033 for (int i
= 0; i
< rank
; i
++)
1034 arg_types
[i
] = TypeManager
.int32_type
.GetMetaInfo ();
1036 var get = mb
.GetArrayMethod (
1037 GetMetaInfo (), "Get",
1038 System
.Reflection
.CallingConventions
.HasThis
| System
.Reflection
.CallingConventions
.Standard
,
1039 Element
.GetMetaInfo (), arg_types
);
1044 public System
.Reflection
.MethodInfo
GetSetMethod ()
1046 var mb
= RootContext
.ToplevelTypes
.Builder
;
1048 var arg_types
= new Type
[rank
+ 1];
1049 for (int i
= 0; i
< rank
; i
++)
1050 arg_types
[i
] = TypeManager
.int32_type
.GetMetaInfo ();
1052 arg_types
[rank
] = Element
.GetMetaInfo ();
1054 var set = mb
.GetArrayMethod (
1055 GetMetaInfo (), "Set",
1056 System
.Reflection
.CallingConventions
.HasThis
| System
.Reflection
.CallingConventions
.Standard
,
1057 TypeManager
.void_type
.GetMetaInfo (), arg_types
);
1062 public override Type
GetMetaInfo ()
1066 info
= Element
.GetMetaInfo ().MakeArrayType ();
1068 info
= Element
.GetMetaInfo ().MakeArrayType (rank
);
1074 protected override string GetPostfixSignature()
1076 return GetPostfixSignature (rank
);
1079 public static string GetPostfixSignature (int rank
)
1081 StringBuilder sb
= new StringBuilder ();
1083 for (int i
= 1; i
< rank
; i
++) {
1088 return sb
.ToString ();
1091 public static ArrayContainer
MakeType (TypeSpec element
)
1093 return MakeType (element
, 1);
1096 public static ArrayContainer
MakeType (TypeSpec element
, int rank
)
1099 var key
= new TypeRankPair (element
, rank
);
1100 if (!instances
.TryGetValue (key
, out ac
)) {
1101 ac
= new ArrayContainer (element
, rank
) {
1102 BaseType
= TypeManager
.array_type
1105 instances
.Add (key
, ac
);
1111 public static void Reset ()
1113 instances
= new Dictionary
<TypeRankPair
, ArrayContainer
> ();
1117 class ReferenceContainer
: ElementTypeSpec
1119 static Dictionary
<TypeSpec
, ReferenceContainer
> instances
= new Dictionary
<TypeSpec
, ReferenceContainer
> ();
1121 private ReferenceContainer (TypeSpec element
)
1122 : base (MemberKind
.Class
, element
, null) // TODO: Kind.Class is most likely wrong
1126 public override Type
GetMetaInfo ()
1129 info
= Element
.GetMetaInfo ().MakeByRefType ();
1135 public static ReferenceContainer
MakeType (TypeSpec element
)
1137 ReferenceContainer pc
;
1138 if (!instances
.TryGetValue (element
, out pc
)) {
1139 pc
= new ReferenceContainer (element
);
1140 instances
.Add (element
, pc
);
1146 public static void Reset ()
1148 instances
= new Dictionary
<TypeSpec
, ReferenceContainer
> ();
1152 class PointerContainer
: ElementTypeSpec
1154 static Dictionary
<TypeSpec
, PointerContainer
> instances
= new Dictionary
<TypeSpec
, PointerContainer
> ();
1156 private PointerContainer (TypeSpec element
)
1157 : base (MemberKind
.PointerType
, element
, null)
1159 // It's never CLS-Compliant
1160 state
&= ~StateFlags
.CLSCompliant_Undetected
;
1163 public override Type
GetMetaInfo ()
1166 info
= Element
.GetMetaInfo ().MakePointerType ();
1172 protected override string GetPostfixSignature()
1177 public static PointerContainer
MakeType (TypeSpec element
)
1179 PointerContainer pc
;
1180 if (!instances
.TryGetValue (element
, out pc
)) {
1181 pc
= new PointerContainer (element
);
1182 instances
.Add (element
, pc
);
1188 public static void Reset ()
1190 instances
= new Dictionary
<TypeSpec
, PointerContainer
> ();