// 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.

// @dart = 2.9

library fasta.transform_set_literals;

import 'package:kernel/ast.dart';

import 'package:kernel/core_types.dart' show CoreTypes;

import 'package:kernel/src/legacy_erasure.dart' show legacyErasure;

import 'package:kernel/type_algebra.dart' show Substitution;

import '../source/source_loader.dart' show SourceLoader;

import 'redirecting_factory_body.dart' show RedirectingFactoryBody;

// TODO(askesc): Delete this class when all backends support set literals.
class SetLiteralTransformer extends Transformer {
  final CoreTypes coreTypes;
  final Procedure setFactory;
  final Procedure addMethod;
  FunctionType _addMethodFunctionType;
  final bool useNewMethodInvocationEncoding;

  /// Library that contains the transformed nodes.
  ///
  /// The transformation of the nodes is affected by the NNBD opt-in status of
  /// the library.
  Library _currentLibrary;

  static Procedure _findSetFactory(CoreTypes coreTypes) {
    Procedure factory = coreTypes.index.getMember('dart:core', 'Set', '');
    RedirectingFactoryBody body = factory?.function?.body;
    return body?.target;
  }

  static Procedure _findAddMethod(CoreTypes coreTypes) {
    return coreTypes.index.getMember('dart:core', 'Set', 'add');
  }

  SetLiteralTransformer(SourceLoader loader)
      : coreTypes = loader.coreTypes,
        setFactory = _findSetFactory(loader.coreTypes),
        addMethod = _findAddMethod(loader.coreTypes),
        useNewMethodInvocationEncoding =
            loader.target.backendTarget.supportsNewMethodInvocationEncoding {
    _addMethodFunctionType = addMethod.getterType;
  }

  TreeNode visitSetLiteral(SetLiteral node) {
    if (node.isConst) return node;

    // Create the set: Set<E> setVar = new Set<E>();
    DartType receiverType;
    VariableDeclaration setVar = new VariableDeclaration.forValue(
        new StaticInvocation(
            setFactory, new Arguments([], types: [node.typeArgument])),
        type: receiverType = new InterfaceType(coreTypes.setClass,
            _currentLibrary.nonNullable, [node.typeArgument]));

    // Now create a list of all statements needed.
    List<Statement> statements = [setVar];
    for (int i = 0; i < node.expressions.length; i++) {
      Expression entry = node.expressions[i].accept<TreeNode>(this);
      Expression methodInvocation;
      if (useNewMethodInvocationEncoding) {
        FunctionType functionType = Substitution.fromInterfaceType(receiverType)
            .substituteType(_addMethodFunctionType);
        if (!_currentLibrary.isNonNullableByDefault) {
          functionType = legacyErasure(functionType);
        }
        methodInvocation = new InstanceInvocation(InstanceAccessKind.Instance,
            new VariableGet(setVar), new Name("add"), new Arguments([entry]),
            functionType: functionType, interfaceTarget: addMethod)
          ..fileOffset = entry.fileOffset
          ..isInvariant = true;
      } else {
        methodInvocation = new MethodInvocation(new VariableGet(setVar),
            new Name("add"), new Arguments([entry]), addMethod)
          ..fileOffset = entry.fileOffset
          ..isInvariant = true;
      }
      statements.add(new ExpressionStatement(methodInvocation)
        ..fileOffset = methodInvocation.fileOffset);
    }

    // Finally, return a BlockExpression with the statements, having the value
    // of the (now created) set.
    return new BlockExpression(new Block(statements), new VariableGet(setVar))
      ..fileOffset = node.fileOffset;
  }

  void enterLibrary(Library library) {
    assert(
        _currentLibrary == null,
        "Attempting to enter library '${library.fileUri}' "
        "without having exited library '${_currentLibrary.fileUri}'.");
    _currentLibrary = library;
  }

  void exitLibrary() {
    assert(_currentLibrary != null,
        "Attempting to exit a library without having entered one.");
    _currentLibrary = null;
  }
}
