diff --git a/README.md b/README.md index 0d0071a..765fe26 100644 --- a/README.md +++ b/README.md @@ -105,6 +105,8 @@ echo $generator->dumpFile([ '', $generator->dumpAttribute('Example\Attributes\Something'), + $generator->dumpAttribute('Example\Attributes\Single', ['value: "Hello, World!"']), + $generator->dumpAttribute('Example\Attributes\Multiple', ['value: "Hello, World!"', 'other: "Other value"']), sprintf( 'final readonly class %s extends %s', $generator->import('Example\Demo'), @@ -140,6 +142,8 @@ declare(strict_types=1); namespace Example\Demo; use DateTimeImmutable; +use Example\Attributes\Multiple; +use Example\Attributes\Single; use Example\Attributes\Something; use Example\Demo; use Example\Parent; @@ -147,6 +151,11 @@ use Example\Parent; // Auto-generated example file #[Something] +#[Single(value: "Hello, World!")] +#[Multiple( + value: "Hello, World!", + other: "Other value", +)] final readonly class Demo extends Parent { public function __construct( @@ -183,8 +192,8 @@ echo $generator->dumpFile(function () use ($generator) { yield ''; // Class with attributes - yield $generator->dumpAttribute('Example\Attributes\Entity'); - yield $generator->dumpAttribute('Example\Attributes\Table'); + yield from $generator->dumpAttribute('Example\Attributes\Entity'); + yield from $generator->dumpAttribute('Example\Attributes\Table'); yield sprintf( 'final class DemoClass extends %s implements %s, %s', $generator->import('Example\BaseClass'), diff --git a/examples/class.php b/examples/class.php index 97c0bdc..0232b55 100644 --- a/examples/class.php +++ b/examples/class.php @@ -13,6 +13,8 @@ '', $generator->dumpAttribute('Example\Attributes\Something'), + $generator->dumpAttribute('Example\Attributes\Single', ['value: "Hello, World!"']), + $generator->dumpAttribute('Example\Attributes\Multiple', ['value: "Hello, World!"', 'other: "Other value"']), sprintf( 'final readonly class %s extends %s', $generator->import('Example\Demo'), diff --git a/examples/example.php b/examples/example.php index bb3a378..d285b69 100644 --- a/examples/example.php +++ b/examples/example.php @@ -17,8 +17,8 @@ yield ''; // Class with attributes - yield $generator->dumpAttribute('Example\Attributes\Entity'); - yield $generator->dumpAttribute('Example\Attributes\Table'); + yield from $generator->dumpAttribute('Example\Attributes\Entity'); + yield from $generator->dumpAttribute('Example\Attributes\Table'); yield sprintf( 'final class DemoClass extends %s implements %s, %s', $generator->import('Example\BaseClass'), diff --git a/src/CodeGenerator.php b/src/CodeGenerator.php index b0b3b6a..e5473e6 100644 --- a/src/CodeGenerator.php +++ b/src/CodeGenerator.php @@ -255,10 +255,26 @@ public function importByParent(Importable | string $name) : string /** * Generates a PHP attribute string for the given fully qualified class name + * + * @param CodeLines $args + * @return Generator */ - public function dumpAttribute(FullyQualified | string $fqcn) : string - { - return sprintf('#[%s]', $this->import($fqcn)); + public function dumpAttribute( + FullyQualified | string $fqcn, + array | Closure | Generator | string $args = [], + bool $addCommaAfterEachArgument = true, + ) : Generator { + $args = self::resolveIterable($args); + + if ($args === []) { + yield sprintf('#[%s]', $this->import($fqcn)); + } elseif (count($args) === 1) { + yield from $this->wrap(sprintf('#[%s(', $this->import($fqcn)), $args, ')]'); + } else { + yield sprintf('#[%s(', $this->import($fqcn)); + yield Group::indent($addCommaAfterEachArgument ? $this->allSuffix(',', $args) : $args); + yield ')]'; + } } /** diff --git a/tests/CodeGeneratorTest.php b/tests/CodeGeneratorTest.php index f43454d..a527e3d 100644 --- a/tests/CodeGeneratorTest.php +++ b/tests/CodeGeneratorTest.php @@ -414,10 +414,23 @@ public function testImportByParentWithDeepSubNamespace() : void public function testDumpAttribute() : void { - self::assertSame( + $this->assertDump( '#[Required]', $this->generator->dumpAttribute('App\\Attributes\\Required'), ); + $this->assertDump( + '#[Required(true)]', + $this->generator->dumpAttribute('App\\Attributes\\Required', ['true']), + ); + $this->assertDump( + <<<'PHP' + #[Required( + true, + false, + )] + PHP, + $this->generator->dumpAttribute('App\\Attributes\\Required', ['true', 'false']), + ); } public function testDumpClassReference() : void