X-Git-Url: http://wien.tomnetworks.com/gitweb/?a=blobdiff_plain;f=mcs%2Fmcs%2Ftypespec.cs;h=7ed97604a0f209ab5db2269ec37d8641e858fc8a;hb=fb0fdcd98cff272b06f7df7911cb694cc740d1ce;hp=99b8919ef35cf9b80dce99873fa3e795334da6e1;hpb=2c810c3ed9592c43ab0734b78e49cd206641e9fe;p=mono.git diff --git a/mcs/mcs/typespec.cs b/mcs/mcs/typespec.cs index 99b8919ef35..7ed97604a0f 100644 --- a/mcs/mcs/typespec.cs +++ b/mcs/mcs/typespec.cs @@ -6,18 +6,26 @@ // 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; 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 ifaces; TypeSpec base_type; @@ -26,9 +34,10 @@ namespace Mono.CSharp 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 () { @@ -38,8 +47,9 @@ namespace Mono.CSharp 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; @@ -66,6 +76,12 @@ namespace Mono.CSharp } } + public virtual BuiltinTypeSpec.Type BuiltinType { + get { + return BuiltinTypeSpec.Type.None; + } + } + public bool HasDynamicElement { get { return (state & StateFlags.HasDynamicElement) != 0; @@ -94,11 +110,11 @@ namespace Mono.CSharp var type = this; do { + if (type.BuiltinType == BuiltinTypeSpec.Type.Attribute) + return true; + if (type.IsGeneric) return false; - - if (type == TypeManager.attribute_type) - return true; type = type.base_type; } while (type != null); @@ -124,7 +140,25 @@ namespace Mono.CSharp 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; + 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; + } + + return false; } } @@ -134,8 +168,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 @@ -155,7 +227,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 { @@ -172,6 +258,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; @@ -180,8 +275,34 @@ namespace Mono.CSharp public bool IsTypeBuilder { get { +#if STATIC + return true; +#else var meta = GetMetaInfo().GetType (); return meta == TypeBuilder || meta == GenericTypeBuilder; +#endif + } + } + + // + // 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); } } @@ -241,6 +362,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) @@ -262,7 +435,7 @@ namespace Mono.CSharp return aua; } - public virtual Type GetMetaInfo () + public virtual MetaType GetMetaInfo () { return info; } @@ -272,6 +445,65 @@ namespace Mono.CSharp return this; } + 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; @@ -290,6 +522,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) @@ -302,16 +539,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); @@ -320,7 +559,11 @@ namespace Mono.CSharp protected virtual void InitializeMemberCache (bool onlyTypes) { - MemberDefinition.LoadMembers (this, onlyTypes, ref cache); + try { + MemberDefinition.LoadMembers (this, onlyTypes, ref cache); + } catch (Exception e) { + throw new InternalErrorException (e, "Unexpected error when loading type `{0}'", GetSignatureForError ()); + } if (onlyTypes) state |= StateFlags.PendingMemberCacheMembers; @@ -341,10 +584,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; @@ -359,6 +604,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; @@ -367,28 +644,42 @@ namespace Mono.CSharp // 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) - return MakeGenericType (targs); + if (DeclaringType == inflator.TypeInstance) { + return MakeGenericType (inflator.Context, targs); + } - return new InflatedTypeSpec (this, inflator.TypeInstance, targs); + return new InflatedTypeSpec (inflator.Context, this, inflator.TypeInstance, targs); } - public InflatedTypeSpec MakeGenericType (TypeSpec[] targs) + public InflatedTypeSpec MakeGenericType (IModuleContext context, TypeSpec[] targs) { if (targs.Length == 0 && !IsNested) throw new ArgumentException ("Empty type arguments for type " + GetSignatureForError ()); InflatedTypeSpec instance; - if (inflated_instances == null) + if (inflated_instances == null) { inflated_instances = new Dictionary (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 ("`{0}' must be type definition or nested non-inflated type to MakeGenericType", GetSignatureForError ()); - instance = new InflatedTypeSpec (this, declaringType, targs); + instance = new InflatedTypeSpec (context, this, declaringType, targs); inflated_instances.Add (targs, instance); } @@ -400,7 +691,43 @@ namespace Mono.CSharp return this; } - public void SetMetaInfo (Type info) + public override List ResolveMissingDependencies () + { + List missing = null; + + if (Kind == MemberKind.MissingType) { + missing = new List (); + missing.Add (this); + return missing; + } + + foreach (var targ in TypeArguments) { + if (targ.Kind == MemberKind.MissingType) { + if (missing == null) + missing = new List (); + + missing.Add (targ); + } + } + + if (Interfaces != null) { + foreach (var iface in Interfaces) { + if (iface.Kind == MemberKind.MissingType) { + if (missing == null) + missing = new List (); + + 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"); @@ -414,19 +741,68 @@ namespace Mono.CSharp } } - public class PredefinedTypeSpec : TypeSpec + public sealed class BuiltinTypeSpec : TypeSpec { - string name; - string ns; + public enum Type + { + None = 0, + + // Ordered carefully for fast compares + FirstPrimitive = 1, + Bool = 1, + Byte = 2, + SByte = 3, + Char = 4, + Short = 5, + UShort = 6, + Int = 7, + UInt = 8, + Long = 9, + ULong = 10, + Float = 11, + Double = 12, + LastPrimitive = 12, + Decimal = 13, + + IntPtr = 14, + UIntPtr = 15, + + Object = 16, + Dynamic = 17, + String = 18, + Type = 19, + + ValueType = 20, + Enum = 21, + Delegate = 22, + MulticastDelegate = 23, + Array = 24, + + IEnumerator, + IEnumerable, + IDisposable, + Exception, + Attribute, + Other, + } + + readonly Type type; + readonly string ns; + readonly string name; - public PredefinedTypeSpec (MemberKind kind, string ns, string name) + public BuiltinTypeSpec (MemberKind kind, string ns, string name, Type builtinKind) : base (kind, null, null, null, Modifiers.PUBLIC) { - if (kind == MemberKind.Struct) - modifiers |= Modifiers.SEALED; - - this.name = name; + this.type = builtinKind; this.ns = ns; + this.name = name; + } + + 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; } #region Properties @@ -437,6 +813,18 @@ namespace Mono.CSharp } } + public override BuiltinTypeSpec.Type BuiltinType { + get { + return type; + } + } + + public string FullName { + get { + return ns + '.' + name; + } + } + public override string Name { get { return name; @@ -451,9 +839,19 @@ namespace Mono.CSharp #endregion + public static bool IsPrimitiveType (TypeSpec type) + { + return type.BuiltinType >= Type.FirstPrimitive && type.BuiltinType <= Type.LastPrimitive; + } + + public static bool IsPrimitiveTypeOrDecimal (TypeSpec type) + { + return type.BuiltinType >= Type.FirstPrimitive && type.BuiltinType <= Type.Decimal; + } + public override string GetSignatureForError () { - switch (name) { + switch (Name) { case "Int32": return "int"; case "Int64": return "long"; case "String": return "string"; @@ -472,13 +870,46 @@ namespace Mono.CSharp case "SByte": return "sbyte"; } - return ns + "." + name; + if (ns.Length == 0) + return name; + + return FullName; + } + + // + // Returns the size of type if known, otherwise, 0 + // + public static int GetSize (TypeSpec type) + { + switch (type.BuiltinType) { + case Type.Int: + case Type.UInt: + case Type.Float: + return 4; + case Type.Long: + case Type.ULong: + case Type.Double: + return 8; + case Type.Byte: + case Type.SByte: + case Type.Bool: + return 1; + case Type.Short: + case Type.Char: + case Type.UShort: + return 2; + case Type.Decimal: + return 16; + default: + return 0; + } } - 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) @@ -487,6 +918,7 @@ namespace Mono.CSharp this.info = ts.GetMetaInfo (); this.BaseType = ts.BaseType; this.Interfaces = ts.Interfaces; + this.modifiers = ts.Modifiers; } } @@ -565,31 +997,29 @@ namespace Mono.CSharp 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; + var ac_a = a as ArrayContainer; + if (ac_a != null) { + var ac_b = b as ArrayContainer; + return ac_b != null && ac_a.Rank == ac_b.Rank && IsEqual (ac_a.Element, ac_b.Element); + } - if (a.TypeArguments.Length != 0) { - if (a.MemberDefinition != b.MemberDefinition) - return false; + 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; + do { 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; - 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 == TypeManager.object_type || a == TypeManager.object_type; + a = a.DeclaringType; + b = b.DeclaringType; + } while (a != null); - return false; + return true; } // @@ -663,17 +1093,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; } } @@ -693,8 +1124,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; @@ -742,7 +1182,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 @@ -817,18 +1257,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 == TypeManager.object_type || a == TypeManager.object_type; - - if (a == null) + if (a == null || b == null) return false; if (a.IsArray) { @@ -837,11 +1269,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; @@ -860,6 +1301,7 @@ namespace Mono.CSharp public interface ITypeDefinition : IMemberDefinition { + IAssemblyDefinition DeclaringAssembly { get; } string Namespace { get; } int TypeParametersCount { get; } TypeParameterSpec[] TypeParameters { get; } @@ -867,6 +1309,7 @@ namespace Mono.CSharp TypeSpec GetAttributeCoClass (); string GetAttributeDefaultMember (); AttributeUsageAttribute GetAttributeUsage (PredefinedAttribute pa); + bool IsInternalAsPublic (IAssemblyDefinition assembly); void LoadMembers (TypeSpec declaringType, bool onlyTypes, ref MemberCache cache); } @@ -874,10 +1317,11 @@ namespace Mono.CSharp { public static readonly InternalType AnonymousMethod = new InternalType ("anonymous method"); public static readonly InternalType Arglist = new InternalType ("__arglist"); - public static readonly InternalType Dynamic = new InternalType ("dynamic", null); public static readonly InternalType MethodGroup = new InternalType ("method group"); - public static readonly InternalType Null = new InternalType ("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; @@ -906,7 +1350,7 @@ namespace Mono.CSharp } } - System.Reflection.Assembly IMemberDefinition.Assembly { + IAssemblyDefinition ITypeDefinition.DeclaringAssembly { get { throw new NotImplementedException (); } @@ -966,6 +1410,11 @@ namespace Mono.CSharp return null; } + bool ITypeDefinition.IsInternalAsPublic (IAssemblyDefinition assembly) + { + throw new NotImplementedException (); + } + void ITypeDefinition.LoadMembers (TypeSpec declaringType, bool onlyTypes, ref MemberCache cache) { throw new NotImplementedException (); @@ -981,9 +1430,10 @@ namespace Mono.CSharp return null; } - bool IMemberDefinition.IsNotCLSCompliant () - { - return false; + bool? IMemberDefinition.CLSAttributeValue { + get { + return null; + } } void IMemberDefinition.SetIsAssigned () @@ -999,11 +1449,18 @@ namespace Mono.CSharp public abstract class ElementTypeSpec : TypeSpec, ITypeDefinition { - protected ElementTypeSpec (MemberKind kind, TypeSpec element, Type info) + protected ElementTypeSpec (MemberKind kind, TypeSpec element, MetaType info) : base (kind, element.DeclaringType, null, info, element.Modifiers) { this.Element = element; - if (element == InternalType.Dynamic || element.HasDynamicElement) + + // 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.BuiltinType == BuiltinTypeSpec.Type.Dynamic) state |= StateFlags.HasDynamicElement; // Has to use its own type definition instead of just element definition to @@ -1035,6 +1492,11 @@ namespace Mono.CSharp return null; } + public override string GetSignatureForDocumentation () + { + return Element.GetSignatureForDocumentation () + GetPostfixSignature (); + } + public override string GetSignatureForError () { return Element.GetSignatureForError () + GetPostfixSignature (); @@ -1054,12 +1516,17 @@ namespace Mono.CSharp #region ITypeDefinition Members - System.Reflection.Assembly IMemberDefinition.Assembly { + IAssemblyDefinition ITypeDefinition.DeclaringAssembly { get { - return Element.Assembly; + return Element.MemberDefinition.DeclaringAssembly; } } + bool ITypeDefinition.IsInternalAsPublic (IAssemblyDefinition assembly) + { + return Element.MemberDefinition.IsInternalAsPublic (assembly); + } + public string Namespace { get { throw new NotImplementedException (); } } @@ -1102,9 +1569,10 @@ namespace Mono.CSharp return Element.MemberDefinition.ConditionalConditions (); } - bool IMemberDefinition.IsNotCLSCompliant () - { - return Element.MemberDefinition.IsNotCLSCompliant (); + bool? IMemberDefinition.CLSAttributeValue { + get { + return Element.MemberDefinition.CLSAttributeValue; + } } public void SetIsAssigned () @@ -1122,7 +1590,7 @@ namespace Mono.CSharp public class ArrayContainer : ElementTypeSpec { - struct TypeRankPair : IEquatable + public struct TypeRankPair : IEquatable { TypeSpec ts; int rank; @@ -1149,11 +1617,12 @@ namespace Mono.CSharp } readonly int rank; - static Dictionary instances = new Dictionary (); + readonly ModuleContainer module; - private ArrayContainer (TypeSpec element, int rank) + private ArrayContainer (ModuleContainer module, TypeSpec element, int rank) : base (MemberKind.ArrayType, element, null) { + this.module = module; this.rank = rank; } @@ -1163,73 +1632,73 @@ namespace Mono.CSharp } } - public System.Reflection.MethodInfo GetConstructor () + public MethodInfo GetConstructor () { - var mb = RootContext.ToplevelTypes.Builder; + var mb = module.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 (); + arg_types[i] = module.Compiler.BuiltinTypes.Int.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 mb = module.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 (); + arg_types[i] = module.Compiler.BuiltinTypes.Int.GetMetaInfo (); var address = mb.GetArrayMethod ( GetMetaInfo (), "Address", - System.Reflection.CallingConventions.HasThis | System.Reflection.CallingConventions.Standard, - ReferenceContainer.MakeType (Element).GetMetaInfo (), arg_types); + CallingConventions.HasThis | CallingConventions.Standard, + ReferenceContainer.MakeType (module, Element).GetMetaInfo (), arg_types); return address; } - public System.Reflection.MethodInfo GetGetMethod () + public MethodInfo GetGetMethod () { - var mb = RootContext.ToplevelTypes.Builder; + var mb = module.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 (); + arg_types[i] = module.Compiler.BuiltinTypes.Int.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 mb = module.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 (); + arg_types[i] = module.Compiler.BuiltinTypes.Int.GetMetaInfo (); arg_types[rank] = Element.GetMetaInfo (); var set = mb.GetArrayMethod ( GetMetaInfo (), "Set", - System.Reflection.CallingConventions.HasThis | System.Reflection.CallingConventions.Standard, - TypeManager.void_type.GetMetaInfo (), arg_types); + CallingConventions.HasThis | CallingConventions.Standard, + module.Compiler.BuiltinTypes.Void.GetMetaInfo (), arg_types); return set; } - public override Type GetMetaInfo () + public override MetaType GetMetaInfo () { if (info == null) { if (rank == 1) @@ -1258,42 +1727,60 @@ namespace Mono.CSharp return sb.ToString (); } - public static ArrayContainer MakeType (TypeSpec element) + 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 (element, 1); + return MakeType (module, element, 1); } - public static ArrayContainer MakeType (TypeSpec element, int rank) + public static ArrayContainer MakeType (ModuleContainer module, TypeSpec element, int rank) { ArrayContainer ac; var key = new TypeRankPair (element, rank); - if (!instances.TryGetValue (key, out ac)) { - ac = new ArrayContainer (element, rank) { - BaseType = TypeManager.array_type + if (!module.ArrayTypesCache.TryGetValue (key, out ac)) { + ac = new ArrayContainer (module, element, rank) { + BaseType = module.Compiler.BuiltinTypes.Array }; - instances.Add (key, ac); + module.ArrayTypesCache.Add (key, ac); } return ac; } - - public static void Reset () - { - instances = new Dictionary (); - } } class ReferenceContainer : ElementTypeSpec { - static Dictionary instances = new Dictionary (); - private ReferenceContainer (TypeSpec element) : base (MemberKind.Class, element, null) // TODO: Kind.Class is most likely wrong { } - public override Type GetMetaInfo () + public override MetaType GetMetaInfo () { if (info == null) { info = Element.GetMetaInfo ().MakeByRefType (); @@ -1302,27 +1789,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) { @@ -1330,7 +1810,7 @@ namespace Mono.CSharp state &= ~StateFlags.CLSCompliant_Undetected; } - public override Type GetMetaInfo () + public override MetaType GetMetaInfo () { if (info == null) { info = Element.GetMetaInfo ().MakePointerType (); @@ -1344,20 +1824,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 (); - } } }