Fix a special case for preview/apply fix.
When a file doesn't have end of line mark at the end, some fixes have
the end at the line after the last line instead of last character in the
last line and this caused an exception.
It seems this is a common case for some checkers/linters/etc..., so we
should accept such input as well.
Google-Bug: b/362428689
Release-Notes: skip
Change-Id: Idfb99fed9148584c9b7eb83e6ac9216689bbb3da
diff --git a/java/com/google/gerrit/server/fixes/FixCalculator.java b/java/com/google/gerrit/server/fixes/FixCalculator.java
index c471245..d841054 100644
--- a/java/com/google/gerrit/server/fixes/FixCalculator.java
+++ b/java/com/google/gerrit/server/fixes/FixCalculator.java
@@ -258,6 +258,20 @@
} else {
contentProcessor.processToEndOfLine(append);
contentProcessor.processMultiline(toLine, append);
+ if (contentProcessor.endOfSource
+ && toLine == contentProcessor.srcPosition.line + 1
+ && toColumn == 0) {
+ // There is a special case, when the file doesn't have EOL mark at the end.
+ // The end of a fix replacement range can be expressed in 2 ways:
+ // 1) Line number = the last line number, column = the length of the last line (i.e. a
+ // character after the end of the string)
+ // Or
+ // 2) Line number = the last line number + 1, column = 0 (so it points to a non-existing
+ // line after the last line).
+ // This should be treated as a valid case, but processLineToColumn shouldn't be called
+ // (otherwise it throws an exceptions).
+ return;
+ }
contentProcessor.processLineToColumn(toColumn, append);
}
}
diff --git a/javatests/com/google/gerrit/server/fixes/fixCalculator/MultilineContentNoEOLTest.java b/javatests/com/google/gerrit/server/fixes/fixCalculator/MultilineContentNoEOLTest.java
index dd36e3a..b6c5d47 100644
--- a/javatests/com/google/gerrit/server/fixes/fixCalculator/MultilineContentNoEOLTest.java
+++ b/javatests/com/google/gerrit/server/fixes/fixCalculator/MultilineContentNoEOLTest.java
@@ -276,6 +276,30 @@
}
@Test
+ public void replaceLastLine() throws Exception {
+ FixResult fixResult =
+ FixCalculatorVariousTest.calculateFixSingleReplacement(
+ "First line\nSecond line\nThird line", 3, 0, 3, 10, "Abc\ndef");
+ assertThat(fixResult).text().isEqualTo("First line\nSecond line\nAbc\ndef");
+ assertThat(fixResult).edits().hasSize(1);
+ Edit edit = fixResult.edits.get(0);
+ assertThat(edit).isReplace(2, 1, 2, 2);
+ assertThat(edit).internalEdits().onlyElement().isReplace(0, 10, 0, 7);
+ }
+
+ @Test
+ public void replaceLastLineEndLineNotExists() throws Exception {
+ FixResult fixResult =
+ FixCalculatorVariousTest.calculateFixSingleReplacement(
+ "First line\nSecond line\nThird line", 3, 0, 4, 0, "Abc\ndef");
+ assertThat(fixResult).text().isEqualTo("First line\nSecond line\nAbc\ndef");
+ assertThat(fixResult).edits().hasSize(1);
+ Edit edit = fixResult.edits.get(0);
+ assertThat(edit).isReplace(2, 1, 2, 2);
+ assertThat(edit).internalEdits().onlyElement().isReplace(0, 10, 0, 7);
+ }
+
+ @Test
public void replaceWholeContent() throws Exception {
FixResult fixResult =
FixCalculatorVariousTest.calculateFixSingleReplacement(