|
6 | 6 |
|
7 | 7 | use Illuminate\Database\Eloquent\Builder; |
8 | 8 | use Illuminate\Database\Eloquent\Collection; |
| 9 | +use Illuminate\Database\Eloquent\Model; |
9 | 10 | use Illuminate\Database\Query\Builder as QueryBuilder; |
10 | 11 | use Illuminate\Support\Str; |
11 | 12 | use NunoMaduro\Larastan\Methods\ModelTypeHelper; |
@@ -78,31 +79,45 @@ public function getTypeFromMethodCall( |
78 | 79 | return null; |
79 | 80 | } |
80 | 81 |
|
81 | | - /** @var ObjectType $model */ |
82 | | - $model = $methodReflection->getDeclaringClass()->getActiveTemplateTypeMap()->getType('TModelClass'); |
| 82 | + /** @var Type $modelClassType */ |
| 83 | + $modelClassType = $methodReflection->getDeclaringClass()->getActiveTemplateTypeMap()->getType('TModelClass'); |
| 84 | + |
| 85 | + if ((new ObjectType(Model::class))->isSuperTypeOf($modelClassType)->no()) { |
| 86 | + return null; |
| 87 | + } |
| 88 | + |
83 | 89 | $returnType = $methodReflection->getVariants()[0]->getReturnType(); |
84 | 90 | $argType = $scope->getType($methodCall->getArgs()[0]->value); |
85 | 91 |
|
86 | | - $returnType = ModelTypeHelper::replaceStaticTypeWithModel($returnType, $model->getClassName()); |
| 92 | + if ($argType instanceof MixedType) { |
| 93 | + return $returnType; |
| 94 | + } |
87 | 95 |
|
88 | | - if ($argType->isIterable()->yes()) { |
89 | | - if (in_array(Collection::class, $returnType->getReferencedClasses(), true)) { |
90 | | - return $this->collectionHelper->determineCollectionClass($model->getClassName()); |
91 | | - } |
| 96 | + $models = []; |
92 | 97 |
|
93 | | - return TypeCombinator::remove($returnType, $model); |
94 | | - } |
| 98 | + foreach ($modelClassType->getObjectClassReflections() as $objectClassReflection) { |
| 99 | + $modelName = $objectClassReflection->getName(); |
95 | 100 |
|
96 | | - if ($argType instanceof MixedType) { |
97 | | - return $returnType; |
| 101 | + $returnType = ModelTypeHelper::replaceStaticTypeWithModel($returnType, $modelName); |
| 102 | + |
| 103 | + if ($argType->isIterable()->yes()) { |
| 104 | + if (in_array(Collection::class, $returnType->getReferencedClasses(), true)) { |
| 105 | + $models[] = $this->collectionHelper->determineCollectionClass($modelName); |
| 106 | + continue; |
| 107 | + } |
| 108 | + |
| 109 | + $models[] = TypeCombinator::remove($returnType, new ObjectType($modelName)); |
| 110 | + } else { |
| 111 | + $models[] = TypeCombinator::remove( |
| 112 | + TypeCombinator::remove( |
| 113 | + $returnType, |
| 114 | + new ArrayType(new MixedType(), $modelClassType) |
| 115 | + ), |
| 116 | + new ObjectType(Collection::class) |
| 117 | + ); |
| 118 | + } |
98 | 119 | } |
99 | 120 |
|
100 | | - return TypeCombinator::remove( |
101 | | - TypeCombinator::remove( |
102 | | - $returnType, |
103 | | - new ArrayType(new MixedType(), $model) |
104 | | - ), |
105 | | - new ObjectType(Collection::class) |
106 | | - ); |
| 121 | + return count($models) > 0 ? TypeCombinator::union(...$models) : null; |
107 | 122 | } |
108 | 123 | } |
0 commit comments