fail fast when creating range marker with invalid offsets from virtual file in presence of cached document

This commit is contained in:
Alexey Kudravtsev
2018-11-06 19:09:59 +03:00
parent ba5dd7a2ee
commit f1b217be4c
2 changed files with 26 additions and 4 deletions
@@ -54,7 +54,12 @@ public class RangeMarkerImpl extends UserDataHolderBase implements RangeMarkerEx
// constructor which creates marker without document and saves it in the virtual file directly. Can be cheaper than loading document.
RangeMarkerImpl(@NotNull VirtualFile virtualFile, int start, int end, boolean register) {
// unfortunately we don't know the exact document size until we load it
this(virtualFile, Integer.MAX_VALUE, start, end, register, false, false);
this(virtualFile, estimateDocumentLength(virtualFile), start, end, register, false, false);
}
private static int estimateDocumentLength(@NotNull VirtualFile virtualFile) {
Document document = FileDocumentManager.getInstance().getCachedDocument(virtualFile);
return document == null ? Integer.MAX_VALUE : document.getTextLength();
}
private RangeMarkerImpl(@NotNull Object documentOrFile, int documentTextLength, int start,
@@ -1112,22 +1112,39 @@ public class RangeMarkerTest extends LightPlatformTestCase {
marker.dispose();
}
public void testLazyRangeMarkersWithInvalidOffset() {
public void testLazyRangeMarkersWithInvalidOffsetWhenNoDocumentCreatedMustInvalidateThemSelvesOnFirstOpportunity() {
psiFile = createFile("x.txt", "");
LazyRangeMarkerFactoryImpl factory = (LazyRangeMarkerFactoryImpl)LazyRangeMarkerFactory.getInstance(getProject());
VirtualFile virtualFile = psiFile.getVirtualFile();
Document document = FileDocumentManager.getInstance().getDocument(virtualFile);
assertEquals("", document.getText());
assertEquals("", psiFile.getText());
RangeMarker marker = factory.createRangeMarker(virtualFile, 1 /* invalid offset */);
document = FileDocumentManager.getInstance().getDocument(virtualFile);
document.replaceString(0, 0, "\n\t\n"); // used to throw AssertionError from RangeMarkerTree.updateMarkersOnChange
assertEquals("\n\t\n", document.getText());
assertFalse(marker.isValid());
}
public void testLazyRangeMarkersWithInvalidOffsetWhenCachedDocumentAlreadyExistsMustRejectInvalidOffsetsRightAway() {
psiFile = createFile("x.txt", "");
LazyRangeMarkerFactoryImpl factory = (LazyRangeMarkerFactoryImpl)LazyRangeMarkerFactory.getInstance(getProject());
VirtualFile virtualFile = psiFile.getVirtualFile();
document = FileDocumentManager.getInstance().getDocument(virtualFile);
assertEquals("", psiFile.getText());
try {
factory.createRangeMarker(virtualFile, 1 /* invalid offset */);
fail("Must fail fast");
}
catch (IllegalArgumentException ignored) {
}
}
public void testNonGreedyMarkersGrowOnAppendingReplace() {
Document doc = new DocumentImpl("foo");
RangeMarker marker = doc.createRangeMarker(0, 3);