Merge
[mono.git] / mcs / mcs / generic.cs
index a5ee0b4beb1177ed40b052d70e07d74ac2e0528e..21dcbd9480dbecd7f284e39ff06a4fab5054ce40 100644 (file)
@@ -312,7 +312,7 @@ namespace Mono.CSharp {
                                if (type.IsSealed || !type.IsClass) {
                                        context.Module.Compiler.Report.Error (701, loc,
                                                "`{0}' is not a valid constraint. A constraint must be an interface, a non-sealed class or a type parameter",
-                                               TypeManager.CSharpName (type));
+                                               type.GetSignatureForError ());
                                        continue;
                                }
 
@@ -358,7 +358,7 @@ namespace Mono.CSharp {
                
                Constraints constraints;
                GenericTypeParameterBuilder builder;
-               TypeParameterSpec spec;
+               readonly TypeParameterSpec spec;
 
                public TypeParameter (int index, MemberName name, Constraints constraints, Attributes attrs, Variance variance)
                        : base (null, name, attrs)
@@ -375,7 +375,7 @@ namespace Mono.CSharp {
                {
                        this.spec = new TypeParameterSpec (null, -1, this, SpecialConstraint.None, variance, null);
                }
-
+               
                public TypeParameter (TypeParameterSpec spec, TypeSpec parentSpec, MemberName name, Attributes attrs)
                        : base (null, name, attrs)
                {
@@ -385,7 +385,7 @@ namespace Mono.CSharp {
                                TypeArguments = spec.TypeArguments
                        };
                }
-
+               
                #region Properties
 
                public override AttributeTargets AttributeTargets {
@@ -428,6 +428,12 @@ namespace Mono.CSharp {
                        }
                }
 
+               bool ITypeDefinition.IsPlayScriptType {
+                       get {
+                               return false;
+                       }
+               }
+
                public bool IsMethodTypeParameter {
                        get {
                                return spec.IsMethodOwned;
@@ -489,7 +495,7 @@ namespace Mono.CSharp {
                //
                // If partial type parameters constraints are not null and we don't
                // already have constraints they become our constraints. If we already
-               // have constraints, we must check that they're the same.
+               // have constraints, we must check that they're same.
                //
                public bool AddPartialConstraints (TypeDefinition part, TypeParameter tp)
                {
@@ -545,15 +551,19 @@ namespace Mono.CSharp {
                // with SRE (by calling `DefineGenericParameters()' on the TypeBuilder /
                // MethodBuilder).
                //
-               public void Define (GenericTypeParameterBuilder type, TypeSpec declaringType, TypeContainer parent)
+               public void Create (TypeSpec declaringType, TypeContainer parent)
                {
                        if (builder != null)
                                throw new InternalErrorException ();
 
                        // Needed to get compiler reference
                        this.Parent = parent;
-                       this.builder = type;
                        spec.DeclaringType = declaringType;
+               }
+
+               public void Define (GenericTypeParameterBuilder type)
+               {
+                       this.builder = type;
                        spec.SetMetaInfo (type);
                }
 
@@ -776,6 +786,8 @@ namespace Mono.CSharp {
                                                                }
                                                        }
                                                }
+                                       } else if (ifaces_defined == null) {
+                                               ifaces_defined = ifaces == null ? TypeSpec.EmptyTypes : ifaces.ToArray ();
                                        }
 
                                        //
@@ -793,9 +805,6 @@ namespace Mono.CSharp {
                                                }
                                        }
 
-                                       if (ifaces_defined == null)
-                                               ifaces_defined = ifaces == null ? TypeSpec.EmptyTypes : ifaces.ToArray ();
-
                                        state |= StateFlags.InterfacesExpanded;
                                }
 
@@ -1377,6 +1386,9 @@ namespace Mono.CSharp {
                                return ac;
                        }
 
+                       if (type.Kind == MemberKind.MissingType)
+                               return type;
+
                        //
                        // When inflating a nested type, inflate its parent first
                        // in case it's using same type parameters (was inflated within the type)
@@ -1474,6 +1486,7 @@ namespace Mono.CSharp {
        {
                readonly TypeParameters mvar;
                readonly TypeParameters var;
+               readonly TypeParameterSpec[] src;
                Dictionary<TypeSpec, TypeSpec> mutated_typespec;
 
                public TypeParameterMutator (TypeParameters mvar, TypeParameters var)
@@ -1485,6 +1498,15 @@ namespace Mono.CSharp {
                        this.var = var;
                }
 
+               public TypeParameterMutator (TypeParameterSpec[] srcVar, TypeParameters destVar)
+               {
+                       if (srcVar.Length != destVar.Count)
+                               throw new ArgumentException ();
+
+                       this.src = srcVar;
+                       this.var = destVar;
+               }
+
                #region Properties
 
                public TypeParameters MethodTypeParameters {
@@ -1524,9 +1546,16 @@ namespace Mono.CSharp {
 
                public TypeParameterSpec Mutate (TypeParameterSpec tp)
                {
-                       for (int i = 0; i < mvar.Count; ++i) {
-                               if (mvar[i].Type == tp)
-                                       return var[i].Type;
+                       if (mvar != null) {
+                               for (int i = 0; i < mvar.Count; ++i) {
+                                       if (mvar[i].Type == tp)
+                                               return var[i].Type;
+                               }
+                       } else {
+                               for (int i = 0; i < src.Length; ++i) {
+                                       if (src[i] == tp)
+                                               return var[i].Type;
+                               }
                        }
 
                        return tp;
@@ -2159,13 +2188,13 @@ namespace Mono.CSharp {
                        names.AddRange (tparams.names);
                }
 
-               public void Define (GenericTypeParameterBuilder[] buiders, TypeSpec declaringType, int parentOffset, TypeContainer parent)
+               public void Create (TypeSpec declaringType, int parentOffset, TypeContainer parent)
                {
                        types = new TypeParameterSpec[Count];
                        for (int i = 0; i < types.Length; ++i) {
                                var tp = names[i];
 
-                               tp.Define (buiders[i + parentOffset], declaringType, parent);
+                               tp.Create (declaringType, parent);
                                types[i] = tp.Type;
                                types[i].DeclaredPosition = i + parentOffset;
 
@@ -2175,6 +2204,14 @@ namespace Mono.CSharp {
                        }
                }
 
+               public void Define (GenericTypeParameterBuilder[] builders)
+               {
+                       for (int i = 0; i < types.Length; ++i) {
+                               var tp = names[i];
+                               tp.Define (builders [types [i].DeclaredPosition]);
+                       }
+               }
+
                public TypeParameter this[int index] {
                        get {
                                return names [index];
@@ -2214,6 +2251,44 @@ namespace Mono.CSharp {
                        return sb.ToString ();
                }
 
+
+               public void CheckPartialConstraints (Method part)
+               {
+                       var partTypeParameters = part.CurrentTypeParameters;
+
+                       for (int i = 0; i < Count; i++) {
+                               var tp_a = names[i];
+                               var tp_b = partTypeParameters [i];
+                               if (tp_a.Constraints == null) {
+                                       if (tp_b.Constraints == null)
+                                               continue;
+                               } else if (tp_b.Constraints != null && tp_a.Type.HasSameConstraintsDefinition (tp_b.Type)) {
+                                       continue;
+                               }
+
+                               part.Compiler.Report.SymbolRelatedToPreviousError (this[i].CurrentMemberDefinition.Location, "");
+                               part.Compiler.Report.Error (761, part.Location,
+                                       "Partial method declarations of `{0}' have inconsistent constraints for type parameter `{1}'",
+                                       part.GetSignatureForError (), partTypeParameters[i].GetSignatureForError ());
+                       }
+               }
+
+               public void UpdateConstraints (TypeDefinition part)
+               {
+                       var partTypeParameters = part.MemberName.TypeParameters;
+
+                       for (int i = 0; i < Count; i++) {
+                               var tp = names [i];
+                               if (tp.AddPartialConstraints (part, partTypeParameters [i]))
+                                       continue;
+
+                               part.Compiler.Report.SymbolRelatedToPreviousError (this[i].CurrentMemberDefinition);
+                               part.Compiler.Report.Error (265, part.Location,
+                                       "Partial declarations of `{0}' have inconsistent constraints for type parameter `{1}'",
+                                       part.GetSignatureForError (), tp.GetSignatureForError ());
+                       }
+               }
+
                public void VerifyClsCompliance ()
                {
                        foreach (var tp in names) {
@@ -2244,7 +2319,7 @@ namespace Mono.CSharp {
 
                public override string GetSignatureForError ()
                {
-                       return TypeManager.CSharpName (type);
+                       return type.GetSignatureForError ();
                }
 
                public override TypeSpec ResolveAsType (IMemberContext mc)
@@ -2392,7 +2467,7 @@ namespace Mono.CSharp {
                                if (mc != null) {
                                        mc.Module.Compiler.Report.Error (452, loc,
                                                "The type `{0}' must be a reference type in order to use it as type parameter `{1}' in the generic type or method `{2}'",
-                                               TypeManager.CSharpName (atype), tparam.GetSignatureForError (), context.GetSignatureForError ());
+                                               atype.GetSignatureForError (), tparam.GetSignatureForError (), context.GetSignatureForError ());
                                }
 
                                return false;
@@ -2402,7 +2477,7 @@ namespace Mono.CSharp {
                                if (mc != null) {
                                        mc.Module.Compiler.Report.Error (453, loc,
                                                "The type `{0}' must be a non-nullable value type in order to use it as type parameter `{1}' in the generic type or method `{2}'",
-                                               TypeManager.CSharpName (atype), tparam.GetSignatureForError (), context.GetSignatureForError ());
+                                               atype.GetSignatureForError (), tparam.GetSignatureForError (), context.GetSignatureForError ());
                                }
 
                                return false;
@@ -2463,7 +2538,7 @@ namespace Mono.CSharp {
                                        mc.Module.Compiler.Report.SymbolRelatedToPreviousError (atype);
                                        mc.Module.Compiler.Report.Error (310, loc,
                                                "The type `{0}' must have a public parameterless constructor in order to use it as parameter `{1}' in the generic type or method `{2}'",
-                                               TypeManager.CSharpName (atype), tparam.GetSignatureForError (), context.GetSignatureForError ());
+                                               atype.GetSignatureForError (), tparam.GetSignatureForError (), context.GetSignatureForError ());
                                }
                                return false;
                        }