aboutsummaryrefslogtreecommitdiff
path: root/src/delombok
diff options
context:
space:
mode:
Diffstat (limited to 'src/delombok')
-rw-r--r--src/delombok/lombok/delombok/Delombok.java31
-rw-r--r--src/delombok/lombok/delombok/DelombokApp.java3
-rw-r--r--src/delombok/lombok/delombok/DocCommentIntegrator.java127
-rw-r--r--src/delombok/lombok/delombok/LombokOptionsFactory.java57
-rw-r--r--src/delombok/lombok/delombok/PrettyCommentsPrinter.java547
5 files changed, 441 insertions, 324 deletions
diff --git a/src/delombok/lombok/delombok/Delombok.java b/src/delombok/lombok/delombok/Delombok.java
index f4e02786..0128e44f 100644
--- a/src/delombok/lombok/delombok/Delombok.java
+++ b/src/delombok/lombok/delombok/Delombok.java
@@ -52,7 +52,6 @@ import lombok.javac.LombokOptions;
import com.sun.tools.javac.comp.Todo;
import com.sun.tools.javac.main.JavaCompiler;
-import com.sun.tools.javac.main.OptionName;
import com.sun.tools.javac.tree.JCTree.JCCompilationUnit;
import com.sun.tools.javac.util.Context;
import com.zwitserloot.cmdreader.CmdReader;
@@ -359,12 +358,12 @@ public class Delombok {
}
public boolean delombok() throws IOException {
- LombokOptions options = LombokOptions.replaceWithDelombokOptions(context);
- options.put(OptionName.ENCODING, charset.name());
- if (classpath != null) options.put(OptionName.CLASSPATH, classpath);
- if (sourcepath != null) options.put(OptionName.SOURCEPATH, sourcepath);
- if (bootclasspath != null) options.put(OptionName.BOOTCLASSPATH, bootclasspath);
- options.put("compilePolicy", "attr");
+ LombokOptions options = LombokOptionsFactory.getDelombokOptions(context);
+ options.putJavacOption("ENCODING", charset.name());
+ if (classpath != null) options.putJavacOption("CLASSPATH", classpath);
+ if (sourcepath != null) options.putJavacOption("SOURCEPATH", sourcepath);
+ if (bootclasspath != null) options.putJavacOption("BOOTCLASSPATH", bootclasspath);
+ options.put("compilePolicy", "check");
CommentCatcher catcher = CommentCatcher.create(context);
JavaCompiler compiler = catcher.getCompiler();
@@ -375,10 +374,7 @@ public class Delombok {
compiler.initProcessAnnotations(Collections.singleton(new lombok.javac.apt.Processor()));
for (File fileToParse : filesToParse) {
-
- @SuppressWarnings("deprecation")
- JCCompilationUnit unit = compiler.parse(fileToParse.getAbsolutePath());
-
+ @SuppressWarnings("deprecation") JCCompilationUnit unit = compiler.parse(fileToParse.getAbsolutePath());
baseMap.put(unit, fileToBase.get(fileToParse));
roots.add(unit);
}
@@ -387,8 +383,17 @@ public class Delombok {
return false;
}
- JavaCompiler delegate = compiler.processAnnotations(compiler.enterTrees(toJavacList(roots)));
- callFlowMethodOnJavaCompiler(delegate, callAttributeMethodOnJavaCompiler(delegate, delegate.todo));
+ for (JCCompilationUnit unit : roots) {
+ catcher.setComments(unit, new DocCommentIntegrator().integrate(catcher.getComments(unit), unit));
+ }
+
+ com.sun.tools.javac.util.List<JCCompilationUnit> trees = compiler.enterTrees(toJavacList(roots));
+
+ JavaCompiler delegate = compiler.processAnnotations(trees);
+
+ Object care = callAttributeMethodOnJavaCompiler(delegate, delegate.todo);
+
+ callFlowMethodOnJavaCompiler(delegate, care);
for (JCCompilationUnit unit : roots) {
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");
diff --git a/src/delombok/lombok/delombok/DelombokApp.java b/src/delombok/lombok/delombok/DelombokApp.java
index e0d6ef1c..276bd7de 100644
--- a/src/delombok/lombok/delombok/DelombokApp.java
+++ b/src/delombok/lombok/delombok/DelombokApp.java
@@ -84,10 +84,9 @@ public class DelombokApp extends LombokApp {
return null;
}
- @SuppressWarnings("resource")
// The jar file is used for the lifetime of the classLoader, therefore the lifetime of delombok.
// Since we only read from it, not closing it should not be a problem.
- final JarFile toolsJarFile = new JarFile(toolsJar);
+ @SuppressWarnings({"resource", "all"}) final JarFile toolsJarFile = new JarFile(toolsJar);
ClassLoader loader = new ClassLoader() {
private Class<?> loadStreamAsClass(String name, boolean resolve, InputStream in) throws ClassNotFoundException {
diff --git a/src/delombok/lombok/delombok/DocCommentIntegrator.java b/src/delombok/lombok/delombok/DocCommentIntegrator.java
new file mode 100644
index 00000000..0955a003
--- /dev/null
+++ b/src/delombok/lombok/delombok/DocCommentIntegrator.java
@@ -0,0 +1,127 @@
+package lombok.delombok;
+
+import java.util.ArrayList;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Map;
+import java.util.regex.Pattern;
+
+import lombok.javac.CommentInfo;
+import lombok.javac.Javac;
+import lombok.javac.handlers.JavacHandlerUtil;
+
+import com.sun.tools.javac.parser.Tokens.Comment;
+import com.sun.tools.javac.tree.DocCommentTable;
+import com.sun.tools.javac.tree.JCTree;
+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;
+
+public class DocCommentIntegrator {
+ /**
+ * Returns the same comment list as when this integrator was created, minus all doc comments that have been successfully integrated into the compilation unit.
+ */
+ public List<CommentInfo> integrate(List<CommentInfo> comments, JCCompilationUnit unit) {
+ List<CommentInfo> out = new ArrayList<CommentInfo>();
+ CommentInfo lastExcisedComment = null;
+ JCTree lastNode = null;
+
+ for (CommentInfo cmt : comments) {
+ if (!cmt.isJavadoc()) {
+ out.add(cmt);
+ continue;
+ }
+
+ JCTree node = findJavadocableNodeOnOrAfter(unit, cmt.endPos);
+ if (node == null) {
+ out.add(cmt);
+ continue;
+ }
+
+ if (node == lastNode) {
+ out.add(lastExcisedComment);
+ }
+ if (!attach(unit, node, cmt)) {
+ out.add(cmt);
+ } else {
+ lastNode = node;
+ lastExcisedComment = cmt;
+ }
+ }
+ return out;
+ }
+
+ private static final Pattern CONTENT_STRIPPER = Pattern.compile("^(?:\\s*\\*)?[ \\t]*(.*?)$", Pattern.MULTILINE);
+ @SuppressWarnings("unchecked") private boolean attach(JCCompilationUnit top, final JCTree node, CommentInfo cmt) {
+ String docCommentContent = cmt.content;
+ if (docCommentContent.startsWith("/**")) docCommentContent = docCommentContent.substring(3);
+ if (docCommentContent.endsWith("*/")) docCommentContent = docCommentContent.substring(0, docCommentContent.length() -2);
+ docCommentContent = CONTENT_STRIPPER.matcher(docCommentContent).replaceAll("$1");
+ docCommentContent = docCommentContent.trim();
+
+ if (Javac.getDocComments(top) == null) Javac.initDocComments(top);
+
+ Object map_ = Javac.getDocComments(top);
+ if (map_ instanceof Map) {
+ ((Map<JCTree, String>) map_).put(node, docCommentContent);
+ return true;
+ } else if (Javac.instanceOfDocCommentTable(map_)) {
+ CommentAttacher_8.attach(node, docCommentContent, map_);
+ return true;
+ }
+
+ return false;
+ }
+
+ /* Container for code which will cause class loader exceptions on javac below 8. By being in a separate class, we avoid the problem. */
+ private static class CommentAttacher_8 {
+ static void attach(final JCTree node, String docCommentContent, Object map_) {
+ final String docCommentContent_ = docCommentContent;
+ ((DocCommentTable) map_).putComment(node, new Comment() {
+ @Override public String getText() {
+ return docCommentContent_;
+ }
+
+ @Override public int getSourcePos(int index) {
+ return -1;
+ }
+
+ @Override public CommentStyle getStyle() {
+ return CommentStyle.JAVADOC;
+ }
+
+ @Override public boolean isDeprecated() {
+ return JavacHandlerUtil.nodeHasDeprecatedFlag(node);
+ }
+ });
+ }
+ }
+
+ private JCTree findJavadocableNodeOnOrAfter(JCCompilationUnit unit, int endPos) {
+ if (unit.pid != null && endPos <= unit.pid.pos) return null;
+ Iterator<JCTree> it = unit.defs.iterator();
+
+ while (it.hasNext()) {
+ JCTree node = it.next();
+ if (node.pos < endPos) {
+ if (node instanceof JCClassDecl) {
+ com.sun.tools.javac.util.List<JCTree> defs = ((JCClassDecl) node).defs;
+ if (!defs.isEmpty()) while (!defs.tail.isEmpty()) defs = defs.tail;
+ if (defs.head != null && defs.head.pos >= endPos) {
+ // The associated node is IN this class declaration, so, replace the iterator.
+ // There's no point looking beyond this member in the current iteration 'context'
+ // so we don't need to save the old ref. Just start over inside this type declaration.
+ it = ((JCClassDecl) node).defs.iterator();
+ }
+ }
+ continue;
+ }
+
+ if (node instanceof JCMethodDecl || node instanceof JCClassDecl || node instanceof JCVariableDecl) return node;
+ return null;
+ }
+
+ return null;
+ }
+}
diff --git a/src/delombok/lombok/delombok/LombokOptionsFactory.java b/src/delombok/lombok/delombok/LombokOptionsFactory.java
new file mode 100644
index 00000000..e581593f
--- /dev/null
+++ b/src/delombok/lombok/delombok/LombokOptionsFactory.java
@@ -0,0 +1,57 @@
+/*
+ * Copyright (C) 2013 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.delombok;
+
+import lombok.javac.Javac;
+import lombok.javac.Javac6BasedLombokOptions;
+import lombok.javac.Javac8BasedLombokOptions;
+import lombok.javac.LombokOptions;
+
+import com.sun.tools.javac.util.Context;
+
+public class LombokOptionsFactory {
+ enum LombokOptionCompilerVersion {
+ JDK7_AND_LOWER {
+ @Override LombokOptions createAndRegisterOptions(Context context) {
+ return Javac6BasedLombokOptions.replaceWithDelombokOptions(context);
+ }
+ },
+
+ JDK8 {
+ @Override LombokOptions createAndRegisterOptions(Context context) {
+ return Javac8BasedLombokOptions.replaceWithDelombokOptions(context);
+ }
+ };
+
+ abstract LombokOptions createAndRegisterOptions(Context context);
+ }
+
+ public static LombokOptions getDelombokOptions(Context context) {
+ LombokOptions options;
+ if (Javac.getJavaCompilerVersion() < 8) {
+ options = LombokOptionCompilerVersion.JDK7_AND_LOWER.createAndRegisterOptions(context);
+ } else {
+ options = LombokOptionCompilerVersion.JDK8.createAndRegisterOptions(context);
+ }
+ return options;
+ }
+}
diff --git a/src/delombok/lombok/delombok/PrettyCommentsPrinter.java b/src/delombok/lombok/delombok/PrettyCommentsPrinter.java
index 1bb2ce23..f9152e68 100644
--- a/src/delombok/lombok/delombok/PrettyCommentsPrinter.java
+++ b/src/delombok/lombok/delombok/PrettyCommentsPrinter.java
@@ -29,34 +29,27 @@
*/
package lombok.delombok;
-import static com.sun.tools.javac.code.Flags.ANNOTATION;
-import static com.sun.tools.javac.code.Flags.ENUM;
-import static com.sun.tools.javac.code.Flags.INTERFACE;
-import static com.sun.tools.javac.code.Flags.SYNTHETIC;
-import static com.sun.tools.javac.code.Flags.StandardFlags;
-import static com.sun.tools.javac.code.Flags.VARARGS;
+import static com.sun.tools.javac.code.Flags.*;
+import static lombok.javac.Javac.*;
+import static lombok.javac.JavacTreeMaker.TreeTag.treeTag;
+import static lombok.javac.JavacTreeMaker.TypeTag.typeTag;
import java.io.IOException;
import java.io.Writer;
import java.lang.reflect.Field;
-import java.lang.reflect.InvocationTargetException;
-import java.lang.reflect.Method;
import java.util.HashMap;
import java.util.Map;
import lombok.javac.CommentInfo;
-import lombok.javac.Javac;
import lombok.javac.CommentInfo.EndConnection;
import lombok.javac.CommentInfo.StartConnection;
+import lombok.javac.JavacTreeMaker.TreeTag;
+import lombok.javac.JavacTreeMaker.TypeTag;
import com.sun.source.tree.Tree;
-import com.sun.tools.javac.code.BoundKind;
import com.sun.tools.javac.code.Flags;
import com.sun.tools.javac.code.Symbol;
-import com.sun.tools.javac.code.TypeTags;
import com.sun.tools.javac.tree.JCTree;
-import com.sun.tools.javac.tree.TreeInfo;
-import com.sun.tools.javac.tree.TreeScanner;
import com.sun.tools.javac.tree.JCTree.JCAnnotation;
import com.sun.tools.javac.tree.JCTree.JCArrayAccess;
import com.sun.tools.javac.tree.JCTree.JCArrayTypeTree;
@@ -108,10 +101,14 @@ import com.sun.tools.javac.tree.JCTree.JCWhileLoop;
import com.sun.tools.javac.tree.JCTree.JCWildcard;
import com.sun.tools.javac.tree.JCTree.LetExpr;
import com.sun.tools.javac.tree.JCTree.TypeBoundKind;
+import com.sun.tools.javac.tree.DocCommentTable;
+import com.sun.tools.javac.tree.TreeInfo;
+import com.sun.tools.javac.tree.TreeScanner;
import com.sun.tools.javac.util.Convert;
import com.sun.tools.javac.util.List;
import com.sun.tools.javac.util.Name;
import com.sun.tools.javac.util.Position;
+//import com.sun.tools.javac.code.TypeTags;
/** Prints out a tree as an indented Java source program.
*
@@ -122,214 +119,177 @@ import com.sun.tools.javac.util.Position;
*/
@SuppressWarnings("all") // Mainly sun code that has other warning settings
public class PrettyCommentsPrinter extends JCTree.Visitor {
-
- private static final Method GET_TAG_METHOD;
- private static final Field TAG_FIELD;
+ private static final TreeTag PARENS = treeTag("PARENS");
+ private static final TreeTag IMPORT = treeTag("IMPORT");
+ private static final TreeTag VARDEF = treeTag("VARDEF");
+ private static final TreeTag SELECT = treeTag("SELECT");
- private static final int PARENS = Javac.getCtcInt(JCTree.class, "PARENS");
- private static final int IMPORT = Javac.getCtcInt(JCTree.class, "IMPORT");
- private static final int VARDEF = Javac.getCtcInt(JCTree.class, "VARDEF");
- private static final int SELECT = Javac.getCtcInt(JCTree.class, "SELECT");
-
- private static final Map<Integer, String> OPERATORS;
+ private static final Map<TreeTag, String> OPERATORS;
static {
- Method m = null;
- Field f = null;
- try {
- m = JCTree.class.getDeclaredMethod("getTag");
- }
- catch (NoSuchMethodException e) {
- try {
- f = JCTree.class.getDeclaredField("tag");
- }
- catch (NoSuchFieldException e1) {
- e1.printStackTrace();
- }
- }
- GET_TAG_METHOD = m;
- TAG_FIELD = f;
-
- Map<Integer, String> map = new HashMap<Integer, String>();
-
- map.put(Javac.getCtcInt(JCTree.class, "POS"), "+");
- map.put(Javac.getCtcInt(JCTree.class, "NEG"), "-");
- map.put(Javac.getCtcInt(JCTree.class, "NOT"), "!");
- map.put(Javac.getCtcInt(JCTree.class, "COMPL"), "~");
- map.put(Javac.getCtcInt(JCTree.class, "PREINC"), "++");
- map.put(Javac.getCtcInt(JCTree.class, "PREDEC"), "--");
- map.put(Javac.getCtcInt(JCTree.class, "POSTINC"), "++");
- map.put(Javac.getCtcInt(JCTree.class, "POSTDEC"), "--");
- map.put(Javac.getCtcInt(JCTree.class, "NULLCHK"), "<*nullchk*>");
- map.put(Javac.getCtcInt(JCTree.class, "OR"), "||");
- map.put(Javac.getCtcInt(JCTree.class, "AND"), "&&");
- map.put(Javac.getCtcInt(JCTree.class, "EQ"), "==");
- map.put(Javac.getCtcInt(JCTree.class, "NE"), "!=");
- map.put(Javac.getCtcInt(JCTree.class, "LT"), "<");
- map.put(Javac.getCtcInt(JCTree.class, "GT"), ">");
- map.put(Javac.getCtcInt(JCTree.class, "LE"), "<=");
- map.put(Javac.getCtcInt(JCTree.class, "GE"), ">=");
- map.put(Javac.getCtcInt(JCTree.class, "BITOR"), "|");
- map.put(Javac.getCtcInt(JCTree.class, "BITXOR"), "^");
- map.put(Javac.getCtcInt(JCTree.class, "BITAND"), "&");
- map.put(Javac.getCtcInt(JCTree.class, "SL"), "<<");
- map.put(Javac.getCtcInt(JCTree.class, "SR"), ">>");
- map.put(Javac.getCtcInt(JCTree.class, "USR"), ">>>");
- map.put(Javac.getCtcInt(JCTree.class, "PLUS"), "+");
- map.put(Javac.getCtcInt(JCTree.class, "MINUS"), "-");
- map.put(Javac.getCtcInt(JCTree.class, "MUL"), "*");
- map.put(Javac.getCtcInt(JCTree.class, "DIV"), "/");
- map.put(Javac.getCtcInt(JCTree.class, "MOD"), "%");
-
- OPERATORS = map;
+ Map<TreeTag, String> map = new HashMap<TreeTag, String>();
+
+ map.put(treeTag("POS"), "+");
+ map.put(treeTag("NEG"), "-");
+ map.put(treeTag("NOT"), "!");
+ map.put(treeTag("COMPL"), "~");
+ map.put(treeTag("PREINC"), "++");
+ map.put(treeTag("PREDEC"), "--");
+ map.put(treeTag("POSTINC"), "++");
+ map.put(treeTag("POSTDEC"), "--");
+ map.put(treeTag("NULLCHK"), "<*nullchk*>");
+ map.put(treeTag("OR"), "||");
+ map.put(treeTag("AND"), "&&");
+ map.put(treeTag("EQ"), "==");
+ map.put(treeTag("NE"), "!=");
+ map.put(treeTag("LT"), "<");
+ map.put(treeTag("GT"), ">");
+ map.put(treeTag("LE"), "<=");
+ map.put(treeTag("GE"), ">=");
+ map.put(treeTag("BITOR"), "|");
+ map.put(treeTag("BITXOR"), "^");
+ map.put(treeTag("BITAND"), "&");
+ map.put(treeTag("SL"), "<<");
+ map.put(treeTag("SR"), ">>");
+ map.put(treeTag("USR"), ">>>");
+ map.put(treeTag("PLUS"), "+");
+ map.put(treeTag("MINUS"), "-");
+ map.put(treeTag("MUL"), "*");
+ map.put(treeTag("DIV"), "/");
+ map.put(treeTag("MOD"), "%");
+
+ map.put(treeTag("BITOR_ASG"), "|=");
+ map.put(treeTag("BITXOR_ASG"), "^=");
+ map.put(treeTag("BITAND_ASG"), "&=");
+ map.put(treeTag("SL_ASG"), "<<=");
+ map.put(treeTag("SR_ASG"), ">>=");
+ map.put(treeTag("USR_ASG"), ">>>=");
+ map.put(treeTag("PLUS_ASG"), "+=");
+ map.put(treeTag("MINUS_ASG"), "-=");
+ map.put(treeTag("MUL_ASG"), "*=");
+ map.put(treeTag("DIV_ASG"), "/=");
+ map.put(treeTag("MOD_ASG"), "%=");
+
+ OPERATORS = map;
}
- static int getTag(JCTree tree) {
- if (GET_TAG_METHOD != null) {
- try {
- return (Integer)GET_TAG_METHOD.invoke(tree);
- }
- catch (IllegalAccessException e) {
- throw new RuntimeException(e);
- }
- catch (InvocationTargetException e) {
- throw new RuntimeException(e.getCause());
- }
- }
- try {
- return TAG_FIELD.getInt(tree);
- }
- catch (IllegalAccessException e) {
- throw new RuntimeException(e);
- }
- }
-
- private List<CommentInfo> comments;
- private final JCCompilationUnit cu;
- private boolean onNewLine = true;
- private boolean aligned = false;
- private boolean inParams = false;
-
- private boolean needsSpace = false;
- private boolean needsNewLine = false;
- private boolean needsAlign = false;
-
+ private List<CommentInfo> comments;
+ private final JCCompilationUnit cu;
+ private boolean onNewLine = true;
+ private boolean aligned = false;
+ private boolean inParams = false;
+
+ private boolean needsSpace = false;
+ private boolean needsNewLine = false;
+ private boolean needsAlign = false;
+
public PrettyCommentsPrinter(Writer out, JCCompilationUnit cu, List<CommentInfo> comments) {
this.out = out;
- this.comments = comments;
- this.cu = cu;
+ this.comments = comments;
+ this.cu = cu;
}
-
- private int endPos(JCTree tree) {
- return tree.getEndPosition(cu.endPositions);
- }
- private void consumeComments(int until) throws IOException {
- consumeComments(until, null);
- }
- private void consumeComments(int until, JCTree tree) throws IOException {
- boolean prevNewLine = onNewLine;
- boolean found = false;
- CommentInfo head = comments.head;
- while (comments.nonEmpty() && head.pos < until) {
- if (tree != null && docComments != null && docComments.containsKey(tree) && head.isJavadoc() && noFurtherJavadocForthcoming(until)) {
- // This is (presumably) the exact same javadoc that has already been associated with the node that we're just about to
- // print. These javadoc can be modified by lombok handlers, and as such we should NOT print them from the consumed comments db,
- // and instead print the actual javadoc associated with the upcoming node (which the visit method for that node will take care of).
- } else {
- printComment(head);
- }
- comments = comments.tail;
- head = comments.head;
- }
- if (!onNewLine && prevNewLine) {
- println();
- }
- }
+ private int endPos(JCTree tree) {
+ return getEndPosition(tree, cu);
+ }
- private boolean noFurtherJavadocForthcoming(int until) {
- List<CommentInfo> c = comments;
- if (c.nonEmpty()) c = c.tail;
- while (c.nonEmpty()) {
- if (c.head.pos >= until) return true;
- if (c.head.isJavadoc()) return false;
- c = c.tail;
- }
- return true;
+ private void consumeComments(int until) throws IOException {
+ consumeComments(until, null);
}
-
+
+ private void consumeComments(int until, JCTree tree) throws IOException {
+ boolean prevNewLine = onNewLine;
+ boolean found = false;
+ CommentInfo head = comments.head;
+ while (comments.nonEmpty() && head.pos < until) {
+ printComment(head);
+ comments = comments.tail;
+ head = comments.head;
+ }
+ if (!onNewLine && prevNewLine) {
+ println();
+ }
+ }
+
private void consumeTrailingComments(int from) throws IOException {
- boolean prevNewLine = onNewLine;
- CommentInfo head = comments.head;
- boolean stop = false;
- while (comments.nonEmpty() && head.prevEndPos == from && !stop && !(head.start == StartConnection.ON_NEXT_LINE || head.start == StartConnection.START_OF_LINE)) {
- from = head.endPos;
- printComment(head);
- stop = (head.end == EndConnection.ON_NEXT_LINE);
- comments = comments.tail;
- head = comments.head;
- }
- if (!onNewLine && prevNewLine) {
- println();
- }
- }
-
- private void printComment(CommentInfo comment) throws IOException {
- prepareComment(comment.start);
- print(comment.content);
- switch (comment.end) {
- case ON_NEXT_LINE:
- if (!aligned) {
- needsNewLine = true;
- needsAlign = true;
- }
- break;
- case AFTER_COMMENT:
- needsSpace = true;
- break;
- case DIRECT_AFTER_COMMENT:
- // do nothing
- break;
- }
+ boolean prevNewLine = onNewLine;
+ CommentInfo head = comments.head;
+ boolean stop = false;
+ while (comments.nonEmpty() && head.prevEndPos == from && !stop && !(head.start == StartConnection.ON_NEXT_LINE || head.start == StartConnection.START_OF_LINE)) {
+ from = head.endPos;
+ printComment(head);
+ stop = (head.end == EndConnection.ON_NEXT_LINE);
+ comments = comments.tail;
+ head = comments.head;
+ }
+ if (!onNewLine && prevNewLine) {
+ println();
+ }
+ }
+
+ private void printComment(CommentInfo comment) throws IOException {
+ prepareComment(comment.start);
+ print(comment.content);
+ switch (comment.end) {
+ case ON_NEXT_LINE:
+ if (!aligned) {
+ needsNewLine = true;
+ needsAlign = true;
+ }
+ break;
+ case AFTER_COMMENT:
+ needsSpace = true;
+ break;
+ case DIRECT_AFTER_COMMENT:
+ // do nothing
+ break;
+ }
+ }
+
+ private void prepareComment(StartConnection start) throws IOException {
+ switch (start) {
+ case DIRECT_AFTER_PREVIOUS:
+ needsSpace = false;
+ break;
+ case AFTER_PREVIOUS:
+ needsSpace = true;
+ break;
+ case START_OF_LINE:
+ needsNewLine = true;
+ needsAlign = false;
+ break;
+ case ON_NEXT_LINE:
+ if (!aligned) {
+ needsNewLine = true;
+ needsAlign = true;
+ }
+ break;
+ }
}
-
- private void prepareComment(StartConnection start) throws IOException {
- switch (start) {
- case DIRECT_AFTER_PREVIOUS:
- needsSpace = false;
- break;
- case AFTER_PREVIOUS:
- needsSpace = true;
- break;
- case START_OF_LINE:
- needsNewLine = true;
- needsAlign = false;
- break;
- case ON_NEXT_LINE:
- if (!aligned) {
- needsNewLine = true;
- needsAlign = true;
- }
- break;
- }
- }
/** The output stream on which trees are printed.
*/
Writer out;
-
+
/** The current left margin.
*/
int lmargin = 0;
-
+
/** The enclosing class name.
*/
Name enclClassName;
-
+
/** A hashtable mapping trees to their documentation comments
* (can be null)
*/
Map<JCTree, String> docComments = null;
+ DocCommentTable docTable = null;
+
+ String getJavadocFor(JCTree node) {
+ if (docComments != null) return docComments.get(node);
+ if (docTable != null) return docTable.getCommentText(node);
+ return null;
+ }
/** Align code to be indented to left margin.
*/
@@ -339,19 +299,19 @@ public class PrettyCommentsPrinter extends JCTree.Visitor {
needsAlign = false;
for (int i = 0; i < lmargin; i++) out.write("\t");
}
-
+
/** Increase left margin by indentation width.
*/
void indent() {
lmargin++;
}
-
+
/** Decrease left margin by indentation width.
*/
void undent() {
lmargin--;
}
-
+
/** Enter a new precedence level. Emit a `(' if new precedence level
* is less than precedence level so far.
* @param contextPrec The precedence level in force so far.
@@ -360,7 +320,7 @@ public class PrettyCommentsPrinter extends JCTree.Visitor {
void open(int contextPrec, int ownPrec) throws IOException {
if (ownPrec < contextPrec) out.write("(");
}
-
+
/** Leave precedence level. Emit a `(' if inner precedence level
* is less than precedence level we revert to.
* @param contextPrec The precedence level we revert to.
@@ -369,7 +329,7 @@ public class PrettyCommentsPrinter extends JCTree.Visitor {
void close(int contextPrec, int ownPrec) throws IOException {
if (ownPrec < contextPrec) out.write(")");
}
-
+
/** Print string, replacing all non-ascii character with unicode escapes.
*/
public void print(Object s) throws IOException {
@@ -524,31 +484,28 @@ public class PrettyCommentsPrinter extends JCTree.Visitor {
* @param tree The tree for which a documentation comment should be printed.
*/
public void printDocComment(JCTree tree) throws IOException {
- if (docComments != null) {
- String dc = docComments.get(tree);
- if (dc != null) {
- print("/**"); println();
- int pos = 0;
- int endpos = lineEndPos(dc, pos);
- boolean atStart = true;
- while (pos < dc.length()) {
- String line = dc.substring(pos, endpos);
- if (line.trim().isEmpty() && atStart) {
- atStart = false;
- continue;
- }
- atStart = false;
- align();
- print(" *");
- if (pos < dc.length() && dc.charAt(pos) > ' ') print(" ");
- print(dc.substring(pos, endpos)); println();
- pos = endpos + 1;
- endpos = lineEndPos(dc, pos);
- }
- align(); print(" */"); println();
- align();
+ String dc = getJavadocFor(tree);
+ if (dc == null) return;
+ print("/**"); println();
+ int pos = 0;
+ int endpos = lineEndPos(dc, pos);
+ boolean atStart = true;
+ while (pos < dc.length()) {
+ String line = dc.substring(pos, endpos);
+ if (line.trim().isEmpty() && atStart) {
+ atStart = false;
+ continue;
}
+ atStart = false;
+ align();
+ print(" *");
+ if (pos < dc.length() && dc.charAt(pos) > ' ') print(" ");
+ print(dc.substring(pos, endpos)); println();
+ pos = endpos + 1;
+ endpos = lineEndPos(dc, pos);
}
+ align(); print(" */"); println();
+ align();
}
//where
static int lineEndPos(String s, int start) {
@@ -633,7 +590,7 @@ public class PrettyCommentsPrinter extends JCTree.Visitor {
/** Is the given tree an enumerator definition? */
boolean isEnumerator(JCTree t) {
- return getTag(t) == VARDEF && (((JCVariableDecl) t).mods.flags & ENUM) != 0;
+ return VARDEF.equals(treeTag(t)) && (((JCVariableDecl) t).mods.flags & ENUM) != 0;
}
/** Print unit consisting of package clause and import statements in toplevel,
@@ -644,7 +601,9 @@ public class PrettyCommentsPrinter extends JCTree.Visitor {
* toplevel tree.
*/
public void printUnit(JCCompilationUnit tree, JCClassDecl cdef) throws IOException {
- docComments = tree.docComments;
+ Object dc = getDocComments(tree);
+ if (dc instanceof Map) this.docComments = (Map) dc;
+ else if (dc instanceof DocCommentTable) this.docTable = (DocCommentTable) dc;
printDocComment(tree);
if (tree.pid != null) {
consumeComments(tree.pos, tree);
@@ -655,9 +614,9 @@ public class PrettyCommentsPrinter extends JCTree.Visitor {
}
boolean firstImport = true;
for (List<JCTree> l = tree.defs;
- l.nonEmpty() && (cdef == null || getTag(l.head) == IMPORT);
+ l.nonEmpty() && (cdef == null || IMPORT.equals(treeTag(l.head)));
l = l.tail) {
- if (getTag(l.head) == IMPORT) {
+ if (IMPORT.equals(treeTag(l.head))) {
JCImport imp = (JCImport)l.head;
Name name = TreeInfo.name(imp.qualid);
if (name == name.table.fromChars(new char[] {'*'}, 0, 1) ||
@@ -741,9 +700,9 @@ public class PrettyCommentsPrinter extends JCTree.Visitor {
else
print("class " + tree.name);
printTypeParameters(tree.typarams);
- if (tree.getExtendsClause() != null) {
+ if (getExtendsClause(tree) != null) {
print(" extends ");
- printExpr(tree.getExtendsClause());
+ printExpr(getExtendsClause(tree));
}
if (tree.implementing.nonEmpty()) {
print(" implements ");
@@ -826,7 +785,7 @@ public class PrettyCommentsPrinter extends JCTree.Visitor {
public void visitVarDef(JCVariableDecl tree) {
try {
- if (docComments != null && docComments.get(tree) != null) {
+ if (getJavadocFor(tree) != null) {
println(); align();
}
printDocComment(tree);
@@ -876,7 +835,7 @@ public class PrettyCommentsPrinter extends JCTree.Visitor {
printStat(tree.body);
align();
print(" while ");
- if (getTag(tree.cond) == PARENS) {
+ if (PARENS.equals(treeTag(tree.cond))) {
printExpr(tree.cond);
} else {
print("(");
@@ -892,7 +851,7 @@ public class PrettyCommentsPrinter extends JCTree.Visitor {
public void visitWhileLoop(JCWhileLoop tree) {
try {
print("while ");
- if (getTag(tree.cond) == PARENS) {
+ if (PARENS.equals(treeTag(tree.cond))) {
printExpr(tree.cond);
} else {
print("(");
@@ -910,7 +869,7 @@ public class PrettyCommentsPrinter extends JCTree.Visitor {
try {
print("for (");
if (tree.init.nonEmpty()) {
- if (getTag(tree.init.head) == VARDEF) {
+ if (VARDEF.equals(treeTag(tree.init.head))) {
printExpr(tree.init.head);
for (List<JCStatement> l = tree.init.tail; l.nonEmpty(); l = l.tail) {
JCVariableDecl vdef = (JCVariableDecl)l.head;
@@ -957,7 +916,7 @@ public class PrettyCommentsPrinter extends JCTree.Visitor {
public void visitSwitch(JCSwitch tree) {
try {
print("switch ");
- if (getTag(tree.selector) == PARENS) {
+ if (PARENS.equals(treeTag(tree.selector))) {
printExpr(tree.selector);
} else {
print("(");
@@ -996,7 +955,7 @@ public class PrettyCommentsPrinter extends JCTree.Visitor {
public void visitSynchronized(JCSynchronized tree) {
try {
print("synchronized ");
- if (getTag(tree.lock) == PARENS) {
+ if (PARENS.equals(treeTag(tree.lock))) {
printExpr(tree.lock);
} else {
print("(");
@@ -1077,7 +1036,7 @@ public class PrettyCommentsPrinter extends JCTree.Visitor {
public void visitIf(JCIf tree) {
try {
print("if ");
- if (getTag(tree.cond) == PARENS) {
+ if (PARENS.equals(treeTag(tree.cond))) {
printExpr(tree.cond);
} else {
print("(");
@@ -1173,7 +1132,7 @@ public class PrettyCommentsPrinter extends JCTree.Visitor {
public void visitApply(JCMethodInvocation tree) {
try {
if (!tree.typeargs.isEmpty()) {
- if (getTag(tree.meth) == SELECT) {
+ if (SELECT.equals(treeTag(tree.meth))) {
JCFieldAccess left = (JCFieldAccess)tree.meth;
printExpr(left.selected);
print(".<");
@@ -1277,7 +1236,7 @@ public class PrettyCommentsPrinter extends JCTree.Visitor {
}
}
- public String operatorName(int tag) {
+ public String operatorName(TreeTag tag) {
String result = OPERATORS.get(tag);
if (result == null) throw new Error();
return result;
@@ -1287,7 +1246,8 @@ public class PrettyCommentsPrinter extends JCTree.Visitor {
try {
open(prec, TreeInfo.assignopPrec);
printExpr(tree.lhs, TreeInfo.assignopPrec + 1);
- print(" " + operatorName(getTag(tree) - JCTree.ASGOffset) + "= ");
+ String opname = operatorName(treeTag(tree));
+ print(" " + opname + " ");
printExpr(tree.rhs, TreeInfo.assignopPrec);
close(prec, TreeInfo.assignopPrec);
} catch (IOException e) {
@@ -1297,10 +1257,10 @@ public class PrettyCommentsPrinter extends JCTree.Visitor {
public void visitUnary(JCUnary tree) {
try {
- int ownprec = TreeInfo.opPrec(getTag(tree));
- String opname = operatorName(getTag(tree));
+ int ownprec = isOwnPrec(tree);
+ String opname = operatorName(treeTag(tree));
open(prec, ownprec);
- if (getTag(tree) <= Javac.getCtcInt(JCTree.class, "PREDEC")) {
+ if (isPrefixUnary(tree)) {
print(opname);
printExpr(tree.arg, ownprec);
} else {
@@ -1312,11 +1272,19 @@ public class PrettyCommentsPrinter extends JCTree.Visitor {
throw new UncheckedIOException(e);
}
}
-
+
+ private int isOwnPrec(JCExpression tree) {
+ return treeTag(tree).getOperatorPrecedenceLevel();
+ }
+
+ private boolean isPrefixUnary(JCUnary tree) {
+ return treeTag(tree).isPrefixUnaryOp();
+ }
+
public void visitBinary(JCBinary tree) {
try {
- int ownprec = TreeInfo.opPrec(getTag(tree));
- String opname = operatorName(getTag(tree));
+ int ownprec = isOwnPrec(tree);
+ String opname = operatorName(treeTag(tree));
open(prec, ownprec);
printExpr(tree.lhs, ownprec);
print(" " + opname + " ");
@@ -1381,78 +1349,39 @@ public class PrettyCommentsPrinter extends JCTree.Visitor {
}
public void visitLiteral(JCLiteral tree) {
+ TypeTag typeTag = typeTag(tree);
try {
- switch (tree.typetag) {
- case TypeTags.INT:
- print(tree.value.toString());
- break;
- case TypeTags.LONG:
- print(tree.value + "L");
- break;
- case TypeTags.FLOAT:
- print(tree.value + "F");
- break;
- case TypeTags.DOUBLE:
- print(tree.value.toString());
- break;
- case TypeTags.CHAR:
- print("\'" +
- Convert.quote(
- String.valueOf((char)((Number)tree.value).intValue())) +
- "\'");
- break;
- case TypeTags.BOOLEAN:
- print(((Number)tree.value).intValue() == 1 ? "true" : "false");
- break;
- case TypeTags.BOT:
- print("null");
- break;
- default:
- print("\"" + Convert.quote(tree.value.toString()) + "\"");
- break;
+ if (CTC_INT.equals(typeTag)) print(tree.value.toString());
+ else if (CTC_LONG.equals(typeTag)) print(tree.value + "L");
+ else if (CTC_FLOAT.equals(typeTag)) print(tree.value + "F");
+ else if (CTC_DOUBLE.equals(typeTag)) print(tree.value.toString());
+ else if (CTC_CHAR.equals(typeTag)) {
+ print("\'" + Convert.quote(String.valueOf((char)((Number)tree.value).intValue())) + "\'");
}
+ else if (CTC_BOOLEAN.equals(typeTag)) print(((Number)tree.value).intValue() == 1 ? "true" : "false");
+ else if (CTC_BOT.equals(typeTag)) print("null");
+ else print("\"" + Convert.quote(tree.value.toString()) + "\"");
} catch (IOException e) {
throw new UncheckedIOException(e);
}
}
- public void visitTypeIdent(JCPrimitiveTypeTree tree) {
- try {
- switch(tree.typetag) {
- case TypeTags.BYTE:
- print("byte");
- break;
- case TypeTags.CHAR:
- print("char");
- break;
- case TypeTags.SHORT:
- print("short");
- break;
- case TypeTags.INT:
- print("int");
- break;
- case TypeTags.LONG:
- print("long");
- break;
- case TypeTags.FLOAT:
- print("float");
- break;
- case TypeTags.DOUBLE:
- print("double");
- break;
- case TypeTags.BOOLEAN:
- print("boolean");
- break;
- case TypeTags.VOID:
- print("void");
- break;
- default:
- print("error");
- break;
- }
- } catch (IOException e) {
- throw new UncheckedIOException(e);
- }
+ public void visitTypeIdent(JCPrimitiveTypeTree tree) {
+ TypeTag typetag = typeTag(tree);
+ try {
+ if (CTC_BYTE.equals(typetag)) print ("byte");
+ else if (CTC_CHAR.equals(typetag)) print ("char");
+ else if (CTC_SHORT.equals(typetag)) print ("short");
+ else if (CTC_INT.equals(typetag)) print ("int");
+ else if (CTC_LONG.equals(typetag)) print ("long");
+ else if (CTC_FLOAT.equals(typetag)) print ("float");
+ else if (CTC_DOUBLE.equals(typetag)) print ("double");
+ else if (CTC_BOOLEAN.equals(typetag)) print ("boolean");
+ else if (CTC_VOID.equals(typetag)) print ("void");
+ else print("error");
+ } catch (IOException e) {
+ throw new UncheckedIOException(e);
+ }
}
public void visitTypeArray(JCArrayTypeTree tree) {