[core] saxon rulechain: consider boolean expr
This commit is contained in:
@ -38,13 +38,18 @@ public class RuleChainAnalyzer extends Visitor {
|
||||
private final Configuration configuration;
|
||||
private String rootElement;
|
||||
private boolean rootElementReplaced;
|
||||
private boolean insideLazyExpression;
|
||||
private boolean foundPathInsideLazy;
|
||||
|
||||
public RuleChainAnalyzer(Configuration currentConfiguration) {
|
||||
this.configuration = currentConfiguration;
|
||||
}
|
||||
|
||||
public String getRootElement() {
|
||||
return rootElement;
|
||||
if (!foundPathInsideLazy && rootElementReplaced) {
|
||||
return rootElement;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -56,7 +61,7 @@ public class RuleChainAnalyzer extends Visitor {
|
||||
|
||||
@Override
|
||||
public Expression visit(PathExpression e) {
|
||||
if (rootElement == null) {
|
||||
if (!insideLazyExpression && rootElement == null) {
|
||||
Expression result = super.visit(e);
|
||||
if (rootElement != null && !rootElementReplaced) {
|
||||
if (result instanceof PathExpression) {
|
||||
@ -80,6 +85,9 @@ public class RuleChainAnalyzer extends Visitor {
|
||||
}
|
||||
return result;
|
||||
} else {
|
||||
if (insideLazyExpression) {
|
||||
foundPathInsideLazy = true;
|
||||
}
|
||||
return super.visit(e);
|
||||
}
|
||||
}
|
||||
@ -99,11 +107,10 @@ public class RuleChainAnalyzer extends Visitor {
|
||||
|
||||
@Override
|
||||
public Expression visit(LazyExpression e) {
|
||||
if (e.getBaseExpression() instanceof PathExpression) {
|
||||
this.rootElement = null;
|
||||
return e;
|
||||
}
|
||||
return super.visit(e);
|
||||
insideLazyExpression = true;
|
||||
Expression result = super.visit(e);
|
||||
insideLazyExpression = false;
|
||||
return result;
|
||||
}
|
||||
|
||||
public static Comparator<Node> documentOrderComparator() {
|
||||
|
@ -5,6 +5,7 @@
|
||||
package net.sourceforge.pmd.lang.rule.xpath.internal;
|
||||
|
||||
import net.sf.saxon.expr.AxisExpression;
|
||||
import net.sf.saxon.expr.BooleanExpression;
|
||||
import net.sf.saxon.expr.Expression;
|
||||
import net.sf.saxon.expr.FilterExpression;
|
||||
import net.sf.saxon.expr.LazyExpression;
|
||||
@ -69,6 +70,13 @@ abstract class Visitor {
|
||||
return LazyExpression.makeLazyExpression(base);
|
||||
}
|
||||
|
||||
public Expression visit(BooleanExpression e) {
|
||||
final Expression[] operands = e.getOperands();
|
||||
Expression operand0 = visit(operands[0]);
|
||||
Expression operand1 = visit(operands[1]);
|
||||
return new BooleanExpression(operand0, e.getOperator(), operand1);
|
||||
}
|
||||
|
||||
public Expression visit(Expression expr) {
|
||||
Expression result;
|
||||
if (expr instanceof DocumentSorter) {
|
||||
@ -89,6 +97,8 @@ abstract class Visitor {
|
||||
result = visit((LetExpression) expr);
|
||||
} else if (expr instanceof LazyExpression) {
|
||||
result = visit((LazyExpression) expr);
|
||||
} else if (expr instanceof BooleanExpression) {
|
||||
result = visit((BooleanExpression) expr);
|
||||
} else {
|
||||
result = expr;
|
||||
}
|
||||
|
@ -70,7 +70,6 @@ public class SaxonXPathRuleQueryTest {
|
||||
Assert.assertEquals(1, ruleChainVisits.size());
|
||||
Assert.assertTrue(ruleChainVisits.contains("dummyNode"));
|
||||
Assert.assertEquals(2, query.nodeNameToXPaths.size());
|
||||
System.out.println(query.nodeNameToXPaths);
|
||||
assertExpression("(self::node()[pmd-dummy:typeIs(CardinalityChecker(ItemChecker(UntypedAtomicConverter(Atomizer(attribute::attribute(Image, xs:anyAtomicType))))))])", query.nodeNameToXPaths.get("dummyNode").get(0));
|
||||
assertExpression("DocumentSorter((((/)/descendant-or-self::node())/(child::element(dummyNode, xs:anyType)[pmd-dummy:typeIs(CardinalityChecker(ItemChecker(UntypedAtomicConverter(Atomizer(attribute::attribute(Image, xs:anyAtomicType))))))])))", query.nodeNameToXPaths.get(SaxonXPathRuleQuery.AST_ROOT).get(0));
|
||||
}
|
||||
@ -93,6 +92,13 @@ public class SaxonXPathRuleQueryTest {
|
||||
Assert.assertEquals(0, ruleChainVisits.size());
|
||||
Assert.assertEquals(1, query.nodeNameToXPaths.size());
|
||||
assertExpression("LetExpression(LazyExpression(((/)/descendant::element(ClassOrInterfaceType, xs:anyType))), (((/)/descendant::element(dummyNode, xs:anyType))[(ancestor::element(ClassOrInterfaceDeclaration, xs:anyType)[$zz:zz106374177])]))", query.nodeNameToXPaths.get(SaxonXPathRuleQuery.AST_ROOT).get(0));
|
||||
|
||||
// third example, with boolean expr
|
||||
query = createQuery("//dummyNode[//ClassOrInterfaceType or //OtherNode]");
|
||||
ruleChainVisits = query.getRuleChainVisits();
|
||||
Assert.assertEquals(0, ruleChainVisits.size());
|
||||
Assert.assertEquals(1, query.nodeNameToXPaths.size());
|
||||
assertExpression("LetExpression(LazyExpression((((/)/descendant::element(ClassOrInterfaceType, xs:anyType)) or ((/)/descendant::element(OtherNode, xs:anyType)))), (((/)/descendant::element(dummyNode, xs:anyType))[$zz:zz1364913072]))", query.nodeNameToXPaths.get(SaxonXPathRuleQuery.AST_ROOT).get(0));
|
||||
}
|
||||
|
||||
@Test
|
||||
|
Reference in New Issue
Block a user