57 import javax.lang.model.element.TypeElement; 58 import javax.lang.model.element.VariableElement; 59 import javax.lang.model.type.TypeKind; 60 import javax.lang.model.util.ElementFilter; 61 import javax.lang.model.util.ElementScanner9; 62 import javax.tools.Diagnostic.Kind; 63 64 import toolbox.JavacTask; 65 import toolbox.Task; 66 import toolbox.Task.Mode; 67 68 public class AnnotationProcessing extends ModuleTestBase { 69 70 public static void main(String... args) throws Exception { 71 new AnnotationProcessing().runTests(); 72 } 73 74 @Test 75 public void testAPSingleModule(Path base) throws Exception { 76 Path moduleSrc = base.resolve("module-src"); 77 Path m1 = moduleSrc.resolve("m1"); 78 79 Path classes = base.resolve("classes"); 80 81 Files.createDirectories(classes); 82 83 tb.writeJavaFiles(m1, 84 "module m1 { }", 85 "package impl; public class Impl { }"); 86 87 String log = new JavacTask(tb) 88 .options("--module-source-path", moduleSrc.toString(), 89 "-processor", AP.class.getName(), 90 "-AexpectedEnclosedElements=m1=>impl") 91 .outdir(classes) 92 .files(findJavaFiles(moduleSrc)) 93 .run() 94 .writeAll() 95 .getOutput(Task.OutputKind.DIRECT); 96 97 if (!log.isEmpty()) 98 throw new AssertionError("Unexpected output: " + log); 99 } 100 101 @Test 102 public void testAPMultiModule(Path base) throws Exception { 103 Path moduleSrc = base.resolve("module-src"); 104 Path m1 = moduleSrc.resolve("m1"); 105 Path m2 = moduleSrc.resolve("m2"); 106 107 Path classes = base.resolve("classes"); 108 109 Files.createDirectories(classes); 110 111 tb.writeJavaFiles(m1, 112 "module m1 { }", 113 "package impl1; public class Impl1 { }"); 114 115 tb.writeJavaFiles(m2, 116 "module m2 { }", 117 "package impl2; public class Impl2 { }"); 118 119 String log = new JavacTask(tb) 120 .options("--module-source-path", moduleSrc.toString(), 121 "-processor", AP.class.getName(), 122 "-AexpectedEnclosedElements=m1=>impl1,m2=>impl2") 123 .outdir(classes) 124 .files(findJavaFiles(moduleSrc)) 125 .run() 126 .writeAll() 127 .getOutput(Task.OutputKind.DIRECT); 128 129 if (!log.isEmpty()) 130 throw new AssertionError("Unexpected output: " + log); 131 } 132 133 @SupportedAnnotationTypes("*") 134 @SupportedOptions("expectedEnclosedElements") 135 public static final class AP extends AbstractProcessor { 136 137 private Map<String, List<String>> module2ExpectedEnclosedElements; 138 139 @Override 140 public boolean process(Set<? extends TypeElement> annotations, RoundEnvironment roundEnv) { 141 if (module2ExpectedEnclosedElements == null) { 142 module2ExpectedEnclosedElements = new HashMap<>(); 185 actualElements); 186 } 187 188 if (roundEnv.processingOver()) { 189 assertEquals(true, module2ExpectedEnclosedElements.isEmpty()); 190 } 191 192 return false; 193 } 194 195 @Override 196 public SourceVersion getSupportedSourceVersion() { 197 return SourceVersion.latest(); 198 } 199 200 } 201 202 @Test 203 public void testVerifyUsesProvides(Path base) throws Exception { 204 Path moduleSrc = base.resolve("module-src"); 205 Path m1 = moduleSrc.resolve("m1"); 206 207 Path classes = base.resolve("classes"); 208 209 Files.createDirectories(classes); 210 211 tb.writeJavaFiles(m1, 212 "module m1 { exports api; uses api.Api; provides api.Api with impl.Impl; }", 213 "package api; public class Api { }", 214 "package impl; public class Impl extends api.Api { }"); 215 216 String log = new JavacTask(tb) 217 .options("-doe", "-processor", VerifyUsesProvidesAP.class.getName()) 218 .outdir(classes) 219 .files(findJavaFiles(moduleSrc)) 220 .run() 221 .writeAll() 222 .getOutput(Task.OutputKind.DIRECT); 223 224 if (!log.isEmpty()) 225 throw new AssertionError("Unexpected output: " + log); 226 } 227 228 @SupportedAnnotationTypes("*") 229 public static final class VerifyUsesProvidesAP extends AbstractProcessor { 230 231 @Override 232 public boolean process(Set<? extends TypeElement> annotations, RoundEnvironment roundEnv) { 290 291 assertNonNull("Cannot find api.Api", api); 292 293 ModuleElement modle = (ModuleElement) processingEnv.getElementUtils().getPackageOf(api).getEnclosingElement(); 294 295 assertNull("modle is not null", modle); 296 297 return false; 298 } 299 300 @Override 301 public SourceVersion getSupportedSourceVersion() { 302 return SourceVersion.latest(); 303 } 304 305 } 306 307 @Test 308 public void testQualifiedClassForProcessing(Path base) throws Exception { 309 Path moduleSrc = base.resolve("module-src"); 310 Path m1 = moduleSrc.resolve("m1"); 311 Path m2 = moduleSrc.resolve("m2"); 312 313 Path classes = base.resolve("classes"); 314 315 Files.createDirectories(classes); 316 317 tb.writeJavaFiles(m1, 318 "module m1 { }", 319 "package impl; public class Impl { int m1; }"); 320 321 tb.writeJavaFiles(m2, 322 "module m2 { }", 323 "package impl; public class Impl { int m2; }"); 324 325 new JavacTask(tb) 326 .options("--module-source-path", moduleSrc.toString()) 327 .outdir(classes) 328 .files(findJavaFiles(moduleSrc)) 329 .run() 330 .writeAll() 331 .getOutput(Task.OutputKind.DIRECT); 332 333 List<String> expected = Arrays.asList("Note: field: m1"); 334 335 for (Mode mode : new Mode[] {Mode.API, Mode.CMDLINE}) { 336 List<String> log = new JavacTask(tb, mode) 337 .options("-processor", QualifiedClassForProcessing.class.getName(), 338 "--module-path", classes.toString()) 339 .classes("m1/impl.Impl") 340 .outdir(classes) 341 .run() 342 .writeAll() 343 .getOutputLines(Task.OutputKind.DIRECT); 344 345 if (!expected.equals(log)) 346 throw new AssertionError("Unexpected output: " + log); 347 } 348 } 349 350 @SupportedAnnotationTypes("*") 351 public static final class QualifiedClassForProcessing extends AbstractProcessor { 352 353 @Override 354 public boolean process(Set<? extends TypeElement> annotations, RoundEnvironment roundEnv) { 355 if (processingEnv.getElementUtils().getModuleElement("m1") == null) { 356 throw new AssertionError("No m1 module found."); 357 } 358 359 Messager messager = processingEnv.getMessager(); 360 361 for (TypeElement clazz : ElementFilter.typesIn(roundEnv.getRootElements())) { 362 for (VariableElement field : ElementFilter.fieldsIn(clazz.getEnclosedElements())) { 363 messager.printMessage(Kind.NOTE, "field: " + field.getSimpleName()); 364 } 365 } 366 367 return false; 368 } 369 370 @Override 371 public SourceVersion getSupportedSourceVersion() { 372 return SourceVersion.latest(); 373 } 374 375 } 376 | 57 import javax.lang.model.element.TypeElement; 58 import javax.lang.model.element.VariableElement; 59 import javax.lang.model.type.TypeKind; 60 import javax.lang.model.util.ElementFilter; 61 import javax.lang.model.util.ElementScanner9; 62 import javax.tools.Diagnostic.Kind; 63 64 import toolbox.JavacTask; 65 import toolbox.Task; 66 import toolbox.Task.Mode; 67 68 public class AnnotationProcessing extends ModuleTestBase { 69 70 public static void main(String... args) throws Exception { 71 new AnnotationProcessing().runTests(); 72 } 73 74 @Test 75 public void testAPSingleModule(Path base) throws Exception { 76 Path moduleSrc = base.resolve("module-src"); 77 Path m1 = moduleSrc.resolve("m1x"); 78 79 Path classes = base.resolve("classes"); 80 81 Files.createDirectories(classes); 82 83 tb.writeJavaFiles(m1, 84 "module m1x { }", 85 "package impl; public class Impl { }"); 86 87 String log = new JavacTask(tb) 88 .options("--module-source-path", moduleSrc.toString(), 89 "-processor", AP.class.getName(), 90 "-AexpectedEnclosedElements=m1x=>impl") 91 .outdir(classes) 92 .files(findJavaFiles(moduleSrc)) 93 .run() 94 .writeAll() 95 .getOutput(Task.OutputKind.DIRECT); 96 97 if (!log.isEmpty()) 98 throw new AssertionError("Unexpected output: " + log); 99 } 100 101 @Test 102 public void testAPMultiModule(Path base) throws Exception { 103 Path moduleSrc = base.resolve("module-src"); 104 Path m1 = moduleSrc.resolve("m1x"); 105 Path m2 = moduleSrc.resolve("m2x"); 106 107 Path classes = base.resolve("classes"); 108 109 Files.createDirectories(classes); 110 111 tb.writeJavaFiles(m1, 112 "module m1x { }", 113 "package impl1; public class Impl1 { }"); 114 115 tb.writeJavaFiles(m2, 116 "module m2x { }", 117 "package impl2; public class Impl2 { }"); 118 119 String log = new JavacTask(tb) 120 .options("--module-source-path", moduleSrc.toString(), 121 "-processor", AP.class.getName(), 122 "-AexpectedEnclosedElements=m1x=>impl1,m2x=>impl2") 123 .outdir(classes) 124 .files(findJavaFiles(moduleSrc)) 125 .run() 126 .writeAll() 127 .getOutput(Task.OutputKind.DIRECT); 128 129 if (!log.isEmpty()) 130 throw new AssertionError("Unexpected output: " + log); 131 } 132 133 @SupportedAnnotationTypes("*") 134 @SupportedOptions("expectedEnclosedElements") 135 public static final class AP extends AbstractProcessor { 136 137 private Map<String, List<String>> module2ExpectedEnclosedElements; 138 139 @Override 140 public boolean process(Set<? extends TypeElement> annotations, RoundEnvironment roundEnv) { 141 if (module2ExpectedEnclosedElements == null) { 142 module2ExpectedEnclosedElements = new HashMap<>(); 185 actualElements); 186 } 187 188 if (roundEnv.processingOver()) { 189 assertEquals(true, module2ExpectedEnclosedElements.isEmpty()); 190 } 191 192 return false; 193 } 194 195 @Override 196 public SourceVersion getSupportedSourceVersion() { 197 return SourceVersion.latest(); 198 } 199 200 } 201 202 @Test 203 public void testVerifyUsesProvides(Path base) throws Exception { 204 Path moduleSrc = base.resolve("module-src"); 205 Path m1 = moduleSrc.resolve("m1x"); 206 207 Path classes = base.resolve("classes"); 208 209 Files.createDirectories(classes); 210 211 tb.writeJavaFiles(m1, 212 "module m1x { exports api; uses api.Api; provides api.Api with impl.Impl; }", 213 "package api; public class Api { }", 214 "package impl; public class Impl extends api.Api { }"); 215 216 String log = new JavacTask(tb) 217 .options("-doe", "-processor", VerifyUsesProvidesAP.class.getName()) 218 .outdir(classes) 219 .files(findJavaFiles(moduleSrc)) 220 .run() 221 .writeAll() 222 .getOutput(Task.OutputKind.DIRECT); 223 224 if (!log.isEmpty()) 225 throw new AssertionError("Unexpected output: " + log); 226 } 227 228 @SupportedAnnotationTypes("*") 229 public static final class VerifyUsesProvidesAP extends AbstractProcessor { 230 231 @Override 232 public boolean process(Set<? extends TypeElement> annotations, RoundEnvironment roundEnv) { 290 291 assertNonNull("Cannot find api.Api", api); 292 293 ModuleElement modle = (ModuleElement) processingEnv.getElementUtils().getPackageOf(api).getEnclosingElement(); 294 295 assertNull("modle is not null", modle); 296 297 return false; 298 } 299 300 @Override 301 public SourceVersion getSupportedSourceVersion() { 302 return SourceVersion.latest(); 303 } 304 305 } 306 307 @Test 308 public void testQualifiedClassForProcessing(Path base) throws Exception { 309 Path moduleSrc = base.resolve("module-src"); 310 Path m1 = moduleSrc.resolve("m1x"); 311 Path m2 = moduleSrc.resolve("m2x"); 312 313 Path classes = base.resolve("classes"); 314 315 Files.createDirectories(classes); 316 317 tb.writeJavaFiles(m1, 318 "module m1x { }", 319 "package impl; public class Impl { int m1x; }"); 320 321 tb.writeJavaFiles(m2, 322 "module m2x { }", 323 "package impl; public class Impl { int m2x; }"); 324 325 new JavacTask(tb) 326 .options("--module-source-path", moduleSrc.toString()) 327 .outdir(classes) 328 .files(findJavaFiles(moduleSrc)) 329 .run() 330 .writeAll() 331 .getOutput(Task.OutputKind.DIRECT); 332 333 List<String> expected = Arrays.asList("Note: field: m1x"); 334 335 for (Mode mode : new Mode[] {Mode.API, Mode.CMDLINE}) { 336 List<String> log = new JavacTask(tb, mode) 337 .options("-processor", QualifiedClassForProcessing.class.getName(), 338 "--module-path", classes.toString()) 339 .classes("m1x/impl.Impl") 340 .outdir(classes) 341 .run() 342 .writeAll() 343 .getOutputLines(Task.OutputKind.DIRECT); 344 345 if (!expected.equals(log)) 346 throw new AssertionError("Unexpected output: " + log); 347 } 348 } 349 350 @SupportedAnnotationTypes("*") 351 public static final class QualifiedClassForProcessing extends AbstractProcessor { 352 353 @Override 354 public boolean process(Set<? extends TypeElement> annotations, RoundEnvironment roundEnv) { 355 if (processingEnv.getElementUtils().getModuleElement("m1x") == null) { 356 throw new AssertionError("No m1x module found."); 357 } 358 359 Messager messager = processingEnv.getMessager(); 360 361 for (TypeElement clazz : ElementFilter.typesIn(roundEnv.getRootElements())) { 362 for (VariableElement field : ElementFilter.fieldsIn(clazz.getEnclosedElements())) { 363 messager.printMessage(Kind.NOTE, "field: " + field.getSimpleName()); 364 } 365 } 366 367 return false; 368 } 369 370 @Override 371 public SourceVersion getSupportedSourceVersion() { 372 return SourceVersion.latest(); 373 } 374 375 } 376 |