anchor.diff:        var invokeClass = invokeType.element2;
         displayName = "${invokeClass.name}.${element.displayName}";
       }
  +    var message = _deprecatedMessage(element);
  +    reportError(errorNode, element, displayName, message);
  +  }
  +
  +  void _invocationArguments(Element? element, ArgumentList arguments) {
  +    element = element?.declaration;
  +    if (element is ExecutableElement) {
  +      _visitParametersAndArguments(
  +        element.parameters,
  +        arguments.arguments,
  +        _checkForDeprecated,
  +      );
  +    }
  +  }
  +
  +  void _simpleIdentifier(SimpleIdentifier identifier) {
  +    _checkForDeprecated(identifier.staticElement, identifier);
  +  }
  +
  +  /// Return 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) {
  +    // Implicit getters/setters.
  +    if (element.isSynthetic && element is PropertyAccessorElement) {
  +      element = element.variable;
  +    }
  +    var annotation = element.metadata.firstWhereOrNull((e) => e.isDeprecated);
  +    if (annotation == null || annotation.element is PropertyAccessorElement) {
  +      return null;
  +    }
  +    var constantValue = annotation.computeConstantValue();
  +    return constantValue?.getField('message')?.toStringValue() ??
  +        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) {
  +      // TODO(brianwilkerson) Why isn't this the implementation for PropertyAccessorElement?
  +      Element variable = element.variable;
  +      return variable.hasDeprecated;
  +    }
  +    return element.hasDeprecated;
  +  }
  +
  +  /// Return `true` if [element] is a [ParameterElement] declared in [node].
  +  static bool _isLocalParameter(Element? element, AstNode? node) {
  +    if (element is ParameterElement) {
  +      var definingFunction = element.enclosingElement3 as ExecutableElement;
  +
  +      for (; node != null; node = node.parent) {
  +        if (node is ConstructorDeclaration) {
  +          if (node.declaredElement2 == definingFunction) {
  +            return true;
  +          }
  +        } else if (node is FunctionExpression) {
  +          if (node.declaredElement == definingFunction) {
  +            return true;
  +          }
  +        } else if (node is MethodDeclaration) {
  +          if (node.declaredElement2 == definingFunction) {
  +            return true;
  +          }
  +        }
  +      }
  +    }
  +    return false;
  +  }
  +
  +  static void _visitParametersAndArguments(
  +    List<ParameterElement> parameters,
  +    List<Expression> arguments,
  +    void Function(ParameterElement, Expression) f,
  +  ) {
  +    Map<String, ParameterElement>? namedParameters;
  +
  +    var positionalIndex = 0;
  +    for (var argument in arguments) {
  +      if (argument is NamedExpression) {
  +        if (namedParameters == null) {
  +          namedParameters = {};
  +          for (var parameter in parameters) {
  +            if (parameter.isNamed) {
  +              namedParameters[parameter.name] = parameter;
  +            }
  +          }
  +        }
  +        var name = argument.name.label.name;
  +        var parameter = namedParameters[name];
  +        if (parameter != null) {
  +          f(parameter, argument);
  +        }
  +      } else {
  +        if (positionalIndex < parameters.length) {
  +          var parameter = parameters[positionalIndex++];
  +          if (parameter.isPositional) {
  +            f(parameter, argument);
  +          }
  +        }
  +      }
  +    }
  +  }
  +}
  +
  +class DeprecatedMemberUseVerifier extends BaseDeprecatedMemberUseVerifier {
  +  final WorkspacePackage? _workspacePackage;
  +  final ErrorReporter _errorReporter;
  +
  +  DeprecatedMemberUseVerifier(this._workspacePackage, this._errorReporter);
  +
  +  @override
  +  void reportError(
  +      AstNode errorNode, Element element, String displayName, String? message) {
       var library = element is LibraryElement ? element : element.library;
  -    var message = _deprecatedMessage(element);
  +
       if (message == null || message.isEmpty) {
         _errorReporter.reportErrorForNode(
           _isLibraryInWorkspacePackage(library)
  
positive.code:     _checkForDeprecated(node.staticElement, node);
      _invocationArguments(node.staticElement, node.argumentList);
    }
  
    void simpleIdentifier(SimpleIdentifier node) {
      // Don't report declared identifiers.
  
negative.code:     }
      return _workspacePackage!.contains(library.source);
    }
  }
  