// Copyright (c) 2014, 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/dart/element/type.dart';
import 'package:analyzer/src/dart/ast/ast.dart';
import 'package:analyzer/src/dart/element/element.dart';
import 'package:analyzer/src/dart/element/type.dart';
import 'package:analyzer/src/dart/element/type_provider.dart';
import 'package:analyzer/src/dart/resolver/comment_reference_resolver.dart';
import 'package:analyzer/src/dart/resolver/method_invocation_resolver.dart';
import 'package:analyzer/src/dart/resolver/scope.dart';
import 'package:analyzer/src/diagnostic/diagnostic.dart' as diag;
import 'package:analyzer/src/error/listener.dart';
import 'package:analyzer/src/generated/resolver.dart';
import 'package:analyzer/src/generated/super_context.dart';
import 'package:analyzer/src/utilities/extensions/object.dart';

/// An object used by instances of [ResolverVisitor] to resolve references
/// within the AST structure to the elements being referenced. The requirements
/// for the element resolver are:
///
/// 1. Every [SimpleIdentifier] should be resolved to the element to which it
///    refers. Specifically:
///    * An identifier within the declaration of that name should resolve to the
///      element being declared.
///    * An identifier denoting a prefix should resolve to the element
///      representing the import that defines the prefix (an [LibraryImport]).
///    * An identifier denoting a variable should resolve to the element
///      representing the variable (a [VariableElement]).
///    * An identifier denoting a parameter should resolve to the element
///      representing the parameter (a [FormalParameterElement]).
///    * An identifier denoting a field should resolve to the element
///      representing the getter or setter being invoked (a
///      [PropertyAccessorElement]).
///    * An identifier denoting the name of a method or function being invoked
///      should resolve to the element representing the method or function (an
///      [ExecutableElement]).
///    * An identifier denoting a label should resolve to the element
///      representing the label (a [LabelElement]).
///    The identifiers within directives are exceptions to this rule and are
///    covered below.
/// 2. Every node containing a token representing an operator that can be
///    overridden ( [BinaryExpression], [PrefixExpression], [PostfixExpression])
///    should resolve to the element representing the method invoked by that
///    operator (a [MethodElement]).
/// 3. Every [FunctionExpressionInvocation] should resolve to the element
///    representing the function being invoked (a [ExecutableElement]). This
///    will be the same element as that to which the name is resolved if the
///    function has a name, but is provided for those cases where an unnamed
///    function is being invoked.
/// 4. Every [LibraryDirective] and [PartOfDirective] should resolve to the
///    element representing the library being specified by the directive (a
///    [LibraryElement]) unless, in the case of a part-of directive, the
///    specified library does not exist.
/// 5. Every [ImportDirective] and [ExportDirective] should resolve to the
///    element representing the library being specified by the directive unless
///    the specified library does not exist (an [LibraryImport] or
///    [LibraryExport]).
/// 6. The identifier representing the prefix in an [ImportDirective] should
///    resolve to the element representing the prefix (a [PrefixElement]).
/// 7. The identifiers in the hide and show combinators in [ImportDirective]s
///    and [ExportDirective]s should resolve to the elements that are being
///    hidden or shown, respectively, unless those names are not defined in the
///    specified library (or the specified library does not exist).
/// 8. Every [PartDirective] should resolve to the element representing the
///    compilation unit being specified by the string unless the specified
///    compilation unit does not exist (a [LibraryFragment]).
///
/// Note that AST nodes that would represent elements that are not defined are
/// not resolved to anything. This includes such things as references to
/// undeclared variables (which is an error) and names in hide and show
/// combinators that are not defined in the imported library (which is not an
/// error).
class ElementResolver {
  /// The resolver driving this participant.
  final ResolverVisitor _resolver;

  /// The element for the library containing the compilation unit being visited.
  final LibraryElementImpl _definingLibrary;

  final MethodInvocationResolver _methodInvocationResolver;

  late final _commentReferenceResolver = CommentReferenceResolver(
    _typeProvider,
    _resolver,
  );

