Revise parser to generate handleLiteralSetOrMap

... and no longer generate handleLiteralSet or handleLiteralMap.
In addition, a new hasSetEntry parameter has been added to the
handleLiteralSetOrMap event generated by the parser to support
existing behavior. Once all listeners have implemented
unified collections and that feature is enabled by default,
the hasSetEntry parameter can be removed.

This is the third of several CLs updating the parser and its listeners
to conform to the unified collection spec:
https://github.com/dart-lang/language/pull/200

Change-Id: Ia305eab1f720658f357ac4102b0b0c8128d16997
Reviewed-on: https://dart-review.googlesource.com/c/93963
Reviewed-by: Brian Wilkerson <brianwilkerson@google.com>
diff --git a/pkg/analyzer/lib/src/fasta/ast_builder.dart b/pkg/analyzer/lib/src/fasta/ast_builder.dart
index c3c23b6..e4c3c61 100644
--- a/pkg/analyzer/lib/src/fasta/ast_builder.dart
+++ b/pkg/analyzer/lib/src/fasta/ast_builder.dart
@@ -1071,7 +1071,14 @@
 
   @override
   void handleLiteralSetOrMap(
-      int count, Token leftBrace, Token constKeyword, Token rightBrace) {
+    int count,
+    Token leftBrace,
+    Token constKeyword,
+    Token rightBrace,
+    // TODO(danrubel): hasSetEntry parameter exists for replicating existing
+    // behavior and will be removed once unified collection has been enabled
+    bool hasSetEntry,
+  ) {
     if (enableControlFlowCollections || enableSpreadCollections) {
       List<CollectionElement> elements = popCollectionElements(count);
 
@@ -1097,21 +1104,12 @@
 
       // Determine if this is a set or map based on type args and content
       final typeArgCount = typeArguments?.arguments?.length;
-      bool isSet = typeArgCount == 1 ? true : typeArgCount == 2 ? false : null;
-      if (isSet == null && elements != null) {
-        for (var elem in elements) {
-          if (elem is MapLiteralEntry) {
-            isSet = false;
-            break;
-          } else if (elem is Expression) {
-            isSet = true;
-            break;
-          }
-        }
-      }
+      bool isSet =
+          typeArgCount == 1 ? true : typeArgCount != null ? false : null;
+      isSet ??= hasSetEntry;
 
       // Build the set or map
-      if (isSet ?? false) {
+      if (isSet) {
         final setEntries = <Expression>[];
         if (elements != null) {
           for (var elem in elements) {
@@ -1154,22 +1152,6 @@
     }
   }
 
-  @override
-  void handleLiteralSet(
-      int count, Token leftBracket, Token constKeyword, Token rightBracket) {
-    // TODO(danrubel): Remove this once the parser stops generating this event
-    // and only generates handleLiteralSetOrMap
-    handleLiteralSetOrMap(count, leftBracket, constKeyword, rightBracket);
-  }
-
-  @override
-  void handleLiteralMap(
-      int count, Token leftBracket, Token constKeyword, Token rightBracket) {
-    // TODO(danrubel): Remove this once the parser stops generating this event
-    // and only generates handleLiteralSetOrMap
-    handleLiteralSetOrMap(count, leftBracket, constKeyword, rightBracket);
-  }
-
   void handleLiteralMapEntry(Token colon, Token endToken) {
     assert(optional(':', colon));
     debugEvent("LiteralMapEntry");
diff --git a/pkg/analyzer/test/generated/parser_fasta_test.dart b/pkg/analyzer/test/generated/parser_fasta_test.dart
index df2e0f7..1f55fa4 100644
--- a/pkg/analyzer/test/generated/parser_fasta_test.dart
+++ b/pkg/analyzer/test/generated/parser_fasta_test.dart
@@ -1061,7 +1061,7 @@
 
   void test_setLiteral_invalid_map_entry() {
     SetLiteral set = parseExpression('<int>{1: 1}', errors: [
-      expectedError(ParserErrorCode.EXPECTED_TOKEN, 7, 1),
+      expectedError(ParserErrorCode.UNEXPECTED_TOKEN, 7, 1),
     ]);
     expect(set.constKeyword, isNull);
     expect(set.typeArguments.arguments, hasLength(1));
diff --git a/pkg/front_end/lib/src/fasta/kernel/body_builder.dart b/pkg/front_end/lib/src/fasta/kernel/body_builder.dart
index 9486fd6..c39e47f 100644
--- a/pkg/front_end/lib/src/fasta/kernel/body_builder.dart
+++ b/pkg/front_end/lib/src/fasta/kernel/body_builder.dart
@@ -2411,17 +2411,6 @@
     push(node);
   }
 
-  @override
-  void handleLiteralSet(
-      int count, Token leftBrace, Token constKeyword, Token rightBrace) {
-    debugEvent("LiteralSet");
-
-    // TODO(danrubel): Remove this once the parser stops generating this event
-    // and only generates handleLiteralSetOrMap
-
-    handleLiteralSetOrMap2(count, leftBrace, constKeyword, rightBrace, false);
-  }
-
   void buildLiteralSet(List<UnresolvedType<KernelTypeBuilder>> typeArguments,
       Token constKeyword, Token leftBrace, List<dynamic> setOrMapEntries) {
     DartType typeArgument;
@@ -2468,19 +2457,13 @@
 
   @override
   void handleLiteralSetOrMap(
-      int count, Token leftBrace, Token constKeyword, Token rightBrace) {
-    handleLiteralSetOrMap2(count, leftBrace, constKeyword, rightBrace, false);
-  }
-
-  void handleLiteralSetOrMap2(
     int count,
     Token leftBrace,
     Token constKeyword,
     Token rightBrace,
-    // TODO(danrubel): revise handleLiteralSetOrMap to have the additional
-    // hasMapEntry parameter for replicating existing behavior. This parameter
-    // will be removed once unified collection has been implemented.
-    bool hasMapEntry,
+    // TODO(danrubel): hasSetEntry parameter exists for replicating existing
+    // behavior and will be removed once unified collection has been enabled
+    bool hasSetEntry,
   ) {
     debugEvent("LiteralSetOrMap");
 
@@ -2512,13 +2495,9 @@
     // defer set/map determination until after type resolution as per the
     // unified collection spec: https://github.com/dart-lang/language/pull/200
     // rather than trying to guess as done below.
-    if (isSet == null &&
-        setOrMapEntries != null &&
-        setOrMapEntries.isNotEmpty) {
-      isSet = !hasMapEntry;
-    }
+    isSet ??= hasSetEntry;
 
-    if (isSet ?? false) {
+    if (isSet) {
       buildLiteralSet(typeArguments, constKeyword, leftBrace, setOrMapEntries);
     } else {
       buildLiteralMap(typeArguments, constKeyword, leftBrace, setOrMapEntries);
@@ -2545,28 +2524,12 @@
     push(forest.literalNull(token));
   }
 
-  @override
-  void handleLiteralMap(
-      int count, Token leftBrace, Token constKeyword, Token rightBrace) {
-    debugEvent("LiteralMap");
-
-    // TODO(danrubel): Remove this once the parser stops generating this event
-    // and only generates handleLiteralSetOrMap
-
-    handleLiteralSetOrMap2(count, leftBrace, constKeyword, rightBrace, true);
-  }
-
   void buildLiteralMap(List<UnresolvedType<KernelTypeBuilder>> typeArguments,
       Token constKeyword, Token leftBrace, List<dynamic> setOrMapEntries) {
     DartType keyType;
     DartType valueType;
     if (typeArguments != null) {
       if (typeArguments.length != 2) {
-        // TODO(danrubel): Remove once parser generates this error message
-        addProblem(
-            fasta.messageMapLiteralTypeArgumentMismatch,
-            offsetForToken(leftBrace),
-            lengthOfSpan(leftBrace, leftBrace.endGroup));
         keyType = const InvalidType();
         valueType = const InvalidType();
       } else {
diff --git a/pkg/front_end/lib/src/fasta/parser/forwarding_listener.dart b/pkg/front_end/lib/src/fasta/parser/forwarding_listener.dart
index 585a7b2..05bff97 100644
--- a/pkg/front_end/lib/src/fasta/parser/forwarding_listener.dart
+++ b/pkg/front_end/lib/src/fasta/parser/forwarding_listener.dart
@@ -703,6 +703,20 @@
   }
 
   @override
+  void handleLiteralSetOrMap(
+    int count,
+    Token leftBrace,
+    Token constKeyword,
+    Token rightBrace,
+    // TODO(danrubel): hasSetEntry parameter exists for replicating existing
+    // behavior and will be removed once unified collection has been enabled
+    bool hasSetEntry,
+  ) {
+    listener?.handleLiteralSetOrMap(
+        count, leftBrace, constKeyword, rightBrace, hasSetEntry);
+  }
+
+  @override
   void endLiteralString(int interpolationCount, Token endToken) {
     listener?.endLiteralString(interpolationCount, endToken);
   }
@@ -1013,12 +1027,6 @@
   }
 
   @override
-  void handleLiteralSetOrMap(
-      int count, Token leftBrace, Token constKeyword, Token rightBrace) {
-    listener?.handleLiteralSetOrMap(count, leftBrace, constKeyword, rightBrace);
-  }
-
-  @override
   void handleExpressionFunctionBody(Token arrowToken, Token endToken) {
     listener?.handleExpressionFunctionBody(arrowToken, endToken);
   }
@@ -1145,23 +1153,11 @@
   }
 
   @override
-  void handleLiteralMap(
-      int count, Token beginToken, Token constKeyword, Token endToken) {
-    listener?.handleLiteralMap(count, beginToken, constKeyword, endToken);
-  }
-
-  @override
   void handleLiteralNull(Token token) {
     listener?.handleLiteralNull(token);
   }
 
   @override
-  void handleLiteralSet(
-      int count, Token beginToken, Token constKeyword, Token token) {
-    listener?.handleLiteralSet(count, beginToken, constKeyword, token);
-  }
-
-  @override
   void handleMixinHeader(Token mixinKeyword) {
     listener?.handleMixinHeader(mixinKeyword);
   }
diff --git a/pkg/front_end/lib/src/fasta/parser/listener.dart b/pkg/front_end/lib/src/fasta/parser/listener.dart
index 86036d3..51809a5 100644
--- a/pkg/front_end/lib/src/fasta/parser/listener.dart
+++ b/pkg/front_end/lib/src/fasta/parser/listener.dart
@@ -1200,18 +1200,15 @@
     logEvent("LiteralList");
   }
 
-  void handleLiteralMap(
-      int count, Token leftBrace, Token constKeyword, Token rightBrace) {
-    logEvent("LiteralMap");
-  }
-
-  void handleLiteralSet(
-      int count, Token beginToken, Token constKeyword, Token token) {
-    logEvent("LiteralSet");
-  }
-
   void handleLiteralSetOrMap(
-      int count, Token leftBrace, Token constKeyword, Token rightBrace) {
+    int count,
+    Token leftBrace,
+    Token constKeyword,
+    Token rightBrace,
+    // TODO(danrubel): hasSetEntry parameter exists for replicating existing
+    // behavior and will be removed once unified collection has been enabled
+    bool hasSetEntry,
+  ) {
     logEvent('LiteralSetOrMap');
   }
 
diff --git a/pkg/front_end/lib/src/fasta/parser/literal_entry_info.dart b/pkg/front_end/lib/src/fasta/parser/literal_entry_info.dart
index 00bf0a1..cb85853 100644
--- a/pkg/front_end/lib/src/fasta/parser/literal_entry_info.dart
+++ b/pkg/front_end/lib/src/fasta/parser/literal_entry_info.dart
@@ -8,6 +8,10 @@
 import 'parser.dart';
 import 'util.dart';
 
+/// [simpleEntry] is the first step for parsing a literal entry
+/// without any control flow or spread collection operator.
+const LiteralEntryInfo simpleEntry = const LiteralEntryInfo(true);
+
 /// [LiteralEntryInfo] represents steps for processing an entry
 /// in a literal list, map, or set. These steps will handle parsing
 /// both control flow and spreadable operators, and indicate
diff --git a/pkg/front_end/lib/src/fasta/parser/literal_entry_info_impl.dart b/pkg/front_end/lib/src/fasta/parser/literal_entry_info_impl.dart
index 87bd6ad..f62ba96 100644
--- a/pkg/front_end/lib/src/fasta/parser/literal_entry_info_impl.dart
+++ b/pkg/front_end/lib/src/fasta/parser/literal_entry_info_impl.dart
@@ -11,10 +11,6 @@
 /// starting with `if` control flow.
 const LiteralEntryInfo ifCondition = const IfCondition();
 
-/// [simpleEntry] is the first step for parsing a literal entry
-/// without any control flow or spread collection operator.
-const LiteralEntryInfo simpleEntry = const LiteralEntryInfo(true);
-
 /// [spreadOperator] is the first step for parsing a literal entry
 /// preceded by a '...' spread operator.
 const LiteralEntryInfo spreadOperator = const SpreadOperator();
diff --git a/pkg/front_end/lib/src/fasta/parser/parser.dart b/pkg/front_end/lib/src/fasta/parser/parser.dart
index e8126e7..2f84e1d 100644
--- a/pkg/front_end/lib/src/fasta/parser/parser.dart
+++ b/pkg/front_end/lib/src/fasta/parser/parser.dart
@@ -69,7 +69,11 @@
 import 'listener.dart' show Listener;
 
 import 'literal_entry_info.dart'
-    show computeLiteralEntry, LiteralEntryInfo, looksLikeLiteralEntry;
+    show
+        LiteralEntryInfo,
+        computeLiteralEntry,
+        looksLikeLiteralEntry,
+        simpleEntry;
 
 import 'loop_state.dart' show LoopState;
 
@@ -4242,51 +4246,56 @@
     assert(optional('{', leftBrace));
     Token next = token.next;
     if (optional('}', next)) {
-      listener.handleLiteralSetOrMap(0, leftBrace, constKeyword, next);
+      listener.handleLiteralSetOrMap(0, leftBrace, constKeyword, next, false);
       return next;
     }
 
     final old = mayParseFunctionExpressions;
     mayParseFunctionExpressions = true;
     int count = 0;
-    bool isMap;
+    // TODO(danrubel): hasSetEntry parameter exists for replicating existing
+    // behavior and will be removed once unified collection has been enabled
+    bool hasSetEntry;
 
-    // Parse entries until we determine it's a map, or set, or no more entries
     while (true) {
       LiteralEntryInfo info = computeLiteralEntry(token);
-      while (info != null) {
-        if (info.hasEntry) {
-          token = parseExpression(token);
-          if (isMap == null) {
-            isMap = optional(':', token.next);
-          }
-          if (isMap) {
-            Token colon = ensureColon(token);
-            token = parseExpression(colon);
-            listener.handleLiteralMapEntry(colon, token.next);
-          }
-        } else {
-          token = info.parse(token, this);
+      if (info == simpleEntry) {
+        // TODO(danrubel): Remove this section and use the while loop below
+        // once hasSetEntry is no longer needed.
+        token = parseExpression(token);
+        var isMapEntry = optional(':', token.next);
+        hasSetEntry ??= !isMapEntry;
+        if (isMapEntry) {
+          Token colon = token.next;
+          token = parseExpression(colon);
+          listener.handleLiteralMapEntry(colon, token.next);
         }
-        info = info.computeNext(token);
+      } else {
+        while (info != null) {
+          if (info.hasEntry) {
+            token = parseExpression(token);
+            if (optional(':', token.next)) {
+              Token colon = token.next;
+              token = parseExpression(colon);
+              listener.handleLiteralMapEntry(colon, token.next);
+            }
+          } else {
+            token = info.parse(token, this);
+          }
+          info = info.computeNext(token);
+        }
       }
       ++count;
       next = token.next;
 
-      if (isMap != null) {
-        mayParseFunctionExpressions = old;
-        return isMap
-            ? parseLiteralMapRest(token, count, constKeyword, leftBrace)
-            : parseLiteralSetRest(token, count, constKeyword, leftBrace);
-      }
-
       Token comma;
       if (optional(',', next)) {
         comma = token = next;
         next = token.next;
       }
       if (optional('}', next)) {
-        listener.handleLiteralSetOrMap(count, leftBrace, constKeyword, next);
+        listener.handleLiteralSetOrMap(
+            count, leftBrace, constKeyword, next, hasSetEntry ?? false);
         mayParseFunctionExpressions = old;
         return next;
       }
@@ -4305,7 +4314,8 @@
               next, fasta.templateExpectedButGot.withArguments('}'));
           // Scanner guarantees a closing curly bracket
           next = leftBrace.endGroup;
-          listener.handleLiteralSetOrMap(count, leftBrace, constKeyword, next);
+          listener.handleLiteralSetOrMap(
+              count, leftBrace, constKeyword, next, hasSetEntry ?? false);
           mayParseFunctionExpressions = old;
           return next;
         }
@@ -4313,148 +4323,6 @@
     }
   }
 
-  /// This method parses the portion of a map literal that starts with the left
-  /// curly brace.
-  ///
-  /// ```
-  /// mapLiteral:
-  ///   'const'? typeArguments? '{' mapLiteralEntry (',' mapLiteralEntry)* ','? '}'
-  /// ;
-  /// ```
-  ///
-  /// Provide a [constKeyword] if the literal is preceded by 'const', or `null`
-  /// if not. This is a suffix parser because it is assumed that type arguments
-  /// have been parsed, or `listener.handleNoTypeArguments` has been executed.
-  Token parseLiteralMapSuffix(Token token, Token constKeyword) {
-    Token beginToken = token = token.next;
-    assert(optional('{', beginToken));
-    if (optional('}', token.next)) {
-      token = token.next;
-      listener.handleLiteralMap(0, beginToken, constKeyword, token);
-      return token;
-    }
-
-    bool old = mayParseFunctionExpressions;
-    mayParseFunctionExpressions = true;
-    token = parseMapLiteralEntry(token);
-    mayParseFunctionExpressions = old;
-
-    return parseLiteralMapRest(token, 1, constKeyword, beginToken);
-  }
-
-  /// Parse a literal map after the first entry.
-  Token parseLiteralMapRest(
-      Token token, int count, Token constKeyword, Token beginToken) {
-    bool old = mayParseFunctionExpressions;
-    mayParseFunctionExpressions = true;
-    while (true) {
-      Token next = token.next;
-      Token comma;
-      if (optional(',', next)) {
-        comma = token = next;
-        next = token.next;
-      }
-      if (optional('}', next)) {
-        token = next;
-        break;
-      }
-      if (comma == null) {
-        // Recovery
-        if (looksLikeLiteralEntry(next)) {
-          // If this looks like the start of an expression,
-          // then report an error, insert the comma, and continue parsing.
-          token = rewriteAndRecover(
-              token,
-              fasta.templateExpectedButGot.withArguments(','),
-              new SyntheticToken(TokenType.COMMA, next.offset));
-        } else {
-          reportRecoverableError(
-              next, fasta.templateExpectedButGot.withArguments('}'));
-          // Scanner guarantees a closing curly bracket
-          token = beginToken.endGroup;
-          break;
-        }
-      }
-      token = parseMapLiteralEntry(token);
-      ++count;
-    }
-    assert(optional('}', token));
-    mayParseFunctionExpressions = old;
-    listener.handleLiteralMap(count, beginToken, constKeyword, token);
-    return token;
-  }
-
-  /// This method parses the portion of a set literal that starts with the left
-  /// curly brace.
-  ///
-  /// ```
-  /// setLiteral:
-  ///   'const'?  typeArguments? '{' expression (',' expression)* ','? '}'
-  /// ;
-  /// ```
-  ///
-  /// Provide a [constKeyword] if the literal is preceded by 'const', or `null`
-  /// if not. This is a suffix parser because it is assumed that type arguments
-  /// have been parsed, or `listener.handleNoTypeArguments` has been executed.
-  Token parseLiteralSetSuffix(Token token, Token constKeyword) {
-    Token beginToken = token = token.next;
-    assert(optional('{', beginToken));
-    if (optional('}', token.next)) {
-      token = token.next;
-      listener.handleLiteralSet(0, beginToken, constKeyword, token);
-      return token;
-    }
-
-    bool old = mayParseFunctionExpressions;
-    mayParseFunctionExpressions = true;
-    token = parseListOrSetLiteralEntry(token);
-    mayParseFunctionExpressions = old;
-
-    return parseLiteralSetRest(token, 1, constKeyword, beginToken);
-  }
-
-  /// Parse a literal set after the first expression.
-  Token parseLiteralSetRest(
-      Token token, int count, Token constKeyword, Token beginToken) {
-    bool old = mayParseFunctionExpressions;
-    mayParseFunctionExpressions = true;
-    while (true) {
-      Token next = token.next;
-      Token comma;
-      if (optional(',', next)) {
-        comma = token = next;
-        next = token.next;
-      }
-      if (optional('}', next)) {
-        token = next;
-        break;
-      }
-      if (comma == null) {
-        // Recovery
-        if (looksLikeLiteralEntry(next)) {
-          // If this looks like the start of an expression,
-          // then report an error, insert the comma, and continue parsing.
-          token = rewriteAndRecover(
-              token,
-              fasta.templateExpectedButGot.withArguments(','),
-              new SyntheticToken(TokenType.COMMA, next.offset));
-        } else {
-          reportRecoverableError(
-              next, fasta.templateExpectedButGot.withArguments('}'));
-          // Scanner guarantees a closing curly bracket
-          token = beginToken.endGroup;
-          break;
-        }
-      }
-      token = parseListOrSetLiteralEntry(token);
-      ++count;
-    }
-    assert(optional('}', token));
-    mayParseFunctionExpressions = old;
-    listener.handleLiteralSet(count, beginToken, constKeyword, token);
-    return token;
-  }
-
   /// formalParameterList functionBody.
   ///
   /// This is a suffix parser because it is assumed that type arguments have
@@ -4498,16 +4366,14 @@
     }
     token = typeParamOrArg.parseArguments(start, this);
     if (optional('{', next)) {
-      switch (typeParamOrArg.typeArgumentCount) {
-        case 0:
-          return parseLiteralSetOrMapSuffix(token, constKeyword);
-        case 1:
-          return parseLiteralSetSuffix(token, constKeyword);
-        case 2:
-          return parseLiteralMapSuffix(token, constKeyword);
-        default:
-          return parseLiteralSetOrMapSuffix(token, constKeyword);
+      if (typeParamOrArg.typeArgumentCount > 2) {
+        // TODO(danrubel): remove code in listeners which report this error
+        listener.handleRecoverableError(
+            fasta.messageSetOrMapLiteralTooManyTypeArguments,
+            start.next,
+            token);
       }
+      return parseLiteralSetOrMapSuffix(token, constKeyword);
     }
     if (!optional('[', next) && !optional('[]', next)) {
       // TODO(danrubel): Improve this error message.
diff --git a/pkg/front_end/lib/src/fasta/source/type_promotion_look_ahead_listener.dart b/pkg/front_end/lib/src/fasta/source/type_promotion_look_ahead_listener.dart
index c78a6a1..c818a43 100644
--- a/pkg/front_end/lib/src/fasta/source/type_promotion_look_ahead_listener.dart
+++ b/pkg/front_end/lib/src/fasta/source/type_promotion_look_ahead_listener.dart
@@ -871,24 +871,15 @@
   }
 
   @override
-  void handleLiteralSet(
-      int count, Token leftBrace, Token constKeyword, Token rightBrace) {
-    debugEvent("LiteralSet", leftBrace);
-    state.discard(count);
-    state.pushNull("{}", leftBrace);
-  }
-
-  @override
-  void handleLiteralMap(
-      int count, Token leftBrace, Token constKeyword, Token rightBrace) {
-    debugEvent("LiteralMap", leftBrace);
-    state.discard(count);
-    state.pushNull("{}", leftBrace);
-  }
-
-  @override
   void handleLiteralSetOrMap(
-      int count, Token leftBrace, Token constKeyword, Token rightBrace) {
+    int count,
+    Token leftBrace,
+    Token constKeyword,
+    Token rightBrace,
+    // TODO(danrubel): hasSetEntry parameter exists for replicating existing
+    // behavior and will be removed once unified collection has been enabled
+    bool hasSetEntry,
+  ) {
     debugEvent("LiteralSetOrMap", leftBrace);
     state.discard(count);
     state.pushNull("{}", leftBrace);
diff --git a/pkg/front_end/test/fasta/parser/literal_entry_info_test.dart b/pkg/front_end/test/fasta/parser/literal_entry_info_test.dart
index 0da8a6c..31ca046 100644
--- a/pkg/front_end/test/fasta/parser/literal_entry_info_test.dart
+++ b/pkg/front_end/test/fasta/parser/literal_entry_info_test.dart
@@ -480,7 +480,7 @@
         'beginConstLiteral {',
         'handleNoTypeArguments {',
         'handleLiteralInt 5',
-        'handleLiteralSet 1, {, const, }',
+        'handleLiteralSetOrMap 1, {, const, }',
         'endConstLiteral ',
         'handleSpreadExpression ...',
         'endIfElseControlFlow }',
@@ -696,7 +696,7 @@
         'handleLiteralInt 2',
         'handleLiteralInt 3',
         'handleLiteralMapEntry :, }',
-        'handleLiteralMap 1, {, null, }',
+        'handleLiteralSetOrMap 1, {, null, }',
         'handleSpreadExpression ...',
         'endForInControlFlow }',
       ],
@@ -733,7 +733,7 @@
         'handleLiteralInt 2',
         'handleLiteralInt 7',
         'handleLiteralMapEntry :, }',
-        'handleLiteralMap 1, {, null, }',
+        'handleLiteralSetOrMap 1, {, null, }',
         'handleSpreadExpression ...?',
         'endForControlFlow }',
       ],
@@ -766,7 +766,7 @@
         'handleLiteralInt 2',
         'handleLiteralInt 3',
         'handleLiteralMapEntry :, }',
-        'handleLiteralMap 1, {, null, }',
+        'handleLiteralSetOrMap 1, {, null, }',
         'handleSpreadExpression ...',
         'endIfControlFlow }',
       ],
@@ -788,7 +788,7 @@
       'handleLiteralInt 1',
       'handleLiteralInt 2',
       'handleLiteralMapEntry :, }',
-      'handleLiteralMap 1, {, const, }',
+      'handleLiteralSetOrMap 1, {, const, }',
       'endConstLiteral ',
       'handleSpreadExpression ...',
     ]);
@@ -801,7 +801,7 @@
       'handleLiteralInt 1',
       'handleLiteralInt 3',
       'handleLiteralMapEntry :, }',
-      'handleLiteralMap 1, {, const, }',
+      'handleLiteralSetOrMap 1, {, const, }',
       'endConstLiteral ',
       'handleSpreadExpression ...?',
     ]);
@@ -996,10 +996,17 @@
   }
 
   @override
-  void handleLiteralMap(
-      int count, Token leftBrace, Token constKeyword, Token rightBrace) {
-    calls
-        .add('handleLiteralMap $count, $leftBrace, $constKeyword, $rightBrace');
+  void handleLiteralSetOrMap(
+    int count,
+    Token leftBrace,
+    Token constKeyword,
+    Token rightBrace,
+    // TODO(danrubel): hasSetEntry parameter exists for replicating existing
+    // behavior and will be removed once unified collection has been enabled
+    bool hasSetEntry,
+  ) {
+    calls.add(
+        'handleLiteralSetOrMap $count, $leftBrace, $constKeyword, $rightBrace');
   }
 
   @override
@@ -1008,12 +1015,6 @@
   }
 
   @override
-  void handleLiteralSet(
-      int count, Token beginToken, Token constKeyword, Token token) {
-    calls.add('handleLiteralSet $count, $beginToken, $constKeyword, $token');
-  }
-
-  @override
   void handleNoArguments(Token token) {
     calls.add('handleNoArguments $token');
   }