Skip to content

Commit 6563215

Browse files
cushonError Prone Team
authored andcommitted
Make AppliedFix more efficient
PiperOrigin-RevId: 439646636
1 parent fe05664 commit 6563215

File tree

2 files changed

+27
-10
lines changed

2 files changed

+27
-10
lines changed

check_api/src/main/java/com/google/errorprone/JavacErrorDescriptionListener.java

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -83,7 +83,8 @@ private JavacErrorDescriptionListener(
8383
checkNotNull(endPositions);
8484
try {
8585
CharSequence sourceFileContent = sourceFile.getCharContent(true);
86-
fixToAppliedFix = fix -> AppliedFix.fromSource(sourceFileContent, endPositions).apply(fix);
86+
AppliedFix.Applier applier = AppliedFix.fromSource(sourceFileContent, endPositions);
87+
fixToAppliedFix = applier::apply;
8788
} catch (IOException e) {
8889
throw new UncheckedIOException(e);
8990
}

check_api/src/main/java/com/google/errorprone/fixes/AppliedFix.java

Lines changed: 25 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -18,12 +18,18 @@
1818

1919
import static com.google.common.base.Preconditions.checkArgument;
2020

21+
import com.google.common.base.Supplier;
22+
import com.google.common.base.Suppliers;
2123
import com.sun.tools.javac.tree.EndPosTable;
2224
import java.io.IOException;
2325
import java.io.LineNumberReader;
2426
import java.io.StringReader;
2527
import java.util.HashSet;
28+
import java.util.NavigableMap;
2629
import java.util.Set;
30+
import java.util.TreeMap;
31+
import java.util.regex.Matcher;
32+
import java.util.regex.Pattern;
2733
import javax.annotation.Nullable;
2834

2935
/**
@@ -52,10 +58,12 @@ public boolean isRemoveLine() {
5258
public static class Applier {
5359
private final CharSequence source;
5460
private final EndPosTable endPositions;
61+
private final Supplier<NavigableMap<Integer, Integer>> lineOffsets;
5562

5663
public Applier(CharSequence source, EndPosTable endPositions) {
5764
this.source = source;
5865
this.endPositions = endPositions;
66+
this.lineOffsets = Suppliers.memoize(() -> lineOffsets(source.toString()));
5967
}
6068

6169
/**
@@ -80,15 +88,7 @@ public AppliedFix apply(Fix suggestedFix) {
8088
replaced.replace(repl.startPosition(), repl.endPosition(), repl.replaceWith());
8189

8290
// Find the line number(s) being modified
83-
// TODO: this could be more efficient
84-
try {
85-
LineNumberReader lineNumberReader =
86-
new LineNumberReader(new StringReader(source.toString()));
87-
lineNumberReader.skip(repl.startPosition());
88-
modifiedLines.add(lineNumberReader.getLineNumber());
89-
} catch (IOException e) {
90-
// impossible since source is in-memory
91-
}
91+
modifiedLines.add(lineOffsets.get().floorEntry(repl.startPosition()).getValue());
9292
}
9393

9494
// Not sure this is really the right behavior, but otherwise we can end up with an infinite
@@ -138,4 +138,20 @@ private static Set<Replacement> descending(Set<Replacement> set) {
138138
public static Applier fromSource(CharSequence source, EndPosTable endPositions) {
139139
return new Applier(source, endPositions);
140140
}
141+
142+
private static final Pattern NEWLINE = Pattern.compile("\\R");
143+
144+
/** Returns the start offsets of the lines in the input. */
145+
private static NavigableMap<Integer, Integer> lineOffsets(String input) {
146+
NavigableMap<Integer, Integer> lines = new TreeMap<>();
147+
int line = 0;
148+
int idx = 0;
149+
lines.put(idx, line++);
150+
Matcher matcher = NEWLINE.matcher(input);
151+
while (matcher.find(idx)) {
152+
idx = matcher.end();
153+
lines.put(idx, line++);
154+
}
155+
return lines;
156+
}
141157
}

0 commit comments

Comments
 (0)