From 7f1328fc65d9de3cdcae0474cd2720c6746e7e54 Mon Sep 17 00:00:00 2001 From: Akihito Koriyama Date: Fri, 15 Nov 2024 21:56:11 +0900 Subject: [PATCH] Add support for PHP 8 attributes in method signatures Enhanced MethodSignatureString to include attribute handling if PHP version is 8 or higher. Additional fake attributes and test cases were introduced to validate the new functionality. --- src/MethodSignatureString.php | 28 +++++++++++++++++++++++++++- tests/AopCodeTest.php | 3 ++- tests/Fake/Attribute/FakeAttr1.php | 7 +++++++ tests/Fake/Attribute/FakeAttr2.php | 7 +++++++ tests/Fake/FakePhp8Types.php | 9 +++++++++ 5 files changed, 52 insertions(+), 2 deletions(-) create mode 100644 tests/Fake/Attribute/FakeAttr1.php create mode 100644 tests/Fake/Attribute/FakeAttr2.php diff --git a/src/MethodSignatureString.php b/src/MethodSignatureString.php index 26536583..799bb2ca 100644 --- a/src/MethodSignatureString.php +++ b/src/MethodSignatureString.php @@ -139,6 +139,12 @@ private function formatArg($name, $value): string private function generateParameterCode(ReflectionParameter $param): string { + // Support attributes + $attributesStr = ''; + if (PHP_MAJOR_VERSION >= 8) { + $attributesStr = $this->getAttributeStr($param); + } + $typeStr = ($this->typeString)($param->getType()); $typeStrWithSpace = $typeStr ? $typeStr . ' ' : $typeStr; $variadicStr = $param->isVariadic() ? '...' : ''; @@ -149,6 +155,26 @@ private function generateParameterCode(ReflectionParameter $param): string $defaultStr = ' = ' . str_replace(["\r", "\n"], '', $default); } - return "{$typeStrWithSpace}{$referenceStr}{$variadicStr}\${$param->getName()}{$defaultStr}"; + return "{$attributesStr}{$typeStrWithSpace}{$referenceStr}{$variadicStr}\${$param->getName()}{$defaultStr}"; + } + + public function getAttributeStr(ReflectionParameter $param): string + { + if (PHP_MAJOR_VERSION < 8) { + return ''; + } + + $attributesStr = ''; + $attributes = $param->getAttributes(); + if (! empty($attributes)) { + $attributeStrings = []; + foreach ($attributes as $attribute) { + $attributeStrings[] = sprintf('#[%s]', $attribute->getName()); + } + + $attributesStr = implode(' ', $attributeStrings) . ' '; + } + + return $attributesStr; } } diff --git a/tests/AopCodeTest.php b/tests/AopCodeTest.php index afcf7ff0..132a60dd 100644 --- a/tests/AopCodeTest.php +++ b/tests/AopCodeTest.php @@ -49,7 +49,7 @@ public function testReturnType(): void public function testVariousMethodSignature(): void { $bind = new Bind(); - for ($i = 1; $i <= 24; $i++) { + for ($i = 1; $i <= 25; $i++) { $bind->bindInterceptors('method' . (string) $i, []); } @@ -91,6 +91,7 @@ public function method22()', $code); public function method23()', $code); $this->assertStringContainsString('#[\\Ray\\Aop\\Annotation\\FakeMarker6(fruit1: \\Ray\\Aop\\FakePhp81Enum::Apple, fruit2: \\Ray\\Aop\\FakePhp81Enum::Orange)] public function method24()', $code); + $this->assertStringContainsString('public function method25(#[Ray\Aop\Attribute\FakeAttr1] $a, #[Ray\Aop\FakeAttri1] #[Ray\Aop\FakeAttr2] $b): void', $code); } /** @requires PHP 8.2 */ diff --git a/tests/Fake/Attribute/FakeAttr1.php b/tests/Fake/Attribute/FakeAttr1.php new file mode 100644 index 00000000..7602a56b --- /dev/null +++ b/tests/Fake/Attribute/FakeAttr1.php @@ -0,0 +1,7 @@ +