Add completion support for late and required

Change-Id: I418aaa3aea9e6da6bcaf02e00c7e329e91175bbd
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/100467
Reviewed-by: Konstantin Shcheglov <scheglov@google.com>
Commit-Queue: Brian Wilkerson <brianwilkerson@google.com>
diff --git a/pkg/analysis_server/lib/src/provisional/completion/dart/completion_dart.dart b/pkg/analysis_server/lib/src/provisional/completion/dart/completion_dart.dart
index 26a8028..18e26c5 100644
--- a/pkg/analysis_server/lib/src/provisional/completion/dart/completion_dart.dart
+++ b/pkg/analysis_server/lib/src/provisional/completion/dart/completion_dart.dart
@@ -5,6 +5,7 @@
 import 'dart:async';
 
 import 'package:analysis_server/src/provisional/completion/completion_core.dart';
+import 'package:analyzer/dart/analysis/features.dart';
 import 'package:analyzer/dart/ast/ast.dart';
 import 'package:analyzer/dart/element/element.dart';
 import 'package:analyzer/dart/element/type.dart';
@@ -49,6 +50,12 @@
   List<String> get enabledExperiments;
 
   /**
+   * Return the feature set that was used to analyze the compilation unit in
+   * which suggestions are being made.
+   */
+  FeatureSet get featureSet;
+
+  /**
    * Return `true` if free standing identifiers should be suggested
    */
   bool get includeIdentifiers;
diff --git a/pkg/analysis_server/lib/src/services/completion/dart/completion_manager.dart b/pkg/analysis_server/lib/src/services/completion/dart/completion_manager.dart
index 942ace0..ff5c730 100644
--- a/pkg/analysis_server/lib/src/services/completion/dart/completion_manager.dart
+++ b/pkg/analysis_server/lib/src/services/completion/dart/completion_manager.dart
@@ -30,6 +30,7 @@
 import 'package:analysis_server/src/services/completion/dart/type_member_contributor.dart';
 import 'package:analysis_server/src/services/completion/dart/uri_contributor.dart';
 import 'package:analysis_server/src/services/completion/dart/variable_name_contributor.dart';
+import 'package:analyzer/dart/analysis/features.dart';
 import 'package:analyzer/dart/analysis/results.dart';
 import 'package:analyzer/dart/analysis/session.dart';
 import 'package:analyzer/dart/ast/ast.dart';
@@ -334,6 +335,10 @@
       result.session.analysisContext.analysisOptions.enabledExperiments;
 
   @override
+  FeatureSet get featureSet =>
+      result.session.analysisContext.analysisOptions.contextFeatures;
+
+  @override
   bool get includeIdentifiers {
     return opType.includeIdentifiers;
   }
diff --git a/pkg/analysis_server/lib/src/services/completion/dart/keyword_contributor.dart b/pkg/analysis_server/lib/src/services/completion/dart/keyword_contributor.dart
index 9da6534..b68e34a 100644
--- a/pkg/analysis_server/lib/src/services/completion/dart/keyword_contributor.dart
+++ b/pkg/analysis_server/lib/src/services/completion/dart/keyword_contributor.dart
@@ -6,10 +6,10 @@
 
 import 'package:analysis_server/src/provisional/completion/dart/completion_dart.dart';
 import 'package:analysis_server/src/services/completion/dart/completion_manager.dart';
+import 'package:analyzer/dart/analysis/features.dart';
 import 'package:analyzer/dart/ast/ast.dart';
 import 'package:analyzer/dart/ast/token.dart';
 import 'package:analyzer/dart/ast/visitor.dart';
-import 'package:analyzer/src/dart/analysis/experiments.dart';
 import 'package:analyzer/src/dart/ast/token.dart';
 import 'package:analyzer_plugin/protocol/protocol_common.dart';
 import 'package:analyzer_plugin/src/utilities/completion/optype.dart';
@@ -295,6 +295,10 @@
     if (node.covariantKeyword == null) {
       _addSuggestion(Keyword.COVARIANT);
     }
+    if (node.fields.lateKeyword == null &&
+        request.featureSet.isEnabled(Feature.non_nullable)) {
+      _addSuggestion(Keyword.LATE);
+    }
     if (!node.isStatic) {
       _addSuggestion(Keyword.STATIC);
     }
@@ -343,10 +347,16 @@
     }
     if (entity is Token && (entity as Token).type == TokenType.CLOSE_PAREN) {
       _addSuggestion(Keyword.COVARIANT);
+      if (request.featureSet.isEnabled(Feature.non_nullable)) {
+        _addSuggestion(Keyword.REQUIRED);
+      }
     } else if (entity is FormalParameter) {
       Token beginToken = (entity as FormalParameter).beginToken;
       if (beginToken != null && request.target.offset == beginToken.end) {
         _addSuggestion(Keyword.COVARIANT);
+        if (request.featureSet.isEnabled(Feature.non_nullable)) {
+          _addSuggestion(Keyword.REQUIRED);
+        }
       }
     }
   }
@@ -645,6 +655,9 @@
       Keyword.VAR,
       Keyword.VOID
     ]);
