mirror of
https://github.com/silverstripe/silverstripe-framework
synced 2024-10-22 14:05:37 +02:00
FIX Fix namespace parsing under PHP 8, tweak readability of parser
$hadNamespace was ambiguously named, so the original PHP 8 support update marked it true when it was strictly meant to indicate that a namespace separator token had been encountered, resulting in bungled parsing of complex class specs like Class(["arg" => true]).
This commit is contained in:
parent
effe5c2e6f
commit
8ad4c4e024
@ -430,7 +430,7 @@ class ClassInfo
|
|||||||
// Keep track of the current bucket that we're putting data into
|
// Keep track of the current bucket that we're putting data into
|
||||||
$bucket = &$args;
|
$bucket = &$args;
|
||||||
$bucketStack = [];
|
$bucketStack = [];
|
||||||
$hadNamespace = false;
|
$lastTokenWasNSSeparator = false;
|
||||||
$currentKey = null;
|
$currentKey = null;
|
||||||
|
|
||||||
foreach ($tokens as $token) {
|
foreach ($tokens as $token) {
|
||||||
@ -443,20 +443,20 @@ class ClassInfo
|
|||||||
($token[0] === T_NAME_QUALIFIED || $token[0] === T_NAME_FULLY_QUALIFIED)
|
($token[0] === T_NAME_QUALIFIED || $token[0] === T_NAME_FULLY_QUALIFIED)
|
||||||
) {
|
) {
|
||||||
// PHP 8 exposes the FQCN as a single T_NAME_QUALIFIED or T_NAME_FULLY_QUALIFIED token
|
// PHP 8 exposes the FQCN as a single T_NAME_QUALIFIED or T_NAME_FULLY_QUALIFIED token
|
||||||
$class .= $token[1];
|
$class = $token[1];
|
||||||
$hadNamespace = true;
|
|
||||||
} elseif ($class === null && is_array($token) && $token[0] === T_STRING) {
|
} elseif ($class === null && is_array($token) && $token[0] === T_STRING) {
|
||||||
$class = $token[1];
|
$class = $token[1];
|
||||||
} elseif (is_array($token) && $token[0] === T_NS_SEPARATOR) {
|
} elseif (is_array($token) && $token[0] === T_NS_SEPARATOR) {
|
||||||
$class .= $token[1];
|
$class .= $token[1];
|
||||||
$hadNamespace = true;
|
$lastTokenWasNSSeparator = true;
|
||||||
} elseif ($token === '.') {
|
} elseif ($token === '.') {
|
||||||
// Treat service name separator as NS separator
|
// Treat service name separator as NS separator
|
||||||
$class .= '.';
|
$class .= '.';
|
||||||
$hadNamespace = true;
|
$lastTokenWasNSSeparator = true;
|
||||||
} elseif ($hadNamespace && is_array($token) && $token[0] === T_STRING) {
|
} elseif ($lastTokenWasNSSeparator && is_array($token) && $token[0] === T_STRING) {
|
||||||
|
// Found another section of a namespaced class
|
||||||
$class .= $token[1];
|
$class .= $token[1];
|
||||||
$hadNamespace = false;
|
$lastTokenWasNSSeparator = false;
|
||||||
// Get arguments
|
// Get arguments
|
||||||
} elseif (is_array($token)) {
|
} elseif (is_array($token)) {
|
||||||
switch ($token[0]) {
|
switch ($token[0]) {
|
||||||
|
@ -265,4 +265,41 @@ class ClassInfoTest extends SapphireTest
|
|||||||
'ClassInfo::testClassesWithExtension() returns no classes after an extension being removed'
|
'ClassInfo::testClassesWithExtension() returns no classes after an extension being removed'
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @dataProvider provideClassSpecCases
|
||||||
|
*/
|
||||||
|
public function testParseClassSpec($input, $output)
|
||||||
|
{
|
||||||
|
$this->assertEquals(
|
||||||
|
$output,
|
||||||
|
ClassInfo::parse_class_spec($input)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function provideClassSpecCases()
|
||||||
|
{
|
||||||
|
return [
|
||||||
|
'Standard class' => [
|
||||||
|
'SimpleClass',
|
||||||
|
['SimpleClass', []],
|
||||||
|
],
|
||||||
|
'Namespaced class' => [
|
||||||
|
'Foo\\Bar\\NamespacedClass',
|
||||||
|
['Foo\\Bar\\NamespacedClass', []],
|
||||||
|
],
|
||||||
|
'Namespaced class with service name' => [
|
||||||
|
'Foo\\Bar\\NamespacedClass.withservicename',
|
||||||
|
['Foo\\Bar\\NamespacedClass.withservicename', []],
|
||||||
|
],
|
||||||
|
'Namespaced class with argument' => [
|
||||||
|
'Foo\\Bar\\NamespacedClass(["with-arg" => true])',
|
||||||
|
['Foo\\Bar\\NamespacedClass', [["with-arg" => true]]],
|
||||||
|
],
|
||||||
|
'Namespaced class with service name and argument' => [
|
||||||
|
'Foo\\Bar\\NamespacedClass.withmodifier(["and-arg" => true])',
|
||||||
|
['Foo\\Bar\\NamespacedClass.withmodifier', [["and-arg" => true]]],
|
||||||
|
],
|
||||||
|
];
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user