analyzer: Improve code quality around used element checking
This is being mailed ahead of the fix, as the fix will probably
require google3 cleanup first.
* Change outermost loop over `usedElements.prefixMap` from forEach to a
for-each loop which allows more efficient short-circuiting.
* Short-circuit continue when `_prefixElementMap[prefix] is null.
* Short-circuit continue when `namespace` is null in a few locations.
Bug: https://github.com/dart-lang/sdk/issues/45028
Change-Id: I5bf1e571c436132665a87625a46cdc0c3f1ef2d9
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/186040
Reviewed-by: Brian Wilkerson <brianwilkerson@google.com>
Commit-Queue: Samuel Rawlins <srawlins@google.com>
diff --git a/pkg/analyzer/lib/src/error/imports_verifier.dart b/pkg/analyzer/lib/src/error/imports_verifier.dart
index caeba58..c421a30 100644
--- a/pkg/analyzer/lib/src/error/imports_verifier.dart
+++ b/pkg/analyzer/lib/src/error/imports_verifier.dart
@@ -414,15 +414,18 @@
_unusedImports.isEmpty && _unusedShownNamesMap.isEmpty;
// Process import prefixes.
- usedElements.prefixMap
- .forEach((PrefixElement prefix, List<Element> elements) {
+ for (var entry in usedElements.prefixMap.entries) {
if (everythingIsKnownToBeUsed()) {
return;
}
+ var prefix = entry.key;
+ var importDirectives = _prefixElementMap[prefix];
+ if (importDirectives == null) {
+ continue;
+ }
+ var elements = entry.value;
// Find import directives using namespaces.
- for (var importDirective
- in _prefixElementMap[prefix] ?? <ImportDirective>[]) {
- var namespace = _computeNamespace(importDirective);
+ for (var importDirective in importDirectives) {
if (elements.isEmpty) {
// [prefix] and [elements] were added to [usedElements.prefixMap] but
// [elements] is empty, so the prefix was referenced incorrectly.
@@ -430,14 +433,19 @@
// shouldn't confuse by also reporting an unused prefix.
_unusedImports.remove(importDirective);
}
+ var namespace = _computeNamespace(importDirective);
+ if (namespace == null) {
+ continue;
+ }
for (var element in elements) {
- if (namespace?.getPrefixed(prefix.name, element.name!) != null) {
+ if (namespace.getPrefixed(prefix.name, element.name!) != null) {
_unusedImports.remove(importDirective);
_removeFromUnusedShownNamesMap(element, importDirective);
}
}
}
- });
+ }
+
// Process top-level elements.
for (Element element in usedElements.elements) {
if (everythingIsKnownToBeUsed()) {
@@ -460,10 +468,13 @@
// Find import directives using namespaces.
for (ImportDirective importDirective in _allImports) {
var namespace = _computeNamespace(importDirective);
+ if (namespace == null) {
+ continue;
+ }
var prefix = importDirective.prefix?.name;
var elementName = extensionElement.name!;
if (prefix == null) {
- if (namespace?.get(elementName) == extensionElement) {
+ if (namespace.get(elementName) == extensionElement) {
_unusedImports.remove(importDirective);
_removeFromUnusedShownNamesMap(extensionElement, importDirective);
}
@@ -471,7 +482,7 @@
// An extension might be used solely because one or more instance
// members are referenced, which does not require explicit use of the
// prefix. We still indicate that the import directive is used.
- if (namespace?.getPrefixed(prefix, elementName) == extensionElement) {
+ if (namespace.getPrefixed(prefix, elementName) == extensionElement) {
_unusedImports.remove(importDirective);
_removeFromUnusedShownNamesMap(extensionElement, importDirective);
}