2009-08-13 Marek Safar <marek.safar@gmail.com>
authorMarek Safar <marek.safar@gmail.com>
Thu, 13 Aug 2009 16:35:49 +0000 (16:35 -0000)
committerMarek Safar <marek.safar@gmail.com>
Thu, 13 Aug 2009 16:35:49 +0000 (16:35 -0000)
* decl.cs, namespace.cs, ecore.cs, class.cs, attribute.cs,
codegen.cs: Add IResolveContext::LookupTypeParameter.

svn path=/trunk/mcs/; revision=139857

mcs/mcs/ChangeLog
mcs/mcs/attribute.cs
mcs/mcs/class.cs
mcs/mcs/codegen.cs
mcs/mcs/decl.cs
mcs/mcs/ecore.cs
mcs/mcs/namespace.cs

index 68cfea6894d7329cf807d0905c5717945a1b391c..e25766cfeff7f7de68d46545ad146e5135bc40fc 100644 (file)
@@ -1,3 +1,8 @@
+2009-08-13  Marek Safar  <marek.safar@gmail.com>
+
+       * decl.cs, namespace.cs, ecore.cs, class.cs, attribute.cs,
+       codegen.cs: Add IResolveContext::LookupTypeParameter.
+
 2009-08-13  Marek Safar  <marek.safar@gmail.com>
 
        * lambda.cs, expression.cs, statement.cs, namespace.cs, ecore.cs:
index 5a89543c8144c1886f9b3704baef70961f98e8ce..c98bcf01b2e3b434722fe80fc0b2ff1fdbc9814d 100644 (file)
@@ -198,12 +198,6 @@ namespace Mono.CSharp {
                                      "expression or array creation expression");
                }
                
-               static void Error_TypeParameterInAttribute (Location loc)
-               {
-                       Report.Error (
-                               -202, loc, "Can not use a type parameter in an attribute");
-               }
-
                public void Error_MissingGuidAttribute ()
                {
                        Report.Error (596, Location, "The Guid attribute must be specified with the ComImport attribute");
@@ -393,7 +387,7 @@ namespace Mono.CSharp {
                                }
                        }
 
-                       DeclSpace ds = context.GenericDeclContainer;            
+                       DeclSpace ds = context.GenericDeclContainer;
                        EmitContext ec = new EmitContext (context, ds, ds,
                                Location, null, typeof (Attribute), ds.ModFlags, false);
                        ec.IsAnonymousMethodAllowed = false;
@@ -562,11 +556,6 @@ namespace Mono.CSharp {
                                        return false;
                                }
 
