InnerClassesIndexTest.java revision 2942:08092deced3f
1/*
2 * Copyright (c) 2014, 2015, Oracle and/or its affiliates. All rights reserved.
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 *
5 * This code is free software; you can redistribute it and/or modify it
6 * under the terms of the GNU General Public License version 2 only, as
7 * published by the Free Software Foundation.
8 *
9 * This code is distributed in the hope that it will be useful, but WITHOUT
10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11 * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
12 * version 2 for more details (a copy is included in the LICENSE file that
13 * accompanied this code).
14 *
15 * You should have received a copy of the GNU General Public License version
16 * 2 along with this work; if not, write to the Free Software Foundation,
17 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
18 *
19 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
20 * or visit www.oracle.com if you need additional information or have any
21 * questions.
22 */
23
24/*
25 * @test
26 * @bug 8042251
27 * @summary Test that outer_class_info_index of local and anonymous class is zero.
28 * @library /tools/lib /tools/javac/lib ../lib
29 * @modules jdk.jdeps/com.sun.tools.classfile
30 *          jdk.compiler/com.sun.tools.javac.api
31 *          jdk.compiler/com.sun.tools.javac.file
32 *          jdk.compiler/com.sun.tools.javac.main
33 * @build TestBase TestResult InMemoryFileManager ToolBox
34 * @run main InnerClassesIndexTest
35 */
36
37import java.io.File;
38import java.io.FilenameFilter;
39import java.util.HashSet;
40import java.util.Set;
41import java.util.stream.Collectors;
42import java.util.stream.Stream;
43
44import com.sun.tools.classfile.Attribute;
45import com.sun.tools.classfile.ClassFile;
46import com.sun.tools.classfile.InnerClasses_attribute;
47import com.sun.tools.classfile.InnerClasses_attribute.Info;
48
49public class InnerClassesIndexTest extends TestResult {
50
51    public static void main(String[] args) throws TestFailedException {
52        new InnerClassesIndexTest().test();
53    }
54
55    private boolean isExcluded(String className) {
56        return !className.startsWith(InnerClassesIndexTest.class.getName())
57                || "InnerClassesIndexTest$Inner".equals(className);
58    }
59
60    private Set<String> getInnerClasses() {
61        FilenameFilter filter = (dir, name) -> name.matches("InnerClassesIndexTest\\$.*\\.class");
62        return Stream.of(getClassDir().listFiles(filter))
63                .map(File::getName)
64                .map(s -> s.replace(".class", ""))
65                .collect(Collectors.toSet());
66    }
67
68    public void test() throws TestFailedException {
69        try {
70            addTestCase("Source is InnerClassesIndexTest.java");
71            ClassFile classFile = readClassFile(InnerClassesIndexTest.class);
72            InnerClasses_attribute attr = (InnerClasses_attribute)
73                    classFile.getAttribute(Attribute.InnerClasses);
74
75            Set<String> foundClasses = new HashSet<>();
76            for (Info info : attr.classes) {
77                String innerName = classFile.constant_pool.
78                        getClassInfo(info.inner_class_info_index).getBaseName();
79                echo("Testing class : " + innerName);
80                if (isExcluded(innerName)) {
81                    echo("Ignored : " + innerName);
82                    continue;
83                }
84                foundClasses.add(innerName);
85                checkEquals(info.outer_class_info_index, 0,
86                        "outer_class_info_index of " + innerName);
87                if (innerName.matches("\\$\\d+")) {
88                    checkEquals(info.inner_name_index, 0,
89                            "inner_name_index of anonymous class");
90                }
91            }
92            Set<String> expectedClasses = getInnerClasses();
93            expectedClasses.remove("InnerClassesIndexTest$Inner");
94            checkEquals(foundClasses, expectedClasses, "All classes are found");
95        } catch (Exception e) {
96            addFailure(e);
97        } finally {
98            checkStatus();
99        }
100    }
101
102    static class Inner {
103    }
104
105    Inner inner1 = new Inner() {
106    };
107
108    static Inner inner2 = new Inner() {
109    };
110
111    Runnable r = () -> {
112        class Local {
113        }
114        new Local() {
115        };
116    };
117
118    public void local() {
119        class Local {
120        }
121        new Local() {
122        };
123    }
124
125    public InnerClassesIndexTest() {
126        class Local {
127        }
128        new Local() {
129        };
130    }
131
132    {
133        class Local {
134        }
135        new Local() {
136        };
137    }
138
139    static {
140        class Local {
141        }
142        new Local() {
143        };
144    }
145}
146