1 /* 2 * Copyright (c) 2018, 2019, 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 8214031 27 * @summary Test the CharacterRangeTable generated for switch expressions 28 * @library /tools/lib 29 * @modules jdk.compiler/com.sun.tools.javac.api 30 * jdk.compiler/com.sun.tools.javac.main 31 * jdk.jdeps/com.sun.tools.javap 32 * @build toolbox.Assert toolbox.ToolBox toolbox.JavacTask 33 * @run main CRT 34 */ 35 36 37 import java.nio.file.Path; 38 import java.nio.file.Paths; 39 import java.util.stream.Collectors; 40 41 import toolbox.JavacTask; 42 import toolbox.JavapTask; 43 import toolbox.Task.OutputKind; 44 import toolbox.ToolBox; 45 46 public class CRT { main(String... args)47 public static void main(String... args) throws Exception { 48 new CRT().run(); 49 } 50 51 private static final String SOURCE_VERSION = Integer.toString(Runtime.version().feature()); 52 53 private ToolBox tb = new ToolBox(); 54 run()55 private void run() throws Exception { 56 doTest(" private String convert(int i) {\n" + 57 " String res;" + 58 " switch (i) {\n" + 59 " case 0: res = \"a\"; break;\n" + 60 " default: res = \"\"; break;\n" + 61 " };\n" + 62 " return res;\n" + 63 " }\n", 64 "CharacterRangeTable:\n" + 65 " 0, 0, c24, c25, 8 // 0, 0, 3:36, 3:37, flow-controller\n" + 66 " 20, 22, 1015, 101f, 1 // 20, 22, 4:21, 4:31, statement\n" + 67 " 23, 25, 1020, 1026, 1 // 23, 25, 4:32, 4:38, statement\n" + 68 " 20, 25, 1015, 1026, 10 // 20, 25, 4:21, 4:38, flow-target\n" + 69 " 26, 28, 1416, 141f, 1 // 26, 28, 5:22, 5:31, statement\n" + 70 " 29, 31, 1420, 1426, 1 // 29, 31, 5:32, 5:38, statement\n" + 71 " 26, 31, 1416, 1426, 10 // 26, 31, 5:22, 5:38, flow-target\n" + 72 " 0, 31, c1c, 180a, 1 // 0, 31, 3:28, 6:10, statement\n" + 73 " 32, 33, 1c09, 1c14, 1 // 32, 33, 7:09, 7:20, statement\n" + 74 " 0, 33, 823, 2006, 2 // 0, 33, 2:35, 8:06, block\n"); 75 doTest(" private String convert(int i) {\n" + 76 " return switch (i) {\n" + 77 " case 0 -> \"a\";\n" + 78 " default -> \"\";\n" + 79 " };\n" + 80 " }\n", 81 "CharacterRangeTable:\n" + 82 " 0, 0, c18, c19, 8 // 0, 0, 3:24, 3:25, flow-controller\n" + 83 " 20, 24, 1017, 101b, 11 // 20, 24, 4:23, 4:27, statement, flow-target\n" + 84 " 25, 29, 1418, 141b, 11 // 25, 29, 5:24, 5:27, statement, flow-target\n" + 85 " 0, 30, c09, 180b, 1 // 0, 30, 3:09, 6:11, statement\n" + 86 " 0, 30, 823, 1c06, 2 // 0, 30, 2:35, 7:06, block"); 87 doTest(" private boolean convert(int i) {\n" + 88 " return switch (i) {\n" + 89 " case 0 -> true;\n" + 90 " default -> false;\n" + 91 " } && i == 0;\n" + 92 " }\n", 93 "CharacterRangeTable:\n" + 94 " 0, 0, c18, c19, 8 // 0, 0, 3:24, 3:25, flow-controller\n" + 95 " 20, 22, 1017, 101c, 11 // 20, 22, 4:23, 4:28, statement, flow-target\n" + 96 " 23, 25, 1418, 141e, 11 // 23, 25, 5:24, 5:30, statement, flow-target\n" + 97 " 0, 25, c10, 180a, 8 // 0, 25, 3:16, 6:10, flow-controller\n" + 98 " 26, 26, 180e, 1814, 10 // 26, 26, 6:14, 6:20, flow-target\n" + 99 " 0, 35, c09, 1815, 1 // 0, 35, 3:09, 6:21, statement\n" + 100 " 0, 35, 824, 1c06, 2 // 0, 35, 2:36, 7:06, block\n"); 101 doTest(" private boolean convert(int i) {\n" + 102 " return i >= 0 ? i == 0\n" + 103 " ? true\n" + 104 " : false\n" + 105 " : i == -1\n" + 106 " ? false\n" + 107 " : true;\n" + 108 " }\n", 109 "CharacterRangeTable:\n" + 110 " 0, 0, c10, c16, 8 // 0, 0, 3:16, 3:22, flow-controller\n" + 111 " 1, 3, c10, c16, 100 // 1, 3, 3:16, 3:22, branch-false\n" + 112 " 4, 4, c19, c1f, 8 // 4, 4, 3:25, 3:31, flow-controller\n" + 113 " 5, 7, c19, c1f, 100 // 5, 7, 3:25, 3:31, branch-false\n" + 114 " 8, 8, 101b, 101f, 10 // 8, 8, 4:27, 4:31, flow-target\n" + 115 " 12, 12, 141b, 1420, 10 // 12, 12, 5:27, 5:32, flow-target\n" + 116 " 4, 12, c19, 1420, 10 // 4, 12, 3:25, 5:32, flow-target\n" + 117 " 16, 17, 1819, 1820, 8 // 16, 17, 6:25, 6:32, flow-controller\n" + 118 " 18, 20, 1819, 1820, 100 // 18, 20, 6:25, 6:32, branch-false\n" + 119 " 21, 21, 1c1b, 1c20, 10 // 21, 21, 7:27, 7:32, flow-target\n" + 120 " 25, 25, 201b, 201f, 10 // 25, 25, 8:27, 8:31, flow-target\n" + 121 " 16, 25, 1819, 201f, 10 // 16, 25, 6:25, 8:31, flow-target\n" + 122 " 0, 26, c09, 2020, 1 // 0, 26, 3:09, 8:32, statement\n" + 123 " 0, 26, 824, 2406, 2 // 0, 26, 2:36, 9:06, block\n"); 124 doTest(" private boolean convert(int i) {\n" + 125 " return i >= 0 ? switch (i) {\n" + 126 " case 0 -> true;\n" + 127 " default -> false;\n" + 128 " } : switch (i) {\n" + 129 " case -1 -> false;\n" + 130 " default -> true;\n" + 131 " };\n" + 132 " }\n", 133 "CharacterRangeTable:\n" + 134 " 0, 0, c10, c16, 8 // 0, 0, 3:16, 3:22, flow-controller\n" + 135 " 1, 3, c10, c16, 100 // 1, 3, 3:16, 3:22, branch-false\n" + 136 " 4, 4, c21, c22, 8 // 4, 4, 3:33, 3:34, flow-controller\n" + 137 " 24, 27, 1017, 101c, 11 // 24, 27, 4:23, 4:28, statement, flow-target\n" + 138 " 28, 31, 1418, 141e, 11 // 28, 31, 5:24, 5:30, statement, flow-target\n" + 139 " 4, 31, c19, 180a, 10 // 4, 31, 3:25, 6:10, flow-target\n" + 140 " 35, 35, 1815, 1816, 8 // 35, 35, 6:21, 6:22, flow-controller\n" + 141 " 56, 59, 1c18, 1c1e, 11 // 56, 59, 7:24, 7:30, statement, flow-target\n" + 142 " 60, 63, 2018, 201d, 11 // 60, 63, 8:24, 8:29, statement, flow-target\n" + 143 " 35, 63, 180d, 240a, 10 // 35, 63, 6:13, 9:10, flow-target\n" + 144 " 0, 64, c09, 240b, 1 // 0, 64, 3:09, 9:11, statement\n" + 145 " 0, 64, 824, 2806, 2 // 0, 64, 2:36, 10:06, block\n"); 146 } 147 doTest(String code, String expected)148 private void doTest(String code, String expected) throws Exception { 149 Path base = Paths.get("."); 150 Path classes = base.resolve("classes"); 151 tb.createDirectories(classes); 152 tb.cleanDirectory(classes); 153 new JavacTask(tb) 154 .options("-Xjcov") 155 .outdir(classes) 156 .sources("public class Test {\n" + 157 code + 158 "}\n") 159 .run() 160 .writeAll(); 161 String out = new JavapTask(tb) 162 .options("-private", 163 "-verbose", 164 "-s") 165 .classpath(classes.toString()) 166 .classes("Test") 167 .run() 168 .writeAll() 169 .getOutputLines(OutputKind.DIRECT) 170 .stream() 171 .collect(Collectors.joining("\n")); 172 String crt = cutCRT(out); 173 if (!expected.trim().equals(crt.trim())) { 174 throw new AssertionError("Expected CharacterRangeTable not found, found: " + crt); 175 } 176 } 177 cutCRT(String from)178 private static String cutCRT(String from) { 179 int start = from.indexOf("CharacterRangeTable:", from.indexOf("convert(int);")); 180 int end = from.indexOf("StackMapTable:"); 181 return from.substring(start, end); 182 } 183 184 } 185