php-ide-serenata icon indicating copy to clipboard operation
php-ide-serenata copied to clipboard

Constructor injection autocompletion

Open Gert-dev opened this issue 7 years ago • 2 comments

Originally posted by @cabloo.

Original issue (copied below). I have recently been made aware of the Generate Constructor feature of this package, which is on the right track for what I'm looking for, but not quite as easy.

I have yet to find an Atom package for this, and it may be out of the scope of this package (i.e. should be added to another php-integrator package), but I was really hoping for a package that would automate Service Injection as much as possible for me.

For those unfamiliar, almost every start of a class in my project looks something like this:

class TargetFinder
{
    /**
     * @var FormatService
     */
    protected $format;

    /**
     * @var RtgRouterRepository
     */
    protected $routers;

    /**
     * @var RtgInterfaceRepository
     */
    protected $targets;

    public function __construct(
        FormatService $format,
        RtgRouterRepository $routers,
        RtgInterfaceRepository $targets
    ) {
        $this->format = $format;
        $this->routers = $routers;
        $this->targets = $targets;
    }

    // Implementation...
}

Laravel detects and injects (resolves an instance of and passes as an argument) each of those variables required by the constructor. I find myself typing most of that out, which is quite inefficient. I have snippets for the doc blocks and usually use multi-copy-paste but that still is not quick enough for me.

I think ideal functionality for me would be a command I run that asks for the name of the variable and the class name (auto-completed), but another thing that could work is when typing in a function I could ctrl-shift-click (or similar) on a class variable that does not exist yet and it would request a class name to auto inject for it. For instance, if I were in the above class, and I decided I needed a Cache implementation, I could type

function find($id)
{
    return $this->cache->get('targets.'.$id, function () use ($id) {
        // resolve from database
    });
}

And since cache isn't a class variable I could trigger a special click on it that asks what class and adds it above, i.e. if I typed Cache it would use the right Cache and then add it to the constructor and add the protected variable with a doc block. Since this would only occur if $this->cache was not found as a variable, maybe it would be the same command as the php-integrator-navigator package (ctrl-alt-click), since navigator would essentially be saying "I don't know where this variable is, do you want to inject one?"

This is a Sublime command which seems to do something similar to what I'm trying to achieve above:

https://github.com/erichard/SublimePHPCompanion/blob/master/php_companion/commands/insert_php_constructor_property.py

Gert-dev avatar May 04 '18 19:05 Gert-dev

Screenshot of the replies, just for reference and because I'm too lazy to copy-paste all the text:

replies

Gert-dev avatar May 04 '18 19:05 Gert-dev

netbeans has something similar called 'fix uses'. You type hint your methods (works within method bodies too) hit ctrl+u, then it will resolve each class short name to it's FQCN. It pops up a dialogue allowing users to select the correct namespace for each class. It was a great feature which I miss.

Extending it to create class properties would indeed be a massive time saver.

twifty avatar May 05 '18 00:05 twifty