Parse collection literals as atomic expressions

This commit is contained in:
Mikhail Zarechenskiy
2017-03-17 12:40:47 +03:00
parent 3c7678092e
commit d3fd96ceed
10 changed files with 341 additions and 45 deletions
@@ -1,5 +1,5 @@
/*
* Copyright 2010-2015 JetBrains s.r.o.
* Copyright 2010-2017 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -201,6 +201,8 @@ public interface KtNodeTypes {
KtNodeType WHEN_CONDITION_IS_PATTERN = new KtNodeType("WHEN_CONDITION_IS_PATTERN", KtWhenConditionIsPattern.class);
KtNodeType WHEN_CONDITION_EXPRESSION = new KtNodeType("WHEN_CONDITION_WITH_EXPRESSION", KtWhenConditionWithExpression.class);
KtNodeType COLLECTION_LITERAL_EXPRESSION = new KtNodeType("COLLECTION_LITERAL_EXPRESSION", KtCollectionLiteralExpression.class);
IElementType PACKAGE_DIRECTIVE = KtStubElementTypes.PACKAGE_DIRECTIVE;
IElementType SCRIPT = KtStubElementTypes.SCRIPT;
@@ -1,5 +1,5 @@
/*
* Copyright 2010-2015 JetBrains s.r.o.
* Copyright 2010-2017 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -111,7 +111,9 @@ public class KotlinExpressionParsing extends AbstractKotlinParsing {
IDENTIFIER, // SimpleName
AT // Just for better recovery and maybe for annotations
AT, // Just for better recovery and maybe for annotations
LBRACKET // Collection literal expression
);
private static final TokenSet STATEMENT_FIRST = TokenSet.orSet(
@@ -613,6 +615,7 @@ public class KotlinExpressionParsing extends AbstractKotlinParsing {
* : functionLiteral
* : declaration
* : SimpleName
* : collectionLiteral
* ;
*/
private boolean parseAtomicExpression() {
@@ -621,6 +624,9 @@ public class KotlinExpressionParsing extends AbstractKotlinParsing {
if (at(LPAR)) {
parseParenthesizedExpression();
}
else if (at(LBRACKET)) {
parseCollectionLiteralExpression();
}
else if (at(THIS_KEYWORD)) {
parseThisExpression();
}
@@ -987,28 +993,59 @@ public class KotlinExpressionParsing extends AbstractKotlinParsing {
* ;
*/
private void parseArrayAccess() {
parseAsCollectionLiteralExpression(INDICES, false, "Expecting an index element");
}
/*
* collectionLiteral
* : "[" element{","}? "]"
* ;
*/
private void parseCollectionLiteralExpression() {
parseAsCollectionLiteralExpression(COLLECTION_LITERAL_EXPRESSION, true, "Expecting an element");
}
private void parseAsCollectionLiteralExpression(KtNodeType nodeType, boolean canBeEmpty, String missingElementErrorMessage) {
assert _at(LBRACKET);
PsiBuilder.Marker indices = mark();
PsiBuilder.Marker innerExpressions = mark();
myBuilder.disableNewlines();
advance(); // LBRACKET
while (true) {
if (at(COMMA)) errorAndAdvance("Expecting an index element");
if (at(RBRACKET)) {
error("Expecting an index element");
break;
}
parseExpression();
if (!at(COMMA)) break;
advance(); // COMMA
if (!canBeEmpty && at(RBRACKET)) {
error(missingElementErrorMessage);
}
else {
parseInnerExpressions(missingElementErrorMessage);
}
expect(RBRACKET, "Expecting ']'");
myBuilder.restoreNewlinesState();
indices.done(INDICES);
innerExpressions.done(nodeType);
}
private void parseInnerExpressions(String missingElementErrorMessage) {
boolean firstElement = true;
while (true) {
if (at(COMMA)) errorAndAdvance(missingElementErrorMessage);
if (at(RBRACKET)) {
if (firstElement) {
break;
}
else {
error(missingElementErrorMessage);
}
break;
}
parseExpression();
firstElement = false;
if (!at(COMMA)) break;
advance(); // COMMA
}
}
/*
@@ -0,0 +1,21 @@
/*
* Copyright 2010-2017 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.jetbrains.kotlin.psi
import com.intellij.lang.ASTNode
class KtCollectionLiteralExpression(node: ASTNode) : KtExpressionImpl(node)