23b83c518d
Reviewed-by: jjg
229 lines
13 KiB
Java
229 lines
13 KiB
Java
/*
|
|
* Copyright (c) 2018, 2019, 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 8214031
|
|
* @summary Test the CharacterRangeTable generated for switch expressions
|
|
* @library /tools/lib
|
|
* @modules jdk.compiler/com.sun.tools.javac.api
|
|
* jdk.compiler/com.sun.tools.javac.main
|
|
* jdk.jdeps/com.sun.tools.javap
|
|
* @build toolbox.Assert toolbox.ToolBox toolbox.JavacTask
|
|
* @run main CRT
|
|
*/
|
|
|
|
|
|
import java.nio.file.Path;
|
|
import java.nio.file.Paths;
|
|
import java.util.stream.Collectors;
|
|
|
|
import toolbox.JavacTask;
|
|
import toolbox.JavapTask;
|
|
import toolbox.Task.OutputKind;
|
|
import toolbox.ToolBox;
|
|
|
|
public class CRT {
|
|
public static void main(String... args) throws Exception {
|
|
new CRT().run();
|
|
}
|
|
|
|
private static final String SOURCE_VERSION = Integer.toString(Runtime.version().feature());
|
|
|
|
private ToolBox tb = new ToolBox();
|
|
|
|
private void run() throws Exception {
|
|
doTest(" private String convert(int i) {\n" +
|
|
" String res;" +
|
|
" switch (i) {\n" +
|
|
" case 0: res = \"a\"; break;\n" +
|
|
" default: res = \"\"; break;\n" +
|
|
" };\n" +
|
|
" return res;\n" +
|
|
" }\n",
|
|
"CharacterRangeTable:\n" +
|
|
" 0, 0, c24, c25, 8 // 0, 0, 3:36, 3:37, flow-controller\n" +
|
|
" 20, 22, 1015, 101f, 1 // 20, 22, 4:21, 4:31, statement\n" +
|
|
" 23, 25, 1020, 1026, 1 // 23, 25, 4:32, 4:38, statement\n" +
|
|
" 20, 25, 1015, 1026, 10 // 20, 25, 4:21, 4:38, flow-target\n" +
|
|
" 26, 28, 1416, 141f, 1 // 26, 28, 5:22, 5:31, statement\n" +
|
|
" 29, 31, 1420, 1426, 1 // 29, 31, 5:32, 5:38, statement\n" +
|
|
" 26, 31, 1416, 1426, 10 // 26, 31, 5:22, 5:38, flow-target\n" +
|
|
" 0, 31, c1c, 180a, 1 // 0, 31, 3:28, 6:10, statement\n" +
|
|
" 32, 33, 1c09, 1c14, 1 // 32, 33, 7:09, 7:20, statement\n" +
|
|
" 0, 33, 823, 2006, 2 // 0, 33, 2:35, 8:06, block\n");
|
|
doTest(" private String convert(int i) {\n" +
|
|
" return switch (i) {\n" +
|
|
" case 0 -> \"a\";\n" +
|
|
" default -> \"\";\n" +
|
|
" };\n" +
|
|
" }\n",
|
|
"CharacterRangeTable:\n" +
|
|
" 0, 0, c18, c19, 8 // 0, 0, 3:24, 3:25, flow-controller\n" +
|
|
" 20, 24, 1017, 101b, 11 // 20, 24, 4:23, 4:27, statement, flow-target\n" +
|
|
" 25, 29, 1418, 141b, 11 // 25, 29, 5:24, 5:27, statement, flow-target\n" +
|
|
" 0, 30, c09, 180b, 1 // 0, 30, 3:09, 6:11, statement\n" +
|
|
" 0, 30, 823, 1c06, 2 // 0, 30, 2:35, 7:06, block");
|
|
doTest(" private boolean convert(int i) {\n" +
|
|
" return switch (i) {\n" +
|
|
" case 0 -> true;\n" +
|
|
" default -> false;\n" +
|
|
" } && i == 0;\n" +
|
|
" }\n",
|
|
"CharacterRangeTable:\n" +
|
|
" 0, 0, c18, c19, 8 // 0, 0, 3:24, 3:25, flow-controller\n" +
|
|
" 20, 22, 1017, 101c, 11 // 20, 22, 4:23, 4:28, statement, flow-target\n" +
|
|
" 23, 25, 1418, 141e, 11 // 23, 25, 5:24, 5:30, statement, flow-target\n" +
|
|
" 0, 25, c10, 180a, 8 // 0, 25, 3:16, 6:10, flow-controller\n" +
|
|
" 26, 26, 180e, 1814, 10 // 26, 26, 6:14, 6:20, flow-target\n" +
|
|
" 0, 35, c09, 1815, 1 // 0, 35, 3:09, 6:21, statement\n" +
|
|
" 0, 35, 824, 1c06, 2 // 0, 35, 2:36, 7:06, block\n");
|
|
doTest(" private boolean convert(int i) {\n" +
|
|
" return i >= 0 ? i == 0\n" +
|
|
" ? true\n" +
|
|
" : false\n" +
|
|
" : i == -1\n" +
|
|
" ? false\n" +
|
|
" : true;\n" +
|
|
" }\n",
|
|
"CharacterRangeTable:\n" +
|
|
" 0, 0, c10, c16, 8 // 0, 0, 3:16, 3:22, flow-controller\n" +
|
|
" 1, 3, c10, c16, 100 // 1, 3, 3:16, 3:22, branch-false\n" +
|
|
" 4, 4, c19, c1f, 8 // 4, 4, 3:25, 3:31, flow-controller\n" +
|
|
" 5, 7, c19, c1f, 100 // 5, 7, 3:25, 3:31, branch-false\n" +
|
|
" 8, 8, 101b, 101f, 10 // 8, 8, 4:27, 4:31, flow-target\n" +
|
|
" 12, 12, 141b, 1420, 10 // 12, 12, 5:27, 5:32, flow-target\n" +
|
|
" 4, 12, c19, 1420, 10 // 4, 12, 3:25, 5:32, flow-target\n" +
|
|
" 16, 17, 1819, 1820, 8 // 16, 17, 6:25, 6:32, flow-controller\n" +
|
|
" 18, 20, 1819, 1820, 100 // 18, 20, 6:25, 6:32, branch-false\n" +
|
|
" 21, 21, 1c1b, 1c20, 10 // 21, 21, 7:27, 7:32, flow-target\n" +
|
|
" 25, 25, 201b, 201f, 10 // 25, 25, 8:27, 8:31, flow-target\n" +
|
|
" 16, 25, 1819, 201f, 10 // 16, 25, 6:25, 8:31, flow-target\n" +
|
|
" 0, 26, c09, 2020, 1 // 0, 26, 3:09, 8:32, statement\n" +
|
|
" 0, 26, 824, 2406, 2 // 0, 26, 2:36, 9:06, block\n");
|
|
doTest(" private boolean convert(int i) {\n" +
|
|
" return i >= 0 ? switch (i) {\n" +
|
|
" case 0 -> true;\n" +
|
|
" default -> false;\n" +
|
|
" } : switch (i) {\n" +
|
|
" case -1 -> false;\n" +
|
|
" default -> true;\n" +
|
|
" };\n" +
|
|
" }\n",
|
|
"CharacterRangeTable:\n" +
|
|
" 0, 0, c10, c16, 8 // 0, 0, 3:16, 3:22, flow-controller\n" +
|
|
" 1, 3, c10, c16, 100 // 1, 3, 3:16, 3:22, branch-false\n" +
|
|
" 4, 4, c21, c22, 8 // 4, 4, 3:33, 3:34, flow-controller\n" +
|
|
" 24, 27, 1017, 101c, 11 // 24, 27, 4:23, 4:28, statement, flow-target\n" +
|
|
" 28, 31, 1418, 141e, 11 // 28, 31, 5:24, 5:30, statement, flow-target\n" +
|
|
" 4, 31, c19, 180a, 10 // 4, 31, 3:25, 6:10, flow-target\n" +
|
|
" 35, 35, 1815, 1816, 8 // 35, 35, 6:21, 6:22, flow-controller\n" +
|
|
" 56, 59, 1c18, 1c1e, 11 // 56, 59, 7:24, 7:30, statement, flow-target\n" +
|
|
" 60, 63, 2018, 201d, 11 // 60, 63, 8:24, 8:29, statement, flow-target\n" +
|
|
" 35, 63, 180d, 240a, 10 // 35, 63, 6:13, 9:10, flow-target\n" +
|
|
" 0, 64, c09, 240b, 1 // 0, 64, 3:09, 9:11, statement\n" +
|
|
" 0, 64, 824, 2806, 2 // 0, 64, 2:36, 10:06, block\n");
|
|
doTest(
|
|
"""
|
|
private boolean convert(int i) {
|
|
return switch (i) {
|
|
default -> (i < 256) ? true : false;
|
|
};
|
|
}
|
|
""",
|
|
"""
|
|
CharacterRangeTable:
|
|
0, 0, c14, c15, 8 // 0, 0, 3:20, 3:21, flow-controller
|
|
12, 15, 1014, 101d, 8 // 12, 15, 4:20, 4:29, flow-controller
|
|
16, 18, 1014, 101d, 100 // 16, 18, 4:20, 4:29, branch-false
|
|
19, 19, 1020, 1024, 10 // 19, 19, 4:32, 4:36, flow-target
|
|
23, 23, 1027, 102c, 10 // 23, 23, 4:39, 4:44, flow-target
|
|
12, 26, 1014, 102d, 11 // 12, 26, 4:20, 4:45, statement, flow-target
|
|
0, 27, c05, 1407, 1 // 0, 27, 3:05, 5:07, statement
|
|
0, 27, 820, 1802, 2 // 0, 27, 2:32, 6:02, block
|
|
"""
|
|
);
|
|
doTest(
|
|
"""
|
|
private boolean convert(int i) {
|
|
return switch (i) {
|
|
case 1 -> switch (Integer.toString(i)) {
|
|
case "1" -> true;
|
|
default -> throw new IllegalStateException("failure");
|
|
};
|
|
default -> throw new IllegalStateException("failure");
|
|
};
|
|
}
|
|
""",
|
|
"""
|
|
CharacterRangeTable:
|
|
0, 0, c14, c15, 8 // 0, 0, 3:20, 3:21, flow-controller
|
|
20, 24, 1013, 102f, 1 // 20, 24, 4:19, 4:47, statement
|
|
80, 83, 1419, 141e, 11 // 80, 83, 5:25, 5:30, statement, flow-target
|
|
84, 93, 1818, 1843, 11 // 84, 93, 6:24, 6:67, statement, flow-target
|
|
20, 96, 1013, 1c0b, 11 // 20, 96, 4:19, 7:11, statement, flow-target
|
|
97, 106, 2014, 203f, 11 // 97, 106, 8:20, 8:63, statement, flow-target
|
|
0, 107, c05, 2407, 1 // 0, 107, 3:05, 9:07, statement
|
|
0, 107, 820, 2802, 2 // 0, 107, 2:32, 10:02, block
|
|
"""
|
|
);
|
|
}
|
|
|
|
private void doTest(String code, String expected) throws Exception {
|
|
Path base = Paths.get(".");
|
|
Path classes = base.resolve("classes");
|
|
tb.createDirectories(classes);
|
|
tb.cleanDirectory(classes);
|
|
new JavacTask(tb)
|
|
.options("-Xjcov")
|
|
.outdir(classes)
|
|
.sources("public class Test {\n" +
|
|
code +
|
|
"}\n")
|
|
.run()
|
|
.writeAll();
|
|
String out = new JavapTask(tb)
|
|
.options("-private",
|
|
"-verbose",
|
|
"-s")
|
|
.classpath(classes.toString())
|
|
.classes("Test")
|
|
.run()
|
|
.writeAll()
|
|
.getOutputLines(OutputKind.DIRECT)
|
|
.stream()
|
|
.collect(Collectors.joining("\n"));
|
|
String crt = cutCRT(out);
|
|
if (!expected.trim().equals(crt.trim())) {
|
|
throw new AssertionError("Expected CharacterRangeTable not found, found: " + crt);
|
|
}
|
|
}
|
|
|
|
private static String cutCRT(String from) {
|
|
int start = from.indexOf("CharacterRangeTable:", from.indexOf("convert(int);"));
|
|
int end = from.indexOf("StackMapTable:");
|
|
return from.substring(start, end);
|
|
}
|
|
|
|
}
|