Package home | Report new bug | New search | Development Roadmap Status: Open | Feedback | All | Closed Since Version 1.5.0a1

Bug #6305 array typehints break the parser
Submitted: 2005-12-20 19:06 UTC
From: derick Assigned: cellog
Status: Closed Package: PhpDocumentor (version 1.3.0RC6)
PHP Version: 5.1.1 OS: Linux
Roadmaps: (Not assigned)    
Subscription  


 [2005-12-20 19:06 UTC] derick
Description: ------------ When encountering an array typehint in a function, the parser gets messed up. When this happens, the rest of the file doesn't get parsed correctly either resulting in missing methods in some cases. Test script: --------------- /** * Constructs the ezcTranslation object. * * The constructor receives an array containing the map between the * original string and the translation. * * @param array(string=>ezcTranslationData) $data */ function __construct( array $data ) { $this->translationMap = array(); foreach ( $data as $translationElement ) { $this->translationMap[$translationElement->original] = $translationElement; } } Expected result: ---------------- ezcTranslation __construct ( array $data ); Actual result: -------------- the following (broken) summary: Summary: ezcTranslation __construct ([translationMap {$this-> = array $data )();foreach($dataas$translationElement){$this->translationMap[$translationElement->original]=$translationElement;}}privatefu nctionparameter_callback($key,array$params){if(!isset($params[strtolower($key)])){thrownewezcTranslationException("TheThe parameter <%{$key}> does not exist."], PARAMETER_MISSING ::, array(string=>ezcTranslationData) $data)

Comments

 [2006-02-23 05:50 UTC] cellog
