How to documenting a class decorator?

Hi!

I have some class like this:

class A {
     public function method1() { /** do somethig **/ }

     public function method2() { /** do somethig **/ }

     public function method3() { /** do somethig **/ }
}

and I want to decorate class with another like this:

class B {
     private $aInstance = null;

     public function __construct( A $aInstance ) {
          $this->aInstance = $aInstance;
     }

     public function __call( $Method, $Args ) {
          return call_user_func_array( array($this->aInstance, $Method), $Args );
     }

     public function method2() { /** do somethig different from class A **/ }
}

and now, writing my code in phpStorm, I want autocomplete methods from class B like a class A:

It works cool:
$a = new A();
$a->method1();
$a->method2();
$a->method3();

but:
$b = new B();

$b->method1();
$b->method2(); // Only this method present in autocomplete
$b->method3();



Which phpDoc tag before class I can achieve the desired behavior?

Sorry for my bad english, thank you! )
5 comments
Comment actions Permalink

Hi Arthur,

You need to use @method tag in class PHPDoc comment -- you have to describe each of such "magic" methods. For example:

/**
* Your class description

*
* @method null method1() My first method
*/
class B {
...


http://www.phpdoc.org/docs/latest/for-users/tags/method.html

0
Comment actions Permalink

Hi Andriy!

I know this trick, but, imagine if I want to decorate class with 1000 methods?)

0
Comment actions Permalink

That is the price you have to pay for using rather unconventional approaches.

Currently PhpStorm does not support any custom tags that could do this with single line. AFAIK this is the right ticket for your case: http://youtrack.jetbrains.com/issue/WI-1730

0
Comment actions Permalink

There is actually a way of doing it right now, but it rather inconvenient as you will have to do it for each instance (not a big deal at all in my eyes, but other people can be very picky).

The idea is to tell PhpStorm that variable can be of any of the listed classes which makes methods/fields from both classes available for code completion.

/** @var $b B|A */

$b = new B ($a);

1
Comment actions Permalink
That is the price you have to pay for using rather unconventional approaches.


I disagree that this is unconventional.  Advanced maybe, but not unconventional because for use-cases where it's needed it's simply (one of?) the only option(s).

Anyway, similarly I would like to see PhpStorm be able to Navigate to the Declaration (Keystroke on Mac: [Cmd-B]).

I have a main class and lots of helper classes where any of the methods of the helper classes can be called statically via the main class. This allows for a simple library "api" where the developer using the library need not know which of the many classes contains a method and allows for more logical code organization, i.e. grouping related methods into different class files.

  static function __callStatic( $method, $args ) {
    $value = null;
    if ( $found = isset( self::$_cached_callables[$method] ) ) {
      $value = call_user_func_array( self::$_cached_callables[$method], $args );
    } else {
      foreach( self::$_helper_classes as $class ) {
        if ( method_exists( $class, $method ) ) {
          self::$_cached_callables[$method] = array( $class, $method );
          $value = call_user_func_array( self::$_cached_callables[$method], $args );
          $found = true;
          break;
        }
      }
    }
    if ( ! isset( $found ) ) {
      $message = sprintf( 'ERROR: There is no method MyApiClass::%s().', $method );
      trigger_error( $message, E_USER_ERROR );
    }
    return $value;
  }

Currently I have a PHPDoc comment at the top of the main class for each method contributed but the problem with that is that I cannot use PhpStorm's navigation functionality.  It would be great if there were some why that I could indicate in PhpStorm the names of the other classes that contribute methods to this class, for example using a @mixin attribute, something like:

/**
  * @mixin _MyApiHelperClass
  * @mixin _MyApiMethodAdderClass::myAddedMethod()
  */
class MyApiClass {
   ...
}


Given the above I would then like to be able to place my cursor on the method name in

MyApiClass::myAddedMethod()
and press [Cmd-B] and have it jump to the definition of myAddedMethod() in _MyApiMethodAdderClass.

Message was edited by: Mike Schinkel - fixed a bug in the example code.
0

Please sign in to leave a comment.