Skip to content

Commit 6f0909d

Browse files
scheglovCommit Queue
authored andcommitted
DAS. For foo.name and foo.name() include ElementMatcher(s) for supertypes too.
Change-Id: I46c88a185af73951d46815053c997984735b853a Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/440961 Reviewed-by: Brian Wilkerson <[email protected]> Commit-Queue: Konstantin Shcheglov <[email protected]>
1 parent deb804f commit 6f0909d

File tree

3 files changed

+141
-17
lines changed

3 files changed

+141
-17
lines changed

pkg/analysis_server/lib/src/services/correction/fix/data_driven/element_matcher.dart

Lines changed: 39 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -346,6 +346,28 @@ class _MatcherBuilder {
346346
// return _buildFromElement(element);
347347
// }
348348
var methodName = node.methodName;
349+
350+
var targetType = node.realTarget?.staticType;
351+
if (targetType is InterfaceType) {
352+
// We can invoke both methods and constructors of the target type.
353+
_addMatcher(
354+
components: [methodName.name, targetType.element.name!],
355+
kinds: const [ElementKind.constructorKind, ElementKind.methodKind],
356+
);
357+
// We can invoke methods of supertypes of the target type.
358+
var superElements =
359+
targetType.allSupertypes
360+
.map((superType) => superType.element)
361+
.toList();
362+
for (var element in superElements) {
363+
_addMatcher(
364+
components: [methodName.name, element.name!],
365+
kinds: const [ElementKind.methodKind],
366+
);
367+
}
368+
return;
369+
}
370+
349371
var targetName = _nameOfTarget(node.realTarget);
350372
if (targetName != null) {
351373
// If there is a target, and we know the type of the target, then we know
@@ -455,17 +477,23 @@ class _MatcherBuilder {
455477
// name of the type defining the member.
456478
var targetType = node.prefix.staticType;
457479
if (targetType is InterfaceType) {
458-
_addMatcher(
459-
components: [node.identifier.name, targetType.element.name!],
460-
kinds: const [
461-
ElementKind.constantKind,
462-
ElementKind.fieldKind,
463-
ElementKind.functionKind, // tear-off
464-
ElementKind.getterKind,
465-
ElementKind.methodKind, // tear-off
466-
ElementKind.setterKind,
467-
],
468-
);
480+
var elements = [
481+
targetType.element,
482+
...targetType.allSupertypes.map((t) => t.element),
483+
];
484+
for (var element in elements) {
485+
_addMatcher(
486+
components: [node.identifier.name, element.name!],
487+
kinds: const [
488+
ElementKind.constantKind,
489+
ElementKind.fieldKind,
490+
ElementKind.functionKind, // tear-off
491+
ElementKind.getterKind,
492+
ElementKind.methodKind, // tear-off
493+
ElementKind.setterKind,
494+
],
495+
);
496+
}
469497
}
470498
// It looks like we're accessing a member, but we don't know what kind of
471499
// member, so we include all of the member kinds.

pkg/analysis_server/test/src/services/correction/fix/data_driven/element_matcher_test.dart

Lines changed: 48 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ import 'package:analysis_server/src/services/correction/fix/data_driven/element_
66
import 'package:analysis_server/src/services/correction/fix/data_driven/element_kind.dart';
77
import 'package:analysis_server/src/services/correction/fix/data_driven/element_matcher.dart';
88
import 'package:analyzer/utilities/package_config_file_builder.dart';
9+
import 'package:collection/collection.dart';
910
import 'package:test/test.dart';
1011
import 'package:test_reflective_loader/test_reflective_loader.dart';
1112

@@ -19,6 +20,47 @@ void main() {
1920
}
2021

2122
abstract class AbstractElementMatcherTest extends DataDrivenFixProcessorTest {
23+
/// Assert that there is exactly one [ElementMatcher] for the node described
24+
/// by [search] that satisfies `expectedXyz` requirements.
25+
void _assertHasMatcher(
26+
String search, {
27+
List<String>? expectedComponents,
28+
List<ElementKind>? expectedKinds,
29+
List<String>? expectedUris,
30+
}) {
31+
var node = findNode.any(search);
32+
var matchers = ElementMatcher.matchersForNode(node, node.beginToken);
33+
var matchedMatchers = <ElementMatcher>[];
34+
for (var matcher in matchers) {
35+
if (expectedUris != null) {
36+
if (!const UnorderedIterableEquality<Uri>().equals(
37+
matcher.importedUris,
38+
expectedUris.map((uri) => Uri.parse(uri)),
39+
)) {
40+
continue;
41+
}
42+
}
43+
if (expectedComponents != null) {
44+
if (!const ListEquality<String>().equals(
45+
matcher.components,
46+
expectedComponents,
47+
)) {
48+
continue;
49+
}
50+
}
51+
if (expectedKinds != null) {
52+
if (!const ListEquality<ElementKind>().equals(
53+
matcher.validKinds,
54+
expectedKinds,
55+
)) {
56+
continue;
57+
}
58+
}
59+
matchedMatchers.add(matcher);
60+
}
61+
expect(matchedMatchers, hasLength(1));
62+
}
63+
2264
void _assertMatcher(
2365
String search, {
2466
List<String>? expectedComponents,
@@ -145,7 +187,7 @@ void f(String s) {
145187
s.length;
146188
}
147189
''');
148-
_assertMatcher(
190+
_assertHasMatcher(
149191
'length',
150192
expectedComponents: ['length', 'String'],
151193
expectedKinds: accessorKinds,
@@ -158,7 +200,7 @@ void f(String s) {
158200
s.foo;
159201
}
160202
''');
161-
_assertMatcher(
203+
_assertHasMatcher(
162204
'foo',
163205
expectedComponents: ['foo', 'String'],
164206
expectedKinds: accessorKinds,
@@ -245,7 +287,7 @@ void f(String s) {
245287
s.substring(2);
246288
}
247289
''');
248-
_assertMatcher(
290+
_assertHasMatcher(
249291
'substring',
250292
expectedComponents: ['substring', 'String'],
251293
expectedKinds: methodKinds,
@@ -258,7 +300,7 @@ void f(String s) {
258300
s.foo(2);
259301
}
260302
''');
261-
_assertMatcher(
303+
_assertHasMatcher(
262304
'foo',
263305
expectedComponents: ['foo', 'String'],
264306
expectedKinds: methodKinds,
@@ -297,7 +339,7 @@ class C {
297339
set s(String s) {}
298340
}
299341
''');
300-
_assertMatcher(
342+
_assertHasMatcher(
301343
's =',
302344
expectedComponents: ['s', 'C'],
303345
expectedKinds: accessorKinds,
@@ -310,7 +352,7 @@ void f(String s) {
310352
s.foo = '';
311353
}
312354
''');
313-
_assertMatcher(
355+
_assertHasMatcher(
314356
'foo',
315357
expectedComponents: ['foo', 'String'],
316358
expectedKinds: accessorKinds,

pkg/analysis_server/test/src/services/correction/fix/data_driven/rename_test.dart

Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1168,6 +1168,33 @@ void f(C c) {
11681168
''');
11691169
}
11701170

1171+
Future<void> test_instance_reference_direct_deprecated_viaSubclass() async {
1172+
setPackageContent('''
1173+
class A {
1174+
@deprecated
1175+
int get old => 0;
1176+
int get replacement => 1;
1177+
}
1178+
1179+
class B extends A {}
1180+
''');
1181+
setPackageData(_rename(['old', 'A'], 'replacement'));
1182+
await resolveTestCode('''
1183+
import '$importUri';
1184+
1185+
void f(B b) {
1186+
b.old;
1187+
}
1188+
''');
1189+
await assertHasFix('''
1190+
import '$importUri';
1191+
1192+
void f(B b) {
1193+
b.replacement;
1194+
}
1195+
''');
1196+
}
1197+
11711198
Future<void> test_instance_reference_direct_removed() async {
11721199
setPackageContent('''
11731200
class C {
@@ -1394,6 +1421,33 @@ void f(C c) {
13941421
''');
13951422
}
13961423

1424+
Future<void> test_instance_reference_direct_deprecated_viaSubclass() async {
1425+
setPackageContent('''
1426+
class A {
1427+
@deprecated
1428+
void old() {}
1429+
void replacement() {}
1430+
}
1431+
1432+
class B extends A {}
1433+
''');
1434+
setPackageData(_rename(['old', 'A'], 'replacement'));
1435+
await resolveTestCode('''
1436+
import '$importUri';
1437+
1438+
void f(B b) {
1439+
b.old();
1440+
}
1441+
''');
1442+
await assertHasFix('''
1443+
import '$importUri';
1444+
1445+
void f(B b) {
1446+
b.replacement();
1447+
}
1448+
''');
1449+
}
1450+
13971451
Future<void> test_instance_reference_removed() async {
13981452
setPackageContent('''
13991453
class C {

0 commit comments

Comments
 (0)