+    if (request.featureSet.isEnabled(Feature.non_nullable)) {
+      _addSuggestion(Keyword.LATE);
+    }
   }
 
   void _addClassDeclarationKeywords(ClassDeclaration node) {
@@ -661,9 +674,7 @@
   }
 
   void _addCollectionElementKeywords() {
-    List<String> enabledExperiments = request.enabledExperiments;
-    if (enabledExperiments.contains(EnableString.control_flow_collections) ||
-        enabledExperiments.contains(EnableString.spread_collections)) {
+    if (request.featureSet.isEnabled(Feature.control_flow_collections)) {
       _addSuggestions([
         Keyword.FOR,
         Keyword.IF,
@@ -683,6 +694,9 @@
       Keyword.VAR,
       Keyword.VOID
     ], DART_RELEVANCE_HIGH);
+    if (request.featureSet.isEnabled(Feature.non_nullable)) {
+      _addSuggestion(Keyword.LATE, DART_RELEVANCE_HIGH);
+    }
   }
 
   void _addExpressionKeywords(AstNode node) {
@@ -769,6 +783,9 @@
       Keyword.VOID,
       Keyword.WHILE
     ]);
+    if (request.featureSet.isEnabled(Feature.non_nullable)) {
+      _addSuggestion(Keyword.LATE);
+    }
   }
 
   void _addSuggestion(Keyword keyword,
diff --git a/pkg/analysis_server/test/services/completion/dart/keyword_contributor_test.dart b/pkg/analysis_server/test/services/completion/dart/keyword_contributor_test.dart
index 2955d79..0bd591f 100644
--- a/pkg/analysis_server/test/services/completion/dart/keyword_contributor_test.dart
+++ b/pkg/analysis_server/test/services/completion/dart/keyword_contributor_test.dart
@@ -15,190 +15,24 @@
 main() {
   defineReflectiveSuite(() {
     defineReflectiveTests(KeywordContributorTest);
-    defineReflectiveTests(KeywordContributorWithUiAsCodeTest);
+    defineReflectiveTests(KeywordContributorWithNnbdTest);
   });
 }
 
 @reflectiveTest
 class KeywordContributorTest extends DartCompletionContributorTest {
-  static const List<Keyword> CLASS_BODY_KEYWORDS = const [
+  static const List<Keyword> COLLECTION_ELEMENT_START = const [
     Keyword.CONST,
-    Keyword.COVARIANT,
-    Keyword.DYNAMIC,
-    Keyword.FACTORY,
-    Keyword.FINAL,
-    Keyword.GET,
-    Keyword.OPERATOR,
-    Keyword.SET,
-    Keyword.STATIC,
-    Keyword.VAR,
-    Keyword.VOID
-  ];
-
-  static const List<Keyword> DECLARATION_KEYWORDS = const [
-    Keyword.ABSTRACT,
-    Keyword.CLASS,
-    Keyword.CONST,
-    Keyword.COVARIANT,
-    Keyword.DYNAMIC,
-    Keyword.FINAL,
-    Keyword.TYPEDEF,
-    Keyword.VAR,
-    Keyword.VOID
-  ];
-
-  static const List<Keyword> DIRECTIVE_AND_DECLARATION_KEYWORDS = const [
-    Keyword.ABSTRACT,
-    Keyword.CLASS,
-    Keyword.CONST,
-    Keyword.COVARIANT,
-    Keyword.DYNAMIC,
-    Keyword.EXPORT,
-    Keyword.FINAL,
-    Keyword.IMPORT,
-    Keyword.PART,
-    Keyword.TYPEDEF,
-    Keyword.VAR,
-    Keyword.VOID
-  ];
-
-  static const List<Keyword> DIRECTIVE_DECLARATION_AND_LIBRARY_KEYWORDS =
-      const [
-    Keyword.ABSTRACT,
-    Keyword.CLASS,
-    Keyword.CONST,
-    Keyword.COVARIANT,
-    Keyword.DYNAMIC,
-    Keyword.EXPORT,
-    Keyword.FINAL,
-    Keyword.IMPORT,
-    Keyword.LIBRARY,
-    Keyword.PART,
-    Keyword.TYPEDEF,
-    Keyword.VAR,
-    Keyword.VOID
+    Keyword.FALSE,
+    Keyword.FOR,
+    Keyword.IF,
+    Keyword.NEW,
+    Keyword.NULL,
+    Keyword.TRUE,
   ];
 
   static const List<String> NO_PSEUDO_KEYWORDS = const [];
 
-  static const List<Keyword> STMT_START_IN_CLASS = const [
-    Keyword.ASSERT,
-    Keyword.CONST,
-    Keyword.DO,
-    Keyword.FINAL,
-    Keyword.FOR,
-    Keyword.IF,
-    Keyword.NEW,
-    Keyword.RETURN,
-    Keyword.SUPER,
-    Keyword.SWITCH,
-    Keyword.THIS,
-    Keyword.THROW,
-    Keyword.TRY,
-    Keyword.VAR,
-    Keyword.VOID,
-    Keyword.WHILE
-  ];
-
-  static const List<Keyword> STMT_START_IN_LOOP_IN_CLASS = const [
-    Keyword.ASSERT,
-    Keyword.BREAK,
-    Keyword.CONST,
-    Keyword.CONTINUE,
-    Keyword.DO,
-    Keyword.FINAL,
-    Keyword.FOR,
-    Keyword.IF,
-    Keyword.NEW,
-    Keyword.RETURN,
-    Keyword.SUPER,
-    Keyword.SWITCH,
-    Keyword.THIS,
-    Keyword.THROW,
-    Keyword.TRY,
-    Keyword.VAR,
-    Keyword.VOID,
-    Keyword.WHILE
-  ];
-
-  static const List<Keyword> STMT_START_IN_SWITCH_IN_CLASS = const [
-    Keyword.ASSERT,
-    Keyword.BREAK,
-    Keyword.CASE,
-    Keyword.CONST,
-    Keyword.DEFAULT,
-    Keyword.DO,
-    Keyword.FINAL,
-    Keyword.FOR,
-    Keyword.IF,
-    Keyword.NEW,
-    Keyword.RETURN,
-    Keyword.SUPER,
-    Keyword.SWITCH,
-    Keyword.THIS,
-    Keyword.THROW,
-    Keyword.TRY,
-    Keyword.VAR,
-    Keyword.VOID,
-    Keyword.WHILE
-  ];
-
-  static const List<Keyword> STMT_START_IN_SWITCH_OUTSIDE_CLASS = const [
-    Keyword.ASSERT,
-    Keyword.BREAK,
-    Keyword.CASE,
-    Keyword.CONST,
-    Keyword.DEFAULT,
-    Keyword.DO,
-    Keyword.FINAL,
-    Keyword.FOR,
-    Keyword.IF,
-    Keyword.NEW,
-    Keyword.RETURN,
-    Keyword.SWITCH,
-    Keyword.THROW,
-    Keyword.TRY,
-    Keyword.VAR,
-    Keyword.VOID,
-    Keyword.WHILE
-  ];
-
-  static const List<Keyword> STMT_START_OUTSIDE_CLASS = const [
-    Keyword.ASSERT,
-    Keyword.CONST,
-    Keyword.DO,
-    Keyword.FINAL,
-    Keyword.FOR,
-    Keyword.IF,
-    Keyword.NEW,
-    Keyword.RETURN,
-    Keyword.SWITCH,
-    Keyword.THROW,
-    Keyword.TRY,
-    Keyword.VAR,
-    Keyword.VOID,
-    Keyword.WHILE
-  ];
-
-  static const List<Keyword> STMT_START_IN_LOOP_OUTSIDE_CLASS = const [
-    Keyword.ASSERT,
-    Keyword.BREAK,
-    Keyword.CONST,
-    Keyword.CONTINUE,
-    Keyword.DO,
-    Keyword.FINAL,
-    Keyword.FOR,
-    Keyword.IF,
-    Keyword.NEW,
-    Keyword.RETURN,
-    Keyword.SWITCH,
-    Keyword.THROW,
-    Keyword.TRY,
-    Keyword.VAR,
-    Keyword.VOID,
-    Keyword.WHILE
-  ];
-
   static const List<Keyword> EXPRESSION_START_INSTANCE = const [
     Keyword.CONST,
     Keyword.FALSE,
@@ -217,6 +51,190 @@
     Keyword.TRUE,
   ];
 
+  List<Keyword> get classBodyKeywords => [
+        Keyword.CONST,
+        Keyword.COVARIANT,
+        Keyword.DYNAMIC,
+        Keyword.FACTORY,
+        Keyword.FINAL,
+        Keyword.GET,
+        Keyword.OPERATOR,
+        Keyword.SET,
+        Keyword.STATIC,
+        Keyword.VAR,
+        Keyword.VOID
+      ];
+
+  List<Keyword> get constructorParameter => [Keyword.COVARIANT, Keyword.THIS];
+
+  List<Keyword> get declarationKeywords => [
+        Keyword.ABSTRACT,
+        Keyword.CLASS,
+        Keyword.CONST,
+        Keyword.COVARIANT,
+        Keyword.DYNAMIC,
+        Keyword.FINAL,
+        Keyword.TYPEDEF,
+        Keyword.VAR,
+        Keyword.VOID
+      ];
+
+  List<Keyword> get directiveAndDeclarationKeywords => [
+        Keyword.ABSTRACT,
+        Keyword.CLASS,
+        Keyword.CONST,
+        Keyword.COVARIANT,
+        Keyword.DYNAMIC,
+        Keyword.EXPORT,
+        Keyword.FINAL,
+        Keyword.IMPORT,
+        Keyword.PART,
+        Keyword.TYPEDEF,
+        Keyword.VAR,
+        Keyword.VOID
+      ];
+
+  List<Keyword> get directiveDeclarationAndLibraryKeywords =>
+      directiveDeclarationKeywords..add(Keyword.LIBRARY);
+
+  List<Keyword> get directiveDeclarationKeywords => [
+        Keyword.ABSTRACT,
+        Keyword.CLASS,
+        Keyword.CONST,
+        Keyword.COVARIANT,
+        Keyword.DYNAMIC,
+        Keyword.EXPORT,
+        Keyword.FINAL,
+        Keyword.IMPORT,
+        Keyword.PART,
+        Keyword.TYPEDEF,
+        Keyword.VAR,
+        Keyword.VOID
+      ];
+
+  List<Keyword> get methodParameter => [Keyword.COVARIANT];
+
+  List<Keyword> get statementStartInClass => [
+        Keyword.ASSERT,
+        Keyword.CONST,
+        Keyword.DO,
+        Keyword.FINAL,
+        Keyword.FOR,
+        Keyword.IF,
+        Keyword.NEW,
+        Keyword.RETURN,
+        Keyword.SUPER,
+        Keyword.SWITCH,
+        Keyword.THIS,
+        Keyword.THROW,
+        Keyword.TRY,
+        Keyword.VAR,
+        Keyword.VOID,
+        Keyword.WHILE
+      ];
+
+  List<Keyword> get statementStartInLoopInClass => [
+        Keyword.ASSERT,
+        Keyword.BREAK,
+        Keyword.CONST,
+        Keyword.CONTINUE,
+        Keyword.DO,
+        Keyword.FINAL,
+        Keyword.FOR,
+        Keyword.IF,
+        Keyword.NEW,
+        Keyword.RETURN,
+        Keyword.SUPER,
+        Keyword.SWITCH,
+        Keyword.THIS,
+        Keyword.THROW,
+        Keyword.TRY,
+        Keyword.VAR,
+        Keyword.VOID,
+        Keyword.WHILE
+      ];
+
+  List<Keyword> get statementStartInLoopOutsideClass => [
+        Keyword.ASSERT,
+        Keyword.BREAK,
+        Keyword.CONST,
+        Keyword.CONTINUE,
+        Keyword.DO,
+        Keyword.FINAL,
+        Keyword.FOR,
+        Keyword.IF,
+        Keyword.NEW,
+        Keyword.RETURN,
+        Keyword.SWITCH,
+        Keyword.THROW,
+        Keyword.TRY,
+        Keyword.VAR,
+        Keyword.VOID,
+        Keyword.WHILE
+      ];
+
+  List<Keyword> get statementStartInSwitchInClass => [
+        Keyword.ASSERT,
+        Keyword.BREAK,
+        Keyword.CASE,
+        Keyword.CONST,
+        Keyword.DEFAULT,
+        Keyword.DO,
+        Keyword.FINAL,
+        Keyword.FOR,
+        Keyword.IF,
+        Keyword.NEW,
+        Keyword.RETURN,
+        Keyword.SUPER,
+        Keyword.SWITCH,
+        Keyword.THIS,
+        Keyword.THROW,
+        Keyword.TRY,
+        Keyword.VAR,
+        Keyword.VOID,
+        Keyword.WHILE
+      ];
+
+  List<Keyword> get statementStartInSwitchOutsideClass => [
+        Keyword.ASSERT,
+        Keyword.BREAK,
+        Keyword.CASE,
+        Keyword.CONST,
+        Keyword.DEFAULT,
+        Keyword.DO,
+        Keyword.FINAL,
+        Keyword.FOR,
+        Keyword.IF,
+        Keyword.NEW,
+        Keyword.RETURN,
+        Keyword.SWITCH,
+        Keyword.THROW,
+        Keyword.TRY,
+        Keyword.VAR,
+        Keyword.VOID,
+        Keyword.WHILE
+      ];
+
+  List<Keyword> get statementStartOutsideClass => [
+        Keyword.ASSERT,
+        Keyword.CONST,
+        Keyword.DO,
+        Keyword.FINAL,
+        Keyword.FOR,
+        Keyword.IF,
+        Keyword.NEW,
+        Keyword.RETURN,
+        Keyword.SWITCH,
+        Keyword.THROW,
+        Keyword.TRY,
+        Keyword.VAR,
+        Keyword.VOID,
+        Keyword.WHILE
+      ];
+
+  List<Keyword> get staticMember =>
+      [Keyword.CONST, Keyword.COVARIANT, Keyword.FINAL];
+
   void assertSuggestKeywords(Iterable<Keyword> expectedKeywords,
       {List<String> pseudoKeywords: NO_PSEUDO_KEYWORDS,
       int relevance: DART_RELEVANCE_KEYWORD}) {
@@ -287,29 +305,29 @@
     return new KeywordContributor();
   }
 
-  test_after_class() async {
+  test_after_class_noPrefix() async {
     addTestSource('class A {} ^');
     await computeSuggestions();
-    assertSuggestKeywords(DECLARATION_KEYWORDS, relevance: DART_RELEVANCE_HIGH);
+    assertSuggestKeywords(declarationKeywords, relevance: DART_RELEVANCE_HIGH);
   }
 
-  test_after_class2() async {
+  test_after_class_prefix() async {
     addTestSource('class A {} c^');
     await computeSuggestions();
-    assertSuggestKeywords(DECLARATION_KEYWORDS, relevance: DART_RELEVANCE_HIGH);
+    assertSuggestKeywords(declarationKeywords, relevance: DART_RELEVANCE_HIGH);
   }
 
-  test_after_import() async {
+  test_after_import_noPrefix() async {
     addTestSource('import "foo"; ^');
     await computeSuggestions();
-    assertSuggestKeywords(DIRECTIVE_AND_DECLARATION_KEYWORDS,
+    assertSuggestKeywords(directiveAndDeclarationKeywords,
         relevance: DART_RELEVANCE_HIGH);
   }
 
-  test_after_import2() async {
+  test_after_import_prefix() async {
     addTestSource('import "foo"; c^');
     await computeSuggestions();
-    assertSuggestKeywords(DIRECTIVE_AND_DECLARATION_KEYWORDS,
+    assertSuggestKeywords(directiveAndDeclarationKeywords,
         relevance: DART_RELEVANCE_HIGH);
   }
 
@@ -328,14 +346,9 @@
     // and reports a single function expression argument
     // while analyzer adds the closing paren before the `a`
     // and adds synthetic `;`s making `a` a statement.
-    if (usingFastaParser) {
-      assertSuggestKeywords([],
-          pseudoKeywords: ['async', 'async*', 'sync*'],
-          relevance: DART_RELEVANCE_HIGH);
-    } else {
-      assertSuggestKeywords(STMT_START_OUTSIDE_CLASS,
-          pseudoKeywords: ['async', 'async*', 'sync*']);
-    }
+    assertSuggestKeywords([],
+        pseudoKeywords: ['async', 'async*', 'sync*'],
+        relevance: DART_RELEVANCE_HIGH);
   }
 
   test_anonymous_function_async3() async {
@@ -388,14 +401,9 @@
     await computeSuggestions();
     // Fasta interprets the argument as a function expression
     // while analyzer adds synthetic `;`s making `a` a statement.
-    if (usingFastaParser) {
-      assertSuggestKeywords([],
-          pseudoKeywords: ['async', 'async*', 'sync*'],
-          relevance: DART_RELEVANCE_HIGH);
-    } else {
-      assertSuggestKeywords(STMT_START_OUTSIDE_CLASS,
-          pseudoKeywords: ['async', 'async*', 'sync*']);
-    }
+    assertSuggestKeywords([],
+        pseudoKeywords: ['async', 'async*', 'sync*'],
+        relevance: DART_RELEVANCE_HIGH);
   }
 
   test_argument() async {
@@ -527,7 +535,7 @@
     var keywords = <Keyword>[];
     keywords.add(Keyword.CATCH);
     keywords.add(Keyword.FINALLY);
-    keywords.addAll(STMT_START_OUTSIDE_CLASS);
+    keywords.addAll(statementStartOutsideClass);
     assertSuggestKeywords(keywords, pseudoKeywords: ['on']);
   }
 
@@ -538,7 +546,7 @@
     var keywords = <Keyword>[];
     keywords.add(Keyword.CATCH);
     keywords.add(Keyword.FINALLY);
-    keywords.addAll(STMT_START_OUTSIDE_CLASS);
+    keywords.addAll(statementStartOutsideClass);
     assertSuggestKeywords(keywords, pseudoKeywords: ['on']);
   }
 
@@ -549,7 +557,7 @@
     var keywords = <Keyword>[];
     keywords.add(Keyword.CATCH);
     keywords.add(Keyword.FINALLY);
-    keywords.addAll(STMT_START_OUTSIDE_CLASS);
+    keywords.addAll(statementStartOutsideClass);
     assertSuggestKeywords(keywords, pseudoKeywords: ['on']);
   }
 
@@ -560,7 +568,7 @@
     var keywords = <Keyword>[];
     keywords.add(Keyword.CATCH);
     keywords.add(Keyword.FINALLY);
-    keywords.addAll(STMT_START_OUTSIDE_CLASS);
+    keywords.addAll(statementStartOutsideClass);
     assertSuggestKeywords(keywords, pseudoKeywords: ['on']);
   }
 
@@ -571,7 +579,7 @@
     var keywords = <Keyword>[];
     keywords.add(Keyword.CATCH);
     keywords.add(Keyword.FINALLY);
-    keywords.addAll(STMT_START_OUTSIDE_CLASS);
+    keywords.addAll(statementStartOutsideClass);
     assertSuggestKeywords(keywords, pseudoKeywords: ['on']);
   }
 
@@ -582,7 +590,7 @@
     var keywords = <Keyword>[];
     keywords.add(Keyword.CATCH);
     keywords.add(Keyword.FINALLY);
-    keywords.addAll(STMT_START_OUTSIDE_CLASS);
+    keywords.addAll(statementStartOutsideClass);
     assertSuggestKeywords(keywords, pseudoKeywords: ['on']);
   }
 
@@ -593,7 +601,7 @@
     var keywords = <Keyword>[];
     keywords.add(Keyword.CATCH);
     keywords.add(Keyword.FINALLY);
-    keywords.addAll(STMT_START_OUTSIDE_CLASS);
+    keywords.addAll(statementStartOutsideClass);
     assertSuggestKeywords(keywords, pseudoKeywords: ['on']);
   }
 
@@ -604,7 +612,7 @@
     var keywords = <Keyword>[];
     keywords.add(Keyword.CATCH);
     keywords.add(Keyword.FINALLY);
-    keywords.addAll(STMT_START_OUTSIDE_CLASS);
+    keywords.addAll(statementStartOutsideClass);
     assertSuggestKeywords(keywords, pseudoKeywords: ['on']);
   }
 
@@ -673,7 +681,7 @@
     addTestSource('main() {try {} catch (e) {^}}}');
     await computeSuggestions();
     var keywords = <Keyword>[];
-    keywords.addAll(STMT_START_OUTSIDE_CLASS);
+    keywords.addAll(statementStartOutsideClass);
     keywords.add(Keyword.RETHROW);
     assertSuggestKeywords(keywords);
   }
