Merge remote-tracking branch 'origin/master' into issue-1559
This commit is contained in:
@ -0,0 +1,49 @@
|
||||
/**
|
||||
* BSD-style license; for more info see http://pmd.sourceforge.net/license.html
|
||||
*/
|
||||
|
||||
package net.sourceforge.pmd.internal.util;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.Iterator;
|
||||
import java.util.List;
|
||||
|
||||
|
||||
/**
|
||||
* @author Clément Fournier
|
||||
* @since 6.11.0
|
||||
*/
|
||||
public final class IteratorUtil {
|
||||
|
||||
private IteratorUtil() {
|
||||
|
||||
}
|
||||
|
||||
|
||||
public static <T> Iterator<T> reverse(Iterator<T> it) {
|
||||
List<T> tmp = toList(it);
|
||||
Collections.reverse(tmp);
|
||||
return tmp.iterator();
|
||||
}
|
||||
|
||||
|
||||
public static <T> List<T> toList(Iterator<T> it) {
|
||||
List<T> list = new ArrayList<>();
|
||||
while (it.hasNext()) {
|
||||
list.add(it.next());
|
||||
}
|
||||
return list;
|
||||
}
|
||||
|
||||
|
||||
public static <T> Iterable<T> toIterable(final Iterator<T> it) {
|
||||
return new Iterable<T>() {
|
||||
@Override
|
||||
public Iterator<T> iterator() {
|
||||
return it;
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
}
|
@ -6,6 +6,7 @@ package net.sourceforge.pmd.lang.ast.xpath;
|
||||
|
||||
import java.lang.reflect.InvocationTargetException;
|
||||
import java.lang.reflect.Method;
|
||||
import java.util.Objects;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
import java.util.concurrent.ConcurrentMap;
|
||||
import java.util.logging.Level;
|
||||
@ -18,6 +19,9 @@ import net.sourceforge.pmd.lang.ast.Node;
|
||||
* Attributes know their name, the node they wrap,
|
||||
* and have access to their value.
|
||||
*
|
||||
* <p>Two attributes are equal if they have the same name
|
||||
* and their parent nodes are equal.
|
||||
*
|
||||
* @author daniels
|
||||
*/
|
||||
public class Attribute {
|
||||
@ -28,8 +32,8 @@ public class Attribute {
|
||||
|
||||
private static final Object[] EMPTY_OBJ_ARRAY = new Object[0];
|
||||
|
||||
private Node parent;
|
||||
private String name;
|
||||
private final Node parent;
|
||||
private final String name;
|
||||
private Method method;
|
||||
private Object value;
|
||||
private String stringValue;
|
||||
@ -41,7 +45,6 @@ public class Attribute {
|
||||
this.method = m;
|
||||
}
|
||||
|
||||
|
||||
/** Creates a new attribute belonging to the given node using its string value. */
|
||||
public Attribute(Node parent, String name, String value) {
|
||||
this.parent = parent;
|
||||
@ -93,12 +96,33 @@ public class Attribute {
|
||||
return stringValue;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public boolean equals(Object o) {
|
||||
if (this == o) {
|
||||
return true;
|
||||
}
|
||||
if (o == null || getClass() != o.getClass()) {
|
||||
return false;
|
||||
}
|
||||
Attribute attribute = (Attribute) o;
|
||||
return Objects.equals(parent, attribute.parent)
|
||||
&& Objects.equals(name, attribute.name);
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return Objects.hash(parent, name);
|
||||
}
|
||||
|
||||
|
||||
private String getLoggableAttributeName() {
|
||||
return parent.getXPathNodeName() + "/@" + name;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return name + ':' + getValue() + ':' + parent;
|
||||
return name + ':' + getValue() + ':' + parent.getXPathNodeName();
|
||||
}
|
||||
}
|
||||
|
@ -69,7 +69,6 @@ public class AttributeAxisIterator implements Iterator<Attribute> {
|
||||
this.currObj = getNextAttribute();
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Returns whether the given method is an attribute accessor,
|
||||
* in which case a corresponding Attribute will be added to
|
||||
@ -80,12 +79,16 @@ public class AttributeAxisIterator implements Iterator<Attribute> {
|
||||
protected boolean isAttributeAccessor(Method method) {
|
||||
String methodName = method.getName();
|
||||
|
||||
return CONSIDERED_RETURN_TYPES.contains(method.getReturnType())
|
||||
return isConsideredReturnType(method.getReturnType())
|
||||
&& method.getParameterTypes().length == 0
|
||||
&& !methodName.startsWith("jjt")
|
||||
&& !FILTERED_OUT_NAMES.contains(methodName);
|
||||
}
|
||||
|
||||
private boolean isConsideredReturnType(Class<?> klass) {
|
||||
return CONSIDERED_RETURN_TYPES.contains(klass) || klass.isEnum();
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public Attribute next() {
|
||||
|
@ -236,7 +236,9 @@ public class SaxonXPathRuleQuery extends AbstractXPathRuleQuery {
|
||||
*/
|
||||
if (value == null) {
|
||||
return UntypedAtomicValue.ZERO_LENGTH_UNTYPED;
|
||||
|
||||
} else if (value instanceof Enum) {
|
||||
// enums use their toString
|
||||
return new StringValue(value.toString());
|
||||
} else if (value instanceof String) {
|
||||
return new StringValue((String) value);
|
||||
} else if (value instanceof Boolean) {
|
||||
|
@ -164,6 +164,7 @@ public abstract class AbstractPropertySource implements PropertySource {
|
||||
|
||||
|
||||
@Override
|
||||
@Deprecated
|
||||
public <V> void setProperty(MultiValuePropertyDescriptor<V> propertyDescriptor, V... values) {
|
||||
checkValidPropertyDescriptor(propertyDescriptor);
|
||||
propertyValuesByDescriptor.put(propertyDescriptor, Collections.unmodifiableList(Arrays.asList(values)));
|
||||
|
@ -112,7 +112,10 @@ public interface PropertySource {
|
||||
* @param propertyDescriptor The property descriptor for which to add a value
|
||||
* @param values Values
|
||||
* @param <V> The type of the values
|
||||
*
|
||||
* @deprecated {@link MultiValuePropertyDescriptor} is deprecated
|
||||
*/
|
||||
@Deprecated
|
||||
<V> void setProperty(MultiValuePropertyDescriptor<V> propertyDescriptor, V... values);
|
||||
|
||||
|
||||
|
@ -6,6 +6,7 @@ package net.sourceforge.pmd.lang.ast.xpath;
|
||||
|
||||
|
||||
import static org.hamcrest.MatcherAssert.assertThat;
|
||||
import static org.junit.Assert.assertEquals;
|
||||
import static org.junit.Assert.assertTrue;
|
||||
|
||||
import java.util.HashMap;
|
||||
@ -52,6 +53,17 @@ public class AttributeAxisIteratorTest {
|
||||
assertTrue(atts.containsKey("EndLine"));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testAttributeAxisIteratorWithEnum() {
|
||||
DummyNodeWithEnum dummyNode = new DummyNodeWithEnum(1);
|
||||
|
||||
AttributeAxisIterator it = new AttributeAxisIterator(dummyNode);
|
||||
Map<String, Attribute> atts = toMap(it);
|
||||
Assert.assertEquals(8, atts.size());
|
||||
assertTrue(atts.containsKey("Enum"));
|
||||
assertEquals(DummyNodeWithEnum.MyEnum.FOO, atts.get("Enum").getValue());
|
||||
}
|
||||
|
||||
|
||||
private Map<String, Attribute> toMap(AttributeAxisIterator it) {
|
||||
Map<String, Attribute> atts = new HashMap<>();
|
||||
@ -61,4 +73,19 @@ public class AttributeAxisIteratorTest {
|
||||
}
|
||||
return atts;
|
||||
}
|
||||
|
||||
public static class DummyNodeWithEnum extends DummyNode {
|
||||
|
||||
public DummyNodeWithEnum(int id) {
|
||||
super(id);
|
||||
}
|
||||
|
||||
public enum MyEnum {
|
||||
FOO, BAR
|
||||
}
|
||||
|
||||
public MyEnum getEnum() {
|
||||
return MyEnum.FOO;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
Reference in New Issue
Block a user