mirror of
https://github.com/openjdk/jdk.git
synced 2025-09-16 09:04:41 +02:00
8044537: Implement classfile tests for Synthetic attribute
Reviewed-by: jjg, shurailine, anazarov
This commit is contained in:
parent
b97b136530
commit
153dc079bb
12 changed files with 850 additions and 0 deletions
|
@ -0,0 +1,92 @@
|
|||
/*
|
||||
* Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
/*
|
||||
* @test
|
||||
* @bug 8044537
|
||||
* @summary Checking ACC_SYNTHETIC flag is generated for access method
|
||||
* generated to access to private methods and fields.
|
||||
* @library /tools/lib /tools/javac/lib ../lib
|
||||
* @build TestBase TestResult InMemoryFileManager ToolBox
|
||||
* @build AccessToPrivateInnerClassMembersTest SyntheticTestDriver ExpectedClass ExpectedClasses
|
||||
* @run main SyntheticTestDriver AccessToPrivateInnerClassMembersTest 1
|
||||
*/
|
||||
|
||||
/**
|
||||
* Access from top level class to inner classes.
|
||||
* Synthetic members:
|
||||
* 1. inner classes for Inner*.
|
||||
* 2. getter/setter for private field var.
|
||||
* 3. access method for private method function().
|
||||
* 4. getter/setter for private field staticVar.
|
||||
* 5. access method for private method staticFunction().
|
||||
* 6. field this in Inner1.
|
||||
* 7. constructor for Inner*.
|
||||
*/
|
||||
@ExpectedClass(className = "AccessToPrivateInnerClassMembersTest",
|
||||
expectedMethods = {"<init>()", "<clinit>()"})
|
||||
@ExpectedClass(className = "AccessToPrivateInnerClassMembersTest$Inner1",
|
||||
expectedMethods = {"<init>(AccessToPrivateInnerClassMembersTest)", "function()"},
|
||||
expectedFields = "var",
|
||||
expectedNumberOfSyntheticMethods = 4,
|
||||
expectedNumberOfSyntheticFields = 1)
|
||||
@ExpectedClass(className = "AccessToPrivateInnerClassMembersTest$Inner2",
|
||||
expectedMethods = {"function()", "staticFunction()", "<init>()"},
|
||||
expectedFields = {"staticVar", "var"},
|
||||
expectedNumberOfSyntheticMethods = 7)
|
||||
public class AccessToPrivateInnerClassMembersTest {
|
||||
|
||||
private class Inner1 {
|
||||
private Inner1() {}
|
||||
private int var;
|
||||
private void function() {}
|
||||
}
|
||||
|
||||
{
|
||||
Inner1 inner = new Inner1();
|
||||
inner.var = 0;
|
||||
int i = inner.var;
|
||||
inner.function();
|
||||
}
|
||||
|
||||
private static class Inner2 {
|
||||
private Inner2() {}
|
||||
private int var;
|
||||
private static int staticVar;
|
||||
private void function() {}
|
||||
private static void staticFunction() {}
|
||||
}
|
||||
|
||||
{
|
||||
Inner2 inner = new Inner2();
|
||||
inner.var = 0;
|
||||
int i = inner.var;
|
||||
inner.function();
|
||||
}
|
||||
|
||||
static {
|
||||
Inner2.staticFunction();
|
||||
Inner2.staticVar = 0;
|
||||
int i = Inner2.staticVar;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,109 @@
|
|||
/*
|
||||
* Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
/*
|
||||
* @test
|
||||
* @bug 8044537
|
||||
* @summary Checking ACC_SYNTHETIC flag is generated for access method
|
||||
* generated to access to private methods and fields.
|
||||
* @library /tools/lib /tools/javac/lib ../lib
|
||||
* @build TestBase TestResult InMemoryFileManager ToolBox
|
||||
* @build AccessToPrivateSiblingsTest SyntheticTestDriver ExpectedClass ExpectedClasses
|
||||
* @run main SyntheticTestDriver AccessToPrivateSiblingsTest 1
|
||||
*/
|
||||
|
||||
/**
|
||||
* Access from sibling classes to sibling classes.
|
||||
* Synthetic members:
|
||||
* 1. inner classes for Inner*.
|
||||
* 2. getter/setter for private field var.
|
||||
* 3. access method for private method function().
|
||||
* 4. getter/setter for private field staticVar.
|
||||
* 5. access method for private method staticFunction().
|
||||
* 6. field this in Inner1.
|
||||
* 7. constructor for Inner*.
|
||||
*/
|
||||
@ExpectedClass(className = "AccessToPrivateSiblingsTest", expectedMethods = "<init>()")
|
||||
@ExpectedClass(className = "AccessToPrivateSiblingsTest$Inner1",
|
||||
expectedMethods = {"function()", "<init>(AccessToPrivateSiblingsTest)"},
|
||||
expectedFields = "var",
|
||||
expectedNumberOfSyntheticMethods = 4,
|
||||
expectedNumberOfSyntheticFields = 1)
|
||||
@ExpectedClass(className = "AccessToPrivateSiblingsTest$Inner2",
|
||||
expectedMethods = "<init>(AccessToPrivateSiblingsTest)",
|
||||
expectedNumberOfSyntheticFields = 1)
|
||||
@ExpectedClass(className = "AccessToPrivateSiblingsTest$Inner3",
|
||||
expectedMethods = {"<init>()", "function()", "staticFunction()", "<clinit>()"},
|
||||
expectedFields = {"var", "staticVar"},
|
||||
expectedNumberOfSyntheticMethods = 4)
|
||||
@ExpectedClass(className = "AccessToPrivateSiblingsTest$Inner4",
|
||||
expectedMethods = {"<init>()", "function()", "staticFunction()"},
|
||||
expectedFields = {"var", "staticVar"},
|
||||
expectedNumberOfSyntheticMethods = 4)
|
||||
public class AccessToPrivateSiblingsTest {
|
||||
|
||||
private class Inner1 {
|
||||
private Inner1() {}
|
||||
private int var;
|
||||
private void function() {}
|
||||
|
||||
{
|
||||
Inner3 inner = new Inner3();
|
||||
inner.var = 0;
|
||||
int i = inner.var;
|
||||
inner.function();
|
||||
}
|
||||
}
|
||||
|
||||
private class Inner2 {
|
||||
{
|
||||
Inner1 inner = new Inner1();
|
||||
inner.var = 0;
|
||||
int i = inner.var;
|
||||
inner.function();
|
||||
}
|
||||
}
|
||||
|
||||
private static class Inner3 {
|
||||
private Inner3() {}
|
||||
private int var;
|
||||
private static int staticVar;
|
||||
private void function() {}
|
||||
private static void staticFunction() {}
|
||||
|
||||
static {
|
||||
Inner4 inner = new Inner4();
|
||||
inner.var = 0;
|
||||
int i = inner.var;
|
||||
inner.function();
|
||||
}
|
||||
}
|
||||
|
||||
private static class Inner4 {
|
||||
private Inner4() {}
|
||||
private int var;
|
||||
private static int staticVar;
|
||||
private void function() {}
|
||||
private static void staticFunction() {}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,45 @@
|
|||
/*
|
||||
* Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
/*
|
||||
* @test
|
||||
* @bug 8044537
|
||||
* @summary Checking ACC_SYNTHETIC flag is generated for assert statement.
|
||||
* @library /tools/lib /tools/javac/lib ../lib
|
||||
* @build TestBase TestResult InMemoryFileManager ToolBox
|
||||
* @build AssertFieldTest SyntheticTestDriver ExpectedClass ExpectedClasses
|
||||
* @run main SyntheticTestDriver AssertFieldTest
|
||||
*/
|
||||
|
||||
/**
|
||||
* Synthetic field for assert.
|
||||
*/
|
||||
@ExpectedClass(className = "AssertFieldTest",
|
||||
expectedMethods = {"<init>()", "function(boolean)", "<clinit>()"},
|
||||
expectedNumberOfSyntheticFields = 1)
|
||||
public class AssertFieldTest {
|
||||
|
||||
public void function(boolean flag) {
|
||||
assert flag;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,48 @@
|
|||
/*
|
||||
* Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
/*
|
||||
* @test
|
||||
* @bug 8044537
|
||||
* @summary Checking ACC_SYNTHETIC flag is generated for bridge method generated for generic method.
|
||||
* @library /tools/lib /tools/javac/lib ../lib
|
||||
* @build TestBase TestResult InMemoryFileManager ToolBox
|
||||
* @build BridgeMethodForGenericMethodTest SyntheticTestDriver ExpectedClass ExpectedClasses
|
||||
* @run main SyntheticTestDriver BridgeMethodForGenericMethodTest
|
||||
*/
|
||||
|
||||
import java.util.ArrayList;
|
||||
|
||||
/**
|
||||
* Synthetic method add(Object i) for method add(Integer)
|
||||
*/
|
||||
@ExpectedClass(className = "BridgeMethodForGenericMethodTest",
|
||||
expectedMethods = {"<init>()", "add(java.lang.Integer)"},
|
||||
expectedNumberOfSyntheticMethods = 1)
|
||||
public class BridgeMethodForGenericMethodTest extends ArrayList<Integer> {
|
||||
|
||||
@Override
|
||||
public boolean add(Integer i) {
|
||||
return true;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,122 @@
|
|||
/*
|
||||
* Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
/*
|
||||
* @test
|
||||
* @bug 8044537
|
||||
* @summary Checking ACC_SYNTHETIC flag is generated for bridge method
|
||||
* generated for lambda expressions and method references.
|
||||
* @library /tools/lib /tools/javac/lib ../lib
|
||||
* @build TestBase TestResult InMemoryFileManager ToolBox
|
||||
* @build BridgeMethodsForLambdaTest SyntheticTestDriver ExpectedClass ExpectedClasses
|
||||
* @run main SyntheticTestDriver BridgeMethodsForLambdaTest 1
|
||||
*/
|
||||
|
||||
import java.util.Comparator;
|
||||
import java.util.stream.IntStream;
|
||||
|
||||
/**
|
||||
* Synthetic members:
|
||||
* 1. inner class for Inner1.
|
||||
* 2. method for () -> {} in Inner1
|
||||
* 3. method for () -> {} in Inner2
|
||||
* 4. method references to private methods.
|
||||
* 5. method for super::function()
|
||||
* 6. method references to private static methods.
|
||||
* 7. access method for private method function().
|
||||
* 8. access method for private static method staticFunction().
|
||||
* 9. method reference to vararg method.
|
||||
* 10. method reference to array's method.
|
||||
* 11. constructors for Inner1 and Inner2.
|
||||
*/
|
||||
@ExpectedClass(className = "BridgeMethodsForLambdaTest",
|
||||
expectedMethods = {"<init>()", "<clinit>()", "function(java.lang.Integer[])"},
|
||||
expectedNumberOfSyntheticMethods = 6)
|
||||
@ExpectedClass(className = "BridgeMethodsForLambdaTest$Inner1",
|
||||
expectedMethods = {"<init>(BridgeMethodsForLambdaTest)", "function()", "run()"},
|
||||
expectedFields = "lambda1",
|
||||
expectedNumberOfSyntheticMethods = 4,
|
||||
expectedNumberOfSyntheticFields = 1)
|
||||
@ExpectedClass(className = "BridgeMethodsForLambdaTest$Inner2",
|
||||
expectedMethods = {"<init>()", "staticFunction()"},
|
||||
expectedFields = "lambda1",
|
||||
expectedNumberOfSyntheticMethods = 3)
|
||||
@ExpectedClass(className = "BridgeMethodsForLambdaTest$Inner3",
|
||||
expectedMethods = {"<init>(BridgeMethodsForLambdaTest)", "function()"},
|
||||
expectedNumberOfSyntheticMethods = 1,
|
||||
expectedNumberOfSyntheticFields = 1)
|
||||
@ExpectedClass(className = "BridgeMethodsForLambdaTest$Inner4",
|
||||
expectedMethods = {"<init>(BridgeMethodsForLambdaTest)", "function()"},
|
||||
expectedNumberOfSyntheticMethods = 1,
|
||||
expectedNumberOfSyntheticFields = 1)
|
||||
public class BridgeMethodsForLambdaTest {
|
||||
|
||||
private class Inner1 implements Runnable {
|
||||
private Inner1() {
|
||||
}
|
||||
private Runnable lambda1 = () -> {
|
||||
};
|
||||
private void function() {
|
||||
}
|
||||
@Override
|
||||
public void run() {
|
||||
}
|
||||
}
|
||||
|
||||
private static class Inner2 {
|
||||
private Runnable lambda1 = () -> {
|
||||
};
|
||||
private static void staticFunction() {
|
||||
}
|
||||
}
|
||||
|
||||
private class Inner3 {
|
||||
public void function() {
|
||||
}
|
||||
}
|
||||
|
||||
private class Inner4 extends Inner3 {
|
||||
@Override
|
||||
public void function() {
|
||||
Runnable r = super::function;
|
||||
}
|
||||
}
|
||||
|
||||
private static int function(Integer...vararg) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
{
|
||||
Inner1 inner = new Inner1();
|
||||
Runnable l1 = inner::function;
|
||||
Runnable l2 = Inner1::new;
|
||||
inner.lambda1 = inner::function;
|
||||
Comparator<Integer> c = BridgeMethodsForLambdaTest::function;
|
||||
IntStream.of(2).mapToObj(int[]::new);
|
||||
}
|
||||
|
||||
static {
|
||||
Inner2 inner = new Inner2();
|
||||
Runnable l1 = Inner2::staticFunction;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,44 @@
|
|||
/*
|
||||
* Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
/*
|
||||
* @test
|
||||
* @bug 8044537
|
||||
* @summary Checking ACC_SYNTHETIC flag is generated for enum members.
|
||||
* @library /tools/lib /tools/javac/lib ../lib
|
||||
* @build TestBase TestResult InMemoryFileManager ToolBox
|
||||
* @build EnumTest SyntheticTestDriver ExpectedClass ExpectedClasses
|
||||
* @run main SyntheticTestDriver EnumTest
|
||||
*/
|
||||
|
||||
/**
|
||||
* Synthetic members:
|
||||
* 1. field $VALUES.
|
||||
*/
|
||||
@ExpectedClass(className = "EnumTest",
|
||||
expectedMethods = {"values()", "valueOf(java.lang.String)", "<clinit>()", "<init>(java.lang.String, int)"},
|
||||
expectedFields = {"A", "B"},
|
||||
expectedNumberOfSyntheticFields = 1)
|
||||
public enum EnumTest {
|
||||
A, B
|
||||
}
|
|
@ -0,0 +1,36 @@
|
|||
/*
|
||||
* Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
import java.lang.annotation.Repeatable;
|
||||
import java.lang.annotation.Retention;
|
||||
import java.lang.annotation.RetentionPolicy;
|
||||
|
||||
@Repeatable(ExpectedClasses.class)
|
||||
@Retention(RetentionPolicy.RUNTIME)
|
||||
public @interface ExpectedClass {
|
||||
String className();
|
||||
String[] expectedMethods() default {};
|
||||
String[] expectedFields() default {};
|
||||
int expectedNumberOfSyntheticMethods() default 0;
|
||||
int expectedNumberOfSyntheticFields() default 0;
|
||||
}
|
|
@ -0,0 +1,30 @@
|
|||
/*
|
||||
* Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
import java.lang.annotation.Retention;
|
||||
import java.lang.annotation.RetentionPolicy;
|
||||
|
||||
@Retention(RetentionPolicy.RUNTIME)
|
||||
public @interface ExpectedClasses {
|
||||
ExpectedClass[] value();
|
||||
}
|
|
@ -0,0 +1,36 @@
|
|||
/*
|
||||
* Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
/*
|
||||
* @test
|
||||
* @bug 8044537
|
||||
* @summary Checking ACC_SYNTHETIC flag is generated for package-info.
|
||||
* @library /tools/lib /tools/javac/lib ../lib
|
||||
* @build TestBase TestResult InMemoryFileManager ToolBox
|
||||
* @build SyntheticTestDriver ExpectedClass ExpectedClasses
|
||||
* @compile -Xpkginfo:always package_info_test/package-info.java
|
||||
* @run main SyntheticTestDriver package_info_test.package-info 1
|
||||
*/
|
||||
|
||||
public class PackageInfoTest {
|
||||
}
|
|
@ -0,0 +1,210 @@
|
|||
/*
|
||||
* Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
import java.io.IOException;
|
||||
import java.nio.file.Files;
|
||||
import java.nio.file.Path;
|
||||
import java.util.*;
|
||||
import java.util.function.Function;
|
||||
import java.util.function.Supplier;
|
||||
import java.util.stream.Collectors;
|
||||
import java.util.stream.Stream;
|
||||
|
||||
import com.sun.tools.classfile.*;
|
||||
|
||||
/**
|
||||
* The tests work as follows. Firstly, it looks through the test cases
|
||||
* and extracts the appropriate compiled classes. Each test case contains
|
||||
* a set of expected classes, methods and fields. Those class members must not have
|
||||
* the Synthetic attribute, while other found classes, methods and fields must have
|
||||
* the Synthetic attribute if they are not in the set of expected class members.
|
||||
*
|
||||
* Each test executes SyntheticTestDriver specifying the name of test cases and
|
||||
* the number of expected synthetic classes. Each test class is annotated by
|
||||
* annotations which contains non-synthetic class members.
|
||||
*
|
||||
* See the appropriate class for more information about a test case.
|
||||
*/
|
||||
public class SyntheticTestDriver extends TestResult {
|
||||
|
||||
private static final String ACC_SYNTHETIC = "ACC_SYNTHETIC";
|
||||
|
||||
private final String testCaseName;
|
||||
private final Map<String, ClassFile> classes;
|
||||
private final Map<String, ExpectedClass> expectedClasses;
|
||||
|
||||
public static void main(String[] args)
|
||||
throws TestFailedException, ConstantPoolException, IOException, ClassNotFoundException {
|
||||
if (args.length != 1 && args.length != 2) {
|
||||
throw new IllegalArgumentException("Usage: SyntheticTestDriver <class-name> [<number-of-synthetic-classes>]");
|
||||
}
|
||||
int numberOfSyntheticClasses = args.length == 1 ? 0 : Integer.parseInt(args[1]);
|
||||
new SyntheticTestDriver(args[0]).test(numberOfSyntheticClasses);
|
||||
}
|
||||
|
||||
public SyntheticTestDriver(String testCaseName) throws IOException, ConstantPoolException, ClassNotFoundException {
|
||||
Class<?> clazz = Class.forName(testCaseName);
|
||||
this.testCaseName = testCaseName;
|
||||
this.expectedClasses = Stream.of(clazz.getAnnotationsByType(ExpectedClass.class))
|
||||
.collect(Collectors.toMap(ExpectedClass::className, Function.identity()));
|
||||
this.classes = new HashMap<>();
|
||||
Path classDir = getClassDir().toPath();
|
||||
String sourceFileName = testCaseName.replace('.', '/');
|
||||
List<Path> paths = Files.walk(classDir)
|
||||
.map(p -> classDir.relativize(p.toAbsolutePath()))
|
||||
.filter(p -> p.toString().matches(sourceFileName + ".*\\.class"))
|
||||
.collect(Collectors.toList());
|
||||
for (Path path : paths) {
|
||||
String className = path.toString().replace(".class", "").replace('/', '.');
|
||||
classes.put(className, readClassFile(classDir.resolve(path).toFile()));
|
||||
}
|
||||
if (classes.isEmpty()) {
|
||||
throw new RuntimeException("Classes have not been found.");
|
||||
}
|
||||
boolean success = classes.entrySet().stream()
|
||||
.allMatch(e -> e.getKey().startsWith(testCaseName));
|
||||
if (!success) {
|
||||
classes.forEach((className, $) -> printf("Found class: %s\n", className));
|
||||
throw new RuntimeException("Found classes are not from the test case : " + testCaseName);
|
||||
}
|
||||
}
|
||||
|
||||
private String getMethodName(ClassFile classFile, Method method)
|
||||
throws ConstantPoolException, Descriptor.InvalidDescriptor {
|
||||
String methodName = method.getName(classFile.constant_pool);
|
||||
String parameters = method.descriptor.getParameterTypes(classFile.constant_pool);
|
||||
return methodName + parameters;
|
||||
}
|
||||
|
||||
public void test(int expectedNumberOfSyntheticClasses) throws TestFailedException {
|
||||
try {
|
||||
addTestCase(testCaseName);
|
||||
Set<String> foundClasses = new HashSet<>();
|
||||
|
||||
int numberOfSyntheticClasses = 0;
|
||||
for (Map.Entry<String, ClassFile> entry : classes.entrySet()) {
|
||||
String className = entry.getKey();
|
||||
ClassFile classFile = entry.getValue();
|
||||
foundClasses.add(className);
|
||||
if (testAttribute(
|
||||
classFile,
|
||||
() -> (Synthetic_attribute) classFile.getAttribute(Attribute.Synthetic),
|
||||
classFile.access_flags::getClassFlags,
|
||||
expectedClasses.keySet(),
|
||||
className,
|
||||
"Testing class " + className)) {
|
||||
++numberOfSyntheticClasses;
|
||||
}
|
||||
ExpectedClass expectedClass = expectedClasses.get(className);
|
||||
Set<String> expectedMethods = expectedClass != null
|
||||
? toSet(expectedClass.expectedMethods())
|
||||
: new HashSet<>();
|
||||
int numberOfSyntheticMethods = 0;
|
||||
Set<String> foundMethods = new HashSet<>();
|
||||
for (Method method : classFile.methods) {
|
||||
String methodName = getMethodName(classFile, method);
|
||||
foundMethods.add(methodName);
|
||||
if (testAttribute(
|
||||
classFile,
|
||||
() -> (Synthetic_attribute) method.attributes.get(Attribute.Synthetic),
|
||||
method.access_flags::getMethodFlags,
|
||||
expectedMethods,
|
||||
methodName,
|
||||
"Testing method " + methodName + " in class "
|
||||
+ className)) {
|
||||
++numberOfSyntheticMethods;
|
||||
}
|
||||
}
|
||||
checkContains(foundMethods, expectedMethods,
|
||||
"Checking that all methods of class " + className
|
||||
+ " without Synthetic attribute have been found");
|
||||
checkEquals(numberOfSyntheticMethods,
|
||||
expectedClass == null ? 0 : expectedClass.expectedNumberOfSyntheticMethods(),
|
||||
"Checking number of synthetic methods in class: " + className);
|
||||
|
||||
Set<String> expectedFields = expectedClass != null
|
||||
? toSet(expectedClass.expectedFields())
|
||||
: new HashSet<>();
|
||||
int numberOfSyntheticFields = 0;
|
||||
Set<String> foundFields = new HashSet<>();
|
||||
for (Field field : classFile.fields) {
|
||||
String fieldName = field.getName(classFile.constant_pool);
|
||||
foundFields.add(fieldName);
|
||||
if (testAttribute(
|
||||
classFile,
|
||||
() -> (Synthetic_attribute) field.attributes.get(Attribute.Synthetic),
|
||||
field.access_flags::getFieldFlags,
|
||||
expectedFields,
|
||||
fieldName,
|
||||
"Testing field " + fieldName + " in class "
|
||||
+ className)) {
|
||||
++numberOfSyntheticFields;
|
||||
}
|
||||
}
|
||||
checkContains(foundFields, expectedFields,
|
||||
"Checking that all fields of class " + className
|
||||
+ " without Synthetic attribute have been found");
|
||||
checkEquals(numberOfSyntheticFields,
|
||||
expectedClass == null ? 0 : expectedClass.expectedNumberOfSyntheticFields(),
|
||||
"Checking number of synthetic fields in class: " + className);
|
||||
}
|
||||
checkContains(foundClasses, expectedClasses.keySet(),
|
||||
"Checking that all classes have been found");
|
||||
checkEquals(numberOfSyntheticClasses, expectedNumberOfSyntheticClasses,
|
||||
"Checking number of synthetic classes");
|
||||
} catch (Exception e) {
|
||||
addFailure(e);
|
||||
} finally {
|
||||
checkStatus();
|
||||
}
|
||||
}
|
||||
|
||||
private boolean testAttribute(ClassFile classFile,
|
||||
Supplier<Synthetic_attribute> getSyntheticAttribute,
|
||||
Supplier<Set<String>> getAccessFlags,
|
||||
Set<String> expectedMembers, String memberName,
|
||||
String info) throws ConstantPoolException {
|
||||
echo(info);
|
||||
String className = classFile.getName();
|
||||
Synthetic_attribute attr = getSyntheticAttribute.get();
|
||||
Set<String> flags = getAccessFlags.get();
|
||||
if (expectedMembers.contains(memberName)) {
|
||||
checkNull(attr, "Member must not have synthetic attribute : "
|
||||
+ memberName);
|
||||
checkFalse(flags.contains(ACC_SYNTHETIC),
|
||||
"Member must not have synthetic flag : " + memberName
|
||||
+ " in class : " + className);
|
||||
return false;
|
||||
} else {
|
||||
return checkNull(attr, "Synthetic attribute should not be generated")
|
||||
&& checkTrue(flags.contains(ACC_SYNTHETIC), "Member must have synthetic flag : "
|
||||
+ memberName + " in class : " + className);
|
||||
}
|
||||
}
|
||||
|
||||
private Set<String> toSet(String[] strings) {
|
||||
HashSet<String> set = new HashSet<>();
|
||||
Collections.addAll(set, strings);
|
||||
return set;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,54 @@
|
|||
/*
|
||||
* Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
/*
|
||||
* @test
|
||||
* @bug 8044537
|
||||
* @summary Checking ACC_SYNTHETIC flag is generated for "this$0" field.
|
||||
* @library /tools/lib /tools/javac/lib ../lib
|
||||
* @build TestBase TestResult InMemoryFileManager ToolBox
|
||||
* @build ThisFieldTest SyntheticTestDriver ExpectedClass ExpectedClasses
|
||||
* @run main SyntheticTestDriver ThisFieldTest
|
||||
*/
|
||||
|
||||
/**
|
||||
* Synthetic members:
|
||||
* 1. fields this$0 for local and anonymous classes.
|
||||
*/
|
||||
@ExpectedClass(className = "ThisFieldTest",
|
||||
expectedMethods = "<init>()")
|
||||
@ExpectedClass(className = "ThisFieldTest$1Local",
|
||||
expectedMethods = "<init>(ThisFieldTest)",
|
||||
expectedNumberOfSyntheticFields = 1)
|
||||
@ExpectedClass(className = "ThisFieldTest$1",
|
||||
expectedMethods = "<init>(ThisFieldTest)",
|
||||
expectedNumberOfSyntheticFields = 1)
|
||||
public class ThisFieldTest {
|
||||
{
|
||||
class Local {
|
||||
}
|
||||
|
||||
new Local() {
|
||||
};
|
||||
}
|
||||
}
|
|
@ -0,0 +1,24 @@
|
|||
/*
|
||||
* Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
package package_info_test;
|
Loading…
Add table
Add a link
Reference in a new issue