Update parse mixin to use computeType and add recovery tests

... and address comments in
https://dart-review.googlesource.com/c/sdk/+/55560

Change-Id: Ifc97b0b43d91e6c04a344a862d2de0e11ae001cf
Reviewed-on: https://dart-review.googlesource.com/55800
Commit-Queue: Dan Rubel <danrubel@google.com>
Reviewed-by: Brian Wilkerson <brianwilkerson@google.com>
diff --git a/pkg/analyzer/test/generated/parser_test.dart b/pkg/analyzer/test/generated/parser_test.dart
index 5948064..00ee762 100644
--- a/pkg/analyzer/test/generated/parser_test.dart
+++ b/pkg/analyzer/test/generated/parser_test.dart
@@ -2601,11 +2601,16 @@
   void test_classTypeAlias_abstractAfterEq() {
     // This syntax has been removed from the language in favor of
     // "abstract class A = B with C;" (issue 18098).
-    createParser('class A = abstract B with C;');
+    createParser('class A = abstract B with C;', expectedEndOffset: 21);
     CompilationUnitMember member = parseFullCompilationUnitMember();
     expectNotNullIfNoErrors(member);
     listener.assertErrors(usingFastaParser
-        ? [expectedError(ParserErrorCode.EXPECTED_TYPE_NAME, 10, 8)]
+        ? [
+            expectedError(
+                CompileTimeErrorCode.BUILT_IN_IDENTIFIER_AS_TYPE, 10, 8),
+            expectedError(ParserErrorCode.EXPECTED_TOKEN, 19, 1),
+            expectedError(ParserErrorCode.EXPECTED_TOKEN, 21, 4)
+          ]
         : [
             expectedError(ParserErrorCode.EXPECTED_TOKEN, 0, 0),
             expectedError(ParserErrorCode.EXPECTED_TOKEN, 0, 0)
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 5041adb..a6872a0 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
@@ -130,6 +130,36 @@
               'class A implements B, {}',
               [ParserErrorCode.EXPECTED_TYPE_NAME],
               'class A implements B, _s_ {}'),
+          new TestDescriptor(
+              'equals',
+              'class A =',
+              [
+                ParserErrorCode.EXPECTED_TYPE_NAME,
+                ParserErrorCode.EXPECTED_TOKEN,
+                ParserErrorCode.EXPECTED_TOKEN
+              ],
+              'class A = _s_ with _s_;',
+              failing: ['functionVoid', 'functionNonVoid', 'getter']),
+          new TestDescriptor(
+              'equalsName',
+              'class A = B',
+              [ParserErrorCode.EXPECTED_TOKEN, ParserErrorCode.EXPECTED_TOKEN],
+              'class A = B with _s_;',
+              failing: ['functionVoid', 'functionNonVoid', 'getter']),
+          new TestDescriptor(
+              'equalsNameWith',
+              'class A = B with',
+              [
+                ParserErrorCode.EXPECTED_TYPE_NAME,
+                ParserErrorCode.EXPECTED_TOKEN
+              ],
+              'class A = B with _s_;',
+              failing: ['functionVoid', 'functionNonVoid', 'getter']),
+          new TestDescriptor(
+              'equalsNameName',
+              'class A = B C',
+              [ParserErrorCode.EXPECTED_TOKEN, ParserErrorCode.EXPECTED_TOKEN],
+              'class A = B with C;'),
         ],
         PartialCodeTest.declarationSuffixes);
   }
diff --git a/pkg/front_end/lib/src/fasta/parser/listener.dart b/pkg/front_end/lib/src/fasta/parser/listener.dart
index 1d674ca..e7bcb52 100644
--- a/pkg/front_end/lib/src/fasta/parser/listener.dart
+++ b/pkg/front_end/lib/src/fasta/parser/listener.dart
@@ -1113,10 +1113,18 @@
     logEvent("InvalidOperatorName");
   }
 
+  /// Handle the condition in a control structure:
+  /// - if statement
+  /// - do while loop
+  /// - switch statement
+  /// - while loop
   void handleParenthesizedCondition(Token token) {
     logEvent("ParenthesizedCondition");
   }
 
+  /// Handle a parenthesized expression.
+  /// These may be within the condition expression of a control structure
+  /// but will not be the condition of a control structure.
   void handleParenthesizedExpression(Token token) {
     logEvent("ParenthesizedExpression");
   }
diff --git a/pkg/front_end/lib/src/fasta/parser/parser.dart b/pkg/front_end/lib/src/fasta/parser/parser.dart
index 2e9973d..9e09c20 100644
--- a/pkg/front_end/lib/src/fasta/parser/parser.dart
+++ b/pkg/front_end/lib/src/fasta/parser/parser.dart
@@ -1651,7 +1651,7 @@
     Token abstractToken = beforeAbstractToken?.next;
     Token begin = abstractToken ?? token;
     Token classKeyword = token;
-    expect("class", token);
+    assert(optional('class', token));
     Token name =
         ensureIdentifier(token, IdentifierContext.classOrNamedMixinDeclaration);
     token = parseTypeVariablesOpt(name);
@@ -1668,7 +1668,7 @@
       Token token, Token begin, Token classKeyword) {
     Token equals = token = token.next;
     assert(optional('=', equals));
-    token = parseType(token);
+    token = computeType(token, true).ensureTypeNotVoid(token, this);
     token = parseMixinApplicationRest(token);
     Token implementsKeyword = null;
     if (optional('implements', token.next)) {