using System;
using System.Collections.Generic;
using System.Text;
-using System.Linq;
+
+#if STATIC
+using MetaType = IKVM.Reflection.Type;
+using IKVM.Reflection;
+#else
+using MetaType = System.Type;
+using System.Reflection;
+#endif
namespace Mono.CSharp
{
public class TypeSpec : MemberSpec
{
- protected Type info;
+ protected MetaType info;
protected MemberCache cache;
protected IList<TypeSpec> ifaces;
TypeSpec base_type;
public static readonly TypeSpec[] EmptyTypes = new TypeSpec[0];
+#if !STATIC
// Reflection Emit hacking
- static Type TypeBuilder;
- static Type GenericTypeBuilder;
+ static readonly Type TypeBuilder;
+ static readonly Type GenericTypeBuilder;
static TypeSpec ()
{
if (GenericTypeBuilder == null)
GenericTypeBuilder = assembly.GetType ("System.Reflection.Emit.TypeBuilderInstantiation");
}
+#endif
- public TypeSpec (MemberKind kind, TypeSpec declaringType, ITypeDefinition definition, Type info, Modifiers modifiers)
+ public TypeSpec (MemberKind kind, TypeSpec declaringType, ITypeDefinition definition, MetaType info, Modifiers modifiers)
: base (kind, declaringType, definition, modifiers)
{
this.declaringType = declaringType;
}
}
+ public virtual BuildinTypeSpec.Type BuildinType {
+ get {
+ return BuildinTypeSpec.Type.None;
+ }
+ }
+
+ public bool HasDynamicElement {
+ get {
+ return (state & StateFlags.HasDynamicElement) != 0;
+ }
+ }
+
public virtual IList<TypeSpec> Interfaces {
get {
return ifaces;
}
public bool IsArray {
- get { return this is ArrayContainer; }
+ get {
+ return Kind == MemberKind.ArrayType;
+ }
}
public bool IsAttribute {
public bool IsConstantCompatible {
get {
- if ((Kind & (MemberKind.Enum | MemberKind.Class | MemberKind.Interface | MemberKind.Delegate)) != 0)
+ if ((Kind & (MemberKind.Enum | MemberKind.Class | MemberKind.Interface | MemberKind.Delegate | MemberKind.ArrayType)) != 0)
return true;
return TypeManager.IsPrimitiveType (this) || this == TypeManager.decimal_type || this == InternalType.Dynamic;
public bool IsTypeBuilder {
get {
+#if STATIC
+ return true;
+#else
var meta = GetMetaInfo().GetType ();
return meta == TypeBuilder || meta == GenericTypeBuilder;
+#endif
}
}
}
}
- public virtual MemberCache MemberCacheTypes {
+ public MemberCache MemberCacheTypes {
get {
- return MemberCache;
+ if (cache == null)
+ InitializeMemberCache (true);
+
+ return cache;
}
}
return aua;
}
- public virtual Type GetMetaInfo ()
+ public virtual MetaType GetMetaInfo ()
{
return info;
}
if (IsNested) {
s = DeclaringType.GetSignatureForError ();
+ } else if (MemberDefinition is AnonymousTypeClass) {
+ return ((AnonymousTypeClass) MemberDefinition).GetSignatureForError ();
} else {
s = MemberDefinition.Namespace;
}
return "<" + TypeManager.CSharpName (MemberDefinition.TypeParameters) + ">";
}
- public bool ImplementsInterface (TypeSpec iface)
+ public bool ImplementsInterface (TypeSpec iface, bool variantly)
{
var t = this;
do {
if (t.Interfaces != null) { // TODO: Try t.iface
foreach (TypeSpec i in t.Interfaces) {
- if (i == iface || TypeSpecComparer.Variant.IsEqual (i, iface))
+ if (i == iface || TypeSpecComparer.IsEqual (i, iface))
+ return true;
+
+ if (variantly && TypeSpecComparer.Variant.IsEqual (i, iface))
return true;
}
}
protected virtual void InitializeMemberCache (bool onlyTypes)
{
- //
- // Not interested in members of nested private types
- //
- if (IsPrivate) {
- cache = new MemberCache (0);
- } else {
- cache = MemberDefinition.LoadMembers (this);
+ MemberDefinition.LoadMembers (this, onlyTypes, ref cache);
+
+ if (onlyTypes)
+ state |= StateFlags.PendingMemberCacheMembers;
+ else
+ state &= ~StateFlags.PendingMemberCacheMembers;
+ }
+
+ //
+ // Is @baseClass base implementation of @type. With enabled @dynamicIsEqual the slower
+ // comparison is used to hide differences between `object' and `dynamic' for generic
+ // types. Should not be used for comparisons where G<object> != G<dynamic>
+ //
+ public static bool IsBaseClass (TypeSpec type, TypeSpec baseClass, bool dynamicIsObject)
+ {
+ if (dynamicIsObject && baseClass.IsGeneric) {
+ //
+ // Returns true for a hierarchies like this when passing baseClass of A<dynamic>
+ //
+ // class B : A<object> {}
+ //
+ while (type != null) {
+ type = type.BaseType;
+ if (TypeSpecComparer.IsEqual (type, baseClass))
+ return true;
+ }
+
+ return false;
}
+
+ while (type != null) {
+ type = type.BaseType;
+ if (type == baseClass)
+ return true;
+ }
+
+ return false;
}
public override MemberSpec InflateMember (TypeParameterInflator inflator)
// When inflating nested type from inside the type instance will be same
// because type parameters are same for all nested types
//
- if (DeclaringType == inflator.TypeInstance)
+ if (DeclaringType == inflator.TypeInstance) {
return MakeGenericType (targs);
+ }
return new InflatedTypeSpec (this, inflator.TypeInstance, targs);
}
public InflatedTypeSpec MakeGenericType (TypeSpec[] targs)
{
if (targs.Length == 0 && !IsNested)
- throw new ArgumentException ("Empty type arguments");
+ throw new ArgumentException ("Empty type arguments for type " + GetSignatureForError ());
InflatedTypeSpec instance;
- if (inflated_instances == null)
+ if (inflated_instances == null) {
inflated_instances = new Dictionary<TypeSpec[], InflatedTypeSpec> (TypeSpecComparer.Default);
+ if (IsNested) {
+ instance = this as InflatedTypeSpec;
+ if (instance != null) {
+ //
+ // Nested types could be inflated on already inflated instances
+ // Caching this type ensured we are using same instance for
+ // inside/outside inflation using local type parameters
+ //
+ inflated_instances.Add (TypeArguments, instance);
+ }
+ }
+ }
+
if (!inflated_instances.TryGetValue (targs, out instance)) {
if (GetDefinition () != this && !IsNested)
- throw new InternalErrorException ("Only type definition or nested non-inflated types can be used to call MakeGenericType");
+ throw new InternalErrorException ("`{0}' must be type definition or nested non-inflated type to MakeGenericType",
+ GetSignatureForError ());
instance = new InflatedTypeSpec (this, declaringType, targs);
inflated_instances.Add (targs, instance);
return this;
}
- public void SetMetaInfo (Type info)
+ public override List<TypeSpec> ResolveMissingDependencies ()
+ {
+ List<TypeSpec> missing = null;
+
+ if (Kind == MemberKind.MissingType) {
+ missing = new List<TypeSpec> ();
+ missing.Add (this);
+ return missing;
+ }
+
+ foreach (var targ in TypeArguments) {
+ if (targ.Kind == MemberKind.MissingType) {
+ if (missing == null)
+ missing = new List<TypeSpec> ();
+
+ missing.Add (targ);
+ }
+ }
+
+ if (Interfaces != null) {
+ foreach (var iface in Interfaces) {
+ if (iface.Kind == MemberKind.MissingType) {
+ if (missing == null)
+ missing = new List<TypeSpec> ();
+
+ missing.Add (iface);
+ }
+ }
+ }
+
+ if (missing != null || BaseType == null)
+ return missing;
+
+ return BaseType.ResolveMissingDependencies ();
+ }
+
+ public void SetMetaInfo (MetaType info)
{
if (this.info != null)
throw new InternalErrorException ("MetaInfo reset");
}
}
- public class PredefinedTypeSpec : TypeSpec
+ public sealed class BuildinTypeSpec : TypeSpec
{
- string name;
- string ns;
+ public enum Type
+ {
+ None = 0,
+
+ // TODO: Reorder it more carefully so we can do fast compares
+ Object,
+ ValueType,
+ Attribute,
+ Int,
+ UInt,
+ Long,
+ ULong,
+ Float,
+ Double,
+ Char,
+ Short,
+ Decimal,
+ Bool,
+ SByte,
+ Byte,
+ UShort,
+ String,
+ Enum,
+ Delegate,
+ MulticastDelegate,
+ Void,
+ Array,
+ Type,
+ IEnumerator,
+ IEnumerable,
+ IDisposable,
+ IntPtr,
+ UIntPtr,
+ RuntimeFieldHandle,
+ RuntimeTypeHandle,
+ Exception,
+
+ Null,
+ Dynamic
+ }
+
+ readonly Type type;
+ readonly string ns;
+ readonly string name;
- public PredefinedTypeSpec (MemberKind kind, string ns, string name)
+ public BuildinTypeSpec (MemberKind kind, string ns, string name, Type buildinKind)
: base (kind, null, null, null, Modifiers.PUBLIC)
{
- this.name = name;
+ this.type = buildinKind;
this.ns = ns;
+ this.name = name;
+ }
+
+ public BuildinTypeSpec (string name, Type buildinKind)
+ : this (MemberKind.InternalCompilerType, "", name, buildinKind)
+ {
+ // Make all internal types CLS-compliant, non-obsolete, compact
+ state = (state & ~(StateFlags.CLSCompliant_Undetected | StateFlags.Obsolete_Undetected | StateFlags.MissingDependency_Undetected)) | StateFlags.CLSCompliant;
}
+ #region Properties
+
public override int Arity {
get {
return 0;
}
}
+ public override BuildinTypeSpec.Type BuildinType {
+ get {
+ return type;
+ }
+ }
+
+ public string FullName {
+ get {
+ return ns + '.' + name;
+ }
+ }
+
public override string Name {
get {
return name;
}
}
+ #endregion
+
public override string GetSignatureForError ()
{
- switch (name) {
+ switch (Name) {
case "Int32": return "int";
case "Int64": return "long";
case "String": return "string";
case "SByte": return "sbyte";
}
- return ns + "." + name;
+ if (ns.Length == 0)
+ return name;
+
+ return FullName;
}
- public void SetDefinition (ITypeDefinition td, Type type)
+ public void SetDefinition (ITypeDefinition td, MetaType type, Modifiers mod)
{
this.definition = td;
this.info = type;
+ this.modifiers |= (mod & ~Modifiers.AccessibilityMask);
}
public void SetDefinition (TypeSpec ts)
this.info = ts.GetMetaInfo ();
this.BaseType = ts.BaseType;
this.Interfaces = ts.Interfaces;
+ this.modifiers = ts.Modifiers;
}
}
static class TypeSpecComparer
{
//
- // Default reference comparison
+ // Does strict reference comparion only
//
public static readonly DefaultImpl Default = new DefaultImpl ();
- public class DefaultImpl : IEqualityComparer<TypeSpec[]>, IEqualityComparer<Tuple<TypeSpec, TypeSpec[]>>
+ public class DefaultImpl : IEqualityComparer<TypeSpec[]>
{
#region IEqualityComparer<TypeSpec[]> Members
- public bool Equals (TypeSpec[] x, TypeSpec[] y)
+ bool IEqualityComparer<TypeSpec[]>.Equals (TypeSpec[] x, TypeSpec[] y)
{
- if (x.Length != y.Length)
- return false;
-
if (x == y)
return true;
+ if (x.Length != y.Length)
+ return false;
+
for (int i = 0; i < x.Length; ++i)
if (x[i] != y[i])
return false;
return true;
}
- public int GetHashCode (TypeSpec[] obj)
+ int IEqualityComparer<TypeSpec[]>.GetHashCode (TypeSpec[] obj)
{
int hash = 0;
for (int i = 0; i < obj.Length; ++i)
}
#endregion
-
- #region IEqualityComparer<Tuple<TypeSpec,TypeSpec[]>> Members
-
- bool IEqualityComparer<Tuple<TypeSpec, TypeSpec[]>>.Equals (Tuple<TypeSpec, TypeSpec[]> x, Tuple<TypeSpec, TypeSpec[]> y)
- {
- return Equals (x.Item2, y.Item2) && x.Item1 == y.Item1;
- }
-
- int IEqualityComparer<Tuple<TypeSpec, TypeSpec[]>>.GetHashCode (Tuple<TypeSpec, TypeSpec[]> obj)
- {
- return GetHashCode (obj.Item2) ^ obj.Item1.GetHashCode ();
- }
-
- #endregion
}
//
return tp_b != null && tp_a.IsMethodOwned == tp_b.IsMethodOwned && tp_a.DeclaredPosition == tp_b.DeclaredPosition;
}
- if (a.TypeArguments.Length != b.TypeArguments.Length)
- return false;
-
- if (a.TypeArguments.Length != 0) {
- if (a.MemberDefinition != b.MemberDefinition)
- return false;
-
- for (int i = 0; i < a.TypeArguments.Length; ++i) {
- if (!IsEqual (a.TypeArguments[i], b.TypeArguments[i]))
- return false;
- }
-
- return true;
- }
-
var ac_a = a as ArrayContainer;
if (ac_a != null) {
var ac_b = b as ArrayContainer;
if (a == InternalType.Dynamic || b == InternalType.Dynamic)
return b == TypeManager.object_type || a == TypeManager.object_type;
- return false;
+ if (a.MemberDefinition != b.MemberDefinition)
+ return false;
+
+ do {
+ for (int i = 0; i < a.TypeArguments.Length; ++i) {
+ if (!IsEqual (a.TypeArguments[i], b.TypeArguments[i]))
+ return false;
+ }
+
+ a = a.DeclaringType;
+ b = b.DeclaringType;
+ } while (a != null);
+
+ return true;
}
//
if (type1.MemberDefinition != target_type_def)
return false;
- if (!type1.IsInterface && !type1.IsDelegate)
- return false;
-
var t1_targs = type1.TypeArguments;
var t2_targs = type2.TypeArguments;
var targs_definition = target_type_def.TypeParameters;
+
+ if (!type1.IsInterface && !type1.IsDelegate) {
+ return false;
+ }
+
for (int i = 0; i < targs_definition.Length; ++i) {
Variance v = targs_definition[i].Variance;
if (v == Variance.None) {
return true;
}
+ static bool ContainsTypeParameter (TypeSpec tparam, TypeSpec type)
+ {
+ TypeSpec[] targs = type.TypeArguments;
+ for (int i = 0; i < targs.Length; i++) {
+ if (tparam == targs[i])
+ return true;
+
+ if (ContainsTypeParameter (tparam, targs[i]))
+ return true;
+ }
+
+ return false;
+ }
+
/// <summary>
/// Check whether `a' and `b' may become equal generic types.
/// The algorithm to do that is a little bit complicated.
// class X<T> : I<T>, I<X<T>> -> ok
//
- TypeSpec[] bargs = b.TypeArguments;
- for (int i = 0; i < bargs.Length; i++) {
- if (a.Equals (bargs[i]))
- return false;
- }
-
- return true;
+ return !ContainsTypeParameter (a, b);
}
if (b.IsGenericParameter)
return false;
}
}
+
+ public static bool Equals (TypeSpec[] x, TypeSpec[] y)
+ {
+ if (x == y)
+ return true;
+
+ if (x.Length != y.Length)
+ return false;
+
+ for (int i = 0; i < x.Length; ++i)
+ if (!IsEqual (x[i], y[i]))
+ return false;
+
+ return true;
+ }
+
+ //
+ // Identity type conversion
+ //
+ // Default reference comparison, it has to be used when comparing
+ // two possible dynamic/internal types
+ //
+ public static bool IsEqual (TypeSpec a, TypeSpec b)
+ {
+ if (a == b) {
+ // This also rejects dynamic == dynamic
+ return a.Kind != MemberKind.InternalCompilerType || a == InternalType.Dynamic;
+ }
+
+ //
+ // object and dynamic are considered equivalent there is an identity conversion
+ // between object and dynamic, and between constructed types that are the same
+ // when replacing all occurences of dynamic with object.
+ //
+ if (a == InternalType.Dynamic || b == InternalType.Dynamic)
+ return b == TypeManager.object_type || a == TypeManager.object_type;
+
+ if (a == null)
+ return false;
+
+ if (a.IsArray) {
+ var a_a = (ArrayContainer) a;
+ var b_a = b as ArrayContainer;
+ if (b_a == null)
+ return false;
+
+ return IsEqual (a_a.Element, b_a.Element) && a_a.Rank == b_a.Rank;
+ }
+
+ if (!a.IsGeneric || b == null || !b.IsGeneric)
+ return false;
+
+ if (a.MemberDefinition != b.MemberDefinition)
+ return false;
+
+ do {
+ if (!Equals (a.TypeArguments, b.TypeArguments))
+ return false;
+
+ a = a.DeclaringType;
+ b = b.DeclaringType;
+ } while (a != null);
+
+ return true;
+ }
}
public interface ITypeDefinition : IMemberDefinition
{
+ IAssemblyDefinition DeclaringAssembly { get; }
string Namespace { get; }
int TypeParametersCount { get; }
TypeParameterSpec[] TypeParameters { get; }
TypeSpec GetAttributeCoClass ();
string GetAttributeDefaultMember ();
AttributeUsageAttribute GetAttributeUsage (PredefinedAttribute pa);
- MemberCache LoadMembers (TypeSpec declaringType);
+ bool IsInternalAsPublic (IAssemblyDefinition assembly);
+ void LoadMembers (TypeSpec declaringType, bool onlyTypes, ref MemberCache cache);
}
- class InternalType : TypeSpec
+ class InternalType : TypeSpec, ITypeDefinition
{
- private class DynamicType : InternalType
- {
- public DynamicType ()
- : base ("dynamic")
- {
- }
-
- public override Type GetMetaInfo ()
- {
- return typeof (object);
- }
- }
-
- public static readonly TypeSpec AnonymousMethod = new InternalType ("anonymous method");
- public static readonly TypeSpec Arglist = new InternalType ("__arglist");
- public static readonly TypeSpec Dynamic = new DynamicType ();
- public static readonly TypeSpec MethodGroup = new InternalType ("method group");
- public static readonly TypeSpec Null = new InternalType ("null");
- public static readonly TypeSpec FakeInternalType = new InternalType ("<fake$type>");
+ public static readonly InternalType AnonymousMethod = new InternalType ("anonymous method");
+ public static readonly InternalType Arglist = new InternalType ("__arglist");
+ public static BuildinTypeSpec Dynamic;
+ public static readonly InternalType MethodGroup = new InternalType ("method group");
+ public static BuildinTypeSpec Null;
+ public static readonly InternalType FakeInternalType = new InternalType ("<fake$type>");
readonly string name;
- protected InternalType (string name)
+ InternalType (string name, MemberCache cache)
+ : this (name)
+ {
+ this.cache = cache;
+ }
+
+ InternalType (string name)
: base (MemberKind.InternalCompilerType, null, null, null, Modifiers.PUBLIC)
{
this.name = name;
+ this.definition = this;
cache = MemberCache.Empty;
// Make all internal types CLS-compliant, non-obsolete
state = (state & ~(StateFlags.CLSCompliant_Undetected | StateFlags.Obsolete_Undetected)) | StateFlags.CLSCompliant;
}
+ #region Properties
+
+ public override int Arity {
+ get {
+ return 0;
+ }
+ }
+
+ IAssemblyDefinition ITypeDefinition.DeclaringAssembly {
+ get {
+ throw new NotImplementedException ();
+ }
+ }
+
+ bool IMemberDefinition.IsImported {
+ get {
+ return false;
+ }
+ }
+
+ public override string Name {
+ get {
+ return name;
+ }
+ }
+
+ string ITypeDefinition.Namespace {
+ get {
+ return null;
+ }
+ }
+
+ int ITypeDefinition.TypeParametersCount {
+ get {
+ return 0;
+ }
+ }
+
+ TypeParameterSpec[] ITypeDefinition.TypeParameters {
+ get {
+ return null;
+ }
+ }
+
+ #endregion
+
public override string GetSignatureForError ()
{
return name;
}
+
+ #region ITypeDefinition Members
+
+ TypeSpec ITypeDefinition.GetAttributeCoClass ()
+ {
+ return null;
+ }
+
+ string ITypeDefinition.GetAttributeDefaultMember ()
+ {
+ return null;
+ }
+
+ AttributeUsageAttribute ITypeDefinition.GetAttributeUsage (PredefinedAttribute pa)
+ {
+ return null;
+ }
+
+ bool ITypeDefinition.IsInternalAsPublic (IAssemblyDefinition assembly)
+ {
+ throw new NotImplementedException ();
+ }
+
+ void ITypeDefinition.LoadMembers (TypeSpec declaringType, bool onlyTypes, ref MemberCache cache)
+ {
+ throw new NotImplementedException ();
+ }
+
+ string[] IMemberDefinition.ConditionalConditions ()
+ {
+ return null;
+ }
+
+ ObsoleteAttribute IMemberDefinition.GetAttributeObsolete ()
+ {
+ return null;
+ }
+
+ bool? IMemberDefinition.CLSAttributeValue {
+ get {
+ return null;
+ }
+ }
+
+ void IMemberDefinition.SetIsAssigned ()
+ {
+ }
+
+ void IMemberDefinition.SetIsUsed ()
+ {
+ }
+
+ #endregion
}
- public abstract class ElementTypeSpec : TypeSpec
+ public abstract class ElementTypeSpec : TypeSpec, ITypeDefinition
{
- protected ElementTypeSpec (MemberKind kind, TypeSpec element, Type info)
- : base (kind, element.DeclaringType, element.MemberDefinition, info, element.Modifiers)
+ protected ElementTypeSpec (MemberKind kind, TypeSpec element, MetaType info)
+ : base (kind, element.DeclaringType, null, info, element.Modifiers)
{
this.Element = element;
+
+ // Some flags can be copied directly from the element
+ const StateFlags shared_flags = StateFlags.CLSCompliant | StateFlags.CLSCompliant_Undetected
+ | StateFlags.Obsolete | StateFlags.Obsolete_Undetected | StateFlags.HasDynamicElement;
+ state &= ~shared_flags;
+ state |= (element.state & shared_flags);
+
+ if (element == InternalType.Dynamic)
+ state |= StateFlags.HasDynamicElement;
+
+ // Has to use its own type definition instead of just element definition to
+ // correctly identify itself for cases like x.MemberDefininition == predefined.MemberDefinition
+ this.definition = this;
+
cache = MemberCache.Empty;
}
mutated.info = null;
return mutated;
}
+
+ #region ITypeDefinition Members
+
+ IAssemblyDefinition ITypeDefinition.DeclaringAssembly {
+ get {
+ return Element.MemberDefinition.DeclaringAssembly;
+ }
+ }
+
+ bool ITypeDefinition.IsInternalAsPublic (IAssemblyDefinition assembly)
+ {
+ return Element.MemberDefinition.IsInternalAsPublic (assembly);
+ }
+
+ public string Namespace {
+ get { throw new NotImplementedException (); }
+ }
+
+ public int TypeParametersCount {
+ get {
+ return 0;
+ }
+ }
+
+ public TypeParameterSpec[] TypeParameters {
+ get {
+ throw new NotSupportedException ();
+ }
+ }
+
+ public TypeSpec GetAttributeCoClass ()
+ {
+ return Element.MemberDefinition.GetAttributeCoClass ();
+ }
+
+ public string GetAttributeDefaultMember ()
+ {
+ return Element.MemberDefinition.GetAttributeDefaultMember ();
+ }
+
+ public void LoadMembers (TypeSpec declaringType, bool onlyTypes, ref MemberCache cache)
+ {
+ Element.MemberDefinition.LoadMembers (declaringType, onlyTypes, ref cache);
+ }
+
+ public bool IsImported {
+ get {
+ return Element.MemberDefinition.IsImported;
+ }
+ }
+
+ public string[] ConditionalConditions ()
+ {
+ return Element.MemberDefinition.ConditionalConditions ();
+ }
+
+ bool? IMemberDefinition.CLSAttributeValue {
+ get {
+ return Element.MemberDefinition.CLSAttributeValue;
+ }
+ }
+
+ public void SetIsAssigned ()
+ {
+ Element.MemberDefinition.SetIsAssigned ();
+ }
+
+ public void SetIsUsed ()
+ {
+ Element.MemberDefinition.SetIsUsed ();
+ }
+
+ #endregion
}
public class ArrayContainer : ElementTypeSpec
{
+ struct TypeRankPair : IEquatable<TypeRankPair>
+ {
+ TypeSpec ts;
+ int rank;
+
+ public TypeRankPair (TypeSpec ts, int rank)
+ {
+ this.ts = ts;
+ this.rank = rank;
+ }
+
+ public override int GetHashCode ()
+ {
+ return ts.GetHashCode () ^ rank.GetHashCode ();
+ }
+
+ #region IEquatable<Tuple<T1,T2>> Members
+
+ public bool Equals (TypeRankPair other)
+ {
+ return other.ts == ts && other.rank == rank;
+ }
+
+ #endregion
+ }
+
readonly int rank;
- static Dictionary<Tuple<TypeSpec, int>, ArrayContainer> instances = new Dictionary<Tuple<TypeSpec, int>, ArrayContainer> ();
+ static Dictionary<TypeRankPair, ArrayContainer> instances = new Dictionary<TypeRankPair, ArrayContainer> ();
private ArrayContainer (TypeSpec element, int rank)
- : base (MemberKind.Class, element, null)
+ : base (MemberKind.ArrayType, element, null)
{
this.rank = rank;
}
}
}
- public System.Reflection.MethodInfo GetConstructor ()
+ public MethodInfo GetConstructor ()
{
var mb = RootContext.ToplevelTypes.Builder;
- var arg_types = new Type[rank];
+ var arg_types = new MetaType[rank];
for (int i = 0; i < rank; i++)
arg_types[i] = TypeManager.int32_type.GetMetaInfo ();
var ctor = mb.GetArrayMethod (
- GetMetaInfo (), ".ctor",
- System.Reflection.CallingConventions.HasThis,
+ GetMetaInfo (), Constructor.ConstructorName,
+ CallingConventions.HasThis,
null, arg_types);
return ctor;
}
- public System.Reflection.MethodInfo GetAddressMethod ()
+ public MethodInfo GetAddressMethod ()
{
var mb = RootContext.ToplevelTypes.Builder;
- var arg_types = new Type[rank];
+ var arg_types = new MetaType[rank];
for (int i = 0; i < rank; i++)
arg_types[i] = TypeManager.int32_type.GetMetaInfo ();
var address = mb.GetArrayMethod (
GetMetaInfo (), "Address",
- System.Reflection.CallingConventions.HasThis | System.Reflection.CallingConventions.Standard,
+ CallingConventions.HasThis | CallingConventions.Standard,
ReferenceContainer.MakeType (Element).GetMetaInfo (), arg_types);
return address;
}
- public System.Reflection.MethodInfo GetGetMethod ()
+ public MethodInfo GetGetMethod ()
{
var mb = RootContext.ToplevelTypes.Builder;
- var arg_types = new Type[rank];
+ var arg_types = new MetaType[rank];
for (int i = 0; i < rank; i++)
arg_types[i] = TypeManager.int32_type.GetMetaInfo ();
var get = mb.GetArrayMethod (
GetMetaInfo (), "Get",
- System.Reflection.CallingConventions.HasThis | System.Reflection.CallingConventions.Standard,
+ CallingConventions.HasThis | CallingConventions.Standard,
Element.GetMetaInfo (), arg_types);
return get;
}
- public System.Reflection.MethodInfo GetSetMethod ()
+ public MethodInfo GetSetMethod ()
{
var mb = RootContext.ToplevelTypes.Builder;
- var arg_types = new Type[rank + 1];
+ var arg_types = new MetaType[rank + 1];
for (int i = 0; i < rank; i++)
arg_types[i] = TypeManager.int32_type.GetMetaInfo ();
var set = mb.GetArrayMethod (
GetMetaInfo (), "Set",
- System.Reflection.CallingConventions.HasThis | System.Reflection.CallingConventions.Standard,
+ CallingConventions.HasThis | CallingConventions.Standard,
TypeManager.void_type.GetMetaInfo (), arg_types);
return set;
}
- public override Type GetMetaInfo ()
+ public override MetaType GetMetaInfo ()
{
if (info == null) {
if (rank == 1)
}
protected override string GetPostfixSignature()
+ {
+ return GetPostfixSignature (rank);
+ }
+
+ public static string GetPostfixSignature (int rank)
{
StringBuilder sb = new StringBuilder ();
sb.Append ("[");
public static ArrayContainer MakeType (TypeSpec element, int rank)
{
ArrayContainer ac;
- var key = Tuple.Create (element, rank);
+ var key = new TypeRankPair (element, rank);
if (!instances.TryGetValue (key, out ac)) {
ac = new ArrayContainer (element, rank) {
BaseType = TypeManager.array_type
public static void Reset ()
{
- instances = new Dictionary<Tuple<TypeSpec, int>, ArrayContainer> ();
+ instances = new Dictionary<TypeRankPair, ArrayContainer> ();
}
}
{
}
- public override Type GetMetaInfo ()
+ public override MetaType GetMetaInfo ()
{
if (info == null) {
info = Element.GetMetaInfo ().MakeByRefType ();
state &= ~StateFlags.CLSCompliant_Undetected;
}
- public override Type GetMetaInfo ()
+ public override MetaType GetMetaInfo ()
{
if (info == null) {
info = Element.GetMetaInfo ().MakePointerType ();