// Copyright (c) 2019, 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.

// ignore_for_file: analyzer_use_new_elements

import 'package:analyzer/dart/element/element.dart';
import 'package:analyzer/dart/element/scope.dart';
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/ast/extensions.dart';
import 'package:analyzer/src/dart/ast/utilities.dart';
import 'package:analyzer/src/error/codes.dart';

/// Handles possible rewrites of AST.
///
/// When code is initially parsed, many assumptions are made which may be
/// incorrect given newer Dart syntax. For example, `new a.b()` is parsed as an
/// [InstanceCreationExpression], but `a.b()` (without `new`) is parsed as a
/// [MethodInvocation]. The public methods of this class carry out the minimal
/// amount of resolution in order to determine whether a node (and its
/// descendants) should be replaced by another, and perform such replacements.
///
/// The public methods of this class form a complete accounting of possible
/// node replacements.
class AstRewriter {
  final ErrorReporter _errorReporter;

  AstRewriter(this._errorReporter);

  /// Possibly rewrites [node] as a [MethodInvocation] with a
  /// [FunctionReference] target.
  ///
  /// Code such as `a<...>.b(...);` (or with a prefix such as `p.a<...>.b(...)`)
  /// is parsed as an [ExpressionStatement] with an [InstanceCreationExpression]
  /// with `a<...>.b` as the [ConstructorName] (which has 'type' of `a<...>`
  /// and 'name' of `b`). The [InstanceCreationExpression] is rewritten as a
  /// [MethodInvocation] if `a` resolves to a function.
  AstNode instanceCreationExpression(
      Scope nameScope, InstanceCreationExpressionImpl node) {
    if (node.keyword != null) {
      // Either `new` or `const` has been specified.
      return node;
    }
    var typeNode = node.constructorName.type;
    var importPrefix = typeNode.importPrefix;
    if (importPrefix == null) {
      var element = nameScope.lookup(typeNode.name2.lexeme).getter;
      if (element is FunctionElement ||
          element is MethodElement ||
          element is PropertyAccessorElement) {
        return _toMethodInvocationOfFunctionReference(
          node: node,
          function: SimpleIdentifierImpl(typeNode.name2),
        );
      } else if (element is TypeAliasElement &&
          element.aliasedElement is GenericFunctionTypeElement) {
        return _toMethodInvocationOfAliasedTypeLiteral(
          node: node,
          function: SimpleIdentifierImpl(typeNode.name2),
          element: element,
        );
      }
    } else {
      var prefixName = importPrefix.name.lexeme;
      var prefixElement = nameScope.lookup(prefixName).getter;
      if (prefixElement is PrefixElement) {
        var prefixedName = typeNode.name2.lexeme;
        var element = prefixElement.scope.lookup(prefixedName).getter;
        if (element is FunctionElement) {
          return _toMethodInvocationOfFunctionReference(
            node: node,
            function: PrefixedIdentifierImpl(
              prefix: SimpleIdentifierImpl(importPrefix.name),
              period: importPrefix.period,
              identifier: SimpleIdentifierImpl(typeNode.name2),
            ),
          );
        } else if (element is TypeAliasElement &&
            element.aliasedElement is GenericFunctionTypeElement) {
          return _toMethodInvocationOfAliasedTypeLiteral(
            node: node,
            function: PrefixedIdentifierImpl(
              prefix: SimpleIdentifierImpl(importPrefix.name),
              period: importPrefix.period,
              identifier: SimpleIdentifierImpl(typeNode.name2),
            ),
            element: element,
          );
        }

        // If `element` is a [ClassElement], or a [TypeAliasElement] aliasing
        // an interface type, then this indeed looks like a constructor call; do
        // not rewrite `node`.

        // If `element` is a [TypeAliasElement] aliasing a function type, then
        // this looks like an attempt type instantiate a function type alias
        // (which is not a feature), and then call a method on the resulting
        // [Type] object; no not rewrite `node`.

        // If `typeName.identifier` cannot be resolved, do not rewrite `node`.
        return node;
      } else {
        // In the case that `prefixElement` is not a [PrefixElement], then
        // `typeName`, as a [PrefixedIdentifier], cannot refer to a class or an
        // aliased type; rewrite `node` as a [MethodInvocation].
        return _toMethodInvocationOfFunctionReference(
          node: node,
          function: PrefixedIdentifierImpl(
            prefix: SimpleIdentifierImpl(importPrefix.name),
            period: importPrefix.period,
            identifier: SimpleIdentifierImpl(typeNode.name2),
          ),
        );
      }
    }

    return node;
  }

