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

// @dart = 2.9

import 'package:kernel/ast.dart';
import 'package:kernel/visitor.dart';

import '../type_inference/type_schema.dart';

import 'internal_ast.dart';

/// Check if [type] contains [InvalidType] as its part.
///
/// The helper function is intended for stopping cascading errors because of
/// occurrences of [InvalidType].  In most cases it's safe to assume that if an
/// [InvalidType] was produced, an error was reported as the part of its
/// creation, so other errors raising, for example, from inability to assign to
/// a variable of an [InvalidType], could be omitted.
bool containsInvalidType(DartType type) {
  return type.accept1(const _InvalidTypeFinder(), <TypedefType>{});
}

class _InvalidTypeFinder implements DartTypeVisitor1<bool, Set<TypedefType>> {
  const _InvalidTypeFinder();

  @override
  bool defaultDartType(DartType node, Set<TypedefType> visitedTypedefs) {
    if (node is UnknownType) {
      return false;
    } else if (node is ExtensionType) {
      for (DartType typeArgument in node.typeArguments) {
        if (typeArgument.accept1(this, visitedTypedefs)) return true;
      }
      return false;
    } else {
      throw new StateError("Unhandled type ${node.runtimeType}.");
    }
  }

  @override
  bool visitDynamicType(DynamicType node, Set<TypedefType> visitedTypedefs) =>
      false;

  @override
  bool visitVoidType(VoidType node, Set<TypedefType> visitedTypedefs) => false;

  @override
  bool visitInvalidType(InvalidType node, Set<TypedefType> visitedTypedefs) =>
      true;

  @override
  bool visitInterfaceType(
      InterfaceType node, Set<TypedefType> visitedTypedefs) {
    for (DartType typeArgument in node.typeArguments) {
      if (typeArgument.accept1(this, visitedTypedefs)) return true;
    }
    return false;
  }

  @override
  bool visitFutureOrType(FutureOrType node, Set<TypedefType> visitedTypedefs) {
    return node.typeArgument.accept1(this, visitedTypedefs);
  }

  @override
  bool visitNeverType(NeverType node, Set<TypedefType> visitedTypedefs) =>
      false;

  @override
  bool visitNullType(NullType node, Set<TypedefType> visitedTypedefs) => false;

  @override
  bool visitFunctionType(FunctionType node, Set<TypedefType> visitedTypedefs) {
    if (node.returnType.accept1(this, visitedTypedefs)) return true;
    for (TypeParameter typeParameter in node.typeParameters) {
      if (typeParameter.bound.accept1(this, visitedTypedefs)) return true;
      // TODO(dmitryas): Check defaultTypes as well if they cause cascading
      // errors.
    }
    for (DartType parameter in node.positionalParameters) {
      if (parameter.accept1(this, visitedTypedefs)) return true;
    }
    for (NamedType parameter in node.namedParameters) {
      if (parameter.type.accept1(this, visitedTypedefs)) return true;
    }
    if (node.typedefType != null && visitedTypedefs.add(node.typedefType)) {
      if (node.typedefType.accept1(this, visitedTypedefs)) return true;
    }
    return false;
  }

  @override
  bool visitTypedefType(TypedefType node, Set<TypedefType> visitedTypedefs) {
    // The unaliased type should be checked, but it's faster to check the type
    // arguments and the RHS separately than do the unaliasing because it avoids
    // type substitution.
    for (DartType typeArgument in node.typeArguments) {
      if (typeArgument.accept1(this, visitedTypedefs)) return true;
    }
    if (node.typedefNode.type.accept1(this, visitedTypedefs)) return true;
    return false;
  }

  @override
  bool visitTypeParameterType(
      TypeParameterType node, Set<TypedefType> visitedTypedefs) {
    // node.parameter.bound is not checked because such a bound doesn't
    // automatically means that the potential errors related to the occurrences
    // of the type-parameter type itself are reported.
    if (node.promotedBound != null &&
        node.promotedBound.accept1(this, visitedTypedefs)) {
      return true;
    }
    return false;
  }
}
