From cf16484ec6d294d0c1c7aa8ccac1e05dbb522a5f Mon Sep 17 00:00:00 2001 From: YoonhoChoi96 Date: Fri, 5 Jul 2019 10:04:37 +0900 Subject: [PATCH] Modifiying for reduce Fasle Positive in DFA Analysis Rule --- .../lang/java/dfa/VariableAccessVisitor.java | 58 ++++++++++++++++++- 1 file changed, 56 insertions(+), 2 deletions(-) diff --git a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/dfa/VariableAccessVisitor.java b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/dfa/VariableAccessVisitor.java index ecd6348877..d60c3649d1 100644 --- a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/dfa/VariableAccessVisitor.java +++ b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/dfa/VariableAccessVisitor.java @@ -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 undefinitions = markUsages(inode); @@ -65,7 +70,6 @@ public class VariableAccessVisitor extends JavaParserVisitorAdapter { for (Map> declarations : variableDeclarations) { for (Map.Entry> 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 data = new ArrayList<>(); + + //make arraylist which could store sorted name occurrences + List 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> 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 tempPair : assignments) { + order.add(tempPair.getValue()); + } + //add access to the sorted arraylist + for (NameOccurrence orderedOccurrence : order) { + addAccess((JavaNameOccurrence) orderedOccurrence, inode); } } }