1 /* 2 * Copyright (c) 2014, 2016, 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 Testing InnerClasses_attribute of inner classes in local class. 28 * @library /tools/lib /tools/javac/lib ../lib 29 * @enablePreview 30 * @modules java.base/jdk.internal.classfile.impl 31 * jdk.compiler/com.sun.tools.javac.api 32 * jdk.compiler/com.sun.tools.javac.main 33 * @build toolbox.ToolBox InMemoryFileManager TestResult TestBase 34 * @build InnerClassesTestBase 35 * @run main InnerClassesInLocalClassTest 36 */ 37 38 import java.util.*; 39 40 public class InnerClassesInLocalClassTest extends InnerClassesTestBase { 41 42 private final static Modifier[] LOCAL_CLASS_MODIFIERS = 43 new Modifier[]{Modifier.EMPTY, Modifier.ABSTRACT, Modifier.FINAL}; 44 private final static String CLASS_TEMPLATE = 45 "public %CLASS% OuterClass {\n" + 46 "%SOURCE%\n" + 47 "}"; 48 49 private final List<Data> innerClassesData; 50 51 public InnerClassesInLocalClassTest() { 52 innerClassesData = new ArrayList<>(); 53 for (Modifier outerModifier : LOCAL_CLASS_MODIFIERS) { 54 StringBuilder sb = new StringBuilder(); 55 sb.append(outerModifier.getString()).append(' '); 56 sb.append("class Local {"); 57 Map<String, Set<String>> class2Flags = new HashMap<>(); 58 for (int i = 0; i < LOCAL_CLASS_MODIFIERS.length; ++i) { 59 Modifier innerModifier = LOCAL_CLASS_MODIFIERS[i]; 60 sb.append(innerModifier.getString()).append(' ') 61 .append("class").append(' ') 62 .append('A').append(i).append("{}\n"); 63 class2Flags.put("A" + i, getFlags(innerModifier)); 64 } 65 sb.append("};"); 66 class2Flags.put("1Local", getFlags(outerModifier)); 67 innerClassesData.add(new Data(sb.toString(), class2Flags)); 68 } 69 } 70 71 public static void main(String[] args) throws TestFailedException { 72 InnerClassesTestBase test = new InnerClassesInLocalClassTest(); 73 test.test("OuterClass$1Local", "1Local"); 74 } 75 76 @Override 77 public void setProperties() { 78 } 79 80 @Override 81 public List<TestCase> generateTestCases() { 82 List<TestCase> testCases = new ArrayList<>(); 83 testCases.addAll(localClassInClassMethod()); 84 testCases.addAll(localClassInInterfaceMethod()); 85 return testCases; 86 } 87 88 private List<TestCase> localClassInClassMethod() { 89 List<TestCase> list = new ArrayList<>(); 90 String template = CLASS_TEMPLATE.replace("%CLASS%", "class"); 91 list.addAll(lambda(template)); 92 list.addAll(constructor(template)); 93 list.addAll(method(template, 94 new Modifier[]{Modifier.EMPTY, Modifier.PRIVATE, Modifier.PROTECTED, Modifier.PUBLIC}, 95 new Modifier[]{Modifier.EMPTY, Modifier.FINAL, Modifier.STATIC})); 96 list.addAll(staticAndInstanceInitializer(template)); 97 return list; 98 } 99 100 private List<TestCase> localClassInInterfaceMethod() { 101 String template = CLASS_TEMPLATE.replace("%CLASS%", "interface"); 102 return method(template, 103 new Modifier[]{Modifier.EMPTY, Modifier.PUBLIC}, 104 new Modifier[]{Modifier.DEFAULT, Modifier.STATIC}); 105 } 106 107 private List<TestCase> generate(String template, String prefix, String suffix) { 108 List<TestCase> list = new ArrayList<>(); 109 for (Data data : innerClassesData) { 110 list.add(new TestCase(template.replace("%SOURCE%", 111 prefix + data.sources + suffix), 112 data.class2Flags)); 113 } 114 return list; 115 } 116 117 private List<TestCase> lambda(String template) { 118 return generate(template, "Runnable run = () -> {", "};"); 119 } 120 121 private List<TestCase> constructor(String template) { 122 List<TestCase> list = new ArrayList<>(); 123 for (Modifier modifier : 124 new Modifier[]{Modifier.EMPTY, Modifier.PRIVATE, Modifier.PROTECTED, Modifier.PUBLIC}) { 125 list.addAll(generate(template, modifier.getString() + " OuterClass() {", "}")); 126 } 127 return list; 128 } 129 130 private List<TestCase> method(String template, Modifier[] mods, Modifier[] otherMods) { 131 List<TestCase> list = new ArrayList<>(); 132 for (Modifier modifier : mods) { 133 for (Modifier otherMod : otherMods) { 134 list.addAll(generate(template, 135 String.format("%s %s void method() {", 136 modifier.getString(), 137 otherMod.getString()), 138 "}")); 139 } 140 } 141 return list; 142 } 143 144 private List<TestCase> staticAndInstanceInitializer(String template) { 145 List<TestCase> list = new ArrayList<>(); 146 for (Modifier modifier : new Modifier[]{Modifier.EMPTY, Modifier.STATIC}) { 147 list.addAll(generate(template, modifier.getString() + "{", "}")); 148 } 149 return list; 150 } 151 152 private Set<String> getFlags(Modifier modifier) { 153 HashSet<String> set = new HashSet<>(); 154 if (modifier != Modifier.EMPTY) { 155 set.add("ACC_" + modifier.getString().toUpperCase()); 156 } 157 return set; 158 } 159 160 /** 161 * Class represents part of sources which is inserted in other code. 162 */ 163 private static class Data { 164 public final String sources; 165 public final Map<String, Set<String>> class2Flags; 166 167 public Data(String sources, Map<String, Set<String>> class2Flags) { 168 this.sources = sources; 169 this.class2Flags = class2Flags; 170 } 171 } 172 }