Convert more IdentiferContext consts

* Update local function identifier context
* Update IdentifierContext.operatorName
* Simplify top level declaration identifier context

Change-Id: Ie977769dde3374f109283b9af49be18dd71144bf
Reviewed-on: https://dart-review.googlesource.com/55803
Reviewed-by: Brian Wilkerson <brianwilkerson@google.com>
Commit-Queue: Dan Rubel <danrubel@google.com>
diff --git a/pkg/front_end/lib/src/fasta/parser/identifier_context.dart b/pkg/front_end/lib/src/fasta/parser/identifier_context.dart
index 72cf7d5..962bded 100644
--- a/pkg/front_end/lib/src/fasta/parser/identifier_context.dart
+++ b/pkg/front_end/lib/src/fasta/parser/identifier_context.dart
@@ -119,14 +119,16 @@
 
   /// Identifier is a name being declared by a top level variable declaration.
   static const topLevelVariableDeclaration =
-      const TopLevelVariableIdentifierContext();
+      const TopLevelDeclarationIdentifierContext(
+          'topLevelVariableDeclaration', const [';', '=', ',']);
 
   /// Identifier is a name being declared by a field declaration.
   static const fieldDeclaration = const FieldDeclarationIdentifierContext();
 
   /// Identifier is the name being declared by a top level function declaration.
   static const topLevelFunctionDeclaration =
-      const TopLevelFunctionDeclarationIdentifierContext();
+      const TopLevelDeclarationIdentifierContext(
+          'topLevelFunctionDeclaration', const ['<', '(', '{', '=>']);
 
   /// Identifier is the start of the name being declared by a method
   /// declaration.
@@ -146,7 +148,8 @@
   /// TODO(paulberry,ahe): Does this ever occur in valid Dart, or does it only
   /// occur as part of error recovery?  If it's only as part of error recovery,
   /// perhaps we should just re-use methodDeclaration.
-  static const operatorName = const IdentifierContext('operatorName');
+  static const operatorName =
+      const MethodDeclarationIdentifierContext.continuation();
 
   /// Identifier is the name being declared by a local function declaration that
   /// uses a "get" or "set" keyword.
@@ -160,17 +163,15 @@
   /// Identifier is the start of the name being declared by a local function
   /// declaration.
   static const localFunctionDeclaration =
-      const IdentifierContext('localFunctionDeclaration', inDeclaration: true);
+      const LocalFunctionDeclarationIdentifierContext();
 
   /// Identifier is part of the name being declared by a local function
   /// declaration, but it's not the first identifier of the name.
   ///
   /// TODO(paulberry,ahe): Does this ever occur in valid Dart, or does it only
   /// occur as part of error recovery?
-  static const localFunctionDeclarationContinuation = const IdentifierContext(
-      'localFunctionDeclarationContinuation',
-      inDeclaration: true,
-      isContinuation: true);
+  static const localFunctionDeclarationContinuation =
+      const LocalFunctionDeclarationIdentifierContext.continuation();
 
   /// Identifier is the name appearing in a function expression.
   ///
diff --git a/pkg/front_end/lib/src/fasta/parser/identifier_context_impl.dart b/pkg/front_end/lib/src/fasta/parser/identifier_context_impl.dart
index 938d52b..01d59f3 100644
--- a/pkg/front_end/lib/src/fasta/parser/identifier_context_impl.dart
+++ b/pkg/front_end/lib/src/fasta/parser/identifier_context_impl.dart
@@ -298,6 +298,43 @@
   }
 }
 
