X-Git-Url: http://wien.tomnetworks.com/gitweb/?a=blobdiff_plain;f=mcs%2Fmcs%2Ftypespec.cs;h=d1e1b709d1d17027443723e76bd265ae80133350;hb=e2b2d181084848f3c5dde2788370db1b79893c69;hp=cfd3e40f6fd580a4877f3c6ab091010dac7cb15d;hpb=626a21b0f57c9d2a83391c25d3b1cdd19def03a5;p=mono.git diff --git a/mcs/mcs/typespec.cs b/mcs/mcs/typespec.cs index cfd3e40f6fd..d1e1b709d1d 100644 --- a/mcs/mcs/typespec.cs +++ b/mcs/mcs/typespec.cs @@ -6,6 +6,7 @@ // Dual licensed under the terms of the MIT X11 or GNU GPL // // Copyright 2010 Novell, Inc +// Copyright 2011 Xamarin, Inc (http://www.xamarin.com) // using System; @@ -22,6 +23,9 @@ using System.Reflection; namespace Mono.CSharp { + // + // Inflated or non-inflated representation of any type. + // public class TypeSpec : MemberSpec { protected MetaType info; @@ -75,9 +79,9 @@ namespace Mono.CSharp } } - public virtual BuildinTypeSpec.Type BuildinType { + public virtual BuiltinTypeSpec.Type BuiltinType { get { - return BuildinTypeSpec.Type.None; + return BuiltinTypeSpec.Type.None; } } @@ -109,11 +113,11 @@ namespace Mono.CSharp var type = this; do { + if (type.BuiltinType == BuiltinTypeSpec.Type.Attribute) + return true; + if (type.IsGeneric) return false; - - if (type.BuildinType == BuildinTypeSpec.Type.Attribute) - return true; type = type.base_type; } while (type != null); @@ -139,21 +143,21 @@ namespace Mono.CSharp if ((Kind & (MemberKind.Enum | MemberKind.Class | MemberKind.Interface | MemberKind.Delegate | MemberKind.ArrayType)) != 0) return true; - switch (BuildinType) { - case BuildinTypeSpec.Type.Int: - case BuildinTypeSpec.Type.UInt: - case BuildinTypeSpec.Type.Long: - case BuildinTypeSpec.Type.ULong: - case BuildinTypeSpec.Type.Float: - case BuildinTypeSpec.Type.Double: - case BuildinTypeSpec.Type.Char: - case BuildinTypeSpec.Type.Short: - case BuildinTypeSpec.Type.Decimal: - case BuildinTypeSpec.Type.Bool: - case BuildinTypeSpec.Type.SByte: - case BuildinTypeSpec.Type.Byte: - case BuildinTypeSpec.Type.UShort: - case BuildinTypeSpec.Type.Dynamic: + switch (BuiltinType) { + case BuiltinTypeSpec.Type.Int: + case BuiltinTypeSpec.Type.UInt: + case BuiltinTypeSpec.Type.Long: + case BuiltinTypeSpec.Type.ULong: + case BuiltinTypeSpec.Type.Float: + case BuiltinTypeSpec.Type.Double: + case BuiltinTypeSpec.Type.Char: + case BuiltinTypeSpec.Type.Short: + case BuiltinTypeSpec.Type.Decimal: + case BuiltinTypeSpec.Type.Bool: + case BuiltinTypeSpec.Type.SByte: + case BuiltinTypeSpec.Type.Byte: + case BuiltinTypeSpec.Type.UShort: + case BuiltinTypeSpec.Type.Dynamic: return true; } @@ -167,8 +171,46 @@ namespace Mono.CSharp } } + // + // Returns true for instances of Expression + // + public virtual bool IsExpressionTreeType { + get { + return false; + } + set { + state = value ? state | StateFlags.InflatedExpressionType : state & ~StateFlags.InflatedExpressionType; + } + } + public bool IsEnum { - get { return Kind == MemberKind.Enum; } + get { + return Kind == MemberKind.Enum; + } + } + + // + // Returns true for instances of IList, IEnumerable, ICollection + // + public virtual bool IsGenericIterateInterface { + get { + return false; + } + set { + state = value ? state | StateFlags.GenericIterateInterface : state & ~StateFlags.GenericIterateInterface; + } + } + + // + // Returns true for instances of System.Threading.Tasks.Task + // + public virtual bool IsGenericTask { + get { + return false; + } + set { + state = value ? state | StateFlags.GenericTask : state & ~StateFlags.GenericTask; + } } // TODO: Should probably do @@ -188,7 +230,21 @@ namespace Mono.CSharp } public bool IsGenericParameter { - get { return Kind == MemberKind.TypeParameter; } + get { + return Kind == MemberKind.TypeParameter; + } + } + + // + // Returns true for instances of Nullable + // + public virtual bool IsNullableType { + get { + return false; + } + set { + state = value ? state | StateFlags.InflatedNullableType : state & ~StateFlags.InflatedNullableType; + } } public bool IsNested { @@ -205,6 +261,15 @@ namespace Mono.CSharp get { return (Modifiers & Modifiers.SEALED) != 0; } } + public bool IsSpecialRuntimeType { + get { + return (state & StateFlags.SpecialRuntimeType) != 0; + } + set { + state = value ? state | StateFlags.SpecialRuntimeType : state & ~StateFlags.SpecialRuntimeType; + } + } + public bool IsStruct { get { return Kind == MemberKind.Struct; @@ -222,6 +287,31 @@ namespace Mono.CSharp } } + // + // Whether a type is unmanaged. This is used by the unsafe code + // + public bool IsUnmanaged { + get { + if (IsPointer) + return ((ElementTypeSpec) this).Element.IsUnmanaged; + + var ds = MemberDefinition as TypeDefinition; + if (ds != null) + return ds.IsUnmanagedType (); + + if (Kind == MemberKind.Void) + return true; + + if (IsNested && DeclaringType.IsGenericOrParentIsGeneric) + return false; + + return IsValueType (this); + } + } + + // + // A cache of all type members (including nested types) + // public MemberCache MemberCache { get { if (cache == null || (state & StateFlags.PendingMemberCacheMembers) != 0) @@ -278,6 +368,58 @@ namespace Mono.CSharp return false; } + // + // Special version used during type definition + // + public bool AddInterfaceDefined (TypeSpec iface) + { + if (!AddInterface (iface)) + return false; + + // + // We can get into a situation where a type is inflated before + // its interfaces are resoved. Consider this situation + // + // class A : X>, IFoo {} + // + // When resolving base class of X`1 we inflate context type A`1 + // All this happens before we even hit IFoo resolve. Without + // additional expansion any inside usage of A would miss IFoo + // interface because it comes from early inflated TypeSpec + // + if (inflated_instances != null) { + foreach (var inflated in inflated_instances) { + inflated.Value.AddInterface (iface); + } + } + + return true; + } + + // + // Returns all type arguments, usefull for nested types + // + public static TypeSpec[] GetAllTypeArguments (TypeSpec type) + { + IList targs = TypeSpec.EmptyTypes; + + do { + if (type.Arity > 0) { + if (targs.Count == 0) { + targs = type.TypeArguments; + } else { + var list = targs as List ?? new List (targs); + list.AddRange (type.TypeArguments); + targs = list; + } + } + + type = type.declaringType; + } while (type != null); + + return targs as TypeSpec[] ?? ((List) targs).ToArray (); + } + public AttributeUsageAttribute GetAttributeUsage (PredefinedAttribute pa) { if (Kind != MemberKind.Class) @@ -299,6 +441,9 @@ namespace Mono.CSharp return aua; } + // + // Return metadata information used during emit to describe the type + // public virtual MetaType GetMetaInfo () { return info; @@ -309,6 +454,68 @@ namespace Mono.CSharp return this; } + // + // Text representation of type used by documentation writer + // + public override string GetSignatureForDocumentation () + { + StringBuilder sb = new StringBuilder (); + if (IsNested) { + sb.Append (DeclaringType.GetSignatureForDocumentation ()); + } else { + sb.Append (MemberDefinition.Namespace); + } + + if (sb.Length != 0) + sb.Append ("."); + + sb.Append (Name); + if (Arity > 0) { + if (this is InflatedTypeSpec) { + sb.Append ("{"); + for (int i = 0; i < Arity; ++i) { + if (i > 0) + sb.Append (","); + + sb.Append (TypeArguments[i].GetSignatureForDocumentation ()); + } + sb.Append ("}"); + } else { + sb.Append ("`"); + sb.Append (Arity.ToString ()); + } + } + + return sb.ToString (); + } + + public string GetExplicitNameSignatureForDocumentation () + { + StringBuilder sb = new StringBuilder (); + if (IsNested) { + sb.Append (DeclaringType.GetExplicitNameSignatureForDocumentation ()); + } else if (MemberDefinition.Namespace != null) { + sb.Append (MemberDefinition.Namespace.Replace ('.', '#')); + } + + if (sb.Length != 0) + sb.Append ("#"); + + sb.Append (Name); + if (Arity > 0) { + sb.Append ("{"); + for (int i = 0; i < Arity; ++i) { + if (i > 0) + sb.Append (","); + + sb.Append (TypeArguments[i].GetExplicitNameSignatureForDocumentation ()); + } + sb.Append ("}"); + } + + return sb.ToString (); + } + public override string GetSignatureForError () { string s; @@ -327,6 +534,11 @@ namespace Mono.CSharp return s + Name + GetTypeNameSignature (); } + public string GetSignatureForErrorIncludingAssemblyName () + { + return string.Format ("{0} [{1}]", GetSignatureForError (), MemberDefinition.DeclaringAssembly.FullName); + } + protected virtual string GetTypeNameSignature () { if (!IsGeneric) @@ -339,16 +551,18 @@ namespace Mono.CSharp { var t = this; do { - if (t.Interfaces != null) { // TODO: Try t.iface - foreach (TypeSpec i in t.Interfaces) { - if (i == iface || TypeSpecComparer.IsEqual (i, iface)) + var ifaces = t.Interfaces; + if (ifaces != null) { + for (int i = 0; i < ifaces.Count; ++i) { + if (TypeSpecComparer.IsEqual (ifaces[i], iface)) return true; - if (variantly && TypeSpecComparer.Variant.IsEqual (i, iface)) + if (variantly && TypeSpecComparer.Variant.IsEqual (ifaces[i], iface)) return true; } } + // TODO: Why is it needed when we do it during import t = t.BaseType; } while (t != null); @@ -382,10 +596,12 @@ namespace Mono.CSharp // // class B : A {} // + type = type.BaseType; while (type != null) { - type = type.BaseType; if (TypeSpecComparer.IsEqual (type, baseClass)) return true; + + type = type.BaseType; } return false; @@ -400,6 +616,38 @@ namespace Mono.CSharp return false; } + public static bool IsReferenceType (TypeSpec t) + { + switch (t.Kind) { + case MemberKind.TypeParameter: + return ((TypeParameterSpec) t).IsReferenceType; + case MemberKind.Struct: + case MemberKind.Enum: + case MemberKind.Void: + return false; + case MemberKind.InternalCompilerType: + // + // Null is considered to be a reference type + // + return t == InternalType.NullLiteral || t.BuiltinType == BuiltinTypeSpec.Type.Dynamic; + default: + return true; + } + } + + public static bool IsValueType (TypeSpec t) + { + switch (t.Kind) { + case MemberKind.TypeParameter: + return ((TypeParameterSpec) t).IsValueType; + case MemberKind.Struct: + case MemberKind.Enum: + return true; + default: + return false; + } + } + public override MemberSpec InflateMember (TypeParameterInflator inflator) { var targs = IsGeneric ? MemberDefinition.TypeParameters : TypeSpec.EmptyTypes; @@ -415,6 +663,9 @@ namespace Mono.CSharp return new InflatedTypeSpec (inflator.Context, this, inflator.TypeInstance, targs); } + // + // Inflates current type using specific type arguments + // public InflatedTypeSpec MakeGenericType (IModuleContext context, TypeSpec[] targs) { if (targs.Length == 0 && !IsNested) @@ -485,6 +736,18 @@ namespace Mono.CSharp } } + if (MemberDefinition.TypeParametersCount > 0) { + foreach (var tp in MemberDefinition.TypeParameters) { + var tp_missing = tp.GetMissingDependencies (); + if (tp_missing != null) { + if (missing == null) + missing = new List (); + + missing.AddRange (tp_missing); + } + } + } + if (missing != null || BaseType == null) return missing; @@ -505,7 +768,11 @@ namespace Mono.CSharp } } - public sealed class BuildinTypeSpec : TypeSpec + // + // Special version used for types which must exist in corlib or + // the compiler cannot work + // + public sealed class BuiltinTypeSpec : TypeSpec { public enum Type { @@ -548,24 +815,22 @@ namespace Mono.CSharp Exception, Attribute, Other, - - Null, } readonly Type type; readonly string ns; readonly string name; - public BuildinTypeSpec (MemberKind kind, string ns, string name, Type buildinKind) + public BuiltinTypeSpec (MemberKind kind, string ns, string name, Type builtinKind) : base (kind, null, null, null, Modifiers.PUBLIC) { - this.type = buildinKind; + this.type = builtinKind; this.ns = ns; this.name = name; } - public BuildinTypeSpec (string name, Type buildinKind) - : this (MemberKind.InternalCompilerType, "", name, buildinKind) + public BuiltinTypeSpec (string name, Type builtinKind) + : this (MemberKind.InternalCompilerType, "", name, builtinKind) { // Make all internal types CLS-compliant, non-obsolete, compact state = (state & ~(StateFlags.CLSCompliant_Undetected | StateFlags.Obsolete_Undetected | StateFlags.MissingDependency_Undetected)) | StateFlags.CLSCompliant; @@ -579,7 +844,7 @@ namespace Mono.CSharp } } - public override BuildinTypeSpec.Type BuildinType { + public override BuiltinTypeSpec.Type BuiltinType { get { return type; } @@ -607,12 +872,12 @@ namespace Mono.CSharp public static bool IsPrimitiveType (TypeSpec type) { - return type.BuildinType >= Type.FirstPrimitive && type.BuildinType <= Type.LastPrimitive; + return type.BuiltinType >= Type.FirstPrimitive && type.BuiltinType <= Type.LastPrimitive; } public static bool IsPrimitiveTypeOrDecimal (TypeSpec type) { - return type.BuildinType >= Type.FirstPrimitive && type.BuildinType <= Type.Decimal; + return type.BuiltinType >= Type.FirstPrimitive && type.BuiltinType <= Type.Decimal; } public override string GetSignatureForError () @@ -647,7 +912,7 @@ namespace Mono.CSharp // public static int GetSize (TypeSpec type) { - switch (type.BuildinType) { + switch (type.BuiltinType) { case Type.Int: case Type.UInt: case Type.Float: @@ -688,6 +953,9 @@ namespace Mono.CSharp } } + // + // Various type comparers used by compiler + // static class TypeSpecComparer { // @@ -769,8 +1037,8 @@ namespace Mono.CSharp return ac_b != null && ac_a.Rank == ac_b.Rank && IsEqual (ac_a.Element, ac_b.Element); } - if (a == InternalType.Dynamic || b == InternalType.Dynamic) - return b.BuildinType == BuildinTypeSpec.Type.Object || a.BuildinType == BuildinTypeSpec.Type.Object; + if (a.BuiltinType == BuiltinTypeSpec.Type.Dynamic || b.BuiltinType == BuiltinTypeSpec.Type.Dynamic) + return b.BuiltinType == BuiltinTypeSpec.Type.Object || a.BuiltinType == BuiltinTypeSpec.Type.Object; if (a.MemberDefinition != b.MemberDefinition) return false; @@ -788,6 +1056,23 @@ namespace Mono.CSharp return true; } + public static bool IsEqual (TypeSpec[] a, TypeSpec[] b) + { + if (a == b) + return true; + + if (a.Length != b.Length) + return false; + + for (int i = 0; i < a.Length; ++i) { + if (!IsEqual (a[i], b[i])) + return false; + } + + return true; + } + + // // Compares unordered arrays // @@ -827,8 +1112,7 @@ namespace Mono.CSharp if (!IsEqual (a.Types[i], b.Types[i])) return false; - const Parameter.Modifier ref_out = Parameter.Modifier.REF | Parameter.Modifier.OUT; - if ((a.FixedParameters[i].ModFlags & ref_out) != (b.FixedParameters[i].ModFlags & ref_out)) + if ((a.FixedParameters[i].ModFlags & Parameter.Modifier.RefOutMask) != (b.FixedParameters[i].ModFlags & Parameter.Modifier.RefOutMask)) return false; } @@ -859,17 +1143,18 @@ namespace Mono.CSharp } for (int i = 0; i < targs_definition.Length; ++i) { + if (TypeSpecComparer.IsEqual (t1_targs[i], t2_targs[i])) + continue; + Variance v = targs_definition[i].Variance; if (v == Variance.None) { - if (t1_targs[i] == t2_targs[i]) - continue; return false; } if (v == Variance.Covariant) { - if (!Convert.ImplicitReferenceConversionExists (new EmptyExpression (t1_targs[i]), t2_targs[i])) + if (!Convert.ImplicitReferenceConversionExists (t1_targs[i], t2_targs[i])) return false; - } else if (!Convert.ImplicitReferenceConversionExists (new EmptyExpression (t2_targs[i]), t1_targs[i])) { + } else if (!Convert.ImplicitReferenceConversionExists (t2_targs[i], t1_targs[i])) { return false; } } @@ -889,8 +1174,17 @@ namespace Mono.CSharp // public static bool IsEqual (TypeSpec a, TypeSpec b) { - if (a.MemberDefinition != b.MemberDefinition) + if (a.MemberDefinition != b.MemberDefinition) { + var base_ifaces = a.Interfaces; + if (base_ifaces != null) { + foreach (var base_iface in base_ifaces) { + if (base_iface.Arity > 0 && IsEqual (base_iface, b)) + return true; + } + } + return false; + } var ta = a.TypeArguments; var tb = b.TypeArguments; @@ -938,7 +1232,7 @@ namespace Mono.CSharp // class X : I, I // if (b.IsGenericParameter) - return a.DeclaringType == b.DeclaringType; + return a != b && a.DeclaringType == b.DeclaringType; // // We're now comparing a type parameter with a @@ -1013,18 +1307,10 @@ namespace Mono.CSharp { if (a == b) { // This also rejects dynamic == dynamic - return a.Kind != MemberKind.InternalCompilerType || a == InternalType.Dynamic; + return a.Kind != MemberKind.InternalCompilerType || a.BuiltinType == BuiltinTypeSpec.Type.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.BuildinType == BuildinTypeSpec.Type.Object || a.BuildinType == BuildinTypeSpec.Type.Object; - - if (a == null) + if (a == null || b == null) return false; if (a.IsArray) { @@ -1033,11 +1319,20 @@ namespace Mono.CSharp if (b_a == null) return false; - return IsEqual (a_a.Element, b_a.Element) && a_a.Rank == b_a.Rank; + return a_a.Rank == b_a.Rank && IsEqual (a_a.Element, b_a.Element); } - if (!a.IsGeneric || b == null || !b.IsGeneric) + if (!a.IsGeneric || !b.IsGeneric) { + // + // 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.BuiltinType == BuiltinTypeSpec.Type.Dynamic || b.BuiltinType == BuiltinTypeSpec.Type.Dynamic) + return b.BuiltinType == BuiltinTypeSpec.Type.Object || a.BuiltinType == BuiltinTypeSpec.Type.Object; + return false; + } if (a.MemberDefinition != b.MemberDefinition) return false; @@ -1058,6 +1353,9 @@ namespace Mono.CSharp { IAssemblyDefinition DeclaringAssembly { get; } string Namespace { get; } + bool IsPartial { get; } + bool IsComImport { get; } + bool IsTypeForwarder { get; } int TypeParametersCount { get; } TypeParameterSpec[] TypeParameters { get; } @@ -1072,19 +1370,14 @@ namespace Mono.CSharp { 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 NullLiteral = new InternalType ("null"); public static readonly InternalType FakeInternalType = new InternalType (""); + public static readonly InternalType Namespace = new InternalType (""); + public static readonly InternalType ErrorType = new InternalType (""); readonly string name; - InternalType (string name, MemberCache cache) - : this (name) - { - this.cache = cache; - } - InternalType (string name) : base (MemberKind.InternalCompilerType, null, null, null, Modifiers.PUBLIC) { @@ -1093,7 +1386,7 @@ namespace Mono.CSharp cache = MemberCache.Empty; // Make all internal types CLS-compliant, non-obsolete - state = (state & ~(StateFlags.CLSCompliant_Undetected | StateFlags.Obsolete_Undetected)) | StateFlags.CLSCompliant; + state = (state & ~(StateFlags.CLSCompliant_Undetected | StateFlags.Obsolete_Undetected | StateFlags.MissingDependency_Undetected)) | StateFlags.CLSCompliant; } #region Properties @@ -1110,12 +1403,30 @@ namespace Mono.CSharp } } + bool ITypeDefinition.IsComImport { + get { + return false; + } + } + bool IMemberDefinition.IsImported { get { return false; } } + bool ITypeDefinition.IsPartial { + get { + return false; + } + } + + bool ITypeDefinition.IsTypeForwarder { + get { + return false; + } + } + public override string Name { get { return name; @@ -1201,6 +1512,9 @@ namespace Mono.CSharp #endregion } + // + // Common base class for composite types + // public abstract class ElementTypeSpec : TypeSpec, ITypeDefinition { protected ElementTypeSpec (MemberKind kind, TypeSpec element, MetaType info) @@ -1208,13 +1522,10 @@ namespace Mono.CSharp { 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); + state &= ~SharedStateFlags; + state |= (element.state & SharedStateFlags); - if (element == InternalType.Dynamic) + if (element.BuiltinType == BuiltinTypeSpec.Type.Dynamic) state |= StateFlags.HasDynamicElement; // Has to use its own type definition instead of just element definition to @@ -1228,6 +1539,24 @@ namespace Mono.CSharp public TypeSpec Element { get; private set; } + bool ITypeDefinition.IsComImport { + get { + return false; + } + } + + bool ITypeDefinition.IsPartial { + get { + return false; + } + } + + bool ITypeDefinition.IsTypeForwarder { + get { + return false; + } + } + public override string Name { get { throw new NotSupportedException (); @@ -1246,6 +1575,11 @@ namespace Mono.CSharp return null; } + public override string GetSignatureForDocumentation () + { + return Element.GetSignatureForDocumentation () + GetPostfixSignature (); + } + public override string GetSignatureForError () { return Element.GetSignatureForError () + GetPostfixSignature (); @@ -1387,7 +1721,7 @@ namespace Mono.CSharp var arg_types = new MetaType[rank]; for (int i = 0; i < rank; i++) - arg_types[i] = module.Compiler.BuildinTypes.Int.GetMetaInfo (); + arg_types[i] = module.Compiler.BuiltinTypes.Int.GetMetaInfo (); var ctor = mb.GetArrayMethod ( GetMetaInfo (), Constructor.ConstructorName, @@ -1403,12 +1737,12 @@ namespace Mono.CSharp var arg_types = new MetaType[rank]; for (int i = 0; i < rank; i++) - arg_types[i] = module.Compiler.BuildinTypes.Int.GetMetaInfo (); + arg_types[i] = module.Compiler.BuiltinTypes.Int.GetMetaInfo (); var address = mb.GetArrayMethod ( GetMetaInfo (), "Address", CallingConventions.HasThis | CallingConventions.Standard, - ReferenceContainer.MakeType (Element).GetMetaInfo (), arg_types); + ReferenceContainer.MakeType (module, Element).GetMetaInfo (), arg_types); return address; } @@ -1419,7 +1753,7 @@ namespace Mono.CSharp var arg_types = new MetaType[rank]; for (int i = 0; i < rank; i++) - arg_types[i] = module.Compiler.BuildinTypes.Int.GetMetaInfo (); + arg_types[i] = module.Compiler.BuiltinTypes.Int.GetMetaInfo (); var get = mb.GetArrayMethod ( GetMetaInfo (), "Get", @@ -1435,14 +1769,14 @@ namespace Mono.CSharp var arg_types = new MetaType[rank + 1]; for (int i = 0; i < rank; i++) - arg_types[i] = module.Compiler.BuildinTypes.Int.GetMetaInfo (); + arg_types[i] = module.Compiler.BuiltinTypes.Int.GetMetaInfo (); arg_types[rank] = Element.GetMetaInfo (); var set = mb.GetArrayMethod ( GetMetaInfo (), "Set", CallingConventions.HasThis | CallingConventions.Standard, - module.Compiler.BuildinTypes.Void.GetMetaInfo (), arg_types); + module.Compiler.BuiltinTypes.Void.GetMetaInfo (), arg_types); return set; } @@ -1476,6 +1810,31 @@ namespace Mono.CSharp return sb.ToString (); } + public override string GetSignatureForDocumentation () + { + StringBuilder sb = new StringBuilder (); + GetElementSignatureForDocumentation (sb); + return sb.ToString (); + } + + void GetElementSignatureForDocumentation (StringBuilder sb) + { + var ac = Element as ArrayContainer; + if (ac == null) + sb.Append (Element.GetSignatureForDocumentation ()); + else + ac.GetElementSignatureForDocumentation (sb); + + sb.Append ("["); + for (int i = 1; i < rank; i++) { + if (i == 1) + sb.Append ("0:"); + + sb.Append (",0:"); + } + sb.Append ("]"); + } + public static ArrayContainer MakeType (ModuleContainer module, TypeSpec element) { return MakeType (module, element, 1); @@ -1485,12 +1844,12 @@ namespace Mono.CSharp { ArrayContainer ac; var key = new TypeRankPair (element, rank); - if (!module.ArraysCache.TryGetValue (key, out ac)) { + if (!module.ArrayTypesCache.TryGetValue (key, out ac)) { ac = new ArrayContainer (module, element, rank) { - BaseType = module.Compiler.BuildinTypes.Array + BaseType = module.Compiler.BuiltinTypes.Array }; - module.ArraysCache.Add (key, ac); + module.ArrayTypesCache.Add (key, ac); } return ac; @@ -1499,8 +1858,6 @@ namespace Mono.CSharp class ReferenceContainer : ElementTypeSpec { - static Dictionary instances = new Dictionary (); - private ReferenceContainer (TypeSpec element) : base (MemberKind.Class, element, null) // TODO: Kind.Class is most likely wrong { @@ -1515,27 +1872,20 @@ namespace Mono.CSharp return info; } - public static ReferenceContainer MakeType (TypeSpec element) + public static ReferenceContainer MakeType (ModuleContainer module, TypeSpec element) { ReferenceContainer pc; - if (!instances.TryGetValue (element, out pc)) { + if (!module.ReferenceTypesCache.TryGetValue (element, out pc)) { pc = new ReferenceContainer (element); - instances.Add (element, pc); + module.ReferenceTypesCache.Add (element, pc); } return pc; } - - public static void Reset () - { - instances = new Dictionary (); - } } class PointerContainer : ElementTypeSpec { - static Dictionary instances = new Dictionary (); - private PointerContainer (TypeSpec element) : base (MemberKind.PointerType, element, null) { @@ -1557,20 +1907,15 @@ namespace Mono.CSharp return "*"; } - public static PointerContainer MakeType (TypeSpec element) + public static PointerContainer MakeType (ModuleContainer module, TypeSpec element) { PointerContainer pc; - if (!instances.TryGetValue (element, out pc)) { + if (!module.PointerTypesCache.TryGetValue (element, out pc)) { pc = new PointerContainer (element); - instances.Add (element, pc); + module.PointerTypesCache.Add (element, pc); } return pc; } - - public static void Reset () - { - instances = new Dictionary (); - } } }