Skip to content

Commit 1b128bd

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

2 files changed

Lines changed: 101 additions & 9 deletions

File tree

Neos.Flow/Classes/Reflection/ReflectionService.php

Lines changed: 6 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1320,11 +1320,9 @@ protected function reflectClassMethod(string $className, MethodReflection $metho
13201320
$this->classesByMethodAnnotations[$annotationClassName][$className][$methodName] = $methodName;
13211321
}
13221322

1323-
$returnType = $method->getDeclaredReturnType();
1324-
$applyLeadingSlashIfNeeded = static function (string $type): string {
1325-
if (!in_array($type, ['self', 'parent', 'static', 'null', 'callable', 'void', 'never', 'iterable', 'object', 'resource', 'mixed'])
1326-
&& !TypeHandling::isSimpleType($type)
1327-
) {
1323+
$returnType= $method->getDeclaredReturnType();
1324+
$applyLeadingSlashIfNeeded = function (string $type): string {
1325+
if ($type[0] !== '\\' && TypeHandling::isUserDefinedType($type)) {
13281326
return '\\' . $type;
13291327
}
13301328
return $type;
@@ -1415,8 +1413,8 @@ protected function expandType(ClassReflection $class, string $type): string
14151413
return 'array<' . $this->expandType($class, $elementType) . '>' . ($isNullable ? '|null' : '');
14161414
}
14171415

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

@@ -1777,7 +1775,7 @@ protected function convertParameterReflectionToArray(ParameterReflection $parame
17771775
}
17781776

17791777
$parameterType = $this->renderParameterType($parameter->getType());
1780-
if ($parameterType !== null && !TypeHandling::isSimpleType($parameterType)) {
1778+
if ($parameterType !== null && TypeHandling::isUserDefinedType($parameterType)) {
17811779
// We use parameter type here to make class_alias usage work and return the hinted class name instead of the alias
17821780
$parameterInformation[self::DATA_PARAMETER_CLASS] = $parameterType;
17831781
} 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<int,string|class-string<\Traversable<mixed>>>
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)