  /// Initialize a newly created visitor to work for the given [_resolver] to
  /// resolve the nodes in a compilation unit.
  ElementResolver(this._resolver)
    : _definingLibrary = _resolver.definingLibrary,
      _methodInvocationResolver = MethodInvocationResolver(
        _resolver,
        inferenceHelper: _resolver.inferenceHelper,
      );

  DiagnosticReporter get _diagnosticReporter => _resolver.diagnosticReporter;

  TypeProviderImpl get _typeProvider => _resolver.typeProvider;

  void visitClassDeclaration(ClassDeclaration node) {}

  void visitClassTypeAlias(ClassTypeAlias node) {}

  void visitCommentReference(CommentReference node) {
    _commentReferenceResolver.resolve(node);
  }

  void visitConstructorDeclaration(ConstructorDeclarationImpl node) {
    var element = node.declaredFragment!.element;
    var redirectedNode = node.redirectedConstructor;
    if (redirectedNode != null) {
      // set redirected factory constructor
      var redirectedElement = redirectedNode.element;
      element.redirectedConstructor = redirectedElement;
    } else {
      // set redirected generative constructor
      for (ConstructorInitializer initializer in node.initializers) {
        if (initializer is RedirectingConstructorInvocationImpl) {
          var redirectedElement = initializer.element;
          element.redirectedConstructor = redirectedElement;
        }
      }
    }
  }

  void visitConstructorName(covariant ConstructorNameImpl node) {
    var type = node.type.type;
    if (type == null) {
      return;
    }
    if (type is DynamicType) {
      // Nothing to do.
    } else if (type is InterfaceTypeImpl) {
      // look up ConstructorElement
      InternalConstructorElement? constructor;
      var name = node.name;
      if (name == null) {
        constructor = type.lookUpConstructor(null, _definingLibrary);
      } else {
        constructor = type.lookUpConstructor(name.name, _definingLibrary);
        name.element = constructor;
      }
      node.element = constructor;
    }
  }

  void visitDeclaredIdentifier(DeclaredIdentifier node) {}

  void visitDotShorthandConstructorInvocation(
    covariant DotShorthandConstructorInvocationImpl node,
  ) {
    var invokedConstructor = node.element;
    var argumentList = node.argumentList;
    var parameters = _resolveArgumentsToFunction(
      argumentList,
      invokedConstructor,
    );
    if (parameters != null) {
      argumentList.correspondingStaticParameters = parameters;
    }
  }

  /// Resolves the dot shorthand invocation, [node].
  ///
  /// If [node] is rewritten to be a [FunctionExpressionInvocation] or a
  /// [DotShorthandConstructorInvocation] in the process, then returns that new
  /// node. Otherwise, returns `null`.
  RewrittenMethodInvocationImpl? visitDotShorthandInvocation(
    covariant DotShorthandInvocationImpl node, {
    List<WhyNotPromotedGetter>? whyNotPromotedArguments,
    required TypeImpl contextType,
  }) {
    whyNotPromotedArguments ??= [];
    return _methodInvocationResolver.resolveDotShorthand(
      node,
      whyNotPromotedArguments,
      contextType: contextType,
    );
  }

  void visitEnumConstantDeclaration(EnumConstantDeclaration node) {}

  void visitEnumDeclaration(EnumDeclaration node) {}

  void visitExportDirective(ExportDirectiveImpl node) {
    var exportElement = node.libraryExport;
    if (exportElement != null) {
      // The element is null when the URI is invalid
      // TODO(brianwilkerson): Figure out whether the element can ever be
      // something other than an ExportElement
      _resolveCombinators(exportElement.exportedLibrary, node.combinators);
    }
  }

  void visitExtensionDeclaration(ExtensionDeclaration node) {}

  void visitExtensionTypeDeclaration(ExtensionTypeDeclaration node) {}

  void visitFieldDeclaration(FieldDeclaration node) {}

  void visitFieldFormalParameter(FieldFormalParameter node) {}

  void visitFunctionDeclaration(FunctionDeclaration node) {}

  void visitFunctionTypeAlias(FunctionTypeAlias node) {}

  void visitGenericTypeAlias(GenericTypeAlias node) {}

