Merge remote-tracking branch 'origin/master' into issue-1559

This commit is contained in:
Andreas Dangel
2019-01-26 11:28:36 +01:00
30 changed files with 1241 additions and 958 deletions

View File

@ -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;
}
};
}
}

View File

@ -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();
}
}

View File

@ -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() {

View File

@ -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) {

View File

@ -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)));

View File

@ -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);

View File

@ -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;
}
}
}