Skip to content

Commit a741399

Browse files
committed
Use a BufferedReader to parse diff trees
By using `BufferedReader`s all the platform dependent line endings are handled automatically. This also reduces space usage if the input is read from a file, because not all lines are duplicated in memory at the same time. Call sites which generate a `String` and have to use `StringReader` are subject to future refactoring.
1 parent ed8aa8a commit a741399

3 files changed

Lines changed: 34 additions & 15 deletions

File tree

src/main/java/org/variantsync/diffdetective/diff/difftree/DiffTree.java

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -8,9 +8,10 @@
88
import org.variantsync.diffdetective.diff.difftree.traverse.DiffTreeVisitor;
99
import org.variantsync.diffdetective.diff.result.DiffResult;
1010
import org.variantsync.diffdetective.util.Assert;
11-
import org.variantsync.diffdetective.util.IO;
1211

12+
import java.io.BufferedReader;
1313
import java.io.IOException;
14+
import java.nio.file.Files;
1415
import java.nio.file.Path;
1516
import java.util.ArrayList;
1617
import java.util.HashMap;
@@ -48,10 +49,11 @@ public static DiffResult<DiffTree> fromDiff(final String diff, boolean collapseM
4849
}
4950

5051
public static DiffResult<DiffTree> fromFile(final Path p, boolean collapseMultipleCodeLines, boolean ignoreEmptyLines, final DiffNodeParser annotationParser) throws IOException {
51-
final String fullDiff = IO.readAsString(p);
52-
final DiffResult<DiffTree> tree = DiffTreeParser.createDiffTree(fullDiff, collapseMultipleCodeLines, ignoreEmptyLines, annotationParser);
53-
tree.unwrap().ifSuccess(t -> t.setSource(new PatchFile(p)));
54-
return tree;
52+
try (BufferedReader file = Files.newBufferedReader(p)) {
53+
final DiffResult<DiffTree> tree = DiffTreeParser.createDiffTree(file, collapseMultipleCodeLines, ignoreEmptyLines, annotationParser);
54+
tree.unwrap().ifSuccess(t -> t.setSource(new PatchFile(p)));
55+
return tree;
56+
}
5557
}
5658

5759
public static DiffResult<DiffTree> fromDiff(final String diff, boolean collapseMultipleCodeLines, boolean ignoreEmptyLines, final DiffNodeParser annotationParser) {

src/main/java/org/variantsync/diffdetective/diff/difftree/parse/DiffTreeParser.java

Lines changed: 17 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,9 @@
1717
import org.variantsync.diffdetective.util.Assert;
1818
import org.variantsync.diffdetective.util.StringUtils;
1919

20+
import java.io.BufferedReader;
2021
import java.io.IOException;
22+
import java.io.StringReader;
2123
import java.util.ArrayList;
2224
import java.util.List;
2325
import java.util.Stack;
@@ -46,8 +48,19 @@ public static DiffResult<DiffTree> createDiffTree(
4648
boolean ignoreEmptyLines,
4749
DiffNodeParser nodeParser)
4850
{
49-
final String[] fullDiffLines = fullDiff.split(LINEBREAK_REGEX);
51+
try {
52+
return createDiffTree(new BufferedReader(new StringReader(fullDiff)), collapseMultipleCodeLines, ignoreEmptyLines, nodeParser);
53+
} catch (IOException e) {
54+
throw new AssertionError("No actual IO should be performed, because only a StringReader is used");
55+
}
56+
}
5057

58+
public static DiffResult<DiffTree> createDiffTree(
59+
BufferedReader fullDiff,
60+
boolean collapseMultipleCodeLines,
61+
boolean ignoreEmptyLines,
62+
DiffNodeParser nodeParser) throws IOException
63+
{
5164
final List<DiffNode> nodes = new ArrayList<>();
5265
final Stack<DiffNode> beforeStack = new Stack<>();
5366
final Stack<DiffNode> afterStack = new Stack<>();
@@ -68,8 +81,9 @@ public static DiffResult<DiffTree> createDiffTree(
6881
beforeStack.push(root);
6982
afterStack.push(root);
7083

71-
for (int i = 0; i < fullDiffLines.length; i++) {
72-
final String currentLine = fullDiffLines[i];
84+
String line;
85+
for (int i = 0; (line = fullDiff.readLine()) != null; i++) {
86+
final String currentLine = line; // Has to be final, because it's used in a lambda.
7387
final DiffType diffType = DiffType.ofDiffLine(currentLine);
7488

7589
// count line numbers

src/test/java/TestMultiLineMacros.java

Lines changed: 10 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -15,20 +15,23 @@
1515
import org.variantsync.diffdetective.util.StringUtils;
1616
import org.variantsync.functjonal.Pair;
1717

18+
import java.io.BufferedReader;
1819
import java.io.IOException;
20+
import java.nio.file.Files;
1921
import java.nio.file.Path;
2022

2123
public class TestMultiLineMacros {
2224
private static final Path resDir = Constants.RESOURCE_DIR.resolve("multilinemacros");
2325

2426
public void diffToDiffTree(DiffTreeLineGraphExportOptions exportOptions, Path p) throws IOException {
25-
final String fullDiff = IO.readAsString(p);
26-
27-
final DiffTree tree = DiffTreeParser.createDiffTree(
28-
fullDiff,
29-
true,
30-
true,
31-
DiffNodeParser.Default).unwrap().getSuccess();
27+
DiffTree tree;
28+
try (BufferedReader fullDiff = Files.newBufferedReader(p)) {
29+
tree = DiffTreeParser.createDiffTree(
30+
fullDiff,
31+
true,
32+
true,
33+
DiffNodeParser.Default).unwrap().getSuccess();
34+
}
3235

3336
final Pair<DiffTreeSerializeDebugData, String> result = LineGraphExport.toLineGraphFormat(tree, exportOptions);
3437
Assert.assertNotNull(result);

0 commit comments

Comments
 (0)