|
4 | 4 |
|
5 | 5 | import 'package:analysis_server/src/services/correction/fix/data_driven/element_descriptor.dart'; |
6 | 6 | import 'package:analysis_server/src/services/correction/fix/data_driven/element_kind.dart'; |
| 7 | +import 'package:analysis_server/src/services/correction/util.dart'; |
7 | 8 | import 'package:analyzer/dart/ast/token.dart'; |
8 | 9 | import 'package:analyzer/dart/element/element.dart' |
9 | 10 | show |
@@ -141,15 +142,19 @@ class ElementMatcher { |
141 | 142 | /// |
142 | 143 | /// The list will be empty if there are no appropriate matchers for the |
143 | 144 | /// [node]. |
144 | | - static List<ElementMatcher> matchersForNode(AstNode? node, Token? nameToken) { |
| 145 | + static List<ElementMatcher> matchersForNode( |
| 146 | + AstNode? node, |
| 147 | + Token? nameToken, |
| 148 | + LibraryElement libraryElement, |
| 149 | + ) { |
145 | 150 | if (node == null) { |
146 | 151 | return const []; |
147 | 152 | } |
148 | 153 | var importedUris = _importElementsForNode(node); |
149 | 154 | if (importedUris == null) { |
150 | 155 | return const []; |
151 | 156 | } |
152 | | - var builder = _MatcherBuilder(importedUris); |
| 157 | + var builder = _MatcherBuilder(importedUris, libraryElement); |
153 | 158 | builder.buildMatchersForNode(node, nameToken); |
154 | 159 | return builder.matchers.toList(); |
155 | 160 | } |
@@ -189,7 +194,9 @@ class _MatcherBuilder { |
189 | 194 |
|
190 | 195 | final List<Uri> importedUris; |
191 | 196 |
|
192 | | - _MatcherBuilder(this.importedUris); |
| 197 | + final LibraryElement libraryElement; |
| 198 | + |
| 199 | + _MatcherBuilder(this.importedUris, this.libraryElement); |
193 | 200 |
|
194 | 201 | void buildMatchersForNode(AstNode? node, Token? nameToken) { |
195 | 202 | if (node is ArgumentList) { |
@@ -251,6 +258,14 @@ class _MatcherBuilder { |
251 | 258 | // } else if (parent is ExtensionOverride) { |
252 | 259 | // // `TODO`(brianwilkerson) Determine whether this branch can be reached. |
253 | 260 | // _buildFromExtensionOverride(parent); |
| 261 | + } else if (parent is DotShorthandConstructorInvocation) { |
| 262 | + _buildFromDotShorthand(parent, parent.constructorName.name, [ |
| 263 | + ElementKind.constructorKind, |
| 264 | + ]); |
| 265 | + } else if (parent is DotShorthandInvocation) { |
| 266 | + _buildFromDotShorthand(parent, parent.memberName.name, [ |
| 267 | + ElementKind.methodKind, |
| 268 | + ]); |
254 | 269 | } else if (parent is FunctionExpressionInvocation) { |
255 | 270 | _buildFromFunctionExpressionInvocation(parent); |
256 | 271 | } else if (parent is InstanceCreationExpression) { |
@@ -308,6 +323,22 @@ class _MatcherBuilder { |
308 | 323 | ); |
309 | 324 | } |
310 | 325 |
|
| 326 | + /// Build a matcher for the dot shorthand [node] being accessed. |
| 327 | + void _buildFromDotShorthand( |
| 328 | + AstNode node, |
| 329 | + String memberName, |
| 330 | + List<ElementKind> kinds, |
| 331 | + ) { |
| 332 | + var typeElement = computeDotShorthandContextTypeElement( |
| 333 | + node, |
| 334 | + libraryElement, |
| 335 | + ); |
| 336 | + var typeName = typeElement?.displayName; |
| 337 | + if (typeName != null) { |
| 338 | + _addMatcher(components: [memberName, typeName], kinds: kinds); |
| 339 | + } |
| 340 | + } |
| 341 | + |
311 | 342 | /// Build a matcher for the extension. |
312 | 343 | void _buildFromExtensionOverride(ExtensionOverride node) { |
313 | 344 | _addMatcher( |
@@ -555,7 +586,26 @@ class _MatcherBuilder { |
555 | 586 | // TODO(brianwilkerson): Use the static element, if there is one, in order to |
556 | 587 | // get a more exact matcher. |
557 | 588 | var parent = node.parent; |
558 | | - if (parent is Label && parent.parent is NamedExpression) { |
| 589 | + if (parent is DotShorthandInvocation && node == parent.memberName) { |
| 590 | + var kinds = [ElementKind.methodKind]; |
| 591 | + if (parent.typeArguments == null) { |
| 592 | + kinds.add(ElementKind.constructorKind); |
| 593 | + } |
| 594 | + _buildFromDotShorthand(parent, parent.memberName.name, kinds); |
| 595 | + } else if (parent is DotShorthandPropertyAccess && |
| 596 | + node == parent.propertyName) { |
| 597 | + _buildFromDotShorthand(parent, parent.propertyName.name, [ |
| 598 | + ElementKind.constantKind, |
| 599 | + ElementKind.fieldKind, |
| 600 | + ElementKind.getterKind, |
| 601 | + ElementKind.methodKind, // tear-off |
| 602 | + ]); |
| 603 | + } else if (parent is DotShorthandConstructorInvocation && |
| 604 | + node == parent.constructorName) { |
| 605 | + _buildFromDotShorthand(parent, parent.constructorName.name, [ |
| 606 | + ElementKind.constructorKind, |
| 607 | + ]); |
| 608 | + } else if (parent is Label && parent.parent is NamedExpression) { |
559 | 609 | // The parent of the named expression is an argument list. Because we |
560 | 610 | // don't represent parameters as elements, the element we need to match |
561 | 611 | // against is the invocation containing those arguments. |
@@ -609,6 +659,10 @@ class _MatcherBuilder { |
609 | 659 | _buildFromFunctionExpressionInvocation(parent); |
610 | 660 | } else if (parent is InstanceCreationExpression) { |
611 | 661 | _buildFromInstanceCreationExpression(parent); |
| 662 | + } else if (parent is DotShorthandInvocation) { |
| 663 | + _buildFromDotShorthand(parent, parent.memberName.name, [ |
| 664 | + ElementKind.methodKind, |
| 665 | + ]); |
612 | 666 | } else if (parent is MethodInvocation) { |
613 | 667 | _buildFromMethodInvocation(parent); |
614 | 668 | } |
|
0 commit comments