Recovery for expressions. Bug with return inside if fixed
This commit is contained in:
@@ -76,6 +76,7 @@ postfixUnaryExpression
|
|||||||
: memberAccess postfixUnaryOperation*
|
: memberAccess postfixUnaryOperation*
|
||||||
;
|
;
|
||||||
|
|
||||||
|
// !!! When you add here, remember to update the FIRST set in the parser
|
||||||
atomicExpression
|
atomicExpression
|
||||||
: "(" expression ")" // see tupleLiteral
|
: "(" expression ")" // see tupleLiteral
|
||||||
: literalConstant
|
: literalConstant
|
||||||
@@ -92,6 +93,7 @@ atomicExpression
|
|||||||
: jump
|
: jump
|
||||||
: loop
|
: loop
|
||||||
: SimpleName
|
: SimpleName
|
||||||
|
: FieldName
|
||||||
: "namespace" // for the root namespace
|
: "namespace" // for the root namespace
|
||||||
;
|
;
|
||||||
|
|
||||||
|
|||||||
@@ -29,6 +29,57 @@ public class JetExpressionParsing extends AbstractJetParsing {
|
|||||||
COLON
|
COLON
|
||||||
);
|
);
|
||||||
|
|
||||||
|
private static final TokenSet EXPRESSION_FIRST = TokenSet.orSet(TokenSet.create(
|
||||||
|
// Prefix
|
||||||
|
MINUS, PLUS, MINUSMINUS, PLUSPLUS, EXCL, LBRACKET,
|
||||||
|
// Atomic
|
||||||
|
|
||||||
|
LPAR, // parenthesized
|
||||||
|
|
||||||
|
// literal constant
|
||||||
|
TRUE_KEYWORD, FALSE_KEYWORD,
|
||||||
|
STRING_LITERAL, RAW_STRING_LITERAL,
|
||||||
|
INTEGER_LITERAL, LONG_LITERAL, CHARACTER_LITERAL, FLOAT_LITERAL,
|
||||||
|
NULL_KEYWORD,
|
||||||
|
|
||||||
|
LBRACE, // functionLiteral
|
||||||
|
|
||||||
|
LPAR, // tuple
|
||||||
|
|
||||||
|
THIS_KEYWORD, // this
|
||||||
|
|
||||||
|
IF_KEYWORD, // if
|
||||||
|
WHEN_KEYWORD, // when
|
||||||
|
TRY_KEYWORD, // try
|
||||||
|
TYPEOF_KEYWORD, // typeof
|
||||||
|
NEW_KEYWORD, // new
|
||||||
|
OBJECT_KEYWORD, // object
|
||||||
|
|
||||||
|
// declaration
|
||||||
|
LBRACKET, // attribute
|
||||||
|
FUN_KEYWORD,
|
||||||
|
VAL_KEYWORD, VAR_KEYWORD,
|
||||||
|
EXTENSION_KEYWORD,
|
||||||
|
CLASS_KEYWORD,
|
||||||
|
TYPE_KEYWORD,
|
||||||
|
|
||||||
|
// jump
|
||||||
|
THROW_KEYWORD,
|
||||||
|
RETURN_KEYWORD,
|
||||||
|
CONTINUE_KEYWORD,
|
||||||
|
BREAK_KEYWORD,
|
||||||
|
|
||||||
|
// loop
|
||||||
|
FOR_KEYWORD,
|
||||||
|
WHILE_KEYWORD,
|
||||||
|
DO_KEYWORD,
|
||||||
|
|
||||||
|
IDENTIFIER, // SimpleName
|
||||||
|
FIELD_IDENTIFIER, // Field reference
|
||||||
|
|
||||||
|
NAMESPACE_KEYWORD // for absolute qualified names
|
||||||
|
), MODIFIER_KEYWORDS);
|
||||||
|
|
||||||
private final JetParsing myJetParsing;
|
private final JetParsing myJetParsing;
|
||||||
|
|
||||||
public JetExpressionParsing(SemanticWhitespaceAwarePsiBuilder builder, JetParsing jetParsing) {
|
public JetExpressionParsing(SemanticWhitespaceAwarePsiBuilder builder, JetParsing jetParsing) {
|
||||||
@@ -141,8 +192,7 @@ public class JetExpressionParsing extends AbstractJetParsing {
|
|||||||
* ;
|
* ;
|
||||||
*/
|
*/
|
||||||
public void parseExpression() {
|
public void parseExpression() {
|
||||||
// TODO: better recovery for expressions
|
if (!atSet(EXPRESSION_FIRST)) {
|
||||||
if (atSet(RPAR, RBRACE, RBRACKET, GT)) {
|
|
||||||
error("Expecting an expression");
|
error("Expecting an expression");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@@ -906,7 +956,12 @@ public class JetExpressionParsing extends AbstractJetParsing {
|
|||||||
public void parseExpressions() {
|
public void parseExpressions() {
|
||||||
while (at(SEMICOLON)) advance(); // SEMICOLON
|
while (at(SEMICOLON)) advance(); // SEMICOLON
|
||||||
while (!eof() && !at(RBRACE)) {
|
while (!eof() && !at(RBRACE)) {
|
||||||
parseExpression();
|
if (!atSet(EXPRESSION_FIRST)) {
|
||||||
|
errorAndAdvance("Expecting an expression");
|
||||||
|
}
|
||||||
|
if (atSet(EXPRESSION_FIRST)) {
|
||||||
|
parseExpression();
|
||||||
|
}
|
||||||
if (at(SEMICOLON)) {
|
if (at(SEMICOLON)) {
|
||||||
while (at(SEMICOLON)) advance(); // SEMICOLON
|
while (at(SEMICOLON)) advance(); // SEMICOLON
|
||||||
} else if (at(RBRACE)) {
|
} else if (at(RBRACE)) {
|
||||||
@@ -993,6 +1048,8 @@ public class JetExpressionParsing extends AbstractJetParsing {
|
|||||||
* for
|
* for
|
||||||
* : "for" "(" attributes valOrVar? SimpleName (":" type)? "in" expression ")" expression
|
* : "for" "(" attributes valOrVar? SimpleName (":" type)? "in" expression ")" expression
|
||||||
* ;
|
* ;
|
||||||
|
*
|
||||||
|
* TODO: empty loop body (at the end of the block)?
|
||||||
*/
|
*/
|
||||||
private void parseFor() {
|
private void parseFor() {
|
||||||
assert _at(FOR_KEYWORD);
|
assert _at(FOR_KEYWORD);
|
||||||
@@ -1162,7 +1219,7 @@ public class JetExpressionParsing extends AbstractJetParsing {
|
|||||||
|
|
||||||
advance(); // RETURN_KEYWORD
|
advance(); // RETURN_KEYWORD
|
||||||
|
|
||||||
if (!at(EOL_OR_SEMICOLON)) parseExpression();
|
if (atSet(EXPRESSION_FIRST) && !at(EOL_OR_SEMICOLON)) parseExpression();
|
||||||
|
|
||||||
returnExpression.done(RETURN);
|
returnExpression.done(RETURN);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,9 @@
|
|||||||
|
val f = if (true) return else {
|
||||||
|
dfsd
|
||||||
|
);;;);;;~;;;
|
||||||
|
srgsdfg
|
||||||
|
|
||||||
|
~
|
||||||
|
|
||||||
|
]
|
||||||
|
}
|
||||||
@@ -0,0 +1,58 @@
|
|||||||
|
JetFile: Expressions_ERR.jet
|
||||||
|
NAMESPACE
|
||||||
|
PROPERTY
|
||||||
|
PsiElement(val)('val')
|
||||||
|
PsiWhiteSpace(' ')
|
||||||
|
PsiElement(IDENTIFIER)('f')
|
||||||
|
PsiWhiteSpace(' ')
|
||||||
|
PsiElement(EQ)('=')
|
||||||
|
PsiWhiteSpace(' ')
|
||||||
|
IF
|
||||||
|
PsiElement(if)('if')
|
||||||
|
PsiWhiteSpace(' ')
|
||||||
|
PsiElement(LPAR)('(')
|
||||||
|
CONDITION
|
||||||
|
BOOLEAN_CONSTANT
|
||||||
|
PsiElement(true)('true')
|
||||||
|
PsiElement(RPAR)(')')
|
||||||
|
PsiWhiteSpace(' ')
|
||||||
|
THEN
|
||||||
|
RETURN
|
||||||
|
PsiElement(return)('return')
|
||||||
|
PsiWhiteSpace(' ')
|
||||||
|
PsiElement(else)('else')
|
||||||
|
PsiWhiteSpace(' ')
|
||||||
|
ELSE
|
||||||
|
FUNCTION_LITERAL
|
||||||
|
PsiElement(LBRACE)('{')
|
||||||
|
PsiWhiteSpace('\n ')
|
||||||
|
BODY
|
||||||
|
REFERENCE_EXPRESSION
|
||||||
|
PsiElement(IDENTIFIER)('dfsd')
|
||||||
|
PsiWhiteSpace('\n ')
|
||||||
|
PsiErrorElement:Expecting an expression
|
||||||
|
PsiElement(RPAR)(')')
|
||||||
|
PsiElement(SEMICOLON)(';')
|
||||||
|
PsiElement(SEMICOLON)(';')
|
||||||
|
PsiElement(SEMICOLON)(';')
|
||||||
|
PsiErrorElement:Expecting an expression
|
||||||
|
PsiElement(RPAR)(')')
|
||||||
|
PsiElement(SEMICOLON)(';')
|
||||||
|
PsiElement(SEMICOLON)(';')
|
||||||
|
PsiElement(SEMICOLON)(';')
|
||||||
|
PsiErrorElement:Expecting an expression
|
||||||
|
PsiElement(BAD_CHARACTER)('~')
|
||||||
|
PsiElement(SEMICOLON)(';')
|
||||||
|
PsiElement(SEMICOLON)(';')
|
||||||
|
PsiElement(SEMICOLON)(';')
|
||||||
|
PsiWhiteSpace('\n ')
|
||||||
|
REFERENCE_EXPRESSION
|
||||||
|
PsiElement(IDENTIFIER)('srgsdfg')
|
||||||
|
PsiWhiteSpace('\n\n ')
|
||||||
|
PsiErrorElement:Expecting an expression
|
||||||
|
PsiElement(BAD_CHARACTER)('~')
|
||||||
|
PsiWhiteSpace('\n\n ')
|
||||||
|
PsiErrorElement:Expecting an expression
|
||||||
|
PsiElement(RBRACKET)(']')
|
||||||
|
PsiWhiteSpace('\n')
|
||||||
|
PsiElement(RBRACE)('}')
|
||||||
@@ -152,9 +152,10 @@ JetFile: When_ERR.jet
|
|||||||
<empty list>
|
<empty list>
|
||||||
PsiWhiteSpace(' ')
|
PsiWhiteSpace(' ')
|
||||||
PsiElement(DOUBLE_ARROW)('=>')
|
PsiElement(DOUBLE_ARROW)('=>')
|
||||||
PsiWhiteSpace(' ')
|
|
||||||
PsiErrorElement:Expecting an expression
|
PsiErrorElement:Expecting an expression
|
||||||
PsiElement(SEMICOLON)(';')
|
<empty list>
|
||||||
|
PsiWhiteSpace(' ')
|
||||||
|
PsiElement(SEMICOLON)(';')
|
||||||
PsiWhiteSpace('\n ')
|
PsiWhiteSpace('\n ')
|
||||||
WHEN_ENTRY
|
WHEN_ENTRY
|
||||||
WHEN_CONDITION
|
WHEN_CONDITION
|
||||||
|
|||||||
Reference in New Issue
Block a user