// Copyright (c) 2021, 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/ast/ast.dart';
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/member.dart';
import 'package:analyzer/src/dart/element/type.dart';
import 'package:analyzer/src/error/codes.dart';
import 'package:analyzer/src/generated/resolver.dart';

/// A resolver for [ConstructorReference] nodes.
class ConstructorReferenceResolver {
  /// The resolver driving this participant.
  final ResolverVisitor _resolver;

  ConstructorReferenceResolver(this._resolver);

  void resolve(ConstructorReferenceImpl node) {
    if (!_resolver.isConstructorTearoffsEnabled &&
        node.constructorName.type.typeArguments == null) {
      // Only report this if [node] has no explicit type arguments; otherwise
      // the parser has already reported an error.
      _resolver.errorReporter.reportErrorForNode(
          HintCode.SDK_VERSION_CONSTRUCTOR_TEAROFFS, node, []);
    }
    node.constructorName.accept(_resolver);
    var element = node.constructorName.staticElement;
    if (element != null &&
        !element.isFactory &&
        element.enclosingElement.isAbstract) {
      _resolver.errorReporter.reportErrorForNode(
        CompileTimeErrorCode
            .TEAROFF_OF_GENERATIVE_CONSTRUCTOR_OF_ABSTRACT_CLASS,
        node,
        [],
      );
    }
    var name = node.constructorName.name;
    if (element == null &&
        name != null &&
        _resolver.isConstructorTearoffsEnabled) {
      // The illegal construction, which looks like a type-instantiated
      // constructor tearoff, may be an attempt to reference a member on
      // [enclosingElement]. Try to provide a helpful error, and fall back to
      // "unknown constructor."
      //
      // Only report errors when the constructor tearoff feature is enabled,
      // to avoid reporting redundant errors.
      var enclosingElement = node.constructorName.type.name.staticElement;
      if (enclosingElement is TypeAliasElement) {
        enclosingElement = enclosingElement.aliasedType.element;
      }
      // TODO(srawlins): Handle `enclosingElement` being a functio typedef:
      // typedef F<T> = void Function(); var a = F<int>.extensionOnType;`.
      // This is illegal.
      if (enclosingElement is ClassElement) {
        var method = enclosingElement.getMethod(name.name) ??
            enclosingElement.getGetter(name.name) ??
            enclosingElement.getSetter(name.name);
        if (method != null) {
          var error = method.isStatic
              ? CompileTimeErrorCode.CLASS_INSTANTIATION_ACCESS_TO_STATIC_MEMBER
              : CompileTimeErrorCode
                  .CLASS_INSTANTIATION_ACCESS_TO_INSTANCE_MEMBER;
          _resolver.errorReporter.reportErrorForNode(
            error,
            node,
            [name.name],
          );
        } else {
          _resolver.errorReporter.reportErrorForNode(
            CompileTimeErrorCode.CLASS_INSTANTIATION_ACCESS_TO_UNKNOWN_MEMBER,
            node,
            [enclosingElement.name, name.name],
          );
        }
      }
    }
    _inferArgumentTypes(node);
  }

  void _inferArgumentTypes(ConstructorReferenceImpl node) {
    var constructorName = node.constructorName;
    var elementToInfer = _resolver.inferenceHelper.constructorElementToInfer(
      constructorName: constructorName,
      definingLibrary: _resolver.definingLibrary,
    );

    // If the constructor is generic, we'll have a ConstructorMember that
    // substitutes in type arguments (possibly `dynamic`) from earlier in
    // resolution.
    //
    // Otherwise we'll have a ConstructorElement, and we can skip inference
    // because there's nothing to infer in a non-generic type.
    if (elementToInfer != null) {
      // TODO(leafp): Currently, we may re-infer types here, since we
      // sometimes resolve multiple times.  We should really check that we
      // have not already inferred something.  However, the obvious ways to
      // check this don't work, since we may have been instantiated
      // to bounds in an earlier phase, and we *do* want to do inference
      // in that case.

      // Get back to the uninstantiated generic constructor.
      // TODO(jmesserly): should we store this earlier in resolution?
      // Or look it up, instead of jumping backwards through the Member?
      var rawElement = elementToInfer.element;
      var constructorType = elementToInfer.asType;

      var inferred = _resolver.inferenceHelper.inferTearOff(
          node, constructorName.name!, constructorType) as FunctionType?;

      if (inferred != null) {
        var inferredReturnType = inferred.returnType as InterfaceType;

        // Update the static element as well. This is used in some cases, such
        // as computing constant values. It is stored in two places.
        var constructorElement =
            ConstructorMember.from(rawElement, inferredReturnType);

        constructorName.staticElement = constructorElement.declaration;
        constructorName.name?.staticElement = constructorElement.declaration;
        node.staticType = inferred;
        // TODO(srawlins): Always set the TypeName's type to `null`, here, and
        // in the "else" case below, at the very end of [_inferArgumentTypes].
        // This requires refactoring how type arguments are checked against
        // bounds, as this is currently always done with the [TypeName], in
        // type_argument_verifier.dart.
        if (inferred.typeFormals.isNotEmpty) {
          constructorName.type.type = null;
        } else {
          constructorName.type.type = inferredReturnType;
        }
      }
    } else {
      var constructorElement = constructorName.staticElement;
      if (constructorElement == null) {
        node.staticType = DynamicTypeImpl.instance;
      } else {
        node.staticType = constructorElement.type;
      }
    }
  }
}
