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

library fasta.types;

import 'package:kernel/ast.dart'
    show
        BottomType,
        Class,
        DartType,
        DynamicType,
        FunctionType,
        InterfaceType,
        InvalidType,
        NamedType,
        Nullability,
        TypeParameter,
        TypeParameterType,
        TypedefType,
        VoidType;

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

import 'kernel_builder.dart' show ClassHierarchyBuilder;

class Types {
  final ClassHierarchyBuilder hierarchy;

  Types(this.hierarchy);

  /// Returns true if [s] is a subtype of [t].
  bool isSubtypeOfKernel(DartType s, DartType t) {
    if (s is InvalidType) {
      // InvalidType is a bottom type.
      return true;
    }
    if (t is InvalidType) {
      return false;
    }
    return isSubtypeOfKernelNullability(s, s.nullability, t, t.nullability);
  }

  bool isSubtypeOfKernelNullability(
      DartType s, Nullability sNullability, DartType t, tNullability) {
    if (s is BottomType) {
      return true; // Rule 3.
    }
    if (t is DynamicType) {
      return true; // Rule 2.
    }
    if (t is VoidType) {
      return true; // Rule 2.
    }
    if (t is BottomType) {
      return false;
    }
    if (t is InterfaceType) {
      Class cls = t.classNode;
      if (cls == hierarchy.objectClass) {
        return true; // Rule 2.
      }
      if (cls == hierarchy.futureOrClass) {
        const IsFutureOrSubtypeOf relation = const IsFutureOrSubtypeOf();
        if (s is DynamicType) {
          return relation.isDynamicRelated(
              s, sNullability, t, tNullability, this);
        } else if (s is VoidType) {
          return relation.isVoidRelated(s, sNullability, t, tNullability, this);
        } else if (s is InterfaceType) {
          return s.classNode == hierarchy.futureOrClass
              ? relation.isFutureOrRelated(
                  s, sNullability, t, tNullability, this)
              : relation.isInterfaceRelated(
                  s, sNullability, t, tNullability, this);
        } else if (s is FunctionType) {
          return relation.isFunctionRelated(
              s, sNullability, t, tNullability, this);
        } else if (s is TypeParameterType) {
          return s.promotedBound == null
              ? relation.isTypeParameterRelated(
                  s, sNullability, t, tNullability, this)
              : relation.isIntersectionRelated(
                  s, sNullability, t, tNullability, this);
        } else if (s is TypedefType) {
          return relation.isTypedefRelated(
              s, sNullability, t, tNullability, this);
        }
      } else {
        const IsInterfaceSubtypeOf relation = const IsInterfaceSubtypeOf();
        if (s is DynamicType) {
          return relation.isDynamicRelated(
              s, sNullability, t, tNullability, this);
        } else if (s is VoidType) {
          return relation.isVoidRelated(s, sNullability, t, tNullability, this);
        } else if (s is InterfaceType) {
          return s.classNode == hierarchy.futureOrClass
              ? relation.isFutureOrRelated(
                  s, sNullability, t, tNullability, this)
              : relation.isInterfaceRelated(
                  s, sNullability, t, tNullability, this);
        } else if (s is FunctionType) {
          return relation.isFunctionRelated(
              s, sNullability, t, tNullability, this);
        } else if (s is TypeParameterType) {
          return s.promotedBound == null
              ? relation.isTypeParameterRelated(
                  s, sNullability, t, tNullability, this)
              : relation.isIntersectionRelated(
                  s, sNullability, t, tNullability, this);
        } else if (s is TypedefType) {
          return relation.isTypedefRelated(
              s, sNullability, t, tNullability, this);
        }
      }
    } else if (t is FunctionType) {
      const IsFunctionSubtypeOf relation = const IsFunctionSubtypeOf();
      if (s is DynamicType) {
        return relation.isDynamicRelated(
            s, sNullability, t, tNullability, this);
      } else if (s is VoidType) {
        return relation.isVoidRelated(s, sNullability, t, tNullability, this);
      } else if (s is InterfaceType) {
        return s.classNode == hierarchy.futureOrClass
            ? relation.isFutureOrRelated(s, sNullability, t, tNullability, this)
            : relation.isInterfaceRelated(
                s, sNullability, t, tNullability, this);
      } else if (s is FunctionType) {
        return relation.isFunctionRelated(
            s, sNullability, t, tNullability, this);
      } else if (s is TypeParameterType) {
        return s.promotedBound == null
            ? relation.isTypeParameterRelated(
                s, sNullability, t, tNullability, this)
            : relation.isIntersectionRelated(
                s, sNullability, t, tNullability, this);
      } else if (s is TypedefType) {
        return relation.isTypedefRelated(
            s, sNullability, t, tNullability, this);
      }
    } else if (t is TypeParameterType) {
      if (t.promotedBound == null) {
        const IsTypeParameterSubtypeOf relation =
            const IsTypeParameterSubtypeOf();
        if (s is DynamicType) {
          return relation.isDynamicRelated(
              s, sNullability, t, tNullability, this);
        } else if (s is VoidType) {
          return relation.isVoidRelated(s, sNullability, t, tNullability, this);
        } else if (s is InterfaceType) {
          return s.classNode == hierarchy.futureOrClass
              ? relation.isFutureOrRelated(
                  s, sNullability, t, tNullability, this)
              : relation.isInterfaceRelated(
                  s, sNullability, t, tNullability, this);
        } else if (s is FunctionType) {
          return relation.isFunctionRelated(
              s, sNullability, t, tNullability, this);
        } else if (s is TypeParameterType) {
          return s.promotedBound == null
              ? relation.isTypeParameterRelated(
                  s, sNullability, t, tNullability, this)
              : relation.isIntersectionRelated(
                  s, sNullability, t, tNullability, this);
        } else if (s is TypedefType) {
          return relation.isTypedefRelated(
              s, sNullability, t, tNullability, this);
        }
      } else {
        const IsIntersectionSubtypeOf relation =
            const IsIntersectionSubtypeOf();
        if (s is DynamicType) {
          return relation.isDynamicRelated(
              s, sNullability, t, tNullability, this);
        } else if (s is VoidType) {
          return relation.isVoidRelated(s, sNullability, t, tNullability, this);
        } else if (s is InterfaceType) {
          return s.classNode == hierarchy.futureOrClass
              ? relation.isFutureOrRelated(
                  s, sNullability, t, tNullability, this)
              : relation.isInterfaceRelated(
                  s, sNullability, t, tNullability, this);
        } else if (s is FunctionType) {
          return relation.isFunctionRelated(
              s, sNullability, t, tNullability, this);
        } else if (s is TypeParameterType) {
          return s.promotedBound == null
              ? relation.isTypeParameterRelated(
                  s, sNullability, t, tNullability, this)
              : relation.isIntersectionRelated(
                  s, sNullability, t, tNullability, this);
        } else if (s is TypedefType) {
          return relation.isTypedefRelated(
              s, sNullability, t, tNullability, this);
        }
      }
    } else if (t is TypedefType) {
      const IsTypedefSubtypeOf relation = const IsTypedefSubtypeOf();
      if (s is DynamicType) {
        return relation.isDynamicRelated(
            s, sNullability, t, tNullability, this);
      } else if (s is VoidType) {
        return relation.isVoidRelated(s, sNullability, t, tNullability, this);
      } else if (s is InterfaceType) {
        return s.classNode == hierarchy.futureOrClass
            ? relation.isFutureOrRelated(s, sNullability, t, tNullability, this)
            : relation.isInterfaceRelated(
                s, sNullability, t, tNullability, this);
      } else if (s is FunctionType) {
        return relation.isFunctionRelated(
            s, sNullability, t, tNullability, this);
      } else if (s is TypeParameterType) {
        return s.promotedBound == null
            ? relation.isTypeParameterRelated(
                s, sNullability, t, tNullability, this)
            : relation.isIntersectionRelated(
                s, sNullability, t, tNullability, this);
      } else if (s is TypedefType) {
        return relation.isTypedefRelated(
            s, sNullability, t, tNullability, this);
      }
    } else {
      throw "Unhandled type: ${t.runtimeType}";
    }
    throw "Unhandled type combination: ${t.runtimeType} ${s.runtimeType}";
  }

