2009-05-27 Marek Safar <marek.safar@gmail.com>
authorMarek Safar <marek.safar@gmail.com>
Wed, 27 May 2009 14:11:59 +0000 (14:11 -0000)
committerMarek Safar <marek.safar@gmail.com>
Wed, 27 May 2009 14:11:59 +0000 (14:11 -0000)
* generic.cs, parameter.cs, decl.cs, ecore.cs, class.cs, delegate.cs
    cs-parser.jay, generic-mcs.cs: Report wrong variant types declarations.

* driver.cs, rootcontext.cs, report.cs: Add 3.0 language version
filter.

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

12 files changed:
mcs/mcs/ChangeLog
mcs/mcs/class.cs
mcs/mcs/cs-parser.jay
mcs/mcs/decl.cs
mcs/mcs/delegate.cs
mcs/mcs/driver.cs
mcs/mcs/ecore.cs
mcs/mcs/generic-mcs.cs
mcs/mcs/generic.cs
mcs/mcs/parameter.cs
mcs/mcs/report.cs
mcs/mcs/rootcontext.cs

index 12e756fcba8e56e6c5885d118d87d10702af874e..4fc1c06abb16198fc16734393c11247852cb4559 100644 (file)
@@ -1,3 +1,12 @@
+2009-05-27  Marek Safar  <marek.safar@gmail.com>
+
+       * generic.cs, parameter.cs, decl.cs, ecore.cs, class.cs, delegate.cs
+    cs-parser.jay, generic-mcs.cs: Report wrong variant types
+       declarations.
+         
+       * driver.cs, rootcontext.cs, report.cs: Add 3.0 language version
+       filter.
+
 2009-05-26  Rodrigo Kumpera  <rkumpera@novell.com>
                        Marek Safar  <marek.safar@gmail.com>
 
index 0a829a5629fb62f252fb829e421c24af6c60aeba..551d5c6e6d30ea70b0ad5767b95e067557febc92 100644 (file)
@@ -1289,7 +1289,7 @@ namespace Mono.CSharp {
 
                                        GenericTypeExpr ct = iface as GenericTypeExpr;
                                        if (ct != null) {
-                                               if (!ct.CheckConstraints (this) || !ct.VerifyVariantTypeParameters ())
+                                               if (!ct.CheckConstraints (this) || !ct.VerifyVariantTypeParameters (this))
                                                        return false;
                                        }
                                }
@@ -5286,11 +5286,10 @@ namespace Mono.CSharp {
                                                      "accessible than field `" + GetSignatureForError () + "'");
                                }
                        }
-#if GMCS_SOURCE
-                       if (MemberType.IsGenericParameter && (MemberType.GenericParameterAttributes & GenericParameterAttributes.Contravariant) != 0) {
-                               Report.Error (-33, Location, "Contravariant type parameters can only be used in input positions");
-                       }
-#endif
+
+                       var tp = TypeManager.LookupTypeParameter (MemberType);
+                       if (tp != null && tp.Variance == Variance.Contravariant)
+                               tp.ErrorInvalidVariance (this, Variance.Covariant);
                }
 
                protected bool IsTypePermitted ()
index c7a5aa16f8683c10041e799ca067ae24ebe705cb..9b535d7e5dc404b999fce5cab4949d4b4f554962 100644 (file)
@@ -2769,7 +2769,7 @@ type_parameter
        : opt_attributes opt_type_parameter_variance IDENTIFIER
          {
                LocatedToken lt = (LocatedToken)$3;
-               $$ = new TypeParameterName (lt.Value, (Attributes)$1, (Variance)$2, lt.Location);
+               $$ = new TypeParameterName (lt.Value, (Attributes)$1, (Variance) $2, lt.Location);
          }
        | error
          {
@@ -4237,8 +4237,9 @@ opt_type_parameter_variance
          }
        | type_parameter_variance
          {
-               if (RootContext.Version < LanguageVersion.Future)
-                       Report.FeatureIsNotAvailable (lexer.Location, "generic variance");
+               if (RootContext.Version <= LanguageVersion.V_3)
+                       Report.FeatureIsNotAvailable (lexer.Location, "generic type variance");
+
                $$ = $1;
          }
        ;
