nette / php-generator

🐘 Generates neat PHP code for you. Supports new PHP 8.3 features.

Home Page:https://doc.nette.org/php-generator

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Automatically build nested attributes from object

Eydamos opened this issue · comments

If I'm not missing something in the documentation it is currently very cumbersome to have nested attributes as the nested attributes use the new keyword.
Therefore I would need to manually build a string like new SomeClassName('argument1', someOptionalParam: 'argument2') and then wrap it with Literal() to be able to generate nested attributes.
Instead it would be very helpful if the generator would recognise that there is an object as a parameter for the attribute and render it accordingly.

Example generator:

$file = new PhpFile();
$namespace = $file->addNamespace('App');
$class = $namespace->addClass('SomeEntity');

$tableAttributeParams = [
    'name'    => new Literal('self::TABLE_NAME'),
    'indexes' => [],
];

$index = new ORM\Index();
$index->name = new Literal('self::INDEX_STATUS');
$index->columns = [new Literal('self::COLUMN_STATUS')];
$tableAttributeParams['indexes'][] = $index;

$printer = new PsrPrinter();
echo $printer->printFile($file);

Expected result:

#[ORM\Table(
    name: self::TABLE_NAME,
    indexes: [
        new ORM\Index(columns: [self::COLUMN_STATUS], name: self::INDEX_STATUS)
    ]
)]
// ...

Actual result:

#[ORM\Table(
    name: self::TABLE_NAME,
    indexes: [
        \Nette\PhpGenerator\Dumper::createObject(\Doctrine\ORM\Mapping\Index::class, [
            'name' => self::INDEX_STATUS,
            'columns' => [self::COLUMN_STATUS],
            'fields' => null,
            'flags' => null,
            'options' => null,
        ]),
    ],
    uniqueConstraints: [],
    options: [],
)]
// ...

Agree with the problem, not so much with the proposed solution. You cannot revert __construct call, unless it uses promoted properties only.

What I think should work always is nesting Nette\PhpGenerator\Attribute objects, i.e.

$class->addAttribute(ORM\Table::class, [
    'name' => new Literal('self::TABLE_NAME'),
    'indexes' => [
        new Attribute(ORM\Index::class, [
            'columns' => [...],
        ]),
    ],
]);