KT-337 Can't break a line before a dot
This commit is contained in:
@@ -178,7 +178,10 @@ public class JetExpressionParsing extends AbstractJetParsing {
|
||||
}
|
||||
}
|
||||
|
||||
public static final TokenSet ALLOW_NEWLINE_OPERATIONS = TokenSet.create(DOT, SAFE_ACCESS);
|
||||
|
||||
public static final TokenSet ALL_OPERATIONS;
|
||||
|
||||
static {
|
||||
Set<IElementType> operations = new HashSet<IElementType>();
|
||||
Precedence[] values = Precedence.values();
|
||||
@@ -272,7 +275,7 @@ public class JetExpressionParsing extends AbstractJetParsing {
|
||||
|
||||
precedence.parseHigherPrecedence(this);
|
||||
|
||||
while (!myBuilder.newlineBeforeCurrentToken() && atSet(precedence.getOperations())) {
|
||||
while (!breakedWithNewLine() && atSet(precedence.getOperations())) {
|
||||
IElementType operation = tt();
|
||||
|
||||
parseOperationReference();
|
||||
@@ -328,7 +331,7 @@ public class JetExpressionParsing extends AbstractJetParsing {
|
||||
PsiBuilder.Marker expression = mark();
|
||||
parseAtomicExpression();
|
||||
while (true) {
|
||||
if (myBuilder.newlineBeforeCurrentToken()) {
|
||||
if (breakedWithNewLine()) {
|
||||
break;
|
||||
}
|
||||
else if (at(LBRACKET)) {
|
||||
@@ -1704,4 +1707,8 @@ public class JetExpressionParsing extends AbstractJetParsing {
|
||||
protected JetParsing create(SemanticWhitespaceAwarePsiBuilder builder) {
|
||||
return myJetParsing.create(builder);
|
||||
}
|
||||
|
||||
private boolean breakedWithNewLine() {
|
||||
return !ALLOW_NEWLINE_OPERATIONS.contains(tt()) && myBuilder.newlineBeforeCurrentToken();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -124,9 +124,11 @@ public class JetParsing extends AbstractJetParsing {
|
||||
parseNamespaceName();
|
||||
|
||||
if (at(LBRACE)) {
|
||||
// Because it's blocked namespace and it will be parsed as one of top level objects
|
||||
firstEntry.rollbackTo();
|
||||
return;
|
||||
}
|
||||
|
||||
firstEntry.drop();
|
||||
|
||||
consumeIf(SEMICOLON);
|
||||
@@ -134,6 +136,7 @@ public class JetParsing extends AbstractJetParsing {
|
||||
firstEntry.rollbackTo();
|
||||
}
|
||||
|
||||
// TODO: Duplicate with parsing imports in parseToplevelDeclarations
|
||||
while (at(IMPORT_KEYWORD)) {
|
||||
parseImportDirective();
|
||||
}
|
||||
|
||||
+12
-2
@@ -25,27 +25,37 @@ public class SemanticWhitespaceAwarePsiBuilderImpl extends PsiBuilderAdapter imp
|
||||
|
||||
@Override
|
||||
public boolean newlineBeforeCurrentToken() {
|
||||
|
||||
if (!newlinesEnabled.peek()) return false;
|
||||
|
||||
if (eof()) return true;
|
||||
// TODO: maybe, memoize this somehow?
|
||||
|
||||
// TODO: maybe, memorize this somehow?
|
||||
for (int i = 1; i <= getCurrentOffset(); i++) {
|
||||
IElementType previousToken = rawLookup(-i);
|
||||
|
||||
if (previousToken == JetTokens.BLOCK_COMMENT
|
||||
|| previousToken == JetTokens.DOC_COMMENT
|
||||
|| previousToken == JetTokens.EOL_COMMENT) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (previousToken != TokenType.WHITE_SPACE) {
|
||||
break;
|
||||
}
|
||||
|
||||
int previousTokenStart = rawTokenTypeStart(-i);
|
||||
int previousTokenEnd = rawTokenTypeStart(-i + 1);
|
||||
|
||||
assert previousTokenStart >= 0;
|
||||
assert previousTokenEnd < getOriginalText().length();
|
||||
|
||||
for (int j = previousTokenStart; j < previousTokenEnd; j++) {
|
||||
if (getOriginalText().charAt(j) == '\n') return true;
|
||||
if (getOriginalText().charAt(j) == '\n')
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
@@ -0,0 +1,14 @@
|
||||
//KT-337 Can't break a line before a dot
|
||||
|
||||
class A() {
|
||||
fun foo() {}
|
||||
}
|
||||
|
||||
fun test() {
|
||||
val a = A()
|
||||
|
||||
a
|
||||
|
||||
.foo() // Should be a valid expression
|
||||
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
fun test() {
|
||||
val str = ""
|
||||
|
||||
str
|
||||
|
||||
.length
|
||||
|
||||
str
|
||||
|
||||
?.length
|
||||
}
|
||||
@@ -0,0 +1,41 @@
|
||||
JetFile: NewLinesValidOperations.jet
|
||||
NAMESPACE
|
||||
FUN
|
||||
PsiElement(fun)('fun')
|
||||
PsiWhiteSpace(' ')
|
||||
PsiElement(IDENTIFIER)('test')
|
||||
VALUE_PARAMETER_LIST
|
||||
PsiElement(LPAR)('(')
|
||||
PsiElement(RPAR)(')')
|
||||
PsiWhiteSpace(' ')
|
||||
BLOCK
|
||||
PsiElement(LBRACE)('{')
|
||||
PsiWhiteSpace('\n ')
|
||||
PROPERTY
|
||||
PsiElement(val)('val')
|
||||
PsiWhiteSpace(' ')
|
||||
PsiElement(IDENTIFIER)('str')
|
||||
PsiWhiteSpace(' ')
|
||||
PsiElement(EQ)('=')
|
||||
PsiWhiteSpace(' ')
|
||||
STRING_TEMPLATE
|
||||
PsiElement(OPEN_QUOTE)('"')
|
||||
PsiElement(CLOSING_QUOTE)('"')
|
||||
PsiWhiteSpace('\n\n ')
|
||||
DOT_QUALIFIED_EXPRESSION
|
||||
REFERENCE_EXPRESSION
|
||||
PsiElement(IDENTIFIER)('str')
|
||||
PsiWhiteSpace('\n\n ')
|
||||
PsiElement(DOT)('.')
|
||||
REFERENCE_EXPRESSION
|
||||
PsiElement(IDENTIFIER)('length')
|
||||
PsiWhiteSpace('\n\n ')
|
||||
SAFE_ACCESS_EXPRESSION
|
||||
REFERENCE_EXPRESSION
|
||||
PsiElement(IDENTIFIER)('str')
|
||||
PsiWhiteSpace('\n\n ')
|
||||
PsiElement(SAFE_ACCESS)('?.')
|
||||
REFERENCE_EXPRESSION
|
||||
PsiElement(IDENTIFIER)('length')
|
||||
PsiWhiteSpace('\n')
|
||||
PsiElement(RBRACE)('}')
|
||||
Reference in New Issue
Block a user