From 2a45abae273f5c5bde212a62a3fa048d0bf492f7 Mon Sep 17 00:00:00 2001 From: Dave Mc Nicoll Date: Mon, 18 Jul 2022 16:19:20 +0000 Subject: [PATCH] - Fixed a bug caused by a new T_NAME_QUALIFIED constant --- src/ObjectReflection.php | 69 ++++++++++++++++++++++++---------------- 1 file changed, 42 insertions(+), 27 deletions(-) diff --git a/src/ObjectReflection.php b/src/ObjectReflection.php index 53b2f7d..eb4c94f 100644 --- a/src/ObjectReflection.php +++ b/src/ObjectReflection.php @@ -2,7 +2,7 @@ namespace Notes; -use Reflector, ReflectionClass, ReflectionProperty, ReflectionMethod; +use Reflector, ReflectionClass, ReflectionProperty, ReflectionMethod, ReflectionUnionType, ReflectionNamedType, ReflectionParameter; class ObjectReflection { @@ -39,7 +39,7 @@ class ObjectReflection { } 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 ?? [], [ - 'tags' => $this->annotationReader->getClass($this->classReflection) - ] + ( ! $full ? [] : [ - 'traits' => array_map($itemName, $traits), - 'interfaces' => array_map($itemName, $interfaces), - ] )); + 'tags' => $this->annotationReader->getClass($this->classReflection) + ] + ( ! $full ? [] : [ + 'traits' => array_map($itemName, $traits), + 'interfaces' => array_map($itemName, $interfaces), + ] )); } public function gatherProperties(bool $full = true, int $filter = - ReflectionProperty::IS_PUBLIC | - ReflectionProperty::IS_PROTECTED | - ReflectionProperty::IS_PRIVATE + ReflectionProperty::IS_PUBLIC | + ReflectionProperty::IS_PROTECTED | + ReflectionProperty::IS_PRIVATE ) : array { $defaultValues = $this->classReflection->getDefaultProperties(); @@ -106,6 +106,7 @@ class ObjectReflection { if ( $property->hasType() ) { $current['type'] = $property->getType()->getName(); + $current['builtin'] = $property->getType()->isBuiltIn(); $current['nullable'] = $property->getType()->allowsNull(); } @@ -122,10 +123,10 @@ class ObjectReflection { } public function gatherMethods(bool $full = true, int $filter = - ReflectionMethod::IS_PUBLIC | - ReflectionMethod::IS_PROTECTED | - ReflectionMethod::IS_PRIVATE | - ReflectionMethod::IS_STATIC + ReflectionMethod::IS_PUBLIC | + ReflectionMethod::IS_PROTECTED | + ReflectionMethod::IS_PRIVATE | + ReflectionMethod::IS_STATIC ) : array { $list = []; @@ -148,8 +149,8 @@ class ObjectReflection { 'null' => $parameter->allowsNull(), 'position' => $parameter->getPosition(), 'type' => $parameter->hasType() ? $parameter->getType()->getName() : false, - 'array' => $parameter->isArray(), - 'callable' => $parameter->isCallable(), + 'array' => $this->isType('array', $parameter), + 'callable' => $this->isType('callable', $parameter), 'optional' => $parameter->isOptional(), 'byReference' => $parameter->isPassedByReference(), ]; @@ -188,6 +189,18 @@ class ObjectReflection { 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 { $uses = []; @@ -205,50 +218,52 @@ class ObjectReflection { case T_INTERFACE: break 2; - case T_USE: + case T_USE: $isUse = true; - break; + break; case T_NS_SEPARATOR: $isNamespace = $isUse; - break; + break; + case T_NAME_QUALIFIED: case T_STRING: if ( $isNamespace && $latestString ) { $statement[] = $latestString; } $latestString = $value; - break; + break; case T_AS: # My\Name\Space\aClassHere `as` ClassAlias; $replacedClass = implode("\\", array_merge($statement, [ $latestString ])); $latestString = null; - break; + break; case T_WHITESPACE: case T_COMMENT: case T_DOC_COMMENT: - break; + break; case '{': # opening a sub-namespace -> \My\Name\Space\`{`OneItem, AnotherItem} if ( $isNamespace ) { $inNamespace = true; } - break; + break; case ';'; case ',': case '}': if ( $isUse ) { + $clsName = ltrim(substr($latestString, strrpos($latestString, "\\") ), '\\'); if ( $replacedClass ) { - $uses[$replacedClass] = $latestString; + $uses[$replacedClass] = $clsName; $replacedClass = ""; } elseif ( $latestString ) { - $uses[implode("\\", array_merge($statement, [ $latestString ]))] = $latestString; + $uses[implode("\\", array_merge($statement, [ $latestString ]))] = $clsName; } } @@ -268,9 +283,9 @@ class ObjectReflection { $replacedClass = null; $isNamespace = $inNamespace = false; $isUse = ( $isUse ?? false ) && ( $token === ',' ); - break; + break; } - } + } return $uses; }