  /// Returns true if all types in [s] and [t] pairwise are subtypes.
  bool areSubtypesOfKernel(List<DartType> s, List<DartType> t) {
    if (s.length != t.length) {
      throw "Numbers of type arguments don't match $s $t.";
    }
    for (int i = 0; i < s.length; i++) {
      if (!isSubtypeOfKernel(s[i], t[i])) return false;
    }
    return true;
  }

  bool isSameTypeKernel(DartType s, DartType t) {
    return isSubtypeOfKernel(s, t) && isSubtypeOfKernel(t, s);
  }
}

abstract class TypeRelation<T extends DartType> {
  const TypeRelation();

  bool isDynamicRelated(DynamicType s, Nullability sNullability, T t,
      Nullability tNullability, Types types);

  bool isVoidRelated(VoidType s, Nullability sNullability, T t,
      Nullability tNullability, Types types);

  bool isInterfaceRelated(InterfaceType s, Nullability sNullability, T t,
      Nullability tNullability, Types types);

  bool isIntersectionRelated(
      TypeParameterType intersection,
      Nullability intersectionNullability,
      T t,
      Nullability tNullability,
      Types types);

  bool isFunctionRelated(FunctionType s, Nullability sNullability, T t,
      Nullability tNullability, Types types);

  bool isFutureOrRelated(
      InterfaceType futureOr,
      Nullability futureOrNullability,
      T t,
      Nullability tNullability,
      Types types);

