blob: 0d839ecb354a080f42832157bca46864d4dc85a5 [file] [log] [blame]
// Copyright (c) 2014, the Dart project authors. Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.
import 'package:analysis_server/src/provisional/completion/dart/completion_dart.dart';
import 'package:analysis_server/src/services/completion/dart/completion_manager.dart';
import 'package:analysis_server/src/services/completion/dart/keyword_contributor.dart';
import 'package:analysis_server/src/services/completion/dart/suggestion_builder.dart';
import 'package:analyzer/dart/analysis/features.dart';
import 'package:analyzer/dart/ast/token.dart';
import 'package:analyzer/src/dart/analysis/experiments.dart';
import 'package:analyzer_plugin/protocol/protocol_common.dart';
import 'package:test/test.dart';
import 'package:test_reflective_loader/test_reflective_loader.dart';
import 'completion_contributor_util.dart';
void main() {
defineReflectiveSuite(() {
defineReflectiveTests(KeywordContributorTest);
});
}
@reflectiveTest
class KeywordContributorTest extends DartCompletionContributorTest {
static const List<Keyword> COLLECTION_ELEMENT_START = [
Keyword.CONST,
Keyword.FALSE,
Keyword.FOR,
Keyword.IF,
Keyword.NULL,
Keyword.TRUE,
];
static const List<String> NO_PSEUDO_KEYWORDS = [];
static const List<Keyword> EXPRESSION_START_INSTANCE = [
Keyword.CONST,
Keyword.FALSE,
Keyword.NULL,
Keyword.SUPER,
Keyword.THIS,
Keyword.TRUE,
];
static const List<Keyword> EXPRESSION_START_NO_INSTANCE = [
Keyword.CONST,
Keyword.FALSE,
Keyword.NULL,
Keyword.TRUE,
];
List<Keyword> get classBodyKeywords {
var keywords = <Keyword>[
Keyword.CONST,
Keyword.COVARIANT,
Keyword.DYNAMIC,
Keyword.FACTORY,
Keyword.FINAL,
Keyword.GET,
Keyword.OPERATOR,
Keyword.SET,
Keyword.STATIC,
Keyword.VAR,
Keyword.VOID
];
if (isEnabled(ExperimentalFeatures.non_nullable)) {
keywords.add(Keyword.LATE);
}
return keywords;
}
List<Keyword> get constructorParameter {
var keywords = <Keyword>[
Keyword.COVARIANT,
Keyword.DYNAMIC,
Keyword.SUPER,
Keyword.THIS,
Keyword.VOID
];
return keywords;
}
List<Keyword> get constructorParameter_language215 {
var keywords = <Keyword>[
Keyword.COVARIANT,
Keyword.DYNAMIC,
Keyword.THIS,
Keyword.VOID
];
return keywords;
}
List<Keyword> get declarationKeywords {
var keywords = <Keyword>[
Keyword.ABSTRACT,
Keyword.CLASS,
Keyword.CONST,
Keyword.COVARIANT,
Keyword.DYNAMIC,
Keyword.EXTENSION,
Keyword.FINAL,
Keyword.TYPEDEF,
Keyword.VAR,
Keyword.VOID
];
if (isEnabled(ExperimentalFeatures.non_nullable)) {
keywords.add(Keyword.LATE);
}
return keywords;
}
List<Keyword> get directiveAndDeclarationKeywords {
var keywords = <Keyword>[
Keyword.ABSTRACT,
Keyword.CLASS,
Keyword.CONST,
Keyword.COVARIANT,
Keyword.DYNAMIC,
Keyword.EXPORT,
Keyword.EXTENSION,
Keyword.FINAL,
Keyword.IMPORT,
Keyword.PART,
Keyword.TYPEDEF,
Keyword.VAR,
Keyword.VOID
];
if (isEnabled(ExperimentalFeatures.non_nullable)) {
keywords.add(Keyword.LATE);
}
return keywords;
}
List<Keyword> get directiveDeclarationAndLibraryKeywords {
var keywords = directiveDeclarationKeywords..add(Keyword.LIBRARY);
if (isEnabled(ExperimentalFeatures.non_nullable)) {
keywords.add(Keyword.LATE);
}
return keywords;
}
List<Keyword> get directiveDeclarationKeywords {
var keywords = <Keyword>[
Keyword.ABSTRACT,
Keyword.CLASS,
Keyword.CONST,
Keyword.COVARIANT,
Keyword.DYNAMIC,
Keyword.EXPORT,
Keyword.EXTENSION,
Keyword.FINAL,
Keyword.IMPORT,
Keyword.PART,
Keyword.TYPEDEF,
Keyword.VAR,
Keyword.VOID
];
if (isEnabled(ExperimentalFeatures.non_nullable)) {
keywords.add(Keyword.LATE);
}
return keywords;
}
List<Keyword> get extensionBodyKeywords {
var keywords = [
Keyword.CONST,
Keyword.DYNAMIC,
Keyword.FINAL,
Keyword.GET,
Keyword.OPERATOR,
Keyword.SET,
Keyword.STATIC,
Keyword.VAR,
Keyword.VOID
];
if (isEnabled(ExperimentalFeatures.non_nullable)) {
keywords.add(Keyword.LATE);
}
return keywords;
}
List<Keyword> get methodParameter {
var keywords = <Keyword>[Keyword.COVARIANT, Keyword.DYNAMIC, Keyword.VOID];
return keywords;
}
List<Keyword> get statementStartInClass {
var keywords = <Keyword>[
Keyword.ASSERT,
Keyword.CONST,
Keyword.DO,
Keyword.DYNAMIC,
Keyword.FINAL,
Keyword.FOR,
Keyword.IF,
Keyword.RETURN,
Keyword.SUPER,
Keyword.SWITCH,
Keyword.THIS,
Keyword.THROW,
Keyword.TRY,
Keyword.VAR,
Keyword.VOID,
Keyword.WHILE
];
if (isEnabled(ExperimentalFeatures.non_nullable)) {
keywords.add(Keyword.LATE);
}
return keywords;
}
List<Keyword> get statementStartInLoopInClass {
var keywords = <Keyword>[
Keyword.ASSERT,
Keyword.BREAK,
Keyword.CONST,
Keyword.CONTINUE,
Keyword.DO,
Keyword.DYNAMIC,
Keyword.FINAL,
Keyword.FOR,
Keyword.IF,
Keyword.RETURN,
Keyword.SUPER,
Keyword.SWITCH,
Keyword.THIS,
Keyword.THROW,
Keyword.TRY,
Keyword.VAR,
Keyword.VOID,
Keyword.WHILE
];
if (isEnabled(ExperimentalFeatures.non_nullable)) {
keywords.add(Keyword.LATE);
}
return keywords;
}
List<Keyword> get statementStartInLoopOutsideClass {
var keywords = <Keyword>[
Keyword.ASSERT,
Keyword.BREAK,
Keyword.CONST,
Keyword.CONTINUE,
Keyword.DO,
Keyword.DYNAMIC,
Keyword.FINAL,
Keyword.FOR,
Keyword.IF,
Keyword.RETURN,
Keyword.SWITCH,
Keyword.THROW,
Keyword.TRY,
Keyword.VAR,
Keyword.VOID,
Keyword.WHILE
];
if (isEnabled(ExperimentalFeatures.non_nullable)) {
keywords.add(Keyword.LATE);
}
return keywords;
}
List<Keyword> get statementStartInSwitchCaseInClass {
var keywords = <Keyword>[
Keyword.ASSERT,
Keyword.BREAK,
Keyword.CONST,
Keyword.DO,
Keyword.DYNAMIC,
Keyword.FINAL,
Keyword.FOR,
Keyword.IF,
Keyword.RETURN,
Keyword.SUPER,
Keyword.THIS,
Keyword.SWITCH,
Keyword.THROW,
Keyword.TRY,
Keyword.VAR,
Keyword.VOID,
Keyword.WHILE
];
if (isEnabled(ExperimentalFeatures.non_nullable)) {
keywords.add(Keyword.LATE);
}
return keywords;
}
List<Keyword> get statementStartInSwitchCaseOutsideClass {
var keywords = <Keyword>[
Keyword.ASSERT,
Keyword.BREAK,
Keyword.CONST,
Keyword.DO,
Keyword.DYNAMIC,
Keyword.FINAL,
Keyword.FOR,
Keyword.IF,
Keyword.RETURN,
Keyword.SWITCH,
Keyword.THROW,
Keyword.TRY,
Keyword.VAR,
Keyword.VOID,
Keyword.WHILE
];
if (isEnabled(ExperimentalFeatures.non_nullable)) {
keywords.add(Keyword.LATE);
}
return keywords;
}
List<Keyword> get statementStartInSwitchInClass {
var keywords = <Keyword>[
Keyword.ASSERT,
Keyword.BREAK,
Keyword.CASE,
Keyword.CONST,
Keyword.DEFAULT,
Keyword.DO,
Keyword.DYNAMIC,
Keyword.FINAL,
Keyword.FOR,
Keyword.IF,
Keyword.RETURN,
Keyword.SUPER,
Keyword.SWITCH,
Keyword.THIS,
Keyword.THROW,
Keyword.TRY,
Keyword.VAR,
Keyword.VOID,
Keyword.WHILE
];
if (isEnabled(ExperimentalFeatures.non_nullable)) {
keywords.add(Keyword.LATE);
}
return keywords;
}
List<Keyword> get statementStartInSwitchOutsideClass {
var keywords = <Keyword>[
Keyword.ASSERT,
Keyword.BREAK,
Keyword.CASE,
Keyword.CONST,
Keyword.DEFAULT,
Keyword.DO,
Keyword.DYNAMIC,
Keyword.FINAL,
Keyword.FOR,
Keyword.IF,
Keyword.RETURN,
Keyword.SWITCH,
Keyword.THROW,
Keyword.TRY,
Keyword.VAR,
Keyword.VOID,
Keyword.WHILE
];
if (isEnabled(ExperimentalFeatures.non_nullable)) {
keywords.add(Keyword.LATE);
}
return keywords;
}
List<Keyword> get statementStartOutsideClass {
var keywords = <Keyword>[
Keyword.ASSERT,
Keyword.CONST,
Keyword.DO,
Keyword.DYNAMIC,
Keyword.FINAL,
Keyword.FOR,
Keyword.IF,
Keyword.RETURN,
Keyword.SWITCH,
Keyword.THROW,
Keyword.TRY,
Keyword.VAR,
Keyword.VOID,
Keyword.WHILE
];
if (isEnabled(ExperimentalFeatures.non_nullable)) {
keywords.add(Keyword.LATE);
}
return keywords;
}
List<Keyword> get staticMember {
var keywords = <Keyword>[
Keyword.ABSTRACT,
Keyword.CONST,
Keyword.COVARIANT,
Keyword.DYNAMIC,
Keyword.EXTERNAL,
Keyword.FINAL
];
if (isEnabled(ExperimentalFeatures.non_nullable)) {
keywords.add(Keyword.LATE);
}
return keywords;
}
void assertSuggestKeywords(Iterable<Keyword> expectedKeywords,
{List<String> pseudoKeywords = NO_PSEUDO_KEYWORDS}) {
var expectedCompletions = <String>{};
var expectedOffsets = <String, int>{};
var actualCompletions = <String>{};
expectedCompletions.addAll(expectedKeywords.map((keyword) {
var text = keyword.lexeme;
if (['import', 'export', 'part'].contains(text)) {
return '$text \'\';';
} else if (text == 'default') {
return '$text:';
}
return text;
}));
expectedCompletions.addAll(pseudoKeywords);
for (var s in suggestions) {
if (s.kind == CompletionSuggestionKind.KEYWORD) {
var k = Keyword.keywords[s.completion];
if (k == null && !expectedCompletions.contains(s.completion)) {
fail('Invalid keyword suggested: ${s.completion}');
} else {
if (!actualCompletions.add(s.completion)) {
fail('Duplicate keyword suggested: ${s.completion}');
}
}
}
}
if (!_equalSets(expectedCompletions, actualCompletions)) {
var msg = StringBuffer();
msg.writeln('Expected:');
_appendCompletions(msg, expectedCompletions, actualCompletions);
msg.writeln('but found:');
_appendCompletions(msg, actualCompletions, expectedCompletions);
fail(msg.toString());
}
for (var s in suggestions) {
if (s.kind == CompletionSuggestionKind.KEYWORD) {
var expectedOffset = expectedOffsets[s.completion];
expectedOffset ??= s.completion.length;
expect(
s.selectionOffset,
equals(s.completion.endsWith('\'\';')
? expectedOffset - 2
: expectedOffset));
expect(s.selectionLength, equals(0));
expect(s.isDeprecated, equals(false));
expect(s.isPotential, equals(false));
}
}
}
@override
DartCompletionContributor createContributor(
DartCompletionRequest request,
SuggestionBuilder builder,
) {
return KeywordContributor(request, builder);
}
/// Return `true` if the given [feature] is enabled.
bool isEnabled(Feature feature) =>
result.libraryElement.featureSet.isEnabled(feature);
Future<void> test_after_class_noPrefix() async {
addTestSource('class A {} ^');
await computeSuggestions();
assertSuggestKeywords(declarationKeywords);
}
Future<void> test_after_class_prefix() async {
addTestSource('class A {} c^');
await computeSuggestions();
assertSuggestKeywords(declarationKeywords);
}
Future<void> test_after_import_noPrefix() async {
addTestSource('import "foo"; ^');
await computeSuggestions();
assertSuggestKeywords(directiveAndDeclarationKeywords);
}
Future<void> test_after_import_prefix() async {
addTestSource('import "foo"; c^');
await computeSuggestions();
assertSuggestKeywords(directiveAndDeclarationKeywords);
}
Future<void> test_anonymous_function_async() async {
addTestSource('void f() {foo(() ^ {}}}');
await computeSuggestions();
assertSuggestKeywords([], pseudoKeywords: ['async', 'async*', 'sync*']);
}
Future<void> test_anonymous_function_async2() async {
addTestSource('void f() {foo(() a^ {}}}');
await computeSuggestions();
// Fasta adds a closing paren after the first `}`
// and reports a single function expression argument
// while analyzer adds the closing paren before the `a`
// and adds synthetic `;`s making `a` a statement.
assertSuggestKeywords([], pseudoKeywords: ['async', 'async*', 'sync*']);
}
Future<void> test_anonymous_function_async3() async {
addTestSource('void f() {foo(() async ^ {}}}');
await computeSuggestions();
assertSuggestKeywords([]);
}
Future<void> test_anonymous_function_async4() async {
addTestSource('void f() {foo(() ^ => 2}}');
await computeSuggestions();
assertSuggestKeywords([], pseudoKeywords: ['async']);
}
Future<void> test_anonymous_function_async5() async {
addTestSource('void f() {foo(() ^}}');
await computeSuggestions();
assertSuggestKeywords(EXPRESSION_START_NO_INSTANCE,
pseudoKeywords: ['async', 'async*', 'sync*']);
}
Future<void> test_anonymous_function_async6() async {
addTestSource('void f() {foo("bar", () as^{}}');
await computeSuggestions();
assertSuggestKeywords([], pseudoKeywords: ['async', 'async*', 'sync*']);
}
Future<void> test_anonymous_function_async7() async {
addTestSource('void f() {foo("bar", () as^ => null');
await computeSuggestions();
assertSuggestKeywords([], pseudoKeywords: ['async']);
}
Future<void> test_anonymous_function_async8() async {
addTestSource('void f() {foo(() ^ {})}}');
await computeSuggestions();
assertSuggestKeywords([], pseudoKeywords: ['async', 'async*', 'sync*']);
}
Future<void> test_anonymous_function_async9() async {
addTestSource('void f() {foo(() a^ {})}}');
await computeSuggestions();
// Fasta interprets the argument as a function expression
// while analyzer adds synthetic `;`s making `a` a statement.
assertSuggestKeywords([], pseudoKeywords: ['async', 'async*', 'sync*']);
}
Future<void> test_argument() async {
addTestSource('void f() {foo(^);}');
await computeSuggestions();
assertSuggestKeywords(EXPRESSION_START_NO_INSTANCE);
}
Future<void> test_argument2() async {
addTestSource('void f() {foo(n^);}');
await computeSuggestions();
assertSuggestKeywords(EXPRESSION_START_NO_INSTANCE);
}
Future<void> test_argument_literal() async {
addTestSource('void f() {foo("^");}');
await computeSuggestions();
assertSuggestKeywords([]);
}
Future<void> test_argument_named() async {
addTestSource('void f() {foo(bar: ^);}');
await computeSuggestions();
assertSuggestKeywords(EXPRESSION_START_NO_INSTANCE);
}
Future<void> test_argument_named2() async {
addTestSource('void f() {foo(bar: n^);}');
await computeSuggestions();
assertSuggestKeywords(EXPRESSION_START_NO_INSTANCE);
}
Future<void> test_argument_named_literal() async {
addTestSource('void f() {foo(bar: "^");}');
await computeSuggestions();
assertSuggestKeywords([]);
}
Future<void> test_assignment_field() async {
addTestSource('class A {var foo = ^}');
await computeSuggestions();
assertSuggestKeywords(EXPRESSION_START_NO_INSTANCE);
}
Future<void> test_assignment_field2() async {
addTestSource('class A {var foo = n^}');
await computeSuggestions();
assertSuggestKeywords(EXPRESSION_START_NO_INSTANCE);
}
Future<void> test_assignment_local() async {
addTestSource('void f() {var foo = ^}');
await computeSuggestions();
assertSuggestKeywords(EXPRESSION_START_NO_INSTANCE);
}
Future<void> test_assignment_local2() async {
addTestSource('void f() {var foo = n^}');
await computeSuggestions();
assertSuggestKeywords(EXPRESSION_START_NO_INSTANCE);
}
Future<void> test_assignment_local2_async() async {
addTestSource('void f() async {var foo = n^}');
await computeSuggestions();
assertSuggestKeywords(EXPRESSION_START_NO_INSTANCE,
pseudoKeywords: ['await']);
}
Future<void> test_assignment_local_async() async {
addTestSource('void f() async {var foo = ^}');
await computeSuggestions();
assertSuggestKeywords(EXPRESSION_START_NO_INSTANCE,
pseudoKeywords: ['await']);
}
Future<void> test_before_import() async {
addTestSource('^ import foo;');
await computeSuggestions();
assertSuggestKeywords(
[Keyword.EXPORT, Keyword.IMPORT, Keyword.LIBRARY, Keyword.PART]);
}
Future<void> test_catch_1a() async {
// '}' Block BlockFunctionBody FunctionExpression
addTestSource('void f() {try {} ^}');
await computeSuggestions();
var keywords = <Keyword>[];
keywords.add(Keyword.CATCH);
keywords.add(Keyword.FINALLY);
assertSuggestKeywords(keywords, pseudoKeywords: ['on']);
}
Future<void> test_catch_1b() async {
// [ExpressionStatement 'c'] Block BlockFunctionBody FunctionExpression
addTestSource('void f() {try {} c^}');
await computeSuggestions();
var keywords = <Keyword>[];
keywords.add(Keyword.CATCH);
keywords.add(Keyword.FINALLY);
assertSuggestKeywords(keywords, pseudoKeywords: ['on']);
}
Future<void> test_catch_1c() async {
// [EmptyStatement] Block BlockFunction FunctionExpression
addTestSource('void f() {try {} ^;}');
await computeSuggestions();
var keywords = <Keyword>[];
keywords.add(Keyword.CATCH);
keywords.add(Keyword.FINALLY);
assertSuggestKeywords(keywords, pseudoKeywords: ['on']);
}
Future<void> test_catch_1d() async {
// [EmptyStatement] Block BlockFunction FunctionExpression
addTestSource('void f() {try {} ^ Foo foo;}');
await computeSuggestions();
var keywords = <Keyword>[];
keywords.add(Keyword.CATCH);
keywords.add(Keyword.FINALLY);
assertSuggestKeywords(keywords, pseudoKeywords: ['on']);
}
Future<void> test_catch_2a() async {
// '}' Block BlockFunctionBody FunctionExpression
addTestSource('void f() {try {} on SomeException {} ^}');
await computeSuggestions();
var keywords = <Keyword>[];
keywords.add(Keyword.CATCH);
keywords.add(Keyword.FINALLY);
keywords.addAll(statementStartOutsideClass);
assertSuggestKeywords(keywords, pseudoKeywords: ['on']);
}
Future<void> test_catch_2b() async {
// [ExpressionStatement 'c'] Block BlockFunctionBody FunctionExpression
addTestSource('void f() {try {} on SomeException {} c^}');
await computeSuggestions();
var keywords = <Keyword>[];
keywords.add(Keyword.CATCH);
keywords.add(Keyword.FINALLY);
keywords.addAll(statementStartOutsideClass);
assertSuggestKeywords(keywords, pseudoKeywords: ['on']);
}
Future<void> test_catch_2c() async {
// [EmptyStatement] Block BlockFunction FunctionExpression
addTestSource('void f() {try {} on SomeException {} ^;}');
await computeSuggestions();
var keywords = <Keyword>[];
keywords.add(Keyword.CATCH);
keywords.add(Keyword.FINALLY);
keywords.addAll(statementStartOutsideClass);
assertSuggestKeywords(keywords, pseudoKeywords: ['on']);
}
Future<void> test_catch_2d() async {
// [EmptyStatement] Block BlockFunction FunctionExpression
addTestSource('void f() {try {} on SomeException {} ^ Foo foo;}');
await computeSuggestions();
var keywords = <Keyword>[];
keywords.add(Keyword.CATCH);
keywords.add(Keyword.FINALLY);
keywords.addAll(statementStartOutsideClass);
assertSuggestKeywords(keywords, pseudoKeywords: ['on']);
}
Future<void> test_catch_3a() async {
// '}' Block BlockFunctionBody FunctionExpression
addTestSource('void f() {try {} catch (e) {} ^}');
await computeSuggestions();
var keywords = <Keyword>[];
keywords.add(Keyword.CATCH);
keywords.add(Keyword.FINALLY);
keywords.addAll(statementStartOutsideClass);
assertSuggestKeywords(keywords, pseudoKeywords: ['on']);
}
Future<void> test_catch_3b() async {
// [ExpressionStatement 'c'] Block BlockFunctionBody FunctionExpression
addTestSource('void f() {try {} catch (e) {} c^}');
await computeSuggestions();
var keywords = <Keyword>[];
keywords.add(Keyword.CATCH);
keywords.add(Keyword.FINALLY);
keywords.addAll(statementStartOutsideClass);
assertSuggestKeywords(keywords, pseudoKeywords: ['on']);
}
Future<void> test_catch_3c() async {
// [EmptyStatement] Block BlockFunction FunctionExpression
addTestSource('void f() {try {} catch (e) {} ^;}');
await computeSuggestions();
var keywords = <Keyword>[];
keywords.add(Keyword.CATCH);
keywords.add(Keyword.FINALLY);
keywords.addAll(statementStartOutsideClass);
assertSuggestKeywords(keywords, pseudoKeywords: ['on']);
}
Future<void> test_catch_3d() async {
// [EmptyStatement] Block BlockFunction FunctionExpression
addTestSource('void f() {try {} catch (e) {} ^ Foo foo;}');
await computeSuggestions();
var keywords = <Keyword>[];
keywords.add(Keyword.CATCH);
keywords.add(Keyword.FINALLY);
keywords.addAll(statementStartOutsideClass);
assertSuggestKeywords(keywords, pseudoKeywords: ['on']);
}
Future<void> test_catch_4a1() async {
// [CatchClause] TryStatement Block
addTestSource('void f() {try {} ^ on SomeException {}}');
await computeSuggestions();
var keywords = <Keyword>[];
keywords.add(Keyword.CATCH);
assertSuggestKeywords(keywords, pseudoKeywords: ['on']);
}
Future<void> test_catch_4a2() async {
// ['c' VariableDeclarationStatement] Block BlockFunctionBody
addTestSource('void f() {try {} c^ on SomeException {}}');
await computeSuggestions();
var keywords = <Keyword>[];
keywords.add(Keyword.CATCH);
// TODO(danrubel) finally should not be suggested here
keywords.add(Keyword.FINALLY);
assertSuggestKeywords(keywords, pseudoKeywords: ['on']);
}
Future<void> test_catch_4b1() async {
// [CatchClause] TryStatement Block
addTestSource('void f() {try {} ^ catch (e) {}}');
await computeSuggestions();
var keywords = <Keyword>[];
keywords.add(Keyword.CATCH);
assertSuggestKeywords(keywords, pseudoKeywords: ['on']);
}
Future<void> test_catch_4b2() async {
// ['c' ExpressionStatement] Block BlockFunctionBody
addTestSource('void f() {try {} c^ catch (e) {}}');
await computeSuggestions();
var keywords = <Keyword>[];
keywords.add(Keyword.CATCH);
// TODO(danrubel) finally should not be suggested here
keywords.add(Keyword.FINALLY);
assertSuggestKeywords(keywords, pseudoKeywords: ['on']);
}
Future<void> test_catch_4c1() async {
// ['finally'] TryStatement Block
addTestSource('void f() {try {} ^ finally {}}');
await computeSuggestions();
var keywords = <Keyword>[];
keywords.add(Keyword.CATCH);
assertSuggestKeywords(keywords, pseudoKeywords: ['on']);
}
Future<void> test_catch_4c2() async {
// ['c' ExpressionStatement] Block BlockFunctionBody
addTestSource('void f() {try {} c^ finally {}}');
await computeSuggestions();
var keywords = <Keyword>[];
keywords.add(Keyword.CATCH);
// TODO(danrubel) finally should not be suggested here
keywords.add(Keyword.FINALLY);
assertSuggestKeywords(keywords, pseudoKeywords: ['on']);
}
Future<void> test_catch_block() async {
// '}' Block CatchClause TryStatement Block
addTestSource('void f() {try {} catch (e) {^}}}');
await computeSuggestions();
var keywords = <Keyword>[];
keywords.addAll(statementStartOutsideClass);
keywords.add(Keyword.RETHROW);
assertSuggestKeywords(keywords);
}
Future<void> test_class() async {
addTestSource('class A e^ { }');
await computeSuggestions();
assertSuggestKeywords([Keyword.EXTENDS, Keyword.IMPLEMENTS]);
}
Future<void> test_class_body() async {
addTestSource('class A {^}');
await computeSuggestions();
assertSuggestKeywords(classBodyKeywords);
}
Future<void> test_class_body_beginning() async {
addTestSource('class A {^ var foo;}');
await computeSuggestions();
assertSuggestKeywords(classBodyKeywords);
}
Future<void> test_class_body_between() async {
addTestSource('class A {var bar; ^ var foo;}');
await computeSuggestions();
assertSuggestKeywords(classBodyKeywords);
}
Future<void> test_class_body_empty() async {
addTestSource('extension E on int {^}');
await computeSuggestions();
assertSuggestKeywords(extensionBodyKeywords);
}
Future<void> test_class_body_end() async {
addTestSource('class A {var foo; ^}');
await computeSuggestions();
assertSuggestKeywords(classBodyKeywords);
}
Future<void> test_class_body_return_no_whitespace() async {
addTestSource('class A { ^foo() {}}');
await computeSuggestions();
expect(suggestions, isNotEmpty);
assertSuggestKeywords(classBodyKeywords);
}
Future<void> test_class_body_return_prefix() async {
addTestSource('class A { d^ foo() {}}');
await computeSuggestions();
expect(suggestions, isNotEmpty);
assertSuggestKeywords(classBodyKeywords);
}
Future<void> test_class_body_return_whitespace() async {
addTestSource('class A { ^ foo() {}}');
await computeSuggestions();
expect(suggestions, isNotEmpty);
assertSuggestKeywords(classBodyKeywords);
}
Future<void> test_class_extends() async {
addTestSource('class A extends foo ^');
await computeSuggestions();
assertSuggestKeywords([Keyword.IMPLEMENTS, Keyword.WITH]);
}
Future<void> test_class_extends2() async {
addTestSource('class A extends foo i^');
await computeSuggestions();
assertSuggestKeywords([Keyword.IMPLEMENTS, Keyword.WITH]);
}
Future<void> test_class_extends3() async {
addTestSource('class A extends foo i^ { }');
await computeSuggestions();
assertSuggestKeywords([Keyword.IMPLEMENTS, Keyword.WITH]);
}
Future<void> test_class_extends_name() async {
addTestSource('class A extends ^');
await computeSuggestions();
assertSuggestKeywords([]);
}
Future<void> test_class_implements() async {
addTestSource('class A ^ implements foo');
await computeSuggestions();
assertSuggestKeywords([Keyword.EXTENDS]);
}
Future<void> test_class_implements2() async {
addTestSource('class A e^ implements foo');
await computeSuggestions();
assertSuggestKeywords([Keyword.EXTENDS]);
}
Future<void> test_class_implements3() async {
addTestSource('class A e^ implements foo { }');
await computeSuggestions();
assertSuggestKeywords([Keyword.EXTENDS]);
}
Future<void> test_class_implements_name() async {
addTestSource('class A implements ^');
await computeSuggestions();
assertSuggestKeywords([]);
}
Future<void> test_class_member_const_afterStatic() async {
addTestSource('''
class C {
static c^
}
''');
await computeSuggestions();
assertSuggestKeywords(staticMember);
}
Future<void> test_class_member_final_afterStatic() async {
addTestSource('''
class C {
static f^
}
''');
await computeSuggestions();
assertSuggestKeywords(staticMember);
}
Future<void> test_class_name() async {
addTestSource('class ^');
await computeSuggestions();
assertSuggestKeywords([]);
}
Future<void> test_class_noBody() async {
addTestSource('class A ^');
await computeSuggestions();
assertSuggestKeywords([Keyword.EXTENDS, Keyword.IMPLEMENTS]);
}
Future<void> test_class_noBody2() async {
addTestSource('class A e^');
await computeSuggestions();
assertSuggestKeywords([Keyword.EXTENDS, Keyword.IMPLEMENTS]);
}
Future<void> test_class_noBody3() async {
addTestSource('class A e^ String foo;');
await computeSuggestions();
assertSuggestKeywords([Keyword.EXTENDS, Keyword.IMPLEMENTS]);
}
Future<void> test_class_with() async {
addTestSource('class A extends foo with bar ^');
await computeSuggestions();
assertSuggestKeywords([Keyword.IMPLEMENTS]);
}
Future<void> test_class_with2() async {
addTestSource('class A extends foo with bar i^');
await computeSuggestions();
assertSuggestKeywords([Keyword.IMPLEMENTS]);
}
Future<void> test_class_with3() async {
addTestSource('class A extends foo with bar i^ { }');
await computeSuggestions();
assertSuggestKeywords([Keyword.IMPLEMENTS]);
}
Future<void> test_class_with_name() async {
addTestSource('class A extends foo with ^');
await computeSuggestions();
assertSuggestKeywords([]);
}
Future<void> test_constructor_initializers_first() async {
addTestSource('class A { int f; A() : ^, f = 1; }');
await computeSuggestions();
assertSuggestKeywords([Keyword.ASSERT]);
}
Future<void> test_constructor_initializers_last() async {
addTestSource('class A { A() : ^; }');
await computeSuggestions();
assertSuggestKeywords([Keyword.ASSERT, Keyword.SUPER, Keyword.THIS]);
}
Future<void> test_constructor_param_noPrefix() async {
addTestSource('class A { A(^) {}}');
await computeSuggestions();
assertSuggestKeywords(constructorParameter);
}
Future<void> test_constructor_param_noPrefix_func_parameter() async {
addTestSource('class A { A(^ Function(){}) {}}');
await computeSuggestions();
expect(suggestions, isNotEmpty);
assertSuggestKeywords(constructorParameter);
}
Future<void> test_constructor_param_noPrefix_language215() async {
addTestSource(r'''
// @dart = 2.15
class A {
A(^);
}
''');
await computeSuggestions();
assertSuggestKeywords(constructorParameter_language215);
}
Future<void> test_constructor_param_prefix() async {
addTestSource('class A { A(t^) {}}');
await computeSuggestions();
assertSuggestKeywords(constructorParameter);
}
Future<void> test_constructor_param_prefix_func_parameter() async {
addTestSource('class A { A(v^ Function(){}) {}}');
await computeSuggestions();
expect(suggestions, isNotEmpty);
assertSuggestKeywords(constructorParameter);
}
Future<void> test_do_break_continue_insideClass() async {
addTestSource('class A {foo() {do {^} while (true);}}');
await computeSuggestions();
assertSuggestKeywords(statementStartInLoopInClass);
}
Future<void> test_do_break_continue_outsideClass() async {
addTestSource('void f() {do {^} while (true);}');
await computeSuggestions();
assertSuggestKeywords(statementStartInLoopOutsideClass);
}
Future<void> test_empty() async {
addTestSource('^');
await computeSuggestions();
assertSuggestKeywords(directiveDeclarationAndLibraryKeywords);
}
Future<void> test_extension_body_beginning() async {
addTestSource('extension E on int {^ foo() {}}');
await computeSuggestions();
assertSuggestKeywords(extensionBodyKeywords);
}
Future<void> test_extension_body_between() async {
addTestSource('extension E on int {foo() {} ^ void bar() {}}');
await computeSuggestions();
assertSuggestKeywords(extensionBodyKeywords);
}
Future<void> test_extension_body_end() async {
addTestSource('extension E on int {foo() {} ^}');
await computeSuggestions();
assertSuggestKeywords(extensionBodyKeywords);
}
Future<void> test_extension_member_const_afterStatic() async {
addTestSource('''
extension E on int {
static c^
}
''');
await computeSuggestions();
assertSuggestKeywords(staticMember);
}
Future<void> test_extension_member_final_afterStatic() async {
addTestSource('''
extension E on int {
static f^
}
''');
await computeSuggestions();
assertSuggestKeywords(staticMember);
}
Future<void> test_extension_noBody_named() async {
addTestSource('extension E ^');
await computeSuggestions();
assertSuggestKeywords([Keyword.ON]);
}
Future<void> test_extension_noBody_unnamed() async {
addTestSource('extension ^');
await computeSuggestions();
assertSuggestKeywords([Keyword.ON]);
}
Future<void> test_for_break_continue_insideClass() async {
addTestSource('class A {foo() {for (int x in myList) {^}}}');
await computeSuggestions();
assertSuggestKeywords(statementStartInLoopInClass);
}
Future<void> test_for_break_continue_outsideClass() async {
addTestSource('void f() {for (int x in myList) {^}}');
await computeSuggestions();
assertSuggestKeywords(statementStartInLoopOutsideClass);
}
Future<void> test_for_expression_in() async {
addTestSource('void f() {for (int x i^)}');
await computeSuggestions();
assertSuggestKeywords([Keyword.IN]);
}
Future<void> test_for_expression_in2() async {
addTestSource('void f() {for (int x in^)}');
await computeSuggestions();
assertSuggestKeywords([Keyword.IN]);
}
Future<void> test_for_expression_in_inInitializer() async {
addTestSource('void f() {for (int i^)}');
await computeSuggestions();
assertSuggestKeywords([]);
}
Future<void> test_for_expression_init() async {
addTestSource('void f() {for (int x = i^)}');
await computeSuggestions();
assertSuggestKeywords(EXPRESSION_START_NO_INSTANCE);
}
Future<void> test_for_expression_init2() async {
addTestSource('void f() {for (int x = in^)}');
await computeSuggestions();
assertSuggestKeywords(EXPRESSION_START_NO_INSTANCE);
}
Future<void> test_for_initialization_var() async {
addTestSource('void f() {for (^)}');
await computeSuggestions();
assertSuggestKeywords([Keyword.VAR]);
}
Future<void> test_formalParameterList_beforeFunctionType() async {
addTestSource('void f(^void Function() g) {}');
await computeSuggestions();
expect(suggestions, isNotEmpty);
assertSuggestKeywords(methodParameter);
}
Future<void> test_formalParameterList_named_init() async {
addTestSource('class A { foo({bool bar: ^}) {}}');
await computeSuggestions();
expect(suggestions, isNotEmpty);
assertSuggestKeywords(EXPRESSION_START_NO_INSTANCE);
}
Future<void> test_formalParameterList_named_init2() async {
addTestSource('class A { foo({bool bar: f^}) {}}');
await computeSuggestions();
expect(suggestions, isNotEmpty);
assertSuggestKeywords(EXPRESSION_START_NO_INSTANCE);
}
Future<void> test_formalParameterList_noPrefix() async {
addTestSource('class A { foo(^) {}}');
await computeSuggestions();
expect(suggestions, isNotEmpty);
assertSuggestKeywords(methodParameter);
}
Future<void> test_formalParameterList_noPrefix_func_parameter() async {
addTestSource('class A { foo(^ Function(){}) {}}');
await computeSuggestions();
expect(suggestions, isNotEmpty);
assertSuggestKeywords(methodParameter);
}
Future<void> test_formalParameterList_positional_init() async {
addTestSource('class A { foo([bool bar = ^]) {}}');
await computeSuggestions();
expect(suggestions, isNotEmpty);
assertSuggestKeywords(EXPRESSION_START_NO_INSTANCE);
}
Future<void> test_formalParameterList_positional_init2() async {
addTestSource('class A { foo([bool bar = f^]) {}}');
await computeSuggestions();
expect(suggestions, isNotEmpty);
assertSuggestKeywords(EXPRESSION_START_NO_INSTANCE);
}
Future<void> test_formalParameterList_prefix() async {
addTestSource('class A { foo(t^) {}}');
await computeSuggestions();
expect(suggestions, isNotEmpty);
assertSuggestKeywords(methodParameter);
}
Future<void> test_formalParameterList_prefix_func_parameter() async {
addTestSource('class A { foo(v^ Function(){}) {}}');
await computeSuggestions();
expect(suggestions, isNotEmpty);
assertSuggestKeywords(methodParameter);
}
Future<void> test_function_async() async {
addTestSource('void f()^');
await computeSuggestions();
assertSuggestKeywords([], pseudoKeywords: ['async', 'async*', 'sync*']);
}
Future<void> test_function_async2() async {
addTestSource('void f()^{}');
await computeSuggestions();
assertSuggestKeywords([], pseudoKeywords: ['async', 'async*', 'sync*']);
}
Future<void> test_function_async3() async {
addTestSource('void f()a^');
await computeSuggestions();
assertSuggestKeywords(declarationKeywords,
pseudoKeywords: ['async', 'async*', 'sync*']);
}
Future<void> test_function_async4() async {
addTestSource('void f()a^{}');
await computeSuggestions();
assertSuggestKeywords([], pseudoKeywords: ['async', 'async*', 'sync*']);
}
Future<void> test_function_async5() async {
addTestSource('void f()a^ Foo foo;');
await computeSuggestions();
assertSuggestKeywords(declarationKeywords,
pseudoKeywords: ['async', 'async*', 'sync*']);
}
Future<void> test_function_body_inClass_constructorInitializer() async {
addTestSource(r'''
foo(p) {}
class A {
final f;
A() : f = foo(() {^});
}
''');
await computeSuggestions();
assertSuggestKeywords(statementStartOutsideClass);
}
Future<void> test_function_body_inClass_constructorInitializer_async() async {
addTestSource(r'''
foo(p) {}
class A {
final f;
A() : f = foo(() async {^});
}
''');
await computeSuggestions();
assertSuggestKeywords(statementStartOutsideClass,
pseudoKeywords: ['await']);
}
Future<void>
test_function_body_inClass_constructorInitializer_async_star() async {
addTestSource(r'''
foo(p) {}
class A {
final f;
A() : f = foo(() async* {^});
}
''');
await computeSuggestions();
assertSuggestKeywords(statementStartOutsideClass,
pseudoKeywords: ['await', 'yield', 'yield*']);
}
Future<void> test_function_body_inClass_field() async {
addTestSource(r'''
class A {
var f = () {^};
}
''');
await computeSuggestions();
assertSuggestKeywords(statementStartOutsideClass);
}
Future<void> test_function_body_inClass_methodBody() async {
addTestSource(r'''
class A {
m() {
f() {^};
}
}
''');
await computeSuggestions();
assertSuggestKeywords(statementStartInClass);
}
Future<void> test_function_body_inClass_methodBody_inFunction() async {
addTestSource(r'''
class A {
m() {
f() {
f2() {^};
};
}
}
''');
await computeSuggestions();
assertSuggestKeywords(statementStartInClass);
}
Future<void> test_function_body_inClass_methodBody_inFunction_async() async {
addTestSource(r'''
class A {
m() {
f() {
f2() async {^};
};
}
}
''');
await computeSuggestions();
assertSuggestKeywords(statementStartInClass, pseudoKeywords: ['await']);
}
Future<void>
test_function_body_inClass_methodBody_inFunction_async_star() async {
addTestSource(r'''
class A {
m() {
f() {
f2() async* {^};
};
}
}
''');
await computeSuggestions();
assertSuggestKeywords(statementStartInClass,
pseudoKeywords: ['await', 'yield', 'yield*']);
}
Future<void> test_function_body_inUnit() async {
addTestSource('void f() {^}');
await computeSuggestions();
assertSuggestKeywords(statementStartOutsideClass);
}
Future<void> test_function_body_inUnit_afterBlock() async {
addTestSource('void f() {{}^}');
await computeSuggestions();
assertSuggestKeywords(statementStartOutsideClass);
}
Future<void> test_function_body_inUnit_async() async {
addTestSource('void f() async {^}');
await computeSuggestions();
assertSuggestKeywords(statementStartOutsideClass,
pseudoKeywords: ['await']);
}
Future<void> test_function_body_inUnit_async_star() async {
addTestSource('void f() async* {n^}');
await computeSuggestions();
assertSuggestKeywords(statementStartOutsideClass,
pseudoKeywords: ['await', 'yield', 'yield*']);
}
Future<void> test_function_body_inUnit_async_star2() async {
addTestSource('void f() async* {n^ foo}');
await computeSuggestions();
assertSuggestKeywords(statementStartOutsideClass,
pseudoKeywords: ['await', 'yield', 'yield*']);
}
Future<void> test_function_body_inUnit_return_with_header() async {
addTestSource('/// comment\n ^ foo() {}}');
await computeSuggestions();
assertSuggestKeywords([Keyword.DYNAMIC, Keyword.VOID]);
}
Future<void> test_function_body_inUnit_return_with_header_prefix() async {
addTestSource('/// comment\n d^ foo() {}}');
await computeSuggestions();
assertSuggestKeywords([Keyword.DYNAMIC, Keyword.VOID]);
}
Future<void> test_function_body_inUnit_sync_star() async {
addTestSource('void f() sync* {n^}');
await computeSuggestions();
assertSuggestKeywords(statementStartOutsideClass,
pseudoKeywords: ['await', 'yield', 'yield*']);
}
Future<void> test_function_body_inUnit_sync_star2() async {
addTestSource('void f() sync* {n^ foo}');
await computeSuggestions();
assertSuggestKeywords(statementStartOutsideClass,
pseudoKeywords: ['await', 'yield', 'yield*']);
}
Future<void> test_if_after_else() async {
addTestSource('void f() { if (true) {} else ^ }');
await computeSuggestions();
assertSuggestKeywords(statementStartOutsideClass);
}
Future<void> test_if_afterThen_nextCloseCurlyBrace0() async {
addTestSource('void f() { if (true) {} ^ }');
await computeSuggestions();
var keywords = <Keyword>[];
keywords.addAll(statementStartOutsideClass);
keywords.add(Keyword.ELSE);
assertSuggestKeywords(keywords);
}
Future<void> test_if_afterThen_nextCloseCurlyBrace1() async {
addTestSource('void f() { if (true) {} e^ }');
await computeSuggestions();
var keywords = <Keyword>[];
keywords.addAll(statementStartOutsideClass);
keywords.add(Keyword.ELSE);
assertSuggestKeywords(keywords);
}
Future<void> test_if_afterThen_nextStatement0() async {
addTestSource('void f() { if (true) {} ^ print(0); }');
await computeSuggestions();
var keywords = <Keyword>[];
keywords.addAll(statementStartOutsideClass);
keywords.add(Keyword.ELSE);
assertSuggestKeywords(keywords);
}
Future<void> test_if_condition_isKeyword() async {
addTestSource('void f() { if (v i^) {} }');
await computeSuggestions();
assertSuggestKeywords([Keyword.IS]);
}
Future<void> test_if_condition_isKeyword2() async {
addTestSource('void f() { if (v i^ && false) {} }');
await computeSuggestions();
assertSuggestKeywords([Keyword.IS]);
}
Future<void> test_if_expression_in_class() async {
addTestSource('class A {foo() {if (^) }}');
await computeSuggestions();
assertSuggestKeywords(EXPRESSION_START_INSTANCE);
}
Future<void> test_if_expression_in_class2() async {
addTestSource('class A {foo() {if (n^) }}');
await computeSuggestions();
assertSuggestKeywords(EXPRESSION_START_INSTANCE);
}
Future<void> test_if_expression_in_function() async {
addTestSource('foo() {if (^) }');
await computeSuggestions();
assertSuggestKeywords(EXPRESSION_START_NO_INSTANCE);
}
Future<void> test_if_expression_in_function2() async {
addTestSource('foo() {if (n^) }');
await computeSuggestions();
assertSuggestKeywords(EXPRESSION_START_NO_INSTANCE);
}
Future<void> test_if_in_class() async {
addTestSource('class A {foo() {if (true) ^}}');
await computeSuggestions();
assertSuggestKeywords(statementStartInClass);
}
Future<void> test_if_in_class2() async {
addTestSource('class A {foo() {if (true) ^;}}');
await computeSuggestions();
assertSuggestKeywords(statementStartInClass);
}
Future<void> test_if_in_class3() async {
addTestSource('class A {foo() {if (true) r^;}}');
await computeSuggestions();
assertSuggestKeywords(statementStartInClass);
}
Future<void> test_if_in_class4() async {
addTestSource('class A {foo() {if (true) ^ go();}}');
await computeSuggestions();
assertSuggestKeywords(statementStartInClass);
}
Future<void> test_if_outside_class() async {
addTestSource('foo() {if (true) ^}');
await computeSuggestions();
assertSuggestKeywords(statementStartOutsideClass);
}
Future<void> test_if_outside_class2() async {
addTestSource('foo() {if (true) ^;}');
await computeSuggestions();
assertSuggestKeywords(statementStartOutsideClass);
}
Future<void> test_if_outside_class3() async {
addTestSource('foo() {if (true) r^;}');
await computeSuggestions();
assertSuggestKeywords(statementStartOutsideClass);
}
Future<void> test_if_outside_class4() async {
addTestSource('foo() {if (true) ^ go();}');
await computeSuggestions();
assertSuggestKeywords(statementStartOutsideClass);
}
Future<void> test_ifElement_list_hasElse_notLast() async {
addTestSource('''
void f(int i) {
[if (true) 1 else 2 e^, i, i];
}
''');
await computeSuggestions();
assertSuggestKeywords([
...COLLECTION_ELEMENT_START,
...EXPRESSION_START_NO_INSTANCE,
]);
}
Future<void> test_ifElement_list_noElse_insideForElement() async {
addTestSource('''
void f(int i) {
[for (var e in []) if (true) i ^];
}
''');
await computeSuggestions();
assertSuggestKeywords([
...COLLECTION_ELEMENT_START,
...EXPRESSION_START_NO_INSTANCE,
Keyword.ELSE
]);
}
Future<void> test_ifElement_list_noElse_insideIfElement_else() async {
addTestSource('''
void f(int i) {
[if (false) i else if (true) i ^];
}
''');
await computeSuggestions();
assertSuggestKeywords([
...COLLECTION_ELEMENT_START,
...EXPRESSION_START_NO_INSTANCE,
Keyword.ELSE
]);
}
Future<void> test_ifElement_list_noElse_insideIfElement_then() async {
addTestSource('''
void f(int i) {
[if (false) if (true) i ^];
}
''');
await computeSuggestions();
assertSuggestKeywords([
...COLLECTION_ELEMENT_START,
...EXPRESSION_START_NO_INSTANCE,
Keyword.ELSE
]);
}
Future<void> test_ifElement_list_noElse_last() async {
addTestSource('''
void f(int i) {
[if (true) i ^];
}
''');
await computeSuggestions();
assertSuggestKeywords([
...COLLECTION_ELEMENT_START,
...EXPRESSION_START_NO_INSTANCE,
Keyword.ELSE
]);
}
Future<void> test_ifElement_list_noElse_notInElement() async {
addTestSource('''
void f() {
[if (true) 1, ^];
}
''');
await computeSuggestions();
assertSuggestKeywords(
[...COLLECTION_ELEMENT_START, ...EXPRESSION_START_NO_INSTANCE]);
}
@FailingTest(
issue: 'https://github.com/dart-lang/sdk/issues/48837',
reason:
'The CompletionTarget for this test is determined to be "j", which '
'prevents us from suggesting "else". This CompletionTarget bug seems '
'to stem from the current state of `ListLiteralImpl.childEntities` '
'not including comma tokens.')
Future<void> test_ifElement_list_noElse_notLast() async {
addTestSource('''
void f(int i, int j) {
[if (true) i ^, j];
}
''');
await computeSuggestions();
assertSuggestKeywords([
...COLLECTION_ELEMENT_START,
...EXPRESSION_START_NO_INSTANCE,
Keyword.ELSE
]);
}
Future<void> test_ifElement_list_partialElse_last() async {
addTestSource('''
void f() {
[if (true) 1 e^];
}
''');
await computeSuggestions();
assertSuggestKeywords([
...COLLECTION_ELEMENT_START,
...EXPRESSION_START_NO_INSTANCE,
Keyword.ELSE
]);
}
Future<void> test_ifElement_list_partialElse_notLast() async {
addTestSource('''
void f(int i) {
[if (true) 1 e^, i];
}
''');
await computeSuggestions();
assertSuggestKeywords([
...COLLECTION_ELEMENT_START,
...EXPRESSION_START_NO_INSTANCE,
Keyword.ELSE
]);
}
Future<void> test_ifElement_list_partialElse_thenIsForElement() async {
addTestSource('''
void f(int i) {
[if (b) for (var e in c) e e^];
}
''');
await computeSuggestions();
assertSuggestKeywords([
...COLLECTION_ELEMENT_START,
...EXPRESSION_START_NO_INSTANCE,
Keyword.ELSE
]);
}
Future<void> test_ifElement_map_partialElse_notLast() async {
addTestSource('''
void f(int i) {
<int, int>{if (true) 1: 1 e^, 2: i};
}
''');
await computeSuggestions();
assertSuggestKeywords([
...COLLECTION_ELEMENT_START,
...EXPRESSION_START_NO_INSTANCE,
Keyword.ELSE
]);
}
Future<void> test_ifElement_set_partialElse_notLast() async {
addTestSource('''
void f(int i) {
<int>{if (true) 1 e^, i};
}
''');
await computeSuggestions();
assertSuggestKeywords([
...COLLECTION_ELEMENT_START,
...EXPRESSION_START_NO_INSTANCE,
Keyword.ELSE
]);
}
Future<void> test_ifOrForElement_list_empty() async {
addTestSource('''
f() => [^];
''');
await computeSuggestions();
assertSuggestKeywords(COLLECTION_ELEMENT_START);
}
Future<void> test_ifOrForElement_list_first() async {
addTestSource('''
f() => [^1, 2];
''');
await computeSuggestions();
assertSuggestKeywords(COLLECTION_ELEMENT_START);
}
Future<void> test_ifOrForElement_list_forElement() async {
addTestSource('''
f() => [for (var e in c) ^];
''');
await computeSuggestions();
assertSuggestKeywords(COLLECTION_ELEMENT_START);
}
Future<void> test_ifOrForElement_list_ifElement_else() async {
addTestSource('''
f() => [if (true) 1 else ^];
''');
await computeSuggestions();
assertSuggestKeywords(COLLECTION_ELEMENT_START);
}
Future<void> test_ifOrForElement_list_ifElement_then() async {
addTestSource('''
f() => [if (true) ^];
''');
await computeSuggestions();
assertSuggestKeywords(COLLECTION_ELEMENT_START);
}
Future<void> test_ifOrForElement_list_last() async {
addTestSource('''
f() => [1, 2, ^];
''');
await computeSuggestions();
assertSuggestKeywords(COLLECTION_ELEMENT_START);
}
Future<void> test_ifOrForElement_list_middle() async {
addTestSource('''
f() => [1, ^, 2];
''');
await computeSuggestions();
assertSuggestKeywords(COLLECTION_ELEMENT_START);
}
Future<void> test_ifOrForElement_map_empty() async {
addTestSource('''
f() => <String, int>{^};
''');
await computeSuggestions();
assertSuggestKeywords(COLLECTION_ELEMENT_START);
}
Future<void> test_ifOrForElement_map_first() async {
addTestSource('''
f() => <String, int>{^'a' : 1};
''');
await computeSuggestions();
assertSuggestKeywords(COLLECTION_ELEMENT_START);
}
Future<void> test_ifOrForElement_map_last() async {
addTestSource('''
f() => <String, int>{'a' : 1, 'b' : 2, ^};
''');
await computeSuggestions();
assertSuggestKeywords(COLLECTION_ELEMENT_START);
}
Future<void> test_ifOrForElement_map_middle() async {
addTestSource('''
f() => <String, int>{'a' : 1, ^, 'b' : 2];
''');
await computeSuggestions();
assertSuggestKeywords(COLLECTION_ELEMENT_START);
}
Future<void> test_ifOrForElement_set_empty() async {
addTestSource('''
f() => <int>{^};
''');
await computeSuggestions();
assertSuggestKeywords(COLLECTION_ELEMENT_START);
}
Future<void> test_ifOrForElement_set_first() async {
addTestSource('''
f() => <int>{^1, 2};
''');
await computeSuggestions();
assertSuggestKeywords(COLLECTION_ELEMENT_START);
}
Future<void> test_ifOrForElement_set_last() async {
addTestSource('''
f() => <int>{1, 2, ^};
''');
await computeSuggestions();
assertSuggestKeywords(COLLECTION_ELEMENT_START);
}
Future<void> test_ifOrForElement_set_middle() async {
addTestSource('''
f() => <int>{1, ^, 2};
''');
await computeSuggestions();
assertSuggestKeywords(COLLECTION_ELEMENT_START);
}
Future<void> test_import() async {
addTestSource('import "foo" deferred as foo ^;');
await computeSuggestions();
assertSuggestKeywords([], pseudoKeywords: ['show', 'hide']);
}
Future<void> test_import_as() async {
addTestSource('import "foo" deferred ^;');
await computeSuggestions();
assertSuggestKeywords([Keyword.AS]);
}
Future<void> test_import_as2() async {
addTestSource('import "foo" deferred a^;');
await computeSuggestions();
assertSuggestKeywords([Keyword.AS]);
}
Future<void> test_import_as3() async {
addTestSource('import "foo" deferred a^');
await computeSuggestions();
assertSuggestKeywords([Keyword.AS]);
}
Future<void> test_import_deferred() async {
addTestSource('import "foo" ^ as foo;');
await computeSuggestions();
assertSuggestKeywords([Keyword.DEFERRED]);
}
Future<void> test_import_deferred2() async {
addTestSource('import "foo" d^ as foo;');
await computeSuggestions();
assertSuggestKeywords([Keyword.DEFERRED]);
}
Future<void> test_import_deferred3() async {
addTestSource('import "foo" d^ show foo;');
await computeSuggestions();
assertSuggestKeywords([Keyword.AS], pseudoKeywords: ['deferred as']);
}
Future<void> test_import_deferred4() async {
addTestSource('import "foo" d^ hide foo;');
await computeSuggestions();
assertSuggestKeywords([Keyword.AS], pseudoKeywords: ['deferred as']);
}
Future<void> test_import_deferred5() async {
addTestSource('import "foo" d^');
await computeSuggestions();
assertSuggestKeywords([Keyword.AS],
pseudoKeywords: ['deferred as', 'show', 'hide']);
}
Future<void> test_import_deferred6() async {
addTestSource('import "foo" d^ import');
await computeSuggestions();
assertSuggestKeywords([Keyword.AS],
pseudoKeywords: ['deferred as', 'show', 'hide']);
}
Future<void> test_import_deferred_as() async {
addTestSource('import "foo" ^;');
await computeSuggestions();
assertSuggestKeywords([Keyword.AS],
pseudoKeywords: ['deferred as', 'show', 'hide']);
}
Future<void> test_import_deferred_as2() async {
addTestSource('import "foo" d^;');
await computeSuggestions();
assertSuggestKeywords([Keyword.AS],
pseudoKeywords: ['deferred as', 'show', 'hide']);
}
Future<void> test_import_deferred_as3() async {
addTestSource('import "foo" ^');
await computeSuggestions();
assertSuggestKeywords([Keyword.AS],
pseudoKeywords: ['deferred as', 'show', 'hide']);
}
Future<void> test_import_deferred_as4() async {
addTestSource('import "foo" d^');
await computeSuggestions();
assertSuggestKeywords([Keyword.AS],
pseudoKeywords: ['deferred as', 'show', 'hide']);
}
Future<void> test_import_deferred_as5() async {
addTestSource('import "foo" sh^ import "bar"; import "baz";');
await computeSuggestions();
assertSuggestKeywords([Keyword.AS],
pseudoKeywords: ['deferred as', 'show', 'hide']);
}
Future<void> test_import_deferred_not() async {
addTestSource('import "foo" as foo ^;');
await computeSuggestions();
assertSuggestKeywords([], pseudoKeywords: ['show', 'hide']);
}
Future<void> test_import_deferred_partial() async {
addTestSource('import "package:foo/foo.dart" def^ as foo;');
await computeSuggestions();
expect(replacementOffset, 30);
expect(replacementLength, 3);
assertSuggestKeywords([Keyword.DEFERRED]);
expect(suggestions[0].selectionOffset, 8);
expect(suggestions[0].selectionLength, 0);
}
Future<void> test_import_incomplete() async {
addTestSource('import "^"');
await computeSuggestions();
expect(suggestions, isEmpty);
}
Future<void> test_import_partial() async {
addTestSource('imp^ import "package:foo/foo.dart"; import "bar.dart";');
await computeSuggestions();
expect(replacementOffset, 0);
expect(replacementLength, 3);
// TODO(danrubel) should not suggest declaration keywords
assertSuggestKeywords(directiveDeclarationAndLibraryKeywords);
}
Future<void> test_import_partial2() async {
addTestSource('^imp import "package:foo/foo.dart";');
await computeSuggestions();
expect(replacementOffset, 0);
expect(replacementLength, 3);
// TODO(danrubel) should not suggest declaration keywords
assertSuggestKeywords(directiveDeclarationAndLibraryKeywords);
}
Future<void> test_import_partial3() async {
addTestSource(' ^imp import "package:foo/foo.dart"; import "bar.dart";');
await computeSuggestions();
expect(replacementOffset, 1);
expect(replacementLength, 3);
// TODO(danrubel) should not suggest declaration keywords
assertSuggestKeywords(directiveDeclarationAndLibraryKeywords);
}
Future<void> test_import_partial4() async {
addTestSource('^ imp import "package:foo/foo.dart";');
await computeSuggestions();
expect(replacementOffset, 0);
expect(replacementLength, 0);
// TODO(danrubel) should not suggest declaration keywords
assertSuggestKeywords(directiveDeclarationAndLibraryKeywords);
}
Future<void> test_import_partial5() async {
addTestSource('library libA; imp^ import "package:foo/foo.dart";');
await computeSuggestions();
expect(replacementOffset, 14);
expect(replacementLength, 3);
// TODO(danrubel) should not suggest declaration keywords
assertSuggestKeywords(directiveDeclarationKeywords);
}
Future<void> test_import_partial6() async {
addTestSource(
'library bar; import "zoo.dart"; imp^ import "package:foo/foo.dart";');
await computeSuggestions();
expect(replacementOffset, 32);
expect(replacementLength, 3);
// TODO(danrubel) should not suggest declaration keywords
assertSuggestKeywords(directiveDeclarationKeywords);
}
Future<void> test_integerLiteral_inArgumentList() async {
addTestSource('void f() { print(42^); }');
await computeSuggestions();
assertSuggestKeywords([]);
}
Future<void> test_integerLiteral_inListLiteral() async {
addTestSource('void f() { var items = [42^]; }');
await computeSuggestions();
assertSuggestKeywords([]);
}
Future<void> test_is_expression() async {
addTestSource('void f() {if (x is^)}');
await computeSuggestions();
assertSuggestKeywords([Keyword.IS]);
}
Future<void> test_is_expression_partial() async {
addTestSource('void f() {if (x i^)}');
await computeSuggestions();
assertSuggestKeywords([Keyword.IS]);
}
Future<void> test_library() async {
addTestSource('library foo;^');
await computeSuggestions();
assertSuggestKeywords(directiveAndDeclarationKeywords);
}
Future<void> test_library_declaration() async {
addTestSource('library ^');
await computeSuggestions();
assertSuggestKeywords([]);
}
Future<void> test_library_declaration2() async {
addTestSource('library a^');
await computeSuggestions();
assertSuggestKeywords([]);
}
Future<void> test_library_declaration3() async {
addTestSource('library a.^');
await computeSuggestions();
assertSuggestKeywords([]);
}
Future<void> test_library_name() async {
addTestSource('library ^');
await computeSuggestions();
assertSuggestKeywords([]);
}
Future<void> test_method_async() async {
addTestSource('class A { foo() ^}');
await computeSuggestions();
assertSuggestKeywords(classBodyKeywords,
pseudoKeywords: ['async', 'async*', 'sync*']);
}
Future<void> test_method_async2() async {
addTestSource('class A { foo() ^{}}');
await computeSuggestions();
assertSuggestKeywords([], pseudoKeywords: ['async', 'async*', 'sync*']);
}
Future<void> test_method_async3() async {
addTestSource('class A { foo() a^}');
await computeSuggestions();
assertSuggestKeywords(classBodyKeywords,
pseudoKeywords: ['async', 'async*', 'sync*']);
}
Future<void> test_method_async4() async {
addTestSource('class A { foo() a^{}}');
await computeSuggestions();
assertSuggestKeywords([], pseudoKeywords: ['async', 'async*', 'sync*']);
}
Future<void> test_method_async5() async {
addTestSource('class A { foo() ^ Foo foo;}');
await computeSuggestions();
assertSuggestKeywords(classBodyKeywords,
pseudoKeywords: ['async', 'async*', 'sync*']);
}
Future<void> test_method_async6() async {
addTestSource('class A { foo() a^ Foo foo;}');
await computeSuggestions();
assertSuggestKeywords(classBodyKeywords,
pseudoKeywords: ['async', 'async*', 'sync*']);
}
Future<void> test_method_async7() async {
addTestSource('class A { foo() ^ => Foo foo;}');
await computeSuggestions();
assertSuggestKeywords([], pseudoKeywords: ['async']);
}
Future<void> test_method_async8() async {
addTestSource('class A { foo() a^ Foo foo;}');
await computeSuggestions();
assertSuggestKeywords(classBodyKeywords,
pseudoKeywords: ['async', 'async*', 'sync*']);
}
Future<void> test_method_body() async {
addTestSource('class A { foo() {^}}');
await computeSuggestions();
assertSuggestKeywords(statementStartInClass);
}
Future<void> test_method_body2() async {
addTestSource('class A { foo() => ^}');
await computeSuggestions();
assertSuggestKeywords(EXPRESSION_START_INSTANCE);
}
Future<void> test_method_body3() async {
addTestSource('class A { foo() => ^ Foo foo;}');
await computeSuggestions();
assertSuggestKeywords(EXPRESSION_START_INSTANCE);
}
Future<void> test_method_body4() async {
addTestSource('class A { foo() => ^;}');
await computeSuggestions();
assertSuggestKeywords(EXPRESSION_START_INSTANCE);
}
Future<void> test_method_body_async() async {
addTestSource('class A { foo() async {^}}');
await computeSuggestions();
assertSuggestKeywords(statementStartInClass, pseudoKeywords: ['await']);
}
Future<void> test_method_body_async2() async {
addTestSource('class A { foo() async => ^}');
await computeSuggestions();
assertSuggestKeywords(EXPRESSION_START_INSTANCE, pseudoKeywords: ['await']);
}
Future<void> test_method_body_async3() async {
addTestSource('class A { foo() async => ^ Foo foo;}');
await computeSuggestions();
assertSuggestKeywords(EXPRESSION_START_INSTANCE, pseudoKeywords: ['await']);
}
Future<void> test_method_body_async4() async {
addTestSource('class A { foo() async => ^;}');
await computeSuggestions();
assertSuggestKeywords(EXPRESSION_START_INSTANCE, pseudoKeywords: ['await']);
}
Future<void> test_method_body_async_star() async {
addTestSource('class A { foo() async* {^}}');
await computeSuggestions();
assertSuggestKeywords(statementStartInClass,
pseudoKeywords: ['await', 'yield', 'yield*']);
}
Future<void> test_method_body_expression1() async {
addTestSource('class A { foo() {return b == true ? ^}}');
await computeSuggestions();
assertSuggestKeywords(EXPRESSION_START_INSTANCE);
}
Future<void> test_method_body_expression2() async {
addTestSource('class A { foo() {return b == true ? 1 : ^}}');
await computeSuggestions();
assertSuggestKeywords(EXPRESSION_START_INSTANCE);
}
Future<void> test_method_body_return() async {
addTestSource('class A { foo() {return ^}}');
await computeSuggestions();
assertSuggestKeywords(EXPRESSION_START_INSTANCE);
}
Future<void> test_method_body_return_with_header() async {
addTestSource('class A { @override ^ foo() {}}');
await computeSuggestions();
expect(suggestions, isNotEmpty);
assertSuggestKeywords(classBodyKeywords);
}
Future<void> test_method_body_return_with_header_prefix() async {
addTestSource('class A { @override d^ foo() {}}');
await computeSuggestions();
expect(suggestions, isNotEmpty);
assertSuggestKeywords(classBodyKeywords);
}
Future<void> test_method_invocation() async {
addTestSource('class A { foo() {bar.^}}');
await computeSuggestions();
assertNoSuggestions();
}
Future<void> test_method_invocation2() async {
addTestSource('class A { foo() {bar.as^}}');
await computeSuggestions();
assertNoSuggestions();
}
Future<void> test_method_type_params() async {
addTestSource('''
void f<T>() {}
void m() {
f<^>();
}
''');
await computeSuggestions();
assertSuggestKeywords([Keyword.DYNAMIC, Keyword.VOID]);
}
Future<void> test_mixin() async {
addTestSource('mixin M o^ { }');
await computeSuggestions();
assertSuggestKeywords([Keyword.ON, Keyword.IMPLEMENTS]);
}
Future<void> test_mixin_afterOnClause() async {
addTestSource('mixin M on A i^ { } class A {}');
await computeSuggestions();
assertSuggestKeywords([Keyword.IMPLEMENTS]);
}
Future<void> test_named_constructor_invocation() async {
addTestSource('void f() {new Future.^}');
await computeSuggestions();
assertSuggestKeywords([]);
}
Future<void> test_newInstance() async {
addTestSource('class A { foo() {new ^}}');
await computeSuggestions();
assertSuggestKeywords([]);
}
Future<void> test_newInstance2() async {
addTestSource('class A { foo() {new ^ print("foo");}}');
await computeSuggestions();
assertSuggestKeywords([]);
}
Future<void> test_newInstance_prefixed() async {
addTestSource('class A { foo() {new A.^}}');
await computeSuggestions();
assertSuggestKeywords([]);
}
Future<void> test_newInstance_prefixed2() async {
addTestSource('class A { foo() {new A.^ print("foo");}}');
await computeSuggestions();
assertSuggestKeywords([]);
}
Future<void> test_part_of() async {
addTestSource('part of foo;^');
await computeSuggestions();
assertSuggestKeywords(directiveAndDeclarationKeywords);
}
Future<void> test_partial_class() async {
addTestSource('cl^');
await computeSuggestions();
assertSuggestKeywords(directiveDeclarationAndLibraryKeywords);
}
Future<void> test_partial_class2() async {
addTestSource('library a; cl^');
await computeSuggestions();
assertSuggestKeywords(directiveAndDeclarationKeywords);
}
Future<void> test_prefixed_field() async {
addTestSource('class A { int x; foo() {x.^}}');
await computeSuggestions();
assertSuggestKeywords([]);
}
Future<void> test_prefixed_field2() async {
addTestSource('class A { int x; foo() {x.^ print("foo");}}');
await computeSuggestions();
assertSuggestKeywords([]);
}
Future<void> test_prefixed_library() async {
addTestSource('import "b" as b; class A { foo() {b.^}}');
await computeSuggestions();
assertSuggestKeywords([]);
}
Future<void> test_prefixed_local() async {
addTestSource('class A { foo() {int x; x.^}}');
await computeSuggestions();
assertSuggestKeywords([]);
}
Future<void> test_prefixed_local2() async {
addTestSource('class A { foo() {int x; x.^ print("foo");}}');
await computeSuggestions();
assertSuggestKeywords([]);
}
Future<void> test_property_access() async {
addTestSource('class A { get x => 7; foo() {new A().^}}');
await computeSuggestions();
assertSuggestKeywords([]);
}
Future<void> test_spreadElement() async {
addTestSource('''
f() => [...^];
''');
await computeSuggestions();
assertSuggestKeywords(KeywordContributorTest.EXPRESSION_START_NO_INSTANCE);
}
Future<void> test_switch_expression() async {
addTestSource('void f() {switch(^) {}}');
await computeSuggestions();
assertSuggestKeywords(EXPRESSION_START_NO_INSTANCE);
}
Future<void> test_switch_expression2() async {
addTestSource('void f() {switch(n^) {}}');
await computeSuggestions();
assertSuggestKeywords(EXPRESSION_START_NO_INSTANCE);
}
Future<void> test_switch_expression3() async {
addTestSource('void f() {switch(n^)}');
await computeSuggestions();
assertSuggestKeywords(EXPRESSION_START_NO_INSTANCE);
}
Future<void> test_switch_start() async {
addTestSource('void f() {switch(1) {^}}');
await computeSuggestions();
assertSuggestKeywords([Keyword.CASE, Keyword.DEFAULT]);
}
Future<void> test_switch_start2() async {
addTestSource('void f() {switch(1) {^ case 1:}}');
await computeSuggestions();
assertSuggestKeywords([Keyword.CASE, Keyword.DEFAULT]);
}
Future<void> test_switch_start3() async {
addTestSource('void f() {switch(1) {^default:}}');
await computeSuggestions();
assertSuggestKeywords([Keyword.CASE, Keyword.DEFAULT]);
}
Future<void> test_switch_start4() async {
addTestSource('void f() {switch(1) {^ default:}}');
await computeSuggestions();
assertSuggestKeywords([Keyword.CASE, Keyword.DEFAULT]);
}
Future<void> test_switch_start5() async {
addTestSource('void f() {switch(1) {c^ default:}}');
await computeSuggestions();
expect(replacementOffset, 21);
expect(replacementLength, 1);
assertSuggestKeywords([Keyword.CASE, Keyword.DEFAULT]);
}
Future<void> test_switch_start6() async {
addTestSource('void f() {switch(1) {c^}}');
await computeSuggestions();
expect(replacementOffset, 21);
expect(replacementLength, 1);
assertSuggestKeywords([Keyword.CASE, Keyword.DEFAULT]);
}
Future<void> test_switch_start7() async {
addTestSource('void f() {switch(1) { c^ }}');
await computeSuggestions();
expect(replacementOffset, 22);
expect(replacementLength, 1);
assertSuggestKeywords([Keyword.CASE, Keyword.DEFAULT]);
}
Future<void> test_switch_statement_case_break_insideClass() async {
addTestSource('class A{foo() {switch(1) {case 1: b^}}}');
await computeSuggestions();
assertSuggestKeywords(statementStartInSwitchCaseInClass);
}
Future<void> test_switch_statement_case_break_outsideClass() async {
addTestSource('foo() {switch(1) {case 1: b^}}');
await computeSuggestions();
assertSuggestKeywords(statementStartInSwitchCaseOutsideClass);
}
Future<void> test_switch_statement_insideClass() async {
addTestSource('class A{foo() {switch(1) {case 1:^}}}');
await computeSuggestions();
assertSuggestKeywords(statementStartInSwitchInClass);
}
Future<void> test_switch_statement_outsideClass() async {
addTestSource('void f() {switch(1) {case 1:^}}');
await computeSuggestions();
assertSuggestKeywords(statementStartInSwitchOutsideClass);
}
Future<void> test_variable_decl_type_args() async {
addTestSource('void m() {List<^> list;}');
await computeSuggestions();
assertSuggestKeywords([Keyword.DYNAMIC, Keyword.VOID]);
}
Future<void> test_while_break_continue() async {
addTestSource('void f() {while (true) {^}}');
await computeSuggestions();
assertSuggestKeywords(statementStartInLoopOutsideClass);
}
Future<void> test_while_break_continue2() async {
addTestSource('class A {foo() {while (true) {^}}}');
await computeSuggestions();
assertSuggestKeywords(statementStartInLoopInClass);
}
void _appendCompletions(
StringBuffer msg, Iterable<String> completions, Iterable<String> other) {
var sorted = completions.toList();
sorted.sort((c1, c2) => c1.compareTo(c2));
for (var c in sorted) {
msg.writeln(' $c, ${other.contains(c) ? '' : '<<<<<<<<<<<'}');
}
}
bool _equalSets(Iterable<String> iter1, Iterable<String> iter2) {
if (iter1.length != iter2.length) return false;
if (iter1.any((c) => !iter2.contains(c))) return false;
if (iter2.any((c) => !iter1.contains(c))) return false;
return true;
}
}