  void visitImportDirective(covariant ImportDirectiveImpl node) {
    var prefixNode = node.prefix;
    if (prefixNode != null) {
      String prefixName = prefixNode.name;
      var prefixes = _resolver.libraryFragment.prefixes;
      int count = prefixes.length;
      for (int i = 0; i < count; i++) {
        var prefixElement = prefixes[i];
        if (prefixElement.displayName == prefixName) {
          prefixNode.element = prefixElement;
          break;
        }
      }
    }
    var importElement = node.libraryImport;
    if (importElement != null) {
      // The element is null when the URI is invalid
      var library = importElement.importedLibrary;
      if (library != null) {
        _resolveCombinators(library, node.combinators);
      }
    }
  }

  void visitInstanceCreationExpression(
    covariant InstanceCreationExpressionImpl node,
  ) {
    var invokedConstructor = node.constructorName.element;
    var argumentList = node.argumentList;
    var parameters = _resolveArgumentsToFunction(
      argumentList,
      invokedConstructor,
    );
    if (parameters != null) {
      argumentList.correspondingStaticParameters = parameters;
    }
  }

  void visitLibraryDirective(LibraryDirective node) {}

  void visitMethodDeclaration(MethodDeclaration node) {}

  /// Resolves the method invocation, [node].
  void visitMethodInvocation(
    MethodInvocation node, {
    List<WhyNotPromotedGetter>? whyNotPromotedArguments,
    required TypeImpl contextType,
  }) {
    whyNotPromotedArguments ??= [];
    _methodInvocationResolver.resolve(
      node as MethodInvocationImpl,
      whyNotPromotedArguments,
      contextType: contextType,
    );
  }

  void visitMixinDeclaration(MixinDeclaration node) {}

  void visitPartDirective(PartDirective node) {}

  void visitPartOfDirective(PartOfDirective node) {}

  void visitRecordTypeAnnotationNamedField(
    RecordTypeAnnotationNamedField node,
  ) {}

  void visitRecordTypeAnnotationPositionalField(
    RecordTypeAnnotationPositionalField node,
  ) {}

  void visitRedirectingConstructorInvocation(
    covariant RedirectingConstructorInvocationImpl node,
  ) {
    var enclosingClass = _resolver.enclosingClass;
    if (enclosingClass is! InterfaceElementImpl) {
      // TODO(brianwilkerson): Report this error.
      return;
    }
    ConstructorElementImpl? element;
    var name = node.constructorName;
    if (name == null) {
      element = enclosingClass.unnamedConstructor;
    } else {
      element = enclosingClass.getNamedConstructor(name.name);
    }
    if (element == null) {
      // TODO(brianwilkerson): Report this error and decide what element to
      // associate with the node.
      return;
    }
    if (name != null) {
      name.element = element;
    }
    node.element = element;
    var argumentList = node.argumentList;
    var parameters = _resolveArgumentsToFunction(argumentList, element);
    if (parameters != null) {
      argumentList.correspondingStaticParameters = parameters;
    }
  }

  void visitRegularFormalParameter(RegularFormalParameter node) {}

