Analyzer warnings: add support for @Deprecation.extend and .implement

Work towards https://github.com/dart-lang/sdk/issues/60504

For each annotation, we implement several features in the analyzer:

* The annotation causes certain usage to generate a warning (+ tests).
* Possible fixes for this new warning are offered (+ tests).
* Placing the annotation on an invalid element generates a different
  warning (+ tests).
* Possible fixes for the invalid annotation are offered (+ tests).

Change-Id: I55f8663a4c0589bc8409dda879f28b072eca6197
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/442705
Reviewed-by: Konstantin Shcheglov <scheglov@google.com>
Commit-Queue: Samuel Rawlins <srawlins@google.com>
Reviewed-by: Brian Wilkerson <brianwilkerson@google.com>
diff --git a/pkg/analysis_server/lib/src/services/correction/error_fix_status.yaml b/pkg/analysis_server/lib/src/services/correction/error_fix_status.yaml
index 8a12b05..1f5b2f2 100644
--- a/pkg/analysis_server/lib/src/services/correction/error_fix_status.yaml
+++ b/pkg/analysis_server/lib/src/services/correction/error_fix_status.yaml
@@ -3462,10 +3462,14 @@
   status: hasFix
   notes: |-
     A data driven fix using `replacedBy`.
+WarningCode.DEPRECATED_EXTEND:
+  status: hasFix
 WarningCode.DEPRECATED_EXTENDS_FUNCTION:
   status: needsFix
   notes: |-
-    The fix is to remove `Function` from where it's referenced.
+    The fix is to remove the class from the implements list.
+WarningCode.DEPRECATED_IMPLEMENT:
+  status: hasFix
 WarningCode.DEPRECATED_IMPLEMENTS_FUNCTION:
   status: hasFix
 WarningCode.DEPRECATED_MIXIN_FUNCTION:
@@ -3551,6 +3555,12 @@
   status: hasFix
 WarningCode.INVALID_AWAIT_NOT_REQUIRED_ANNOTATION:
   status: needsFix
+WarningCode.INVALID_DEPRECATED_EXTEND_ANNOTATION:
+  status: needsFix
+  notes: The fix is to remove the annotation.
+WarningCode.INVALID_DEPRECATED_IMPLEMENT_ANNOTATION:
+  status: needsFix
+  notes: The fix is to remove the annotation.
 WarningCode.INVALID_EXPORT_OF_INTERNAL_ELEMENT:
   status: needsFix
   notes: |-
diff --git a/pkg/analysis_server/lib/src/services/correction/fix_internal.dart b/pkg/analysis_server/lib/src/services/correction/fix_internal.dart
index b571416..fc4d65d 100644
--- a/pkg/analysis_server/lib/src/services/correction/fix_internal.dart
+++ b/pkg/analysis_server/lib/src/services/correction/fix_internal.dart
@@ -1197,6 +1197,8 @@
     //  a place where it can be reached (when possible).
     RemoveDeadCode.new,
   ],
+  WarningCode.DEPRECATED_EXTEND: [RemoveExtendsClause.new],
+  WarningCode.DEPRECATED_IMPLEMENT: [RemoveNameFromDeclarationClause.new],
   WarningCode.DEPRECATED_IMPLEMENTS_FUNCTION: [
     RemoveNameFromDeclarationClause.new,
   ],
diff --git a/pkg/analysis_server/test/src/services/correction/fix/remove_extends_clause_test.dart b/pkg/analysis_server/test/src/services/correction/fix/remove_extends_clause_test.dart
index 2810262..1a87b3a 100644
--- a/pkg/analysis_server/test/src/services/correction/fix/remove_extends_clause_test.dart
+++ b/pkg/analysis_server/test/src/services/correction/fix/remove_extends_clause_test.dart
@@ -43,6 +43,34 @@
   @override
   FixKind get kind => DartFixKind.REMOVE_EXTENDS_CLAUSE;
 
