Chromium Code Reviews| Index: dart/lib/compiler/implementation/scanner/parser.dart |
| diff --git a/dart/lib/compiler/implementation/scanner/parser.dart b/dart/lib/compiler/implementation/scanner/parser.dart |
| index 0e618a50aeaad948e4cc5e0bb315e2067be2f9e8..a5cf90c2fc14ff0dd1f26d93f2c871710c99632d 100644 |
| --- a/dart/lib/compiler/implementation/scanner/parser.dart |
| +++ b/dart/lib/compiler/implementation/scanner/parser.dart |
| @@ -285,7 +285,6 @@ class Parser { |
| Token parseTypeOpt(Token token) { |
| String value = token.stringValue; |
| - if (value === 'var') return parseType(token); |
| if (value !== 'this') { |
| Token peek = peekAfterExpectedType(token); |
| if (isIdentifier(peek) || optional('this', peek)) { |
| @@ -506,16 +505,42 @@ class Parser { |
| Token parseTopLevelMember(Token token) { |
| Token start = token; |
| listener.beginTopLevelMember(token); |
| - token = parseModifiers(token); |
| - Token getOrSet = findGetOrSet(token); |
| - if (token === getOrSet) token = token.next; |
| - Token peek = peekAfterExpectedType(token); |
| - if (isIdentifier(peek)) { |
| - // Skip type. |
| - token = peek; |
| + |
| + Link<Token> identifiers = findMemberName(token); |
| + if (identifiers.isEmpty()) { |
| + return listener.unexpected(start); |
| } |
| - if (token === getOrSet) token = token.next; |
| - token = parseIdentifier(token); |
| + Token name = identifiers.head; |
| + identifiers = identifiers.tail; |
| + if (!identifiers.isEmpty()) { |
| + if (optional('operator', identifiers.head)) { |
|
ngeoffray
2012/09/10 14:24:49
'operator' does not apply to top level methods.
ahe
2012/09/10 19:03:02
Done.
|
| + name = identifiers.head; |
| + identifiers = identifiers.tail; |
| + } |
| + } |
| + Token getOrSet; |
| + if (!identifiers.isEmpty()) { |
| + String value = identifiers.head.stringValue; |
| + if ((value === 'get') || (value === 'set')) { |
| + getOrSet = identifiers.head; |
| + identifiers = identifiers.tail; |
| + } |
| + } |
| + Token type; |
| + if (!identifiers.isEmpty()) { |
| + if (isValidTypeReference(identifiers.head)) { |
| + type = identifiers.head; |
| + identifiers = identifiers.tail; |
| + } |
| + } |
| + parseModifierList(identifiers.reverse()); |
| + if (type === null) { |
| + listener.handleNoType(token); |
| + } else { |
| + parseReturnTypeOpt(type); |
| + } |
| + token = parseIdentifier(name); |
| + |
| bool isField; |
| while (true) { |
| // Loop to allow the listener to rewrite the token stream for |
| @@ -555,6 +580,39 @@ class Parser { |
| return token.next; |
| } |
| + Link<Token> findMemberName(Token token) { |
| + Link<Token> identifiers = const EmptyLink<Token>(); |
| + while (token.kind !== EOF_TOKEN) { |
| + String value = token.stringValue; |
| + if ((value === '(') || (value === '{') || (value === '=>')) { |
| + // A method. |
| + return identifiers; |
| + } else if ((value === '=') || (value === ';') || (value === ',')) { |
| + // A field or abstract getter. |
| + return identifiers; |
| + } |
| + identifiers = identifiers.prepend(token); |
| + if (isValidTypeReference(token)) { |
| + // type ... |
| + if (optional('.', token.next)) { |
| + // type '.' ... |
| + if (isIdentifier(token.next.next)) { |
| + // type '.' identifier |
| + token = token.next.next; |
| + } |
| + } |
| + if (optional('<', token.next)) { |
| + if (token.next is BeginGroupToken) { |
| + BeginGroupToken beginGroup = token.next; |
| + token = beginGroup.endGroup; |
| + } |
| + } |
| + } |
| + token = token.next; |
| + } |
| + return listener.unexpected(token); |
| + } |
| + |
| Token parseVariableInitializerOpt(Token token) { |
| if (optional('=', token)) { |
| Token assignment = token; |
| @@ -637,6 +695,20 @@ class Parser { |
| return token.next; |
| } |
| + void parseModifierList(Link<Token> tokens) { |
| + int count = 0; |
| + for (; !tokens.isEmpty(); tokens = tokens.tail) { |
| + Token token = tokens.head; |
| + if (isModifier(token)) { |
| + parseModifier(token); |
| + } else { |
| + listener.unexpected(token); |
| + } |
| + count++; |
| + } |
| + listener.handleModifiers(count); |
| + } |
| + |
| Token parseModifiers(Token token) { |
| int count = 0; |
| while (token.kind === KEYWORD_TOKEN) { |
| @@ -705,35 +777,6 @@ class Parser { |
| return (value === 'get') || (value === 'set'); |
| } |
| - Token findGetOrSet(Token token) { |
| - if (isGetOrSet(token)) { |
| - if (optional('<', token.next)) { |
| - // For example: get<T> ... |
| - final Token peek = peekAfterExpectedType(token); |
| - if (isGetOrSet(peek) && isIdentifier(peek.next)) { |
| - // For example: get<T> get identifier |
| - return peek; |
| - } |
| - } else { |
| - // For example: get ... |
| - if (isGetOrSet(token.next) && isIdentifier(token.next.next)) { |
| - // For example: get get identifier |
| - return token.next; |
| - } else { |
| - // For example: get identifier |
| - return token; |
| - } |
| - } |
| - } else if (token.stringValue !== 'operator') { |
| - final Token peek = peekAfterExpectedType(token); |
| - if (isGetOrSet(peek) && isIdentifier(peek.next)) { |
| - // type? get identifier |
| - return peek; |
| - } |
| - } |
| - return null; |
| - } |
| - |
| Token parseMember(Token token) { |
| token = parseMetadataStar(token); |
| String value = token.stringValue; |
| @@ -743,19 +786,44 @@ class Parser { |
| } |
| Token start = token; |
| listener.beginMember(token); |
| - token = parseModifiers(token); |
| - Token getOrSet = findGetOrSet(token); |
| - if (token === getOrSet) token = token.next; |
| - Token peek = peekAfterExpectedType(token); |
| - if (isIdentifier(peek) && token.stringValue !== 'operator') { |
| - // Skip type. |
| - token = peek; |
| + |
| + Link<Token> identifiers = findMemberName(token); |
| + if (identifiers.isEmpty()) { |
| + return listener.unexpected(start); |
| } |
| - if (token === getOrSet) token = token.next; |
| - if (optional('operator', token)) { |
| - token = parseOperatorName(token); |
| + Token name = identifiers.head; |
| + identifiers = identifiers.tail; |
| + if (!identifiers.isEmpty()) { |
| + if (optional('operator', identifiers.head)) { |
| + name = identifiers.head; |
| + identifiers = identifiers.tail; |
| + } |
| + } |
| + Token getOrSet; |
| + if (!identifiers.isEmpty()) { |
| + if (isGetOrSet(identifiers.head)) { |
| + getOrSet = identifiers.head; |
| + identifiers = identifiers.tail; |
| + } |
| + } |
| + Token type; |
| + if (!identifiers.isEmpty()) { |
| + if (isValidTypeReference(identifiers.head)) { |
| + type = identifiers.head; |
| + identifiers = identifiers.tail; |
| + } |
| + } |
| + parseModifierList(identifiers.reverse()); |
| + if (type === null) { |
| + listener.handleNoType(token); |
| } else { |
| - token = parseIdentifier(token); |
| + parseReturnTypeOpt(type); |
| + } |
| + |
| + if (optional('operator', name)) { |
| + token = parseOperatorName(name); |
| + } else { |
| + token = parseIdentifier(name); |
| } |
| bool isField; |
| while (true) { |