@@ -91,7 +91,7 @@ public function checkProperty(
91
91
92
92
if (!$ phpDocPropertyType instanceof MixedType || $ phpDocPropertyType ->isExplicitMixed ()) {
93
93
$ phpDocPropertyType = TypeUtils::resolveLateResolvableTypes (TypehintHelper::decideType ($ nativePropertyType , $ phpDocPropertyType ));
94
- $ narrowedPhpDocType = $ this ->narrowType ($ phpDocPropertyType , $ assignedType , $ scope , false );
94
+ $ narrowedPhpDocType = $ this ->narrowType ($ phpDocPropertyType , $ assignedType , $ scope , false , false );
95
95
if (!$ narrowedPhpDocType ->equals ($ phpDocPropertyType )) {
96
96
$ phpDocPropertyTypeDescription = $ phpDocPropertyType ->describe (VerbosityLevel::getRecommendedLevelByType ($ phpDocPropertyType ));
97
97
return $ this ->createErrors (
@@ -110,7 +110,7 @@ public function checkProperty(
110
110
}
111
111
112
112
$ narrowedPhpDocType = SimultaneousTypeTraverser::map ($ phpDocPropertyType , $ assignedType , function (Type $ declaredType , Type $ actualType , callable $ traverse ) use ($ scope ) {
113
- $ narrowed = $ this ->narrowType ($ declaredType , $ actualType , $ scope , false );
113
+ $ narrowed = $ this ->narrowType ($ declaredType , $ actualType , $ scope , false , false );
114
114
if (!$ narrowed ->equals ($ declaredType )) {
115
115
return $ narrowed ;
116
116
}
@@ -132,7 +132,7 @@ public function checkProperty(
132
132
];
133
133
}
134
134
135
- $ narrowedNativeType = $ this ->narrowType ($ nativePropertyType , $ assignedType , $ scope , true );
135
+ $ narrowedNativeType = $ this ->narrowType ($ nativePropertyType , $ assignedType , $ scope , false , true );
136
136
if (!$ narrowedNativeType ->equals ($ nativePropertyType )) {
137
137
$ propertyTypeDescription = $ nativePropertyType ->describe (VerbosityLevel::getRecommendedLevelByType ($ nativePropertyType ));
138
138
return $ this ->createErrors (
@@ -213,7 +213,7 @@ public function checkFunctionReturnType(
213
213
if (!$ phpDocFunctionReturnType instanceof MixedType || $ phpDocFunctionReturnType ->isExplicitMixed ()) {
214
214
$ phpDocFunctionReturnType = TypeUtils::resolveLateResolvableTypes (TypehintHelper::decideType ($ nativeFunctionReturnType , $ phpDocFunctionReturnType ));
215
215
216
- $ narrowedPhpDocType = $ this ->narrowType ($ phpDocFunctionReturnType , $ returnType , $ scope , false );
216
+ $ narrowedPhpDocType = $ this ->narrowType ($ phpDocFunctionReturnType , $ returnType , $ scope , false , false );
217
217
if (!$ narrowedPhpDocType ->equals ($ phpDocFunctionReturnType )) {
218
218
return $ this ->createErrors (
219
219
$ narrowedPhpDocType ,
@@ -230,8 +230,8 @@ public function checkFunctionReturnType(
230
230
return [];
231
231
}
232
232
233
- $ narrowedPhpDocType = SimultaneousTypeTraverser::map ($ phpDocFunctionReturnType , $ returnType , function (Type $ declaredType , Type $ actualReturnType , callable $ traverse ) use ($ scope ) {
234
- $ narrowed = $ this ->narrowType ($ declaredType , $ actualReturnType , $ scope , false );
233
+ $ narrowedPhpDocType = SimultaneousTypeTraverser::map ($ phpDocFunctionReturnType , $ returnType , function (Type $ declaredType , Type $ actualReturnType , callable $ traverse ) use ($ scope, $ checkDescendantClass ) {
234
+ $ narrowed = $ this ->narrowType ($ declaredType , $ actualReturnType , $ scope , $ checkDescendantClass , false );
235
235
if (!$ narrowed ->equals ($ declaredType )) {
236
236
return $ narrowed ;
237
237
}
@@ -253,7 +253,7 @@ public function checkFunctionReturnType(
253
253
];
254
254
}
255
255
256
- $ narrowedNativeType = $ this ->narrowType ($ nativeFunctionReturnType , $ returnType , $ scope , true );
256
+ $ narrowedNativeType = $ this ->narrowType ($ nativeFunctionReturnType , $ returnType , $ scope , false , true );
257
257
if (!$ narrowedNativeType ->equals ($ nativeFunctionReturnType )) {
258
258
return $ this ->createErrors (
259
259
$ narrowedNativeType ,
@@ -286,14 +286,14 @@ public function checkParameterOutType(
286
286
): array
287
287
{
288
288
$ parameterOutType = TypeUtils::resolveLateResolvableTypes ($ parameterOutType );
289
- $ narrowedType = $ this ->narrowType ($ parameterOutType , $ actualVariableType , $ scope , false );
289
+ $ narrowedType = $ this ->narrowType ($ parameterOutType , $ actualVariableType , $ scope , false , false );
290
290
if ($ narrowedType ->equals ($ parameterOutType )) {
291
291
if (!$ this ->reportTooWideBool ) {
292
292
return [];
293
293
}
294
294
295
295
$ narrowedType = SimultaneousTypeTraverser::map ($ parameterOutType , $ actualVariableType , function (Type $ declaredType , Type $ actualType , callable $ traverse ) use ($ scope ) {
296
- $ narrowed = $ this ->narrowType ($ declaredType , $ actualType , $ scope , false );
296
+ $ narrowed = $ this ->narrowType ($ declaredType , $ actualType , $ scope , false , false );
297
297
if (!$ narrowed ->equals ($ declaredType )) {
298
298
return $ narrowed ;
299
299
}
@@ -408,6 +408,7 @@ private function narrowType(
408
408
Type $ declaredType ,
409
409
Type $ actualReturnType ,
410
410
Scope $ scope ,
411
+ bool $ checkDescendantClass ,
411
412
bool $ native ,
412
413
): Type
413
414
{
@@ -421,7 +422,20 @@ private function narrowType(
421
422
$ usedTypes = [];
422
423
foreach ($ declaredType ->getTypes () as $ innerType ) {
423
424
if ($ innerType ->isSuperTypeOf ($ actualReturnType )->no ()) {
424
- continue ;
425
+ if (!$ checkDescendantClass ) {
426
+ continue ;
427
+ }
428
+ if ($ innerType ->isNull ()->yes ()) {
429
+ $ usedTypes [] = $ innerType ;
430
+ continue ;
431
+ }
432
+ if (
433
+ !$ actualReturnType ->isTrue ()->yes ()
434
+ && !$ actualReturnType ->isFalse ()->yes ()
435
+ && !$ actualReturnType ->isNull ()->yes ()
436
+ ) {
437
+ continue ;
438
+ }
425
439
}
426
440
427
441
$ usedTypes [] = $ innerType ;
0 commit comments