Improve class declaration header recovery

This improves recovery when parsing type names in a class declaration header
by replacing calls to parseType with calls to computeType.

Change-Id: Icbb86fd977d4d92b00abf2282baea34a1ff21e1d
Reviewed-on: https://dart-review.googlesource.com/55802
Reviewed-by: Brian Wilkerson <brianwilkerson@google.com>
Commit-Queue: Dan Rubel <danrubel@google.com>
diff --git a/pkg/analyzer/test/src/fasta/recovery/partial_code/class_declaration_test.dart b/pkg/analyzer/test/src/fasta/recovery/partial_code/class_declaration_test.dart
index a6872a0..af6f438 100644
--- a/pkg/analyzer/test/src/fasta/recovery/partial_code/class_declaration_test.dart
+++ b/pkg/analyzer/test/src/fasta/recovery/partial_code/class_declaration_test.dart
@@ -12,17 +12,6 @@
 
 class ClassDeclarationTest extends PartialCodeTest {
   buildAll() {
-    List<String> allExceptEof = <String>[
-      'class',
-      'typedef',
-      'functionVoid',
-      'functionNonVoid',
-      'var',
-      'const',
-      'final',
-      'getter',
-      'setter'
-    ];
     buildTests(
         'class_declaration',
         [
@@ -45,15 +34,14 @@
                 ParserErrorCode.MISSING_CLASS_BODY
               ],
               'class A extends _s_ {}',
-              failing: allExceptEof),
+              failing: ['functionVoid', 'functionNonVoid', 'getter']),
           new TestDescriptor('extendsBody', 'class A extends {}',
               [ParserErrorCode.EXPECTED_TYPE_NAME], 'class A extends _s_ {}'),
           new TestDescriptor(
               'extendsWithNameBody',
               'class A extends with B {}',
               [ParserErrorCode.EXPECTED_TYPE_NAME],
-              'class A extends _s_ with B {}',
-              allFailing: true),
+              'class A extends _s_ with B {}'),
           new TestDescriptor(
               'extendsImplementsNameBody',
               'class A extends implements B {}',
@@ -82,7 +70,7 @@
                 ParserErrorCode.MISSING_CLASS_BODY
               ],
               'class A extends B implements _s_ {}',
-              failing: allExceptEof),
+              failing: ['functionVoid', 'functionNonVoid', 'getter']),
           new TestDescriptor(
               'extendsNameImplementsBody',
               'class A extends B implements {}',
@@ -96,7 +84,7 @@
                 ParserErrorCode.MISSING_CLASS_BODY
               ],
               'class A extends B with C implements _s_ {}',
-              failing: allExceptEof),
+              failing: ['functionVoid', 'functionNonVoid', 'getter']),
           new TestDescriptor(
               'extendsNameWithNameImplementsBody',
               'class A extends B with C implements {}',
@@ -110,7 +98,7 @@
                 ParserErrorCode.MISSING_CLASS_BODY
               ],
               'class A implements _s_ {}',
-              failing: allExceptEof),
+              failing: ['functionVoid', 'functionNonVoid', 'getter']),
           new TestDescriptor(
               'implementsBody',
               'class A implements {}',
@@ -124,7 +112,7 @@
                 ParserErrorCode.MISSING_CLASS_BODY
               ],
               'class A implements B, _s_ {}',
-              failing: allExceptEof),
+              failing: ['functionVoid', 'functionNonVoid', 'getter']),
           new TestDescriptor(
               'implementsNameCommaBody',
               'class A implements B, {}',
diff --git a/pkg/front_end/lib/src/fasta/parser/parser.dart b/pkg/front_end/lib/src/fasta/parser/parser.dart
index 19cd743..d8d359f 100644
--- a/pkg/front_end/lib/src/fasta/parser/parser.dart
+++ b/pkg/front_end/lib/src/fasta/parser/parser.dart
@@ -1756,7 +1756,8 @@
             TokenType.IDENTIFIER, 'Object', next.offset, 0);
         rewriter.insertTokenAfter(token, extendsKeyword);
         rewriter.insertTokenAfter(extendsKeyword, superclassToken);
-        token = parseType(extendsKeyword);
+        token = computeType(extendsKeyword, true)
+            .ensureTypeNotVoid(extendsKeyword, this);
         token = parseMixinApplicationRest(token);
         listener.handleClassExtends(extendsKeyword);
       } else {
@@ -1820,7 +1821,7 @@
     Token next = token.next;
     if (optional('extends', next)) {
       Token extendsKeyword = next;
-      token = parseType(next);
+      token = computeType(next, true).ensureTypeNotVoid(next, this);
       if (optional('with', token.next)) {
         token = parseMixinApplicationRest(token);
       } else {
@@ -1845,7 +1846,8 @@
     if (optional('implements', token.next)) {
       implementsKeyword = token.next;
       do {
-        token = parseType(token.next);
+        token =
+            computeType(token.next, true).ensureTypeNotVoid(token.next, this);
         ++interfacesCount;
       } while (optional(',', token.next));
     }