8006582: Test for parameter names feature

Wed, 20 Feb 2013 15:47:14 -0800

author
strarup
date
Wed, 20 Feb 2013 15:47:14 -0800
changeset 1594
267225edc1fe
parent 1593
4cf6e84f844f
child 1595
d686d8a7eb78

8006582: Test for parameter names feature
Reviewed-by: jjg, darcy, emc

test/tools/javac/MethodParameters.java file | annotate | diff | comparison | revisions
test/tools/javac/MethodParameters/AnnotationTest.java file | annotate | diff | comparison | revisions
test/tools/javac/MethodParameters/AnonymousClass.java file | annotate | diff | comparison | revisions
test/tools/javac/MethodParameters/AttributeVisitor.java file | annotate | diff | comparison | revisions
test/tools/javac/MethodParameters/ClassFileVisitor.java file | annotate | diff | comparison | revisions
test/tools/javac/MethodParameters/Constructors.java file | annotate | diff | comparison | revisions
test/tools/javac/MethodParameters/EnumTest.java file | annotate | diff | comparison | revisions
test/tools/javac/MethodParameters/InstanceMethods.java file | annotate | diff | comparison | revisions
test/tools/javac/MethodParameters/LambdaTest.java file | annotate | diff | comparison | revisions
test/tools/javac/MethodParameters/LocalClassTest.java file | annotate | diff | comparison | revisions
test/tools/javac/MethodParameters/MemberClassTest.java file | annotate | diff | comparison | revisions
test/tools/javac/MethodParameters/ReflectionVisitor.java file | annotate | diff | comparison | revisions
test/tools/javac/MethodParameters/StaticMethods.java file | annotate | diff | comparison | revisions
test/tools/javac/MethodParameters/Tester.java file | annotate | diff | comparison | revisions
test/tools/javac/MethodParameters/UncommonParamNames.java file | annotate | diff | comparison | revisions
test/tools/javac/MethodParametersTest.java file | annotate | diff | comparison | revisions
     1.1 --- a/test/tools/javac/MethodParameters.java	Tue Feb 19 20:53:35 2013 -0800
     1.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
     1.3 @@ -1,344 +0,0 @@
     1.4 -/*
     1.5 - * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved.
     1.6 - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
     1.7 - *
     1.8 - * This code is free software; you can redistribute it and/or modify it
     1.9 - * under the terms of the GNU General Public License version 2 only, as
    1.10 - * published by the Free Software Foundation.
    1.11 - *
    1.12 - * This code is distributed in the hope that it will be useful, but WITHOUT
    1.13 - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
    1.14 - * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
    1.15 - * version 2 for more details (a copy is included in the LICENSE file that
    1.16 - * accompanied this code).
    1.17 - *
    1.18 - * You should have received a copy of the GNU General Public License version
    1.19 - * 2 along with this work; if not, write to the Free Software Foundation,
    1.20 - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
    1.21 - *
    1.22 - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
    1.23 - * or visit www.oracle.com if you need additional information or have any
    1.24 - * questions.
    1.25 - */
    1.26 -
    1.27 -/*
    1.28 - * @test
    1.29 - * @bug 8004727
    1.30 - * @summary javac should generate method parameters correctly.
    1.31 - */
    1.32 -// key: opt.arg.parameters
    1.33 -import com.sun.tools.classfile.*;
    1.34 -import com.sun.tools.javac.file.JavacFileManager;
    1.35 -import com.sun.tools.javac.main.Main;
    1.36 -import com.sun.tools.javac.util.Context;
    1.37 -import com.sun.tools.javac.util.Name;
    1.38 -import com.sun.tools.javac.util.Names;
    1.39 -import java.io.*;
    1.40 -import javax.lang.model.element.*;
    1.41 -import java.util.*;
    1.42 -
    1.43 -public class MethodParameters {
    1.44 -
    1.45 -    static final String Foo_name = "Foo";
    1.46 -    static final String Foo_contents =
    1.47 -        "public class Foo {\n" +
    1.48 -        "  Foo() {}\n" +
    1.49 -        "  void foo0() {}\n" +
    1.50 -        "  void foo2(int j, int k) {}\n" +
    1.51 -        "}";
    1.52 -    static final String Bar_name = "Bar";
    1.53 -    static final String Bar_contents =
    1.54 -        "public class Bar {\n" +
    1.55 -        "  Bar(int i) {}" +
    1.56 -        "  Foo foo() { return new Foo(); }\n" +
    1.57 -        "}";
    1.58 -    static final String Baz_name = "Baz";
    1.59 -    static final String Baz_contents =
    1.60 -        "public class Baz {\n" +
    1.61 -        "  int baz;" +
    1.62 -        "  Baz(int i) {}" +
    1.63 -        "}";
    1.64 -    static final String Qux_name = "Qux";
    1.65 -    static final String Qux_contents =
    1.66 -        "public class Qux extends Baz {\n" +
    1.67 -        "  Qux(int i) { super(i); }" +
    1.68 -        "}";
    1.69 -    static final File classesdir = new File("methodparameters");
    1.70 -
    1.71 -    public static void main(String... args) throws Exception {
    1.72 -        new MethodParameters().run();
    1.73 -    }
    1.74 -
    1.75 -    void run() throws Exception {
    1.76 -        classesdir.mkdir();
    1.77 -        final File Foo_java =
    1.78 -            writeFile(classesdir, Foo_name + ".java", Foo_contents);
    1.79 -        final File Bar_java =
    1.80 -            writeFile(classesdir, Bar_name + ".java", Bar_contents);
    1.81 -        final File Baz_java =
    1.82 -            writeFile(classesdir, Baz_name + ".java", Baz_contents);
    1.83 -        System.err.println("Test compile with -parameter");
    1.84 -        compile("-parameters", "-d", classesdir.getPath(), Foo_java.getPath());
    1.85 -        // First test: make sure javac doesn't choke to death on
    1.86 -        // MethodParameter attributes
    1.87 -        System.err.println("Test compile with classfile containing MethodParameter attributes");
    1.88 -        compile("-parameters", "-d", classesdir.getPath(),
    1.89 -                "-cp", classesdir.getPath(), Bar_java.getPath());
    1.90 -        System.err.println("Examine class foo");
    1.91 -        checkFoo();
    1.92 -        checkBar();
    1.93 -        System.err.println("Test debug information conflict");
    1.94 -        compile("-g", "-parameters", "-d", classesdir.getPath(),
    1.95 -                "-cp", classesdir.getPath(), Baz_java.getPath());
    1.96 -        System.err.println("Introducing debug information conflict");
    1.97 -        Baz_java.delete();
    1.98 -        modifyBaz(false);
    1.99 -        System.err.println("Checking language model");
   1.100 -        inspectBaz();
   1.101 -        System.err.println("Permuting attributes");
   1.102 -        modifyBaz(true);
   1.103 -        System.err.println("Checking language model");
   1.104 -        inspectBaz();
   1.105 -
   1.106 -        if(0 != errors)
   1.107 -            throw new Exception("MethodParameters test failed with " +
   1.108 -                                errors + " errors");
   1.109 -    }
   1.110 -
   1.111 -    void inspectBaz() throws Exception {
   1.112 -        final File Qux_java =
   1.113 -            writeFile(classesdir, Qux_name + ".java", Qux_contents);
   1.114 -        final String[] args = { "-XDsave-parameter-names", "-d",
   1.115 -                                classesdir.getPath(),
   1.116 -                                "-cp", classesdir.getPath(),
   1.117 -                                Qux_java.getPath() };
   1.118 -        final StringWriter sw = new StringWriter();
   1.119 -        final PrintWriter pw = new PrintWriter(sw);
   1.120 -
   1.121 -        // We need to be able to crack open javac and look at its data
   1.122 -        // structures.  We'll rig up a compiler instance, but keep its
   1.123 -        // Context, thus allowing us to get at the ClassReader.
   1.124 -        Context context = new Context();
   1.125 -        Main comp =  new Main("javac", pw);
   1.126 -        JavacFileManager.preRegister(context);
   1.127 -
   1.128 -        // Compile Qux, which uses Baz.
   1.129 -        comp.compile(args, context);
   1.130 -        pw.close();
   1.131 -        final String out = sw.toString();
   1.132 -        if (out.length() > 0)
   1.133 -            System.err.println(out);
   1.134 -
   1.135 -        // Now get the class reader, construct a name for Baz, and load it.
   1.136 -        com.sun.tools.javac.jvm.ClassReader cr =
   1.137 -            com.sun.tools.javac.jvm.ClassReader.instance(context);
   1.138 -        Name name = Names.instance(context).fromString(Baz_name);
   1.139 -
   1.140 -        // Now walk down the language model and check the name of the
   1.141 -        // parameter.
   1.142 -        final Element baz = cr.loadClass(name);
   1.143 -        for (Element e : baz.getEnclosedElements()) {
   1.144 -            if (e instanceof ExecutableElement) {
   1.145 -                final ExecutableElement ee = (ExecutableElement) e;
   1.146 -                final List<? extends VariableElement> params =
   1.147 -                    ee.getParameters();
   1.148 -                if (1 != params.size())
   1.149 -                    throw new Exception("Classfile Baz badly formed: wrong number of methods");
   1.150 -                final VariableElement param = params.get(0);
   1.151 -                if (!param.getSimpleName().contentEquals("baz")) {
   1.152 -                    errors++;
   1.153 -                    System.err.println("javac did not correctly resolve the metadata conflict, parameter's name reads as " + param.getSimpleName());
   1.154 -                } else
   1.155 -                    System.err.println("javac did correctly resolve the metadata conflict");
   1.156 -            }
   1.157 -        }
   1.158 -    }
   1.159 -
   1.160 -    void modifyBaz(boolean flip) throws Exception {
   1.161 -        final File Baz_class = new File(classesdir, Baz_name + ".class");
   1.162 -        final ClassFile baz = ClassFile.read(Baz_class);
   1.163 -        final int ind = baz.constant_pool.getUTF8Index("baz");
   1.164 -        MethodParameters_attribute mpattr = null;
   1.165 -        int mpind = 0;
   1.166 -        Code_attribute cattr = null;
   1.167 -        int cind = 0;
   1.168 -
   1.169 -        // Find the indexes of the MethodParameters and the Code attributes
   1.170 -        if (baz.methods.length != 1)
   1.171 -            throw new Exception("Classfile Baz badly formed: wrong number of methods");
   1.172 -        if (!baz.methods[0].getName(baz.constant_pool).equals("<init>"))
   1.173 -            throw new Exception("Classfile Baz badly formed: method has name " +
   1.174 -                                baz.methods[0].getName(baz.constant_pool));
   1.175 -        for (int i = 0; i < baz.methods[0].attributes.attrs.length; i++) {
   1.176 -            if (baz.methods[0].attributes.attrs[i] instanceof
   1.177 -                MethodParameters_attribute) {
   1.178 -                mpattr = (MethodParameters_attribute)
   1.179 -                    baz.methods[0].attributes.attrs[i];
   1.180 -                mpind = i;
   1.181 -            } else if (baz.methods[0].attributes.attrs[i] instanceof
   1.182 -                       Code_attribute) {
   1.183 -                cattr = (Code_attribute) baz.methods[0].attributes.attrs[i];
   1.184 -                cind = i;
   1.185 -            }
   1.186 -        }
   1.187 -        if (null == mpattr)
   1.188 -            throw new Exception("Classfile Baz badly formed: no method parameters info");
   1.189 -        if (null == cattr)
   1.190 -            throw new Exception("Classfile Baz badly formed: no local variable table");
   1.191 -
   1.192 -        int flags = mpattr.method_parameter_table[0].flags;
   1.193 -
   1.194 -        // Alter the MethodParameters attribute, changing the name of
   1.195 -        // the parameter from i to baz.  This requires Black Magic...
   1.196 -        //
   1.197 -        // The (well-designed) classfile library (correctly) does not
   1.198 -        // allow us to mess around with the attribute data structures,
   1.199 -        // or arbitrarily generate new ones.
   1.200 -        //
   1.201 -        // Instead, we install a new subclass of Attribute that
   1.202 -        // hijacks the Visitor pattern and outputs the sequence of
   1.203 -        // bytes that we want.  This only works in this particular
   1.204 -        // instance, because we know we'll only every see one kind of
   1.205 -        // visitor.
   1.206 -        //
   1.207 -        // If anyone ever changes the makeup of the Baz class, or
   1.208 -        // tries to install some kind of visitor that gets run prior
   1.209 -        // to serialization, this will break.
   1.210 -        baz.methods[0].attributes.attrs[mpind] =
   1.211 -            new Attribute(mpattr.attribute_name_index,
   1.212 -                          mpattr.attribute_length) {
   1.213 -                public <R, D> R accept(Visitor<R, D> visitor, D data) {
   1.214 -                    if (data instanceof ByteArrayOutputStream) {
   1.215 -                        ByteArrayOutputStream out =
   1.216 -                            (ByteArrayOutputStream) data;
   1.217 -                        out.write(1);
   1.218 -                        out.write((ind >> 8) & 0xff);
   1.219 -                        out.write(ind & 0xff);
   1.220 -                        out.write((flags >> 24) & 0xff);
   1.221 -                        out.write((flags >> 16) & 0xff);
   1.222 -                        out.write((flags >> 8) & 0xff);
   1.223 -                        out.write(flags & 0xff);
   1.224 -                    } else
   1.225 -                        throw new RuntimeException("Output stream is of type " + data.getClass() + ", which is not handled by this test.  Update the test and it should work.");
   1.226 -                    return null;
   1.227 -                }
   1.228 -            };
   1.229 -
   1.230 -        // Flip the code and method attributes.  This is for checking
   1.231 -        // that order doesn't matter.
   1.232 -        if (flip) {
   1.233 -            baz.methods[0].attributes.attrs[mpind] = cattr;
   1.234 -            baz.methods[0].attributes.attrs[cind] = mpattr;
   1.235 -        }
   1.236 -
   1.237 -        new ClassWriter().write(baz, Baz_class);
   1.238 -    }
   1.239 -
   1.240 -    // Run a bunch of structural tests on foo to make sure it looks right.
   1.241 -    void checkFoo() throws Exception {
   1.242 -        final File Foo_class = new File(classesdir, Foo_name + ".class");
   1.243 -        final ClassFile foo = ClassFile.read(Foo_class);
   1.244 -        for (int i = 0; i < foo.methods.length; i++) {
   1.245 -            System.err.println("Examine method Foo." + foo.methods[i].getName(foo.constant_pool));
   1.246 -            if (foo.methods[i].getName(foo.constant_pool).equals("foo2")) {
   1.247 -                for (int j = 0; j < foo.methods[i].attributes.attrs.length; j++)
   1.248 -                    if (foo.methods[i].attributes.attrs[j] instanceof
   1.249 -                        MethodParameters_attribute) {
   1.250 -                        MethodParameters_attribute mp =
   1.251 -                            (MethodParameters_attribute)
   1.252 -                            foo.methods[i].attributes.attrs[j];
   1.253 -                        System.err.println("Foo.foo2 should have 2 parameters: j and k");
   1.254 -                        if (2 != mp.method_parameter_table_length)
   1.255 -                            error("expected 2 method parameter entries in foo2, got " +
   1.256 -                                  mp.method_parameter_table_length);
   1.257 -                        else if (!foo.constant_pool.getUTF8Value(mp.method_parameter_table[0].name_index).equals("j"))
   1.258 -                            error("expected first parameter to foo2 to be \"j\", got \"" +
   1.259 -                                  foo.constant_pool.getUTF8Value(mp.method_parameter_table[0].name_index) +
   1.260 -                                  "\" instead");
   1.261 -                        else if  (!foo.constant_pool.getUTF8Value(mp.method_parameter_table[1].name_index).equals("k"))
   1.262 -                            error("expected first parameter to foo2 to be \"k\", got \"" +
   1.263 -                                  foo.constant_pool.getUTF8Value(mp.method_parameter_table[1].name_index) +
   1.264 -                                  "\" instead");
   1.265 -                    }
   1.266 -            }
   1.267 -            else if (foo.methods[i].getName(foo.constant_pool).equals("<init>")) {
   1.268 -                for (int j = 0; j < foo.methods[i].attributes.attrs.length; j++) {
   1.269 -                    if (foo.methods[i].attributes.attrs[j] instanceof
   1.270 -                        MethodParameters_attribute)
   1.271 -                        error("Zero-argument constructor shouldn't have MethodParameters");
   1.272 -                }
   1.273 -            }
   1.274 -            else if (foo.methods[i].getName(foo.constant_pool).equals("foo0")) {
   1.275 -                for (int j = 0; j < foo.methods[i].attributes.attrs.length; j++)
   1.276 -                    if (foo.methods[i].attributes.attrs[j] instanceof
   1.277 -                        MethodParameters_attribute)
   1.278 -                        error("Zero-argument method shouldn't have MethodParameters");
   1.279 -            }
   1.280 -            else
   1.281 -                error("Unknown method " + foo.methods[i].getName(foo.constant_pool) + " showed up in class Foo");
   1.282 -        }
   1.283 -    }
   1.284 -
   1.285 -    // Run a bunch of structural tests on Bar to make sure it looks right.
   1.286 -    void checkBar() throws Exception {
   1.287 -        final File Bar_class = new File(classesdir, Bar_name + ".class");
   1.288 -        final ClassFile bar = ClassFile.read(Bar_class);
   1.289 -        for (int i = 0; i < bar.methods.length; i++) {
   1.290 -            System.err.println("Examine method Bar." + bar.methods[i].getName(bar.constant_pool));
   1.291 -            if (bar.methods[i].getName(bar.constant_pool).equals("<init>")) {
   1.292 -                for (int j = 0; j < bar.methods[i].attributes.attrs.length; j++)
   1.293 -                    if (bar.methods[i].attributes.attrs[j] instanceof
   1.294 -                        MethodParameters_attribute) {
   1.295 -                        MethodParameters_attribute mp =
   1.296 -                            (MethodParameters_attribute)
   1.297 -                            bar.methods[i].attributes.attrs[j];
   1.298 -                        System.err.println("Bar constructor should have 1 parameter: i");
   1.299 -                        if (1 != mp.method_parameter_table_length)
   1.300 -                            error("expected 1 method parameter entries in constructor, got " +
   1.301 -                                  mp.method_parameter_table_length);
   1.302 -                        else if (!bar.constant_pool.getUTF8Value(mp.method_parameter_table[0].name_index).equals("i"))
   1.303 -                            error("expected first parameter to foo2 to be \"i\", got \"" +
   1.304 -                                  bar.constant_pool.getUTF8Value(mp.method_parameter_table[0].name_index) +
   1.305 -                                  "\" instead");
   1.306 -                    }
   1.307 -            }
   1.308 -            else if (bar.methods[i].getName(bar.constant_pool).equals("foo")) {
   1.309 -                for (int j = 0; j < bar.methods[i].attributes.attrs.length; j++) {
   1.310 -                    if (bar.methods[i].attributes.attrs[j] instanceof
   1.311 -                        MethodParameters_attribute)
   1.312 -                        error("Zero-argument constructor shouldn't have MethodParameters");
   1.313 -                }
   1.314 -            }
   1.315 -        }
   1.316 -    }
   1.317 -
   1.318 -    String compile(String... args) throws Exception {
   1.319 -        System.err.println("compile: " + Arrays.asList(args));
   1.320 -        StringWriter sw = new StringWriter();
   1.321 -        PrintWriter pw = new PrintWriter(sw);
   1.322 -        int rc = com.sun.tools.javac.Main.compile(args, pw);
   1.323 -        pw.close();
   1.324 -        String out = sw.toString();
   1.325 -        if (out.length() > 0)
   1.326 -            System.err.println(out);
   1.327 -        if (rc != 0)
   1.328 -            error("compilation failed, rc=" + rc);
   1.329 -        return out;
   1.330 -    }
   1.331 -
   1.332 -    File writeFile(File dir, String path, String body) throws IOException {
   1.333 -        File f = new File(dir, path);
   1.334 -        f.getParentFile().mkdirs();
   1.335 -        FileWriter out = new FileWriter(f);
   1.336 -        out.write(body);
   1.337 -        out.close();
   1.338 -        return f;
   1.339 -    }
   1.340 -
   1.341 -    void error(String msg) {
   1.342 -        System.err.println("Error: " + msg);
   1.343 -        errors++;
   1.344 -    }
   1.345 -
   1.346 -    int errors;
   1.347 -}
     2.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     2.2 +++ b/test/tools/javac/MethodParameters/AnnotationTest.java	Wed Feb 20 15:47:14 2013 -0800
     2.3 @@ -0,0 +1,54 @@
     2.4 +/*
     2.5 + * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
     2.6 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
     2.7 + *
     2.8 + * This code is free software; you can redistribute it and/or modify it
     2.9 + * under the terms of the GNU General Public License version 2 only, as
    2.10 + * published by the Free Software Foundation.
    2.11 + *
    2.12 + * This code is distributed in the hope that it will be useful, but WITHOUT
    2.13 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
    2.14 + * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
    2.15 + * version 2 for more details (a copy is included in the LICENSE file that
    2.16 + * accompanied this code).
    2.17 + *
    2.18 + * You should have received a copy of the GNU General Public License version
    2.19 + * 2 along with this work; if not, write to the Free Software Foundation,
    2.20 + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
    2.21 + *
    2.22 + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
    2.23 + * or visit www.oracle.com if you need additional information or have any
    2.24 + * questions.
    2.25 + */
    2.26 +
    2.27 +/*
    2.28 + * @test
    2.29 + * @bug 8006582
    2.30 + * @summary javac should generate method parameters correctly.
    2.31 + * @build Tester
    2.32 + * @compile -parameters AnnotationTest.java
    2.33 + * @run main Tester AnnotationTest
    2.34 + */
    2.35 +
    2.36 +import java.lang.annotation.*;
    2.37 +
    2.38 +/** Test that annotations do not interfere with recording of parameter names */
    2.39 +class AnnotationTest {
    2.40 +
    2.41 +    @Repeatable(Annos.class)
    2.42 +    @interface Anno {
    2.43 +        Class f() default int.class;
    2.44 +    }
    2.45 +
    2.46 +    @interface Annos { Anno[] value(); String foo() default "hello"; }
    2.47 +
    2.48 +    interface I {
    2.49 +        int m(@Anno @Anno int i, @Anno int ji);
    2.50 +    }
    2.51 +
    2.52 +    public AnnotationTest(@Anno @Anno I i, @Anno int ji) { }
    2.53 +    public @Anno String foo(@Anno @Anno I i, int ji) { return null; }
    2.54 +}
    2.55 +
    2.56 +
    2.57 +
     3.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     3.2 +++ b/test/tools/javac/MethodParameters/AnonymousClass.java	Wed Feb 20 15:47:14 2013 -0800
     3.3 @@ -0,0 +1,104 @@
     3.4 +/*
     3.5 + * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
     3.6 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
     3.7 + *
     3.8 + * This code is free software; you can redistribute it and/or modify it
     3.9 + * under the terms of the GNU General Public License version 2 only, as
    3.10 + * published by the Free Software Foundation.
    3.11 + *
    3.12 + * This code is distributed in the hope that it will be useful, but WITHOUT
    3.13 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
    3.14 + * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
    3.15 + * version 2 for more details (a copy is included in the LICENSE file that
    3.16 + * accompanied this code).
    3.17 + *
    3.18 + * You should have received a copy of the GNU General Public License version
    3.19 + * 2 along with this work; if not, write to the Free Software Foundation,
    3.20 + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
    3.21 + *
    3.22 + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
    3.23 + * or visit www.oracle.com if you need additional information or have any
    3.24 + * questions.
    3.25 + */
    3.26 +
    3.27 +/*
    3.28 + * @test
    3.29 + * @bug 8006582
    3.30 + * @summary javac should generate method parameters correctly.
    3.31 + * @build Tester
    3.32 + * @compile -parameters AnonymousClass.java
    3.33 + * @run main Tester AnonymousClass
    3.34 + */
    3.35 +
    3.36 +class AnonymousClass {
    3.37 +
    3.38 +    interface I<T> {
    3.39 +        T m();
    3.40 +        T m(T x, T yx);
    3.41 +    }
    3.42 +
    3.43 +    private class Inner implements I<String> {
    3.44 +        public Inner()  { }
    3.45 +        public Inner(String arg, String barg)  { }
    3.46 +        public String m() { return "0"; }
    3.47 +        public String m(String s, String ts) { return "0"; }
    3.48 +    }
    3.49 +
    3.50 +    public static class Sinner implements I<Long> {
    3.51 +        public Sinner()  { }
    3.52 +        public Sinner(Long arg, Long barg)  { }
    3.53 +        public Long m() { return 0L; }
    3.54 +        public Long m(Long s, Long ts) { return s + ts; }
    3.55 +    }
    3.56 +
    3.57 +    /** Inner class in constructor context */
    3.58 +    public AnonymousClass(final Long a, Long ba) {
    3.59 +        new I<Long>() {
    3.60 +            public Long m() { return null; }
    3.61 +            public Long m(Long i, Long ji) { return i + ji; }
    3.62 +        }.m(a, ba);
    3.63 +        new Inner() {
    3.64 +            public String m() { return null; }
    3.65 +            public String m(String i, String ji) { return i + ji; }
    3.66 +        }.m(a.toString(), ba.toString());
    3.67 +        new Inner(a.toString(), ba.toString()) {
    3.68 +            public String m() { return null; }
    3.69 +            public String m(String i, String ji) { return i + ji; }
    3.70 +        }.m(a.toString(), ba.toString());
    3.71 +        new Sinner() {
    3.72 +            public Long m() { return null; }
    3.73 +            public Long m(Long i, Long ji) { return i + ji; }
    3.74 +        }.m(a, ba);
    3.75 +        new Sinner(a, ba) {
    3.76 +            public Long m() { return null; }
    3.77 +            public Long m(Long i, Long ji) { return i + ji; }
    3.78 +        }.m(a, ba);
    3.79 +    }
    3.80 +
    3.81 +    /** Inner class in method context */
    3.82 +    public void foo(final Long a, Long ba) {
    3.83 +        new I<Long>() {
    3.84 +            public Long m() { return null; }
    3.85 +            public Long m(Long i, Long ji) { return i + ji; }
    3.86 +        }.m(a, ba);
    3.87 +        new Inner() {
    3.88 +            public String m() { return null; }
    3.89 +            public String m(String i, String ji) { return i + ji; }
    3.90 +        }.m(a.toString(), ba.toString());
    3.91 +        new Inner(a.toString(), ba.toString()) {
    3.92 +            public String m() { return null; }
    3.93 +            public String m(String i, String ji) { return i + ji; }
    3.94 +        }.m(a.toString(), ba.toString());
    3.95 +        new Sinner() {
    3.96 +            public Long m() { return null; }
    3.97 +            public Long m(Long i, Long ji) { return i + ji; }
    3.98 +        }.m(a, ba);
    3.99 +        new Sinner(a, ba) {
   3.100 +            public Long m() { return null; }
   3.101 +            public Long m(Long i, Long ji) { return i + ji; }
   3.102 +        }.m(a, ba);
   3.103 +    }
   3.104 +}
   3.105 +
   3.106 +
   3.107 +
     4.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     4.2 +++ b/test/tools/javac/MethodParameters/AttributeVisitor.java	Wed Feb 20 15:47:14 2013 -0800
     4.3 @@ -0,0 +1,59 @@
     4.4 +/*
     4.5 + * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
     4.6 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
     4.7 + *
     4.8 + * This code is free software; you can redistribute it and/or modify it
     4.9 + * under the terms of the GNU General Public License version 2 only, as
    4.10 + * published by the Free Software Foundation.
    4.11 + *
    4.12 + * This code is distributed in the hope that it will be useful, but WITHOUT
    4.13 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
    4.14 + * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
    4.15 + * version 2 for more details (a copy is included in the LICENSE file that
    4.16 + * accompanied this code).
    4.17 + *
    4.18 + * You should have received a copy of the GNU General Public License version
    4.19 + * 2 along with this work; if not, write to the Free Software Foundation,
    4.20 + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
    4.21 + *
    4.22 + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
    4.23 + * or visit www.oracle.com if you need additional information or have any
    4.24 + * questions.
    4.25 + */
    4.26 +
    4.27 +import com.sun.tools.classfile.*;
    4.28 +
    4.29 +/**
    4.30 + * Trivial {@code Attribute.Visitor} implementation, to make it easy to
    4.31 + * write visitors for specific attributes.
    4.32 + */
    4.33 +class AttributeVisitor<R, P> implements Attribute.Visitor<R, P> {
    4.34 +    public R visitBootstrapMethods(BootstrapMethods_attribute attr, P p) { return null; }
    4.35 +    public R visitDefault(DefaultAttribute attr, P p) { return null; }
    4.36 +    public R visitAnnotationDefault(AnnotationDefault_attribute attr, P p) { return null; }
    4.37 +    public R visitCharacterRangeTable(CharacterRangeTable_attribute attr, P p) { return null; }
    4.38 +    public R visitCode(Code_attribute attr, P p) { return null; }
    4.39 +    public R visitCompilationID(CompilationID_attribute attr, P p) { return null; }
    4.40 +    public R visitConstantValue(ConstantValue_attribute attr, P p) { return null; }
    4.41 +    public R visitDeprecated(Deprecated_attribute attr, P p) { return null; }
    4.42 +    public R visitEnclosingMethod(EnclosingMethod_attribute attr, P p) { return null; }
    4.43 +    public R visitExceptions(Exceptions_attribute attr, P p) { return null; }
    4.44 +    public R visitInnerClasses(InnerClasses_attribute attr, P p) { return null; }
    4.45 +    public R visitLineNumberTable(LineNumberTable_attribute attr, P p) { return null; }
    4.46 +    public R visitLocalVariableTable(LocalVariableTable_attribute attr, P p) { return null; }
    4.47 +    public R visitLocalVariableTypeTable(LocalVariableTypeTable_attribute attr, P p) { return null; }
    4.48 +    public R visitMethodParameters(MethodParameters_attribute attr, P p) { return null; }
    4.49 +    public R visitRuntimeVisibleAnnotations(RuntimeVisibleAnnotations_attribute attr, P p) { return null; }
    4.50 +    public R visitRuntimeInvisibleAnnotations(RuntimeInvisibleAnnotations_attribute attr, P p) { return null; }
    4.51 +    public R visitRuntimeVisibleParameterAnnotations(RuntimeVisibleParameterAnnotations_attribute attr, P p) { return null; }
    4.52 +    public R visitRuntimeInvisibleParameterAnnotations(RuntimeInvisibleParameterAnnotations_attribute attr, P p) { return null; }
    4.53 +    public R visitRuntimeVisibleTypeAnnotations(RuntimeVisibleTypeAnnotations_attribute attr, P p) { return null; }
    4.54 +    public R visitRuntimeInvisibleTypeAnnotations(RuntimeInvisibleTypeAnnotations_attribute attr, P p) { return null; }
    4.55 +    public R visitSignature(Signature_attribute attr, P p) { return null; }
    4.56 +    public R visitSourceDebugExtension(SourceDebugExtension_attribute attr, P p) { return null; }
    4.57 +    public R visitSourceFile(SourceFile_attribute attr, P p) { return null; }
    4.58 +    public R visitSourceID(SourceID_attribute attr, P p) { return null; }
    4.59 +    public R visitStackMap(StackMap_attribute attr, P p) { return null; }
    4.60 +    public R visitStackMapTable(StackMapTable_attribute attr, P p) { return null; }
    4.61 +    public R visitSynthetic(Synthetic_attribute attr, P p) { return null; }
    4.62 +}
     5.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     5.2 +++ b/test/tools/javac/MethodParameters/ClassFileVisitor.java	Wed Feb 20 15:47:14 2013 -0800
     5.3 @@ -0,0 +1,387 @@
     5.4 +/*
     5.5 + * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
     5.6 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
     5.7 + *
     5.8 + * This code is free software; you can redistribute it and/or modify it
     5.9 + * under the terms of the GNU General Public License version 2 only, as
    5.10 + * published by the Free Software Foundation.
    5.11 + *
    5.12 + * This code is distributed in the hope that it will be useful, but WITHOUT
    5.13 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
    5.14 + * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
    5.15 + * version 2 for more details (a copy is included in the LICENSE file that
    5.16 + * accompanied this code).
    5.17 + *
    5.18 + * You should have received a copy of the GNU General Public License version
    5.19 + * 2 along with this work; if not, write to the Free Software Foundation,
    5.20 + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
    5.21 + *
    5.22 + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
    5.23 + * or visit www.oracle.com if you need additional information or have any
    5.24 + * questions.
    5.25 + */
    5.26 +
    5.27 +import com.sun.tools.classfile.*;
    5.28 +import java.io.*;
    5.29 +import javax.lang.model.element.*;
    5.30 +import java.util.*;
    5.31 +
    5.32 +/**
    5.33 + * The {@code ClassFileVisitor} reads a class file using the
    5.34 + * {@code com.sun.tools.classfile} library. It iterates over the methods
    5.35 + * in a class, and checks MethodParameters attributes against JLS
    5.36 + * requirements, as well as assumptions about the javac implementations.
    5.37 + * <p>
    5.38 + * It enforces the following rules:
    5.39 + * <ul>
    5.40 + * <li>All non-synthetic methods with arguments must have the
    5.41 + * MethodParameters attribute. </li>
    5.42 + * <li>At most one MethodParameters attribute per method.</li>
    5.43 + * <li>An empty MethodParameters attribute is not allowed (i.e. no
    5.44 + * attribute for methods taking no parameters).</li>
    5.45 + * <li>The number of recorded parameter names much equal the number
    5.46 + * of parameters, including any implicit or synthetic parameters generated
    5.47 + * by the compiler.</li>
    5.48 + * <li>Although the spec allow recording parameters with no name, the javac
    5.49 + * implementation is assumed to record a name for all parameters. That is,
    5.50 + * the Methodparameters attribute must record a non-zero, valid constant
    5.51 + * pool index for each parameter.</li>
    5.52 + * <li>Check presence, expected names (e.g. this$N, $enum$name, ...) and flags
    5.53 + * (e.g. ACC_SYNTHETIC, ACC_MANDATED) for compiler generated parameters.</li>
    5.54 + * <li>Names of explicit parameters must reflect the names in the Java source.
    5.55 + * This is checked by assuming a design pattern where any name is permitted
    5.56 + * for the first explicit parameter. For subsequent parameters the following
    5.57 + * rule is checked: <i>param[n] == ++param[n-1].charAt(0) + param[n-1]</i>
    5.58 + * </ul>
    5.59 + */
    5.60 +class ClassFileVisitor extends Tester.Visitor {
    5.61 +
    5.62 +    Tester tester;
    5.63 +
    5.64 +    public String cname;
    5.65 +    public boolean isEnum;
    5.66 +    public boolean isInterface;
    5.67 +    public boolean isInner;
    5.68 +    public boolean isPublic;
    5.69 +    public boolean isStatic;
    5.70 +    public boolean isAnon;
    5.71 +    public ClassFile classFile;
    5.72 +
    5.73 +
    5.74 +    public ClassFileVisitor(Tester tester) {
    5.75 +        super(tester);
    5.76 +    }
    5.77 +
    5.78 +    public void error(String msg) {
    5.79 +        super.error("classfile: " + msg);
    5.80 +    }
    5.81 +
    5.82 +    public void warn(String msg) {
    5.83 +        super.warn("classfile: " + msg);
    5.84 +    }
    5.85 +
    5.86 +    /**
    5.87 +     * Read the class and determine some key characteristics, like if it's
    5.88 +     * an enum, or inner class, etc.
    5.89 +     */
    5.90 +    void visitClass(final String cname, final File cfile, final StringBuilder sb)
    5.91 +        throws Exception {
    5.92 +        this.cname = cname;
    5.93 +        classFile = ClassFile.read(cfile);
    5.94 +        isEnum = classFile.access_flags.is(AccessFlags.ACC_ENUM);
    5.95 +        isInterface = classFile.access_flags.is(AccessFlags.ACC_INTERFACE);
    5.96 +        isPublic = classFile.access_flags.is(AccessFlags.ACC_PUBLIC);
    5.97 +        isInner = false;
    5.98 +        isStatic = true;
    5.99 +        isAnon = false;
   5.100 +
   5.101 +        Attribute attr = classFile.getAttribute("InnerClasses");
   5.102 +        if (attr != null) attr.accept(new InnerClassVisitor(), null);
   5.103 +        isAnon = isInner & isAnon;
   5.104 +
   5.105 +        sb.append(isStatic ? "static " : "")
   5.106 +            .append(isPublic ? "public " : "")
   5.107 +            .append(isEnum ? "enum " : isInterface ? "interface " : "class ")
   5.108 +            .append(cname).append(" -- ")
   5.109 +            .append(isInner? "inner " : "" )
   5.110 +            .append(isAnon ?  "anon" : "")
   5.111 +            .append("\n");;
   5.112 +
   5.113 +        for (Method method : classFile.methods) {
   5.114 +            new MethodVisitor().visitMethod(method, sb);
   5.115 +        }
   5.116 +    }
   5.117 +
   5.118 +    /**
   5.119 +     * Used to visit InnerClasses_attribute of a class,
   5.120 +     * to determne if this class is an local class, and anonymous
   5.121 +     * inner class or a none-static member class. These types of
   5.122 +     * classes all have an containing class instances field that
   5.123 +     * requires an implicit or synthetic constructor argument.
   5.124 +     */
   5.125 +    class InnerClassVisitor extends AttributeVisitor<Void, Void> {
   5.126 +        public Void visitInnerClasses(InnerClasses_attribute iattr, Void v) {
   5.127 +            try{
   5.128 +                for (InnerClasses_attribute.Info info : iattr.classes) {
   5.129 +                    if (info.getInnerClassInfo(classFile.constant_pool) == null) continue;
   5.130 +                    String in = info.getInnerClassInfo(classFile.constant_pool).getName();
   5.131 +                    if (in == null || !cname.equals(in)) continue;
   5.132 +                    isInner = true;
   5.133 +                    isAnon = null == info.getInnerName(classFile.constant_pool);
   5.134 +                    isStatic = info.inner_class_access_flags.is(AccessFlags.ACC_STATIC);
   5.135 +                    break;
   5.136 +                }
   5.137 +            } catch(Exception e) {
   5.138 +                throw new IllegalStateException(e);
   5.139 +            }
   5.140 +            return null;
   5.141 +        }
   5.142 +    }
   5.143 +
   5.144 +    /**
   5.145 +     * Check the MethodParameters attribute of a method.
   5.146 +     */
   5.147 +    class MethodVisitor extends AttributeVisitor<Void, StringBuilder> {
   5.148 +
   5.149 +        public String mName;
   5.150 +        public Descriptor mDesc;
   5.151 +        public int mParams;
   5.152 +        public int mAttrs;
   5.153 +        public int mNumParams;
   5.154 +        public boolean mSynthetic;
   5.155 +        public boolean mIsConstructor;
   5.156 +        public String prefix;
   5.157 +
   5.158 +        void visitMethod(Method method, StringBuilder sb) throws Exception {
   5.159 +
   5.160 +            mName = method.getName(classFile.constant_pool);
   5.161 +            mDesc = method.descriptor;
   5.162 +            mParams =  mDesc.getParameterCount(classFile.constant_pool);
   5.163 +            mAttrs = method.attributes.attrs.length;
   5.164 +            mNumParams = -1; // no MethodParameters attribute found
   5.165 +            mSynthetic = method.access_flags.is(AccessFlags.ACC_SYNTHETIC);
   5.166 +            mIsConstructor = mName.equals("<init>");
   5.167 +            prefix = cname + "." + mName + "() - ";
   5.168 +
   5.169 +            sb.append(cname).append(".").append(mName).append("(");
   5.170 +
   5.171 +            for (Attribute a : method.attributes) {
   5.172 +                a.accept(this, sb);
   5.173 +            }
   5.174 +            if (mNumParams == -1) {
   5.175 +                if (mSynthetic) {
   5.176 +                    sb.append("<none>)!!");
   5.177 +                } else {
   5.178 +                    sb.append("<none>)");
   5.179 +                }
   5.180 +            }
   5.181 +            sb.append("\n");
   5.182 +
   5.183 +            // IMPL: methods with arguments must have a MethodParameters
   5.184 +            // attribute, except possibly some synthetic methods.
   5.185 +            if (mNumParams == -1 && mParams > 0 && ! mSynthetic) {
   5.186 +                error(prefix + "missing MethodParameters attribute");
   5.187 +            }
   5.188 +        }
   5.189 +
   5.190 +        public Void visitMethodParameters(MethodParameters_attribute mp,
   5.191 +                                          StringBuilder sb) {
   5.192 +
   5.193 +            // SPEC: At most one MethodParameters attribute allowed
   5.194 +            if (mNumParams != -1) {
   5.195 +                error(prefix + "Multiple MethodParameters attributes");
   5.196 +                return null;
   5.197 +            }
   5.198 +
   5.199 +            mNumParams = mp.method_parameter_table_length;
   5.200 +
   5.201 +            // SPEC: An empty attribute is not allowed!
   5.202 +            if (mNumParams == 0) {
   5.203 +                error(prefix + "0 length MethodParameters attribute");
   5.204 +                return null;
   5.205 +            }
   5.206 +
   5.207 +            // SPEC: one name per parameter.
   5.208 +            if (mNumParams != mParams) {
   5.209 +                error(prefix + "found " + mNumParams +
   5.210 +                      " parameters, expected " + mParams);
   5.211 +                return null;
   5.212 +            }
   5.213 +
   5.214 +            // IMPL: Whether MethodParameters attributes will be generated
   5.215 +            // for some synthetics is unresolved. For now, assume no.
   5.216 +            if (mSynthetic) {
   5.217 +                warn(prefix + "synthetic has MethodParameter attribute");
   5.218 +            }
   5.219 +
   5.220 +            String sep = "";
   5.221 +            String userParam = null;
   5.222 +            for (int x = 0; x <  mNumParams; x++) {
   5.223 +
   5.224 +                // IMPL: Assume all parameters are named, something.
   5.225 +                int cpi = mp.method_parameter_table[x].name_index;
   5.226 +                if (cpi == 0) {
   5.227 +                    error(prefix + "name expected, param[" + x + "]");
   5.228 +                    return null;
   5.229 +                }
   5.230 +
   5.231 +                // SPEC: a non 0 index, must be valid!
   5.232 +                String param = null;
   5.233 +                try {
   5.234 +                    param = classFile.constant_pool.getUTF8Value(cpi);
   5.235 +                    sb.append(sep).append(param);
   5.236 +                    sep = ", ";
   5.237 +                } catch(ConstantPoolException e) {
   5.238 +                    error(prefix + "invalid index " + cpi + " for param["
   5.239 +                          + x + "]");
   5.240 +                    return null;
   5.241 +                }
   5.242 +
   5.243 +
   5.244 +                // Check availability, flags and special names
   5.245 +                int check = checkParam(mp, param, x, sb);
   5.246 +                if (check < 0) {
   5.247 +                    return null;
   5.248 +                }
   5.249 +
   5.250 +                // TEST: check test assumptions about parameter name.
   5.251 +                // Expected names are calculated starting with the
   5.252 +                // 2nd explicit (user given) parameter.
   5.253 +                // param[n] == ++param[n-1].charAt(0) + param[n-1]
   5.254 +                String expect = null;
   5.255 +                if (userParam != null) {
   5.256 +                    char c = userParam.charAt(0);
   5.257 +                    expect =  (++c) + userParam;
   5.258 +                }
   5.259 +                if (check > 0) {
   5.260 +                    userParam = param;
   5.261 +                }
   5.262 +                if (expect != null && !param.equals(expect)) {
   5.263 +                    error(prefix + "param[" + x + "]='"
   5.264 +                          + param + "' expected '" + expect + "'");
   5.265 +                    return null;
   5.266 +                }
   5.267 +            }
   5.268 +            if (mSynthetic) {
   5.269 +                sb.append(")!!");
   5.270 +            } else {
   5.271 +                sb.append(")");
   5.272 +            }
   5.273 +            return null;
   5.274 +        }
   5.275 +
   5.276 +        /*
   5.277 +         * Check a parameter for conformity to JLS and javac specific
   5.278 +         * assumptions.
   5.279 +         * Return -1, if an error is detected. Otherwise, return 0, if
   5.280 +         * the parameter is compiler generated, or 1 for an (presumably)
   5.281 +         * explicitly declared parameter.
   5.282 +         */
   5.283 +        int checkParam(MethodParameters_attribute mp, String param, int index,
   5.284 +                       StringBuilder sb) {
   5.285 +
   5.286 +            boolean synthetic = (mp.method_parameter_table[index].flags
   5.287 +                                 & AccessFlags.ACC_SYNTHETIC) != 0;
   5.288 +            boolean mandated = (mp.method_parameter_table[index].flags
   5.289 +                                & AccessFlags.ACC_MANDATED) != 0;
   5.290 +
   5.291 +            // Setup expectations for flags and special names
   5.292 +            String expect = null;
   5.293 +            boolean allowMandated = false;
   5.294 +            boolean allowSynthetic = false;
   5.295 +            if (mSynthetic || synthetic) {
   5.296 +                // not an implementation gurantee, but okay for now
   5.297 +                expect = "arg" + index; // default
   5.298 +            }
   5.299 +            if (mIsConstructor) {
   5.300 +                if (isEnum) {
   5.301 +                    if (index == 0) {
   5.302 +                        expect = "\\$enum\\$name";
   5.303 +                        allowSynthetic = true;
   5.304 +                    } else if(index == 1) {
   5.305 +                        expect = "\\$enum\\$ordinal";
   5.306 +                        allowSynthetic = true;
   5.307 +                    }
   5.308 +                } else if (index == 0) {
   5.309 +                    if (isAnon) {
   5.310 +                        allowMandated = true;
   5.311 +                        expect = "this\\$[0-n]*";
   5.312 +                    } else if (isInner && !isStatic) {
   5.313 +                        allowMandated = true;
   5.314 +                        if (!isPublic) {
   5.315 +                            // some but not all non-public inner classes
   5.316 +                            // have synthetic argument. For now we give
   5.317 +                            // the test a bit of slack and allow either.
   5.318 +                            allowSynthetic = true;
   5.319 +                        }
   5.320 +                        expect = "this\\$[0-n]*";
   5.321 +                    }
   5.322 +                } else if (isAnon) {
   5.323 +                    // not an implementation gurantee, but okay for now
   5.324 +                    expect = "x[0-n]*";
   5.325 +                }
   5.326 +            } else if (isEnum && mNumParams == 1 && index == 0 && mName.equals("valueOf")) {
   5.327 +                expect = "name";
   5.328 +                allowMandated = true;
   5.329 +            }
   5.330 +            if (mandated) sb.append("!");
   5.331 +            if (synthetic) sb.append("!!");
   5.332 +
   5.333 +            // IMPL: our rules a somewhat fuzzy, sometimes allowing both mandated
   5.334 +            // and synthetic. However, a parameters cannot be both.
   5.335 +            if (mandated && synthetic) {
   5.336 +                error(prefix + "param[" + index + "] == \"" + param
   5.337 +                      + "\" ACC_SYNTHETIC and ACC_MANDATED");
   5.338 +                return -1;
   5.339 +            }
   5.340 +            // ... but must be either, if both "allowed".
   5.341 +            if (!(mandated || synthetic) && allowMandated && allowSynthetic) {
   5.342 +                error(prefix + "param[" + index + "] == \"" + param
   5.343 +                      + "\" expected ACC_MANDATED or ACC_SYNTHETIC");
   5.344 +                return -1;
   5.345 +            }
   5.346 +
   5.347 +            // ... if only one is "allowed", we meant "required".
   5.348 +            if (!mandated && allowMandated && !allowSynthetic) {
   5.349 +                error(prefix + "param[" + index + "] == \"" + param
   5.350 +                      + "\" expected ACC_MANDATED");
   5.351 +                return -1;
   5.352 +            }
   5.353 +            if (!synthetic && !allowMandated && allowSynthetic) {
   5.354 +                error(prefix + "param[" + index + "] == \"" + param
   5.355 +                      + "\" expected ACC_SYNTHETIC");
   5.356 +                return -1;
   5.357 +            }
   5.358 +
   5.359 +            // ... and not "allowed", means prohibited.
   5.360 +            if (mandated && !allowMandated) {
   5.361 +                error(prefix + "param[" + index + "] == \"" + param
   5.362 +                      + "\" unexpected, is ACC_MANDATED");
   5.363 +                return -1;
   5.364 +            }
   5.365 +            if (synthetic && !allowSynthetic) {
   5.366 +                error(prefix + "param[" + index + "] == \"" + param
   5.367 +                      + "\" unexpected, is ACC_SYNTHETIC");
   5.368 +                return -1;
   5.369 +            }
   5.370 +
   5.371 +            // Test special name expectations
   5.372 +            if (expect != null) {
   5.373 +                if (param.matches(expect)) {
   5.374 +                    return 0;
   5.375 +                }
   5.376 +                error(prefix + "param[" + index + "]='" + param +
   5.377 +                      "' expected '" + expect + "'");
   5.378 +                return -1;
   5.379 +            }
   5.380 +
   5.381 +            // No further checking for synthetic methods.
   5.382 +            if (mSynthetic) {
   5.383 +                return 0;
   5.384 +            }
   5.385 +
   5.386 +            // Otherwise, do check test parameter naming convention.
   5.387 +            return 1;
   5.388 +        }
   5.389 +    }
   5.390 +}
     6.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     6.2 +++ b/test/tools/javac/MethodParameters/Constructors.java	Wed Feb 20 15:47:14 2013 -0800
     6.3 @@ -0,0 +1,41 @@
     6.4 +/*
     6.5 + * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
     6.6 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
     6.7 + *
     6.8 + * This code is free software; you can redistribute it and/or modify it
     6.9 + * under the terms of the GNU General Public License version 2 only, as
    6.10 + * published by the Free Software Foundation.
    6.11 + *
    6.12 + * This code is distributed in the hope that it will be useful, but WITHOUT
    6.13 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
    6.14 + * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
    6.15 + * version 2 for more details (a copy is included in the LICENSE file that
    6.16 + * accompanied this code).
    6.17 + *
    6.18 + * You should have received a copy of the GNU General Public License version
    6.19 + * 2 along with this work; if not, write to the Free Software Foundation,
    6.20 + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
    6.21 + *
    6.22 + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
    6.23 + * or visit www.oracle.com if you need additional information or have any
    6.24 + * questions.
    6.25 + */
    6.26 +
    6.27 +/*
    6.28 + * @test
    6.29 + * @bug 8006582
    6.30 + * @summary javac should generate method parameters correctly.
    6.31 + * @build Tester
    6.32 + * @compile -parameters Constructors.java
    6.33 + * @run main Tester Constructors
    6.34 + */
    6.35 +
    6.36 +public class Constructors {
    6.37 +    public Constructors() {}
    6.38 +    Constructors(final Object a, final String... ba) { }
    6.39 +    protected Constructors(Object a, final Object ba, final String... cba) { }
    6.40 +    private Constructors(int a, Object ba, final Object cba, final String... dcba) { }
    6.41 +}
    6.42 +
    6.43 +
    6.44 +
     7.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     7.2 +++ b/test/tools/javac/MethodParameters/EnumTest.java	Wed Feb 20 15:47:14 2013 -0800
     7.3 @@ -0,0 +1,45 @@
     7.4 +/*
     7.5 + * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
     7.6 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
     7.7 + *
     7.8 + * This code is free software; you can redistribute it and/or modify it
     7.9 + * under the terms of the GNU General Public License version 2 only, as
    7.10 + * published by the Free Software Foundation.
    7.11 + *
    7.12 + * This code is distributed in the hope that it will be useful, but WITHOUT
    7.13 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
    7.14 + * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
    7.15 + * version 2 for more details (a copy is included in the LICENSE file that
    7.16 + * accompanied this code).
    7.17 + *
    7.18 + * You should have received a copy of the GNU General Public License version
    7.19 + * 2 along with this work; if not, write to the Free Software Foundation,
    7.20 + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
    7.21 + *
    7.22 + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
    7.23 + * or visit www.oracle.com if you need additional information or have any
    7.24 + * questions.
    7.25 + */
    7.26 +
    7.27 +/*
    7.28 + * @test
    7.29 + * @bug 8006582
    7.30 + * @summary javac should generate method parameters correctly.
    7.31 + * @build Tester
    7.32 + * @compile -parameters EnumTest.java
    7.33 + * @run main Tester EnumTest
    7.34 + */
    7.35 +
    7.36 +/** Test that parameter names are recorded for enum methods */
    7.37 +enum EnumTest {
    7.38 +    E1(0), E2(1, "x"), E3(2, "x", "y"), E4;
    7.39 +
    7.40 +    EnumTest() { }
    7.41 +    EnumTest(int a, String... ba) { }
    7.42 +    boolean ok(int c, String... dc) { return true; }
    7.43 +
    7.44 +    int valueOf(EnumTest A, EnumTest BA) { return 0; }
    7.45 +}
    7.46 +
    7.47 +
    7.48 +
     8.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     8.2 +++ b/test/tools/javac/MethodParameters/InstanceMethods.java	Wed Feb 20 15:47:14 2013 -0800
     8.3 @@ -0,0 +1,46 @@
     8.4 +/*
     8.5 + * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
     8.6 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
     8.7 + *
     8.8 + * This code is free software; you can redistribute it and/or modify it
     8.9 + * under the terms of the GNU General Public License version 2 only, as
    8.10 + * published by the Free Software Foundation.
    8.11 + *
    8.12 + * This code is distributed in the hope that it will be useful, but WITHOUT
    8.13 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
    8.14 + * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
    8.15 + * version 2 for more details (a copy is included in the LICENSE file that
    8.16 + * accompanied this code).
    8.17 + *
    8.18 + * You should have received a copy of the GNU General Public License version
    8.19 + * 2 along with this work; if not, write to the Free Software Foundation,
    8.20 + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
    8.21 + *
    8.22 + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
    8.23 + * or visit www.oracle.com if you need additional information or have any
    8.24 + * questions.
    8.25 + */
    8.26 +
    8.27 +/*
    8.28 + * @test
    8.29 + * @bug 8006582
    8.30 + * @summary javac should generate method parameters correctly.
    8.31 + * @build Tester
    8.32 + * @compile -parameters InstanceMethods.java
    8.33 + * @run main Tester InstanceMethods
    8.34 + */
    8.35 +
    8.36 +public class InstanceMethods {
    8.37 +    public void empty() {}
    8.38 +    final void def(Object a, final Object ba, final String... cba) { }
    8.39 +    final public void pub(Object d, final Object ed, final String... fed) { }
    8.40 +    protected boolean prot(Object g, final Object hg, final String... ihg) { return true; }
    8.41 +    private boolean priv(Object j, final Object kj, final String... lkj) { return true; }
    8.42 +    void def(int A, Object BA, final Object CBA, final String... DCBA) { }
    8.43 +    public void pub(int B, Object CB, final Object DCB, final String... EDCB) { }
    8.44 +    final protected boolean prot(int C, Object DC, final Object EDC, final String... FEDC) { return true; }
    8.45 +    final private boolean priv(int D, Object ED, final Object FED, final String... GFED) { return true; }
    8.46 +}
    8.47 +
    8.48 +
    8.49 +
     9.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     9.2 +++ b/test/tools/javac/MethodParameters/LambdaTest.java	Wed Feb 20 15:47:14 2013 -0800
     9.3 @@ -0,0 +1,51 @@
     9.4 +/*
     9.5 + * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
     9.6 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
     9.7 + *
     9.8 + * This code is free software; you can redistribute it and/or modify it
     9.9 + * under the terms of the GNU General Public License version 2 only, as
    9.10 + * published by the Free Software Foundation.
    9.11 + *
    9.12 + * This code is distributed in the hope that it will be useful, but WITHOUT
    9.13 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
    9.14 + * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
    9.15 + * version 2 for more details (a copy is included in the LICENSE file that
    9.16 + * accompanied this code).
    9.17 + *
    9.18 + * You should have received a copy of the GNU General Public License version
    9.19 + * 2 along with this work; if not, write to the Free Software Foundation,
    9.20 + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
    9.21 + *
    9.22 + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
    9.23 + * or visit www.oracle.com if you need additional information or have any
    9.24 + * questions.
    9.25 + */
    9.26 +
    9.27 +/*
    9.28 + * @test
    9.29 + * @bug 8006582
    9.30 + * @summary javac should generate method parameters correctly.
    9.31 + * @build Tester
    9.32 + * @compile -parameters LambdaTest.java
    9.33 + * @run main Tester LambdaTest
    9.34 + */
    9.35 +
    9.36 +/**
    9.37 + * Parameter names are not recorded for lambdas. This test verifies
    9.38 + * that there are no MethodParameters attribute for lambdas.
    9.39 + */
    9.40 +class LambdaTest {
    9.41 +
    9.42 +    interface I {
    9.43 +        int m(int x);
    9.44 +    }
    9.45 +
    9.46 +    static int foo(I i) { return i.m(0); }
    9.47 +
    9.48 +    static {
    9.49 +        foo((int x1) -> { return foo((int x2) -> { return x1 + x2; }); });
    9.50 +    }
    9.51 +}
    9.52 +
    9.53 +
    9.54 +
    10.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    10.2 +++ b/test/tools/javac/MethodParameters/LocalClassTest.java	Wed Feb 20 15:47:14 2013 -0800
    10.3 @@ -0,0 +1,50 @@
    10.4 +/*
    10.5 + * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
    10.6 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
    10.7 + *
    10.8 + * This code is free software; you can redistribute it and/or modify it
    10.9 + * under the terms of the GNU General Public License version 2 only, as
   10.10 + * published by the Free Software Foundation.
   10.11 + *
   10.12 + * This code is distributed in the hope that it will be useful, but WITHOUT
   10.13 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
   10.14 + * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
   10.15 + * version 2 for more details (a copy is included in the LICENSE file that
   10.16 + * accompanied this code).
   10.17 + *
   10.18 + * You should have received a copy of the GNU General Public License version
   10.19 + * 2 along with this work; if not, write to the Free Software Foundation,
   10.20 + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
   10.21 + *
   10.22 + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
   10.23 + * or visit www.oracle.com if you need additional information or have any
   10.24 + * questions.
   10.25 + */
   10.26 +
   10.27 +/*
   10.28 + * @test
   10.29 + * @bug 8006582
   10.30 + * @summary javac should generate method parameters correctly.
   10.31 + * @build Tester
   10.32 + * @compile -parameters LocalClassTest.java
   10.33 + * @run main Tester LocalClassTest
   10.34 + */
   10.35 +
   10.36 +class LocalClassTest {
   10.37 +    void foo() {
   10.38 +        class Local_default_constructor {
   10.39 +            public void foo() {}
   10.40 +            public void foo(int m, int nm) {}
   10.41 +        }
   10.42 +        class Local_has_constructor {
   10.43 +            public Local_has_constructor() {}
   10.44 +            public Local_has_constructor(int a, int ba) {}
   10.45 +            public void foo() {}
   10.46 +            public void foo(int m, int nm) {}
   10.47 +        }
   10.48 +        new LocalClassTest().foo();
   10.49 +    }
   10.50 +}
   10.51 +
   10.52 +
   10.53 +
    11.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    11.2 +++ b/test/tools/javac/MethodParameters/MemberClassTest.java	Wed Feb 20 15:47:14 2013 -0800
    11.3 @@ -0,0 +1,86 @@
    11.4 +/*
    11.5 + * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
    11.6 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
    11.7 + *
    11.8 + * This code is free software; you can redistribute it and/or modify it
    11.9 + * under the terms of the GNU General Public License version 2 only, as
   11.10 + * published by the Free Software Foundation.
   11.11 + *
   11.12 + * This code is distributed in the hope that it will be useful, but WITHOUT
   11.13 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
   11.14 + * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
   11.15 + * version 2 for more details (a copy is included in the LICENSE file that
   11.16 + * accompanied this code).
   11.17 + *
   11.18 + * You should have received a copy of the GNU General Public License version
   11.19 + * 2 along with this work; if not, write to the Free Software Foundation,
   11.20 + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
   11.21 + *
   11.22 + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
   11.23 + * or visit www.oracle.com if you need additional information or have any
   11.24 + * questions.
   11.25 + */
   11.26 +
   11.27 +/*
   11.28 + * @test
   11.29 + * @bug 8006582
   11.30 + * @summary javac should generate method parameters correctly.
   11.31 + * @build Tester
   11.32 + * @compile -parameters MemberClassTest.java
   11.33 + * @run main Tester MemberClassTest
   11.34 + */
   11.35 +
   11.36 +class MemberClassTest {
   11.37 +
   11.38 +    interface I {
   11.39 +        Long m();
   11.40 +        Long m(Long x, Long yx);
   11.41 +    }
   11.42 +
   11.43 +    public class Member implements I {
   11.44 +        public class Member_Member {
   11.45 +            public Member_Member() {}
   11.46 +            public Member_Member(String x, String yx) {}
   11.47 +        }
   11.48 +
   11.49 +        public Member()  { }
   11.50 +        public Member(Long a, Long ba)  { }
   11.51 +        public Long m() { return 0L; }
   11.52 +        public Long m(Long s, Long ts) { return 0L; }
   11.53 +    }
   11.54 +
   11.55 +    static class Static_Member implements I {
   11.56 +        public class Static_Member_Member {
   11.57 +            public Static_Member_Member() {}
   11.58 +            public Static_Member_Member(String x, String yx) {}
   11.59 +        }
   11.60 +
   11.61 +        public static class Static_Member_Static_Member {
   11.62 +            public Static_Member_Static_Member() {}
   11.63 +            public Static_Member_Static_Member(String x, String yx) {}
   11.64 +        }
   11.65 +        public Static_Member()  { }
   11.66 +        public Static_Member(Long arg, Long barg)  { }
   11.67 +        public Long m() { return 0L; }
   11.68 +        public Long m(Long s, Long ts) { return s + ts; }
   11.69 +    }
   11.70 +
   11.71 +    public MemberClassTest() {
   11.72 +    }
   11.73 +    public MemberClassTest(final Long a, Long ba) {
   11.74 +    }
   11.75 +
   11.76 +    public void foo() {
   11.77 +
   11.78 +        new I() {
   11.79 +
   11.80 +            class Anonymous_Member {
   11.81 +                public Anonymous_Member() {}
   11.82 +                public Anonymous_Member(String x, String yx) {}
   11.83 +            }
   11.84 +
   11.85 +            public Long m() { return 0L; }
   11.86 +            public Long m(Long s, Long ts) { return s + ts; }
   11.87 +        }.m();
   11.88 +    }
   11.89 +}
    12.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    12.2 +++ b/test/tools/javac/MethodParameters/ReflectionVisitor.java	Wed Feb 20 15:47:14 2013 -0800
    12.3 @@ -0,0 +1,270 @@
    12.4 +/*
    12.5 + * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
    12.6 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
    12.7 + *
    12.8 + * This code is free software; you can redistribute it and/or modify it
    12.9 + * under the terms of the GNU General Public License version 2 only, as
   12.10 + * published by the Free Software Foundation.
   12.11 + *
   12.12 + * This code is distributed in the hope that it will be useful, but WITHOUT
   12.13 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
   12.14 + * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
   12.15 + * version 2 for more details (a copy is included in the LICENSE file that
   12.16 + * accompanied this code).
   12.17 + *
   12.18 + * You should have received a copy of the GNU General Public License version
   12.19 + * 2 along with this work; if not, write to the Free Software Foundation,
   12.20 + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
   12.21 + *
   12.22 + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
   12.23 + * or visit www.oracle.com if you need additional information or have any
   12.24 + * questions.
   12.25 + */
   12.26 +
   12.27 +import java.io.*;
   12.28 +import java.util.*;
   12.29 +import java.net.*;
   12.30 +import java.lang.reflect.*;
   12.31 +
   12.32 +/**
   12.33 + * Test MethodParameter attributs by reflection API
   12.34 + */
   12.35 +public class ReflectionVisitor extends Tester.Visitor {
   12.36 +
   12.37 +    public ReflectionVisitor(Tester tester) {
   12.38 +        super(tester);
   12.39 +    }
   12.40 +
   12.41 +    public void error(String msg) {
   12.42 +        super.error("reflection: " + msg);
   12.43 +    }
   12.44 +
   12.45 +    public void warn(String msg) {
   12.46 +        super.warn("reflection: " + msg);
   12.47 +    }
   12.48 +
   12.49 +    boolean isEnum;
   12.50 +    boolean isInterface;
   12.51 +    boolean isAnon;
   12.52 +    boolean isLocal;
   12.53 +    boolean isMember;
   12.54 +    boolean isStatic;
   12.55 +    boolean isPublic;
   12.56 +    Class clazz;
   12.57 +    StringBuilder sb;
   12.58 +
   12.59 +    /**
   12.60 +     * Read class using {@code ClassFile}, and generate a list of methods
   12.61 +     * with parameter names as available in the MethodParameters attribute.
   12.62 +     */
   12.63 +    void visitClass(final String cl, final File cfile, final StringBuilder sb)
   12.64 +        throws Exception {
   12.65 +
   12.66 +        this.sb = sb;
   12.67 +        clazz = Class.forName(cl);
   12.68 +        isEnum = clazz.isEnum();
   12.69 +        isInterface = clazz.isInterface();
   12.70 +        isAnon = clazz.isAnonymousClass();
   12.71 +        isLocal = clazz.isLocalClass();
   12.72 +        isMember = clazz.isMemberClass();
   12.73 +        isStatic = ((clazz.getModifiers() & Modifier.STATIC) != 0);
   12.74 +        isPublic = ((clazz.getModifiers() & Modifier.PUBLIC) != 0);
   12.75 +
   12.76 +        sb.append(isStatic ? "static " : "")
   12.77 +            .append(isPublic ? "public " : "")
   12.78 +            .append(isEnum ? "enum " : isInterface ? "interface " : "class ")
   12.79 +            .append(cl).append(" -- ")
   12.80 +            .append(isMember? "member " : "" )
   12.81 +            .append(isLocal? "local " : "" )
   12.82 +            .append(isAnon ?  "anon" : "")
   12.83 +            .append("\n");
   12.84 +
   12.85 +        for (Constructor c : clazz.getDeclaredConstructors()) {
   12.86 +            testConstructor(c);
   12.87 +        }
   12.88 +
   12.89 +        for (Method m :clazz.getDeclaredMethods()) {
   12.90 +
   12.91 +            testMethod(m);
   12.92 +        }
   12.93 +    }
   12.94 +
   12.95 +    void testConstructor(Constructor c) {
   12.96 +
   12.97 +        String prefix = clazz.getName() + "." + c.getName() + "() - ";
   12.98 +
   12.99 +        // Parameters must match parameter types
  12.100 +        Parameter params[] = c.getParameters();
  12.101 +        int paramTypes =  c.getParameterTypes().length;
  12.102 +        if (paramTypes != params.length) {
  12.103 +            error(prefix + "number of parameter types (" + paramTypes
  12.104 +                  + ") != number of parameters (" + params.length + ")");
  12.105 +            return;
  12.106 +        }
  12.107 +
  12.108 +        sb.append(clazz.getName()).append(".").append("<init>").append("(");
  12.109 +        String sep = "";
  12.110 +
  12.111 +        // Some paramters are expected
  12.112 +        if (params.length < 2 && isEnum) {
  12.113 +            error(prefix + "enum constuctor, two arguments expected");
  12.114 +        } else if (params.length < 1 && (isAnon || isLocal ||
  12.115 +                                         (isMember && !isStatic ))) {
  12.116 +            error(prefix + "class constuctor,expected implicit argument");
  12.117 +        }
  12.118 +
  12.119 +        int i = -1;
  12.120 +        String param = null;
  12.121 +        for (Parameter p : c.getParameters()) {
  12.122 +            i++;
  12.123 +            String pname = p.getName();
  12.124 +            sb.append(sep).append(pname);
  12.125 +            if (p.isImplicit()) sb.append("!");
  12.126 +            if (p.isSynthetic()) sb.append("!!");
  12.127 +            sep = ", ";
  12.128 +
  12.129 +            // Set expectations
  12.130 +            String expect = null;
  12.131 +            boolean allowImplicit = false;
  12.132 +            boolean allowSynthetic = false;
  12.133 +            if (isEnum) {
  12.134 +                if (i == 0) {
  12.135 +                    expect = "\\$enum\\$name";
  12.136 +                    allowSynthetic = true;
  12.137 +                } else if(i == 1) {
  12.138 +                    expect = "\\$enum\\$ordinal";
  12.139 +                    allowSynthetic = true;
  12.140 +                }
  12.141 +            } else if (i == 0) {
  12.142 +                if (isAnon) {
  12.143 +                    allowImplicit = true;
  12.144 +                } else if (isLocal) {
  12.145 +                    allowImplicit = true;
  12.146 +                    expect = "this\\$[0-n]*";
  12.147 +                } else if ((isMember && !isStatic)) {
  12.148 +                    allowImplicit = true;
  12.149 +                    if (!isPublic) {
  12.150 +                        // some but not all non-public inner classes
  12.151 +                        // have synthetic argument. For now we give
  12.152 +                        // the test a bit of slack and allow either.
  12.153 +                        allowSynthetic = true;
  12.154 +                    }
  12.155 +                    expect = "this\\$[0-n]*";
  12.156 +                }
  12.157 +            } else if (isAnon) {
  12.158 +                // not an implementation gurantee, but okay for now
  12.159 +                expect = "x[0-n]*";
  12.160 +            }
  12.161 +
  12.162 +            // Check expected flags
  12.163 +            if (p.isSynthetic() && p.isImplicit()) {
  12.164 +                error(prefix + "param[" + i + "]='" + pname +
  12.165 +                      "' both isImplicit() and isSynthetic()");
  12.166 +                break;
  12.167 +            }
  12.168 +            if (allowImplicit && allowSynthetic &&
  12.169 +                !(p.isSynthetic() || p.isImplicit())) {
  12.170 +                error(prefix + "param[" + i + "]='" + pname +
  12.171 +                      "' isImplicit() or isSynthetic() expected");
  12.172 +                break;
  12.173 +            }
  12.174 +
  12.175 +            if (allowImplicit && !allowSynthetic && !p.isImplicit()) {
  12.176 +                error(prefix + "param[" + i + "]='" + pname +
  12.177 +                      "' isImplicit() expected");
  12.178 +                break;
  12.179 +            }
  12.180 +            if (!allowImplicit && allowSynthetic && !p.isSynthetic()) {
  12.181 +                error(prefix + "param[" + i + "]='" + pname +
  12.182 +                      "' isSynthetic() expected");
  12.183 +                break;
  12.184 +            }
  12.185 +
  12.186 +            if (!allowImplicit && p.isImplicit()) {
  12.187 +                error(prefix + "param[" + i + "]='" + pname +
  12.188 +                      "' isImplicit() unexpected");
  12.189 +                break;
  12.190 +            }
  12.191 +
  12.192 +            if (!allowSynthetic && p.isSynthetic()) {
  12.193 +                error(prefix + "param[" + i + "]='" + pname +
  12.194 +                      "' isSynthetic() unexpected");
  12.195 +                break;
  12.196 +            }
  12.197 +
  12.198 +            // Check expected names
  12.199 +            if (expect != null) {
  12.200 +                if (pname.matches(expect))  continue;
  12.201 +                error(prefix + "param[" + i + "]='" + pname +
  12.202 +                      "' expected '" + expect + "'");
  12.203 +                break;
  12.204 +            }
  12.205 +
  12.206 +            // Test naming convention for explicit parameters.
  12.207 +            boolean fidelity = !isAnon;
  12.208 +            if (param != null && fidelity) {
  12.209 +                char ch = param.charAt(0);
  12.210 +                expect =  (++ch) + param;
  12.211 +            }
  12.212 +
  12.213 +            if (pname != null && fidelity) {
  12.214 +                param = pname;
  12.215 +            }
  12.216 +
  12.217 +            if (expect != null && !expect.equals(pname)) {
  12.218 +                error(prefix + "param[" + i + "]='" + pname +
  12.219 +                      "' expected '" + expect + "'");
  12.220 +                break;
  12.221 +            }
  12.222 +        }
  12.223 +        if  (c.isSynthetic()) {
  12.224 +            sb.append(")!!\n");
  12.225 +        } else {
  12.226 +            sb.append(")\n");
  12.227 +        }
  12.228 +    }
  12.229 +
  12.230 +    void testMethod(Method m) {
  12.231 +
  12.232 +        String prefix = clazz.getName() + "." + m.getName() + "() - ";
  12.233 +
  12.234 +        // Parameters must match parameter types
  12.235 +        int paramTypes =  m.getParameterTypes().length;
  12.236 +        int params = m.getParameters().length;
  12.237 +        if (paramTypes != params) {
  12.238 +            error(prefix + "number of parameter types (" + paramTypes
  12.239 +                  + ") != number of parameters (" + params + ")");
  12.240 +            return;
  12.241 +        }
  12.242 +
  12.243 +        sb.append(clazz.getName()).append(".").append(m.getName()).append("(");
  12.244 +        String sep = "";
  12.245 +        String param = null;
  12.246 +        int i = -1;
  12.247 +        // For methods we expect all parameters to follow
  12.248 +        // the test-case design pattern, except synthetic methods.
  12.249 +        for (Parameter p : m.getParameters()) {
  12.250 +            i++;
  12.251 +            if (param == null) {
  12.252 +                param = p.getName();
  12.253 +                sb.append(sep).append(param);
  12.254 +            } else  {
  12.255 +                char c = param.charAt(0);
  12.256 +                String expect =  m.isSynthetic() ? ("arg" + i) : ((++c) + param);
  12.257 +                param = p.getName();
  12.258 +                sb.append(sep).append(param);
  12.259 +                if (!expect.equals(param)) {
  12.260 +                    error(prefix + "param[" + i + "]='"
  12.261 +                          + param + "' expected '" + expect + "'");
  12.262 +                    break;
  12.263 +                }
  12.264 +            }
  12.265 +            sep = ", ";
  12.266 +        }
  12.267 +        if  (m.isSynthetic()) {
  12.268 +            sb.append(")!!\n");
  12.269 +        } else {
  12.270 +            sb.append(")\n");
  12.271 +        }
  12.272 +    }
  12.273 +}
    13.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    13.2 +++ b/test/tools/javac/MethodParameters/StaticMethods.java	Wed Feb 20 15:47:14 2013 -0800
    13.3 @@ -0,0 +1,46 @@
    13.4 +/*
    13.5 + * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
    13.6 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
    13.7 + *
    13.8 + * This code is free software; you can redistribute it and/or modify it
    13.9 + * under the terms of the GNU General Public License version 2 only, as
   13.10 + * published by the Free Software Foundation.
   13.11 + *
   13.12 + * This code is distributed in the hope that it will be useful, but WITHOUT
   13.13 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
   13.14 + * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
   13.15 + * version 2 for more details (a copy is included in the LICENSE file that
   13.16 + * accompanied this code).
   13.17 + *
   13.18 + * You should have received a copy of the GNU General Public License version
   13.19 + * 2 along with this work; if not, write to the Free Software Foundation,
   13.20 + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
   13.21 + *
   13.22 + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
   13.23 + * or visit www.oracle.com if you need additional information or have any
   13.24 + * questions.
   13.25 + */
   13.26 +
   13.27 +/*
   13.28 + * @test
   13.29 + * @bug 8006582
   13.30 + * @summary javac should generate method parameters correctly.
   13.31 + * @build Tester
   13.32 + * @compile -parameters StaticMethods.java
   13.33 + * @run main Tester StaticMethods
   13.34 + */
   13.35 +
   13.36 +public class StaticMethods {
   13.37 +    static public void empty() {}
   13.38 +    static final void def(Object a, final Object ba, final String... cba) { }
   13.39 +    static final public void pub(Object d, final Object ed, final String... fed) { }
   13.40 +    static protected boolean prot(Object g, final Object hg, final String... ihg) { return true; }
   13.41 +    static private boolean priv(Object j, final Object kj, final String... lkj) { return true; }
   13.42 +    static void def(int a, Object ba, final Object cba, final String... dcba) { }
   13.43 +    static public void pub(int a, Object ba, final Object cba , final String... dcba) { }
   13.44 +    static final protected boolean prot(int aa, Object baa, final Object cbaa, final String... dcbaa) { return true; }
   13.45 +    static final private boolean priv(int abc, Object babc, final Object cbabc, final String... dcbabc) { return true; }
   13.46 +}
   13.47 +
   13.48 +
   13.49 +
    14.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    14.2 +++ b/test/tools/javac/MethodParameters/Tester.java	Wed Feb 20 15:47:14 2013 -0800
    14.3 @@ -0,0 +1,162 @@
    14.4 +/*
    14.5 + * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
    14.6 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
    14.7 + *
    14.8 + * This code is free software; you can redistribute it and/or modify it
    14.9 + * under the terms of the GNU General Public License version 2 only, as
   14.10 + * published by the Free Software Foundation.
   14.11 + *
   14.12 + * This code is distributed in the hope that it will be useful, but WITHOUT
   14.13 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
   14.14 + * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
   14.15 + * version 2 for more details (a copy is included in the LICENSE file that
   14.16 + * accompanied this code).
   14.17 + *
   14.18 + * You should have received a copy of the GNU General Public License version
   14.19 + * 2 along with this work; if not, write to the Free Software Foundation,
   14.20 + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
   14.21 + *
   14.22 + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
   14.23 + * or visit www.oracle.com if you need additional information or have any
   14.24 + * questions.
   14.25 + */
   14.26 +
   14.27 +import java.io.*;
   14.28 +import java.util.*;
   14.29 +import java.lang.reflect.Constructor;
   14.30 +
   14.31 +/**
   14.32 + * Test driver for MethodParameters testing.
   14.33 + * <p>
   14.34 + * The intended use of this driver is to run it, giving the name of
   14.35 + * a single class compiled with -parameters as argument. The driver
   14.36 + * will test the specified class, and any nested classes it finds.
   14.37 + * <p>
   14.38 + * Each class is tested in two way. By refelction, and by directly
   14.39 + * checking MethodParameters attributes in the classfile. The checking
   14.40 + * is done using two visitor classes {@link ClassFileVisitor} and
   14.41 + * {@link ReflectionVisitor}.
   14.42 + * <p>
   14.43 + * The {@code ReflectionVisitor} test logically belongs with library tests.
   14.44 + * we wish to reuse the same test-cases, so both test are committed together,
   14.45 + * under langtools. The tests, may be duplicated in the jdk repository.
   14.46 + */
   14.47 +public class Tester {
   14.48 +
   14.49 +    final static File classesdir = new File(System.getProperty("test.classes", "."));
   14.50 +
   14.51 +    /**
   14.52 +     * The visitor classes that does the actual checking are referenced
   14.53 +     * statically, to force compilations, without having to reference
   14.54 +     * them in individual test cases.
   14.55 +     * <p>
   14.56 +     * This makes it easy to change the set of visitors, without
   14.57 +     * complicating the design with dynamic discovery and compilation
   14.58 +     * of visitor classes.
   14.59 +     */
   14.60 +    static final Class visitors[] = {
   14.61 +        ClassFileVisitor.class,
   14.62 +        ReflectionVisitor.class
   14.63 +    };
   14.64 +
   14.65 +    /**
   14.66 +     * Test-driver expect a single classname as argument.
   14.67 +     */
   14.68 +    public static void main(String... args) throws Exception {
   14.69 +        if (args.length != 1) {
   14.70 +            throw new Error("A single class name is expected as argument");
   14.71 +        }
   14.72 +        final String pattern = args[0] + ".*\\.class";
   14.73 +        File files[] = classesdir.listFiles(new FileFilter() {
   14.74 +                public boolean accept(File f) {
   14.75 +                    return f.getName().matches(pattern);
   14.76 +                }
   14.77 +            });
   14.78 +        if (files.length == 0) {
   14.79 +            File file = new File(classesdir, args[0] + ".class");
   14.80 +            throw new Error(file.getPath() + " not found");
   14.81 +        }
   14.82 +
   14.83 +        new Tester(args[0], files).run();
   14.84 +    }
   14.85 +
   14.86 +    public Tester(String name, File files[]) {
   14.87 +        this.classname = name;
   14.88 +        this.files = files;
   14.89 +    }
   14.90 +
   14.91 +    void run() throws Exception {
   14.92 +
   14.93 +        // Test with each visitor
   14.94 +        for (Class<Visitor> vclass : visitors) {
   14.95 +            try {
   14.96 +                String vname = vclass.getName();
   14.97 +                Constructor c = vclass.getConstructor(Tester.class);
   14.98 +
   14.99 +                info("\nRun " + vname + " for " + classname + "\n");
  14.100 +                StringBuilder sb = new StringBuilder();
  14.101 +                for (File f : files) {
  14.102 +                    String fname = f.getName();
  14.103 +                    fname = fname.substring(0, fname.length() - 6);
  14.104 +                    Visitor v = (Visitor) c.newInstance(this);
  14.105 +                    try {
  14.106 +                        v.visitClass(fname, f,  sb);
  14.107 +                    } catch(Exception e) {
  14.108 +                        error("Uncaught exception in visitClass()");
  14.109 +                        e.printStackTrace();
  14.110 +                    }
  14.111 +                }
  14.112 +                info(sb.toString());
  14.113 +            } catch(ReflectiveOperationException e) {
  14.114 +                warn("Class " + vclass.getName() + " ignored, not a Visitor");
  14.115 +                continue;
  14.116 +            }
  14.117 +        }
  14.118 +
  14.119 +        if(0 != warnings)
  14.120 +                System.err.println("Test generated " + warnings + " warnings");
  14.121 +
  14.122 +        if(0 != errors)
  14.123 +            throw new Exception("Tester test failed with " +
  14.124 +                                errors + " errors");
  14.125 +    }
  14.126 +
  14.127 +    abstract static  class Visitor {
  14.128 +        Tester tester;
  14.129 +        File classesdir;
  14.130 +
  14.131 +        public Visitor(Tester tester) {
  14.132 +            this.tester = tester;
  14.133 +        }
  14.134 +
  14.135 +        abstract void visitClass(final String classname, final File  cfile,
  14.136 +                final StringBuilder sb) throws Exception;
  14.137 +
  14.138 +        public void error(String msg) {
  14.139 +            tester.error(msg);
  14.140 +        }
  14.141 +
  14.142 +        public void warn(String msg) {
  14.143 +            tester.warn(msg);
  14.144 +        }
  14.145 +    }
  14.146 +
  14.147 +    void error(String msg) {
  14.148 +        System.err.println("Error: " + msg);
  14.149 +        errors++;
  14.150 +    }
  14.151 +
  14.152 +    void warn(String msg) {
  14.153 +        System.err.println("Warning: " + msg);
  14.154 +        warnings++;
  14.155 +    }
  14.156 +
  14.157 +    void info(String msg) {
  14.158 +        System.out.println(msg);
  14.159 +    }
  14.160 +
  14.161 +    int errors;
  14.162 +    int warnings;
  14.163 +    String classname;
  14.164 +    File files[];
  14.165 +}
    15.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    15.2 +++ b/test/tools/javac/MethodParameters/UncommonParamNames.java	Wed Feb 20 15:47:14 2013 -0800
    15.3 @@ -0,0 +1,68 @@
    15.4 +/*
    15.5 + * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
    15.6 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
    15.7 + *
    15.8 + * This code is free software; you can redistribute it and/or modify it
    15.9 + * under the terms of the GNU General Public License version 2 only, as
   15.10 + * published by the Free Software Foundation.
   15.11 + *
   15.12 + * This code is distributed in the hope that it will be useful, but WITHOUT
   15.13 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
   15.14 + * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
   15.15 + * version 2 for more details (a copy is included in the LICENSE file that
   15.16 + * accompanied this code).
   15.17 + *
   15.18 + * You should have received a copy of the GNU General Public License version
   15.19 + * 2 along with this work; if not, write to the Free Software Foundation,
   15.20 + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
   15.21 + *
   15.22 + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
   15.23 + * or visit www.oracle.com if you need additional information or have any
   15.24 + * questions.
   15.25 + */
   15.26 +
   15.27 +/*
   15.28 + * @test
   15.29 + * @bug 8006582
   15.30 + * @summary javac should generate method parameters correctly.
   15.31 + * @build Tester
   15.32 + * @compile -parameters UncommonParamNames.java
   15.33 + * @run main Tester UncommonParamNames
   15.34 + */
   15.35 +
   15.36 +/** Test uncommon parameter names */
   15.37 +class UncommonParamNames {
   15.38 +    public UncommonParamNames(int _x) { }
   15.39 +    public UncommonParamNames(short $1) { }
   15.40 +    public UncommonParamNames(long \u0061) { }
   15.41 +    public UncommonParamNames(char zero\u0000zero\u0000) { }
   15.42 +    public UncommonParamNames(String zero\u0000zero\u0000seven\u0007) { }
   15.43 +    public UncommonParamNames(Object zero\u0000zero\u0000eight\u0008) { }
   15.44 +    public UncommonParamNames(Object aLoooooooooooooooooooooooooooooooooooooooooooooooooooooooooooongName,
   15.45 +                              Object baLoooooooooooooooooooooooooooooooooooooooooooooooooooooooooooongName,
   15.46 +                              Object cbaLoooooooooooooooooooooooooooooooooooooooooooooooooooooooooooongName) { }
   15.47 +    public UncommonParamNames(int a, int ba, int cba, int dcba, int edcba, int fedcba, int gfedcba,
   15.48 +                              int hgfedcba, int ihgfedcba, int jihgfedcba, int kjihgfedcba, int lkjihgfedcba,
   15.49 +                              int mlkjihgfedcba, int nmlkjihgfedcba, int onmlkjihgfedcba, int ponmlkjihgfedcba,
   15.50 +                              int qponmlkjihgfedcba, int rqponmlkjihgfedcba, int srqponmlkjihgfedcba,
   15.51 +                              int tsrqponmlkjihgfedcba, int utsrqponmlkjihgfedcba, int vutsrqponmlkjihgfedcba,
   15.52 +                              int wvutsrqponmlkjihgfedcba, int xwvutsrqponmlkjihgfedcba,
   15.53 +                              int yxwvutsrqponmlkjihgfedcba, int zyxwvutsrqponmlkjihgfedcba) { }
   15.54 +
   15.55 +    public void foo(int _x) { }
   15.56 +    public void foo(short $1) { }
   15.57 +    public void foo(long \u0061) { }
   15.58 +    public void foo(char zero\u0000zero\u0000) { }
   15.59 +    public void foo(String zero\u0000zero\u0000seven\u0007) { }
   15.60 +    public void foo(Object zero\u0000zero\u0000eight\u0008) { }
   15.61 +    public void foo(Object aLoooooooooooooooooooooooooooooooooooooooooooooooooooooooooooongName,
   15.62 +                    Object baLoooooooooooooooooooooooooooooooooooooooooooooooooooooooooooongName,
   15.63 +                    Object cbaLoooooooooooooooooooooooooooooooooooooooooooooooooooooooooooongName) { }
   15.64 +    public void foo(int a, int ba, int cba, int dcba, int edcba, int fedcba, int gfedcba,
   15.65 +                    int hgfedcba, int ihgfedcba, int jihgfedcba, int kjihgfedcba, int lkjihgfedcba,
   15.66 +                    int mlkjihgfedcba, int nmlkjihgfedcba, int onmlkjihgfedcba, int ponmlkjihgfedcba,
   15.67 +                    int qponmlkjihgfedcba, int rqponmlkjihgfedcba, int srqponmlkjihgfedcba,
   15.68 +                    int tsrqponmlkjihgfedcba, int utsrqponmlkjihgfedcba, int vutsrqponmlkjihgfedcba,
   15.69 +                    int wvutsrqponmlkjihgfedcba, int xwvutsrqponmlkjihgfedcba,
   15.70 +                    int yxwvutsrqponmlkjihgfedcba, int zyxwvutsrqponmlkjihgfedcba) { }
   15.71 +}
    16.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    16.2 +++ b/test/tools/javac/MethodParametersTest.java	Wed Feb 20 15:47:14 2013 -0800
    16.3 @@ -0,0 +1,344 @@
    16.4 +/*
    16.5 + * Copyright (c) 2012, 2013, Oracle and/or its affiliates. All rights reserved.
    16.6 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
    16.7 + *
    16.8 + * This code is free software; you can redistribute it and/or modify it
    16.9 + * under the terms of the GNU General Public License version 2 only, as
   16.10 + * published by the Free Software Foundation.
   16.11 + *
   16.12 + * This code is distributed in the hope that it will be useful, but WITHOUT
   16.13 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
   16.14 + * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
   16.15 + * version 2 for more details (a copy is included in the LICENSE file that
   16.16 + * accompanied this code).
   16.17 + *
   16.18 + * You should have received a copy of the GNU General Public License version
   16.19 + * 2 along with this work; if not, write to the Free Software Foundation,
   16.20 + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
   16.21 + *
   16.22 + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
   16.23 + * or visit www.oracle.com if you need additional information or have any
   16.24 + * questions.
   16.25 + */
   16.26 +
   16.27 +/*
   16.28 + * @test
   16.29 + * @bug 8004727
   16.30 + * @summary javac should generate method parameters correctly.
   16.31 + */
   16.32 +// key: opt.arg.parameters
   16.33 +import com.sun.tools.classfile.*;
   16.34 +import com.sun.tools.javac.file.JavacFileManager;
   16.35 +import com.sun.tools.javac.main.Main;
   16.36 +import com.sun.tools.javac.util.Context;
   16.37 +import com.sun.tools.javac.util.Name;
   16.38 +import com.sun.tools.javac.util.Names;
   16.39 +import java.io.*;
   16.40 +import javax.lang.model.element.*;
   16.41 +import java.util.*;
   16.42 +
   16.43 +public class MethodParametersTest {
   16.44 +
   16.45 +    static final String Foo_name = "Foo";
   16.46 +    static final String Foo_contents =
   16.47 +        "public class Foo {\n" +
   16.48 +        "  Foo() {}\n" +
   16.49 +        "  void foo0() {}\n" +
   16.50 +        "  void foo2(int j, int k) {}\n" +
   16.51 +        "}";
   16.52 +    static final String Bar_name = "Bar";
   16.53 +    static final String Bar_contents =
   16.54 +        "public class Bar {\n" +
   16.55 +        "  Bar(int i) {}" +
   16.56 +        "  Foo foo() { return new Foo(); }\n" +
   16.57 +        "}";
   16.58 +    static final String Baz_name = "Baz";
   16.59 +    static final String Baz_contents =
   16.60 +        "public class Baz {\n" +
   16.61 +        "  int baz;" +
   16.62 +        "  Baz(int i) {}" +
   16.63 +        "}";
   16.64 +    static final String Qux_name = "Qux";
   16.65 +    static final String Qux_contents =
   16.66 +        "public class Qux extends Baz {\n" +
   16.67 +        "  Qux(int i) { super(i); }" +
   16.68 +        "}";
   16.69 +    static final File classesdir = new File("methodparameters");
   16.70 +
   16.71 +    public static void main(String... args) throws Exception {
   16.72 +        new MethodParametersTest().run();
   16.73 +    }
   16.74 +
   16.75 +    void run() throws Exception {
   16.76 +        classesdir.mkdir();
   16.77 +        final File Foo_java =
   16.78 +            writeFile(classesdir, Foo_name + ".java", Foo_contents);
   16.79 +        final File Bar_java =
   16.80 +            writeFile(classesdir, Bar_name + ".java", Bar_contents);
   16.81 +        final File Baz_java =
   16.82 +            writeFile(classesdir, Baz_name + ".java", Baz_contents);
   16.83 +        System.err.println("Test compile with -parameter");
   16.84 +        compile("-parameters", "-d", classesdir.getPath(), Foo_java.getPath());
   16.85 +        // First test: make sure javac doesn't choke to death on
   16.86 +        // MethodParameter attributes
   16.87 +        System.err.println("Test compile with classfile containing MethodParameter attributes");
   16.88 +        compile("-parameters", "-d", classesdir.getPath(),
   16.89 +                "-cp", classesdir.getPath(), Bar_java.getPath());
   16.90 +        System.err.println("Examine class foo");
   16.91 +        checkFoo();
   16.92 +        checkBar();
   16.93 +        System.err.println("Test debug information conflict");
   16.94 +        compile("-g", "-parameters", "-d", classesdir.getPath(),
   16.95 +                "-cp", classesdir.getPath(), Baz_java.getPath());
   16.96 +        System.err.println("Introducing debug information conflict");
   16.97 +        Baz_java.delete();
   16.98 +        modifyBaz(false);
   16.99 +        System.err.println("Checking language model");
  16.100 +        inspectBaz();
  16.101 +        System.err.println("Permuting attributes");
  16.102 +        modifyBaz(true);
  16.103 +        System.err.println("Checking language model");
  16.104 +        inspectBaz();
  16.105 +
  16.106 +        if(0 != errors)
  16.107 +            throw new Exception("MethodParameters test failed with " +
  16.108 +                                errors + " errors");
  16.109 +    }
  16.110 +
  16.111 +    void inspectBaz() throws Exception {
  16.112 +        final File Qux_java =
  16.113 +            writeFile(classesdir, Qux_name + ".java", Qux_contents);
  16.114 +        final String[] args = { "-XDsave-parameter-names", "-d",
  16.115 +                                classesdir.getPath(),
  16.116 +                                "-cp", classesdir.getPath(),
  16.117 +                                Qux_java.getPath() };
  16.118 +        final StringWriter sw = new StringWriter();
  16.119 +        final PrintWriter pw = new PrintWriter(sw);
  16.120 +
  16.121 +        // We need to be able to crack open javac and look at its data
  16.122 +        // structures.  We'll rig up a compiler instance, but keep its
  16.123 +        // Context, thus allowing us to get at the ClassReader.
  16.124 +        Context context = new Context();
  16.125 +        Main comp =  new Main("javac", pw);
  16.126 +        JavacFileManager.preRegister(context);
  16.127 +
  16.128 +        // Compile Qux, which uses Baz.
  16.129 +        comp.compile(args, context);
  16.130 +        pw.close();
  16.131 +        final String out = sw.toString();
  16.132 +        if (out.length() > 0)
  16.133 +            System.err.println(out);
  16.134 +
  16.135 +        // Now get the class reader, construct a name for Baz, and load it.
  16.136 +        com.sun.tools.javac.jvm.ClassReader cr =
  16.137 +            com.sun.tools.javac.jvm.ClassReader.instance(context);
  16.138 +        Name name = Names.instance(context).fromString(Baz_name);
  16.139 +
  16.140 +        // Now walk down the language model and check the name of the
  16.141 +        // parameter.
  16.142 +        final Element baz = cr.loadClass(name);
  16.143 +        for (Element e : baz.getEnclosedElements()) {
  16.144 +            if (e instanceof ExecutableElement) {
  16.145 +                final ExecutableElement ee = (ExecutableElement) e;
  16.146 +                final List<? extends VariableElement> params =
  16.147 +                    ee.getParameters();
  16.148 +                if (1 != params.size())
  16.149 +                    throw new Exception("Classfile Baz badly formed: wrong number of methods");
  16.150 +                final VariableElement param = params.get(0);
  16.151 +                if (!param.getSimpleName().contentEquals("baz")) {
  16.152 +                    errors++;
  16.153 +                    System.err.println("javac did not correctly resolve the metadata conflict, parameter's name reads as " + param.getSimpleName());
  16.154 +                } else
  16.155 +                    System.err.println("javac did correctly resolve the metadata conflict");
  16.156 +            }
  16.157 +        }
  16.158 +    }
  16.159 +
  16.160 +    void modifyBaz(boolean flip) throws Exception {
  16.161 +        final File Baz_class = new File(classesdir, Baz_name + ".class");
  16.162 +        final ClassFile baz = ClassFile.read(Baz_class);
  16.163 +        final int ind = baz.constant_pool.getUTF8Index("baz");
  16.164 +        MethodParameters_attribute mpattr = null;
  16.165 +        int mpind = 0;
  16.166 +        Code_attribute cattr = null;
  16.167 +        int cind = 0;
  16.168 +
  16.169 +        // Find the indexes of the MethodParameters and the Code attributes
  16.170 +        if (baz.methods.length != 1)
  16.171 +            throw new Exception("Classfile Baz badly formed: wrong number of methods");
  16.172 +        if (!baz.methods[0].getName(baz.constant_pool).equals("<init>"))
  16.173 +            throw new Exception("Classfile Baz badly formed: method has name " +
  16.174 +                                baz.methods[0].getName(baz.constant_pool));
  16.175 +        for (int i = 0; i < baz.methods[0].attributes.attrs.length; i++) {
  16.176 +            if (baz.methods[0].attributes.attrs[i] instanceof
  16.177 +                MethodParameters_attribute) {
  16.178 +                mpattr = (MethodParameters_attribute)
  16.179 +                    baz.methods[0].attributes.attrs[i];
  16.180 +                mpind = i;
  16.181 +            } else if (baz.methods[0].attributes.attrs[i] instanceof
  16.182 +                       Code_attribute) {
  16.183 +                cattr = (Code_attribute) baz.methods[0].attributes.attrs[i];
  16.184 +                cind = i;
  16.185 +            }
  16.186 +        }
  16.187 +        if (null == mpattr)
  16.188 +            throw new Exception("Classfile Baz badly formed: no method parameters info");
  16.189 +        if (null == cattr)
  16.190 +            throw new Exception("Classfile Baz badly formed: no local variable table");
  16.191 +
  16.192 +        int flags = mpattr.method_parameter_table[0].flags;
  16.193 +
  16.194 +        // Alter the MethodParameters attribute, changing the name of
  16.195 +        // the parameter from i to baz.  This requires Black Magic...
  16.196 +        //
  16.197 +        // The (well-designed) classfile library (correctly) does not
  16.198 +        // allow us to mess around with the attribute data structures,
  16.199 +        // or arbitrarily generate new ones.
  16.200 +        //
  16.201 +        // Instead, we install a new subclass of Attribute that
  16.202 +        // hijacks the Visitor pattern and outputs the sequence of
  16.203 +        // bytes that we want.  This only works in this particular
  16.204 +        // instance, because we know we'll only every see one kind of
  16.205 +        // visitor.
  16.206 +        //
  16.207 +        // If anyone ever changes the makeup of the Baz class, or
  16.208 +        // tries to install some kind of visitor that gets run prior
  16.209 +        // to serialization, this will break.
  16.210 +        baz.methods[0].attributes.attrs[mpind] =
  16.211 +            new Attribute(mpattr.attribute_name_index,
  16.212 +                          mpattr.attribute_length) {
  16.213 +                public <R, D> R accept(Visitor<R, D> visitor, D data) {
  16.214 +                    if (data instanceof ByteArrayOutputStream) {
  16.215 +                        ByteArrayOutputStream out =
  16.216 +                            (ByteArrayOutputStream) data;
  16.217 +                        out.write(1);
  16.218 +                        out.write((ind >> 8) & 0xff);
  16.219 +                        out.write(ind & 0xff);
  16.220 +                        out.write((flags >> 24) & 0xff);
  16.221 +                        out.write((flags >> 16) & 0xff);
  16.222 +                        out.write((flags >> 8) & 0xff);
  16.223 +                        out.write(flags & 0xff);
  16.224 +                    } else
  16.225 +                        throw new RuntimeException("Output stream is of type " + data.getClass() + ", which is not handled by this test.  Update the test and it should work.");
  16.226 +                    return null;
  16.227 +                }
  16.228 +            };
  16.229 +
  16.230 +        // Flip the code and method attributes.  This is for checking
  16.231 +        // that order doesn't matter.
  16.232 +        if (flip) {
  16.233 +            baz.methods[0].attributes.attrs[mpind] = cattr;
  16.234 +            baz.methods[0].attributes.attrs[cind] = mpattr;
  16.235 +        }
  16.236 +
  16.237 +        new ClassWriter().write(baz, Baz_class);
  16.238 +    }
  16.239 +
  16.240 +    // Run a bunch of structural tests on foo to make sure it looks right.
  16.241 +    void checkFoo() throws Exception {
  16.242 +        final File Foo_class = new File(classesdir, Foo_name + ".class");
  16.243 +        final ClassFile foo = ClassFile.read(Foo_class);
  16.244 +        for (int i = 0; i < foo.methods.length; i++) {
  16.245 +            System.err.println("Examine method Foo." + foo.methods[i].getName(foo.constant_pool));
  16.246 +            if (foo.methods[i].getName(foo.constant_pool).equals("foo2")) {
  16.247 +                for (int j = 0; j < foo.methods[i].attributes.attrs.length; j++)
  16.248 +                    if (foo.methods[i].attributes.attrs[j] instanceof
  16.249 +                        MethodParameters_attribute) {
  16.250 +                        MethodParameters_attribute mp =
  16.251 +                            (MethodParameters_attribute)
  16.252 +                            foo.methods[i].attributes.attrs[j];
  16.253 +                        System.err.println("Foo.foo2 should have 2 parameters: j and k");
  16.254 +                        if (2 != mp.method_parameter_table_length)
  16.255 +                            error("expected 2 method parameter entries in foo2, got " +
  16.256 +                                  mp.method_parameter_table_length);
  16.257 +                        else if (!foo.constant_pool.getUTF8Value(mp.method_parameter_table[0].name_index).equals("j"))
  16.258 +                            error("expected first parameter to foo2 to be \"j\", got \"" +
  16.259 +                                  foo.constant_pool.getUTF8Value(mp.method_parameter_table[0].name_index) +
  16.260 +                                  "\" instead");
  16.261 +                        else if  (!foo.constant_pool.getUTF8Value(mp.method_parameter_table[1].name_index).equals("k"))
  16.262 +                            error("expected first parameter to foo2 to be \"k\", got \"" +
  16.263 +                                  foo.constant_pool.getUTF8Value(mp.method_parameter_table[1].name_index) +
  16.264 +                                  "\" instead");
  16.265 +                    }
  16.266 +            }
  16.267 +            else if (foo.methods[i].getName(foo.constant_pool).equals("<init>")) {
  16.268 +                for (int j = 0; j < foo.methods[i].attributes.attrs.length; j++) {
  16.269 +                    if (foo.methods[i].attributes.attrs[j] instanceof
  16.270 +                        MethodParameters_attribute)
  16.271 +                        error("Zero-argument constructor shouldn't have MethodParameters");
  16.272 +                }
  16.273 +            }
  16.274 +            else if (foo.methods[i].getName(foo.constant_pool).equals("foo0")) {
  16.275 +                for (int j = 0; j < foo.methods[i].attributes.attrs.length; j++)
  16.276 +                    if (foo.methods[i].attributes.attrs[j] instanceof
  16.277 +                        MethodParameters_attribute)
  16.278 +                        error("Zero-argument method shouldn't have MethodParameters");
  16.279 +            }
  16.280 +            else
  16.281 +                error("Unknown method " + foo.methods[i].getName(foo.constant_pool) + " showed up in class Foo");
  16.282 +        }
  16.283 +    }
  16.284 +
  16.285 +    // Run a bunch of structural tests on Bar to make sure it looks right.
  16.286 +    void checkBar() throws Exception {
  16.287 +        final File Bar_class = new File(classesdir, Bar_name + ".class");
  16.288 +        final ClassFile bar = ClassFile.read(Bar_class);
  16.289 +        for (int i = 0; i < bar.methods.length; i++) {
  16.290 +            System.err.println("Examine method Bar." + bar.methods[i].getName(bar.constant_pool));
  16.291 +            if (bar.methods[i].getName(bar.constant_pool).equals("<init>")) {
  16.292 +                for (int j = 0; j < bar.methods[i].attributes.attrs.length; j++)
  16.293 +                    if (bar.methods[i].attributes.attrs[j] instanceof
  16.294 +                        MethodParameters_attribute) {
  16.295 +                        MethodParameters_attribute mp =
  16.296 +                            (MethodParameters_attribute)
  16.297 +                            bar.methods[i].attributes.attrs[j];
  16.298 +                        System.err.println("Bar constructor should have 1 parameter: i");
  16.299 +                        if (1 != mp.method_parameter_table_length)
  16.300 +                            error("expected 1 method parameter entries in constructor, got " +
  16.301 +                                  mp.method_parameter_table_length);
  16.302 +                        else if (!bar.constant_pool.getUTF8Value(mp.method_parameter_table[0].name_index).equals("i"))
  16.303 +                            error("expected first parameter to foo2 to be \"i\", got \"" +
  16.304 +                                  bar.constant_pool.getUTF8Value(mp.method_parameter_table[0].name_index) +
  16.305 +                                  "\" instead");
  16.306 +                    }
  16.307 +            }
  16.308 +            else if (bar.methods[i].getName(bar.constant_pool).equals("foo")) {
  16.309 +                for (int j = 0; j < bar.methods[i].attributes.attrs.length; j++) {
  16.310 +                    if (bar.methods[i].attributes.attrs[j] instanceof
  16.311 +                        MethodParameters_attribute)
  16.312 +                        error("Zero-argument constructor shouldn't have MethodParameters");
  16.313 +                }
  16.314 +            }
  16.315 +        }
  16.316 +    }
  16.317 +
  16.318 +    String compile(String... args) throws Exception {
  16.319 +        System.err.println("compile: " + Arrays.asList(args));
  16.320 +        StringWriter sw = new StringWriter();
  16.321 +        PrintWriter pw = new PrintWriter(sw);
  16.322 +        int rc = com.sun.tools.javac.Main.compile(args, pw);
  16.323 +        pw.close();
  16.324 +        String out = sw.toString();
  16.325 +        if (out.length() > 0)
  16.326 +            System.err.println(out);
  16.327 +        if (rc != 0)
  16.328 +            error("compilation failed, rc=" + rc);
  16.329 +        return out;
  16.330 +    }
  16.331 +
  16.332 +    File writeFile(File dir, String path, String body) throws IOException {
  16.333 +        File f = new File(dir, path);
  16.334 +        f.getParentFile().mkdirs();
  16.335 +        FileWriter out = new FileWriter(f);
  16.336 +        out.write(body);
  16.337 +        out.close();
  16.338 +        return f;
  16.339 +    }
  16.340 +
  16.341 +    void error(String msg) {
  16.342 +        System.err.println("Error: " + msg);
  16.343 +        errors++;
  16.344 +    }
  16.345 +
  16.346 +    int errors;
  16.347 +}

mercurial