Chromium Code Reviews| Index: pkg/front_end/lib/src/fasta/parser/parser.dart |
| diff --git a/pkg/front_end/lib/src/fasta/parser/parser.dart b/pkg/front_end/lib/src/fasta/parser/parser.dart |
| index 02bee28ffd2e7a27d90d854c873a7754b8e2dd98..270320dd9a68f9005ec81b678990a2908138881d 100644 |
| --- a/pkg/front_end/lib/src/fasta/parser/parser.dart |
| +++ b/pkg/front_end/lib/src/fasta/parser/parser.dart |
| @@ -180,6 +180,10 @@ enum Assert { |
| Statement, |
| } |
| +enum TypeContinuation { |
|
Paul Berry
2017/06/24 14:16:26
It would be nice to have a comment explaining what
ahe
2017/06/26 10:14:00
I want to reserve that word for you :-)
|
| + Typedef, |
| +} |
| + |
| /// An event generating parser of Dart programs. This parser expects all tokens |
| /// in a linked list (aka a token stream). |
| /// |
| @@ -615,14 +619,16 @@ class Parser { |
| Token typedefKeyword = token; |
| listener.beginFunctionTypeAlias(token); |
| Token equals; |
| - if (optional('=', peekAfterNominalType(token.next))) { |
| + Token afterType = parseType(token.next, |
| + isOptional: true, continuation: TypeContinuation.Typedef); |
| + if (afterType == null) { |
| token = parseIdentifier(token.next, IdentifierContext.typedefDeclaration); |
| token = parseTypeVariablesOpt(token); |
| equals = token; |
| token = expect('=', token); |
| token = parseType(token); |
| } else { |
| - token = parseType(token.next, isOptional: true); |
| + token = afterType; |
| token = parseIdentifier(token, IdentifierContext.typedefDeclaration); |
| token = parseTypeVariablesOpt(token); |
| token = parseFormalParameters(token, MemberKind.FunctionTypeAlias); |
| @@ -968,40 +974,28 @@ class Parser { |
| } |
| Token parseClassOrNamedMixinApplication(Token token) { |
| + listener.beginClassOrNamedMixinApplication(token); |
| Token begin = token; |
| - Token abstractKeyword; |
| - Token classKeyword = token; |
| if (optional('abstract', token)) { |
| - abstractKeyword = token; |
| - token = token.next; |
| - classKeyword = token; |
| - } |
| - assert(optional('class', classKeyword)); |
| - int modifierCount = 0; |
| - if (abstractKeyword != null) { |
| - parseModifier(abstractKeyword); |
| - modifierCount++; |
| - } |
| - listener.handleModifiers(modifierCount); |
| - bool isMixinApplication = optional('=', peekAfterNominalType(token)); |
| - Token name = token.next; |
| - |
| - if (isMixinApplication) { |
| - token = parseIdentifier(name, IdentifierContext.namedMixinDeclaration); |
| - listener.beginNamedMixinApplication(begin, name); |
| + token = parseModifier(token); |
| + listener.handleModifiers(1); |
| } else { |
| - token = parseIdentifier(name, IdentifierContext.classDeclaration); |
| - listener.beginClassDeclaration(begin, name); |
| + listener.handleModifiers(0); |
| } |
| - |
| + Token classKeyword = token; |
| + token = expect("class", token); |
| + Token name = token; |
| + token = |
| + parseIdentifier(name, IdentifierContext.classOrNamedMixinDeclaration); |
| token = parseTypeVariablesOpt(token); |
| - |
| if (optional('=', token)) { |
| + listener.beginNamedMixinApplication(begin, name); |
| Token equals = token; |
| token = token.next; |
| return parseNamedMixinApplication( |
| token, begin, classKeyword, name, equals); |
| } else { |
| + listener.beginClassDeclaration(begin, name); |
| return parseClass(token, begin, classKeyword, name); |
| } |
| } |
| @@ -1139,7 +1133,20 @@ class Parser { |
| (optional('<', token.next) || optional('(', token.next)); |
| } |
| - Token parseType(Token token, {bool isOptional: false}) { |
| + Token parseType(Token token, |
|
Paul Berry
2017/06/24 14:16:26
It would be nice to have a comment here explaining
ahe
2017/06/26 10:14:01
Done.
|
| + {bool isOptional: false, TypeContinuation continuation}) { |
| + if (continuation != null) { |
|
ahe
2017/06/24 10:10:31
A little bit of context here:
My plan is to move
|
| + switch (continuation) { |
|
Paul Berry
2017/06/24 14:16:26
Nit: It seems odd to have a null check followed by
ahe
2017/06/26 10:14:00
Done.
|
| + case TypeContinuation.Typedef: |
| + if (optional('=', peekAfterNominalType(token))) { |
| + return null; // This isn't a type, it's a new-style typedef. |
| + } |
| + break; |
| + |
| + default: |
| + throw "Internal error: Unhandled continuation '$continuation'."; |
| + } |
| + } |
| if (isOptional) { |
| do { |
| if (optional("void", token)) { |