@@ -688,25 +696,25 @@
   test_class_body() async {
     addTestSource('class A {^}');
     await computeSuggestions();
-    assertSuggestKeywords(CLASS_BODY_KEYWORDS);
+    assertSuggestKeywords(classBodyKeywords);
   }
 
   test_class_body_beginning() async {
     addTestSource('class A {^ var foo;}');
     await computeSuggestions();
-    assertSuggestKeywords(CLASS_BODY_KEYWORDS);
+    assertSuggestKeywords(classBodyKeywords);
   }
 
   test_class_body_between() async {
     addTestSource('class A {var bar; ^ var foo;}');
     await computeSuggestions();
-    assertSuggestKeywords(CLASS_BODY_KEYWORDS);
+    assertSuggestKeywords(classBodyKeywords);
   }
 
   test_class_body_end() async {
     addTestSource('class A {var foo; ^}');
     await computeSuggestions();
-    assertSuggestKeywords(CLASS_BODY_KEYWORDS);
+    assertSuggestKeywords(classBodyKeywords);
   }
 
   test_class_extends() async {
@@ -775,7 +783,7 @@
 }
 ''');
     await computeSuggestions();
-    assertSuggestKeywords([Keyword.CONST, Keyword.COVARIANT, Keyword.FINAL]);
+    assertSuggestKeywords(staticMember);
   }
 
   test_class_member_final_afterStatic() async {
@@ -785,7 +793,7 @@
 }
 ''');
     await computeSuggestions();
