diff --git a/core/src/main/java/edu/ucr/cs/riple/core/Annotator.java b/core/src/main/java/edu/ucr/cs/riple/core/Annotator.java index 1ed2a7e04..dd7b91552 100644 --- a/core/src/main/java/edu/ucr/cs/riple/core/Annotator.java +++ b/core/src/main/java/edu/ucr/cs/riple/core/Annotator.java @@ -53,7 +53,6 @@ import java.util.Objects; import java.util.Set; import java.util.stream.Collectors; -import java.util.stream.Stream; /** * The main class of the core module. Responsible for analyzing the target module and injecting the @@ -185,7 +184,7 @@ private void executeNextIteration( Set selectedFixes = latestReports.stream() .filter(Report::approved) - .flatMap(report -> config.chain ? report.tree.stream() : Stream.of(report.root)) + .flatMap(report -> report.getSelectedFixes(config)) .collect(Collectors.toSet()); injector.injectFixes(selectedFixes); diff --git a/core/src/main/java/edu/ucr/cs/riple/core/Report.java b/core/src/main/java/edu/ucr/cs/riple/core/Report.java index b67d98fa4..4c1533b47 100644 --- a/core/src/main/java/edu/ucr/cs/riple/core/Report.java +++ b/core/src/main/java/edu/ucr/cs/riple/core/Report.java @@ -34,6 +34,7 @@ import java.util.Objects; import java.util.Set; import java.util.stream.Collectors; +import java.util.stream.Stream; /** * Container class to store information regarding effectiveness of a fix, its associated fix tree @@ -247,4 +248,28 @@ public boolean isInProgress(Config config) { return (!finished && (!config.bailout || localEffect > 0)) || triggeredFixes.stream().anyMatch(input -> !input.fixSourceIsInTarget); } + + /** + * Returns the stream of fixes that needs to be applied to source code if report is tagged as + * {@link Tag#APPROVE}. + * + * @param config Annotator config. + * @return Stream of selected fixes. + */ + public Stream getSelectedFixes(Config config) { + return tree.stream() + .filter( + input -> { + // If chain is active, add all fixes + if (config.chain) { + return true; + } + // Add all fixes reported from downstream + if (!input.fixSourceIsInTarget) { + return true; + } + // Add root. + return input.equals(root); + }); + } } diff --git a/core/src/main/java/edu/ucr/cs/riple/core/metadata/graph/Node.java b/core/src/main/java/edu/ucr/cs/riple/core/metadata/graph/Node.java index 47de6ad04..14dfa8ff7 100644 --- a/core/src/main/java/edu/ucr/cs/riple/core/metadata/graph/Node.java +++ b/core/src/main/java/edu/ucr/cs/riple/core/metadata/graph/Node.java @@ -203,7 +203,6 @@ public void updateTriggered(Collection fixes) { /** Merges triggered fixes to the tree, to prepare the analysis for the next depth. */ public void mergeTriggered() { this.tree.addAll(this.triggeredFixes); - this.tree.forEach(fix -> fix.fixSourceIsInTarget = true); this.triggeredFixes.clear(); } diff --git a/core/src/test/java/edu/ucr/cs/riple/core/tools/CoreTestHelper.java b/core/src/test/java/edu/ucr/cs/riple/core/tools/CoreTestHelper.java index 05431ca92..51165251b 100644 --- a/core/src/test/java/edu/ucr/cs/riple/core/tools/CoreTestHelper.java +++ b/core/src/test/java/edu/ucr/cs/riple/core/tools/CoreTestHelper.java @@ -67,6 +67,7 @@ public class CoreTestHelper { private boolean downstreamDependencyAnalysisActivated = false; private AnalysisMode mode = AnalysisMode.LOCAL; private Config config; + private boolean chain = true; public CoreTestHelper(Path projectPath, Path outDirPath, List modules) { this.projectPath = projectPath; @@ -150,6 +151,11 @@ public CoreTestHelper enableDownstreamDependencyAnalysis() { return enableDownstreamDependencyAnalysis(AnalysisMode.LOWER_BOUND); } + public CoreTestHelper applyRootFixOnly() { + this.chain = false; + return this; + } + public void start() { Path configPath = outDirPath.resolve("config.json"); createFiles(); @@ -264,7 +270,7 @@ private void makeAnnotatorConfigFile(Path configPath) { builder.outputDir = outDirPath.toString(); builder.depth = depth; builder.bailout = !disableBailout; - builder.chain = true; + builder.chain = chain; builder.outerLoopActivation = requestCompleteLoop; builder.optimized = true; builder.downStreamDependenciesAnalysisActivated = downstreamDependencyAnalysisActivated;