aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/delombok/lombok/delombok/Delombok.java4
-rw-r--r--src/delombok/lombok/delombok/DocCommentIntegrator.java97
-rw-r--r--src/delombok/lombok/delombok/PrettyCommentsPrinter.java42
-rw-r--r--src/utils/lombok/javac/CommentCatcher.java13
-rw-r--r--src/utils/lombok/javac/Javac.java11
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);