-    assertSuggestKeywords([Keyword.CONST, Keyword.COVARIANT, Keyword.FINAL]);
+    assertSuggestKeywords(staticMember);
   }
 
   test_class_name() async {
@@ -851,50 +859,50 @@
     assertSuggestKeywords([Keyword.ASSERT, Keyword.SUPER, Keyword.THIS]);
   }
 
-  test_constructor_param() async {
+  test_constructor_param_noPrefix() async {
     addTestSource('class A { A(^) {});}');
     await computeSuggestions();
-    assertSuggestKeywords([Keyword.COVARIANT, Keyword.THIS]);
+    assertSuggestKeywords(constructorParameter);
   }
 
-  test_constructor_param2() async {
+  test_constructor_param_prefix() async {
     addTestSource('class A { A(t^) {});}');
     await computeSuggestions();
-    assertSuggestKeywords([Keyword.COVARIANT, Keyword.THIS]);
+    assertSuggestKeywords(constructorParameter);
   }
 
-  test_do_break_continue() async {
-    addTestSource('main() {do {^} while (true);}');
+  test_do_break_continue_insideClass() async {
+    addTestSource('class A {foo() {do {^} while (true);}}');
     await computeSuggestions();
-    assertSuggestKeywords(STMT_START_IN_LOOP_OUTSIDE_CLASS,
+    assertSuggestKeywords(statementStartInLoopInClass,
         relevance: DART_RELEVANCE_KEYWORD);
   }
 
-  test_do_break_continue2() async {
-    addTestSource('class A {foo() {do {^} while (true);}}');
+  test_do_break_continue_outsideClass() async {
+    addTestSource('main() {do {^} while (true);}');
     await computeSuggestions();
-    assertSuggestKeywords(STMT_START_IN_LOOP_IN_CLASS,
+    assertSuggestKeywords(statementStartInLoopOutsideClass,
         relevance: DART_RELEVANCE_KEYWORD);
   }
 
   test_empty() async {
     addTestSource('^');
     await computeSuggestions();
-    assertSuggestKeywords(DIRECTIVE_DECLARATION_AND_LIBRARY_KEYWORDS,
+    assertSuggestKeywords(directiveDeclarationAndLibraryKeywords,
         relevance: DART_RELEVANCE_HIGH);
   }
 
-  test_for_break_continue() async {
-    addTestSource('main() {for (int x in myList) {^}}');
+  test_for_break_continue_insideClass() async {
+    addTestSource('class A {foo() {for (int x in myList) {^}}}');
     await computeSuggestions();
-    assertSuggestKeywords(STMT_START_IN_LOOP_OUTSIDE_CLASS,
+    assertSuggestKeywords(statementStartInLoopInClass,
         relevance: DART_RELEVANCE_KEYWORD);
   }
 
-  test_for_break_continue2() async {
-    addTestSource('class A {foo() {for (int x in myList) {^}}}');
+  test_for_break_continue_outsideClass() async {
+    addTestSource('main() {for (int x in myList) {^}}');
     await computeSuggestions();
-    assertSuggestKeywords(STMT_START_IN_LOOP_IN_CLASS,
+    assertSuggestKeywords(statementStartInLoopOutsideClass,
         relevance: DART_RELEVANCE_KEYWORD);
   }
 
@@ -937,7 +945,7 @@
   test_function_async() async {
     addTestSource('main()^');
     await computeSuggestions();
-    assertSuggestKeywords(usingFastaParser ? [] : DECLARATION_KEYWORDS,
+    assertSuggestKeywords([],
         pseudoKeywords: ['async', 'async*', 'sync*'],
         relevance: DART_RELEVANCE_HIGH);
   }
@@ -953,7 +961,7 @@
   test_function_async3() async {
     addTestSource('main()a^');
     await computeSuggestions();
-    assertSuggestKeywords(DECLARATION_KEYWORDS,
+    assertSuggestKeywords(declarationKeywords,
         pseudoKeywords: ['async', 'async*', 'sync*'],
         relevance: DART_RELEVANCE_HIGH);
   }
@@ -961,7 +969,7 @@
   test_function_async4() async {
     addTestSource('main()a^{}');
     await computeSuggestions();
-    assertSuggestKeywords(usingFastaParser ? [] : DECLARATION_KEYWORDS,
+    assertSuggestKeywords([],
         pseudoKeywords: ['async', 'async*', 'sync*'],
         relevance: DART_RELEVANCE_HIGH);
   }
@@ -969,7 +977,7 @@
   test_function_async5() async {
     addTestSource('main()a^ Foo foo;');
     await computeSuggestions();
-    assertSuggestKeywords(DECLARATION_KEYWORDS,
+    assertSuggestKeywords(declarationKeywords,
         pseudoKeywords: ['async', 'async*', 'sync*'],
         relevance: DART_RELEVANCE_HIGH);
   }
@@ -983,7 +991,7 @@
 }
 ''');
     await computeSuggestions();
-    assertSuggestKeywords(STMT_START_OUTSIDE_CLASS);
+    assertSuggestKeywords(statementStartOutsideClass);
   }
 
   test_function_body_inClass_constructorInitializer_async() async {
@@ -995,7 +1003,8 @@
 }
 ''');
     await computeSuggestions();
-    assertSuggestKeywords(STMT_START_OUTSIDE_CLASS, pseudoKeywords: ['await']);
+    assertSuggestKeywords(statementStartOutsideClass,
+        pseudoKeywords: ['await']);
   }
 
   test_function_body_inClass_constructorInitializer_async_star() async {
@@ -1007,7 +1016,7 @@
   }
   ''');
     await computeSuggestions();
-    assertSuggestKeywords(STMT_START_OUTSIDE_CLASS,
+    assertSuggestKeywords(statementStartOutsideClass,
         pseudoKeywords: ['await', 'yield', 'yield*']);
   }
 
@@ -1018,7 +1027,7 @@
 }
 ''');
     await computeSuggestions();
-    assertSuggestKeywords(STMT_START_OUTSIDE_CLASS);
+    assertSuggestKeywords(statementStartOutsideClass);
   }
 
   test_function_body_inClass_methodBody() async {
@@ -1030,7 +1039,7 @@
 }
 ''');
     await computeSuggestions();
-    assertSuggestKeywords(STMT_START_IN_CLASS);
+    assertSuggestKeywords(statementStartInClass);
   }
 
   test_function_body_inClass_methodBody_inFunction() async {
@@ -1044,7 +1053,7 @@
 }
 ''');
     await computeSuggestions();
-    assertSuggestKeywords(STMT_START_IN_CLASS);
+    assertSuggestKeywords(statementStartInClass);
   }
 
   test_function_body_inClass_methodBody_inFunction_async() async {
@@ -1058,7 +1067,7 @@
 }
 ''');
     await computeSuggestions();
-    assertSuggestKeywords(STMT_START_IN_CLASS, pseudoKeywords: ['await']);
+    assertSuggestKeywords(statementStartInClass, pseudoKeywords: ['await']);
   }
 
   test_function_body_inClass_methodBody_inFunction_async_star() async {
@@ -1072,82 +1081,89 @@
   }
   ''');
     await computeSuggestions();
-    assertSuggestKeywords(STMT_START_IN_CLASS,
+    assertSuggestKeywords(statementStartInClass,
         pseudoKeywords: ['await', 'yield', 'yield*']);
   }
 
   test_function_body_inUnit() async {
     addTestSource('main() {^}');
     await computeSuggestions();
-    assertSuggestKeywords(STMT_START_OUTSIDE_CLASS);
+    assertSuggestKeywords(statementStartOutsideClass);
   }
 
   test_function_body_inUnit_afterBlock() async {
     addTestSource('main() {{}^}');
     await computeSuggestions();
-    assertSuggestKeywords(STMT_START_OUTSIDE_CLASS);
+    assertSuggestKeywords(statementStartOutsideClass);
   }
 
   test_function_body_inUnit_async() async {
     addTestSource('main() async {^}');
     await computeSuggestions();
-    assertSuggestKeywords(STMT_START_OUTSIDE_CLASS, pseudoKeywords: ['await']);
+    assertSuggestKeywords(statementStartOutsideClass,
+        pseudoKeywords: ['await']);
   }
 
   test_function_body_inUnit_async_star() async {
     addTestSource('main() async* {n^}');
     await computeSuggestions();
-    assertSuggestKeywords(STMT_START_OUTSIDE_CLASS,
+    assertSuggestKeywords(statementStartOutsideClass,
         pseudoKeywords: ['await', 'yield', 'yield*']);
   }
 
   test_function_body_inUnit_async_star2() async {
     addTestSource('main() async* {n^ foo}');
     await computeSuggestions();
-    assertSuggestKeywords(STMT_START_OUTSIDE_CLASS,
+    assertSuggestKeywords(statementStartOutsideClass,
         pseudoKeywords: ['await', 'yield', 'yield*']);
   }
 
   test_function_body_inUnit_sync_star() async {
     addTestSource('main() sync* {n^}');
     await computeSuggestions();
-    assertSuggestKeywords(STMT_START_OUTSIDE_CLASS,
+    assertSuggestKeywords(statementStartOutsideClass,
         pseudoKeywords: ['await', 'yield', 'yield*']);
   }
 
   test_function_body_inUnit_sync_star2() async {
     addTestSource('main() sync* {n^ foo}');
     await computeSuggestions();
-    assertSuggestKeywords(STMT_START_OUTSIDE_CLASS,
+    assertSuggestKeywords(statementStartOutsideClass,
         pseudoKeywords: ['await', 'yield', 'yield*']);
   }
 
   test_if_after_else() async {
     addTestSource('main() { if (true) {} else ^ }');
     await computeSuggestions();
-    assertSuggestKeywords(STMT_START_OUTSIDE_CLASS,
+    assertSuggestKeywords(statementStartOutsideClass,
         relevance: DART_RELEVANCE_KEYWORD);
   }
 
   test_if_afterThen_nextCloseCurlyBrace0() async {
     addTestSource('main() { if (true) {} ^ }');
     await computeSuggestions();
-    assertSuggestKeywords(STMT_START_OUTSIDE_CLASS.toList()..add(Keyword.ELSE),
-        relevance: DART_RELEVANCE_KEYWORD);
+    List<Keyword> keywords = [];
+    keywords.addAll(statementStartOutsideClass);
+    keywords.add(Keyword.ELSE);
+    assertSuggestKeywords(keywords, relevance: DART_RELEVANCE_KEYWORD);
   }
 
   test_if_afterThen_nextCloseCurlyBrace1() async {
     addTestSource('main() { if (true) {} e^ }');
     await computeSuggestions();
-    assertSuggestKeywords(STMT_START_OUTSIDE_CLASS.toList()..add(Keyword.ELSE),
-        relevance: DART_RELEVANCE_KEYWORD);
+    List<Keyword> keywords = [];
+    keywords.addAll(statementStartOutsideClass);
+    keywords.add(Keyword.ELSE);
+    assertSuggestKeywords(keywords, relevance: DART_RELEVANCE_KEYWORD);
   }
 
   test_if_afterThen_nextStatement0() async {
     addTestSource('main() { if (true) {} ^ print(0); }');
     await computeSuggestions();
-    assertSuggestKeywords(STMT_START_OUTSIDE_CLASS.toList()..add(Keyword.ELSE),
-        relevance: DART_RELEVANCE_KEYWORD);
+    List<Keyword> keywords = [];
+    keywords.addAll(statementStartOutsideClass);
+    keywords.add(Keyword.ELSE);
+    assertSuggestKeywords(keywords, relevance: DART_RELEVANCE_KEYWORD);
   }
 
   test_if_condition_isKeyword() async {
@@ -1189,49 +1205,169 @@
   test_if_in_class() async {
     addTestSource('class A {foo() {if (true) ^}}');
     await computeSuggestions();
-    assertSuggestKeywords(STMT_START_IN_CLASS);
+    assertSuggestKeywords(statementStartInClass);
   }
 
   test_if_in_class2() async {
     addTestSource('class A {foo() {if (true) ^;}}');
     await computeSuggestions();
-    assertSuggestKeywords(STMT_START_IN_CLASS);
+    assertSuggestKeywords(statementStartInClass);
   }
 
   test_if_in_class3() async {
     addTestSource('class A {foo() {if (true) r^;}}');
     await computeSuggestions();
-    assertSuggestKeywords(STMT_START_IN_CLASS);
+    assertSuggestKeywords(statementStartInClass);
   }
 
   test_if_in_class4() async {
     addTestSource('class A {foo() {if (true) ^ go();}}');
     await computeSuggestions();
-    assertSuggestKeywords(STMT_START_IN_CLASS);
+    assertSuggestKeywords(statementStartInClass);
   }
 
   test_if_outside_class() async {
     addTestSource('foo() {if (true) ^}');
     await computeSuggestions();
-    assertSuggestKeywords(STMT_START_OUTSIDE_CLASS);
+    assertSuggestKeywords(statementStartOutsideClass);
   }
 
   test_if_outside_class2() async {
     addTestSource('foo() {if (true) ^;}');
     await computeSuggestions();
-    assertSuggestKeywords(STMT_START_OUTSIDE_CLASS);
+    assertSuggestKeywords(statementStartOutsideClass);
   }
 
   test_if_outside_class3() async {
     addTestSource('foo() {if (true) r^;}');
     await computeSuggestions();
-    assertSuggestKeywords(STMT_START_OUTSIDE_CLASS);
+    assertSuggestKeywords(statementStartOutsideClass);
   }
 
   test_if_outside_class4() async {
     addTestSource('foo() {if (true) ^ go();}');
     await computeSuggestions();
-    assertSuggestKeywords(STMT_START_OUTSIDE_CLASS);
+    assertSuggestKeywords(statementStartOutsideClass);
+  }
+
+  test_ifOrForElement_forElement() async {
+    addTestSource('''
+f() => [for (var e in c) ^];
+''');
+    await computeSuggestions();
+    assertSuggestKeywords(COLLECTION_ELEMENT_START);
+  }
+
+  test_ifOrForElement_ifElement_else() async {
+    addTestSource('''
+f() => [if (true) 1 else ^];
+''');
+    await computeSuggestions();
+    assertSuggestKeywords(COLLECTION_ELEMENT_START);
+  }
+
+  test_ifOrForElement_ifElement_then() async {
+    addTestSource('''
+f() => [if (true) ^];
+''');
+    await computeSuggestions();
+    assertSuggestKeywords(COLLECTION_ELEMENT_START);
+  }
+
+  test_ifOrForElement_list_empty() async {
+    addTestSource('''
+f() => [^];
+''');
+    await computeSuggestions();
+    assertSuggestKeywords(COLLECTION_ELEMENT_START);
+  }
+
+  test_ifOrForElement_list_first() async {
+    addTestSource('''
+f() => [^1, 2];
+''');
+    await computeSuggestions();
+    assertSuggestKeywords(COLLECTION_ELEMENT_START);
+  }
+
+  test_ifOrForElement_list_last() async {
+    addTestSource('''
+f() => [1, 2, ^];
+''');
+    await computeSuggestions();
+    assertSuggestKeywords(COLLECTION_ELEMENT_START);
+  }
+
+  test_ifOrForElement_list_middle() async {
+    addTestSource('''
+f() => [1, ^, 2];
+''');
+    await computeSuggestions();
+    assertSuggestKeywords(COLLECTION_ELEMENT_START);
+  }
+
+  test_ifOrForElement_map_empty() async {
+    addTestSource('''
+f() => <String, int>{^};
+''');
+    await computeSuggestions();
+    assertSuggestKeywords(COLLECTION_ELEMENT_START);
+  }
+
+  test_ifOrForElement_map_first() async {
+    addTestSource('''
+f() => <String, int>{^'a' : 1};
+''');
+    await computeSuggestions();
+    assertSuggestKeywords(COLLECTION_ELEMENT_START);
+  }
+
+  test_ifOrForElement_map_last() async {
+    addTestSource('''
+f() => <String, int>{'a' : 1, 'b' : 2, ^};
+''');
+    await computeSuggestions();
+    assertSuggestKeywords(COLLECTION_ELEMENT_START);
+  }
+
+  test_ifOrForElement_map_middle() async {
+    addTestSource('''
+f() => <String, int>{'a' : 1, ^, 'b' : 2];
+''');
+    await computeSuggestions();
+    assertSuggestKeywords(COLLECTION_ELEMENT_START);
+  }
+
+  test_ifOrForElement_set_empty() async {
+    addTestSource('''
+f() => <int>{^};
+''');
+    await computeSuggestions();
+    assertSuggestKeywords(COLLECTION_ELEMENT_START);
+  }
+
+  test_ifOrForElement_set_first() async {
+    addTestSource('''
+f() => <int>{^1, 2};
+''');
+    await computeSuggestions();
+    assertSuggestKeywords(COLLECTION_ELEMENT_START);
+  }
+
+  test_ifOrForElement_set_last() async {
+    addTestSource('''
+f() => <int>{1, 2, ^};
+''');
+    await computeSuggestions();
+    assertSuggestKeywords(COLLECTION_ELEMENT_START);
+  }
+
+  test_ifOrForElement_set_middle() async {
+    addTestSource('''
+f() => <int>{1, ^, 2};
+''');
+    await computeSuggestions();
+    assertSuggestKeywords(COLLECTION_ELEMENT_START);
   }
 
   test_import() async {
@@ -1370,7 +1506,7 @@
     expect(replacementOffset, 0);
     expect(replacementLength, 3);
     // TODO(danrubel) should not suggest declaration keywords
-    assertSuggestKeywords(DIRECTIVE_DECLARATION_AND_LIBRARY_KEYWORDS,
+    assertSuggestKeywords(directiveDeclarationAndLibraryKeywords,
         relevance: DART_RELEVANCE_HIGH);
   }
 
@@ -1380,7 +1516,7 @@
     expect(replacementOffset, 0);
     expect(replacementLength, 3);
     // TODO(danrubel) should not suggest declaration keywords
-    assertSuggestKeywords(DIRECTIVE_DECLARATION_AND_LIBRARY_KEYWORDS,
+    assertSuggestKeywords(directiveDeclarationAndLibraryKeywords,
         relevance: DART_RELEVANCE_HIGH);
   }
 
@@ -1390,7 +1526,7 @@
     expect(replacementOffset, 1);
     expect(replacementLength, 3);
     // TODO(danrubel) should not suggest declaration keywords
-    assertSuggestKeywords(DIRECTIVE_DECLARATION_AND_LIBRARY_KEYWORDS,
+    assertSuggestKeywords(directiveDeclarationAndLibraryKeywords,
         relevance: DART_RELEVANCE_HIGH);
   }
 
@@ -1400,7 +1536,7 @@
     expect(replacementOffset, 0);
     expect(replacementLength, 0);
     // TODO(danrubel) should not suggest declaration keywords
-    assertSuggestKeywords(DIRECTIVE_DECLARATION_AND_LIBRARY_KEYWORDS,
+    assertSuggestKeywords(directiveDeclarationAndLibraryKeywords,
         relevance: DART_RELEVANCE_HIGH);
   }
 
@@ -1410,7 +1546,7 @@
     expect(replacementOffset, 14);
     expect(replacementLength, 3);
     // TODO(danrubel) should not suggest declaration keywords
-    assertSuggestKeywords(DIRECTIVE_AND_DECLARATION_KEYWORDS,
+    assertSuggestKeywords(directiveDeclarationKeywords,
         relevance: DART_RELEVANCE_HIGH);
   }
 
@@ -1421,7 +1557,7 @@
     expect(replacementOffset, 32);
     expect(replacementLength, 3);
     // TODO(danrubel) should not suggest declaration keywords
-    assertSuggestKeywords(DIRECTIVE_AND_DECLARATION_KEYWORDS,
+    assertSuggestKeywords(directiveDeclarationKeywords,
         relevance: DART_RELEVANCE_HIGH);
   }
 
@@ -1452,7 +1588,7 @@
   test_library() async {
     addTestSource('library foo;^');
     await computeSuggestions();
-    assertSuggestKeywords(DIRECTIVE_AND_DECLARATION_KEYWORDS,
+    assertSuggestKeywords(directiveAndDeclarationKeywords,
         relevance: DART_RELEVANCE_HIGH);
   }
 
@@ -1483,7 +1619,7 @@
   test_method_async() async {
     addTestSource('class A { foo() ^}');
     await computeSuggestions();
-    assertSuggestKeywords(CLASS_BODY_KEYWORDS,
+    assertSuggestKeywords(classBodyKeywords,
         pseudoKeywords: ['async', 'async*', 'sync*']);
   }
 
@@ -1498,34 +1634,29 @@
   test_method_async3() async {
     addTestSource('class A { foo() a^}');
     await computeSuggestions();
-    assertSuggestKeywords(CLASS_BODY_KEYWORDS,
+    assertSuggestKeywords(classBodyKeywords,
         pseudoKeywords: ['async', 'async*', 'sync*']);
   }
 
   test_method_async4() async {
     addTestSource('class A { foo() a^{}}');
     await computeSuggestions();
-    if (usingFastaParser) {
-      assertSuggestKeywords([],
-          pseudoKeywords: ['async', 'async*', 'sync*'],
-          relevance: DART_RELEVANCE_HIGH);
-    } else {
-      assertSuggestKeywords(CLASS_BODY_KEYWORDS,
-          pseudoKeywords: ['async', 'async*', 'sync*']);
-    }
+    assertSuggestKeywords([],
+        pseudoKeywords: ['async', 'async*', 'sync*'],
+        relevance: DART_RELEVANCE_HIGH);
   }
 
   test_method_async5() async {
     addTestSource('class A { foo() ^ Foo foo;}');
     await computeSuggestions();
-    assertSuggestKeywords(CLASS_BODY_KEYWORDS,
+    assertSuggestKeywords(classBodyKeywords,
         pseudoKeywords: ['async', 'async*', 'sync*']);
   }
 
   test_method_async6() async {
     addTestSource('class A { foo() a^ Foo foo;}');
     await computeSuggestions();
-    assertSuggestKeywords(CLASS_BODY_KEYWORDS,
+    assertSuggestKeywords(classBodyKeywords,
         pseudoKeywords: ['async', 'async*', 'sync*']);
   }
 
@@ -1539,14 +1670,14 @@
   test_method_async8() async {
     addTestSource('class A { foo() a^ Foo foo;}');
     await computeSuggestions();
-    assertSuggestKeywords(CLASS_BODY_KEYWORDS,
+    assertSuggestKeywords(classBodyKeywords,
         pseudoKeywords: ['async', 'async*', 'sync*']);
   }
 
   test_method_body() async {
     addTestSource('class A { foo() {^}}');
     await computeSuggestions();
-    assertSuggestKeywords(STMT_START_IN_CLASS);
+    assertSuggestKeywords(statementStartInClass);
   }
 
   test_method_body2() async {
@@ -1570,7 +1701,7 @@
   test_method_body_async() async {
     addTestSource('class A { foo() async {^}}');
     await computeSuggestions();
-    assertSuggestKeywords(STMT_START_IN_CLASS, pseudoKeywords: ['await']);
+    assertSuggestKeywords(statementStartInClass, pseudoKeywords: ['await']);
   }
 
   test_method_body_async2() async {
@@ -1594,7 +1725,7 @@
   test_method_body_async_star() async {
     addTestSource('class A { foo() async* {^}}');
     await computeSuggestions();
-    assertSuggestKeywords(STMT_START_IN_CLASS,
+    assertSuggestKeywords(statementStartInClass,
         pseudoKeywords: ['await', 'yield', 'yield*']);
   }
 
@@ -1628,20 +1759,6 @@
     assertNoSuggestions();
   }
 
-  test_method_param() async {
-    addTestSource('class A { foo(^) {});}');
-    await computeSuggestions();
-    expect(suggestions, isNotEmpty);
-    assertSuggestKeywords([Keyword.COVARIANT]);
-  }
-
-  test_method_param2() async {
-    addTestSource('class A { foo(t^) {});}');
-    await computeSuggestions();
-    expect(suggestions, isNotEmpty);
-    assertSuggestKeywords([Keyword.COVARIANT]);
-  }
-
   test_method_param_named_init() async {
     addTestSource('class A { foo({bool bar: ^}) {}}');
     await computeSuggestions();
@@ -1656,6 +1773,13 @@
     assertSuggestKeywords(EXPRESSION_START_NO_INSTANCE);
   }
 
+  test_method_param_noPrefix() async {
+    addTestSource('class A { foo(^) {});}');
+    await computeSuggestions();
+    expect(suggestions, isNotEmpty);
+    assertSuggestKeywords(methodParameter);
+  }
+
   test_method_param_positional_init() async {
     addTestSource('class A { foo([bool bar = ^]) {}}');
     await computeSuggestions();
@@ -1670,6 +1794,13 @@
     assertSuggestKeywords(EXPRESSION_START_NO_INSTANCE);
   }
 
+  test_method_param_prefix() async {
+    addTestSource('class A { foo(t^) {});}');
+    await computeSuggestions();
+    expect(suggestions, isNotEmpty);
+    assertSuggestKeywords(methodParameter);
+  }
+
   test_mixin() async {
     addTestSource('mixin M o^ { }');
     await computeSuggestions();
@@ -1716,21 +1847,21 @@
   test_part_of() async {
     addTestSource('part of foo;^');
     await computeSuggestions();
-    assertSuggestKeywords(DIRECTIVE_AND_DECLARATION_KEYWORDS,
+    assertSuggestKeywords(directiveAndDeclarationKeywords,
         relevance: DART_RELEVANCE_HIGH);
   }
 
   test_partial_class() async {
     addTestSource('cl^');
     await computeSuggestions();
-    assertSuggestKeywords(DIRECTIVE_DECLARATION_AND_LIBRARY_KEYWORDS,
+    assertSuggestKeywords(directiveDeclarationAndLibraryKeywords,
         relevance: DART_RELEVANCE_HIGH);
   }
 
   test_partial_class2() async {
     addTestSource('library a; cl^');
     await computeSuggestions();
-    assertSuggestKeywords(DIRECTIVE_AND_DECLARATION_KEYWORDS,
+    assertSuggestKeywords(directiveAndDeclarationKeywords,
         relevance: DART_RELEVANCE_HIGH);
   }
 
@@ -1770,6 +1901,14 @@
     assertSuggestKeywords([]);
   }
 
+  test_spreadElement() async {
+    addTestSource('''
+f() => [...^];
+''');
+    await computeSuggestions();
+    assertSuggestKeywords(KeywordContributorTest.EXPRESSION_START_NO_INSTANCE);
+  }
+
   test_switch_expression() async {
     addTestSource('main() {switch(^) {}}');
     await computeSuggestions();
@@ -1843,29 +1982,29 @@
         relevance: DART_RELEVANCE_HIGH);
   }
 
-  test_switch_statement() async {
-    addTestSource('main() {switch(1) {case 1:^}}');
-    await computeSuggestions();
-    assertSuggestKeywords(STMT_START_IN_SWITCH_OUTSIDE_CLASS);
-  }
-
-  test_switch_statement2() async {
+  test_switch_statement_insideClass() async {
     addTestSource('class A{foo() {switch(1) {case 1:^}}}');
     await computeSuggestions();
-    assertSuggestKeywords(STMT_START_IN_SWITCH_IN_CLASS);
+    assertSuggestKeywords(statementStartInSwitchInClass);
+  }
+
+  test_switch_statement_outsideClass() async {
+    addTestSource('main() {switch(1) {case 1:^}}');
+    await computeSuggestions();
+    assertSuggestKeywords(statementStartInSwitchOutsideClass);
   }
 
   test_while_break_continue() async {
     addTestSource('main() {while (true) {^}}');
     await computeSuggestions();
-    assertSuggestKeywords(STMT_START_IN_LOOP_OUTSIDE_CLASS,
+    assertSuggestKeywords(statementStartInLoopOutsideClass,
         relevance: DART_RELEVANCE_KEYWORD);
   }
 
   test_while_break_continue2() async {
     addTestSource('class A {foo() {while (true) {^}}}');
     await computeSuggestions();
-    assertSuggestKeywords(STMT_START_IN_LOOP_IN_CLASS,
+    assertSuggestKeywords(statementStartInLoopInClass,
         relevance: DART_RELEVANCE_KEYWORD);
   }
 
@@ -1886,151 +2025,65 @@
 }
 
 @reflectiveTest
-class KeywordContributorWithUiAsCodeTest extends KeywordContributorTest {
-  static const List<Keyword> COLLECTION_ELEMENT_START = const [
-    Keyword.CONST,
-    Keyword.FALSE,
-    Keyword.FOR,
-    Keyword.IF,
-    Keyword.NEW,
-    Keyword.NULL,
-    Keyword.TRUE,
-  ];
+class KeywordContributorWithNnbdTest extends KeywordContributorTest {
+  @override
+  List<Keyword> get classBodyKeywords =>
+      super.classBodyKeywords..add(Keyword.LATE);
+
+  @override
+  List<Keyword> get constructorParameter =>
+      super.constructorParameter..add(Keyword.REQUIRED);
+
+  @override
+  List<Keyword> get declarationKeywords =>
+      super.declarationKeywords..add(Keyword.LATE);
+
+  @override
+  List<Keyword> get directiveAndDeclarationKeywords =>
+      super.directiveAndDeclarationKeywords..add(Keyword.LATE);
+
+  @override
+  List<Keyword> get directiveDeclarationAndLibraryKeywords =>
+      super.directiveDeclarationAndLibraryKeywords..add(Keyword.LATE);
+
+  @override
+  List<Keyword> get directiveDeclarationKeywords =>
+      super.directiveDeclarationKeywords..add(Keyword.LATE);
+
+  @override
+  List<Keyword> get methodParameter =>
+      super.methodParameter..add(Keyword.REQUIRED);
+
+  @override
+  List<Keyword> get statementStartInClass =>
+      super.statementStartInClass..add(Keyword.LATE);
+
+  @override
+  List<Keyword> get statementStartInLoopInClass =>
+      super.statementStartInLoopInClass..add(Keyword.LATE);
+
+  @override
+  List<Keyword> get statementStartInLoopOutsideClass =>
+      super.statementStartInLoopOutsideClass..add(Keyword.LATE);
+
+  @override
+  List<Keyword> get statementStartInSwitchInClass =>
+      super.statementStartInSwitchInClass..add(Keyword.LATE);
+
+  @override
+  List<Keyword> get statementStartInSwitchOutsideClass =>
+      super.statementStartInSwitchOutsideClass..add(Keyword.LATE);
+
+  @override
+  List<Keyword> get statementStartOutsideClass =>
+      super.statementStartOutsideClass..add(Keyword.LATE);
+
+  @override
+  List<Keyword> get staticMember => super.staticMember..add(Keyword.LATE);
 
   @override
   void setupResourceProvider() {
     super.setupResourceProvider();
-    createAnalysisOptionsFile(experiments: [
-      EnableString.control_flow_collections,
-      EnableString.spread_collections
-    ]);
-  }
-
-  test_ifOrForElement_forElement() async {
-    addTestSource('''
-f() => [for (var e in c) ^];
-''');
-    await computeSuggestions();
-    assertSuggestKeywords(COLLECTION_ELEMENT_START);
-  }
-
-  test_ifOrForElement_ifElement_else() async {
-    addTestSource('''
-f() => [if (true) 1 else ^];
-''');
-    await computeSuggestions();
-    assertSuggestKeywords(COLLECTION_ELEMENT_START);
-  }
-
-  test_ifOrForElement_ifElement_then() async {
-    addTestSource('''
-f() => [if (true) ^];
-''');
-    await computeSuggestions();
-    assertSuggestKeywords(COLLECTION_ELEMENT_START);
-  }
-
-  test_ifOrForElement_list_empty() async {
-    addTestSource('''
-f() => [^];
-''');
-    await computeSuggestions();
-    assertSuggestKeywords(COLLECTION_ELEMENT_START);
-  }
-
-  test_ifOrForElement_list_first() async {
-    addTestSource('''
-f() => [^1, 2];
-''');
-    await computeSuggestions();
-    assertSuggestKeywords(COLLECTION_ELEMENT_START);
-  }
-
-  test_ifOrForElement_list_last() async {
-    addTestSource('''
-f() => [1, 2, ^];
-''');
-    await computeSuggestions();
-    assertSuggestKeywords(COLLECTION_ELEMENT_START);
-  }
-
-  test_ifOrForElement_list_middle() async {
-    addTestSource('''
-f() => [1, ^, 2];
-''');
-    await computeSuggestions();
-    assertSuggestKeywords(COLLECTION_ELEMENT_START);
-  }
-
-  test_ifOrForElement_map_empty() async {
-    addTestSource('''
-f() => <String, int>{^};
-''');
-    await computeSuggestions();
-    assertSuggestKeywords(COLLECTION_ELEMENT_START);
-  }
-
-  test_ifOrForElement_map_first() async {
-    addTestSource('''
-f() => <String, int>{^'a' : 1};
-''');
-    await computeSuggestions();
-    assertSuggestKeywords(COLLECTION_ELEMENT_START);
-  }
-
-  test_ifOrForElement_map_last() async {
-    addTestSource('''
-f() => <String, int>{'a' : 1, 'b' : 2, ^};
-''');
-    await computeSuggestions();
-    assertSuggestKeywords(COLLECTION_ELEMENT_START);
-  }
-
-  test_ifOrForElement_map_middle() async {
-    addTestSource('''
-f() => <String, int>{'a' : 1, ^, 'b' : 2];
-''');
-    await computeSuggestions();
-    assertSuggestKeywords(COLLECTION_ELEMENT_START);
-  }
-
-  test_ifOrForElement_set_empty() async {
-    addTestSource('''
-f() => <int>{^};
-''');
-    await computeSuggestions();
-    assertSuggestKeywords(COLLECTION_ELEMENT_START);
-  }
-
-  test_ifOrForElement_set_first() async {
-    addTestSource('''
-f() => <int>{^1, 2};
-''');
-    await computeSuggestions();
-    assertSuggestKeywords(COLLECTION_ELEMENT_START);
-  }
-
-  test_ifOrForElement_set_last() async {
-    addTestSource('''
-f() => <int>{1, 2, ^};
-''');
-    await computeSuggestions();
-    assertSuggestKeywords(COLLECTION_ELEMENT_START);
-  }
-
-  test_ifOrForElement_set_middle() async {
-    addTestSource('''
-f() => <int>{1, ^, 2};
-''');
-    await computeSuggestions();
-    assertSuggestKeywords(COLLECTION_ELEMENT_START);
-  }
-
-  test_spreadElement() async {
-    addTestSource('''
-f() => [...^];
-''');
-    await computeSuggestions();
-    assertSuggestKeywords(KeywordContributorTest.EXPRESSION_START_NO_INSTANCE);
+    createAnalysisOptionsFile(experiments: [EnableString.non_nullable]);
   }
 }