Skip to content

Commit f8f77eb

Browse files
bwilkersoncommit-bot@chromium.org
authored andcommitted
Add keyword completion suggestions
Change-Id: I2ec6de7a68397aa9e43b155db52c5473e3d7035d Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/111667 Reviewed-by: Konstantin Shcheglov <[email protected]> Commit-Queue: Brian Wilkerson <[email protected]>
1 parent a408e8e commit f8f77eb

File tree

2 files changed

+141
-0
lines changed

2 files changed

+141
-0
lines changed

pkg/analysis_server/lib/src/services/completion/dart/keyword_contributor.dart

Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -194,6 +194,15 @@ class _KeywordVisitor extends GeneralizingAstVisitor {
194194
return;
195195
}
196196
}
197+
if (previousMember is ExtensionDeclaration) {
198+
if (previousMember.leftBracket == null ||
199+
previousMember.leftBracket.isSynthetic) {
200+
// If the prior member is an unfinished extension declaration then the
201+
// user is probably finishing that.
202+
_addExtensionDeclarationKeywords(previousMember);
203+
return;
204+
}
205+
}
197206
if (previousMember is MixinDeclaration) {
198207
if (previousMember.leftBracket == null ||
199208
previousMember.leftBracket.isSynthetic) {
@@ -282,6 +291,21 @@ class _KeywordVisitor extends GeneralizingAstVisitor {
282291
}
283292
}
284293

294+
@override
295+
visitExtensionDeclaration(ExtensionDeclaration node) {
296+
// Don't suggest extension name
297+
if (entity == node.name) {
298+
return;
299+
}
300+
if (entity == node.rightBracket) {
301+
_addExtensionBodyKeywords();
302+
} else if (entity is ClassMember) {
303+
_addExtensionBodyKeywords();
304+
} else {
305+
_addExtensionDeclarationKeywords(node);
306+
}
307+
}
308+
285309
@override
286310
visitFieldDeclaration(FieldDeclaration node) {
287311
VariableDeclarationList fields = node.fields;
@@ -660,6 +684,23 @@ class _KeywordVisitor extends GeneralizingAstVisitor {
660684
}
661685
}
662686

687+
void _addExtensionBodyKeywords() {
688+
_addSuggestions([
689+
Keyword.CONST,
690+
Keyword.DYNAMIC,
691+
Keyword.FINAL,
692+
Keyword.GET,
693+
Keyword.OPERATOR,
694+
Keyword.SET,
695+
Keyword.STATIC,
696+
Keyword.VAR,
697+
Keyword.VOID
698+
]);
699+
if (request.featureSet.isEnabled(Feature.non_nullable)) {
700+
_addSuggestion(Keyword.LATE);
701+
}
702+
}
703+
663704
void _addClassDeclarationKeywords(ClassDeclaration node) {
664705
// Very simplistic suggestion because analyzer will warn if
665706
// the extends / with / implements keywords are out of order
@@ -694,6 +735,9 @@ class _KeywordVisitor extends GeneralizingAstVisitor {
694735
Keyword.VAR,
695736
Keyword.VOID
696737
], DART_RELEVANCE_HIGH);
738+
if (request.featureSet.isEnabled(Feature.extension_methods)) {
739+
_addSuggestion(Keyword.EXTENSION, DART_RELEVANCE_HIGH);
740+
}
697741
if (request.featureSet.isEnabled(Feature.non_nullable)) {
698742
_addSuggestion(Keyword.LATE, DART_RELEVANCE_HIGH);
699743
}
@@ -715,6 +759,12 @@ class _KeywordVisitor extends GeneralizingAstVisitor {
715759
}
716760
}
717761