  bool isTypeParameterRelated(TypeParameterType s, Nullability sNullability,
      T t, Nullability tNullability, Types types);

  bool isTypedefRelated(TypedefType s, Nullability sNullability, T t,
      Nullability tNullability, Types types);
}

class IsInterfaceSubtypeOf extends TypeRelation<InterfaceType> {
  const IsInterfaceSubtypeOf();

  @override
  bool isInterfaceRelated(InterfaceType s, Nullability sNullability,
      InterfaceType t, Nullability tNullability, Types types) {
    if (s.classNode == types.hierarchy.nullClass) {
      // This is an optimization, to avoid instantiating unnecessary type
      // arguments in getKernelTypeAsInstanceOf.
      return true;
    }
    InterfaceType asSupertype =
        types.hierarchy.getKernelTypeAsInstanceOf(s, t.classNode);
    if (asSupertype == null) {
      return false;
    } else {
      return types.areSubtypesOfKernel(
          asSupertype.typeArguments, t.typeArguments);
    }
  }

  @override
  bool isTypeParameterRelated(TypeParameterType s, Nullability sNullability,
      InterfaceType t, Nullability tNullability, Types types) {
    return types.isSubtypeOfKernel(s.parameter.bound, t);
  }

  @override
  bool isFutureOrRelated(
      InterfaceType futureOr,
      Nullability futureOrNullability,
      InterfaceType t,
      Nullability tNullability,
      Types types) {
    List<DartType> arguments = futureOr.typeArguments;
    if (!types.isSubtypeOfKernel(arguments.single, t)) {
      return false; // Rule 7.1
    }
    if (!types.isSubtypeOfKernel(
        new InterfaceType(types.hierarchy.futureClass, arguments), t)) {
      return false; // Rule 7.2
    }
    return true;
  }

  @override
  bool isIntersectionRelated(
      TypeParameterType intersection,
      Nullability intersectionNullability,
      InterfaceType t,
      Nullability tNullability,
      Types types) {
    return types.isSubtypeOfKernel(intersection.promotedBound, t); // Rule 12.
  }

  @override
  bool isDynamicRelated(DynamicType s, Nullability sNullability,
      InterfaceType t, Nullability tNullability, Types types) {
    return false;
  }

  @override
  bool isFunctionRelated(FunctionType s, Nullability sNullability,
      InterfaceType t, Nullability tNullability, Types types) {
    return t.classNode == types.hierarchy.functionClass; // Rule 14.
  }

  @override
  bool isTypedefRelated(TypedefType s, Nullability sNullability,
      InterfaceType t, Nullability tNullability, Types types) {
    // Rule 5.
    return types.isSubtypeOfKernel(s.unalias, t);
  }

  @override
  bool isVoidRelated(VoidType s, Nullability sNullability, InterfaceType t,
      Nullability tNullability, Types types) {
    return false;
  }
}

class IsFunctionSubtypeOf extends TypeRelation<FunctionType> {
  const IsFunctionSubtypeOf();

