@@ -4103,27 +4103,9 @@ class GatherUsedImportedElementsVisitor extends RecursiveAstVisitor {
4103
4103
_visitDirective (node);
4104
4104
}
4105
4105
4106
- @override
4107
- void visitPrefixedIdentifier (PrefixedIdentifier node) {
4108
- // If the prefixed identifier references some A.B, where A is a library
4109
- // prefix, then we can lookup the associated ImportDirective in
4110
- // prefixElementMap and remove it from the unusedImports list.
4111
- SimpleIdentifier prefixIdentifier = node.prefix;
4112
- Element element = prefixIdentifier.staticElement;
4113
- if (element is PrefixElement ) {
4114
- List <Element > prefixedElements =
4115
- usedElements.prefixMap.putIfAbsent (element, () => < Element > []);
4116
- prefixedElements.add (node.identifier.staticElement);
4117
- return ;
4118
- }
4119
- // Otherwise, pass the prefixed identifier element and name onto
4120
- // visitIdentifier.
4121
- _visitIdentifier (element, prefixIdentifier.name);
4122
- }
4123
-
4124
4106
@override
4125
4107
void visitSimpleIdentifier (SimpleIdentifier node) {
4126
- _visitIdentifier (node.staticElement , node.name );
4108
+ _visitIdentifier (node, node.staticElement );
4127
4109
}
4128
4110
4129
4111
/**
@@ -4134,7 +4116,7 @@ class GatherUsedImportedElementsVisitor extends RecursiveAstVisitor {
4134
4116
directive.metadata.accept (this );
4135
4117
}
4136
4118
4137
- void _visitIdentifier (Element element, String name ) {
4119
+ void _visitIdentifier (SimpleIdentifier identifier, Element element ) {
4138
4120
if (element == null ) {
4139
4121
return ;
4140
4122
}
@@ -4143,10 +4125,17 @@ class GatherUsedImportedElementsVisitor extends RecursiveAstVisitor {
4143
4125
if (element is MultiplyDefinedElement ) {
4144
4126
MultiplyDefinedElement multiplyDefinedElement = element;
4145
4127
for (Element elt in multiplyDefinedElement.conflictingElements) {
4146
- _visitIdentifier (elt, name );
4128
+ _visitIdentifier (identifier, elt );
4147
4129
}
4148
4130
return ;
4149
- } else if (element is PrefixElement ) {
4131
+ }
4132
+
4133
+ // Record `importPrefix.identifier` into 'prefixMap'.
4134
+ if (_recordPrefixMap (identifier, element)) {
4135
+ return ;
4136
+ }
4137
+
4138
+ if (element is PrefixElement ) {
4150
4139
usedElements.prefixMap.putIfAbsent (element, () => < Element > []);
4151
4140
return ;
4152
4141
} else if (element.enclosingElement is ! CompilationUnitElement ) {
@@ -4168,6 +4157,30 @@ class GatherUsedImportedElementsVisitor extends RecursiveAstVisitor {
4168
4157
// Remember the element.
4169
4158
usedElements.elements.add (element);
4170
4159
}
4160
+
4161
+ /**
4162
+ * If the given [identifier] is prefixed with a [PrefixElement] , fill the
4163
+ * corresponding `UsedImportedElements.prefixMap` entry and return `true` .
4164
+ */
4165
+ bool _recordPrefixMap (SimpleIdentifier identifier, Element element) {
4166
+ bool recordIfTargetIsPrefixElement (Expression target) {
4167
+ if (target is SimpleIdentifier && target.staticElement is PrefixElement ) {
4168
+ List <Element > prefixedElements = usedElements.prefixMap
4169
+ .putIfAbsent (target.staticElement, () => < Element > []);
4170
+ prefixedElements.add (element);
4171
+ return true ;
4172
+ }
4173
+ return false ;
4174
+ }
4175
+ AstNode parent = identifier.parent;
4176
+ if (parent is MethodInvocation && parent.methodName == identifier) {
4177
+ return recordIfTargetIsPrefixElement (parent.target);
4178
+ }
4179
+ if (parent is PrefixedIdentifier && parent.identifier == identifier) {
4180
+ return recordIfTargetIsPrefixElement (parent.prefix);
4181
+ }
4182
+ return false ;
4183
+ }
4171
4184
}
4172
4185
4173
4186
/**
@@ -4652,15 +4665,16 @@ class ImportsVerifier {
4652
4665
* hints
4653
4666
*/
4654
4667
void generateUnusedShownNameHints (ErrorReporter reporter) {
4655
- _unusedShownNamesMap.forEach (( ImportDirective importDirective,
4656
- List <SimpleIdentifier > identifiers) {
4668
+ _unusedShownNamesMap.forEach (
4669
+ ( ImportDirective importDirective, List <SimpleIdentifier > identifiers) {
4657
4670
if (_unusedImports.contains (importDirective)) {
4658
4671
// This import is actually wholly unused, not just one or more shown names from it.
4659
4672
// This is then an "unused import", rather than unused shown names.
4660
4673
return ;
4661
4674
}
4662
4675
for (Identifier identifier in identifiers) {
4663
- reporter.reportErrorForNode (HintCode .UNUSED_SHOWN_NAME , identifier, [identifier.name]);
4676
+ reporter.reportErrorForNode (
4677
+ HintCode .UNUSED_SHOWN_NAME , identifier, [identifier.name]);
4664
4678
}
4665
4679
});
4666
4680
}
@@ -4674,7 +4688,8 @@ class ImportsVerifier {
4674
4688
return ;
4675
4689
}
4676
4690
// Process import prefixes.
4677
- usedElements.prefixMap.forEach ((PrefixElement prefix, List <Element > elements) {
4691
+ usedElements.prefixMap
4692
+ .forEach ((PrefixElement prefix, List <Element > elements) {
4678
4693
List <ImportDirective > importDirectives = _prefixElementMap[prefix];
4679
4694
if (importDirectives != null ) {
4680
4695
for (ImportDirective importDirective in importDirectives) {
@@ -4711,9 +4726,6 @@ class ImportsVerifier {
4711
4726
String name = element.displayName;
4712
4727
for (ImportDirective importDirective in importsLibrary) {
4713
4728
Namespace namespace = _computeNamespace (importDirective);
4714
- if (importDirective.prefix != null ) {
4715
- name = "${importDirective .prefix .name }.$name " ;
4716
- }
4717
4729
if (namespace != null && namespace.get (name) != null ) {
4718
4730
_unusedImports.remove (importDirective);
4719
4731
_removeFromUnusedShownNamesMap (element, importDirective);
@@ -4722,35 +4734,6 @@ class ImportsVerifier {
4722
4734
}
4723
4735
}
4724
4736
4725
- /**
4726
- * Remove [element] from the list of names shown by [importDirective] .
4727
- */
4728
- void _removeFromUnusedShownNamesMap (Element element,
4729
- ImportDirective importDirective) {
4730
- List <SimpleIdentifier > identifiers = _unusedShownNamesMap[importDirective];
4731
- if (identifiers == null ) {
4732
- return ;
4733
- }
4734
- for (Identifier identifier in identifiers) {
4735
- if (element is PropertyAccessorElement ) {
4736
- // If the getter or setter of a variable is used, then the variable (the
4737
- // shown name) is used.
4738
- if (identifier.staticElement == element.variable) {
4739
- identifiers.remove (identifier);
4740
- break ;
4741
- }
4742
- } else {
4743
- if (identifier.staticElement == element) {
4744
- identifiers.remove (identifier);
4745
- break ;
4746
- }
4747
- }
4748
- }
4749
- if (identifiers.isEmpty) {
4750
- _unusedShownNamesMap.remove (importDirective);
4751
- }
4752
- }
4753
-
4754
4737
/**
4755
4738
* Recursively add any exported library elements into the [libraryMap] .
4756
4739
*/
@@ -4767,6 +4750,24 @@ class ImportsVerifier {
4767
4750
}
4768
4751
}
4769
4752
4753
+ /**
4754
+ * Add every shown name from [importDirective] into [_unusedShownNamesMap] .
4755
+ */
4756
+ void _addShownNames (ImportDirective importDirective) {
4757
+ if (importDirective.combinators == null ) {
4758
+ return ;
4759
+ }
4760
+ List <SimpleIdentifier > identifiers = new List <SimpleIdentifier >();
4761
+ _unusedShownNamesMap[importDirective] = identifiers;
4762
+ for (Combinator combinator in importDirective.combinators) {
4763
+ if (combinator is ShowCombinator ) {
4764
+ for (SimpleIdentifier name in combinator.shownNames) {
4765
+ identifiers.add (name);
4766
+ }
4767
+ }
4768
+ }
4769
+ }
4770
+
4770
4771
/**
4771
4772
* Lookup and return the [Namespace] from the [_namespaceMap] .
4772
4773
*
@@ -4808,21 +4809,32 @@ class ImportsVerifier {
4808
4809
}
4809
4810
4810
4811
/**
4811
- * Add every shown name from [importDirective] into [_unusedShownNamesMap ] .
4812
+ * Remove [element] from the list of names shown by [importDirective ] .
4812
4813
*/
4813
- void _addShownNames (ImportDirective importDirective) {
4814
- if (importDirective.combinators == null ) {
4814
+ void _removeFromUnusedShownNamesMap (
4815
+ Element element, ImportDirective importDirective) {
4816
+ List <SimpleIdentifier > identifiers = _unusedShownNamesMap[importDirective];
4817
+ if (identifiers == null ) {
4815
4818
return ;
4816
4819
}
4817
- List <SimpleIdentifier > identifiers = new List <SimpleIdentifier >();
4818
- _unusedShownNamesMap[importDirective] = identifiers;
4819
- for (Combinator combinator in importDirective.combinators) {
4820
- if (combinator is ShowCombinator ) {
4821
- for (SimpleIdentifier name in combinator.shownNames) {
4822
- identifiers.add (name);
4820
+ for (Identifier identifier in identifiers) {
4821
+ if (element is PropertyAccessorElement ) {
4822
+ // If the getter or setter of a variable is used, then the variable (the
4823
+ // shown name) is used.
4824
+ if (identifier.staticElement == element.variable) {
4825
+ identifiers.remove (identifier);
4826
+ break ;
4827
+ }
4828
+ } else {
4829
+ if (identifier.staticElement == element) {
4830
+ identifiers.remove (identifier);
4831
+ break ;
4823
4832
}
4824
4833
}
4825
4834
}
4835
+ if (identifiers.isEmpty) {
4836
+ _unusedShownNamesMap.remove (importDirective);
4837
+ }
4826
4838
}
4827
4839
}
4828
4840
0 commit comments