1 /* 2 * Copyright (c) 2022, 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 8278834 27 * @summary Verify pattern matching nested inside initializers of classes nested in methods 28 * works correctly. 29 * @enablePreview 30 * @library /tools/lib /tools/javac/lib 31 * @modules 32 * jdk.compiler/com.sun.tools.javac.api 33 * jdk.compiler/com.sun.tools.javac.file 34 * jdk.compiler/com.sun.tools.javac.main 35 * jdk.compiler/com.sun.tools.javac.util 36 * @build toolbox.ToolBox toolbox.JavacTask 37 * @build combo.ComboTestHelper 38 * @compile BindingsInitializer.java 39 * @run main BindingsInitializer 40 */ 41 42 import combo.ComboInstance; 43 import combo.ComboParameter; 44 import combo.ComboTask; 45 import combo.ComboTestHelper; 46 import java.nio.file.Path; 47 import java.nio.file.Paths; 48 import toolbox.ToolBox; 49 50 public class BindingsInitializer extends ComboInstance<BindingsInitializer> { 51 protected ToolBox tb; 52 53 BindingsInitializer() { 54 super(); 55 tb = new ToolBox(); 56 } 57 58 public static void main(String... args) throws Exception { 59 new ComboTestHelper<BindingsInitializer>() 60 .withDimension("OUTER", (x, outer) -> x.outer = outer, Outer.values()) 61 .withDimension("MIDDLE", (x, middle) -> x.middle = middle, Middle.values()) 62 .withDimension("INNER", (x, inner) -> x.inner = inner, Inner.values()) 63 .withDimension("TEST", (x, test) -> x.test = test, Test.values()) 64 .run(BindingsInitializer::new); 65 } 66 67 private Outer outer; 68 private Middle middle; 69 private Inner inner; 70 private Test test; 71 72 private static final String MAIN_TEMPLATE = 73 """ 74 public class Test { 75 private static Object obj = ""; 76 #{OUTER} 77 } 78 """; 79 80 @Override 81 protected void doWork() throws Throwable { 82 Path base = Paths.get("."); 83 84 ComboTask task = newCompilationTask() 85 .withSourceFromTemplate(MAIN_TEMPLATE, pname -> switch (pname) { 86 case "OUTER" -> outer; 87 case "MIDDLE" -> middle; 88 case "INNER" -> inner; 89 case "TESST" -> test; 90 default -> throw new UnsupportedOperationException(pname); 91 }); 92 93 task.generate(result -> { 94 if (result.hasErrors()) { 95 throw new AssertionError("Unexpected result: " + result.compilationInfo()); 96 } 97 }); 98 } 99 100 public enum Outer implements ComboParameter { 101 NONE("#{MIDDLE}"), 102 STATIC_CLASS("static class Nested { #{MIDDLE} }"), 103 CLASS("class Inner { #{MIDDLE} }"); 104 private final String code; 105 106 private Outer(String code) { 107 this.code = code; 108 } 109 110 @Override 111 public String expand(String optParameter) { 112 return code; 113 } 114 } 115 116 public enum Middle implements ComboParameter { 117 STATIC_INIT("static { #{INNER} }"), 118 INIT("{ #{INNER} }"), 119 METHOD("void test() { #{INNER} }"); 120 private final String code; 121 122 private Middle(String code) { 123 this.code = code; 124 } 125 126 @Override 127 public String expand(String optParameter) { 128 return code; 129 } 130 } 131 132 public enum Inner implements ComboParameter { 133 DIRECT("#{TEST}"), 134 CLASS_STATIC_INIT("class C { static { #{TEST} } }"), 135 CLASS_INIT("class C { { #{TEST} } }"), 136 CLASS_METHOD("class C { void t() { #{TEST} } }"), 137 ANNONYMOUS_CLASS_STATIC_INIT("new Object() { static { #{TEST} } };"), 138 ANNONYMOUS_CLASS_INIT("new Object() { { #{TEST} } };"), 139 ANNONYMOUS_CLASS_METHOD("new Object() { void t() { #{TEST} } };"); 140 private final String code; 141 142 private Inner(String code) { 143 this.code = code; 144 } 145 146 @Override 147 public String expand(String optParameter) { 148 return code; 149 } 150 } 151 152 public enum Test implements ComboParameter { 153 TEST("if (obj instanceof String str) System.err.println(str);"); 154 private final String code; 155 156 private Test(String code) { 157 this.code = code; 158 } 159 160 @Override 161 public String expand(String optParameter) { 162 return code; 163 } 164 } 165 }