aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/core/lombok/javac/JavacAST.java2
-rw-r--r--src/core/lombok/javac/JavacNode.java9
-rw-r--r--src/core/lombok/javac/handlers/JavacHandlerUtil.java12
-rw-r--r--src/delombok/lombok/delombok/PrettyCommentsPrinter.java225
-rw-r--r--src/utils/lombok/javac/JavacTreeMaker.java58
5 files changed, 184 insertions, 122 deletions
diff --git a/src/core/lombok/javac/JavacAST.java b/src/core/lombok/javac/JavacAST.java
index 1f3b04a4..e49d8ac8 100644
--- a/src/core/lombok/javac/JavacAST.java
+++ b/src/core/lombok/javac/JavacAST.java
@@ -375,7 +375,7 @@ public class JavacAST extends AST<JavacAST, JavacNode, JCTree> {
if (pos == null) pos = astObject.pos();
}
if (pos != null && attemptToRemoveErrorsInRange) {
- removeFromDeferredDiagnostics(pos.getStartPosition(), pos.getEndPosition(top.endPositions));
+ removeFromDeferredDiagnostics(pos.getStartPosition(), node.getEndPosition(pos));
}
try {
switch (kind) {
diff --git a/src/core/lombok/javac/JavacNode.java b/src/core/lombok/javac/JavacNode.java
index 30a470a9..6eef36eb 100644
--- a/src/core/lombok/javac/JavacNode.java
+++ b/src/core/lombok/javac/JavacNode.java
@@ -51,6 +51,15 @@ public class JavacNode extends lombok.core.LombokNode<JavacAST, JavacNode, JCTre
super(ast, node, children, kind);
}
+ public int getEndPosition(DiagnosticPosition pos) {
+ JCCompilationUnit cu = (JCCompilationUnit) top().get();
+ return Javac.getEndPosition(pos, cu);
+ }
+
+ public int getEndPosition() {
+ return getEndPosition(node);
+ }
+
/**
* Visits this node and all child nodes depth-first, calling the provided visitor's visit methods.
*/
diff --git a/src/core/lombok/javac/handlers/JavacHandlerUtil.java b/src/core/lombok/javac/handlers/JavacHandlerUtil.java
index d0673c57..c245d506 100644
--- a/src/core/lombok/javac/handlers/JavacHandlerUtil.java
+++ b/src/core/lombok/javac/handlers/JavacHandlerUtil.java
@@ -44,6 +44,7 @@ import lombok.core.AnnotationValues.AnnotationValue;
import lombok.core.TransformationsUtil;
import lombok.core.TypeResolver;
import lombok.experimental.Accessors;
+import lombok.javac.Javac;
import lombok.javac.JavacNode;
import lombok.javac.JavacTreeMaker;
@@ -1275,17 +1276,20 @@ public class JavacHandlerUtil {
*
* in 'SETTER' mode, stripping works similarly to 'GETTER' mode, except {@code param} are copied and stripped from the original and {@code @return} are skipped.
*/
+ @SuppressWarnings("unchecked")
public static void copyJavadoc(JavacNode from, JCTree to, CopyJavadoc copyMode) {
if (copyMode == null) copyMode = CopyJavadoc.VERBATIM;
try {
JCCompilationUnit cu = ((JCCompilationUnit) from.top().get());
- if (cu.docComments != null) {
- String javadoc = cu.docComments.get(from.get());
+ Object dc = Javac.getDocComments(cu);
+ if (dc instanceof Map) {
+ Map<JCTree, String> docComments = (Map<JCTree, String>) dc;
+ String javadoc = docComments.get(from.get());
if (javadoc != null) {
String[] filtered = copyMode.split(javadoc);
- cu.docComments.put(to, filtered[0]);
- cu.docComments.put(from.get(), filtered[1]);
+ docComments.put(to, filtered[0]);
+ docComments.put(from.get(), filtered[1]);
}
}
} catch (Exception ignore) {}
diff --git a/src/delombok/lombok/delombok/PrettyCommentsPrinter.java b/src/delombok/lombok/delombok/PrettyCommentsPrinter.java
index fd0b0f0d..9978a681 100644
--- a/src/delombok/lombok/delombok/PrettyCommentsPrinter.java
+++ b/src/delombok/lombok/delombok/PrettyCommentsPrinter.java
@@ -131,12 +131,12 @@ public class PrettyCommentsPrinter extends JCTree.Visitor {
private static final TreeTag IMPORT = treeTag("IMPORT");
private static final TreeTag VARDEF = treeTag("VARDEF");
private static final TreeTag SELECT = treeTag("SELECT");
-
+
private static final Map<TreeTag, String> OPERATORS;
static {
- Map<TreeTag, String> map = new HashMap<TreeTag, String>();
-
+ Map<TreeTag, String> map = new HashMap<TreeTag, String>();
+
map.put(treeTag("POS"), "+");
map.put(treeTag("NEG"), "-");
map.put(treeTag("NOT"), "!");
@@ -165,132 +165,133 @@ public class PrettyCommentsPrinter extends JCTree.Visitor {
map.put(treeTag("MUL"), "*");
map.put(treeTag("DIV"), "/");
map.put(treeTag("MOD"), "%");
-
- OPERATORS = map;
+
+ OPERATORS = map;
}
- 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 getEndPosition(tree, cu);
+ }
+
+ private void consumeComments(int until) throws IOException {
+ consumeComments(until, null);
}
-
- 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();
- }
- }
+ 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 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;
+ 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;
- 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)
*/
@@ -304,19 +305,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.
@@ -325,7 +326,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.
@@ -334,7 +335,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 {
diff --git a/src/utils/lombok/javac/JavacTreeMaker.java b/src/utils/lombok/javac/JavacTreeMaker.java
index edbf55af..12baf5af 100644
--- a/src/utils/lombok/javac/JavacTreeMaker.java
+++ b/src/utils/lombok/javac/JavacTreeMaker.java
@@ -116,6 +116,18 @@ public class JavacTreeMaker {
this.paramTypes = types;
this.returnType = returnType;
}
+
+ @Override public String toString() {
+ StringBuilder out = new StringBuilder();
+ out.append(returnType.getName()).append(" ").append(owner.getName()).append(".").append(name).append("(");
+ boolean f = true;
+ for (Class<?> p : paramTypes) {
+ if (f) f = false;
+ else out.append(", ");
+ out.append(p.getName());
+ }
+ return out.append(")").toString();
+ }
}
private static class SchroedingerType {
@@ -154,13 +166,23 @@ public class JavacTreeMaker {
return value;
}
- static Object getFieldCached(ConcurrentMap<Class<?>, Field> cache, Object ref, String fieldName) {
+ private static Field NOSUCHFIELDEX_MARKER;
+ static {
+ try {
+ NOSUCHFIELDEX_MARKER = SchroedingerType.class.getDeclaredField("NOSUCHFIELDEX_MARKER");
+ } catch (NoSuchFieldException e) {
+ throw Javac.sneakyThrow(e);
+ }
+ }
+
+ static Object getFieldCached(ConcurrentMap<Class<?>, Field> cache, Object ref, String fieldName) throws NoSuchFieldException {
Class<?> c = ref.getClass();
Field field = cache.get(c);
if (field == null) {
try {
field = c.getField(fieldName);
} catch (NoSuchFieldException e) {
+ cache.putIfAbsent(c, NOSUCHFIELDEX_MARKER);
throw Javac.sneakyThrow(e);
}
field.setAccessible(true);
@@ -168,6 +190,7 @@ public class JavacTreeMaker {
if (old != null) field = old;
}
+ if (field == NOSUCHFIELDEX_MARKER) throw new NoSuchFieldException(fieldName);
try {
return field.get(ref);
} catch (IllegalAccessException e) {
@@ -179,17 +202,42 @@ public class JavacTreeMaker {
public static class TypeTag extends SchroedingerType {
private static final ConcurrentMap<String, Object> TYPE_TAG_CACHE = new ConcurrentHashMap<String, Object>();
private static final ConcurrentMap<Class<?>, Field> FIELD_CACHE = new ConcurrentHashMap<Class<?>, Field>();
+ private static final Method TYPE_TYPETAG_METHOD;
+
+ static {
+ Method m = null;
+ try {
+ m = Type.class.getDeclaredMethod("getTag");
+ m.setAccessible(true);
+ } catch (NoSuchMethodException e) {}
+ TYPE_TYPETAG_METHOD = m;
+ }
private TypeTag(Object value) {
super(value);
}
public static TypeTag typeTag(JCTree o) {
- return new TypeTag(getFieldCached(FIELD_CACHE, o, "typetag"));
+ try {
+ return new TypeTag(getFieldCached(FIELD_CACHE, o, "typetag"));
+ } catch (NoSuchFieldException e) {
+ throw Javac.sneakyThrow(e);
+ }
}
public static TypeTag typeTag(Type t) {
- return new TypeTag(getFieldCached(FIELD_CACHE, t, "tag"));
+ try {
+ return new TypeTag(getFieldCached(FIELD_CACHE, t, "tag"));
+ } catch (NoSuchFieldException e) {
+ if (TYPE_TYPETAG_METHOD == null) throw new IllegalStateException("Type " + t.getClass() + " has neither 'tag' nor getTag()");
+ try {
+ return new TypeTag(TYPE_TYPETAG_METHOD.invoke(t));
+ } catch (IllegalAccessException ex) {
+ throw Javac.sneakyThrow(ex);
+ } catch (InvocationTargetException ex) {
+ throw Javac.sneakyThrow(ex.getCause());
+ }
+ }
}
public static TypeTag typeTag(String identifier) {
@@ -331,7 +379,7 @@ public class JavacTreeMaker {
if (found == null) found = method;
else throw new IllegalStateException("Lombok TreeMaker frontend issue: multiple matches when looking for method: " + m);
}
- if (found == null) throw new IllegalStateException("Lombok TreeMaker frontedn issue: no match when looking for method: " + m);
+ if (found == null) throw new IllegalStateException("Lombok TreeMaker frontend issue: no match when looking for method: " + m);
found.setAccessible(true);
Object marker = METHOD_CACHE.putIfAbsent(m, found);
if (marker == null) return found;
@@ -496,7 +544,7 @@ public class JavacTreeMaker {
//javac versions: 6-8
private static final MethodId<JCThrow> Throw = MethodId("Throw");
- public JCThrow Throw(JCTree expr) {
+ public JCThrow Throw(JCExpression expr) {
return invoke(Throw, expr);
}