+/// See [IdentifierContext.localFunctionDeclaration]
+/// and [IdentifierContext.localFunctionDeclarationContinuation].
+class LocalFunctionDeclarationIdentifierContext extends IdentifierContext {
+  const LocalFunctionDeclarationIdentifierContext()
+      : super('localFunctionDeclaration', inDeclaration: true);
+
+  const LocalFunctionDeclarationIdentifierContext.continuation()
+      : super('localFunctionDeclarationContinuation',
+            inDeclaration: true, isContinuation: true);
+
+  @override
+  Token ensureIdentifier(Token token, Parser parser) {
+    Token identifier = token.next;
+    assert(identifier.kind != IDENTIFIER_TOKEN);
+    if (identifier.isIdentifier) {
+      checkAsyncAwaitYieldAsIdentifier(identifier, parser);
+      return identifier;
+    }
+
+    // Recovery
+    if (isOneOfOrEof(identifier, const ['.', '(', '{', '=>']) ||
+        looksLikeStartOfNextStatement(identifier)) {
+      identifier = parser.insertSyntheticIdentifier(token, this,
+          message: fasta.templateExpectedIdentifier.withArguments(identifier));
+    } else {
+      parser.reportRecoverableErrorWithToken(
+          identifier, fasta.templateExpectedIdentifier);
+      if (!identifier.isKeywordOrIdentifier) {
+        // When in doubt, consume the token to ensure we make progress
+        // but insert a synthetic identifier to satisfy listeners.
+        identifier = insertSyntheticIdentifierAfter(identifier, parser);
+      }
+    }
+    return identifier;
+  }
+}
+
 /// See [IdentifierContext.libraryName].
 class LibraryIdentifierContext extends IdentifierContext {
   const LibraryIdentifierContext()
@@ -374,7 +411,9 @@
   }
 }
 
-/// See [IdentifierContext.methodDeclaration].
+/// See [IdentifierContext.methodDeclaration],
+/// and [IdentifierContext.methodDeclarationContinuation],
+/// and [IdentifierContext.operatorName].
 class MethodDeclarationIdentifierContext extends IdentifierContext {
   const MethodDeclarationIdentifierContext()
       : super('methodDeclaration', inDeclaration: true);
@@ -383,6 +422,9 @@
       : super('methodDeclarationContinuation',
             inDeclaration: true, isContinuation: true);
 
+  const MethodDeclarationIdentifierContext.operatorName()
+      : super('operatorName', inDeclaration: true);
+
   @override
   Token ensureIdentifier(Token token, Parser parser) {
     Token identifier = token.next;
@@ -413,10 +455,12 @@
   }
 }
 
-class TopLevelIdentifierContext extends IdentifierContext {
+/// See [IdentifierContext.topLevelFunctionDeclaration]
+/// and [IdentifierContext.topLevelVariableDeclaration].
+class TopLevelDeclarationIdentifierContext extends IdentifierContext {
   final List<String> followingValues;
 
-  const TopLevelIdentifierContext(String name, this.followingValues)
+  const TopLevelDeclarationIdentifierContext(String name, this.followingValues)
       : super(name, inDeclaration: true);
 
   @override
@@ -456,19 +500,6 @@
   }
 }
 
-/// See [IdentifierContext.topLevelFunctionDeclaration].
-class TopLevelFunctionDeclarationIdentifierContext
-    extends TopLevelIdentifierContext {
-  const TopLevelFunctionDeclarationIdentifierContext()
-      : super('topLevelFunctionDeclaration', const ['<', '(', '{', '=>']);
-}
-
-/// See [IdentifierContext.topLevelVariableDeclaration].
-class TopLevelVariableIdentifierContext extends TopLevelIdentifierContext {
-  const TopLevelVariableIdentifierContext()
-      : super('topLevelVariableDeclaration', const [';', '=', ',']);
-}
-
 /// See [IdentifierContext.typedefDeclaration].
 class TypedefDeclarationIdentifierContext extends IdentifierContext {
   const TypedefDeclarationIdentifierContext()
diff --git a/pkg/front_end/lib/src/fasta/parser/parser.dart b/pkg/front_end/lib/src/fasta/parser/parser.dart
index d8d359f..65efd13 100644
--- a/pkg/front_end/lib/src/fasta/parser/parser.dart
+++ b/pkg/front_end/lib/src/fasta/parser/parser.dart
@@ -2017,9 +2017,6 @@
       followingValues = ['.', ';'];
     } else if (context == IdentifierContext.localAccessorDeclaration) {
       followingValues = ['(', '{', '=>'];
-    } else if (context == IdentifierContext.localFunctionDeclaration ||
-        context == IdentifierContext.localFunctionDeclarationContinuation) {
-      followingValues = ['.', '(', '{', '=>'];
     } else {
       return false;
     }
@@ -2081,8 +2078,6 @@
       initialKeywords = statementKeywords();
     } else if (context == IdentifierContext.localAccessorDeclaration) {
       initialKeywords = statementKeywords();
-    } else if (context == IdentifierContext.localFunctionDeclaration) {
-      initialKeywords = statementKeywords();
     } else if (context ==
         IdentifierContext.localFunctionDeclarationContinuation) {
       initialKeywords = statementKeywords();