// Copyright (c) 2017, 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.md file.

import 'package:kernel/ast.dart'
    show
        DartType,
        DartTypeVisitor,
        DynamicType,
        FunctionType,
        InterfaceType,
        NamedType;

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

import 'type_schema.dart' show UnknownType;

/// Returns the greatest closure of the given type [schema] with respect to `?`.
///
/// The greatest closure of a type schema `P` with respect to `?` is defined as
/// `P` with every covariant occurrence of `?` replaced with `Null`, and every
/// contravariant occurrence of `?` replaced with `Object`.
///
/// If the schema contains no instances of `?`, the original schema object is
/// returned to avoid unnecessary allocation.
///
/// Note that the closure of a type schema is a proper type.
///
/// Note that the greatest closure of a type schema is always a supertype of any
/// type which matches the schema.
DartType greatestClosure(CoreTypes coreTypes, DartType schema) =>
    _TypeSchemaEliminationVisitor.run(coreTypes, false, schema);

/// Returns the least closure of the given type [schema] with respect to `?`.
///
/// The least closure of a type schema `P` with respect to `?` is defined as
/// `P` with every covariant occurrence of `?` replaced with `Object`, and every
/// contravariant occurrence of `?` replaced with `Null`.
///
/// If the schema contains no instances of `?`, the original schema object is
/// returned to avoid unnecessary allocation.
///
/// Note that the closure of a type schema is a proper type.
///
/// Note that the least closure of a type schema is always a subtype of any type
/// which matches the schema.
DartType leastClosure(CoreTypes coreTypes, DartType schema) =>
    _TypeSchemaEliminationVisitor.run(coreTypes, true, schema);

/// Visitor that computes least and greatest closures of a type schema.
///
/// Each visitor method returns `null` if there are no `?`s contained in the
/// type, otherwise it returns the result of substituting `?` with `Null` or
/// `Object`, as appropriate.
class _TypeSchemaEliminationVisitor extends DartTypeVisitor<DartType> {
  final DartType nullType;

  bool isLeastClosure;

  _TypeSchemaEliminationVisitor(CoreTypes coreTypes, this.isLeastClosure)
      : nullType = coreTypes.nullType;

  @override
  DartType visitFunctionType(FunctionType node) {
    DartType newReturnType = node.returnType.accept(this);
    isLeastClosure = !isLeastClosure;
    List<DartType> newPositionalParameters = null;
    for (int i = 0; i < node.positionalParameters.length; i++) {
      DartType substitution = node.positionalParameters[i].accept(this);
      if (substitution != null) {
        newPositionalParameters ??=
            node.positionalParameters.toList(growable: false);
        newPositionalParameters[i] = substitution;
      }
    }
    List<NamedType> newNamedParameters = null;
    for (int i = 0; i < node.namedParameters.length; i++) {
      DartType substitution = node.namedParameters[i].type.accept(this);
      if (substitution != null) {
        newNamedParameters ??= node.namedParameters.toList(growable: false);
        newNamedParameters[i] = new NamedType(
            node.namedParameters[i].name, substitution,
            isRequired: node.namedParameters[i].isRequired);
      }
    }
    isLeastClosure = !isLeastClosure;
    DartType typedefType = node.typedefType?.accept(this);
    if (newReturnType == null &&
        newPositionalParameters == null &&
        newNamedParameters == null &&
        typedefType == null) {
      // No types had to be substituted.
      return null;
    } else {
      return new FunctionType(
          newPositionalParameters ?? node.positionalParameters,
          newReturnType ?? node.returnType,
          namedParameters: newNamedParameters ?? node.namedParameters,
          typeParameters: node.typeParameters,
          requiredParameterCount: node.requiredParameterCount,
          typedefType: typedefType);
    }
  }

  @override
  DartType visitInterfaceType(InterfaceType node) {
    List<DartType> newTypeArguments = null;
    for (int i = 0; i < node.typeArguments.length; i++) {
      DartType substitution = node.typeArguments[i].accept(this);
      if (substitution != null) {
        newTypeArguments ??= node.typeArguments.toList(growable: false);
        newTypeArguments[i] = substitution;
      }
    }
    if (newTypeArguments == null) {
      // No type arguments needed to be substituted.
      return null;
    } else {
      return new InterfaceType(node.classNode, newTypeArguments);
    }
  }

  @override
  DartType defaultDartType(DartType node) {
    if (node is UnknownType) {
      return isLeastClosure ? nullType : const DynamicType();
    }
    return null;
  }

  /// Runs an instance of the visitor on the given [schema] and returns the
  /// resulting type.  If the schema contains no instances of `?`, the original
  /// schema object is returned to avoid unnecessary allocation.
  static DartType run(
      CoreTypes coreTypes, bool isLeastClosure, DartType schema) {
    _TypeSchemaEliminationVisitor visitor =
        new _TypeSchemaEliminationVisitor(coreTypes, isLeastClosure);
    DartType result = schema.accept(visitor);
    assert(visitor.isLeastClosure == isLeastClosure);
    return result ?? schema;
  }
}
