Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Introduce syntax to autocomplete from docblock? #215

Open
dereuromark opened this issue Feb 26, 2024 · 4 comments
Open

Introduce syntax to autocomplete from docblock? #215

dereuromark opened this issue Feb 26, 2024 · 4 comments

Comments

@dereuromark
Copy link

Refs dereuromark/cakephp-ide-helper#346

Would be nice if we could use some kind of option keys list in the docblock to document all possible
array keys for assoc arrays.

So when someone types

    $this->hasMany('ADmad/SocialAuth.SocialProfiles', [
        'f
    ]);

it would autocomplete the foreignKey option right away.

Or are there other ways of accomplishing this?

The method and its docblock currently reads as

    /**
     * The options array accept the following keys:
     *
     * - className: The class name of the target table object
     * - targetTable: An instance of a table object to be used as the target table
     * - foreignKey: The name of the field to use as foreign key, if false none
     *   will be used
     * - dependent: Set to true if you want CakePHP to cascade deletes to the
     *   associated table when an entity is removed on this table. The delete operation
     *   on the associated table will not cascade further. To get recursive cascades enable
     *   `cascadeCallbacks` as well. Set to false if you don't want CakePHP to remove
     *   associated data, or when you are using database constraints.
     * - cascadeCallbacks: Set to true if you want CakePHP to fire callbacks on
     *   cascaded deletes. If false the ORM will use deleteAll() to remove data.
     *   When true records will be loaded and then deleted.
     * - conditions: array with a list of conditions to filter the join with
     * - sort: The order in which results for this association should be returned
     * - saveStrategy: Either 'append' or 'replace'. When 'append' the current records
     *   are appended to any records in the database. When 'replace' associated records
     *   not in the current set will be removed. If the foreign key is a null able column
     *   or if `dependent` is true records will be orphaned.
     * - strategy: The strategy to be used for selecting results Either 'select'
     *   or 'subquery'. If subquery is selected the query used to return results
     *   in the source table will be used as conditions for getting rows in the
     *   target table.
     * - finder: The finder method to use when loading records from this association.
     *   Defaults to 'all'.
     *
     * This method will return the association object that was built.
     *
     * @param string $associated the alias for the target table. This is used to
     * uniquely identify the association
     * @param array<string, mixed> $options list of options to configure the association definition
     * @return \Cake\ORM\Association\HasMany
     */
    public function hasMany(string $associated, array $options = []): HasMany
    {

If sth like this list is not formal enough, maybe we can find a syntax for it that is.

@klesun
Copy link
Owner

klesun commented Feb 26, 2024

If I understood the question correctly, the format from phpstan and other linters does cover the union type and the string literal type, so following should work in the plugin: (unless some breaking change in modern IDE versions broke that)

    /**
     * @param array<'className' | 'targetTable' | 'foreignKey' | 'dependent' | 'cascadeCallbacks' | 'conditions' | 'sort' | 'saveStrategy' | 'strategy' | 'finder', mixed> $options list of options to configure the association definition
     */
    public function hasMany(string $associated, array $options = []): HasMany
    {
        $options['<completion should come up here>']

@dereuromark
Copy link
Author

dereuromark commented Feb 26, 2024

I mean from the outside, the using function of ->hasMany()
See my example.

Your code snippet does not seem to work. Only AI (tabinePro in my case) seems to sometimes guess the possible types correctly, but more like 20% of the time.

@dereuromark
Copy link
Author

dereuromark commented Feb 26, 2024

That said

@param array{className: string, targetTable: string, foreignKey: string, webroot: string, dependent: bool, cascadeCallbacks: bool, conditions: array, sort: array, saveStrategy: string, finder: string} $options List of options to configure the association definition

seems to work, but that makes the docblock line super loong, would be nice if there was a way outside of the param docblock line directly.

@klesun
Copy link
Owner

klesun commented Feb 27, 2024

When completion works it suppossedly works both inside and outside the ->hasMany() function.

One more way, specific to the plugin, is to express the type through a dummy function:

function hasManyOptionsType()
{
    return [
        /** The class name of the target table object */
        'className' => 'example value',
        /** An instance of a table object to be used as the target table */
        'targetTable' => 'example value',
        /** The name of the field to use as foreign key, if false none will ve used */
        'foreignKey' => 'example value',
        // and so on
    ];
}

class Something()
{
    /**
     * @param $options = hasManyOptionsType()
     */
    public function hasMany(string $associated, array $options = []): HasMany
    {
        $options['<completion should come up here>']
    }
}

(new Something())->hasMany('ADmad/SocialAuth.SocialProfiles', [
    '<completion should come up here too>'
]);

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants