Chromium Code Reviews| Index: lib/compiler/implementation/scanner/parser.dart |
| diff --git a/lib/compiler/implementation/scanner/parser.dart b/lib/compiler/implementation/scanner/parser.dart |
| index d8831568f4ff97186162762bdcac013b3007c3e1..795b14043786076d908e152f508491262ec49f97 100644 |
| --- a/lib/compiler/implementation/scanner/parser.dart |
| +++ b/lib/compiler/implementation/scanner/parser.dart |
| @@ -841,11 +841,16 @@ class Parser { |
| return (value === 'get') || (value === 'set'); |
| } |
| + bool isFactoryDeclaration(Token token) { |
| + if (optional('external', token)) token = token.next; |
| + if (optional('const', token)) token = token.next; |
| + return optional('factory', token); |
| + } |
| + |
| Token parseMember(Token token) { |
| token = parseMetadataStar(token); |
| String value = token.stringValue; |
| - if (value === 'factory' || |
| - (value === 'external' && optional('factory', token.next))) { |
| + if (isFactoryDeclaration(token)) { |
| return parseFactoryMethod(token); |
| } |
| Token start = token; |
| @@ -945,10 +950,14 @@ class Parser { |
| } |
| Token parseFactoryMethod(Token token) { |
| - assert((optional('external', token) && optional('factory', token.next)) || |
| - optional('factory', token)); |
| + assert(isFactoryDeclaration(token)); |
| Token start = token; |
| if (token.stringValue === 'external') token = token.next; |
| + Token constKeyword = null; |
| + if (optional('const', token)) { |
| + constKeyword = token; |
| + token = token.next; |
| + } |
| Token factoryKeyword = token; |
| listener.beginFactoryMethod(factoryKeyword); |
| token = token.next; // Skip 'factory'. |
| @@ -961,7 +970,11 @@ class Parser { |
| token = parseIdentifier(token.next); |
| } |
| token = parseFormalParameters(token); |
| - token = parseFunctionBody(token, false); |
| + if (optional('=', token)) { |
| + token = parseRedirectingFactoryBody(token); |
| + } else { |
| + token = parseFunctionBody(token, false); |
| + } |
| listener.endFactoryMethod(start, period, token); |
| return token.next; |
| } |
| @@ -1036,6 +1049,37 @@ class Parser { |
| return isBlock ? token.next : token; |
| } |
| + Token parseQualifiedList(Token token) { |
| + listener.beginQualifiedList(token); |
| + Token parseQualifiedPart(Token token) { |
|
ahe
2012/10/09 10:51:37
Why is this a nested function?
Lasse Reichstein Nielsen
2012/10/09 11:51:26
because I didn't want to duplicate the code, but i
ahe
2012/10/09 12:16:51
There is no reason to create extra overhead by cre
|
| + Token start = token; |
| + token = parseIdentifier(token); |
| + token = parseTypeVariablesOpt(token); |
| + listener.endType(start, null); |
| + return token; |
| + } |
| + Token beginToken = token; |
| + token = parseQualifiedPart(token); |
| + int count = 1; |
| + while (optional('.', token)) { |
| + token = parseQualifiedPart(token.next); |
| + count++; |
| + } |
| + listener.endQualifiedList(count); |
| + return token; |
| + } |
| + |
| + Token parseRedirectingFactoryBody(Token token) { |
| + assert(optional('=', token)); |
| + Token equals = token; |
| + listener.beginRedirectingFactoryBody(token); |
|
ahe
2012/10/09 10:51:37
Move this before the assert.
Lasse Reichstein Nielsen
2012/10/09 11:51:26
Done.
|
| + token = parseQualifiedList(token.next); |
| + Token semicolon = token; |
| + expectSemicolon(token); |
| + listener.endRedirectingFactoryBody(equals, semicolon); |
| + return token; |
| + } |
| + |
| Token parseFunctionBody(Token token, bool isExpression) { |
| if (optional(';', token)) { |
| listener.endFunctionBody(0, null, token); |