#1308 PMD runs endlessly on some generated files

This commit is contained in:
Andreas Dangel
2015-01-24 10:03:46 +01:00
parent 9522ab3cd4
commit 4be14adebb
6 changed files with 52 additions and 24 deletions

View File

@ -24,6 +24,7 @@ public abstract class AbstractNode implements Node {
protected Node parent;
protected Node[] children;
protected int childIndex;
protected int id;
private String image;
@ -76,6 +77,13 @@ public abstract class AbstractNode implements Node {
children = newChildren;
}
children[index] = child;
child.jjtSetChildIndex(index);
}
public void jjtSetChildIndex(int index) {
childIndex = index;
}
public int jjtGetChildIndex() {
return childIndex;
}
public Node jjtGetChild(int index) {

View File

@ -44,6 +44,16 @@ public interface Node {
*/
void jjtAddChild(Node child, int index);
/**
* Sets the index of this node from the perspective of its parent.
* This means: this.jjtGetParent().jjtGetChild(index) == this.
*
* @param index the child index
*/
void jjtSetChildIndex(int index);
int jjtGetChildIndex();
/**
* This method returns a child node. The children are numbered
* from zero, left to right.

View File

@ -43,7 +43,7 @@ public abstract class NodeIterator implements Iterator<Node> {
protected Node getPreviousSibling(Node contextNode) {
Node parentNode = contextNode.jjtGetParent();
if (parentNode != null) {
int prevPosition = getPositionFromParent(contextNode) - 1;
int prevPosition = contextNode.jjtGetChildIndex() - 1;
if (prevPosition >= 0) {
return parentNode.jjtGetChild(prevPosition);
}
@ -51,20 +51,10 @@ public abstract class NodeIterator implements Iterator<Node> {
return null;
}
private int getPositionFromParent(Node contextNode) {
Node parentNode = contextNode.jjtGetParent();
for (int i = 0; i < parentNode.jjtGetNumChildren(); i++) {
if (parentNode.jjtGetChild(i) == contextNode) {
return i;
}
}
throw new RuntimeException("Node was not a child of it's parent ???");
}
protected Node getNextSibling(Node contextNode) {
Node parentNode = contextNode.jjtGetParent();
if (parentNode != null) {
int nextPosition = getPositionFromParent(contextNode) + 1;
int nextPosition = contextNode.jjtGetChildIndex() + 1;
if (nextPosition < parentNode.jjtGetNumChildren()) {
return parentNode.jjtGetChild(nextPosition);
}

View File

@ -4,6 +4,7 @@
package net.sourceforge.pmd.lang.symboltable;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
@ -15,7 +16,9 @@ import java.util.Map;
public abstract class AbstractScope implements Scope {
private Scope parent;
private Map<NameDeclaration, List<NameOccurrence>> nameDeclarations = new LinkedHashMap<NameDeclaration, List<NameOccurrence>>();
/** Stores the name declaration already sorted by class. */
private Map<Class<? extends NameDeclaration>, Map<NameDeclaration, List<NameOccurrence>>> nameDeclarations =
new LinkedHashMap<Class<? extends NameDeclaration>, Map<NameDeclaration,List<NameOccurrence>>>();
@Override
public Scope getParent() {
@ -29,25 +32,26 @@ public abstract class AbstractScope implements Scope {
@Override
public Map<NameDeclaration, List<NameOccurrence>> getDeclarations() {
return nameDeclarations;
Map<NameDeclaration, List<NameOccurrence>> result = new LinkedHashMap<NameDeclaration, List<NameOccurrence>>();
for (Map<NameDeclaration, List<NameOccurrence>> e : nameDeclarations.values()) {
result.putAll(e);
}
return result;
}
@Override
public <T extends NameDeclaration> Map<T, List<NameOccurrence>> getDeclarations(Class<T> clazz) {
Map<T, List<NameOccurrence>> result = new LinkedHashMap<T, List<NameOccurrence>>();
for (Map.Entry<NameDeclaration, List<NameOccurrence>> e : nameDeclarations.entrySet()) {
if (clazz.isAssignableFrom(e.getKey().getClass())) {
@SuppressWarnings("unchecked") // it's assignable from, so should be ok
T cast = (T)e.getKey();
result.put(cast, e.getValue());
}
@SuppressWarnings("unchecked")
Map<T, List<NameOccurrence>> result = (Map<T, List<NameOccurrence>>)nameDeclarations.get(clazz);
if (result == null) {
result = new LinkedHashMap<T, List<NameOccurrence>>();
}
return result;
}
@Override
public boolean contains(NameOccurrence occ) {
for (NameDeclaration d : nameDeclarations.keySet()) {
for (NameDeclaration d : getDeclarations().keySet()) {
if (d.getImage().equals(occ.getImage())) {
return true;
}
@ -57,7 +61,12 @@ public abstract class AbstractScope implements Scope {
@Override
public void addDeclaration(NameDeclaration declaration) {
nameDeclarations.put(declaration, new ArrayList<NameOccurrence>());
Map<NameDeclaration, List<NameOccurrence>> declarationsPerClass = nameDeclarations.get(declaration.getClass());
if (declarationsPerClass == null) {
declarationsPerClass = new HashMap<NameDeclaration, List<NameOccurrence>>();
nameDeclarations.put(declaration.getClass(), declarationsPerClass);
}
declarationsPerClass.put(declaration, new ArrayList<NameOccurrence>());
}
@Override
@ -78,7 +87,7 @@ public abstract class AbstractScope implements Scope {
@Override
public NameDeclaration addNameOccurrence(NameOccurrence occurrence) {
NameDeclaration result = null;
for (Map.Entry<NameDeclaration, List<NameOccurrence>> e : nameDeclarations.entrySet()) {
for (Map.Entry<NameDeclaration, List<NameOccurrence>> e : getDeclarations().entrySet()) {
if (e.getKey().getImage().equals(occurrence.getImage())) {
result = e.getKey();
e.getValue().add(occurrence);

View File

@ -21,6 +21,7 @@ import net.sourceforge.pmd.util.CompoundIterator;
import org.w3c.dom.Document;
import org.w3c.dom.NamedNodeMap;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;
import org.w3c.dom.Text;
public class XmlNodeInvocationHandler implements InvocationHandler {
@ -41,6 +42,15 @@ public class XmlNodeInvocationHandler implements InvocationHandler {
return node.hasChildNodes() ? node.getChildNodes().getLength() : 0;
} else if ("jjtGetChild".equals(method.getName())) {
return parser.createProxy(node.getChildNodes().item(((Integer) args[0]).intValue()));
} else if ("jjtGetChildIndex".equals(method.getName())) {
Node parent = node.getParentNode();
NodeList childNodes = parent.getChildNodes();
for (int i = 0; i < childNodes.getLength(); i++) {
if (node == childNodes.item(i)) {
return i;
}
}
throw new IllegalStateException("This node is not a child of its parent: " + node);
} else if ("getImage".equals(method.getName())) {
if (node instanceof Text) {
return ((Text) node).getData();

View File

@ -32,3 +32,4 @@
* [#1298](https://sourceforge.net/p/pmd/bugs/1298/): Member variable int type with value 0xff000000 causes processing error
* [#1299](https://sourceforge.net/p/pmd/bugs/1299/): MethodReturnsInternalArray false positive
* [#1306](https://sourceforge.net/p/pmd/bugs/1306/): False positive on duplicate when using static imports
* [#1308](https://sourceforge.net/p/pmd/bugs/1308/): PMD runs endlessly on some generated files