diff --git a/pkg/analyzer/lib/src/dart/ast/ast.dart b/pkg/analyzer/lib/src/dart/ast/ast.dart index 87a27d42f484..7e6c7eafe1dc 100644 --- a/pkg/analyzer/lib/src/dart/ast/ast.dart +++ b/pkg/analyzer/lib/src/dart/ast/ast.dart @@ -8076,6 +8076,8 @@ final class ForStatementImpl extends StatementImpl /// A declaration of a fragment of an element. @experimental abstract final class FragmentDeclaration implements Declaration { + // TODO(pq): move `declaredFragment` into `Declaration` and remove this class. + /// The fragment declared by this declaration. /// /// Returns `null` if the AST structure hasn't been resolved. diff --git a/pkg/analyzer/lib/src/dart/element/element.dart b/pkg/analyzer/lib/src/dart/element/element.dart index 877a6bea9b59..e27bb65354b8 100644 --- a/pkg/analyzer/lib/src/dart/element/element.dart +++ b/pkg/analyzer/lib/src/dart/element/element.dart @@ -1970,6 +1970,9 @@ class DynamicElementImpl2 extends TypeDefiningElementImpl2 { @override Null get documentationComment => null; + @override + Element2? get enclosingElement2 => null; + @override DynamicElementImpl get firstFragment => DynamicElementImpl.instance; @@ -8431,6 +8434,9 @@ class NeverElementImpl extends ElementImpl @override NeverElementImpl2 get element => NeverElementImpl2.instance; + @override + Element2? get enclosingElement2 => null; + @override Null get enclosingFragment => null; @@ -8480,6 +8486,9 @@ class NeverElementImpl2 extends TypeDefiningElementImpl2 { @override Null get documentationComment => null; + @override + Element2? get enclosingElement2 => null; + @override NeverElementImpl get firstFragment => NeverElementImpl.instance; diff --git a/pkg/analyzer/lib/src/dart/element/inheritance_manager3.dart b/pkg/analyzer/lib/src/dart/element/inheritance_manager3.dart index e4d44321263d..37fe1f5095a2 100644 --- a/pkg/analyzer/lib/src/dart/element/inheritance_manager3.dart +++ b/pkg/analyzer/lib/src/dart/element/inheritance_manager3.dart @@ -401,9 +401,7 @@ class InheritanceManager3 { if (elements == null) { return null; } - return elements - .map((fragment) => (fragment as ExecutableFragment).element) - .toList(); + return elements.map((fragment) => fragment.asExecutableElement2).toList(); } /// Return all members of mixins, superclasses, and interfaces that a member diff --git a/pkg/linter/lib/src/rules/unreachable_from_main.dart b/pkg/linter/lib/src/rules/unreachable_from_main.dart index 16ff3f99d049..af153ee8cdf1 100644 --- a/pkg/linter/lib/src/rules/unreachable_from_main.dart +++ b/pkg/linter/lib/src/rules/unreachable_from_main.dart @@ -4,10 +4,11 @@ import 'dart:collection'; -import 'package:analyzer/dart/ast/ast.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'; +// ignore: implementation_imports +import 'package:analyzer/src/dart/ast/ast.dart'; import 'package:collection/collection.dart'; import 'package:pub_semver/pub_semver.dart'; @@ -52,19 +53,21 @@ class _DeclarationGatherer { if (declaration is TopLevelVariableDeclaration) { declarations.addAll(declaration.variables.variables); } else { + if (declaration is! FragmentDeclaration) continue; declarations.add(declaration); - var declaredElement = declaration.declaredElement; + var declaredElement = + (declaration as FragmentDeclaration).declaredFragment?.element; if (declaredElement == null || declaredElement.isPrivate) { continue; } if (declaration is ClassDeclaration) { _addMembers( - containerElement: declaration.declaredElement, + containerElement: declaration.declaredFragment?.element, members: declaration.members, ); } else if (declaration is EnumDeclaration) { _addMembers( - containerElement: declaration.declaredElement, + containerElement: declaration.declaredFragment?.element, members: declaration.members, ); } else if (declaration is ExtensionDeclaration) { @@ -79,7 +82,7 @@ class _DeclarationGatherer { ); } else if (declaration is MixinDeclaration) { _addMembers( - containerElement: declaration.declaredElement, + containerElement: declaration.declaredFragment?.element, members: declaration.members, ); } @@ -88,44 +91,44 @@ class _DeclarationGatherer { } void _addMembers({ - required Element? containerElement, + required Element2? containerElement, required List members, }) { - bool isOverride(String rawName) { - if (containerElement is! InterfaceElement) { + bool isOverride(String? rawName) { + if (rawName == null || containerElement is! InterfaceElement2) { return false; } - var libraryUri = containerElement.library.source.uri; + var libraryUri = containerElement.library2.firstFragment.source.uri; var name = Name(libraryUri, rawName); var inheritance = linterContext.inheritanceManager; - return inheritance.getOverridden2(containerElement, name) != null; + return inheritance.getOverridden(containerElement, name) != null; } for (var member in members) { switch (member) { case ConstructorDeclaration(): - var e = member.declaredElement; + var e = member.declaredFragment?.element; if (e != null && e.isPublic && member.parent is! EnumDeclaration) { declarations.add(member); } case FieldDeclaration(): for (var field in member.fields.variables) { - var element = field.declaredElement; + var element = field.declaredFragment?.element; if (element != null && element.isPublic) { - if (!isOverride(element.name)) { + if (!isOverride(element.name3)) { declarations.add(field); } } } case MethodDeclaration(): - var element = member.declaredElement; + var element = member.declaredFragment?.element; if (element != null && element.isPublic) { var rawName = member.name.lexeme; var isTestMethod = rawName.startsWith('test_') || rawName.startsWith('solo_test_') || rawName == 'setUp' || rawName == 'tearDown'; - if (!isOverride(element.name) && !isTestMethod) { + if (!isOverride(element.name3) && !isTestMethod) { declarations.add(member); } } @@ -139,7 +142,7 @@ class _DeclarationGatherer { /// "References" are most often [SimpleIdentifier]s, but can also be other /// nodes which refer to a declaration. class _ReferenceVisitor extends RecursiveAstVisitor { - Map declarationMap; + Map declarationMap; Set declarations = {}; @@ -150,7 +153,7 @@ class _ReferenceVisitor extends RecursiveAstVisitor { @override void visitAnnotation(Annotation node) { - var e = node.element; + var e = node.element2; if (e != null) { _addDeclaration(e); } @@ -169,7 +172,8 @@ class _ReferenceVisitor extends RecursiveAstVisitor { _addNamedTypes(node.withClause?.mixinTypes); _addNamedTypes(node.implementsClause?.interfaces); - var element = node.declaredElement; + var element = node.declaredFragment?.element; + if (element != null) { var hasConstructors = node.members.any((e) => e is ConstructorDeclaration); @@ -179,18 +183,18 @@ class _ReferenceVisitor extends RecursiveAstVisitor { _addDefaultSuperConstructorDeclaration(node); } - var metadata = element.metadata; + var metadata = element.metadata2; // This for-loop style is copied from analyzer's `hasX` getters on // [Element]. - for (var i = 0; i < metadata.length; i++) { - var annotation = metadata[i].element; - if (annotation is PropertyAccessorElement && - annotation.name == 'reflectiveTest' && - annotation.library.name == 'test_reflective_loader') { + for (var i = 0; i < metadata.annotations.length; i++) { + var annotation = metadata.annotations[i].element2; + if (annotation is GetterElement && + annotation.name3 == 'reflectiveTest' && + annotation.library2?.name3 == 'test_reflective_loader') { // The class is instantiated through the use of mirrors in // 'test_reflective_loader'. - var unnamedConstructor = element.constructors - .firstWhereOrNull((constructor) => constructor.name == ''); + var unnamedConstructor = element.constructors2 + .firstWhereOrNull((constructor) => constructor.name3 == 'new'); if (unnamedConstructor != null) { _addDeclaration(unnamedConstructor); } @@ -228,10 +232,10 @@ class _ReferenceVisitor extends RecursiveAstVisitor { @override void visitConstructorName(ConstructorName node) { - var e = node.staticElement; + var e = node.element; if (e != null && _patternLevel == 0) { _addDeclaration(e); - var type = node.type.element; + var type = node.type.element2; if (type != null) { _addDeclaration(type); } @@ -252,7 +256,7 @@ class _ReferenceVisitor extends RecursiveAstVisitor { // The 'dart:convert' library uses dynamic invocation to call `toJson` on // arbitrary objects. Any declaration of `toJson` is automatically // reachable. - var element = node.declaredElement; + var element = node.declaredFragment?.element; if (element != null) { _addDeclaration(element); } @@ -262,7 +266,7 @@ class _ReferenceVisitor extends RecursiveAstVisitor { @override void visitNamedType(NamedType node) { - var element = node.element; + var element = node.element2; if (element == null) { return; } @@ -276,7 +280,7 @@ class _ReferenceVisitor extends RecursiveAstVisitor { node.type?.alias != null || // Any reference to an extension type marks it as reachable, since // casting can be used to instantiate the type. - node.type?.element is ExtensionTypeElement || + node.type?.element3 is ExtensionTypeElement2 || nodeIsInTypeArgument || // A reference to any type in an external variable declaration marks // that type as reachable, since the external implementation can @@ -301,7 +305,7 @@ class _ReferenceVisitor extends RecursiveAstVisitor { @override void visitPatternField(PatternField node) { - var e = node.element; + var e = node.element2; if (e != null) { _addDeclaration(e); } @@ -323,7 +327,7 @@ class _ReferenceVisitor extends RecursiveAstVisitor { @override void visitRedirectingConstructorInvocation( RedirectingConstructorInvocation node) { - var element = node.staticElement; + var element = node.element; if (element != null) { _addDeclaration(element); } @@ -333,7 +337,7 @@ class _ReferenceVisitor extends RecursiveAstVisitor { @override void visitSimpleIdentifier(SimpleIdentifier node) { if (!node.inDeclarationContext()) { - var e = node.staticElement; + var e = node.element; if (e != null) { _addDeclaration(e); } @@ -343,7 +347,7 @@ class _ReferenceVisitor extends RecursiveAstVisitor { @override void visitSuperConstructorInvocation(SuperConstructorInvocation node) { - var e = node.staticElement; + var e = node.element; if (e != null) { _addDeclaration(e); } @@ -367,11 +371,10 @@ class _ReferenceVisitor extends RecursiveAstVisitor { /// /// Also adds the declaration of [element] if it is a public static accessor /// or static method on a public top-level element. - void _addDeclaration(Element element) { + void _addDeclaration(Element2 element) { // First add the enclosing top-level declaration. - var enclosingTopLevelElement = element.thisOrAncestorMatching((a) => - a.enclosingElement3 == null || - a.enclosingElement3 is CompilationUnitElement); + var enclosingTopLevelElement = element.thisOrAncestorMatching2((a) => + a.enclosingElement2 == null || a.enclosingElement2 is LibraryElement2); var enclosingTopLevelDeclaration = declarationMap[enclosingTopLevelElement]; if (enclosingTopLevelDeclaration != null) { declarations.add(enclosingTopLevelDeclaration); @@ -382,14 +385,14 @@ class _ReferenceVisitor extends RecursiveAstVisitor { if (element.isPrivate) { return; } - var enclosingElement = element.enclosingElement3; + var enclosingElement = element.enclosingElement2; if (enclosingElement == null || enclosingElement.isPrivate) { return; } - if (enclosingElement is InterfaceElement || - enclosingElement is ExtensionElement || - enclosingElement is ExtensionTypeElement) { - var declarationElement = element.declaration; + if (enclosingElement is InterfaceElement2 || + enclosingElement is ExtensionElement2 || + enclosingElement is ExtensionTypeElement2) { + var declarationElement = element.baseElement; var declaration = declarationMap[declarationElement]; if (declaration != null) { declarations.add(declaration); @@ -398,11 +401,11 @@ class _ReferenceVisitor extends RecursiveAstVisitor { } void _addDefaultSuperConstructorDeclaration(ClassDeclaration class_) { - var classElement = class_.declaredElement; + var classElement = class_.declaredFragment?.element; var supertype = classElement?.supertype; if (supertype != null) { var unnamedConstructor = - supertype.constructors.firstWhereOrNull((e) => e.name.isEmpty); + supertype.constructors2.firstWhereOrNull((e) => e.name3 == 'new'); if (unnamedConstructor != null) { _addDeclaration(unnamedConstructor); } @@ -414,7 +417,7 @@ class _ReferenceVisitor extends RecursiveAstVisitor { return; } - var element = node.element; + var element = node.element2; if (element == null) { return; } @@ -432,11 +435,11 @@ class _ReferenceVisitor extends RecursiveAstVisitor { } void _visitCompoundAssignmentExpression(CompoundAssignmentExpression node) { - var readElement = node.readElement; + var readElement = node.readElement2; if (readElement != null) { _addDeclaration(readElement); } - var writeElement = node.writeElement; + var writeElement = node.writeElement2; if (writeElement != null) { _addDeclaration(writeElement); } @@ -460,20 +463,21 @@ class _Visitor extends SimpleAstVisitor { if (entryPoints.isEmpty) return; // Map each top-level and static element to its declaration. - var declarationByElement = {}; + var declarationByElement = {}; for (var declaration in declarations) { - var element = declaration.declaredElement; + var element = + (declaration as FragmentDeclaration).declaredFragment?.element; if (element != null) { declarationByElement[element] = declaration; - if (element is TopLevelVariableElement) { - var getter = element.getter; + if (element is TopLevelVariableElement2) { + var getter = element.getter2; if (getter != null) declarationByElement[getter] = declaration; - var setter = element.setter; + var setter = element.setter2; if (setter != null) declarationByElement[setter] = declaration; - } else if (element is FieldElement) { - var getter = element.getter; + } else if (element is FieldElement2) { + var getter = element.getter2; if (getter != null) declarationByElement[getter] = declaration; - var setter = element.setter; + var setter = element.setter2; if (setter != null) declarationByElement[setter] = declaration; } } @@ -512,7 +516,8 @@ class _Visitor extends SimpleAstVisitor { var unitDeclarations = unitDeclarationGatherer.declarations; var unusedDeclarations = unitDeclarations.difference(usedMembers); var unusedMembers = unusedDeclarations.where((declaration) { - var element = declaration.declaredElement; + var element = + (declaration as FragmentDeclaration).declaredFragment?.element; return element != null && element.isPublic && !element.hasVisibleForTesting; @@ -559,23 +564,27 @@ class _Visitor extends SimpleAstVisitor { } } -extension on Element { - bool get isPragma => (library?.isDartCore ?? false) && name == 'pragma'; +extension on Element2 { + bool get hasVisibleForTesting => switch (this) { + Annotatable(:var metadata2) => metadata2.hasVisibleForTesting, + _ => false, + }; + bool get isPragma => (library2?.isDartCore ?? false) && name3 == 'pragma'; } extension on Annotation { bool get isPragma { - var element = elementAnnotation?.element; + var element = elementAnnotation?.element2; DartType type; - if (element is ConstructorElement) { + if (element is ConstructorElement2) { type = element.returnType; - } else if (element is PropertyAccessorElement && element.isGetter) { + } else if (element is GetterElement) { type = element.returnType; } else { // Dunno what this is. return false; } - return type is InterfaceType && type.element.isPragma; + return type is InterfaceType && type.element3.isPragma; } }