Merge pull request #2040 from esdrubal/monoman
[mono.git] / mcs / mcs / method.cs
index 32d76fbc8c8b0c9ee16d8cd41726cd3ee96a3fab..d1e0b3e2b83027c080f3cd70b615ba25f28411b2 100644 (file)
@@ -165,6 +165,12 @@ namespace Mono.CSharp {
                        return s + parameters.GetSignatureForDocumentation ();
                }
 
+               public override void PrepareEmit ()
+               {
+                       base.PrepareEmit ();
+                       parameters.ResolveDefaultValues (this);
+               }
+
                public MethodSpec Spec {
                        get { return spec; }
                }
@@ -816,8 +822,10 @@ namespace Mono.CSharp {
 
                #endregion
 
-               public virtual void PrepareEmit ()
+               public override void PrepareEmit ()
                {
+                       base.PrepareEmit ();
+
                        var mb = MethodData.DefineMethodBuilder (Parent);
 
                        if (CurrentTypeParameters != null) {
@@ -1083,19 +1091,12 @@ namespace Mono.CSharp {
                                        }
 
                                        if (base_override.IsGeneric) {
-                                               ObsoleteAttribute oa;
                                                foreach (var base_tp in base_tparams) {
-                                                       oa = base_tp.BaseType.GetAttributeObsolete ();
-                                                       if (oa != null) {
-                                                               AttributeTester.Report_ObsoleteMessage (oa, base_tp.BaseType.GetSignatureForError (), Location, Report);
-                                                       }
+                                                       base_tp.BaseType.CheckObsoleteness (this, Location);
 
                                                        if (base_tp.InterfacesDefined != null) {
                                                                foreach (var iface in base_tp.InterfacesDefined) {
-                                                                       oa = iface.GetAttributeObsolete ();
-                                                                       if (oa != null) {
-                                                                               AttributeTester.Report_ObsoleteMessage (oa, iface.GetSignatureForError (), Location, Report);
-                                                                       }
+                                                                       iface.CheckObsoleteness (this, Location);
                                                                }
                                                        }
                                                }
@@ -1187,7 +1188,8 @@ namespace Mono.CSharp {
 
                                        // Using container location because the interface can be implemented
                                        // by base class
-                                       container.Compiler.Report.Error (425, container.Location,
+                                       var tp = (tparams [i].MemberDefinition as MemberCore) ?? container;
+                                       container.Compiler.Report.Error (425, tp.Location,
                                                "The constraints for type parameter `{0}' of method `{1}' must match the constraints for type parameter `{2}' of interface method `{3}'. Consider using an explicit interface implementation instead",
                                                tparams[i].GetSignatureForError (), method.GetSignatureForError (),
                                                base_tparams[i].GetSignatureForError (), baseMethod.GetSignatureForError ());
@@ -1284,7 +1286,7 @@ namespace Mono.CSharp {
                        // This is used to track the Entry Point,
                        //
                        var settings = Compiler.Settings;
-                       if (settings.NeedsEntryPoint && MemberName.Name == "Main" && (settings.MainClass == null || settings.MainClass == Parent.TypeBuilder.FullName)) {
+                       if (settings.NeedsEntryPoint && MemberName.Name == "Main" && !IsPartialDefinition && (settings.MainClass == null || settings.MainClass == Parent.TypeBuilder.FullName)) {
                                if (IsEntryPoint ()) {
                                        if (Parent.DeclaringAssembly.EntryPoint == null) {
                                                if (Parent.IsGenericOrParentIsGeneric || MemberName.IsGeneric) {
@@ -1335,6 +1337,12 @@ namespace Mono.CSharp {
                                if (IsPartialDefinition) {
                                        if (partialMethodImplementation != null && CurrentTypeParameters != null) {
                                                CurrentTypeParameters.CheckPartialConstraints (partialMethodImplementation);
+
+                                               var otp = partialMethodImplementation.CurrentTypeParameters;
+                                               for (int i = 0; i < CurrentTypeParameters.Count; ++i) {
+                                                       var tp = CurrentTypeParameters [i];
+                                                       tp.Define (otp[i]);
+                                               }
                                        }
 
                                        return;
@@ -1392,17 +1400,36 @@ namespace Mono.CSharp {
 
                        // Ensure we are always using method declaration parameters
                        for (int i = 0; i < methodDefinition.parameters.Count; ++i ) {
-                               parameters [i].Name = methodDefinition.parameters [i].Name;
-                               parameters [i].DefaultValue = methodDefinition.parameters [i].DefaultValue;
+                               var md_p = methodDefinition.parameters [i];
+                               var p = parameters [i];
+                               p.Name = md_p.Name;
+                               p.DefaultValue = md_p.DefaultValue;
+                               if (md_p.OptAttributes != null) {
+                                       Attributes.AttachFromPartial (p, md_p);
+                               }
                        }
 
-                       if (methodDefinition.attributes == null)
-                               return;
+                       if (methodDefinition.attributes != null) {
+                               if (attributes == null) {
+                                       attributes = methodDefinition.attributes;
+                               } else {
+                                       attributes.Attrs.AddRange (methodDefinition.attributes.Attrs);
+                               }
+                       }
 
-                       if (attributes == null) {
-                               attributes = methodDefinition.attributes;
-                       } else {
-                               attributes.Attrs.AddRange (methodDefinition.attributes.Attrs);
+                       if (CurrentTypeParameters != null) {
+                               for (int i = 0; i < CurrentTypeParameters.Count; ++i) {
+                                       var tp_other = methodDefinition.CurrentTypeParameters [i];
+                                       if (tp_other.OptAttributes == null)
+                                               continue;
+
+                                       var tp = CurrentTypeParameters [i];
+                                       if (tp.OptAttributes == null) {
+                                               tp.OptAttributes = tp_other.OptAttributes;
+                                       } else {
+                                               tp.OptAttributes.Attrs.AddRange (tp.OptAttributes.Attrs);
+                                       }
+                               }
                        }
                }
        }
@@ -1468,15 +1495,6 @@ namespace Mono.CSharp {
                                                        "`{0}': Struct constructors cannot call base constructors", caller_builder.GetSignatureForError ());
                                                return this;
                                        }
-                               } else {
-                                       //
-                                       // It is legal to have "this" initializers that take no arguments
-                                       // in structs
-                                       //
-                                       // struct D { public D (int a) : this () {}
-                                       //
-                                       if (ec.CurrentType.IsStruct && argument_list == null)
-                                               return this;
                                }
 
                                base_ctor = ConstructorLookup (ec, type, ref argument_list, loc);
@@ -1506,7 +1524,7 @@ namespace Mono.CSharp {
                        
                        var call = new CallEmitter ();
                        call.InstanceExpression = new CompilerGeneratedThis (type, loc); 
-                       call.EmitPredefined (ec, base_ctor, argument_list);
+                       call.EmitPredefined (ec, base_ctor, argument_list, false);
                }
 
                public override void EmitStatement (EmitContext ec)
@@ -1591,7 +1609,6 @@ namespace Mono.CSharp {
                }
 
                public bool IsPrimaryConstructor { get; set; }
-
                
                MethodBase IMethodDefinition.Metadata {
                        get {
@@ -1634,12 +1651,6 @@ namespace Mono.CSharp {
                protected override bool CheckBase ()
                {
                        if ((ModFlags & Modifiers.STATIC) != 0) {
-                               if (!parameters.IsEmpty) {
-                                       Report.Error (132, Location, "`{0}': The static constructor must be parameterless",
-                                               GetSignatureForError ());
-                                       return false;
-                               }
-
                                if ((caching_flags & Flags.MethodOverloadsExist) != 0)
                                        Parent.MemberCache.CheckExistingMembersOverloads (this, parameters);
 
@@ -1654,12 +1665,6 @@ namespace Mono.CSharp {
                        if ((caching_flags & Flags.MethodOverloadsExist) != 0)
                                Parent.MemberCache.CheckExistingMembersOverloads (this, parameters);
 
-                       if (Parent.PartialContainer.Kind == MemberKind.Struct && parameters.IsEmpty) {
-                               Report.Error (568, Location, 
-                                       "Structs cannot contain explicit parameterless constructors");
-                               return false;
-                       }
-
                        CheckProtectedModifier ();
                        
                        return true;
@@ -1680,16 +1685,21 @@ namespace Mono.CSharp {
                        if (!CheckBase ())
                                return false;
 
-                       if (Parent.PrimaryConstructorParameters != null && !IsPrimaryConstructor) {
-                               if (Parent.Kind == MemberKind.Struct) {
-                                       Report.Error (9009, Location, "`{0}': Structs with primary constructor cannot have explicit constructor",
+                       if (Parent.PrimaryConstructorParameters != null && !IsPrimaryConstructor && !IsStatic) {
+                               if (Parent.Kind == MemberKind.Struct && Initializer is ConstructorThisInitializer && Initializer.Arguments == null) {
+                                       Report.Error (8043, Location, "`{0}': Structs with primary constructor cannot specify default constructor initializer",
                                                GetSignatureForError ());
                                } else if (Initializer == null || Initializer is ConstructorBaseInitializer) {
-                                       Report.Error (9002, Location, "`{0}': Instance constructor of type with primary constructor must specify `this' constructor initializer",
+                                       Report.Error (8037, Location, "`{0}': Instance constructor of type with primary constructor must specify `this' constructor initializer",
                                                GetSignatureForError ());
                                }
                        }
 
+                       if ((ModFlags & Modifiers.EXTERN) != 0 && Initializer != null) {
+                               Report.Error (8091, Location, "`{0}': Contructors cannot be extern and have a constructor initializer",
+                                       GetSignatureForError ());
+                       }
+
                        var ca = ModifiersExtensions.MethodAttr (ModFlags) | MethodAttributes.RTSpecialName | MethodAttributes.SpecialName;
 
                        ConstructorBuilder = Parent.TypeBuilder.DefineConstructor (
@@ -1745,6 +1755,14 @@ namespace Mono.CSharp {
                        bc.Set (ResolveContext.Options.ConstructorScope);
 
                        if (block != null) {
+                               if (!IsStatic && Initializer == null && Parent.PartialContainer.Kind == MemberKind.Struct) {
+                                       //
+                                       // If this is a non-static `struct' constructor and doesn't have any
+                                       // initializer, it must initialize all of the struct's fields.
+                                       //
+                                       block.AddThisVariable (bc);
+                               }
+
                                //
                                // If we use a "this (...)" constructor initializer, then
                                // do not emit field initializers, they are initialized in the other constructor
@@ -1753,16 +1771,8 @@ namespace Mono.CSharp {
                                        Parent.PartialContainer.ResolveFieldInitializers (bc);
 
                                if (!IsStatic) {
-                                       if (Initializer == null) {
-                                               if (Parent.PartialContainer.Kind == MemberKind.Struct) {
-                                                       //
-                                                       // If this is a non-static `struct' constructor and doesn't have any
-                                                       // initializer, it must initialize all of the struct's fields.
-                                                       //
-                                                       block.AddThisVariable (bc);
-                                               } else if (Parent.PartialContainer.Kind == MemberKind.Class) {
-                                                       Initializer = new GeneratedBaseInitializer (Location, null);
-                                               }
+                                       if (Initializer == null && Parent.PartialContainer.Kind == MemberKind.Class) {
+                                               Initializer = new GeneratedBaseInitializer (Location, null);
                                        }
 
                                        if (Initializer != null) {
@@ -2223,6 +2233,9 @@ namespace Mono.CSharp {
 
                protected override bool CheckBase ()
                {
+                       if ((caching_flags & Flags.MethodOverloadsExist) != 0)
+                               CheckForDuplications ();
+
                        // Don't check base, destructors have special syntax
                        return true;
                }
@@ -2539,6 +2552,9 @@ namespace Mono.CSharp {
                        Implicit,
                        Explicit,
 
+                       // Pattern matching
+                       Is,
+
                        // Just because of enum
                        TOP
                };
@@ -2576,6 +2592,7 @@ namespace Mono.CSharp {
                        names [(int) OpType.LessThanOrEqual] = new string [] { "<=", "op_LessThanOrEqual" };
                        names [(int) OpType.Implicit] = new string [] { "implicit", "op_Implicit" };
                        names [(int) OpType.Explicit] = new string [] { "explicit", "op_Explicit" };
+                       names [(int) OpType.Is] = new string[] { "is", "op_Is" };
                }
 
                public Operator (TypeDefinition parent, OpType type, FullNamedExpression ret_type, Modifiers mod_flags, ParametersCompiled parameters,
@@ -2631,7 +2648,7 @@ namespace Mono.CSharp {
                        else if (OperatorType == OpType.Implicit)
                                Parent.MemberCache.CheckExistingMembersOverloads (this, GetMetadataName (OpType.Explicit), parameters);
 
-                       TypeSpec declaring_type = Parent.CurrentType;
+                       TypeSpec declaring_type = Parent.PartialContainer.CurrentType;
                        TypeSpec return_type = MemberType;
                        TypeSpec first_arg_type = ParameterTypes [0];