X-Git-Url: http://wien.tomnetworks.com/gitweb/?a=blobdiff_plain;f=mcs%2Fmcs%2Fgeneric.cs;h=625cd0c773f0588fefcd0b3055c1ddbc20d0e44a;hb=34866ac4c20c781f10c40fe6f6fe0c39733fd946;hp=556a08b85241204a64a96bc55d4a65460576f6c9;hpb=c1d81649cc1d16ee47bd6fb951e220d8aba6a1d0;p=mono.git diff --git a/mcs/mcs/generic.cs b/mcs/mcs/generic.cs index 556a08b8524..625cd0c773f 100644 --- a/mcs/mcs/generic.cs +++ b/mcs/mcs/generic.cs @@ -428,13 +428,13 @@ namespace Mono.CSharp { public TypeParameter (TypeParameterSpec spec, TypeSpec parentSpec, MemberName name, Attributes attrs) : base (null, name, attrs) { - this.spec = new TypeParameterSpec (parentSpec, spec.DeclaredPosition, spec.MemberDefinition, spec.SpecialConstraint, spec.Variance, null) { + this.spec = new TypeParameterSpec (parentSpec, spec.DeclaredPosition, this, spec.SpecialConstraint, spec.Variance, null) { BaseType = spec.BaseType, InterfacesDefined = spec.InterfacesDefined, TypeArguments = spec.TypeArguments }; } - + #region Properties public override AttributeTargets AttributeTargets { @@ -773,6 +773,7 @@ namespace Mono.CSharp { TypeSpec[] targs; TypeSpec[] ifaces_defined; TypeSpec effective_base; + MemberCache interface_cache; // // Creates type owned type parameter @@ -882,6 +883,12 @@ namespace Mono.CSharp { } } + public MemberCache InterfaceCache { + get { + return interface_cache; + } + } + // // Unexpanded interfaces list // @@ -1351,13 +1358,27 @@ namespace Mono.CSharp { // For a type parameter the membercache is the union of the sets of members of the types // specified as a primary constraint or secondary constraint // + bool has_user_base_type = false; if (BaseType.BuiltinType != BuiltinTypeSpec.Type.Object && BaseType.BuiltinType != BuiltinTypeSpec.Type.ValueType) { cache.AddBaseType (BaseType); + has_user_base_type = true; } if (InterfacesDefined != null) { + var icache = cache; + if (has_user_base_type) { + // + // type-parameter lookup rules are more complicated that other types lookup rules. + // Effective base class and its base types member have priority over interface + // constraints which means we cannot lookup interface members before class members + // hence we setup secondary cache for such cases. + // + interface_cache = new MemberCache (); + icache = interface_cache; + } + foreach (var iface_type in InterfacesDefined) { - cache.AddInterface (iface_type); + icache.AddInterface (iface_type); } } @@ -1370,8 +1391,14 @@ namespace Mono.CSharp { var ifaces = tps == null ? ta.Interfaces : tps.InterfacesDefined; if (ifaces != null) { + var icache = cache; + if (has_user_base_type) { + interface_cache = new MemberCache (); + icache = interface_cache; + } + foreach (var iface_type in ifaces) { - cache.AddInterface (iface_type); + icache.AddInterface (iface_type); } } } @@ -1516,6 +1543,9 @@ namespace Mono.CSharp { if (ec is PointerContainer) return PointerContainer.MakeType (context.Module, et); + if (ec is ReferenceContainer) + return ReferenceContainer.MakeType (context.Module, et); + throw new NotImplementedException (); } @@ -1551,7 +1581,7 @@ namespace Mono.CSharp { // Parent was inflated, find the same type on inflated type // to use same cache for nested types on same generic parent // - type = MemberCache.FindNestedType (parent, type.Name, type.Arity); + type = MemberCache.FindNestedType (parent, type.Name, type.Arity, false); // // Handle the tricky case where parent shares local type arguments @@ -1745,7 +1775,10 @@ namespace Mono.CSharp { foreach (var arg in targs) { if (arg.HasDynamicElement || arg.BuiltinType == BuiltinTypeSpec.Type.Dynamic) { state |= StateFlags.HasDynamicElement; - break; + } + + if (arg.HasNamedTupleElement) { + state |= StateFlags.HasNamedTupleElement; } } @@ -1825,6 +1858,12 @@ namespace Mono.CSharp { } } + public override bool IsTupleType { + get { + return (open_type.state & StateFlags.Tuple) != 0; + } + } + // // Types used to inflate the generic type // @@ -2135,6 +2174,10 @@ namespace Mono.CSharp { return this; var mutated = (InflatedTypeSpec) MemberwiseClone (); +#if DEBUG + mutated.ID += 1000000; +#endif + if (decl != DeclaringType) { // Gets back MethodInfo in case of metaInfo was inflated //mutated.info = MemberCache.GetMember (DeclaringType.GetDefinition (), this).info; @@ -3060,7 +3103,11 @@ namespace Mono.CSharp { // Some types cannot be used as type arguments // if ((bound.Type.Kind == MemberKind.Void && !voidAllowed) || bound.Type.IsPointer || bound.Type.IsSpecialRuntimeType || - bound.Type == InternalType.MethodGroup || bound.Type == InternalType.AnonymousMethod || bound.Type == InternalType.VarOutType) + bound.Type == InternalType.MethodGroup || bound.Type == InternalType.AnonymousMethod || bound.Type == InternalType.VarOutType || + bound.Type == InternalType.ThrowExpr) + return; + + if (bound.Type.IsTupleType && TupleLiteral.ContainsNoTypeElement (bound.Type)) return; var a = bounds [index]; @@ -3132,7 +3179,7 @@ namespace Mono.CSharp { var ga_u = u.TypeArguments; var ga_v = v.TypeArguments; - if (u.TypeArguments.Length != u.TypeArguments.Length) + if (u.TypeArguments.Length != v.TypeArguments.Length) return 0; int score = 0;