index d49d0641e855b6cb179a3ac2122e9a3166e701eb..13065b52be7896c3a0bea8bc3fe324ac13cfdadd 100644 (file)
@@ -349,7 +349,7 @@ namespace Mono.CSharp {
                                }
                        } else {
                                if ((ModFlags & (Modifiers.ABSTRACT | Modifiers.EXTERN | Modifiers.PARTIAL)) == 0) {
-                                       if (RootContext.Version >= LanguageVersion.LINQ) {
+                                       if (RootContext.Version >= LanguageVersion.V_3) {
                                                Property.PropertyMethod pm = this as Property.PropertyMethod;
                                                if (pm is Indexer.GetIndexerMethod || pm is Indexer.SetIndexerMethod)
                                                        pm = null;
@@ -1334,9 +1334,14 @@ namespace Mono.CSharp {
                                        }
                                }
 
+                               var variance = name.Variance;
+                               if (name.Variance != Variance.None && !(this is Delegate || this is Interface)) {
+                                       Report.Error (1960, name.Location, "Variant type parameters can only be used with interfaces and delegates");
+                                       variance = Variance.None;
+                               }
+
                                type_params [i] = new TypeParameter (
-                                       Parent, this, name.Name, constraints, name.OptAttributes, name.Variance,
-                                       Location);
+                                       Parent, this, name.Name, constraints, name.OptAttributes, variance, Location);
 
                                AddToContainer (type_params [i], name.Name);
                        }
index 24fe57e9120801c4c9315445e89339fd56e24766..8a5a7df610ffc52caf8d29537ffd62363c2ba336 100644 (file)
@@ -229,12 +229,9 @@ namespace Mono.CSharp {
                                return false;
                        }
 
-#if GMCS_SOURCE
-                       if (ret_type.IsGenericParameter && (ret_type.GenericParameterAttributes & GenericParameterAttributes.Contravariant) != 0) {
-                               Report.Error (-33, Location, "Contravariant type parameters can only be used in input positions");
-                               return false;
-                       }
-#endif
+                       var tp = TypeManager.LookupTypeParameter (ret_type);
+                       if (tp != null && tp.Variance == Variance.Contravariant)
+                               tp.ErrorInvalidVariance (this, Variance.Covariant);
 
                        //
                        // We don't have to check any others because they are all
index 8c365456a9aeca4208c5037e8ef7afb21235bf90..1408000d27f0cf276335bd776317253d4fa81d10 100644 (file)
@@ -1506,12 +1506,15 @@ namespace Mono.CSharp
                                case "iso-2":
                                        RootContext.Version = LanguageVersion.ISO_2;
                                        return true;
+                               case "3":
+                                       RootContext.Version = LanguageVersion.V_3;
+                                       return true;
                                case "future":
                                        RootContext.Version = LanguageVersion.Future;
                                        return true;
 #endif
                                }
-                               Report.Error (1617, "Invalid option `{0}' for /langversion. It must be either `ISO-1', `ISO-2' or `Default'", value);
+                               Report.Error (1617, "Invalid -langversion option `{0}'. It must be `ISO-1', `ISO-2', `3' or `Default'", value);
                                return true;
 
                        case "/codepage":
index b465ee56f7f8243744769a5711c1b393a2d4db47..0248dec0e76dafadf842490c1cbcab86e72aa4a6 100644 (file)
@@ -294,7 +294,7 @@ namespace Mono.CSharp {
 
                                // TODO: silent flag is ignored
                                ct.CheckConstraints (ec);
-                               ct.VerifyVariantTypeParameters ();
+                               ct.VerifyVariantTypeParameters (ec);
                        }
 
                        return te;
index 4cb0639ce5b59966dd8f9c9bc899bdfb6fb985d5..cba46aabd5dd0dca715231a7119a2b846cf6c608 100644 (file)
@@ -124,6 +124,10 @@ namespace Mono.CSharp
                {
                        throw new NotImplementedException ();
                }
+               
+               public void ErrorInvalidVariance (MemberCore mc, Variance v)
+               {
+               }
 
                //
                // MemberContainer
@@ -310,7 +314,7 @@ namespace Mono.CSharp
                        get { throw new NotImplementedException (); }
                }
 
-               public bool VerifyVariantTypeParameters ()
+               public bool VerifyVariantTypeParameters (IResolveContext rc)
                {
                        throw new NotImplementedException ();
                }
