aboutsummaryrefslogtreecommitdiff
path: root/src/core/lombok
diff options
context:
space:
mode:
Diffstat (limited to 'src/core/lombok')
-rw-r--r--src/core/lombok/core/AST.java28
-rw-r--r--src/core/lombok/javac/JavacAST.java43
2 files changed, 59 insertions, 12 deletions
diff --git a/src/core/lombok/core/AST.java b/src/core/lombok/core/AST.java
index 30297418..e6721b80 100644
--- a/src/core/lombok/core/AST.java
+++ b/src/core/lombok/core/AST.java
@@ -54,7 +54,7 @@ public abstract class AST<A extends AST<A, L, N>, L extends LombokNode<A, L, N>,
private final String fileName;
private final String packageDeclaration;
private final ImportList imports;
- Map<N, Void> identityDetector = new IdentityHashMap<N, Void>();
+ Map<N, N> identityDetector = new IdentityHashMap<N, N>();
private Map<N, L> nodeMap = new IdentityHashMap<N, L>();
private boolean changed = false;
@@ -105,7 +105,7 @@ public abstract class AST<A extends AST<A, L, N>, L extends LombokNode<A, L, N>,
*/
protected L putInMap(L node) {
nodeMap.put(node.get(), node);
- identityDetector.put(node.get(), null);
+ identityDetector.put(node.get(), node.get());
return node;
}
@@ -117,7 +117,7 @@ public abstract class AST<A extends AST<A, L, N>, L extends LombokNode<A, L, N>,
/** Clears the registry that avoids endless loops, and empties the node map. The existing node map
* object is left untouched, and instead a new map is created. */
protected void clearState() {
- identityDetector = new IdentityHashMap<N, Void>();
+ identityDetector = new IdentityHashMap<N, N>();
nodeMap = new IdentityHashMap<N, L>();
}
@@ -127,9 +127,7 @@ public abstract class AST<A extends AST<A, L, N>, L extends LombokNode<A, L, N>,
* case you should do nothing lest the AST build process loops endlessly.
*/
protected boolean setAndGetAsHandled(N node) {
- if (identityDetector.containsKey(node)) return true;
- identityDetector.put(node, null);
- return false;
+ return identityDetector.put(node, node) != null;
}
public String getFileName() {
@@ -234,14 +232,12 @@ public abstract class AST<A extends AST<A, L, N>, L extends LombokNode<A, L, N>,
}
}
- for (Class<?> statementType : getStatementTypes()) {
- if (statementType.isAssignableFrom(t)) {
- f.setAccessible(true);
- fields.add(new FieldAccess(f, dim));
- break;
- }
+ if (shouldDrill(c, t, f.getName())) {
+ f.setAccessible(true);
+ fields.add(new FieldAccess(f, dim));
}
}
+
getFields(c.getSuperclass(), fields);
}
@@ -258,6 +254,14 @@ public abstract class AST<A extends AST<A, L, N>, L extends LombokNode<A, L, N>,
* though some platforms (such as Eclipse) group these under one common supertype. */
protected abstract Collection<Class<? extends N>> getStatementTypes();
+ protected boolean shouldDrill(Class<?> parentType, Class<?> childType, String fieldName) {
+ for (Class<?> statementType : getStatementTypes()) {
+ if (statementType.isAssignableFrom(childType)) return true;
+ }
+
+ return false;
+ }
+
/**
* buildTree implementation that uses reflection to find all child nodes by way of inspecting
* the fields. */
diff --git a/src/core/lombok/javac/JavacAST.java b/src/core/lombok/javac/JavacAST.java
index 8197dae6..5a91258c 100644
--- a/src/core/lombok/javac/JavacAST.java
+++ b/src/core/lombok/javac/JavacAST.java
@@ -24,6 +24,7 @@ package lombok.javac;
import java.lang.reflect.Field;
import java.util.ArrayList;
import java.util.Collection;
+import java.util.Collections;
import java.util.List;
import javax.annotation.processing.Messager;
@@ -39,6 +40,7 @@ import com.sun.tools.javac.model.JavacElements;
import com.sun.tools.javac.model.JavacTypes;
import com.sun.tools.javac.tree.JCTree;
import com.sun.tools.javac.tree.JCTree.JCCatch;
+import com.sun.tools.javac.tree.JCTree.JCTry;
import com.sun.tools.javac.tree.TreeMaker;
import com.sun.tools.javac.tree.JCTree.JCAnnotation;
import com.sun.tools.javac.tree.JCTree.JCBlock;
@@ -224,6 +226,46 @@ public class JavacAST extends AST<JavacAST, JavacNode, JCTree> {
return putInMap(new JavacNode(this, local, childNodes, kind));
}
+ private static boolean JCTRY_RESOURCES_FIELD_INITIALIZED;
+ private static Field JCTRY_RESOURCES_FIELD;
+
+ @SuppressWarnings("unchecked")
+ private static List<JCTree> getResourcesForTryNode(JCTry tryNode) {
+ if (!JCTRY_RESOURCES_FIELD_INITIALIZED) {
+ try {
+ JCTRY_RESOURCES_FIELD = JCTry.class.getField("resources");
+ } catch (NoSuchFieldException ignore) {
+ // Java 1.6 or lower won't have this at all.
+ } catch (Exception ignore) {
+ // Shouldn't happen. Best thing we can do is just carry on and break on try/catch.
+ }
+ JCTRY_RESOURCES_FIELD_INITIALIZED = true;
+ }
+
+ if (JCTRY_RESOURCES_FIELD == null) return Collections.emptyList();
+ Object rv = null;
+ try {
+ rv = JCTRY_RESOURCES_FIELD.get(tryNode);
+ } catch (Exception ignore) {}
+
+ if (rv instanceof List) return (List<JCTree>) rv;
+ return Collections.emptyList();
+ }
+
+ private JavacNode buildTry(JCTry tryNode) {
+ if (setAndGetAsHandled(tryNode)) return null;
+ List<JavacNode> childNodes = new ArrayList<JavacNode>();
+ for (JCTree varDecl : getResourcesForTryNode(tryNode)) {
+ if (varDecl instanceof JCVariableDecl) {
+ addIfNotNull(childNodes, buildLocalVar((JCVariableDecl) varDecl, Kind.LOCAL));
+ }
+ }
+ addIfNotNull(childNodes, buildStatement(tryNode.body));
+ for (JCCatch jcc : tryNode.catchers) addIfNotNull(childNodes, buildTree(jcc, Kind.STATEMENT));
+ addIfNotNull(childNodes, buildStatement(tryNode.finalizer));
+ return putInMap(new JavacNode(this, tryNode, childNodes, Kind.STATEMENT));
+ }
+
private JavacNode buildInitializer(JCBlock initializer) {
if (setAndGetAsHandled(initializer)) return null;
List<JavacNode> childNodes = new ArrayList<JavacNode>();
@@ -265,6 +307,7 @@ public class JavacAST extends AST<JavacAST, JavacNode, JCTree> {
if (statement instanceof JCAnnotation) return null;
if (statement instanceof JCClassDecl) return buildType((JCClassDecl)statement);
if (statement instanceof JCVariableDecl) return buildLocalVar((JCVariableDecl)statement, Kind.LOCAL);
+ if (statement instanceof JCTry) return buildTry((JCTry) statement);
if (setAndGetAsHandled(statement)) return null;