65 import java.lang.annotation.Retention;
66 import java.lang.annotation.RetentionPolicy;
67 import java.lang.annotation.Target;
68 import java.lang.reflect.Method;
69 import java.net.URI;
70 import java.util.ArrayList;
71 import java.util.Arrays;
72 import java.util.LinkedList;
73 import java.util.List;
74 import java.util.regex.Pattern;
75 import javax.lang.model.type.TypeKind;
76 import javax.tools.Diagnostic;
77 import javax.tools.DiagnosticCollector;
78 import javax.tools.DiagnosticListener;
79 import javax.tools.JavaCompiler;
80 import javax.tools.JavaFileManager;
81 import javax.tools.JavaFileObject;
82 import javax.tools.SimpleJavaFileObject;
83 import javax.tools.ToolProvider;
84
85 public class JavacParserTest extends TestCase {
86 static final JavaCompiler tool = ToolProvider.getSystemJavaCompiler();
87 static final JavaFileManager fm = tool.getStandardFileManager(null, null, null);
88
89 private JavacParserTest(){}
90
91 public static void main(String... args) throws Exception {
92 try {
93 new JavacParserTest().run(args);
94 } finally {
95 fm.close();
96 }
97 }
98
99 class MyFileObject extends SimpleJavaFileObject {
100
101 private String text;
102
103 public MyFileObject(String text) {
104 super(URI.create("myfo:/Test.java"), JavaFileObject.Kind.SOURCE);
1017 Arrays.asList("-XDrawDiagnostics"), null, Arrays.asList(new MyFileObject(code)));
1018
1019 Iterable<? extends CompilationUnitTree> cuts = ct.parse();
1020 boolean[] foundVar = new boolean[1];
1021
1022 new TreePathScanner<Void, Void>() {
1023 @Override public Void visitVariable(VariableTree vt, Void p) {
1024 assertNotNull(vt.getModifiers());
1025 assertNotNull(vt.getType());
1026 assertNotNull(vt.getName());
1027 assertEquals("name should be <error>", "<error>", vt.getName().toString());
1028 foundVar[0] = true;
1029 return super.visitVariable(vt, p);
1030 }
1031 }.scan(cuts, null);
1032
1033 if (!foundVar[0]) {
1034 fail("haven't found a variable");
1035 }
1036
1037 String actualErrors = normalize(out.toString());
1038 assertEquals("the error message is not correct, actual: " + actualErrors, expectedErrors, actualErrors);
1039 }
1040
1041 @Test
1042 void testTypeParamsWithoutMethod() throws IOException {
1043 assert tool != null;
1044
1045 String code = "package test; class Test { /**javadoc*/ |public <T> |}";
1046 String[] parts = code.split("\\|");
1047
1048 code = parts[0] + parts[1] + parts[2];
1049
1050 JavacTaskImpl ct = (JavacTaskImpl) tool.getTask(null, fm, null, null,
1051 null, Arrays.asList(new MyFileObject(code)));
1052 Trees trees = Trees.instance(ct);
1053 SourcePositions pos = trees.getSourcePositions();
1054 CompilationUnitTree cut = ct.parse().iterator().next();
1055 ClassTree clazz = (ClassTree) cut.getTypeDecls().get(0);
1056 ErroneousTree err = (ErroneousTree) clazz.getMembers().get(0);
|
65 import java.lang.annotation.Retention;
66 import java.lang.annotation.RetentionPolicy;
67 import java.lang.annotation.Target;
68 import java.lang.reflect.Method;
69 import java.net.URI;
70 import java.util.ArrayList;
71 import java.util.Arrays;
72 import java.util.LinkedList;
73 import java.util.List;
74 import java.util.regex.Pattern;
75 import javax.lang.model.type.TypeKind;
76 import javax.tools.Diagnostic;
77 import javax.tools.DiagnosticCollector;
78 import javax.tools.DiagnosticListener;
79 import javax.tools.JavaCompiler;
80 import javax.tools.JavaFileManager;
81 import javax.tools.JavaFileObject;
82 import javax.tools.SimpleJavaFileObject;
83 import javax.tools.ToolProvider;
84
85 import com.sun.source.tree.CaseTree;
86 import com.sun.source.util.TreePathScanner;
87
88 public class JavacParserTest extends TestCase {
89 static final JavaCompiler tool = ToolProvider.getSystemJavaCompiler();
90 static final JavaFileManager fm = tool.getStandardFileManager(null, null, null);
91
92 private JavacParserTest(){}
93
94 public static void main(String... args) throws Exception {
95 try {
96 new JavacParserTest().run(args);
97 } finally {
98 fm.close();
99 }
100 }
101
102 class MyFileObject extends SimpleJavaFileObject {
103
104 private String text;
105
106 public MyFileObject(String text) {
107 super(URI.create("myfo:/Test.java"), JavaFileObject.Kind.SOURCE);
1020 Arrays.asList("-XDrawDiagnostics"), null, Arrays.asList(new MyFileObject(code)));
1021
1022 Iterable<? extends CompilationUnitTree> cuts = ct.parse();
1023 boolean[] foundVar = new boolean[1];
1024
1025 new TreePathScanner<Void, Void>() {
1026 @Override public Void visitVariable(VariableTree vt, Void p) {
1027 assertNotNull(vt.getModifiers());
1028 assertNotNull(vt.getType());
1029 assertNotNull(vt.getName());
1030 assertEquals("name should be <error>", "<error>", vt.getName().toString());
1031 foundVar[0] = true;
1032 return super.visitVariable(vt, p);
1033 }
1034 }.scan(cuts, null);
1035
1036 if (!foundVar[0]) {
1037 fail("haven't found a variable");
1038 }
1039
1040 String actualErrors = normalize(out.toString());
1041 assertEquals("the error message is not correct, actual: " + actualErrors, expectedErrors, actualErrors);
1042 }
1043
1044 @Test
1045 void testCaseBodyStatements() throws IOException {
1046 String code = "class C {" +
1047 " void t(int i) {" +
1048 " switch (i) {" +
1049 " case 0 -> i++;" +
1050 " case 1 -> { i++; }" +
1051 " case 2 -> throw new RuntimeException();" +
1052 " case 3 -> if (true) ;" +
1053 " default -> i++;" +
1054 " }" +
1055 " switch (i) {" +
1056 " case 0: i++; break;" +
1057 " case 1: { i++; break;}" +
1058 " case 2: throw new RuntimeException();" +
1059 " case 3: if (true) ; break;" +
1060 " default: i++; break;" +
1061 " }" +
1062 " int j = switch (i) {" +
1063 " case 0 -> i + 1;" +
1064 " case 1 -> { break i + 1; }" +
1065 " default -> throw new RuntimeException();" +
1066 " };" +
1067 " int k = switch (i) {" +
1068 " case 0: break i + 1;" +
1069 " case 1: { break i + 1; }" +
1070 " default: throw new RuntimeException();" +
1071 " };" +
1072 " }" +
1073 "}";
1074 String expectedErrors = "Test.java:1:178: compiler.err.switch.case.unexpected.statement\n";
1075 StringWriter out = new StringWriter();
1076 JavacTaskImpl ct = (JavacTaskImpl) tool.getTask(out, fm, null,
1077 Arrays.asList("-XDrawDiagnostics", "--enable-preview", "-source", "12"),
1078 null, Arrays.asList(new MyFileObject(code)));
1079
1080 CompilationUnitTree cut = ct.parse().iterator().next();
1081 Trees trees = Trees.instance(ct);
1082 List<String> spans = new ArrayList<>();
1083
1084 new TreePathScanner<Void, Void>() {
1085 @Override
1086 public Void visitCase(CaseTree tree, Void v) {
1087 if (tree.getBody() != null) {
1088 int start = (int) trees.getSourcePositions().getStartPosition(cut, tree.getBody());
1089 int end = (int) trees.getSourcePositions().getEndPosition(cut, tree.getBody());
1090 spans.add(code.substring(start, end));
1091 } else {
1092 spans.add("<null>");
1093 }
1094 return super.visitCase(tree, v);
1095 }
1096 }.scan(cut, null);
1097
1098 List<String> expectedSpans = List.of(
1099 "i++;", "{ i++; }", "throw new RuntimeException();", "if (true) ;", "i++;",
1100 "<null>", "<null>", "<null>", "<null>", "<null>",
1101 "i + 1"/*TODO semicolon?*/, "{ break i + 1; }", "throw new RuntimeException();",
1102 "<null>", "<null>", "<null>");
1103 assertEquals("the error spans are not correct; actual:" + spans, expectedSpans, spans);
1104 String toString = cut.toString();
1105 String expectedToString =
1106 "\n" +
1107 "class C {\n" +
1108 " \n" +
1109 " void t(int i) {\n" +
1110 " switch (i) {\n" +
1111 " case 0 -> i++;\n" +
1112 " case 1 -> {\n" +
1113 " i++;\n" +
1114 " }\n" +
1115 " case 2 -> throw new RuntimeException();\n" +
1116 " case 3 -> if (true) ;\n" +
1117 " default -> i++;\n" +
1118 " }\n" +
1119 " switch (i) {\n" +
1120 " case 0:\n" +
1121 " i++;\n" +
1122 " break;\n" +
1123 " \n" +
1124 " case 1:\n" +
1125 " {\n" +
1126 " i++;\n" +
1127 " break;\n" +
1128 " }\n" +
1129 " \n" +
1130 " case 2:\n" +
1131 " throw new RuntimeException();\n" +
1132 " \n" +
1133 " case 3:\n" +
1134 " if (true) ;\n" +
1135 " break;\n" +
1136 " \n" +
1137 " default:\n" +
1138 " i++;\n" +
1139 " break;\n" +
1140 " \n" +
1141 " }\n" +
1142 " int j = switch (i) {\n" +
1143 " case 0 -> break i + 1;\n" +
1144 " case 1 -> {\n" +
1145 " break i + 1;\n" +
1146 " }\n" +
1147 " default -> throw new RuntimeException();\n" +
1148 " };\n" +
1149 " int k = switch (i) {\n" +
1150 " case 0:\n" +
1151 " break i + 1;\n" +
1152 " \n" +
1153 " case 1:\n" +
1154 " {\n" +
1155 " break i + 1;\n" +
1156 " }\n" +
1157 " \n" +
1158 " default:\n" +
1159 " throw new RuntimeException();\n" +
1160 " \n" +
1161 " };\n" +
1162 " }\n" +
1163 "}";
1164 System.err.println("toString:");
1165 System.err.println(toString);
1166 System.err.println("expectedToString:");
1167 System.err.println(expectedToString);
1168 assertEquals("the error spans are not correct; actual:" + toString, expectedToString, toString);
1169 String actualErrors = normalize(out.toString());
1170 assertEquals("the error message is not correct, actual: " + actualErrors, expectedErrors, actualErrors);
1171 }
1172
1173 @Test
1174 void testTypeParamsWithoutMethod() throws IOException {
1175 assert tool != null;
1176
1177 String code = "package test; class Test { /**javadoc*/ |public <T> |}";
1178 String[] parts = code.split("\\|");
1179
1180 code = parts[0] + parts[1] + parts[2];
1181
1182 JavacTaskImpl ct = (JavacTaskImpl) tool.getTask(null, fm, null, null,
1183 null, Arrays.asList(new MyFileObject(code)));
1184 Trees trees = Trees.instance(ct);
1185 SourcePositions pos = trees.getSourcePositions();
1186 CompilationUnitTree cut = ct.parse().iterator().next();
1187 ClassTree clazz = (ClassTree) cut.getTypeDecls().get(0);
1188 ErroneousTree err = (ErroneousTree) clazz.getMembers().get(0);
|