  @override
  bool isFunctionRelated(FunctionType s, Nullability sNullability,
      FunctionType t, Nullability tNullability, Types types) {
    List<TypeParameter> sTypeVariables = s.typeParameters;
    List<TypeParameter> tTypeVariables = t.typeParameters;
    if (sTypeVariables.length != tTypeVariables.length) return false;
    if (sTypeVariables.isNotEmpty) {
      // If the function types have type variables, we alpha-rename the type
      // variables of [s] to use those of [t].
      List<DartType> typeVariableSubstitution = <DartType>[];
      bool secondBoundsCheckNeeded = false;
      for (int i = 0; i < sTypeVariables.length; i++) {
        TypeParameter sTypeVariable = sTypeVariables[i];
        TypeParameter tTypeVariable = tTypeVariables[i];
        if (!types.isSameTypeKernel(sTypeVariable.bound, tTypeVariable.bound)) {
          // If the bounds aren't the same, we need to try again after
          // computing the substitution of type variables.
          secondBoundsCheckNeeded = true;
        }
        typeVariableSubstitution.add(new TypeParameterType(tTypeVariable));
      }
      Substitution substitution =
          Substitution.fromPairs(sTypeVariables, typeVariableSubstitution);
      if (secondBoundsCheckNeeded) {
        for (int i = 0; i < sTypeVariables.length; i++) {
          TypeParameter sTypeVariable = sTypeVariables[i];
          TypeParameter tTypeVariable = tTypeVariables[i];
          if (!types.isSameTypeKernel(
              substitution.substituteType(sTypeVariable.bound),
              tTypeVariable.bound)) {
            return false;
          }
        }
      }
      s = substitution.substituteType(s.withoutTypeParameters);
    }
    if (!types.isSubtypeOfKernel(s.returnType, t.returnType)) return false;
    List<DartType> sPositional = s.positionalParameters;
    List<DartType> tPositional = t.positionalParameters;
    if (s.requiredParameterCount > t.requiredParameterCount) {
      // Rule 15, n1 <= n2.
      return false;
    }
    if (sPositional.length < tPositional.length) {
      // Rule 15, n1 + k1 >= n2 + k2.
      return false;
    }
    for (int i = 0; i < tPositional.length; i++) {
      if (!types.isSubtypeOfKernel(tPositional[i], sPositional[i])) {
        // Rule 15, Tj <: Sj.
        return false;
      }
    }
    List<NamedType> sNamed = s.namedParameters;
    List<NamedType> tNamed = t.namedParameters;
    if (sNamed.isNotEmpty || tNamed.isNotEmpty) {
      // Rule 16, the number of positional parameters must be the same.
      if (sPositional.length != tPositional.length) return false;
      if (s.requiredParameterCount != t.requiredParameterCount) return false;

      // Rule 16, the parameter names of [t] must be a subset of those of
      // [s]. Also, for the intersection, the type of the parameter of [t] must
      // be a subtype of the type of the parameter of [s].
      int sCount = 0;
      for (int tCount = 0; tCount < tNamed.length; tCount++) {
        String name = tNamed[tCount].name;
        for (; sCount < sNamed.length; sCount++) {
          if (sNamed[sCount].name == name) break;
        }
        if (sCount == sNamed.length) return false;
        if (!types.isSubtypeOfKernel(
            tNamed[tCount].type, sNamed[sCount].type)) {
          return false;
        }
      }
    }
    return true;
  }

  @override
  bool isInterfaceRelated(InterfaceType s, Nullability sNullability,
      FunctionType t, Nullability tNullability, Types types) {
    return s.classNode == types.hierarchy.nullClass; // Rule 4.
  }

  @override
  bool isDynamicRelated(DynamicType s, Nullability sNullability, FunctionType t,
      Nullability tNullability, Types types) {
    return false;
  }

  @override
  bool isFutureOrRelated(
      InterfaceType futureOr,
      Nullability futureOrNullability,
      FunctionType t,
      Nullability tNullability,
      Types types) {
    return false;
  }

  @override
  bool isIntersectionRelated(
      TypeParameterType intersection,
      Nullability intersectionNullability,
      FunctionType t,
      Nullability tNullability,
      Types types) {
    // Rule 12.
    return types.isSubtypeOfKernel(intersection.promotedBound, t);
  }

  @override
  bool isTypeParameterRelated(TypeParameterType s, Nullability sNullability,
      FunctionType t, Nullability tNullability, Types types) {
    // Rule 13.
    return types.isSubtypeOfKernel(s.parameter.bound, t);
  }

  @override
  bool isTypedefRelated(TypedefType s, Nullability sNullability, FunctionType t,
      Nullability tNullability, Types types) {
    // Rule 5.
    return types.isSubtypeOfKernel(s.unalias, t);
  }

  @override
  bool isVoidRelated(VoidType s, Nullability sNullability, FunctionType t,
      Nullability tNullability, Types types) {
    return false;
  }
}

class IsTypeParameterSubtypeOf extends TypeRelation<TypeParameterType> {
  const IsTypeParameterSubtypeOf();

  @override
  bool isTypeParameterRelated(TypeParameterType s, Nullability sNullability,
      TypeParameterType t, Nullability tNullability, Types types) {
    return s.parameter == t.parameter ||
        // Rule 13.
        types.isSubtypeOfKernel(s.bound, t);
  }

