Skip to content

Commit 666dad0

Browse files
bwilkersoncommit-bot@chromium.org
authored andcommitted
Use the information we have about the kind of element when computing fixes
This puts in place support for using the element kind when determining whether a transform applies. It is not as fully tested as it should be but I plan to add more tests in future CLs. Change-Id: Ife89c49384d1ceba9de5b18b7ef197018747ee25 Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/167000 Commit-Queue: Brian Wilkerson <[email protected]> Reviewed-by: Konstantin Shcheglov <[email protected]>
1 parent e98f5db commit 666dad0

File tree

8 files changed

+166
-17
lines changed

8 files changed

+166
-17
lines changed

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

Lines changed: 48 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,12 +5,13 @@
55
import 'package:analysis_server/src/services/correction/dart/abstract_producer.dart';
66
import 'package:analysis_server/src/services/correction/fix.dart';
77
import 'package:analysis_server/src/services/correction/fix/data_driven/element_descriptor.dart';
8+
import 'package:analysis_server/src/services/correction/fix/data_driven/element_kind.dart';
89
import 'package:analysis_server/src/services/correction/fix/data_driven/element_matcher.dart';
910
import 'package:analysis_server/src/services/correction/fix/data_driven/transform.dart';
1011
import 'package:analysis_server/src/services/correction/fix/data_driven/transform_set.dart';
1112
import 'package:analysis_server/src/services/correction/fix/data_driven/transform_set_manager.dart';
1213
import 'package:analyzer/dart/ast/ast.dart';
13-
import 'package:analyzer/dart/element/element.dart';
14+
import 'package:analyzer/dart/element/element.dart' show LibraryElement;
1415
import 'package:analyzer_plugin/utilities/change_builder/change_builder_core.dart';
1516
import 'package:analyzer_plugin/utilities/fixes/fixes.dart';
1617
import 'package:meta/meta.dart';
@@ -34,14 +35,59 @@ class DataDriven extends MultiCorrectionProducer {
3435
importedUris.add(Uri.parse(uri));
3536
}
3637
}
37-
var matcher = ElementMatcher(importedUris: importedUris, name: name);
38+
var matcher =
39+
ElementMatcher(importedUris: importedUris, name: name, kinds: _kinds);
3840
for (var set in _availableTransformSetsForLibrary(library)) {
3941
for (var transform in set.transformsFor(matcher)) {
4042
yield DataDrivenFix(transform);
4143
}
4244
}
4345
}
4446

