Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 5 additions & 7 deletions Neos.Flow/Classes/Reflection/ReflectionService.php
Original file line number Diff line number Diff line change
Expand Up @@ -1321,10 +1321,8 @@ protected function reflectClassMethod(string $className, MethodReflection $metho
}

$returnType = $method->getDeclaredReturnType();
$applyLeadingSlashIfNeeded = static function (string $type): string {
if (!in_array($type, ['self', 'parent', 'static', 'null', 'callable', 'void', 'never', 'iterable', 'object', 'resource', 'mixed'])
&& !TypeHandling::isSimpleType($type)
) {
$applyLeadingSlashIfNeeded = function (string $type): string {
if (!str_starts_with($type, '\\') && TypeHandling::isUserDefinedType($type)) {
return '\\' . $type;
}
return $type;
Expand Down Expand Up @@ -1415,8 +1413,8 @@ protected function expandType(ClassReflection $class, string $type): string
return 'array<' . $this->expandType($class, $elementType) . '>' . ($isNullable ? '|null' : '');
}

// skip simple types and types with fully qualified namespaces
if ($type === 'mixed' || $type[0] === '\\' || TypeHandling::isSimpleType($type)) {
// skip non user-defined types and types with fully qualified namespaces
if ($typeWithoutNull[0] === '\\' || !TypeHandling::isUserDefinedType($typeWithoutNull)) {
return TypeHandling::normalizeType($typeWithoutNull) . ($isNullable ? '|null' : '');
}

Expand Down Expand Up @@ -1777,7 +1775,7 @@ protected function convertParameterReflectionToArray(ParameterReflection $parame
}

$parameterType = $this->renderParameterType($parameter->getType());
if ($parameterType !== null && !TypeHandling::isSimpleType($parameterType)) {
if ($parameterType !== null && TypeHandling::isUserDefinedType($parameterType)) {
// We use parameter type here to make class_alias usage work and return the hinted class name instead of the alias
$parameterInformation[self::DATA_PARAMETER_CLASS] = $parameterType;
} elseif ($parameterType === 'array') {
Expand Down
98 changes: 96 additions & 2 deletions Neos.Utility.ObjectHandling/Classes/TypeHandling.php
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,22 @@ abstract class TypeHandling
/**
* A type pattern to detect literal types.
*/
const LITERAL_TYPE_PATTERN = '/^(?:integer|int|float|double|boolean|bool|string)$/';
const LITERAL_TYPE_PATTERN = '/^(?:integer|int|float|double|boolean|bool|string|true|false|null)$/';

/**
* A type pattern to detect scalar types.
*/
const SCALAR_TYPE_PATTERN = '/^(?:int|float|bool|string)$/';

/**
* @var array<string>
*/
protected static $builtInTypes = ['null', 'array', 'object', 'resource', 'never', 'void', 'self', 'parent', 'static'];

/**
* @var array<string>
*/
protected static $builtInTypeAliases = ['mixed', 'iterable'];

Comment on lines +33 to +47

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I wonder about the mix here between regex and array configuration.

/**
* @var array<int,string|class-string<\Traversable<mixed>>>
Expand Down Expand Up @@ -96,21 +111,100 @@ public static function normalizeType(string $type): string
*
* @param string $type
* @return boolean
* @deprecated use isLiteralType()
*/
public static function isLiteral(string $type): bool
{
return self::isLiteralType($type);
}

/**
* Returns true if the $type is a scalar type.
*
* @param string $type
* @return bool
*/
public static function isScalarType(string $type): bool
{
return preg_match(self::SCALAR_TYPE_PATTERN, $type) === 1;
}

/**
* Returns true if the $type is a built-in type.
*
* @param string $type
* @return bool
*/
public static function isBuiltInType(string $type): bool
{
if (self::isScalarType($type)) {
return true;
}

return in_array($type, self::$builtInTypes, true);
}

/**
* Returns true if the $type is a literal type.
*
* @param string $type
* @return bool
*/
public static function isLiteralType(string $type): bool
{
return preg_match(self::LITERAL_TYPE_PATTERN, $type) === 1;
}

/**
* Returns true if the $type is callable.
*
* @param string $type
* @return bool
*/
public static function isCallableType(string $type): bool
{
return $type === 'callable';
}

/**
* Returns true if the $type is a built-in type alias.
*
* @param string $type
* @return bool
*/
public static function isBuiltInTypeAlias(string $type): bool
{
return in_array($type, self::$builtInTypeAliases, true);
}

/**
* Returns true if the $type is user-defined.
*
* @param string $type
* @return bool
*/
public static function isUserDefinedType(string $type): bool
{
return !self::isBuiltInType($type)
&& !self::isLiteralType($type)
&& !self::isCallableType($type)
&& !self::isBuiltInTypeAlias($type);
}

/**
* Returns true if the $type is a simple type.
*
* @param string $type
* @return boolean
* @deprecated use isBuiltInType(), isLiteralType(), isCallableType() or isBuiltInTypeAlias()
*/
public static function isSimpleType(string $type): bool
{
return in_array(self::normalizeType($type), ['array', 'string', 'float', 'integer', 'boolean', 'null', 'false', 'true'], true);
$normalizedType = self::normalizeType($type);

return $normalizedType === 'array'
|| self::isLiteralType($type)
|| in_array($normalizedType, ['null', 'false', 'true'], true);
}

/**
Expand Down
Loading