  @override
  bool isIntersectionRelated(
      TypeParameterType intersection,
      Nullability intersectionNullability,
      TypeParameterType t,
      Nullability tNullability,
      Types types) {
    return intersection.parameter == t.parameter; // Rule 8.
  }

  @override
  bool isInterfaceRelated(InterfaceType s, Nullability sNullability,
      TypeParameterType t, Nullability tNullability, Types types) {
    return s.classNode == types.hierarchy.nullClass; // Rule 4.
  }

  @override
  bool isDynamicRelated(DynamicType s, Nullability sNullability,
      TypeParameterType t, Nullability tNullability, Types types) {
    return false;
  }

  @override
  bool isFunctionRelated(FunctionType s, Nullability sNullability,
      TypeParameterType t, Nullability tNullability, Types types) {
    return false;
  }

  @override
  bool isFutureOrRelated(
      InterfaceType futureOr,
      Nullability futureOrNullability,
      TypeParameterType t,
      Nullability tNullability,
      Types types) {
    return false;
  }

  @override
  bool isTypedefRelated(TypedefType s, Nullability sNullability,
      TypeParameterType t, Nullability tNullability, Types types) {
    return types.isSubtypeOfKernel(s.unalias, t);
  }

  @override
  bool isVoidRelated(VoidType s, Nullability sNullability, TypeParameterType t,
      Nullability tNullability, Types types) {
    return false;
  }
}

class IsTypedefSubtypeOf extends TypeRelation<TypedefType> {
  const IsTypedefSubtypeOf();

  @override
  bool isInterfaceRelated(InterfaceType s, Nullability sNullability,
      TypedefType t, Nullability tNullability, Types types) {
    return types.isSubtypeOfKernel(s, t.unalias);
  }

  @override
  bool isDynamicRelated(DynamicType s, Nullability sNullability, TypedefType t,
      Nullability tNullability, Types types) {
    return types.isSubtypeOfKernel(s, t.unalias);
  }

  @override
  bool isFunctionRelated(FunctionType s, Nullability sNullability,
      TypedefType t, Nullability tNullability, Types types) {
    return types.isSubtypeOfKernel(s, t.unalias);
  }

  @override
  bool isFutureOrRelated(
      InterfaceType futureOr,
      Nullability futureOrNullability,
      TypedefType t,
      Nullability tNullability,
      Types types) {
    return types.isSubtypeOfKernel(futureOr, t.unalias);
  }

  @override
  bool isIntersectionRelated(
      TypeParameterType intersection,
      Nullability intersectionNullability,
      TypedefType t,
      Nullability tNullability,
      Types types) {
    return types.isSubtypeOfKernel(intersection, t.unalias);
  }

  @override
  bool isTypeParameterRelated(TypeParameterType s, Nullability sNullability,
      TypedefType t, Nullability tNullability, Types types) {
    return types.isSubtypeOfKernel(s, t.unalias);
  }

  @override
  bool isTypedefRelated(TypedefType s, Nullability sNullability, TypedefType t,
      Nullability tNullability, Types types) {
    return types.isSubtypeOfKernel(s.unalias, t.unalias);
  }

  @override
  bool isVoidRelated(VoidType s, Nullability sNullability, TypedefType t,
      Nullability tNullability, Types types) {
    return types.isSubtypeOfKernel(s, t.unalias);
  }
}

class IsFutureOrSubtypeOf extends TypeRelation<InterfaceType> {
  const IsFutureOrSubtypeOf();

  @override
  bool isInterfaceRelated(InterfaceType s, Nullability sNullability,
      InterfaceType futureOr, Nullability futureOrNullability, Types types) {
    List<DartType> arguments = futureOr.typeArguments;
    if (types.isSubtypeOfKernel(s, arguments.single)) {
      return true; // Rule 11.
    }
    // Rule 10.
    return types.isSubtypeOfKernel(
        s, new InterfaceType(types.hierarchy.futureClass, arguments));
  }

  @override
  bool isFutureOrRelated(
      InterfaceType sFutureOr,
      Nullability sFutureOrNullability,
      InterfaceType tFutureOr,
      Nullability tFutureOrNullability,
      Types types) {
    // This follows from combining rules 7, 10, and 11.
    return types.isSubtypeOfKernel(
        sFutureOr.typeArguments.single, tFutureOr.typeArguments.single);
  }