+  Future<void> test_deprecatedExtends() async {
+    newFile('$testPackageLibPath/a.dart', '''
+@Deprecated.extend()
+class A {}
+''');
+    await resolveTestCode('''
+import 'a.dart';
+class B extends A {}
+''');
+    await assertHasFix('''
+import 'a.dart';
+class B {}
+''');
+  }
+
+  Future<void> test_deprecatedExtends_classTypeAlias() async {
+    newFile('$testPackageLibPath/a.dart', '''
+@Deprecated.extend()
+class A {}
+''');
+    await resolveTestCode('''
+import 'a.dart';
+mixin M {}
+class B = A with M;
+''');
+    await assertNoFix();
+  }
+
   Future<void> test_mixinClass_extends_class() async {
     await resolveTestCode('''
 class A {}
diff --git a/pkg/analysis_server/test/src/services/correction/fix/remove_name_from_declaration_clause_test.dart b/pkg/analysis_server/test/src/services/correction/fix/remove_name_from_declaration_clause_test.dart
index f299d72..4c1dba5 100644
--- a/pkg/analysis_server/test/src/services/correction/fix/remove_name_from_declaration_clause_test.dart
+++ b/pkg/analysis_server/test/src/services/correction/fix/remove_name_from_declaration_clause_test.dart
@@ -15,6 +15,7 @@
     defineReflectiveTests(ExtendsDisallowedClassTest);
     defineReflectiveTests(ExtendsNonClassTest);
     defineReflectiveTests(ExtendsTypeAliasExpandsToTypeParameterTest);
+    defineReflectiveTests(ImplementsDeprecatedImplementTest);
     defineReflectiveTests(ImplementsDisallowedClassTest);
     defineReflectiveTests(ImplementsRepeatedTest);
     defineReflectiveTests(ImplementsSuperClassTest);
@@ -93,6 +94,27 @@
 }
 
 @reflectiveTest
+class ImplementsDeprecatedImplementTest extends FixProcessorTest {
+  @override
+  FixKind get kind => DartFixKind.REMOVE_NAME_FROM_DECLARATION_CLAUSE;
+
+  Future<void> test_deprecatedExtends() async {
+    newFile('$testPackageLibPath/a.dart', '''
+@Deprecated.implement()
+class A {}
+''');
+    await resolveTestCode('''
+import 'a.dart';
+class B implements A {}
+''');
+    await assertHasFix('''
+import 'a.dart';
+class B {}
+''');
+  }
+}
+
+@reflectiveTest
 class ImplementsDisallowedClassTest extends FixProcessorTest {
   @override
   FixKind get kind => DartFixKind.REMOVE_NAME_FROM_DECLARATION_CLAUSE;
diff --git a/pkg/analyzer/lib/src/dart/element/extensions.dart b/pkg/analyzer/lib/src/dart/element/extensions.dart
index 7b9f516..dad9779 100644
--- a/pkg/analyzer/lib/src/dart/element/extensions.dart
+++ b/pkg/analyzer/lib/src/dart/element/extensions.dart
@@ -74,6 +74,22 @@
     return false;
   }
 
+  /// Whether the use of this element is deprecated.
+  bool get isUseDeprecated {
+    var element = this;
+
+    var metadata =
+        (element is PropertyAccessorElement && element.isSynthetic)
+            ? element.variable.metadata
+            : element.metadata;
+
+    var annotations = metadata.annotations.where((e) => e.isDeprecated);
+    return annotations.any((annotation) {
+      var value = annotation.computeConstantValue();
+      return value?.getField('_isUse')?.toBoolValue() ?? true;
+    });
+  }
+
   /// Whether this element is a wildcard variable.
   bool get isWildcardVariable {
     return name == '_' &&
diff --git a/pkg/analyzer/lib/src/diagnostic/diagnostic_code_values.g.dart b/pkg/analyzer/lib/src/diagnostic/diagnostic_code_values.g.dart
index eafef2a..9147cac 100644
--- a/pkg/analyzer/lib/src/diagnostic/diagnostic_code_values.g.dart
+++ b/pkg/analyzer/lib/src/diagnostic/diagnostic_code_values.g.dart
@@ -988,7 +988,9 @@
   WarningCode.DEAD_CODE_LATE_WILDCARD_VARIABLE_INITIALIZER,
   WarningCode.DEAD_CODE_ON_CATCH_SUBTYPE,
   WarningCode.DEPRECATED_EXPORT_USE,
+  WarningCode.DEPRECATED_EXTEND,
   WarningCode.DEPRECATED_EXTENDS_FUNCTION,
+  WarningCode.DEPRECATED_IMPLEMENT,
   WarningCode.DEPRECATED_IMPLEMENTS_FUNCTION,
   WarningCode.DEPRECATED_MIXIN_FUNCTION,
   WarningCode.DEPRECATED_NEW_IN_COMMENT_REFERENCE,
@@ -1022,6 +1024,8 @@
   WarningCode.INFERENCE_FAILURE_ON_UNTYPED_PARAMETER,
   WarningCode.INVALID_ANNOTATION_TARGET,
   WarningCode.INVALID_AWAIT_NOT_REQUIRED_ANNOTATION,
+  WarningCode.INVALID_DEPRECATED_EXTEND_ANNOTATION,
+  WarningCode.INVALID_DEPRECATED_IMPLEMENT_ANNOTATION,
   WarningCode.INVALID_EXPORT_OF_INTERNAL_ELEMENT,
   WarningCode.INVALID_EXPORT_OF_INTERNAL_ELEMENT_INDIRECTLY,
   WarningCode.INVALID_FACTORY_METHOD_DECL,
diff --git a/pkg/analyzer/lib/src/error/annotation_verifier.dart b/pkg/analyzer/lib/src/error/annotation_verifier.dart
index 9803161..4c49cd8 100644
--- a/pkg/analyzer/lib/src/error/annotation_verifier.dart
+++ b/pkg/analyzer/lib/src/error/annotation_verifier.dart
@@ -45,6 +45,8 @@
     var parent = node.parent;
     if (element.isAwaitNotRequired) {
       _checkAwaitNotRequired(node);
+    } else if (element.isDeprecated) {
+      _checkDeprecated(node);
     } else if (element.isFactory) {
       _checkFactory(node);
     } else if (element.isInternal) {
@@ -113,6 +115,88 @@
     }
   }
 
+  void _checkDeprecated(Annotation node) {
+    var element = node.elementAnnotation;
+    var value = element?.computeConstantValue();
+    if (value == null) return;
+
+    // The vast majority of deprecated annotations use the default constructor.
+    // Check this case first.
+    if (value.getField('_isUse')?.toBoolValue() ?? true) return;
+
+    var isExtend = value.getField('_isExtend')?.toBoolValue() ?? false;
+    if (isExtend) {
+      _checkDeprecatedExtend(node, node.parent);
+      return;
+    }
+
+    var isImplement = value.getField('_isImplement')?.toBoolValue() ?? false;
+    if (isImplement) {
+      _checkDeprecatedImplement(node, node.parent);
+      return;
+    }
+  }
+
+  void _checkDeprecatedExtend(Annotation node, AstNode parent) {
+    if (parent
+        case ClassDeclaration(:var declaredFragment) ||
+            ClassTypeAlias(:var declaredFragment)) {
+      var classElement = declaredFragment?.element;
+      if (classElement == null) return;
+      var hasGenerativeConstructor = classElement.constructors.any(
+        (c) => c.isPublic && c.isGenerative,
+      );
+      if (classElement.isExtendableOutside && hasGenerativeConstructor) return;
+    }
+
+    if (parent is GenericTypeAlias) {
+      var classElement = parent.type.type?.element;
+      if (classElement is ClassElement) {
+        var hasGenerativeConstructor = classElement.constructors.any(
+          (c) => c.isPublic && c.isGenerative,
+        );
+        if (classElement.isExtendableOutside && hasGenerativeConstructor) {
+          return;
+        }
+      }
+    }
+
+    _diagnosticReporter.atNode(
+      node.name,
+      WarningCode.INVALID_DEPRECATED_EXTEND_ANNOTATION,
+    );
+  }
+
+  void _checkDeprecatedImplement(Annotation node, AstNode parent) {
+    if (parent
+        case ClassDeclaration(:var declaredFragment) ||
+            ClassTypeAlias(:var declaredFragment)) {
+      var classElement = declaredFragment?.element;
+      if (classElement == null) return;
+      if (classElement.isImplementableOutside) return;
+    }
+
+    if (parent is MixinDeclaration) {
+      var mixinElement = parent.declaredFragment?.element;
+      if (mixinElement == null) return;
+      if (mixinElement.isImplementableOutside) return;
+    }
+
+    if (parent is GenericTypeAlias) {
+      var element = parent.type.type?.element;
+      if (element is ClassElement && element.isImplementableOutside) {
+        return;
+      } else if (element is MixinElement && element.isImplementableOutside) {
+        return;
+      }
+    }
+
+    _diagnosticReporter.atNode(
+      node.name,
+      WarningCode.INVALID_DEPRECATED_IMPLEMENT_ANNOTATION,
+    );
+  }
+
   /// Reports a warning at [node] if its parent is not a valid target for a
   /// `@factory` annotation.
   void _checkFactory(Annotation node) {
diff --git a/pkg/analyzer/lib/src/error/best_practices_verifier.dart b/pkg/analyzer/lib/src/error/best_practices_verifier.dart
index 728c455..ba46426 100644
--- a/pkg/analyzer/lib/src/error/best_practices_verifier.dart
+++ b/pkg/analyzer/lib/src/error/best_practices_verifier.dart
@@ -28,6 +28,7 @@
 import 'package:analyzer/src/dart/resolver/scope.dart';
 import 'package:analyzer/src/error/annotation_verifier.dart';
 import 'package:analyzer/src/error/codes.dart';
+import 'package:analyzer/src/error/deprecated_functionality_verifier.dart';
 import 'package:analyzer/src/error/deprecated_member_use_verifier.dart';
 import 'package:analyzer/src/error/doc_comment_verifier.dart';
 import 'package:analyzer/src/error/error_handler_verifier.dart';
@@ -64,7 +65,9 @@
 
   final AnnotationVerifier _annotationVerifier;
 
-  final DeprecatedMemberUseVerifier _deprecatedVerifier;
+  final DeprecatedFunctionalityVerifier _deprecatedFunctionalityVerifier;
+
+  final DeprecatedMemberUseVerifier _deprecatedMemberUseVerifier;
 
   final ErrorHandlerVerifier _errorHandlerVerifier;
 
@@ -107,10 +110,13 @@
          _currentLibrary,
          workspacePackage,
        ),
-       _deprecatedVerifier = DeprecatedMemberUseVerifier(
+       _deprecatedFunctionalityVerifier = DeprecatedFunctionalityVerifier(
+         _diagnosticReporter,
+         _currentLibrary,
+       ),
+       _deprecatedMemberUseVerifier = DeprecatedMemberUseVerifier(
          workspacePackage,
          _diagnosticReporter,
-         strictCasts: analysisOptions.strictCasts,
        ),
        _errorHandlerVerifier = ErrorHandlerVerifier(
          _diagnosticReporter,
@@ -131,8 +137,8 @@
        ),
        _widgetPreviewVerifier = WidgetPreviewVerifier(_diagnosticReporter),
        _workspacePackage = workspacePackage {
-    _deprecatedVerifier.pushInDeprecatedValue(
-      _currentLibrary.metadata.hasDeprecated,
+    _deprecatedMemberUseVerifier.pushInDeprecatedValue(
+      _currentLibrary.isUseDeprecated,
     );
     _inDoNotStoreMember = _currentLibrary.metadata.hasDoNotStore;
   }
@@ -166,13 +172,13 @@
 
   @override
   void visitAssignmentExpression(AssignmentExpression node) {
-    _deprecatedVerifier.assignmentExpression(node);
+    _deprecatedMemberUseVerifier.assignmentExpression(node);
     super.visitAssignmentExpression(node);
   }
 
   @override
   void visitBinaryExpression(BinaryExpression node) {
-    _deprecatedVerifier.binaryExpression(node);
+    _deprecatedMemberUseVerifier.binaryExpression(node);
     _checkForInvariantNanComparison(node);
     _checkForInvariantNullComparison(node);
     _invalidAccessVerifier.verifyBinary(node);
@@ -206,7 +212,8 @@
     _invalidAccessVerifier._enclosingClass = element;
 
     bool wasInDoNotStoreMember = _inDoNotStoreMember;
-    _deprecatedVerifier.pushInDeprecatedValue(element.metadata.hasDeprecated);
+    _deprecatedFunctionalityVerifier.classDeclaration(node);
+    _deprecatedMemberUseVerifier.pushInDeprecatedValue(element.isUseDeprecated);
     if (element.metadata.hasDoNotStore) {
       _inDoNotStoreMember = true;
     }
@@ -218,7 +225,7 @@
     } finally {
       _enclosingClass = null;
       _invalidAccessVerifier._enclosingClass = null;
-      _deprecatedVerifier.popInDeprecated();
+      _deprecatedMemberUseVerifier.popInDeprecated();
       _inDoNotStoreMember = wasInDoNotStoreMember;
     }
   }
@@ -227,14 +234,15 @@
   void visitClassTypeAlias(ClassTypeAlias node) {
     _checkForImmutable(node);
     _checkForInvalidSealedSuperclass(node);
-    _deprecatedVerifier.pushInDeprecatedValue(
-      node.declaredFragment!.element.metadata.hasDeprecated,
+    _deprecatedFunctionalityVerifier.classTypeAlias(node);
+    _deprecatedMemberUseVerifier.pushInDeprecatedValue(
+      node.declaredFragment!.element.isUseDeprecated,
     );
 
     try {
       super.visitClassTypeAlias(node);
     } finally {
-      _deprecatedVerifier.popInDeprecated();
+      _deprecatedMemberUseVerifier.popInDeprecated();
     }
   }
 
@@ -281,17 +289,17 @@
       body: node.body,
       initializers: node.initializers,
     );
-    _deprecatedVerifier.pushInDeprecatedValue(element.metadata.hasDeprecated);
+    _deprecatedMemberUseVerifier.pushInDeprecatedValue(element.isUseDeprecated);
     try {
       super.visitConstructorDeclaration(node);
     } finally {
-      _deprecatedVerifier.popInDeprecated();
+      _deprecatedMemberUseVerifier.popInDeprecated();
     }
   }
 
   @override
   void visitConstructorName(ConstructorName node) {
-    _deprecatedVerifier.constructorName(node);
+    _deprecatedMemberUseVerifier.constructorName(node);
     super.visitConstructorName(node);
   }
 
@@ -315,14 +323,14 @@
         );
       }
     }
-    _deprecatedVerifier.pushInDeprecatedValue(
-      node.declaredFragment!.element.metadata.hasDeprecated,
+    _deprecatedMemberUseVerifier.pushInDeprecatedValue(
+      node.declaredFragment!.element.isUseDeprecated,
     );
 
     try {
       super.visitDefaultFormalParameter(node);
     } finally {
-      _deprecatedVerifier.popInDeprecated();
+      _deprecatedMemberUseVerifier.popInDeprecated();
     }
   }
 
@@ -330,27 +338,28 @@
   void visitDotShorthandConstructorInvocation(
     DotShorthandConstructorInvocation node,
   ) {
-    _deprecatedVerifier.dotShorthandConstructorInvocation(node);
+    _deprecatedMemberUseVerifier.dotShorthandConstructorInvocation(node);
     _checkForLiteralConstructorUseInDotShorthand(node);
     super.visitDotShorthandConstructorInvocation(node);
   }
 
   @override
   void visitEnumDeclaration(EnumDeclaration node) {
-    _deprecatedVerifier.pushInDeprecatedValue(
-      node.declaredFragment!.element.metadata.hasDeprecated,
+    _deprecatedMemberUseVerifier.pushInDeprecatedValue(
+      node.declaredFragment!.element.isUseDeprecated,
     );
+    _deprecatedFunctionalityVerifier.enumDeclaration(node);
 
     try {
       super.visitEnumDeclaration(node);
     } finally {
-      _deprecatedVerifier.popInDeprecated();
+      _deprecatedMemberUseVerifier.popInDeprecated();
     }
   }
 
   @override
   void visitExportDirective(covariant ExportDirectiveImpl node) {
-    _deprecatedVerifier.exportDirective(node);
+    _deprecatedMemberUseVerifier.exportDirective(node);
     _checkForInternalExport(node);
     super.visitExportDirective(node);
   }
@@ -365,39 +374,39 @@
 
   @override
   void visitExtensionDeclaration(ExtensionDeclaration node) {
-    _deprecatedVerifier.pushInDeprecatedValue(
-      node.declaredFragment!.element.metadata.hasDeprecated,
+    _deprecatedMemberUseVerifier.pushInDeprecatedValue(
+      node.declaredFragment!.element.isUseDeprecated,
     );
 
     try {
       super.visitExtensionDeclaration(node);
     } finally {
-      _deprecatedVerifier.popInDeprecated();
+      _deprecatedMemberUseVerifier.popInDeprecated();
     }
   }
 
   @override
   void visitExtensionOverride(ExtensionOverride node) {
-    _deprecatedVerifier.extensionOverride(node);
+    _deprecatedMemberUseVerifier.extensionOverride(node);
     super.visitExtensionOverride(node);
   }
 
   @override
   void visitExtensionTypeDeclaration(ExtensionTypeDeclaration node) {
-    _deprecatedVerifier.pushInDeprecatedValue(
-      node.declaredFragment!.element.metadata.hasDeprecated,
+    _deprecatedMemberUseVerifier.pushInDeprecatedValue(
+      node.declaredFragment!.element.isUseDeprecated,
     );
 
     try {
       super.visitExtensionTypeDeclaration(node);
     } finally {
-      _deprecatedVerifier.popInDeprecated();
+      _deprecatedMemberUseVerifier.popInDeprecated();
     }
   }
 
   @override
   void visitFieldDeclaration(FieldDeclaration node) {
-    _deprecatedVerifier.pushInDeprecatedMetadata(node.metadata);
+    _deprecatedMemberUseVerifier.pushInDeprecatedMetadata(node.metadata);
 
     try {
       super.visitFieldDeclaration(node);
@@ -438,7 +447,7 @@
         }
       }
     } finally {
-      _deprecatedVerifier.popInDeprecated();
+      _deprecatedMemberUseVerifier.popInDeprecated();
     }
   }
 
@@ -458,7 +467,7 @@
   void visitFunctionDeclaration(FunctionDeclaration node) {
     bool wasInDoNotStoreMember = _inDoNotStoreMember;
     var element = node.declaredFragment!.element;
-    _deprecatedVerifier.pushInDeprecatedValue(element.metadata.hasDeprecated);
+    _deprecatedMemberUseVerifier.pushInDeprecatedValue(element.isUseDeprecated);
     if (element.metadata.hasDoNotStore) {
       _inDoNotStoreMember = true;
     }
@@ -477,7 +486,7 @@
       );
       super.visitFunctionDeclaration(node);
     } finally {
-      _deprecatedVerifier.popInDeprecated();
+      _deprecatedMemberUseVerifier.popInDeprecated();
       _inDoNotStoreMember = wasInDoNotStoreMember;
     }
   }
@@ -501,7 +510,7 @@
 
   @override
   void visitFunctionExpressionInvocation(FunctionExpressionInvocation node) {
-    _deprecatedVerifier.functionExpressionInvocation(node);
+    _deprecatedMemberUseVerifier.functionExpressionInvocation(node);
     super.visitFunctionExpressionInvocation(node);
   }
 
@@ -509,14 +518,14 @@
   void visitFunctionTypeAlias(FunctionTypeAlias node) {
     _checkStrictInferenceReturnType(node.returnType, node, node.name.lexeme);
     _checkStrictInferenceInParameters(node.parameters);
-    _deprecatedVerifier.pushInDeprecatedValue(
-      node.declaredFragment!.element.metadata.hasDeprecated,
+    _deprecatedMemberUseVerifier.pushInDeprecatedValue(
+      node.declaredFragment!.element.isUseDeprecated,
     );
 
     try {
       super.visitFunctionTypeAlias(node);
     } finally {
-      _deprecatedVerifier.popInDeprecated();
+      _deprecatedMemberUseVerifier.popInDeprecated();
     }
   }
 
@@ -546,20 +555,20 @@
         node.name.lexeme,
       );
     }
-    _deprecatedVerifier.pushInDeprecatedValue(
-      node.declaredFragment!.element.metadata.hasDeprecated,
+    _deprecatedMemberUseVerifier.pushInDeprecatedValue(
+      node.declaredFragment!.element.isUseDeprecated,
     );
 
     try {
       super.visitGenericTypeAlias(node);
     } finally {
-      _deprecatedVerifier.popInDeprecated();
+      _deprecatedMemberUseVerifier.popInDeprecated();
     }
   }
 
   @override
   void visitImportDirective(ImportDirective node) {
-    _deprecatedVerifier.importDirective(node);
+    _deprecatedMemberUseVerifier.importDirective(node);
     var import = node.libraryImport;
     if (import != null && import.prefix?.isDeferred == true) {
       _checkForLoadLibraryFunction(node, import);
@@ -570,7 +579,7 @@
 
   @override
   void visitIndexExpression(IndexExpression node) {
-    _deprecatedVerifier.indexExpression(node);
+    _deprecatedMemberUseVerifier.indexExpression(node);
     super.visitIndexExpression(node);
   }
 
@@ -578,7 +587,7 @@
   void visitInstanceCreationExpression(
     covariant InstanceCreationExpressionImpl node,
   ) {
-    _deprecatedVerifier.instanceCreationExpression(node);
+    _deprecatedMemberUseVerifier.instanceCreationExpression(node);
     _nullSafeApiVerifier.instanceCreation(node);
     _checkForLiteralConstructorUse(node);
     super.visitInstanceCreationExpression(node);
@@ -596,7 +605,7 @@
     var element = node.declaredFragment!.element;
     var enclosingElement = element.enclosingElement;
 
-    _deprecatedVerifier.pushInDeprecatedValue(element.metadata.hasDeprecated);
+    _deprecatedMemberUseVerifier.pushInDeprecatedValue(element.isUseDeprecated);
     if (element.metadata.hasDoNotStore) {
       _inDoNotStoreMember = true;
     }
@@ -650,14 +659,14 @@
 
       super.visitMethodDeclaration(node);
     } finally {
-      _deprecatedVerifier.popInDeprecated();
+      _deprecatedMemberUseVerifier.popInDeprecated();
       _inDoNotStoreMember = wasInDoNotStoreMember;
     }
   }
 
   @override
   void visitMethodInvocation(covariant MethodInvocationImpl node) {
-    _deprecatedVerifier.methodInvocation(node);
+    _deprecatedMemberUseVerifier.methodInvocation(node);
     _errorHandlerVerifier.verifyMethodInvocation(node);
     _nullSafeApiVerifier.methodInvocation(node);
     super.visitMethodInvocation(node);
@@ -670,7 +679,7 @@
     _enclosingClass = element;
     _invalidAccessVerifier._enclosingClass = _enclosingClass;
 
-    _deprecatedVerifier.pushInDeprecatedValue(element.metadata.hasDeprecated);
+    _deprecatedMemberUseVerifier.pushInDeprecatedValue(element.isUseDeprecated);
 
     try {
       _checkForImmutable(node);
@@ -679,13 +688,13 @@
     } finally {
       _enclosingClass = null;
       _invalidAccessVerifier._enclosingClass = null;
-      _deprecatedVerifier.popInDeprecated();
+      _deprecatedMemberUseVerifier.popInDeprecated();
     }
   }
 
   @override
   void visitNamedType(NamedType node) {
-    _deprecatedVerifier.namedType(node);
+    _deprecatedMemberUseVerifier.namedType(node);
     _invalidAccessVerifier.verifyNamedType(node);
     var question = node.question;
     if (question != null) {
@@ -707,14 +716,14 @@
 
   @override
   void visitPatternField(PatternField node) {
-    _deprecatedVerifier.patternField(node);
+    _deprecatedMemberUseVerifier.patternField(node);
     _invalidAccessVerifier.verifyPatternField(node as PatternFieldImpl);
     super.visitPatternField(node);
   }
 
   @override
   void visitPostfixExpression(PostfixExpression node) {
-    _deprecatedVerifier.postfixExpression(node);
+    _deprecatedMemberUseVerifier.postfixExpression(node);
     if (node.operator.type == TokenType.BANG &&
         node.operand.typeOrThrow.isDartCoreNull) {
       _diagnosticReporter.atNode(node, WarningCode.NULL_CHECK_ALWAYS_FAILS);
@@ -724,7 +733,7 @@
 
   @override
   void visitPrefixExpression(PrefixExpression node) {
-    _deprecatedVerifier.prefixExpression(node);
+    _deprecatedMemberUseVerifier.prefixExpression(node);
     super.visitPrefixExpression(node);
   }
 
@@ -732,7 +741,7 @@
   void visitRedirectingConstructorInvocation(
     RedirectingConstructorInvocation node,
   ) {
-    _deprecatedVerifier.redirectingConstructorInvocation(node);
+    _deprecatedMemberUseVerifier.redirectingConstructorInvocation(node);
     super.visitRedirectingConstructorInvocation(node);
   }
 
@@ -752,14 +761,14 @@
 
   @override
   void visitSimpleIdentifier(SimpleIdentifier node) {
-    _deprecatedVerifier.simpleIdentifier(node);
+    _deprecatedMemberUseVerifier.simpleIdentifier(node);
     _invalidAccessVerifier.verify(node);
     super.visitSimpleIdentifier(node);
   }
 
   @override
   void visitSuperConstructorInvocation(SuperConstructorInvocation node) {
-    _deprecatedVerifier.superConstructorInvocation(node);
+    _deprecatedMemberUseVerifier.superConstructorInvocation(node);
     _invalidAccessVerifier.verifySuperConstructorInvocation(node);
     super.visitSuperConstructorInvocation(node);
   }
@@ -772,7 +781,7 @@
 
   @override
   void visitTopLevelVariableDeclaration(TopLevelVariableDeclaration node) {
-    _deprecatedVerifier.pushInDeprecatedMetadata(node.metadata);
+    _deprecatedMemberUseVerifier.pushInDeprecatedMetadata(node.metadata);
 
     if (!_invalidAccessVerifier._inTestDirectory) {
       for (var decl in node.variables.variables) {
@@ -783,7 +792,7 @@
     try {
       super.visitTopLevelVariableDeclaration(node);
     } finally {
-      _deprecatedVerifier.popInDeprecated();
+      _deprecatedMemberUseVerifier.popInDeprecated();
     }
   }
 
diff --git a/pkg/analyzer/lib/src/error/codes.g.dart b/pkg/analyzer/lib/src/error/codes.g.dart
index 0da04bb..25da688 100644
--- a/pkg/analyzer/lib/src/error/codes.g.dart
+++ b/pkg/analyzer/lib/src/error/codes.g.dart
@@ -6372,6 +6372,14 @@
     hasPublishedDocs: true,
   );
 
+  ///  Parameters:
+  ///  0: the name of the member
+  static const WarningCode DEPRECATED_EXTEND = WarningCode(
+    'DEPRECATED_EXTEND',
+    "Extending '{0}' is deprecated.",
+    correctionMessage: "Try removing the 'extends' clause.",
+  );
+
   ///  No parameters.
   static const WarningCode DEPRECATED_EXTENDS_FUNCTION = WarningCode(
     'DEPRECATED_SUBTYPE_OF_FUNCTION',
@@ -6381,6 +6389,14 @@
     uniqueName: 'DEPRECATED_EXTENDS_FUNCTION',
   );
 
+  ///  Parameters:
+  ///  0: the name of the member
+  static const WarningCode DEPRECATED_IMPLEMENT = WarningCode(
+    'DEPRECATED_IMPLEMENT',
+    "Implementing '{0}' is deprecated.",
+    correctionMessage: "Try removing '{0}' from the 'implements' clause.",
+  );
+
   ///  No parameters.
   static const WarningCode DEPRECATED_IMPLEMENTS_FUNCTION = WarningCode(
     'DEPRECATED_SUBTYPE_OF_FUNCTION',
@@ -6700,6 +6716,24 @@
         "Future-returning function, or a Future-typed field.",
   );
 
+  ///  No parameters.
+  static const WarningCode INVALID_DEPRECATED_EXTEND_ANNOTATION = WarningCode(
+    'INVALID_DEPRECATED_EXTEND_ANNOTATION',
+    "The annotation '@Deprecated.extend' can only be applied to extendable "
+        "classes.",
+    correctionMessage: "Try removing the '@Deprecated.extend' annotation.",
+  );
+
+  ///  No parameters.
+  static const WarningCode INVALID_DEPRECATED_IMPLEMENT_ANNOTATION =
+      WarningCode(
+        'INVALID_DEPRECATED_IMPLEMENT_ANNOTATION',
+        "The annotation '@Deprecated.implement' can only be applied to "
+            "implementable classes.",
+        correctionMessage:
+            "Try removing the '@Deprecated.implement' annotation.",
+      );
+
   ///  Parameters:
   ///  0: the name of the element
   static const WarningCode INVALID_EXPORT_OF_INTERNAL_ELEMENT = WarningCode(
diff --git a/pkg/analyzer/lib/src/error/deprecated_functionality_verifier.dart b/pkg/analyzer/lib/src/error/deprecated_functionality_verifier.dart
new file mode 100644
index 0000000..58aa4e5
--- /dev/null
+++ b/pkg/analyzer/lib/src/error/deprecated_functionality_verifier.dart
@@ -0,0 +1,79 @@
+// Copyright (c) 2025, the Dart project authors. Please see the AUTHORS file
+// 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.
+
+import 'package:analyzer/dart/element/element.dart';
+import 'package:analyzer/error/listener.dart';
+import 'package:analyzer/src/dart/ast/ast.dart';
+import 'package:analyzer/src/error/codes.dart';
+
+class DeprecatedFunctionalityVerifier {
+  final DiagnosticReporter _diagnosticReporter;
+
+  final LibraryElement _currentLibrary;
+
+  DeprecatedFunctionalityVerifier(
+    this._diagnosticReporter,
+    this._currentLibrary,
+  );
+
+  void classDeclaration(ClassDeclaration node) {
+    _checkForDeprecatedExtend(node.extendsClause?.superclass);
+    _checkForDeprecatedImplement(node.implementsClause);
+  }
+
+  void classTypeAlias(ClassTypeAlias node) {
+    _checkForDeprecatedExtend(node.superclass);
+    _checkForDeprecatedImplement(node.implementsClause);
+  }
+
+  void enumDeclaration(EnumDeclaration node) {
+    _checkForDeprecatedImplement(node.implementsClause);
+  }
+
+  void _checkForDeprecatedExtend(NamedType? node) {
+    if (node == null) return;
+    var element = node.element;
+    if (element == null) return;
+    if (node.type?.element is InterfaceElement) {
+      if (element.library == _currentLibrary) return;
+      if (element.hasDeprecatedWithField('_isExtend')) {
+        _diagnosticReporter.atNode(
+          node,
+          WarningCode.DEPRECATED_EXTEND,
+          arguments: [element.name!],
+        );
+      }
+    }
+  }
+
+  void _checkForDeprecatedImplement(ImplementsClause? node) {
+    if (node == null) return;
+    var interfaces = node.interfaces;
+    for (var interface in interfaces) {
+      var element = interface.element;
+      if (element == null) continue;
+      if (interface.type?.element is InterfaceElement) {
+        if (element.library == _currentLibrary) continue;
+        if (element.hasDeprecatedWithField('_isImplement')) {
+          _diagnosticReporter.atNode(
+            interface,
+            WarningCode.DEPRECATED_IMPLEMENT,
+            arguments: [element.name!],
+          );
+        }
+      }
+    }
+  }
+}
+
+extension on Element {
+  /// Whether this Element is annotated with a `Deprecated` annotation with a
+  /// `true` value for [fieldName].
+  bool hasDeprecatedWithField(String fieldName) {
+    return metadata.annotations.where((e) => e.isDeprecated).any((annotation) {
+      var value = annotation.computeConstantValue();
+      return value?.getField(fieldName)?.toBoolValue() ?? false;
+    });
+  }
+}
diff --git a/pkg/analyzer/lib/src/error/deprecated_member_use_verifier.dart b/pkg/analyzer/lib/src/error/deprecated_member_use_verifier.dart
index 351ecc7e..3876ec7 100644
--- a/pkg/analyzer/lib/src/error/deprecated_member_use_verifier.dart
+++ b/pkg/analyzer/lib/src/error/deprecated_member_use_verifier.dart
@@ -7,6 +7,7 @@
 import 'package:analyzer/dart/element/type.dart';
 import 'package:analyzer/error/listener.dart';
 import 'package:analyzer/src/dart/ast/ast.dart';
+import 'package:analyzer/src/dart/element/extensions.dart';
 import 'package:analyzer/src/dart/error/hint_codes.dart';
 import 'package:analyzer/src/workspace/workspace.dart';
 import 'package:collection/collection.dart';
@@ -16,10 +17,7 @@
   /// can be marked as deprecated - a class, a method, fields (multiple).
   final List<bool> _inDeprecatedMemberStack = [false];
 
-  final bool _strictCasts;
-
-  BaseDeprecatedMemberUseVerifier({bool strictCasts = false})
-    : _strictCasts = strictCasts;
+  BaseDeprecatedMemberUseVerifier();
 
   void assignmentExpression(AssignmentExpression node) {
     _checkForDeprecated(node.readElement, node.leftHandSide);
@@ -98,7 +96,7 @@
   }
 
   void pushInDeprecatedMetadata(List<Annotation> metadata) {
-    var hasDeprecated = _hasDeprecatedAnnotation(metadata);
+    var hasDeprecated = _hasDeprecatedUseAnnotation(metadata);
     pushInDeprecatedValue(hasDeprecated);
   }
 
@@ -161,11 +159,9 @@
     _invocationArguments(node.element, node.argumentList);
   }
 
-  /// Given some [element], look at the associated metadata and report the use
-  /// of the member if it is declared as deprecated. If a diagnostic is reported
-  /// it should be reported at the given [node].
+  /// Reports the use of [element] at [node] if its use is deprecated.
   void _checkForDeprecated(Element? element, AstNode node) {
-    if (!_isDeprecated(element)) {
+    if (element == null || !element.isUseDeprecated) {
       return;
     }
 
@@ -212,7 +208,7 @@
       }
     }
 
-    String displayName = element!.displayName;
+    String displayName = element.displayName;
     if (element is ConstructorElement) {
       // TODO(jwren): We should modify ConstructorElement.displayName,
       // or have the logic centralized elsewhere, instead of doing this logic
@@ -227,9 +223,9 @@
         displayName == MethodElement.CALL_METHOD_NAME) {
       var invokeType = node.staticInvokeType as InterfaceType;
       var invokeClass = invokeType.element;
-      displayName = "${invokeClass.name}.${element.displayName}";
+      displayName = '${invokeClass.name}.${element.displayName}';
     }
-    var message = _deprecatedMessage(element, strictCasts: _strictCasts);
+    var message = _deprecatedMessage(element);
     reportError(errorEntity, element, displayName, message);
   }
 
@@ -248,13 +244,10 @@
     _checkForDeprecated(identifier.element, identifier);
   }
 
-  /// Return the message in the deprecated annotation on the given [element], or
+  /// The message in the deprecated annotation on the given [element], or
   /// `null` if the element doesn't have a deprecated annotation or if the
   /// annotation does not have a message.
-  static String? _deprecatedMessage(
-    Element element, {
-    required bool strictCasts,
-  }) {
+  static String? _deprecatedMessage(Element element) {
     // Implicit getters/setters.
     if (element.isSynthetic && element is PropertyAccessorElement) {
       element = element.variable;
@@ -270,24 +263,19 @@
         constantValue?.getField('expires')?.toStringValue();
   }
 
-  static bool _hasDeprecatedAnnotation(List<Annotation> annotations) {
-    for (var i = 0; i < annotations.length; i++) {
-      if (annotations[i].elementAnnotation!.isDeprecated) {
-        return true;
-      }
-    }
-    return false;
-  }
-
-  static bool _isDeprecated(Element? element) {
-    if (element == null) {
-      return false;
-    }
-
-    if (element is PropertyAccessorElement && element.isSynthetic) {
-      return element.variable.metadata.hasDeprecated;
-    }
-    return element.metadata.hasDeprecated;
+  /// Whether [annotations] includes an annotation indicating "deprecated use."
+  ///
+  /// This amounts to any annotation using `deprecated` or `Deprecated()` (the
+  /// default constructor) from `dart:core`.
+  static bool _hasDeprecatedUseAnnotation(List<Annotation> annotations) {
+    var deprecatedAnnotations = annotations
+        .map((a) => a.elementAnnotation)
+        .nonNulls
+        .where((a) => a.isDeprecated);
+    return deprecatedAnnotations.any((deprecated) {
+      var value = deprecated.computeConstantValue();
+      return value?.getField('_isUse')?.toBoolValue() ?? true;
+    });
   }
 
   /// Returns whether [element] is a [FormalParameterElement] declared in
@@ -357,11 +345,7 @@
   final WorkspacePackageImpl? _workspacePackage;
   final DiagnosticReporter _diagnosticReporter;
 
-  DeprecatedMemberUseVerifier(
-    this._workspacePackage,
-    this._diagnosticReporter, {
-    required super.strictCasts,
-  });
+  DeprecatedMemberUseVerifier(this._workspacePackage, this._diagnosticReporter);
 
   @override
   void reportError(
diff --git a/pkg/analyzer/lib/src/test_utilities/mock_sdk.dart b/pkg/analyzer/lib/src/test_utilities/mock_sdk.dart
index a7a4bf9..4ce79b8 100644
--- a/pkg/analyzer/lib/src/test_utilities/mock_sdk.dart
+++ b/pkg/analyzer/lib/src/test_utilities/mock_sdk.dart
@@ -314,7 +314,21 @@
 
 class Deprecated extends Object {
   final String message;
-  const Deprecated(this.message);
+  final bool _isUse;
+  final bool _isImplement;
+  final bool _isExtend;
+  const Deprecated(this.message)
+      : _isUse = true,
+        _isImplement = false,
+        _isExtend = false;
+  const Deprecated.implement([this.message = "next release"])
+      : _isUse = false,
+        _isImplement = true,
+        _isExtend = false;
+  const Deprecated.extend([this.message = "next release"])
+      : _isUse = false,
+        _isImplement = false,
+        _isExtend = true;
 }
 
 class pragma {
diff --git a/pkg/analyzer/messages.yaml b/pkg/analyzer/messages.yaml
index 200f8a6..4b75e8f 100644
--- a/pkg/analyzer/messages.yaml
+++ b/pkg/analyzer/messages.yaml
@@ -24009,6 +24009,47 @@
 
       If the name isn't available, then look for instructions from the library
       author or contact them directly to find out how to update your code.
+  DEPRECATED_EXTEND:
+    problemMessage: "Extending '{0}' is deprecated."
+    correctionMessage: Try removing the 'extends' clause.
+    hasPublishedDocs: false
+    comment: |-
+      Parameters:
+      0: the name of the member
+    documentation: |-
+      #### Description
+
+      The analyzer produces this diagnostic when a class which is annotated with
+      `@Deprecated.extend` is used in the `extends` clause of a class
+      declaration.
+
+      This annotation indicates that the ability for classes to extend the
+      annotated class is deprecated, and will soon be removed, perhaps by
+      marking the annotated class with `interface`, `final`, or `sealed`.
+
+      #### Example
+
+      If the library `p` defines a class annotated with `@Deprecated.extend`:
+
+      ```dart
+      %uri="package:p/p.dart"
+      @Deprecated.extend()
+      class C {}
+      ```
+
+      Then, the following code, when in a library other than `p`, produces this
+      diagnostic:
+
+      ```dart
+      import 'package:p/p.dart';
+
+      class D extends [!C!] {}
+      ```
+
+      #### Common fixes
+
+      Follow any directions found in the `Deprecation.extend` annotation, or
+      just remove the class name from the `extends` clause.
   DEPRECATED_EXTENDS_FUNCTION:
     sharedName: DEPRECATED_SUBTYPE_OF_FUNCTION
     problemMessage: "Extending 'Function' is deprecated."
@@ -24040,6 +24081,46 @@
       ```dart
       class F {}
       ```
+  DEPRECATED_IMPLEMENT:
+    problemMessage: "Implementing '{0}' is deprecated."
+    correctionMessage: Try removing '{0}' from the 'implements' clause.
+    hasPublishedDocs: false
+    comment: |-
+      Parameters:
+      0: the name of the member
+    documentation: |-
+      #### Description
+
+      The analyzer produces this diagnostic when a class which is annotated with
+      `@Deprecated.implement` is used in the `implements` clause of a class or
+      enum declaration. This annotation indicates that the ability for classes
+      to implement the annotated class is deprecated, and will soon be removed,
+      perhaps
+      by marking the annotated class with `interface`, `final`, or `sealed`.
+
+      #### Example
+
+      If the library `p` defines a class annotated with `@Deprecated.implement`:
+
+      ```dart
+      %uri="package:p/p.dart"
+      @Deprecated.implement()
+      class C {}
+      ```
+
+      Then, the following code, when in a library other than `p`, produces this
+      diagnostic:
+
+      ```dart
+      import 'package:p/p.dart';
+
+      class D implements [!C!] {}
+      ```
+
+      #### Common fixes
+
+      Follow any directions found in the `Deprecation.implement` annotation, or
+      just remove the class name from the `implements` clause.
   DEPRECATED_IMPLEMENTS_FUNCTION:
     sharedName: DEPRECATED_SUBTYPE_OF_FUNCTION
     problemMessage: "Implementing 'Function' has no effect."
@@ -24730,6 +24811,60 @@
       ```dart
       void f() {}
       ```
+  INVALID_DEPRECATED_EXTEND_ANNOTATION:
+    problemMessage: "The annotation '@Deprecated.extend' can only be applied to extendable classes."
+    correctionMessage: Try removing the '@Deprecated.extend' annotation.
+    hasPublishedDocs: false
+    comment: No parameters.
+    documentation: |-
+      #### Description
+
+      The analyzer produces this diagnostic when anything other than an
+      extendable class is annotated with
+      [`Deprecated.extend`][meta-deprecated-extend]. An extendable class is a
+      class not declared with the `interface`, `final`, or `sealed` keywords,
+      and with at least one public generative constructor.
+
+      #### Example
+
+      The following code produces this diagnostic because the annotation is on a
+      sealed class:
+
+      ```dart
+      @[!Deprecated.extend!]()
+      sealed class C {}
+      ```
+
+      #### Common fixes
+
+      Remove the annotation.
+  INVALID_DEPRECATED_IMPLEMENT_ANNOTATION:
+    problemMessage: "The annotation '@Deprecated.implement' can only be applied to implementable classes."
+    correctionMessage: Try removing the '@Deprecated.implement' annotation.
+    hasPublishedDocs: false
+    comment: No parameters.
+    documentation: |-
+      #### Description
+
+      The analyzer produces this diagnostic when anything other than an
+      implementable class or mixin is annotated with
+      [`Deprecated.implement`][meta-deprecated-implement]. An implementable
+      class or mixin is one not declared with the `base`, `final`, or `sealed`
+      keywords.
+
+      #### Example
+
+      The following code produces this diagnostic because the annotation is on a
+      sealed class:
+
+      ```dart
+      @[!Deprecated.implement!]()
+      sealed class C {}
+      ```
+
+      #### Common fixes
+
+      Remove the annotation.
   INVALID_EXPORT_OF_INTERNAL_ELEMENT:
     problemMessage: "The member '{0}' can't be exported as a part of a package's public API."
     correctionMessage: "Try using a hide clause to hide '{0}'."
diff --git a/pkg/analyzer/test/src/diagnostics/deprecated_extend_test.dart b/pkg/analyzer/test/src/diagnostics/deprecated_extend_test.dart
new file mode 100644
index 0000000..2b252d7
--- /dev/null
+++ b/pkg/analyzer/test/src/diagnostics/deprecated_extend_test.dart
@@ -0,0 +1,109 @@
+// Copyright (c) 2025, the Dart project authors. Please see the AUTHORS file
+// 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.
+
+import 'package:analyzer/src/error/codes.dart';
+import 'package:test_reflective_loader/test_reflective_loader.dart';
+
+import '../dart/resolution/context_collection_resolution.dart';
+
+main() {
+  defineReflectiveSuite(() {
+    defineReflectiveTests(DeprecatedExtendTest);
+  });
+}
+
+@reflectiveTest
+class DeprecatedExtendTest extends PubPackageResolutionTest {
+  test_annotatedClass() async {
+    newFile('$testPackageLibPath/foo.dart', r'''
+@Deprecated.extend()
+class Foo {}
+''');
+
+    await assertErrorsInCode(
+      r'''
+import 'foo.dart';
+class Bar extends Foo {}
+''',
+      [error(WarningCode.DEPRECATED_EXTEND, 37, 3)],
+    );
+  }
+
+  test_annotatedClass_indirect() async {
+    newFile('$testPackageLibPath/foo.dart', r'''
+@Deprecated.extend()
+class Foo {}
+class Bar extends Foo {}
+''');
+
+    await assertNoErrorsInCode(r'''
+import 'foo.dart';
+class Baz extends Bar {}
+''');
+  }
+
+  test_annotatedClass_typedef() async {
+    newFile('$testPackageLibPath/foo.dart', r'''
+@Deprecated.extend()
+class Foo {}
+typedef Foo2 = Foo;
+''');
+
+    await assertNoErrorsInCode(r'''
+import 'foo.dart';
+class Bar extends Foo2 {}
+''');
+  }
+
+  test_annotatedClassTypeAlias() async {
+    newFile('$testPackageLibPath/foo.dart', r'''
+@Deprecated.extend()
+class Foo = Object with M;
+mixin M {}
+''');
+
+    await assertErrorsInCode(
+      r'''
+import 'foo.dart';
+class Bar extends Foo {}
+''',
+      [error(WarningCode.DEPRECATED_EXTEND, 37, 3)],
+    );
+  }
+
+  test_classTypeAlias() async {
+    newFile('$testPackageLibPath/foo.dart', r'''
+@Deprecated.extend()
+class Foo {}
+''');
+
+    await assertErrorsInCode(
+      r'''
+import 'foo.dart';
+mixin M {}
+class Bar = Foo with M;
+''',
+      [error(WarningCode.DEPRECATED_EXTEND, 42, 3)],
+    );
+  }
+
+  test_insideLibrary() async {
+    await assertNoErrorsInCode(r'''
+@Deprecated.extend()
+class Foo {}
+class Bar extends Foo {}
+''');
+  }
+
+  test_noAnnotation() async {
+    newFile('$testPackageLibPath/foo.dart', r'''
+class Foo {}
+''');
+
+    await assertNoErrorsInCode(r'''
+import 'foo.dart';
+class Bar extends Foo {}
+''');
+  }
+}
diff --git a/pkg/analyzer/test/src/diagnostics/deprecated_implement_test.dart b/pkg/analyzer/test/src/diagnostics/deprecated_implement_test.dart
new file mode 100644
index 0000000..0213299
--- /dev/null
+++ b/pkg/analyzer/test/src/diagnostics/deprecated_implement_test.dart
@@ -0,0 +1,124 @@
+// Copyright (c) 2025, the Dart project authors. Please see the AUTHORS file
+// 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.
+
+import 'package:analyzer/src/error/codes.dart';
+import 'package:test_reflective_loader/test_reflective_loader.dart';
+
+import '../dart/resolution/context_collection_resolution.dart';
+
+main() {
+  defineReflectiveSuite(() {
+    defineReflectiveTests(DeprecatedImplementTest);
+  });
+}
+
+@reflectiveTest
+class DeprecatedImplementTest extends PubPackageResolutionTest {
+  test_annotatedClass() async {
+    newFile('$testPackageLibPath/foo.dart', r'''
+@Deprecated.implement()
+class Foo {}
+''');
+
+    await assertErrorsInCode(
+      r'''
+import 'foo.dart';
+class Bar implements Foo {}
+''',
+      [error(WarningCode.DEPRECATED_IMPLEMENT, 40, 3)],
+    );
+  }
+
+  test_annotatedClass_indirect() async {
+    newFile('$testPackageLibPath/foo.dart', r'''
+@Deprecated.implement()
+class Foo {}
+class Bar extends Foo {}
+''');
+
+    await assertNoErrorsInCode(r'''
+import 'foo.dart';
+class Baz implements Bar {}
+''');
+  }
+
+  test_annotatedClass_typedef() async {
+    newFile('$testPackageLibPath/foo.dart', r'''
+@Deprecated.implement()
+class Foo {}
+typedef Foo2 = Foo;
+''');
+
+    await assertNoErrorsInCode(r'''
+import 'foo.dart';
+class Bar implements Foo2 {}
+''');
+  }
+
+  test_annotatedClassTypeAlias() async {
+    newFile('$testPackageLibPath/foo.dart', r'''
+@Deprecated.implement()
+class Foo  = Object with M;
+mixin M {}
+''');
+
+    await assertErrorsInCode(
+      r'''
+import 'foo.dart';
+class Bar implements Foo {}
+''',
+      [error(WarningCode.DEPRECATED_IMPLEMENT, 40, 3)],
+    );
+  }
+
+  test_classTypeAlias() async {
+    newFile('$testPackageLibPath/foo.dart', r'''
+@Deprecated.implement()
+class Foo {}
+''');
+
+    await assertErrorsInCode(
+      r'''
+import 'foo.dart';
+mixin M {}
+class Bar = Object with M implements Foo;
+''',
+      [error(WarningCode.DEPRECATED_IMPLEMENT, 67, 3)],
+    );
+  }
+
+  test_enum() async {
+    newFile('$testPackageLibPath/foo.dart', r'''
+@Deprecated.implement()
+class Foo {}
+''');
+
+    await assertErrorsInCode(
+      r'''
+import 'foo.dart';
+enum Bar implements Foo { one; }
+''',
+      [error(WarningCode.DEPRECATED_IMPLEMENT, 39, 3)],
+    );
+  }
+
+  test_insideLibrary() async {
+    await assertNoErrorsInCode(r'''
+@Deprecated.implement()
+class Foo {}
+class Bar implements Foo {}
+''');
+  }
+
+  test_noAnnotation() async {
+    newFile('$testPackageLibPath/foo.dart', r'''
+class Foo {}
+''');
+
+    await assertNoErrorsInCode(r'''
+import 'foo.dart';
+class Bar implements Foo {}
+''');
+  }
+}
diff --git a/pkg/analyzer/test/src/diagnostics/invalid_deprecated_extend_annotation_test.dart b/pkg/analyzer/test/src/diagnostics/invalid_deprecated_extend_annotation_test.dart
new file mode 100644
index 0000000..d81fb6e
--- /dev/null
+++ b/pkg/analyzer/test/src/diagnostics/invalid_deprecated_extend_annotation_test.dart
@@ -0,0 +1,103 @@
+// Copyright (c) 2025, the Dart project authors. Please see the AUTHORS file
+// 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.
+
+import 'package:analyzer/src/error/codes.dart';
+import 'package:test_reflective_loader/test_reflective_loader.dart';
+
+import '../dart/resolution/context_collection_resolution.dart';
+
+main() {
+  defineReflectiveSuite(() {
+    defineReflectiveTests(InvalidDeprecatedExtendAnnotationTest);
+  });
+}
+
+@reflectiveTest
+class InvalidDeprecatedExtendAnnotationTest extends PubPackageResolutionTest {
+  test_class() async {
+    await assertNoErrorsInCode(r'''
+@Deprecated.extend()
+class C {}
+''');
+  }
+
+  test_class_final() async {
+    await assertErrorsInCode(
+      r'''
+@Deprecated.extend()
+final class C {}
+''',
+      [error(WarningCode.INVALID_DEPRECATED_EXTEND_ANNOTATION, 1, 17)],
+    );
+  }
+
+  test_class_interface() async {
+    await assertErrorsInCode(
+      r'''
+@Deprecated.extend()
+interface class C {}
+''',
+      [error(WarningCode.INVALID_DEPRECATED_EXTEND_ANNOTATION, 1, 17)],
+    );
+  }
+
+  test_class_noPublicGenerativeConstructor() async {
+    await assertErrorsInCode(
+      r'''
+@Deprecated.extend()
+class C {
+  C._();
+}
+''',
+      [error(WarningCode.INVALID_DEPRECATED_EXTEND_ANNOTATION, 1, 17)],
+    );
+  }
+
+  test_class_sealed() async {
+    await assertErrorsInCode(
+      r'''
+@Deprecated.extend()
+sealed class C {}
+''',
+      [error(WarningCode.INVALID_DEPRECATED_EXTEND_ANNOTATION, 1, 17)],
+    );
+  }
+
+  test_classTypeAlias() async {
+    await assertNoErrorsInCode(r'''
+mixin M {}
+@Deprecated.extend()
+class C = Object with M;
+''');
+  }
+
+  test_mixin() async {
+    await assertErrorsInCode(
+      r'''
+@Deprecated.extend()
+mixin M {}
+''',
+      [error(WarningCode.INVALID_DEPRECATED_EXTEND_ANNOTATION, 1, 17)],
+    );
+  }
+
+  test_typeAlias_forClass() async {
+    await assertNoErrorsInCode(r'''
+class C {}
+@Deprecated.extend()
+typedef D = C;
+''');
+  }
+
+  test_typeAlias_forEnum() async {
+    await assertErrorsInCode(
+      r'''
+enum E { one; }
+@Deprecated.extend()
+typedef F = E;
+''',
+      [error(WarningCode.INVALID_DEPRECATED_EXTEND_ANNOTATION, 17, 17)],
+    );
+  }
+}
diff --git a/pkg/analyzer/test/src/diagnostics/invalid_deprecated_implement_annotation_test.dart b/pkg/analyzer/test/src/diagnostics/invalid_deprecated_implement_annotation_test.dart
new file mode 100644
index 0000000..b556be3
--- /dev/null
+++ b/pkg/analyzer/test/src/diagnostics/invalid_deprecated_implement_annotation_test.dart
@@ -0,0 +1,109 @@
+// Copyright (c) 2025, the Dart project authors. Please see the AUTHORS file
+// 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.
+
+import 'package:analyzer/src/error/codes.dart';
+import 'package:test_reflective_loader/test_reflective_loader.dart';
+
+import '../dart/resolution/context_collection_resolution.dart';
+
+main() {
+  defineReflectiveSuite(() {
+    defineReflectiveTests(InvalidDeprecatedImplementAnnotationTest);
+  });
+}
+
+@reflectiveTest
+class InvalidDeprecatedImplementAnnotationTest
+    extends PubPackageResolutionTest {
+  test_class() async {
+    await assertNoErrorsInCode(r'''
+@Deprecated.implement()
+class C {}
+''');
+  }
+
+  test_class_base() async {
+    await assertErrorsInCode(
+      r'''
+@Deprecated.implement()
+base class C {}
+''',
+      [error(WarningCode.INVALID_DEPRECATED_IMPLEMENT_ANNOTATION, 1, 20)],
+    );
+  }
+
+  test_class_final() async {
+    await assertErrorsInCode(
+      r'''
+@Deprecated.implement()
+final class C {}
+''',
+      [error(WarningCode.INVALID_DEPRECATED_IMPLEMENT_ANNOTATION, 1, 20)],
+    );
+  }
+
+  test_class_sealed() async {
+    await assertErrorsInCode(
+      r'''
+@Deprecated.implement()
+sealed class C {}
+''',
+      [error(WarningCode.INVALID_DEPRECATED_IMPLEMENT_ANNOTATION, 1, 20)],
+    );
+  }
+
+  test_classTypeAlias() async {
+    await assertNoErrorsInCode(r'''
+mixin M {}
+@Deprecated.implement()
+class C = Object with M;
+''');
+  }
+
+  test_function() async {
+    await assertErrorsInCode(
+      r'''
+@Deprecated.implement()
+void f() {}
+''',
+      [error(WarningCode.INVALID_DEPRECATED_IMPLEMENT_ANNOTATION, 1, 20)],
+    );
+  }
+
+  test_mixin() async {
+    await assertNoErrorsInCode(r'''
+@Deprecated.implement()
+mixin M {}
+''');
+  }
+
+  test_mixin_base() async {
+    await assertErrorsInCode(
+      r'''
+@Deprecated.implement()
+base mixin M {}
+''',
+      [error(WarningCode.INVALID_DEPRECATED_IMPLEMENT_ANNOTATION, 1, 20)],
+    );
+  }
+
+  test_typeAlias_forClass() async {
+    await assertNoErrorsInCode(r'''
+class C {}
+@Deprecated.implement()
+typedef D = C;
+''');
+  }
+
+  test_typeAlias_forEnum() async {
+    await assertErrorsInCode(
+      r'''
+enum E { one; }
+@Deprecated.implement()
+typedef F = E;
+''',
+      [error(WarningCode.INVALID_DEPRECATED_IMPLEMENT_ANNOTATION, 17, 20)],
+    );
+  }
+}
diff --git a/pkg/analyzer/test/src/diagnostics/test_all.dart b/pkg/analyzer/test/src/diagnostics/test_all.dart
index 3304af3..da053cc 100644
--- a/pkg/analyzer/test/src/diagnostics/test_all.dart
+++ b/pkg/analyzer/test/src/diagnostics/test_all.dart
@@ -180,7 +180,9 @@
 import 'deprecated_colon_for_default_value_test.dart'
     as deprecated_colon_for_default_value;
 import 'deprecated_export_use_test.dart' as deprecated_export_use;
+import 'deprecated_extend_test.dart' as deprecated_extend;
 import 'deprecated_extends_function_test.dart' as deprecated_extends_function;
+import 'deprecated_implement_test.dart' as deprecated_implement;
 import 'deprecated_implements_function_test.dart'
     as deprecated_implements_function;
 import 'deprecated_member_use_test.dart' as deprecated_member_use;
@@ -434,6 +436,10 @@
     as await_not_required_annotation;
 import 'invalid_constant_test.dart' as invalid_constant;
 import 'invalid_constructor_name_test.dart' as invalid_constructor_name;
+import 'invalid_deprecated_extend_annotation_test.dart'
+    as invalid_deprecated_extend_annotation;
+import 'invalid_deprecated_implement_annotation_test.dart'
+    as invalid_deprecated_implement_annotation;
 import 'invalid_do_not_submit_test.dart' as invalid_do_not_submit;
 import 'invalid_exception_value_test.dart' as invalid_exception_value;
 import 'invalid_export_of_internal_element_test.dart'
@@ -690,7 +696,8 @@
     as nullable_type_in_implements_clause;
 import 'nullable_type_in_on_clause_test.dart' as nullable_type_in_on_clause;
 import 'nullable_type_in_with_clause_test.dart' as nullable_type_in_with_clause;
-import 'number_literals_with_separators_test.dart' as number_literals_with_separators;
+import 'number_literals_with_separators_test.dart'
+    as number_literals_with_separators;
 import 'object_cannot_extend_another_class_test.dart'
     as object_cannot_extend_another_class;
 import 'obsolete_colon_for_default_value_test.dart'
@@ -1056,7 +1063,9 @@
     definitely_unassigned_late_local_variable.main();
     deprecated_colon_for_default_value.main();
     deprecated_export_use.main();
+    deprecated_extend.main();
     deprecated_extends_function.main();
+    deprecated_implement.main();
     deprecated_implements_function.main();
     deprecated_member_use.main();
     deprecated_mixin_function.main();
@@ -1214,6 +1223,8 @@
     await_not_required_annotation.main();
     invalid_constant.main();
     invalid_constructor_name.main();
+    invalid_deprecated_extend_annotation.main();
+    invalid_deprecated_implement_annotation.main();
     invalid_do_not_submit.main();
     invalid_exception_value.main();
     invalid_export_of_internal_element.main();
diff --git a/pkg/linter/lib/src/rules/deprecated_member_use_from_same_package.dart b/pkg/linter/lib/src/rules/deprecated_member_use_from_same_package.dart
index d294e03..4e75d4e 100644
--- a/pkg/linter/lib/src/rules/deprecated_member_use_from_same_package.dart
+++ b/pkg/linter/lib/src/rules/deprecated_member_use_from_same_package.dart
@@ -11,6 +11,7 @@
 import 'package:analyzer/dart/ast/visitor.dart';
 import 'package:analyzer/dart/element/element.dart';
 import 'package:analyzer/error/error.dart';
+import 'package:analyzer/src/dart/element/extensions.dart'; // ignore: implementation_imports
 import 'package:analyzer/src/error/deprecated_member_use_verifier.dart' // ignore: implementation_imports
     show BaseDeprecatedMemberUseVerifier;
 import 'package:analyzer/workspace/workspace.dart';
@@ -343,11 +344,7 @@
   }
 
   void _withDeprecatedFragment(Fragment? fragment, void Function() recurse) {
-    var isDeprecated = false;
-    if (fragment?.element case var element?) {
-      isDeprecated = element.metadata.hasDeprecated;
-    }
-
+    var isDeprecated = fragment?.element.isUseDeprecated ?? false;
     _deprecatedVerifier.pushInDeprecatedValue(isDeprecated);
     try {
       recurse();