-                               if (a.Expr is TypeParameterExpr){
-                                       Error_TypeParameterInAttribute (Location);
-                                       return false;
-                               }
-
                                ObsoleteAttribute obsolete_attr;
 
                                if (member is PropertyExpr) {
index 980b6858a1c92377bcd1e881dbe5201bc19f59ff..956146da018522cc8ffa90f728e92640155314ff 100644 (file)
@@ -187,6 +187,11 @@ namespace Mono.CSharp {
                                return tc.Parent.LookupNamespaceOrType (name, loc, ignore_cs0104);
                        }
 
+                       public Type LookupTypeParameter (string name)
+                       {
+                               return tc.PartialContainer.LookupTypeParameter (name);
+                       }
+
                        public DeclSpace GenericDeclContainer {
                                get { return tc.GenericDeclContainer; }
                        }
@@ -893,7 +898,7 @@ namespace Mono.CSharp {
                                        if (base_class == TypeManager.system_object_expr)
                                                base_class = new_base_class;
                                        else {
-                                               if (new_base_class != null && !new_base_class.Equals (base_class)) {
+                                               if (new_base_class != null && !TypeManager.IsEqual (new_base_class.Type, base_class.Type)) {
                                                        Report.SymbolRelatedToPreviousError (base_class.Location, "");
                                                        Report.Error (263, part.Location,
                                                                "Partial declarations of `{0}' must not specify different base classes",
@@ -3576,9 +3581,7 @@ namespace Mono.CSharp {
 
                protected bool DefineParameters (ParametersCompiled parameters)
                {
-                       IResolveContext rc = GenericMethod == null ? this : (IResolveContext)ds;
-
-                       if (!parameters.Resolve (rc))
+                       if (!parameters.Resolve (this))
                                return false;
 
                        bool error = false;
@@ -4371,6 +4374,17 @@ namespace Mono.CSharp {
                        return mi;
                }
 
+               public override Type LookupTypeParameter (string name)
+               {
+                       if (GenericMethod != null) {
+                               Type t = GenericMethod.LookupTypeParameter (name);
+                               if (t != null)
+                                       return t;
+                       }
+
+                       return base.LookupTypeParameter (name);
+               }
+
                public void SetPartialDefinition (Method methodDefinition)
                {
                        caching_flags |= Flags.PartialDefinitionExists;
index c8399ee1381347aa8ec8b1ef3672fdf556fcba51..a189283d21767a1fb4613133438fd58eeb8aea7a 100644 (file)
@@ -258,6 +258,7 @@ namespace Mono.CSharp {
                bool IsInUnsafeScope { get; }
 
                FullNamedExpression LookupNamespaceOrType (string name, Location loc, bool ignore_cs0104);
+               Type LookupTypeParameter (string name);
 
                // the declcontainer to lookup for type-parameters.  Should only use LookupGeneric on it.
                //
@@ -1057,6 +1058,11 @@ namespace Mono.CSharp {
                        return ResolveContext.LookupNamespaceOrType (name, loc, ignore_cs0104);
                }
 
+               public Type LookupTypeParameter (string name)
+               {
+                       return ResolveContext.LookupTypeParameter (name);
+               }
+
                #endregion
        }
 
@@ -1115,6 +1121,11 @@ namespace Mono.CSharp {
                        return RootContext.ToplevelTypes.LookupNamespaceOrType (name, loc, ignore_cs0104);
                }
 
+               public Type LookupTypeParameter (string name)
+               {
+                       return null;
+               }
+
                #endregion
        }
                 
index 13cd1e38858eb76b2e844cfc6719825b7c97acf5..7b4062d75644f5d721f8f78aa89db392b709fd78 100644 (file)
@@ -675,6 +675,11 @@ namespace Mono.CSharp {
                        return Parent.LookupNamespaceOrType (name, loc, ignore_cs0104);
                }
 
+               public virtual Type LookupTypeParameter (string name)
+               {
+                       return Parent.LookupTypeParameter (name);
+               }
+
                /// <summary>
                /// Goes through class hierarchy and gets value of first found CLSCompliantAttribute.
                /// If no is attribute exists then assembly CLSCompliantAttribute is returned.
@@ -1075,6 +1080,9 @@ namespace Mono.CSharp {
                        if (TypeManager.HasElementType (check_type))
                                return CheckAccessLevel (TypeManager.GetElementType (check_type));
 
+                       if (TypeManager.IsGenericParameter (check_type))
+                               return true;
+
                        TypeAttributes check_attr = check_type.Attributes & TypeAttributes.VisibilityMask;
 
                        switch (check_attr){
@@ -1223,6 +1231,30 @@ namespace Mono.CSharp {
                        return e;
                }
 
+               public override Type LookupTypeParameter (string name)
+               {
+                       if (type_params != null) {
+                               Type t = LookupLocalTypeParameter (name);
+                               if (t != null)
+                                       return t;
+                       }
+
+                       if (Parent != null)
+                               return Parent.LookupTypeParameter (name);
+
+                       return null;
+               }
+
+               Type LookupLocalTypeParameter (string name)
+               {
+                       foreach (var tp in CurrentTypeParameters) {
+                               if (tp.Name == name)
+                                       return tp.Type;
+                       }
+
+                       return null;
+               }
+
                /// <remarks>
                ///   This function is broken and not what you're looking for.  It should only
                ///   be used while the type is still being created since it doesn't use the cache
@@ -1387,28 +1419,6 @@ namespace Mono.CSharp {
                        }
                }
 
-               public TypeParameterExpr LookupGeneric (string name, Location loc)
-               {
-                       if (!IsGeneric)
-                               return null;
-
-                       TypeParameter [] current_params;
-                       if (this is TypeContainer)
-                               current_params = PartialContainer.CurrentTypeParameters;
-                       else
-                               current_params = CurrentTypeParameters;
-
-                       foreach (TypeParameter type_param in current_params) {
-                               if (type_param.Name == name)
-                                       return new TypeParameterExpr (type_param, loc);
-                       }
-
-                       if (Parent != null)
-                               return Parent.LookupGeneric (name, loc);
-
-                       return null;
-               }
-
                // Used for error reporting only
                public virtual Type LookupAnyGeneric (string typeName)
                {
index b45499f278967d10d4a9577fec15d01b0b9e8893..c8eec124407851959995418ea0c7a29874e73b98 100644 (file)
@@ -284,9 +284,15 @@ namespace Mono.CSharp {
 
                        GenericTypeExpr ct = te as GenericTypeExpr;
                        if (ct != null) {
-                               // Skip constrains check for overrides and explicit implementations
-                               // TODO: they should use different overload
-                               GenericMethod gm = ec.GenericDeclContainer as GenericMethod;
+                               //
+                               // TODO: Constrained type parameters check for parameters of generic method overrides is broken
+                               // There are 2 solutions.
+                               // 1, Skip this check completely when we are in override/explicit impl scope
+                               // 2, Copy type parameters constraints from base implementation and pass (they have to be emitted anyway)
+                               //
+                               MemberCore gm = ec as GenericMethod;
+                               if (gm == null)
+                                       gm = ec as Method;
                                if (gm != null && ((gm.ModFlags & Modifiers.OVERRIDE) != 0 || gm.MemberName.Left != null)) {
                                        te.loc = loc;
                                        return te;
@@ -2520,12 +2526,12 @@ namespace Mono.CSharp {
 
                public override FullNamedExpression ResolveAsTypeStep (IResolveContext ec, bool silent)
                {
-                       FullNamedExpression fne = ec.GenericDeclContainer.LookupGeneric (Name, loc);
-                       if (fne != null)
-                               return fne.ResolveAsTypeStep (ec, silent);
+                       Type t = ec.LookupTypeParameter (Name);
+                       if (t != null)
+                               return new TypeParameterExpr (TypeManager.LookupTypeParameter (t), loc).ResolveAsTypeStep (ec, false);
 
                        int errors = Report.Errors;
-                       fne = ec.LookupNamespaceOrType (Name, loc, /*ignore_cs0104=*/ false);
+                       FullNamedExpression fne = ec.LookupNamespaceOrType (Name, loc, /*ignore_cs0104=*/ false);
 
                        if (fne != null) {
                                if (fne.Type == null)
index 6892ba0f5bfa124971653c503e0fb4fb7079944f..72e0dcc6438575187a0eaad4799e2d928d120201 100644 (file)
@@ -1090,6 +1090,11 @@ namespace Mono.CSharp {
                        return resolved;
                }
 
+               public Type LookupTypeParameter (string name)
+               {
+                       return null;
+               }
+
                public ICollection CompletionGetTypesStartingWith (DeclSpace ds, string prefix)
                {
                        Hashtable result = new Hashtable ();