[692149] Fixed ordering of named arguments list when starting with positional argument
authorMarek Safar <marek.safar@gmail.com>
Mon, 16 May 2011 15:41:39 +0000 (16:41 +0100)
committerMarek Safar <marek.safar@gmail.com>
Mon, 16 May 2011 15:43:25 +0000 (16:43 +0100)
mcs/mcs/argument.cs
mcs/tests/gtest-named-04.cs [new file with mode: 0644]
mcs/tests/ver-il-net_4_0.xml

index 050644f06ab4a10f6e3ec76ae7eb1e325b19c6f7..a246066896e4620d9111b3216b0255476038443c 100644 (file)
@@ -158,28 +158,18 @@ namespace Mono.CSharp
                }
        }
 
-       public class NamedArgument : Argument
+       public class MovableArgument : Argument
        {
-               public readonly string Name;
-               readonly Location loc;
                LocalTemporary variable;
 
-               public NamedArgument (string name, Location loc, Expression expr)
-                       : this (name, loc, expr, AType.None)
+               public MovableArgument (Argument arg)
+                       : this (arg.Expr, arg.ArgType)
                {
                }
 
-               public NamedArgument (string name, Location loc, Expression expr, AType modifier)
+               protected MovableArgument (Expression expr, AType modifier)
                        : base (expr, modifier)
                {
-                       this.Name = name;
-                       this.loc = loc;
-               }
-
-               public override Expression CreateExpressionTree (ResolveContext ec)
-               {
-                       ec.Report.Error (853, loc, "An expression tree cannot contain named argument");
-                       return base.CreateExpressionTree (ec);
                }
 
                public override void Emit (EmitContext ec)
@@ -208,6 +198,30 @@ namespace Mono.CSharp
 
                        Expr = variable;
                }
+       }
+
+       public class NamedArgument : MovableArgument
+       {
+               public readonly string Name;
+               readonly Location loc;
+
+               public NamedArgument (string name, Location loc, Expression expr)
+                       : this (name, loc, expr, AType.None)
+               {
+               }
+
+               public NamedArgument (string name, Location loc, Expression expr, AType modifier)
+                       : base (expr, modifier)
+               {
+                       this.Name = name;
+                       this.loc = loc;
+               }
+
+               public override Expression CreateExpressionTree (ResolveContext ec)
+               {
+                       ec.Report.Error (853, loc, "An expression tree cannot contain named argument");
+                       return base.CreateExpressionTree (ec);
+               }
 
                public Location Location {
                        get { return loc; }
@@ -218,24 +232,25 @@ namespace Mono.CSharp
        {
                sealed class ArgumentsOrdered : Arguments
                {
-                       List<NamedArgument> ordered;
+                       readonly List<MovableArgument> ordered;
 
                        public ArgumentsOrdered (Arguments args)
                                : base (args.Count)
                        {
                                AddRange (args);
-                               ordered = new List<NamedArgument> ();
+                               ordered = new List<MovableArgument> ();
                        }
 
-                       public void AddOrdered (NamedArgument na)
+                       public void AddOrdered (MovableArgument arg)
                        {
-                               ordered.Add (na);
+                               ordered.Add (arg);
                        }
 
                        public override Expression[] Emit (EmitContext ec, bool dup_args)
                        {
-                               foreach (NamedArgument na in ordered)
-                                       na.EmitAssign (ec);
+                               foreach (var a in ordered) {
+                                       a.EmitAssign (ec);
+                               }
 
                                return base.Emit (ec, dup_args);
                        }
@@ -488,9 +503,24 @@ namespace Mono.CSharp
                                return this;
 
                        ArgumentsOrdered ra = this as ArgumentsOrdered;
-                       if (ra == null)
+                       if (ra == null) {
                                ra = new ArgumentsOrdered (this);
 
+                               for (int i = 0; i < args.Count; ++i) {
+                                       var la = args [i];
+                                       if (la == a)
+                                               break;
+
+                                       var ma = la as MovableArgument;
+                                       if (ma == null) {
+                                               ma = new MovableArgument (la);
+                                               ra.args[i] = ma;
+                                       }
+
+                                       ra.AddOrdered (ma);
+                               }
+                       }
+
                        ra.AddOrdered (a);
                        return ra;
                }
diff --git a/mcs/tests/gtest-named-04.cs b/mcs/tests/gtest-named-04.cs
new file mode 100644 (file)
index 0000000..17cb06b
--- /dev/null
@@ -0,0 +1,48 @@
+class Test
+{
+       static string V;
+
+       static int f (int a)
+       {
+               V += a;
+               return a;
+       }
+
+       static void m (int a, int b, int c)
+       {
+       }
+
+       static void m (int a, int b, int c, int d)
+       {
+       }
+
+       static int Main ()
+       {
+               V = "";
+               m (f (1), b: f (2), c: f (3));
+               if (V != "123")
+                       return 1;
+
+               V = "";
+               m (a: f (1), c: f (2), b: f (3));
+               if (V != "123")
+                       return 2;
+
+               V = "";
+               m (f (1), c: f (2), b: f (3));
+               if (V != "123")
+                       return 3;
+
+               V = "";
+               m (f (1), f (2), c: f (3), d: f (4));
+               if (V != "1234")
+                       return 4;
+
+               V = "";
+               m (f (1), f (2), d: f (3), c: f (4));
+               if (V != "1234")
+                       return 5;
+
+               return 0;
+       }
+}
index 8f054670757536a1e36a005541ca2a80fb8c08c2..efc96725de8b67c08b788a10154d47d5192f128a 100644 (file)
       </method>
     </type>
   </test>
+  <test name="gtest-named-04.cs">
+    <type name="Test">
+      <method name="Int32 f(Int32)">
+        <size>23</size>
+      </method>
+      <method name="Void m(Int32, Int32, Int32)">
+        <size>1</size>
+      </method>
+      <method name="Void m(Int32, Int32, Int32, Int32)">
+        <size>1</size>
+      </method>
+      <method name="Int32 Main()">
+        <size>303</size>
+      </method>
+      <method name="Void .ctor()">
+        <size>7</size>
+      </method>
+    </type>
+  </test>
   <test name="gtest-optional-01.cs">
     <type name="C">
       <method name="Void TestA(Int32)">