RegionDiffFormatter may drop essential changes at the boundary of a

change region #1559

- handle and test windows line ends, too.

Signed-off-by: Stephan Herrmann <stephan.herrmann@berlin.de>
This commit is contained in:
Stephan Herrmann 2020-08-26 18:47:31 +02:00 committed by Christian Dietrich
parent 45142a25fc
commit 2f436d8985
3 changed files with 59 additions and 5 deletions

View file

@ -506,6 +506,25 @@ class ChangeSerializerTest {
} }
@Test @Test
def void testAddElementsWithEmptyLineUnix() {
val oldLineSeparator = System.getProperty("line.separator")
System.setProperty("line.separator", "\n")
try {
testAddElementsWithEmptyLine()
} finally {
System.setProperty("line.separator", oldLineSeparator)
}
}
@Test
def void testAddElementsWithEmptyLineWindows() {
val oldLineSeparator = System.getProperty("line.separator")
System.setProperty("line.separator", "\r\n")
try {
testAddElementsWithEmptyLine()
} finally {
System.setProperty("line.separator", oldLineSeparator)
}
}
def void testAddElementsWithEmptyLine() { def void testAddElementsWithEmptyLine() {
val uri = "inmemory:/file-add.pstl" val uri = "inmemory:/file-add.pstl"
val fs = new InMemoryURIHandler() val fs = new InMemoryURIHandler()

View file

@ -839,6 +839,27 @@ public class ChangeSerializerTest {
} }
@Test @Test
public void testAddElementsWithEmptyLineUnix() {
final String oldLineSeparator = System.getProperty("line.separator");
System.setProperty("line.separator", "\n");
try {
this.testAddElementsWithEmptyLine();
} finally {
System.setProperty("line.separator", oldLineSeparator);
}
}
@Test
public void testAddElementsWithEmptyLineWindows() {
final String oldLineSeparator = System.getProperty("line.separator");
System.setProperty("line.separator", "\r\n");
try {
this.testAddElementsWithEmptyLine();
} finally {
System.setProperty("line.separator", oldLineSeparator);
}
}
public void testAddElementsWithEmptyLine() { public void testAddElementsWithEmptyLine() {
final String uri = "inmemory:/file-add.pstl"; final String uri = "inmemory:/file-add.pstl";
final InMemoryURIHandler fs = new InMemoryURIHandler(); final InMemoryURIHandler fs = new InMemoryURIHandler();

View file

@ -108,7 +108,7 @@ public class RegionDiffFormatter {
local.add(re); local.add(re);
} else if (hasOverlappingWhitespacePrefix(r, re)) { } else if (hasOverlappingWhitespacePrefix(r, re)) {
// change overlaps with a region boundary, trim it to the part within // change overlaps with a region boundary, trim it to the part within
TextReplacement newReplacement = trimReplacement(re, re.getText()); TextReplacement newReplacement = trimReplacement(re);
if (newReplacement != null) if (newReplacement != null)
local.add(newReplacement); local.add(newReplacement);
} }
@ -141,14 +141,28 @@ public class RegionDiffFormatter {
return false; return false;
} }
private TextReplacement trimReplacement(ITextReplacement re, String prefixText) { private TextReplacement trimReplacement(ITextReplacement re) {
String prefixText = re.getText();
TextReplacement newReplacement = null; TextReplacement newReplacement = null;
int prefixLen = prefixText.length(); int prefixLen = prefixText.length();
String newText = re.getReplacementText(); String newText = re.getReplacementText();
if (newText.length() > prefixLen) { if (newText.length() > prefixLen) {
newText = newText.substring(prefixLen); int prefixLenNew = 0;
int newOffset = re.getOffset()+prefixLen; for (int i = 0; i < prefixLen && prefixLenNew < newText.length(); i++) {
int newLength = re.getLength()-prefixLen; char pchar = prefixText.charAt(i);
char rchar = newText.charAt(prefixLenNew++);
if (pchar != rchar) {
if (pchar == '\n' && rchar == '\r' && prefixLenNew < newText.length() && newText.charAt(prefixLenNew) == '\n')
prefixLenNew++; // found '\n' -> '\r\n', cut off one more char
else
return null; // not a true prefix match
}
}
newText = newText.substring(prefixLenNew);
int newOffset = re.getOffset() + prefixLen;
int newLength = re.getLength() - prefixLen;
if (newLength < 0)
return null;
newReplacement = new TextReplacement(re.getTextRegionAccess(), newOffset, newLength, newText); newReplacement = new TextReplacement(re.getTextRegionAccess(), newOffset, newLength, newText);
} }
return newReplacement; return newReplacement;