index 850a1709d04ce35c0de98f5b705ee2f903995924..5495a2421b53af2b11a41b5f60ebb723d3d131c2 100644 (file)
@@ -656,9 +656,6 @@ namespace Mono.CSharp {
                        this.decl = decl;
                        this.constraints = constraints;
                        this.variance = variance;
-                       if (variance != Variance.None && !(decl is Interface) && !(decl is Delegate)) {
-                               Report.Error (-36, loc, "Generic variance can only be used with interfaces and delegates");
-                       }
                }
 
                public GenericConstraints GenericConstraints {
@@ -699,6 +696,22 @@ namespace Mono.CSharp {
                        TypeManager.AddTypeParameter (type, this);
                }
 
+               public void ErrorInvalidVariance (MemberCore mc, Variance expected)
+               {
+                       Report.SymbolRelatedToPreviousError (mc);
+                       string input_variance = Variance == Variance.Contravariant ? "contravariant" : "covariant";
+                       string gtype_variance;
+                       switch (expected) {
+                       case Variance.Contravariant: gtype_variance = "contravariantly"; break;
+                       case Variance.Covariant: gtype_variance = "covariantly"; break;
+                       default: gtype_variance = "invariantly"; break;
+                       }
+
+                       Report.Error (1961, Location,
+                               "The {2} type parameter `{0}' must be {3} valid on `{1}'",
+                                       GetSignatureForError (), mc.GetSignatureForError (), input_variance, gtype_variance);
+               }
+
                /// <summary>
                ///   This is the second method which is called during the resolving
                ///   process - in case of class type parameters, we're called from
@@ -1364,37 +1377,21 @@ namespace Mono.CSharp {
                {
                        return ConstraintChecker.CheckConstraints (ec, open_type, gen_params, args.Arguments, loc);
                }
-
-               static bool IsVariant (Type type)
-               {
-                       return (type.GenericParameterAttributes & GenericParameterAttributes.VarianceMask) != 0;
-               }
-       
-               static bool IsCovariant (Type type)
-               {
-                       return (type.GenericParameterAttributes & GenericParameterAttributes.Covariant) != 0;
-               }
-       
-               static bool IsContravariant (Type type)
-               {
-                       return (type.GenericParameterAttributes & GenericParameterAttributes.Contravariant) != 0;
-               }
        
-               public bool VerifyVariantTypeParameters ()
+               public bool VerifyVariantTypeParameters (IResolveContext rc)
                {
                        for (int i = 0; i < args.Count; i++) {
-                               Type argument = args.Arguments[i];
-                               if (argument.IsGenericParameter && IsVariant (argument)) {
-                                       if (IsContravariant (argument) && !IsContravariant (gen_params[i])) {
-                                               Report.Error (-34, loc, "Contravariant type parameters can only be used " +
-                                             "as type arguments in contravariant positions");
-                                               return false;
-                                       }
-                                       else if (IsCovariant (argument) && !IsCovariant (gen_params[i])) {
-                                               Report.Error (-35, loc, "Covariant type parameters can only be used " +
-                                             "as type arguments in covariant positions");
-                                               return false;
-                                       }
+                               var argument = args.Arguments [i];
+                               TypeParameter tparam = TypeManager.LookupTypeParameter (argument);
+                               if (tparam == null)
+                                       continue;
+
+                               if (tparam.Variance == Variance.None)
+                                       continue;
+
+                               if (tparam.Variance != TypeManager.GetTypeParameterVariance (gen_params [i])) {
+                                       var mc = (MemberCore) rc;
+                                       tparam.ErrorInvalidVariance (mc, TypeManager.GetTypeParameterVariance (gen_params[i]));
                                }
                        }
                        return true;
@@ -1879,6 +1876,22 @@ namespace Mono.CSharp {
                        return LookupTypeContainer (t);
                }
 
+               public static Variance GetTypeParameterVariance (Type type)
+               {
+                       TypeParameter tparam = LookupTypeParameter (type);
+                       if (tparam != null)
+                               return tparam.Variance;
+
+                       switch (type.GenericParameterAttributes & GenericParameterAttributes.VarianceMask) {
+                       case GenericParameterAttributes.Covariant:
+                               return Variance.Covariant;
+                       case GenericParameterAttributes.Contravariant:
+                               return Variance.Contravariant;
+                       default:
+                               return Variance.None;
+                       }
+               }
+
                /// <summary>
                ///   Check whether `a' and `b' may become equal generic types.
                ///   The algorithm to do that is a little bit complicated.
index 1396929467346622bc3b6cb75fc24cf501944c3e..d1b4eada89e5e2022a35df912ce3ffb4362e1ea7 100644 (file)
@@ -361,32 +361,25 @@ namespace Mono.CSharp {
                                return null;
                        }
 
-#if GMCS_SOURCE
-                       if (parameter_type.IsGenericParameter) {
-                               AbstractPropertyEventMethod accessor = ec as AbstractPropertyEventMethod;
-                               if (accessor == null || !accessor.IsDummy) {
-                                       if ((parameter_type.GenericParameterAttributes & GenericParameterAttributes.Covariant) != 0) {
-                                               Report.Error (-38, Location, "Covariant type parameters cannot be used as method parameters");
-                                               return null;
-                                       } else if ((ModFlags & Modifier.ISBYREF) != 0 &&
-                                                  (parameter_type.GenericParameterAttributes & GenericParameterAttributes.Contravariant) != 0) {
-                                               Report.Error (-37, Location, "Contravariant type parameters cannot be used in output positions");
-                                               return null;
-                                       }
+                       var tp = TypeManager.LookupTypeParameter (parameter_type);
+                       if (tp != null) {
+                               if ((modFlags & Parameter.Modifier.ISBYREF) != 0) {
+                                       if (tp.Variance != Variance.None)
+                                               tp.ErrorInvalidVariance ((MemberCore) ec, Variance.None);
+                               } else if (tp.Variance == Variance.Covariant) {
+                                       tp.ErrorInvalidVariance ((MemberCore) ec, Variance.Contravariant);
+                               }
+                       } else {
+                               if ((parameter_type.Attributes & Class.StaticClassAttribute) == Class.StaticClassAttribute) {
+                                       Report.Error (721, Location, "`{0}': static types cannot be used as parameters",
+                                               texpr.GetSignatureForError ());
+                                       return parameter_type;
                                }
-                               return parameter_type;
-                       }
-#endif
-
-                       if ((parameter_type.Attributes & Class.StaticClassAttribute) == Class.StaticClassAttribute) {
-                               Report.Error (721, Location, "`{0}': static types cannot be used as parameters",
-                                       texpr.GetSignatureForError ());
-                               return parameter_type;
-                       }
 
-                       if ((modFlags & Modifier.This) != 0 && parameter_type.IsPointer) {
-                               Report.Error (1103, Location, "The type of extension method cannot be `{0}'",
-                                       TypeManager.CSharpName (parameter_type));
+                               if ((modFlags & Modifier.This) != 0 && parameter_type.IsPointer) {
+                                       Report.Error (1103, Location, "The type of extension method cannot be `{0}'",
+                                               TypeManager.CSharpName (parameter_type));
+                               }
                        }
 
                        return parameter_type;
index cd938eeec63e2ef157b8cebe35c0e5353aeb402e..d8a90577092417ca0d580c960f5f11523b34bdc4 100644 (file)
@@ -587,6 +587,9 @@ namespace Mono.CSharp {
                        case LanguageVersion.ISO_2:
                                version = "2.0";
                                break;
+                       case LanguageVersion.V_3:
+                               version = "3.0";
+                               break;
                        case LanguageVersion.Default_MCS:
                                Report.Error (1644, loc, "Feature `{0}' is not available in Mono mcs1 compiler. Consider using the `gmcs' compiler instead",
                                              feature);
index e6c2c4b2f1dc5ea543ad89cab34d2add27f13dc4..1e50adb5634121a253d7dc8eb8ae0585315ef2cc 100644 (file)
@@ -24,11 +24,14 @@ namespace Mono.CSharp {
                ISO_1           = 1,
                Default_MCS     = 2,
                ISO_2           = 3,
-               LINQ            = 4,
-               Future          = 5,
-
-#if GMCS_SOURCE
-               Default         = LINQ
+               V_3                     = 4,
+               V_4                     = 5,
+               Future          = 100,
+
+#if NET_4_0
+               Default         = V_4,
+#elif GMCS_SOURCE
+               Default         = V_3
 #else
                Default         = Default_MCS
 #endif