提交 6f241b7f 编写于 作者: A Andrey Breslav

Parsing property declarations by looking ahead

上级 6361d0eb
......@@ -94,6 +94,28 @@ import static org.jetbrains.jet.lexer.JetTokens.*;
return false;
}
protected boolean atSet(final TokenSet set) {
IElementType token = tt();
if (set.contains(token)) return true;
if (set.contains(EOL_OR_SEMICOLON)) {
if (eof()) return true;
if (token == SEMICOLON) return true;
if (myBuilder.eolInLastWhitespace()) return true;
}
if (token == IDENTIFIER) {
for (IElementType type : set.getTypes()) {
if (type instanceof JetKeywordToken) {
JetKeywordToken expectedKeyword = (JetKeywordToken) type;
if (expectedKeyword.isSoft() && expectedKeyword.getValue().equals(myBuilder.getTokenText())) {
myBuilder.remapCurrentToken(type);
return true;
}
}
}
}
return false;
}
protected IElementType lookahead(int k) {
PsiBuilder.Marker tmp = mark();
for (int i = 0; i < k; i++) advance();
......
......@@ -188,7 +188,7 @@ public class JetParsing extends AbstractJetParsing {
declType = parseProperty();
}
else if (keywordToken == TYPE_KEYWORD) {
declType = parseTypedef();
declType = parseTypeDef();
}
else if (keywordToken == DECOMPOSER_KEYWORD) {
declType = parseDecomposer();
......@@ -450,7 +450,7 @@ public class JetParsing extends AbstractJetParsing {
* : modifiers "type" SimpleName typeParameters? "=" type
* ;
*/
private JetNodeType parseTypedef() {
private JetNodeType parseTypeDef() {
assert at(TYPE_KEYWORD);
advance(); // TYPE_KEYWORD
......@@ -479,32 +479,50 @@ public class JetParsing extends AbstractJetParsing {
advance(); // VAL_KEYWORD or VAR_KEYWORD
PsiBuilder.Marker receiverTypeAttributes = mark();
parseAttributeList();
TokenSet propertyNameFollow = TokenSet.create(COLON, EQ, LBRACE, EOL_OR_SEMICOLON);
if (at(IDENTIFIER) && propertyNameFollow.contains(lookahead(1))) { // There's no explicit receiver specified
// val [a] name = foo
receiverTypeAttributes.done(RECEIVER_TYPE_ATTRIBUTES);
advance(); // IDENTIFIER
}
else { // There must be an explicit receiver
receiverTypeAttributes.rollbackTo(); // Attributes are a part of the receiver type
if (!TYPE_REF_FIRST.contains(tt())) {
errorUntil("Expecting receiver type or property name", propertyNameFollow);
}
else {
// 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();
// The property name may appear as the last section of the type
if (at(DOT)) {
advance(); // DOT
expect(IDENTIFIER, "Expecting property name", propertyNameFollow);
}
}
int lastDot = findLastDotBefore(propertyNameFollow);
if (lastDot == -1) {
parseAttributeList();
expect(IDENTIFIER, "Expecting property name or receiver type", propertyNameFollow);
}
else {
// The code below is NOT REENTRANT
myBuilder.setEOFPosition(lastDot);
parseTypeRef();
myBuilder.unSetEOFPosition();
expect(DOT, "Expecting '.' before a property name", propertyNameFollow);
expect(IDENTIFIER, "Expecting property name", propertyNameFollow);
}
// PsiBuilder.Marker receiverTypeAttributes = mark();
// parseAttributeList();
//
// if (at(IDENTIFIER) && propertyNameFollow.contains(lookahead(1))) { // There's no explicit receiver specified
// // val [a] name = foo
// receiverTypeAttributes.done(RECEIVER_TYPE_ATTRIBUTES);
// advance(); // IDENTIFIER
// }
// else { // There must be an explicit receiver
// receiverTypeAttributes.rollbackTo(); // Attributes are a part of the receiver type
// if (!TYPE_REF_FIRST.contains(tt())) {
// errorUntil("Expecting receiver type or property name", propertyNameFollow);
// }
// else {
// // 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();
// // The property name may appear as the last section of the type
// if (at(DOT)) {
// advance(); // DOT
// expect(IDENTIFIER, "Expecting property name", propertyNameFollow);
// }
// }
// }
if (at(COLON)) {
advance(); // COLON
parseTypeRef();
......@@ -584,7 +602,7 @@ public class JetParsing extends AbstractJetParsing {
// TODO: This code is very close to what we have for properties
int lastDot = findLastDotBeforeLPAR();
int lastDot = findLastDotBefore(TokenSet.create(LPAR));
if (lastDot == -1) { // There's no explicit receiver type specified
parseAttributeList();
......@@ -598,7 +616,6 @@ public class JetParsing extends AbstractJetParsing {
TokenSet functionNameFollow = TokenSet.create(LT, LPAR, COLON, EQ);
expect(DOT, "Expecting '.' before a function name", functionNameFollow);
expect(IDENTIFIER, "Expecting function name", functionNameFollow);
}
// PsiBuilder.Marker receiverTypeAttributes = mark();
......@@ -631,6 +648,7 @@ public class JetParsing extends AbstractJetParsing {
parseTypeParameterList(TokenSet.orSet(TokenSet.create(LPAR), valueParametersFollow));
parseValueParameterList(false, valueParametersFollow);
if (at(COLON)) {
......@@ -649,21 +667,26 @@ public class JetParsing extends AbstractJetParsing {
}
/*
* Looks for a the last top-level (not inside any {} [] () <>) '.' occurring before a top-level '('
* Looks for a the last top-level (not inside any {} [] () <>) '.' occurring before a
* top-level occurrence of a token from the <code>stopSet</code>
*/
private int findLastDotBeforeLPAR() {
private int findLastDotBefore(TokenSet stopSet) {
PsiBuilder.Marker currentPosition = mark();
int lastDot = -1;
int openAngleBrackets = 0;
int openBraces = 0;
int openParentheses = 0;
int openBrackets = 0;
IElementType previousToken = null;
while (!eof()) {
if (at(LPAR)) {
if (atSet(stopSet)) {
if (openAngleBrackets == 0
&& openBrackets == 0
&& openBraces == 0
&& openParentheses == 0) break;
&& openParentheses == 0
&& previousToken != DOT) break;
}
if (at(LPAR)) {
openParentheses++;
}
else if (at(LT)) {
......@@ -694,6 +717,7 @@ public class JetParsing extends AbstractJetParsing {
&& openParentheses == 0) {
lastDot = myBuilder.getCurrentOffset();
}
previousToken = tt();
advance(); // skip token
}
currentPosition.rollbackTo();
......
fun foo)
fun [a] f foo()
fun [a] T.foo.()
fun [a] T<T>.{(A<B>) : ()}()
fun [a] T.foo(a : ) : bar
fun [a()] T.foo<T : {(a) : b>(a : foo) : bar
fun [a()] T.foo<>(a : foo) : bar
......@@ -10,3 +8,6 @@ fun [a()] T.foo<, T, , T>(a : foo) : bar
fun [a()] T.foo<T, T>(, a : foo, , a: b) : bar
fun foo() : = a;
fun [a] T<T>.{(A<B>) : ()}.-()
\ No newline at end of file
......@@ -33,84 +33,6 @@ JetFile: Functions_ERR.jet
PsiElement(LPAR)('(')
PsiElement(RPAR)(')')
PsiWhiteSpace('\n')
FUN
PsiElement(fun)('fun')
PsiWhiteSpace(' ')
TYPE_REFERENCE
ATTRIBUTE_ANNOTATION
PsiElement(LBRACKET)('[')
ATTRIBUTE
USER_TYPE
USER_TYPE
PsiElement(IDENTIFIER)('a')
PsiElement(RBRACKET)(']')
PsiWhiteSpace(' ')
USER_TYPE
PsiElement(IDENTIFIER)('T')
PsiElement(DOT)('.')
USER_TYPE
PsiElement(IDENTIFIER)('foo')
PsiElement(DOT)('.')
PsiErrorElement:Expecting function name
<empty list>
TYPE_PARAMETER_LIST
<empty list>
VALUE_PARAMETER_LIST
PsiElement(LPAR)('(')
PsiElement(RPAR)(')')
PsiWhiteSpace('\n')
FUN
PsiElement(fun)('fun')
PsiWhiteSpace(' ')
TYPE_REFERENCE
ATTRIBUTE_ANNOTATION
PsiElement(LBRACKET)('[')
ATTRIBUTE
USER_TYPE
USER_TYPE
PsiElement(IDENTIFIER)('a')
PsiElement(RBRACKET)(']')
PsiWhiteSpace(' ')
USER_TYPE
PsiElement(IDENTIFIER)('T')
TYPE_ARGUMENT_LIST
PsiElement(LT)('<')
TYPE_REFERENCE
USER_TYPE
PsiElement(IDENTIFIER)('T')
PsiElement(GT)('>')
PsiElement(DOT)('.')
PsiErrorElement:Expecting function name
PsiElement(LBRACE)('{')
TYPE_PARAMETER_LIST
<empty list>
VALUE_PARAMETER_LIST
PsiElement(LPAR)('(')
PsiErrorElement:Expecting a parameter declaration
PsiElement(IDENTIFIER)('A')
PsiErrorElement:Expecting ')'
PsiElement(LT)('<')
PsiErrorElement:Expecting function body
PsiElement(IDENTIFIER)('B')
PsiErrorElement:Expecting namespace or top level declaration
PsiElement(GT)('>')
PsiErrorElement:Expecting namespace or top level declaration
PsiElement(RPAR)(')')
PsiWhiteSpace(' ')
PsiErrorElement:Expecting namespace or top level declaration
PsiElement(COLON)(':')
PsiWhiteSpace(' ')
PsiErrorElement:Expecting namespace or top level declaration
PsiElement(LPAR)('(')
PsiErrorElement:Expecting namespace or top level declaration
PsiElement(RPAR)(')')
PsiErrorElement:Expecting namespace or top level declaration
PsiElement(RBRACE)('}')
PsiErrorElement:Expecting namespace or top level declaration
PsiElement(LPAR)('(')
PsiErrorElement:Expecting namespace or top level declaration
PsiElement(RPAR)(')')
PsiWhiteSpace('\n')
FUN
PsiElement(fun)('fun')
PsiWhiteSpace(' ')
......@@ -431,4 +353,56 @@ JetFile: Functions_ERR.jet
PsiElement(EQ)('=')
PsiWhiteSpace(' ')
PsiElement(IDENTIFIER)('a')
PsiElement(SEMICOLON)(';')
\ No newline at end of file
PsiElement(SEMICOLON)(';')
PsiWhiteSpace('\n\n\n')
FUN
PsiElement(fun)('fun')
PsiWhiteSpace(' ')
TYPE_REFERENCE
ATTRIBUTE_ANNOTATION
PsiElement(LBRACKET)('[')
ATTRIBUTE
USER_TYPE
USER_TYPE
PsiElement(IDENTIFIER)('a')
PsiElement(RBRACKET)(']')
PsiWhiteSpace(' ')
USER_TYPE
PsiElement(IDENTIFIER)('T')
TYPE_ARGUMENT_LIST
PsiElement(LT)('<')
TYPE_REFERENCE
USER_TYPE
PsiElement(IDENTIFIER)('T')
PsiElement(GT)('>')
PsiElement(DOT)('.')
FUNCTION_TYPE
PsiElement(LBRACE)('{')
VALUE_PARAMETER_LIST
PsiElement(LPAR)('(')
TYPE_REFERENCE
USER_TYPE
PsiElement(IDENTIFIER)('A')
TYPE_ARGUMENT_LIST
PsiElement(LT)('<')
TYPE_REFERENCE
USER_TYPE
PsiElement(IDENTIFIER)('B')
PsiElement(GT)('>')
PsiElement(RPAR)(')')
PsiWhiteSpace(' ')
PsiElement(COLON)(':')
PsiWhiteSpace(' ')
TYPE_REFERENCE
TUPLE_TYPE
PsiElement(LPAR)('(')
PsiElement(RPAR)(')')
PsiElement(RBRACE)('}')
PsiElement(DOT)('.')
PsiErrorElement:Expecting function name
PsiElement(MINUS)('-')
TYPE_PARAMETER_LIST
<empty list>
VALUE_PARAMETER_LIST
PsiElement(LPAR)('(')
PsiElement(RPAR)(')')
\ No newline at end of file
......@@ -3,24 +3,20 @@ JetFile: Properties.jet
PROPERTY
PsiElement(val)('val')
PsiWhiteSpace(' ')
TYPE_REFERENCE
USER_TYPE
PsiElement(IDENTIFIER)('foo')
PsiElement(IDENTIFIER)('foo')
PsiWhiteSpace('\n ')
PROPERTY
PsiElement(val)('val')
PsiWhiteSpace(' ')
TYPE_REFERENCE
ATTRIBUTE_ANNOTATION
PsiElement(LBRACKET)('[')
ATTRIBUTE
ATTRIBUTE_ANNOTATION
PsiElement(LBRACKET)('[')
ATTRIBUTE
USER_TYPE
USER_TYPE
USER_TYPE
PsiElement(IDENTIFIER)('a')
PsiElement(RBRACKET)(']')
PsiWhiteSpace(' ')
USER_TYPE
PsiElement(IDENTIFIER)('foo')
PsiElement(IDENTIFIER)('a')
PsiElement(RBRACKET)(']')
PsiWhiteSpace(' ')
PsiElement(IDENTIFIER)('foo')
PsiWhiteSpace('\n ')
PROPERTY
PsiElement(val)('val')
......@@ -28,9 +24,8 @@ JetFile: Properties.jet
TYPE_REFERENCE
USER_TYPE
PsiElement(IDENTIFIER)('foo')
PsiElement(DOT)('.')
USER_TYPE
PsiElement(IDENTIFIER)('bar')
PsiElement(DOT)('.')
PsiElement(IDENTIFIER)('bar')
PsiWhiteSpace('\n ')
PROPERTY
PsiElement(val)('val')
......@@ -55,15 +50,12 @@ JetFile: Properties.jet
PsiElement(LPAR)('(')
PsiElement(RPAR)(')')
PsiElement(RBRACE)('}')
PsiElement(DOT)('.')
USER_TYPE
PsiElement(IDENTIFIER)('foo')
PsiElement(DOT)('.')
PsiElement(IDENTIFIER)('foo')
PsiWhiteSpace('\n\n ')
PROPERTY
PsiElement(val)('val')
PsiWhiteSpace(' ')
RECEIVER_TYPE_ATTRIBUTES
<empty list>
PsiElement(IDENTIFIER)('foo')
PsiWhiteSpace(' ')
PsiElement(COLON)(':')
......@@ -75,14 +67,13 @@ JetFile: Properties.jet
PROPERTY
PsiElement(val)('val')
PsiWhiteSpace(' ')
RECEIVER_TYPE_ATTRIBUTES
ATTRIBUTE_ANNOTATION
PsiElement(LBRACKET)('[')
ATTRIBUTE
ATTRIBUTE_ANNOTATION
PsiElement(LBRACKET)('[')
ATTRIBUTE
USER_TYPE
USER_TYPE
USER_TYPE
PsiElement(IDENTIFIER)('a')
PsiElement(RBRACKET)(']')
PsiElement(IDENTIFIER)('a')
PsiElement(RBRACKET)(']')
PsiWhiteSpace(' ')
PsiElement(IDENTIFIER)('foo')
PsiWhiteSpace(' ')
......@@ -96,9 +87,8 @@ JetFile: Properties.jet
TYPE_REFERENCE
USER_TYPE
PsiElement(IDENTIFIER)('foo')
PsiElement(DOT)('.')
USER_TYPE
PsiElement(IDENTIFIER)('bar')
PsiElement(DOT)('.')
PsiElement(IDENTIFIER)('bar')
PsiWhiteSpace(' ')
PsiElement(LBRACE)('{')
PsiWhiteSpace('\n ')
......@@ -146,9 +136,8 @@ JetFile: Properties.jet
PsiElement(LPAR)('(')
PsiElement(RPAR)(')')
PsiElement(RBRACE)('}')
PsiElement(DOT)('.')
USER_TYPE
PsiElement(IDENTIFIER)('foo')
PsiElement(DOT)('.')
PsiElement(IDENTIFIER)('foo')
PsiWhiteSpace(' ')
PsiElement(EQ)('=')
PsiWhiteSpace(' ')
......@@ -199,9 +188,8 @@ JetFile: Properties.jet
PsiElement(LPAR)('(')
PsiElement(RPAR)(')')
PsiElement(RBRACE)('}')
PsiElement(DOT)('.')
USER_TYPE
PsiElement(IDENTIFIER)('foo')
PsiElement(DOT)('.')
PsiElement(IDENTIFIER)('foo')
PsiWhiteSpace(' ')
PsiElement(COLON)(':')
PsiWhiteSpace(' ')
......@@ -280,9 +268,8 @@ JetFile: Properties.jet
PsiElement(LPAR)('(')
PsiElement(RPAR)(')')
PsiElement(RBRACE)('}')
PsiElement(DOT)('.')
USER_TYPE
PsiElement(IDENTIFIER)('foo')
PsiElement(DOT)('.')
PsiElement(IDENTIFIER)('foo')
PsiWhiteSpace(' ')
PsiElement(COLON)(':')
PsiWhiteSpace(' ')
......@@ -341,9 +328,8 @@ JetFile: Properties.jet
PsiElement(LPAR)('(')
PsiElement(RPAR)(')')
PsiElement(RBRACE)('}')
PsiElement(DOT)('.')
USER_TYPE
PsiElement(IDENTIFIER)('foo')
PsiElement(DOT)('.')
PsiElement(IDENTIFIER)('foo')
PsiWhiteSpace(' ')
PsiElement(COLON)(':')
PsiWhiteSpace(' ')
......
var - f = s
var - f {}
var - f :
var - {}
var f {}
var f :
val foo :
val [a foo = foo
val foo.bar.
......
......@@ -3,22 +3,18 @@ JetFile: Properties_ERR.jet
PROPERTY
PsiElement(var)('var')
PsiWhiteSpace(' ')
PsiErrorElement:Expecting receiver type or property name
PsiErrorElement:Expecting property name or receiver type
PsiElement(MINUS)('-')
PsiWhiteSpace(' ')
PsiElement(IDENTIFIER)('f')
PsiWhiteSpace(' ')
PsiElement(EQ)('=')
PsiWhiteSpace(' ')
PsiElement(IDENTIFIER)('s')
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')
PsiElement(IDENTIFIER)('f')
PsiWhiteSpace(' ')
PsiElement(LBRACE)('{')
PsiErrorElement:Expecting a getter and/or setter
......@@ -28,10 +24,7 @@ JetFile: Properties_ERR.jet
PROPERTY
PsiElement(var)('var')
PsiWhiteSpace(' ')
PsiErrorElement:Expecting receiver type or property name
PsiElement(MINUS)('-')
PsiWhiteSpace(' ')
PsiElement(IDENTIFIER)('f')
PsiElement(IDENTIFIER)('f')
PsiWhiteSpace(' ')
PsiElement(COLON)(':')
PsiWhiteSpace('\n')
......@@ -41,8 +34,6 @@ JetFile: Properties_ERR.jet
PROPERTY
PsiElement(val)('val')
PsiWhiteSpace(' ')
RECEIVER_TYPE_ATTRIBUTES
<empty list>
PsiElement(IDENTIFIER)('foo')
PsiWhiteSpace(' ')
PsiElement(COLON)(':')
......@@ -53,15 +44,14 @@ JetFile: Properties_ERR.jet
PROPERTY
PsiElement(val)('val')
PsiWhiteSpace(' ')
RECEIVER_TYPE_ATTRIBUTES
ATTRIBUTE_ANNOTATION
PsiElement(LBRACKET)('[')
ATTRIBUTE
ATTRIBUTE_ANNOTATION
PsiElement(LBRACKET)('[')
ATTRIBUTE
USER_TYPE
USER_TYPE
USER_TYPE
PsiElement(IDENTIFIER)('a')
PsiErrorElement:Expecting ']' to close an attribute annotation
<empty list>
PsiElement(IDENTIFIER)('a')
PsiErrorElement:Expecting ']' to close an attribute annotation
<empty list>
PsiWhiteSpace(' ')
PsiElement(IDENTIFIER)('foo')
PsiWhiteSpace(' ')
......@@ -85,14 +75,13 @@ JetFile: Properties_ERR.jet
PROPERTY
PsiElement(val)('val')
PsiWhiteSpace(' ')
RECEIVER_TYPE_ATTRIBUTES
ATTRIBUTE_ANNOTATION
PsiElement(LBRACKET)('[')
ATTRIBUTE
ATTRIBUTE_ANNOTATION
PsiElement(LBRACKET)('[')
ATTRIBUTE
USER_TYPE
USER_TYPE
USER_TYPE
PsiElement(IDENTIFIER)('a')
PsiElement(RBRACKET)(']')
PsiElement(IDENTIFIER)('a')
PsiElement(RBRACKET)(']')
PsiWhiteSpace(' ')
PsiElement(IDENTIFIER)('foo')
PsiWhiteSpace(' ')
......@@ -111,9 +100,8 @@ JetFile: Properties_ERR.jet
TYPE_REFERENCE
USER_TYPE
PsiElement(IDENTIFIER)('foo')
PsiElement(DOT)('.')
USER_TYPE
PsiElement(IDENTIFIER)('bar')
PsiElement(DOT)('.')
PsiElement(IDENTIFIER)('bar')
PsiWhiteSpace(' ')
PsiElement(LBRACE)('{')
PsiWhiteSpace('\n ')
......@@ -166,9 +154,8 @@ JetFile: Properties_ERR.jet
PsiElement(LPAR)('(')
PsiElement(RPAR)(')')
PsiElement(RBRACE)('}')
PsiElement(DOT)('.')
USER_TYPE
PsiElement(IDENTIFIER)('foo')
PsiElement(DOT)('.')
PsiElement(IDENTIFIER)('foo')
PsiWhiteSpace(' ')
PsiElement(EQ)('=')
PsiWhiteSpace(' ')
......@@ -221,9 +208,8 @@ JetFile: Properties_ERR.jet
PsiElement(LPAR)('(')
PsiElement(RPAR)(')')
PsiElement(RBRACE)('}')
PsiElement(DOT)('.')
USER_TYPE
PsiElement(IDENTIFIER)('foo')
PsiElement(DOT)('.')
PsiElement(IDENTIFIER)('foo')
PsiWhiteSpace(' ')
PsiElement(EQ)('=')
PsiWhiteSpace(' ')
......@@ -282,8 +268,6 @@ JetFile: Properties_ERR.jet
PROPERTY
PsiElement(val)('val')
PsiWhiteSpace(' ')
RECEIVER_TYPE_ATTRIBUTES
<empty list>
PsiElement(IDENTIFIER)('foo')
PsiWhiteSpace(' ')
PsiElement(LBRACE)('{')
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册