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

import 'package:kernel/ast.dart';
import 'package:kernel/type_environment.dart'
    show StaticTypeContext, SubtypeCheckMode, TypeEnvironment;

// Removes redundant type casts and reduces casts to null checks.
//
// Handles the following patterns:
// If S <: T (this includes S <: T? in weak mode)
//
//    S x; x as T => x
//
// If S <: T? in strong mode
//
//    S x; x as T => (x == null) ? x as T : x
//
TreeNode transformAsExpression(
    AsExpression node, StaticTypeContext staticTypeContext, bool nullSafety) {
  final DartType operandType = node.operand.getStaticType(staticTypeContext);
  final env = staticTypeContext.typeEnvironment;

  if (isRedundantTypeCast(node, operandType, env, nullSafety)) {
    return node.operand;
  }

  if (canBeReducedToNullCheckAndCast(node, operandType, env, nullSafety)) {
    // Transform 'x as T' to 'Let tmp = x in (tmp == null) ? tmp as T : tmp'.
    final tmp =
        VariableDeclaration(null, initializer: node.operand, type: operandType);
    final dstType = node.type;
    return Let(
        tmp,
        ConditionalExpression(
            MethodInvocation(
                VariableGet(tmp), Name('=='), Arguments([NullLiteral()])),
            AsExpression(VariableGet(tmp), dstType)
              ..flags = node.flags
              ..fileOffset = node.fileOffset,
            VariableGet(tmp, dstType),
            dstType));
  }

  return node;
}

// Returns true if type cast [node] which has operand of the given
// [operandStaticType] is redundant and can be removed (replaced with its
// operand).
bool isRedundantTypeCast(AsExpression node, DartType operandStaticType,
    TypeEnvironment env, bool nullSafety) {
  if (!_canBeTransformed(node)) {
    return false;
  }

  return env.isSubtypeOf(
      operandStaticType,
      node.type,
      nullSafety
          ? SubtypeCheckMode.withNullabilities
          : SubtypeCheckMode.ignoringNullabilities);
}

// Returns true if type cast [node] which has operand of the given
// [operandStaticType] can be reduced to the null-check-and-cast pattern
// 'Let tmp = [node.operand] in (tmp == null) ? tmp as T : tmp'.
bool canBeReducedToNullCheckAndCast(AsExpression node,
    DartType operandStaticType, TypeEnvironment env, bool nullSafety) {
  if (!_canBeTransformed(node)) {
    return false;
  }

  final DartType dst = node.type;

  if (nullSafety && dst.nullability != Nullability.nullable) {
    final nullableDst = dst.withDeclaredNullability(Nullability.nullable);
    return env.isSubtypeOf(
        operandStaticType, nullableDst, SubtypeCheckMode.withNullabilities);
  }

  return false;
}

bool _canBeTransformed(AsExpression node) {
  if (node.isCovarianceCheck) {
    // Keep casts inserted by the front-end to ensure soundness of
    // covariant types.
    return false;
  }

  final DartType dst = node.type;
  if (dst is DynamicType || dst is InvalidType) {
    // Keep casts to dynamic as they have zero overhead but change
    // the semantics of calls. Also keep invalid types.
    return false;
  }

  return true;
}
