aboutsummaryrefslogtreecommitdiff
path: root/src/lombok/core/AST.java
diff options
context:
space:
mode:
authorReinier Zwitserloot <reinier@tipit.to>2009-06-28 05:44:11 +0200
committerReinier Zwitserloot <reinier@tipit.to>2009-06-28 05:44:11 +0200
commit71f67e1f65ca1a90b60555075c67194e8a1db752 (patch)
tree2d843965d70e53825324f0e2c966b20c9e8049db /src/lombok/core/AST.java
parentb4cab3f65c854ba4bda03528a87bff7654ccb817 (diff)
downloadlombok-71f67e1f65ca1a90b60555075c67194e8a1db752.tar.gz
lombok-71f67e1f65ca1a90b60555075c67194e8a1db752.tar.bz2
lombok-71f67e1f65ca1a90b60555075c67194e8a1db752.zip
Added rebuild support to AST.Node.
Diffstat (limited to 'src/lombok/core/AST.java')
-rw-r--r--src/lombok/core/AST.java58
1 files changed, 53 insertions, 5 deletions
diff --git a/src/lombok/core/AST.java b/src/lombok/core/AST.java
index 8e060f07..871f24be 100644
--- a/src/lombok/core/AST.java
+++ b/src/lombok/core/AST.java
@@ -71,6 +71,25 @@ public abstract class AST<N> {
return nodeMap.get(node);
}
+ @SuppressWarnings("unchecked")
+ private Node replaceNewWithExistingOld(Map<N, Node> oldNodes, Node newNode) {
+ Node oldNode = oldNodes.get(newNode.get());
+ if ( oldNode == null ) return newNode;
+
+ List<Object> oldChildren = new ArrayList<Object>();
+ for ( Node child : newNode.children ) {
+ Node oldChild = replaceNewWithExistingOld(oldNodes, child);
+ if ( oldChild == null ) oldChildren.add(child);
+ else {
+ oldChildren.add(oldChild);
+ oldChild.parent = oldNode;
+ }
+ }
+
+ oldNode.children.addAll((Collection) oldChildren);
+ return oldNode;
+ }
+
public abstract class Node {
protected final Kind kind;
protected final N node;
@@ -87,6 +106,11 @@ public abstract class AST<N> {
this.isStructurallySignificant = calculateIsStructurallySignificant();
}
+ @Override public String toString() {
+ return String.format("NODE %s (%s) %s%s",
+ kind, node == null ? "(NULL)" : node.getClass(), handled ? "[HANDLED]" : "", node == null ? "" : node);
+ }
+
public String getPackageDeclaration() {
return AST.this.getPackageDeclaration();
}
@@ -162,6 +186,29 @@ public abstract class AST<N> {
return n;
}
+ /**
+ * Reparses the AST node represented by this node. Any existing nodes that occupy a different space in the AST are rehomed, any
+ * nodes that no longer exist are removed, and new nodes are created.
+ *
+ * Careful - the node you call this on must not itself have been removed or rehomed - it rebuilds <i>all children</i>.
+ */
+ public void rebuild() {
+ Map<N, Node> oldNodes = new HashMap<N, Node>();
+ gatherAndRemoveChildren(oldNodes);
+
+ Node newNode = buildTree(get(), kind);
+
+ replaceNewWithExistingOld(oldNodes, newNode);
+ }
+
+ private void gatherAndRemoveChildren(Map<N, Node> map) {
+ for ( Node child : children ) child.gatherAndRemoveChildren(map);
+ map.put(get(), this);
+ children.clear();
+ identityDetector.remove(get());
+ nodeMap.remove(get());
+ }
+
public void removeChild(Node child) {
children.remove(child);
}
@@ -254,12 +301,13 @@ public abstract class AST<N> {
return list;
}
+ @SuppressWarnings("unchecked")
private <T extends Node> void buildWithField0(Class<T> nodeType, N child, FieldAccess fa, Collection<T> list) {
try {
Object o = fa.field.get(child);
if ( o == null ) return;
if ( fa.dim == 0 ) {
- Node node = buildStatement(o);
+ Node node = buildTree((N)o, Kind.STATEMENT);
if ( node != null ) list.add(nodeType.cast(node));
} else if ( o.getClass().isArray() ) buildWithArray(nodeType, o, list, fa.dim);
else if ( Collection.class.isInstance(o) ) buildWithCollection(nodeType, o, list, fa.dim);
@@ -268,10 +316,11 @@ public abstract class AST<N> {
}
}
+ @SuppressWarnings("unchecked")
private <T extends Node> void buildWithArray(Class<T> nodeType, Object array, Collection<T> list, int dim) {
if ( dim == 1 ) for ( Object v : (Object[])array ) {
if ( v == null ) continue;
- Node node = buildStatement(v);
+ Node node = buildTree((N)v, Kind.STATEMENT);
if ( node != null ) list.add(nodeType.cast(node));
} else for ( Object v : (Object[])array ) {
if ( v == null ) return;
@@ -279,15 +328,14 @@ public abstract class AST<N> {
}
}
+ @SuppressWarnings("unchecked")
private <T extends Node> void buildWithCollection(Class<T> nodeType, Object collection, Collection<T> list, int dim) {
if ( dim == 1 ) for ( Object v : (Collection<?>)collection ) {
if ( v == null ) continue;
- Node node = buildStatement(v);
+ Node node = buildTree((N)v, Kind.STATEMENT);
if ( node != null ) list.add(nodeType.cast(node));
} else for ( Object v : (Collection<?>)collection ) {
buildWithCollection(nodeType, v, list, dim-1);
}
}
-
- protected abstract Node buildStatement(Object statement);
}