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 IDENTIFIER = new JetToken("IDENTIFIER");
JetToken LABEL_IDENTIFIER = new JetToken("LABEL_IDENTIFIER");
JetToken FIELD_IDENTIFIER = new JetToken("FIELD_IDENTIFIER");
JetSingleValueToken LBRACKET = new JetSingleValueToken("LBRACKET", "[");
@@ -127,6 +126,7 @@ public interface JetTokens {
JetKeywordToken NOT_IN = JetKeywordToken.keyword("NOT_IN", "!in");
JetKeywordToken NOT_IS = JetKeywordToken.keyword("NOT_IS", "!is");
JetSingleValueToken HASH = new JetSingleValueToken("HASH", "#");
JetSingleValueToken AT = new JetSingleValueToken("AT", "@");
JetSingleValueToken COMMA = new JetSingleValueToken("COMMA", ",");
@@ -211,7 +211,7 @@ public interface JetTokens {
COLON,
RANGE, EQ, MULTEQ, DIVEQ, PERCEQ, PLUSEQ, MINUSEQ,
NOT_IN, NOT_IS,
IDENTIFIER, LABEL_IDENTIFIER);
IDENTIFIER);
TokenSet AUGMENTED_ASSIGNMENTS = TokenSet.create(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]+`
IDENTIFIER = {PLAIN_IDENTIFIER}|{ESCAPED_IDENTIFIER}
FIELD_IDENTIFIER = \${IDENTIFIER}
LABEL_IDENTIFIER = \@{IDENTIFIER}?
EOL_COMMENT="/""/"[^\n]*
SHEBANG_COMMENT="#!"[^\n]*
@@ -273,7 +272,6 @@ LONG_TEMPLATE_ENTRY_START=\$\{
{FIELD_IDENTIFIER} { return JetTokens.FIELD_IDENTIFIER; }
{IDENTIFIER} { return JetTokens.IDENTIFIER; }
{LABEL_IDENTIFIER} { return JetTokens.LABEL_IDENTIFIER; }
\!in{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.COMMA ; }
"#" { return JetTokens.HASH ; }
"@" { return JetTokens.AT ; }
// error fallback
. { return TokenType.BAD_CHARACTER; }
@@ -71,7 +71,7 @@ public class JetExpressionParsing extends AbstractJetParsing {
// Prefix
MINUS, PLUS, MINUSMINUS, PLUSPLUS,
EXCL, EXCLEXCL, // Joining complex tokens makes it necessary to put EXCLEXCL here
LBRACKET, LABEL_IDENTIFIER,
LBRACKET,
// Atomic
COLONCOLON, // callable reference
@@ -112,7 +112,8 @@ public class JetExpressionParsing extends AbstractJetParsing {
IDENTIFIER, // SimpleName
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(
@@ -143,7 +144,7 @@ public class JetExpressionParsing extends AbstractJetParsing {
POSTFIX(PLUSPLUS, MINUSMINUS, EXCLEXCL,
DOT, SAFE_ACCESS), // typeArguments? valueArguments : typeArguments : arrayAccess
PREFIX(MINUS, PLUS, MINUSMINUS, PLUSPLUS, EXCL, LABEL_IDENTIFIER) { // annotations
PREFIX(MINUS, PLUS, MINUSMINUS, PLUSPLUS, EXCL) { // annotations
@Override
public void parseHigherPrecedence(JetExpressionParsing parser) {
@@ -328,9 +329,8 @@ public class JetExpressionParsing extends AbstractJetParsing {
* label prefixExpression
*/
private void parseLabeledExpression() {
assert _at(LABEL_IDENTIFIER);
PsiBuilder.Marker expression = mark();
parseLabel();
parseLabelDefinition();
parsePrefixExpression();
expression.done(LABELED_EXPRESSION);
}
@@ -351,7 +351,7 @@ public class JetExpressionParsing extends AbstractJetParsing {
}
else {
myBuilder.disableJoiningComplexTokens();
if (at(LABEL_IDENTIFIER)) {
if (isAtLabelDefinitionOrMissingIdentifier()) {
myBuilder.restoreJoiningComplexTokensState();
parseLabeledExpression();
}
@@ -532,10 +532,10 @@ public class JetExpressionParsing extends AbstractJetParsing {
*/
protected boolean parseCallWithClosure() {
boolean success = false;
while ((at(LBRACE) || at(LABEL_IDENTIFIER) && lookahead(1) == LBRACE)) {
while (at(LBRACE) || isAtLabelDefinitionBeforeLBrace()) {
PsiBuilder.Marker argument = mark();
if (!at(LBRACE)) {
assert _at(LABEL_IDENTIFIER);
parseLabeledExpression();
}
else {
@@ -548,6 +548,19 @@ public class JetExpressionParsing extends AbstractJetParsing {
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
* : tupleLiteral // or parenthesized element
@@ -982,7 +995,8 @@ public class JetExpressionParsing extends AbstractJetParsing {
if (declType != null) {
// 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;
}
else {
@@ -1450,10 +1464,10 @@ public class JetExpressionParsing extends AbstractJetParsing {
if (at(LBRACE)) {
parseFunctionLiteral(true);
}
else if (at(LABEL_IDENTIFIER) && lookahead(1) == LBRACE ) {
else if (isAtLabelDefinitionBeforeLBrace()) {
PsiBuilder.Marker mark = mark();
parseLabel();
parseLabelDefinition();
parseFunctionLiteral(true);
@@ -1609,7 +1623,7 @@ public class JetExpressionParsing extends AbstractJetParsing {
advance(); // BREAK_KEYWORD or CONTINUE_KEYWORD
parseLabelOnTheSameLine();
parseLabelReferenceWithNoWhitespace();
marker.done(type);
}
@@ -1624,7 +1638,7 @@ public class JetExpressionParsing extends AbstractJetParsing {
advance(); // RETURN_KEYWORD
parseLabelOnTheSameLine();
parseLabelReferenceWithNoWhitespace();
if (atSet(EXPRESSION_FIRST) && !at(EOL_OR_SEMICOLON)) parseExpression();
@@ -1634,28 +1648,55 @@ public class JetExpressionParsing extends AbstractJetParsing {
/*
* label?
*/
private void parseLabelOnTheSameLine() {
if (!eol() && at(LABEL_IDENTIFIER)) {
parseLabel();
private void parseLabelReferenceWithNoWhitespace() {
if (at(AT) && !WHITE_SPACE_OR_COMMENT_BIT_SET.contains(myBuilder.rawLookup(-1))) {
parseLabelReference();
}
}
/*
* label
* IDENTIFIER "@"
*/
private void parseLabel() {
assert _at(LABEL_IDENTIFIER);
String labelText = myBuilder.getTokenText();
if ("@".equals(labelText)) {
errorAndAdvance("Label must be named");
private void parseLabelDefinition() {
if (at(AT)) {
// recovery for empty label identifier
errorAndAdvance("Label must be named"); // AT
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 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);
labelWrap.done(LABEL_QUALIFIER);
@@ -1753,7 +1794,7 @@ public class JetExpressionParsing extends AbstractJetParsing {
advance(); // THIS_KEYWORD
thisReference.done(REFERENCE_EXPRESSION);
parseLabelOnTheSameLine();
parseLabelReferenceWithNoWhitespace();
mark.done(THIS_EXPRESSION);
}
@@ -1787,7 +1828,7 @@ public class JetExpressionParsing extends AbstractJetParsing {
}
myBuilder.restoreNewlinesState();
}
parseLabelOnTheSameLine();
parseLabelReferenceWithNoWhitespace();
mark.done(SUPER_EXPRESSION);
}
+6 -6
View File
@@ -3,9 +3,9 @@ fun a(
a : foo = throw Foo(),
a : foo = return 10,
a : foo = break,
a : foo = break @la,
a : foo = break@la,
a : foo = continue,
a : foo = continue @la,
a : foo = continue@la,
a : foo = if (10) foo else bar,
a : foo = if (10) foo
) {
@@ -13,11 +13,11 @@ fun a(
return
10
break
@la
break @la
la@
break@la
continue
@la
continue @la
la@
continue@la
if (foo)
if (foo)
bar
+12 -10
View File
@@ -80,10 +80,10 @@ JetFile: ControlStructures.kt
PsiWhiteSpace(' ')
BREAK
PsiElement(break)('break')
PsiWhiteSpace(' ')
LABEL_QUALIFIER
LABEL
PsiElement(LABEL_IDENTIFIER)('@la')
PsiElement(AT)('@')
PsiElement(IDENTIFIER)('la')
PsiElement(COMMA)(',')
PsiWhiteSpace('\n ')
VALUE_PARAMETER
@@ -116,10 +116,10 @@ JetFile: ControlStructures.kt
PsiWhiteSpace(' ')
CONTINUE
PsiElement(continue)('continue')
PsiWhiteSpace(' ')
LABEL_QUALIFIER
LABEL
PsiElement(LABEL_IDENTIFIER)('@la')
PsiElement(AT)('@')
PsiElement(IDENTIFIER)('la')
PsiElement(COMMA)(',')
PsiWhiteSpace('\n ')
VALUE_PARAMETER
@@ -202,14 +202,15 @@ JetFile: ControlStructures.kt
LABELED_EXPRESSION
LABEL_QUALIFIER
LABEL
PsiElement(LABEL_IDENTIFIER)('@la')
PsiElement(IDENTIFIER)('la')
PsiElement(AT)('@')
PsiWhiteSpace('\n ')
BREAK
PsiElement(break)('break')
PsiWhiteSpace(' ')
LABEL_QUALIFIER
LABEL
PsiElement(LABEL_IDENTIFIER)('@la')
PsiElement(AT)('@')
PsiElement(IDENTIFIER)('la')
PsiWhiteSpace('\n ')
CONTINUE
PsiElement(continue)('continue')
@@ -217,14 +218,15 @@ JetFile: ControlStructures.kt
LABELED_EXPRESSION
LABEL_QUALIFIER
LABEL
PsiElement(LABEL_IDENTIFIER)('@la')
PsiElement(IDENTIFIER)('la')
PsiElement(AT)('@')
PsiWhiteSpace('\n ')
CONTINUE
PsiElement(continue)('continue')
PsiWhiteSpace(' ')
LABEL_QUALIFIER
LABEL
PsiElement(LABEL_IDENTIFIER)('@la')
PsiElement(AT)('@')
PsiElement(IDENTIFIER)('la')
PsiWhiteSpace('\n ')
IF
PsiElement(if)('if')
+4 -4
View File
@@ -1,7 +1,7 @@
fun foo() {
return
return 1
return (@a 1)
return (a@ 1)
return@
return@ 1
@@ -10,8 +10,8 @@ fun foo() {
return@a
return@a 1
return@a (@a 1)
return@a @a 1
return@a (a@ 1)
return@a a@ 1
return@@
return@@ 1
@@ -24,7 +24,7 @@ fun foo() {
continue@
continue@a
a.filter @f{
a.filter f@{
if (1) return
return@f true
}
+42 -29
View File
@@ -29,7 +29,8 @@ JetFile: Labels.kt
LABELED_EXPRESSION
LABEL_QUALIFIER
LABEL
PsiElement(LABEL_IDENTIFIER)('@a')
PsiElement(IDENTIFIER)('a')
PsiElement(AT)('@')
PsiWhiteSpace(' ')
INTEGER_CONSTANT
PsiElement(INTEGER_LITERAL)('1')
@@ -38,12 +39,12 @@ JetFile: Labels.kt
RETURN
PsiElement(return)('return')
PsiErrorElement:Label must be named
PsiElement(LABEL_IDENTIFIER)('@')
PsiElement(AT)('@')
PsiWhiteSpace('\n ')
RETURN
PsiElement(return)('return')
PsiErrorElement:Label must be named
PsiElement(LABEL_IDENTIFIER)('@')
PsiElement(AT)('@')
PsiWhiteSpace(' ')
INTEGER_CONSTANT
PsiElement(INTEGER_LITERAL)('1')
@@ -51,13 +52,13 @@ JetFile: Labels.kt
RETURN
PsiElement(return)('return')
PsiErrorElement:Label must be named
PsiElement(LABEL_IDENTIFIER)('@')
PsiElement(AT)('@')
PsiWhiteSpace(' ')
PARENTHESIZED
PsiElement(LPAR)('(')
LABELED_EXPRESSION
PsiErrorElement:Label must be named
PsiElement(LABEL_IDENTIFIER)('@')
PsiElement(AT)('@')
PsiWhiteSpace(' ')
INTEGER_CONSTANT
PsiElement(INTEGER_LITERAL)('1')
@@ -66,11 +67,11 @@ JetFile: Labels.kt
RETURN
PsiElement(return)('return')
PsiErrorElement:Label must be named
PsiElement(LABEL_IDENTIFIER)('@')
PsiElement(AT)('@')
PsiWhiteSpace(' ')
LABELED_EXPRESSION
PsiErrorElement:Label must be named
PsiElement(LABEL_IDENTIFIER)('@')
PsiElement(AT)('@')
PsiWhiteSpace(' ')
INTEGER_CONSTANT
PsiElement(INTEGER_LITERAL)('1')
@@ -79,13 +80,15 @@ JetFile: Labels.kt
PsiElement(return)('return')
LABEL_QUALIFIER
LABEL
PsiElement(LABEL_IDENTIFIER)('@a')
PsiElement(AT)('@')
PsiElement(IDENTIFIER)('a')
PsiWhiteSpace('\n ')
RETURN
PsiElement(return)('return')
LABEL_QUALIFIER
LABEL
PsiElement(LABEL_IDENTIFIER)('@a')
PsiElement(AT)('@')
PsiElement(IDENTIFIER)('a')
PsiWhiteSpace(' ')
INTEGER_CONSTANT
PsiElement(INTEGER_LITERAL)('1')
@@ -94,14 +97,16 @@ JetFile: Labels.kt
PsiElement(return)('return')
LABEL_QUALIFIER
LABEL
PsiElement(LABEL_IDENTIFIER)('@a')
PsiElement(AT)('@')
PsiElement(IDENTIFIER)('a')
PsiWhiteSpace(' ')
PARENTHESIZED
PsiElement(LPAR)('(')
LABELED_EXPRESSION
LABEL_QUALIFIER
LABEL
PsiElement(LABEL_IDENTIFIER)('@a')
PsiElement(IDENTIFIER)('a')
PsiElement(AT)('@')
PsiWhiteSpace(' ')
INTEGER_CONSTANT
PsiElement(INTEGER_LITERAL)('1')
@@ -111,12 +116,14 @@ JetFile: Labels.kt
PsiElement(return)('return')
LABEL_QUALIFIER
LABEL
PsiElement(LABEL_IDENTIFIER)('@a')
PsiElement(AT)('@')
PsiElement(IDENTIFIER)('a')
PsiWhiteSpace(' ')
LABELED_EXPRESSION
LABEL_QUALIFIER
LABEL
PsiElement(LABEL_IDENTIFIER)('@a')
PsiElement(IDENTIFIER)('a')
PsiElement(AT)('@')
PsiWhiteSpace(' ')
INTEGER_CONSTANT
PsiElement(INTEGER_LITERAL)('1')
@@ -124,18 +131,18 @@ JetFile: Labels.kt
RETURN
PsiElement(return)('return')
PsiErrorElement:Label must be named
PsiElement(LABEL_IDENTIFIER)('@')
PsiElement(AT)('@')
LABELED_EXPRESSION
PsiErrorElement:Label must be named
PsiElement(LABEL_IDENTIFIER)('@')
PsiElement(AT)('@')
PsiWhiteSpace('\n ')
RETURN
PsiElement(return)('return')
PsiErrorElement:Label must be named
PsiElement(LABEL_IDENTIFIER)('@')
PsiElement(AT)('@')
LABELED_EXPRESSION
PsiErrorElement:Label must be named
PsiElement(LABEL_IDENTIFIER)('@')
PsiElement(AT)('@')
PsiWhiteSpace(' ')
INTEGER_CONSTANT
PsiElement(INTEGER_LITERAL)('1')
@@ -146,13 +153,14 @@ JetFile: Labels.kt
BREAK
PsiElement(break)('break')
PsiErrorElement:Label must be named
PsiElement(LABEL_IDENTIFIER)('@')
PsiElement(AT)('@')
PsiWhiteSpace('\n ')
BREAK
PsiElement(break)('break')
LABEL_QUALIFIER
LABEL
PsiElement(LABEL_IDENTIFIER)('@a')
PsiElement(AT)('@')
PsiElement(IDENTIFIER)('a')
PsiWhiteSpace('\n\n ')
CONTINUE
PsiElement(continue)('continue')
@@ -160,13 +168,14 @@ JetFile: Labels.kt
CONTINUE
PsiElement(continue)('continue')
PsiErrorElement:Label must be named
PsiElement(LABEL_IDENTIFIER)('@')
PsiElement(AT)('@')
PsiWhiteSpace('\n ')
CONTINUE
PsiElement(continue)('continue')
LABEL_QUALIFIER
LABEL
PsiElement(LABEL_IDENTIFIER)('@a')
PsiElement(AT)('@')
PsiElement(IDENTIFIER)('a')
PsiWhiteSpace('\n\n ')
DOT_QUALIFIED_EXPRESSION
REFERENCE_EXPRESSION
@@ -180,7 +189,8 @@ JetFile: Labels.kt
LABELED_EXPRESSION
LABEL_QUALIFIER
LABEL
PsiElement(LABEL_IDENTIFIER)('@f')
PsiElement(IDENTIFIER)('f')
PsiElement(AT)('@')
FUNCTION_LITERAL_EXPRESSION
FUNCTION_LITERAL
PsiElement(LBRACE)('{')
@@ -203,7 +213,8 @@ JetFile: Labels.kt
PsiElement(return)('return')
LABEL_QUALIFIER
LABEL
PsiElement(LABEL_IDENTIFIER)('@f')
PsiElement(AT)('@')
PsiElement(IDENTIFIER)('f')
PsiWhiteSpace(' ')
BOOLEAN_CONSTANT
PsiElement(true)('true')
@@ -221,7 +232,7 @@ JetFile: Labels.kt
FUNCTION_LITERAL_ARGUMENT
LABELED_EXPRESSION
PsiErrorElement:Label must be named
PsiElement(LABEL_IDENTIFIER)('@')
PsiElement(AT)('@')
FUNCTION_LITERAL_EXPRESSION
FUNCTION_LITERAL
PsiElement(LBRACE)('{')
@@ -243,7 +254,7 @@ JetFile: Labels.kt
RETURN
PsiElement(return)('return')
PsiErrorElement:Label must be named
PsiElement(LABEL_IDENTIFIER)('@')
PsiElement(AT)('@')
PsiWhiteSpace(' ')
BOOLEAN_CONSTANT
PsiElement(true)('true')
@@ -258,14 +269,15 @@ JetFile: Labels.kt
REFERENCE_EXPRESSION
PsiElement(this)('this')
PsiErrorElement:Label must be named
PsiElement(LABEL_IDENTIFIER)('@')
PsiElement(AT)('@')
PsiWhiteSpace('\n ')
THIS_EXPRESSION
REFERENCE_EXPRESSION
PsiElement(this)('this')
LABEL_QUALIFIER
LABEL
PsiElement(LABEL_IDENTIFIER)('@a')
PsiElement(AT)('@')
PsiElement(IDENTIFIER)('a')
PsiWhiteSpace('\n\n ')
SUPER_EXPRESSION
REFERENCE_EXPRESSION
@@ -287,7 +299,7 @@ JetFile: Labels.kt
PsiElement(IDENTIFIER)('A')
PsiElement(GT)('>')
PsiErrorElement:Label must be named
PsiElement(LABEL_IDENTIFIER)('@')
PsiElement(AT)('@')
PsiWhiteSpace('\n ')
SUPER_EXPRESSION
REFERENCE_EXPRESSION
@@ -300,6 +312,7 @@ JetFile: Labels.kt
PsiElement(GT)('>')
LABEL_QUALIFIER
LABEL
PsiElement(LABEL_IDENTIFIER)('@a')
PsiElement(AT)('@')
PsiElement(IDENTIFIER)('a')
PsiWhiteSpace('\n')
PsiElement(RBRACE)('}')
+6 -6
View File
@@ -25,9 +25,9 @@ fun a(
a : foo = throw Foo(),
a : foo = return 10,
a : foo = break,
a : foo = break @la,
a : foo = break@la,
a : foo = continue,
a : foo = continue @la,
a : foo = continue@la,
a : foo = 10,
a : foo = 10,
a : foo = 10,
@@ -38,9 +38,9 @@ fun a(
return
10
break
@la
break @la
la@
break@la
continue
@la
continue @la
la@
continue@la
}
+12 -10
View File
@@ -552,10 +552,10 @@ JetFile: SimpleExpressions.kt
PsiWhiteSpace(' ')
BREAK
PsiElement(break)('break')
PsiWhiteSpace(' ')
LABEL_QUALIFIER
LABEL
PsiElement(LABEL_IDENTIFIER)('@la')
PsiElement(AT)('@')
PsiElement(IDENTIFIER)('la')
PsiElement(COMMA)(',')
PsiWhiteSpace('\n ')
VALUE_PARAMETER
@@ -588,10 +588,10 @@ JetFile: SimpleExpressions.kt
PsiWhiteSpace(' ')
CONTINUE
PsiElement(continue)('continue')
PsiWhiteSpace(' ')
LABEL_QUALIFIER
LABEL
PsiElement(LABEL_IDENTIFIER)('@la')
PsiElement(AT)('@')
PsiElement(IDENTIFIER)('la')
PsiElement(COMMA)(',')
PsiWhiteSpace('\n ')
VALUE_PARAMETER
@@ -700,14 +700,15 @@ JetFile: SimpleExpressions.kt
LABELED_EXPRESSION
LABEL_QUALIFIER
LABEL
PsiElement(LABEL_IDENTIFIER)('@la')
PsiElement(IDENTIFIER)('la')
PsiElement(AT)('@')
PsiWhiteSpace('\n ')
BREAK
PsiElement(break)('break')
PsiWhiteSpace(' ')
LABEL_QUALIFIER
LABEL
PsiElement(LABEL_IDENTIFIER)('@la')
PsiElement(AT)('@')
PsiElement(IDENTIFIER)('la')
PsiWhiteSpace('\n ')
CONTINUE
PsiElement(continue)('continue')
@@ -715,13 +716,14 @@ JetFile: SimpleExpressions.kt
LABELED_EXPRESSION
LABEL_QUALIFIER
LABEL
PsiElement(LABEL_IDENTIFIER)('@la')
PsiElement(IDENTIFIER)('la')
PsiElement(AT)('@')
PsiWhiteSpace('\n ')
CONTINUE
PsiElement(continue)('continue')
PsiWhiteSpace(' ')
LABEL_QUALIFIER
LABEL
PsiElement(LABEL_IDENTIFIER)('@la')
PsiElement(AT)('@')
PsiElement(IDENTIFIER)('la')
PsiWhiteSpace('\n')
PsiElement(RBRACE)('}')
+2 -1
View File
@@ -76,7 +76,8 @@ JetFile: Super.kt
PsiElement(GT)('>')
LABEL_QUALIFIER
LABEL
PsiElement(LABEL_IDENTIFIER)('@label')
PsiElement(AT)('@')
PsiElement(IDENTIFIER)('label')
PsiElement(DOT)('.')
CALL_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")
@TestDataPath("$PROJECT_ROOT")
@RunWith(JUnit3RunnerWithInners.class)
+15 -13
View File
@@ -8,7 +8,7 @@
| Precedence | Title | Symbols |
|------------|-------|---------|
| Highest | Postfix | `++`, `--`, `.`, `?.`, `?` |
| | Prefix | `-`, `+`, `++`, `--`, `!`, [`@label`](#LabelName), `@`, `@@` |
| | Prefix | `-`, `+`, `++`, `--`, `!`, [`labelDefinition@`](#IDENTIFIER)`@` |
| | Type RHS | `:`, `as`, `as?` |
| | Multiplicative | `*`, `/`, `%` |
| | Additive | `+`, `-` |
@@ -112,8 +112,8 @@ atomicExpression
: "(" expression ")"
: literalConstant
: functionLiteral
: "this" label?
: "super" ("<" type ">")? label?
: "this" labelReference?
: "super" ("<" type ">")? labelReference?
: if
: when
: try
@@ -125,10 +125,12 @@ atomicExpression
: "package" // for the root package
;
label
: "@"
: "@@"
: LabelName
labelReference
: "@" LabelName
;
labelDefinition
: LabelName "@"
;
literalConstant
@@ -212,7 +214,7 @@ prefixUnaryOperation
: "++" : "--"
: "!" // No ~
: annotations // mandatory
: label
: labelDefinition
;
postfixUnaryOperation
@@ -223,8 +225,8 @@ postfixUnaryOperation
;
callSuffix
: typeArguments? valueArguments (label? functionLiteral)
: typeArguments (label? functionLiteral)
: typeArguments? valueArguments (labelDefinition? functionLiteral)
: typeArguments (labelDefinition? functionLiteral)
;
memberAccessOperation
@@ -241,9 +243,9 @@ valueArguments
jump
: "throw" expression
: "return" label? expression?
: "continue" label?
: "break" label?
: "return" labelReference? expression?
: "continue" labelReference?
: "break" labelReference?
// yield ?
;