From 71f67e1f65ca1a90b60555075c67194e8a1db752 Mon Sep 17 00:00:00 2001 From: Reinier Zwitserloot Date: Sun, 28 Jun 2009 05:44:11 +0200 Subject: Added rebuild support to AST.Node. --- src/lombok/core/AST.java | 58 +++++++++++++++++++++++++++++++++++++++++++----- 1 file changed, 53 insertions(+), 5 deletions(-) (limited to 'src/lombok/core/AST.java') 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 { return nodeMap.get(node); } + @SuppressWarnings("unchecked") + private Node replaceNewWithExistingOld(Map oldNodes, Node newNode) { + Node oldNode = oldNodes.get(newNode.get()); + if ( oldNode == null ) return newNode; + + List oldChildren = new ArrayList(); + 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 { 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 { 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 all children. + */ + public void rebuild() { + Map oldNodes = new HashMap(); + gatherAndRemoveChildren(oldNodes); + + Node newNode = buildTree(get(), kind); + + replaceNewWithExistingOld(oldNodes, newNode); + } + + private void gatherAndRemoveChildren(Map 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 { return list; } + @SuppressWarnings("unchecked") private void buildWithField0(Class nodeType, N child, FieldAccess fa, Collection 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 { } } + @SuppressWarnings("unchecked") private void buildWithArray(Class nodeType, Object array, Collection 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 { } } + @SuppressWarnings("unchecked") private void buildWithCollection(Class nodeType, Object collection, Collection 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); } -- cgit