  /// Possibly rewrites [node] as an [ExtensionOverride] or as an
  /// [InstanceCreationExpression].
  AstNode methodInvocation(Scope nameScope, MethodInvocationImpl node) {
    var methodName = node.methodName;
    if (methodName.isSynthetic) {
      // This isn't a constructor invocation because the method name is
      // synthetic.
      return node;
    }

    var target = node.target;
    var operator = node.operator;
    if (target == null) {
      // Possible cases: C() or C<>()
      if (node.realTarget != null) {
        // This isn't a constructor invocation because it's in a cascade.
        return node;
      }
      var element = nameScope.lookup(methodName.name).getter;
      if (element is InterfaceElement) {
        return _toInstanceCreation_type(
          node: node,
          typeIdentifier: methodName,
        );
      } else if (element is ExtensionElement) {
        var extensionOverride = ExtensionOverrideImpl(
          importPrefix: null,
          name: methodName.token,
          element: element,
          typeArguments: node.typeArguments,
          argumentList: node.argumentList,
        );
        NodeReplacer.replace(node, extensionOverride);
        return extensionOverride;
      } else if (element is TypeAliasElement &&
          element.aliasedType is InterfaceType) {
        return _toInstanceCreation_type(
          node: node,
          typeIdentifier: methodName,
        );
      }
    } else if (target is SimpleIdentifierImpl && operator != null) {
      // Possible cases: C.n(), p.C() or p.C<>()
      if (node.isNullAware) {
        // This isn't a constructor invocation because a null aware operator is
        // being used.
      }
      var element = nameScope.lookup(target.name).getter;
      if (element is InterfaceElement) {
        // class C { C.named(); }
        // C.named()
        return _toInstanceCreation_type_constructor(
          node: node,
          typeIdentifier: target,
          constructorIdentifier: methodName,
          classElement: element,
        );
      } else if (element is PrefixElement) {
        // Possible cases: p.C() or p.C<>()
        var prefixedElement = element.scope.lookup(methodName.name).getter;
        if (prefixedElement is InterfaceElement) {
          return _toInstanceCreation_prefix_type(
            node: node,
            prefixIdentifier: target,
            typeIdentifier: methodName,
          );
        } else if (prefixedElement is ExtensionElement) {
          var extensionOverride = ExtensionOverrideImpl(
            importPrefix: ImportPrefixReferenceImpl(
              name: target.token,
              period: operator,
            )..element = element,
            name: node.methodName.token,
            element: prefixedElement,
            typeArguments: node.typeArguments,
            argumentList: node.argumentList,
          );
          NodeReplacer.replace(node, extensionOverride);
          return extensionOverride;
        } else if (prefixedElement is TypeAliasElement &&
            prefixedElement.aliasedType is InterfaceType) {
          return _toInstanceCreation_prefix_type(
            node: node,
            prefixIdentifier: target,
            typeIdentifier: methodName,
          );
        }
      } else if (element is TypeAliasElement) {
        var aliasedType = element.aliasedType;
        if (aliasedType is InterfaceType) {
          // class C { C.named(); }
          // typedef X = C;
          // X.named()
          return _toInstanceCreation_type_constructor(
            node: node,
            typeIdentifier: target,
            constructorIdentifier: methodName,
            classElement: aliasedType.element,
          );
        }
      }
    } else if (target is PrefixedIdentifierImpl) {
      // Possible case: p.C.n()
      var prefixElement = nameScope.lookup(target.prefix.name).getter;
      target.prefix.staticElement = prefixElement;
      if (prefixElement is PrefixElement) {
        var prefixedName = target.identifier.name;
        var element = prefixElement.scope.lookup(prefixedName).getter;
        if (element is InterfaceElement) {
          return _instanceCreation_prefix_type_name(
            node: node,
            typeNameIdentifier: target,
            constructorIdentifier: methodName,
            classElement: element,
          );
        } else if (element is TypeAliasElement) {
          var aliasedType = element.aliasedType;
          if (aliasedType is InterfaceType) {
            return _instanceCreation_prefix_type_name(
              node: node,
              typeNameIdentifier: target,
              constructorIdentifier: methodName,
              classElement: aliasedType.element,
            );
          }
        }
      }
    }
    return node;
  }

