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

Annotation for magic static methods available with __callStatic #22

Closed
lisachenko opened this issue Sep 21, 2013 · 14 comments
Closed

Annotation for magic static methods available with __callStatic #22

lisachenko opened this issue Sep 21, 2013 · 14 comments

Comments

@lisachenko
Copy link

Currently there is no clear way to declare a magic static methods available for a class that uses __callStatic(). Traditional @method annotation is parsed by IDE and listed as dynamic method, so when I trigger the autocompletion for $this-> IDE can suggest me the name of magic method that is handled with __call(). When I use magic static methods there is not any help from the IDE because it can not understand that method is magic and static and doesn't list it for self:: or static::.

My proposal is to add an extension for that via @static or @static-method. Look at the following example:

/**
 * Class Example
 * 
 * @method bool foo()
 * @method bool bar()
 */
class Example
{
    public function __call($name, $arguments)
    {
        if ($name === 'foo') {
            return true;
        }
        throw new \InvalidArgumentException("Unknown dynamic method {$name}");
    }

    public function __callStatic($name, $arguments)
    {
        if ($name === 'bar') {
            return true;
        }
        throw new \InvalidArgumentException("Unknown static method {$name}");
    }
}

Autocompletion for dynamic methods is nice, but the method bar is listed too:
image

For static methods there is nothing:
image

@samdark
Copy link

samdark commented Oct 9, 2013

Since there's no magic way of defining static class members, @static sounds good enough.

@neuro159
Copy link

PhpStorm support @method static returnType name ...

@neuro159
Copy link

@samdark please provide an example on how you intend to apply @static to multiple @method declarations.

@samdark
Copy link

samdark commented Jul 22, 2014

/**
 * Class Example
 * 
 * @method bool foo()
 * @method static bool bar()
 */

That's for example above. foo is dynamic, bar is static.

@lisachenko
Copy link
Author

@samdark @neuro159 this can be a good solution, but I prefer shorter version:

/**
 * Class Example
 * 
 * @method bool foo()
 * @static bool bar()
 */

less symbols to type :)

However, I will be happy with any standard way of declaring such methods, especially for Laravel static facades.

@samdark
Copy link

samdark commented Jul 22, 2014

@lisachenko what about static class members?

/**
 * Class Example
 * 
 * @property static boolean $isTest
 * @method bool foo()
 * @method static bool bar()
 */

@lisachenko
Copy link
Author

@samdark PHP doesn't support magic static properties, so there is no need to declare such things.

But I agree with your example, because it's more general and will allow static properties declaration (if we will have __getStatic() magic method for that). Usage of @static for properties will be not so clear as @property static or @property-static.

@neuro159
Copy link

IMO having static as optional modifier for @method.. or @property.. is better than adding more tags.

PhpStorm users adopted this convention since 2011 http://youtrack.jetbrains.com/issue/WI-4051

@mvriel
Copy link
Member

mvriel commented Aug 15, 2014

I agree with @neuro159; I prefer adding static as the first keyword in an @method tag as well. This is because static has multiple meanings (static methods vs. late static binding) and hence a tag @static would be potentially confusing AND @static already exists as tag to indicate that an associated element is static and was used in the pre-PHP 5 days.

This PSR explicitly omits @static because it is no longer necessary with PHP5.

@sun
Copy link

sun commented Aug 15, 2014

Hm. Static and object-scope methods are completely different cans of worms in PHP.

Due to that, I dislike the optional static modifier and would rather go with a @method-static tag, which - for now, in terms of PHPDoc - would be an "alias" for @method.

However, because there is a fundamental differentiation, it does not have to stay that way. The "alias" (wrapper) may diverge from @method later on.

The same applies to @property-static. Static properties equally have fundamental differences, because every static variable is a global state construct in PHP core.
— I dunno whether static properties can really be dynamically composed, but at least Reflection's source code does account for the case of "retrieving the value of a static property that does not exist" with special code paths.

A clean separation should allow IDEs to offer autocomplete options at an earlier point in time already. Just typing SomeClass should offer autocompletion for its static methods and properties already.

At the same time, @method-static retains the standard signature of PHPDoc tags (by not prepending an optional modifier to the standard signature).

Example:

/**
 * Class Example
 * 
 * @property bool $isOverloadedProperty
 * @property-static bool $isOverloadedStaticProperty
 *
 * @method bool overloadedMethod()
 * @method-static bool overloadedStaticMethod()
 */

@mvriel
Copy link
Member

mvriel commented Aug 15, 2014

Due to that, I dislike the optional static modifier and would rather go with a @method-static tag

Can you explain what you mean? I can see how @static would be ambiguous but I do not see what benefit @method-static would have over @method static (counting that the latter is already supported by phpStorm).

@sun
Copy link

sun commented Aug 18, 2014

  1. "static" is a defined "Type" keyword in PSR-5, so @return static would mean something completely different than @method static, because @method uses an optional modifier in its tag signature that diverges from the other tags in the same space (@param, @return, @property, etc), which is always:

    @tag ["Type"] ...
    
  2. The technical difference is __callStatic() as opposed to __call(), scope differences due LSB, and quite potentially many others. PHP core makes substantial differences between static methods and object-scope methods. I don't think it is wise to pretend that they're the same.

@aduh95
Copy link

aduh95 commented Aug 2, 2016

It's been almost two years, and no solution has been selected. Can we implement one of those solutions in the PSR please?

@ashnazg ashnazg closed this as completed in d0a9c5c Oct 2, 2018
ashnazg pushed a commit that referenced this issue Oct 2, 2018
@jimbonator
Copy link

Why did the above commit close this ticket? I believe this issue should still be open.

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

7 participants