8044537: Implement classfile tests for Synthetic attribute

Reviewed-by: jjg, shurailine, anazarov
This commit is contained in:
Andrei Eremeev 2015-04-28 11:08:25 +03:00
parent b97b136530
commit 153dc079bb
12 changed files with 850 additions and 0 deletions

View file

@ -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;
}
}

View file

@ -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() {}
}
}

View file

@ -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;
}
}

View file

@ -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;
}
}

View file

@ -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;
}
}

View file

@ -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
}

View file

@ -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;
}

View file

@ -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();
}

View file

@ -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 {
}

View file

@ -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;
}
}

View file

@ -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() {
};
}
}

View file

@ -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;