diff options
author | Reinier Zwitserloot <reinier@tipit.to> | 2009-11-25 07:32:49 +0100 |
---|---|---|
committer | Reinier Zwitserloot <reinier@tipit.to> | 2009-11-25 07:32:49 +0100 |
commit | 1a0e611a9c5e1ee518670647ce1a44beae559b44 (patch) | |
tree | e5ef8f671bc6688f486e874d4e2e1a7813e4f0b2 /src/core/lombok/javac/apt | |
parent | 7fd947ea40c25dad9ee543ebc4b92de9a2e05efc (diff) | |
download | lombok-1a0e611a9c5e1ee518670647ce1a44beae559b44.tar.gz lombok-1a0e611a9c5e1ee518670647ce1a44beae559b44.tar.bz2 lombok-1a0e611a9c5e1ee518670647ce1a44beae559b44.zip |
Refactored the source folders.
Diffstat (limited to 'src/core/lombok/javac/apt')
-rw-r--r-- | src/core/lombok/javac/apt/Processor.java | 175 | ||||
-rw-r--r-- | src/core/lombok/javac/apt/package-info.java | 26 |
2 files changed, 201 insertions, 0 deletions
diff --git a/src/core/lombok/javac/apt/Processor.java b/src/core/lombok/javac/apt/Processor.java new file mode 100644 index 00000000..9c851762 --- /dev/null +++ b/src/core/lombok/javac/apt/Processor.java @@ -0,0 +1,175 @@ +/* + * Copyright © 2009 Reinier Zwitserloot and Roel Spilker. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ +package lombok.javac.apt; + +import java.util.ArrayList; +import java.util.IdentityHashMap; +import java.util.List; +import java.util.Set; + +import javax.annotation.processing.AbstractProcessor; +import javax.annotation.processing.ProcessingEnvironment; +import javax.annotation.processing.RoundEnvironment; +import javax.annotation.processing.SupportedAnnotationTypes; +import javax.annotation.processing.SupportedSourceVersion; +import javax.lang.model.SourceVersion; +import javax.lang.model.element.Element; +import javax.lang.model.element.TypeElement; +import javax.tools.Diagnostic.Kind; + +import lombok.javac.HandlerLibrary; +import lombok.javac.JavacAST; +import lombok.javac.JavacASTAdapter; +import lombok.javac.JavacNode; + +import com.sun.source.util.TreePath; +import com.sun.source.util.Trees; +import com.sun.tools.javac.processing.JavacProcessingEnvironment; +import com.sun.tools.javac.tree.JCTree.JCAnnotation; +import com.sun.tools.javac.tree.JCTree.JCClassDecl; +import com.sun.tools.javac.tree.JCTree.JCCompilationUnit; +import com.sun.tools.javac.tree.JCTree.JCMethodDecl; +import com.sun.tools.javac.tree.JCTree.JCVariableDecl; + + +/** + * This Annotation Processor is the standard injection mechanism for lombok-enabling the javac compiler. + * + * Due to lots of changes in the core javac code, as well as lombok's heavy usage of non-public API, this + * code only works for the javac v1.6 compiler; it definitely won't work for javac v1.5, and it probably + * won't work for javac v1.7 without modifications. + * + * To actually enable lombok in a javac compilation run, this class should be in the classpath when + * running javac; that's the only requirement. + */ +@SupportedAnnotationTypes("*") +@SupportedSourceVersion(SourceVersion.RELEASE_6) +public class Processor extends AbstractProcessor { + private ProcessingEnvironment rawProcessingEnv; + private JavacProcessingEnvironment processingEnv; + private HandlerLibrary handlers; + private Trees trees; + private String errorToShow; + + /** {@inheritDoc} */ + @Override public void init(ProcessingEnvironment procEnv) { + super.init(procEnv); + this.rawProcessingEnv = procEnv; + String className = procEnv.getClass().getName(); + if (className.startsWith("org.eclipse.jdt.")) { + errorToShow = "You should not install lombok.jar as an annotation processor in eclipse. Instead, run lombok.jar as a java application and follow the instructions."; + procEnv.getMessager().printMessage(Kind.WARNING, errorToShow); + this.processingEnv = null; + } else if (!procEnv.getClass().getName().equals("com.sun.tools.javac.processing.JavacProcessingEnvironment")) { + procEnv.getMessager().printMessage(Kind.WARNING, "You aren't using a compiler based around javac v1.6, so lombok will not work properly.\n" + + "Your processor class is: " + className); + this.processingEnv = null; + this.errorToShow = null; + } else { + this.processingEnv = (JavacProcessingEnvironment) procEnv; + handlers = HandlerLibrary.load(procEnv.getMessager()); + trees = Trees.instance(procEnv); + this.errorToShow = null; + } + } + + /** {@inheritDoc} */ + @Override public boolean process(Set<? extends TypeElement> annotations, RoundEnvironment roundEnv) { + if (processingEnv == null) { + if (errorToShow != null) { + Set<? extends Element> rootElements = roundEnv.getRootElements(); + if (!rootElements.isEmpty()) { + rawProcessingEnv.getMessager().printMessage(Kind.WARNING, errorToShow, rootElements.iterator().next()); + errorToShow = null; + } + } + return false; + } + + IdentityHashMap<JCCompilationUnit, Void> units = new IdentityHashMap<JCCompilationUnit, Void>(); + for (Element element : roundEnv.getRootElements()) { + JCCompilationUnit unit = toUnit(element); + if (unit != null) units.put(unit, null); + } + + List<JavacAST> asts = new ArrayList<JavacAST>(); + + for (JCCompilationUnit unit : units.keySet()) asts.add( + new JavacAST(trees, processingEnv.getMessager(), processingEnv.getContext(), unit)); + + handlers.skipPrintAST(); + for (JavacAST ast : asts) { + ast.traverse(new AnnotationVisitor()); + handlers.callASTVisitors(ast); + } + + handlers.skipAllButPrintAST(); + for (JavacAST ast : asts) { + ast.traverse(new AnnotationVisitor()); + } + return false; + } + + private class AnnotationVisitor extends JavacASTAdapter { + @Override public void visitAnnotationOnType(JCClassDecl type, JavacNode annotationNode, JCAnnotation annotation) { + if (annotationNode.isHandled()) return; + JCCompilationUnit top = (JCCompilationUnit) annotationNode.top().get(); + boolean handled = handlers.handleAnnotation(top, annotationNode, annotation); + if (handled) annotationNode.setHandled(); + } + + @Override public void visitAnnotationOnField(JCVariableDecl field, JavacNode annotationNode, JCAnnotation annotation) { + if (annotationNode.isHandled()) return; + JCCompilationUnit top = (JCCompilationUnit) annotationNode.top().get(); + boolean handled = handlers.handleAnnotation(top, annotationNode, annotation); + if (handled) annotationNode.setHandled(); + } + + @Override public void visitAnnotationOnMethod(JCMethodDecl method, JavacNode annotationNode, JCAnnotation annotation) { + if (annotationNode.isHandled()) return; + JCCompilationUnit top = (JCCompilationUnit) annotationNode.top().get(); + boolean handled = handlers.handleAnnotation(top, annotationNode, annotation); + if (handled) annotationNode.setHandled(); + } + + @Override public void visitAnnotationOnMethodArgument(JCVariableDecl argument, JCMethodDecl method, JavacNode annotationNode, JCAnnotation annotation) { + if (annotationNode.isHandled()) return; + JCCompilationUnit top = (JCCompilationUnit) annotationNode.top().get(); + boolean handled = handlers.handleAnnotation(top, annotationNode, annotation); + if (handled) annotationNode.setHandled(); + } + + @Override public void visitAnnotationOnLocal(JCVariableDecl local, JavacNode annotationNode, JCAnnotation annotation) { + if (annotationNode.isHandled()) return; + JCCompilationUnit top = (JCCompilationUnit) annotationNode.top().get(); + boolean handled = handlers.handleAnnotation(top, annotationNode, annotation); + if (handled) annotationNode.setHandled(); + } + } + + private JCCompilationUnit toUnit(Element element) { + TreePath path = trees == null ? null : trees.getPath(element); + if (path == null) return null; + + return (JCCompilationUnit) path.getCompilationUnit(); + } +} diff --git a/src/core/lombok/javac/apt/package-info.java b/src/core/lombok/javac/apt/package-info.java new file mode 100644 index 00000000..0c47c40f --- /dev/null +++ b/src/core/lombok/javac/apt/package-info.java @@ -0,0 +1,26 @@ +/* + * Copyright © 2009 Reinier Zwitserloot and Roel Spilker. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +/** + * Contains the mechanism that instruments javac as an annotation processor. + */ +package lombok.javac.apt; |