8006582: Test for parameter names feature
authorstrarup
Wed, 20 Feb 2013 15:47:14 -0800
changeset 16307 3027c91f329a
parent 16306 da9b3b678b1a
child 16308 a0658c36f717
8006582: Test for parameter names feature Reviewed-by: jjg, darcy, emc
langtools/test/tools/javac/MethodParameters.java
langtools/test/tools/javac/MethodParameters/AnnotationTest.java
langtools/test/tools/javac/MethodParameters/AnonymousClass.java
langtools/test/tools/javac/MethodParameters/AttributeVisitor.java
langtools/test/tools/javac/MethodParameters/ClassFileVisitor.java
langtools/test/tools/javac/MethodParameters/Constructors.java
langtools/test/tools/javac/MethodParameters/EnumTest.java
langtools/test/tools/javac/MethodParameters/InstanceMethods.java
langtools/test/tools/javac/MethodParameters/LambdaTest.java
langtools/test/tools/javac/MethodParameters/LocalClassTest.java
langtools/test/tools/javac/MethodParameters/MemberClassTest.java
langtools/test/tools/javac/MethodParameters/ReflectionVisitor.java
langtools/test/tools/javac/MethodParameters/StaticMethods.java
langtools/test/tools/javac/MethodParameters/Tester.java
langtools/test/tools/javac/MethodParameters/UncommonParamNames.java
langtools/test/tools/javac/MethodParametersTest.java
--- a/langtools/test/tools/javac/MethodParameters.java	Tue Feb 19 20:53:35 2013 -0800
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,344 +0,0 @@
-/*
- * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-
-/*
- * @test
- * @bug 8004727
- * @summary javac should generate method parameters correctly.
- */
-// key: opt.arg.parameters
-import com.sun.tools.classfile.*;
-import com.sun.tools.javac.file.JavacFileManager;
-import com.sun.tools.javac.main.Main;
-import com.sun.tools.javac.util.Context;
-import com.sun.tools.javac.util.Name;
-import com.sun.tools.javac.util.Names;
-import java.io.*;
-import javax.lang.model.element.*;
-import java.util.*;
-
-public class MethodParameters {
-
-    static final String Foo_name = "Foo";
-    static final String Foo_contents =
-        "public class Foo {\n" +
-        "  Foo() {}\n" +
-        "  void foo0() {}\n" +
-        "  void foo2(int j, int k) {}\n" +
-        "}";
-    static final String Bar_name = "Bar";
-    static final String Bar_contents =
-        "public class Bar {\n" +
-        "  Bar(int i) {}" +
-        "  Foo foo() { return new Foo(); }\n" +
-        "}";
-    static final String Baz_name = "Baz";
-    static final String Baz_contents =
-        "public class Baz {\n" +
-        "  int baz;" +
-        "  Baz(int i) {}" +
-        "}";
-    static final String Qux_name = "Qux";
-    static final String Qux_contents =
-        "public class Qux extends Baz {\n" +
-        "  Qux(int i) { super(i); }" +
-        "}";
-    static final File classesdir = new File("methodparameters");
-
-    public static void main(String... args) throws Exception {
-        new MethodParameters().run();
-    }
-
-    void run() throws Exception {
-        classesdir.mkdir();
-        final File Foo_java =
-            writeFile(classesdir, Foo_name + ".java", Foo_contents);
-        final File Bar_java =
-            writeFile(classesdir, Bar_name + ".java", Bar_contents);
-        final File Baz_java =
-            writeFile(classesdir, Baz_name + ".java", Baz_contents);
-        System.err.println("Test compile with -parameter");
-        compile("-parameters", "-d", classesdir.getPath(), Foo_java.getPath());
-        // First test: make sure javac doesn't choke to death on
-        // MethodParameter attributes
-        System.err.println("Test compile with classfile containing MethodParameter attributes");
-        compile("-parameters", "-d", classesdir.getPath(),
-                "-cp", classesdir.getPath(), Bar_java.getPath());
-        System.err.println("Examine class foo");
-        checkFoo();
-        checkBar();
-        System.err.println("Test debug information conflict");
-        compile("-g", "-parameters", "-d", classesdir.getPath(),
-                "-cp", classesdir.getPath(), Baz_java.getPath());
-        System.err.println("Introducing debug information conflict");
-        Baz_java.delete();
-        modifyBaz(false);
-        System.err.println("Checking language model");
-        inspectBaz();
-        System.err.println("Permuting attributes");
-        modifyBaz(true);
-        System.err.println("Checking language model");
-        inspectBaz();
-
-        if(0 != errors)
-            throw new Exception("MethodParameters test failed with " +
-                                errors + " errors");
-    }
-
-    void inspectBaz() throws Exception {
-        final File Qux_java =
-            writeFile(classesdir, Qux_name + ".java", Qux_contents);
-        final String[] args = { "-XDsave-parameter-names", "-d",
-                                classesdir.getPath(),
-                                "-cp", classesdir.getPath(),
-                                Qux_java.getPath() };
-        final StringWriter sw = new StringWriter();
-        final PrintWriter pw = new PrintWriter(sw);
-
-        // We need to be able to crack open javac and look at its data
-        // structures.  We'll rig up a compiler instance, but keep its
-        // Context, thus allowing us to get at the ClassReader.
-        Context context = new Context();
-        Main comp =  new Main("javac", pw);
-        JavacFileManager.preRegister(context);
-
-        // Compile Qux, which uses Baz.
-        comp.compile(args, context);
-        pw.close();
-        final String out = sw.toString();
-        if (out.length() > 0)
-            System.err.println(out);
-
-        // Now get the class reader, construct a name for Baz, and load it.
-        com.sun.tools.javac.jvm.ClassReader cr =
-            com.sun.tools.javac.jvm.ClassReader.instance(context);
-        Name name = Names.instance(context).fromString(Baz_name);
-
-        // Now walk down the language model and check the name of the
-        // parameter.
-        final Element baz = cr.loadClass(name);
-        for (Element e : baz.getEnclosedElements()) {
-            if (e instanceof ExecutableElement) {
-                final ExecutableElement ee = (ExecutableElement) e;
-                final List<? extends VariableElement> params =
-                    ee.getParameters();
-                if (1 != params.size())
-                    throw new Exception("Classfile Baz badly formed: wrong number of methods");
-                final VariableElement param = params.get(0);
-                if (!param.getSimpleName().contentEquals("baz")) {
-                    errors++;
-                    System.err.println("javac did not correctly resolve the metadata conflict, parameter's name reads as " + param.getSimpleName());
-                } else
-                    System.err.println("javac did correctly resolve the metadata conflict");
-            }
-        }
-    }
-
-    void modifyBaz(boolean flip) throws Exception {
-        final File Baz_class = new File(classesdir, Baz_name + ".class");
-        final ClassFile baz = ClassFile.read(Baz_class);
-        final int ind = baz.constant_pool.getUTF8Index("baz");
-        MethodParameters_attribute mpattr = null;
-        int mpind = 0;
-        Code_attribute cattr = null;
-        int cind = 0;
-
-        // Find the indexes of the MethodParameters and the Code attributes
-        if (baz.methods.length != 1)
-            throw new Exception("Classfile Baz badly formed: wrong number of methods");
-        if (!baz.methods[0].getName(baz.constant_pool).equals("<init>"))
-            throw new Exception("Classfile Baz badly formed: method has name " +
-                                baz.methods[0].getName(baz.constant_pool));
-        for (int i = 0; i < baz.methods[0].attributes.attrs.length; i++) {
-            if (baz.methods[0].attributes.attrs[i] instanceof
-                MethodParameters_attribute) {
-                mpattr = (MethodParameters_attribute)
-                    baz.methods[0].attributes.attrs[i];
-                mpind = i;
-            } else if (baz.methods[0].attributes.attrs[i] instanceof
-                       Code_attribute) {
-                cattr = (Code_attribute) baz.methods[0].attributes.attrs[i];
-                cind = i;
-            }
-        }
-        if (null == mpattr)
-            throw new Exception("Classfile Baz badly formed: no method parameters info");
-        if (null == cattr)
-            throw new Exception("Classfile Baz badly formed: no local variable table");
-
-        int flags = mpattr.method_parameter_table[0].flags;
-
-        // Alter the MethodParameters attribute, changing the name of
-        // the parameter from i to baz.  This requires Black Magic...
-        //
-        // The (well-designed) classfile library (correctly) does not
-        // allow us to mess around with the attribute data structures,
-        // or arbitrarily generate new ones.
-        //
-        // Instead, we install a new subclass of Attribute that
-        // hijacks the Visitor pattern and outputs the sequence of
-        // bytes that we want.  This only works in this particular
-        // instance, because we know we'll only every see one kind of
-        // visitor.
-        //
-        // If anyone ever changes the makeup of the Baz class, or
-        // tries to install some kind of visitor that gets run prior
-        // to serialization, this will break.
-        baz.methods[0].attributes.attrs[mpind] =
-            new Attribute(mpattr.attribute_name_index,
-                          mpattr.attribute_length) {
-                public <R, D> R accept(Visitor<R, D> visitor, D data) {
-                    if (data instanceof ByteArrayOutputStream) {
-                        ByteArrayOutputStream out =
-                            (ByteArrayOutputStream) data;
-                        out.write(1);
-                        out.write((ind >> 8) & 0xff);
-                        out.write(ind & 0xff);
-                        out.write((flags >> 24) & 0xff);
-                        out.write((flags >> 16) & 0xff);
-                        out.write((flags >> 8) & 0xff);
-                        out.write(flags & 0xff);
-                    } else
-                        throw new RuntimeException("Output stream is of type " + data.getClass() + ", which is not handled by this test.  Update the test and it should work.");
-                    return null;
-                }
-            };
-
-        // Flip the code and method attributes.  This is for checking
-        // that order doesn't matter.
-        if (flip) {
-            baz.methods[0].attributes.attrs[mpind] = cattr;
-            baz.methods[0].attributes.attrs[cind] = mpattr;
-        }
-
-        new ClassWriter().write(baz, Baz_class);
-    }
-
-    // Run a bunch of structural tests on foo to make sure it looks right.
-    void checkFoo() throws Exception {
-        final File Foo_class = new File(classesdir, Foo_name + ".class");
-        final ClassFile foo = ClassFile.read(Foo_class);
-        for (int i = 0; i < foo.methods.length; i++) {
-            System.err.println("Examine method Foo." + foo.methods[i].getName(foo.constant_pool));
-            if (foo.methods[i].getName(foo.constant_pool).equals("foo2")) {
-                for (int j = 0; j < foo.methods[i].attributes.attrs.length; j++)
-                    if (foo.methods[i].attributes.attrs[j] instanceof
-                        MethodParameters_attribute) {
-                        MethodParameters_attribute mp =
-                            (MethodParameters_attribute)
-                            foo.methods[i].attributes.attrs[j];
-                        System.err.println("Foo.foo2 should have 2 parameters: j and k");
-                        if (2 != mp.method_parameter_table_length)
-                            error("expected 2 method parameter entries in foo2, got " +
-                                  mp.method_parameter_table_length);
-                        else if (!foo.constant_pool.getUTF8Value(mp.method_parameter_table[0].name_index).equals("j"))
-                            error("expected first parameter to foo2 to be \"j\", got \"" +
-                                  foo.constant_pool.getUTF8Value(mp.method_parameter_table[0].name_index) +
-                                  "\" instead");
-                        else if  (!foo.constant_pool.getUTF8Value(mp.method_parameter_table[1].name_index).equals("k"))
-                            error("expected first parameter to foo2 to be \"k\", got \"" +
-                                  foo.constant_pool.getUTF8Value(mp.method_parameter_table[1].name_index) +
-                                  "\" instead");
-                    }
-            }
-            else if (foo.methods[i].getName(foo.constant_pool).equals("<init>")) {
-                for (int j = 0; j < foo.methods[i].attributes.attrs.length; j++) {
-                    if (foo.methods[i].attributes.attrs[j] instanceof
-                        MethodParameters_attribute)
-                        error("Zero-argument constructor shouldn't have MethodParameters");
-                }
-            }
-            else if (foo.methods[i].getName(foo.constant_pool).equals("foo0")) {
-                for (int j = 0; j < foo.methods[i].attributes.attrs.length; j++)
-                    if (foo.methods[i].attributes.attrs[j] instanceof
-                        MethodParameters_attribute)
-                        error("Zero-argument method shouldn't have MethodParameters");
-            }
-            else
-                error("Unknown method " + foo.methods[i].getName(foo.constant_pool) + " showed up in class Foo");
-        }
-    }
-
-    // Run a bunch of structural tests on Bar to make sure it looks right.
-    void checkBar() throws Exception {
-        final File Bar_class = new File(classesdir, Bar_name + ".class");
-        final ClassFile bar = ClassFile.read(Bar_class);
-        for (int i = 0; i < bar.methods.length; i++) {
-            System.err.println("Examine method Bar." + bar.methods[i].getName(bar.constant_pool));
-            if (bar.methods[i].getName(bar.constant_pool).equals("<init>")) {
-                for (int j = 0; j < bar.methods[i].attributes.attrs.length; j++)
-                    if (bar.methods[i].attributes.attrs[j] instanceof
-                        MethodParameters_attribute) {
-                        MethodParameters_attribute mp =
-                            (MethodParameters_attribute)
-                            bar.methods[i].attributes.attrs[j];
-                        System.err.println("Bar constructor should have 1 parameter: i");
-                        if (1 != mp.method_parameter_table_length)
-                            error("expected 1 method parameter entries in constructor, got " +
-                                  mp.method_parameter_table_length);
-                        else if (!bar.constant_pool.getUTF8Value(mp.method_parameter_table[0].name_index).equals("i"))
-                            error("expected first parameter to foo2 to be \"i\", got \"" +
-                                  bar.constant_pool.getUTF8Value(mp.method_parameter_table[0].name_index) +
-                                  "\" instead");
-                    }
-            }
-            else if (bar.methods[i].getName(bar.constant_pool).equals("foo")) {
-                for (int j = 0; j < bar.methods[i].attributes.attrs.length; j++) {
-                    if (bar.methods[i].attributes.attrs[j] instanceof
-                        MethodParameters_attribute)
-                        error("Zero-argument constructor shouldn't have MethodParameters");
-                }
-            }
-        }
-    }
-
-    String compile(String... args) throws Exception {
-        System.err.println("compile: " + Arrays.asList(args));
-        StringWriter sw = new StringWriter();
-        PrintWriter pw = new PrintWriter(sw);
-        int rc = com.sun.tools.javac.Main.compile(args, pw);
-        pw.close();
-        String out = sw.toString();
-        if (out.length() > 0)
-            System.err.println(out);
-        if (rc != 0)
-            error("compilation failed, rc=" + rc);
-        return out;
-    }
-
-    File writeFile(File dir, String path, String body) throws IOException {
-        File f = new File(dir, path);
-        f.getParentFile().mkdirs();
-        FileWriter out = new FileWriter(f);
-        out.write(body);
-        out.close();
-        return f;
-    }
-
-    void error(String msg) {
-        System.err.println("Error: " + msg);
-        errors++;
-    }
-
-    int errors;
-}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/MethodParameters/AnnotationTest.java	Wed Feb 20 15:47:14 2013 -0800
@@ -0,0 +1,54 @@
+/*
+ * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/*
+ * @test
+ * @bug 8006582
+ * @summary javac should generate method parameters correctly.
+ * @build Tester
+ * @compile -parameters AnnotationTest.java
+ * @run main Tester AnnotationTest
+ */
+
+import java.lang.annotation.*;
+
+/** Test that annotations do not interfere with recording of parameter names */
+class AnnotationTest {
+
+    @Repeatable(Annos.class)
+    @interface Anno {
+        Class f() default int.class;
+    }
+
+    @interface Annos { Anno[] value(); String foo() default "hello"; }
+
+    interface I {
+        int m(@Anno @Anno int i, @Anno int ji);
+    }
+
+    public AnnotationTest(@Anno @Anno I i, @Anno int ji) { }
+    public @Anno String foo(@Anno @Anno I i, int ji) { return null; }
+}
+
+
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/MethodParameters/AnonymousClass.java	Wed Feb 20 15:47:14 2013 -0800
@@ -0,0 +1,104 @@
+/*
+ * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/*
+ * @test
+ * @bug 8006582
+ * @summary javac should generate method parameters correctly.
+ * @build Tester
+ * @compile -parameters AnonymousClass.java
+ * @run main Tester AnonymousClass
+ */
+
+class AnonymousClass {
+
+    interface I<T> {
+        T m();
+        T m(T x, T yx);
+    }
+
+    private class Inner implements I<String> {
+        public Inner()  { }
+        public Inner(String arg, String barg)  { }
+        public String m() { return "0"; }
+        public String m(String s, String ts) { return "0"; }
+    }
+
+    public static class Sinner implements I<Long> {
+        public Sinner()  { }
+        public Sinner(Long arg, Long barg)  { }
+        public Long m() { return 0L; }
+        public Long m(Long s, Long ts) { return s + ts; }
+    }
+
+    /** Inner class in constructor context */
+    public AnonymousClass(final Long a, Long ba) {
+        new I<Long>() {
+            public Long m() { return null; }
+            public Long m(Long i, Long ji) { return i + ji; }
+        }.m(a, ba);
+        new Inner() {
+            public String m() { return null; }
+            public String m(String i, String ji) { return i + ji; }
+        }.m(a.toString(), ba.toString());
+        new Inner(a.toString(), ba.toString()) {
+            public String m() { return null; }
+            public String m(String i, String ji) { return i + ji; }
+        }.m(a.toString(), ba.toString());
+        new Sinner() {
+            public Long m() { return null; }
+            public Long m(Long i, Long ji) { return i + ji; }
+        }.m(a, ba);
+        new Sinner(a, ba) {
+            public Long m() { return null; }
+            public Long m(Long i, Long ji) { return i + ji; }
+        }.m(a, ba);
+    }
+
+    /** Inner class in method context */
+    public void foo(final Long a, Long ba) {
+        new I<Long>() {
+            public Long m() { return null; }
+            public Long m(Long i, Long ji) { return i + ji; }
+        }.m(a, ba);
+        new Inner() {
+            public String m() { return null; }
+            public String m(String i, String ji) { return i + ji; }
+        }.m(a.toString(), ba.toString());
+        new Inner(a.toString(), ba.toString()) {
+            public String m() { return null; }
+            public String m(String i, String ji) { return i + ji; }
+        }.m(a.toString(), ba.toString());
+        new Sinner() {
+            public Long m() { return null; }
+            public Long m(Long i, Long ji) { return i + ji; }
+        }.m(a, ba);
+        new Sinner(a, ba) {
+            public Long m() { return null; }
+            public Long m(Long i, Long ji) { return i + ji; }
+        }.m(a, ba);
+    }
+}
+
+
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/MethodParameters/AttributeVisitor.java	Wed Feb 20 15:47:14 2013 -0800
@@ -0,0 +1,59 @@
+/*
+ * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+import com.sun.tools.classfile.*;
+
+/**
+ * Trivial {@code Attribute.Visitor} implementation, to make it easy to
+ * write visitors for specific attributes.
+ */
+class AttributeVisitor<R, P> implements Attribute.Visitor<R, P> {
+    public R visitBootstrapMethods(BootstrapMethods_attribute attr, P p) { return null; }
+    public R visitDefault(DefaultAttribute attr, P p) { return null; }
+    public R visitAnnotationDefault(AnnotationDefault_attribute attr, P p) { return null; }
+    public R visitCharacterRangeTable(CharacterRangeTable_attribute attr, P p) { return null; }
+    public R visitCode(Code_attribute attr, P p) { return null; }
+    public R visitCompilationID(CompilationID_attribute attr, P p) { return null; }
+    public R visitConstantValue(ConstantValue_attribute attr, P p) { return null; }
+    public R visitDeprecated(Deprecated_attribute attr, P p) { return null; }
+    public R visitEnclosingMethod(EnclosingMethod_attribute attr, P p) { return null; }
+    public R visitExceptions(Exceptions_attribute attr, P p) { return null; }
+    public R visitInnerClasses(InnerClasses_attribute attr, P p) { return null; }
+    public R visitLineNumberTable(LineNumberTable_attribute attr, P p) { return null; }
+    public R visitLocalVariableTable(LocalVariableTable_attribute attr, P p) { return null; }
+    public R visitLocalVariableTypeTable(LocalVariableTypeTable_attribute attr, P p) { return null; }
+    public R visitMethodParameters(MethodParameters_attribute attr, P p) { return null; }
+    public R visitRuntimeVisibleAnnotations(RuntimeVisibleAnnotations_attribute attr, P p) { return null; }
+    public R visitRuntimeInvisibleAnnotations(RuntimeInvisibleAnnotations_attribute attr, P p) { return null; }
+    public R visitRuntimeVisibleParameterAnnotations(RuntimeVisibleParameterAnnotations_attribute attr, P p) { return null; }
+    public R visitRuntimeInvisibleParameterAnnotations(RuntimeInvisibleParameterAnnotations_attribute attr, P p) { return null; }
+    public R visitRuntimeVisibleTypeAnnotations(RuntimeVisibleTypeAnnotations_attribute attr, P p) { return null; }
+    public R visitRuntimeInvisibleTypeAnnotations(RuntimeInvisibleTypeAnnotations_attribute attr, P p) { return null; }
+    public R visitSignature(Signature_attribute attr, P p) { return null; }
+    public R visitSourceDebugExtension(SourceDebugExtension_attribute attr, P p) { return null; }
+    public R visitSourceFile(SourceFile_attribute attr, P p) { return null; }
+    public R visitSourceID(SourceID_attribute attr, P p) { return null; }
+    public R visitStackMap(StackMap_attribute attr, P p) { return null; }
+    public R visitStackMapTable(StackMapTable_attribute attr, P p) { return null; }
+    public R visitSynthetic(Synthetic_attribute attr, P p) { return null; }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/MethodParameters/ClassFileVisitor.java	Wed Feb 20 15:47:14 2013 -0800
@@ -0,0 +1,387 @@
+/*
+ * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+import com.sun.tools.classfile.*;
+import java.io.*;
+import javax.lang.model.element.*;
+import java.util.*;
+
+/**
+ * The {@code ClassFileVisitor} reads a class file using the
+ * {@code com.sun.tools.classfile} library. It iterates over the methods
+ * in a class, and checks MethodParameters attributes against JLS
+ * requirements, as well as assumptions about the javac implementations.
+ * <p>
+ * It enforces the following rules:
+ * <ul>
+ * <li>All non-synthetic methods with arguments must have the
+ * MethodParameters attribute. </li>
+ * <li>At most one MethodParameters attribute per method.</li>
+ * <li>An empty MethodParameters attribute is not allowed (i.e. no
+ * attribute for methods taking no parameters).</li>
+ * <li>The number of recorded parameter names much equal the number
+ * of parameters, including any implicit or synthetic parameters generated
+ * by the compiler.</li>
+ * <li>Although the spec allow recording parameters with no name, the javac
+ * implementation is assumed to record a name for all parameters. That is,
+ * the Methodparameters attribute must record a non-zero, valid constant
+ * pool index for each parameter.</li>
+ * <li>Check presence, expected names (e.g. this$N, $enum$name, ...) and flags
+ * (e.g. ACC_SYNTHETIC, ACC_MANDATED) for compiler generated parameters.</li>
+ * <li>Names of explicit parameters must reflect the names in the Java source.
+ * This is checked by assuming a design pattern where any name is permitted
+ * for the first explicit parameter. For subsequent parameters the following
+ * rule is checked: <i>param[n] == ++param[n-1].charAt(0) + param[n-1]</i>
+ * </ul>
+ */
+class ClassFileVisitor extends Tester.Visitor {
+
+    Tester tester;
+
+    public String cname;
+    public boolean isEnum;
+    public boolean isInterface;
+    public boolean isInner;
+    public boolean isPublic;
+    public boolean isStatic;
+    public boolean isAnon;
+    public ClassFile classFile;
+
+
+    public ClassFileVisitor(Tester tester) {
+        super(tester);
+    }
+
+    public void error(String msg) {
+        super.error("classfile: " + msg);
+    }
+
+    public void warn(String msg) {
+        super.warn("classfile: " + msg);
+    }
+
+    /**
+     * Read the class and determine some key characteristics, like if it's
+     * an enum, or inner class, etc.
+     */
+    void visitClass(final String cname, final File cfile, final StringBuilder sb)
+        throws Exception {
+        this.cname = cname;
+        classFile = ClassFile.read(cfile);
+        isEnum = classFile.access_flags.is(AccessFlags.ACC_ENUM);
+        isInterface = classFile.access_flags.is(AccessFlags.ACC_INTERFACE);
+        isPublic = classFile.access_flags.is(AccessFlags.ACC_PUBLIC);
+        isInner = false;
+        isStatic = true;
+        isAnon = false;
+
+        Attribute attr = classFile.getAttribute("InnerClasses");
+        if (attr != null) attr.accept(new InnerClassVisitor(), null);
+        isAnon = isInner & isAnon;
+
+        sb.append(isStatic ? "static " : "")
+            .append(isPublic ? "public " : "")
+            .append(isEnum ? "enum " : isInterface ? "interface " : "class ")
+            .append(cname).append(" -- ")
+            .append(isInner? "inner " : "" )
+            .append(isAnon ?  "anon" : "")
+            .append("\n");;
+
+        for (Method method : classFile.methods) {
+            new MethodVisitor().visitMethod(method, sb);
+        }
+    }
+
+    /**
+     * Used to visit InnerClasses_attribute of a class,
+     * to determne if this class is an local class, and anonymous
+     * inner class or a none-static member class. These types of
+     * classes all have an containing class instances field that
+     * requires an implicit or synthetic constructor argument.
+     */
+    class InnerClassVisitor extends AttributeVisitor<Void, Void> {
+        public Void visitInnerClasses(InnerClasses_attribute iattr, Void v) {
+            try{
+                for (InnerClasses_attribute.Info info : iattr.classes) {
+                    if (info.getInnerClassInfo(classFile.constant_pool) == null) continue;
+                    String in = info.getInnerClassInfo(classFile.constant_pool).getName();
+                    if (in == null || !cname.equals(in)) continue;
+                    isInner = true;
+                    isAnon = null == info.getInnerName(classFile.constant_pool);
+                    isStatic = info.inner_class_access_flags.is(AccessFlags.ACC_STATIC);
+                    break;
+                }
+            } catch(Exception e) {
+                throw new IllegalStateException(e);
+            }
+            return null;
+        }
+    }
+
+    /**
+     * Check the MethodParameters attribute of a method.
+     */
+    class MethodVisitor extends AttributeVisitor<Void, StringBuilder> {
+
+        public String mName;
+        public Descriptor mDesc;
+        public int mParams;
+        public int mAttrs;
+        public int mNumParams;
+        public boolean mSynthetic;
+        public boolean mIsConstructor;
+        public String prefix;
+
+        void visitMethod(Method method, StringBuilder sb) throws Exception {
+
+            mName = method.getName(classFile.constant_pool);
+            mDesc = method.descriptor;
+            mParams =  mDesc.getParameterCount(classFile.constant_pool);
+            mAttrs = method.attributes.attrs.length;
+            mNumParams = -1; // no MethodParameters attribute found
+            mSynthetic = method.access_flags.is(AccessFlags.ACC_SYNTHETIC);
+            mIsConstructor = mName.equals("<init>");
+            prefix = cname + "." + mName + "() - ";
+
+            sb.append(cname).append(".").append(mName).append("(");
+
+            for (Attribute a : method.attributes) {
+                a.accept(this, sb);
+            }
+            if (mNumParams == -1) {
+                if (mSynthetic) {
+                    sb.append("<none>)!!");
+                } else {
+                    sb.append("<none>)");
+                }
+            }
+            sb.append("\n");
+
+            // IMPL: methods with arguments must have a MethodParameters
+            // attribute, except possibly some synthetic methods.
+            if (mNumParams == -1 && mParams > 0 && ! mSynthetic) {
+                error(prefix + "missing MethodParameters attribute");
+            }
+        }
+
+        public Void visitMethodParameters(MethodParameters_attribute mp,
+                                          StringBuilder sb) {
+
+            // SPEC: At most one MethodParameters attribute allowed
+            if (mNumParams != -1) {
+                error(prefix + "Multiple MethodParameters attributes");
+                return null;
+            }
+
+            mNumParams = mp.method_parameter_table_length;
+
+            // SPEC: An empty attribute is not allowed!
+            if (mNumParams == 0) {
+                error(prefix + "0 length MethodParameters attribute");
+                return null;
+            }
+
+            // SPEC: one name per parameter.
+            if (mNumParams != mParams) {
+                error(prefix + "found " + mNumParams +
+                      " parameters, expected " + mParams);
+                return null;
+            }
+
+            // IMPL: Whether MethodParameters attributes will be generated
+            // for some synthetics is unresolved. For now, assume no.
+            if (mSynthetic) {
+                warn(prefix + "synthetic has MethodParameter attribute");
+            }
+
+            String sep = "";
+            String userParam = null;
+            for (int x = 0; x <  mNumParams; x++) {
+
+                // IMPL: Assume all parameters are named, something.
+                int cpi = mp.method_parameter_table[x].name_index;
+                if (cpi == 0) {
+                    error(prefix + "name expected, param[" + x + "]");
+                    return null;
+                }
+
+                // SPEC: a non 0 index, must be valid!
+                String param = null;
+                try {
+                    param = classFile.constant_pool.getUTF8Value(cpi);
+                    sb.append(sep).append(param);
+                    sep = ", ";
+                } catch(ConstantPoolException e) {
+                    error(prefix + "invalid index " + cpi + " for param["
+                          + x + "]");
+                    return null;
+                }
+
+
+                // Check availability, flags and special names
+                int check = checkParam(mp, param, x, sb);
+                if (check < 0) {
+                    return null;
+                }
+
+                // TEST: check test assumptions about parameter name.
+                // Expected names are calculated starting with the
+                // 2nd explicit (user given) parameter.
+                // param[n] == ++param[n-1].charAt(0) + param[n-1]
+                String expect = null;
+                if (userParam != null) {
+                    char c = userParam.charAt(0);
+                    expect =  (++c) + userParam;
+                }
+                if (check > 0) {
+                    userParam = param;
+                }
+                if (expect != null && !param.equals(expect)) {
+                    error(prefix + "param[" + x + "]='"
+                          + param + "' expected '" + expect + "'");
+                    return null;
+                }
+            }
+            if (mSynthetic) {
+                sb.append(")!!");
+            } else {
+                sb.append(")");
+            }
+            return null;
+        }
+
+        /*
+         * Check a parameter for conformity to JLS and javac specific
+         * assumptions.
+         * Return -1, if an error is detected. Otherwise, return 0, if
+         * the parameter is compiler generated, or 1 for an (presumably)
+         * explicitly declared parameter.
+         */
+        int checkParam(MethodParameters_attribute mp, String param, int index,
+                       StringBuilder sb) {
+
+            boolean synthetic = (mp.method_parameter_table[index].flags
+                                 & AccessFlags.ACC_SYNTHETIC) != 0;
+            boolean mandated = (mp.method_parameter_table[index].flags
+                                & AccessFlags.ACC_MANDATED) != 0;
+
+            // Setup expectations for flags and special names
+            String expect = null;
+            boolean allowMandated = false;
+            boolean allowSynthetic = false;
+            if (mSynthetic || synthetic) {
+                // not an implementation gurantee, but okay for now
+                expect = "arg" + index; // default
+            }
+            if (mIsConstructor) {
+                if (isEnum) {
+                    if (index == 0) {
+                        expect = "\\$enum\\$name";
+                        allowSynthetic = true;
+                    } else if(index == 1) {
+                        expect = "\\$enum\\$ordinal";
+                        allowSynthetic = true;
+                    }
+                } else if (index == 0) {
+                    if (isAnon) {
+                        allowMandated = true;
+                        expect = "this\\$[0-n]*";
+                    } else if (isInner && !isStatic) {
+                        allowMandated = true;
+                        if (!isPublic) {
+                            // some but not all non-public inner classes
+                            // have synthetic argument. For now we give
+                            // the test a bit of slack and allow either.
+                            allowSynthetic = true;
+                        }
+                        expect = "this\\$[0-n]*";
+                    }
+                } else if (isAnon) {
+                    // not an implementation gurantee, but okay for now
+                    expect = "x[0-n]*";
+                }
+            } else if (isEnum && mNumParams == 1 && index == 0 && mName.equals("valueOf")) {
+                expect = "name";
+                allowMandated = true;
+            }
+            if (mandated) sb.append("!");
+            if (synthetic) sb.append("!!");
+
+            // IMPL: our rules a somewhat fuzzy, sometimes allowing both mandated
+            // and synthetic. However, a parameters cannot be both.
+            if (mandated && synthetic) {
+                error(prefix + "param[" + index + "] == \"" + param
+                      + "\" ACC_SYNTHETIC and ACC_MANDATED");
+                return -1;
+            }
+            // ... but must be either, if both "allowed".
+            if (!(mandated || synthetic) && allowMandated && allowSynthetic) {
+                error(prefix + "param[" + index + "] == \"" + param
+                      + "\" expected ACC_MANDATED or ACC_SYNTHETIC");
+                return -1;
+            }
+
+            // ... if only one is "allowed", we meant "required".
+            if (!mandated && allowMandated && !allowSynthetic) {
+                error(prefix + "param[" + index + "] == \"" + param
+                      + "\" expected ACC_MANDATED");
+                return -1;
+            }
+            if (!synthetic && !allowMandated && allowSynthetic) {
+                error(prefix + "param[" + index + "] == \"" + param
+                      + "\" expected ACC_SYNTHETIC");
+                return -1;
+            }
+
+            // ... and not "allowed", means prohibited.
+            if (mandated && !allowMandated) {
+                error(prefix + "param[" + index + "] == \"" + param
+                      + "\" unexpected, is ACC_MANDATED");
+                return -1;
+            }
+            if (synthetic && !allowSynthetic) {
+                error(prefix + "param[" + index + "] == \"" + param
+                      + "\" unexpected, is ACC_SYNTHETIC");
+                return -1;
+            }
+
+            // Test special name expectations
+            if (expect != null) {
+                if (param.matches(expect)) {
+                    return 0;
+                }
+                error(prefix + "param[" + index + "]='" + param +
+                      "' expected '" + expect + "'");
+                return -1;
+            }
+
+            // No further checking for synthetic methods.
+            if (mSynthetic) {
+                return 0;
+            }
+
+            // Otherwise, do check test parameter naming convention.
+            return 1;
+        }
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/MethodParameters/Constructors.java	Wed Feb 20 15:47:14 2013 -0800
@@ -0,0 +1,41 @@
+/*
+ * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/*
+ * @test
+ * @bug 8006582
+ * @summary javac should generate method parameters correctly.
+ * @build Tester
+ * @compile -parameters Constructors.java
+ * @run main Tester Constructors
+ */
+
+public class Constructors {
+    public Constructors() {}
+    Constructors(final Object a, final String... ba) { }
+    protected Constructors(Object a, final Object ba, final String... cba) { }
+    private Constructors(int a, Object ba, final Object cba, final String... dcba) { }
+}
+
+
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/MethodParameters/EnumTest.java	Wed Feb 20 15:47:14 2013 -0800
@@ -0,0 +1,45 @@
+/*
+ * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/*
+ * @test
+ * @bug 8006582
+ * @summary javac should generate method parameters correctly.
+ * @build Tester
+ * @compile -parameters EnumTest.java
+ * @run main Tester EnumTest
+ */
+
+/** Test that parameter names are recorded for enum methods */
+enum EnumTest {
+    E1(0), E2(1, "x"), E3(2, "x", "y"), E4;
+
+    EnumTest() { }
+    EnumTest(int a, String... ba) { }
+    boolean ok(int c, String... dc) { return true; }
+
+    int valueOf(EnumTest A, EnumTest BA) { return 0; }
+}
+
+
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/MethodParameters/InstanceMethods.java	Wed Feb 20 15:47:14 2013 -0800
@@ -0,0 +1,46 @@
+/*
+ * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/*
+ * @test
+ * @bug 8006582
+ * @summary javac should generate method parameters correctly.
+ * @build Tester
+ * @compile -parameters InstanceMethods.java
+ * @run main Tester InstanceMethods
+ */
+
+public class InstanceMethods {
+    public void empty() {}
+    final void def(Object a, final Object ba, final String... cba) { }
+    final public void pub(Object d, final Object ed, final String... fed) { }
+    protected boolean prot(Object g, final Object hg, final String... ihg) { return true; }
+    private boolean priv(Object j, final Object kj, final String... lkj) { return true; }
+    void def(int A, Object BA, final Object CBA, final String... DCBA) { }
+    public void pub(int B, Object CB, final Object DCB, final String... EDCB) { }
+    final protected boolean prot(int C, Object DC, final Object EDC, final String... FEDC) { return true; }
+    final private boolean priv(int D, Object ED, final Object FED, final String... GFED) { return true; }
+}
+
+
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/MethodParameters/LambdaTest.java	Wed Feb 20 15:47:14 2013 -0800
@@ -0,0 +1,51 @@
+/*
+ * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/*
+ * @test
+ * @bug 8006582
+ * @summary javac should generate method parameters correctly.
+ * @build Tester
+ * @compile -parameters LambdaTest.java
+ * @run main Tester LambdaTest
+ */
+
+/**
+ * Parameter names are not recorded for lambdas. This test verifies
+ * that there are no MethodParameters attribute for lambdas.
+ */
+class LambdaTest {
+
+    interface I {
+        int m(int x);
+    }
+
+    static int foo(I i) { return i.m(0); }
+
+    static {
+        foo((int x1) -> { return foo((int x2) -> { return x1 + x2; }); });
+    }
+}
+
+
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/MethodParameters/LocalClassTest.java	Wed Feb 20 15:47:14 2013 -0800
@@ -0,0 +1,50 @@
+/*
+ * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/*
+ * @test
+ * @bug 8006582
+ * @summary javac should generate method parameters correctly.
+ * @build Tester
+ * @compile -parameters LocalClassTest.java
+ * @run main Tester LocalClassTest
+ */
+
+class LocalClassTest {
+    void foo() {
+        class Local_default_constructor {
+            public void foo() {}
+            public void foo(int m, int nm) {}
+        }
+        class Local_has_constructor {
+            public Local_has_constructor() {}
+            public Local_has_constructor(int a, int ba) {}
+            public void foo() {}
+            public void foo(int m, int nm) {}
+        }
+        new LocalClassTest().foo();
+    }
+}
+
+
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/MethodParameters/MemberClassTest.java	Wed Feb 20 15:47:14 2013 -0800
@@ -0,0 +1,86 @@
+/*
+ * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/*
+ * @test
+ * @bug 8006582
+ * @summary javac should generate method parameters correctly.
+ * @build Tester
+ * @compile -parameters MemberClassTest.java
+ * @run main Tester MemberClassTest
+ */
+
+class MemberClassTest {
+
+    interface I {
+        Long m();
+        Long m(Long x, Long yx);
+    }
+
+    public class Member implements I {
+        public class Member_Member {
+            public Member_Member() {}
+            public Member_Member(String x, String yx) {}
+        }
+
+        public Member()  { }
+        public Member(Long a, Long ba)  { }
+        public Long m() { return 0L; }
+        public Long m(Long s, Long ts) { return 0L; }
+    }
+
+    static class Static_Member implements I {
+        public class Static_Member_Member {
+            public Static_Member_Member() {}
+            public Static_Member_Member(String x, String yx) {}
+        }
+
+        public static class Static_Member_Static_Member {
+            public Static_Member_Static_Member() {}
+            public Static_Member_Static_Member(String x, String yx) {}
+        }
+        public Static_Member()  { }
+        public Static_Member(Long arg, Long barg)  { }
+        public Long m() { return 0L; }
+        public Long m(Long s, Long ts) { return s + ts; }
+    }
+
+    public MemberClassTest() {
+    }
+    public MemberClassTest(final Long a, Long ba) {
+    }
+
+    public void foo() {
+
+        new I() {
+
+            class Anonymous_Member {
+                public Anonymous_Member() {}
+                public Anonymous_Member(String x, String yx) {}
+            }
+
+            public Long m() { return 0L; }
+            public Long m(Long s, Long ts) { return s + ts; }
+        }.m();
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/MethodParameters/ReflectionVisitor.java	Wed Feb 20 15:47:14 2013 -0800
@@ -0,0 +1,270 @@
+/*
+ * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+import java.io.*;
+import java.util.*;
+import java.net.*;
+import java.lang.reflect.*;
+
+/**
+ * Test MethodParameter attributs by reflection API
+ */
+public class ReflectionVisitor extends Tester.Visitor {
+
+    public ReflectionVisitor(Tester tester) {
+        super(tester);
+    }
+
+    public void error(String msg) {
+        super.error("reflection: " + msg);
+    }
+
+    public void warn(String msg) {
+        super.warn("reflection: " + msg);
+    }
+
+    boolean isEnum;
+    boolean isInterface;
+    boolean isAnon;
+    boolean isLocal;
+    boolean isMember;
+    boolean isStatic;
+    boolean isPublic;
+    Class clazz;
+    StringBuilder sb;
+
+    /**
+     * Read class using {@code ClassFile}, and generate a list of methods
+     * with parameter names as available in the MethodParameters attribute.
+     */
+    void visitClass(final String cl, final File cfile, final StringBuilder sb)
+        throws Exception {
+
+        this.sb = sb;
+        clazz = Class.forName(cl);
+        isEnum = clazz.isEnum();
+        isInterface = clazz.isInterface();
+        isAnon = clazz.isAnonymousClass();
+        isLocal = clazz.isLocalClass();
+        isMember = clazz.isMemberClass();
+        isStatic = ((clazz.getModifiers() & Modifier.STATIC) != 0);
+        isPublic = ((clazz.getModifiers() & Modifier.PUBLIC) != 0);
+
+        sb.append(isStatic ? "static " : "")
+            .append(isPublic ? "public " : "")
+            .append(isEnum ? "enum " : isInterface ? "interface " : "class ")
+            .append(cl).append(" -- ")
+            .append(isMember? "member " : "" )
+            .append(isLocal? "local " : "" )
+            .append(isAnon ?  "anon" : "")
+            .append("\n");
+
+        for (Constructor c : clazz.getDeclaredConstructors()) {
+            testConstructor(c);
+        }
+
+        for (Method m :clazz.getDeclaredMethods()) {
+
+            testMethod(m);
+        }
+    }
+
+    void testConstructor(Constructor c) {
+
+        String prefix = clazz.getName() + "." + c.getName() + "() - ";
+
+        // Parameters must match parameter types
+        Parameter params[] = c.getParameters();
+        int paramTypes =  c.getParameterTypes().length;
+        if (paramTypes != params.length) {
+            error(prefix + "number of parameter types (" + paramTypes
+                  + ") != number of parameters (" + params.length + ")");
+            return;
+        }
+
+        sb.append(clazz.getName()).append(".").append("<init>").append("(");
+        String sep = "";
+
+        // Some paramters are expected
+        if (params.length < 2 && isEnum) {
+            error(prefix + "enum constuctor, two arguments expected");
+        } else if (params.length < 1 && (isAnon || isLocal ||
+                                         (isMember && !isStatic ))) {
+            error(prefix + "class constuctor,expected implicit argument");
+        }
+
+        int i = -1;
+        String param = null;
+        for (Parameter p : c.getParameters()) {
+            i++;
+            String pname = p.getName();
+            sb.append(sep).append(pname);
+            if (p.isImplicit()) sb.append("!");
+            if (p.isSynthetic()) sb.append("!!");
+            sep = ", ";
+
+            // Set expectations
+            String expect = null;
+            boolean allowImplicit = false;
+            boolean allowSynthetic = false;
+            if (isEnum) {
+                if (i == 0) {
+                    expect = "\\$enum\\$name";
+                    allowSynthetic = true;
+                } else if(i == 1) {
+                    expect = "\\$enum\\$ordinal";
+                    allowSynthetic = true;
+                }
+            } else if (i == 0) {
+                if (isAnon) {
+                    allowImplicit = true;
+                } else if (isLocal) {
+                    allowImplicit = true;
+                    expect = "this\\$[0-n]*";
+                } else if ((isMember && !isStatic)) {
+                    allowImplicit = true;
+                    if (!isPublic) {
+                        // some but not all non-public inner classes
+                        // have synthetic argument. For now we give
+                        // the test a bit of slack and allow either.
+                        allowSynthetic = true;
+                    }
+                    expect = "this\\$[0-n]*";
+                }
+            } else if (isAnon) {
+                // not an implementation gurantee, but okay for now
+                expect = "x[0-n]*";
+            }
+
+            // Check expected flags
+            if (p.isSynthetic() && p.isImplicit()) {
+                error(prefix + "param[" + i + "]='" + pname +
+                      "' both isImplicit() and isSynthetic()");
+                break;
+            }
+            if (allowImplicit && allowSynthetic &&
+                !(p.isSynthetic() || p.isImplicit())) {
+                error(prefix + "param[" + i + "]='" + pname +
+                      "' isImplicit() or isSynthetic() expected");
+                break;
+            }
+
+            if (allowImplicit && !allowSynthetic && !p.isImplicit()) {
+                error(prefix + "param[" + i + "]='" + pname +
+                      "' isImplicit() expected");
+                break;
+            }
+            if (!allowImplicit && allowSynthetic && !p.isSynthetic()) {
+                error(prefix + "param[" + i + "]='" + pname +
+                      "' isSynthetic() expected");
+                break;
+            }
+
+            if (!allowImplicit && p.isImplicit()) {
+                error(prefix + "param[" + i + "]='" + pname +
+                      "' isImplicit() unexpected");
+                break;
+            }
+
+            if (!allowSynthetic && p.isSynthetic()) {
+                error(prefix + "param[" + i + "]='" + pname +
+                      "' isSynthetic() unexpected");
+                break;
+            }
+
+            // Check expected names
+            if (expect != null) {
+                if (pname.matches(expect))  continue;
+                error(prefix + "param[" + i + "]='" + pname +
+                      "' expected '" + expect + "'");
+                break;
+            }
+
+            // Test naming convention for explicit parameters.
+            boolean fidelity = !isAnon;
+            if (param != null && fidelity) {
+                char ch = param.charAt(0);
+                expect =  (++ch) + param;
+            }
+
+            if (pname != null && fidelity) {
+                param = pname;
+            }
+
+            if (expect != null && !expect.equals(pname)) {
+                error(prefix + "param[" + i + "]='" + pname +
+                      "' expected '" + expect + "'");
+                break;
+            }
+        }
+        if  (c.isSynthetic()) {
+            sb.append(")!!\n");
+        } else {
+            sb.append(")\n");
+        }
+    }
+
+    void testMethod(Method m) {
+
+        String prefix = clazz.getName() + "." + m.getName() + "() - ";
+
+        // Parameters must match parameter types
+        int paramTypes =  m.getParameterTypes().length;
+        int params = m.getParameters().length;
+        if (paramTypes != params) {
+            error(prefix + "number of parameter types (" + paramTypes
+                  + ") != number of parameters (" + params + ")");
+            return;
+        }
+
+        sb.append(clazz.getName()).append(".").append(m.getName()).append("(");
+        String sep = "";
+        String param = null;
+        int i = -1;
+        // For methods we expect all parameters to follow
+        // the test-case design pattern, except synthetic methods.
+        for (Parameter p : m.getParameters()) {
+            i++;
+            if (param == null) {
+                param = p.getName();
+                sb.append(sep).append(param);
+            } else  {
+                char c = param.charAt(0);
+                String expect =  m.isSynthetic() ? ("arg" + i) : ((++c) + param);
+                param = p.getName();
+                sb.append(sep).append(param);
+                if (!expect.equals(param)) {
+                    error(prefix + "param[" + i + "]='"
+                          + param + "' expected '" + expect + "'");
+                    break;
+                }
+            }
+            sep = ", ";
+        }
+        if  (m.isSynthetic()) {
+            sb.append(")!!\n");
+        } else {
+            sb.append(")\n");
+        }
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/MethodParameters/StaticMethods.java	Wed Feb 20 15:47:14 2013 -0800
@@ -0,0 +1,46 @@
+/*
+ * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/*
+ * @test
+ * @bug 8006582
+ * @summary javac should generate method parameters correctly.
+ * @build Tester
+ * @compile -parameters StaticMethods.java
+ * @run main Tester StaticMethods
+ */
+
+public class StaticMethods {
+    static public void empty() {}
+    static final void def(Object a, final Object ba, final String... cba) { }
+    static final public void pub(Object d, final Object ed, final String... fed) { }
+    static protected boolean prot(Object g, final Object hg, final String... ihg) { return true; }
+    static private boolean priv(Object j, final Object kj, final String... lkj) { return true; }
+    static void def(int a, Object ba, final Object cba, final String... dcba) { }
+    static public void pub(int a, Object ba, final Object cba , final String... dcba) { }
+    static final protected boolean prot(int aa, Object baa, final Object cbaa, final String... dcbaa) { return true; }
+    static final private boolean priv(int abc, Object babc, final Object cbabc, final String... dcbabc) { return true; }
+}
+
+
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/MethodParameters/Tester.java	Wed Feb 20 15:47:14 2013 -0800
@@ -0,0 +1,162 @@
+/*
+ * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+import java.io.*;
+import java.util.*;
+import java.lang.reflect.Constructor;
+
+/**
+ * Test driver for MethodParameters testing.
+ * <p>
+ * The intended use of this driver is to run it, giving the name of
+ * a single class compiled with -parameters as argument. The driver
+ * will test the specified class, and any nested classes it finds.
+ * <p>
+ * Each class is tested in two way. By refelction, and by directly
+ * checking MethodParameters attributes in the classfile. The checking
+ * is done using two visitor classes {@link ClassFileVisitor} and
+ * {@link ReflectionVisitor}.
+ * <p>
+ * The {@code ReflectionVisitor} test logically belongs with library tests.
+ * we wish to reuse the same test-cases, so both test are committed together,
+ * under langtools. The tests, may be duplicated in the jdk repository.
+ */
+public class Tester {
+
+    final static File classesdir = new File(System.getProperty("test.classes", "."));
+
+    /**
+     * The visitor classes that does the actual checking are referenced
+     * statically, to force compilations, without having to reference
+     * them in individual test cases.
+     * <p>
+     * This makes it easy to change the set of visitors, without
+     * complicating the design with dynamic discovery and compilation
+     * of visitor classes.
+     */
+    static final Class visitors[] = {
+        ClassFileVisitor.class,
+        ReflectionVisitor.class
+    };
+
+    /**
+     * Test-driver expect a single classname as argument.
+     */
+    public static void main(String... args) throws Exception {
+        if (args.length != 1) {
+            throw new Error("A single class name is expected as argument");
+        }
+        final String pattern = args[0] + ".*\\.class";
+        File files[] = classesdir.listFiles(new FileFilter() {
+                public boolean accept(File f) {
+                    return f.getName().matches(pattern);
+                }
+            });
+        if (files.length == 0) {
+            File file = new File(classesdir, args[0] + ".class");
+            throw new Error(file.getPath() + " not found");
+        }
+
+        new Tester(args[0], files).run();
+    }
+
+    public Tester(String name, File files[]) {
+        this.classname = name;
+        this.files = files;
+    }
+
+    void run() throws Exception {
+
+        // Test with each visitor
+        for (Class<Visitor> vclass : visitors) {
+            try {
+                String vname = vclass.getName();
+                Constructor c = vclass.getConstructor(Tester.class);
+
+                info("\nRun " + vname + " for " + classname + "\n");
+                StringBuilder sb = new StringBuilder();
+                for (File f : files) {
+                    String fname = f.getName();
+                    fname = fname.substring(0, fname.length() - 6);
+                    Visitor v = (Visitor) c.newInstance(this);
+                    try {
+                        v.visitClass(fname, f,  sb);
+                    } catch(Exception e) {
+                        error("Uncaught exception in visitClass()");
+                        e.printStackTrace();
+                    }
+                }
+                info(sb.toString());
+            } catch(ReflectiveOperationException e) {
+                warn("Class " + vclass.getName() + " ignored, not a Visitor");
+                continue;
+            }
+        }
+
+        if(0 != warnings)
+                System.err.println("Test generated " + warnings + " warnings");
+
+        if(0 != errors)
+            throw new Exception("Tester test failed with " +
+                                errors + " errors");
+    }
+
+    abstract static  class Visitor {
+        Tester tester;
+        File classesdir;
+
+        public Visitor(Tester tester) {
+            this.tester = tester;
+        }
+
+        abstract void visitClass(final String classname, final File  cfile,
+                final StringBuilder sb) throws Exception;
+
+        public void error(String msg) {
+            tester.error(msg);
+        }
+
+        public void warn(String msg) {
+            tester.warn(msg);
+        }
+    }
+
+    void error(String msg) {
+        System.err.println("Error: " + msg);
+        errors++;
+    }
+
+    void warn(String msg) {
+        System.err.println("Warning: " + msg);
+        warnings++;
+    }
+
+    void info(String msg) {
+        System.out.println(msg);
+    }
+
+    int errors;
+    int warnings;
+    String classname;
+    File files[];
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/MethodParameters/UncommonParamNames.java	Wed Feb 20 15:47:14 2013 -0800
@@ -0,0 +1,68 @@
+/*
+ * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/*
+ * @test
+ * @bug 8006582
+ * @summary javac should generate method parameters correctly.
+ * @build Tester
+ * @compile -parameters UncommonParamNames.java
+ * @run main Tester UncommonParamNames
+ */
+
+/** Test uncommon parameter names */
+class UncommonParamNames {
+    public UncommonParamNames(int _x) { }
+    public UncommonParamNames(short $1) { }
+    public UncommonParamNames(long \u0061) { }
+    public UncommonParamNames(char zero\u0000zero\u0000) { }
+    public UncommonParamNames(String zero\u0000zero\u0000seven\u0007) { }
+    public UncommonParamNames(Object zero\u0000zero\u0000eight\u0008) { }
+    public UncommonParamNames(Object aLoooooooooooooooooooooooooooooooooooooooooooooooooooooooooooongName,
+                              Object baLoooooooooooooooooooooooooooooooooooooooooooooooooooooooooooongName,
+                              Object cbaLoooooooooooooooooooooooooooooooooooooooooooooooooooooooooooongName) { }
+    public UncommonParamNames(int a, int ba, int cba, int dcba, int edcba, int fedcba, int gfedcba,
+                              int hgfedcba, int ihgfedcba, int jihgfedcba, int kjihgfedcba, int lkjihgfedcba,
+                              int mlkjihgfedcba, int nmlkjihgfedcba, int onmlkjihgfedcba, int ponmlkjihgfedcba,
+                              int qponmlkjihgfedcba, int rqponmlkjihgfedcba, int srqponmlkjihgfedcba,
+                              int tsrqponmlkjihgfedcba, int utsrqponmlkjihgfedcba, int vutsrqponmlkjihgfedcba,
+                              int wvutsrqponmlkjihgfedcba, int xwvutsrqponmlkjihgfedcba,
+                              int yxwvutsrqponmlkjihgfedcba, int zyxwvutsrqponmlkjihgfedcba) { }
+
+    public void foo(int _x) { }
+    public void foo(short $1) { }
+    public void foo(long \u0061) { }
+    public void foo(char zero\u0000zero\u0000) { }
+    public void foo(String zero\u0000zero\u0000seven\u0007) { }
+    public void foo(Object zero\u0000zero\u0000eight\u0008) { }
+    public void foo(Object aLoooooooooooooooooooooooooooooooooooooooooooooooooooooooooooongName,
+                    Object baLoooooooooooooooooooooooooooooooooooooooooooooooooooooooooooongName,
+                    Object cbaLoooooooooooooooooooooooooooooooooooooooooooooooooooooooooooongName) { }
+    public void foo(int a, int ba, int cba, int dcba, int edcba, int fedcba, int gfedcba,
+                    int hgfedcba, int ihgfedcba, int jihgfedcba, int kjihgfedcba, int lkjihgfedcba,
+                    int mlkjihgfedcba, int nmlkjihgfedcba, int onmlkjihgfedcba, int ponmlkjihgfedcba,
+                    int qponmlkjihgfedcba, int rqponmlkjihgfedcba, int srqponmlkjihgfedcba,
+                    int tsrqponmlkjihgfedcba, int utsrqponmlkjihgfedcba, int vutsrqponmlkjihgfedcba,
+                    int wvutsrqponmlkjihgfedcba, int xwvutsrqponmlkjihgfedcba,
+                    int yxwvutsrqponmlkjihgfedcba, int zyxwvutsrqponmlkjihgfedcba) { }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/MethodParametersTest.java	Wed Feb 20 15:47:14 2013 -0800
@@ -0,0 +1,344 @@
+/*
+ * Copyright (c) 2012, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/*
+ * @test
+ * @bug 8004727
+ * @summary javac should generate method parameters correctly.
+ */
+// key: opt.arg.parameters
+import com.sun.tools.classfile.*;
+import com.sun.tools.javac.file.JavacFileManager;
+import com.sun.tools.javac.main.Main;
+import com.sun.tools.javac.util.Context;
+import com.sun.tools.javac.util.Name;
+import com.sun.tools.javac.util.Names;
+import java.io.*;
+import javax.lang.model.element.*;
+import java.util.*;
+
+public class MethodParametersTest {
+
+    static final String Foo_name = "Foo";
+    static final String Foo_contents =
+        "public class Foo {\n" +
+        "  Foo() {}\n" +
+        "  void foo0() {}\n" +
+        "  void foo2(int j, int k) {}\n" +
+        "}";
+    static final String Bar_name = "Bar";
+    static final String Bar_contents =
+        "public class Bar {\n" +
+        "  Bar(int i) {}" +
+        "  Foo foo() { return new Foo(); }\n" +
+        "}";
+    static final String Baz_name = "Baz";
+    static final String Baz_contents =
+        "public class Baz {\n" +
+        "  int baz;" +
+        "  Baz(int i) {}" +
+        "}";
+    static final String Qux_name = "Qux";
+    static final String Qux_contents =
+        "public class Qux extends Baz {\n" +
+        "  Qux(int i) { super(i); }" +
+        "}";
+    static final File classesdir = new File("methodparameters");
+
+    public static void main(String... args) throws Exception {
+        new MethodParametersTest().run();
+    }
+
+    void run() throws Exception {
+        classesdir.mkdir();
+        final File Foo_java =
+            writeFile(classesdir, Foo_name + ".java", Foo_contents);
+        final File Bar_java =
+            writeFile(classesdir, Bar_name + ".java", Bar_contents);
+        final File Baz_java =
+            writeFile(classesdir, Baz_name + ".java", Baz_contents);
+        System.err.println("Test compile with -parameter");
+        compile("-parameters", "-d", classesdir.getPath(), Foo_java.getPath());
+        // First test: make sure javac doesn't choke to death on
+        // MethodParameter attributes
+        System.err.println("Test compile with classfile containing MethodParameter attributes");
+        compile("-parameters", "-d", classesdir.getPath(),
+                "-cp", classesdir.getPath(), Bar_java.getPath());
+        System.err.println("Examine class foo");
+        checkFoo();
+        checkBar();
+        System.err.println("Test debug information conflict");
+        compile("-g", "-parameters", "-d", classesdir.getPath(),
+                "-cp", classesdir.getPath(), Baz_java.getPath());
+        System.err.println("Introducing debug information conflict");
+        Baz_java.delete();
+        modifyBaz(false);
+        System.err.println("Checking language model");
+        inspectBaz();
+        System.err.println("Permuting attributes");
+        modifyBaz(true);
+        System.err.println("Checking language model");
+        inspectBaz();
+
+        if(0 != errors)
+            throw new Exception("MethodParameters test failed with " +
+                                errors + " errors");
+    }
+
+    void inspectBaz() throws Exception {
+        final File Qux_java =
+            writeFile(classesdir, Qux_name + ".java", Qux_contents);
+        final String[] args = { "-XDsave-parameter-names", "-d",
+                                classesdir.getPath(),
+                                "-cp", classesdir.getPath(),
+                                Qux_java.getPath() };
+        final StringWriter sw = new StringWriter();
+        final PrintWriter pw = new PrintWriter(sw);
+
+        // We need to be able to crack open javac and look at its data
+        // structures.  We'll rig up a compiler instance, but keep its
+        // Context, thus allowing us to get at the ClassReader.
+        Context context = new Context();
+        Main comp =  new Main("javac", pw);
+        JavacFileManager.preRegister(context);
+
+        // Compile Qux, which uses Baz.
+        comp.compile(args, context);
+        pw.close();
+        final String out = sw.toString();
+        if (out.length() > 0)
+            System.err.println(out);
+
+        // Now get the class reader, construct a name for Baz, and load it.
+        com.sun.tools.javac.jvm.ClassReader cr =
+            com.sun.tools.javac.jvm.ClassReader.instance(context);
+        Name name = Names.instance(context).fromString(Baz_name);
+
+        // Now walk down the language model and check the name of the
+        // parameter.
+        final Element baz = cr.loadClass(name);
+        for (Element e : baz.getEnclosedElements()) {
+            if (e instanceof ExecutableElement) {
+                final ExecutableElement ee = (ExecutableElement) e;
+                final List<? extends VariableElement> params =
+                    ee.getParameters();
+                if (1 != params.size())
+                    throw new Exception("Classfile Baz badly formed: wrong number of methods");
+                final VariableElement param = params.get(0);
+                if (!param.getSimpleName().contentEquals("baz")) {
+                    errors++;
+                    System.err.println("javac did not correctly resolve the metadata conflict, parameter's name reads as " + param.getSimpleName());
+                } else
+                    System.err.println("javac did correctly resolve the metadata conflict");
+            }
+        }
+    }
+
+    void modifyBaz(boolean flip) throws Exception {
+        final File Baz_class = new File(classesdir, Baz_name + ".class");
+        final ClassFile baz = ClassFile.read(Baz_class);
+        final int ind = baz.constant_pool.getUTF8Index("baz");
+        MethodParameters_attribute mpattr = null;
+        int mpind = 0;
+        Code_attribute cattr = null;
+        int cind = 0;
+
+        // Find the indexes of the MethodParameters and the Code attributes
+        if (baz.methods.length != 1)
+            throw new Exception("Classfile Baz badly formed: wrong number of methods");
+        if (!baz.methods[0].getName(baz.constant_pool).equals("<init>"))
+            throw new Exception("Classfile Baz badly formed: method has name " +
+                                baz.methods[0].getName(baz.constant_pool));
+        for (int i = 0; i < baz.methods[0].attributes.attrs.length; i++) {
+            if (baz.methods[0].attributes.attrs[i] instanceof
+                MethodParameters_attribute) {
+                mpattr = (MethodParameters_attribute)
+                    baz.methods[0].attributes.attrs[i];
+                mpind = i;
+            } else if (baz.methods[0].attributes.attrs[i] instanceof
+                       Code_attribute) {
+                cattr = (Code_attribute) baz.methods[0].attributes.attrs[i];
+                cind = i;
+            }
+        }
+        if (null == mpattr)
+            throw new Exception("Classfile Baz badly formed: no method parameters info");
+        if (null == cattr)
+            throw new Exception("Classfile Baz badly formed: no local variable table");
+
+        int flags = mpattr.method_parameter_table[0].flags;
+
+        // Alter the MethodParameters attribute, changing the name of
+        // the parameter from i to baz.  This requires Black Magic...
+        //
+        // The (well-designed) classfile library (correctly) does not
+        // allow us to mess around with the attribute data structures,
+        // or arbitrarily generate new ones.
+        //
+        // Instead, we install a new subclass of Attribute that
+        // hijacks the Visitor pattern and outputs the sequence of
+        // bytes that we want.  This only works in this particular
+        // instance, because we know we'll only every see one kind of
+        // visitor.
+        //
+        // If anyone ever changes the makeup of the Baz class, or
+        // tries to install some kind of visitor that gets run prior
+        // to serialization, this will break.
+        baz.methods[0].attributes.attrs[mpind] =
+            new Attribute(mpattr.attribute_name_index,
+                          mpattr.attribute_length) {
+                public <R, D> R accept(Visitor<R, D> visitor, D data) {
+                    if (data instanceof ByteArrayOutputStream) {
+                        ByteArrayOutputStream out =
+                            (ByteArrayOutputStream) data;
+                        out.write(1);
+                        out.write((ind >> 8) & 0xff);
+                        out.write(ind & 0xff);
+                        out.write((flags >> 24) & 0xff);
+                        out.write((flags >> 16) & 0xff);
+                        out.write((flags >> 8) & 0xff);
+                        out.write(flags & 0xff);
+                    } else
+                        throw new RuntimeException("Output stream is of type " + data.getClass() + ", which is not handled by this test.  Update the test and it should work.");
+                    return null;
+                }
+            };
+
+        // Flip the code and method attributes.  This is for checking
+        // that order doesn't matter.
+        if (flip) {
+            baz.methods[0].attributes.attrs[mpind] = cattr;
+            baz.methods[0].attributes.attrs[cind] = mpattr;
+        }
+
+        new ClassWriter().write(baz, Baz_class);
+    }
+
+    // Run a bunch of structural tests on foo to make sure it looks right.
+    void checkFoo() throws Exception {
+        final File Foo_class = new File(classesdir, Foo_name + ".class");
+        final ClassFile foo = ClassFile.read(Foo_class);
+        for (int i = 0; i < foo.methods.length; i++) {
+            System.err.println("Examine method Foo." + foo.methods[i].getName(foo.constant_pool));
+            if (foo.methods[i].getName(foo.constant_pool).equals("foo2")) {
+                for (int j = 0; j < foo.methods[i].attributes.attrs.length; j++)
+                    if (foo.methods[i].attributes.attrs[j] instanceof
+                        MethodParameters_attribute) {
+                        MethodParameters_attribute mp =
+                            (MethodParameters_attribute)
+                            foo.methods[i].attributes.attrs[j];
+                        System.err.println("Foo.foo2 should have 2 parameters: j and k");
+                        if (2 != mp.method_parameter_table_length)
+                            error("expected 2 method parameter entries in foo2, got " +
+                                  mp.method_parameter_table_length);
+                        else if (!foo.constant_pool.getUTF8Value(mp.method_parameter_table[0].name_index).equals("j"))
+                            error("expected first parameter to foo2 to be \"j\", got \"" +
+                                  foo.constant_pool.getUTF8Value(mp.method_parameter_table[0].name_index) +
+                                  "\" instead");
+                        else if  (!foo.constant_pool.getUTF8Value(mp.method_parameter_table[1].name_index).equals("k"))
+                            error("expected first parameter to foo2 to be \"k\", got \"" +
+                                  foo.constant_pool.getUTF8Value(mp.method_parameter_table[1].name_index) +
+                                  "\" instead");
+                    }
+            }
+            else if (foo.methods[i].getName(foo.constant_pool).equals("<init>")) {
+                for (int j = 0; j < foo.methods[i].attributes.attrs.length; j++) {
+                    if (foo.methods[i].attributes.attrs[j] instanceof
+                        MethodParameters_attribute)
+                        error("Zero-argument constructor shouldn't have MethodParameters");
+                }
+            }
+            else if (foo.methods[i].getName(foo.constant_pool).equals("foo0")) {
+                for (int j = 0; j < foo.methods[i].attributes.attrs.length; j++)
+                    if (foo.methods[i].attributes.attrs[j] instanceof
+                        MethodParameters_attribute)
+                        error("Zero-argument method shouldn't have MethodParameters");
+            }
+            else
+                error("Unknown method " + foo.methods[i].getName(foo.constant_pool) + " showed up in class Foo");
+        }
+    }
+
+    // Run a bunch of structural tests on Bar to make sure it looks right.
+    void checkBar() throws Exception {
+        final File Bar_class = new File(classesdir, Bar_name + ".class");
+        final ClassFile bar = ClassFile.read(Bar_class);
+        for (int i = 0; i < bar.methods.length; i++) {
+            System.err.println("Examine method Bar." + bar.methods[i].getName(bar.constant_pool));
+            if (bar.methods[i].getName(bar.constant_pool).equals("<init>")) {
+                for (int j = 0; j < bar.methods[i].attributes.attrs.length; j++)
+                    if (bar.methods[i].attributes.attrs[j] instanceof
+                        MethodParameters_attribute) {
+                        MethodParameters_attribute mp =
+                            (MethodParameters_attribute)
+                            bar.methods[i].attributes.attrs[j];
+                        System.err.println("Bar constructor should have 1 parameter: i");
+                        if (1 != mp.method_parameter_table_length)
+                            error("expected 1 method parameter entries in constructor, got " +
+                                  mp.method_parameter_table_length);
+                        else if (!bar.constant_pool.getUTF8Value(mp.method_parameter_table[0].name_index).equals("i"))
+                            error("expected first parameter to foo2 to be \"i\", got \"" +
+                                  bar.constant_pool.getUTF8Value(mp.method_parameter_table[0].name_index) +
+                                  "\" instead");
+                    }
+            }
+            else if (bar.methods[i].getName(bar.constant_pool).equals("foo")) {
+                for (int j = 0; j < bar.methods[i].attributes.attrs.length; j++) {
+                    if (bar.methods[i].attributes.attrs[j] instanceof
+                        MethodParameters_attribute)
+                        error("Zero-argument constructor shouldn't have MethodParameters");
+                }
+            }
+        }
+    }
+
+    String compile(String... args) throws Exception {
+        System.err.println("compile: " + Arrays.asList(args));
+        StringWriter sw = new StringWriter();
+        PrintWriter pw = new PrintWriter(sw);
+        int rc = com.sun.tools.javac.Main.compile(args, pw);
+        pw.close();
+        String out = sw.toString();
+        if (out.length() > 0)
+            System.err.println(out);
+        if (rc != 0)
+            error("compilation failed, rc=" + rc);
+        return out;
+    }
+
+    File writeFile(File dir, String path, String body) throws IOException {
+        File f = new File(dir, path);
+        f.getParentFile().mkdirs();
+        FileWriter out = new FileWriter(f);
+        out.write(body);
+        out.close();
+        return f;
+    }
+
+    void error(String msg) {
+        System.err.println("Error: " + msg);
+        errors++;
+    }
+
+    int errors;
+}