emc@1808: /* emc@1808: * Copyright (c) 2012, 2013, Oracle and/or its affiliates. All rights reserved. emc@1808: * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. emc@1808: * emc@1808: * This code is free software; you can redistribute it and/or modify it emc@1808: * under the terms of the GNU General Public License version 2 only, as emc@1808: * published by the Free Software Foundation. emc@1808: * emc@1808: * This code is distributed in the hope that it will be useful, but WITHOUT emc@1808: * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or emc@1808: * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License emc@1808: * version 2 for more details (a copy is included in the LICENSE file that emc@1808: * accompanied this code). emc@1808: * emc@1808: * You should have received a copy of the GNU General Public License version emc@1808: * 2 along with this work; if not, write to the Free Software Foundation, emc@1808: * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. emc@1808: * emc@1808: * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA emc@1808: * or visit www.oracle.com if you need additional information or have any emc@1808: * questions. emc@1808: */ emc@1808: emc@1808: /* emc@1808: * @test emc@1808: * @bug 8015701 emc@1975: * @summary Test method parameter attribute generation with captured locals. emc@1975: * @compile -parameters CaptureTest.java emc@1975: * @run main CaptureTest emc@1808: */ emc@1808: import java.lang.Class; emc@1808: import java.lang.reflect.Constructor; emc@1808: import java.lang.reflect.Parameter; emc@1975: import java.lang.reflect.Modifier; emc@1975: import java.util.List; emc@1975: import java.util.ArrayList; emc@1808: emc@1975: public class CaptureTest { emc@1808: emc@1975: private static final int SYNTHETIC = 0x1000; emc@1975: private static final int MANDATED = 0x8000; emc@1808: emc@1808: public static void main(String... args) throws Exception { emc@1975: new CaptureTest().run(); emc@1808: } emc@1808: emc@1808: emc@1975: private void run() throws Exception { emc@1975: final Encloser pn = new Encloser(); emc@1808: emc@1975: /* Cases covered here: emc@1975: * emc@1975: * - Local class emc@1975: * - Inner class emc@1975: * - Anonymous class emc@1975: * - Anonymous class extending a local emc@1975: * - Anonymous class extending an inner emc@1975: */ emc@1975: pn.makeLocal("hello").check(); emc@1975: pn.makeInner("hello").check(); emc@1975: pn.makeAnon("hello").check(); emc@1975: pn.makeAnonExtendsLocal("hello").check(); emc@1975: pn.makeAnonExtendsInner("hello").check(); emc@1975: emc@1975: if (0 != errors) emc@1808: throw new Exception("MethodParameters test failed with " + emc@1808: errors + " errors"); emc@1808: } emc@1808: emc@1975: private void error(final String msg) { emc@1808: System.err.println("Error: " + msg); emc@1808: errors++; emc@1808: } emc@1808: emc@1808: int errors; emc@1808: emc@1975: abstract class Tester { emc@1808: emc@1975: public Tester(final int param) {} emc@1975: emc@1975: protected abstract String[] names(); emc@1975: protected abstract int[] modifiers(); emc@1975: protected abstract Class[] types(); emc@1975: emc@1975: public void check() { emc@1975: final Class cls = this.getClass(); emc@1975: final Constructor ctor = cls.getDeclaredConstructors()[0]; emc@1975: final Parameter[] params = ctor.getParameters(); emc@1975: final String[] names = names(); emc@1975: final int[] modifiers = modifiers(); emc@1975: final Class[] types = types(); emc@1975: emc@1975: System.err.println("Testing class " + cls); emc@1975: emc@1975: if (params.length == names.length) { emc@1975: for (int i = 0; i < names.length; i++) { emc@1975: System.err.println("Testing parameter " + params[i].getName()); emc@1975: if (!params[i].getName().equals(names[i])) emc@1975: error("Expected parameter name " + names[i] + emc@1975: " got " + params[i].getName()); emc@1975: if (params[i].getModifiers() != modifiers[i]) emc@1975: error("Expected parameter modifiers " + emc@1975: modifiers[i] + " got " + emc@1975: params[i].getModifiers()); emc@1975: if (!params[i].getType().equals(types[i])) emc@1975: error("Expected parameter type " + types[i] + emc@1975: " got " + params[i].getType()); emc@1975: } emc@1975: } else emc@1975: error("Expected " + names.length + " parameters"); emc@1975: emc@1975: } emc@1975: emc@1808: } emc@1808: emc@1975: class Encloser { emc@1975: private class InnerTester extends Tester { emc@1975: public InnerTester(final int innerparam) { emc@1975: super(innerparam); emc@1975: } emc@1975: emc@1975: protected String[] names() { emc@1975: return new String[] { emc@1975: "this$1", emc@1975: "innerparam" emc@1975: }; emc@1975: } emc@1975: emc@1975: protected int[] modifiers() { emc@1975: return new int[] { emc@1975: Modifier.FINAL | SYNTHETIC, emc@1975: Modifier.FINAL emc@1975: }; emc@1975: } emc@1975: emc@1975: protected Class[] types() { emc@1975: return new Class[] { emc@1975: Encloser.class, emc@1975: int.class emc@1975: }; emc@1975: } emc@1975: } emc@1975: emc@1975: public Tester makeInner(final String message) { emc@1975: return new InnerTester(2); emc@1975: } emc@1975: emc@1975: public Tester makeLocal(final String message) { emc@1975: class LocalTester extends Tester { emc@1975: public LocalTester(final int localparam) { emc@1975: super(localparam); emc@1975: } emc@1975: emc@1975: protected String[] names() { emc@1975: return new String[] { emc@1975: "this$1", emc@1975: "localparam", emc@1975: "val$message" emc@1975: }; emc@1975: } emc@1975: emc@1975: protected int[] modifiers() { emc@1975: return new int[] { emc@1975: Modifier.FINAL | MANDATED, emc@1975: Modifier.FINAL, emc@1975: Modifier.FINAL | SYNTHETIC emc@1975: }; emc@1975: } emc@1975: emc@1975: protected Class[] types() { emc@1975: return new Class[] { emc@1975: Encloser.class, emc@1975: int.class, emc@1975: String.class emc@1975: }; emc@1975: } emc@1975: emc@1975: public String message() { emc@1975: return message; emc@1975: } emc@1975: } emc@1975: emc@1975: return new LocalTester(2); emc@1975: } emc@1975: emc@1975: public Tester makeAnonExtendsLocal(final String message) { emc@1975: abstract class LocalTester extends Tester { emc@1975: public LocalTester(final int localparam) { emc@1975: super(localparam); emc@1975: } emc@1975: emc@1975: protected String[] names() { emc@1975: return new String[] { emc@1975: "this$1", emc@1975: "localparam", emc@1975: "val$message" emc@1975: }; emc@1975: } emc@1975: emc@1975: protected int[] modifiers() { emc@1975: return new int[] { emc@1975: Modifier.FINAL | MANDATED, emc@1975: Modifier.FINAL, emc@1975: Modifier.FINAL | SYNTHETIC emc@1975: }; emc@1975: } emc@1975: emc@1975: protected Class[] types() { emc@1975: return new Class[] { emc@1975: Encloser.class, emc@1975: int.class, emc@1975: String.class emc@1975: }; emc@1975: } emc@1975: emc@1975: } emc@1975: emc@1975: return new LocalTester(2) { emc@1975: public String message() { emc@1975: return message; emc@1975: } emc@1975: }; emc@1975: } emc@1975: emc@1975: public Tester makeAnonExtendsInner(final String message) { emc@1975: return new InnerTester(2) { emc@1975: protected String[] names() { emc@1975: return new String[] { emc@1975: "this$1", emc@1975: "innerparam", emc@1975: "val$message" emc@1975: }; emc@1975: } emc@1975: emc@1975: protected int[] modifiers() { emc@1975: return new int[] { emc@1975: Modifier.FINAL | MANDATED, emc@1975: Modifier.FINAL, emc@1975: Modifier.FINAL | SYNTHETIC emc@1975: }; emc@1975: } emc@1975: emc@1975: protected Class[] types() { emc@1975: return new Class[] { emc@1975: Encloser.class, emc@1975: int.class, emc@1975: String.class emc@1975: }; emc@1975: } emc@1975: emc@1975: public String message() { emc@1975: return message; emc@1975: } emc@1975: }; emc@1975: } emc@1975: emc@1975: public Tester makeAnon(final String message) { emc@1975: return new Tester(2) { emc@1975: protected String[] names() { emc@1975: return new String[] { emc@1975: "this$1", emc@1975: "param", emc@1975: "val$message" emc@1975: }; emc@1975: } emc@1975: emc@1975: protected int[] modifiers() { emc@1975: return new int[] { emc@1975: Modifier.FINAL | MANDATED, emc@1975: Modifier.FINAL, emc@1975: Modifier.FINAL | SYNTHETIC emc@1975: }; emc@1975: } emc@1975: emc@1975: protected Class[] types() { emc@1975: return new Class[] { emc@1975: Encloser.class, emc@1975: int.class, emc@1975: String.class emc@1975: }; emc@1975: } emc@1975: emc@1975: public String message() { emc@1975: return message; emc@1975: } emc@1975: }; emc@1975: } emc@1808: } emc@1808: }