Skip to content

Commit 37369b3

Browse files
bwilkersoncommit-bot@chromium.org
authored andcommitted
Refactor and add tests for creating an ElementMatcher for a node
The code that was moved contains some additional fixes. I'm happy to break this up into two CLs if you'd prefer. Change-Id: I4e2407d28b238ff75934fcf92a411d5fe0b94585 Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/179364 Reviewed-by: Konstantin Shcheglov <[email protected]> Commit-Queue: Brian Wilkerson <[email protected]>
1 parent cb2aed6 commit 37369b3

File tree

4 files changed

+655
-179
lines changed

4 files changed

+655
-179
lines changed

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

Lines changed: 3 additions & 179 deletions
Original file line numberDiff line numberDiff line change
@@ -6,14 +6,11 @@ import 'package:analysis_server/src/services/correction/dart/abstract_producer.d
66
import 'package:analysis_server/src/services/correction/fix.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';
109
import 'package:analysis_server/src/services/correction/fix/data_driven/element_matcher.dart';
1110
import 'package:analysis_server/src/services/correction/fix/data_driven/transform.dart';
1211
import 'package:analysis_server/src/services/correction/fix/data_driven/transform_set.dart';
1312
import 'package:analysis_server/src/services/correction/fix/data_driven/transform_set_manager.dart';
14-
import 'package:analyzer/dart/ast/ast.dart';
1513
import 'package:analyzer/dart/element/element.dart' show LibraryElement;
16-
import 'package:analyzer/dart/element/type.dart';
1714
import 'package:analyzer_plugin/utilities/change_builder/change_builder_core.dart';
1815
import 'package:analyzer_plugin/utilities/fixes/fixes.dart';
1916
import 'package:meta/meta.dart';
@@ -36,16 +33,11 @@ class DataDriven extends MultiCorrectionProducer {
3633
importedUris.add(Uri.parse(uri));
3734
}
3835
}
39-
var components = _computeComponents();
40-
if (components == null) {
41-
// If we couldn't compute the components it's because the node doesn't
42-
// represent an element that can be transformed.
36+
var matcher = ElementMatcher.forNode(node);
37+
if (matcher == null) {
38+
// The node doesn't represent an element that can be transformed.
4339
return;
4440
}
45-
var matcher = ElementMatcher(
46-
importedUris: importedUris,
47-
components: components,
48-
kinds: _kindsForNode(node));
4941
for (var set in _availableTransformSetsForLibrary(library)) {
5042
for (var transform
5143
in set.transformsFor(matcher, applyingBulkFixes: applyingBulkFixes)) {
@@ -63,174 +55,6 @@ class DataDriven extends MultiCorrectionProducer {
6355
return TransformSetManager.instance.forLibrary(library);
6456
}
6557

66-
/// Return the components for the element associated with the given [node] by
67-
/// looking at the parent of the [node].
68-
List<String> _componentsFromParent(AstNode node) {
69-
var parent = node.parent;
70-
if (parent is ArgumentList) {
71-
parent = parent.parent;
72-
}
73-
if (parent is Annotation) {
74-
return [parent.constructorName?.name ?? '', parent.name.name];
75-
} else if (parent is ExtensionOverride) {
76-
return [parent.extensionName.name];
77-
} else if (parent is InstanceCreationExpression) {
78-
var constructorName = parent.constructorName;
79-
return [constructorName.name?.name ?? '', constructorName.type.name.name];
80-
} else if (parent is MethodInvocation) {
81-
var target = _nameOfTarget(parent.realTarget);
82-
if (target != null) {
83-
return [parent.methodName.name, target];
84-
}
85-
var ancestor = parent.parent;
86-
while (ancestor != null) {
87-
if (ancestor is ClassOrMixinDeclaration) {
88-
return [parent.methodName.name, ancestor.name.name];
89-
} else if (ancestor is ExtensionDeclaration) {
90-
return [parent.methodName.name, ancestor.name.name];
91-
}
92-
ancestor = ancestor.parent;
93-
}
94-
return [parent.methodName.name];
95-
} else if (parent is RedirectingConstructorInvocation) {
96-
var ancestor = parent.parent;
97-
if (ancestor is ConstructorDeclaration) {
98-
return [parent.constructorName?.name ?? '', ancestor.returnType.name];
99-
}
100-
} else if (parent is SuperConstructorInvocation) {
101-
var ancestor = parent.parent;
102-
if (ancestor is ConstructorDeclaration) {
103-
return [parent.constructorName?.name ?? '', ancestor.returnType.name];
104-
}
105-
}
106-
return null;
107-
}
108-
109-
/// Return the components of the path of the element associated with the
110-
/// diagnostic. The components are ordered from the most local to the most
111-
/// global. For example, for a constructor this would be the name of the
112-
/// constructor followed by the name of the class in which the constructor is
113-
/// declared (with an empty string for the unnamed constructor).
114-
List<String> _computeComponents() {
115-
var node = this.node;
116-
if (node is SimpleIdentifier) {
117-
var parent = node.parent;
118-
if (parent is Label && parent.parent is NamedExpression) {
119-
// The parent of the named expression is an argument list. Because we
120-
// don't represent parameters as elements, the element we need to match
121-
// against is the invocation containing those arguments.
122-
return _componentsFromParent(parent.parent.parent);
123-
} else if (parent is TypeName && parent.parent is ConstructorName) {
124-
return ['', node.name];
125-
} else if (parent is MethodInvocation) {
126-
return _componentsFromParent(node);
127-
}
128-
return [node.name];
129-
} else if (node is PrefixedIdentifier) {
130-
var parent = node.parent;
131-
if (parent is TypeName && parent.parent is ConstructorName) {
132-
return ['', node.identifier.name];
133-
}
134-
return [node.identifier.name];
135-
} else if (node is ConstructorName) {
136-
return [node.name.name];
137-
} else if (node is NamedType) {
138-
return [node.name.name];
139-
} else if (node is TypeArgumentList) {
140-
return _componentsFromParent(node);
141-
} else if (node is ArgumentList) {
142-
return _componentsFromParent(node);
143-
} else if (node?.parent is ArgumentList) {
144-
return _componentsFromParent(node.parent);
145-
}
146-
return null;
147-
}
148-
149-
List<ElementKind> _kindsForNode(AstNode node, {AstNode child}) {
150-
if (node is ConstructorName) {
151-
return const [ElementKind.constructorKind];
152-
} else if (node is ExtensionOverride) {
153-
return const [ElementKind.extensionKind];
154-
} else if (node is InstanceCreationExpression) {
155-
return const [ElementKind.constructorKind];
156-
} else if (node is Label) {
157-
var argumentList = node.parent.parent;
158-
return _kindsForNode(argumentList.parent, child: argumentList);
159-
} else if (node is MethodInvocation) {
160-
assert(child != null);
161-
if (node.target == child) {
162-
return const [
163-
ElementKind.classKind,
164-
ElementKind.enumKind,
165-
ElementKind.mixinKind
166-
];
167-
} else if (node.realTarget != null) {
168-
return const [ElementKind.constructorKind, ElementKind.methodKind];
169-
}
170-
return const [
171-
ElementKind.classKind,
172-
ElementKind.extensionKind,
173-
ElementKind.functionKind,
174-
ElementKind.methodKind
175-
];
176-
} else if (node is NamedType) {
177-
var parent = node.parent;
178-
if (parent is ConstructorName && parent.name == null) {
179-
return const [ElementKind.classKind, ElementKind.constructorKind];
180-
}
181-
return const [
182-
ElementKind.classKind,
183-
ElementKind.enumKind,
184-
ElementKind.mixinKind,
185-
ElementKind.typedefKind
186-
];
187-
} else if (node is PrefixedIdentifier) {
188-
if (node.prefix == child) {
189-
return const [
190-
ElementKind.classKind,
191-
ElementKind.enumKind,
192-
ElementKind.extensionKind,
193-
ElementKind.mixinKind,
194-
ElementKind.typedefKind
195-
];
196-
}
197-
return const [
198-
ElementKind.fieldKind,
199-
ElementKind.getterKind,
200-
ElementKind.setterKind
201-
];
202-
} else if (node is PropertyAccess) {
203-
return const [ElementKind.getterKind, ElementKind.setterKind];
204-
} else if (node is SimpleIdentifier) {
205-
return _kindsForNode(node.parent, child: node);
206-
}
207-
return null;
208-
}
209-
210-
/// Return the name of the class associated with the given [target].
211-
String _nameOfTarget(Expression target) {
212-
if (target is SimpleIdentifier) {
213-
var type = target.staticType;
214-
if (type != null) {
215-
if (type is InterfaceType) {
216-
return type.element.name;
217-
} else if (type.isDynamic) {
218-
// The name is likely to be undefined.
219-
return target.name;
220-
}
221-
return null;
222-
}
223-
return target.name;
224-
} else if (target != null) {
225-
var type = target.staticType;
226-
if (type is InterfaceType) {
227-
return type.element.name;
228-
}
229-
return null;
230-
}
231-
return null;
232-
}
233-
23458
/// Return an instance of this class. Used as a tear-off in `FixProcessor`.
23559
static DataDriven newInstance() => DataDriven();
23660
}

0 commit comments

Comments
 (0)