Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Use .equals() for nodeValues if == does not work; fixes #3484 #3523

Closed
wants to merge 39 commits into from
Closed
Show file tree
Hide file tree
Changes from 7 commits
Commits
Show all changes
39 commits
Select commit Hold shift + click to select a range
90cdc60
Routines to format AnalysisResult objects
mernst Jul 29, 2020
62376b7
Merge ../checker-framework-branch-master into analysisresult-repr
mernst Jul 29, 2020
c057cdf
Fix issues
mernst Jul 29, 2020
f420843
Use .equals() for nodeValues if == does not work
mernst Jul 29, 2020
fe18877
Javadoc fixes
mernst Jul 29, 2020
65d71dc
Merge ../checker-framework-fork-mernst-branch-analysisresult-repr int…
mernst Jul 29, 2020
c27c7b4
Remove commented-out code
mernst Jul 29, 2020
702f803
Add a repr() method for ControlFlowGraph
mernst Jul 29, 2020
2f6efa5
Add SystemUtil.sleep method
mernst Jul 29, 2020
d1045e1
Remove stray character
mernst Jul 29, 2020
4c9b3cd
Address code review feedback
mernst Jul 30, 2020
b4a3db7
Merge ../checker-framework-branch-master into analysisresult-repr
mernst Jul 30, 2020
3e37f6f
Merge ../checker-framework-fork-mernst-branch-javacutil-sleep into an…
mernst Jul 30, 2020
31f73b8
Fix import statement
mernst Jul 30, 2020
cf227e1
Merge ../checker-framework-branch-master into javacutil-sleep
mernst Jul 30, 2020
ffc8fc9
Fix typo, remove throw
mernst Jul 30, 2020
b5f101b
Merge ../checker-framework-fork-mernst-branch-javacutil-sleep into an…
mernst Jul 30, 2020
1f01fcd
Address code review feedback
mernst Jul 31, 2020
6b00d1e
Merge ../checker-framework-branch-master into analysisresult-repr
mernst Jul 31, 2020
6d76803
More changes from code review
mernst Jul 31, 2020
0453ce1
Merge ../checker-framework-branch-master into analysisresult-repr
mernst Jul 31, 2020
7cc2236
Merge ../checker-framework-fork-mernst-branch-analysisresult-repr int…
mernst Jul 31, 2020
20f244c
Merge ../checker-framework-branch-master into analysisresult-repr
mernst Jul 31, 2020
e45f915
Merge ../checker-framework-fork-mernst-branch-analysisresult-repr int…
mernst Jul 31, 2020
6b2cec3
Merge ../checker-framework-branch-master into analysisresult-repr
mernst Jul 31, 2020
a309b83
Add AnalysisResult.checkRep method
mernst Jul 31, 2020
ca60260
Remove AnalysisResult.checkRep
mernst Jul 31, 2020
6e10edb
Merge ../checker-framework-branch-master into analysisresult-repr
mernst Jul 31, 2020
6194e5c
Merge ../checker-framework-branch-master into analysisresult-checkrep…
mernst Jul 31, 2020
98fe42c
Merge ../checker-framework-fork-mernst-branch-analysisresult-repr int…
mernst Jul 31, 2020
c4bdb38
Merge ../checker-framework-fork-mernst-branch-analysisresult-checkrep…
mernst Jul 31, 2020
835d152
Explain repr()
mernst Jul 31, 2020
f3ebe6f
Don't use repr()
mernst Jul 31, 2020
f0fc6cc
Tweak wording
mernst Jul 31, 2020
cbdde4b
Fix HTML tag
mernst Aug 1, 2020
9c4209a
Merge ../checker-framework-branch-master into analysisresult-checkrep…
mernst Aug 1, 2020
4bcb7ef
Merge ../checker-framework-branch-master into analysisresult-repr
mernst Aug 1, 2020
c429f18
Merge ../checker-framework-fork-mernst-branch-analysisresult-repr int…
mernst Aug 1, 2020
5c39fb6
Merge ../checker-framework-fork-mernst-branch-analysisresult-checkrep…
mernst Aug 1, 2020
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
1 change: 0 additions & 1 deletion checker/tests/nullness/TryCatch.java
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,6 @@ void unreachableCatch(String[] xs) {
t.toString();
try {
} catch (Throwable e) {
// :: error: (dereference.of.nullable)
t.toString();
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,11 +2,14 @@

import com.sun.source.tree.Tree;
import com.sun.source.tree.UnaryTree;
import java.util.ArrayList;
import java.util.Collection;
import java.util.HashMap;
import java.util.IdentityHashMap;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.StringJoiner;
import javax.lang.model.element.Element;
import org.checkerframework.checker.nullness.qual.Nullable;
import org.checkerframework.dataflow.cfg.block.Block;
Expand Down Expand Up @@ -166,7 +169,24 @@ public HashMap<Element, V> getFinalLocalValues() {
* available
*/
public @Nullable V getValue(Node n) {
return nodeValues.get(n);
V result = nodeValues.get(n);
if (result != null) {
return result;
}
List<Node> equalNodes = new ArrayList<>();
for (Node candidate : nodeValues.keySet()) {
if (n.equals(candidate)) {
equalNodes.add(candidate);
}
}
switch (equalNodes.size()) {
case 0:
return null;
case 1:
return nodeValues.get(equalNodes.get(0));
default:
return null;
}
}

/**
Expand Down Expand Up @@ -443,4 +463,125 @@ public static <V extends AbstractValue<V>, S extends Store<S>> S runAnalysisFor(
return transferInput.analysis.runAnalysisFor(
node, before, transferInput, nodeValues, analysisCaches);
}

/**
* Returns a string representation of this.
*
* @return a string representation of this
*/
public String repr() {
StringJoiner result =
new StringJoiner(
String.format("%n "),
String.format("AnalysisResult{%n "),
String.format("%n}"));
result.add("nodeValues = " + nodeValuesRepr(nodeValues));
result.add("treeLookup = " + treeLookupRepr(treeLookup));
result.add("unaryAssignNodeLookup = " + unaryAssignNodeLookup);
result.add("finalLocalValues = " + finalLocalValues);
result.add("stores = " + stores);
result.add("analysisCaches = " + analysisCaches);
return result.toString();
}

/**
* Return a printed representation of a map with the same type as the {@code nodeValues} field.
*
* @param <V> the type of values in the map
* @param nodeValues a map to format
* @return a printed representation of the given map
*/
public static <V> String nodeValuesRepr(Map<Node, V> nodeValues) {
if (nodeValues.isEmpty()) {
return "{}";
}
StringJoiner result = new StringJoiner(String.format("%n "));
result.add("{");
for (Map.Entry<Node, V> entry : nodeValues.entrySet()) {
Node key = entry.getKey();
result.add(String.format("%s => %s", nodeRepr(key), entry.getValue()));
}
result.add("}");
return result.toString();
}

/**
* Return a printed representation of a node.
*
* @param n a node to format
* @return a printed representation of the given node
*/
public static String nodeRepr(Node n) {
return String.format(
"%s [%s %s %s]",
n, n.getClass().getSimpleName(), n.hashCode(), System.identityHashCode(n));
}

/**
* Return a printed representation of a collection of nodes.
*
* @param nodes a collection of nodes to format
* @return a printed representation of the given collection
*/
public static String nodeCollectionRepr(Collection<? extends Node> nodes) {
StringJoiner result = new StringJoiner(", ", "[", "]");
for (Node n : nodes) {
result.add(nodeRepr(n));
}
;
return result.toString();
}

/**
* Return a printed representation of a map with the same type as the {@code treeLookup} field.
*
* @param treeLookup a map to format
* @return a printed representation of the given map
*/
public static String treeLookupRepr(Map<Tree, Set<Node>> treeLookup) {
if (treeLookup.isEmpty()) {
return "{}";
}
StringJoiner result = new StringJoiner(String.format("%n "));
result.add("{");
for (Map.Entry<Tree, Set<Node>> entry : treeLookup.entrySet()) {
Tree key = entry.getKey();
String treeString = key.toString().replaceAll("[ \n\t]+", " ");
if (treeString.length() > 65) {
treeString = "\"" + treeString.substring(0, 60) + "...\"";
}
result.add(treeString + " => " + nodeCollectionRepr(entry.getValue()));
}
result.add("}");
return result.toString();
}

/** Checks representation invariants on this. */
public void checkRep() {
// Require that each node in treeLookup exists in nodeValues.
for (Map.Entry<Tree, Set<Node>> entry : treeLookup.entrySet()) {
for (Node n : entry.getValue()) {
if (!nodeValues.containsKey(n)) {
sleep(100);
throw new BugInCF(
"node %s is in treeLookup but not in nodeValues%n%s",
nodeRepr(n), repr());
}
}
}
}

/**
* Sleep (do nothing) for the given number of milliseconds. This can help to prevent output from
* being interleaved.
*
* @param msec the number of milliseconds to delay before the next action
*/
private void sleep(int msec) {
try {
Thread.sleep(msec);
} catch (InterruptedException ex) {
Thread.currentThread().interrupt(); // Here!
}
}
}