|
17 | 17 | use PHPStan\ShouldNotHappenException;
|
18 | 18 | use PHPStan\TrinaryLogic;
|
19 | 19 | use PHPStan\Type\Generic\GenericObjectType;
|
| 20 | +use PHPStan\Type\ObjectType; |
20 | 21 | use PHPStan\Type\Type;
|
| 22 | +use PHPStan\Type\TypeCombinator; |
| 23 | +use PHPStan\Type\TypeWithClassName; |
21 | 24 | use PHPStan\Type\VerbosityLevel;
|
22 | 25 |
|
23 | 26 | use function array_key_exists;
|
24 | 27 | use function array_shift;
|
| 28 | +use function collect; |
25 | 29 | use function count;
|
26 | 30 | use function in_array;
|
| 31 | +use function is_string; |
27 | 32 | use function preg_split;
|
28 | 33 | use function substr;
|
29 | 34 | use function ucfirst;
|
@@ -232,4 +237,33 @@ public function determineBuilderName(string $modelClassName): string
|
232 | 237 |
|
233 | 238 | return $returnType->describe(VerbosityLevel::value());
|
234 | 239 | }
|
| 240 | + |
| 241 | + /** |
| 242 | + * @param array<int, string|TypeWithClassName>|string|TypeWithClassName $models |
| 243 | + * |
| 244 | + * @return ($models is array<int, string|TypeWithClassName> ? Type : ObjectType) |
| 245 | + */ |
| 246 | + public function getBuilderTypeForModels(array|string|TypeWithClassName $models): Type |
| 247 | + { |
| 248 | + return collect() |
| 249 | + ->wrap($models) |
| 250 | + ->unique() |
| 251 | + ->mapWithKeys(static function ($model) { |
| 252 | + if (is_string($model)) { |
| 253 | + return [$model => new ObjectType($model)]; |
| 254 | + } |
| 255 | + |
| 256 | + return [$model->getClassName() => $model]; |
| 257 | + }) |
| 258 | + ->mapToGroups(fn ($type, $class) => [$this->determineBuilderName($class) => $type]) |
| 259 | + ->map(function ($models, $builder) { |
| 260 | + $builderReflection = $this->reflectionProvider->getClass($builder); |
| 261 | + |
| 262 | + return $builderReflection->isGeneric() |
| 263 | + ? new GenericObjectType($builder, [TypeCombinator::union(...$models)]) |
| 264 | + : new ObjectType($builder); |
| 265 | + }) |
| 266 | + ->values() |
| 267 | + ->pipe(static fn ($types) => TypeCombinator::union(...$types)); |
| 268 | + } |
235 | 269 | }
|
0 commit comments