<?xml version="1.0"?>
<?xml-stylesheet 
 href="http://www.w3.org/2000/08/w3c-synd/style.css" type="text/css"
?>
<rdf:RDF xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" xmlns="http://purl.org/rss/1.0/" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:sy="http://purl.org/rss/1.0/modules/syndication/" xmlns:admin="http://webns.net/mvcb/" xmlns:content="http://purl.org/rss/1.0/modules/content/">
    <channel rdf:about="http://pear.php.net/bugs/6305/bug">
    <title>PEAR Bug #6305</title>
    <link>http://pear.php.net/bugs/6305</link>
    <description>[Closed] array typehints break the parser</description>
    <dc:language>en-us</dc:language>
    <dc:creator>pear-webmaster@lists.php.net</dc:creator>
    <dc:publisher>pear-webmaster@lists.php.net</dc:publisher>
    <admin:generatorAgent rdf:resource="http://pear.php.net/bugs"/>
    <sy:updatePeriod>hourly</sy:updatePeriod>
    <sy:updateFrequency>1</sy:updateFrequency>
    <sy:updateBase>2000-01-01T12:00+00:00</sy:updateBase>
    <items>
     <rdf:Seq>
      <rdf:li rdf:resource="http://pear.php.net/bugs/6305"/>
      <rdf:li rdf:resource="http://pear.php.net/bugs/6305/2006-02-23+00%3A50%3A10#2006-02-23+00%3A50%3A10"/>
     </rdf:Seq>
    </items>
  </channel>
    <item rdf:about="http://pear.php.net/bugs/6305">
      <title>derick</title>
      <link>http://pear.php.net/bugs/6305</link>
      <description><![CDATA[<pre>PhpDocumentor Bug
Reported by derick
2005-12-20T19:06:27-00:00
PHP: 5.1.1 OS: Linux Package Version: 1.3.0RC6

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=&gt;ezcTranslationData) $data
      */
     function __construct( array $data )
     {
         $this-&gt;translationMap = array();
         foreach ( $data as $translationElement )
         {
             $this-&gt;translationMap[$translationElement-&gt;original] = $translationElement;
         }
     }

Expected result:
----------------
ezcTranslation __construct ( array $data );


Actual result:
--------------
the following (broken) summary:

Summary:
ezcTranslation __construct ([translationMap {$this-&gt; = array $data
)();foreach($dataas$translationElement){$this-&gt;translationMap[$translationElement-&gt;original]=$translationElement;}}privatefu
nctionparameter_callback($key,array$params){if(!isset($params[strtolower($key)])){thrownewezcTranslationException(&quot;TheThe
parameter &lt;%{$key}&gt; does not exist.&quot;], PARAMETER_MISSING ::,
array(string=&gt;ezcTranslationData) $data)</pre>]]></description>
      <content:encoded><![CDATA[<pre>PhpDocumentor Bug
Reported by derick
2005-12-20T19:06:27-00:00
PHP: 5.1.1 OS: Linux Package Version: 1.3.0RC6

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=&gt;ezcTranslationData) $data
      */
     function __construct( array $data )
     {
         $this-&gt;translationMap = array();
         foreach ( $data as $translationElement )
         {
             $this-&gt;translationMap[$translationElement-&gt;original] = $translationElement;
         }
     }

Expected result:
----------------
ezcTranslation __construct ( array $data );


Actual result:
--------------
the following (broken) summary:

Summary:
ezcTranslation __construct ([translationMap {$this-&gt; = array $data
)();foreach($dataas$translationElement){$this-&gt;translationMap[$translationElement-&gt;original]=$translationElement;}}privatefu
nctionparameter_callback($key,array$params){if(!isset($params[strtolower($key)])){thrownewezcTranslationException(&quot;TheThe
parameter &lt;%{$key}&gt; does not exist.&quot;], PARAMETER_MISSING ::,
array(string=&gt;ezcTranslationData) $data)</pre>]]></content:encoded>
      <dc:date>2005-12-20T19:06:27-00:00</dc:date>
    </item>
    <item rdf:about="http://pear.php.net/bugs/6305/2006-02-23+00%3A50%3A10#2006-02-23+00%3A50%3A10">
      <title>cellog [2006-02-23 05:50]</title>
      <link>http://pear.php.net/bugs/6305#1140673810</link>
      <description><![CDATA[<pre>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(&quot;STATE_VAR_ARRAY_COMMENT&quot;    ,    243);
 
+/** used when a $param is encountered in a function definition */
+define(&quot;PARSER_EVENT_FUNCTION_PARAM_VAR&quot;, 144);
+/** currently parsing a $param in a function definition */
+define(&quot;STATE_FUNCTION_PARAM_VAR&quot;, 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-&gt;params[$name] = array($value, $has_default);
+        if (isset($typehint))
+        {
+            $this-&gt;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 =&gt; 'handleHereDoc',
                                 PARSER_EVENT_FUNCTION =&gt; 'handleFunction',
                                 PARSER_EVENT_FUNCTION_PARAMS =&gt; 'handleFunctionParams',
+                                PARSER_EVENT_FUNCTION_PARAM_VAR =&gt; 'handleFunctionParams',
                                 PARSER_EVENT_FUNC_GLOBAL =&gt; 'handleFuncGlobal',
                                 PARSER_EVENT_DEFINE_GLOBAL =&gt; 'handleGlobal',
                                 PARSER_EVENT_GLOBAL_VALUE =&gt; 'handleGlobalValue',
@@ -549,23 +550,24 @@
     
     function handleFunctionParams($word, $pevent)
     {
-        //echo $this-&gt;wp-&gt;getPos() . &quot;: word=|$word|\t\t\tlastword=|&quot;.$this-&gt;_pv_last_word.&quot;|\n&quot;;
+        //echo $this-&gt;_wp-&gt;getPos() . &quot;: word=|$word|\t\t\tlastword=|&quot;.$this-&gt;_pv_last_word.&quot;|\n&quot;;
         //echo &quot;function_param = '&quot;.$this-&gt;_pv_function_param.&quot;'\n&quot;;
         //echo &quot;function_data = '&quot;.$this-&gt;_pv_function_data.&quot;'\n&quot;;
-        $e1 = $this-&gt;checkEventPush( $word, $pevent); 
+        $e1 = $this-&gt;checkEventPush($word, $pevent); 
 
         if (!$e1)
         {
-            if ($word == ',' || $this-&gt;checkEventPop($word,$pevent))
-            {
+            if ($this-&gt;checkEventPop($word,$pevent) &amp;&amp; $pevent == PARSER_EVENT_FUNCTION_PARAM_VAR)
+            { // end of [typehint ]$param[= defaultval]
+                $this-&gt;_wp-&gt;backupPos();
                 $this-&gt;endFunctionParam($word);
             } elseif ($word == '=')
-            {
+            { // about to parse the default value
                 $this-&gt;_pf_funcparam_val = true;
             } else
             {
                 if ($this-&gt;_pf_funcparam_val)
-                {
+                { // parsing default value
                     if (isset($this-&gt;_pv_quote_data))
                     {
                         $this-&gt;_pv_function_data .= $this-&gt;_pv_quote_data;
@@ -574,12 +576,12 @@
                     if (is_array($word)) $word = $word[1];
                     $this-&gt;_pv_function_data .= $word;
                 } else
-                {
+                { // pre-param
                     if (!isset($this-&gt;_pv_function_param)) $this-&gt;_pv_function_param = '';
-                    if (is_array($word))
+                    if (is_array($word) &amp;&amp; $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-&gt;_pv_function_param_type = $word[1];
                             return;
                         }
@@ -591,6 +593,9 @@
         } elseif ($e1 == PARSER_EVENT_ARRAY)
         {
             $this-&gt;_wp-&gt;setWhiteSpace(true);
+        } elseif ($e1 == PARSER_EVENT_FUNCTION_PARAM_VAR) {
+            // we just got the $var part of the param
+            $this-&gt;_pv_function_param .= $word[1];
         }
     }
 
@@ -2396,17 +2401,26 @@
 
         $this-&gt;tokenpushEvent[PARSER_EVENT_FUNCTION_PARAMS] =
             array(
+                T_VARIABLE =&gt; PARSER_EVENT_FUNCTION_PARAM_VAR,
+                T_COMMENT =&gt; PARSER_EVENT_COMMENT,
+                T_DOC_COMMENT =&gt; PARSER_EVENT_COMMENT,
+            );
+        $this-&gt;wordpopEvent[PARSER_EVENT_FUNCTION_PARAMS] = array(&quot;)&quot;);
+/**************************************************************/
+
+        $this-&gt;tokenpushEvent[PARSER_EVENT_FUNCTION_PARAM_VAR] =
+            array(
                 T_CONSTANT_ENCAPSED_STRING =&gt; PARSER_EVENT_QUOTE,
-                T_ARRAY =&gt; PARSER_EVENT_ARRAY,
                 T_COMMENT =&gt; PARSER_EVENT_COMMENT,
                 T_DOC_COMMENT =&gt; PARSER_EVENT_COMMENT,
+                T_ARRAY =&gt; PARSER_EVENT_ARRAY,
             );
-        $this-&gt;wordpushEvent[PARSER_EVENT_FUNCTION_PARAMS] =
+        $this-&gt;wordpushEvent[PARSER_EVENT_FUNCTION_PARAM_VAR] =
             array(
                 '&quot;' =&gt; PARSER_EVENT_QUOTE,
                 &quot;'&quot; =&gt; PARSER_EVENT_QUOTE,
             );
-        $this-&gt;wordpopEvent[PARSER_EVENT_FUNCTION_PARAMS] = array(&quot;)&quot;);
+        $this-&gt;wordpopEvent[PARSER_EVENT_FUNCTION_PARAM_VAR] = array(&quot;,&quot;, &quot;)&quot;);
 /**************************************************************/
 
         $this-&gt;tokenpushEvent[PARSER_EVENT_ARRAY] =</pre>]]></description>
      <content:encoded><![CDATA[<pre>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(&quot;STATE_VAR_ARRAY_COMMENT&quot;    ,    243);
 
+/** used when a $param is encountered in a function definition */
+define(&quot;PARSER_EVENT_FUNCTION_PARAM_VAR&quot;, 144);
+/** currently parsing a $param in a function definition */
+define(&quot;STATE_FUNCTION_PARAM_VAR&quot;, 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-&gt;params[$name] = array($value, $has_default);
+        if (isset($typehint))
+        {
+            $this-&gt;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 =&gt; 'handleHereDoc',
                                 PARSER_EVENT_FUNCTION =&gt; 'handleFunction',
                                 PARSER_EVENT_FUNCTION_PARAMS =&gt; 'handleFunctionParams',
+                                PARSER_EVENT_FUNCTION_PARAM_VAR =&gt; 'handleFunctionParams',
                                 PARSER_EVENT_FUNC_GLOBAL =&gt; 'handleFuncGlobal',
                                 PARSER_EVENT_DEFINE_GLOBAL =&gt; 'handleGlobal',
                                 PARSER_EVENT_GLOBAL_VALUE =&gt; 'handleGlobalValue',
@@ -549,23 +550,24 @@
     
     function handleFunctionParams($word, $pevent)
     {
-        //echo $this-&gt;wp-&gt;getPos() . &quot;: word=|$word|\t\t\tlastword=|&quot;.$this-&gt;_pv_last_word.&quot;|\n&quot;;
+        //echo $this-&gt;_wp-&gt;getPos() . &quot;: word=|$word|\t\t\tlastword=|&quot;.$this-&gt;_pv_last_word.&quot;|\n&quot;;
         //echo &quot;function_param = '&quot;.$this-&gt;_pv_function_param.&quot;'\n&quot;;
         //echo &quot;function_data = '&quot;.$this-&gt;_pv_function_data.&quot;'\n&quot;;
-        $e1 = $this-&gt;checkEventPush( $word, $pevent); 
+        $e1 = $this-&gt;checkEventPush($word, $pevent); 
 
         if (!$e1)
         {
-            if ($word == ',' || $this-&gt;checkEventPop($word,$pevent))
-            {
+            if ($this-&gt;checkEventPop($word,$pevent) &amp;&amp; $pevent == PARSER_EVENT_FUNCTION_PARAM_VAR)
+            { // end of [typehint ]$param[= defaultval]
+                $this-&gt;_wp-&gt;backupPos();
                 $this-&gt;endFunctionParam($word);
             } elseif ($word == '=')
-            {
+            { // about to parse the default value
                 $this-&gt;_pf_funcparam_val = true;
             } else
             {
                 if ($this-&gt;_pf_funcparam_val)
-                {
+                { // parsing default value
                     if (isset($this-&gt;_pv_quote_data))
                     {
                         $this-&gt;_pv_function_data .= $this-&gt;_pv_quote_data;
@@ -574,12 +576,12 @@
                     if (is_array($word)) $word = $word[1];
                     $this-&gt;_pv_function_data .= $word;
                 } else
-                {
+                { // pre-param
                     if (!isset($this-&gt;_pv_function_param)) $this-&gt;_pv_function_param = '';
-                    if (is_array($word))
+                    if (is_array($word) &amp;&amp; $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-&gt;_pv_function_param_type = $word[1];
                             return;
                         }
@@ -591,6 +593,9 @@
         } elseif ($e1 == PARSER_EVENT_ARRAY)
         {
             $this-&gt;_wp-&gt;setWhiteSpace(true);
+        } elseif ($e1 == PARSER_EVENT_FUNCTION_PARAM_VAR) {
+            // we just got the $var part of the param
+            $this-&gt;_pv_function_param .= $word[1];
         }
     }
 
@@ -2396,17 +2401,26 @@
 
         $this-&gt;tokenpushEvent[PARSER_EVENT_FUNCTION_PARAMS] =
             array(
+                T_VARIABLE =&gt; PARSER_EVENT_FUNCTION_PARAM_VAR,
+                T_COMMENT =&gt; PARSER_EVENT_COMMENT,
+                T_DOC_COMMENT =&gt; PARSER_EVENT_COMMENT,
+            );
+        $this-&gt;wordpopEvent[PARSER_EVENT_FUNCTION_PARAMS] = array(&quot;)&quot;);
+/**************************************************************/
+
+        $this-&gt;tokenpushEvent[PARSER_EVENT_FUNCTION_PARAM_VAR] =
+            array(
                 T_CONSTANT_ENCAPSED_STRING =&gt; PARSER_EVENT_QUOTE,
-                T_ARRAY =&gt; PARSER_EVENT_ARRAY,
                 T_COMMENT =&gt; PARSER_EVENT_COMMENT,
                 T_DOC_COMMENT =&gt; PARSER_EVENT_COMMENT,
+                T_ARRAY =&gt; PARSER_EVENT_ARRAY,
             );
-        $this-&gt;wordpushEvent[PARSER_EVENT_FUNCTION_PARAMS] =
+        $this-&gt;wordpushEvent[PARSER_EVENT_FUNCTION_PARAM_VAR] =
             array(
                 '&quot;' =&gt; PARSER_EVENT_QUOTE,
                 &quot;'&quot; =&gt; PARSER_EVENT_QUOTE,
             );
-        $this-&gt;wordpopEvent[PARSER_EVENT_FUNCTION_PARAMS] = array(&quot;)&quot;);
+        $this-&gt;wordpopEvent[PARSER_EVENT_FUNCTION_PARAM_VAR] = array(&quot;,&quot;, &quot;)&quot;);
 /**************************************************************/
 
         $this-&gt;tokenpushEvent[PARSER_EVENT_ARRAY] =</pre>]]></content:encoded>
      <dc:date>2006-02-23T05:50:10-00:00</dc:date>
    </item>
</rdf:RDF>