mirror of
https://github.com/barryvdh/laravel-ide-helper.git
synced 2026-08-18 10:07:12 +00:00
Support all DNF types from PHP RFC (#1751)
* Support all DNF types from PHP RFC * Update failing test --------- Co-authored-by: Sava Markovic <[email protected]>
This commit is contained in:
@@ -1661,7 +1661,8 @@ class ModelsCommand extends Command
|
||||
$type = implode('|', $types);
|
||||
|
||||
if ($paramType->allowsNull()) {
|
||||
if (count($types) == 1) {
|
||||
// Use ?Type syntax only for single named types, not for intersection types
|
||||
if (count($types) == 1 && !str_starts_with($type, '(')) {
|
||||
$type = '?' . $type;
|
||||
} else {
|
||||
$type .= '|null';
|
||||
@@ -1734,24 +1735,53 @@ class ModelsCommand extends Command
|
||||
return $type;
|
||||
}
|
||||
|
||||
protected function extractReflectionTypes(ReflectionType $reflection_type)
|
||||
protected function extractReflectionTypes(ReflectionType $reflection_type): array
|
||||
{
|
||||
if ($reflection_type instanceof ReflectionNamedType) {
|
||||
$types[] = $this->getReflectionNamedType($reflection_type);
|
||||
} else {
|
||||
$types = [];
|
||||
foreach ($reflection_type->getTypes() as $named_type) {
|
||||
if ($named_type->getName() === 'null') {
|
||||
return [$this->getReflectionNamedType($reflection_type)];
|
||||
}
|
||||
|
||||
if ($reflection_type instanceof \ReflectionIntersectionType) {
|
||||
return [$this->formatIntersectionType($reflection_type)];
|
||||
}
|
||||
|
||||
if ($reflection_type instanceof \ReflectionUnionType) {
|
||||
return $this->extractUnionTypes($reflection_type);
|
||||
}
|
||||
|
||||
// Unknown type - return empty array as fallback
|
||||
return [];
|
||||
}
|
||||
|
||||
protected function extractUnionTypes(\ReflectionUnionType $union_type): array
|
||||
{
|
||||
$types = [];
|
||||
|
||||
foreach ($union_type->getTypes() as $inner_type) {
|
||||
if ($inner_type instanceof ReflectionNamedType) {
|
||||
if ($inner_type->getName() === 'null') {
|
||||
continue;
|
||||
}
|
||||
|
||||
$types[] = $this->getReflectionNamedType($named_type);
|
||||
$types[] = $this->getReflectionNamedType($inner_type);
|
||||
} elseif ($inner_type instanceof \ReflectionIntersectionType) {
|
||||
$types[] = $this->formatIntersectionType($inner_type);
|
||||
}
|
||||
// ReflectionUnionType cannot be nested per PHP's DNF rules
|
||||
}
|
||||
|
||||
return $types;
|
||||
}
|
||||
|
||||
protected function formatIntersectionType(\ReflectionIntersectionType $intersection_type): string
|
||||
{
|
||||
$parts = [];
|
||||
foreach ($intersection_type->getTypes() as $type) {
|
||||
$parts[] = $this->getReflectionNamedType($type);
|
||||
}
|
||||
|
||||
return '(' . implode('&', $parts) . ')';
|
||||
}
|
||||
|
||||
protected function getReflectionNamedType(ReflectionNamedType $paramType): string
|
||||
{
|
||||
$parameterName = $paramType->getName();
|
||||
|
||||
+37
-6
@@ -93,17 +93,48 @@ class Macro extends Method
|
||||
|
||||
protected function concatReflectionTypes(?\ReflectionType $type): string
|
||||
{
|
||||
/** @psalm-suppress UndefinedClass */
|
||||
$returnTypes = $type instanceof \ReflectionUnionType
|
||||
? $type->getTypes()
|
||||
: [$type];
|
||||
if ($type instanceof \ReflectionNamedType) {
|
||||
return $type->getName();
|
||||
}
|
||||
|
||||
return Collection::make($returnTypes)
|
||||
if ($type instanceof \ReflectionIntersectionType) {
|
||||
return $this->formatIntersectionType($type);
|
||||
}
|
||||
|
||||
if ($type instanceof \ReflectionUnionType) {
|
||||
return $this->formatUnionType($type);
|
||||
}
|
||||
|
||||
// Unknown or null type
|
||||
return '';
|
||||
}
|
||||
|
||||
protected function formatUnionType(\ReflectionUnionType $type): string
|
||||
{
|
||||
return Collection::make($type->getTypes())
|
||||
->map(function (\ReflectionType $inner) {
|
||||
if ($inner instanceof \ReflectionNamedType) {
|
||||
return $inner->getName();
|
||||
}
|
||||
if ($inner instanceof \ReflectionIntersectionType) {
|
||||
return $this->formatIntersectionType($inner);
|
||||
}
|
||||
// ReflectionUnionType cannot be nested per PHP's DNF rules
|
||||
return null;
|
||||
})
|
||||
->filter()
|
||||
->map->getName()
|
||||
->implode('|');
|
||||
}
|
||||
|
||||
protected function formatIntersectionType(\ReflectionIntersectionType $type): string
|
||||
{
|
||||
$parts = Collection::make($type->getTypes())
|
||||
->map(fn (\ReflectionNamedType $t) => $t->getName())
|
||||
->toArray();
|
||||
|
||||
return '(' . implode('&', $parts) . ')';
|
||||
}
|
||||
|
||||
protected function addLocationToPhpDoc()
|
||||
{
|
||||
if ($this->method->name === '__invoke') {
|
||||
|
||||
Reference in New Issue
Block a user