  /// Possibly rewrites [node] as a [ConstructorReference].
  ///
  /// Code such as `List.filled;` is parsed as (an [ExpressionStatement] with) a
  /// [PrefixedIdentifier] with 'prefix' of `List` and 'identifier' of `filled`.
  /// The [PrefixedIdentifier] may need to be rewritten as a
  /// [ConstructorReference].
  AstNode prefixedIdentifier(Scope nameScope, PrefixedIdentifierImpl node) {
    var parent = node.parent;
    if (parent is Annotation) {
      // An annotations which is a const constructor invocation can initially be
      // represented with a [PrefixedIdentifier]. Do not rewrite such nodes.
      return node;
    }
    if (parent is CommentReferenceImpl) {
      // TODO(srawlins): This probably should be allowed to be rewritten to a
      // [ConstructorReference] at some point.
      return node;
    }
    if (parent is AssignmentExpressionImpl && parent.leftHandSide == node) {
      // A constructor cannot be assigned to, in some expression like
      // `C.new = foo`; do not rewrite.
      return node;
    }
    var identifier = node.identifier;
    if (identifier.isSynthetic) {
      // This isn't a constructor reference.
      return node;
    }
    var prefix = node.prefix;
    var prefixElement = nameScope.lookup(prefix.name).getter;
    if (parent is ConstantPattern && prefixElement is PrefixElement) {
      var element = prefixElement.scope.lookup(node.identifier.name).getter;
      if (element is TypeDefiningElement) {
        return _toPatternTypeLiteral(parent, node);
      }
    }
    if (prefixElement is InterfaceElement) {
      // Example:
      //     class C { C.named(); }
      //     C.named
      return _toConstructorReference_prefixed(
          node: node, classElement: prefixElement);
    } else if (prefixElement is TypeAliasElement) {
      var aliasedType = prefixElement.aliasedType;
      if (aliasedType is InterfaceType) {
        // Example:
        //     class C { C.named(); }
        //     typedef X = C;
        //     X.named
        return _toConstructorReference_prefixed(
          node: node,
          classElement: aliasedType.element,
        );
      }
    }
    return node;
  }

