X-Git-Url: http://wien.tomnetworks.com/gitweb/?a=blobdiff_plain;f=mcs%2Fmcs%2Ftypespec.cs;h=22278a08dacd4806887da44e02ad0cfb9f93184e;hb=9f075fd34a9d9afcc6a4d2fdef6bd8b4200e3a7a;hp=2a4b8a06bad466ffe48cbad1d1739a31263082b3;hpb=9ea478b7f796f8b3afc461afbe844b232052915c;p=mono.git diff --git a/mcs/mcs/typespec.cs b/mcs/mcs/typespec.cs index 2a4b8a06bad..22278a08dac 100644 --- a/mcs/mcs/typespec.cs +++ b/mcs/mcs/typespec.cs @@ -76,7 +76,9 @@ namespace Mono.CSharp } public bool IsArray { - get { return this is ArrayContainer; } + get { + return Kind == MemberKind.ArrayType; + } } public bool IsAttribute { @@ -113,7 +115,7 @@ namespace Mono.CSharp 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; @@ -238,8 +240,17 @@ namespace Mono.CSharp if (!pa.IsDefined) return Attribute.DefaultUsageAttribute; - var aua = MemberDefinition.GetAttributeUsage (pa); - return aua ?? Attribute.DefaultUsageAttribute; + AttributeUsageAttribute aua = null; + var type = this; + while (type != null) { + aua = type.MemberDefinition.GetAttributeUsage (pa); + if (aua != null) + break; + + type = type.BaseType; + } + + return aua; } public virtual Type GetMetaInfo () @@ -606,12 +617,23 @@ namespace Mono.CSharp 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) { + // + // Internal compiler variance between G and G + // + for (int i = 0; i < targs_definition.Length; ++i) { + if ((t1_targs[i] != TypeManager.object_type && t1_targs[i] != InternalType.Dynamic) || + (t2_targs[i] != TypeManager.object_type && t2_targs[i] != InternalType.Dynamic)) + return false; + } + + return true; + } + for (int i = 0; i < targs_definition.Length; ++i) { Variance v = targs_definition[i].Variance; if (v == Variance.None) { @@ -656,6 +678,20 @@ namespace Mono.CSharp 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; + } + /// /// Check whether `a' and `b' may become equal generic types. /// The algorithm to do that is a little bit complicated. @@ -693,13 +729,7 @@ namespace Mono.CSharp // class X : I, I> -> 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) @@ -781,18 +811,35 @@ namespace Mono.CSharp state = (state & ~(StateFlags.CLSCompliant_Undetected | StateFlags.Obsolete_Undetected)) | StateFlags.CLSCompliant; } + public override int Arity { + get { + return 0; + } + } + + public override string Name { + get { + return name; + } + } + public override string GetSignatureForError () { return name; } } - 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) + : base (kind, element.DeclaringType, null, info, element.Modifiers) { this.Element = element; + + // 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; } @@ -834,15 +881,108 @@ namespace Mono.CSharp mutated.info = null; return mutated; } + + #region ITypeDefinition Members + + System.Reflection.Assembly IMemberDefinition.Assembly { + get { + return Element.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 MemberCache LoadMembers (TypeSpec declaringType) + { + return Element.MemberDefinition.LoadMembers (declaringType); + } + + public bool IsImported { + get { + return Element.MemberDefinition.IsImported; + } + } + + public string[] ConditionalConditions () + { + return Element.MemberDefinition.ConditionalConditions (); + } + + bool IMemberDefinition.IsNotCLSCompliant () + { + return Element.MemberDefinition.IsNotCLSCompliant (); + } + + public void SetIsAssigned () + { + Element.MemberDefinition.SetIsAssigned (); + } + + public void SetIsUsed () + { + Element.MemberDefinition.SetIsUsed (); + } + + #endregion } public class ArrayContainer : ElementTypeSpec { + struct TypeRankPair : IEquatable + { + 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> Members + + public bool Equals (TypeRankPair other) + { + return other.ts == ts && other.rank == rank; + } + + #endregion + } + readonly int rank; - static Dictionary, ArrayContainer> instances = new Dictionary, ArrayContainer> (); + static Dictionary instances = new Dictionary (); private ArrayContainer (TypeSpec element, int rank) - : base (MemberKind.Class, element, null) + : base (MemberKind.ArrayType, element, null) { this.rank = rank; } @@ -869,6 +1009,22 @@ namespace Mono.CSharp return ctor; } + public System.Reflection.MethodInfo GetAddressMethod () + { + var mb = RootContext.ToplevelTypes.Builder; + + var arg_types = new Type[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, + ReferenceContainer.MakeType (Element).GetMetaInfo (), arg_types); + + return address; + } + public System.Reflection.MethodInfo GetGetMethod () { var mb = RootContext.ToplevelTypes.Builder; @@ -916,6 +1072,11 @@ namespace Mono.CSharp } protected override string GetPostfixSignature() + { + return GetPostfixSignature (rank); + } + + public static string GetPostfixSignature (int rank) { StringBuilder sb = new StringBuilder (); sb.Append ("["); @@ -935,7 +1096,7 @@ namespace Mono.CSharp 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 @@ -949,7 +1110,7 @@ namespace Mono.CSharp public static void Reset () { - instances = new Dictionary, ArrayContainer> (); + instances = new Dictionary (); } }