From e5d248c3ccf64211fd8a301f584bde82dd426601 Mon Sep 17 00:00:00 2001 From: Reinier Zwitserloot Date: Fri, 27 Nov 2009 00:38:58 +0100 Subject: delombok now calls lombok. wahey! --- src/core/lombok/javac/JavacAST.java | 5 +- src/core/lombok/javac/JavacTransformer.java | 98 +++++++++++++++++++++++++++++ src/core/lombok/javac/apt/Processor.java | 67 ++------------------ 3 files changed, 103 insertions(+), 67 deletions(-) create mode 100644 src/core/lombok/javac/JavacTransformer.java (limited to 'src/core') diff --git a/src/core/lombok/javac/JavacAST.java b/src/core/lombok/javac/JavacAST.java index f2c83fb8..77c63cfe 100644 --- a/src/core/lombok/javac/JavacAST.java +++ b/src/core/lombok/javac/JavacAST.java @@ -32,7 +32,6 @@ import javax.tools.JavaFileObject; import lombok.core.AST; -import com.sun.source.util.Trees; import com.sun.tools.javac.code.Symtab; import com.sun.tools.javac.tree.JCTree; import com.sun.tools.javac.tree.TreeMaker; @@ -66,13 +65,11 @@ public class JavacAST extends AST { /** * Creates a new JavacAST of the provided Compilation Unit. * - * @param trees The trees instance to use to inspect the compilation unit. Generate via: - * {@code Trees.getInstance(env)} * @param messager A Messager for warning and error reporting. * @param context A Context object for interfacing with the compiler. * @param top The compilation unit, which serves as the top level node in the tree to be built. */ - public JavacAST(Trees trees, Messager messager, Context context, JCCompilationUnit top) { + public JavacAST(Messager messager, Context context, JCCompilationUnit top) { super(top.sourcefile == null ? null : top.sourcefile.toString()); setTop(buildCompilationUnit(top)); this.context = context; diff --git a/src/core/lombok/javac/JavacTransformer.java b/src/core/lombok/javac/JavacTransformer.java new file mode 100644 index 00000000..d004414d --- /dev/null +++ b/src/core/lombok/javac/JavacTransformer.java @@ -0,0 +1,98 @@ +/* + * 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; + +import java.util.ArrayList; +import java.util.List; + +import javax.annotation.processing.Messager; + +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; +import com.sun.tools.javac.util.Context; + +public class JavacTransformer { + private final HandlerLibrary handlers; + private final Messager messager; + + public JavacTransformer(Messager messager) { + this.messager = messager; + this.handlers = HandlerLibrary.load(messager); + } + + public void transform(Context context, Iterable compilationUnits) { + List asts = new ArrayList(); + + for (JCCompilationUnit unit : compilationUnits) asts.add(new JavacAST(messager, context, unit)); + + handlers.skipPrintAST(); + for (JavacAST ast : asts) { + ast.traverse(new AnnotationVisitor()); + handlers.callASTVisitors(ast); + } + + handlers.skipAllButPrintAST(); + for (JavacAST ast : asts) { + ast.traverse(new AnnotationVisitor()); + } + } + + 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(); + } + } +} diff --git a/src/core/lombok/javac/apt/Processor.java b/src/core/lombok/javac/apt/Processor.java index 9c851762..b779a680 100644 --- a/src/core/lombok/javac/apt/Processor.java +++ b/src/core/lombok/javac/apt/Processor.java @@ -21,9 +21,7 @@ */ 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; @@ -36,19 +34,12 @@ 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 lombok.javac.JavacTransformer; 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; /** @@ -66,7 +57,7 @@ import com.sun.tools.javac.tree.JCTree.JCVariableDecl; public class Processor extends AbstractProcessor { private ProcessingEnvironment rawProcessingEnv; private JavacProcessingEnvironment processingEnv; - private HandlerLibrary handlers; + private JavacTransformer transformer; private Trees trees; private String errorToShow; @@ -86,7 +77,7 @@ public class Processor extends AbstractProcessor { this.errorToShow = null; } else { this.processingEnv = (JavacProcessingEnvironment) procEnv; - handlers = HandlerLibrary.load(procEnv.getMessager()); + transformer = new JavacTransformer(procEnv.getMessager()); trees = Trees.instance(procEnv); this.errorToShow = null; } @@ -111,61 +102,11 @@ public class Processor extends AbstractProcessor { if (unit != null) units.put(unit, null); } - List asts = new ArrayList(); + transformer.transform(processingEnv.getContext(), units.keySet()); - 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; -- cgit From e54c3f36e3122dfe34a119178cfcca2dcdbad998 Mon Sep 17 00:00:00 2001 From: Roel Spilker Date: Fri, 27 Nov 2009 03:10:03 +0100 Subject: Added change tracking so that 1 AST instance can tell you if any processor changed anything. --- src/core/lombok/core/AST.java | 13 +++++++++++++ src/core/lombok/core/LombokNode.java | 6 ++++++ src/core/lombok/eclipse/EclipseAST.java | 3 +++ src/core/lombok/javac/JavacAST.java | 1 + 4 files changed, 23 insertions(+) (limited to 'src/core') diff --git a/src/core/lombok/core/AST.java b/src/core/lombok/core/AST.java index 6d786d1e..e769ce34 100644 --- a/src/core/lombok/core/AST.java +++ b/src/core/lombok/core/AST.java @@ -54,11 +54,24 @@ public abstract class AST, L extends LombokNode, private final String fileName; Map identityDetector = new IdentityHashMap(); private Map nodeMap = new IdentityHashMap(); + private boolean changed = false; protected AST(String fileName) { this.fileName = fileName == null ? "(unknown).java" : fileName; } + protected void setChanged() { + this.changed = true; + } + + protected void clearChanged() { + this.changed = false; + } + + public boolean isChanged() { + return changed; + } + /** Set the node object that wraps the internal Compilation Unit node. */ protected void setTop(L top) { this.top = top; diff --git a/src/core/lombok/core/LombokNode.java b/src/core/lombok/core/LombokNode.java index c8ee4c00..95c5a0cb 100644 --- a/src/core/lombok/core/LombokNode.java +++ b/src/core/lombok/core/LombokNode.java @@ -126,6 +126,7 @@ public abstract class LombokNode, L extends LombokNode, L extends LombokNode, L extends LombokNode, L extends LombokNode, L extends LombokNode { this.compilationUnitDeclaration = ast; setTop(buildCompilationUnit(ast)); this.completeParse = isComplete(ast); + clearChanged(); } /** {@inheritDoc} */ @@ -201,12 +202,14 @@ public class EclipseAST extends AST { public void reparse() { propagateProblems(); if (completeParse) return; + boolean changed = isChanged(); boolean newCompleteParse = isComplete(compilationUnitDeclaration); if (!newCompleteParse) return; top().rebuild(); this.completeParse = true; + if (!changed) clearChanged(); } private static boolean isComplete(CompilationUnitDeclaration unit) { diff --git a/src/core/lombok/javac/JavacAST.java b/src/core/lombok/javac/JavacAST.java index 77c63cfe..93e3f3dc 100644 --- a/src/core/lombok/javac/JavacAST.java +++ b/src/core/lombok/javac/JavacAST.java @@ -78,6 +78,7 @@ public class JavacAST extends AST { this.nameTable = Name.Table.instance(context); this.treeMaker = TreeMaker.instance(context); this.symtab = Symtab.instance(context); + clearChanged(); } public Context getContext() { -- cgit From 391db3dcecdd0d94eb76b656e655346891b02bb4 Mon Sep 17 00:00:00 2001 From: Roel Spilker Date: Fri, 27 Nov 2009 04:18:28 +0100 Subject: Thorough work on inserting comments in the proper place for delombok; should now work fine with GWT native methods! NON-NLS-1 is still theoretically problematic, but that'll be a fix for another day. Also added ability to recognize that nothing has changed, which will copy the original file instead of reparsing it. --- src/core/lombok/javac/JavacTransformer.java | 7 ++- src/core/lombok/javac/handlers/HandleCleanup.java | 2 + src/core/lombok/javac/handlers/HandleData.java | 1 + .../javac/handlers/HandleEqualsAndHashCode.java | 1 + src/core/lombok/javac/handlers/HandleGetter.java | 2 + src/core/lombok/javac/handlers/HandleSetter.java | 2 + .../lombok/javac/handlers/HandleSneakyThrows.java | 2 + .../lombok/javac/handlers/HandleSynchronized.java | 3 ++ src/core/lombok/javac/handlers/HandleToString.java | 2 + .../lombok/javac/handlers/JavacHandlerUtil.java | 51 ++++++++++++++++++++++ 10 files changed, 72 insertions(+), 1 deletion(-) (limited to 'src/core') diff --git a/src/core/lombok/javac/JavacTransformer.java b/src/core/lombok/javac/JavacTransformer.java index d004414d..5f145460 100644 --- a/src/core/lombok/javac/JavacTransformer.java +++ b/src/core/lombok/javac/JavacTransformer.java @@ -42,7 +42,7 @@ public class JavacTransformer { this.handlers = HandlerLibrary.load(messager); } - public void transform(Context context, Iterable compilationUnits) { + public boolean transform(Context context, Iterable compilationUnits) { List asts = new ArrayList(); for (JCCompilationUnit unit : compilationUnits) asts.add(new JavacAST(messager, context, unit)); @@ -57,6 +57,11 @@ public class JavacTransformer { for (JavacAST ast : asts) { ast.traverse(new AnnotationVisitor()); } + + for (JavacAST ast : asts) { + if (ast.isChanged()) return true; + } + return false; } private class AnnotationVisitor extends JavacASTAdapter { diff --git a/src/core/lombok/javac/handlers/HandleCleanup.java b/src/core/lombok/javac/handlers/HandleCleanup.java index 88a8e1d7..2c89d9ad 100644 --- a/src/core/lombok/javac/handlers/HandleCleanup.java +++ b/src/core/lombok/javac/handlers/HandleCleanup.java @@ -21,6 +21,7 @@ */ package lombok.javac.handlers; +import static lombok.javac.handlers.JavacHandlerUtil.markAnnotationAsProcessed; import lombok.Cleanup; import lombok.core.AnnotationValues; import lombok.core.AST.Kind; @@ -53,6 +54,7 @@ import com.sun.tools.javac.util.Name; @ProviderFor(JavacAnnotationHandler.class) public class HandleCleanup implements JavacAnnotationHandler { @Override public boolean handle(AnnotationValues annotation, JCAnnotation ast, JavacNode annotationNode) { + markAnnotationAsProcessed(annotationNode, Cleanup.class); String cleanupName = annotation.getInstance().value(); if (cleanupName.length() == 0) { annotationNode.addError("cleanupName cannot be the empty string."); diff --git a/src/core/lombok/javac/handlers/HandleData.java b/src/core/lombok/javac/handlers/HandleData.java index eef7f78d..a0315d08 100644 --- a/src/core/lombok/javac/handlers/HandleData.java +++ b/src/core/lombok/javac/handlers/HandleData.java @@ -59,6 +59,7 @@ import com.sun.tools.javac.util.List; @ProviderFor(JavacAnnotationHandler.class) public class HandleData implements JavacAnnotationHandler { @Override public boolean handle(AnnotationValues annotation, JCAnnotation ast, JavacNode annotationNode) { + markAnnotationAsProcessed(annotationNode, Data.class); JavacNode typeNode = annotationNode.up(); JCClassDecl typeDecl = null; if (typeNode.get() instanceof JCClassDecl) typeDecl = (JCClassDecl)typeNode.get(); diff --git a/src/core/lombok/javac/handlers/HandleEqualsAndHashCode.java b/src/core/lombok/javac/handlers/HandleEqualsAndHashCode.java index 61a4ef63..f388336d 100644 --- a/src/core/lombok/javac/handlers/HandleEqualsAndHashCode.java +++ b/src/core/lombok/javac/handlers/HandleEqualsAndHashCode.java @@ -72,6 +72,7 @@ public class HandleEqualsAndHashCode implements JavacAnnotationHandler annotation, JCAnnotation ast, JavacNode annotationNode) { + markAnnotationAsProcessed(annotationNode, EqualsAndHashCode.class); EqualsAndHashCode ann = annotation.getInstance(); List excludes = List.from(ann.exclude()); List includes = List.from(ann.of()); diff --git a/src/core/lombok/javac/handlers/HandleGetter.java b/src/core/lombok/javac/handlers/HandleGetter.java index e60e426d..b0343eaf 100644 --- a/src/core/lombok/javac/handlers/HandleGetter.java +++ b/src/core/lombok/javac/handlers/HandleGetter.java @@ -80,8 +80,10 @@ public class HandleGetter implements JavacAnnotationHandler { } @Override public boolean handle(AnnotationValues annotation, JCAnnotation ast, JavacNode annotationNode) { + markAnnotationAsProcessed(annotationNode, Getter.class); JavacNode fieldNode = annotationNode.up(); AccessLevel level = annotation.getInstance().value(); + if (level == AccessLevel.NONE) return true; return createGetterForField(level, fieldNode, annotationNode, true); diff --git a/src/core/lombok/javac/handlers/HandleSetter.java b/src/core/lombok/javac/handlers/HandleSetter.java index 84032e9c..1d029f33 100644 --- a/src/core/lombok/javac/handlers/HandleSetter.java +++ b/src/core/lombok/javac/handlers/HandleSetter.java @@ -82,8 +82,10 @@ public class HandleSetter implements JavacAnnotationHandler { } @Override public boolean handle(AnnotationValues annotation, JCAnnotation ast, JavacNode annotationNode) { + markAnnotationAsProcessed(annotationNode, Setter.class); JavacNode fieldNode = annotationNode.up(); AccessLevel level = annotation.getInstance().value(); + if (level == AccessLevel.NONE) return true; return createSetterForField(level, fieldNode, annotationNode, true); diff --git a/src/core/lombok/javac/handlers/HandleSneakyThrows.java b/src/core/lombok/javac/handlers/HandleSneakyThrows.java index e7879dd1..8a185e87 100644 --- a/src/core/lombok/javac/handlers/HandleSneakyThrows.java +++ b/src/core/lombok/javac/handlers/HandleSneakyThrows.java @@ -22,6 +22,7 @@ package lombok.javac.handlers; import static lombok.javac.handlers.JavacHandlerUtil.chainDots; +import static lombok.javac.handlers.JavacHandlerUtil.markAnnotationAsProcessed; import java.util.ArrayList; import java.util.Collection; @@ -49,6 +50,7 @@ import com.sun.tools.javac.util.List; @ProviderFor(JavacAnnotationHandler.class) public class HandleSneakyThrows implements JavacAnnotationHandler { @Override public boolean handle(AnnotationValues annotation, JCAnnotation ast, JavacNode annotationNode) { + markAnnotationAsProcessed(annotationNode, SneakyThrows.class); Collection exceptionNames = annotation.getRawExpressions("value"); List memberValuePairs = ast.getArguments(); diff --git a/src/core/lombok/javac/handlers/HandleSynchronized.java b/src/core/lombok/javac/handlers/HandleSynchronized.java index c86d99c6..eaa0ad6d 100644 --- a/src/core/lombok/javac/handlers/HandleSynchronized.java +++ b/src/core/lombok/javac/handlers/HandleSynchronized.java @@ -51,10 +51,12 @@ public class HandleSynchronized implements JavacAnnotationHandler private static final String STATIC_LOCK_NAME = "$LOCK"; @Override public boolean handle(AnnotationValues annotation, JCAnnotation ast, JavacNode annotationNode) { + markAnnotationAsProcessed(annotationNode, Synchronized.class); JavacNode methodNode = annotationNode.up(); if (methodNode == null || methodNode.getKind() != Kind.METHOD || !(methodNode.get() instanceof JCMethodDecl)) { annotationNode.addError("@Synchronized is legal only on methods."); + return true; } @@ -62,6 +64,7 @@ public class HandleSynchronized implements JavacAnnotationHandler if ((method.mods.flags & Flags.ABSTRACT) != 0) { annotationNode.addError("@Synchronized is legal only on concrete methods."); + return true; } boolean isStatic = (method.mods.flags & Flags.STATIC) != 0; diff --git a/src/core/lombok/javac/handlers/HandleToString.java b/src/core/lombok/javac/handlers/HandleToString.java index f7251ab8..dd3df620 100644 --- a/src/core/lombok/javac/handlers/HandleToString.java +++ b/src/core/lombok/javac/handlers/HandleToString.java @@ -68,6 +68,8 @@ public class HandleToString implements JavacAnnotationHandler { } @Override public boolean handle(AnnotationValues annotation, JCAnnotation ast, JavacNode annotationNode) { + markAnnotationAsProcessed(annotationNode, ToString.class); + ToString ann = annotation.getInstance(); List excludes = List.from(ann.exclude()); List includes = List.from(ann.of()); diff --git a/src/core/lombok/javac/handlers/JavacHandlerUtil.java b/src/core/lombok/javac/handlers/JavacHandlerUtil.java index 34d8b849..caa8a998 100644 --- a/src/core/lombok/javac/handlers/JavacHandlerUtil.java +++ b/src/core/lombok/javac/handlers/JavacHandlerUtil.java @@ -21,6 +21,7 @@ */ package lombok.javac.handlers; +import java.lang.annotation.Annotation; import java.util.regex.Pattern; import lombok.AccessLevel; @@ -34,7 +35,9 @@ import com.sun.tools.javac.tree.JCTree; import com.sun.tools.javac.tree.TreeMaker; 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.JCExpression; +import com.sun.tools.javac.tree.JCTree.JCImport; import com.sun.tools.javac.tree.JCTree.JCMethodDecl; import com.sun.tools.javac.tree.JCTree.JCStatement; import com.sun.tools.javac.tree.JCTree.JCVariableDecl; @@ -57,6 +60,54 @@ public class JavacHandlerUtil { return TransformationsUtil.PRIMITIVE_TYPE_NAME_PATTERN.matcher(typeName).matches(); } + /** + * Removes the annotation from javac's AST, then removes it from lombok's AST, + * then removes any import statement that imports this exact annotation (not star imports). + */ + public static void markAnnotationAsProcessed(JavacNode annotation, Class annotationType) { + JavacNode parentNode = annotation.directUp(); + switch (parentNode.getKind()) { + case FIELD: + case ARGUMENT: + case LOCAL: + JCVariableDecl variable = (JCVariableDecl) parentNode.get(); + variable.mods.annotations = filterList(variable.mods.annotations, annotation.get()); + break; + case METHOD: + JCMethodDecl method = (JCMethodDecl) parentNode.get(); + method.mods.annotations = filterList(method.mods.annotations, annotation.get()); + break; + default: + throw new IllegalStateException("Don't know how to remove annotations from: " + parentNode.getKind()); + } + parentNode.removeChild(annotation); + + JCCompilationUnit unit = (JCCompilationUnit) annotation.top().get(); + deleteImportFromCompilationUnit(unit, annotationType.getName()); + } + + private static void deleteImportFromCompilationUnit(JCCompilationUnit unit, String name) { + List newDefs = List.nil(); + + for (JCTree def : unit.defs) { + boolean delete = false; + if (def instanceof JCImport) { + JCImport imp0rt = (JCImport)def; + delete = (!imp0rt.staticImport && imp0rt.qualid.toString().equals(name)); + } + if (!delete) newDefs = newDefs.append(def); + } + unit.defs = newDefs; + } + + private static List filterList(List annotations, JCTree jcTree) { + List newAnnotations = List.nil(); + for (JCAnnotation ann : annotations) { + if (jcTree != ann) newAnnotations = newAnnotations.append(ann); + } + return newAnnotations; + } + /** * Translates the given field into all possible getter names. * Convenient wrapper around {@link TransformationsUtil#toAllGetterNames(CharSequence, boolean)}. -- cgit