762+
void _addExtensionDeclarationKeywords(ExtensionDeclaration node) {
763+
if (node.onKeyword == null || node.onKeyword.isSynthetic) {
764+
_addSuggestion(Keyword.ON, DART_RELEVANCE_HIGH);
765+
}
766+
}
767+
718768
void _addImportDirectiveKeywords(ImportDirective node) {
719769
bool hasDeferredKeyword = node.deferredKeyword != null;
720770
bool hasAsKeyword = node.asKeyword != null;

pkg/analysis_server/test/services/completion/dart/keyword_contributor_test.dart

Lines changed: 91 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@ import 'completion_contributor_util.dart';
1515
main() {
1616
defineReflectiveSuite(() {
1717
defineReflectiveTests(KeywordContributorTest);
18+
defineReflectiveTests(KeywordContributorWithExtensionMethodsTest);
1819
defineReflectiveTests(KeywordContributorWithNnbdTest);
1920
});
2021
}
@@ -2024,6 +2025,96 @@ f() => [...^];
20242025
}
20252026
}
20262027

2028+
@reflectiveTest
2029+
class KeywordContributorWithExtensionMethodsTest
2030+
extends KeywordContributorTest {
2031+
@override
2032+
List<Keyword> get declarationKeywords =>
2033+
super.declarationKeywords..add(Keyword.EXTENSION);
2034+
2035+
@override
2036+
List<Keyword> get directiveAndDeclarationKeywords =>
2037+
super.directiveAndDeclarationKeywords..add(Keyword.EXTENSION);
2038+
2039+
@override
2040+
List<Keyword> get directiveDeclarationKeywords =>
2041+
super.directiveDeclarationKeywords..add(Keyword.EXTENSION);
2042+
2043+
List<Keyword> get extensionBodyKeywords => [
2044+
Keyword.CONST,
2045+
Keyword.DYNAMIC,
2046+
Keyword.FINAL,
2047+
Keyword.GET,
2048+
Keyword.OPERATOR,
2049+
Keyword.SET,
2050+
Keyword.STATIC,
2051+
Keyword.VAR,
2052+
Keyword.VOID
2053+
];
2054+
2055+
@override
2056+
void setupResourceProvider() {
2057+
super.setupResourceProvider();
2058+
createAnalysisOptionsFile(experiments: [EnableString.extension_methods]);
2059+
}
2060+
2061+
test_class_body_empty() async {
2062+
addTestSource('extension E on int {^}');
2063+
await computeSuggestions();
2064+
assertSuggestKeywords(extensionBodyKeywords);
2065+
}
2066+
2067+
test_extension_body_beginning() async {
2068+
addTestSource('extension E on int {^ foo() {}}');
2069+
await computeSuggestions();
2070+
assertSuggestKeywords(extensionBodyKeywords);
2071+
}
2072+
2073+
test_extension_body_between() async {
2074+
addTestSource('extension E on int {foo() {} ^ void bar() {}}');
2075+
await computeSuggestions();
2076+
assertSuggestKeywords(extensionBodyKeywords);
2077+
}
2078+
2079+
test_extension_body_end() async {
2080+
addTestSource('extension E on int {foo() {} ^}');
2081+
await computeSuggestions();
2082+
assertSuggestKeywords(extensionBodyKeywords);
2083+
}
2084+
2085+
test_extension_member_const_afterStatic() async {
2086+
addTestSource('''
2087+
extension E on int {
2088+
static c^
2089+
}
2090+
''');
2091+
await computeSuggestions();
2092+
assertSuggestKeywords(staticMember);
2093+
}
2094+
2095+
test_extension_member_final_afterStatic() async {
2096+
addTestSource('''
2097+
extension E on int {
2098+
static f^
2099+
}
2100+
''');
2101+
await computeSuggestions();
2102+
assertSuggestKeywords(staticMember);
2103+
}
2104+
2105+
test_extension_noBody_named() async {
2106+
addTestSource('extension E ^');
2107+
await computeSuggestions();
2108+
assertSuggestKeywords([Keyword.ON], relevance: DART_RELEVANCE_HIGH);
2109+
}
2110+
2111+
test_extension_noBody_unnamed() async {
2112+
addTestSource('extension ^');
2113+
await computeSuggestions();
2114+
assertSuggestKeywords([Keyword.ON], relevance: DART_RELEVANCE_HIGH);
2115+
}
2116+
}
2117+
20272118
@reflectiveTest
20282119
class KeywordContributorWithNnbdTest extends KeywordContributorTest {
20292120
@override

0 commit comments

Comments
 (0)