From e24ac22aaa286cb91a0dcdbff1f95d09fb62f8ef Mon Sep 17 00:00:00 2001 From: Reinier Zwitserloot Date: Mon, 21 Nov 2011 23:53:00 +0100 Subject: Made an API for creating a (oracle javac) JavaCompiler which tracks comments on a per Compilation Unit basis. The old way involved making reflective calls and detecting whether you need the 1.6 or the 1.7 variant to do this. These shenanigans are now hidden behind a nice API (lombok.javac.CommentCatcher). --- src/core/lombok/javac/JavacNode.java | 4 +- src/core/lombok/javac/JavacTransformer.java | 6 +- src/core/lombok/javac/LombokOptions.java | 19 ++++- src/delombok/lombok/delombok/Delombok.java | 44 +--------- src/delombok/lombok/delombok/DelombokResult.java | 8 +- src/utils/lombok/javac/CommentCatcher.java | 93 ++++++++++++++++++++++ .../javac/java7/CommentCollectingParser.java | 3 +- .../java7/CommentCollectingParserFactory.java | 2 +- 8 files changed, 123 insertions(+), 56 deletions(-) create mode 100644 src/utils/lombok/javac/CommentCatcher.java (limited to 'src') diff --git a/src/core/lombok/javac/JavacNode.java b/src/core/lombok/javac/JavacNode.java index 5b4782e8..b478781b 100644 --- a/src/core/lombok/javac/JavacNode.java +++ b/src/core/lombok/javac/JavacNode.java @@ -39,7 +39,6 @@ import com.sun.tools.javac.tree.JCTree.JCMethodDecl; import com.sun.tools.javac.tree.JCTree.JCVariableDecl; import com.sun.tools.javac.util.Context; import com.sun.tools.javac.util.Name; -import com.sun.tools.javac.util.Options; import com.sun.tools.javac.util.JCDiagnostic.DiagnosticPosition; /** @@ -198,8 +197,7 @@ public class JavacNode extends lombok.core.LombokNode changed = new HashSet(); - public boolean deleteLombokAnnotations = true; - public final Set changed = new HashSet(); - public static LombokOptions replaceWithDelombokOptions(Context context) { Options options = Options.instance(context); context.put(optionsKey, (Options)null); @@ -41,6 +40,20 @@ public class LombokOptions extends Options { return result; } + public boolean isChanged(JCCompilationUnit ast) { + return changed.contains(ast); + } + + public static void markChanged(Context context, JCCompilationUnit ast) { + Options options = context.get(Options.optionsKey); + if (options instanceof LombokOptions) ((LombokOptions) options).changed.add(ast); + } + + public static boolean shouldDeleteLombokAnnotations(Context context) { + Options options = context.get(Options.optionsKey); + return (options instanceof LombokOptions) && ((LombokOptions) options).deleteLombokAnnotations; + } + private LombokOptions(Context context) { super(context); } diff --git a/src/delombok/lombok/delombok/Delombok.java b/src/delombok/lombok/delombok/Delombok.java index 1bc550e1..a639a1f6 100644 --- a/src/delombok/lombok/delombok/Delombok.java +++ b/src/delombok/lombok/delombok/Delombok.java @@ -44,7 +44,7 @@ import java.util.Map; import javax.tools.DiagnosticListener; import javax.tools.JavaFileObject; -import lombok.javac.Comment; +import lombok.javac.CommentCatcher; import lombok.javac.LombokOptions; import com.sun.tools.javac.main.JavaCompiler; @@ -357,15 +357,8 @@ public class Delombok { if (sourcepath != null) options.put(OptionName.SOURCEPATH, sourcepath); options.put("compilePolicy", "attr"); - - registerCommentsCollectingScannerFactory(context); - JavaCompiler compiler = new JavaCompiler(context); - - Map> commentsMap = new IdentityHashMap>(); - setInCompiler(compiler, context, commentsMap); - - compiler.keepComments = true; - compiler.genEndPos = true; + CommentCatcher catcher = CommentCatcher.create(context); + JavaCompiler compiler = catcher.getCompiler(); List roots = new ArrayList(); Map baseMap = new IdentityHashMap(); @@ -389,7 +382,7 @@ public class Delombok { JavaCompiler delegate = compiler.processAnnotations(compiler.enterTrees(toJavacList(roots))); for (JCCompilationUnit unit : roots) { - DelombokResult result = new DelombokResult(commentsMap.get(unit), unit, force || options.changed.contains(unit)); + DelombokResult result = new DelombokResult(catcher.getComments(unit), unit, force || options.isChanged(unit)); if (verbose) feedback.printf("File: %s [%s]\n", unit.sourcefile.getName(), result.isChanged() ? "delomboked" : "unchanged"); Writer rawWriter; if (presetWriter != null) rawWriter = presetWriter; @@ -411,35 +404,6 @@ public class Delombok { return true; } - public static void setInCompiler(JavaCompiler compiler, Context context, Map> commentsMap) { - - try { - if (JavaCompiler.version().startsWith("1.6")) { - Class parserFactory = Class.forName("lombok.javac.java6.CommentCollectingParserFactory"); - parserFactory.getMethod("setInCompiler",JavaCompiler.class, Context.class, Map.class).invoke(null, compiler, context, commentsMap); - } else { - Class parserFactory = Class.forName("lombok.javac.java7.CommentCollectingParserFactory"); - parserFactory.getMethod("setInCompiler",JavaCompiler.class, Context.class, Map.class).invoke(null, compiler, context, commentsMap); - } - } catch (Exception e) { - if (e instanceof RuntimeException) throw (RuntimeException)e; - throw new RuntimeException(e); - } - } - - public static void registerCommentsCollectingScannerFactory(Context context) { - try { - if (JavaCompiler.version().startsWith("1.6")) { - Class.forName("lombok.javac.java6.CommentCollectingScannerFactory").getMethod("preRegister", Context.class).invoke(null, context); - } else { - Class.forName("lombok.javac.java7.CommentCollectingScannerFactory").getMethod("preRegister", Context.class).invoke(null, context); - } - } catch (Exception e) { - if (e instanceof RuntimeException) throw (RuntimeException)e; - throw new RuntimeException(e); - } - } - private static String canonical(File dir) { try { return dir.getCanonicalPath(); diff --git a/src/delombok/lombok/delombok/DelombokResult.java b/src/delombok/lombok/delombok/DelombokResult.java index 11755707..0ed39607 100644 --- a/src/delombok/lombok/delombok/DelombokResult.java +++ b/src/delombok/lombok/delombok/DelombokResult.java @@ -23,13 +23,13 @@ import java.io.IOException; import java.io.Writer; import java.util.Date; +import java.util.List; import javax.tools.JavaFileObject; import lombok.javac.Comment; import com.sun.tools.javac.tree.JCTree.JCCompilationUnit; -import com.sun.tools.javac.util.List; public class DelombokResult { private final List comments; @@ -55,7 +55,11 @@ public class DelombokResult { out.write(String.valueOf(new Date())); out.write(System.getProperty("line.separator")); - compilationUnit.accept(new PrettyCommentsPrinter(out, compilationUnit, comments)); + com.sun.tools.javac.util.List comments_; + if (comments instanceof com.sun.tools.javac.util.List) comments_ = (com.sun.tools.javac.util.List) comments; + else comments_ = com.sun.tools.javac.util.List.from(comments.toArray(new Comment[0])); + + compilationUnit.accept(new PrettyCommentsPrinter(out, compilationUnit, comments_)); } public boolean isChanged() { diff --git a/src/utils/lombok/javac/CommentCatcher.java b/src/utils/lombok/javac/CommentCatcher.java new file mode 100644 index 00000000..3bd64ec7 --- /dev/null +++ b/src/utils/lombok/javac/CommentCatcher.java @@ -0,0 +1,93 @@ +/* + * Copyright (C) 2011 The Project Lombok Authors. + * + * 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.Collections; +import java.util.List; +import java.util.Map; +import java.util.WeakHashMap; + +import com.sun.tools.javac.main.JavaCompiler; +import com.sun.tools.javac.tree.JCTree.JCCompilationUnit; +import com.sun.tools.javac.util.Context; + +public class CommentCatcher { + private final JavaCompiler compiler; + private final Map> commentsMap; + + public static CommentCatcher create(Context context) { + registerCommentsCollectingScannerFactory(context); + JavaCompiler compiler = new JavaCompiler(context); + + Map> commentsMap = new WeakHashMap>(); + setInCompiler(compiler, context, commentsMap); + + compiler.keepComments = true; + compiler.genEndPos = true; + + return new CommentCatcher(compiler, commentsMap); + } + + private CommentCatcher(JavaCompiler compiler, Map> commentsMap) { + this.compiler = compiler; + this.commentsMap = commentsMap; + } + + public JavaCompiler getCompiler() { + return compiler; + } + + public List getComments(JCCompilationUnit ast) { + List list = commentsMap.get(ast); + return list == null ? Collections.emptyList() : list; + } + + private static void registerCommentsCollectingScannerFactory(Context context) { + try { + if (JavaCompiler.version().startsWith("1.6")) { + Class.forName("lombok.javac.java6.CommentCollectingScannerFactory").getMethod("preRegister", Context.class).invoke(null, context); + } else { + Class.forName("lombok.javac.java7.CommentCollectingScannerFactory").getMethod("preRegister", Context.class).invoke(null, context); + } + } catch (Exception e) { + if (e instanceof RuntimeException) throw (RuntimeException)e; + throw new RuntimeException(e); + } + } + + private static void setInCompiler(JavaCompiler compiler, Context context, Map> commentsMap) { + + try { + if (JavaCompiler.version().startsWith("1.6")) { + Class parserFactory = Class.forName("lombok.javac.java6.CommentCollectingParserFactory"); + parserFactory.getMethod("setInCompiler",JavaCompiler.class, Context.class, Map.class).invoke(null, compiler, context, commentsMap); + } else { + Class parserFactory = Class.forName("lombok.javac.java7.CommentCollectingParserFactory"); + parserFactory.getMethod("setInCompiler",JavaCompiler.class, Context.class, Map.class).invoke(null, compiler, context, commentsMap); + } + } catch (Exception e) { + if (e instanceof RuntimeException) throw (RuntimeException)e; + throw new RuntimeException(e); + } + } + +} diff --git a/src/utils/lombok/javac/java7/CommentCollectingParser.java b/src/utils/lombok/javac/java7/CommentCollectingParser.java index 7c3cdc71..54cdb6a9 100644 --- a/src/utils/lombok/javac/java7/CommentCollectingParser.java +++ b/src/utils/lombok/javac/java7/CommentCollectingParser.java @@ -1,5 +1,6 @@ package lombok.javac.java7; +import java.util.List; import java.util.Map; import lombok.javac.Comment; @@ -8,10 +9,8 @@ import com.sun.tools.javac.parser.EndPosParser; import com.sun.tools.javac.parser.Lexer; import com.sun.tools.javac.parser.ParserFactory; import com.sun.tools.javac.tree.JCTree.JCCompilationUnit; -import com.sun.tools.javac.util.List; class CommentCollectingParser extends EndPosParser { - private final Map> commentsMap; private final Lexer lexer; diff --git a/src/utils/lombok/javac/java7/CommentCollectingParserFactory.java b/src/utils/lombok/javac/java7/CommentCollectingParserFactory.java index 8b93376a..7d8c9537 100644 --- a/src/utils/lombok/javac/java7/CommentCollectingParserFactory.java +++ b/src/utils/lombok/javac/java7/CommentCollectingParserFactory.java @@ -1,6 +1,7 @@ package lombok.javac.java7; import java.lang.reflect.Field; +import java.util.List; import java.util.Map; import lombok.javac.Comment; @@ -12,7 +13,6 @@ import com.sun.tools.javac.parser.ParserFactory; import com.sun.tools.javac.parser.ScannerFactory; import com.sun.tools.javac.tree.JCTree.JCCompilationUnit; import com.sun.tools.javac.util.Context; -import com.sun.tools.javac.util.List; public class CommentCollectingParserFactory extends ParserFactory { private final Map> commentsMap; -- cgit