zend-code icon indicating copy to clipboard operation
zend-code copied to clipboard

Adding parameters of type that exists in "use" statements

Open postalservice14 opened this issue 9 years ago • 11 comments

Unless I'm missing something, there is no way to add a type-hinted parameter to a method that does not use the fully-qualified name (as it exists as a use statement).

e.g. (See SomeClass type-hint in method)


use Foo\Bar\SomeClass;

class GeneratedClass
{
    public function generatedMethod(SomeClass $instance) {
    }
}

If you don't supply a fully-qualified name, it looks like:


use Foo\Bar\SomeClass;

class GeneratedClass
{
    public function generatedMethod(\SomeClass $instance) {
    }
}

postalservice14 avatar Jan 25 '16 15:01 postalservice14

@postalservice14 this is intentional, as a MethodGenerator is unaware of the context it is being generated in.

Basically, generated code is typically not nice, but at least working correctly.

Ocramius avatar Jan 25 '16 15:01 Ocramius

@Ocramius yeah, I guess I was just trying to get it to generate "nice" code.

I suppose this might be a fundamental shift, but it would be nice if there was a way to force it. Let the code doing the generation take on the responsibility of knowing the context.

postalservice14 avatar Jan 25 '16 15:01 postalservice14

If I were to create a PR that allowed something like this (would that be okay?):

see forceGlobal option

$method = MethodGenerator::fromArray(array(
    'name' => 'someMethod',
    'parameters' => array(array('name' => 'reader', 'type' => 'FileReader', 'forceGlobal' => false))
));

postalservice14 avatar Jan 25 '16 15:01 postalservice14

@postalservice14 I tried working around it many times, and every time it leads to circular dependencies (ClassGenerator<->FileGenerator<->MethodGenerator loops) that are just hellish to test and keep BC compliant. The benefits are not worth it, compared to the additional complexity...

Ocramius avatar Jan 25 '16 15:01 Ocramius

Ah, I see what you mean... could work, but requires a lot of internal rework.

Ocramius avatar Jan 25 '16 15:01 Ocramius

Hello, @Ocramius I don't know if it's suitable, but I have made some little changes to allow to use alias in parameters.

The main goal was to keep the current behavior but allow to override it if necessary. You can found all the code on my fork. https://github.com/vonglasow/zend-code/tree/type-alias

@postalservice14 You can use it like this.

<?php
require_once 'vendor/autoload.php';

use Zend\Code\Generator\ClassGenerator;
use Zend\Code\Generator\DocBlockGenerator;
use Zend\Code\Generator\FileGenerator;
use Zend\Code\Generator\DocBlock\Tag;
use Zend\Code\Generator\MethodGenerator;

$foo = new ClassGenerator('foo', 'bar', null, null, ['FactoryInterface']);
$foo
    ->addUse('Zend\ServiceManager\FactoryInterface')
    ->addUse('Zend\ServiceManager\ServiceLocatorInterface')
    ->addMethods(array(
        MethodGenerator::fromArray(
            [
                'name' => 'createService',
                'parameters' => [
                    [
                        /**
                         * You can use this syntax or the second one.
                         */
                        'type' => ['name' =>'ServiceLocatorInterface', 'alias' => true],
                        //'type' => 'ServiceLocatorInterface',
                        'name' => 'serviceLocator',
                    ]
                ],
                'body' => 'return $this;',
                'docblock'   => DocBlockGenerator::fromArray([
                    'shortDescription' => 'Factory to create service ',
                    'longDescription'  => null,
                    'tags'             => [
                        new Tag\ParamTag('bar', 'string'),
                    ],
                ]),
            ]
        ),
    ));

echo FileGenerator::fromArray(['classes'  => [$foo]])->generate();

vonglasow avatar Feb 01 '16 12:02 vonglasow

@vonglasow please send a PR with that branch, so it can eventually be reviewed.

I would rather suggest passing in a type object, instead of an array with some sort of key/value pre-defined structure (hard to debug when things go wrong).

Ocramius avatar Feb 01 '16 19:02 Ocramius

@Ocramius PR is done see https://github.com/zendframework/zend-code/pull/40 feel free to make any feedback

vonglasow avatar Feb 01 '16 19:02 vonglasow

@vonglasow thanks!

Ocramius avatar Feb 01 '16 20:02 Ocramius

:+1: to this feature request. I've been trying for the last hour to find how to remove the fully qualified classname from type hints, should have checked here first :)

josephmcdermott avatar Feb 15 '16 21:02 josephmcdermott

This repository has been closed and moved to laminas/laminas-code; a new issue has been opened at https://github.com/laminas/laminas-code/issues/30.

weierophinney avatar Dec 31 '19 21:12 weierophinney