47+
List<ElementKind> get _kinds {
48+
AstNode child;
49+
var node = this.node;
50+
while (node != null) {
51+
if (node is ConstructorName) {
52+
return const [ElementKind.constructorKind];
53+
} else if (node is ExtensionOverride) {
54+
return const [ElementKind.extensionKind];
55+
} else if (node is InstanceCreationExpression) {
56+
return const [ElementKind.constructorKind];
57+
} else if (node is MethodInvocation) {
58+
if (node.target == child) {
59+
return const [
60+
ElementKind.classKind,
61+
ElementKind.enumKind,
62+
ElementKind.mixinKind
63+
];
64+
} else if (node.realTarget != null) {
65+
return const [ElementKind.constructorKind, ElementKind.methodKind];
66+
}
67+
return const [
68+
ElementKind.classKind,
69+
ElementKind.extensionKind,
70+
ElementKind.functionKind,
71+
ElementKind.methodKind
72+
];
73+
} else if (node is NamedType) {
74+
var parent = node.parent;
75+
if (parent is ConstructorName && parent.name == null) {
76+
return const [ElementKind.classKind, ElementKind.constructorKind];
77+
}
78+
return const [
79+
ElementKind.classKind,
80+
ElementKind.enumKind,
81+
ElementKind.mixinKind,
82+
ElementKind.typedefKind
83+
];
84+
}
85+
child = node;
86+
node = node.parent;
87+
}
88+
return null;
89+
}
90+
4591
/// Return the name of the element that was changed.
4692
String get _name {
4793
String nameFromParent(AstNode node) {

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

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22
// for details. All rights reserved. Use of this source code is governed by a
33
// BSD-style license that can be found in the LICENSE file.
44

5+
import 'package:analysis_server/src/services/correction/fix/data_driven/element_kind.dart';
56
import 'package:meta/meta.dart';
67

78
/// The path to an element.
@@ -10,7 +11,7 @@ class ElementDescriptor {
1011
final List<Uri> libraryUris;
1112

1213
/// The kind of element that was changed.
13-
final String _kind;
14+
final ElementKind kind;
1415

1516
/// The components that uniquely identify the element within its library.
1617
final List<String> components;
@@ -21,10 +22,9 @@ class ElementDescriptor {
2122
/// element is represented by the key used in the data file.
2223
ElementDescriptor(
2324
{@required this.libraryUris,
24-
@required String kind,
25-
@required this.components})
26-
: _kind = kind;
25+
@required this.kind,
26+
@required this.components});
2727

2828
/// Return `true` if the described element is a constructor.
29-
bool get isConstructor => _kind == 'constructor';
29+
bool get isConstructor => kind == ElementKind.constructorKind;
3030
}
Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
// Copyright (c) 2020, the Dart project authors. Please see the AUTHORS file
2+
// for details. All rights reserved. Use of this source code is governed by a
3+
// BSD-style license that can be found in the LICENSE file.
4+
5+
/// An indication of the kind of an element.
6+
enum ElementKind {
7+
classKind,
8+
constantKind,
9+
constructorKind,
10+
enumKind,
11+
extensionKind,
12+
fieldKind,
13+
functionKind,
14+
getterKind,
15+
methodKind,
16+
mixinKind,
17+
setterKind,
18+
typedefKind,
19+
variableKind
20+
}
21+
22+
extension ElementKindUtilities on ElementKind {
23+
/// Return the element kind corresponding to the given [name].
24+
static ElementKind fromName(String name) {
25+
for (var kind in ElementKind.values) {
26+
if (kind.toString() == 'ElementKind.${name}Kind') {
27+
return kind;
28+
}
29+
}
30+
return null;
31+
}
32+
}

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

Lines changed: 16 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
// BSD-style license that can be found in the LICENSE file.
44

55
import 'package:analysis_server/src/services/correction/fix/data_driven/element_descriptor.dart';
6+
import 'package:analysis_server/src/services/correction/fix/data_driven/element_kind.dart';
67
import 'package:meta/meta.dart';
78

89
/// An object that can be used to determine whether an element is appropriate
@@ -15,9 +16,18 @@ class ElementMatcher {
1516
/// The name of the element being referenced.
1617
final String name;
1718

19+
/// A list of the kinds of elements that are appropriate for some given
20+
/// location in the code An empty list represents all kinds rather than no
21+
/// kinds.
22+
List<ElementKind> validKinds;
23+
1824
/// Initialize a newly created matcher representing a reference to an element
1925
/// with the given [name] in a library that imports the [importedUris].
20-
ElementMatcher({@required this.importedUris, @required this.name});
26+
ElementMatcher(
27+
{@required this.importedUris,
28+
@required this.name,
29+
List<ElementKind> kinds})
30+
: validKinds = kinds ?? const [];
2131

2232
/// Return `true` if this matcher matches the given [element].
2333
bool matches(ElementDescriptor element) {
@@ -30,6 +40,11 @@ class ElementMatcher {
3040
} else if (lastComponent != name) {
3141
return false;
3242
}
43+
44+
if (validKinds.isNotEmpty && !validKinds.contains(element.kind)) {
45+
return false;
46+
}
47+
3348
var libraryUris = element.libraryUris;
3449
for (var importedUri in importedUris) {
3550
if (libraryUris.contains(importedUri)) {

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

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ import 'package:analysis_server/src/services/correction/fix/data_driven/add_type
66
import 'package:analysis_server/src/services/correction/fix/data_driven/change.dart';
77
import 'package:analysis_server/src/services/correction/fix/data_driven/code_template.dart';
88
import 'package:analysis_server/src/services/correction/fix/data_driven/element_descriptor.dart';
9+
import 'package:analysis_server/src/services/correction/fix/data_driven/element_kind.dart';
910
import 'package:analysis_server/src/services/correction/fix/data_driven/modify_parameters.dart';
1011
import 'package:analysis_server/src/services/correction/fix/data_driven/parameter_reference.dart';
1112
import 'package:analysis_server/src/services/correction/fix/data_driven/rename.dart';
@@ -534,7 +535,9 @@ class TransformSetParser {
534535
return null;
535536
}
536537
return ElementDescriptor(
537-
libraryUris: uris, kind: elementKey, components: components);
538+
libraryUris: uris,
539+
kind: ElementKindUtilities.fromName(elementKey),
540+
components: components);
538541
} else if (node == null) {
539542
return _reportMissingKey(context);
540543
} else {

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

Lines changed: 23 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44

55
import 'package:analysis_server/src/services/correction/fix/data_driven/add_type_parameter.dart';
66
import 'package:analysis_server/src/services/correction/fix/data_driven/element_descriptor.dart';
7+
import 'package:analysis_server/src/services/correction/fix/data_driven/element_kind.dart';
78
import 'package:analysis_server/src/services/correction/fix/data_driven/transform.dart';
89
import 'package:test_reflective_loader/test_reflective_loader.dart';
910

@@ -22,6 +23,9 @@ void main() {
2223

2324
@reflectiveTest
2425
class AddTypeParameterToClassTest extends _AddTypeParameterChange {
26+
@override
27+
String get _kind => 'class';
28+
2529
Future<void> test_constructorInvocation_removed() async {
2630
setPackageContent('''
2731
class C<S, T> {
@@ -133,6 +137,9 @@ class B with A<String, int> {}
133137

134138
@reflectiveTest
135139
class AddTypeParameterToExtensionTest extends _AddTypeParameterChange {
140+
@override
141+
String get _kind => 'extension';
142+
136143
Future<void> test_override_removed() async {
137144
setPackageContent('''
138145
class C {}
@@ -160,6 +167,9 @@ void f(C c) {
160167

161168
@reflectiveTest
162169
class AddTypeParameterToMethodTest extends _AddTypeParameterChange {
170+
@override
171+
String get _kind => 'method';
172+
163173
Future<void> test_first_deprecated() async {
164174
setPackageContent('''
165175
class C {
@@ -332,6 +342,9 @@ class D extends C {
332342

333343
@reflectiveTest
334344
class AddTypeParameterToMixinTest extends _AddTypeParameterChange {
345+
@override
346+
String get _kind => 'mixin';
347+
335348
Future<void> test_inWith_removed() async {
336349
setPackageContent('''
337350
mixin M<S, T> {}
@@ -352,6 +365,9 @@ class B with M<String, int> {}
352365

353366
@reflectiveTest
354367
class AddTypeParameterToTopLevelFunctionTest extends _AddTypeParameterChange {
368+
@override
369+
String get _kind => 'function';
370+
355371
Future<void> test_only_deprecated() async {
356372
setPackageContent('''
357373
@deprecated
@@ -377,6 +393,9 @@ void g() {
377393

378394
@reflectiveTest
379395
class AddTypeParameterToTypedefTest extends _AddTypeParameterChange {
396+
@override
397+
String get _kind => 'typedef';
398+
380399
@failingTest
381400
Future<void> test_functionType_removed() async {
382401
// The test fails because the change is to the typedef `F`, not to the
@@ -454,13 +473,15 @@ void g(F<String> f) {
454473
}
455474

456475
abstract class _AddTypeParameterChange extends DataDrivenFixProcessorTest {
476+
/// Return the kind of element whose parameters are being modified.
477+
String get _kind;
478+
457479
Transform _add(int index, {List<String> components, String extendedType}) =>
458480
Transform(
459481
title: 'title',
460482
element: ElementDescriptor(
461483
libraryUris: [Uri.parse(importUri)],
462-
// The kind isn't important to these tests.
463-
kind: '',
484+
kind: ElementKindUtilities.fromName(_kind),
464485
components: components ?? ['C', 'm']),
465486
changes: [
466487
AddTypeParameter(

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

Lines changed: 12 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
// BSD-style license that can be found in the LICENSE file.
44

55
import 'package:analysis_server/src/services/correction/fix/data_driven/element_descriptor.dart';
6+
import 'package:analysis_server/src/services/correction/fix/data_driven/element_kind.dart';
67
import 'package:analysis_server/src/services/correction/fix/data_driven/modify_parameters.dart';
78
import 'package:analysis_server/src/services/correction/fix/data_driven/parameter_reference.dart';
89
import 'package:analysis_server/src/services/correction/fix/data_driven/rename.dart';
@@ -20,6 +21,9 @@ void main() {
2021

2122
@reflectiveTest
2223
class ModifyParametersOfMethodTest extends _ModifyParameters {
24+
@override
25+
String get _kind => 'method';
26+
2327
Future<void> test_add_first_optionalNamed_deprecated() async {
2428
setPackageContent('''
2529
class C {
@@ -817,6 +821,9 @@ void f(C c) {
817821
/// applied to top-level functions, but are not intended to be exhaustive.
818822
@reflectiveTest
819823
class ModifyParametersOfTopLevelFunctionTest extends _ModifyParameters {
824+
@override
825+
String get _kind => 'function';
826+
820827
Future<void> test_add_first_requiredNamed_deprecated() async {
821828
setPackageContent('''
822829
@deprecated
@@ -871,15 +878,16 @@ void h() {
871878
}
872879

873880
abstract class _ModifyParameters extends DataDrivenFixProcessorTest {
881+
/// Return the kind of element whose parameters are being modified.
882+
String get _kind;
883+
874884
Transform _modify(List<String> originalComponents,
875-
List<ParameterModification> modifications,
876-
{String newName}) =>
885+
List<ParameterModification> modifications, {String newName}) =>
877886
Transform(
878887
title: 'title',
879888
element: ElementDescriptor(
880889
libraryUris: [Uri.parse(importUri)],
881-
// The kind isn't important to these tests.
882-
kind: '',
890+
kind: ElementKindUtilities.fromName(_kind),
883891
components: originalComponents),
884892
changes: [
885893
ModifyParameters(modifications: modifications),

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

Lines changed: 26 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
// BSD-style license that can be found in the LICENSE file.
44

55
import 'package:analysis_server/src/services/correction/fix/data_driven/element_descriptor.dart';
6+
import 'package:analysis_server/src/services/correction/fix/data_driven/element_kind.dart';
67
import 'package:analysis_server/src/services/correction/fix/data_driven/rename.dart';
78
import 'package:analysis_server/src/services/correction/fix/data_driven/transform.dart';
89
import 'package:test_reflective_loader/test_reflective_loader.dart';
@@ -746,7 +747,30 @@ class RenameGetterTest extends _AbstractRenameTest {
746747
@override
747748
String get _kind => 'getter';
748749

749-
Future<void> test_instance_nonReference_deprecated() async {
750+
Future<void> test_instance_nonReference_method_deprecated() async {
751+
setPackageContent('''
752+
class C {
753+
@deprecated
754+
int get a => 0;
755+
int get b => 1;
756+
}
757+
class D {
758+
@deprecated
759+
void a(int b) {}
760+
}
761+
''');
762+
setPackageData(_rename(['C', 'a'], 'b'));
763+
await resolveTestUnit('''
764+
import '$importUri';
765+
766+
void f(D d) {
767+
d.a(2);
768+
}
769+
''');
770+
await assertNoFix();
771+
}
772+
773+
Future<void> test_instance_nonReference_parameter_deprecated() async {
750774
setPackageContent('''
751775
class C {
752776
@deprecated
@@ -1156,7 +1180,7 @@ abstract class _AbstractRenameTest extends DataDrivenFixProcessorTest {
11561180
title: 'title',
11571181
element: ElementDescriptor(
11581182
libraryUris: [Uri.parse(importUri)],
1159-
kind: _kind,
1183+
kind: ElementKindUtilities.fromName(_kind),
11601184
components: components),
11611185
changes: [
11621186
Rename(newName: newName),

0 commit comments

Comments
 (0)