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

import '../ast.dart';
import '../type_algebra.dart';

/// Returns the type defined as `NonNull(type)` in the nnbd specification.
DartType computeNonNull(DartType type) {
  return type.accept(const _NonNullVisitor()) ?? type;
}

/// Visitor that computes the `NonNull` function defined in the nnbd
/// specification.
///
/// The visitor returns `null` if `NonNull(T) = T`.
class _NonNullVisitor implements DartTypeVisitor<DartType?> {
  const _NonNullVisitor();

  @override
  DartType? defaultDartType(DartType node) {
    throw new UnsupportedError(
        "Unexpected DartType ${node} (${node.runtimeType})");
  }

  @override
  DartType? visitDynamicType(DynamicType node) {
    // NonNull(dynamic) = dynamic
    return null;
  }

  @override
  DartType? visitFunctionType(FunctionType node) {
    // NonNull(T0 Function(...)) = T0 Function(...)
    //
    // NonNull(T?) = NonNull(T)
    //
    // NonNull(T*) = NonNull(T)
    if (node.declaredNullability == Nullability.nonNullable) {
      return null;
    }
    return node.withDeclaredNullability(Nullability.nonNullable);
  }

  @override
  DartType? visitRecordType(RecordType node) {
    // By analogy with FunctionType.
    if (node.declaredNullability == Nullability.nonNullable) {
      return null;
    }
    return node.withDeclaredNullability(Nullability.nonNullable);
  }

  @override
  DartType? visitFutureOrType(FutureOrType node) {
    // NonNull(FutureOr<T>) = FutureOr<T>
    //
    // NonNull(T?) = NonNull(T)
    //
    // NonNull(T*) = NonNull(T)

    // Note that we should _not_ compute NonNull of the type argument. Consider
    //
    //     NonNull(FutureOr<int?>?)
    //
    // We have that
    //
    //     FutureOr<int?>? = Future<int?>? | int?
    //
    // and therefore that
    //
    //     NonNull(FutureOr<int?>?) = NonNull(FutureOr<int?>?) | NonNull(int?)
    //                              = FutureOr<int?> | int
    //
    // but that means that while `null` is not a possible value from `int` it
    // is still a possible value from awaiting the future. Taking NonNull on
    // the type argument as well as on the `FutureOr`:
    //
    //     NonNull(FutureOr<int?>?) = NonNull(FutureOr<NonNull(int?)>?)
    //                              = FutureOr<int>
    //
    // would be wrong since it would compute that the awaited result could not
    // be `null`.

    if (node.declaredNullability == Nullability.nonNullable) {
      return null;
    }
    return new FutureOrType(node.typeArgument, Nullability.nonNullable);
  }

  @override
  DartType? visitInterfaceType(InterfaceType node) {
    // NonNull(C<T1, ... , Tn>) = C<T1, ... , Tn> for class C other
    // than Null (including Object).
    //
    // NonNull(Function) = Function
    //
    // NonNull(T?) = NonNull(T)
    //
    // NonNull(T*) = NonNull(T)
    if (node.declaredNullability == Nullability.nonNullable) {
      return null;
    }
    return node.withDeclaredNullability(Nullability.nonNullable);
  }

  @override
  DartType? visitExtensionType(ExtensionType node) {
    // NonNull(C<T1, ... , Tn>) = C<T1, ... , Tn> for class C other
    // than Null (including Object).
    //
    // NonNull(T?) = NonNull(T)
    //
    // NonNull(T*) = NonNull(T)
    if (node.declaredNullability == Nullability.nonNullable) {
      return null;
    }
    return node.withDeclaredNullability(Nullability.nonNullable);
  }

  @override
  DartType? visitInlineType(InlineType node) {
    // NonNull(T?) = NonNull(T)
    //
    // NonNull(T*) = NonNull(T)
    if (node.declaredNullability == Nullability.nonNullable) {
      return null;
    }
    return node.withDeclaredNullability(Nullability.nonNullable);
  }

  @override
  DartType? visitInvalidType(InvalidType node) => null;

  @override
  DartType? visitNeverType(NeverType node) {
    // NonNull(Never) = Never
    //
    // NonNull(T?) = NonNull(T)
    //
    // NonNull(T*) = NonNull(T)
    if (node.declaredNullability == Nullability.nonNullable) {
      return null;
    }
    return const NeverType.nonNullable();
  }

  @override
  DartType? visitNullType(NullType node) {
    // NonNull(Null) = Never
    return const NeverType.nonNullable();
  }

  @override
  DartType? visitTypeParameterType(TypeParameterType node) {
    // NonNull(X) = X & NonNull(B), where B is the bound of X.
    //
    // NonNull(T?) = NonNull(T)
    //
    // NonNull(T*) = NonNull(T)
    if (node.nullability == Nullability.nonNullable) {
      return null;
    }
    // NonNull(X) = X & NonNull(B), where B is the bound of X.
    if (node.bound.nullability == Nullability.nonNullable) {
      // The bound is already non-nullable so we set the declared nullability
      // to non-nullable.
      return node.withDeclaredNullability(Nullability.nonNullable);
    }
    DartType? bound = node.bound.accept(this);
    if (bound == null) {
      // The bound could not be made non-nullable so we set the declared
      // nullability to undetermined.
      if (node.declaredNullability == Nullability.undetermined) {
        return null;
      }
      return node.withDeclaredNullability(Nullability.undetermined);
    } else {
      // The nullability is fully determined by the bound so we pass the
      // default nullability for the declared nullability.
      return new IntersectionType(
          new TypeParameterType(node.parameter,
              TypeParameterType.computeNullabilityFromBound(node.parameter)),
          bound);
    }
  }

  @override
  DartType? visitIntersectionType(IntersectionType node) {
    // NonNull(X & T) = X & NonNull(T)
    if (node.nullability == Nullability.nonNullable) {
      return null;
    }

    if (node.right.nullability == Nullability.nonNullable) {
      // The RHS is already non-nullable so nothing should be changed.
      return node.withDeclaredNullability(Nullability.nonNullable);
    }
    DartType? right = node.right.accept(this);
    if (right == null) {
      // The RHS could not be made non-nullable so we set the
      // declared nullability to undetermined.
      if (node.left.declaredNullability == Nullability.undetermined) {
        return null;
      }
      return new IntersectionType(
          new TypeParameterType(node.left.parameter, Nullability.undetermined),
          node.right);
    } else if (right.nullability == Nullability.nonNullable) {
      // The bound could be made non-nullable so we use it as the promoted
      // bound.
      return new IntersectionType(
          computeTypeWithoutNullabilityMarker(node.left,
              isNonNullableByDefault: true) as TypeParameterType,
          right);
    } else {
      // The bound could not be made non-nullable so we use it as the promoted
      // bound with undetermined nullability.
      return new IntersectionType(
          new TypeParameterType(node.left.parameter, Nullability.undetermined),
          right);
    }
  }

  @override
  DartType? visitTypedefType(TypedefType node) {
    // NonNull(C<T1, ... , Tn>) = C<T1, ... , Tn> for class C other
    // than Null (including Object).
    //
    // NonNull(T?) = NonNull(T)
    //
    // NonNull(T*) = NonNull(T)
    if (node.declaredNullability == Nullability.nonNullable) {
      return null;
    }
    return node.withDeclaredNullability(Nullability.nonNullable);
  }

  @override
  DartType? visitVoidType(VoidType node) {
    // NonNull(void) = void
    return null;
  }
}