This bug has been fixed in CVS. If this was a documentation problem, the fix will appear on pear.php.net by the end of next Sunday (CET). If this was a problem with the pear.php.net website, the change should be live shortly. Otherwise, the fix will appear in the package's next release. Thank you for the report and for helping us make PEAR better. will be in next release :) Here is a patch (can also be grabbed from the cvs commit email) Index: PhpDocumentor/phpDocumentor/Parser.inc =================================================================== RCS file: /repository/pear/PhpDocumentor/phpDocumentor/Parser.inc,v retrieving revision 1.1 diff -u -r1.1 Parser.inc --- PhpDocumentor/phpDocumentor/Parser.inc 17 Oct 2005 18:36:56 -0000 1.1 +++ PhpDocumentor/phpDocumentor/Parser.inc 23 Feb 2006 05:17:25 -0000 @@ -283,6 +283,11 @@ /** currently parsing a comment in a variable array value */ define("STATE_VAR_ARRAY_COMMENT" , 243); +/** used when a $param is encountered in a function definition */ +define("PARSER_EVENT_FUNCTION_PARAM_VAR", 144); +/** currently parsing a $param in a function definition */ +define("STATE_FUNCTION_PARAM_VAR", 244); + if (!defined('T_INTERFACE')) { define('T_INTERFACE', 'foo'); Index: PhpDocumentor/phpDocumentor/ParserElements.inc =================================================================== RCS file: /repository/pear/PhpDocumentor/phpDocumentor/ParserElements.inc,v retrieving revision 1.2 diff -u -r1.2 ParserElements.inc --- PhpDocumentor/phpDocumentor/ParserElements.inc 28 Nov 2005 07:27:59 -0000 1.2 +++ PhpDocumentor/phpDocumentor/ParserElements.inc 23 Feb 2006 05:39:14 -0000 @@ -344,14 +344,20 @@ var $statics = false; var $source = ''; + /** * @param string * @param string default value parsed from function definition * @param boolean indicates whether this parameter has a default value + * @param null|string class type hint */ - function addParam($name, $value, $has_default = true) + function addParam($name, $value, $has_default = true, $typehint = null) { $this->params[$name] = array($value, $has_default); + if (isset($typehint)) + { + $this->params[$name][2] = $typehint; + } } /** Index: PhpDocumentor/phpDocumentor/phpDocumentorTParser.inc =================================================================== RCS file: /repository/pear/PhpDocumentor/phpDocumentor/phpDocumentorTParser.inc,v retrieving revision 1.2 diff -u -r1.2 phpDocumentorTParser.inc --- PhpDocumentor/phpDocumentor/phpDocumentorTParser.inc 20 Nov 2005 21:04:09 -0000 1.2 +++ PhpDocumentor/phpDocumentor/phpDocumentorTParser.inc 23 Feb 2006 05:35:47 -0000 @@ -138,6 +138,7 @@ PARSER_EVENT_EOFQUOTE => 'handleHereDoc', PARSER_EVENT_FUNCTION => 'handleFunction', PARSER_EVENT_FUNCTION_PARAMS => 'handleFunctionParams', + PARSER_EVENT_FUNCTION_PARAM_VAR => 'handleFunctionParams', PARSER_EVENT_FUNC_GLOBAL => 'handleFuncGlobal', PARSER_EVENT_DEFINE_GLOBAL => 'handleGlobal', PARSER_EVENT_GLOBAL_VALUE => 'handleGlobalValue', @@ -549,23 +550,24 @@ function handleFunctionParams($word, $pevent) { - //echo $this->wp->getPos() . ": word=|$word|\t\t\tlastword=|".$this->_pv_last_word."|\n"; + //echo $this->_wp->getPos() . ": word=|$word|\t\t\tlastword=|".$this->_pv_last_word."|\n"; //echo "function_param = '".$this->_pv_function_param."'\n"; //echo "function_data = '".$this->_pv_function_data."'\n"; - $e1 = $this->checkEventPush( $word, $pevent); + $e1 = $this->checkEventPush($word, $pevent); if (!$e1) { - if ($word == ',' || $this->checkEventPop($word,$pevent)) - { + if ($this->checkEventPop($word,$pevent) && $pevent == PARSER_EVENT_FUNCTION_PARAM_VAR) + { // end of [typehint ]$param[= defaultval] + $this->_wp->backupPos(); $this->endFunctionParam($word); } elseif ($word == '=') - { + { // about to parse the default value $this->_pf_funcparam_val = true; } else { if ($this->_pf_funcparam_val) - { + { // parsing default value if (isset($this->_pv_quote_data)) { $this->_pv_function_data .= $this->_pv_quote_data; @@ -574,12 +576,12 @@ if (is_array($word)) $word = $word[1]; $this->_pv_function_data .= $word; } else - { + { // pre-param if (!isset($this->_pv_function_param)) $this->_pv_function_param = ''; - if (is_array($word)) + if (is_array($word) && $pevent == PARSER_EVENT_FUNCTION_PARAMS) { - if ($word[0] == T_STRING) - { + if ($word[0] == T_STRING || $word[0] == T_ARRAY) + { // object or array type hint $this->_pv_function_param_type = $word[1]; return; } @@ -591,6 +593,9 @@ } elseif ($e1 == PARSER_EVENT_ARRAY) { $this->_wp->setWhiteSpace(true); + } elseif ($e1 == PARSER_EVENT_FUNCTION_PARAM_VAR) { + // we just got the $var part of the param + $this->_pv_function_param .= $word[1]; } } @@ -2396,17 +2401,26 @@ $this->tokenpushEvent[PARSER_EVENT_FUNCTION_PARAMS] = array( + T_VARIABLE => PARSER_EVENT_FUNCTION_PARAM_VAR, + T_COMMENT => PARSER_EVENT_COMMENT, + T_DOC_COMMENT => PARSER_EVENT_COMMENT, + ); + $this->wordpopEvent[PARSER_EVENT_FUNCTION_PARAMS] = array(")"); +/**************************************************************/ + + $this->tokenpushEvent[PARSER_EVENT_FUNCTION_PARAM_VAR] = + array( T_CONSTANT_ENCAPSED_STRING => PARSER_EVENT_QUOTE, - T_ARRAY => PARSER_EVENT_ARRAY, T_COMMENT => PARSER_EVENT_COMMENT, T_DOC_COMMENT => PARSER_EVENT_COMMENT, + T_ARRAY => PARSER_EVENT_ARRAY, ); - $this->wordpushEvent[PARSER_EVENT_FUNCTION_PARAMS] = + $this->wordpushEvent[PARSER_EVENT_FUNCTION_PARAM_VAR] = array( '"' => PARSER_EVENT_QUOTE, "'" => PARSER_EVENT_QUOTE, ); - $this->wordpopEvent[PARSER_EVENT_FUNCTION_PARAMS] = array(")"); + $this->wordpopEvent[PARSER_EVENT_FUNCTION_PARAM_VAR] = array(",", ")"); /**************************************************************/ $this->tokenpushEvent[PARSER_EVENT_ARRAY] =