[mcs] Add more error checks
[mono.git] / mcs / mcs / class.cs
index 289dc5fe2cac434faf054d4b5f78573f0a4aee35..cda04c0e840c340724df311555d8b98032efd8bf 100644 (file)
@@ -553,7 +553,8 @@ namespace Mono.CSharp
                public int AnonymousMethodsCounter;
                public int MethodGroupsCounter;
 
-               static readonly string[] attribute_targets = new string[] { "type" };
+               static readonly string[] attribute_targets = new [] { "type" };
+               static readonly string[] attribute_targets_primary = new [] { "type", "method" };
 
                /// <remarks>
                ///  The pending methods that need to be implemented
@@ -732,6 +733,10 @@ namespace Mono.CSharp
 
                public ParametersCompiled PrimaryConstructorParameters { get; set; }
 
+               public Arguments PrimaryConstructorBaseArguments { get; set; }
+
+               public Location PrimaryConstructorBaseArgumentsStart { get; set; }
+
                public TypeParameters TypeParametersAll {
                        get {
                                return all_type_parameters;
@@ -740,7 +745,7 @@ namespace Mono.CSharp
 
                public override string[] ValidAttributeTargets {
                        get {
-                               return attribute_targets;
+                               return PrimaryConstructorParameters != null ? attribute_targets_primary : attribute_targets;
                        }
                }
 
@@ -812,9 +817,6 @@ namespace Mono.CSharp
                        if (symbol is TypeParameter) {
                                Report.Error (692, symbol.Location,
                                        "Duplicate type parameter `{0}'", symbol.GetSignatureForError ());
-                       } else if (symbol is PrimaryConstructorField && mc is TypeParameter) {
-                               Report.Error (9003, symbol.Location, "Primary constructor of type `{0}' has parameter of same name as type parameter `{1}'",
-                                       symbol.Parent.GetSignatureForError (), symbol.GetSignatureForError ());
                        } else {
                                Report.Error (102, symbol.Location,
                                        "The type `{0}' already contains a definition for `{1}'",
@@ -893,6 +895,21 @@ namespace Mono.CSharp
 
                public override void ApplyAttributeBuilder (Attribute a, MethodSpec ctor, byte[] cdata, PredefinedAttributes pa)
                {
+                       if (a.Target == AttributeTargets.Method) {
+                               foreach (var m in members) {
+                                       var c = m as Constructor;
+                                       if (c == null)
+                                               continue;
+
+                                       if (c.IsPrimaryConstructor) {
+                                               c.ApplyAttributeBuilder (a, ctor, cdata, pa);
+                                               return;
+                                       }
+                               }
+
+                               throw new InternalErrorException ();
+                       }
+
                        if (has_normal_indexers && a.Type == pa.DefaultMember) {
                                Report.Error (646, a.Location, "Cannot specify the `DefaultMember' attribute on type containing an indexer");
                                return;
@@ -1526,7 +1543,7 @@ namespace Mono.CSharp
 
                                if (PrimaryConstructorParameters != null) {
                                        if (PartialContainer.PrimaryConstructorParameters != null) {
-                                               Report.Error (9001, Location, "Only one part of a partial type can declare primary constructor parameters");
+                                               Report.Error (8036, Location, "Only one part of a partial type can declare primary constructor parameters");
                                        } else {
                                                PartialContainer.PrimaryConstructorParameters = PrimaryConstructorParameters;
                                        }
@@ -1559,6 +1576,10 @@ namespace Mono.CSharp
                        }
 
                        if (iface_exprs != null) {
+                               if (!PrimaryConstructorBaseArgumentsStart.IsNull) {
+                                       Report.Error (8049, PrimaryConstructorBaseArgumentsStart, "Implemented interfaces cannot have arguments");
+                               }
+
                                foreach (var iface_type in iface_exprs) {
                                        // Prevents a crash, the interface might not have been resolved: 442144
                                        if (iface_type == null)
@@ -1587,8 +1608,12 @@ namespace Mono.CSharp
                        // defined after current container
                        //
                        if (class_partial_parts != null) {
-                               foreach (var pp in class_partial_parts)
+                               foreach (var pp in class_partial_parts) {
+                                       if (pp.PrimaryConstructorBaseArguments != null)
+                                               PrimaryConstructorBaseArguments = pp.PrimaryConstructorBaseArguments;
+
                                        pp.DoDefineBaseType ();
+                               }
 
                        }
 
@@ -2553,7 +2578,7 @@ namespace Mono.CSharp
                {
                }
 
-               public Arguments PrimaryConstructorBaseArguments { get; set; }
+               public ToplevelBlock PrimaryConstructorBlock { get; set; }
 
                protected override TypeAttributes TypeAttr {
                        get {
@@ -2583,12 +2608,6 @@ namespace Mono.CSharp
                                        return;
                                }
 
-                               if (symbol is PrimaryConstructorField) {
-                                       Report.Error (9004, symbol.Location, "Primary constructor of type `{0}' has parameter of same name as containing type",
-                                               symbol.Parent.GetSignatureForError ());
-                                       return;
-                               }
-                       
                                InterfaceMemberBase imb = symbol as InterfaceMemberBase;
                                if (imb == null || !imb.IsExplicitImpl) {
                                        Report.SymbolRelatedToPreviousError (this);
@@ -2632,23 +2651,30 @@ namespace Mono.CSharp
                        // The default static constructor is private
 
                        Modifiers mods;
+                       ParametersCompiled parameters = null;
                        if (is_static) {
                                mods = Modifiers.STATIC | Modifiers.PRIVATE;
+                               parameters = ParametersCompiled.EmptyReadOnlyParameters;
                        } else {
                                mods = ((ModFlags & Modifiers.ABSTRACT) != 0) ? Modifiers.PROTECTED : Modifiers.PUBLIC;
+                               parameters = PrimaryConstructorParameters ?? ParametersCompiled.EmptyReadOnlyParameters;
                        }
 
-                       var c = new Constructor (this, MemberName.Name, mods, null, PrimaryConstructorParameters ?? ParametersCompiled.EmptyReadOnlyParameters, Location);
+                       var c = new Constructor (this, MemberName.Name, mods, null, parameters, Location);
                        if (Kind == MemberKind.Class)
                                c.Initializer = new GeneratedBaseInitializer (Location, PrimaryConstructorBaseArguments);
 
-                       if (PrimaryConstructorParameters != null)
+                       if (PrimaryConstructorParameters != null && !is_static)
                                c.IsPrimaryConstructor = true;
                        
                        AddConstructor (c, true);
-                       c.Block = new ToplevelBlock (Compiler, c.ParameterInfo, Location) {
-                               IsCompilerGenerated = true
-                       };
+                       if (PrimaryConstructorBlock == null) {
+                               c.Block = new ToplevelBlock (Compiler, parameters, Location) {
+                                       IsCompilerGenerated = true
+                               };
+                       } else {
+                               c.Block = PrimaryConstructorBlock;
+                       }
 
                        return c;
                }
@@ -2659,14 +2685,20 @@ namespace Mono.CSharp
 
                        if (PrimaryConstructorParameters != null) {
                                foreach (Parameter p in PrimaryConstructorParameters.FixedParameters) {
-                                       if ((p.ModFlags & Parameter.Modifier.RefOutMask) != 0)
-                                               continue;
-
-                                       var f = new PrimaryConstructorField (this, p);
-                                       AddField (f);
+                                       if (p.Name == MemberName.Name) {
+                                               Report.Error (8039, p.Location, "Primary constructor of type `{0}' has parameter of same name as containing type",
+                                                       GetSignatureForError ());
+                                       }
 
-                                       generated_primary_constructor.Block.AddStatement (
-                                               new StatementExpression (new PrimaryConstructorAssign (f, p), p.Location));
+                                       if (CurrentTypeParameters != null) {
+                                               for (int i = 0; i < CurrentTypeParameters.Count; ++i) {
+                                                       var tp = CurrentTypeParameters [i];
+                                                       if (p.Name == tp.Name) {
+                                                               Report.Error (8038, p.Location, "Primary constructor of type `{0}' has parameter of same name as type parameter `{1}'",
+                                                                       GetSignatureForError (), p.GetSignatureForError ());
+                                                       }
+                                               }
+                                       }
                                }
                        }