  @override
  bool isDynamicRelated(DynamicType s, Nullability sNullability,
      InterfaceType futureOr, Nullability futureOrNullability, Types types) {
    // Rule 11.
    return types.isSubtypeOfKernel(s, futureOr.typeArguments.single);
  }

  @override
  bool isVoidRelated(VoidType s, Nullability sNullability,
      InterfaceType futureOr, Nullability futureOrNullability, Types types) {
    // Rule 11.
    return types.isSubtypeOfKernel(s, futureOr.typeArguments.single);
  }

  @override
  bool isTypeParameterRelated(TypeParameterType s, Nullability sNullability,
      InterfaceType futureOr, Nullability futureOrNullability, Types types) {
    List<DartType> arguments = futureOr.typeArguments;
    if (types.isSubtypeOfKernel(s, arguments.single)) {
      // Rule 11.
      return true;
    }

    if (types.isSubtypeOfKernel(s.parameter.bound, futureOr)) {
      // Rule 13.
      return true;
    }

    // Rule 10.
    return types.isSubtypeOfKernel(
        s, new InterfaceType(types.hierarchy.futureClass, arguments));
  }

  @override
  bool isFunctionRelated(FunctionType s, Nullability sNullability,
      InterfaceType futureOr, Nullability futureOrNullability, Types types) {
    // Rule 11.
    return types.isSubtypeOfKernel(s, futureOr.typeArguments.single);
  }

  @override
  bool isIntersectionRelated(
      TypeParameterType intersection,
      Nullability intersectionNullability,
      InterfaceType futureOr,
      Nullability futureOrNullability,
      Types types) {
    if (isTypeParameterRelated(intersection, intersectionNullability, futureOr,
        futureOrNullability, types)) {
      // Rule 8.
      return true;
    }
    // Rule 12.
    return types.isSubtypeOfKernel(intersection.promotedBound, futureOr);
  }

  @override
  bool isTypedefRelated(TypedefType s, Nullability sNullability,
      InterfaceType futureOr, Nullability futureOrNullability, Types types) {
    return types.isSubtypeOfKernel(s.unalias, futureOr);
  }
}

class IsIntersectionSubtypeOf extends TypeRelation<TypeParameterType> {
  const IsIntersectionSubtypeOf();

  @override
  bool isIntersectionRelated(
      TypeParameterType sIntersection,
      Nullability sIntersectionNullability,
      TypeParameterType tIntersection,
      Nullability tIntersectionNullability,
      Types types) {
    // Rule 9.
    return const IsTypeParameterSubtypeOf().isIntersectionRelated(
            sIntersection,
            sIntersectionNullability,
            tIntersection,
            tIntersectionNullability,
            types) &&
        types.isSubtypeOfKernel(sIntersection, tIntersection.promotedBound);
  }

  @override
  bool isTypeParameterRelated(
      TypeParameterType s,
      Nullability sNullability,
      TypeParameterType intersection,
      Nullability intersectionNullability,
      Types types) {
    // Rule 9.
    return const IsTypeParameterSubtypeOf().isTypeParameterRelated(
            s, sNullability, intersection, intersectionNullability, types) &&
        types.isSubtypeOfKernel(s, intersection.promotedBound);
  }

  @override
  bool isInterfaceRelated(
      InterfaceType s,
      Nullability sNullability,
      TypeParameterType intersection,
      Nullability intersectionNullability,
      Types types) {
    return s.classNode == types.hierarchy.nullClass; // Rule 4.
  }

  @override
  bool isDynamicRelated(
      DynamicType s,
      Nullability sNullability,
      TypeParameterType intersection,
      Nullability intersectionNullability,
      Types types) {
    return false;
  }

  @override
  bool isFunctionRelated(
      FunctionType s,
      Nullability sNullability,
      TypeParameterType intersection,
      Nullability intersectionNullability,
      Types types) {
    return false;
  }

  @override
  bool isFutureOrRelated(
      InterfaceType futureOr,
      Nullability futureOrNullability,
      TypeParameterType intersection,
      Nullability intersectionNullability,
      Types types) {
    return false;
  }

  @override
  bool isTypedefRelated(
      TypedefType s,
      Nullability sNullability,
      TypeParameterType intersection,
      Nullability intersectionNullability,
      Types types) {
    // Rule 5.
    return types.isSubtypeOfKernel(s.unalias, intersection);
  }

  @override
  bool isVoidRelated(
      VoidType s,
      Nullability sNullability,
      TypeParameterType intersection,
      Nullability intersectionNullability,
      Types types) {
    return false;
  }
}