  /// Possibly rewrites [node] as a [ConstructorReference].
  ///
  /// Code such as `async.Future.value;` is parsed as (an [ExpressionStatement]
  /// with) a [PropertyAccess] with a 'target' of [PrefixedIdentifier] (with
  /// 'prefix' of `List` and 'identifier' of `filled`) and a 'propertyName' of
  /// `value`. The [PropertyAccess] may need to be rewritten as a
  /// [ConstructorReference].
  AstNode propertyAccess(Scope nameScope, PropertyAccessImpl node) {
    if (node.isCascaded) {
      // For example, `List..filled`: this is a property access on an instance
      // `Type`.
      return node;
    }
    if (node.parent is CommentReferenceImpl) {
      // TODO(srawlins): This probably should be allowed to be rewritten to a
      // [ConstructorReference] at some point.
      return node;
    }
    var receiver = node.target!;

    IdentifierImpl receiverIdentifier;
    TypeArgumentListImpl? typeArguments;
    if (receiver is PrefixedIdentifierImpl) {
      receiverIdentifier = receiver;
    } else if (receiver is FunctionReferenceImpl) {
      // A [ConstructorReference] with explicit type arguments is initially
      // parsed as a [PropertyAccess] with a [FunctionReference] target; for
      // example: `List<int>.filled` or `core.List<int>.filled`.
      var function = receiver.function;
      if (function is! IdentifierImpl) {
        // If [receiverIdentifier] is not an Identifier then [node] is not a
        // ConstructorReference.
        return node;
      }
      receiverIdentifier = function;
      typeArguments = receiver.typeArguments;
    } else {
      // If the receiver is not (initially) a prefixed identifier or a function
      // reference, then [node] is not a constructor reference.
      return node;
    }

    Element? element;
    if (receiverIdentifier is SimpleIdentifierImpl) {
      element = nameScope.lookup(receiverIdentifier.name).getter;
    } else if (receiverIdentifier is PrefixedIdentifierImpl) {
      var prefixElement =
          nameScope.lookup(receiverIdentifier.prefix.name).getter;
      if (prefixElement is PrefixElement) {
        element = prefixElement.scope
            .lookup(receiverIdentifier.identifier.name)
            .getter;
      } else {
        // This expression is something like `foo.List<int>.filled` where `foo`
        // is not an import prefix.
        // TODO(srawlins): Tease out a `null` prefixElement from others for
        // specific errors.
        return node;
      }
    }

    if (element is InterfaceElement) {
      // Example:
      //     class C<T> { C.named(); }
      //     C<int>.named
      return _toConstructorReference_propertyAccess(
        node: node,
        receiver: receiverIdentifier,
        typeArguments: typeArguments,
        classElement: element,
      );
    } else if (element is TypeAliasElement) {
      var aliasedType = element.aliasedType;
      if (aliasedType is InterfaceType) {
        // Example:
        //     class C<T> { C.named(); }
        //     typedef X<T> = C<T>;
        //     X<int>.named
        return _toConstructorReference_propertyAccess(
          node: node,
          receiver: receiverIdentifier,
          typeArguments: typeArguments,
          classElement: aliasedType.element,
        );
      }
    }

    // If [receiverIdentifier] is an Identifier, but could not be resolved to
    // an Element, we cannot assume [node] is a ConstructorReference.
    //
    // TODO(srawlins): However, take an example like `Lisst<int>.filled;`
    // (where 'Lisst' does not resolve to any element). Possibilities include:
    // the user tried to write a TypeLiteral or a FunctionReference, then access
    // a property on that (these include: hashCode, runtimeType, tearoff of
    // toString, and extension methods on Type); or the user tried to write a
    // ConstructReference. It seems much more likely that the user is trying to
    // do the latter. Consider doing the work so that the user gets an error in
    // this case about `Lisst` not being a type, or `Lisst.filled` not being a
    // known constructor.
    return node;
  }

  AstNode simpleIdentifier(Scope nameScope, SimpleIdentifierImpl node) {
    var parent = node.parent;
    if (parent is ConstantPattern) {
      var element = nameScope.lookup(node.name).getter;
      if (element is TypeDefiningElement) {
        return _toPatternTypeLiteral(parent, node);
      }
    }

    return node;
  }

