mirror of
https://github.com/dart-lang/sdk
synced 2024-09-05 00:13:50 +00:00
Fix override suggestions with protocol2, a few tests.
Change-Id: I0f49c01d68abdf695cc08a466495f7754c6eb91f Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/244363 Reviewed-by: Brian Wilkerson <brianwilkerson@google.com> Commit-Queue: Konstantin Shcheglov <scheglov@google.com>
This commit is contained in:
parent
cae2f4e874
commit
85615ce2e8
|
@ -17,7 +17,7 @@ List<CompletionSuggestionBuilder> fuzzyFilterSort({
|
|||
var matcher = FuzzyMatcher(pattern, matchStyle: MatchStyle.SYMBOL);
|
||||
|
||||
double score(CompletionSuggestionBuilder suggestion) {
|
||||
var textToMatch = suggestion.completion;
|
||||
var textToMatch = suggestion.textToMatch;
|
||||
|
||||
if (suggestion.kind == CompletionSuggestionKind.KEYWORD ||
|
||||
suggestion.kind == CompletionSuggestionKind.NAMED_ARGUMENT) {
|
||||
|
|
|
@ -41,6 +41,9 @@ abstract class CompletionSuggestionBuilder {
|
|||
/// See [CompletionSuggestion.relevance].
|
||||
int get relevance;
|
||||
|
||||
/// Return the text that should be matched against the filter.
|
||||
String get textToMatch;
|
||||
|
||||
CompletionSuggestion build();
|
||||
}
|
||||
|
||||
|
@ -81,6 +84,9 @@ class CompletionSuggestionBuilderImpl implements CompletionSuggestionBuilder {
|
|||
return key;
|
||||
}
|
||||
|
||||
@override
|
||||
String get textToMatch => completion;
|
||||
|
||||
@override
|
||||
CompletionSuggestion build() {
|
||||
return CompletionSuggestion(
|
||||
|
@ -966,7 +972,10 @@ class SuggestionBuilder {
|
|||
displayText: displayText);
|
||||
suggestion.element = protocol.convertElement(element,
|
||||
withNullability: _isNonNullableByDefault);
|
||||
_addSuggestion(suggestion);
|
||||
_addSuggestion(
|
||||
suggestion,
|
||||
textToMatchOverride: element.displayName,
|
||||
);
|
||||
}
|
||||
|
||||
/// Add a suggestion for a [parameter].
|
||||
|
@ -1177,9 +1186,15 @@ class SuggestionBuilder {
|
|||
|
||||
/// Add the given [suggestion] if it isn't shadowed by a previously added
|
||||
/// suggestion.
|
||||
void _addSuggestion(protocol.CompletionSuggestion suggestion) {
|
||||
void _addSuggestion(
|
||||
protocol.CompletionSuggestion suggestion, {
|
||||
String? textToMatchOverride,
|
||||
}) {
|
||||
_addBuilder(
|
||||
ValueCompletionSuggestionBuilder(suggestion),
|
||||
ValueCompletionSuggestionBuilder(
|
||||
suggestion,
|
||||
textToMatchOverride: textToMatchOverride,
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
|
@ -1523,8 +1538,12 @@ abstract class SuggestionListener {
|
|||
/// [CompletionSuggestionBuilder] that is based on a [CompletionSuggestion].
|
||||
class ValueCompletionSuggestionBuilder implements CompletionSuggestionBuilder {
|
||||
final CompletionSuggestion _suggestion;
|
||||
final String? _textToMatchOverride;
|
||||
|
||||
ValueCompletionSuggestionBuilder(this._suggestion);
|
||||
ValueCompletionSuggestionBuilder(
|
||||
this._suggestion, {
|
||||
String? textToMatchOverride,
|
||||
}) : _textToMatchOverride = textToMatchOverride;
|
||||
|
||||
@override
|
||||
String get completion => _suggestion.completion;
|
||||
|
@ -1538,6 +1557,9 @@ class ValueCompletionSuggestionBuilder implements CompletionSuggestionBuilder {
|
|||
@override
|
||||
int get relevance => _suggestion.relevance;
|
||||
|
||||
@override
|
||||
String get textToMatch => _textToMatchOverride ?? completion;
|
||||
|
||||
@override
|
||||
CompletionSuggestion build() {
|
||||
return _suggestion;
|
||||
|
|
|
@ -153,6 +153,14 @@ extension CompletionSuggestionExtension
|
|||
);
|
||||
}
|
||||
|
||||
@useResult
|
||||
CheckTarget<String?> get displayText {
|
||||
return nest(
|
||||
value.suggestion.displayText,
|
||||
(selected) => 'has displayText ${valueStr(selected)}',
|
||||
);
|
||||
}
|
||||
|
||||
@useResult
|
||||
CheckTarget<String?> get docComplete {
|
||||
return nest(
|
||||
|
@ -401,6 +409,18 @@ extension CompletionSuggestionsExtension
|
|||
);
|
||||
}
|
||||
|
||||
@useResult
|
||||
CheckTarget<Iterable<CompletionSuggestionForTesting>> get overrides {
|
||||
var result = value
|
||||
.where((suggestion) =>
|
||||
suggestion.suggestion.kind == CompletionSuggestionKind.OVERRIDE)
|
||||
.toList();
|
||||
return nest(
|
||||
result,
|
||||
(selected) => 'overrides ${valueStr(selected)}',
|
||||
);
|
||||
}
|
||||
|
||||
@useResult
|
||||
CheckTarget<Iterable<CompletionSuggestionForTesting>> get withElementClass {
|
||||
return nest(
|
||||
|
|
|
@ -18,14 +18,14 @@ void main() {
|
|||
|
||||
@reflectiveTest
|
||||
class ClassBodyTest1 extends AbstractCompletionDriverTest
|
||||
with ClassBodyTestCases {
|
||||
with ClassBodyTestCases, OverrideTestCases {
|
||||
@override
|
||||
TestingCompletionProtocol get protocol => TestingCompletionProtocol.version1;
|
||||
}
|
||||
|
||||
@reflectiveTest
|
||||
class ClassBodyTest2 extends AbstractCompletionDriverTest
|
||||
with ClassBodyTestCases {
|
||||
with ClassBodyTestCases, OverrideTestCases {
|
||||
@override
|
||||
TestingCompletionProtocol get protocol => TestingCompletionProtocol.version2;
|
||||
}
|
||||
|
@ -311,6 +311,79 @@ mixin M {
|
|||
}
|
||||
}
|
||||
|
||||
mixin OverrideTestCases on AbstractCompletionDriverTest {
|
||||
Future<void> test_class_method_fromExtends() async {
|
||||
final response = await getTestCodeSuggestions('''
|
||||
class A {
|
||||
void foo01() {}
|
||||
}
|
||||
|
||||
class B extends A {
|
||||
foo^
|
||||
}
|
||||
''');
|
||||
|
||||
check(response).suggestions.overrides.includesAll([
|
||||
(suggestion) => suggestion
|
||||
..displayText.isEqualTo('foo01() { … }')
|
||||
..hasSelection(offset: 60, length: 14)
|
||||
..completion.isEqualTo(r'''
|
||||
@override
|
||||
void foo01() {
|
||||
// TODO: implement foo01
|
||||
super.foo01();
|
||||
}'''),
|
||||
]);
|
||||
}
|
||||
|
||||
Future<void> test_class_method_fromImplements() async {
|
||||
final response = await getTestCodeSuggestions('''
|
||||
class A {
|
||||
void foo01() {}
|
||||
}
|
||||
|
||||
class B implements A {
|
||||
foo^
|
||||
}
|
||||
''');
|
||||
|
||||
check(response).suggestions.overrides.includesAll([
|
||||
(suggestion) => suggestion
|
||||
..displayText.isEqualTo('foo01() { … }')
|
||||
..hasSelection(offset: 55)
|
||||
..completion.isEqualTo(r'''
|
||||
@override
|
||||
void foo01() {
|
||||
// TODO: implement foo01
|
||||
}'''),
|
||||
]);
|
||||
}
|
||||
|
||||
Future<void> test_class_method_fromWith() async {
|
||||
final response = await getTestCodeSuggestions('''
|
||||
mixin M {
|
||||
void foo01() {}
|
||||
}
|
||||
|
||||
class A with M {
|
||||
foo^
|
||||
}
|
||||
''');
|
||||
|
||||
check(response).suggestions.overrides.includesAll([
|
||||
(suggestion) => suggestion
|
||||
..displayText.isEqualTo('foo01() { … }')
|
||||
..hasSelection(offset: 60, length: 14)
|
||||
..completion.isEqualTo(r'''
|
||||
@override
|
||||
void foo01() {
|
||||
// TODO: implement foo01
|
||||
super.foo01();
|
||||
}'''),
|
||||
]);
|
||||
}
|
||||
}
|
||||
|
||||
class _Context {
|
||||
final bool isClass;
|
||||
final bool isMixin;
|
||||
|
|
|
@ -977,6 +977,15 @@ class LibraryAnalyzer {
|
|||
|
||||
// We have a contributor that looks at the type, but it is syntactic.
|
||||
if (parent is VariableDeclaration && parent.name == node) {
|
||||
final parent2 = parent.parent;
|
||||
final parent3 = parent2?.parent;
|
||||
// `class A { foo^ }` looks like `class A { <noType> foo; }`.
|
||||
if (parent2 is VariableDeclarationList &&
|
||||
parent2.type == null &&
|
||||
parent3 is FieldDeclaration &&
|
||||
parent3.semicolon.isSynthetic) {
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -130,6 +130,22 @@ class A with foo^ {}
|
|||
result.assertResolvedNodes([]);
|
||||
}
|
||||
|
||||
test_classDeclaration_body_identifier() async {
|
||||
var result = await _resolveTestCode(r'''
|
||||
class A {}
|
||||
|
||||
class B {
|
||||
void foo() {}
|
||||
|
||||
bar^
|
||||
}
|
||||
''');
|
||||
|
||||
result.assertResolvedNodes([
|
||||
'bar;',
|
||||
]);
|
||||
}
|
||||
|
||||
test_constructorDeclaration_body() async {
|
||||
var result = await _resolveTestCode(r'''
|
||||
class A {}
|
||||
|
|
Loading…
Reference in a new issue