fix SOE on undo

This commit is contained in:
Dennis Ushakov
2015-01-26 21:22:46 +03:00
parent 09ff2cd700
commit aa75a2c9e5
2 changed files with 23 additions and 6 deletions
@@ -152,6 +152,8 @@ public class XmlTagNameSynchronizer extends CommandAdapter implements Applicatio
if (myState == State.APPLYING) return;
final Document document = event.getDocument();
final int offset = event.getOffset();
final int oldLength = event.getOldLength();
if (myState == State.INITIAL) {
final PsiFile file = myDocumentManager.getPsiFile(document);
if (file == null) return;
@@ -186,14 +188,17 @@ public class XmlTagNameSynchronizer extends CommandAdapter implements Applicatio
myMarkers.add(Couple.of(leader, support));
}
if (!fitsInMarker(offset, oldLength)) {
clearMarkers();
return;
}
myState = State.TRACKING;
}
if (myMarkers.isEmpty()) return;
final CharSequence fragment = event.getNewFragment();
final int offset = event.getOffset();
final int newLength = event.getNewLength();
final int oldLength = event.getOldLength();
if (document.getUserData(XmlTagInsertHandler.ENFORCING_TAG) == Boolean.TRUE) {
// xml completion inserts extra space after tag name to ensure correct parsing
@@ -208,6 +213,14 @@ public class XmlTagNameSynchronizer extends CommandAdapter implements Applicatio
}
}
boolean fitsInMarker = fitsInMarker(offset, oldLength);
if (!fitsInMarker) {
clearMarkers();
beforeDocumentChange(event);
}
}
public boolean fitsInMarker(int offset, int oldLength) {
boolean fitsInMarker = false;
for (Couple<RangeMarker> leaderAndSupport : myMarkers) {
final RangeMarker leader = leaderAndSupport.first;
@@ -217,10 +230,7 @@ public class XmlTagNameSynchronizer extends CommandAdapter implements Applicatio
}
fitsInMarker |= offset >= leader.getStartOffset() && offset + oldLength <= leader.getEndOffset();
}
if (!fitsInMarker) {
clearMarkers();
beforeDocumentChange(event);
}
return fitsInMarker;
}
public void clearMarkers() {
@@ -21,6 +21,7 @@ import com.intellij.lang.injection.InjectedLanguageManager;
import com.intellij.lang.injection.MultiHostInjector;
import com.intellij.lang.injection.MultiHostRegistrar;
import com.intellij.lang.xml.XMLLanguage;
import com.intellij.openapi.actionSystem.IdeActions;
import com.intellij.openapi.application.ApplicationManager;
import com.intellij.openapi.command.CommandProcessor;
import com.intellij.openapi.editor.actionSystem.DocCommandGroupId;
@@ -99,6 +100,12 @@ public class XmlSyncTagTest extends LightPlatformCodeInsightFixtureTestCase {
"<html><body></body><bertran></bertran><bertran></bertran><html>");
}
public void testUndo() {
doTest("<div<caret>></div>", "v", "<divv></divv>");
myFixture.performEditorAction(IdeActions.ACTION_UNDO);
myFixture.checkResult("<div></div>");
}
public void testInjection() {
final MultiHostInjector injector = new MultiHostInjector() {
@Override