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)) { |