in pkg/kernel/lib/src/types.dart [73:296]
IsSubtypeOf performNullabilityAwareSubtypeCheck(DartType s, DartType t) {
// TODO(johnniwinther,dmitryas): Ensure complete handling of InvalidType in
// the subtype relation.
if (s is InvalidType || t is InvalidType) {
return const IsSubtypeOf.always();
}
if (t is DynamicType) {
return const IsSubtypeOf.always(); // Rule 2.
}
if (t is VoidType) {
return const IsSubtypeOf.always(); // Rule 2.
}
if (s is NeverType) {
return new IsSubtypeOf.basedSolelyOnNullabilities(s, t);
}
if (s is NullType) {
// Rule 4.
return new IsSubtypeOf.basedSolelyOnNullabilities(s, t);
}
if (t is InterfaceType) {
Class cls = t.classNode;
if (cls == hierarchy.coreTypes.objectClass && s is! FutureOrType) {
return new IsSubtypeOf.basedSolelyOnNullabilities(s, t);
}
const IsInterfaceSubtypeOf relation = const IsInterfaceSubtypeOf();
if (s is DynamicType) {
return relation.isDynamicRelated(s, t, this);
} else if (s is VoidType) {
return relation.isVoidRelated(s, t, this);
} else if (s is InterfaceType) {
return relation.isInterfaceRelated(s, t, this);
} else if (s is FunctionType) {
return relation.isFunctionRelated(s, t, this);
} else if (s is TypeParameterType) {
return s.promotedBound == null
? relation.isTypeParameterRelated(s, t, this)
: relation.isIntersectionRelated(s, t, this);
} else if (s is TypedefType) {
return relation.isTypedefRelated(s, t, this);
} else if (s is FutureOrType) {
return relation.isFutureOrRelated(s, t, this);
} else if (s is ExtensionType) {
return relation.isExtensionRelated(s, t, this);
}
} else if (t is FunctionType) {
const IsFunctionSubtypeOf relation = const IsFunctionSubtypeOf();
if (s is DynamicType) {
return relation.isDynamicRelated(s, t, this);
} else if (s is VoidType) {
return relation.isVoidRelated(s, t, this);
} else if (s is InterfaceType) {
return relation.isInterfaceRelated(s, t, this);
} else if (s is FunctionType) {
return relation.isFunctionRelated(s, t, this);
} else if (s is TypeParameterType) {
return s.promotedBound == null
? relation.isTypeParameterRelated(s, t, this)
: relation.isIntersectionRelated(s, t, this);
} else if (s is TypedefType) {
return relation.isTypedefRelated(s, t, this);
} else if (s is FutureOrType) {
return relation.isFutureOrRelated(s, t, this);
} else if (s is ExtensionType) {
return relation.isExtensionRelated(s, t, this);
}
} else if (t is TypeParameterType) {
if (t.promotedBound == null) {
const IsTypeParameterSubtypeOf relation =
const IsTypeParameterSubtypeOf();
if (s is DynamicType) {
return relation.isDynamicRelated(s, t, this);
} else if (s is VoidType) {
return relation.isVoidRelated(s, t, this);
} else if (s is InterfaceType) {
return relation.isInterfaceRelated(s, t, this);
} else if (s is FunctionType) {
return relation.isFunctionRelated(s, t, this);
} else if (s is TypeParameterType) {
return s.promotedBound == null
? relation.isTypeParameterRelated(s, t, this)
: relation.isIntersectionRelated(s, t, this);
} else if (s is TypedefType) {
return relation.isTypedefRelated(s, t, this);
} else if (s is FutureOrType) {
return relation.isFutureOrRelated(s, t, this);
} else if (s is ExtensionType) {
return relation.isExtensionRelated(s, t, this);
}
} else {
const IsIntersectionSubtypeOf relation =
const IsIntersectionSubtypeOf();
if (s is DynamicType) {
return relation.isDynamicRelated(s, t, this);
} else if (s is VoidType) {
return relation.isVoidRelated(s, t, this);
} else if (s is InterfaceType) {
return relation.isInterfaceRelated(s, t, this);
} else if (s is FunctionType) {
return relation.isFunctionRelated(s, t, this);
} else if (s is TypeParameterType) {
return s.promotedBound == null
? relation.isTypeParameterRelated(s, t, this)
: relation.isIntersectionRelated(s, t, this);
} else if (s is TypedefType) {
return relation.isTypedefRelated(s, t, this);
} else if (s is FutureOrType) {
return relation.isFutureOrRelated(s, t, this);
} else if (s is ExtensionType) {
return relation.isExtensionRelated(s, t, this);
}
}
} else if (t is TypedefType) {
const IsTypedefSubtypeOf relation = const IsTypedefSubtypeOf();
if (s is DynamicType) {
return relation.isDynamicRelated(s, t, this);
} else if (s is VoidType) {
return relation.isVoidRelated(s, t, this);
} else if (s is InterfaceType) {
return relation.isInterfaceRelated(s, t, this);
} else if (s is FunctionType) {
return relation.isFunctionRelated(s, t, this);
} else if (s is TypeParameterType) {
return s.promotedBound == null
? relation.isTypeParameterRelated(s, t, this)
: relation.isIntersectionRelated(s, t, this);
} else if (s is TypedefType) {
return relation.isTypedefRelated(s, t, this);
} else if (s is FutureOrType) {
return relation.isFutureOrRelated(s, t, this);
} else if (s is ExtensionType) {
return relation.isExtensionRelated(s, t, this);
}
} else if (t is FutureOrType) {
const IsFutureOrSubtypeOf relation = const IsFutureOrSubtypeOf();
if (s is DynamicType) {
return relation.isDynamicRelated(s, t, this);
} else if (s is VoidType) {
return relation.isVoidRelated(s, t, this);
} else if (s is InterfaceType) {
return relation.isInterfaceRelated(s, t, this);
} else if (s is FunctionType) {
return relation.isFunctionRelated(s, t, this);
} else if (s is TypeParameterType) {
return s.promotedBound == null
? relation.isTypeParameterRelated(s, t, this)
: relation.isIntersectionRelated(s, t, this);
} else if (s is TypedefType) {
return relation.isTypedefRelated(s, t, this);
} else if (s is FutureOrType) {
return relation.isFutureOrRelated(s, t, this);
} else if (s is ExtensionType) {
return relation.isExtensionRelated(s, t, this);
}
} else if (t is NullType) {
const IsNullTypeSubtypeOf relation = const IsNullTypeSubtypeOf();
if (s is DynamicType) {
return relation.isDynamicRelated(s, t, this);
} else if (s is VoidType) {
return relation.isVoidRelated(s, t, this);
} else if (s is InterfaceType) {
return relation.isInterfaceRelated(s, t, this);
} else if (s is FunctionType) {
return relation.isFunctionRelated(s, t, this);
} else if (s is TypeParameterType) {
return s.promotedBound == null
? relation.isTypeParameterRelated(s, t, this)
: relation.isIntersectionRelated(s, t, this);
} else if (s is TypedefType) {
return relation.isTypedefRelated(s, t, this);
} else if (s is FutureOrType) {
return relation.isFutureOrRelated(s, t, this);
} else if (s is ExtensionType) {
return relation.isExtensionRelated(s, t, this);
}
} else if (t is NeverType) {
const IsNeverTypeSubtypeOf relation = const IsNeverTypeSubtypeOf();
if (s is DynamicType) {
return relation.isDynamicRelated(s, t, this);
} else if (s is VoidType) {
return relation.isVoidRelated(s, t, this);
} else if (s is InterfaceType) {
return relation.isInterfaceRelated(s, t, this);
} else if (s is FunctionType) {
return relation.isFunctionRelated(s, t, this);
} else if (s is TypeParameterType) {
return s.promotedBound == null
? relation.isTypeParameterRelated(s, t, this)
: relation.isIntersectionRelated(s, t, this);
} else if (s is TypedefType) {
return relation.isTypedefRelated(s, t, this);
} else if (s is FutureOrType) {
return relation.isFutureOrRelated(s, t, this);
} else if (s is ExtensionType) {
return relation.isExtensionRelated(s, t, this);
}
} else if (t is ExtensionType) {
const IsExtensionTypeSubtypeOf relation =
const IsExtensionTypeSubtypeOf();
if (s is DynamicType) {
return relation.isDynamicRelated(s, t, this);
} else if (s is VoidType) {
return relation.isVoidRelated(s, t, this);
} else if (s is InterfaceType) {
return relation.isInterfaceRelated(s, t, this);
} else if (s is FunctionType) {
return relation.isFunctionRelated(s, t, this);
} else if (s is TypeParameterType) {
return s.promotedBound == null
? relation.isTypeParameterRelated(s, t, this)
: relation.isIntersectionRelated(s, t, this);
} else if (s is TypedefType) {
return relation.isTypedefRelated(s, t, this);
} else if (s is FutureOrType) {
return relation.isFutureOrRelated(s, t, this);
} else if (s is ExtensionType) {
return relation.isExtensionRelated(s, t, this);
}
} else {
throw "Unhandled type: ${t.runtimeType}";
}
throw "Unhandled type combination: ${t.runtimeType} ${s.runtimeType}";
}