1 /* 2 * Copyright (c) 2012-2017 The ANTLR Project. All rights reserved. 3 * Use of this file is governed by the BSD 3-clause license that 4 * can be found in the LICENSE.txt file in the project root. 5 */ 6 7 package org.antlr.v4.test.runtime; 8 9 import com.sun.tools.javac.model.JavacElements; 10 import com.sun.tools.javac.processing.JavacProcessingEnvironment; 11 import com.sun.tools.javac.tree.JCTree; 12 import com.sun.tools.javac.tree.TreeMaker; 13 import com.sun.tools.javac.util.List; 14 15 import javax.annotation.processing.AbstractProcessor; 16 import javax.annotation.processing.ProcessingEnvironment; 17 import javax.annotation.processing.RoundEnvironment; 18 import javax.annotation.processing.SupportedAnnotationTypes; 19 import javax.annotation.processing.SupportedSourceVersion; 20 import javax.lang.model.SourceVersion; 21 import javax.lang.model.element.Element; 22 import javax.lang.model.element.TypeElement; 23 import java.util.Set; 24 25 /** 26 I think I figured out how to use annotation processors in maven. It's 27 more or less automatic and you don't even need to tell maven, with one minor 28 exception. The idea is to create a project for the annotation and another 29 for the annotation processor. Then, a project that uses the annotation 30 can simply set up the dependency on the other projects. You have to turn 31 off processing, -proc:none on the processor project itself but other than 32 that, java 6+ more or less tries to apply any processors it finds during 33 compilation. maven just works. 34 35 Also you need a META-INF/services/javax.annotation.processing.Processor file 36 with "org.antlr.v4.test.runtime.CommentHasStringValueProcessor" in it. 37 */ 38 @SupportedAnnotationTypes({"org.antlr.v4.test.runtime.CommentHasStringValue"}) 39 @SupportedSourceVersion(SourceVersion.RELEASE_7) 40 public class CommentHasStringValueProcessor extends AbstractProcessor { 41 protected JavacElements utilities; 42 protected TreeMaker treeMaker; 43 44 @Override init(ProcessingEnvironment processingEnv)45 public synchronized void init(ProcessingEnvironment processingEnv) { 46 super.init(processingEnv); 47 // Messager messager = processingEnv.getMessager(); 48 // messager.printMessage(Diagnostic.Kind.NOTE, "WOW INIT--------------------"); 49 JavacProcessingEnvironment javacProcessingEnv = (JavacProcessingEnvironment) processingEnv; 50 utilities = javacProcessingEnv.getElementUtils(); 51 treeMaker = TreeMaker.instance(javacProcessingEnv.getContext()); 52 } 53 54 @Override process(Set<? extends TypeElement> annotations, RoundEnvironment roundEnv)55 public boolean process(Set<? extends TypeElement> annotations, RoundEnvironment roundEnv) { 56 // Messager messager = processingEnv.getMessager(); 57 // messager.printMessage(Diagnostic.Kind.NOTE, "PROCESS--------------------"); 58 Set<? extends Element> annotatedElements = roundEnv.getElementsAnnotatedWith(CommentHasStringValue.class); 59 for (Element annotatedElement : annotatedElements) { 60 String docComment = utilities.getDocComment(annotatedElement); 61 JCTree.JCLiteral literal = treeMaker.Literal(docComment!=null ? docComment : ""); 62 JCTree elementTree = utilities.getTree(annotatedElement); 63 if ( elementTree instanceof JCTree.JCVariableDecl ) { 64 ((JCTree.JCVariableDecl)elementTree).init = literal; 65 } 66 else if ( elementTree instanceof JCTree.JCMethodDecl ) { 67 JCTree.JCStatement[] statements = new JCTree.JCStatement[1]; 68 statements[0] = treeMaker.Return(literal); 69 JCTree.JCBlock body = treeMaker.Block(0, List.from(statements)); 70 ((JCTree.JCMethodDecl)elementTree).body = body; 71 } 72 } 73 return true; 74 } 75 76 @Override getSupportedSourceVersion()77 public SourceVersion getSupportedSourceVersion() { 78 return SourceVersion.latestSupported(); 79 } 80 } 81