  AstNode _instanceCreation_prefix_type_name({
    required MethodInvocationImpl node,
    required PrefixedIdentifierImpl typeNameIdentifier,
    required SimpleIdentifierImpl constructorIdentifier,
    required InterfaceElement classElement,
  }) {
    var augmented = classElement.augmented;
    var constructorElement = augmented.getNamedConstructor(
      constructorIdentifier.name,
    );
    if (constructorElement == null) {
      return node;
    }

    var typeArguments = node.typeArguments;
    if (typeArguments != null) {
      _errorReporter.atNode(
        typeArguments,
        CompileTimeErrorCode.WRONG_NUMBER_OF_TYPE_ARGUMENTS_CONSTRUCTOR,
        arguments: [typeNameIdentifier.toString(), constructorIdentifier.name],
      );
    }

    var typeName = NamedTypeImpl(
      importPrefix: ImportPrefixReferenceImpl(
        name: typeNameIdentifier.prefix.token,
        period: typeNameIdentifier.period,
      ),
      name2: typeNameIdentifier.identifier.token,
      typeArguments: typeArguments,
      question: null,
    );
    var constructorName = ConstructorNameImpl(
      type: typeName,
      period: node.operator,
      name: constructorIdentifier,
    );
    var instanceCreationExpression = InstanceCreationExpressionImpl(
      keyword: null,
      constructorName: constructorName,
      argumentList: node.argumentList,
      typeArguments: null,
    );
    NodeReplacer.replace(node, instanceCreationExpression);
    return instanceCreationExpression;
  }

  AstNode _toConstructorReference_prefixed({
    required PrefixedIdentifierImpl node,
    required InterfaceElement classElement,
  }) {
    var name = node.identifier.name;
    var constructorElement = name == 'new'
        ? classElement.unnamedConstructor
        : classElement.getNamedConstructor(name);
    if (constructorElement == null) {
      return node;
    }

    var typeName = NamedTypeImpl(
      importPrefix: null,
      name2: node.prefix.token,
      typeArguments: null,
      question: null,
    );
    var constructorName = ConstructorNameImpl(
      type: typeName,
      period: node.period,
      name: node.identifier,
    );
    var constructorReference = ConstructorReferenceImpl(
      constructorName: constructorName,
    );
    NodeReplacer.replace(node, constructorReference);
    return constructorReference;
  }

  AstNode _toConstructorReference_propertyAccess({
    required PropertyAccessImpl node,
    required IdentifierImpl receiver,
    required TypeArgumentListImpl? typeArguments,
    required InterfaceElement classElement,
  }) {
    var name = node.propertyName.name;
    var constructorElement = name == 'new'
        ? classElement.unnamedConstructor
        : classElement.getNamedConstructor(name);
    if (constructorElement == null && typeArguments == null) {
      // If there is no constructor by this name, and no type arguments,
      // do not rewrite the node. If there _are_ type arguments (like
      // `prefix.C<int>.name`, then it looks more like a constructor tearoff
      // than anything else, so continue with the rewrite.
      return node;
    }

    var operator = node.operator;

    var typeName = receiver.toNamedType(
      typeArguments: typeArguments,
      question: null,
    );
    var constructorName = ConstructorNameImpl(
      type: typeName,
      period: operator,
      name: node.propertyName,
    );
    var constructorReference = ConstructorReferenceImpl(
      constructorName: constructorName,
    );
    NodeReplacer.replace(node, constructorReference);
    return constructorReference;
  }

  InstanceCreationExpression _toInstanceCreation_prefix_type({
    required MethodInvocationImpl node,
    required SimpleIdentifierImpl prefixIdentifier,
    required SimpleIdentifierImpl typeIdentifier,
  }) {
    var typeName = NamedTypeImpl(
      importPrefix: ImportPrefixReferenceImpl(
        name: prefixIdentifier.token,
        period: node.operator!,
      ),
      name2: typeIdentifier.token,
      typeArguments: node.typeArguments,
      question: null,
    );
    var constructorName = ConstructorNameImpl(
      type: typeName,
      period: null,
      name: null,
    );
    var instanceCreationExpression = InstanceCreationExpressionImpl(
      keyword: null,
      constructorName: constructorName,
      argumentList: node.argumentList,
      typeArguments: null,
    );
    NodeReplacer.replace(node, instanceCreationExpression);
    return instanceCreationExpression;
  }

