mirror of
https://github.com/openjdk/jdk.git
synced 2025-08-28 15:24:43 +02:00
8042251: Implement classfile tests for InnerClasses attribute
Reviewed-by: jjg, anazarov, shurailine
This commit is contained in:
parent
14fcc1d07d
commit
8740c99fbd
28 changed files with 2497 additions and 36 deletions
|
@ -0,0 +1,48 @@
|
||||||
|
/*
|
||||||
|
* Copyright (c) 2014, 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 8042251
|
||||||
|
* @summary Testing InnerClasses_attribute of inner annotations in inner annotation.
|
||||||
|
* @library /tools/javac/lib ../lib
|
||||||
|
* @build InnerClassesInInnerClassTestBase InnerClassesTestBase TestBase TestResult InMemoryFileManager ToolBox
|
||||||
|
* @run main InnerAnnotationsInInnerAnnotationTest
|
||||||
|
*/
|
||||||
|
|
||||||
|
public class InnerAnnotationsInInnerAnnotationTest extends InnerClassesInInnerClassTestBase {
|
||||||
|
|
||||||
|
public static void main(String[] args) throws TestFailedException {
|
||||||
|
InnerClassesTestBase test = new InnerAnnotationsInInnerAnnotationTest();
|
||||||
|
test.test("InnerClassesSrc$Inner", "Inner", "1");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void setProperties() {
|
||||||
|
setOuterOtherModifiers(Modifier.EMPTY, Modifier.ABSTRACT, Modifier.STATIC);
|
||||||
|
setInnerAccessModifiers(Modifier.EMPTY, Modifier.PUBLIC);
|
||||||
|
setInnerOtherModifiers(Modifier.EMPTY, Modifier.ABSTRACT, Modifier.STATIC);
|
||||||
|
setOuterClassType(ClassType.ANNOTATION);
|
||||||
|
setInnerClassType(ClassType.ANNOTATION);
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,47 @@
|
||||||
|
/*
|
||||||
|
* Copyright (c) 2014, 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 8042251
|
||||||
|
* @summary Testing InnerClasses_attribute of inner annotations in inner class.
|
||||||
|
* @library /tools/javac/lib ../lib
|
||||||
|
* @build InnerClassesInInnerClassTestBase InnerClassesTestBase TestBase TestResult InMemoryFileManager ToolBox
|
||||||
|
* @run main InnerAnnotationsInInnerClassTest
|
||||||
|
*/
|
||||||
|
|
||||||
|
public class InnerAnnotationsInInnerClassTest extends InnerClassesInInnerClassTestBase {
|
||||||
|
|
||||||
|
public static void main(String[] args) throws TestFailedException {
|
||||||
|
InnerClassesTestBase test = new InnerAnnotationsInInnerClassTest();
|
||||||
|
test.test("InnerClassesSrc$Inner", "Inner", "1");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void setProperties() {
|
||||||
|
setInnerOtherModifiers(Modifier.EMPTY, Modifier.ABSTRACT, Modifier.STATIC);
|
||||||
|
setForbiddenWithoutStaticInOuterMods(true);
|
||||||
|
setOuterClassType(ClassType.CLASS);
|
||||||
|
setInnerClassType(ClassType.ANNOTATION);
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,49 @@
|
||||||
|
/*
|
||||||
|
* Copyright (c) 2014, 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 8042251
|
||||||
|
* @summary Testing InnerClasses_attribute of inner annotations in inner enum.
|
||||||
|
* @library /tools/javac/lib ../lib
|
||||||
|
* @build InnerClassesInInnerClassTestBase InnerClassesTestBase TestBase TestResult InMemoryFileManager ToolBox
|
||||||
|
* @run main InnerAnnotationsInInnerEnumTest
|
||||||
|
*/
|
||||||
|
|
||||||
|
public class InnerAnnotationsInInnerEnumTest extends InnerClassesInInnerClassTestBase {
|
||||||
|
|
||||||
|
public static void main(String[] args) throws TestFailedException {
|
||||||
|
InnerClassesTestBase test = new InnerAnnotationsInInnerEnumTest();
|
||||||
|
test.test("InnerClassesSrc$Inner", "Inner", "1");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void setProperties() {
|
||||||
|
setOuterOtherModifiers(Modifier.EMPTY, Modifier.STATIC);
|
||||||
|
setInnerOtherModifiers(Modifier.EMPTY, Modifier.STATIC, Modifier.ABSTRACT);
|
||||||
|
setOuterClassType(ClassType.ENUM);
|
||||||
|
setInnerClassType(ClassType.ANNOTATION);
|
||||||
|
setPrefix("Inner {;");
|
||||||
|
setSuffix("}");
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,48 @@
|
||||||
|
/*
|
||||||
|
* Copyright (c) 2014, 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 8042251
|
||||||
|
* @summary Testing InnerClasses_attribute of inner annotations in inner interface.
|
||||||
|
* @library /tools/javac/lib ../lib
|
||||||
|
* @build InnerClassesInInnerClassTestBase InnerClassesTestBase TestBase TestResult InMemoryFileManager ToolBox
|
||||||
|
* @run main InnerAnnotationsInInnerInterfaceTest
|
||||||
|
*/
|
||||||
|
|
||||||
|
public class InnerAnnotationsInInnerInterfaceTest extends InnerClassesInInnerClassTestBase {
|
||||||
|
|
||||||
|
public static void main(String[] args) throws TestFailedException {
|
||||||
|
InnerClassesTestBase test = new InnerAnnotationsInInnerInterfaceTest();
|
||||||
|
test.test("InnerClassesSrc$Inner", "Inner", "1");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void setProperties() {
|
||||||
|
setOuterOtherModifiers(Modifier.EMPTY, Modifier.ABSTRACT, Modifier.STATIC);
|
||||||
|
setInnerAccessModifiers(Modifier.EMPTY, Modifier.PUBLIC);
|
||||||
|
setInnerOtherModifiers(Modifier.EMPTY, Modifier.ABSTRACT, Modifier.STATIC);
|
||||||
|
setOuterClassType(ClassType.INTERFACE);
|
||||||
|
setInnerClassType(ClassType.ANNOTATION);
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,433 @@
|
||||||
|
/*
|
||||||
|
* Copyright (c) 2014, 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 8042251
|
||||||
|
* @summary Test that inner classes have in its inner classes attribute enclosing classes and its immediate members.
|
||||||
|
* @library /tools/javac/lib ../lib
|
||||||
|
* @build TestResult TestBase InMemoryFileManager ToolBox
|
||||||
|
* @run main InnerClassesHierarchyTest
|
||||||
|
*/
|
||||||
|
|
||||||
|
import com.sun.tools.classfile.*;
|
||||||
|
import com.sun.tools.classfile.InnerClasses_attribute.Info;
|
||||||
|
|
||||||
|
import java.io.File;
|
||||||
|
import java.io.FilenameFilter;
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.lang.annotation.Annotation;
|
||||||
|
import java.util.*;
|
||||||
|
import java.util.stream.Collectors;
|
||||||
|
|
||||||
|
public class InnerClassesHierarchyTest extends TestResult {
|
||||||
|
|
||||||
|
private final Map<String, Set<String>> innerClasses;
|
||||||
|
private final String outerClassName;
|
||||||
|
|
||||||
|
public InnerClassesHierarchyTest() throws IOException, ConstantPoolException {
|
||||||
|
innerClasses = new HashMap<>();
|
||||||
|
outerClassName = InnerClassesHierarchyTest.class.getSimpleName();
|
||||||
|
File classDir = getClassDir();
|
||||||
|
FilenameFilter filter =
|
||||||
|
(dir, name) -> name.matches(outerClassName + ".*\\.class");
|
||||||
|
for (File file : Arrays.asList(classDir.listFiles(filter))) {
|
||||||
|
ClassFile classFile = readClassFile(file);
|
||||||
|
String className = classFile.getName();
|
||||||
|
for (ConstantPool.CPInfo info : classFile.constant_pool.entries()) {
|
||||||
|
if (info instanceof ConstantPool.CONSTANT_Class_info) {
|
||||||
|
ConstantPool.CONSTANT_Class_info classInfo =
|
||||||
|
(ConstantPool.CONSTANT_Class_info) info;
|
||||||
|
String cpClassName = classInfo.getBaseName();
|
||||||
|
if (isInnerClass(cpClassName)) {
|
||||||
|
get(className).add(cpClassName);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private boolean isInnerClass(String cpClassName) {
|
||||||
|
return cpClassName.contains("$");
|
||||||
|
}
|
||||||
|
|
||||||
|
private Set<String> get(String className) {
|
||||||
|
if (!innerClasses.containsKey(className)) {
|
||||||
|
innerClasses.put(className, new HashSet<>());
|
||||||
|
}
|
||||||
|
return innerClasses.get(className);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void main(String[] args) throws IOException, ConstantPoolException, TestFailedException {
|
||||||
|
new InnerClassesHierarchyTest().test();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void test() throws TestFailedException {
|
||||||
|
addTestCase("Source file is InnerClassesHierarchyTest.java");
|
||||||
|
try {
|
||||||
|
Queue<String> queue = new LinkedList<>();
|
||||||
|
Set<String> visitedClasses = new HashSet<>();
|
||||||
|
queue.add(outerClassName);
|
||||||
|
while (!queue.isEmpty()) {
|
||||||
|
String currentClassName = queue.poll();
|
||||||
|
if (!currentClassName.startsWith(outerClassName)) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
ClassFile cf = readClassFile(currentClassName);
|
||||||
|
InnerClasses_attribute attr = (InnerClasses_attribute)
|
||||||
|
cf.getAttribute(Attribute.InnerClasses);
|
||||||
|
assertNotNull(attr, "Class should not contain "
|
||||||
|
+ "inner classes attribute : " + currentClassName);
|
||||||
|
assertTrue(innerClasses.containsKey(currentClassName),
|
||||||
|
"map contains class name : " + currentClassName);
|
||||||
|
Set<String> setClasses = innerClasses.get(currentClassName);
|
||||||
|
if (setClasses == null) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
assertEquals(attr.number_of_classes,
|
||||||
|
setClasses.size(),
|
||||||
|
"Check number of inner classes : " + setClasses);
|
||||||
|
for (Info info : attr.classes) {
|
||||||
|
String innerClassName = info
|
||||||
|
.getInnerClassInfo(cf.constant_pool).getBaseName();
|
||||||
|
assertTrue(setClasses.contains(innerClassName),
|
||||||
|
currentClassName + " contains inner class : "
|
||||||
|
+ innerClassName);
|
||||||
|
if (visitedClasses.add(innerClassName)) {
|
||||||
|
queue.add(innerClassName);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Set<String> allClasses = innerClasses.entrySet().stream()
|
||||||
|
.flatMap(entry -> entry.getValue().stream())
|
||||||
|
.collect(Collectors.toSet());
|
||||||
|
|
||||||
|
Set<String> a_b = removeAll(visitedClasses, allClasses);
|
||||||
|
Set<String> b_a = removeAll(allClasses, visitedClasses);
|
||||||
|
assertEquals(visitedClasses, allClasses,
|
||||||
|
"All classes are found\n"
|
||||||
|
+ "visited - all classes : " + a_b
|
||||||
|
+ "\nall classes - visited : " + b_a);
|
||||||
|
} catch (Exception e) {
|
||||||
|
addFailure(e);
|
||||||
|
} finally {
|
||||||
|
checkStatus();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private Set<String> removeAll(Set<String> set1, Set<String> set2) {
|
||||||
|
Set<String> set = new HashSet<>(set1);
|
||||||
|
set.removeAll(set2);
|
||||||
|
return set;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static class A1 {
|
||||||
|
|
||||||
|
public class B1 {
|
||||||
|
}
|
||||||
|
|
||||||
|
public enum B2 {
|
||||||
|
}
|
||||||
|
|
||||||
|
public interface B3 {
|
||||||
|
}
|
||||||
|
|
||||||
|
public @interface B4 {
|
||||||
|
}
|
||||||
|
|
||||||
|
public void f() {
|
||||||
|
new B1() {
|
||||||
|
};
|
||||||
|
new B3() {
|
||||||
|
};
|
||||||
|
new B4() {
|
||||||
|
@Override
|
||||||
|
public Class<? extends Annotation> annotationType() {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
class B5 {
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Runnable r = () -> {
|
||||||
|
new B1() {
|
||||||
|
};
|
||||||
|
new B3() {
|
||||||
|
};
|
||||||
|
new B4() {
|
||||||
|
@Override
|
||||||
|
public Class<? extends Annotation> annotationType() {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
class B5 {
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
public enum A2 {;
|
||||||
|
|
||||||
|
public class B1 {
|
||||||
|
}
|
||||||
|
|
||||||
|
public enum B2 {
|
||||||
|
}
|
||||||
|
|
||||||
|
public interface B3 {
|
||||||
|
}
|
||||||
|
|
||||||
|
public @interface B4 {
|
||||||
|
}
|
||||||
|
|
||||||
|
public void a2() {
|
||||||
|
new B1() {
|
||||||
|
};
|
||||||
|
new B3() {
|
||||||
|
};
|
||||||
|
new B4() {
|
||||||
|
@Override
|
||||||
|
public Class<? extends Annotation> annotationType() {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
class B5 {
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Runnable r = () -> {
|
||||||
|
new B1() {
|
||||||
|
};
|
||||||
|
new B3() {
|
||||||
|
};
|
||||||
|
new B4() {
|
||||||
|
@Override
|
||||||
|
public Class<? extends Annotation> annotationType() {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
class B5 {
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
public interface A3 {
|
||||||
|
|
||||||
|
public class B1 {
|
||||||
|
}
|
||||||
|
|
||||||
|
public enum B2 {
|
||||||
|
}
|
||||||
|
|
||||||
|
public interface B3 {
|
||||||
|
}
|
||||||
|
|
||||||
|
public @interface B4 {
|
||||||
|
}
|
||||||
|
|
||||||
|
default void a1() {
|
||||||
|
new B1() {
|
||||||
|
};
|
||||||
|
new B3() {
|
||||||
|
};
|
||||||
|
new B4() {
|
||||||
|
@Override
|
||||||
|
public Class<? extends Annotation> annotationType() {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
class B5 {
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void a2() {
|
||||||
|
new B1() {
|
||||||
|
};
|
||||||
|
new B3() {
|
||||||
|
};
|
||||||
|
new B4() {
|
||||||
|
@Override
|
||||||
|
public Class<? extends Annotation> annotationType() {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
class B5 {
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public @interface A4 {
|
||||||
|
|
||||||
|
public class B1 {
|
||||||
|
}
|
||||||
|
|
||||||
|
public enum B2 {
|
||||||
|
}
|
||||||
|
|
||||||
|
public interface B3 {
|
||||||
|
}
|
||||||
|
|
||||||
|
public @interface B4 {
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
{
|
||||||
|
new A1() {
|
||||||
|
class B1 {
|
||||||
|
}
|
||||||
|
|
||||||
|
public void a2() {
|
||||||
|
new B1() {
|
||||||
|
};
|
||||||
|
class B5 {
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
new A3() {
|
||||||
|
class B1 {
|
||||||
|
}
|
||||||
|
|
||||||
|
public void a3() {
|
||||||
|
new B1() {
|
||||||
|
};
|
||||||
|
class B5 {
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
new A4() {
|
||||||
|
@Override
|
||||||
|
public Class<? extends Annotation> annotationType() {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
class B1 {
|
||||||
|
}
|
||||||
|
|
||||||
|
public void a4() {
|
||||||
|
new B1() {
|
||||||
|
};
|
||||||
|
class B5 {
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
Runnable r = () -> {
|
||||||
|
new A1() {
|
||||||
|
};
|
||||||
|
new A3() {
|
||||||
|
};
|
||||||
|
new A4() {
|
||||||
|
@Override
|
||||||
|
public Class<? extends Annotation> annotationType() {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
class B5 {
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
static {
|
||||||
|
new A1() {
|
||||||
|
class B1 {
|
||||||
|
}
|
||||||
|
|
||||||
|
public void a2() {
|
||||||
|
new B1() {
|
||||||
|
};
|
||||||
|
class B5 {
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
new A3() {
|
||||||
|
class B1 {
|
||||||
|
}
|
||||||
|
|
||||||
|
public void a3() {
|
||||||
|
new B1() {
|
||||||
|
};
|
||||||
|
class B5 {
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
new A4() {
|
||||||
|
@Override
|
||||||
|
public Class<? extends Annotation> annotationType() {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
class B1 {
|
||||||
|
}
|
||||||
|
|
||||||
|
public void a4() {
|
||||||
|
new B1() {
|
||||||
|
};
|
||||||
|
class B5 {
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
Runnable r = () -> {
|
||||||
|
new A1() {
|
||||||
|
};
|
||||||
|
new A3() {
|
||||||
|
};
|
||||||
|
new A4() {
|
||||||
|
@Override
|
||||||
|
public Class<? extends Annotation> annotationType() {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
class B5 {
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
public void a5() {
|
||||||
|
class A5 {
|
||||||
|
|
||||||
|
class B1 {
|
||||||
|
}
|
||||||
|
|
||||||
|
public void a5() {
|
||||||
|
new B1() {
|
||||||
|
};
|
||||||
|
|
||||||
|
class B5 {
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Runnable r = () -> {
|
||||||
|
new A1() {
|
||||||
|
};
|
||||||
|
new A3() {
|
||||||
|
};
|
||||||
|
new A4() {
|
||||||
|
@Override
|
||||||
|
public Class<? extends Annotation> annotationType() {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
class B5 {
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,78 @@
|
||||||
|
/*
|
||||||
|
* Copyright (c) 2014, 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 8042251
|
||||||
|
* @summary Testing InnerClasses_attribute of inner classes in anonymous class.
|
||||||
|
* @library /tools/javac/lib ../lib
|
||||||
|
* @build InnerClassesTestBase TestResult TestBase InMemoryFileManager ToolBox
|
||||||
|
* @run main InnerClassesInAnonymousClassTest
|
||||||
|
*/
|
||||||
|
|
||||||
|
import java.util.*;
|
||||||
|
|
||||||
|
public class InnerClassesInAnonymousClassTest extends InnerClassesTestBase {
|
||||||
|
|
||||||
|
private ClassType currentClassType;
|
||||||
|
|
||||||
|
public static void main(String[] args) throws TestFailedException {
|
||||||
|
InnerClassesTestBase test = new InnerClassesInAnonymousClassTest();
|
||||||
|
test.test("InnerClassesSrc$1", "Anonymous", "1");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void setProperties() {
|
||||||
|
setOuterOtherModifiers(Modifier.EMPTY, Modifier.ABSTRACT, Modifier.STATIC);
|
||||||
|
setInnerAccessModifiers(Modifier.EMPTY);
|
||||||
|
setInnerOtherModifiers(Modifier.EMPTY, Modifier.ABSTRACT, Modifier.FINAL);
|
||||||
|
setOuterClassType(ClassType.OTHER);
|
||||||
|
setInnerClassType(ClassType.CLASS);
|
||||||
|
setSuffix("};}");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public List<TestCase> generateTestCases() {
|
||||||
|
currentClassType = ClassType.CLASS;
|
||||||
|
setPrefix("class Anonymous {} {new Anonymous() {");
|
||||||
|
List<TestCase> sources = super.generateTestCases();
|
||||||
|
|
||||||
|
currentClassType = ClassType.INTERFACE;
|
||||||
|
setPrefix("interface Anonymous {} {new Anonymous() {");
|
||||||
|
sources.addAll(super.generateTestCases());
|
||||||
|
|
||||||
|
currentClassType = ClassType.ANNOTATION;
|
||||||
|
setPrefix("@interface Anonymous {} {new Anonymous() {@Override public "
|
||||||
|
+ "Class<? extends java.lang.annotation.Annotation> "
|
||||||
|
+ "annotationType() {return null;}");
|
||||||
|
sources.addAll(super.generateTestCases());
|
||||||
|
return sources;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void getAdditionalFlags(Map<String, Set<String>> class2Flags, ClassType type, Modifier... flags) {
|
||||||
|
super.getAdditionalFlags(class2Flags, type, flags);
|
||||||
|
class2Flags.put("Anonymous", getFlags(currentClassType, Arrays.asList(flags)));
|
||||||
|
class2Flags.put("1", new HashSet<>());
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,47 @@
|
||||||
|
/*
|
||||||
|
* Copyright (c) 2014, 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 8042251
|
||||||
|
* @summary Testing InnerClasses_attribute of inner classes in inner annotation.
|
||||||
|
* @library /tools/javac/lib ../lib
|
||||||
|
* @build InnerClassesInInnerClassTestBase InnerClassesTestBase TestResult TestBase InMemoryFileManager ToolBox
|
||||||
|
* @run main InnerClassesInInnerAnnotationTest
|
||||||
|
*/
|
||||||
|
|
||||||
|
public class InnerClassesInInnerAnnotationTest extends InnerClassesInInnerClassTestBase {
|
||||||
|
|
||||||
|
public static void main(String[] args) throws TestFailedException {
|
||||||
|
InnerClassesTestBase test = new InnerClassesInInnerAnnotationTest();
|
||||||
|
test.test("InnerClassesSrc$Inner", "Inner", "1");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void setProperties() {
|
||||||
|
setOuterOtherModifiers(Modifier.EMPTY, Modifier.ABSTRACT, Modifier.STATIC);
|
||||||
|
setInnerAccessModifiers(Modifier.EMPTY, Modifier.PUBLIC);
|
||||||
|
setOuterClassType(ClassType.ANNOTATION);
|
||||||
|
setInnerClassType(ClassType.CLASS);
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,61 @@
|
||||||
|
/*
|
||||||
|
* Copyright (c) 2014, 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 8034854 8042251
|
||||||
|
* @summary Testing InnerClasses_attribute of inner classes in inner class.
|
||||||
|
* @library /tools/javac/lib ../lib
|
||||||
|
* @build InnerClassesInInnerClassTestBase InnerClassesTestBase TestResult TestBase InMemoryFileManager ToolBox
|
||||||
|
* @run main InnerClassesInInnerClassTest
|
||||||
|
*/
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
public class InnerClassesInInnerClassTest extends InnerClassesInInnerClassTestBase {
|
||||||
|
|
||||||
|
public static void main(String[] args) throws TestFailedException {
|
||||||
|
InnerClassesTestBase test = new InnerClassesInInnerClassTest();
|
||||||
|
test.test("InnerClassesSrc$Inner", "Inner", "1");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void setProperties() {
|
||||||
|
setHasSyntheticClass(true);
|
||||||
|
setOuterClassType(ClassType.CLASS);
|
||||||
|
setInnerClassType(ClassType.CLASS);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public List<TestCase> generateTestCases() {
|
||||||
|
setForbiddenWithoutStaticInOuterMods(true);
|
||||||
|
List<TestCase> sources = super.generateTestCases();
|
||||||
|
|
||||||
|
setForbiddenWithoutStaticInOuterMods(false);
|
||||||
|
setOuterOtherModifiers(Modifier.EMPTY, Modifier.ABSTRACT, Modifier.FINAL);
|
||||||
|
setInnerOtherModifiers(Modifier.EMPTY, Modifier.ABSTRACT, Modifier.FINAL);
|
||||||
|
sources.addAll(super.generateTestCases());
|
||||||
|
|
||||||
|
return sources;
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,47 @@
|
||||||
|
/*
|
||||||
|
* Copyright (c) 2014, 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.util.Arrays;
|
||||||
|
import java.util.Map;
|
||||||
|
import java.util.Set;
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* Base class for tests that check inner classes in inner class.
|
||||||
|
*
|
||||||
|
* @author Andrei Eremeev
|
||||||
|
*/
|
||||||
|
public abstract class InnerClassesInInnerClassTestBase extends InnerClassesTestBase {
|
||||||
|
|
||||||
|
public InnerClassesInInnerClassTestBase() {
|
||||||
|
setPrefix("Inner {");
|
||||||
|
setSuffix("}");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void getAdditionalFlags(
|
||||||
|
Map<String, Set<String>> class2Flags, ClassType type, Modifier...flags) {
|
||||||
|
super.getAdditionalFlags(class2Flags, type, flags);
|
||||||
|
class2Flags.put("Inner", getFlags(type, Arrays.asList(flags)));
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,49 @@
|
||||||
|
/*
|
||||||
|
* Copyright (c) 2014, 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 8034854 8042251
|
||||||
|
* @summary Testing InnerClasses_attribute of inner classes in inner enum.
|
||||||
|
* @library /tools/javac/lib ../lib
|
||||||
|
* @build InnerClassesInInnerClassTestBase InnerClassesTestBase TestResult TestBase InMemoryFileManager ToolBox
|
||||||
|
* @run main InnerClassesInInnerEnumTest
|
||||||
|
*/
|
||||||
|
|
||||||
|
public class InnerClassesInInnerEnumTest extends InnerClassesInInnerClassTestBase {
|
||||||
|
|
||||||
|
public static void main(String[] args) throws TestFailedException {
|
||||||
|
InnerClassesTestBase test = new InnerClassesInInnerEnumTest();
|
||||||
|
test.test("InnerClassesSrc$Inner", "Inner", "1");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void setProperties() {
|
||||||
|
setOuterOtherModifiers(Modifier.EMPTY, Modifier.STATIC);
|
||||||
|
setOuterClassType(ClassType.ENUM);
|
||||||
|
setInnerClassType(ClassType.CLASS);
|
||||||
|
setHasSyntheticClass(true);
|
||||||
|
setPrefix("Inner {;");
|
||||||
|
setSuffix("}");
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,47 @@
|
||||||
|
/*
|
||||||
|
* Copyright (c) 2014, 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 8042251
|
||||||
|
* @summary Testing InnerClasses_attribute of inner classes in inner interface.
|
||||||
|
* @library /tools/javac/lib ../lib
|
||||||
|
* @build InnerClassesInInnerClassTestBase InnerClassesTestBase TestResult TestBase InMemoryFileManager ToolBox
|
||||||
|
* @run main InnerClassesInInnerInterfaceTest
|
||||||
|
*/
|
||||||
|
|
||||||
|
public class InnerClassesInInnerInterfaceTest extends InnerClassesInInnerClassTestBase {
|
||||||
|
|
||||||
|
public static void main(String[] args) throws TestFailedException {
|
||||||
|
InnerClassesTestBase test = new InnerClassesInInnerInterfaceTest();
|
||||||
|
test.test("InnerClassesSrc$Inner", "Inner", "1");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void setProperties() {
|
||||||
|
setOuterOtherModifiers(Modifier.EMPTY, Modifier.ABSTRACT);
|
||||||
|
setInnerAccessModifiers(Modifier.EMPTY, Modifier.PUBLIC);
|
||||||
|
setOuterClassType(ClassType.INTERFACE);
|
||||||
|
setInnerClassType(ClassType.CLASS);
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,167 @@
|
||||||
|
/*
|
||||||
|
* Copyright (c) 2014, 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 8042251
|
||||||
|
* @summary Testing InnerClasses_attribute of inner classes in local class.
|
||||||
|
* @library /tools/javac/lib ../lib
|
||||||
|
* @build InnerClassesTestBase TestResult TestBase InMemoryFileManager ToolBox
|
||||||
|
* @run main InnerClassesInLocalClassTest
|
||||||
|
*/
|
||||||
|
|
||||||
|
import java.util.*;
|
||||||
|
|
||||||
|
public class InnerClassesInLocalClassTest extends InnerClassesTestBase {
|
||||||
|
|
||||||
|
private final static Modifier[] LOCAL_CLASS_MODIFIERS =
|
||||||
|
new Modifier[]{Modifier.EMPTY, Modifier.ABSTRACT, Modifier.FINAL};
|
||||||
|
private final static String CLASS_TEMPLATE =
|
||||||
|
"public %CLASS% OuterClass {\n" +
|
||||||
|
"%SOURCE%\n" +
|
||||||
|
"}";
|
||||||
|
|
||||||
|
private final List<Data> innerClassesData;
|
||||||
|
|
||||||
|
public InnerClassesInLocalClassTest() {
|
||||||
|
innerClassesData = new ArrayList<>();
|
||||||
|
for (Modifier outerModifier : LOCAL_CLASS_MODIFIERS) {
|
||||||
|
StringBuilder sb = new StringBuilder();
|
||||||
|
sb.append(outerModifier.getString()).append(' ');
|
||||||
|
sb.append("class Local {");
|
||||||
|
Map<String, Set<String>> class2Flags = new HashMap<>();
|
||||||
|
for (int i = 0; i < LOCAL_CLASS_MODIFIERS.length; ++i) {
|
||||||
|
Modifier innerModifier = LOCAL_CLASS_MODIFIERS[i];
|
||||||
|
sb.append(innerModifier.getString()).append(' ')
|
||||||
|
.append("class").append(' ')
|
||||||
|
.append('A').append(i).append("{}\n");
|
||||||
|
class2Flags.put("A" + i, getFlags(innerModifier));
|
||||||
|
}
|
||||||
|
sb.append("};");
|
||||||
|
class2Flags.put("1Local", getFlags(outerModifier));
|
||||||
|
innerClassesData.add(new Data(sb.toString(), class2Flags));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void main(String[] args) throws TestFailedException {
|
||||||
|
InnerClassesTestBase test = new InnerClassesInLocalClassTest();
|
||||||
|
test.test("OuterClass$1Local", "1Local");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void setProperties() {
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public List<TestCase> generateTestCases() {
|
||||||
|
List<TestCase> testCases = new ArrayList<>();
|
||||||
|
testCases.addAll(localClassInClassMethod());
|
||||||
|
testCases.addAll(localClassInInterfaceMethod());
|
||||||
|
return testCases;
|
||||||
|
}
|
||||||
|
|
||||||
|
private List<TestCase> localClassInClassMethod() {
|
||||||
|
List<TestCase> list = new ArrayList<>();
|
||||||
|
String template = CLASS_TEMPLATE.replace("%CLASS%", "class");
|
||||||
|
list.addAll(lambda(template));
|
||||||
|
list.addAll(constructor(template));
|
||||||
|
list.addAll(method(template,
|
||||||
|
new Modifier[]{Modifier.EMPTY, Modifier.PRIVATE, Modifier.PROTECTED, Modifier.PUBLIC},
|
||||||
|
new Modifier[]{Modifier.EMPTY, Modifier.FINAL, Modifier.STATIC}));
|
||||||
|
list.addAll(staticAndInstanceInitializer(template));
|
||||||
|
return list;
|
||||||
|
}
|
||||||
|
|
||||||
|
private List<TestCase> localClassInInterfaceMethod() {
|
||||||
|
String template = CLASS_TEMPLATE.replace("%CLASS%", "interface");
|
||||||
|
return method(template,
|
||||||
|
new Modifier[]{Modifier.EMPTY, Modifier.PUBLIC},
|
||||||
|
new Modifier[]{Modifier.DEFAULT, Modifier.STATIC});
|
||||||
|
}
|
||||||
|
|
||||||
|
private List<TestCase> generate(String template, String prefix, String suffix) {
|
||||||
|
List<TestCase> list = new ArrayList<>();
|
||||||
|
for (Data data : innerClassesData) {
|
||||||
|
list.add(new TestCase(template.replace("%SOURCE%",
|
||||||
|
prefix + data.sources + suffix),
|
||||||
|
data.class2Flags));
|
||||||
|
}
|
||||||
|
return list;
|
||||||
|
}
|
||||||
|
|
||||||
|
private List<TestCase> lambda(String template) {
|
||||||
|
return generate(template, "Runnable run = () -> {", "};");
|
||||||
|
}
|
||||||
|
|
||||||
|
private List<TestCase> constructor(String template) {
|
||||||
|
List<TestCase> list = new ArrayList<>();
|
||||||
|
for (Modifier modifier :
|
||||||
|
new Modifier[]{Modifier.EMPTY, Modifier.PRIVATE, Modifier.PROTECTED, Modifier.PUBLIC}) {
|
||||||
|
list.addAll(generate(template, modifier.getString() + " OuterClass() {", "}"));
|
||||||
|
}
|
||||||
|
return list;
|
||||||
|
}
|
||||||
|
|
||||||
|
private List<TestCase> method(String template, Modifier[] mods, Modifier[] otherMods) {
|
||||||
|
List<TestCase> list = new ArrayList<>();
|
||||||
|
for (Modifier modifier : mods) {
|
||||||
|
for (Modifier otherMod : otherMods) {
|
||||||
|
list.addAll(generate(template,
|
||||||
|
String.format("%s %s void method() {",
|
||||||
|
modifier.getString(),
|
||||||
|
otherMod.getString()),
|
||||||
|
"}"));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return list;
|
||||||
|
}
|
||||||
|
|
||||||
|
private List<TestCase> staticAndInstanceInitializer(String template) {
|
||||||
|
List<TestCase> list = new ArrayList<>();
|
||||||
|
for (Modifier modifier : new Modifier[]{Modifier.EMPTY, Modifier.STATIC}) {
|
||||||
|
list.addAll(generate(template, modifier.getString() + "{", "}"));
|
||||||
|
}
|
||||||
|
return list;
|
||||||
|
}
|
||||||
|
|
||||||
|
private Set<String> getFlags(Modifier modifier) {
|
||||||
|
HashSet<String> set = new HashSet<>();
|
||||||
|
if (modifier != Modifier.EMPTY) {
|
||||||
|
set.add("ACC_" + modifier.getString().toUpperCase());
|
||||||
|
}
|
||||||
|
return set;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Class represents part of sources which is inserted in other code.
|
||||||
|
*/
|
||||||
|
private static class Data {
|
||||||
|
public final String sources;
|
||||||
|
public final Map<String, Set<String>> class2Flags;
|
||||||
|
|
||||||
|
public Data(String sources, Map<String, Set<String>> class2Flags) {
|
||||||
|
this.sources = sources;
|
||||||
|
this.class2Flags = class2Flags;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,141 @@
|
||||||
|
/*
|
||||||
|
* Copyright (c) 2014, 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 8042251
|
||||||
|
* @summary Test that outer_class_info_index of local and anonymous class is zero.
|
||||||
|
* @library /tools/javac/lib ../lib
|
||||||
|
* @build TestBase TestResult InMemoryFileManager ToolBox
|
||||||
|
* @run main InnerClassesIndexTest
|
||||||
|
*/
|
||||||
|
|
||||||
|
import java.io.File;
|
||||||
|
import java.io.FilenameFilter;
|
||||||
|
import java.util.HashSet;
|
||||||
|
import java.util.Set;
|
||||||
|
import java.util.stream.Collectors;
|
||||||
|
import java.util.stream.Stream;
|
||||||
|
|
||||||
|
import com.sun.tools.classfile.Attribute;
|
||||||
|
import com.sun.tools.classfile.ClassFile;
|
||||||
|
import com.sun.tools.classfile.InnerClasses_attribute;
|
||||||
|
import com.sun.tools.classfile.InnerClasses_attribute.Info;
|
||||||
|
|
||||||
|
public class InnerClassesIndexTest extends TestResult {
|
||||||
|
|
||||||
|
public static void main(String[] args) throws TestFailedException {
|
||||||
|
new InnerClassesIndexTest().test();
|
||||||
|
}
|
||||||
|
|
||||||
|
private boolean isExcluded(String className) {
|
||||||
|
return !className.startsWith(InnerClassesIndexTest.class.getName())
|
||||||
|
|| "InnerClassesIndexTest$Inner".equals(className);
|
||||||
|
}
|
||||||
|
|
||||||
|
private Set<String> getInnerClasses() {
|
||||||
|
FilenameFilter filter = (dir, name) -> name.matches("InnerClassesIndexTest\\$.*\\.class");
|
||||||
|
return Stream.of(getClassDir().listFiles(filter))
|
||||||
|
.map(File::getName)
|
||||||
|
.map(s -> s.replace(".class", ""))
|
||||||
|
.collect(Collectors.toSet());
|
||||||
|
}
|
||||||
|
|
||||||
|
public void test() throws TestFailedException {
|
||||||
|
try {
|
||||||
|
addTestCase("Source is InnerClassesIndexTest.java");
|
||||||
|
ClassFile classFile = readClassFile(InnerClassesIndexTest.class);
|
||||||
|
InnerClasses_attribute attr = (InnerClasses_attribute)
|
||||||
|
classFile.getAttribute(Attribute.InnerClasses);
|
||||||
|
|
||||||
|
Set<String> foundClasses = new HashSet<>();
|
||||||
|
for (Info info : attr.classes) {
|
||||||
|
String innerName = classFile.constant_pool.
|
||||||
|
getClassInfo(info.inner_class_info_index).getBaseName();
|
||||||
|
echo("Testing class : " + innerName);
|
||||||
|
if (isExcluded(innerName)) {
|
||||||
|
echo("Ignored : " + innerName);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
foundClasses.add(innerName);
|
||||||
|
assertEquals(info.outer_class_info_index, 0,
|
||||||
|
"outer_class_info_index of " + innerName);
|
||||||
|
if (innerName.matches("\\$\\d+")) {
|
||||||
|
assertEquals(info.inner_name_index, 0,
|
||||||
|
"inner_name_index of anonymous class");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Set<String> expectedClasses = getInnerClasses();
|
||||||
|
expectedClasses.remove("InnerClassesIndexTest$Inner");
|
||||||
|
assertEquals(foundClasses, expectedClasses, "All classes are found");
|
||||||
|
} catch (Exception e) {
|
||||||
|
addFailure(e);
|
||||||
|
} finally {
|
||||||
|
checkStatus();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static class Inner {
|
||||||
|
}
|
||||||
|
|
||||||
|
Inner inner1 = new Inner() {
|
||||||
|
};
|
||||||
|
|
||||||
|
static Inner inner2 = new Inner() {
|
||||||
|
};
|
||||||
|
|
||||||
|
Runnable r = () -> {
|
||||||
|
class Local {
|
||||||
|
}
|
||||||
|
new Local() {
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
public void local() {
|
||||||
|
class Local {
|
||||||
|
}
|
||||||
|
new Local() {
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
public InnerClassesIndexTest() {
|
||||||
|
class Local {
|
||||||
|
}
|
||||||
|
new Local() {
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
{
|
||||||
|
class Local {
|
||||||
|
}
|
||||||
|
new Local() {
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
static {
|
||||||
|
class Local {
|
||||||
|
}
|
||||||
|
new Local() {
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,82 @@
|
||||||
|
/*
|
||||||
|
* Copyright (c) 2014, 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 8034854 8042251
|
||||||
|
* @summary Testing inner classes attributes.
|
||||||
|
* @library /tools/javac/lib ../lib
|
||||||
|
* @build InnerClassesTestBase TestBase TestResult InMemoryFileManager ToolBox
|
||||||
|
* @run main InnerClassesTest
|
||||||
|
*/
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
public class InnerClassesTest extends InnerClassesTestBase {
|
||||||
|
|
||||||
|
public static void main(String[] args) throws TestFailedException {
|
||||||
|
new InnerClassesTest().test("InnerClassesSrc");
|
||||||
|
}
|
||||||
|
|
||||||
|
private List<TestCase> generateClasses() {
|
||||||
|
setInnerClassType(ClassType.CLASS);
|
||||||
|
setHasSyntheticClass(true);
|
||||||
|
return super.generateTestCases();
|
||||||
|
}
|
||||||
|
|
||||||
|
private List<TestCase> generateEnums() {
|
||||||
|
setInnerOtherModifiers(Modifier.EMPTY, Modifier.STATIC);
|
||||||
|
setInnerClassType(ClassType.ENUM);
|
||||||
|
setHasSyntheticClass(false);
|
||||||
|
return super.generateTestCases();
|
||||||
|
}
|
||||||
|
|
||||||
|
private List<TestCase> generateInterfaces() {
|
||||||
|
setInnerOtherModifiers(Modifier.EMPTY, Modifier.ABSTRACT, Modifier.STATIC);
|
||||||
|
setInnerClassType(ClassType.INTERFACE);
|
||||||
|
return super.generateTestCases();
|
||||||
|
}
|
||||||
|
|
||||||
|
private List<TestCase> generateAnnotations() {
|
||||||
|
setInnerOtherModifiers(Modifier.EMPTY, Modifier.ABSTRACT, Modifier.STATIC);
|
||||||
|
setInnerClassType(ClassType.ANNOTATION);
|
||||||
|
return super.generateTestCases();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void setProperties() {
|
||||||
|
setOuterAccessModifiers(Modifier.EMPTY);
|
||||||
|
setOuterOtherModifiers(Modifier.EMPTY);
|
||||||
|
setOuterClassType(ClassType.OTHER);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public List<TestCase> generateTestCases() {
|
||||||
|
List<TestCase> sources = generateClasses();
|
||||||
|
sources.addAll(generateEnums());
|
||||||
|
sources.addAll(generateInterfaces());
|
||||||
|
sources.addAll(generateAnnotations());
|
||||||
|
return sources;
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,446 @@
|
||||||
|
/*
|
||||||
|
* Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved.
|
||||||
|
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||||
|
*
|
||||||
|
* This code is free software; you can redistribute it and/or modify it
|
||||||
|
* under the terms of the GNU General Public License version 2 only, as
|
||||||
|
* published by the Free Software Foundation.
|
||||||
|
*
|
||||||
|
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||||
|
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||||
|
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||||
|
* version 2 for more details (a copy is included in the LICENSE file that
|
||||||
|
* accompanied this code).
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License version
|
||||||
|
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||||
|
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||||
|
*
|
||||||
|
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||||
|
* or visit www.oracle.com if you need additional information or have any
|
||||||
|
* questions.
|
||||||
|
*/
|
||||||
|
|
||||||
|
import com.sun.tools.classfile.Attribute;
|
||||||
|
import com.sun.tools.classfile.ClassFile;
|
||||||
|
import com.sun.tools.classfile.InnerClasses_attribute;
|
||||||
|
import com.sun.tools.classfile.InnerClasses_attribute.Info;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.Arrays;
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.HashSet;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
|
import java.util.Set;
|
||||||
|
import java.util.stream.Collectors;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Base class for tests of inner classes attribute.
|
||||||
|
* The scenario of tests:
|
||||||
|
* 1. set possible values of class modifiers.
|
||||||
|
* 2. according to set class modifiers, a test generates sources
|
||||||
|
* and golden data with {@code generateTestCases}.
|
||||||
|
* 3. a test loops through all test cases and checks InnerClasses
|
||||||
|
* attribute with {@code test}.
|
||||||
|
*
|
||||||
|
* Example, possible flags for outer class are {@code Modifier.PRIVATE and Modifier.PUBLIC},
|
||||||
|
* possible flags for inner class are {@code Modifier.EMPTY}.
|
||||||
|
* At the second step the test generates two test cases:
|
||||||
|
* 1. public class A {
|
||||||
|
* public class B {
|
||||||
|
* class C {}
|
||||||
|
* }
|
||||||
|
* }
|
||||||
|
* 2. public class A {
|
||||||
|
* private class B {
|
||||||
|
* class C {}
|
||||||
|
* }
|
||||||
|
* }
|
||||||
|
*/
|
||||||
|
public abstract class InnerClassesTestBase extends TestResult {
|
||||||
|
|
||||||
|
private Modifier[] outerAccessModifiers = {Modifier.EMPTY, Modifier.PRIVATE, Modifier.PROTECTED, Modifier.PUBLIC};
|
||||||
|
private Modifier[] outerOtherModifiers = {Modifier.EMPTY, Modifier.STATIC, Modifier.FINAL, Modifier.ABSTRACT};
|
||||||
|
private Modifier[] innerAccessModifiers = outerAccessModifiers;
|
||||||
|
private Modifier[] innerOtherModifiers = outerOtherModifiers;
|
||||||
|
private boolean isForbiddenWithoutStaticInOuterMods = false;
|
||||||
|
|
||||||
|
private ClassType outerClassType;
|
||||||
|
private ClassType innerClassType;
|
||||||
|
private boolean hasSyntheticClass;
|
||||||
|
private String prefix = "";
|
||||||
|
private String suffix = "";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sets properties.
|
||||||
|
*
|
||||||
|
* Returns generated list of test cases. Method is called in {@code test()}.
|
||||||
|
*/
|
||||||
|
public abstract void setProperties();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Runs the test.
|
||||||
|
*
|
||||||
|
* @param classToTest expected name of outer class
|
||||||
|
* @param skipClasses classes that names should not be checked
|
||||||
|
*/
|
||||||
|
public void test(String classToTest, String...skipClasses) throws TestFailedException {
|
||||||
|
try {
|
||||||
|
for (TestCase test : generateTestCases()) {
|
||||||
|
addTestCase(test.getSource());
|
||||||
|
test(classToTest, test, skipClasses);
|
||||||
|
}
|
||||||
|
} catch (Exception e) {
|
||||||
|
addFailure(e);
|
||||||
|
} finally {
|
||||||
|
checkStatus();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* If {@code flag} is {@code true} an outer class can not have static modifier.
|
||||||
|
*
|
||||||
|
* @param flag if {@code true} the outer class can not have static modifier
|
||||||
|
*/
|
||||||
|
public void setForbiddenWithoutStaticInOuterMods(boolean flag) {
|
||||||
|
isForbiddenWithoutStaticInOuterMods = flag;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sets the possible access flags of an outer class.
|
||||||
|
*
|
||||||
|
* @param mods the possible access flags of an outer class
|
||||||
|
*/
|
||||||
|
public void setOuterAccessModifiers(Modifier...mods) {
|
||||||
|
outerAccessModifiers = mods;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sets the possible flags of an outer class.
|
||||||
|
*
|
||||||
|
* @param mods the possible flags of an outer class
|
||||||
|
*/
|
||||||
|
public void setOuterOtherModifiers(Modifier...mods) {
|
||||||
|
outerOtherModifiers = mods;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sets the possible access flags of an inner class.
|
||||||
|
*
|
||||||
|
* @param mods the possible access flags of an inner class
|
||||||
|
*/
|
||||||
|
public void setInnerAccessModifiers(Modifier...mods) {
|
||||||
|
innerAccessModifiers = mods;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sets the possible flags of an inner class.
|
||||||
|
*
|
||||||
|
* @param mods the possible flags of an inner class
|
||||||
|
*/
|
||||||
|
public void setInnerOtherModifiers(Modifier...mods) {
|
||||||
|
innerOtherModifiers = mods;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sets the suffix for the generated source.
|
||||||
|
*
|
||||||
|
* @param suffix a suffix
|
||||||
|
*/
|
||||||
|
public void setSuffix(String suffix) {
|
||||||
|
this.suffix = suffix;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sets the prefix for the generated source.
|
||||||
|
*
|
||||||
|
* @param prefix a prefix
|
||||||
|
*/
|
||||||
|
public void setPrefix(String prefix) {
|
||||||
|
this.prefix = prefix;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* If {@code true} synthetic class is generated.
|
||||||
|
*
|
||||||
|
* @param hasSyntheticClass if {@code true} synthetic class is generated
|
||||||
|
*/
|
||||||
|
public void setHasSyntheticClass(boolean hasSyntheticClass) {
|
||||||
|
this.hasSyntheticClass = hasSyntheticClass;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sets the inner class type.
|
||||||
|
*
|
||||||
|
* @param innerClassType the inner class type
|
||||||
|
*/
|
||||||
|
public void setInnerClassType(ClassType innerClassType) {
|
||||||
|
this.innerClassType = innerClassType;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sets the outer class type.
|
||||||
|
*
|
||||||
|
* @param outerClassType the outer class type
|
||||||
|
*/
|
||||||
|
public void setOuterClassType(ClassType outerClassType) {
|
||||||
|
this.outerClassType = outerClassType;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void test(String classToTest, TestCase test, String...skipClasses) {
|
||||||
|
printf("Testing :\n%s\n", test.getSource());
|
||||||
|
try {
|
||||||
|
Map<String, Set<String>> class2Flags = test.getFlags();
|
||||||
|
ClassFile cf = readClassFile(compile(test.getSource())
|
||||||
|
.getClasses().get(classToTest));
|
||||||
|
InnerClasses_attribute innerClasses = (InnerClasses_attribute)
|
||||||
|
cf.getAttribute(Attribute.InnerClasses);
|
||||||
|
int count = 0;
|
||||||
|
for (Attribute a : cf.attributes.attrs) {
|
||||||
|
if (a instanceof InnerClasses_attribute) {
|
||||||
|
++count;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
assertEquals(1, count, "Number of inner classes attribute");
|
||||||
|
if (innerClasses == null) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
assertEquals(cf.constant_pool.
|
||||||
|
getUTF8Info(innerClasses.attribute_name_index).value, "InnerClasses",
|
||||||
|
"innerClasses.attribute_name_index");
|
||||||
|
// Inner Classes attribute consists of length (2 bytes)
|
||||||
|
// and 8 bytes for each inner class's entry.
|
||||||
|
assertEquals(innerClasses.attribute_length,
|
||||||
|
2 + 8 * class2Flags.size(), "innerClasses.attribute_length");
|
||||||
|
assertEquals(innerClasses.number_of_classes,
|
||||||
|
class2Flags.size(), "innerClasses.number_of_classes");
|
||||||
|
Set<String> visitedClasses = new HashSet<>();
|
||||||
|
for (Info e : innerClasses.classes) {
|
||||||
|
String baseName = cf.constant_pool.getClassInfo(
|
||||||
|
e.inner_class_info_index).getBaseName();
|
||||||
|
if (cf.major_version >= 51 && e.inner_name_index == 0) {
|
||||||
|
assertEquals(e.outer_class_info_index, 0,
|
||||||
|
"outer_class_info_index "
|
||||||
|
+ "in case of inner_name_index is zero : "
|
||||||
|
+ baseName);
|
||||||
|
}
|
||||||
|
String className = baseName.replaceFirst(".*\\$", "");
|
||||||
|
assertTrue(class2Flags.containsKey(className),
|
||||||
|
className);
|
||||||
|
assertTrue(visitedClasses.add(className),
|
||||||
|
"there are no duplicates in attribute : " + className);
|
||||||
|
assertEquals(e.inner_class_access_flags.getInnerClassFlags(),
|
||||||
|
class2Flags.get(className),
|
||||||
|
"inner_class_access_flags " + className);
|
||||||
|
if (!Arrays.asList(skipClasses).contains(className)) {
|
||||||
|
assertEquals(
|
||||||
|
cf.constant_pool.getClassInfo(e.inner_class_info_index).getBaseName(),
|
||||||
|
classToTest + "$" + className,
|
||||||
|
"inner_class_info_index of " + className);
|
||||||
|
if (e.outer_class_info_index > 0) {
|
||||||
|
assertEquals(
|
||||||
|
cf.constant_pool.getClassInfo(e.outer_class_info_index).getName(),
|
||||||
|
classToTest,
|
||||||
|
"outer_class_info_index of " + className);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} catch (Exception e) {
|
||||||
|
addFailure(e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Methods generates list of test cases. Method generates all possible combinations
|
||||||
|
* of acceptable flags for nested inner classes.
|
||||||
|
*
|
||||||
|
* @return generated list of test cases
|
||||||
|
*/
|
||||||
|
protected List<TestCase> generateTestCases() {
|
||||||
|
setProperties();
|
||||||
|
List<TestCase> list = new ArrayList<>();
|
||||||
|
|
||||||
|
List<List<Modifier>> outerMods = getAllCombinations(outerAccessModifiers, outerOtherModifiers);
|
||||||
|
List<List<Modifier>> innerMods = getAllCombinations(innerAccessModifiers, innerOtherModifiers);
|
||||||
|
|
||||||
|
for (List<Modifier> outerMod : outerMods) {
|
||||||
|
if (isForbiddenWithoutStaticInOuterMods && !outerMod.contains(Modifier.STATIC)) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
StringBuilder sb = new StringBuilder();
|
||||||
|
sb.append("public class InnerClassesSrc {")
|
||||||
|
.append(toString(outerMod)).append(' ')
|
||||||
|
.append(outerClassType).append(' ')
|
||||||
|
.append(prefix).append(' ').append('\n');
|
||||||
|
int count = 0;
|
||||||
|
Map<String, Set<String>> class2Flags = new HashMap<>();
|
||||||
|
List<String> syntheticClasses = new ArrayList<>();
|
||||||
|
for (List<Modifier> innerMod : innerMods) {
|
||||||
|
++count;
|
||||||
|
String privateConstructor = "";
|
||||||
|
if (hasSyntheticClass && !innerMod.contains(Modifier.ABSTRACT)) {
|
||||||
|
privateConstructor = "private A" + count + "() {}";
|
||||||
|
syntheticClasses.add("new A" + count + "();");
|
||||||
|
}
|
||||||
|
sb.append(toString(innerMod)).append(' ');
|
||||||
|
sb.append(String.format("%s A%d {%s}\n", innerClassType, count, privateConstructor));
|
||||||
|
Set<String> flags = getFlags(innerClassType, innerMod);
|
||||||
|
class2Flags.put("A" + count, flags);
|
||||||
|
}
|
||||||
|
if (hasSyntheticClass) {
|
||||||
|
// Source to generate synthetic classes
|
||||||
|
sb.append(syntheticClasses.stream().collect(Collectors.joining(" ", "{", "}")));
|
||||||
|
class2Flags.put("1", new HashSet<>(Arrays.asList("ACC_STATIC", "ACC_SYNTHETIC")));
|
||||||
|
}
|
||||||
|
sb.append(suffix).append("\n}");
|
||||||
|
getAdditionalFlags(class2Flags, outerClassType, outerMod.toArray(new Modifier[outerMod.size()]));
|
||||||
|
list.add(new TestCase(sb.toString(), class2Flags));
|
||||||
|
}
|
||||||
|
return list;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Methods returns flags which must have type.
|
||||||
|
*
|
||||||
|
* @param type class, interface, enum or annotation
|
||||||
|
* @param mods modifiers
|
||||||
|
* @return set of access flags
|
||||||
|
*/
|
||||||
|
protected Set<String> getFlags(ClassType type, List<Modifier> mods) {
|
||||||
|
Set<String> flags = mods.stream()
|
||||||
|
.map(Modifier::getString)
|
||||||
|
.filter(str -> !str.isEmpty())
|
||||||
|
.map(str -> "ACC_" + str.toUpperCase())
|
||||||
|
.collect(Collectors.toSet());
|
||||||
|
type.addSpecificFlags(flags);
|
||||||
|
return flags;
|
||||||
|
}
|
||||||
|
|
||||||
|
private List<List<Modifier>> getAllCombinations(Modifier[] accessModifiers, Modifier[] otherModifiers) {
|
||||||
|
List<List<Modifier>> list = new ArrayList<>();
|
||||||
|
for (Modifier access : accessModifiers) {
|
||||||
|
for (int i = 0; i < otherModifiers.length; ++i) {
|
||||||
|
Modifier mod1 = otherModifiers[i];
|
||||||
|
for (int j = i + 1; j < otherModifiers.length; ++j) {
|
||||||
|
Modifier mod2 = otherModifiers[j];
|
||||||
|
if (isForbidden(mod1, mod2)) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
list.add(Arrays.asList(access, mod1, mod2));
|
||||||
|
}
|
||||||
|
if (mod1 == Modifier.EMPTY) {
|
||||||
|
list.add(Arrays.asList(access));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return list;
|
||||||
|
}
|
||||||
|
|
||||||
|
private boolean isForbidden(Modifier mod1, Modifier mod2) {
|
||||||
|
return mod1 == Modifier.FINAL && mod2 == Modifier.ABSTRACT
|
||||||
|
|| mod1 == Modifier.ABSTRACT && mod2 == Modifier.FINAL;
|
||||||
|
}
|
||||||
|
|
||||||
|
private String toString(List<Modifier> mods) {
|
||||||
|
return mods.stream()
|
||||||
|
.map(Modifier::getString)
|
||||||
|
.filter(s -> !s.isEmpty())
|
||||||
|
.collect(Collectors.joining(" "));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Method is called in generateTestCases().
|
||||||
|
* If you need to add additional access flags, you should override this method.
|
||||||
|
*
|
||||||
|
*
|
||||||
|
* @param class2Flags map with flags
|
||||||
|
* @param type class, interface, enum or @annotation
|
||||||
|
* @param mods modifiers
|
||||||
|
*/
|
||||||
|
public void getAdditionalFlags(Map<String, Set<String>> class2Flags, ClassType type, Modifier...mods) {
|
||||||
|
class2Flags.values().forEach(type::addFlags);
|
||||||
|
}
|
||||||
|
|
||||||
|
public enum ClassType {
|
||||||
|
CLASS("class") {
|
||||||
|
@Override
|
||||||
|
public void addSpecificFlags(Set<String> flags) {
|
||||||
|
}
|
||||||
|
},
|
||||||
|
INTERFACE("interface") {
|
||||||
|
@Override
|
||||||
|
public void addFlags(Set<String> flags) {
|
||||||
|
flags.add("ACC_STATIC");
|
||||||
|
flags.add("ACC_PUBLIC");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void addSpecificFlags(Set<String> flags) {
|
||||||
|
flags.add("ACC_INTERFACE");
|
||||||
|
flags.add("ACC_ABSTRACT");
|
||||||
|
flags.add("ACC_STATIC");
|
||||||
|
}
|
||||||
|
},
|
||||||
|
ANNOTATION("@interface") {
|
||||||
|
@Override
|
||||||
|
public void addFlags(Set<String> flags) {
|
||||||
|
flags.add("ACC_STATIC");
|
||||||
|
flags.add("ACC_PUBLIC");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void addSpecificFlags(Set<String> flags) {
|
||||||
|
flags.add("ACC_INTERFACE");
|
||||||
|
flags.add("ACC_ABSTRACT");
|
||||||
|
flags.add("ACC_STATIC");
|
||||||
|
flags.add("ACC_ANNOTATION");
|
||||||
|
}
|
||||||
|
},
|
||||||
|
ENUM("enum") {
|
||||||
|
@Override
|
||||||
|
public void addSpecificFlags(Set<String> flags) {
|
||||||
|
flags.add("ACC_ENUM");
|
||||||
|
flags.add("ACC_FINAL");
|
||||||
|
flags.add("ACC_STATIC");
|
||||||
|
}
|
||||||
|
},
|
||||||
|
OTHER("") {
|
||||||
|
@Override
|
||||||
|
public void addSpecificFlags(Set<String> flags) {
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
private final String classType;
|
||||||
|
|
||||||
|
private ClassType(String clazz) {
|
||||||
|
this.classType = clazz;
|
||||||
|
}
|
||||||
|
|
||||||
|
public abstract void addSpecificFlags(Set<String> flags);
|
||||||
|
|
||||||
|
public String toString() {
|
||||||
|
return classType;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void addFlags(Set<String> set) {
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public enum Modifier {
|
||||||
|
PUBLIC("public"), PRIVATE("private"),
|
||||||
|
PROTECTED("protected"), DEFAULT("default"),
|
||||||
|
FINAL("final"), ABSTRACT("abstract"),
|
||||||
|
STATIC("static"), EMPTY("");
|
||||||
|
|
||||||
|
private final String str;
|
||||||
|
|
||||||
|
private Modifier(String str) {
|
||||||
|
this.str = str;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getString() {
|
||||||
|
return str;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,49 @@
|
||||||
|
/*
|
||||||
|
* Copyright (c) 2014, 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 8042251
|
||||||
|
* @summary Testing InnerClasses_attribute of inner enums in inner annotation.
|
||||||
|
* @library /tools/javac/lib ../lib
|
||||||
|
* @build InnerClassesInInnerClassTestBase InnerClassesTestBase TestBase TestResult InMemoryFileManager ToolBox
|
||||||
|
* @run main InnerEnumInInnerAnnotationTest
|
||||||
|
*/
|
||||||
|
|
||||||
|
public class InnerEnumInInnerAnnotationTest extends InnerClassesInInnerClassTestBase {
|
||||||
|
|
||||||
|
public static void main(String[] args) throws TestFailedException {
|
||||||
|
InnerClassesTestBase test = new InnerEnumInInnerAnnotationTest();
|
||||||
|
test.test("InnerClassesSrc$Inner", "Inner", "1");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void setProperties() {
|
||||||
|
setOuterOtherModifiers(Modifier.EMPTY, Modifier.ABSTRACT, Modifier.STATIC);
|
||||||
|
setInnerAccessModifiers(Modifier.EMPTY, Modifier.PUBLIC);
|
||||||
|
setInnerOtherModifiers(Modifier.EMPTY, Modifier.STATIC);
|
||||||
|
setOuterClassType(ClassType.ANNOTATION);
|
||||||
|
setInnerClassType(ClassType.ENUM);
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,49 @@
|
||||||
|
/*
|
||||||
|
* Copyright (c) 2014, 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 8042251
|
||||||
|
* @summary Testing InnerClasses_attribute of inner enums in inner enum.
|
||||||
|
* @library /tools/javac/lib ../lib
|
||||||
|
* @build InnerClassesInInnerClassTestBase InnerClassesTestBase TestBase TestResult InMemoryFileManager ToolBox
|
||||||
|
* @run main InnerEnumInInnerEnumTest
|
||||||
|
*/
|
||||||
|
|
||||||
|
public class InnerEnumInInnerEnumTest extends InnerClassesInInnerClassTestBase {
|
||||||
|
|
||||||
|
public static void main(String[] args) throws TestFailedException {
|
||||||
|
InnerClassesTestBase test = new InnerEnumInInnerEnumTest();
|
||||||
|
test.test("InnerClassesSrc$Inner", "Inner", "1");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void setProperties() {
|
||||||
|
setOuterOtherModifiers(Modifier.EMPTY, Modifier.STATIC);
|
||||||
|
setInnerOtherModifiers(Modifier.EMPTY, Modifier.STATIC);
|
||||||
|
setOuterClassType(ClassType.ENUM);
|
||||||
|
setInnerClassType(ClassType.ENUM);
|
||||||
|
setPrefix("Inner {;");
|
||||||
|
setSuffix("}");
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,48 @@
|
||||||
|
/*
|
||||||
|
* Copyright (c) 2014, 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 8042251
|
||||||
|
* @summary Testing InnerClasses_attribute of inner enums in inner interface.
|
||||||
|
* @library /tools/javac/lib ../lib
|
||||||
|
* @build InnerClassesInInnerClassTestBase InnerClassesTestBase TestBase TestResult InMemoryFileManager ToolBox
|
||||||
|
* @run main InnerEnumInInnerInterfaceTest
|
||||||
|
*/
|
||||||
|
|
||||||
|
public class InnerEnumInInnerInterfaceTest extends InnerClassesInInnerClassTestBase {
|
||||||
|
|
||||||
|
public static void main(String[] args) throws TestFailedException {
|
||||||
|
InnerClassesTestBase test = new InnerEnumInInnerInterfaceTest();
|
||||||
|
test.test("InnerClassesSrc$Inner", "Inner", "1");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void setProperties() {
|
||||||
|
setOuterOtherModifiers(Modifier.EMPTY, Modifier.ABSTRACT, Modifier.STATIC);
|
||||||
|
setInnerAccessModifiers(Modifier.EMPTY, Modifier.PUBLIC);
|
||||||
|
setInnerOtherModifiers(Modifier.EMPTY, Modifier.STATIC);
|
||||||
|
setOuterClassType(ClassType.INTERFACE);
|
||||||
|
setInnerClassType(ClassType.ENUM);
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,47 @@
|
||||||
|
/*
|
||||||
|
* Copyright (c) 2014, 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 8042251
|
||||||
|
* @summary Testing InnerClasses_attribute of inner enums in inner class.
|
||||||
|
* @library /tools/javac/lib ../lib
|
||||||
|
* @build InnerClassesInInnerClassTestBase InnerClassesTestBase TestBase TestResult InMemoryFileManager ToolBox
|
||||||
|
* @run main InnerEnumsInInnerClassTest
|
||||||
|
*/
|
||||||
|
|
||||||
|
public class InnerEnumsInInnerClassTest extends InnerClassesInInnerClassTestBase {
|
||||||
|
|
||||||
|
public static void main(String[] args) throws TestFailedException {
|
||||||
|
InnerClassesTestBase test = new InnerEnumsInInnerClassTest();
|
||||||
|
test.test("InnerClassesSrc$Inner", "Inner", "1");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void setProperties() {
|
||||||
|
setForbiddenWithoutStaticInOuterMods(true);
|
||||||
|
setInnerOtherModifiers(Modifier.EMPTY, Modifier.STATIC);
|
||||||
|
setOuterClassType(ClassType.CLASS);
|
||||||
|
setInnerClassType(ClassType.ENUM);
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,48 @@
|
||||||
|
/*
|
||||||
|
* Copyright (c) 2014, 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 8042251
|
||||||
|
* @summary Testing InnerClasses_attribute of inner interfaces in inner annotation.
|
||||||
|
* @library /tools/javac/lib ../lib
|
||||||
|
* @build InnerClassesInInnerClassTestBase InnerClassesTestBase TestBase TestResult InMemoryFileManager ToolBox
|
||||||
|
* @run main InnerInterfacesInInnerAnnotationTest
|
||||||
|
*/
|
||||||
|
|
||||||
|
public class InnerInterfacesInInnerAnnotationTest extends InnerClassesInInnerClassTestBase {
|
||||||
|
|
||||||
|
public static void main(String[] args) throws TestFailedException {
|
||||||
|
InnerClassesTestBase test = new InnerInterfacesInInnerAnnotationTest();
|
||||||
|
test.test("InnerClassesSrc$Inner", "Inner", "1");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void setProperties() {
|
||||||
|
setOuterOtherModifiers(Modifier.EMPTY, Modifier.ABSTRACT, Modifier.STATIC);
|
||||||
|
setInnerAccessModifiers(Modifier.EMPTY, Modifier.PUBLIC);
|
||||||
|
setInnerOtherModifiers(Modifier.EMPTY, Modifier.ABSTRACT, Modifier.STATIC);
|
||||||
|
setOuterClassType(ClassType.ANNOTATION);
|
||||||
|
setInnerClassType(ClassType.INTERFACE);
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,47 @@
|
||||||
|
/*
|
||||||
|
* Copyright (c) 2014, 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
|
||||||
|
* @summary Testing InnerClasses_attribute of inner interfaces in inner class.
|
||||||
|
* @author aeremeev
|
||||||
|
* @library /tools/javac/lib ../lib
|
||||||
|
* @build InnerClassesInInnerClassTestBase InnerClassesTestBase TestBase TestResult InMemoryFileManager ToolBox
|
||||||
|
* @run main InnerInterfacesInInnerClassTest
|
||||||
|
*/
|
||||||
|
|
||||||
|
public class InnerInterfacesInInnerClassTest extends InnerClassesInInnerClassTestBase {
|
||||||
|
|
||||||
|
public static void main(String[] args) throws TestFailedException {
|
||||||
|
InnerClassesTestBase test = new InnerInterfacesInInnerClassTest();
|
||||||
|
test.test("InnerClassesSrc$Inner", "Inner", "1");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void setProperties() {
|
||||||
|
setForbiddenWithoutStaticInOuterMods(true);
|
||||||
|
setInnerOtherModifiers(Modifier.EMPTY, Modifier.ABSTRACT, Modifier.STATIC);
|
||||||
|
setOuterClassType(ClassType.CLASS);
|
||||||
|
setInnerClassType(ClassType.INTERFACE);
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,49 @@
|
||||||
|
/*
|
||||||
|
* Copyright (c) 2014, 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 8042251
|
||||||
|
* @summary Testing InnerClasses_attribute of inner interfaces in inner enum.
|
||||||
|
* @library /tools/javac/lib ../lib
|
||||||
|
* @build InnerClassesInInnerClassTestBase InnerClassesTestBase TestBase TestResult InMemoryFileManager ToolBox
|
||||||
|
* @run main InnerInterfacesInInnerEnumTest
|
||||||
|
*/
|
||||||
|
|
||||||
|
public class InnerInterfacesInInnerEnumTest extends InnerClassesInInnerClassTestBase {
|
||||||
|
|
||||||
|
public static void main(String[] args) throws TestFailedException {
|
||||||
|
InnerClassesTestBase test = new InnerInterfacesInInnerEnumTest();
|
||||||
|
test.test("InnerClassesSrc$Inner", "Inner", "1");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void setProperties() {
|
||||||
|
setOuterOtherModifiers(Modifier.EMPTY, Modifier.STATIC);
|
||||||
|
setInnerOtherModifiers(Modifier.EMPTY, Modifier.ABSTRACT, Modifier.STATIC);
|
||||||
|
setOuterClassType(ClassType.ENUM);
|
||||||
|
setInnerClassType(ClassType.INTERFACE);
|
||||||
|
setPrefix("Inner {;");
|
||||||
|
setSuffix("}");
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,50 @@
|
||||||
|
/*
|
||||||
|
* Copyright (c) 2014, 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 8042251
|
||||||
|
* @summary Testing InnerClasses_attribute of inner interfaces in inner interface.
|
||||||
|
* @library /tools/javac/lib ../lib
|
||||||
|
* @build InnerClassesInInnerClassTestBase InnerClassesTestBase TestBase TestResult InMemoryFileManager ToolBox
|
||||||
|
* @run main InnerInterfacesInInnerInterfaceTest
|
||||||
|
*/
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
public class InnerInterfacesInInnerInterfaceTest extends InnerClassesInInnerClassTestBase {
|
||||||
|
|
||||||
|
public static void main(String[] args) throws TestFailedException {
|
||||||
|
InnerClassesTestBase test = new InnerInterfacesInInnerInterfaceTest();
|
||||||
|
test.test("InnerClassesSrc$Inner", "Inner", "1");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void setProperties() {
|
||||||
|
setOuterOtherModifiers(Modifier.EMPTY, Modifier.ABSTRACT, Modifier.STATIC);
|
||||||
|
setInnerAccessModifiers(Modifier.EMPTY, Modifier.PUBLIC);
|
||||||
|
setInnerOtherModifiers(Modifier.EMPTY, Modifier.ABSTRACT, Modifier.STATIC);
|
||||||
|
setOuterClassType(ClassType.INTERFACE);
|
||||||
|
setInnerClassType(ClassType.INTERFACE);
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,49 @@
|
||||||
|
/*
|
||||||
|
* Copyright (c) 2014, 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 8042251
|
||||||
|
* @summary Test that there are no inner classes attributes in case of there are no inner classes.
|
||||||
|
* @library /tools/javac/lib ../lib
|
||||||
|
* @build TestBase InMemoryFileManager ToolBox
|
||||||
|
* @run main NoInnerClassesTest
|
||||||
|
*/
|
||||||
|
|
||||||
|
import com.sun.tools.classfile.Attribute;
|
||||||
|
import com.sun.tools.classfile.ClassFile;
|
||||||
|
import com.sun.tools.classfile.ConstantPoolException;
|
||||||
|
|
||||||
|
import java.io.IOException;
|
||||||
|
|
||||||
|
public class NoInnerClassesTest extends TestBase {
|
||||||
|
|
||||||
|
public static void main(String[] args) throws IOException, ConstantPoolException {
|
||||||
|
new NoInnerClassesTest().test();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void test() throws IOException, ConstantPoolException {
|
||||||
|
ClassFile classFile = readClassFile("NoInnerClassesTest");
|
||||||
|
assertNull(classFile.getAttribute(Attribute.InnerClasses), "Found inner class attribute");
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,92 @@
|
||||||
|
The description of the tests for the InnerClasses attribute.
|
||||||
|
|
||||||
|
InnerClassesTestBase is the base class for tests of inner classes attribute.
|
||||||
|
Each tests extends the base class.
|
||||||
|
The scenario of tests:
|
||||||
|
1. set possible values of class modifiers, outer/inner class types.
|
||||||
|
2. according to set class modifiers, a test generates sources
|
||||||
|
and golden data with generateTestCases.
|
||||||
|
3. a test loops through all test cases and checks InnerClasses attribute in method test().
|
||||||
|
|
||||||
|
Example, possible flags for outer class are Modifier.PRIVATE and Modifier.PUBLIC,
|
||||||
|
possible flags for inner class are Modifier.EMPTY, outer class type is CLASS
|
||||||
|
and inner class type is CLASS.
|
||||||
|
At the second step the test generates two test cases:
|
||||||
|
1. public class A {
|
||||||
|
public class B {
|
||||||
|
class C {}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
2. public class A {
|
||||||
|
private class B {
|
||||||
|
class C {}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
The list of tests.
|
||||||
|
|
||||||
|
Test: test if there is not inner class, the InnerClasses attribute
|
||||||
|
is not generated (NoInnerClasses.java).
|
||||||
|
|
||||||
|
Test: inner classes in anonymous class (InnerClassesInAnonymousClassTest.java).
|
||||||
|
Possible access flags of the inner class: abstract and final.
|
||||||
|
|
||||||
|
Test: inner classes in local class (InnerClassesInLocalClassTest.java).
|
||||||
|
Locations of local class: static and instance initializer, constructor, method, lambda,
|
||||||
|
default and static methods of interface.
|
||||||
|
|
||||||
|
Test: test the outer_class_info_index and inner_name_index of
|
||||||
|
local and anonymous classes (InnerClassesIndexTest.java).
|
||||||
|
|
||||||
|
List of test cases for Inner*InInner*Test:
|
||||||
|
* InnerClassesInInnerClassTest
|
||||||
|
outer flags: all possible flags
|
||||||
|
inner flags: all possible flags
|
||||||
|
* InnerClassesInInnerEnumTest
|
||||||
|
outer flags: all access flags, abstract
|
||||||
|
inner flags: all possible flags
|
||||||
|
* InnerClassesInInnerAnnotationTest
|
||||||
|
outer flags: all access flags, abstract
|
||||||
|
inner flags: all flags, except private and protected
|
||||||
|
* InnerClassesInInnerInterfaceTest
|
||||||
|
outer flags: all access flags, abstract
|
||||||
|
inner flags: all flags, except private and protected
|
||||||
|
|
||||||
|
* InnerEnumsInInnerClassTest
|
||||||
|
outer flags: all possible flags
|
||||||
|
inner flags: all possible flags
|
||||||
|
* InnerEnumsInInnerEnumTest
|
||||||
|
outer flags: all possible flags
|
||||||
|
inner flags: all possible flags
|
||||||
|
* InnerEnumsInInnerAnnotationTest
|
||||||
|
outer flags: all access flags, abstract, static
|
||||||
|
inner flags: public, static
|
||||||
|
* InnerEnumsInInnerInterfaceTest
|
||||||
|
outer flags: all access flags, abstract, static
|
||||||
|
inner flags: public, static
|
||||||
|
|
||||||
|
* InnerAnnotationInInnerClassTest
|
||||||
|
outer flags: all possible flags, except static
|
||||||
|
inner flags: all access flags, abstract and static
|
||||||
|
* InnerAnnotationInInnerEnumTest
|
||||||
|
outer flags: all access flags, static
|
||||||
|
inner flags: all access flags, abstract and static
|
||||||
|
* InnerAnnotationInInnerAnnotation
|
||||||
|
outer flags: all access flags, static and abstract
|
||||||
|
inner flags: public, abstract, static
|
||||||
|
* InnerAnnotationInInnerInterface
|
||||||
|
outer flags: all access flags, static and abstract
|
||||||
|
inner flags: public, abstract, static
|
||||||
|
|
||||||
|
* InnerInterfaceInInnerClassTest
|
||||||
|
outer flags: all possible flags, except static
|
||||||
|
inner flags: all access flags, abstract and static
|
||||||
|
* InnerInterfaceInInnerEnumTest
|
||||||
|
outer flags: all access flags, static
|
||||||
|
inner flags: all access flags, abstract and static
|
||||||
|
* InnerInterfaceInInnerAnnotation
|
||||||
|
outer flags: all access flags, static and abstract
|
||||||
|
inner flags: public, abstract, static
|
||||||
|
* InnerInterfaceInInnerInterface
|
||||||
|
outer flags: all access flags, static and abstract
|
||||||
|
inner flags: public, abstract, static
|
|
@ -0,0 +1,58 @@
|
||||||
|
/*
|
||||||
|
* Copyright (c) 2014, 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.util.Map;
|
||||||
|
import java.util.Set;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Class represents test cases. This class contains source code and
|
||||||
|
* access flags for each inner class in source code.
|
||||||
|
*/
|
||||||
|
public class TestCase {
|
||||||
|
|
||||||
|
private final String sourceCode;
|
||||||
|
private final Map<String, Set<String>> class2Flags;
|
||||||
|
|
||||||
|
public TestCase(String sourceCode, Map<String, Set<String>> class2Flags) {
|
||||||
|
this.sourceCode = sourceCode;
|
||||||
|
this.class2Flags = class2Flags;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns source code.
|
||||||
|
*
|
||||||
|
* @return source code
|
||||||
|
*/
|
||||||
|
public String getSource() {
|
||||||
|
return sourceCode;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns map with entries (ClassName, set of access flags for the ClassName).
|
||||||
|
*
|
||||||
|
* @return map with entries (ClassName, set of access flags for the ClassName)
|
||||||
|
*/
|
||||||
|
public Map<String, Set<String>> getFlags() {
|
||||||
|
return class2Flags;
|
||||||
|
}
|
||||||
|
}
|
|
@ -22,22 +22,23 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import java.io.File;
|
import java.io.File;
|
||||||
|
import java.io.FileInputStream;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
|
import java.io.InputStream;
|
||||||
|
import java.util.Arrays;
|
||||||
|
import java.util.Collections;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Objects;
|
import java.util.Objects;
|
||||||
import java.util.function.Function;
|
import java.util.function.Function;
|
||||||
import java.util.stream.Stream;
|
import java.util.stream.Collectors;
|
||||||
|
|
||||||
import javax.tools.DiagnosticCollector;
|
import javax.tools.DiagnosticCollector;
|
||||||
import javax.tools.JavaCompiler;
|
import javax.tools.JavaCompiler;
|
||||||
import javax.tools.JavaFileObject;
|
import javax.tools.JavaFileObject;
|
||||||
import javax.tools.ToolProvider;
|
import javax.tools.ToolProvider;
|
||||||
|
|
||||||
import static java.lang.String.format;
|
import com.sun.tools.classfile.ClassFile;
|
||||||
import static java.lang.System.lineSeparator;
|
import com.sun.tools.classfile.ConstantPoolException;
|
||||||
import static java.util.Arrays.asList;
|
|
||||||
import static java.util.Collections.emptyList;
|
|
||||||
import static java.util.stream.Collectors.joining;
|
|
||||||
import static java.util.stream.Collectors.toList;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Base class for class file attribute tests.
|
* Base class for class file attribute tests.
|
||||||
|
@ -46,7 +47,7 @@ import static java.util.stream.Collectors.toList;
|
||||||
*/
|
*/
|
||||||
public class TestBase {
|
public class TestBase {
|
||||||
|
|
||||||
public static final String LINE_SEPARATOR = lineSeparator();
|
public static final String LINE_SEPARATOR = System.lineSeparator();
|
||||||
|
|
||||||
private <S> InMemoryFileManager compile(
|
private <S> InMemoryFileManager compile(
|
||||||
List<String> options,
|
List<String> options,
|
||||||
|
@ -57,7 +58,7 @@ public class TestBase {
|
||||||
JavaCompiler compiler = ToolProvider.getSystemJavaCompiler();
|
JavaCompiler compiler = ToolProvider.getSystemJavaCompiler();
|
||||||
List<? extends JavaFileObject> src = sources.stream()
|
List<? extends JavaFileObject> src = sources.stream()
|
||||||
.map(src2JavaFileObject)
|
.map(src2JavaFileObject)
|
||||||
.collect(toList());
|
.collect(Collectors.toList());
|
||||||
|
|
||||||
DiagnosticCollector<? super JavaFileObject> dc = new DiagnosticCollector<>();
|
DiagnosticCollector<? super JavaFileObject> dc = new DiagnosticCollector<>();
|
||||||
try (InMemoryFileManager fileManager
|
try (InMemoryFileManager fileManager
|
||||||
|
@ -67,7 +68,7 @@ public class TestBase {
|
||||||
if (!success) {
|
if (!success) {
|
||||||
String errorMessage = dc.getDiagnostics().stream()
|
String errorMessage = dc.getDiagnostics().stream()
|
||||||
.map(Object::toString)
|
.map(Object::toString)
|
||||||
.collect(joining("\n"));
|
.collect(Collectors.joining("\n"));
|
||||||
throw new CompilationException("Compilation Error\n\n" + errorMessage);
|
throw new CompilationException("Compilation Error\n\n" + errorMessage);
|
||||||
}
|
}
|
||||||
return fileManager;
|
return fileManager;
|
||||||
|
@ -82,7 +83,7 @@ public class TestBase {
|
||||||
*/
|
*/
|
||||||
public InMemoryFileManager compile(String... sources)
|
public InMemoryFileManager compile(String... sources)
|
||||||
throws IOException, CompilationException {
|
throws IOException, CompilationException {
|
||||||
return compile(emptyList(), sources);
|
return compile(Collections.emptyList(), sources);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -94,7 +95,7 @@ public class TestBase {
|
||||||
*/
|
*/
|
||||||
public InMemoryFileManager compile(List<String> options, String... sources)
|
public InMemoryFileManager compile(List<String> options, String... sources)
|
||||||
throws IOException, CompilationException {
|
throws IOException, CompilationException {
|
||||||
return compile(options, ToolBox.JavaSource::new, asList(sources));
|
return compile(options, ToolBox.JavaSource::new, Arrays.asList(sources));
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -105,7 +106,7 @@ public class TestBase {
|
||||||
*/
|
*/
|
||||||
public InMemoryFileManager compile(String[]... sources) throws IOException,
|
public InMemoryFileManager compile(String[]... sources) throws IOException,
|
||||||
CompilationException {
|
CompilationException {
|
||||||
return compile(emptyList(), sources);
|
return compile(Collections.emptyList(), sources);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -117,12 +118,73 @@ public class TestBase {
|
||||||
*/
|
*/
|
||||||
public InMemoryFileManager compile(List<String> options, String[]... sources)
|
public InMemoryFileManager compile(List<String> options, String[]... sources)
|
||||||
throws IOException, CompilationException {
|
throws IOException, CompilationException {
|
||||||
return compile(options, src -> new ToolBox.JavaSource(src[0], src[1]), asList(sources));
|
return compile(options, src -> new ToolBox.JavaSource(src[0], src[1]), Arrays.asList(sources));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns class file that is read from {@code is}.
|
||||||
|
*
|
||||||
|
* @param is an input stream
|
||||||
|
* @return class file that is read from {@code is}
|
||||||
|
* @throws IOException if I/O error occurs
|
||||||
|
* @throws ConstantPoolException if constant pool error occurs
|
||||||
|
*/
|
||||||
|
public ClassFile readClassFile(InputStream is) throws IOException, ConstantPoolException {
|
||||||
|
return ClassFile.read(is);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns class file that is read from {@code fileObject}.
|
||||||
|
*
|
||||||
|
* @param fileObject a file object
|
||||||
|
* @return class file that is read from {@code fileObject}
|
||||||
|
* @throws IOException if I/O error occurs
|
||||||
|
* @throws ConstantPoolException if constant pool error occurs
|
||||||
|
*/
|
||||||
|
public ClassFile readClassFile(JavaFileObject fileObject) throws IOException, ConstantPoolException {
|
||||||
|
return readClassFile(fileObject.openInputStream());
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns class file that corresponds to {@code clazz}.
|
||||||
|
*
|
||||||
|
* @param clazz a class
|
||||||
|
* @return class file that is read from {@code clazz}
|
||||||
|
* @throws IOException if I/O error occurs
|
||||||
|
* @throws ConstantPoolException if constant pool error occurs
|
||||||
|
*/
|
||||||
|
public ClassFile readClassFile(Class<?> clazz) throws IOException, ConstantPoolException {
|
||||||
|
return readClassFile(getClassFile(clazz));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns class file that corresponds to {@code className}.
|
||||||
|
*
|
||||||
|
* @param className a class name
|
||||||
|
* @return class file that is read from {@code className}
|
||||||
|
* @throws IOException if I/O error occurs
|
||||||
|
* @throws ConstantPoolException if constant pool error occurs
|
||||||
|
*/
|
||||||
|
public ClassFile readClassFile(String className) throws IOException, ConstantPoolException {
|
||||||
|
return readClassFile(getClassFile(className + ".class"));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns class file that is read from {@code file}.
|
||||||
|
*
|
||||||
|
* @param file a file
|
||||||
|
* @return class file that is read from {@code file}
|
||||||
|
* @throws IOException if I/O error occurs
|
||||||
|
* @throws ConstantPoolException if constant pool error occurs
|
||||||
|
*/
|
||||||
|
public ClassFile readClassFile(File file) throws IOException, ConstantPoolException {
|
||||||
|
return readClassFile(new FileInputStream(file));
|
||||||
}
|
}
|
||||||
|
|
||||||
public void assertEquals(Object actual, Object expected, String message) {
|
public void assertEquals(Object actual, Object expected, String message) {
|
||||||
if (!Objects.equals(actual, expected))
|
if (!Objects.equals(actual, expected))
|
||||||
throw new AssertionFailedException(format("%s%nGot: %s, Expected: %s", message, actual, expected));
|
throw new AssertionFailedException(String.format("%s%nGot: %s, Expected: %s",
|
||||||
|
message, actual, expected));
|
||||||
}
|
}
|
||||||
|
|
||||||
public void assertNull(Object actual, String message) {
|
public void assertNull(Object actual, String message) {
|
||||||
|
@ -169,22 +231,18 @@ public class TestBase {
|
||||||
* @param message string to print.
|
* @param message string to print.
|
||||||
*/
|
*/
|
||||||
public void echo(String message) {
|
public void echo(String message) {
|
||||||
System.err.println(message.replace("\n", LINE_SEPARATOR));
|
printf(message + "\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Substitutes args in template and prints result to standard error. New lines are converted to system dependent NL.
|
* Substitutes args in template and prints result to standard error.
|
||||||
|
* New lines are converted to system dependent NL.
|
||||||
*
|
*
|
||||||
* @param template template in standard String.format(...) format.
|
* @param template template in standard String.format(...) format.
|
||||||
* @param args arguments to substitute in template.
|
* @param args arguments to substitute in template.
|
||||||
*/
|
*/
|
||||||
public void printf(String template, Object... args) {
|
public void printf(String template, Object... args) {
|
||||||
System.err.printf(template, Stream.of(args)
|
System.err.printf(String.format(template, args).replace("\n", LINE_SEPARATOR));
|
||||||
.map(Objects::toString)
|
|
||||||
.map(m -> m.replace("\n", LINE_SEPARATOR))
|
|
||||||
.collect(toList())
|
|
||||||
.toArray());
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public static class CompilationException extends Exception {
|
public static class CompilationException extends Exception {
|
||||||
|
|
|
@ -23,13 +23,15 @@
|
||||||
|
|
||||||
import java.io.PrintWriter;
|
import java.io.PrintWriter;
|
||||||
import java.io.StringWriter;
|
import java.io.StringWriter;
|
||||||
import java.util.ArrayList;
|
import java.util.*;
|
||||||
import java.util.List;
|
import java.util.stream.Stream;
|
||||||
import java.util.Objects;
|
|
||||||
|
|
||||||
import static java.lang.String.format;
|
import static java.lang.String.format;
|
||||||
import static java.util.stream.Collectors.joining;
|
import static java.util.stream.Collectors.joining;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This class accumulates test results. Test results can be checked with method @{code checkStatus}.
|
||||||
|
*/
|
||||||
public class TestResult extends TestBase {
|
public class TestResult extends TestBase {
|
||||||
|
|
||||||
private final List<Info> testCases;
|
private final List<Info> testCases;
|
||||||
|
@ -39,15 +41,18 @@ public class TestResult extends TestBase {
|
||||||
testCases.add(new Info("Global test info"));
|
testCases.add(new Info("Global test info"));
|
||||||
}
|
}
|
||||||
|
|
||||||
public void addTestCase(String src) {
|
/**
|
||||||
testCases.add(new Info(src));
|
* Adds new test case info.
|
||||||
|
*
|
||||||
|
* @param info the information about test case
|
||||||
|
*/
|
||||||
|
public void addTestCase(String info) {
|
||||||
|
testCases.add(new Info(info));
|
||||||
}
|
}
|
||||||
|
|
||||||
public String errorMessage() {
|
private String errorMessage() {
|
||||||
return testCases.stream().filter(Info::isFailed)
|
return testCases.stream().filter(Info::isFailed)
|
||||||
.map(tc -> format("Failure in test case:\n%s\n%s", tc.info(),
|
.map(tc -> format("Failure in test case:\n%s\n%s", tc.info(), tc.getMessage()))
|
||||||
(tc.asserts.size() > 0 ? tc.getAssertMessage() + "\n" : "")
|
|
||||||
+ tc.getErrorMessage()))
|
|
||||||
.collect(joining("\n"));
|
.collect(joining("\n"));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -76,8 +81,14 @@ public class TestResult extends TestBase {
|
||||||
getLastTestCase().assertEquals(actual, true, message);
|
getLastTestCase().assertEquals(actual, true, message);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void assertContains(Set<?> found, Set<?> expected, String message) {
|
||||||
|
Set<?> copy = new HashSet<>(expected);
|
||||||
|
copy.removeAll(found);
|
||||||
|
assertTrue(found.containsAll(expected), message + " : " + copy);
|
||||||
|
}
|
||||||
|
|
||||||
public void addFailure(Throwable th) {
|
public void addFailure(Throwable th) {
|
||||||
getLastTestCase().addFailure(th);
|
testCases.get(testCases.size() - 1).addFailure(th);
|
||||||
}
|
}
|
||||||
|
|
||||||
private Info getLastTestCase() {
|
private Info getLastTestCase() {
|
||||||
|
@ -87,6 +98,13 @@ public class TestResult extends TestBase {
|
||||||
return testCases.get(testCases.size() - 1);
|
return testCases.get(testCases.size() - 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Throws {@code TestFailedException} if one of the asserts are failed
|
||||||
|
* or an exception occurs. Prints error message of failed test cases.
|
||||||
|
*
|
||||||
|
* @throws TestFailedException if one of the asserts are failed
|
||||||
|
* or an exception occurs
|
||||||
|
*/
|
||||||
public void checkStatus() throws TestFailedException {
|
public void checkStatus() throws TestFailedException {
|
||||||
if (testCases.stream().anyMatch(Info::isFailed)) {
|
if (testCases.stream().anyMatch(Info::isFailed)) {
|
||||||
echo(errorMessage());
|
echo(errorMessage());
|
||||||
|
@ -120,7 +138,13 @@ public class TestResult extends TestBase {
|
||||||
}
|
}
|
||||||
|
|
||||||
public void addFailure(String message) {
|
public void addFailure(String message) {
|
||||||
asserts.add(message);
|
String stackTrace = Stream.of(Thread.currentThread().getStackTrace())
|
||||||
|
// just to get stack trace without TestResult and Thread
|
||||||
|
.filter(e -> !"TestResult.java".equals(e.getFileName()) &&
|
||||||
|
!"java.lang.Thread".equals(e.getClassName()))
|
||||||
|
.map(e -> "\tat " + e)
|
||||||
|
.collect(joining("\n"));
|
||||||
|
asserts.add(format("%s\n%s", message, stackTrace));
|
||||||
printf("[ASSERT] : %s\n", message);
|
printf("[ASSERT] : %s\n", message);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -138,6 +162,10 @@ public class TestResult extends TestBase {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public String getMessage() {
|
||||||
|
return (asserts.size() > 0 ? getAssertMessage() + "\n" : "") + getErrorMessage();
|
||||||
|
}
|
||||||
|
|
||||||
public String getAssertMessage() {
|
public String getAssertMessage() {
|
||||||
return asserts.stream()
|
return asserts.stream()
|
||||||
.map(failure -> "[ASSERT] : " + failure)
|
.map(failure -> "[ASSERT] : " + failure)
|
||||||
|
@ -146,8 +174,7 @@ public class TestResult extends TestBase {
|
||||||
|
|
||||||
public String getErrorMessage() {
|
public String getErrorMessage() {
|
||||||
return errors.stream()
|
return errors.stream()
|
||||||
.map(throwable ->
|
.map(throwable -> format("[ERROR] : %s", getStackTrace(throwable)))
|
||||||
format("[ERROR] : %s", getStackTrace(throwable)))
|
|
||||||
.collect(joining("\n"));
|
.collect(joining("\n"));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue