From 000a3eb3f7103b386d34884285207aecbeab7b8a Mon Sep 17 00:00:00 2001 From: Brian Wilkerson Date: Thu, 25 Apr 2019 13:24:50 +0000 Subject: [PATCH] Add completion support for late and required Change-Id: I418aaa3aea9e6da6bcaf02e00c7e329e91175bbd Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/100467 Reviewed-by: Konstantin Shcheglov Commit-Queue: Brian Wilkerson --- .../completion/dart/completion_dart.dart | 7 + .../completion/dart/completion_manager.dart | 5 + .../completion/dart/keyword_contributor.dart | 25 +- .../dart/keyword_contributor_test.dart | 965 +++++++++--------- 4 files changed, 542 insertions(+), 460 deletions(-) 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 26a80284273..18e26c57b55 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'; @@ -48,6 +49,12 @@ abstract class DartCompletionRequest extends CompletionRequest { */ List 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 */ 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 942ace080bb..ff5c730659f 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/static_member_contr 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'; @@ -333,6 +334,10 @@ class DartCompletionRequestImpl implements DartCompletionRequest { List get enabledExperiments => 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 9da6534d6bc..b68e34a8b8c 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 'dart:async'; 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 @@ class _KeywordVisitor extends GeneralizingAstVisitor { 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 @@ class _KeywordVisitor extends GeneralizingAstVisitor { } 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 @@ class _KeywordVisitor extends GeneralizingAstVisitor { Keyword.VAR, Keyword.VOID ]); + if (request.featureSet.isEnabled(Feature.non_nullable)) { + _addSuggestion(Keyword.LATE); + } } void _addClassDeclarationKeywords(ClassDeclaration node) { @@ -661,9 +674,7 @@ class _KeywordVisitor extends GeneralizingAstVisitor { } void _addCollectionElementKeywords() { - List 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 @@ class _KeywordVisitor extends GeneralizingAstVisitor { 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 @@ class _KeywordVisitor extends GeneralizingAstVisitor { 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 2955d79ed91..0bd591fb7d2 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 @@ import 'completion_contributor_util.dart'; main() { defineReflectiveSuite(() { defineReflectiveTests(KeywordContributorTest); - defineReflectiveTests(KeywordContributorWithUiAsCodeTest); + defineReflectiveTests(KeywordContributorWithNnbdTest); }); } @reflectiveTest class KeywordContributorTest extends DartCompletionContributorTest { - static const List CLASS_BODY_KEYWORDS = const [ + static const List 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 DECLARATION_KEYWORDS = const [ - Keyword.ABSTRACT, - Keyword.CLASS, - Keyword.CONST, - Keyword.COVARIANT, - Keyword.DYNAMIC, - Keyword.FINAL, - Keyword.TYPEDEF, - Keyword.VAR, - Keyword.VOID - ]; - - static const List 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 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 NO_PSEUDO_KEYWORDS = const []; - static const List 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 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 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 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 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 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 EXPRESSION_START_INSTANCE = const [ Keyword.CONST, Keyword.FALSE, @@ -217,6 +51,190 @@ class KeywordContributorTest extends DartCompletionContributorTest { Keyword.TRUE, ]; + List 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 get constructorParameter => [Keyword.COVARIANT, Keyword.THIS]; + + List get declarationKeywords => [ + Keyword.ABSTRACT, + Keyword.CLASS, + Keyword.CONST, + Keyword.COVARIANT, + Keyword.DYNAMIC, + Keyword.FINAL, + Keyword.TYPEDEF, + Keyword.VAR, + Keyword.VOID + ]; + + List 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 get directiveDeclarationAndLibraryKeywords => + directiveDeclarationKeywords..add(Keyword.LIBRARY); + + List 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 get methodParameter => [Keyword.COVARIANT]; + + List 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 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 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 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 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 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 get staticMember => + [Keyword.CONST, Keyword.COVARIANT, Keyword.FINAL]; + void assertSuggestKeywords(Iterable expectedKeywords, {List pseudoKeywords: NO_PSEUDO_KEYWORDS, int relevance: DART_RELEVANCE_KEYWORD}) { @@ -287,29 +305,29 @@ class KeywordContributorTest extends DartCompletionContributorTest { 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 @@ class KeywordContributorTest extends DartCompletionContributorTest { // 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 @@ class KeywordContributorTest extends DartCompletionContributorTest { 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 @@ class KeywordContributorTest extends DartCompletionContributorTest { var keywords = []; 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 @@ class KeywordContributorTest extends DartCompletionContributorTest { var keywords = []; 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 @@ class KeywordContributorTest extends DartCompletionContributorTest { var keywords = []; 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 @@ class KeywordContributorTest extends DartCompletionContributorTest { var keywords = []; 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 @@ class KeywordContributorTest extends DartCompletionContributorTest { var keywords = []; 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 @@ class KeywordContributorTest extends DartCompletionContributorTest { var keywords = []; 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 @@ class KeywordContributorTest extends DartCompletionContributorTest { var keywords = []; 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 @@ class KeywordContributorTest extends DartCompletionContributorTest { var keywords = []; 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 @@ class KeywordContributorTest extends DartCompletionContributorTest { addTestSource('main() {try {} catch (e) {^}}}'); await computeSuggestions(); var keywords = []; - keywords.addAll(STMT_START_OUTSIDE_CLASS); + keywords.addAll(statementStartOutsideClass); keywords.add(Keyword.RETHROW); assertSuggestKeywords(keywords); } @@ -688,25 +696,25 @@ class KeywordContributorTest extends DartCompletionContributorTest { 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 @@ class C { } '''); await computeSuggestions(); - assertSuggestKeywords([Keyword.CONST, Keyword.COVARIANT, Keyword.FINAL]); + assertSuggestKeywords(staticMember); } test_class_member_final_afterStatic() async { @@ -785,7 +793,7 @@ class C { } '''); await computeSuggestions(); - assertSuggestKeywords([Keyword.CONST, Keyword.COVARIANT, Keyword.FINAL]); + assertSuggestKeywords(staticMember); } test_class_name() async { @@ -851,50 +859,50 @@ class C { 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 @@ class C { 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 @@ class C { 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 @@ class C { 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 @@ class C { 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 @@ class A { } '''); await computeSuggestions(); - assertSuggestKeywords(STMT_START_OUTSIDE_CLASS); + assertSuggestKeywords(statementStartOutsideClass); } test_function_body_inClass_constructorInitializer_async() async { @@ -995,7 +1003,8 @@ class A { } '''); 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 @@ class A { } '''); await computeSuggestions(); - assertSuggestKeywords(STMT_START_OUTSIDE_CLASS, + assertSuggestKeywords(statementStartOutsideClass, pseudoKeywords: ['await', 'yield', 'yield*']); } @@ -1018,7 +1027,7 @@ class A { } '''); await computeSuggestions(); - assertSuggestKeywords(STMT_START_OUTSIDE_CLASS); + assertSuggestKeywords(statementStartOutsideClass); } test_function_body_inClass_methodBody() async { @@ -1030,7 +1039,7 @@ class A { } '''); await computeSuggestions(); - assertSuggestKeywords(STMT_START_IN_CLASS); + assertSuggestKeywords(statementStartInClass); } test_function_body_inClass_methodBody_inFunction() async { @@ -1044,7 +1053,7 @@ class A { } '''); await computeSuggestions(); - assertSuggestKeywords(STMT_START_IN_CLASS); + assertSuggestKeywords(statementStartInClass); } test_function_body_inClass_methodBody_inFunction_async() async { @@ -1058,7 +1067,7 @@ class A { } '''); 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 @@ class A { } '''); 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 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 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 keywords = []; + keywords.addAll(statementStartOutsideClass); + keywords.add(Keyword.ELSE); + assertSuggestKeywords(keywords, relevance: DART_RELEVANCE_KEYWORD); } test_if_condition_isKeyword() async { @@ -1189,49 +1205,169 @@ class A { 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() => {^}; +'''); + await computeSuggestions(); + assertSuggestKeywords(COLLECTION_ELEMENT_START); + } + + test_ifOrForElement_map_first() async { + addTestSource(''' +f() => {^'a' : 1}; +'''); + await computeSuggestions(); + assertSuggestKeywords(COLLECTION_ELEMENT_START); + } + + test_ifOrForElement_map_last() async { + addTestSource(''' +f() => {'a' : 1, 'b' : 2, ^}; +'''); + await computeSuggestions(); + assertSuggestKeywords(COLLECTION_ELEMENT_START); + } + + test_ifOrForElement_map_middle() async { + addTestSource(''' +f() => {'a' : 1, ^, 'b' : 2]; +'''); + await computeSuggestions(); + assertSuggestKeywords(COLLECTION_ELEMENT_START); + } + + test_ifOrForElement_set_empty() async { + addTestSource(''' +f() => {^}; +'''); + await computeSuggestions(); + assertSuggestKeywords(COLLECTION_ELEMENT_START); + } + + test_ifOrForElement_set_first() async { + addTestSource(''' +f() => {^1, 2}; +'''); + await computeSuggestions(); + assertSuggestKeywords(COLLECTION_ELEMENT_START); + } + + test_ifOrForElement_set_last() async { + addTestSource(''' +f() => {1, 2, ^}; +'''); + await computeSuggestions(); + assertSuggestKeywords(COLLECTION_ELEMENT_START); + } + + test_ifOrForElement_set_middle() async { + addTestSource(''' +f() => {1, ^, 2}; +'''); + await computeSuggestions(); + assertSuggestKeywords(COLLECTION_ELEMENT_START); } test_import() async { @@ -1370,7 +1506,7 @@ class A { 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 @@ class A { 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 @@ class A { 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 @@ class A { 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 @@ class A { 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 @@ class A { 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 @@ class A { test_library() async { addTestSource('library foo;^'); await computeSuggestions(); - assertSuggestKeywords(DIRECTIVE_AND_DECLARATION_KEYWORDS, + assertSuggestKeywords(directiveAndDeclarationKeywords, relevance: DART_RELEVANCE_HIGH); } @@ -1483,7 +1619,7 @@ class A { test_method_async() async { addTestSource('class A { foo() ^}'); await computeSuggestions(); - assertSuggestKeywords(CLASS_BODY_KEYWORDS, + assertSuggestKeywords(classBodyKeywords, pseudoKeywords: ['async', 'async*', 'sync*']); } @@ -1498,34 +1634,29 @@ class A { 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 @@ class A { 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 @@ class A { 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 @@ class A { 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 @@ class A { 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 @@ class A { 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 @@ class A { 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 @@ class A { 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 @@ class A { 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 @@ class A { 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 @@ class A { } @reflectiveTest -class KeywordContributorWithUiAsCodeTest extends KeywordContributorTest { - static const List COLLECTION_ELEMENT_START = const [ - Keyword.CONST, - Keyword.FALSE, - Keyword.FOR, - Keyword.IF, - Keyword.NEW, - Keyword.NULL, - Keyword.TRUE, - ]; +class KeywordContributorWithNnbdTest extends KeywordContributorTest { + @override + List get classBodyKeywords => + super.classBodyKeywords..add(Keyword.LATE); + + @override + List get constructorParameter => + super.constructorParameter..add(Keyword.REQUIRED); + + @override + List get declarationKeywords => + super.declarationKeywords..add(Keyword.LATE); + + @override + List get directiveAndDeclarationKeywords => + super.directiveAndDeclarationKeywords..add(Keyword.LATE); + + @override + List get directiveDeclarationAndLibraryKeywords => + super.directiveDeclarationAndLibraryKeywords..add(Keyword.LATE); + + @override + List get directiveDeclarationKeywords => + super.directiveDeclarationKeywords..add(Keyword.LATE); + + @override + List get methodParameter => + super.methodParameter..add(Keyword.REQUIRED); + + @override + List get statementStartInClass => + super.statementStartInClass..add(Keyword.LATE); + + @override + List get statementStartInLoopInClass => + super.statementStartInLoopInClass..add(Keyword.LATE); + + @override + List get statementStartInLoopOutsideClass => + super.statementStartInLoopOutsideClass..add(Keyword.LATE); + + @override + List get statementStartInSwitchInClass => + super.statementStartInSwitchInClass..add(Keyword.LATE); + + @override + List get statementStartInSwitchOutsideClass => + super.statementStartInSwitchOutsideClass..add(Keyword.LATE); + + @override + List get statementStartOutsideClass => + super.statementStartOutsideClass..add(Keyword.LATE); + + @override + List 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() => {^}; -'''); - await computeSuggestions(); - assertSuggestKeywords(COLLECTION_ELEMENT_START); - } - - test_ifOrForElement_map_first() async { - addTestSource(''' -f() => {^'a' : 1}; -'''); - await computeSuggestions(); - assertSuggestKeywords(COLLECTION_ELEMENT_START); - } - - test_ifOrForElement_map_last() async { - addTestSource(''' -f() => {'a' : 1, 'b' : 2, ^}; -'''); - await computeSuggestions(); - assertSuggestKeywords(COLLECTION_ELEMENT_START); - } - - test_ifOrForElement_map_middle() async { - addTestSource(''' -f() => {'a' : 1, ^, 'b' : 2]; -'''); - await computeSuggestions(); - assertSuggestKeywords(COLLECTION_ELEMENT_START); - } - - test_ifOrForElement_set_empty() async { - addTestSource(''' -f() => {^}; -'''); - await computeSuggestions(); - assertSuggestKeywords(COLLECTION_ELEMENT_START); - } - - test_ifOrForElement_set_first() async { - addTestSource(''' -f() => {^1, 2}; -'''); - await computeSuggestions(); - assertSuggestKeywords(COLLECTION_ELEMENT_START); - } - - test_ifOrForElement_set_last() async { - addTestSource(''' -f() => {1, 2, ^}; -'''); - await computeSuggestions(); - assertSuggestKeywords(COLLECTION_ELEMENT_START); - } - - test_ifOrForElement_set_middle() async { - addTestSource(''' -f() => {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]); } }