  InstanceCreationExpression _toInstanceCreation_type({
    required MethodInvocationImpl node,
    required SimpleIdentifierImpl typeIdentifier,
  }) {
    var typeName = NamedTypeImpl(
      importPrefix: null,
      name2: typeIdentifier.token,
      typeArguments: node.typeArguments,
      question: null,
    );
    var constructorName = ConstructorNameImpl(
      type: typeName,
      period: null,
      name: null,
    );
    var instanceCreationExpression = InstanceCreationExpressionImpl(
      keyword: null,
      constructorName: constructorName,
      argumentList: node.argumentList,
      typeArguments: null,
    );
    NodeReplacer.replace(node, instanceCreationExpression);
    return instanceCreationExpression;
  }

  AstNode _toInstanceCreation_type_constructor({
    required MethodInvocationImpl node,
    required SimpleIdentifierImpl typeIdentifier,
    required SimpleIdentifierImpl constructorIdentifier,
    required InterfaceElement classElement,
  }) {
    var name = constructorIdentifier.name;
    var augmented = classElement.augmented;
    var constructorElement = augmented.getNamedConstructor(name);
    if (constructorElement == null) {
      return node;
    }

    var typeArguments = node.typeArguments;
    if (typeArguments != null) {
      _errorReporter.atNode(
        typeArguments,
        CompileTimeErrorCode.WRONG_NUMBER_OF_TYPE_ARGUMENTS_CONSTRUCTOR,
        arguments: [typeIdentifier.name, constructorIdentifier.name],
      );
    }
    var typeName = NamedTypeImpl(
      importPrefix: null,
      name2: typeIdentifier.token,
      typeArguments: null,
      question: null,
    );
    var constructorName = ConstructorNameImpl(
      type: typeName,
      period: node.operator,
      name: constructorIdentifier,
    );
    // TODO(scheglov): I think we should drop "typeArguments" below.
    var instanceCreationExpression = InstanceCreationExpressionImpl(
      keyword: null,
      constructorName: constructorName,
      argumentList: node.argumentList,
      typeArguments: typeArguments,
    );
    NodeReplacer.replace(node, instanceCreationExpression);
    return instanceCreationExpression;
  }

  MethodInvocation _toMethodInvocationOfAliasedTypeLiteral({
    required InstanceCreationExpressionImpl node,
    required Identifier function,
    required TypeAliasElement element,
  }) {
    var typeName = NamedTypeImpl(
      importPrefix: node.constructorName.type.importPrefix,
      name2: node.constructorName.type.name2,
      typeArguments: node.constructorName.type.typeArguments,
      question: null,
    );
    typeName.type = element.aliasedType;
    var typeLiteral = TypeLiteralImpl(
      typeName: typeName,
    );
    var methodInvocation = MethodInvocationImpl(
      target: typeLiteral,
      operator: node.constructorName.period,
      methodName: node.constructorName.name!,
      typeArguments: null,
      argumentList: node.argumentList,
    );
    NodeReplacer.replace(node, methodInvocation);
    return methodInvocation;
  }

  AstNode _toMethodInvocationOfFunctionReference({
    required InstanceCreationExpressionImpl node,
    required IdentifierImpl function,
  }) {
    var period = node.constructorName.period;
    var constructorId = node.constructorName.name;
    if (period == null || constructorId == null) {
      return node;
    }

    var functionReference = FunctionReferenceImpl(
      function: function,
      typeArguments: node.constructorName.type.typeArguments,
    );
    var methodInvocation = MethodInvocationImpl(
      target: functionReference,
      operator: period,
      methodName: constructorId,
      typeArguments: null,
      argumentList: node.argumentList,
    );
    NodeReplacer.replace(node, methodInvocation);
    return methodInvocation;
  }

  TypeLiteralImpl _toPatternTypeLiteral(
    ConstantPattern parent,
    IdentifierImpl node,
  ) {
    var result = TypeLiteralImpl(
      typeName: node.toNamedType(
        typeArguments: null,
        question: null,
      ),
    );
    NodeReplacer.replace(node, result, parent: parent);
    return result;
  }
}
