Merge branch 'issue-2218'
This commit is contained in:
@ -133,6 +133,7 @@ methods on {% jdoc apex::lang.apex.ast.ApexParserVisitor %} and its implementati
|
||||
* pmd-core
|
||||
* Many methods on the {% jdoc core::lang.ast.Node %} interface
|
||||
and {% jdoc core::lang.ast.AbstractNode %} base class. See their javadoc for details.
|
||||
* {% jdoc !!core::lang.ast.Node#isFindBoundary() %} is deprecated for XPath queries.
|
||||
* pmd-java
|
||||
* {% jdoc java::lang.java.AbstractJavaParser %}
|
||||
* {% jdoc java::lang.java.AbstractJavaHandler %}
|
||||
|
@ -12,6 +12,7 @@ import org.w3c.dom.Document;
|
||||
|
||||
import net.sourceforge.pmd.annotation.InternalApi;
|
||||
import net.sourceforge.pmd.lang.ast.xpath.Attribute;
|
||||
import net.sourceforge.pmd.lang.ast.xpath.internal.DeprecatedAttribute;
|
||||
import net.sourceforge.pmd.lang.dfa.DataFlowNode;
|
||||
|
||||
/**
|
||||
@ -202,7 +203,11 @@ public interface Node {
|
||||
* look past such boundaries by default, which is usually the expected thing
|
||||
* to do. For example, in Java, lambdas and nested classes are considered
|
||||
* find boundaries.
|
||||
*
|
||||
* <p>Note: This attribute is deprecated for XPath queries. It is not useful
|
||||
* for XPath queries and will be removed with PMD 7.0.0.
|
||||
*/
|
||||
@DeprecatedAttribute
|
||||
boolean isFindBoundary();
|
||||
|
||||
|
||||
|
@ -16,6 +16,7 @@ import java.util.logging.Logger;
|
||||
|
||||
import net.sourceforge.pmd.annotation.Experimental;
|
||||
import net.sourceforge.pmd.lang.ast.Node;
|
||||
import net.sourceforge.pmd.lang.ast.xpath.internal.DeprecatedAttribute;
|
||||
|
||||
/**
|
||||
* Represents an XPath attribute of a specific node.
|
||||
@ -31,7 +32,7 @@ public class Attribute {
|
||||
|
||||
|
||||
private static final Logger LOG = Logger.getLogger(Attribute.class.getName());
|
||||
private static final ConcurrentMap<String, Boolean> DETECTED_DEPRECATED_ATTRIBUTES = new ConcurrentHashMap<>();
|
||||
static final ConcurrentMap<String, Boolean> DETECTED_DEPRECATED_ATTRIBUTES = new ConcurrentHashMap<>();
|
||||
|
||||
private static final Object[] EMPTY_OBJ_ARRAY = new Object[0];
|
||||
|
||||
@ -72,12 +73,17 @@ public class Attribute {
|
||||
return method == null ? String.class : method.getReturnType();
|
||||
}
|
||||
|
||||
private boolean isAttributeDeprecated() {
|
||||
return method != null && (method.isAnnotationPresent(Deprecated.class)
|
||||
|| method.isAnnotationPresent(DeprecatedAttribute.class));
|
||||
}
|
||||
|
||||
public Object getValue() {
|
||||
if (value != null) {
|
||||
return value.get(0);
|
||||
}
|
||||
|
||||
if (method.isAnnotationPresent(Deprecated.class) && LOG.isLoggable(Level.WARNING)
|
||||
if (LOG.isLoggable(Level.WARNING) && isAttributeDeprecated()
|
||||
&& DETECTED_DEPRECATED_ATTRIBUTES.putIfAbsent(getLoggableAttributeName(), Boolean.TRUE) == null) {
|
||||
// this message needs to be kept in sync with PMDCoverageTest / BinaryDistributionIT
|
||||
LOG.warning("Use of deprecated attribute '" + getLoggableAttributeName() + "' in XPath query");
|
||||
|
@ -0,0 +1,25 @@
|
||||
/*
|
||||
* BSD-style license; for more info see http://pmd.sourceforge.net/license.html
|
||||
*/
|
||||
|
||||
package net.sourceforge.pmd.lang.ast.xpath.internal;
|
||||
|
||||
import java.lang.annotation.Documented;
|
||||
import java.lang.annotation.ElementType;
|
||||
import java.lang.annotation.Retention;
|
||||
import java.lang.annotation.RetentionPolicy;
|
||||
import java.lang.annotation.Target;
|
||||
|
||||
|
||||
/**
|
||||
* Node attribute getter methods might be annotated with {@code DeprecatedAttribute}
|
||||
* to mark the attribute as deprecated for XPath. Unlike {@link Deprecated}, this
|
||||
* annotation does not deprecate the method for java usage.
|
||||
*
|
||||
* @since 6.21.0
|
||||
*/
|
||||
@Documented
|
||||
@Retention(RetentionPolicy.RUNTIME)
|
||||
@Target(ElementType.METHOD)
|
||||
public @interface DeprecatedAttribute {
|
||||
}
|
@ -4,6 +4,8 @@
|
||||
|
||||
package net.sourceforge.pmd.lang.ast;
|
||||
|
||||
import net.sourceforge.pmd.lang.ast.xpath.internal.DeprecatedAttribute;
|
||||
|
||||
/**
|
||||
* @author Clément Fournier
|
||||
* @since 6.3.0
|
||||
@ -20,4 +22,11 @@ public class DummyNodeWithDeprecatedAttribute extends DummyNode {
|
||||
public int getSize() {
|
||||
return 2;
|
||||
}
|
||||
|
||||
// this is a attribute that is deprecated for xpath, because it will be removed.
|
||||
// it should still be available via Java.
|
||||
@DeprecatedAttribute
|
||||
public String getName() {
|
||||
return "foo";
|
||||
}
|
||||
}
|
||||
|
@ -16,10 +16,13 @@ import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import org.hamcrest.Matchers;
|
||||
import org.hamcrest.collection.IsMapContaining;
|
||||
import org.junit.Assert;
|
||||
import org.junit.Rule;
|
||||
import org.junit.Test;
|
||||
|
||||
import net.sourceforge.pmd.junit.JavaUtilLoggingRule;
|
||||
import net.sourceforge.pmd.lang.ast.DummyNode;
|
||||
import net.sourceforge.pmd.lang.ast.DummyNodeWithDeprecatedAttribute;
|
||||
import net.sourceforge.pmd.lang.ast.Node;
|
||||
@ -30,10 +33,30 @@ import net.sourceforge.pmd.lang.ast.Node;
|
||||
*/
|
||||
public class AttributeAxisIteratorTest {
|
||||
|
||||
@Rule
|
||||
public JavaUtilLoggingRule loggingRule = new JavaUtilLoggingRule(Attribute.class.getName());
|
||||
|
||||
/**
|
||||
* Verifies that attributes are returned, even if they are deprecated.
|
||||
* Deprecated attributes are still accessible, but a warning is logged, when
|
||||
* the value is used.
|
||||
*/
|
||||
@Test
|
||||
public void testAttributeDeprecation() {
|
||||
// make sure, we log
|
||||
Attribute.DETECTED_DEPRECATED_ATTRIBUTES.clear();
|
||||
|
||||
Node dummy = new DummyNodeWithDeprecatedAttribute(2);
|
||||
assertThat(toMap(new AttributeAxisIterator(dummy)), IsMapContaining.hasKey("Size"));
|
||||
Map<String, Attribute> attributes = toMap(new AttributeAxisIterator(dummy));
|
||||
assertThat(attributes, IsMapContaining.hasKey("Size"));
|
||||
assertThat(attributes, IsMapContaining.hasKey("Name"));
|
||||
|
||||
assertThat(attributes.get("Size").getStringValue(), Matchers.is("2"));
|
||||
assertThat(attributes.get("Name").getStringValue(), Matchers.is("foo"));
|
||||
|
||||
String log = loggingRule.getLog();
|
||||
assertThat(log, Matchers.containsString("Use of deprecated attribute 'dummyNode/@Size' in XPath query"));
|
||||
assertThat(log, Matchers.containsString("Use of deprecated attribute 'dummyNode/@Name' in XPath query"));
|
||||
}
|
||||
|
||||
/**
|
||||
|
Reference in New Issue
Block a user