diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/delombok/lombok/delombok/Delombok.java | 4 | ||||
-rw-r--r-- | src/delombok/lombok/delombok/DocCommentIntegrator.java | 97 | ||||
-rw-r--r-- | src/delombok/lombok/delombok/PrettyCommentsPrinter.java | 42 | ||||
-rw-r--r-- | src/utils/lombok/javac/CommentCatcher.java | 13 | ||||
-rw-r--r-- | src/utils/lombok/javac/Javac.java | 11 |
5 files changed, 131 insertions, 36 deletions
diff --git a/src/delombok/lombok/delombok/Delombok.java b/src/delombok/lombok/delombok/Delombok.java index 1fae4560..0128e44f 100644 --- a/src/delombok/lombok/delombok/Delombok.java +++ b/src/delombok/lombok/delombok/Delombok.java @@ -383,6 +383,10 @@ public class Delombok { return false; } + 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); diff --git a/src/delombok/lombok/delombok/DocCommentIntegrator.java b/src/delombok/lombok/delombok/DocCommentIntegrator.java new file mode 100644 index 00000000..80aec16a --- /dev/null +++ b/src/delombok/lombok/delombok/DocCommentIntegrator.java @@ -0,0 +1,97 @@ +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 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, 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; + } + + return false; + } + + 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/PrettyCommentsPrinter.java b/src/delombok/lombok/delombok/PrettyCommentsPrinter.java index 9978a681..525773f4 100644 --- a/src/delombok/lombok/delombok/PrettyCommentsPrinter.java +++ b/src/delombok/lombok/delombok/PrettyCommentsPrinter.java @@ -29,18 +29,14 @@ */ 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; @@ -49,19 +45,11 @@ import lombok.javac.CommentInfo.EndConnection; import lombok.javac.CommentInfo.StartConnection; import lombok.javac.JavacTreeMaker.TreeTag; import lombok.javac.JavacTreeMaker.TypeTag; -import static lombok.javac.Javac.*; -import static lombok.javac.JavacTreeMaker.TreeTag.treeTag; -import static lombok.javac.JavacTreeMaker.TypeTag.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.main.JavaCompiler; 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; @@ -113,10 +101,13 @@ 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.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. * @@ -198,13 +189,7 @@ public class PrettyCommentsPrinter extends JCTree.Visitor { 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); - } + printComment(head); comments = comments.tail; head = comments.head; } @@ -213,17 +198,6 @@ public class PrettyCommentsPrinter extends JCTree.Visitor { } } - 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 consumeTrailingComments(int from) throws IOException { boolean prevNewLine = onNewLine; CommentInfo head = comments.head; diff --git a/src/utils/lombok/javac/CommentCatcher.java b/src/utils/lombok/javac/CommentCatcher.java index 48dd7e75..36d90e30 100644 --- a/src/utils/lombok/javac/CommentCatcher.java +++ b/src/utils/lombok/javac/CommentCatcher.java @@ -22,13 +22,14 @@ package lombok.javac; import java.lang.reflect.InvocationTargetException; +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; -import com.sun.tools.javac.util.List; public class CommentCatcher { private final JavaCompiler compiler; @@ -56,9 +57,17 @@ public class CommentCatcher { return compiler; } + public void setComments(JCCompilationUnit ast, List<CommentInfo> comments) { + if (comments != null) { + commentsMap.put(ast, comments); + } else { + commentsMap.remove(ast); + } + } + public List<CommentInfo> getComments(JCCompilationUnit ast) { List<CommentInfo> list = commentsMap.get(ast); - return list == null ? List.<CommentInfo>nil() : list; + return list == null ? Collections.<CommentInfo>emptyList() : list; } private static void registerCommentsCollectingScannerFactory(Context context) { diff --git a/src/utils/lombok/javac/Javac.java b/src/utils/lombok/javac/Javac.java index c90b8611..2f3c9be4 100644 --- a/src/utils/lombok/javac/Javac.java +++ b/src/utils/lombok/javac/Javac.java @@ -27,6 +27,7 @@ import static lombok.javac.JavacTreeMaker.TypeTag.typeTag; import java.lang.reflect.Field; import java.lang.reflect.InvocationTargetException; import java.lang.reflect.Method; +import java.util.HashMap; import java.util.concurrent.atomic.AtomicInteger; import java.util.regex.Matcher; import java.util.regex.Pattern; @@ -196,6 +197,16 @@ public class Javac { } } + public static void initDocComments(JCCompilationUnit cu) { + try { + JCCOMPILATIONUNIT_DOCCOMMENTS.set(cu, new HashMap<Object, String>()); + } catch (IllegalArgumentException e) { + // That's fine - we're on JDK8, we'll fix that later. + } catch (IllegalAccessException e) { + throw sneakyThrow(e); + } + } + public static int getEndPosition(DiagnosticPosition pos, JCCompilationUnit top) { try { Object endPositions = JCCOMPILATIONUNIT_ENDPOSITIONS.get(top); |