From 9f465e5b6eab0dc3af96140189d4f0190e0ff925 Mon Sep 17 00:00:00 2001 From: Brian Wilkerson Date: Thu, 16 Jan 2025 14:34:53 -0800 Subject: [PATCH] [Migrate] unused_local_elements_verifier.dart Change-Id: I1d68dda93d6282118827826ea6ee8e5fe13b78fc Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/403907 Commit-Queue: Brian Wilkerson Reviewed-by: Konstantin Shcheglov --- pkg/analyzer/lib/src/dart/ast/extensions.dart | 8 + .../lib/src/dart/element/element.dart | 25 +- .../error/unused_local_elements_verifier.dart | 452 +++++++++--------- .../resolution/instance_creation_test.dart | 24 +- 4 files changed, 280 insertions(+), 229 deletions(-) diff --git a/pkg/analyzer/lib/src/dart/ast/extensions.dart b/pkg/analyzer/lib/src/dart/ast/extensions.dart index 21eeb33a86dc..11ea40e5ecce 100644 --- a/pkg/analyzer/lib/src/dart/ast/extensions.dart +++ b/pkg/analyzer/lib/src/dart/ast/extensions.dart @@ -220,6 +220,10 @@ extension IdentifierExtension on Identifier { return _readElement(this); } + Element2? get readElement2 { + return _readElement(this).asElement2; + } + SimpleIdentifier get simpleName { var self = this; if (self is SimpleIdentifier) { @@ -233,6 +237,10 @@ extension IdentifierExtension on Identifier { return _writeElement(this); } + Element2? get writeElement2 { + return _writeElement(this).asElement2; + } + Element? get writeOrReadElement { return _writeElement(this) ?? staticElement; } diff --git a/pkg/analyzer/lib/src/dart/element/element.dart b/pkg/analyzer/lib/src/dart/element/element.dart index 16d0ae1d5fd2..ae003473a5d0 100644 --- a/pkg/analyzer/lib/src/dart/element/element.dart +++ b/pkg/analyzer/lib/src/dart/element/element.dart @@ -153,8 +153,12 @@ class BindPatternVariableElementImpl2 extends PatternVariableElementImpl2 ]; } - /// This flag is set to `true` if this variable clashes with another - /// pattern variable with the same name within the same pattern. + /// Whether this variable clashes with another pattern variable with the same + /// name within the same pattern. + bool get isDuplicate => _wrappedElement.isDuplicate; + + /// Set whether this variable clashes with another pattern variable with the + /// same name within the same pattern. set isDuplicate(bool value) => _wrappedElement.isDuplicate = value; DeclaredVariablePatternImpl get node => _wrappedElement.node; @@ -6793,6 +6797,23 @@ class JoinPatternVariableElementImpl2 extends PatternVariableElementImpl2 /// The identifiers that reference this element. List get references => _wrappedElement.references; + /// Returns this variable, and variables that join into it. + List get transitiveVariables { + var result = []; + + void append(PatternVariableElementImpl2 variable) { + result.add(variable); + if (variable is JoinPatternVariableElementImpl2) { + for (var variable in variable.variables2) { + append(variable as PatternVariableElementImpl2); + } + } + } + + append(this); + return result; + } + /// The variables that join into this variable. List get variables => _wrappedElement.variables; diff --git a/pkg/analyzer/lib/src/error/unused_local_elements_verifier.dart b/pkg/analyzer/lib/src/error/unused_local_elements_verifier.dart index e912be0b571b..e210d34c7a5f 100644 --- a/pkg/analyzer/lib/src/error/unused_local_elements_verifier.dart +++ b/pkg/analyzer/lib/src/error/unused_local_elements_verifier.dart @@ -2,21 +2,20 @@ // for details. All rights reserved. Use of this source code is governed by a // BSD-style license that can be found in the LICENSE file. -// ignore_for_file: analyzer_use_new_elements - import 'dart:collection'; import 'dart:math' as math; import 'package:analyzer/dart/analysis/features.dart'; import 'package:analyzer/dart/ast/token.dart'; import 'package:analyzer/dart/ast/visitor.dart'; -import 'package:analyzer/dart/element/element.dart'; +import 'package:analyzer/dart/element/element2.dart'; import 'package:analyzer/dart/element/type.dart'; import 'package:analyzer/error/error.dart'; import 'package:analyzer/error/listener.dart'; import 'package:analyzer/src/dart/ast/ast.dart'; import 'package:analyzer/src/dart/ast/extensions.dart'; -import 'package:analyzer/src/dart/element/element.dart'; +import 'package:analyzer/src/dart/element/element.dart' + show JoinPatternVariableElementImpl2, MetadataImpl; import 'package:analyzer/src/dart/element/inheritance_manager3.dart'; import 'package:analyzer/src/dart/element/member.dart' show ExecutableMember; import 'package:analyzer/src/error/codes.dart'; @@ -27,9 +26,9 @@ import 'package:collection/collection.dart'; class GatherUsedLocalElementsVisitor extends RecursiveAstVisitor { final UsedLocalElements usedElements = UsedLocalElements(); - final LibraryElement _enclosingLibrary; - InterfaceElement? _enclosingClass; - ExecutableElement? _enclosingExec; + final LibraryElement2 _enclosingLibrary; + InterfaceElement2? _enclosingClass; + ExecutableElement2? _enclosingExec; /// Non-null when the visitor is inside an [IsExpression]'s type. IsExpression? _enclosingIsExpression; @@ -41,7 +40,7 @@ class GatherUsedLocalElementsVisitor extends RecursiveAstVisitor { @override void visitAssignmentExpression(AssignmentExpression node) { - var element = node.staticElement; + var element = node.element; if (element != null) { usedElements.members.add(element); } @@ -50,7 +49,7 @@ class GatherUsedLocalElementsVisitor extends RecursiveAstVisitor { @override void visitBinaryExpression(BinaryExpression node) { - var element = node.staticElement; + var element = node.element; usedElements.addMember(element); super.visitBinaryExpression(node); } @@ -60,14 +59,14 @@ class GatherUsedLocalElementsVisitor extends RecursiveAstVisitor { var exceptionParameter = node.exceptionParameter; var stackTraceParameter = node.stackTraceParameter; if (exceptionParameter != null) { - var element = exceptionParameter.declaredElement; + var element = exceptionParameter.declaredElement2; usedElements.addCatchException(element); if (stackTraceParameter != null || node.onKeyword == null) { usedElements.addElement(element); } } if (stackTraceParameter != null) { - var element = stackTraceParameter.declaredElement; + var element = stackTraceParameter.declaredElement2; usedElements.addCatchStackTrace(element); } super.visitCatchClause(node); @@ -75,16 +74,16 @@ class GatherUsedLocalElementsVisitor extends RecursiveAstVisitor { @override void visitClassDeclaration(ClassDeclaration node) { - var element = node.declaredElement; + var element = node.declaredFragment?.element; if (element != null) { - if (element.hasJS) { + if (element.metadata2.hasJS) { usedElements.addElement(element); } } var enclosingClassOld = _enclosingClass; try { - _enclosingClass = node.declaredElement; + _enclosingClass = node.declaredFragment?.element; super.visitClassDeclaration(node); } finally { _enclosingClass = enclosingClassOld; @@ -93,15 +92,15 @@ class GatherUsedLocalElementsVisitor extends RecursiveAstVisitor { @override void visitConstructorDeclaration(ConstructorDeclaration node) { - var element = node.declaredElement!; + var element = node.declaredFragment!.element; var redirectedConstructor = node.redirectedConstructor; if (redirectedConstructor != null) { - var redirectedElement = redirectedConstructor.staticElement; + var redirectedElement = redirectedConstructor.element; if (redirectedElement != null) { // TODO(scheglov): Only if not _isPubliclyAccessible _matchParameters( - element.parameters, - redirectedElement.parameters, + element.formalParameters, + redirectedElement.formalParameters, (first, second) { usedElements.addElement(second); }, @@ -114,9 +113,9 @@ class GatherUsedLocalElementsVisitor extends RecursiveAstVisitor { @override void visitDefaultFormalParameter(DefaultFormalParameter node) { - var element = node.declaredElement; - if (element is SuperFormalParameterElement) { - usedElements.addElement(element.superConstructorParameter); + var element = node.declaredFragment?.element; + if (element is SuperFormalParameterElement2) { + usedElements.addElement(element.superConstructorParameter2); } super.visitDefaultFormalParameter(node); @@ -124,7 +123,7 @@ class GatherUsedLocalElementsVisitor extends RecursiveAstVisitor { @override void visitEnumConstantDeclaration(EnumConstantDeclaration node) { - usedElements.addElement(node.constructorElement?.declaration); + usedElements.addElement(node.constructorElement2?.baseElement); var argumentList = node.arguments?.argumentList; if (argumentList != null) { @@ -138,7 +137,7 @@ class GatherUsedLocalElementsVisitor extends RecursiveAstVisitor { void visitFunctionDeclaration(FunctionDeclaration node) { var enclosingExecOld = _enclosingExec; try { - _enclosingExec = node.declaredElement; + _enclosingExec = node.declaredFragment?.element; super.visitFunctionDeclaration(node); } finally { _enclosingExec = enclosingExecOld; @@ -148,14 +147,14 @@ class GatherUsedLocalElementsVisitor extends RecursiveAstVisitor { @override void visitFunctionExpression(FunctionExpression node) { if (node.parent is! FunctionDeclaration) { - usedElements.addElement(node.declaredElement); + usedElements.addElement(node.declaredFragment?.element); } super.visitFunctionExpression(node); } @override void visitFunctionExpressionInvocation(FunctionExpressionInvocation node) { - usedElements.addElement(node.staticElement); + usedElements.addElement(node.element); super.visitFunctionExpressionInvocation(node); } @@ -164,8 +163,8 @@ class GatherUsedLocalElementsVisitor extends RecursiveAstVisitor { if (!Identifier.isPrivateName(node.name.lexeme)) { var type = node.type.type; if (type is InterfaceType) { - for (var constructor in type.constructors) { - if (!Identifier.isPrivateName(constructor.name)) { + for (var constructor in type.constructors2) { + if (!Identifier.isPrivateName(constructor.name3!)) { usedElements.addElement(constructor); } } @@ -176,7 +175,7 @@ class GatherUsedLocalElementsVisitor extends RecursiveAstVisitor { @override void visitIndexExpression(IndexExpression node) { - var element = node.writeOrReadElement; + var element = node.writeOrReadElement2; usedElements.addMember(element); super.visitIndexExpression(node); } @@ -203,7 +202,7 @@ class GatherUsedLocalElementsVisitor extends RecursiveAstVisitor { void visitMethodDeclaration(MethodDeclaration node) { var enclosingExecOld = _enclosingExec; try { - _enclosingExec = node.declaredElement; + _enclosingExec = node.declaredFragment?.element; super.visitMethodDeclaration(node); } finally { _enclosingExec = enclosingExecOld; @@ -212,8 +211,10 @@ class GatherUsedLocalElementsVisitor extends RecursiveAstVisitor { @override void visitMethodInvocation(MethodInvocation node) { - var function = node.methodName.staticElement; - if (function is FunctionElement || function is MethodElement) { + var function = node.methodName.element; + if (function is LocalFunctionElement || + function is MethodElement2 || + function is TopLevelFunctionElement) { _addParametersForArguments(node.argumentList); } super.visitMethodInvocation(node); @@ -221,35 +222,35 @@ class GatherUsedLocalElementsVisitor extends RecursiveAstVisitor { @override void visitNamedType(NamedType node) { - _useIdentifierElement(node.element, parent: node); + _useIdentifierElement(node.element2, parent: node); super.visitNamedType(node); } @override void visitPatternField(PatternField node) { - usedElements.addMember(node.element); - usedElements.addReadMember(node.element); + usedElements.addMember(node.element2); + usedElements.addReadMember(node.element2); super.visitPatternField(node); } @override void visitPostfixExpression(PostfixExpression node) { - var element = node.staticElement; + var element = node.element; usedElements.addMember(element); super.visitPostfixExpression(node); } @override void visitPrefixExpression(PrefixExpression node) { - var element = node.staticElement; + var element = node.element; usedElements.addMember(element); super.visitPrefixExpression(node); } @override void visitRelationalPattern(RelationalPattern node) { - usedElements.addMember(node.element); - usedElements.addReadMember(node.element); + usedElements.addMember(node.element2); + usedElements.addReadMember(node.element2); super.visitRelationalPattern(node); } @@ -261,65 +262,66 @@ class GatherUsedLocalElementsVisitor extends RecursiveAstVisitor { if (_inCommentReference(node)) { return; } - var element = node.writeOrReadElement; + var element = node.writeOrReadElement2; // Store un-parameterized members. if (element is ExecutableMember) { - element = element.declaration; + element = element.baseElement; } - var variable = element.ifTypeOrNull()?.variable2; + var variable = element.ifTypeOrNull()?.variable3; bool isIdentifierRead = _isReadIdentifier(node); - if (element is PropertyAccessorElement && + if (element is PropertyAccessorElement2 && isIdentifierRead && - variable is TopLevelVariableElement) { + variable is TopLevelVariableElement2) { if (element.isSynthetic) { usedElements.addElement(variable); } else { usedElements.members.add(element); _addMemberAndCorrespondingGetter(element); } - } else if (element is LocalVariableElement) { + } else if (element is LocalVariableElement2) { if (isIdentifierRead) { usedElements.addElement(element); } } else { var parent = node.parent!; - _useIdentifierElement(node.readElement, parent: parent); - _useIdentifierElement(node.writeElement, parent: parent); - _useIdentifierElement(node.staticElement, parent: parent); + _useIdentifierElement(node.readElement2, parent: parent); + _useIdentifierElement(node.writeElement2, parent: parent); + _useIdentifierElement(node.element, parent: parent); var grandparent = parent.parent; // If [node] is a tear-off, assume all parameters are used. var functionReferenceIsCall = - (element is ExecutableElement && parent is MethodInvocation) || + (element is ExecutableElement2 && parent is MethodInvocation) || // named constructor - (element is ConstructorElement && + (element is ConstructorElement2 && parent is ConstructorName && grandparent is InstanceCreationExpression) || // unnamed constructor - (element is InterfaceElement && + (element is InterfaceElement2 && grandparent is ConstructorName && grandparent.parent is InstanceCreationExpression); - if (element is ExecutableElement && + if (element is ExecutableElement2 && isIdentifierRead && !functionReferenceIsCall) { - for (var parameter in element.parameters) { + for (var parameter in element.formalParameters) { usedElements.addElement(parameter); } } - var enclosingElement = element?.enclosingElement3; + var enclosingElement = element?.enclosingElement2; if (element == null) { if (isIdentifierRead) { usedElements.unresolvedReadMembers.add(node.name); } - } else if (enclosingElement is EnumElement && element.name == 'values') { + } else if (enclosingElement is EnumElement2 && + element.name3 == 'values') { // If the 'values' static accessor of the enum is accessed, then all of // the enum values have been read. - for (var field in enclosingElement.fields) { + for (var field in enclosingElement.fields2) { if (field.isEnumConstant) { - usedElements.readMembers.add(field.getter!); + usedElements.readMembers.add(field.getter2!); } } - } else if ((enclosingElement is InterfaceElement || - enclosingElement is ExtensionElement) && + } else if ((enclosingElement is InterfaceElement2 || + enclosingElement is ExtensionElement2) && !identical(element, _enclosingExec)) { usedElements.members.add(element); if (isIdentifierRead) { @@ -350,10 +352,10 @@ class GatherUsedLocalElementsVisitor extends RecursiveAstVisitor { /// Add [element] as a used member and, if [element] is a setter, add its /// corresponding getter as a used member. - void _addMemberAndCorrespondingGetter(Element element) { - if (element is PropertyAccessorElement && element.isSetter) { - usedElements.addMember(element.correspondingGetter); - usedElements.addReadMember(element.correspondingGetter); + void _addMemberAndCorrespondingGetter(Element2 element) { + if (element is SetterElement) { + usedElements.addMember(element.correspondingGetter2); + usedElements.addReadMember(element.correspondingGetter2); } else { usedElements.addReadMember(element); } @@ -361,21 +363,21 @@ class GatherUsedLocalElementsVisitor extends RecursiveAstVisitor { void _addParametersForArguments(ArgumentList argumentList) { for (var argument in argumentList.arguments) { - var parameter = argument.staticParameterElement; + var parameter = argument.correspondingParameter; usedElements.addElement(parameter); } } /// Marks the [element] as used in the library. void _useIdentifierElement( - Element? element, { + Element2? element, { required AstNode parent, }) { if (element == null) { return; } // Check if [element] is a local element. - if (!identical(element.library, _enclosingLibrary)) { + if (!identical(element.library2, _enclosingLibrary)) { return; } // Ignore references to an element from itself. @@ -388,7 +390,7 @@ class GatherUsedLocalElementsVisitor extends RecursiveAstVisitor { // Ignore places where the element is not actually used. // TODO(scheglov): Do we need 'parent' at all? if (parent is NamedType) { - if (element is InterfaceElement) { + if (element is InterfaceElement2) { var enclosingVariableDeclaration = _enclosingVariableDeclaration; if (enclosingVariableDeclaration != null) { // If it's a field's type, it still counts as used. @@ -445,24 +447,25 @@ class GatherUsedLocalElementsVisitor extends RecursiveAstVisitor { /// Ignores parameters that don't have a corresponding pair. // TODO(scheglov): There might be a better place for this function. static void _matchParameters( - List firstList, - List secondList, - void Function(ParameterElement first, ParameterElement second) f, + List firstList, + List secondList, + void Function(FormalParameterElement first, FormalParameterElement second) + f, ) { - Map? firstNamed; - Map? secondNamed; - var firstPositional = []; - var secondPositional = []; + Map? firstNamed; + Map? secondNamed; + var firstPositional = []; + var secondPositional = []; for (var element in firstList) { if (element.isNamed) { - (firstNamed ??= {})[element.name] = element; + (firstNamed ??= {})[element.name3!] = element; } else { firstPositional.add(element); } } for (var element in secondList) { if (element.isNamed) { - (secondNamed ??= {})[element.name] = element; + (secondNamed ??= {})[element.name3!] = element; } else { secondPositional.add(element); } @@ -509,24 +512,24 @@ class UnusedLocalElementsVerifier extends RecursiveAstVisitor { /// The current set of pattern variable elements, used to track whether _all_ /// within a [PatternVariableDeclaration] are used. - List? _patternVariableElements; + List? _patternVariableElements; /// Create a new instance of the [UnusedLocalElementsVerifier]. UnusedLocalElementsVerifier(this._errorListener, this._usedElements, - this._inheritanceManager, LibraryElement library) - : _libraryUri = library.source.uri, + this._inheritanceManager, LibraryElement2 library) + : _libraryUri = library.uri, _wildCardVariablesEnabled = library.featureSet.isEnabled(Feature.wildcard_variables); @override void visitCatchClauseParameter(CatchClauseParameter node) { - _visitLocalVariableElement(node.declaredElement!); + _visitLocalVariableElement(node.declaredElement2!); super.visitCatchClauseParameter(node); } @override void visitClassDeclaration(ClassDeclaration node) { - var declaredElement = node.declaredElement!; + var declaredElement = node.declaredFragment!.element; _visitClassElement(declaredElement); super.visitClassDeclaration(node); @@ -535,7 +538,7 @@ class UnusedLocalElementsVerifier extends RecursiveAstVisitor { @override void visitConstructorDeclaration(ConstructorDeclaration node) { if (node.name != null) { - var declaredElement = node.declaredElement!; + var declaredElement = node.declaredFragment!.element; _visitConstructorElement(declaredElement); } @@ -544,7 +547,7 @@ class UnusedLocalElementsVerifier extends RecursiveAstVisitor { @override void visitDeclaredIdentifier(DeclaredIdentifier node) { - _visitLocalVariableElement(node.declaredElement!); + _visitLocalVariableElement(node.declaredFragment!.element); super.visitDeclaredIdentifier(node); } @@ -552,7 +555,7 @@ class UnusedLocalElementsVerifier extends RecursiveAstVisitor { void visitDeclaredVariablePattern( covariant DeclaredVariablePatternImpl node, ) { - var declaredElement = node.declaredElement!; + var declaredElement = node.declaredElement2!; if (!declaredElement.isDuplicate) { var patternVariableElements = _patternVariableElements; if (patternVariableElements != null) { @@ -567,7 +570,7 @@ class UnusedLocalElementsVerifier extends RecursiveAstVisitor { @override void visitEnumConstantDeclaration(EnumConstantDeclaration node) { - var declaredElement = node.declaredElement as FieldElement; + var declaredElement = node.declaredFragment!.element; _visitFieldElement(declaredElement); super.visitEnumConstantDeclaration(node); @@ -575,7 +578,7 @@ class UnusedLocalElementsVerifier extends RecursiveAstVisitor { @override void visitEnumDeclaration(EnumDeclaration node) { - var declaredElement = node.declaredElement!; + var declaredElement = node.declaredFragment!.element; _visitClassElement(declaredElement); super.visitEnumDeclaration(node); @@ -583,7 +586,7 @@ class UnusedLocalElementsVerifier extends RecursiveAstVisitor { @override void visitExtensionTypeDeclaration(ExtensionTypeDeclaration node) { - var declaredElement = node.declaredElement!; + var declaredElement = node.declaredFragment!.element; _visitClassElement(declaredElement); super.visitExtensionTypeDeclaration(node); @@ -593,7 +596,7 @@ class UnusedLocalElementsVerifier extends RecursiveAstVisitor { void visitFieldDeclaration(FieldDeclaration node) { for (var field in node.fields.variables) { _visitFieldElement( - field.declaredElement as FieldElement, + field.declaredFragment!.element as FieldElement2, ); } @@ -602,8 +605,9 @@ class UnusedLocalElementsVerifier extends RecursiveAstVisitor { @override void visitFormalParameterList(FormalParameterList node) { - for (var element in node.parameterElements) { - if (!_isUsedElement(element!)) { + for (var fragment in node.parameterFragments) { + var element = fragment!.element; + if (!_isUsedElement(element)) { _reportErrorForElement(WarningCode.UNUSED_ELEMENT_PARAMETER, element, [element.displayName]); } @@ -615,7 +619,7 @@ class UnusedLocalElementsVerifier extends RecursiveAstVisitor { void visitForPartsWithDeclarations(ForPartsWithDeclarations node) { for (var variable in node.variables.variables) { _visitLocalVariableElement( - variable.declaredElement as LocalVariableElement, + variable.declaredElement2 as LocalVariableElement2, ); } @@ -624,11 +628,13 @@ class UnusedLocalElementsVerifier extends RecursiveAstVisitor { @override void visitFunctionDeclaration(FunctionDeclaration node) { - var declaredElement = node.declaredElement; - if (declaredElement is FunctionElement) { - _visitFunctionElement(declaredElement); - } else if (declaredElement is PropertyAccessorElement) { + var declaredElement = node.declaredFragment?.element; + if (declaredElement is LocalFunctionElement) { + _visitLocalFunctionElement(declaredElement); + } else if (declaredElement is PropertyAccessorElement2) { _visitPropertyAccessorElement(declaredElement); + } else if (declaredElement is TopLevelFunctionElement) { + _visitTopLevelFunctionElement(declaredElement); } super.visitFunctionDeclaration(node); @@ -636,7 +642,7 @@ class UnusedLocalElementsVerifier extends RecursiveAstVisitor { @override void visitFunctionTypeAlias(FunctionTypeAlias node) { - var declaredElement = node.declaredElement!; + var declaredElement = node.declaredFragment!.element; _visitTypeAliasElement(declaredElement); super.visitFunctionTypeAlias(node); @@ -644,7 +650,7 @@ class UnusedLocalElementsVerifier extends RecursiveAstVisitor { @override void visitGenericTypeAlias(GenericTypeAlias node) { - var declaredElement = node.declaredElement as TypeAliasElement; + var declaredElement = node.declaredFragment?.element as TypeAliasElement2; _visitTypeAliasElement(declaredElement); super.visitGenericTypeAlias(node); @@ -652,10 +658,10 @@ class UnusedLocalElementsVerifier extends RecursiveAstVisitor { @override void visitMethodDeclaration(MethodDeclaration node) { - var declaredElement = node.declaredElement; - if (declaredElement is MethodElement) { + var declaredElement = node.declaredFragment?.element; + if (declaredElement is MethodElement2) { _visitMethodElement(declaredElement); - } else if (declaredElement is PropertyAccessorElement) { + } else if (declaredElement is PropertyAccessorElement2) { _visitPropertyAccessorElement(declaredElement); } @@ -664,7 +670,7 @@ class UnusedLocalElementsVerifier extends RecursiveAstVisitor { @override void visitMixinDeclaration(MixinDeclaration node) { - var declaredElement = node.declaredElement!; + var declaredElement = node.declaredFragment!.element; _visitClassElement(declaredElement); super.visitMixinDeclaration(node); @@ -676,7 +682,7 @@ class UnusedLocalElementsVerifier extends RecursiveAstVisitor { var patternVariableElements = _patternVariableElements = []; try { super.visitPatternVariableDeclaration(node); - var elementsToReport = []; + var elementsToReport = []; for (var element in patternVariableElements) { var isUsed = _usedElements.elements.contains(element); // Don't report any of the declared variables as unused, if any of them @@ -702,24 +708,24 @@ class UnusedLocalElementsVerifier extends RecursiveAstVisitor { @override void visitSimpleIdentifier(SimpleIdentifier node) { if (node.inDeclarationContext()) { - var element = node.staticElement; - if (element is ConstructorElement) { + var element = node.element; + if (element is ConstructorElement2) { _visitConstructorElement(element); - } else if (element is FieldElement) { + } else if (element is FieldElement2) { _visitFieldElement(element); - } else if (element is FunctionElement) { - _visitFunctionElement(element); - } else if (element is InterfaceElement) { + } else if (element is LocalFunctionElement) { + _visitLocalFunctionElement(element); + } else if (element is InterfaceElement2) { _visitClassElement(element); - } else if (element is LocalVariableElement) { + } else if (element is LocalVariableElement2) { _visitLocalVariableElement(element); - } else if (element is MethodElement) { + } else if (element is MethodElement2) { _visitMethodElement(element); - } else if (element is PropertyAccessorElement) { + } else if (element is PropertyAccessorElement2) { _visitPropertyAccessorElement(element); - } else if (element is TopLevelVariableElement) { + } else if (element is TopLevelVariableElement2) { _visitTopLevelVariableElement(element); - } else if (element is TypeAliasElement) { + } else if (element is TypeAliasElement2) { _visitTypeAliasElement(element); } } @@ -729,7 +735,7 @@ class UnusedLocalElementsVerifier extends RecursiveAstVisitor { void visitTopLevelVariableDeclaration(TopLevelVariableDeclaration node) { for (var variable in node.variables.variables) { _visitTopLevelVariableElement( - variable.declaredElement as TopLevelVariableElement, + variable.declaredFragment?.element as TopLevelVariableElement2, ); } @@ -740,7 +746,7 @@ class UnusedLocalElementsVerifier extends RecursiveAstVisitor { void visitVariableDeclarationStatement(VariableDeclarationStatement node) { for (var variable in node.variables.variables) { _visitLocalVariableElement( - variable.declaredElement as LocalVariableElement, + variable.declaredElement2 as LocalVariableElement2, ); } @@ -749,34 +755,36 @@ class UnusedLocalElementsVerifier extends RecursiveAstVisitor { /// Returns the parameter element, if any, that corresponds to the given /// parameter in the overridden element. - ParameterElement? _getCorrespondingParameter(ParameterElement parameter, - ExecutableElement overridden, ExecutableElement enclosingElement) { - ParameterElement? correspondingParameter; + FormalParameterElement? _getCorrespondingParameter( + FormalParameterElement parameter, + ExecutableElement2 overridden, + ExecutableElement2 enclosingElement) { + FormalParameterElement? correspondingParameter; if (parameter.isNamed) { - correspondingParameter = overridden.parameters - .firstWhereOrNull((p) => p.name == parameter.name); + correspondingParameter = overridden.formalParameters + .firstWhereOrNull((p) => p.name3 == parameter.name3); } else { var parameterIndex = 0; - var parameterCount = enclosingElement.parameters.length; + var parameterCount = enclosingElement.formalParameters.length; while (parameterIndex < parameterCount) { - if (enclosingElement.parameters[parameterIndex] == parameter) { + if (enclosingElement.formalParameters[parameterIndex] == parameter) { break; } parameterIndex++; } - if (overridden.parameters.length <= parameterIndex) { + if (overridden.formalParameters.length <= parameterIndex) { // Something is wrong with the overridden element. Ignore it. return null; } - correspondingParameter = overridden.parameters[parameterIndex]; + correspondingParameter = overridden.formalParameters[parameterIndex]; } return correspondingParameter; } /// Returns whether the name of [element] should be treated as a wildcard. - bool _isNamedWildcard(LocalElement element) { + bool _isNamedWildcard(LocalElement2 element) { // TODO(pq): ask the element once implemented. - var name = element.name; + var name = element.name3; if (name == null) return false; var length = name.length; @@ -792,32 +800,32 @@ class UnusedLocalElementsVerifier extends RecursiveAstVisitor { return true; } - bool _isPrivateClassOrExtension(Element element) => - (element is InterfaceElement || element is ExtensionElement) && + bool _isPrivateClassOrExtension(Element2 element) => + (element is InterfaceElement2 || element is ExtensionElement2) && element.isPrivate; /// Returns whether [element] is accessible outside of the library in which /// it is declared. - bool _isPubliclyAccessible(ExecutableElement element) { + bool _isPubliclyAccessible(ExecutableElement2 element) { if (element.isPrivate) { return false; } - var enclosingElement = element.enclosingElement3; + var enclosingElement = element.enclosingElement2; - if (enclosingElement is EnumElement) { - if (element is ConstructorElement && element.isGenerative) { + if (enclosingElement is EnumElement2) { + if (element is ConstructorElement2 && element.isGenerative) { return false; } } - if (enclosingElement is InterfaceElement) { + if (enclosingElement is InterfaceElement2) { if (enclosingElement.isPrivate) { - if (element.isStatic || element is ConstructorElement) { + if (element.isStatic || element is ConstructorElement2) { return false; } } } - if (enclosingElement is ExtensionElement) { + if (enclosingElement is ExtensionElement2) { return enclosingElement.isPublic; } @@ -826,11 +834,11 @@ class UnusedLocalElementsVerifier extends RecursiveAstVisitor { /// Returns whether [element] is a private element which is read somewhere in /// the library. - bool _isReadMember(Element element) { + bool _isReadMember(Element2 element) { bool elementIsStaticVariable = - element is VariableElement && element.isStatic; + element is VariableElement2 && element.isStatic; if (element.isPublic) { - if (_isPrivateClassOrExtension(element.enclosingElement3!) && + if (_isPrivateClassOrExtension(element.enclosingElement2!) && elementIsStaticVariable) { // Public static fields of private classes, mixins, and extensions are // inaccessible from outside the library in which they are declared. @@ -841,15 +849,15 @@ class UnusedLocalElementsVerifier extends RecursiveAstVisitor { if (element.isSynthetic) { return true; } - if (element is FieldElement) { - var getter = element.getter; + if (element is FieldElement2) { + var getter = element.getter2; if (getter == null) { return false; } element = getter; } if (_usedElements.readMembers.contains(element) || - _usedElements.unresolvedReadMembers.contains(element.name)) { + _usedElements.unresolvedReadMembers.contains(element.name3)) { return true; } @@ -859,35 +867,36 @@ class UnusedLocalElementsVerifier extends RecursiveAstVisitor { return _overridesUsedElement(element); } - bool _isUsedElement(Element element) { + bool _isUsedElement(Element2 element) { if (element.isSynthetic) { return true; } - if (element is LocalVariableElement || - element is FunctionElement && !element.isStatic) { + if (element is LocalVariableElement2 || + element is LocalFunctionElement && !element.isStatic) { // local variable or function - } else if (element is ParameterElement) { - var enclosingElement = element.enclosingElement3; - // Only report unused parameters of constructors, methods, and functions. - if (enclosingElement is! ConstructorElement && - enclosingElement is! FunctionElement && - enclosingElement is! MethodElement) { + } else if (element is FormalParameterElement) { + var enclosingElement = element.enclosingElement2; + // Only report unused parameters of constructors, methods, and top-level + // functions. + if (enclosingElement is! ConstructorElement2 && + enclosingElement is! MethodElement2 && + enclosingElement is! TopLevelFunctionElement) { return true; } if (!element.isOptional) { return true; } - if (enclosingElement is ConstructorElement && - enclosingElement.enclosingElement3.typeParameters.isNotEmpty) { + if (enclosingElement is ConstructorElement2 && + enclosingElement.enclosingElement2.typeParameters2.isNotEmpty) { // There is an issue matching arguments of instance creation // expressions for generic classes with parameters, so for now, // consider every parameter of a constructor of a generic class // "used". See https://github.com/dart-lang/sdk/issues/47839. return true; } - if (enclosingElement is ConstructorElement) { - var superConstructor = enclosingElement.superConstructor; + if (enclosingElement is ConstructorElement2) { + var superConstructor = enclosingElement.superConstructor2; if (superConstructor != null) { var correspondingParameter = _getCorrespondingParameter( element, superConstructor, enclosingElement); @@ -899,8 +908,8 @@ class UnusedLocalElementsVerifier extends RecursiveAstVisitor { } } } - if (enclosingElement is ExecutableElement) { - if (enclosingElement.typeParameters.isNotEmpty) { + if (enclosingElement is ExecutableElement2) { + if (enclosingElement.typeParameters2.isNotEmpty) { // There is an issue matching arguments of generic function // invocations with parameters, so for now, consider every parameter // of a generic function "used". See @@ -925,7 +934,7 @@ class UnusedLocalElementsVerifier extends RecursiveAstVisitor { return _usedElements.elements.contains(element); } - bool _isUsedMember(ExecutableElement element) { + bool _isUsedMember(ExecutableElement2 element) { if (_isPubliclyAccessible(element)) { return true; } @@ -945,36 +954,38 @@ class UnusedLocalElementsVerifier extends RecursiveAstVisitor { return _overridesUsedElement(element); } - Iterable _overriddenElements(Element element) { - var fragment = element.enclosingElement3; - if (fragment is InterfaceElement) { - var enclosingElement = fragment.augmented.firstFragment; - Name name = Name(_libraryUri, element.name!); - var overridden = - _inheritanceManager.getOverridden2(enclosingElement, name); - if (overridden == null) { - return []; + Iterable _overriddenElements(Element2 element) { + var enclosingElement = element.enclosingElement2; + if (enclosingElement is InterfaceElement2) { + var elementName = element.name3; + if (elementName != null) { + Name name = Name(_libraryUri, elementName); + var overridden = + _inheritanceManager.getOverridden4(enclosingElement, name); + if (overridden == null) { + return []; + } + return overridden + .map((e) => (e is ExecutableMember) ? e.baseElement : e); } - return overridden.map((e) => (e is ExecutableMember) ? e.declaration : e); - } else { - return []; } + return []; } /// Check if [element] is a class member which overrides a super class's class /// member which is used. - bool _overridesUsedElement(Element element) { - return _overriddenElements(element).any((ExecutableElement e) => - _usedElements.members.contains(e) || _overridesUsedElement(e)); + bool _overridesUsedElement(Element2 element) { + return _overriddenElements(element).any( + (e) => _usedElements.members.contains(e) || _overridesUsedElement(e)); } /// Check if [element] is a parameter of a method which overrides a super /// class's method in which the corresponding parameter is used. bool _overridesUsedParameter( - ParameterElement element, ExecutableElement enclosingElement) { + FormalParameterElement element, ExecutableElement2 enclosingElement) { var overriddenElements = _overriddenElements(enclosingElement); for (var overridden in overriddenElements) { - ParameterElement? correspondingParameter = + FormalParameterElement? correspondingParameter = _getCorrespondingParameter(element, overridden, enclosingElement); // The parameter was added in the override. if (correspondingParameter == null) { @@ -993,13 +1004,16 @@ class UnusedLocalElementsVerifier extends RecursiveAstVisitor { } void _reportErrorForElement( - ErrorCode errorCode, Element? element, List arguments) { + ErrorCode errorCode, Element2? element, List arguments) { if (element != null) { + var fragment = element.firstFragment; _errorListener.onError( AnalysisError.tmp( - source: element.source!, - offset: element.nameOffset, - length: element.nameLength, + source: fragment.libraryFragment!.source, + offset: fragment.nameOffset2 ?? + fragment.enclosingFragment?.nameOffset2 ?? + 0, + length: fragment.name2?.length ?? 0, errorCode: errorCode, arguments: arguments, ), @@ -1007,44 +1021,41 @@ class UnusedLocalElementsVerifier extends RecursiveAstVisitor { } } - void _visitClassElement(InterfaceElement element) { + void _visitClassElement(InterfaceElement2 element) { if (!_isUsedElement(element)) { _reportErrorForElement( WarningCode.UNUSED_ELEMENT, element, [element.displayName]); } } - void _visitConstructorElement(ConstructorElement element) { + void _visitConstructorElement(ConstructorElement2 element) { // Only complain about an unused constructor if it is not the only // constructor in the class. A single unused, private constructor may serve // the purpose of preventing the class from being extended. In serving this // purpose, the constructor is "used." - if (element.enclosingElement3.constructors.length > 1 && + if (element.enclosingElement2.constructors2.length > 1 && !_isUsedMember(element)) { _reportErrorForElement( WarningCode.UNUSED_ELEMENT, element, [element.displayName]); } } - void _visitFieldElement(FieldElement element) { + void _visitFieldElement(FieldElement2 element) { if (!_isReadMember(element)) { _reportErrorForElement( WarningCode.UNUSED_FIELD, element, [element.displayName]); } } - void _visitFunctionElement(FunctionElement element) { + void _visitLocalFunctionElement(LocalFunctionElement element) { if (!_isUsedElement(element)) { - if (_wildCardVariablesEnabled) { - if (element.isLocal && _isNamedWildcard(element)) return; - } - + if (_wildCardVariablesEnabled && _isNamedWildcard(element)) return; _reportErrorForElement( WarningCode.UNUSED_ELEMENT, element, [element.displayName]); } } - void _visitLocalVariableElement(LocalVariableElement element) { + void _visitLocalVariableElement(LocalVariableElement2 element) { if (!_isUsedElement(element) && !_isNamedWildcard(element)) { ErrorCode errorCode; if (_usedElements.isCatchException(element)) { @@ -1058,36 +1069,45 @@ class UnusedLocalElementsVerifier extends RecursiveAstVisitor { } } - void _visitMethodElement(MethodElement element) { + void _visitMethodElement(MethodElement2 element) { if (!_isUsedMember(element)) { _reportErrorForElement( WarningCode.UNUSED_ELEMENT, element, [element.displayName]); } } - void _visitPropertyAccessorElement(PropertyAccessorElement element) { + void _visitPropertyAccessorElement(PropertyAccessorElement2 element) { if (!_isUsedMember(element)) { _reportErrorForElement( WarningCode.UNUSED_ELEMENT, element, [element.displayName]); } } - void _visitTopLevelVariableElement(TopLevelVariableElement element) { + void _visitTopLevelFunctionElement(TopLevelFunctionElement element) { if (!_isUsedElement(element)) { _reportErrorForElement( WarningCode.UNUSED_ELEMENT, element, [element.displayName]); } } - void _visitTypeAliasElement(TypeAliasElement element) { + void _visitTopLevelVariableElement(TopLevelVariableElement2 element) { if (!_isUsedElement(element)) { _reportErrorForElement( WarningCode.UNUSED_ELEMENT, element, [element.displayName]); } } - static bool _hasPragmaVmEntryPoint(Element element) { - return element is ElementImpl && element.hasPragmaVmEntryPoint; + void _visitTypeAliasElement(TypeAliasElement2 element) { + if (!_isUsedElement(element)) { + _reportErrorForElement( + WarningCode.UNUSED_ELEMENT, element, [element.displayName]); + } + } + + static bool _hasPragmaVmEntryPoint(Element2 element) { + return element is Annotatable && + ((element as Annotatable).metadata2 as MetadataImpl) + .hasPragmaVmEntryPoint; } } @@ -1096,21 +1116,21 @@ class UnusedLocalElementsVerifier extends RecursiveAstVisitor { class UsedLocalElements { /// Resolved, locally defined elements that are used or potentially can be /// used. - final HashSet elements = HashSet(); + final HashSet elements = HashSet(); /// [LocalVariableElement]s that represent exceptions in [CatchClause]s. - final HashSet catchExceptionElements = - HashSet(); + final HashSet catchExceptionElements = + HashSet(); /// [LocalVariableElement]s that represent stack traces in [CatchClause]s. - final HashSet catchStackTraceElements = - HashSet(); + final HashSet catchStackTraceElements = + HashSet(); /// Resolved class members that are referenced in the library. - final HashSet members = HashSet(); + final HashSet members = HashSet(); /// Resolved class members that are read in the library. - final HashSet readMembers = HashSet(); + final HashSet readMembers = HashSet(); /// Unresolved class members that are read in the library. final HashSet unresolvedReadMembers = HashSet(); @@ -1132,32 +1152,32 @@ class UsedLocalElements { return result; } - void addCatchException(Element? element) { - if (element is LocalVariableElement) { + void addCatchException(Element2? element) { + if (element is LocalVariableElement2) { catchExceptionElements.add(element); } } - void addCatchStackTrace(Element? element) { - if (element is LocalVariableElement) { + void addCatchStackTrace(Element2? element) { + if (element is LocalVariableElement2) { catchStackTraceElements.add(element); } } - void addElement(Element? element) { - if (element is JoinPatternVariableElementImpl) { + void addElement(Element2? element) { + if (element is JoinPatternVariableElementImpl2) { elements.addAll(element.transitiveVariables); } else if (element is ExecutableMember) { - elements.add(element.declaration); + elements.add(element.baseElement); } else if (element != null) { elements.add(element); } } - void addMember(Element? element) { + void addMember(Element2? element) { // Store un-parameterized members. if (element is ExecutableMember) { - element = element.declaration; + element = element.baseElement; } if (element != null) { @@ -1165,10 +1185,10 @@ class UsedLocalElements { } } - void addReadMember(Element? element) { + void addReadMember(Element2? element) { // Store un-parameterized members. if (element is ExecutableMember) { - element = element.declaration; + element = element.baseElement; } if (element != null) { @@ -1176,17 +1196,11 @@ class UsedLocalElements { } } - bool isCatchException(LocalVariableElement element) { + bool isCatchException(LocalVariableElement2 element) { return catchExceptionElements.contains(element); } - bool isCatchStackTrace(LocalVariableElement element) { + bool isCatchStackTrace(LocalVariableElement2 element) { return catchStackTraceElements.contains(element); } } - -extension on FunctionElement { - bool get isLocal => - enclosingElement3 is FunctionElement || - enclosingElement3 is MethodElement; -} diff --git a/pkg/analyzer/test/src/dart/resolution/instance_creation_test.dart b/pkg/analyzer/test/src/dart/resolution/instance_creation_test.dart index 8d2fd2e2bc97..7de33efebc8e 100644 --- a/pkg/analyzer/test/src/dart/resolution/instance_creation_test.dart +++ b/pkg/analyzer/test/src/dart/resolution/instance_creation_test.dart @@ -190,7 +190,7 @@ augment class A { A(T2 value); } '''); - await assertNoErrorsInCode(r''' + await assertErrorsInCode(r''' part 'a.dart'; class A { @@ -200,7 +200,9 @@ class A { void f() { A(0); } -'''); +''', [ + error(WarningCode.UNUSED_ELEMENT, 33, 1), + ]); var node = findNode.singleInstanceCreationExpression; assertResolvedNodeText(node, r''' @@ -533,7 +535,7 @@ augment class A { A(); } '''); - await assertNoErrorsInCode(r''' + await assertErrorsInCode(r''' part 'a.dart'; class A { @@ -543,7 +545,9 @@ class A { void f() { A(); } -'''); +''', [ + error(WarningCode.UNUSED_ELEMENT, 30, 1), + ]); var node = findNode.singleInstanceCreationExpression; assertResolvedNodeText(node, r''' @@ -2048,7 +2052,7 @@ augment class A { A(T2 value); } '''); - await assertNoErrorsInCode(r''' + await assertErrorsInCode(r''' part 'a.dart'; class A { @@ -2060,7 +2064,9 @@ typedef X = A; void f() { X(0); } -'''); +''', [ + error(WarningCode.UNUSED_ELEMENT, 33, 1), + ]); var node = findNode.singleInstanceCreationExpression; assertResolvedNodeText(node, r''' @@ -2415,7 +2421,7 @@ augment class A { A(); } '''); - await assertNoErrorsInCode(r''' + await assertErrorsInCode(r''' part 'a.dart'; class A { @@ -2427,7 +2433,9 @@ typedef X = A; void f() { X(); } -'''); +''', [ + error(WarningCode.UNUSED_ELEMENT, 30, 1), + ]); var node = findNode.singleInstanceCreationExpression; assertResolvedNodeText(node, r'''