diff --git a/build.xml b/build.xml index 151ffa261..3914c3ade 100644 --- a/build.xml +++ b/build.xml @@ -32,6 +32,8 @@ + + @@ -405,8 +407,7 @@ For users of JDK 1.5 at least version 1.6.2 of Ant is required. - + location="${basedir}/src/testinputs/com/puppycrawl/tools/checkstyle"/> + + TreeWalker instance. */ public TreeWalker() { setFileExtensions(new String[]{"java"}); + // Tree walker can use two possible algorithms for + // tree processing (iterative and recursive. + // Recursive is default for now. + String recursive = + System.getProperty("checkstyle.use.recursive.algorithm", "true"); + mRecursive = "true".equals(recursive); + if (mRecursive) { + Utils.getExceptionLogger() + .debug("TreeWalker uses recursive algorithm"); + } + else { + Utils.getExceptionLogger() + .debug("TreeWalker uses iterative algorithm"); + } } /** @param aTabWidth the distance between tab stops */ @@ -389,7 +408,12 @@ public final class TreeWalker // empty files are not flagged by javac, will yield aAST == null if (aAST != null) { - process(aAST); + if (useRecursiveAlgorithm()) { + processRec(aAST); + } + else { + processIter(aAST); + } } notifyEnd(aAST); @@ -426,9 +450,10 @@ public final class TreeWalker /** * Recursively processes a node calling interested checks at each node. + * Uses recursive algorithm. * @param aAST the node to start from */ - private void process(DetailAST aAST) + private void processRec(DetailAST aAST) { if (aAST == null) { return; @@ -438,16 +463,15 @@ public final class TreeWalker final DetailAST child = (DetailAST) aAST.getFirstChild(); if (child != null) { - process(child); + processRec(child); } notifyLeave(aAST); final DetailAST sibling = (DetailAST) aAST.getNextSibling(); if (sibling != null) { - process(sibling); + processRec(sibling); } - } /** @@ -570,4 +594,34 @@ public final class TreeWalker super.destroy(); } + /** + * @return true if we should use recursive algorithm + * for tree processing, false for iterative one. + */ + private boolean useRecursiveAlgorithm() + { + return mRecursive; + } + + /** + * Processes a node calling interested checks at each node. + * Uses iterative algorithm. + * @param aRoot the root of tree for process + */ + private void processIter(DetailAST aRoot) + { + DetailAST curNode = aRoot; + while (curNode != null) { + notifyVisit(curNode); + DetailAST toVisit = (DetailAST) curNode.getFirstChild(); + while (curNode != null && toVisit == null) { + notifyLeave(curNode); + toVisit = (DetailAST) curNode.getNextSibling(); + if (toVisit == null) { + curNode = curNode.getParent(); + } + } + curNode = toVisit; + } + } } diff --git a/src/tests/com/puppycrawl/tools/checkstyle/PackageNamesLoaderTest.java b/src/tests/com/puppycrawl/tools/checkstyle/PackageNamesLoaderTest.java index 5070090ca..e2083d8e5 100644 --- a/src/tests/com/puppycrawl/tools/checkstyle/PackageNamesLoaderTest.java +++ b/src/tests/com/puppycrawl/tools/checkstyle/PackageNamesLoaderTest.java @@ -42,7 +42,8 @@ public class PackageNamesLoaderTest extends TestCase { final ModuleFactory moduleFactory = PackageNamesLoader.loadModuleFactory( - "src/checkstyle/com/puppycrawl/tools/checkstyle/checkstyle_packages.xml"); + System.getProperty("checkstyle.root") + + "/src/checkstyle/com/puppycrawl/tools/checkstyle/checkstyle_packages.xml"); validateFactory(moduleFactory); } diff --git a/src/tests/com/puppycrawl/tools/checkstyle/filters/SuppressionsLoaderTest.java b/src/tests/com/puppycrawl/tools/checkstyle/filters/SuppressionsLoaderTest.java index 82cdc5004..dd8641833 100644 --- a/src/tests/com/puppycrawl/tools/checkstyle/filters/SuppressionsLoaderTest.java +++ b/src/tests/com/puppycrawl/tools/checkstyle/filters/SuppressionsLoaderTest.java @@ -17,7 +17,8 @@ public class SuppressionsLoaderTest extends TestCase { final FilterSet fc = SuppressionsLoader.loadSuppressions( - "src/testinputs/com/puppycrawl/tools/checkstyle/suppressions_none.xml"); + System.getProperty("testinputs.dir") + + "/suppressions_none.xml"); final FilterSet fc2 = new FilterSet(); assertEquals(fc, fc2); } @@ -27,7 +28,8 @@ public class SuppressionsLoaderTest extends TestCase { final FilterSet fc = SuppressionsLoader.loadSuppressions( - "src/testinputs/com/puppycrawl/tools/checkstyle/suppressions_multiple.xml"); + System.getProperty("testinputs.dir") + + "/suppressions_multiple.xml"); final FilterSet fc2 = new FilterSet(); SuppressElement se0 = new SuppressElement("file0", "check0"); fc2.addFilter(se0); @@ -47,13 +49,14 @@ public class SuppressionsLoaderTest extends TestCase public void testNoFile() throws CheckstyleException { + final String fn = System.getProperty("testinputs.dir") + + "/suppressions_no_file.xml"; try { - SuppressionsLoader.loadSuppressions( - "src/testinputs/com/puppycrawl/tools/checkstyle/suppressions_no_file.xml"); + SuppressionsLoader.loadSuppressions(fn); } catch (CheckstyleException ex) { assertEquals( - "unable to parse src/testinputs/com/puppycrawl/tools/checkstyle/suppressions_no_file.xml - Attribute \"files\" is required and must be specified for element type \"suppress\".", + "unable to parse " + fn + " - Attribute \"files\" is required and must be specified for element type \"suppress\".", ex.getMessage()); } } @@ -61,13 +64,14 @@ public class SuppressionsLoaderTest extends TestCase public void testNoCheck() throws CheckstyleException { + final String fn = System.getProperty("testinputs.dir") + + "/suppressions_no_check.xml"; try { - SuppressionsLoader.loadSuppressions( - "src/testinputs/com/puppycrawl/tools/checkstyle/suppressions_no_check.xml"); + SuppressionsLoader.loadSuppressions(fn); } catch (CheckstyleException ex) { assertEquals( - "unable to parse src/testinputs/com/puppycrawl/tools/checkstyle/suppressions_no_check.xml - Attribute \"checks\" is required and must be specified for element type \"suppress\".", + "unable to parse " + fn + " - Attribute \"checks\" is required and must be specified for element type \"suppress\".", ex.getMessage()); } } @@ -75,14 +79,15 @@ public class SuppressionsLoaderTest extends TestCase public void testBadInt() throws CheckstyleException { + final String fn = System.getProperty("testinputs.dir") + + "/suppressions_bad_int.xml"; try { - SuppressionsLoader.loadSuppressions( - "src/testinputs/com/puppycrawl/tools/checkstyle/suppressions_bad_int.xml"); + SuppressionsLoader.loadSuppressions(fn); } catch (CheckstyleException ex) { assertTrue( ex.getMessage(), - ex.getMessage().startsWith("number format exception src/testinputs/com/puppycrawl/tools/checkstyle/suppressions_bad_int.xml - ")); + ex.getMessage().startsWith("number format exception " + fn + " - ")); } } }