diff --git a/pmd/src/net/sourceforge/pmd/AbstractRuleChainVisitor.java b/pmd/src/net/sourceforge/pmd/AbstractRuleChainVisitor.java index 5f32d131b0..74e23010f2 100644 --- a/pmd/src/net/sourceforge/pmd/AbstractRuleChainVisitor.java +++ b/pmd/src/net/sourceforge/pmd/AbstractRuleChainVisitor.java @@ -9,11 +9,12 @@ import java.util.Map; import java.util.Set; import net.sourceforge.pmd.ast.SimpleNode; +import net.sourceforge.pmd.util.Benchmark; /** - * This is a base class for RuleChainVisitor implementations which performs - * extracts interesting nodes from an AST, and lets each Rule visit the nodes it - * has expressed interest in. + * This is a base class for RuleChainVisitor implementations which + * extracts interesting nodes from an AST, and lets each Rule visit + * the nodes it has expressed interest in. */ public abstract class AbstractRuleChainVisitor implements RuleChainVisitor { /** @@ -42,19 +43,27 @@ public abstract class AbstractRuleChainVisitor implements RuleChainVisitor { // Perform a visitation of the AST to index nodes which need visiting by // type + long start = Benchmark.nanoTime(); indexNodes(astCompilationUnits, ctx); + long end = Benchmark.nanoTime(); + Benchmark.mark(Benchmark.TYPE_RULE_CHAIN, "RuleChain Visit", end - start, 1); // For each rule, allow it to visit the nodes it desires + int visits = 0; + start = Benchmark.nanoTime(); for (int i = 0; i < rules.size(); i++) { final Rule rule = (Rule) rules.get(i); final List nodeNames = rule.getRuleChainVisits(); for (int j = 0; j < nodeNames.size(); j++) { - List nodes = (List) nodeNameToNodes.get((String) nodeNames - .get(j)); + List nodes = (List) nodeNameToNodes.get((String) nodeNames.get(j)); for (int k = 0; k < nodes.size(); k++) { visit(rule, (SimpleNode) nodes.get(k), ctx); } + visits += nodes.size(); } + end = Benchmark.nanoTime(); + Benchmark.mark(Benchmark.TYPE_RULE_CHAIN_RULE, rule.getName(), end - start, visits); + start = end; } } @@ -81,7 +90,10 @@ public abstract class AbstractRuleChainVisitor implements RuleChainVisitor { /** * Initialize the RuleChainVisitor to be ready to perform visitations. This * method should not be called until it is know that all Rules participating - * in the RuleChain are ready to be initialized themselves. + * in the RuleChain are ready to be initialized themselves. Some rules + * may require full initialization to determine if they will participate in + * the RuleChain, so this has been delayed as long as possible to ensure + * that manipulation of the Rules is no longer occuring. */ protected void initialize() { if (nodeNameToNodes != null) { @@ -95,16 +107,15 @@ public abstract class AbstractRuleChainVisitor implements RuleChainVisitor { if (rule.usesRuleChain()) { visitedNodes.addAll(rule.getRuleChainVisits()); } - // Drop rules which do not participate in the rule chain. else { - // i.remove(); + // Drop rules which do not participate in the rule chain. + i.remove(); } } // Setup the data structure to manage mapping node names to node - // instances. - // We intend to reuse this data structure between visits to different - // ASTs. + // instances. We intend to reuse this data structure between + // visits to different ASTs. nodeNameToNodes = new HashMap(); for (Iterator i = visitedNodes.iterator(); i.hasNext();) { List nodes = new ArrayList(100); diff --git a/pmd/src/net/sourceforge/pmd/RuleSet.java b/pmd/src/net/sourceforge/pmd/RuleSet.java index 5f23736b45..74f5dc052d 100644 --- a/pmd/src/net/sourceforge/pmd/RuleSet.java +++ b/pmd/src/net/sourceforge/pmd/RuleSet.java @@ -94,13 +94,14 @@ public class RuleSet { public void apply(List acuList, RuleContext ctx) { Iterator rs = rules.iterator(); + long start = Benchmark.nanoTime(); while (rs.hasNext()) { Rule rule = (Rule) rs.next(); if (!rule.usesRuleChain()) { - long start = Benchmark.nanoTime(); rule.apply(acuList, ctx); long end = Benchmark.nanoTime(); Benchmark.mark(Benchmark.TYPE_RULE, rule.getName(), end - start, 1); + start = end; } } } diff --git a/pmd/src/net/sourceforge/pmd/rules/XPathRule.java b/pmd/src/net/sourceforge/pmd/rules/XPathRule.java index 139e27c21d..5ace644441 100644 --- a/pmd/src/net/sourceforge/pmd/rules/XPathRule.java +++ b/pmd/src/net/sourceforge/pmd/rules/XPathRule.java @@ -60,7 +60,6 @@ public class XPathRule extends CommonAbstractRule { public void evaluate(Node compilationUnit, RuleContext data) { try { initializeXPathExpression(); - //String nodeName = compilationUnit.getClass().getName().replaceAll(".*\\.AST", ""); List xpaths = (List)nodeNameToXPaths.get(compilationUnit.toString()); if (xpaths == null) { xpaths = (List)nodeNameToXPaths.get(AST_ROOT); @@ -69,9 +68,7 @@ public class XPathRule extends CommonAbstractRule { XPath xpath = (XPath)xpaths.get(i); List results = xpath.selectNodes(compilationUnit); for (Iterator j = results.iterator(); j.hasNext();) { - //for (int j = 0; j < results.size(); j++) { SimpleNode n = (SimpleNode) j.next(); - //SimpleNode n = (SimpleNode)results.get(j); if (n instanceof ASTVariableDeclaratorId && getBooleanProperty("pluginname")) { addViolation(data, n, n.getImage()); } else { @@ -197,14 +194,13 @@ public class XPathRule extends CommonAbstractRule { } private BaseXPath createXPath(String xpathQueryString) throws JaxenException { - // TODO Need to fix Jaxen! It is not properly escaping the " character in String literals. + // TODO As of Jaxen 1.1, LiteralExpr which contain " or ' characters + // are not escaped properly. The following is fix for the known + // XPath queries built into PMD. It will not necessarily work for + // arbitrary XPath queries users of PMD will create. JAXEN-177 is + // about this problem: http://jira.codehaus.org/browse/JAXEN-177 + // PMD should upgrade to the next Jaxen release containing this fix. xpathQueryString = xpathQueryString.replaceAll("\"\"\"", "'\"'"); - // TODO Need to fix Jaxen! It is not properly formatting context variable references. - xpathQueryString = xpathQueryString.replaceAll("\\$:", "\\$"); - //System.out.println("xpathQueryString: " + xpathQueryString); - - // The following will make the queries look a bit more like one is used to seeing. - // System.out.println(xpathQueryString.replaceAll("child::node\\(\\)", ".").replaceAll("child::", "").replaceAll("attribute::", "@")); BaseXPath xpath = new BaseXPath(xpathQueryString, new DocumentNavigator()); if (properties.size() > 1) {