diff --git a/src/main/java/org/openrewrite/analysis/controlflow/ControlFlowVisualization.java b/src/main/java/org/openrewrite/analysis/controlflow/ControlFlowVisualization.java index 3169773f9..fcf77a078 100644 --- a/src/main/java/org/openrewrite/analysis/controlflow/ControlFlowVisualization.java +++ b/src/main/java/org/openrewrite/analysis/controlflow/ControlFlowVisualization.java @@ -25,6 +25,7 @@ @Value @EqualsAndHashCode(callSuper = false) public class ControlFlowVisualization extends Recipe { + @Option(displayName = "Include Dotfile", description = "Also output with a Dotfile which can be then later visualized by Graphviz.") boolean includeDotfile; diff --git a/src/main/java/org/openrewrite/analysis/dataflow/global/RenderGlobalFlowPaths.java b/src/main/java/org/openrewrite/analysis/dataflow/global/RenderGlobalFlowPaths.java index 5f5559124..ca20bde7e 100644 --- a/src/main/java/org/openrewrite/analysis/dataflow/global/RenderGlobalFlowPaths.java +++ b/src/main/java/org/openrewrite/analysis/dataflow/global/RenderGlobalFlowPaths.java @@ -28,13 +28,16 @@ public class RenderGlobalFlowPaths
extends JavaIsoVisitor
{
@Override
public Expression visitExpression(Expression expression, P p) {
Expression e = super.visitExpression(expression, p);
+ boolean marked = false;
if (acc.isSource(getCursor())) {
e = SearchResult.mergingFound(e, "source");
+ marked = true;
}
if (acc.isSink(getCursor())) {
e = SearchResult.mergingFound(e, "sink");
+ marked = true;
}
- if (expression != e) {
+ if (marked) {
return e;
}
if (acc.isFlowParticipant(getCursor())) {
@@ -46,13 +49,16 @@ public Expression visitExpression(Expression expression, P p) {
@Override
public J.VariableDeclarations.NamedVariable visitVariable(J.VariableDeclarations.NamedVariable variable, P p) {
J.VariableDeclarations.NamedVariable v = super.visitVariable(variable, p);
+ boolean marked = false;
if (acc.isSource(getCursor())) {
v = SearchResult.mergingFound(v, "source");
+ marked = true;
}
if (acc.isSink(getCursor())) {
v = SearchResult.mergingFound(v, "sink");
+ marked = true;
}
- if (variable != v) {
+ if (marked) {
return v;
}
if (acc.isFlowParticipant(getCursor())) {
diff --git a/src/test/java/org/openrewrite/analysis/controlflow/ControlFlowTest.java b/src/test/java/org/openrewrite/analysis/controlflow/ControlFlowTest.java
index eca648e38..0e1cab691 100644
--- a/src/test/java/org/openrewrite/analysis/controlflow/ControlFlowTest.java
+++ b/src/test/java/org/openrewrite/analysis/controlflow/ControlFlowTest.java
@@ -37,6 +37,7 @@ public void defaults(RecipeSpec spec) {
@Test
void displayControlFlowGraphForSingleBasicBlock() {
rewriteRun(
+ //language=java
java(
"""
abstract class Test {
@@ -1665,10 +1666,10 @@ void test() /*~~(BB: 22 CN: 12 EX: 1 | 1L)~~>*/{
/*~~(3L)~~>*/if ((/*~~(2C)~~>*/potato)) /*~~(4L)~~>*/{
// ...
}
- /*~~(5L)~~>*/if (/*~~(3C)~~>*/potato && /*~~(6L)~~>*/turnip) /*~~(7L)~~>*/{
+ /*~~(5L)~~>*/if (/*~~(3C)~~>*/potato && /*~~(6L)~~>*//*~~(4C)~~>*/turnip) /*~~(7L)~~>*/{
// ...
}
- /*~~(8L)~~>*/if (/*~~(5C)~~>*/potato && /*~~(9L)~~>*/turnip || /*~~(10L)~~>*/squash) /*~~(11L)~~>*/{
+ /*~~(8L)~~>*/if (/*~~(5C)~~>*/potato && /*~~(9L)~~>*//*~~(6C)~~>*/turnip || /*~~(10L)~~>*//*~~(7C)~~>*/squash) /*~~(11L)~~>*/{
// ...
}
int a = /*~~(12L)~~>*/1, b = 2;
@@ -1925,7 +1926,7 @@ abstract class Test {
abstract boolean otherCondition();
void test() /*~~(BB: 3 CN: 2 EX: 1 | 1L)~~>*/{
- while (/*~~(1C)~~>*/condition() && /*~~(2L | 2C)~~>*/otherCondition())/*~~(3L)~~>*/;
+ while (/*~~(1C)~~>*/condition() && /*~~(2L | 2C)~~>*//*~~(2C)~~>*/otherCondition())/*~~(3L)~~>*/;
}
}
"""
@@ -1956,7 +1957,7 @@ abstract class Test {
abstract boolean thirdCondition();
void test() /*~~(BB: 4 CN: 3 EX: 1 | 1L)~~>*/{
- while (/*~~(1C)~~>*/condition() && /*~~(2L | 2C)~~>*/otherCondition() && /*~~(3L | 3C)~~>*/thirdCondition())/*~~(4L)~~>*/;
+ while (/*~~(1C)~~>*/condition() && /*~~(2L | 2C)~~>*//*~~(2C)~~>*/otherCondition() && /*~~(3L | 3C)~~>*//*~~(3C)~~>*/thirdCondition())/*~~(4L)~~>*/;
}
}
"""
@@ -2439,7 +2440,7 @@ void test(boolean condition) {
"""
abstract class Test {
abstract String[] array();
-
+
void test(boolean condition) /*~~(BB: 5 CN: 2 EX: 1 | 1L)~~>*/{
for (String s : /*~~(1C)~~>*/condition ? /*~~(2L)~~>*/array() : new /*~~(3L)~~>*/String[] { "Hello!" }) /*~~(4L)~~>*/{
System.out.println(s);
@@ -2698,7 +2699,7 @@ void switchCaseNoDefault() {
"""
class Test {
enum E { A, B, C }
-
+
void test(E x) {
switch (x) {
case A:
@@ -2718,7 +2719,7 @@ void test(E x) {
"""
class Test {
enum E { A, B, C }
-
+
void test(E x) /*~~(BB: 7 CN: 3 EX: 1 | 1L)~~>*/{
switch (x) {
/*~~(1C)~~>*/case A:
diff --git a/src/test/java/org/openrewrite/analysis/controlflow/GuardTest.java b/src/test/java/org/openrewrite/analysis/controlflow/GuardTest.java
index a0b7e14f7..f19719d7c 100644
--- a/src/test/java/org/openrewrite/analysis/controlflow/GuardTest.java
+++ b/src/test/java/org/openrewrite/analysis/controlflow/GuardTest.java
@@ -283,7 +283,7 @@ void test() {
@Test
void identifiesGuardsForControlParenthesesWithMissingTypeInformation() {
rewriteRun(
- spec -> spec.typeValidationOptions(TypeValidation.builder().identifiers(false).build()),
+ spec -> spec.typeValidationOptions(TypeValidation.none()),
java(
"""
class Test {
diff --git a/src/test/java/org/openrewrite/analysis/dataflow/FindLocalTaintFlowTest.java b/src/test/java/org/openrewrite/analysis/dataflow/FindLocalTaintFlowTest.java
index eca95ed47..4c35780a4 100644
--- a/src/test/java/org/openrewrite/analysis/dataflow/FindLocalTaintFlowTest.java
+++ b/src/test/java/org/openrewrite/analysis/dataflow/FindLocalTaintFlowTest.java
@@ -72,6 +72,7 @@ public boolean isSanitizer(DataFlowNode node) {
@Test
void taintTrackingThroughStringManipulations() {
rewriteRun(
+ //language=java
java(
"""
class Test {
@@ -736,7 +737,7 @@ void taintTrackingThroughMethodCallArgument() {
java(
"""
import java.util.Objects;
-
+
class Test {
String source() { return null; }
void test() {
@@ -747,7 +748,7 @@ void test() {
""",
"""
import java.util.Objects;
-
+
class Test {
String source() { return null; }
void test() {
diff --git a/src/test/java/org/openrewrite/analysis/search/FindFlowBetweenMethodsTest.java b/src/test/java/org/openrewrite/analysis/search/FindFlowBetweenMethodsTest.java
index 2425bcad4..65fde12de 100644
--- a/src/test/java/org/openrewrite/analysis/search/FindFlowBetweenMethodsTest.java
+++ b/src/test/java/org/openrewrite/analysis/search/FindFlowBetweenMethodsTest.java
@@ -39,6 +39,7 @@ void taintFlowBetweenSubjectOnly() {
"Taint"
)
),
+ //language=java
java(
"""
import java.util.LinkedList;
@@ -78,6 +79,7 @@ void taintFlowBetweenArgumentsOnly() {
"Taint"
)
),
+ //language=java
java(
"""
import java.util.LinkedList;
@@ -118,6 +120,7 @@ void taintFlowThroughMultipleSubjectsIntegerSourceAndSinkMethodsSpecified() {
"Taint"
)
),
+ //language=java
java(
"""
import java.util.LinkedList;
@@ -160,6 +163,7 @@ void noTaintFlowThroughArguments() {
"Taint"
)
),
+ //language=java
java(
"""
import java.util.LinkedList;
@@ -186,6 +190,7 @@ void taintFlowBetweenArgumentsAndSubject() {
"Taint"
)
),
+ //language=java
java(
"""
import java.util.LinkedList;
@@ -227,6 +232,7 @@ void dataFlowBetweenFiles() {
"Value"
)
),
+ //language=java
java(
"""
class Test {
@@ -246,6 +252,7 @@ void test() {
}
"""
),
+ //language=java
java(
"""
class Provider {
diff --git a/src/test/java/org/openrewrite/analysis/search/FindMethodsTest.java b/src/test/java/org/openrewrite/analysis/search/FindMethodsTest.java
index 8a9291ae0..7059a5dca 100644
--- a/src/test/java/org/openrewrite/analysis/search/FindMethodsTest.java
+++ b/src/test/java/org/openrewrite/analysis/search/FindMethodsTest.java
@@ -29,6 +29,7 @@ class FindMethodsTest implements RewriteTest {
void findConstructors() {
rewriteRun(
spec -> spec.recipe(new FindMethods("A