Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

PHPDoc: document parent class method that always yields itself or descendant class?

Consider this code:

class ParentClass {

    public static function generate($className = __CLASS__){
        if(!$className) return new self();
        else return new $className();
    }
}

class ChildClass extends ParentClass {

    /**
     * @param string $className
     * @return ChildClass
     */
    public static function generate($className = __CLASS__) {
        return parent::generate($className);
    }
}

var_dump($ChildClass::generate()); // object(ChildClass)[1]

ChildClass::generate() returns an instance of ChildClass wherever I use it because I never provide a $className argument. Problem is that my IDE gives me a warning about the parent::generate() call not matching the documented return type:

enter image description here

I would like to make this warning go away by adding documentation to the parent method. I could do:

@return ParentClass | ChildClass

Adding this to the parent method works but that's not practical because there are many dozen children classes, and there could be many more in the future. I have tried both of the following:

@return static
@return $className

but that hasn't made the warning go away. Is there a PHPDoc approved way to indicate that the calling child class will always be returned? Or -- more accurately -- that a class of type $className will be returned? If not, is there a way that works even with just my IDE? (PhpStorm 2017.2)

Update

@gogaz comment below got me to think: it would be enough if a PHPDoc @return could indicate something like self | descendants

like image 583
BeetleJuice Avatar asked Sep 19 '17 12:09

BeetleJuice


1 Answers

You can document parent class method and then just inherit that on a child class method.

class ParentClass
{
    /**
     * @param string $className
     * @return ChildClass
     */
    public static function generate($className = __CLASS__){
        if(!$className) return new self();
        else return new $className();
    }
}

class ChildClass extends ParentClass
{
    /**
     * @inheritdoc
     */
    public static function generate($className = __CLASS__) {
        return parent::generate($className);
    }
}

I hope that this will solve your problem.

UPDATE: Another way to do this is by using interface that all classes will implement, so you could expect that your generate method will return some class that implements that interface.

 /**
  * ...
  * @return MyCustomInterface
  */

If this doesn't solve your issue... Then, you can set return type as "mixed", this will suppress warning and it won't lie :) because your generate method can return any class you specify via argument...

 /**
  * ...
  * @return mixed
  */
like image 73
Branimir Đurek Avatar answered Sep 24 '22 00:09

Branimir Đurek