From 1677fc37aa37d738a0bac854f7c2eebd013d25cb Mon Sep 17 00:00:00 2001 From: circle33 Date: Wed, 25 Dec 2024 02:29:15 +0000 Subject: [PATCH 1/8] Trigger Action From b357187aaf73ca02a186f3966a34070a26d778b3 Mon Sep 17 00:00:00 2001 From: circle33 Date: Wed, 25 Dec 2024 02:34:39 +0000 Subject: [PATCH 2/8] trigger action --- phpstan.neon.dist | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/phpstan.neon.dist b/phpstan.neon.dist index a91cc695a..508afc1aa 100644 --- a/phpstan.neon.dist +++ b/phpstan.neon.dist @@ -1,6 +1,6 @@ includes: - phpstan-baseline.neon - + parameters: level: 5 paths: From 376ac25ee28dd5969c70c27abcfce9bdc61cebeb Mon Sep 17 00:00:00 2001 From: circle33 Date: Wed, 25 Dec 2024 03:04:27 +0000 Subject: [PATCH 3/8] fix phpstan issue --- phpstan-baseline.neon | 2 +- phpstan.neon.dist | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/phpstan-baseline.neon b/phpstan-baseline.neon index 32fc4f3e6..22a10b390 100644 --- a/phpstan-baseline.neon +++ b/phpstan-baseline.neon @@ -121,7 +121,7 @@ parameters: path: src/Support/DataConfig.php - - message: "#^Call to method Illuminate\\\\Support\\\\Collection\\<\\(int\\|string\\),string\\|null\\>\\:\\:isEmpty\\(\\) will always evaluate to false\\.$#" + message: "#^Call to method Illuminate\\\\Support\\\\Collection\\<\\(string\\|int\\),null\\|string\\>\\:\\:isEmpty\\(\\) will always evaluate to false\\.$#" count: 1 path: src/Support/Validation/RuleDenormalizer.php diff --git a/phpstan.neon.dist b/phpstan.neon.dist index 508afc1aa..a91cc695a 100644 --- a/phpstan.neon.dist +++ b/phpstan.neon.dist @@ -1,6 +1,6 @@ includes: - phpstan-baseline.neon - + parameters: level: 5 paths: From 1d18d77334054dad9c8655958e2acad7ce5125d1 Mon Sep 17 00:00:00 2001 From: circle33 Date: Wed, 25 Dec 2024 03:07:39 +0000 Subject: [PATCH 4/8] fix phpstan issue --- phpstan-baseline.neon | 5 ----- 1 file changed, 5 deletions(-) diff --git a/phpstan-baseline.neon b/phpstan-baseline.neon index 22a10b390..c83f5b75e 100644 --- a/phpstan-baseline.neon +++ b/phpstan-baseline.neon @@ -120,11 +120,6 @@ parameters: count: 1 path: src/Support/DataConfig.php - - - message: "#^Call to method Illuminate\\\\Support\\\\Collection\\<\\(string\\|int\\),null\\|string\\>\\:\\:isEmpty\\(\\) will always evaluate to false\\.$#" - count: 1 - path: src/Support/Validation/RuleDenormalizer.php - - message: "#^Call to an undefined method DateTimeInterface\\:\\:setTimezone\\(\\)\\.$#" count: 1 From a75f72ea3a435c83ab678cef3ba86427a251f13f Mon Sep 17 00:00:00 2001 From: circle33 Date: Wed, 25 Dec 2024 03:14:20 +0000 Subject: [PATCH 5/8] fix phpstan issue --- phpstan.neon.dist | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/phpstan.neon.dist b/phpstan.neon.dist index a91cc695a..508afc1aa 100644 --- a/phpstan.neon.dist +++ b/phpstan.neon.dist @@ -1,6 +1,6 @@ includes: - phpstan-baseline.neon - + parameters: level: 5 paths: From 2ab105894874bf53586c9f8b20ca4008da8085f3 Mon Sep 17 00:00:00 2001 From: circle33 Date: Wed, 25 Dec 2024 03:18:34 +0000 Subject: [PATCH 6/8] fix github action issue --- phpstan.neon.dist | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/phpstan.neon.dist b/phpstan.neon.dist index 508afc1aa..a91cc695a 100644 --- a/phpstan.neon.dist +++ b/phpstan.neon.dist @@ -1,6 +1,6 @@ includes: - phpstan-baseline.neon - + parameters: level: 5 paths: From 64fad4c883f0daacf04fa479ca6ea6cd19b5987e Mon Sep 17 00:00:00 2001 From: circle33 Date: Thu, 26 Dec 2024 03:09:29 +0000 Subject: [PATCH 7/8] Update to be compatible with phpdocumentor/reflection-docblock 5.6.1 --- .../Annotations/CollectionAnnotationReader.php | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/src/Support/Annotations/CollectionAnnotationReader.php b/src/Support/Annotations/CollectionAnnotationReader.php index 9187c3855..930c374fa 100644 --- a/src/Support/Annotations/CollectionAnnotationReader.php +++ b/src/Support/Annotations/CollectionAnnotationReader.php @@ -4,7 +4,7 @@ use Iterator; use IteratorAggregate; -use phpDocumentor\Reflection\DocBlock\Tags\Generic; +use phpDocumentor\Reflection\DocBlock\Tag; use phpDocumentor\Reflection\DocBlockFactory; use phpDocumentor\Reflection\TypeResolver; use phpDocumentor\Reflection\Types\Context; @@ -100,12 +100,12 @@ protected function getCollectionReturnType(ReflectionClass $class): ?array $valueType = null; foreach ($docBlock->getTags() as $tag) { - if (! $tag instanceof Generic) { + if (! $tag instanceof Tag) { continue; } if ($tag->getName() === 'template') { - $description = $tag->getDescription(); + $description = (string)$tag; if (preg_match('/^(\w+)\s+of\s+([^\s]+)/', $description, $matches)) { $templateTypes[$matches[1]] = $this->resolve($matches[2]); @@ -115,15 +115,15 @@ protected function getCollectionReturnType(ReflectionClass $class): ?array } if ($tag->getName() === 'extends') { - $description = $tag->getDescription(); + $description = (string)$tag; if (preg_match('/<\s*([^,\s]+)?\s*(?:,\s*([^>\s]+))?\s*>/', $description, $matches)) { if (count($matches) === 3) { - $keyType = $templateTypes[$matches[1]] ?? $this->resolve($matches[1]); - $valueType = $templateTypes[$matches[2]] ?? $this->resolve($matches[2]); + $keyType = $templateTypes[class_basename($matches[1])] ?? $this->resolve($matches[1]); + $valueType = $templateTypes[class_basename($matches[2])] ?? $this->resolve($matches[2]); } else { $keyType = null; - $valueType = $templateTypes[$matches[1]] ?? $this->resolve($matches[1]); + $valueType = $templateTypes[class_basename($matches[1])] ?? $this->resolve($matches[1]); } $keyType = $keyType ? explode('|', $keyType)[0] : null; From 83380df8c5ff92182a426e28c32c061e57799092 Mon Sep 17 00:00:00 2001 From: circle33 Date: Thu, 26 Dec 2024 04:18:06 +0000 Subject: [PATCH 8/8] refactor: improving readability --- .../CollectionAnnotationReader.php | 71 +++++++++++-------- 1 file changed, 42 insertions(+), 29 deletions(-) diff --git a/src/Support/Annotations/CollectionAnnotationReader.php b/src/Support/Annotations/CollectionAnnotationReader.php index 930c374fa..835000481 100644 --- a/src/Support/Annotations/CollectionAnnotationReader.php +++ b/src/Support/Annotations/CollectionAnnotationReader.php @@ -84,9 +84,7 @@ protected function isIterable(ReflectionClass $class): bool protected function getCollectionReturnType(ReflectionClass $class): ?array { $docBlockFactory = DocBlockFactory::createInstance(); - $this->context = $this->contextResolver->execute($class); - $docComment = $class->getDocComment(); if ($docComment === false) { @@ -96,50 +94,65 @@ protected function getCollectionReturnType(ReflectionClass $class): ?array $docBlock = $docBlockFactory->create($docComment, $this->context); $templateTypes = []; - $keyType = null; - $valueType = null; foreach ($docBlock->getTags() as $tag) { if (! $tag instanceof Tag) { continue; } - if ($tag->getName() === 'template') { - $description = (string)$tag; + $tagName = $tag->getName(); + $description = (string) $tag; - if (preg_match('/^(\w+)\s+of\s+([^\s]+)/', $description, $matches)) { - $templateTypes[$matches[1]] = $this->resolve($matches[2]); - } + if ($tagName === 'template') { + $this->processTemplateTag($description, $templateTypes); continue; } - if ($tag->getName() === 'extends') { - $description = (string)$tag; - - if (preg_match('/<\s*([^,\s]+)?\s*(?:,\s*([^>\s]+))?\s*>/', $description, $matches)) { - if (count($matches) === 3) { - $keyType = $templateTypes[class_basename($matches[1])] ?? $this->resolve($matches[1]); - $valueType = $templateTypes[class_basename($matches[2])] ?? $this->resolve($matches[2]); - } else { - $keyType = null; - $valueType = $templateTypes[class_basename($matches[1])] ?? $this->resolve($matches[1]); - } - - $keyType = $keyType ? explode('|', $keyType)[0] : null; - $valueType = explode('|', $valueType)[0]; - - return [ - 'keyType' => $keyType, - 'valueType' => $valueType, - ]; - } + if ($tagName === 'extends') { + return $this->processExtendsTag($description, $templateTypes); } } return null; } + private function processTemplateTag(string $description, array &$templateTypes): void + { + // The pattern matches strings like "T of SomeType", capturing "T" as the template name + // and "SomeType" as the type associated with the template. + if (preg_match('/^(\w+)\s+of\s+([^\s]+)/', $description, $matches)) { + $templateTypes[$matches[1]] = $this->resolve($matches[2]); + } + } + + private function processExtendsTag(string $description, array $templateTypes): ?array + { + // The pattern matches strings like "" or "", + // capturing "KeyType" and "ValueType" or just "ValueType" if no key type is specified. + if (preg_match('/<\s*([^,\s]+)?\s*(?:,\s*([^>\s]+))?\s*>/', $description, $matches)) { + $keyType = null; + $valueType = null; + + if (count($matches) === 3) { + $keyType = $templateTypes[class_basename($matches[1])] ?? $this->resolve($matches[1]); + $valueType = $templateTypes[class_basename($matches[2])] ?? $this->resolve($matches[2]); + } else { + $valueType = $templateTypes[class_basename($matches[1])] ?? $this->resolve($matches[1]); + } + + $keyType = $keyType ? explode('|', $keyType)[0] : null; + $valueType = explode('|', $valueType)[0]; + + return [ + 'keyType' => $keyType, + 'valueType' => $valueType, + ]; + } + + return null; + } + protected function resolve(string $type): ?string { $type = (string) $this->typeResolver->resolve($type, $this->context);