Skip to content

Commit 93f7b5e

Browse files
TASK: Harmonize semantics of Neos\Utility\TypeHandling with PHP 8 type system semantics
Use new Harmonized semantics in Reflection Service
1 parent bdcc59f commit 93f7b5e

2 files changed

Lines changed: 99 additions & 7 deletions

File tree

Neos.Flow/Classes/Reflection/ReflectionService.php

Lines changed: 4 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1462,9 +1462,7 @@ protected function reflectClassMethod($className, MethodReflection $method)
14621462

14631463
$returnType= $method->getDeclaredReturnType();
14641464
$applyLeadingSlashIfNeeded = function (string $type): string {
1465-
if (!in_array($type, ['self', 'parent', 'static', 'null', 'callable', 'void', 'never', 'iterable', 'object', 'resource', 'mixed'])
1466-
&& !TypeHandling::isSimpleType($type)
1467-
) {
1465+
if ($type[0] !== '\\' && TypeHandling::isUserDefinedType($type)) {
14681466
return '\\' . $type;
14691467
}
14701468
return $type;
@@ -1553,8 +1551,8 @@ protected function expandType(ClassReflection $class, $type)
15531551
return 'array<' . $this->expandType($class, $elementType) . '>' . ($isNullable ? '|null' : '');
15541552
}
15551553

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

@@ -1914,7 +1912,7 @@ static function (\ReflectionNamedType $type) {
19141912
$parameterType = $parameterType->getName();
19151913
}
19161914
}
1917-
if ($parameterType !== null && !TypeHandling::isSimpleType($parameterType)) {
1915+
if ($parameterType !== null && TypeHandling::isUserDefinedType($parameterType)) {
19181916
// We use parameter type here to make class_alias usage work and return the hinted class name instead of the alias
19191917
$parameterInformation[self::DATA_PARAMETER_CLASS] = $parameterType;
19201918
} elseif ($parameterType === 'array') {

Neos.Utility.ObjectHandling/Classes/TypeHandling.php

Lines changed: 95 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,21 @@ abstract class TypeHandling
3030
*/
3131
const LITERAL_TYPE_PATTERN = '/^(?:integer|int|float|double|boolean|bool|string)$/';
3232

33+
/**
34+
* A type pattern to detect scalar types.
35+
*/
36+
const SCALAR_TYPE_PATTERN = '/^(?:int|float|bool|string)$/';
37+
38+
/**
39+
* @var array<string>
40+
*/
41+
protected static $builtInTypes = ['null', 'array', 'object', 'resource', 'never', 'void', 'self', 'parent', 'static'];
42+
43+
/**
44+
* @var array<string>
45+
*/
46+
protected static $builtInTypeAliases = ['mixed', 'iterable'];
47+
3348
/**
3449
* @var array
3550
*/
@@ -96,21 +111,100 @@ public static function normalizeType(string $type): string
96111
*
97112
* @param string $type
98113
* @return boolean
114+
* @deprecated use isLiteralType()
99115
*/
100116
public static function isLiteral(string $type): bool
117+
{
118+
return self::isLiteralType($type);
119+
}
120+
121+
/**
122+
* Returns true if the $type is a scalar type.
123+
*
124+
* @param string $type
125+
* @return bool
126+
*/
127+
public static function isScalarType(string $type): bool
128+
{
129+
return preg_match(self::SCALAR_TYPE_PATTERN, $type) === 1;
130+
}
131+
132+
/**
133+
* Returns true if the $type is a built-in type.
134+
*
135+
* @param string $type
136+
* @return bool
137+
*/
138+
public static function isBuiltInType(string $type): bool
139+
{
140+
if (self::isScalarType($type)) {
141+
return true;
142+
}
143+
144+
return in_array($type, self::$builtInTypes, true);
145+
}
146+
147+
/**
148+
* Returns true if the $type is a literal type.
149+
*
150+
* @param string $type
151+
* @return bool
152+
*/
153+
public static function isLiteralType(string $type): bool
101154
{
102155
return preg_match(self::LITERAL_TYPE_PATTERN, $type) === 1;
103156
}
104157

158+
/**
159+
* Returns true if the $type is callable.
160+
*
161+
* @param string $type
162+
* @return bool
163+
*/
164+
public static function isCallableType(string $type): bool
165+
{
166+
return $type === 'callable';
167+
}
168+
169+
/**
170+
* Returns true if the $type is a built-in type alias.
171+
*
172+
* @param string $type
173+
* @return bool
174+
*/
175+
public static function isBuiltInTypeAlias(string $type): bool
176+
{
177+
return in_array($type, self::$builtInTypeAliases, true);
178+
}
179+
180+
/**
181+
* Returns true if the $type is user-defined.
182+
*
183+
* @param string $type
184+
* @return bool
185+
*/
186+
public static function isUserDefinedType(string $type): bool
187+
{
188+
return !self::isBuiltInType($type)
189+
&& !self::isLiteralType($type)
190+
&& !self::isCallableType($type)
191+
&& !self::isBuiltInTypeAlias($type);
192+
}
193+
105194
/**
106195
* Returns true if the $type is a simple type.
107196
*
108197
* @param string $type
109198
* @return boolean
199+
* @deprecated use isBuiltInType(), isLiteralType(), isCallableType() or isBuiltInTypeAlias()
110200
*/
111201
public static function isSimpleType(string $type): bool
112202
{
113-
return in_array(self::normalizeType($type), ['array', 'string', 'float', 'integer', 'boolean', 'null', 'false', 'true'], true);
203+
$normalizedType = self::normalizeType($type);
204+
205+
return $normalizedType === 'array'
206+
|| self::isLiteralType($type)
207+
|| in_array($normalizedType, ['null', 'false', 'true'], true);
114208
}
115209

116210
/**

0 commit comments

Comments
 (0)