From fa9bf2e0ef561ab0e112157fd55c52ffac1b5715 Mon Sep 17 00:00:00 2001 From: Oleg Sukhodolsky Date: Sat, 23 Jul 2005 21:18:27 +0000 Subject: [PATCH] I tired from these horrable long stack traces, so I've added iterative implementation of tree processing, now we can activate it by setting checkstyle.use.recursive.algorithm to false (by default checkstyle still uses recursive algorithm). Also I've chenged build.xml so it will be possible to use it from any location and user will be able to specify filter for tests. --- build.xml | 8 ++- .../tools/checkstyle/TreeWalker.java | 64 +++++++++++++++++-- .../checkstyle/PackageNamesLoaderTest.java | 3 +- .../filters/SuppressionsLoaderTest.java | 27 ++++---- 4 files changed, 83 insertions(+), 19 deletions(-) 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 + " - ")); } } }