Modifiying for reduce Fasle Positive in DFA Analysis Rule

This commit is contained in:
YoonhoChoi96
2019-07-05 10:04:37 +09:00
parent e8f62f8d58
commit cf16484ec6

View File

@ -4,7 +4,9 @@
package net.sourceforge.pmd.lang.java.dfa;
import java.util.AbstractMap.SimpleEntry;
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
@ -14,6 +16,7 @@ import net.sourceforge.pmd.lang.ast.Node;
import net.sourceforge.pmd.lang.dfa.DataFlowNode;
import net.sourceforge.pmd.lang.dfa.StartOrEndDataFlowNode;
import net.sourceforge.pmd.lang.dfa.VariableAccess;
import net.sourceforge.pmd.lang.java.ast.ASTAssignmentOperator;
import net.sourceforge.pmd.lang.java.ast.ASTClassOrInterfaceBodyDeclaration;
import net.sourceforge.pmd.lang.java.ast.ASTConstructorDeclaration;
import net.sourceforge.pmd.lang.java.ast.ASTFormalParameter;
@ -45,6 +48,8 @@ public class VariableAccessVisitor extends JavaParserVisitorAdapter {
}
private void computeNow(Node node) {
DataFlowNode inode = node.getDataFlowNode();
List<VariableAccess> undefinitions = markUsages(inode);
@ -65,7 +70,6 @@ public class VariableAccessVisitor extends JavaParserVisitorAdapter {
for (Map<VariableNameDeclaration, List<NameOccurrence>> declarations : variableDeclarations) {
for (Map.Entry<VariableNameDeclaration, List<NameOccurrence>> entry : declarations.entrySet()) {
VariableNameDeclaration vnd = entry.getKey();
if (vnd.getAccessNodeParent() instanceof ASTFormalParameter) {
// no definition/undefinition/references for parameters
continue;
@ -76,8 +80,58 @@ public class VariableAccessVisitor extends JavaParserVisitorAdapter {
}
undefinitions.add(new VariableAccess(VariableAccess.UNDEFINITION, vnd.getImage()));
//make arraylist which could store all name occurrences
List<NameOccurrence> data = new ArrayList<>();
//make arraylist which could store sorted name occurrences
List<NameOccurrence> order = new ArrayList<>();
//add all occurrences to arraylist(data)
for (NameOccurrence occurrence : entry.getValue()) {
addAccess((JavaNameOccurrence) occurrence, inode);
data.add(occurrence);
}
//make arraylist which could store pair structure which is consist of assignment operator and related Name occurrences
ArrayList<SimpleEntry<Node, NameOccurrence>> assignments = new ArrayList<>();
//travers all elements which are in arraylist(data)
for (NameOccurrence name : data) {
//Make a flag which is for preventing double addition of same name occurrence
int flag = 0;
//traverse parents nodes until it is method declaration or constructor declaration
checker :
for (Node temp = name.getLocation(); !(temp.jjtGetParent() instanceof ASTMethodDeclaration)
&& !(temp.jjtGetParent() instanceof ASTConstructorDeclaration); temp = temp.jjtGetParent()) {
//traverse children nodes to check it has assignment operator as a child
for (int i = 0; i < temp.jjtGetNumChildren(); i++) {
if (temp.jjtGetChild(i) instanceof ASTAssignmentOperator) {
//if assignment operator is found, add to arraylist(assignments) with the assignment operator and its name
assignments.add(new SimpleEntry(temp.jjtGetChild(i), name));
//change flag
flag = 1;
break checker;
}
}
}
//if a name is not related to assignment operator, add to arraylist(assignments) with null and its name
if (flag == 0) {
assignments.add(new SimpleEntry(null, name));
}
}
//swap the arraylist(assignments)'s elements, when it share same assignment operator
for (int i = 0; i < assignments.size() - 1; i++) {
if (assignments.get(i).getKey() != null
&& assignments.get(i).getKey().equals(assignments.get(i + 1).getKey())) {
Collections.swap(assignments, i, i + 1);
}
}
//add sorted element from assignments(arraylist) to order(arraylist)
for (SimpleEntry<Node, NameOccurrence> tempPair : assignments) {
order.add(tempPair.getValue());
}
//add access to the sorted arraylist
for (NameOccurrence orderedOccurrence : order) {
addAccess((JavaNameOccurrence) orderedOccurrence, inode);
}
}
}