[core] Log deprecated attribute usage in findChildNodesWithXPath queries

This commit is contained in:
Andreas Dangel
2020-04-18 17:43:18 +02:00
parent be19da5a07
commit 4a9aa1a926
4 changed files with 32 additions and 2 deletions
pmd-core/src
main/java/net/sourceforge/pmd/lang/ast
test/java/net/sourceforge/pmd/lang/ast

@ -25,6 +25,8 @@ import net.sourceforge.pmd.annotation.InternalApi;
import net.sourceforge.pmd.lang.ast.xpath.Attribute;
import net.sourceforge.pmd.lang.ast.xpath.AttributeAxisIterator;
import net.sourceforge.pmd.lang.ast.xpath.DocumentNavigator;
import net.sourceforge.pmd.lang.ast.xpath.internal.ContextualizedNavigator;
import net.sourceforge.pmd.lang.ast.xpath.internal.DeprecatedAttrLogger;
import net.sourceforge.pmd.lang.dfa.DataFlowNode;
import net.sourceforge.pmd.util.DataMap;
import net.sourceforge.pmd.util.DataMap.DataKey;
@ -513,7 +515,8 @@ public abstract class AbstractNode implements Node {
@Override
@SuppressWarnings("unchecked")
public List<Node> findChildNodesWithXPath(final String xpathString) throws JaxenException {
return new BaseXPath(xpathString, new DocumentNavigator()).selectNodes(this);
return new BaseXPath(xpathString, new ContextualizedNavigator(DeprecatedAttrLogger.createAdHocLogger()))
.selectNodes(this);
}
@Override

@ -1,6 +1,7 @@
/*
* BSD-style license; for more info see http://pmd.sourceforge.net/license.html
*/
package net.sourceforge.pmd.lang.ast.xpath.internal;
import net.sourceforge.pmd.lang.ast.xpath.Attribute;

@ -35,6 +35,14 @@ public abstract class DeprecatedAttrLogger {
}
}
public static DeprecatedAttrLogger createAdHocLogger() {
if (LOG.isLoggable(Level.WARNING)) {
return new AdhocLoggerImpl();
} else {
return noop();
}
}
public static Noop noop() {
return Noop.INSTANCE;
}
@ -89,4 +97,21 @@ public abstract class DeprecatedAttrLogger {
return name;
}
}
private static class AdhocLoggerImpl extends DeprecatedAttrLogger {
@Override
public void recordUsageOf(Attribute attribute) {
String replacement = attribute.replacementIfDeprecated();
if (replacement != null) {
String name = getLoggableAttributeName(attribute);
// this message needs to be kept in sync with PMDCoverageTest / BinaryDistributionIT
String msg = "Use of deprecated attribute '" + name + "' in a findChildNodesWithXPath navigation";
if (!replacement.isEmpty()) {
msg += ", please use " + replacement + " instead";
}
// log with execption stack trace to help figure out where exactly the xpath is used.
LOG.log(Level.WARNING, msg, new RuntimeException(msg));
}
}
}
}

@ -238,7 +238,8 @@ public class AbstractNodeTest {
}
}
addChild(new MyRootNode(nextId()), new DummyNodeWithDeprecatedAttribute(2)).findChildNodesWithXPath("//dummyNode[@Size=1]");
Node root = addChild(new MyRootNode(nextId()), new DummyNodeWithDeprecatedAttribute(2));
root.findChildNodesWithXPath("//dummyNode[@Size=1]");
String log = loggingRule.getLog();