From a4669d1610349ac1b204ed2e0ce3c029c78fafdc Mon Sep 17 00:00:00 2001 From: David Grudl Date: Tue, 29 Aug 2023 19:28:50 +0200 Subject: [PATCH] added Literal::new() [Closes #130] --- readme.md | 26 ++++++++++++++----- src/PhpGenerator/Literal.php | 9 +++++++ tests/PhpGenerator/ClassType.attributes.phpt | 7 ++++- tests/PhpGenerator/ClassType.promotion.phpt | 2 +- tests/PhpGenerator/Dumper.dump().phpt | 6 +++++ .../expected/ClassType.attributes.expect | 2 +- 6 files changed, 43 insertions(+), 9 deletions(-) diff --git a/readme.md b/readme.md index c3ea384d..22b20c43 100644 --- a/readme.md +++ b/readme.md @@ -582,6 +582,13 @@ new Literal('substr(?, ?)', [$a, $b]); // generates, for example: substr('hello', 5); ``` +The literal representing the creation of a new object is easily generated by the `new` method: + +```php +Literal::new(Demo::class, [$a, 'foo' => $b]); +// generates, for example: new Demo(10, foo: 20) +``` + Attributes ---------- @@ -590,10 +597,15 @@ You can add PHP 8 attributes to all classes, methods, properties, constants, enu ```php $class = new Nette\PhpGenerator\ClassType('Demo'); -$class->addAttribute('Deprecated'); +$class->addAttribute('Table', [ + 'name' => 'user', + 'constraints' => [ + Literal::new('UniqueConstraint', ['name' => 'ean', 'columns' => ['ean']]), + ], +]); $class->addProperty('list') - ->addAttribute('WithArguments', [1, 2]); + ->addAttribute('Deprecated'); $method = $class->addMethod('count') ->addAttribute('Foo\Cached', ['mode' => true]); @@ -607,16 +619,18 @@ echo $class; Result: ```php -#[Deprecated] +#[Table(name: 'user', constraints: [new UniqueConstraint(name: 'ean', columns: ['ean'])])] class Demo { - #[WithArguments(1, 2)] + #[Deprecated] public $list; #[Foo\Cached(mode: true)] - public function count(#[Bar] $items) - { + public function count( + #[Bar] + $items, + ) { } } ``` diff --git a/src/PhpGenerator/Literal.php b/src/PhpGenerator/Literal.php index 1d751680..d48f6a4e 100644 --- a/src/PhpGenerator/Literal.php +++ b/src/PhpGenerator/Literal.php @@ -15,6 +15,15 @@ */ class Literal { + /** + * Creates a literal representing the creation of an object using the new operator. + */ + public static function new(string $class, array $args = []): self + { + return new self('new ' . $class . '(...?:)', [$args]); + } + + public function __construct( private string $value, /** @var ?mixed[] */ diff --git a/tests/PhpGenerator/ClassType.attributes.phpt b/tests/PhpGenerator/ClassType.attributes.phpt index b6ea2a00..8ec05719 100644 --- a/tests/PhpGenerator/ClassType.attributes.phpt +++ b/tests/PhpGenerator/ClassType.attributes.phpt @@ -18,7 +18,12 @@ $class ->addComment('Description of class.') ->addAttribute('ExampleAttribute') ->addAttribute('WithArgument', [new Literal('Foo::BAR')]) - ->addAttribute('NamedArguments', ['foo' => 'bar', 'bar' => [1, 2, 3]]); + ->addAttribute('Table', [ + 'name' => 'user', + 'constraints' => [ + Literal::new('UniqueConstraint', ['name' => 'ean', 'columns' => ['ean']]), + ], + ]); $class->addConstant('FOO', 123) ->addComment('Commented') diff --git a/tests/PhpGenerator/ClassType.promotion.phpt b/tests/PhpGenerator/ClassType.promotion.phpt index ba4944ee..06649810 100644 --- a/tests/PhpGenerator/ClassType.promotion.phpt +++ b/tests/PhpGenerator/ClassType.promotion.phpt @@ -18,7 +18,7 @@ $method->addPromotedParameter('c') ->addComment('promo') ->addAttribute('Example'); -$method->addPromotedParameter('d', new Literal('new Draft(?)', [10])) +$method->addPromotedParameter('d', Literal::new('Draft', [10])) ->setType('Draft') ->setReadOnly(); diff --git a/tests/PhpGenerator/Dumper.dump().phpt b/tests/PhpGenerator/Dumper.dump().phpt index 6fb4467c..29115522 100644 --- a/tests/PhpGenerator/Dumper.dump().phpt +++ b/tests/PhpGenerator/Dumper.dump().phpt @@ -51,6 +51,12 @@ Assert::same("[strlen('hello')]", $dumper->dump([new Literal('strlen(?)', ['hell Assert::same("a\nb", $dumper->dump(new Literal("a\r\nb"))); +// Literal::new +Assert::same('new stdClass()', $dumper->dump(Literal::new('stdClass'))); +Assert::same('new stdClass(10, 20)', $dumper->dump(Literal::new('stdClass', [10, 20]))); +Assert::same('new stdClass(10, c: 20)', $dumper->dump(Literal::new('stdClass', [10, 'c' => 20]))); + + // arrays Assert::same('[]', $dumper->dump([])); Assert::same('[1, 2, 3]', $dumper->dump([1, 2, 3])); diff --git a/tests/PhpGenerator/expected/ClassType.attributes.expect b/tests/PhpGenerator/expected/ClassType.attributes.expect index 46ee3389..f9125620 100644 --- a/tests/PhpGenerator/expected/ClassType.attributes.expect +++ b/tests/PhpGenerator/expected/ClassType.attributes.expect @@ -3,7 +3,7 @@ */ #[ExampleAttribute] #[WithArgument(Foo::BAR)] -#[NamedArguments(foo: 'bar', bar: [1, 2, 3])] +#[Table(name: 'user', constraints: [new UniqueConstraint(name: 'ean', columns: ['ean'])])] class Example { /** Commented */