  void visitSuperConstructorInvocation(
    covariant SuperConstructorInvocationImpl node,
  ) {
    var enclosingClass = _resolver.enclosingClass;
    if (enclosingClass is! InterfaceElementImpl) {
      // TODO(brianwilkerson): Report this error.
      return;
    }
    var superType = enclosingClass.supertype;
    if (superType == null) {
      // TODO(brianwilkerson): Report this error.
      return;
    }
    var name = node.constructorName;
    var superName = name?.name;
    var element = superType.lookUpConstructor(superName, _definingLibrary);
    if (element == null || !element.isAccessibleIn(_definingLibrary)) {
      if (name != null) {
        _diagnosticReporter.report(
          diag.undefinedConstructorInInitializer
              .withArguments(type: superType, constructorName: name.name)
              .at(node),
        );
      } else {
        _diagnosticReporter.report(
          diag.undefinedConstructorInInitializerDefault
              .withArguments(className: superType.element.name ?? '<unknown>')
              .at(node),
        );
      }
      return;
    } else {
      if (element.isFactory &&
          // Check if we've reported [NO_GENERATIVE_CONSTRUCTORS_IN_SUPERCLASS].
          !element.enclosingElement.constructors.every(
            (constructor) => constructor.isFactory,
          )) {
        _diagnosticReporter.report(
          diag.nonGenerativeConstructor
              .withArguments(constructor: element)
              .at(node),
        );
      }
    }
    if (name != null) {
      name.element = element;
    }
    node.element = element;
    // TODO(brianwilkerson): Defer this check until we know there's an error (by
    // in-lining _resolveArgumentsToFunction below).
    var declaration = node.thisOrAncestorOfType<ClassDeclaration>();
    var extendedNamedType = declaration?.extendsClause?.superclass;
    if (extendedNamedType != null &&
        _resolver.libraryFragment.shouldIgnoreUndefinedNamedType(
          extendedNamedType,
        )) {
      return;
    }
    var argumentList = node.argumentList;
    var parameters = _resolveArgumentsToFunction(
      argumentList,
      element,
      enclosingConstructorFormalParameterList:
          node.parent.tryCast<ConstructorDeclarationImpl>()?.parameters ??
          node.parent
              .tryCast<PrimaryConstructorBodyImpl>()
              ?.declaration
              ?.formalParameters,
    );
    if (parameters != null) {
      argumentList.correspondingStaticParameters = parameters;
    }
  }

  void visitSuperExpression(SuperExpression node) {
    var context = SuperContext.of(node);
    switch (context) {
      case SuperContext.annotation:
      case SuperContext.static:
      case SuperContext.anonymousMethod:
        _diagnosticReporter.report(diag.superInInvalidContext.at(node));
      case SuperContext.extension:
        _diagnosticReporter.report(diag.superInExtension.at(node));
      case SuperContext.extensionType:
        _diagnosticReporter.report(diag.superInExtensionType.at(node));
    }
  }

  void visitTopLevelVariableDeclaration(TopLevelVariableDeclaration node) {}

  void visitTypeParameter(TypeParameter node) {}

  void visitVariableDeclarationList(VariableDeclarationList node) {}

  /// Given an [argumentList] and the [executableElement] that will be invoked
  /// using those argument, compute the list of parameters that correspond to
  /// the list of arguments. An error will be reported if any of the arguments
  /// cannot be matched to a parameter. Return the parameters that correspond to
  /// the arguments, or `null` if no correspondence could be computed.
  List<InternalFormalParameterElement?>? _resolveArgumentsToFunction(
    ArgumentList argumentList,
    ExecutableElement? executableElement, {
    FormalParameterList? enclosingConstructorFormalParameterList,
  }) {
    if (executableElement == null) {
      return null;
    }
    return ResolverVisitor.resolveArgumentsToParameters(
      argumentList: argumentList,
      formalParameters: executableElement.formalParameters,
      diagnosticReporter: _diagnosticReporter,
      enclosingConstructorFormalParameterList:
          enclosingConstructorFormalParameterList,
    );
  }

  /// Resolve the names in the given [combinators] in the scope of the given
  /// [library].
  void _resolveCombinators(
    LibraryElementImpl? library,
    NodeList<Combinator> combinators,
  ) {
    if (library == null) {
      //
      // The library will be null if the directive containing the combinators
      // has a URI that is not valid.
      //
      return;
    }
    Namespace namespace = library.exportNamespace;
    for (Combinator combinator in combinators) {
      NodeList<SimpleIdentifier> names;
      if (combinator is HideCombinator) {
        names = combinator.hiddenNames;
      } else {
        names = (combinator as ShowCombinator).shownNames;
      }
      for (var name in names) {
        name as SimpleIdentifierImpl;
        String nameStr = name.name;
        var element = namespace.get2(nameStr) ?? namespace.get2("$nameStr=");
        if (element != null) {
          // Ensure that the name always resolves to a top-level variable
          // rather than a getter or setter
          if (element is PropertyAccessorElement) {
            name.element = element.variable;
          } else {
            name.element = element;
          }
        }
      }
    }
  }
}
