15 private function __construct(){}
17 public static function isCovariant(?
BaseType $acceptingType, ?
BaseType $givenType) :
bool{
19 if($acceptingType ===
null || ($acceptingType instanceof
NamedType && $acceptingType->type === BuiltInType::VOID)){
24 if($givenType ===
null){
36 foreach($givenType->types as $type){
37 if(!self::isCovariant($acceptingType, $type)){
50 foreach($givenType->types as $type){
51 if(self::isCovariant($acceptingType, $type)){
60 $acceptingTypeName = $acceptingType->type;
61 $givenTypeName = $givenType->type;
62 if($acceptingTypeName === $givenTypeName){
67 if($acceptingTypeName === BuiltInType::MIXED && $givenTypeName !== BuiltInType::VOID){
72 if($acceptingTypeName === BuiltInType::FLOAT && $givenTypeName === BuiltInType::INT){
78 if($acceptingTypeName === BuiltInType::ITERABLE){
79 return $givenTypeName === BuiltInType::ARRAY
80 || $givenTypeName === \Traversable::class
81 || \is_subclass_of($givenTypeName, \Traversable::class);
85 if($acceptingTypeName === BuiltInType::CALLABLE){
86 return $givenTypeName === \Closure::class
87 || \method_exists($givenTypeName,
'__invoke')
88 || \is_subclass_of($givenTypeName, \Closure::class);
91 if($acceptingTypeName === BuiltInType::OBJECT){
93 return !$givenTypeName instanceof BuiltInType;
96 return is_string($givenTypeName) && is_string($acceptingTypeName) && \is_subclass_of($givenTypeName, $acceptingTypeName);
99 throw new \AssertionError(
"Unhandled reflection type " . get_class($givenType));
104 foreach($acceptingType->types as $type){
105 if(self::isCovariant($type, $givenType)){
115 foreach($acceptingType->types as $type){
116 if(!self::isCovariant($type, $givenType)){