PHP_DocBlockGeneratorでinterfaceを扱う
see PHP_DocBlockGenerator使える! - Do You PHP はてな
いつの間にか1.0.2がリリースされているPHP_DocBlockGeneratorですが、1.0.2でfinalクラスやstatic privateなどの対応もされたようです。しかし、interfaceに対しては、まだ対応していないようです。たとえば、
<?php interface Services_Hatena_Star_Entry { public function canComment(); public function getStars(); public function getUri(); public function getRaw(); }
という内容のPHPファイルに対して
$ docblockgen \ --author="Hideyuki Shimooka" \ --category="Services" \ --email=shimooka@doyouphp.jp \ --infile=Entry.php \ --outfile=Entry.commented.php \ --license=php301 \ --package="Services_Hatena_Star" \ --version=0.0.1 --year=2007
と実行すると
<?php /** * Short description for file * : * @see References to other sections (if any)... */ interface Services_Hatena_Star_Entry { public /** * Short description for function * * Long description (if any) ... * * @return void */ function canComment(); public :
と、正しくコメントされません(publicの位置がズレる)。
ということで、3分間ハッキング(^^; [PEARインストール先]/PHP/DocBlockGenerator/Tokens.phpをちょっと変えるだけでinterface対応できます。
$ diff -u PHP/DocBlockGenerator/Tokens.php.org PHP/DocBlockGenerator/Tokens.php --- PHP/DocBlockGenerator/Tokens.php.org 2007-07-22 15:52:50.000000000 +0900 +++ PHP/DocBlockGenerator/Tokens.php 2007-07-22 15:52:57.000000000 +0900 @@ -269,6 +269,7 @@ break; case T_CLASS: // class classes and objects + case T_INTERFACE: // interfaces and objects $this->inClass = 0; $this->block->setClass($id); break; $
要は、interfaceもclassと同様に扱うようにするだけです(^^;が、
<?php /** * Short description for file : * @see References to other sections (if any)... */ /** * Short description for class * * Long description (if any) ... * * @category Services * @package Services_Hatena_Star * @author Hideyuki Shimooka <shimooka@doyouphp.jp> * @copyright 2007 Hideyuki Shimooka * @license http://www.php.net/license/3_01.txt The PHP License, version 3.01 * @version 0.0.1 * @link http://pear.php.net/package/Services_Hatena_Star * @see References to other sections (if any)... */ interface Services_Hatena_Star_Entry { /** * Short description for function * * Long description (if any) ... * * @return void * @access public */ public function canComment(); :
という具合にinterface定義に対するdocblockも作成されます。ただ、このdocblockもclass用なので、微妙といえば微妙。。。
ということで、Block.phpにinterface用のコードを追加(setClassメソッドをほとんどコピー)して
--- PHP/DocBlockGenerator/Tokens.php.org 2007-07-22 16:21:47.000000000 +0900 +++ PHP/DocBlockGenerator/Tokens.php 2007-07-22 16:13:44.000000000 +0900 @@ -273,6 +273,11 @@ $this->block->setClass($id); break; + case T_INTERFACE: // interfaces + $this->inClass = 0; + $this->block->setInterface($id); + break; + case T_CONST: // const // sets the const DocBlock is_null($this->inClass) or $this->block->setConst($id); --- PHP/DocBlockGenerator/Block.php.org 2007-07-22 16:21:39.000000000 +0900 +++ PHP/DocBlockGenerator/Block.php 2007-07-22 16:18:53.000000000 +0900 @@ -346,6 +346,45 @@ } /** + * Sets the class DocBlock + * + * Extracts the class token. Sets the default package name on the + * first 2 words of the class. Builds the class DocBlock. Resets the + * class variables types cache. + * + * @param integer $id the class token identification number + * @return void + * @access public + */ + public function setInterface($id) + { + // extracts the interface declaration tokens + $tokens = $this->tokens->slice($id, T_INTERFACE, '{'); + + if (count($tokens) >= 3) { + // a interface is found, extracts the interface tokens + $this->interfaceTokens = $this->tokens->slice($id, '{', '}'); + // if the package name is set to its defaults + // extracts the interface name first 2 words, assumed to be the package name + // sets the package name to the first 2 words of the interface name + $this->packageName == self::packageName and + $interfaceName = next($tokens) and + $interfaceName = $interfaceName['value'] and + $words = explode('_', $interfaceName)and + $words = array_slice($words, 0, 2) and + $this->packageName = implode('_', $words) or + $this->packageName = self::packageName; + // adds the default description and the tags to the DocBlock + $block = array($this->description['short'], '', $this->description['long']); + $block = array_merge($block, $this->setPageTags()); + $this->build($id, $block, false, 'interface'); + // resets the variables types cache + $this->type->resetCache('var'); + } + // else: ignore, not a syntax compliant interface declaration + } + + /** * Sets the class constant DocBlock * * Extracts the constant value. Determines its type.
な感じに変更すると、
<?php /** * Short description for file * : * @see References to other sections (if any)... */ /** * Short description for interface * * Long description (if any) ... * * @category Services * @package Services_Hatena_Star * @author Hideyuki Shimooka <shimooka@doyouphp.jp> * @copyright 2007 Hideyuki Shimooka * @license http://www.php.net/license/3_01.txt The PHP License, version 3.01 * @version 0.0.1 * @link http://pear.php.net/package/Services_Hatena_Star * @see References to other sections (if any)... */ interface Services_Hatena_Star_Entry { /** * Short description for function :
結構良い感じになります :-)