Merge pull request #5714 from alexischr/update_bockbuild
[mono.git] / mcs / mcs / method.cs
index 6835ec32b061d3c35ffdbc90a85e1919c49ae7e7..ccd4898e91c7a5ef5169a3460c462ea429e8f38f 100644 (file)
@@ -21,7 +21,7 @@ using System.Linq;
 using Mono.CompilerServices.SymbolWriter;
 using System.Runtime.CompilerServices;
 
-#if NET_2_1
+#if MOBILE
 using XmlElement = System.Object;
 #else
 using System.Xml;
@@ -165,8 +165,9 @@ namespace Mono.CSharp {
                        return s + parameters.GetSignatureForDocumentation ();
                }
 
-               public virtual void PrepareEmit ()
+               public override void PrepareEmit ()
                {
+                       base.PrepareEmit ();
                        parameters.ResolveDefaultValues (this);
                }
 
@@ -443,6 +444,10 @@ namespace Mono.CSharp {
                        return ms;
                }
 
+#if DEBUG
+               int counter = 100000;
+#endif
+
                public MethodSpec MakeGenericMethod (IMemberContext context, params TypeSpec[] targs)
                {
                        if (targs == null)
@@ -464,6 +469,10 @@ namespace Mono.CSharp {
                        inflated.constraints = TypeParameterSpec.InflateConstraints (inflator, constraints ?? GenericDefinition.TypeParameters);
                        inflated.state |= StateFlags.PendingMakeMethod;
 
+#if DEBUG
+                       inflated.ID += counter;
+                       counter += 100000;
+#endif
                        //                      if (inflated.parent == null)
                        //                              inflated.parent = parent;
 
@@ -549,10 +558,7 @@ namespace Mono.CSharp {
                public override void ApplyAttributeBuilder (Attribute a, MethodSpec ctor, byte[] cdata, PredefinedAttributes pa)
                {
                        if (a.Target == AttributeTargets.ReturnValue) {
-                               if (return_attributes == null)
-                                       return_attributes = new ReturnParameter (this, MethodBuilder, Location);
-
-                               return_attributes.ApplyAttributeBuilder (a, ctor, cdata, pa);
+                               CreateReturnBuilder ().ApplyAttributeBuilder (a, ctor, cdata, pa);
                                return;
                        }
 
@@ -615,6 +621,11 @@ namespace Mono.CSharp {
                        return new EmitContext (this, ig, MemberType, sourceMethod);
                }
 
+               ReturnParameter CreateReturnBuilder ()
+               {
+                       return return_attributes ?? (return_attributes = new ReturnParameter (this, MethodBuilder, Location));
+               }
+
                public override bool Define ()
                {
                        if (!base.Define ())
@@ -646,7 +657,7 @@ namespace Mono.CSharp {
 
                                explicit_name = null;
                        } else {
-                               MethodData = new MethodData (this, ModFlags, flags, this, base_method);
+                               MethodData = new MethodData (this, ModFlags, flags, this);
 
                                if (!MethodData.Define (Parent.PartialContainer, GetFullName (MemberName)))
                                        return false;
@@ -702,11 +713,13 @@ namespace Mono.CSharp {
                                Module.PredefinedAttributes.DebuggerStepThrough.EmitAttribute (MethodBuilder);
 
                        if (ReturnType.BuiltinType == BuiltinTypeSpec.Type.Dynamic) {
-                               return_attributes = new ReturnParameter (this, MethodBuilder, Location);
-                               Module.PredefinedAttributes.Dynamic.EmitAttribute (return_attributes.Builder);
+                               Module.PredefinedAttributes.Dynamic.EmitAttribute (CreateReturnBuilder ().Builder);
                        } else if (ReturnType.HasDynamicElement) {
-                               return_attributes = new ReturnParameter (this, MethodBuilder, Location);
-                               Module.PredefinedAttributes.Dynamic.EmitAttribute (return_attributes.Builder, ReturnType, Location);
+                               Module.PredefinedAttributes.Dynamic.EmitAttribute (CreateReturnBuilder ().Builder, ReturnType, Location);
+                       }
+
+                       if (ReturnType.HasNamedTupleElement) {
+                               Module.PredefinedAttributes.TupleElementNames.EmitAttribute (CreateReturnBuilder ().Builder, ReturnType, Location);
                        }
 
                        if (OptAttributes != null)
@@ -722,7 +735,12 @@ namespace Mono.CSharp {
                                }
                        }
 
-                       if (type_expr != null)
+                       //
+                       // Optimization but it also covers cases where we cannot check
+                       // constraints because method is captured into generated class
+                       // and type parameters context is now different
+                       //
+                       if (type_expr != null && !IsCompilerGenerated)
                                ConstraintChecker.Check (this, member_type, type_expr.Location);
 
                        base.Emit ();
@@ -1090,19 +1108,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);
                                                                }
                                                        }
                                                }
@@ -1411,11 +1422,7 @@ namespace Mono.CSharp {
                                p.Name = md_p.Name;
                                p.DefaultValue = md_p.DefaultValue;
                                if (md_p.OptAttributes != null) {
-                                       if (p.OptAttributes == null) {
-                                               p.OptAttributes = md_p.OptAttributes;
-                                       } else {
-                                               p.OptAttributes.Attrs.AddRange (md_p.OptAttributes.Attrs);
-                                       }
+                                       Attributes.AttachFromPartial (p, md_p);
                                }
                        }
 
@@ -1777,8 +1784,12 @@ namespace Mono.CSharp {
                                // If we use a "this (...)" constructor initializer, then
                                // do not emit field initializers, they are initialized in the other constructor
                                //
-                               if (!(Initializer is ConstructorThisInitializer))
+                               if (!(Initializer is ConstructorThisInitializer)) {
+                                       var errors = Compiler.Report.Errors;
                                        Parent.PartialContainer.ResolveFieldInitializers (bc);
+                                       if (errors != Compiler.Report.Errors)
+                                               return;
+                               }
 
                                if (!IsStatic) {
                                        if (Initializer == null && Parent.PartialContainer.Kind == MemberKind.Class) {
@@ -1868,6 +1879,7 @@ namespace Mono.CSharp {
                        if (debug_builder == null)
                                return;
 
+#if !FULL_AOT_RUNTIME
                        var token = ConstructorBuilder.GetToken ();
                        int t = token.Token;
 #if STATIC
@@ -1876,6 +1888,7 @@ namespace Mono.CSharp {
 #endif
 
                        debug_builder.DefineMethod (file, t);
+#endif
                }
 
                #region IMethodData Members
@@ -1938,7 +1951,6 @@ namespace Mono.CSharp {
                protected Modifiers modifiers;
                protected MethodAttributes flags;
                protected TypeSpec declaring_type;
-               protected MethodSpec parent_method;
                SourceMethodBuilder debug_builder;
                string full_name;
 
@@ -1971,15 +1983,6 @@ namespace Mono.CSharp {
                        this.method = method;
                }
 
-               public MethodData (InterfaceMemberBase member,
-                                  Modifiers modifiers, MethodAttributes flags, 
-                                  IMethodData method,
-                                  MethodSpec parent_method)
-                       : this (member, modifiers, flags, method)
-               {
-                       this.parent_method = parent_method;
-               }
-
                public bool Define (TypeDefinition container, string method_full_name)
                {
                        PendingImplementation pending = container.PendingImplementations;
@@ -2036,6 +2039,20 @@ namespace Mono.CSharp {
                                                                }
                                                        }
                                                }
+
+                                               if (!NamedTupleSpec.CheckOverrideName (member.MemberType, implementing.ReturnType)) {
+                                                       container.Compiler.Report.Error (8141, method.Location,
+                                                               "The tuple element names in the signature type of member `{0}' must match the tuple element names of interface member `{1}''",
+                                                               member.GetSignatureForError (), implementing.GetSignatureForError ());
+                                               }
+
+                                               var p_member = method as IParametersMember;
+                                               var p_implementing = implementing as IParametersMember;
+                                               if (p_member != null && p_implementing != null && !NamedTupleSpec.CheckOverrideName (p_member, p_implementing)) {
+                                                       container.Compiler.Report.Error (8141, method.Location,
+                                                               "The tuple element names in the signature type of member `{0}' must match the tuple element names of interface member `{1}''",
+                                                               member.GetSignatureForError (), implementing.GetSignatureForError ());
+                                               }
                                        }
                                }
                        } else {
@@ -2064,7 +2081,7 @@ namespace Mono.CSharp {
                                        }
                                } else {
                                        //
-                                       // Setting implementin to null inside this block will trigger a more
+                                       // Setting implementing to null inside this block will trigger a more
                                        // verbose error reporting for missing interface implementations
                                        //
                                        if (implementing.DeclaringType.IsInterface) {
@@ -2198,6 +2215,7 @@ namespace Mono.CSharp {
                        if (debug_builder == null)
                                return;
 
+#if !FULL_AOT_RUNTIME
                        var token = builder.GetToken ();
                        int t = token.Token;
 #if STATIC
@@ -2206,6 +2224,7 @@ namespace Mono.CSharp {
 #endif
 
                        debug_builder.DefineMethod (file, t);
+#endif
                }
        }
 
@@ -2411,9 +2430,7 @@ namespace Mono.CSharp {
                        }
 
                        if (a.Target == AttributeTargets.ReturnValue) {
-                               if (return_attributes == null)
-                                       return_attributes = new ReturnParameter (this, method_data.MethodBuilder, Location);
-
+                               CreateReturnBuilder ();
                                return_attributes.ApplyAttributeBuilder (a, ctor, cdata, pa);
                                return;
                        }
@@ -2432,6 +2449,11 @@ namespace Mono.CSharp {
                        throw new NotSupportedException ();
                }
 
+               ReturnParameter CreateReturnBuilder ()
+               {
+                       return return_attributes ?? (return_attributes = new ReturnParameter (this, method_data.MethodBuilder, Location));
+               }
+
                public virtual void Emit (TypeDefinition parent)
                {
                        method_data.Emit (parent);
@@ -2442,11 +2464,13 @@ namespace Mono.CSharp {
                                Module.PredefinedAttributes.DebuggerHidden.EmitAttribute (method_data.MethodBuilder);
 
                        if (ReturnType.BuiltinType == BuiltinTypeSpec.Type.Dynamic) {
-                               return_attributes = new ReturnParameter (this, method_data.MethodBuilder, Location);
-                               Module.PredefinedAttributes.Dynamic.EmitAttribute (return_attributes.Builder);
+                               Module.PredefinedAttributes.Dynamic.EmitAttribute (CreateReturnBuilder ().Builder);
                        } else if (ReturnType.HasDynamicElement) {
-                               return_attributes = new ReturnParameter (this, method_data.MethodBuilder, Location);
-                               Module.PredefinedAttributes.Dynamic.EmitAttribute (return_attributes.Builder, ReturnType, Location);
+                               Module.PredefinedAttributes.Dynamic.EmitAttribute (CreateReturnBuilder ().Builder, ReturnType, Location);
+                       }
+
+                       if (ReturnType.HasNamedTupleElement) {
+                               Module.PredefinedAttributes.TupleElementNames.EmitAttribute (CreateReturnBuilder ().Builder, ReturnType, Location);
                        }
 
                        if (OptAttributes != null)