isSubtypeOf method
Checks if this type is a subtype of other.
Implementation
@override
bool isSubtypeOf(RuntimeType other, {Object? value}) {
// Any concrete type is a subtype of a type parameter (T)
if (other is TypeParameter) return true;
if (other is BridgedClass) {
if (isSubtypeOfFunc != null) {
return isSubtypeOfFunc!.call(other, value: value);
}
if (name == 'num') {
final isSubtype = switch (other.name) {
'num' => true,
'int' => true,
'double' => true,
_ => false,
};
return isSubtype;
}
if (nativeType == other.nativeType) return true;
// Common Dart type hierarchy relationships
// Object is a supertype of everything
if (other.name == 'Object') return true;
// List, Set implement Iterable
if (other.name == 'Iterable' && (name == 'List' || name == 'Set')) {
return true;
}
// int, double are subtypes of num
if (other.name == 'num' && (name == 'int' || name == 'double')) {
return true;
}
// GEN-075: Check native type hierarchy via isAssignable
// When the value's native object satisfies the target class's isAssignable,
// the native type IS a subtype (e.g., Row is a subtype of Widget).
if (value != null && other.isAssignable != null) {
final nativeValue = value is BridgedInstance
? value.nativeObject
: value;
if (other.isAssignable!(nativeValue)) return true;
}
// RC-7b: Check static supertype registry for native class hierarchy.
// This handles cases like StatelessWidget→Widget where BridgedClass
// objects don't have parent references.
final supertypes = _supertypeRegistry[name];
if (supertypes != null && supertypes.contains(other.name)) return true;
// Transitive check: walk the registry chain
if (supertypes != null) {
for (final superName in supertypes) {
final superSupertypes = _supertypeRegistry[superName];
if (superSupertypes != null &&
superSupertypes.contains(other.name)) {
return true;
}
}
}
return false;
}
return false;
}