PY-14408 PythonIndentingProcessor includes tabs inside PsiWhitespace elements

Also I partially reverted previous fix in PyBlock#isWhitespaceLineBreaks,
because current approach is more general and that workaround is no longer
needed (multiple whitespaces are collapsed into single element as in other
languages).
This commit is contained in:
Mikhail Golubev
2015-01-28 13:11:03 +03:00
parent 9cf35e4acd
commit 186f1fe5af
5 changed files with 40 additions and 14 deletions
@@ -509,21 +509,15 @@ public class PyBlock implements ASTBlock {
private static boolean isWhitespaceWithLineBreaks(@Nullable ASTNode node, int minCount) {
if (isWhitespace(node)) {
for (ASTNode prevNode = node.getTreePrev(); isWhitespace(prevNode); prevNode = prevNode.getTreePrev()) {
node = prevNode;
}
while (isWhitespace(node)) {
final String nodeText = node.getText();
int count = 0;
for (int i = 0; i < nodeText.length(); i++) {
if (nodeText.charAt(i) == '\n') {
count++;
if (count == minCount) {
return true;
}
final String prevNodeText = node.getText();
int count = 0;
for (int i = 0; i < prevNodeText.length(); i++) {
if (prevNodeText.charAt(i) == '\n') {
count++;
if (count == minCount) {
return true;
}
}
node = node.getTreeNext();
}
}
return false;
@@ -143,6 +143,9 @@ public class PythonIndentingProcessor extends MergingLexerAdapter {
if (text.charAt(i) == ' ') {
spaces++;
}
else if (text.charAt(i) == '\t') {
spaces += 8;
}
}
myCurrentNewLineIndent = spaces;
}
@@ -317,7 +320,8 @@ public class PythonIndentingProcessor extends MergingLexerAdapter {
// line break token
int end = getBaseTokenEnd();
advanceBase();
while (getBaseTokenType() == PyTokenTypes.SPACE || (!breakStatementOnLineBreak && getBaseTokenType() == PyTokenTypes.LINE_BREAK)) {
while (getBaseTokenType() == PyTokenTypes.SPACE || getBaseTokenType() == PyTokenTypes.TAB ||
(!breakStatementOnLineBreak && getBaseTokenType() == PyTokenTypes.LINE_BREAK)) {
end = getBaseTokenEnd();
advanceBase();
}
@@ -0,0 +1,3 @@
x = {
'foo': 42,
}
@@ -0,0 +1,20 @@
PyFile:TabInsideContinuationIndent.py
PyAssignmentStatement
PyTargetExpression: x
PsiElement(Py:IDENTIFIER)('x')
PsiWhiteSpace(' ')
PsiElement(Py:EQ)('=')
PsiWhiteSpace(' ')
PyDictLiteralExpression
PsiElement(Py:LBRACE)('{')
PsiWhiteSpace('\n\t')
PyKeyValueExpression
PyStringLiteralExpression: foo
PsiElement(Py:SINGLE_QUOTED_STRING)(''foo'')
PsiElement(Py:COLON)(':')
PsiWhiteSpace(' ')
PyNumericLiteralExpression
PsiElement(Py:INTEGER_LITERAL)('42')
PsiElement(Py:COMMA)(',')
PsiWhiteSpace('\n')
PsiElement(Py:RBRACE)('}')
@@ -463,6 +463,11 @@ public class PythonParsingTest extends ParsingTestCase {
doTest();
}
// PY-14408
public void testTabInsideContinuationIndent() {
doTest();
}
public void doTest(LanguageLevel languageLevel) {
LanguageLevel prev = myLanguageLevel;
myLanguageLevel = languageLevel;