Recovery fixed for properties and decomposers

This commit is contained in:
Andrey Breslav
2010-12-20 12:45:18 +03:00
parent 32d5da5dc8
commit 346c0fd980
6 changed files with 128 additions and 13 deletions
@@ -107,7 +107,8 @@ import static org.jetbrains.jet.lexer.JetTokens.*;
} }
protected void skipUntil(TokenSet tokenSet) { protected void skipUntil(TokenSet tokenSet) {
while (!eof() && !tokenSet.contains(tt())) { boolean stopAtEolOrSemi = tokenSet.contains(EOL_OR_SEMICOLON);
while (!eof() && !tokenSet.contains(tt()) && !(stopAtEolOrSemi && at(EOL_OR_SEMICOLON))) {
advance(); advance();
} }
} }
@@ -484,18 +484,19 @@ public class JetParsing extends AbstractJetParsing {
parseAttributeList(); parseAttributeList();
TokenSet propertyNameFollow = TokenSet.create(COLON, EQ, LBRACE, EOL_OR_SEMICOLON); TokenSet propertyNameFollow = TokenSet.create(COLON, EQ, LBRACE, EOL_OR_SEMICOLON);
if (at(IDENTIFIER) && propertyNameFollow.contains(lookahead(1))) { if (at(IDENTIFIER) && propertyNameFollow.contains(lookahead(1))) { // There's no explicit receiver specified
// val [a] name = foo // val [a] name = foo
receiverTypeAttributes.done(RECEIVER_TYPE_ATTRIBUTES); receiverTypeAttributes.done(RECEIVER_TYPE_ATTRIBUTES);
advance(); // IDENTIFIER advance(); // IDENTIFIER
} }
else { else { // There must be an explicit receiver
receiverTypeAttributes.rollbackTo(); receiverTypeAttributes.rollbackTo(); // Attributes are a part of the receiver type
if (!TYPE_REF_FIRST.contains(tt())) { if (!TYPE_REF_FIRST.contains(tt())) {
errorAndAdvance("Expecting receiver type or property name"); errorUntil("Expecting receiver type or property name", propertyNameFollow);
} }
else { else {
// TODO: if this type is annotated with an attribute, and it is a single identifier, it is a error (fun [a] foo()) // TODO: if this type is annotated with an attribute, and it is a single identifier,
// TODO: it is NOT an error (fun [a] foo()) -- annotation on receiver
parseTypeRef(); parseTypeRef();
// The property name may appear as the last section of the type // The property name may appear as the last section of the type
if (at(DOT)) { if (at(DOT)) {
@@ -520,7 +521,12 @@ public class JetParsing extends AbstractJetParsing {
// TODO: review // TODO: review
// TODO: $field = foo or something like this // TODO: $field = foo or something like this
parsePropertyGetterOrSetter(); if (at(RBRACE)) {
error("Expecting a getter and/or setter");
}
else {
parsePropertyGetterOrSetter();
}
if (!at(RBRACE)) parsePropertyGetterOrSetter(); if (!at(RBRACE)) parsePropertyGetterOrSetter();
if (!at(RBRACE)) { if (!at(RBRACE)) {
@@ -591,7 +597,7 @@ public class JetParsing extends AbstractJetParsing {
myExpressionParsing.parseExpression(); myExpressionParsing.parseExpression();
} }
else { else {
error("Expecting function body"); errorAndAdvance("Expecting function body");
} }
} }
@@ -812,6 +818,7 @@ public class JetParsing extends AbstractJetParsing {
parseAttributeList(); parseAttributeList();
TokenSet simpleTypeFirst = TokenSet.create(IDENTIFIER, LBRACE, LPAR);
while (true) { while (true) {
if (at(IDENTIFIER)) { if (at(IDENTIFIER)) {
parseSimpleUserType(); parseSimpleUserType();
@@ -826,7 +833,12 @@ public class JetParsing extends AbstractJetParsing {
} }
if (!at(DOT)) break; if (!at(DOT)) break;
advance(); // DOT if (simpleTypeFirst.contains(lookahead(1))) {
advance(); // DOT
} else {
break;
// TODO: ERROR here?
}
} }
type.done(TYPE_REFERENCE); type.done(TYPE_REFERENCE);
} }
+3
View File
@@ -8,3 +8,6 @@ decomposer foobar([a])
decomposer (a, a). decomposer (a, a).
decomposer (). decomposer ().
decomposer foo<T>.{() : ()}.bar(a, a). decomposer foo<T>.{() : ()}.bar(a, a).
decomposer foo.bar.-()
+17 -1
View File
@@ -174,4 +174,20 @@ JetFile: Decomposers_ERR.jet
PsiElement(IDENTIFIER)('a') PsiElement(IDENTIFIER)('a')
PsiElement(RPAR)(')') PsiElement(RPAR)(')')
PsiErrorElement:Expecting namespace or top level declaration PsiErrorElement:Expecting namespace or top level declaration
PsiElement(DOT)('.') PsiElement(DOT)('.')
PsiWhiteSpace('\n\n\n')
DECOMPOSER
PsiElement(decomposer)('decomposer')
PsiWhiteSpace(' ')
TYPE_REFERENCE
USER_TYPE
PsiElement(IDENTIFIER)('foo')
PsiElement(DOT)('.')
USER_TYPE
PsiElement(IDENTIFIER)('bar')
PsiElement(DOT)('.')
PsiErrorElement:Expecting decomposer name
PsiElement(MINUS)('-')
DECOMPOSER_PROPERTY_LIST
PsiElement(LPAR)('(')
PsiElement(RPAR)(')')
+8
View File
@@ -1,3 +1,6 @@
var - f = s
var - f {}
var - f :
val foo : val foo :
val [a foo = foo val [a foo = foo
val foo.bar. val foo.bar.
@@ -15,3 +18,8 @@ val foo.bar.{() : ()}.foo = foo {
set() {} set() {}
set() {} set() {}
} }
val f.d.- = f
val foo {
get() -
}
+78 -3
View File
@@ -1,5 +1,43 @@
JetFile: Properties_ERR.jet JetFile: Properties_ERR.jet
NAMESPACE NAMESPACE
PROPERTY
PsiElement(var)('var')
PsiWhiteSpace(' ')
PsiErrorElement:Expecting receiver type or property name
PsiElement(MINUS)('-')
PsiWhiteSpace(' ')
PsiElement(IDENTIFIER)('f')
PsiWhiteSpace(' ')
PsiElement(EQ)('=')
PsiWhiteSpace(' ')
PsiElement(IDENTIFIER)('s')
PsiWhiteSpace('\n')
PROPERTY
PsiElement(var)('var')
PsiWhiteSpace(' ')
PsiErrorElement:Expecting receiver type or property name
PsiElement(MINUS)('-')
PsiWhiteSpace(' ')
PsiElement(IDENTIFIER)('f')
PsiWhiteSpace(' ')
PsiElement(LBRACE)('{')
PsiErrorElement:Expecting a getter and/or setter
<empty list>
PsiElement(RBRACE)('}')
PsiWhiteSpace('\n')
PROPERTY
PsiElement(var)('var')
PsiWhiteSpace(' ')
PsiErrorElement:Expecting receiver type or property name
PsiElement(MINUS)('-')
PsiWhiteSpace(' ')
PsiElement(IDENTIFIER)('f')
PsiWhiteSpace(' ')
PsiElement(COLON)(':')
PsiWhiteSpace('\n')
TYPE_REFERENCE
PsiErrorElement:Type expected
<empty list>
PROPERTY PROPERTY
PsiElement(val)('val') PsiElement(val)('val')
PsiWhiteSpace(' ') PsiWhiteSpace(' ')
@@ -40,9 +78,9 @@ JetFile: Properties_ERR.jet
PsiElement(DOT)('.') PsiElement(DOT)('.')
USER_TYPE USER_TYPE
PsiElement(IDENTIFIER)('bar') PsiElement(IDENTIFIER)('bar')
PsiElement(DOT)('.') PsiElement(DOT)('.')
PsiErrorElement:Type expected PsiErrorElement:Expecting property name
<empty list> <empty list>
PsiWhiteSpace('\n') PsiWhiteSpace('\n')
PROPERTY PROPERTY
PsiElement(val)('val') PsiElement(val)('val')
@@ -222,4 +260,41 @@ JetFile: Properties_ERR.jet
PsiElement(RBRACE)('}') PsiElement(RBRACE)('}')
PsiWhiteSpace('\n') PsiWhiteSpace('\n')
PsiErrorElement:Expecting namespace or top level declaration PsiErrorElement:Expecting namespace or top level declaration
PsiElement(RBRACE)('}')
PsiWhiteSpace('\n')
PROPERTY
PsiElement(val)('val')
PsiWhiteSpace(' ')
TYPE_REFERENCE
USER_TYPE
PsiElement(IDENTIFIER)('f')
PsiElement(DOT)('.')
USER_TYPE
PsiElement(IDENTIFIER)('d')
PsiElement(DOT)('.')
PsiErrorElement:Expecting property name
PsiElement(MINUS)('-')
PsiWhiteSpace(' ')
PsiElement(EQ)('=')
PsiWhiteSpace(' ')
PsiElement(IDENTIFIER)('f')
PsiWhiteSpace('\n\n')
PROPERTY
PsiElement(val)('val')
PsiWhiteSpace(' ')
RECEIVER_TYPE_ATTRIBUTES
<empty list>
PsiElement(IDENTIFIER)('foo')
PsiWhiteSpace(' ')
PsiElement(LBRACE)('{')
PsiWhiteSpace('\n ')
PROPERTY_GETTER
PsiElement(get)('get')
VALUE_PARAMETER_LIST
PsiElement(LPAR)('(')
PsiElement(RPAR)(')')
PsiWhiteSpace(' ')
PsiErrorElement:Expecting function body
PsiElement(MINUS)('-')
PsiWhiteSpace('\n')
PsiElement(RBRACE)('}') PsiElement(RBRACE)('}')