Externalize creator for XPath rule

This commit is contained in:
Clément Fournier 2020-03-22 04:36:31 +01:00
parent fc304bf70c
commit bcf90ceb8a
17 changed files with 116 additions and 94 deletions

View File

@ -12,7 +12,6 @@ import net.sourceforge.pmd.lang.AbstractLanguageVersionHandler;
import net.sourceforge.pmd.lang.Parser;
import net.sourceforge.pmd.lang.ParserOptions;
import net.sourceforge.pmd.lang.VisitorStarter;
import net.sourceforge.pmd.lang.XPathHandler;
import net.sourceforge.pmd.lang.apex.ast.ASTMethod;
import net.sourceforge.pmd.lang.apex.ast.ASTUserClassOrInterface;
import net.sourceforge.pmd.lang.apex.ast.ApexNode;
@ -22,7 +21,6 @@ import net.sourceforge.pmd.lang.apex.metrics.api.ApexClassMetricKey;
import net.sourceforge.pmd.lang.apex.metrics.api.ApexOperationMetricKey;
import net.sourceforge.pmd.lang.apex.multifile.ApexMultifileVisitorFacade;
import net.sourceforge.pmd.lang.apex.rule.ApexRuleViolationFactory;
import net.sourceforge.pmd.lang.ast.xpath.DefaultASTXPathHandler;
import net.sourceforge.pmd.lang.metrics.LanguageMetricsProvider;
import net.sourceforge.pmd.lang.metrics.internal.AbstractLanguageMetricsProvider;
import net.sourceforge.pmd.lang.rule.RuleViolationFactory;
@ -38,12 +36,6 @@ public class ApexHandler extends AbstractLanguageVersionHandler {
return rootNode -> new ApexMultifileVisitorFacade().initializeWith((ApexNode<?>) rootNode);
}
@Override
public XPathHandler getXPathHandler() {
return new DefaultASTXPathHandler();
}
@Override
public RuleViolationFactory getRuleViolationFactory() {
return ApexRuleViolationFactory.INSTANCE;

View File

@ -18,6 +18,7 @@ import net.sourceforge.pmd.util.designerbindings.DesignerBindings;
*/
public abstract class AbstractLanguageVersionHandler implements LanguageVersionHandler {
@Override
public DataFlowHandler getDataFlowHandler() {
return DataFlowHandler.DUMMY;
@ -25,7 +26,7 @@ public abstract class AbstractLanguageVersionHandler implements LanguageVersionH
@Override
public XPathHandler getXPathHandler() {
return XPathHandler.DUMMY;
return XPathHandler.DEFAULT;
}
@Override

View File

@ -7,43 +7,53 @@ package net.sourceforge.pmd.lang;
import org.jaxen.Navigator;
import net.sourceforge.pmd.Rule;
import net.sourceforge.pmd.annotation.InternalApi;
import net.sourceforge.pmd.lang.ast.xpath.DefaultASTXPathHandler;
import net.sourceforge.pmd.lang.rule.XPathRule;
import net.sourceforge.pmd.lang.rule.xpath.XPathVersion;
import net.sourceforge.pmd.lang.xpath.Initializer;
import net.sf.saxon.sxpath.IndependentContext;
/**
* Interface for performing Language specific XPath handling, such as
* initialization and navigation.
* Handles the XPath-specific behaviour of a language.
*/
@InternalApi
@Deprecated
// TODO move to rule.xpath package
public interface XPathHandler {
XPathHandler DUMMY = new XPathHandler() {
@Override
public void initialize() {
// empty handler - does nothing
}
/**
* @deprecated Use {@link #DEFAULT}.
*/
@Deprecated
XPathHandler DUMMY = new DefaultASTXPathHandler();
@Override
public void initialize(IndependentContext context) {
// empty handler - does nothing
}
/**
* Default instance. Declares no additional XPath functions.
*/
XPathHandler DEFAULT = new DefaultASTXPathHandler();
@Override
public Navigator getNavigator() {
return null;
}
};
Rule newXPathRule()
/**
* Creates a new XPath rule for the given version and expression.
* Note: this isn't used by the ruleset factory for the moment,
* XPath rules are created like normal rules. Programmatic usages
* of {@link XPathRule} should be replaced with calls to this method.
* The ruleset schema will get a new syntax for XPath rules in 7.0.0.
*
* @param version Version of the XPath language
* @param xpathExpression XPath expression
*
* @return A new rule
*
* @throws NullPointerException If any of the arguments is null
*/
Rule newXPathRule(XPathVersion version, String xpathExpression);
/**
* Initialize. This is intended to be called by {@link Initializer} to
* perform Language specific initialization.
*
* @deprecated Jaxen support will be removed in 7.0.0
* @deprecated Support for Jaxen will be removed come 7.0.0
*/
@Deprecated
void initialize();

View File

@ -4,7 +4,10 @@
package net.sourceforge.pmd.lang.ast.xpath;
import net.sourceforge.pmd.Rule;
import net.sourceforge.pmd.annotation.InternalApi;
import net.sourceforge.pmd.lang.rule.XPathRule;
import net.sourceforge.pmd.lang.rule.xpath.XPathVersion;
import net.sf.saxon.sxpath.IndependentContext;
@ -12,6 +15,12 @@ import net.sf.saxon.sxpath.IndependentContext;
@Deprecated
@InternalApi
public class DefaultASTXPathHandler extends AbstractASTXPathHandler {
@Override
public Rule newXPathRule(XPathVersion version, String xpathExpression) {
return new XPathRule(version, xpathExpression);
}
@Override
public void initialize() {
// override if needed

View File

@ -12,25 +12,29 @@ import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import org.apache.commons.lang3.StringUtils;
import net.sourceforge.pmd.RuleContext;
import net.sourceforge.pmd.lang.XPathHandler;
import net.sourceforge.pmd.lang.ast.Node;
import net.sourceforge.pmd.lang.rule.xpath.JaxenXPathRuleQuery;
import net.sourceforge.pmd.lang.rule.xpath.SaxonXPathRuleQuery;
import net.sourceforge.pmd.lang.rule.xpath.XPathRuleQuery;
import net.sourceforge.pmd.lang.rule.xpath.XPathVersion;
import net.sourceforge.pmd.properties.EnumeratedProperty;
import net.sourceforge.pmd.properties.StringProperty;
/**
* Rule that tries to match an XPath expression against a DOM view of an AST.
*
* <p>This rule needs a "xpath" property value in order to function.</p>
*/
public class XPathRule extends AbstractRule {
// TODO 7.0.0 use PropertyDescriptor<String>
/**
* @deprecated Use {@link XPathHandler#newXPathRule(XPathVersion, String)}
*/
@Deprecated
public static final StringProperty XPATH_DESCRIPTOR = StringProperty.named("xpath")
.desc("XPath expression")
.defaultValue("")
@ -47,7 +51,11 @@ public class XPathRule extends AbstractRule {
XPATH_VERSIONS = Collections.unmodifiableMap(tmp);
}
// published, can't be converted
/**
* @deprecated Use {@link XPathHandler#newXPathRule(XPathVersion, String)}
*/
@Deprecated
public static final EnumeratedProperty<String> VERSION_DESCRIPTOR = EnumeratedProperty.<String>named("version")
.desc("XPath specification version")
.mappings(XPATH_VERSIONS)
@ -63,6 +71,8 @@ public class XPathRule extends AbstractRule {
/**
* Creates a new XPathRule without the corresponding XPath query.
*
* @deprecated Use {@link #XPathRule(XPathVersion, String)}
*/
public XPathRule() {
definePropertyDescriptor(XPATH_DESCRIPTOR);
@ -73,6 +83,8 @@ public class XPathRule extends AbstractRule {
/**
* Creates a new XPathRule and associates the XPath query.
*
* @deprecated Use {@link #XPathRule(XPathVersion, String)}
*/
public XPathRule(final String xPath) {
this();
@ -80,21 +92,38 @@ public class XPathRule extends AbstractRule {
}
/**
* Sets the XPath to query against the desired nodes in {@link #apply(List, RuleContext)}.
* Make a new XPath rule with the given version + expression
*
* @param xPath the XPath query
* @param version Version of the XPath language
* @param expression XPath expression
*
* @throws NullPointerException If any of the arguments is null
*/
public XPathRule(XPathVersion version, String expression) {
Objects.requireNonNull(version, "XPath version is null");
Objects.requireNonNull(expression, "XPath expression is null");
setXPath(expression);
setVersion(version.getXmlName());
}
/**
* @deprecated Use the constructor {@link #XPathRule(XPathVersion, String)},
* don't set the expression after the fact.
*/
@Deprecated
public void setXPath(final String xPath) {
setProperty(XPathRule.XPATH_DESCRIPTOR, xPath);
}
/**
* @deprecated Use the constructor {@link #XPathRule(XPathVersion, String)},
* don't set the version after the fact.
*/
@Deprecated
public void setVersion(final String version) {
setProperty(XPathRule.VERSION_DESCRIPTOR, version);
}
/**
* Apply the rule to all nodes.
*/
@Override
public void apply(List<? extends Node> nodes, RuleContext ctx) {
for (Node node : nodes) {
@ -107,7 +136,10 @@ public class XPathRule extends AbstractRule {
*
* @param node The Node that to be checked.
* @param data The RuleContext.
*
* @deprecated Use {@link #apply(List, RuleContext)}
*/
@Deprecated
public void evaluate(final Node node, final RuleContext data) {
if (xPathRuleQueryNeedsInitialization()) {
initXPathRuleQuery();

View File

@ -9,12 +9,17 @@ import java.util.List;
import java.util.Map;
import net.sourceforge.pmd.RuleContext;
import net.sourceforge.pmd.annotation.InternalApi;
import net.sourceforge.pmd.lang.ast.Node;
import net.sourceforge.pmd.properties.PropertyDescriptor;
/**
* This implementation of XPathRuleQuery provides support for RuleChain visits.
*
* @deprecated Internal API
*/
@Deprecated
@InternalApi
public abstract class AbstractXPathRuleQuery implements XPathRuleQuery {
/**

View File

@ -31,12 +31,17 @@ import org.jaxen.expr.XPathFactory;
import org.jaxen.saxpath.Axis;
import net.sourceforge.pmd.RuleContext;
import net.sourceforge.pmd.annotation.InternalApi;
import net.sourceforge.pmd.lang.ast.Node;
import net.sourceforge.pmd.properties.PropertyDescriptor;
/**
* This is a Jaxen based XPathRule query.
*
* @deprecated Internal API
*/
@Deprecated
@InternalApi
public class JaxenXPathRuleQuery extends AbstractXPathRuleQuery {
private static final Logger LOG = Logger.getLogger(JaxenXPathRuleQuery.class.getName());

View File

@ -16,6 +16,7 @@ import java.util.logging.Logger;
import java.util.regex.Pattern;
import net.sourceforge.pmd.RuleContext;
import net.sourceforge.pmd.annotation.InternalApi;
import net.sourceforge.pmd.lang.ast.Node;
import net.sourceforge.pmd.lang.ast.xpath.saxon.DocumentNode;
import net.sourceforge.pmd.lang.ast.xpath.saxon.ElementNode;
@ -50,7 +51,11 @@ import net.sf.saxon.value.Value;
/**
* This is a Saxon based XPathRule query.
*
* @deprecated Internal API
*/
@Deprecated
@InternalApi
public class SaxonXPathRuleQuery extends AbstractXPathRuleQuery {
/**
* Special nodeName that references the root expression.

View File

@ -8,6 +8,7 @@ import java.util.List;
import java.util.Map;
import net.sourceforge.pmd.RuleContext;
import net.sourceforge.pmd.annotation.InternalApi;
import net.sourceforge.pmd.lang.ast.Node;
import net.sourceforge.pmd.properties.PropertyDescriptor;
@ -22,24 +23,38 @@ import net.sourceforge.pmd.properties.PropertyDescriptor;
* are recommended to manage internal state that is invariant over AST Nodes in
* a fashion which facilities high performance (e.g. caching).
* </p>
*
* @deprecated This will be internalized in 7.0.0.
*/
@InternalApi
@Deprecated
public interface XPathRuleQuery {
/**
* XPath 1.0 version.
*
* @deprecated Use {@link XPathVersion}
*/
@Deprecated
String XPATH_1_0 = "1.0";
/**
* XPath 1.0 compatibility version.
*
* @deprecated Use {@link XPathVersion}
*/
@Deprecated
String XPATH_1_0_COMPATIBILITY = "1.0 compatibility";
/**
* XPath 2.0 version.
*
* @deprecated Use {@link XPathVersion}
*/
@Deprecated
String XPATH_2_0 = "2.0";
/**
* Set the XPath query string to be used.
*

View File

@ -17,19 +17,17 @@ public enum XPathVersion {
* @deprecated not supported anymore
*/
@Deprecated
XPATH_1_0("1.0"),
XPATH_1_0(XPathRuleQuery.XPATH_1_0),
/**
* XPath 1.0 compatibility mode.
*
* @deprecated Not supported any more.
*/
@Deprecated
XPATH_1_0_COMPATIBILITY("1.0 compatibility"),
XPATH_1_0_COMPATIBILITY(XPathRuleQuery.XPATH_1_0_COMPATIBILITY),
/** XPath 2.0. */
XPATH_2_0("2.0"),
/** XPath 3.1. */
XPATH_3_1("3.1");
XPATH_2_0(XPathRuleQuery.XPATH_2_0);
private static final Map<String, XPathVersion> BY_NAME = new HashMap<>();
private final String version;

View File

@ -10,9 +10,7 @@ import net.sourceforge.pmd.lang.AbstractLanguageVersionHandler;
import net.sourceforge.pmd.lang.Parser;
import net.sourceforge.pmd.lang.ParserOptions;
import net.sourceforge.pmd.lang.VisitorStarter;
import net.sourceforge.pmd.lang.XPathHandler;
import net.sourceforge.pmd.lang.ast.Node;
import net.sourceforge.pmd.lang.ast.xpath.DefaultASTXPathHandler;
import net.sourceforge.pmd.lang.ecmascript.ast.DumpFacade;
import net.sourceforge.pmd.lang.ecmascript.ast.EcmascriptNode;
import net.sourceforge.pmd.lang.ecmascript.rule.EcmascriptRuleViolationFactory;
@ -23,11 +21,6 @@ import net.sourceforge.pmd.lang.rule.RuleViolationFactory;
*/
public class Ecmascript3Handler extends AbstractLanguageVersionHandler {
@Override
public XPathHandler getXPathHandler() {
return new DefaultASTXPathHandler();
}
@Override
public RuleViolationFactory getRuleViolationFactory() {
return EcmascriptRuleViolationFactory.INSTANCE;

View File

@ -10,9 +10,7 @@ import net.sourceforge.pmd.lang.AbstractLanguageVersionHandler;
import net.sourceforge.pmd.lang.Parser;
import net.sourceforge.pmd.lang.ParserOptions;
import net.sourceforge.pmd.lang.VisitorStarter;
import net.sourceforge.pmd.lang.XPathHandler;
import net.sourceforge.pmd.lang.ast.Node;
import net.sourceforge.pmd.lang.ast.xpath.DefaultASTXPathHandler;
import net.sourceforge.pmd.lang.jsp.ast.DumpFacade;
import net.sourceforge.pmd.lang.jsp.ast.JspNode;
import net.sourceforge.pmd.lang.jsp.rule.JspRuleViolationFactory;
@ -25,11 +23,6 @@ import net.sourceforge.pmd.lang.rule.RuleViolationFactory;
*/
public class JspHandler extends AbstractLanguageVersionHandler {
@Override
public XPathHandler getXPathHandler() {
return new DefaultASTXPathHandler();
}
@Override
public RuleViolationFactory getRuleViolationFactory() {
return JspRuleViolationFactory.INSTANCE;

View File

@ -8,19 +8,13 @@ import net.sourceforge.pmd.lang.AbstractLanguageVersionHandler;
import net.sourceforge.pmd.lang.Parser;
import net.sourceforge.pmd.lang.ParserOptions;
import net.sourceforge.pmd.lang.VisitorStarter;
import net.sourceforge.pmd.lang.XPathHandler;
import net.sourceforge.pmd.lang.ast.Node;
import net.sourceforge.pmd.lang.ast.xpath.DefaultASTXPathHandler;
import net.sourceforge.pmd.lang.modelica.ast.ASTStoredDefinition;
import net.sourceforge.pmd.lang.modelica.resolver.ModelicaSymbolFacade;
import net.sourceforge.pmd.lang.modelica.rule.ModelicaRuleViolationFactory;
import net.sourceforge.pmd.lang.rule.RuleViolationFactory;
public class ModelicaHandler extends AbstractLanguageVersionHandler {
@Override
public XPathHandler getXPathHandler() {
return new DefaultASTXPathHandler();
}
@Override
public RuleViolationFactory getRuleViolationFactory() {

View File

@ -11,9 +11,7 @@ import net.sourceforge.pmd.lang.DataFlowHandler;
import net.sourceforge.pmd.lang.Parser;
import net.sourceforge.pmd.lang.ParserOptions;
import net.sourceforge.pmd.lang.VisitorStarter;
import net.sourceforge.pmd.lang.XPathHandler;
import net.sourceforge.pmd.lang.ast.Node;
import net.sourceforge.pmd.lang.ast.xpath.DefaultASTXPathHandler;
import net.sourceforge.pmd.lang.dfa.DFAGraphRule;
import net.sourceforge.pmd.lang.plsql.ast.ASTInput;
import net.sourceforge.pmd.lang.plsql.ast.DumpFacade;
@ -83,11 +81,4 @@ public class PLSQLHandler extends AbstractLanguageVersionHandler {
};
}
/**
* Return minimal XPathHandler to cope with Jaxen XPath Rules.
*/
@Override
public XPathHandler getXPathHandler() {
return new DefaultASTXPathHandler();
}
}

View File

@ -10,9 +10,7 @@ import net.sourceforge.pmd.lang.AbstractLanguageVersionHandler;
import net.sourceforge.pmd.lang.Parser;
import net.sourceforge.pmd.lang.ParserOptions;
import net.sourceforge.pmd.lang.VisitorStarter;
import net.sourceforge.pmd.lang.XPathHandler;
import net.sourceforge.pmd.lang.ast.Node;
import net.sourceforge.pmd.lang.ast.xpath.DefaultASTXPathHandler;
import net.sourceforge.pmd.lang.rule.RuleViolationFactory;
import net.sourceforge.pmd.lang.vf.ast.DumpFacade;
import net.sourceforge.pmd.lang.vf.ast.VfNode;
@ -20,11 +18,6 @@ import net.sourceforge.pmd.lang.vf.rule.VfRuleViolationFactory;
public class VfHandler extends AbstractLanguageVersionHandler {
@Override
public XPathHandler getXPathHandler() {
return new DefaultASTXPathHandler();
}
@Override
public RuleViolationFactory getRuleViolationFactory() {
return VfRuleViolationFactory.INSTANCE;

View File

@ -10,9 +10,7 @@ import net.sourceforge.pmd.lang.AbstractLanguageVersionHandler;
import net.sourceforge.pmd.lang.Parser;
import net.sourceforge.pmd.lang.ParserOptions;
import net.sourceforge.pmd.lang.VisitorStarter;
import net.sourceforge.pmd.lang.XPathHandler;
import net.sourceforge.pmd.lang.ast.Node;
import net.sourceforge.pmd.lang.ast.xpath.DefaultASTXPathHandler;
import net.sourceforge.pmd.lang.rule.RuleViolationFactory;
import net.sourceforge.pmd.lang.vm.ast.AbstractVmNode;
import net.sourceforge.pmd.lang.vm.rule.VmRuleViolationFactory;
@ -23,11 +21,6 @@ import net.sourceforge.pmd.lang.vm.rule.VmRuleViolationFactory;
*/
public class VmHandler extends AbstractLanguageVersionHandler {
@Override
public XPathHandler getXPathHandler() {
return new DefaultASTXPathHandler();
}
@Override
public RuleViolationFactory getRuleViolationFactory() {
return VmRuleViolationFactory.INSTANCE;

View File

@ -10,9 +10,7 @@ import net.sourceforge.pmd.lang.AbstractLanguageVersionHandler;
import net.sourceforge.pmd.lang.Parser;
import net.sourceforge.pmd.lang.ParserOptions;
import net.sourceforge.pmd.lang.VisitorStarter;
import net.sourceforge.pmd.lang.XPathHandler;
import net.sourceforge.pmd.lang.ast.Node;
import net.sourceforge.pmd.lang.ast.xpath.DefaultASTXPathHandler;
import net.sourceforge.pmd.lang.rule.RuleViolationFactory;
import net.sourceforge.pmd.lang.xml.ast.DumpFacade;
import net.sourceforge.pmd.lang.xml.ast.XmlNode;
@ -23,11 +21,6 @@ import net.sourceforge.pmd.lang.xml.rule.XmlRuleViolationFactory;
*/
public class XmlHandler extends AbstractLanguageVersionHandler {
@Override
public XPathHandler getXPathHandler() {
return new DefaultASTXPathHandler();
}
@Override
public RuleViolationFactory getRuleViolationFactory() {
return XmlRuleViolationFactory.INSTANCE;