diff --git a/src/checkstyle/com/puppycrawl/tools/checkstyle/TreeWalker.java b/src/checkstyle/com/puppycrawl/tools/checkstyle/TreeWalker.java index 736f981f1..c2ab3eb8a 100644 --- a/src/checkstyle/com/puppycrawl/tools/checkstyle/TreeWalker.java +++ b/src/checkstyle/com/puppycrawl/tools/checkstyle/TreeWalker.java @@ -22,7 +22,6 @@ import java.io.File; import java.io.FileNotFoundException; import java.io.IOException; import java.io.Reader; -import java.lang.reflect.Field; import java.util.ArrayList; import java.util.Arrays; import java.util.HashMap; @@ -118,12 +117,6 @@ public final class TreeWalker /** context of child components */ private Context mChildContext; - /** - * HACK - a reference to a private "mParent" field in DetailAST. - * Don't do this at home! - */ - private Field mDetailASTmParent; - /** a factory for creating submodules (i.e. the Checks) */ private ModuleFactory mModuleFactory; @@ -133,21 +126,6 @@ public final class TreeWalker public TreeWalker() { setFileExtensions(new String[]{"java"}); - - // TODO: I (lkuehne) can't believe I wrote this! HACK HACK HACK! - - // the parent relationship should really be managed by the DetailAST - // itself but ANTLR calls setFirstChild and friends in an - // unpredictable way. Introducing this hack for now to make - // DetailsAST.setParent() private... - try { - mDetailASTmParent = DetailAST.class.getDeclaredField("mParent"); - // this will fail in environments with security managers - mDetailASTmParent.setAccessible(true); - } - catch (NoSuchFieldException e) { - mDetailASTmParent = null; - } } /** @param aTabWidth the distance between tab stops */ @@ -355,31 +333,12 @@ public final class TreeWalker // empty files are not flagged by javac, will yield aAST == null if (aAST != null) { - setParent(aAST, null); // TODO: Manage parent in DetailAST process(aAST); } notifyEnd(aAST); } - /** - * Sets the parent of an AST. - * @param aChildAST the child that gets a new parent - * @param aParentAST the new parent - */ - // TODO: remove this method and manage parent in DetailAST - private void setParent(DetailAST aChildAST, DetailAST aParentAST) - { - // HACK - try { - mDetailASTmParent.set(aChildAST, aParentAST); - } - catch (IllegalAccessException iae) { - // can't happen because method has been made accesible - throw new RuntimeException(); - } - // End of HACK - } /** * Notify interested checks that about to begin walking a tree. @@ -423,7 +382,6 @@ public final class TreeWalker final DetailAST child = (DetailAST) aAST.getFirstChild(); if (child != null) { - setParent(child, aAST); // TODO: Manage parent in DetailAST process(child); } @@ -431,7 +389,6 @@ public final class TreeWalker final DetailAST sibling = (DetailAST) aAST.getNextSibling(); if (sibling != null) { - setParent(sibling, aAST.getParent()); // TODO: Manage parent ... process(sibling); } diff --git a/src/checkstyle/com/puppycrawl/tools/checkstyle/api/DetailAST.java b/src/checkstyle/com/puppycrawl/tools/checkstyle/api/DetailAST.java index cd29871cf..9113b264b 100644 --- a/src/checkstyle/com/puppycrawl/tools/checkstyle/api/DetailAST.java +++ b/src/checkstyle/com/puppycrawl/tools/checkstyle/api/DetailAST.java @@ -85,9 +85,34 @@ public final class DetailAST { mChildCount = NOT_INITIALIZED; super.setFirstChild(aAST); + if (aAST != null) { + ((DetailAST) aAST).setParent(this); + } } + /** + * Sets AST's next sibling + * @param aAST the new next sibling + */ + public void setNextSibling(AST aAST) + { + super.setNextSibling(aAST); + if (aAST != null && mParent != null) { + ((DetailAST) aAST).setParent(mParent); + } + } + /** + * Adds new child to AST + * @param aAST the new child + */ + public void addChild(AST aAST) + { + super.addChild(aAST); + if (aAST != null) { + ((DetailAST) aAST).setParent(this); + } + } /** * Returns the number of child nodes one level below this node. That is is @@ -120,6 +145,10 @@ public final class DetailAST // TODO: Check visibility, could be private // if set in setFirstChild() and friends mParent = aParent; + DetailAST nextSibling = (DetailAST) getNextSibling(); + if (nextSibling != null) { + nextSibling.setParent(aParent); + } } /**