- Fixed a bug caused by a new T_NAME_QUALIFIED constant

This commit is contained in:
Dave M. 2022-07-18 16:19:20 +00:00
parent 14d6a0d10a
commit 2a45abae27
1 changed files with 42 additions and 27 deletions

View File

@ -2,7 +2,7 @@
namespace Notes; namespace Notes;
use Reflector, ReflectionClass, ReflectionProperty, ReflectionMethod; use Reflector, ReflectionClass, ReflectionProperty, ReflectionMethod, ReflectionUnionType, ReflectionNamedType, ReflectionParameter;
class ObjectReflection { class ObjectReflection {
@ -39,7 +39,7 @@ class ObjectReflection {
} }
foreach($this->classReflection->getTraits() as $trait) { foreach($this->classReflection->getTraits() as $trait) {
$list = array_replace(static::fromClass($trait)->gatherUses(true), $list ?? []); $list = array_replace(static::fromClass($trait->name)->gatherUses(true), $list ?? []);
} }
} }
@ -71,17 +71,17 @@ class ObjectReflection {
} }
return array_merge_recursive($class ?? [], $traitTags ?? [], $interfaceTags ?? [], [ return array_merge_recursive($class ?? [], $traitTags ?? [], $interfaceTags ?? [], [
'tags' => $this->annotationReader->getClass($this->classReflection) 'tags' => $this->annotationReader->getClass($this->classReflection)
] + ( ! $full ? [] : [ ] + ( ! $full ? [] : [
'traits' => array_map($itemName, $traits), 'traits' => array_map($itemName, $traits),
'interfaces' => array_map($itemName, $interfaces), 'interfaces' => array_map($itemName, $interfaces),
] )); ] ));
} }
public function gatherProperties(bool $full = true, int $filter = public function gatherProperties(bool $full = true, int $filter =
ReflectionProperty::IS_PUBLIC | ReflectionProperty::IS_PUBLIC |
ReflectionProperty::IS_PROTECTED | ReflectionProperty::IS_PROTECTED |
ReflectionProperty::IS_PRIVATE ReflectionProperty::IS_PRIVATE
) : array ) : array
{ {
$defaultValues = $this->classReflection->getDefaultProperties(); $defaultValues = $this->classReflection->getDefaultProperties();
@ -106,6 +106,7 @@ class ObjectReflection {
if ( $property->hasType() ) { if ( $property->hasType() ) {
$current['type'] = $property->getType()->getName(); $current['type'] = $property->getType()->getName();
$current['builtin'] = $property->getType()->isBuiltIn();
$current['nullable'] = $property->getType()->allowsNull(); $current['nullable'] = $property->getType()->allowsNull();
} }
@ -122,10 +123,10 @@ class ObjectReflection {
} }
public function gatherMethods(bool $full = true, int $filter = public function gatherMethods(bool $full = true, int $filter =
ReflectionMethod::IS_PUBLIC | ReflectionMethod::IS_PUBLIC |
ReflectionMethod::IS_PROTECTED | ReflectionMethod::IS_PROTECTED |
ReflectionMethod::IS_PRIVATE | ReflectionMethod::IS_PRIVATE |
ReflectionMethod::IS_STATIC ReflectionMethod::IS_STATIC
) : array ) : array
{ {
$list = []; $list = [];
@ -148,8 +149,8 @@ class ObjectReflection {
'null' => $parameter->allowsNull(), 'null' => $parameter->allowsNull(),
'position' => $parameter->getPosition(), 'position' => $parameter->getPosition(),
'type' => $parameter->hasType() ? $parameter->getType()->getName() : false, 'type' => $parameter->hasType() ? $parameter->getType()->getName() : false,
'array' => $parameter->isArray(), 'array' => $this->isType('array', $parameter),
'callable' => $parameter->isCallable(), 'callable' => $this->isType('callable', $parameter),
'optional' => $parameter->isOptional(), 'optional' => $parameter->isOptional(),
'byReference' => $parameter->isPassedByReference(), 'byReference' => $parameter->isPassedByReference(),
]; ];
@ -188,6 +189,18 @@ class ObjectReflection {
return $code[$fileName] ?? $code[$fileName] = file_get_contents($fileName); return $code[$fileName] ?? $code[$fileName] = file_get_contents($fileName);
} }
# From https://www.php.net/manual/en/reflectionparameter.isarray.php
public static function isType(string $type, ReflectionParameter $reflectionParameter) : bool
{
if ( $reflectionType = $reflectionParameter->getType() ) {
$types = $reflectionType instanceof ReflectionUnionType ? $reflectionType->getTypes() : [$reflectionType];
return in_array($type, array_map(fn(ReflectionNamedType $t) => $t->getName(), $types));
}
return false;
}
protected function getUsesStatements() : array protected function getUsesStatements() : array
{ {
$uses = []; $uses = [];
@ -205,50 +218,52 @@ class ObjectReflection {
case T_INTERFACE: case T_INTERFACE:
break 2; break 2;
case T_USE: case T_USE:
$isUse = true; $isUse = true;
break; break;
case T_NS_SEPARATOR: case T_NS_SEPARATOR:
$isNamespace = $isUse; $isNamespace = $isUse;
break; break;
case T_NAME_QUALIFIED:
case T_STRING: case T_STRING:
if ( $isNamespace && $latestString ) { if ( $isNamespace && $latestString ) {
$statement[] = $latestString; $statement[] = $latestString;
} }
$latestString = $value; $latestString = $value;
break; break;
case T_AS: case T_AS:
# My\Name\Space\aClassHere `as` ClassAlias; # My\Name\Space\aClassHere `as` ClassAlias;
$replacedClass = implode("\\", array_merge($statement, [ $latestString ])); $replacedClass = implode("\\", array_merge($statement, [ $latestString ]));
$latestString = null; $latestString = null;
break; break;
case T_WHITESPACE: case T_WHITESPACE:
case T_COMMENT: case T_COMMENT:
case T_DOC_COMMENT: case T_DOC_COMMENT:
break; break;
case '{': case '{':
# opening a sub-namespace -> \My\Name\Space\`{`OneItem, AnotherItem} # opening a sub-namespace -> \My\Name\Space\`{`OneItem, AnotherItem}
if ( $isNamespace ) { if ( $isNamespace ) {
$inNamespace = true; $inNamespace = true;
} }
break; break;
case ';'; case ';';
case ',': case ',':
case '}': case '}':
if ( $isUse ) { if ( $isUse ) {
$clsName = ltrim(substr($latestString, strrpos($latestString, "\\") ), '\\');
if ( $replacedClass ) { if ( $replacedClass ) {
$uses[$replacedClass] = $latestString; $uses[$replacedClass] = $clsName;
$replacedClass = ""; $replacedClass = "";
} }
elseif ( $latestString ) { elseif ( $latestString ) {
$uses[implode("\\", array_merge($statement, [ $latestString ]))] = $latestString; $uses[implode("\\", array_merge($statement, [ $latestString ]))] = $clsName;
} }
} }
@ -268,9 +283,9 @@ class ObjectReflection {
$replacedClass = null; $replacedClass = null;
$isNamespace = $inNamespace = false; $isNamespace = $inNamespace = false;
$isUse = ( $isUse ?? false ) && ( $token === ',' ); $isUse = ( $isUse ?? false ) && ( $token === ',' );
break; break;
} }
} }
return $uses; return $uses;
} }