Prevent markers from overlapping after whitespace balancing (WEB-12693) [a=Roman Shevchenko, r=Maxim.Mossienko]

This commit is contained in:
Maxim.Mossienko
2014-07-28 11:33:38 +02:00
parent d3b89163aa
commit 5d4e607213
2 changed files with 28 additions and 1 deletions
@@ -1154,6 +1154,7 @@ public class PsiBuilderImpl extends UserDataHolderBase implements PsiBuilder {
private void balanceWhiteSpaces() {
RelativeTokenTypesView wsTokens = new RelativeTokenTypesView();
RelativeTokenTextView tokenTextGetter = new RelativeTokenTextView();
int lastIndex = 0;
for (int i = 1, size = myProduction.size() - 1; i < size; i++) {
ProductionMarker item = myProduction.get(i);
@@ -1162,7 +1163,7 @@ public class PsiBuilderImpl extends UserDataHolderBase implements PsiBuilder {
}
int prevProductionLexIndex = myProduction.get(i - 1).myLexemeIndex;
int wsStartIndex = item.myLexemeIndex;
int wsStartIndex = Math.max(item.myLexemeIndex, lastIndex);
while (wsStartIndex > prevProductionLexIndex && whitespaceOrComment(myLexTypes[wsStartIndex - 1])) wsStartIndex--;
int wsEndIndex = item.myLexemeIndex;
while (wsEndIndex < myLexemeCount && whitespaceOrComment(myLexTypes[wsEndIndex])) wsEndIndex++;
@@ -1173,6 +1174,11 @@ public class PsiBuilderImpl extends UserDataHolderBase implements PsiBuilder {
boolean atEnd = wsStartIndex == 0 || wsEndIndex == myLexemeCount;
item.myLexemeIndex = wsStartIndex + item.myEdgeTokenBinder.getEdgePosition(wsTokens, atEnd, tokenTextGetter);
}
else if (item.myLexemeIndex < wsStartIndex) {
item.myLexemeIndex = wsStartIndex;
}
lastIndex = item.myLexemeIndex;
}
}
@@ -461,6 +461,27 @@ public class PsiBuilderQuickTest extends LightPlatformLangTestCase {
" PsiElement(OTHER)('}')\n");
}
public void testEndMarkersOverlapping() {
doTest("a ",
new Parser() {
@Override
public void parse(PsiBuilder builder) {
PsiBuilder.Marker e1 = builder.mark();
PsiBuilder.Marker e2 = builder.mark();
builder.advanceLexer();
e2.done(OTHER);
e2.setCustomEdgeTokenBinders(null, WhitespacesBinders.GREEDY_RIGHT_BINDER);
e1.done(OTHER);
e1.setCustomEdgeTokenBinders(null, WhitespacesBinders.DEFAULT_RIGHT_BINDER);
assertTrue(builder.eof());
}
},
"Element(ROOT)\n" +
" Element(OTHER)\n" +
" Element(OTHER)\n" +
" PsiElement(LETTER)('a')\n" +
" PsiWhiteSpace(' ')\n");
}
private interface Parser {
void parse(PsiBuilder builder);