Implement new parsing rules for labels

See changes in expressions.grm
This commit is contained in:
Denis Zharkov
2015-04-27 12:34:12 +03:00
parent 0d76634f6b
commit 507eefcaa5
20 changed files with 1048 additions and 109 deletions
@@ -80,7 +80,6 @@ public interface JetTokens {
JetToken AS_SAFE = JetKeywordToken.keyword("AS_SAFE");//new JetToken("as?"); JetToken AS_SAFE = JetKeywordToken.keyword("AS_SAFE");//new JetToken("as?");
JetToken IDENTIFIER = new JetToken("IDENTIFIER"); JetToken IDENTIFIER = new JetToken("IDENTIFIER");
JetToken LABEL_IDENTIFIER = new JetToken("LABEL_IDENTIFIER");
JetToken FIELD_IDENTIFIER = new JetToken("FIELD_IDENTIFIER"); JetToken FIELD_IDENTIFIER = new JetToken("FIELD_IDENTIFIER");
JetSingleValueToken LBRACKET = new JetSingleValueToken("LBRACKET", "["); JetSingleValueToken LBRACKET = new JetSingleValueToken("LBRACKET", "[");
@@ -127,6 +126,7 @@ public interface JetTokens {
JetKeywordToken NOT_IN = JetKeywordToken.keyword("NOT_IN", "!in"); JetKeywordToken NOT_IN = JetKeywordToken.keyword("NOT_IN", "!in");
JetKeywordToken NOT_IS = JetKeywordToken.keyword("NOT_IS", "!is"); JetKeywordToken NOT_IS = JetKeywordToken.keyword("NOT_IS", "!is");
JetSingleValueToken HASH = new JetSingleValueToken("HASH", "#"); JetSingleValueToken HASH = new JetSingleValueToken("HASH", "#");
JetSingleValueToken AT = new JetSingleValueToken("AT", "@");
JetSingleValueToken COMMA = new JetSingleValueToken("COMMA", ","); JetSingleValueToken COMMA = new JetSingleValueToken("COMMA", ",");
@@ -211,7 +211,7 @@ public interface JetTokens {
COLON, COLON,
RANGE, EQ, MULTEQ, DIVEQ, PERCEQ, PLUSEQ, MINUSEQ, RANGE, EQ, MULTEQ, DIVEQ, PERCEQ, PLUSEQ, MINUSEQ,
NOT_IN, NOT_IS, NOT_IN, NOT_IS,
IDENTIFIER, LABEL_IDENTIFIER); IDENTIFIER);
TokenSet AUGMENTED_ASSIGNMENTS = TokenSet.create(PLUSEQ, MINUSEQ, MULTEQ, PERCEQ, DIVEQ); TokenSet AUGMENTED_ASSIGNMENTS = TokenSet.create(PLUSEQ, MINUSEQ, MULTEQ, PERCEQ, DIVEQ);
TokenSet ALL_ASSIGNMENTS = TokenSet.create(EQ, PLUSEQ, MINUSEQ, MULTEQ, PERCEQ, DIVEQ); TokenSet ALL_ASSIGNMENTS = TokenSet.create(EQ, PLUSEQ, MINUSEQ, MULTEQ, PERCEQ, DIVEQ);
@@ -84,7 +84,6 @@ PLAIN_IDENTIFIER={LETTER} {IDENTIFIER_PART}*
ESCAPED_IDENTIFIER = `[^`\n]+` ESCAPED_IDENTIFIER = `[^`\n]+`
IDENTIFIER = {PLAIN_IDENTIFIER}|{ESCAPED_IDENTIFIER} IDENTIFIER = {PLAIN_IDENTIFIER}|{ESCAPED_IDENTIFIER}
FIELD_IDENTIFIER = \${IDENTIFIER} FIELD_IDENTIFIER = \${IDENTIFIER}
LABEL_IDENTIFIER = \@{IDENTIFIER}?
EOL_COMMENT="/""/"[^\n]* EOL_COMMENT="/""/"[^\n]*
SHEBANG_COMMENT="#!"[^\n]* SHEBANG_COMMENT="#!"[^\n]*
@@ -273,7 +272,6 @@ LONG_TEMPLATE_ENTRY_START=\$\{
{FIELD_IDENTIFIER} { return JetTokens.FIELD_IDENTIFIER; } {FIELD_IDENTIFIER} { return JetTokens.FIELD_IDENTIFIER; }
{IDENTIFIER} { return JetTokens.IDENTIFIER; } {IDENTIFIER} { return JetTokens.IDENTIFIER; }
{LABEL_IDENTIFIER} { return JetTokens.LABEL_IDENTIFIER; }
\!in{IDENTIFIER_PART} { yypushback(3); return JetTokens.EXCL; } \!in{IDENTIFIER_PART} { yypushback(3); return JetTokens.EXCL; }
\!is{IDENTIFIER_PART} { yypushback(3); return JetTokens.EXCL; } \!is{IDENTIFIER_PART} { yypushback(3); return JetTokens.EXCL; }
@@ -325,6 +323,7 @@ LONG_TEMPLATE_ENTRY_START=\$\{
"=" { return JetTokens.EQ ; } "=" { return JetTokens.EQ ; }
"," { return JetTokens.COMMA ; } "," { return JetTokens.COMMA ; }
"#" { return JetTokens.HASH ; } "#" { return JetTokens.HASH ; }
"@" { return JetTokens.AT ; }
// error fallback // error fallback
. { return TokenType.BAD_CHARACTER; } . { return TokenType.BAD_CHARACTER; }
@@ -71,7 +71,7 @@ public class JetExpressionParsing extends AbstractJetParsing {
// Prefix // Prefix
MINUS, PLUS, MINUSMINUS, PLUSPLUS, MINUS, PLUS, MINUSMINUS, PLUSPLUS,
EXCL, EXCLEXCL, // Joining complex tokens makes it necessary to put EXCLEXCL here EXCL, EXCLEXCL, // Joining complex tokens makes it necessary to put EXCLEXCL here
LBRACKET, LABEL_IDENTIFIER, LBRACKET,
// Atomic // Atomic
COLONCOLON, // callable reference COLONCOLON, // callable reference
@@ -112,7 +112,8 @@ public class JetExpressionParsing extends AbstractJetParsing {
IDENTIFIER, // SimpleName IDENTIFIER, // SimpleName
FIELD_IDENTIFIER, // Field reference FIELD_IDENTIFIER, // Field reference
PACKAGE_KEYWORD // for absolute qualified names PACKAGE_KEYWORD, // for absolute qualified names
AT // Just for better recovery and maybe for annotations
); );
private static final TokenSet STATEMENT_FIRST = TokenSet.orSet( private static final TokenSet STATEMENT_FIRST = TokenSet.orSet(
@@ -143,7 +144,7 @@ public class JetExpressionParsing extends AbstractJetParsing {
POSTFIX(PLUSPLUS, MINUSMINUS, EXCLEXCL, POSTFIX(PLUSPLUS, MINUSMINUS, EXCLEXCL,
DOT, SAFE_ACCESS), // typeArguments? valueArguments : typeArguments : arrayAccess DOT, SAFE_ACCESS), // typeArguments? valueArguments : typeArguments : arrayAccess
PREFIX(MINUS, PLUS, MINUSMINUS, PLUSPLUS, EXCL, LABEL_IDENTIFIER) { // annotations PREFIX(MINUS, PLUS, MINUSMINUS, PLUSPLUS, EXCL) { // annotations
@Override @Override
public void parseHigherPrecedence(JetExpressionParsing parser) { public void parseHigherPrecedence(JetExpressionParsing parser) {
@@ -328,9 +329,8 @@ public class JetExpressionParsing extends AbstractJetParsing {
* label prefixExpression * label prefixExpression
*/ */
private void parseLabeledExpression() { private void parseLabeledExpression() {
assert _at(LABEL_IDENTIFIER);
PsiBuilder.Marker expression = mark(); PsiBuilder.Marker expression = mark();
parseLabel(); parseLabelDefinition();
parsePrefixExpression(); parsePrefixExpression();
expression.done(LABELED_EXPRESSION); expression.done(LABELED_EXPRESSION);
} }
@@ -351,7 +351,7 @@ public class JetExpressionParsing extends AbstractJetParsing {
} }
else { else {
myBuilder.disableJoiningComplexTokens(); myBuilder.disableJoiningComplexTokens();
if (at(LABEL_IDENTIFIER)) { if (isAtLabelDefinitionOrMissingIdentifier()) {
myBuilder.restoreJoiningComplexTokensState(); myBuilder.restoreJoiningComplexTokensState();
parseLabeledExpression(); parseLabeledExpression();
} }
@@ -532,10 +532,10 @@ public class JetExpressionParsing extends AbstractJetParsing {
*/ */
protected boolean parseCallWithClosure() { protected boolean parseCallWithClosure() {
boolean success = false; boolean success = false;
while ((at(LBRACE) || at(LABEL_IDENTIFIER) && lookahead(1) == LBRACE)) {
while (at(LBRACE) || isAtLabelDefinitionBeforeLBrace()) {
PsiBuilder.Marker argument = mark(); PsiBuilder.Marker argument = mark();
if (!at(LBRACE)) { if (!at(LBRACE)) {
assert _at(LABEL_IDENTIFIER);
parseLabeledExpression(); parseLabeledExpression();
} }
else { else {
@@ -548,6 +548,19 @@ public class JetExpressionParsing extends AbstractJetParsing {
return success; return success;
} }
private boolean isAtLabelDefinitionBeforeLBrace() {
if (at(IDENTIFIER)) {
if (myBuilder.rawLookup(1) != AT) return false;
return lookahead(2) == LBRACE;
}
return at(AT) && lookahead(1) == LBRACE;
}
private boolean isAtLabelDefinitionOrMissingIdentifier() {
return (at(IDENTIFIER) && myBuilder.rawLookup(1) == AT) || at(AT);
}
/* /*
* atomicExpression * atomicExpression
* : tupleLiteral // or parenthesized element * : tupleLiteral // or parenthesized element
@@ -982,7 +995,8 @@ public class JetExpressionParsing extends AbstractJetParsing {
if (declType != null) { if (declType != null) {
// we do not attach preceding comments (non-doc) to local variables because they are likely commenting a few statements below // we do not attach preceding comments (non-doc) to local variables because they are likely commenting a few statements below
closeDeclarationWithCommentBinders(decl, declType, declType != JetNodeTypes.PROPERTY && declType != JetNodeTypes.MULTI_VARIABLE_DECLARATION); closeDeclarationWithCommentBinders(decl, declType,
declType != JetNodeTypes.PROPERTY && declType != JetNodeTypes.MULTI_VARIABLE_DECLARATION);
return true; return true;
} }
else { else {
@@ -1450,10 +1464,10 @@ public class JetExpressionParsing extends AbstractJetParsing {
if (at(LBRACE)) { if (at(LBRACE)) {
parseFunctionLiteral(true); parseFunctionLiteral(true);
} }
else if (at(LABEL_IDENTIFIER) && lookahead(1) == LBRACE ) { else if (isAtLabelDefinitionBeforeLBrace()) {
PsiBuilder.Marker mark = mark(); PsiBuilder.Marker mark = mark();
parseLabel(); parseLabelDefinition();
parseFunctionLiteral(true); parseFunctionLiteral(true);
@@ -1609,7 +1623,7 @@ public class JetExpressionParsing extends AbstractJetParsing {
advance(); // BREAK_KEYWORD or CONTINUE_KEYWORD advance(); // BREAK_KEYWORD or CONTINUE_KEYWORD
parseLabelOnTheSameLine(); parseLabelReferenceWithNoWhitespace();
marker.done(type); marker.done(type);
} }
@@ -1624,7 +1638,7 @@ public class JetExpressionParsing extends AbstractJetParsing {
advance(); // RETURN_KEYWORD advance(); // RETURN_KEYWORD
parseLabelOnTheSameLine(); parseLabelReferenceWithNoWhitespace();
if (atSet(EXPRESSION_FIRST) && !at(EOL_OR_SEMICOLON)) parseExpression(); if (atSet(EXPRESSION_FIRST) && !at(EOL_OR_SEMICOLON)) parseExpression();
@@ -1634,28 +1648,55 @@ public class JetExpressionParsing extends AbstractJetParsing {
/* /*
* label? * label?
*/ */
private void parseLabelOnTheSameLine() { private void parseLabelReferenceWithNoWhitespace() {
if (!eol() && at(LABEL_IDENTIFIER)) { if (at(AT) && !WHITE_SPACE_OR_COMMENT_BIT_SET.contains(myBuilder.rawLookup(-1))) {
parseLabel(); parseLabelReference();
} }
} }
/* /*
* label * IDENTIFIER "@"
*/ */
private void parseLabel() { private void parseLabelDefinition() {
assert _at(LABEL_IDENTIFIER); if (at(AT)) {
// recovery for empty label identifier
String labelText = myBuilder.getTokenText(); errorAndAdvance("Label must be named"); // AT
if ("@".equals(labelText)) {
errorAndAdvance("Label must be named");
return; return;
} }
PsiBuilder.Marker labelWrap = mark();
PsiBuilder.Marker mark = mark();
assert _at(IDENTIFIER) && myBuilder.rawLookup(1) == AT : "Callers must check that current token is IDENTIFIER followed with '@'";
advance(); // IDENTIFIER
advance(); // AT
mark.done(LABEL);
labelWrap.done(LABEL_QUALIFIER);
}
/*
* "@" IDENTIFIER
*/
private void parseLabelReference() {
assert _at(AT);
PsiBuilder.Marker labelWrap = mark(); PsiBuilder.Marker labelWrap = mark();
PsiBuilder.Marker mark = mark(); PsiBuilder.Marker mark = mark();
advance(); // LABEL_IDENTIFIER
if (myBuilder.rawLookup(1) != IDENTIFIER) {
errorAndAdvance("Label must be named"); // AT
labelWrap.drop();
mark.drop();
return;
}
advance(); // AT
advance(); // IDENTIFIER
mark.done(LABEL); mark.done(LABEL);
labelWrap.done(LABEL_QUALIFIER); labelWrap.done(LABEL_QUALIFIER);
@@ -1753,7 +1794,7 @@ public class JetExpressionParsing extends AbstractJetParsing {
advance(); // THIS_KEYWORD advance(); // THIS_KEYWORD
thisReference.done(REFERENCE_EXPRESSION); thisReference.done(REFERENCE_EXPRESSION);
parseLabelOnTheSameLine(); parseLabelReferenceWithNoWhitespace();
mark.done(THIS_EXPRESSION); mark.done(THIS_EXPRESSION);
} }
@@ -1787,7 +1828,7 @@ public class JetExpressionParsing extends AbstractJetParsing {
} }
myBuilder.restoreNewlinesState(); myBuilder.restoreNewlinesState();
} }
parseLabelOnTheSameLine(); parseLabelReferenceWithNoWhitespace();
mark.done(SUPER_EXPRESSION); mark.done(SUPER_EXPRESSION);
} }
+6 -6
View File
@@ -3,9 +3,9 @@ fun a(
a : foo = throw Foo(), a : foo = throw Foo(),
a : foo = return 10, a : foo = return 10,
a : foo = break, a : foo = break,
a : foo = break @la, a : foo = break@la,
a : foo = continue, a : foo = continue,
a : foo = continue @la, a : foo = continue@la,
a : foo = if (10) foo else bar, a : foo = if (10) foo else bar,
a : foo = if (10) foo a : foo = if (10) foo
) { ) {
@@ -13,11 +13,11 @@ fun a(
return return
10 10
break break
@la la@
break @la break@la
continue continue
@la la@
continue @la continue@la
if (foo) if (foo)
if (foo) if (foo)
bar bar
+12 -10
View File
@@ -80,10 +80,10 @@ JetFile: ControlStructures.kt
PsiWhiteSpace(' ') PsiWhiteSpace(' ')
BREAK BREAK
PsiElement(break)('break') PsiElement(break)('break')
PsiWhiteSpace(' ')
LABEL_QUALIFIER LABEL_QUALIFIER
LABEL LABEL
PsiElement(LABEL_IDENTIFIER)('@la') PsiElement(AT)('@')
PsiElement(IDENTIFIER)('la')
PsiElement(COMMA)(',') PsiElement(COMMA)(',')
PsiWhiteSpace('\n ') PsiWhiteSpace('\n ')
VALUE_PARAMETER VALUE_PARAMETER
@@ -116,10 +116,10 @@ JetFile: ControlStructures.kt
PsiWhiteSpace(' ') PsiWhiteSpace(' ')
CONTINUE CONTINUE
PsiElement(continue)('continue') PsiElement(continue)('continue')
PsiWhiteSpace(' ')
LABEL_QUALIFIER LABEL_QUALIFIER
LABEL LABEL
PsiElement(LABEL_IDENTIFIER)('@la') PsiElement(AT)('@')
PsiElement(IDENTIFIER)('la')
PsiElement(COMMA)(',') PsiElement(COMMA)(',')
PsiWhiteSpace('\n ') PsiWhiteSpace('\n ')
VALUE_PARAMETER VALUE_PARAMETER
@@ -202,14 +202,15 @@ JetFile: ControlStructures.kt
LABELED_EXPRESSION LABELED_EXPRESSION
LABEL_QUALIFIER LABEL_QUALIFIER
LABEL LABEL
PsiElement(LABEL_IDENTIFIER)('@la') PsiElement(IDENTIFIER)('la')
PsiElement(AT)('@')
PsiWhiteSpace('\n ') PsiWhiteSpace('\n ')
BREAK BREAK
PsiElement(break)('break') PsiElement(break)('break')
PsiWhiteSpace(' ')
LABEL_QUALIFIER LABEL_QUALIFIER
LABEL LABEL
PsiElement(LABEL_IDENTIFIER)('@la') PsiElement(AT)('@')
PsiElement(IDENTIFIER)('la')
PsiWhiteSpace('\n ') PsiWhiteSpace('\n ')
CONTINUE CONTINUE
PsiElement(continue)('continue') PsiElement(continue)('continue')
@@ -217,14 +218,15 @@ JetFile: ControlStructures.kt
LABELED_EXPRESSION LABELED_EXPRESSION
LABEL_QUALIFIER LABEL_QUALIFIER
LABEL LABEL
PsiElement(LABEL_IDENTIFIER)('@la') PsiElement(IDENTIFIER)('la')
PsiElement(AT)('@')
PsiWhiteSpace('\n ') PsiWhiteSpace('\n ')
CONTINUE CONTINUE
PsiElement(continue)('continue') PsiElement(continue)('continue')
PsiWhiteSpace(' ')
LABEL_QUALIFIER LABEL_QUALIFIER
LABEL LABEL
PsiElement(LABEL_IDENTIFIER)('@la') PsiElement(AT)('@')
PsiElement(IDENTIFIER)('la')
PsiWhiteSpace('\n ') PsiWhiteSpace('\n ')
IF IF
PsiElement(if)('if') PsiElement(if)('if')
+4 -4
View File
@@ -1,7 +1,7 @@
fun foo() { fun foo() {
return return
return 1 return 1
return (@a 1) return (a@ 1)
return@ return@
return@ 1 return@ 1
@@ -10,8 +10,8 @@ fun foo() {
return@a return@a
return@a 1 return@a 1
return@a (@a 1) return@a (a@ 1)
return@a @a 1 return@a a@ 1
return@@ return@@
return@@ 1 return@@ 1
@@ -24,7 +24,7 @@ fun foo() {
continue@ continue@
continue@a continue@a
a.filter @f{ a.filter f@{
if (1) return if (1) return
return@f true return@f true
} }
+42 -29
View File
@@ -29,7 +29,8 @@ JetFile: Labels.kt
LABELED_EXPRESSION LABELED_EXPRESSION
LABEL_QUALIFIER LABEL_QUALIFIER
LABEL LABEL
PsiElement(LABEL_IDENTIFIER)('@a') PsiElement(IDENTIFIER)('a')
PsiElement(AT)('@')
PsiWhiteSpace(' ') PsiWhiteSpace(' ')
INTEGER_CONSTANT INTEGER_CONSTANT
PsiElement(INTEGER_LITERAL)('1') PsiElement(INTEGER_LITERAL)('1')
@@ -38,12 +39,12 @@ JetFile: Labels.kt
RETURN RETURN
PsiElement(return)('return') PsiElement(return)('return')
PsiErrorElement:Label must be named PsiErrorElement:Label must be named
PsiElement(LABEL_IDENTIFIER)('@') PsiElement(AT)('@')
PsiWhiteSpace('\n ') PsiWhiteSpace('\n ')
RETURN RETURN
PsiElement(return)('return') PsiElement(return)('return')
PsiErrorElement:Label must be named PsiErrorElement:Label must be named
PsiElement(LABEL_IDENTIFIER)('@') PsiElement(AT)('@')
PsiWhiteSpace(' ') PsiWhiteSpace(' ')
INTEGER_CONSTANT INTEGER_CONSTANT
PsiElement(INTEGER_LITERAL)('1') PsiElement(INTEGER_LITERAL)('1')
@@ -51,13 +52,13 @@ JetFile: Labels.kt
RETURN RETURN
PsiElement(return)('return') PsiElement(return)('return')
PsiErrorElement:Label must be named PsiErrorElement:Label must be named
PsiElement(LABEL_IDENTIFIER)('@') PsiElement(AT)('@')
PsiWhiteSpace(' ') PsiWhiteSpace(' ')
PARENTHESIZED PARENTHESIZED
PsiElement(LPAR)('(') PsiElement(LPAR)('(')
LABELED_EXPRESSION LABELED_EXPRESSION
PsiErrorElement:Label must be named PsiErrorElement:Label must be named
PsiElement(LABEL_IDENTIFIER)('@') PsiElement(AT)('@')
PsiWhiteSpace(' ') PsiWhiteSpace(' ')
INTEGER_CONSTANT INTEGER_CONSTANT
PsiElement(INTEGER_LITERAL)('1') PsiElement(INTEGER_LITERAL)('1')
@@ -66,11 +67,11 @@ JetFile: Labels.kt
RETURN RETURN
PsiElement(return)('return') PsiElement(return)('return')
PsiErrorElement:Label must be named PsiErrorElement:Label must be named
PsiElement(LABEL_IDENTIFIER)('@') PsiElement(AT)('@')
PsiWhiteSpace(' ') PsiWhiteSpace(' ')
LABELED_EXPRESSION LABELED_EXPRESSION
PsiErrorElement:Label must be named PsiErrorElement:Label must be named
PsiElement(LABEL_IDENTIFIER)('@') PsiElement(AT)('@')
PsiWhiteSpace(' ') PsiWhiteSpace(' ')
INTEGER_CONSTANT INTEGER_CONSTANT
PsiElement(INTEGER_LITERAL)('1') PsiElement(INTEGER_LITERAL)('1')
@@ -79,13 +80,15 @@ JetFile: Labels.kt
PsiElement(return)('return') PsiElement(return)('return')
LABEL_QUALIFIER LABEL_QUALIFIER
LABEL LABEL
PsiElement(LABEL_IDENTIFIER)('@a') PsiElement(AT)('@')
PsiElement(IDENTIFIER)('a')
PsiWhiteSpace('\n ') PsiWhiteSpace('\n ')
RETURN RETURN
PsiElement(return)('return') PsiElement(return)('return')
LABEL_QUALIFIER LABEL_QUALIFIER
LABEL LABEL
PsiElement(LABEL_IDENTIFIER)('@a') PsiElement(AT)('@')
PsiElement(IDENTIFIER)('a')
PsiWhiteSpace(' ') PsiWhiteSpace(' ')
INTEGER_CONSTANT INTEGER_CONSTANT
PsiElement(INTEGER_LITERAL)('1') PsiElement(INTEGER_LITERAL)('1')
@@ -94,14 +97,16 @@ JetFile: Labels.kt
PsiElement(return)('return') PsiElement(return)('return')
LABEL_QUALIFIER LABEL_QUALIFIER
LABEL LABEL
PsiElement(LABEL_IDENTIFIER)('@a') PsiElement(AT)('@')
PsiElement(IDENTIFIER)('a')
PsiWhiteSpace(' ') PsiWhiteSpace(' ')
PARENTHESIZED PARENTHESIZED
PsiElement(LPAR)('(') PsiElement(LPAR)('(')
LABELED_EXPRESSION LABELED_EXPRESSION
LABEL_QUALIFIER LABEL_QUALIFIER
LABEL LABEL
PsiElement(LABEL_IDENTIFIER)('@a') PsiElement(IDENTIFIER)('a')
PsiElement(AT)('@')
PsiWhiteSpace(' ') PsiWhiteSpace(' ')
INTEGER_CONSTANT INTEGER_CONSTANT
PsiElement(INTEGER_LITERAL)('1') PsiElement(INTEGER_LITERAL)('1')
@@ -111,12 +116,14 @@ JetFile: Labels.kt
PsiElement(return)('return') PsiElement(return)('return')
LABEL_QUALIFIER LABEL_QUALIFIER
LABEL LABEL
PsiElement(LABEL_IDENTIFIER)('@a') PsiElement(AT)('@')
PsiElement(IDENTIFIER)('a')
PsiWhiteSpace(' ') PsiWhiteSpace(' ')
LABELED_EXPRESSION LABELED_EXPRESSION
LABEL_QUALIFIER LABEL_QUALIFIER
LABEL LABEL
PsiElement(LABEL_IDENTIFIER)('@a') PsiElement(IDENTIFIER)('a')
PsiElement(AT)('@')
PsiWhiteSpace(' ') PsiWhiteSpace(' ')
INTEGER_CONSTANT INTEGER_CONSTANT
PsiElement(INTEGER_LITERAL)('1') PsiElement(INTEGER_LITERAL)('1')
@@ -124,18 +131,18 @@ JetFile: Labels.kt
RETURN RETURN
PsiElement(return)('return') PsiElement(return)('return')
PsiErrorElement:Label must be named PsiErrorElement:Label must be named
PsiElement(LABEL_IDENTIFIER)('@') PsiElement(AT)('@')
LABELED_EXPRESSION LABELED_EXPRESSION
PsiErrorElement:Label must be named PsiErrorElement:Label must be named
PsiElement(LABEL_IDENTIFIER)('@') PsiElement(AT)('@')
PsiWhiteSpace('\n ') PsiWhiteSpace('\n ')
RETURN RETURN
PsiElement(return)('return') PsiElement(return)('return')
PsiErrorElement:Label must be named PsiErrorElement:Label must be named
PsiElement(LABEL_IDENTIFIER)('@') PsiElement(AT)('@')
LABELED_EXPRESSION LABELED_EXPRESSION
PsiErrorElement:Label must be named PsiErrorElement:Label must be named
PsiElement(LABEL_IDENTIFIER)('@') PsiElement(AT)('@')
PsiWhiteSpace(' ') PsiWhiteSpace(' ')
INTEGER_CONSTANT INTEGER_CONSTANT
PsiElement(INTEGER_LITERAL)('1') PsiElement(INTEGER_LITERAL)('1')
@@ -146,13 +153,14 @@ JetFile: Labels.kt
BREAK BREAK
PsiElement(break)('break') PsiElement(break)('break')
PsiErrorElement:Label must be named PsiErrorElement:Label must be named
PsiElement(LABEL_IDENTIFIER)('@') PsiElement(AT)('@')
PsiWhiteSpace('\n ') PsiWhiteSpace('\n ')
BREAK BREAK
PsiElement(break)('break') PsiElement(break)('break')
LABEL_QUALIFIER LABEL_QUALIFIER
LABEL LABEL
PsiElement(LABEL_IDENTIFIER)('@a') PsiElement(AT)('@')
PsiElement(IDENTIFIER)('a')
PsiWhiteSpace('\n\n ') PsiWhiteSpace('\n\n ')
CONTINUE CONTINUE
PsiElement(continue)('continue') PsiElement(continue)('continue')
@@ -160,13 +168,14 @@ JetFile: Labels.kt
CONTINUE CONTINUE
PsiElement(continue)('continue') PsiElement(continue)('continue')
PsiErrorElement:Label must be named PsiErrorElement:Label must be named
PsiElement(LABEL_IDENTIFIER)('@') PsiElement(AT)('@')
PsiWhiteSpace('\n ') PsiWhiteSpace('\n ')
CONTINUE CONTINUE
PsiElement(continue)('continue') PsiElement(continue)('continue')
LABEL_QUALIFIER LABEL_QUALIFIER
LABEL LABEL
PsiElement(LABEL_IDENTIFIER)('@a') PsiElement(AT)('@')
PsiElement(IDENTIFIER)('a')
PsiWhiteSpace('\n\n ') PsiWhiteSpace('\n\n ')
DOT_QUALIFIED_EXPRESSION DOT_QUALIFIED_EXPRESSION
REFERENCE_EXPRESSION REFERENCE_EXPRESSION
@@ -180,7 +189,8 @@ JetFile: Labels.kt
LABELED_EXPRESSION LABELED_EXPRESSION
LABEL_QUALIFIER LABEL_QUALIFIER
LABEL LABEL
PsiElement(LABEL_IDENTIFIER)('@f') PsiElement(IDENTIFIER)('f')
PsiElement(AT)('@')
FUNCTION_LITERAL_EXPRESSION FUNCTION_LITERAL_EXPRESSION
FUNCTION_LITERAL FUNCTION_LITERAL
PsiElement(LBRACE)('{') PsiElement(LBRACE)('{')
@@ -203,7 +213,8 @@ JetFile: Labels.kt
PsiElement(return)('return') PsiElement(return)('return')
LABEL_QUALIFIER LABEL_QUALIFIER
LABEL LABEL
PsiElement(LABEL_IDENTIFIER)('@f') PsiElement(AT)('@')
PsiElement(IDENTIFIER)('f')
PsiWhiteSpace(' ') PsiWhiteSpace(' ')
BOOLEAN_CONSTANT BOOLEAN_CONSTANT
PsiElement(true)('true') PsiElement(true)('true')
@@ -221,7 +232,7 @@ JetFile: Labels.kt
FUNCTION_LITERAL_ARGUMENT FUNCTION_LITERAL_ARGUMENT
LABELED_EXPRESSION LABELED_EXPRESSION
PsiErrorElement:Label must be named PsiErrorElement:Label must be named
PsiElement(LABEL_IDENTIFIER)('@') PsiElement(AT)('@')
FUNCTION_LITERAL_EXPRESSION FUNCTION_LITERAL_EXPRESSION
FUNCTION_LITERAL FUNCTION_LITERAL
PsiElement(LBRACE)('{') PsiElement(LBRACE)('{')
@@ -243,7 +254,7 @@ JetFile: Labels.kt
RETURN RETURN
PsiElement(return)('return') PsiElement(return)('return')
PsiErrorElement:Label must be named PsiErrorElement:Label must be named
PsiElement(LABEL_IDENTIFIER)('@') PsiElement(AT)('@')
PsiWhiteSpace(' ') PsiWhiteSpace(' ')
BOOLEAN_CONSTANT BOOLEAN_CONSTANT
PsiElement(true)('true') PsiElement(true)('true')
@@ -258,14 +269,15 @@ JetFile: Labels.kt
REFERENCE_EXPRESSION REFERENCE_EXPRESSION
PsiElement(this)('this') PsiElement(this)('this')
PsiErrorElement:Label must be named PsiErrorElement:Label must be named
PsiElement(LABEL_IDENTIFIER)('@') PsiElement(AT)('@')
PsiWhiteSpace('\n ') PsiWhiteSpace('\n ')
THIS_EXPRESSION THIS_EXPRESSION
REFERENCE_EXPRESSION REFERENCE_EXPRESSION
PsiElement(this)('this') PsiElement(this)('this')
LABEL_QUALIFIER LABEL_QUALIFIER
LABEL LABEL
PsiElement(LABEL_IDENTIFIER)('@a') PsiElement(AT)('@')
PsiElement(IDENTIFIER)('a')
PsiWhiteSpace('\n\n ') PsiWhiteSpace('\n\n ')
SUPER_EXPRESSION SUPER_EXPRESSION
REFERENCE_EXPRESSION REFERENCE_EXPRESSION
@@ -287,7 +299,7 @@ JetFile: Labels.kt
PsiElement(IDENTIFIER)('A') PsiElement(IDENTIFIER)('A')
PsiElement(GT)('>') PsiElement(GT)('>')
PsiErrorElement:Label must be named PsiErrorElement:Label must be named
PsiElement(LABEL_IDENTIFIER)('@') PsiElement(AT)('@')
PsiWhiteSpace('\n ') PsiWhiteSpace('\n ')
SUPER_EXPRESSION SUPER_EXPRESSION
REFERENCE_EXPRESSION REFERENCE_EXPRESSION
@@ -300,6 +312,7 @@ JetFile: Labels.kt
PsiElement(GT)('>') PsiElement(GT)('>')
LABEL_QUALIFIER LABEL_QUALIFIER
LABEL LABEL
PsiElement(LABEL_IDENTIFIER)('@a') PsiElement(AT)('@')
PsiElement(IDENTIFIER)('a')
PsiWhiteSpace('\n') PsiWhiteSpace('\n')
PsiElement(RBRACE)('}') PsiElement(RBRACE)('}')
+6 -6
View File
@@ -25,9 +25,9 @@ fun a(
a : foo = throw Foo(), a : foo = throw Foo(),
a : foo = return 10, a : foo = return 10,
a : foo = break, a : foo = break,
a : foo = break @la, a : foo = break@la,
a : foo = continue, a : foo = continue,
a : foo = continue @la, a : foo = continue@la,
a : foo = 10, a : foo = 10,
a : foo = 10, a : foo = 10,
a : foo = 10, a : foo = 10,
@@ -38,9 +38,9 @@ fun a(
return return
10 10
break break
@la la@
break @la break@la
continue continue
@la la@
continue @la continue@la
} }
+12 -10
View File
@@ -552,10 +552,10 @@ JetFile: SimpleExpressions.kt
PsiWhiteSpace(' ') PsiWhiteSpace(' ')
BREAK BREAK
PsiElement(break)('break') PsiElement(break)('break')
PsiWhiteSpace(' ')
LABEL_QUALIFIER LABEL_QUALIFIER
LABEL LABEL
PsiElement(LABEL_IDENTIFIER)('@la') PsiElement(AT)('@')
PsiElement(IDENTIFIER)('la')
PsiElement(COMMA)(',') PsiElement(COMMA)(',')
PsiWhiteSpace('\n ') PsiWhiteSpace('\n ')
VALUE_PARAMETER VALUE_PARAMETER
@@ -588,10 +588,10 @@ JetFile: SimpleExpressions.kt
PsiWhiteSpace(' ') PsiWhiteSpace(' ')
CONTINUE CONTINUE
PsiElement(continue)('continue') PsiElement(continue)('continue')
PsiWhiteSpace(' ')
LABEL_QUALIFIER LABEL_QUALIFIER
LABEL LABEL
PsiElement(LABEL_IDENTIFIER)('@la') PsiElement(AT)('@')
PsiElement(IDENTIFIER)('la')
PsiElement(COMMA)(',') PsiElement(COMMA)(',')
PsiWhiteSpace('\n ') PsiWhiteSpace('\n ')
VALUE_PARAMETER VALUE_PARAMETER
@@ -700,14 +700,15 @@ JetFile: SimpleExpressions.kt
LABELED_EXPRESSION LABELED_EXPRESSION
LABEL_QUALIFIER LABEL_QUALIFIER
LABEL LABEL
PsiElement(LABEL_IDENTIFIER)('@la') PsiElement(IDENTIFIER)('la')
PsiElement(AT)('@')
PsiWhiteSpace('\n ') PsiWhiteSpace('\n ')
BREAK BREAK
PsiElement(break)('break') PsiElement(break)('break')
PsiWhiteSpace(' ')
LABEL_QUALIFIER LABEL_QUALIFIER
LABEL LABEL
PsiElement(LABEL_IDENTIFIER)('@la') PsiElement(AT)('@')
PsiElement(IDENTIFIER)('la')
PsiWhiteSpace('\n ') PsiWhiteSpace('\n ')
CONTINUE CONTINUE
PsiElement(continue)('continue') PsiElement(continue)('continue')
@@ -715,13 +716,14 @@ JetFile: SimpleExpressions.kt
LABELED_EXPRESSION LABELED_EXPRESSION
LABEL_QUALIFIER LABEL_QUALIFIER
LABEL LABEL
PsiElement(LABEL_IDENTIFIER)('@la') PsiElement(IDENTIFIER)('la')
PsiElement(AT)('@')
PsiWhiteSpace('\n ') PsiWhiteSpace('\n ')
CONTINUE CONTINUE
PsiElement(continue)('continue') PsiElement(continue)('continue')
PsiWhiteSpace(' ')
LABEL_QUALIFIER LABEL_QUALIFIER
LABEL LABEL
PsiElement(LABEL_IDENTIFIER)('@la') PsiElement(AT)('@')
PsiElement(IDENTIFIER)('la')
PsiWhiteSpace('\n') PsiWhiteSpace('\n')
PsiElement(RBRACE)('}') PsiElement(RBRACE)('}')
+2 -1
View File
@@ -76,7 +76,8 @@ JetFile: Super.kt
PsiElement(GT)('>') PsiElement(GT)('>')
LABEL_QUALIFIER LABEL_QUALIFIER
LABEL LABEL
PsiElement(LABEL_IDENTIFIER)('@label') PsiElement(AT)('@')
PsiElement(IDENTIFIER)('label')
PsiElement(DOT)('.') PsiElement(DOT)('.')
CALL_EXPRESSION CALL_EXPRESSION
REFERENCE_EXPRESSION REFERENCE_EXPRESSION
+25
View File
@@ -0,0 +1,25 @@
fun foo() {
x1.filter b@ {
return 1
}
c@ {
return 2
}
loop1@ for (i in 1..100) {
return 4
}
loop2@ for (i in 1..100) {
return@loop2 4
return@loop2 5
}
label1@ val x = 1
1 + label3@ 3 + 4
l1@ foo bar l2@ baz // binary expression
return (a@ 1)
}
+229
View File
@@ -0,0 +1,229 @@
JetFile: basic.kt
PACKAGE_DIRECTIVE
<empty list>
FUN
PsiElement(fun)('fun')
PsiWhiteSpace(' ')
PsiElement(IDENTIFIER)('foo')
VALUE_PARAMETER_LIST
PsiElement(LPAR)('(')
PsiElement(RPAR)(')')
PsiWhiteSpace(' ')
BLOCK
PsiElement(LBRACE)('{')
PsiWhiteSpace('\n ')
DOT_QUALIFIED_EXPRESSION
REFERENCE_EXPRESSION
PsiElement(IDENTIFIER)('x1')
PsiElement(DOT)('.')
CALL_EXPRESSION
REFERENCE_EXPRESSION
PsiElement(IDENTIFIER)('filter')
PsiWhiteSpace(' ')
FUNCTION_LITERAL_ARGUMENT
LABELED_EXPRESSION
LABEL_QUALIFIER
LABEL
PsiElement(IDENTIFIER)('b')
PsiElement(AT)('@')
PsiWhiteSpace(' ')
FUNCTION_LITERAL_EXPRESSION
FUNCTION_LITERAL
PsiElement(LBRACE)('{')
PsiWhiteSpace('\n ')
BLOCK
RETURN
PsiElement(return)('return')
PsiWhiteSpace(' ')
INTEGER_CONSTANT
PsiElement(INTEGER_LITERAL)('1')
PsiWhiteSpace('\n ')
PsiElement(RBRACE)('}')
PsiWhiteSpace('\n ')
FUNCTION_LITERAL_ARGUMENT
LABELED_EXPRESSION
LABEL_QUALIFIER
LABEL
PsiElement(IDENTIFIER)('c')
PsiElement(AT)('@')
PsiWhiteSpace(' ')
FUNCTION_LITERAL_EXPRESSION
FUNCTION_LITERAL
PsiElement(LBRACE)('{')
PsiWhiteSpace('\n ')
BLOCK
RETURN
PsiElement(return)('return')
PsiWhiteSpace(' ')
INTEGER_CONSTANT
PsiElement(INTEGER_LITERAL)('2')
PsiWhiteSpace('\n ')
PsiElement(RBRACE)('}')
PsiWhiteSpace('\n\n ')
LABELED_EXPRESSION
LABEL_QUALIFIER
LABEL
PsiElement(IDENTIFIER)('loop1')
PsiElement(AT)('@')
PsiWhiteSpace(' ')
FOR
PsiElement(for)('for')
PsiWhiteSpace(' ')
PsiElement(LPAR)('(')
VALUE_PARAMETER
PsiElement(IDENTIFIER)('i')
PsiWhiteSpace(' ')
PsiElement(in)('in')
PsiWhiteSpace(' ')
LOOP_RANGE
BINARY_EXPRESSION
INTEGER_CONSTANT
PsiElement(INTEGER_LITERAL)('1')
OPERATION_REFERENCE
PsiElement(RANGE)('..')
INTEGER_CONSTANT
PsiElement(INTEGER_LITERAL)('100')
PsiElement(RPAR)(')')
PsiWhiteSpace(' ')
BODY
BLOCK
PsiElement(LBRACE)('{')
PsiWhiteSpace('\n ')
RETURN
PsiElement(return)('return')
PsiWhiteSpace(' ')
INTEGER_CONSTANT
PsiElement(INTEGER_LITERAL)('4')
PsiWhiteSpace('\n ')
PsiElement(RBRACE)('}')
PsiWhiteSpace('\n\n ')
LABELED_EXPRESSION
LABEL_QUALIFIER
LABEL
PsiElement(IDENTIFIER)('loop2')
PsiElement(AT)('@')
PsiWhiteSpace(' ')
FOR
PsiElement(for)('for')
PsiWhiteSpace(' ')
PsiElement(LPAR)('(')
VALUE_PARAMETER
PsiElement(IDENTIFIER)('i')
PsiWhiteSpace(' ')
PsiElement(in)('in')
PsiWhiteSpace(' ')
LOOP_RANGE
BINARY_EXPRESSION
INTEGER_CONSTANT
PsiElement(INTEGER_LITERAL)('1')
OPERATION_REFERENCE
PsiElement(RANGE)('..')
INTEGER_CONSTANT
PsiElement(INTEGER_LITERAL)('100')
PsiElement(RPAR)(')')
PsiWhiteSpace(' ')
BODY
BLOCK
PsiElement(LBRACE)('{')
PsiWhiteSpace('\n ')
RETURN
PsiElement(return)('return')
LABEL_QUALIFIER
LABEL
PsiElement(AT)('@')
PsiElement(IDENTIFIER)('loop2')
PsiWhiteSpace(' ')
INTEGER_CONSTANT
PsiElement(INTEGER_LITERAL)('4')
PsiWhiteSpace('\n ')
RETURN
PsiElement(return)('return')
LABEL_QUALIFIER
LABEL
PsiElement(AT)('@')
PsiElement(IDENTIFIER)('loop2')
PsiWhiteSpace(' ')
INTEGER_CONSTANT
PsiElement(INTEGER_LITERAL)('5')
PsiWhiteSpace('\n ')
PsiElement(RBRACE)('}')
PsiWhiteSpace('\n\n ')
LABELED_EXPRESSION
LABEL_QUALIFIER
LABEL
PsiElement(IDENTIFIER)('label1')
PsiElement(AT)('@')
PsiWhiteSpace(' ')
PROPERTY
PsiElement(val)('val')
PsiWhiteSpace(' ')
PsiElement(IDENTIFIER)('x')
PsiWhiteSpace(' ')
PsiElement(EQ)('=')
PsiWhiteSpace(' ')
INTEGER_CONSTANT
PsiElement(INTEGER_LITERAL)('1')
PsiWhiteSpace('\n\n ')
BINARY_EXPRESSION
BINARY_EXPRESSION
INTEGER_CONSTANT
PsiElement(INTEGER_LITERAL)('1')
PsiWhiteSpace(' ')
OPERATION_REFERENCE
PsiElement(PLUS)('+')
PsiWhiteSpace(' ')
LABELED_EXPRESSION
LABEL_QUALIFIER
LABEL
PsiElement(IDENTIFIER)('label3')
PsiElement(AT)('@')
PsiWhiteSpace(' ')
INTEGER_CONSTANT
PsiElement(INTEGER_LITERAL)('3')
PsiWhiteSpace(' ')
OPERATION_REFERENCE
PsiElement(PLUS)('+')
PsiWhiteSpace(' ')
INTEGER_CONSTANT
PsiElement(INTEGER_LITERAL)('4')
PsiWhiteSpace('\n\n ')
BINARY_EXPRESSION
LABELED_EXPRESSION
LABEL_QUALIFIER
LABEL
PsiElement(IDENTIFIER)('l1')
PsiElement(AT)('@')
PsiWhiteSpace(' ')
REFERENCE_EXPRESSION
PsiElement(IDENTIFIER)('foo')
PsiWhiteSpace(' ')
OPERATION_REFERENCE
PsiElement(IDENTIFIER)('bar')
PsiWhiteSpace(' ')
LABELED_EXPRESSION
LABEL_QUALIFIER
LABEL
PsiElement(IDENTIFIER)('l2')
PsiElement(AT)('@')
PsiWhiteSpace(' ')
REFERENCE_EXPRESSION
PsiElement(IDENTIFIER)('baz')
PsiWhiteSpace(' ')
PsiComment(EOL_COMMENT)('// binary expression')
PsiWhiteSpace('\n\n ')
RETURN
PsiElement(return)('return')
PsiWhiteSpace(' ')
PARENTHESIZED
PsiElement(LPAR)('(')
LABELED_EXPRESSION
LABEL_QUALIFIER
LABEL
PsiElement(IDENTIFIER)('a')
PsiElement(AT)('@')
PsiWhiteSpace(' ')
INTEGER_CONSTANT
PsiElement(INTEGER_LITERAL)('1')
PsiElement(RPAR)(')')
PsiWhiteSpace('\n')
PsiElement(RBRACE)('}')
@@ -0,0 +1,11 @@
fun foo() {
@loop1 for (i in 1..100) { }
x2.filter @f {
return 2
}
return (@f 3)
val x = 1
}
@@ -0,0 +1,99 @@
JetFile: oldSyntaxExpressions.kt
PACKAGE_DIRECTIVE
<empty list>
FUN
PsiElement(fun)('fun')
PsiWhiteSpace(' ')
PsiElement(IDENTIFIER)('foo')
VALUE_PARAMETER_LIST
PsiElement(LPAR)('(')
PsiElement(RPAR)(')')
PsiWhiteSpace(' ')
BLOCK
PsiElement(LBRACE)('{')
PsiWhiteSpace('\n ')
LABELED_EXPRESSION
PsiErrorElement:Label must be named
PsiElement(AT)('@')
REFERENCE_EXPRESSION
PsiElement(IDENTIFIER)('loop1')
PsiErrorElement:Unexpected tokens (use ';' to separate expressions on the same line)
<empty list>
PsiWhiteSpace(' ')
FOR
PsiElement(for)('for')
PsiWhiteSpace(' ')
PsiElement(LPAR)('(')
VALUE_PARAMETER
PsiElement(IDENTIFIER)('i')
PsiWhiteSpace(' ')
PsiElement(in)('in')
PsiWhiteSpace(' ')
LOOP_RANGE
BINARY_EXPRESSION
INTEGER_CONSTANT
PsiElement(INTEGER_LITERAL)('1')
OPERATION_REFERENCE
PsiElement(RANGE)('..')
INTEGER_CONSTANT
PsiElement(INTEGER_LITERAL)('100')
PsiElement(RPAR)(')')
PsiWhiteSpace(' ')
BODY
BLOCK
PsiElement(LBRACE)('{')
PsiWhiteSpace(' ')
PsiElement(RBRACE)('}')
PsiWhiteSpace('\n\n ')
DOT_QUALIFIED_EXPRESSION
REFERENCE_EXPRESSION
PsiElement(IDENTIFIER)('x2')
PsiElement(DOT)('.')
REFERENCE_EXPRESSION
PsiElement(IDENTIFIER)('filter')
PsiWhiteSpace(' ')
PsiErrorElement:Unexpected tokens (use ';' to separate expressions on the same line)
PsiElement(AT)('@')
PsiElement(IDENTIFIER)('f')
PsiWhiteSpace(' ')
FUNCTION_LITERAL_EXPRESSION
FUNCTION_LITERAL
PsiElement(LBRACE)('{')
PsiWhiteSpace('\n ')
BLOCK
RETURN
PsiElement(return)('return')
PsiWhiteSpace(' ')
INTEGER_CONSTANT
PsiElement(INTEGER_LITERAL)('2')
PsiWhiteSpace('\n ')
PsiElement(RBRACE)('}')
PsiWhiteSpace('\n\n ')
RETURN
PsiElement(return)('return')
PsiWhiteSpace(' ')
PARENTHESIZED
PsiElement(LPAR)('(')
LABELED_EXPRESSION
PsiErrorElement:Label must be named
PsiElement(AT)('@')
REFERENCE_EXPRESSION
PsiElement(IDENTIFIER)('f')
PsiErrorElement:Expecting ')'
<empty list>
PsiWhiteSpace(' ')
PsiErrorElement:Unexpected tokens (use ';' to separate expressions on the same line)
PsiElement(INTEGER_LITERAL)('3')
PsiElement(RPAR)(')')
PsiWhiteSpace('\n\n ')
PROPERTY
PsiElement(val)('val')
PsiWhiteSpace(' ')
PsiElement(IDENTIFIER)('x')
PsiWhiteSpace(' ')
PsiElement(EQ)('=')
PsiWhiteSpace(' ')
INTEGER_CONSTANT
PsiElement(INTEGER_LITERAL)('1')
PsiWhiteSpace('\n')
PsiElement(RBRACE)('}')
@@ -0,0 +1,32 @@
fun foo() {
x2.filter c @ { // should be no space after c
return 2
}
x3.filter @ { // no label identifier
return 3
}
loop2 @ for (i in 1..100) { // should be no space after loop2
return@ loop2 5
return @ loop2 7
return
@loop2 4
}
@ while (1) {
return 123
}
label2 @ fun foo() {} // should be no space after label2
1 + label3@ 3 + 4
l1 @ foo bar l2 @ baz // binary expression with extra spaces
foo l3 @ bar baz // binary expression with `@ bar` parsed as wrong label
foo@ bar baz // binary expression labeled `bar` and return as second arg
return @ 1
}
@@ -0,0 +1,268 @@
JetFile: recovery.kt
PACKAGE_DIRECTIVE
<empty list>
FUN
PsiElement(fun)('fun')
PsiWhiteSpace(' ')
PsiElement(IDENTIFIER)('foo')
VALUE_PARAMETER_LIST
PsiElement(LPAR)('(')
PsiElement(RPAR)(')')
PsiWhiteSpace(' ')
BLOCK
PsiElement(LBRACE)('{')
PsiWhiteSpace('\n\n ')
BINARY_EXPRESSION
DOT_QUALIFIED_EXPRESSION
REFERENCE_EXPRESSION
PsiElement(IDENTIFIER)('x2')
PsiElement(DOT)('.')
REFERENCE_EXPRESSION
PsiElement(IDENTIFIER)('filter')
PsiWhiteSpace(' ')
OPERATION_REFERENCE
PsiElement(IDENTIFIER)('c')
PsiWhiteSpace(' ')
LABELED_EXPRESSION
PsiErrorElement:Label must be named
PsiElement(AT)('@')
PsiWhiteSpace(' ')
FUNCTION_LITERAL_EXPRESSION
FUNCTION_LITERAL
PsiElement(LBRACE)('{')
PsiWhiteSpace(' ')
PsiComment(EOL_COMMENT)('// should be no space after c')
PsiWhiteSpace('\n ')
BLOCK
RETURN
PsiElement(return)('return')
PsiWhiteSpace(' ')
INTEGER_CONSTANT
PsiElement(INTEGER_LITERAL)('2')
PsiWhiteSpace('\n ')
PsiElement(RBRACE)('}')
PsiWhiteSpace('\n\n ')
DOT_QUALIFIED_EXPRESSION
REFERENCE_EXPRESSION
PsiElement(IDENTIFIER)('x3')
PsiElement(DOT)('.')
CALL_EXPRESSION
REFERENCE_EXPRESSION
PsiElement(IDENTIFIER)('filter')
PsiWhiteSpace(' ')
FUNCTION_LITERAL_ARGUMENT
LABELED_EXPRESSION
PsiErrorElement:Label must be named
PsiElement(AT)('@')
PsiWhiteSpace(' ')
FUNCTION_LITERAL_EXPRESSION
FUNCTION_LITERAL
PsiElement(LBRACE)('{')
PsiWhiteSpace(' ')
PsiComment(EOL_COMMENT)('// no label identifier')
PsiWhiteSpace('\n ')
BLOCK
RETURN
PsiElement(return)('return')
PsiWhiteSpace(' ')
INTEGER_CONSTANT
PsiElement(INTEGER_LITERAL)('3')
PsiWhiteSpace('\n ')
PsiElement(RBRACE)('}')
PsiWhiteSpace('\n\n ')
REFERENCE_EXPRESSION
PsiElement(IDENTIFIER)('loop2')
PsiWhiteSpace(' ')
PsiErrorElement:Unexpected tokens (use ';' to separate expressions on the same line)
PsiElement(AT)('@')
PsiWhiteSpace(' ')
PsiElement(for)('for')
PsiWhiteSpace(' ')
PsiElement(LPAR)('(')
PsiElement(IDENTIFIER)('i')
PsiWhiteSpace(' ')
PsiElement(in)('in')
PsiWhiteSpace(' ')
PsiElement(INTEGER_LITERAL)('1')
PsiElement(RANGE)('..')
PsiElement(INTEGER_LITERAL)('100')
PsiElement(RPAR)(')')
PsiWhiteSpace(' ')
FUNCTION_LITERAL_EXPRESSION
FUNCTION_LITERAL
PsiElement(LBRACE)('{')
PsiWhiteSpace(' ')
PsiComment(EOL_COMMENT)('// should be no space after loop2')
PsiWhiteSpace('\n ')
BLOCK
RETURN
PsiElement(return)('return')
PsiErrorElement:Label must be named
PsiElement(AT)('@')
PsiWhiteSpace(' ')
REFERENCE_EXPRESSION
PsiElement(IDENTIFIER)('loop2')
PsiWhiteSpace(' ')
PsiErrorElement:Unexpected tokens (use ';' to separate expressions on the same line)
PsiElement(INTEGER_LITERAL)('5')
PsiWhiteSpace('\n ')
RETURN
PsiElement(return)('return')
PsiWhiteSpace(' ')
LABELED_EXPRESSION
PsiErrorElement:Label must be named
PsiElement(AT)('@')
PsiWhiteSpace(' ')
REFERENCE_EXPRESSION
PsiElement(IDENTIFIER)('loop2')
PsiWhiteSpace(' ')
PsiErrorElement:Unexpected tokens (use ';' to separate expressions on the same line)
PsiElement(INTEGER_LITERAL)('7')
PsiWhiteSpace('\n ')
RETURN
PsiElement(return)('return')
PsiWhiteSpace('\n ')
LABELED_EXPRESSION
PsiErrorElement:Label must be named
PsiElement(AT)('@')
REFERENCE_EXPRESSION
PsiElement(IDENTIFIER)('loop2')
PsiWhiteSpace(' ')
PsiErrorElement:Unexpected tokens (use ';' to separate expressions on the same line)
PsiElement(INTEGER_LITERAL)('4')
PsiWhiteSpace('\n ')
PsiElement(RBRACE)('}')
PsiWhiteSpace('\n\n ')
LABELED_EXPRESSION
PsiErrorElement:Label must be named
PsiElement(AT)('@')
PsiWhiteSpace(' ')
WHILE
PsiElement(while)('while')
PsiWhiteSpace(' ')
PsiElement(LPAR)('(')
CONDITION
INTEGER_CONSTANT
PsiElement(INTEGER_LITERAL)('1')
PsiElement(RPAR)(')')
PsiWhiteSpace(' ')
BODY
BLOCK
PsiElement(LBRACE)('{')
PsiWhiteSpace('\n ')
RETURN
PsiElement(return)('return')
PsiWhiteSpace(' ')
INTEGER_CONSTANT
PsiElement(INTEGER_LITERAL)('123')
PsiWhiteSpace('\n ')
PsiElement(RBRACE)('}')
PsiWhiteSpace('\n\n ')
REFERENCE_EXPRESSION
PsiElement(IDENTIFIER)('label2')
PsiWhiteSpace(' ')
PsiErrorElement:Unexpected tokens (use ';' to separate expressions on the same line)
PsiElement(AT)('@')
PsiWhiteSpace(' ')
PsiElement(fun)('fun')
PsiWhiteSpace(' ')
PsiElement(IDENTIFIER)('foo')
PsiElement(LPAR)('(')
PsiElement(RPAR)(')')
PsiWhiteSpace(' ')
FUNCTION_LITERAL_EXPRESSION
FUNCTION_LITERAL
PsiElement(LBRACE)('{')
BLOCK
<empty list>
PsiElement(RBRACE)('}')
PsiWhiteSpace(' ')
PsiComment(EOL_COMMENT)('// should be no space after label2')
PsiWhiteSpace('\n\n ')
BINARY_EXPRESSION
BINARY_EXPRESSION
INTEGER_CONSTANT
PsiElement(INTEGER_LITERAL)('1')
PsiWhiteSpace(' ')
OPERATION_REFERENCE
PsiElement(PLUS)('+')
PsiWhiteSpace(' ')
LABELED_EXPRESSION
LABEL_QUALIFIER
LABEL
PsiElement(IDENTIFIER)('label3')
PsiElement(AT)('@')
PsiWhiteSpace(' ')
INTEGER_CONSTANT
PsiElement(INTEGER_LITERAL)('3')
PsiWhiteSpace(' ')
OPERATION_REFERENCE
PsiElement(PLUS)('+')
PsiWhiteSpace(' ')
INTEGER_CONSTANT
PsiElement(INTEGER_LITERAL)('4')
PsiWhiteSpace('\n\n ')
REFERENCE_EXPRESSION
PsiElement(IDENTIFIER)('l1')
PsiWhiteSpace(' ')
PsiErrorElement:Unexpected tokens (use ';' to separate expressions on the same line)
PsiElement(AT)('@')
PsiWhiteSpace(' ')
PsiElement(IDENTIFIER)('foo')
PsiWhiteSpace(' ')
PsiElement(IDENTIFIER)('bar')
PsiWhiteSpace(' ')
PsiElement(IDENTIFIER)('l2')
PsiWhiteSpace(' ')
PsiElement(AT)('@')
PsiWhiteSpace(' ')
PsiElement(IDENTIFIER)('baz')
PsiWhiteSpace(' ')
PsiComment(EOL_COMMENT)('// binary expression with extra spaces')
PsiWhiteSpace('\n ')
BINARY_EXPRESSION
BINARY_EXPRESSION
BINARY_EXPRESSION
REFERENCE_EXPRESSION
PsiElement(IDENTIFIER)('foo')
PsiWhiteSpace(' ')
OPERATION_REFERENCE
PsiElement(IDENTIFIER)('l3')
PsiWhiteSpace(' ')
LABELED_EXPRESSION
PsiErrorElement:Label must be named
PsiElement(AT)('@')
PsiWhiteSpace(' ')
REFERENCE_EXPRESSION
PsiElement(IDENTIFIER)('bar')
PsiWhiteSpace(' ')
OPERATION_REFERENCE
PsiElement(IDENTIFIER)('baz')
PsiWhiteSpace(' ')
PsiComment(EOL_COMMENT)('// binary expression with `@ bar` parsed as wrong label')
PsiWhiteSpace('\n\n ')
LABELED_EXPRESSION
LABEL_QUALIFIER
LABEL
PsiElement(IDENTIFIER)('foo')
PsiElement(AT)('@')
PsiWhiteSpace(' ')
REFERENCE_EXPRESSION
PsiElement(IDENTIFIER)('bar')
PsiWhiteSpace(' ')
OPERATION_REFERENCE
PsiElement(IDENTIFIER)('baz')
PsiWhiteSpace(' ')
PsiComment(EOL_COMMENT)('// binary expression labeled `bar` and return as second arg')
PsiWhiteSpace('\n\n ')
RETURN
PsiElement(return)('return')
PsiWhiteSpace(' ')
LABELED_EXPRESSION
PsiErrorElement:Label must be named
PsiElement(AT)('@')
PsiWhiteSpace(' ')
INTEGER_CONSTANT
PsiElement(INTEGER_LITERAL)('1')
PsiWhiteSpace('\n')
PsiElement(RBRACE)('}')
@@ -0,0 +1,30 @@
fun foo() {
break @l1
val x = 1
return @l2 1
val x = 2
return @l3
val x = 3
continue @l4 5
val x = 6
break/**/@l5
val x = 7
return /**/@l6
val x = 8
return//
@l7 4
val x = 9
}
@@ -0,0 +1,152 @@
JetFile: spaceBeforeLabelReference.kt
PACKAGE_DIRECTIVE
<empty list>
FUN
PsiElement(fun)('fun')
PsiWhiteSpace(' ')
PsiElement(IDENTIFIER)('foo')
VALUE_PARAMETER_LIST
PsiElement(LPAR)('(')
PsiElement(RPAR)(')')
PsiWhiteSpace(' ')
BLOCK
PsiElement(LBRACE)('{')
PsiWhiteSpace('\n ')
BREAK
PsiElement(break)('break')
PsiWhiteSpace(' ')
PsiErrorElement:Unexpected tokens (use ';' to separate expressions on the same line)
PsiElement(AT)('@')
PsiElement(IDENTIFIER)('l1')
PsiWhiteSpace('\n\n ')
PROPERTY
PsiElement(val)('val')
PsiWhiteSpace(' ')
PsiElement(IDENTIFIER)('x')
PsiWhiteSpace(' ')
PsiElement(EQ)('=')
PsiWhiteSpace(' ')
INTEGER_CONSTANT
PsiElement(INTEGER_LITERAL)('1')
PsiWhiteSpace('\n\n ')
RETURN
PsiElement(return)('return')
PsiWhiteSpace(' ')
LABELED_EXPRESSION
PsiErrorElement:Label must be named
PsiElement(AT)('@')
REFERENCE_EXPRESSION
PsiElement(IDENTIFIER)('l2')
PsiWhiteSpace(' ')
PsiErrorElement:Unexpected tokens (use ';' to separate expressions on the same line)
PsiElement(INTEGER_LITERAL)('1')
PsiWhiteSpace('\n\n ')
PROPERTY
PsiElement(val)('val')
PsiWhiteSpace(' ')
PsiElement(IDENTIFIER)('x')
PsiWhiteSpace(' ')
PsiElement(EQ)('=')
PsiWhiteSpace(' ')
INTEGER_CONSTANT
PsiElement(INTEGER_LITERAL)('2')
PsiWhiteSpace('\n\n ')
RETURN
PsiElement(return)('return')
PsiWhiteSpace(' ')
LABELED_EXPRESSION
PsiErrorElement:Label must be named
PsiElement(AT)('@')
REFERENCE_EXPRESSION
PsiElement(IDENTIFIER)('l3')
PsiWhiteSpace('\n\n ')
PROPERTY
PsiElement(val)('val')
PsiWhiteSpace(' ')
PsiElement(IDENTIFIER)('x')
PsiWhiteSpace(' ')
PsiElement(EQ)('=')
PsiWhiteSpace(' ')
INTEGER_CONSTANT
PsiElement(INTEGER_LITERAL)('3')
PsiWhiteSpace('\n\n ')
CONTINUE
PsiElement(continue)('continue')
PsiWhiteSpace(' ')
PsiErrorElement:Unexpected tokens (use ';' to separate expressions on the same line)
PsiElement(AT)('@')
PsiElement(IDENTIFIER)('l4')
PsiWhiteSpace(' ')
PsiElement(INTEGER_LITERAL)('5')
PsiWhiteSpace('\n\n ')
PROPERTY
PsiElement(val)('val')
PsiWhiteSpace(' ')
PsiElement(IDENTIFIER)('x')
PsiWhiteSpace(' ')
PsiElement(EQ)('=')
PsiWhiteSpace(' ')
INTEGER_CONSTANT
PsiElement(INTEGER_LITERAL)('6')
PsiWhiteSpace('\n\n ')
BREAK
PsiElement(break)('break')
PsiComment(BLOCK_COMMENT)('/**/')
PsiErrorElement:Unexpected tokens (use ';' to separate expressions on the same line)
PsiElement(AT)('@')
PsiElement(IDENTIFIER)('l5')
PsiWhiteSpace('\n\n ')
PROPERTY
PsiElement(val)('val')
PsiWhiteSpace(' ')
PsiElement(IDENTIFIER)('x')
PsiWhiteSpace(' ')
PsiElement(EQ)('=')
PsiWhiteSpace(' ')
INTEGER_CONSTANT
PsiElement(INTEGER_LITERAL)('7')
PsiWhiteSpace('\n\n ')
RETURN
PsiElement(return)('return')
PsiWhiteSpace(' ')
PsiComment(BLOCK_COMMENT)('/**/')
LABELED_EXPRESSION
PsiErrorElement:Label must be named
PsiElement(AT)('@')
REFERENCE_EXPRESSION
PsiElement(IDENTIFIER)('l6')
PsiWhiteSpace('\n\n ')
PROPERTY
PsiElement(val)('val')
PsiWhiteSpace(' ')
PsiElement(IDENTIFIER)('x')
PsiWhiteSpace(' ')
PsiElement(EQ)('=')
PsiWhiteSpace(' ')
INTEGER_CONSTANT
PsiElement(INTEGER_LITERAL)('8')
PsiWhiteSpace('\n\n ')
RETURN
PsiElement(return)('return')
PsiComment(EOL_COMMENT)('//')
PsiWhiteSpace('\n')
LABELED_EXPRESSION
PsiErrorElement:Label must be named
PsiElement(AT)('@')
REFERENCE_EXPRESSION
PsiElement(IDENTIFIER)('l7')
PsiWhiteSpace(' ')
PsiErrorElement:Unexpected tokens (use ';' to separate expressions on the same line)
PsiElement(INTEGER_LITERAL)('4')
PsiWhiteSpace('\n\n ')
PROPERTY
PsiElement(val)('val')
PsiWhiteSpace(' ')
PsiElement(IDENTIFIER)('x')
PsiWhiteSpace(' ')
PsiElement(EQ)('=')
PsiWhiteSpace(' ')
INTEGER_CONSTANT
PsiElement(INTEGER_LITERAL)('9')
PsiWhiteSpace('\n')
PsiElement(RBRACE)('}')
@@ -1201,6 +1201,39 @@ public class JetParsingTestGenerated extends AbstractJetParsingTest {
} }
} }
@TestMetadata("compiler/testData/psi/newLabels")
@TestDataPath("$PROJECT_ROOT")
@RunWith(JUnit3RunnerWithInners.class)
public static class NewLabels extends AbstractJetParsingTest {
public void testAllFilesPresentInNewLabels() throws Exception {
JetTestUtils.assertAllTestsPresentByMetadata(this.getClass(), new File("compiler/testData/psi/newLabels"), Pattern.compile("^(.*)\\.kts?$"), true);
}
@TestMetadata("basic.kt")
public void testBasic() throws Exception {
String fileName = JetTestUtils.navigationMetadata("compiler/testData/psi/newLabels/basic.kt");
doParsingTest(fileName);
}
@TestMetadata("oldSyntaxExpressions.kt")
public void testOldSyntaxExpressions() throws Exception {
String fileName = JetTestUtils.navigationMetadata("compiler/testData/psi/newLabels/oldSyntaxExpressions.kt");
doParsingTest(fileName);
}
@TestMetadata("recovery.kt")
public void testRecovery() throws Exception {
String fileName = JetTestUtils.navigationMetadata("compiler/testData/psi/newLabels/recovery.kt");
doParsingTest(fileName);
}
@TestMetadata("spaceBeforeLabelReference.kt")
public void testSpaceBeforeLabelReference() throws Exception {
String fileName = JetTestUtils.navigationMetadata("compiler/testData/psi/newLabels/spaceBeforeLabelReference.kt");
doParsingTest(fileName);
}
}
@TestMetadata("compiler/testData/psi/packages") @TestMetadata("compiler/testData/psi/packages")
@TestDataPath("$PROJECT_ROOT") @TestDataPath("$PROJECT_ROOT")
@RunWith(JUnit3RunnerWithInners.class) @RunWith(JUnit3RunnerWithInners.class)
+15 -13
View File
@@ -8,7 +8,7 @@
| Precedence | Title | Symbols | | Precedence | Title | Symbols |
|------------|-------|---------| |------------|-------|---------|
| Highest | Postfix | `++`, `--`, `.`, `?.`, `?` | | Highest | Postfix | `++`, `--`, `.`, `?.`, `?` |
| | Prefix | `-`, `+`, `++`, `--`, `!`, [`@label`](#LabelName), `@`, `@@` | | | Prefix | `-`, `+`, `++`, `--`, `!`, [`labelDefinition@`](#IDENTIFIER)`@` |
| | Type RHS | `:`, `as`, `as?` | | | Type RHS | `:`, `as`, `as?` |
| | Multiplicative | `*`, `/`, `%` | | | Multiplicative | `*`, `/`, `%` |
| | Additive | `+`, `-` | | | Additive | `+`, `-` |
@@ -112,8 +112,8 @@ atomicExpression
: "(" expression ")" : "(" expression ")"
: literalConstant : literalConstant
: functionLiteral : functionLiteral
: "this" label? : "this" labelReference?
: "super" ("<" type ">")? label? : "super" ("<" type ">")? labelReference?
: if : if
: when : when
: try : try
@@ -125,10 +125,12 @@ atomicExpression
: "package" // for the root package : "package" // for the root package
; ;
label labelReference
: "@" : "@" LabelName
: "@@" ;
: LabelName
labelDefinition
: LabelName "@"
; ;
literalConstant literalConstant
@@ -212,7 +214,7 @@ prefixUnaryOperation
: "++" : "--" : "++" : "--"
: "!" // No ~ : "!" // No ~
: annotations // mandatory : annotations // mandatory
: label : labelDefinition
; ;
postfixUnaryOperation postfixUnaryOperation
@@ -223,8 +225,8 @@ postfixUnaryOperation
; ;
callSuffix callSuffix
: typeArguments? valueArguments (label? functionLiteral) : typeArguments? valueArguments (labelDefinition? functionLiteral)
: typeArguments (label? functionLiteral) : typeArguments (labelDefinition? functionLiteral)
; ;
memberAccessOperation memberAccessOperation
@@ -241,9 +243,9 @@ valueArguments
jump jump
: "throw" expression : "throw" expression
: "return" label? expression? : "return" labelReference? expression?
: "continue" label? : "continue" labelReference?
: "break" label? : "break" labelReference?
// yield ? // yield ?
; ;