phpDocumentor phpDocumentor
[ class tree: phpDocumentor ] [ index: phpDocumentor ] [ all elements ]

Source for file Classes.inc

Documentation is available at Classes.inc

  1. <?php
  2. /**
  3.  * Intermediate class parsing structure.
  4.  *
  5.  * phpDocumentor :: automatic documentation generator
  6.  * 
  7.  * PHP versions 4 and 5
  8.  *
  9.  * Copyright (c) 2001-2007 Gregory Beaver
  10.  * 
  11.  * LICENSE:
  12.  * 
  13.  * This library is free software; you can redistribute it
  14.  * and/or modify it under the terms of the GNU Lesser General
  15.  * Public License as published by the Free Software Foundation;
  16.  * either version 2.1 of the License, or (at your option) any
  17.  * later version.
  18.  * 
  19.  * This library is distributed in the hope that it will be useful,
  20.  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  21.  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
  22.  * Lesser General Public License for more details.
  23.  * 
  24.  * You should have received a copy of the GNU Lesser General Public
  25.  * License along with this library; if not, write to the Free Software
  26.  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
  27.  *
  28.  * @category  ToolsAndUtilities
  29.  * @package   phpDocumentor
  30.  * @author    Greg Beaver <[email protected]>
  31.  * @copyright 2001-2007 Gregory Beaver
  32.  * @license   http://www.opensource.org/licenses/lgpl-license.php LGPL
  33.  * @version   CVS: $Id: Classes.inc 243933 2007-10-10 01:18:25Z ashnazg $
  34.  * @filesource
  35.  * @link      http://www.phpdoc.org
  36.  * @link      http://pear.php.net/PhpDocumentor
  37.  * @see       parserDocBlock, parserInclude, parserPage, parserClass
  38.  * @see       parserDefine, parserFunction, parserMethod, parserVar
  39.  * @since     1.0rc1
  40.  * @todo      CS cleanup - change package to PhpDocumentor
  41.  */
  42. /**
  43.  * Intermediate class parsing structure.
  44.  *
  45.  * The {@link phpDocumentor_IntermediateParser} class uses this class and its
  46.  * cousin, {@link ProceduralPages} to organize all parsed source code elements.
  47.  * Data is fed to each immediately after it is parsed, and at conversion time,
  48.  * everything is organized.
  49.  *
  50.  * The Classes class is responsible for all inheritance, including resolving
  51.  * name conflicts between classes, determining which classes extend other
  52.  * classes, and is responsible for all inheritance of documentation.
  53.  * {@internal 
  54.  * This structure parses classes, vars and methods by file, and then iterates
  55.  * over the class tree to set up inheritance.  The {@link Inherit()}
  56.  * method is the meat of the class, and processes the class trees from root to
  57.  * branch, ensuring that parsing order is unimportant.}}}
  58.  *
  59.  * @category  ToolsAndUtilities
  60.  * @package   phpDocumentor
  61.  * @author    Greg Beaver <[email protected]>
  62.  * @copyright 2001-2007 Gregory Beaver
  63.  * @license   http://www.opensource.org/licenses/lgpl-license.php LGPL
  64.  * @version   Release: @VER@
  65.  * @link      http://www.phpdoc.org
  66.  * @link      http://pear.php.net/PhpDocumentor
  67.  * @since     1.0rc1
  68.  * @todo      CS cleanup - change package to PhpDocumentor
  69.  */
  70. class Classes
  71. {
  72.     /**#@+
  73.      * @access private
  74.      */
  75.     /**
  76.      * file being parsed, used in every add function to match up elements with
  77.      * the file that contains them
  78.      *
  79.      * This variable is used during parsing to associate class elements added
  80.      * to the data structures that contain them with the file they reside in
  81.      * @see addClass(), addMethod(), addVar(), nextFile()
  82.      * @var string 
  83.      */
  84.     var $curfile;
  85.     /**
  86.      * class being parsed, used to match up methods and vars with their parent
  87.      * class
  88.      *
  89.      * This variable is used during parsing to associate class elements added
  90.      * to the data structures that contain them with the file they reside in
  91.      * @see addMethod(), addVar()
  92.      * @var string 
  93.      */
  94.     var $curclass;
  95.     
  96.     /**
  97.      * Used when a definite match is made between a parent class and a child
  98.      * class
  99.      *
  100.      * This variable is used in post-parsing.
  101.      *
  102.      * Format:<pre>
  103.      * array(
  104.      *     parent => array(
  105.      *         parentfile => array(
  106.      *             child => childfile
  107.      *         )
  108.      *     )
  109.      * )</pre>
  110.      * @var array 
  111.      */
  112.     var $definitechild;
  113.     /**
  114.      * array of parsed classes organized by the name of the file that contains
  115.      * the class.
  116.      *
  117.      * Format:<pre>
  118.      * array(
  119.      *     filename => array(
  120.      *         classname => {@link parserClass}
  121.      *     )
  122.      * )</pre>
  123.      * @var array 
  124.      */
  125.     var $classesbyfile array();
  126.     /**
  127.      * array of file names organized by classes that are in the file.
  128.      *
  129.      * This structure is designed to handle name conflicts.  Two files can
  130.      * contain classes with the same name, and this array will record both
  131.      * filenames to help control linking and inheritance errors
  132.      *
  133.      * Format:<pre>
  134.      * array(
  135.      *     classname => array(
  136.      *         name of file containing classname,
  137.      *         name of file 2 containing classname,
  138.      *         ...
  139.      *     )
  140.      * )</pre>
  141.      * @var array 
  142.      */
  143.     var $classesbynamefile array();
  144.     /**
  145.      * array of parsed methods organized by the file that contains them.
  146.      *
  147.      * Format:<pre>
  148.      * array(
  149.      *     filename => array(
  150.      *         classname => array(
  151.      *             {@link parserMethod} 1,
  152.      *             {@link parserMethod} 2,
  153.      *             ...
  154.      *         )
  155.      *     )
  156.      * )</pre>
  157.      * @var array 
  158.      */
  159.     var $methodsbyfile array();
  160.     /**
  161.      * array of parsed vars organized by the file that contains them.
  162.      *
  163.      * Format:<pre>
  164.      * array(
  165.      *     filename => array(
  166.      *         classname => array(
  167.      *             {@link parserVar} 1,
  168.      *             {@link parserVar} 2,
  169.      *             ...
  170.      *         )
  171.      *     )
  172.      * )</pre>
  173.      * @var array 
  174.      */
  175.     var $varsbyfile array();
  176.     /**
  177.      * array of parsed class constants organized by the file that contains them.
  178.      *
  179.      * Format:<pre>
  180.      * array(
  181.      *     filename => array(
  182.      *         classname => array(
  183.      *             {@link parserConst} 1,
  184.      *             {@link parserConst} 2,
  185.      *             ...
  186.      *         )
  187.      *     )
  188.      * )</pre>
  189.      * @var array 
  190.      */
  191.     var $constsbyfile array();
  192.     /**
  193.      * keeps track of extend declarations by file, used to find inheritance
  194.      *
  195.      * Format:<pre>
  196.      * array(
  197.      *     filename => array(
  198.      *         classname => parentclassname
  199.      *     )
  200.      * )</pre>
  201.      * @var array 
  202.      */
  203.     var $extendsbyfile array();
  204.     /**
  205.      * Keeps track of child classes by file.
  206.      * Since phpDocumentor can document collections of files that contain name
  207.      * conflicts (PHP would give a fatal error), it
  208.      * is impossible to assume a class that declares "extends foo" necessarily
  209.      * extends the class foo in file X.  It could be an
  210.      * extended class of class foo in file Y.  Because of this, phpDocumentor
  211.      * relies on packaging to resolve the name conflict
  212.      * This array keeps track of the packages of a child class
  213.      *
  214.      * Format:<pre>
  215.      * array(
  216.      *     parentclassname => array(
  217.      *         filename => array(
  218.      *             childclassname => array(
  219.      *                 packagename,
  220.      *                 packagename
  221.      *             )
  222.      *         )
  223.      *     )
  224.      * )</pre>
  225.      * @var array 
  226.      */
  227.     var $classchildrenbyfile array();
  228.     /**
  229.      * Keeps track of class packages found in a file.
  230.      * This is used in {@link getParentClass()} to determine the number of
  231.      * packages in a file, in order to resolve inheritance issues
  232.      * Format:<pre>
  233.      * array(
  234.      *     filename => array(
  235.      *         packagename1,
  236.      *         packagename2,
  237.      *         ...
  238.      *     )
  239.      * )</pre>
  240.      * @var array 
  241.      */
  242.     var $classpackagebyfile array();
  243.     /**
  244.      * a tree of class inheritance by name.
  245.      *
  246.      * Format:<pre>
  247.      * array(
  248.      *     childname => parentname,
  249.      *     childname1 => parentname1,
  250.      *     rootname => 0,
  251.      *     ...
  252.      * )</pre>
  253.      * @var array 
  254.      * @see Converter::generateSortedClassTreeFromClass()
  255.      */
  256.     var $classparents array();
  257.     /**
  258.      * Keeps track of package and subpackage for each class name, organized
  259.      * by package
  260.      *
  261.      * Format:<pre>
  262.      * array(
  263.      *     classname => array(
  264.      *         path => array(
  265.      *             package,
  266.      *             subpackage
  267.      *         ),
  268.      *         path2 => array(
  269.      *             package,
  270.      *             subpackage
  271.      *         ),
  272.      *         ...
  273.      *     )
  274.      * )</pre>
  275.      * @var array 
  276.      */
  277.     var $classpathpackages array();
  278.     /**
  279.      * used to delete duplicates in the same package to avoid documentation errors
  280.      *
  281.      * Specifically used in {@link Converter::checkKillClass()}
  282.      */
  283.     var $killclass array();
  284.     /**
  285.      * array of methods by package and class
  286.      *
  287.      * format:<pre>
  288.      * array(packagename =>
  289.      *         array(classname =>
  290.      *               array(methodname1 => {@link parserMethod} class,
  291.      *                     methodname2 => {@link parserMethod} class,...)
  292.      *                      )
  293.      *              )
  294.      *      )</pre>
  295.      * @var array 
  296.      * @see Converter
  297.      */
  298.     var $methods array();
  299.     
  300.     /**
  301.      * array of class variables by package and class
  302.      *
  303.      * format:<pre>
  304.      * array(packagename =>
  305.      *         array(classname =>
  306.      *                array(variablename1 => {@link parserVar} class,
  307.      *                      variablename2 => {@link parserVar} class,...
  308.      *                     )
  309.      *              )
  310.      *      )</pre>
  311.      * @var array 
  312.      * @see Converter
  313.      */
  314.     var $vars array();
  315.     
  316.     /**
  317.      * array of class variables by package and class
  318.      *
  319.      * format:<pre>
  320.      * array(packagename =>
  321.      *         array(classname =>
  322.      *                array(constname1 => {@link parserConst} class,
  323.      *                      constname2 => {@link parserConst} class,...
  324.      *                     )
  325.      *              )
  326.      *      )</pre>
  327.      * @var array 
  328.      * @see Converter
  329.      */
  330.     var $consts array();
  331.     /**
  332.      * Reverse class_packages_by_file, used to prevent duplicates
  333.      * @var array Format: array(packagename => 1)
  334.      */
  335.     var $revcpbf array();
  336.     /**
  337.      * All classes with no parents (no extends clause) are tracked in this array
  338.      * by the file that contains them.
  339.      *
  340.      * Format:<pre>
  341.      * array(
  342.      *     classname => array(
  343.      *         name of file1 that contains root classname,
  344.      *         name of file2 that contains root classname,
  345.      *         ...
  346.      *     )
  347.      * )</pre>
  348.      * @var array 
  349.      */
  350.     var $roots array();
  351.     /**
  352.      * All classes with a parent that was not parsed are included in this array
  353.      *
  354.      * Format:<pre>
  355.      * array(
  356.      *     classname => array(
  357.      *         name of file1 that contains root classname,
  358.      *         name of file2 that contains root classname,
  359.      *         ...
  360.      *     )
  361.      * )</pre>
  362.      * @var array 
  363.      */
  364.     var $specialRoots array();
  365.     
  366.     /**
  367.      * array of all files that contain classes with the same name
  368.      * @var array Format: (classname => array(path1, path2,...))
  369.      */
  370.     var $potentialclassconflicts array();
  371.     
  372.     /**
  373.      * array of all inter-package name conflicts of classes
  374.      *
  375.      * This array allows documentation of PHP namespace conflicts that would
  376.      * occur should a user try to include these files in the same file
  377.      * @var array Format: (classname => array(path1, path2,...))
  378.      */
  379.     var $classconflicts array();
  380.     /**#@-*/
  381.     /**
  382.      * While parsing, add a class to the list of parsed classes
  383.      *
  384.      * sets up the {@link $classesbyfile, $classesbynamefile, $extendsbyfile},
  385.      * {@link $classchildrenbyfile, $roots} arrays, and sets {@link $curclass}
  386.      *
  387.      * @param parserClass &$element element is a {@link parserClass}
  388.      *
  389.      * @return void 
  390.      * @uses addPackageToFile() marks the current class's package as being
  391.      *                           present in a file
  392.      */
  393.     function addClass(&$element)
  394.     {
  395.         $this->curclass   $element->getName();
  396.         $element->curfile $this->curfile;
  397.         if (isset($this->classesbyfile[$this->curfile][$this->curclass])) {
  398.             addWarning(PDERROR_ELEMENT_IGNORED
  399.                 'class'$this->curclass$this->curfile);
  400.             $this->curclass false;
  401.             return;
  402.         }
  403.         $this->
  404.             
  405. classesbyfile
  406.                 [$this->curfile][$this->curclass]
  407.             = $element;
  408.         $this->
  409.             classesbynamefile[$this->curclass][]
  410.             = $this->curfile;
  411.         $this->
  412.             extendsbyfile[$this->curfile][$this->curclass]
  413.             = $element->getExtends();
  414.         $this->
  415.             classchildrenbyfile[$element->getExtends()]
  416.                 [$this->curfile][$this->curclass][
  417.             = $element->docblock->package;
  418.         if ($element->docblock->getExplicitPackage())
  419.         $this->addPackageToFile($element->docblock->package);
  420.         if (!$element->getExtends()) {
  421.             $this->roots[$this->curclass][$this->curfile;
  422.         }
  423.     }
  424.     
  425.     /**
  426.      * While parsing, add a method to the list of parsed methods
  427.      *
  428.      * sets up the {@link $methodsbyfile} array using {@link $curfile} and
  429.      * {@link $curclass}
  430.      *
  431.      * @param parserMethod &$element element is a {@link parserMethod}
  432.      *
  433.      * @return void 
  434.      */
  435.     function addMethod(&$element)
  436.     {
  437.         if (!$this->curclassreturn;
  438.         $this->methodsbyfile[$this->curfile][$this->curclass][$element;
  439.     }
  440.     
  441.     /**
  442.      * While parsing, add a variable to the list of parsed variables
  443.      *
  444.      * sets up the {@link $varsbyfile} array using {@link $curfile}
  445.      * and {@link $curclass}
  446.      *
  447.      * @param parserVar &$element element is a {@link parserVar}
  448.      *
  449.      * @return void 
  450.      */
  451.     function addVar(&$element)
  452.     {
  453.         if (!$this->curclassreturn;
  454.         $this->varsbyfile[$this->curfile][$this->curclass][$element;
  455.     }
  456.     
  457.     /**
  458.      * While parsing, add a variable to the list of parsed variables
  459.      *
  460.      * sets up the {@link $constsbyfile} array using {@link $curfile}
  461.      * and {@link $curclass}
  462.      *
  463.      * @param parserConst &$element element is a {@link parserConst}
  464.      *
  465.      * @return void 
  466.      */
  467.     function addConst(&$element)
  468.     {
  469.         if (!$this->curclassreturn;
  470.         $this->constsbyfile[$this->curfile][$this->curclass][$element;
  471.     }
  472.     
  473.     /**
  474.      * Prepare to parse a new file
  475.      *
  476.      * sets {@link $curfile} to $file and {@link $curclass}
  477.      * to false (no class being parsed)
  478.      *
  479.      * @param string $file file currently being parsed
  480.      *
  481.      * @return void 
  482.      */
  483.     function nextFile($file)
  484.     {
  485.         $this->curfile  $file;
  486.         $this->curclass false;
  487.     }
  488.     
  489.     /**
  490.      * Mark a package as being used in a class
  491.      *
  492.      * {@source } 
  493.      *
  494.      * @param string $package package name
  495.      *
  496.      * @return void 
  497.      */
  498.     function addPackageToFile($package)
  499.     {
  500.         if (!isset($this->revcpbf[$this->curfile][$package]))
  501.         $this->classpackagebyfile[$this->curfile][$package;
  502.         $this->revcpbf[$this->curfile][$package]    1;
  503.     }
  504.     
  505.     /**
  506.      * Find the parent class of $class, and set up structures to note this fact
  507.      *
  508.      * Modifies the {@link parserClass} element in {@link $classesbyfile} to use
  509.      * the parent's package, and inherit methods/vars
  510.      *
  511.      * @param string $class child class to find parent class
  512.      * @param string $file  file child class is located in
  513.      *
  514.      * @return void 
  515.      * @uses $definitechild if a match is made between a parent class and parameter
  516.      *                       $class in file $file, then definitechild is set here
  517.      * @uses getParentClass() to find the parent class
  518.      */
  519.     function setClassParent($class,$file)
  520.     {
  521.         if (is_array($par $this->getParentClass($class$file))) {
  522.             // (for debugging)
  523.             // phpDocumentor_out("$file class $class extends "
  524.             //    . $par[1] ." file ". $par[0] . "\n");
  525.  
  526.             $this->classesbyfile[$file][$class]->setParent($par[1]$par[0]$this);
  527.             $this->definitechild[$par[1]][$par[0]][$class$file;
  528.         else {
  529.             $this->classesbyfile[$file][$class]->setParentNoClass($par);
  530.         }
  531.     }
  532.     
  533.     /**
  534.      * Main processing engine for setting up class inheritance.
  535.      *
  536.      * This function uses {@link $roots} to traverse the inheritance tree via
  537.      * {@link processChild()} and returns the data structures
  538.      * phpDocumentor_IntermediateParser needs to convert parsed data
  539.      * to output using {@link phpDocumentor_IntermediateParser::Convert()}
  540.      *
  541.      * @param phpDocumentor_IntermediateParser &$render the renderer object
  542.      *
  543.      * @return void 
  544.      * @uses processChild() set up inheritance
  545.      * @todo CS Cleanup - rename to "inherit" for CamelCaps naming standard
  546.      */
  547.     function Inherit(&$render)
  548.     {
  549.         phpDocumentor_out("\nProcessing Class Inheritance\n\n");
  550.         flush();
  551.         phpDocumentor_out("\nProcessing Root Trees\n\n");
  552.         flush();
  553.         foreach ($this->roots as $class => $files{
  554.             for ($i=0$i<count($files)$i++{
  555.                 $this->processChild($render$class$files[$i]);
  556.             }
  557.         }
  558.         if (0)
  559.         foreach ($this->classesbyfile as $i => $j{
  560.             foreach ($j as $k => $m{
  561.                 var_dump($i$k);
  562.                 if ($i == 'iConverter'{
  563.                     var_dump($j);
  564.                 }
  565.             }
  566.         }
  567.         phpDocumentor_out("\nProcessing leftover classes "
  568.             . "(classes that extend root classes not found in the same package)\n");
  569.         flush();
  570.         foreach ($this->classesbyfile as $i => $j{
  571.             foreach ($j as $k => $m{
  572.                 $this->processChild($render$k$itrue);
  573.             }
  574.         }
  575.         phpDocumentor_out("done processing leftover classes\n");
  576.         flush();
  577.         $this->setupClassConflicts();
  578.     }
  579.     
  580.     /**
  581.      * Transfers actual conflicts from {@link $potentialClassconflicts} to
  582.      * {@link $classconflicts}
  583.      *
  584.      * @return void 
  585.      * @access private
  586.      * @uses $potentialclassconflicts transfers values to {@link $classconflicts}
  587.      */
  588.     function setupClassConflicts()
  589.     {
  590.         foreach ($this->potentialclassconflicts as $class => $paths{
  591.             if (count($paths1//conflict
  592.                 $package array();
  593.                 foreach ($paths as $path{
  594.                     // create a list of conflicting classes in each package
  595.                     if (isset($this->classpathpackages[$class][$path]))
  596.                     $package[$this->classpathpackages[$class][$path][0]][$path;
  597.                 }
  598.                 foreach ($package as $pathpackages{
  599.                     /*
  600.                      * if at least 2 functions exist in the same package, 
  601.                      * delete all but the first one and add warnings
  602.                      */
  603.                     if (count($pathpackages1{
  604.                         for ($i=1$i count($pathpackages)$i++{
  605.                             if (isset($this->classesbyfile[$pathpackages[$i]])) {
  606.                                 addWarning(PDERROR_ELEMENT_IGNORED
  607.                                     'class'$class$pathpackages[$i]);
  608.                                 $this->killClass($class$pathpackages[$i]);
  609.                                 $oth array_flip($paths);
  610.                                 unset($paths[$oth[$pathpackages[$i]]]);
  611.                             }
  612.                         }
  613.                     }
  614.                 }
  615.                 $this->classconflicts[$class$paths;
  616.             }
  617.         }
  618.     }
  619.     
  620.     /**
  621.      * If a package contains two classes with the same name, this function finds
  622.      * that conflict
  623.      *
  624.      * Returns the {@link $classconflicts} entry for class $class, minus its own path
  625.      *
  626.      * @param mixed $class the class name to search for
  627.      *
  628.      * @return mixed returns false if no conflicts,
  629.      *                or an array of paths containing conflicts
  630.      */
  631.     function getConflicts($class)
  632.     {
  633.         if (!isset($this->classconflicts[$class])) return false;
  634.         $a array();
  635.         foreach ($this->classconflicts[$classas $conflict{
  636.             $a[$this->classesbyfile[$conflict][$class]->docblock->package
  637.                 = $this->classesbyfile[$conflict][$class];
  638.         }
  639.         return $a;
  640.     }
  641.     
  642.     /**
  643.      * sets up {@link $killclass} for use by Converter::checkKillClass()
  644.      *
  645.      * @param mixed $class the class
  646.      * @param mixed $path  the path
  647.      *
  648.      * @return void 
  649.      * @access private
  650.      */
  651.     function killClass($class,$path)
  652.     {
  653.         $this->killclass[$class][$pathtrue;
  654.     }
  655.     
  656.     /**
  657.      * This function recursively climbs up the class tree, setting inherited
  658.      * information like package and adds the elements to
  659.      * {@link phpDocumentor_IntermediateParser}.
  660.      *
  661.      * Using structures defined in {@link Classes},
  662.      * the function first sets package information,
  663.      * and then seeks out child classes.
  664.      * It uses 3 tests to determine whether a class is a child class.
  665.      * <ol>
  666.      *    <li>child class is in the same file as the parent class
  667.      *        and extends parent class
  668.      *    </li>
  669.      *    <li>child class is in a different file and specifies
  670.      *        the parent's @package in its docblock
  671.      *    </li>
  672.      *    <li>child class is in a different file and is in a
  673.      *        different @package, with one possible parent class
  674.      *    </li>
  675.      * </ol>
  676.      *
  677.      * @param phpDocumentor_IntermediateParser &$render the renderer object
  678.      * @param string                           $class   class to process
  679.      * @param string                           $file    name of file $class
  680.      *                                                   is located in
  681.      * @param boolean                          $furb    flag used privately
  682.      *                                                   to control informational
  683.      *                                                   output while parsing
  684.      *                                                   (used when processing
  685.      *                                                   leftover classes in
  686.      *                                                   {@link Inherit()}
  687.      *
  688.      * @return void 
  689.      * @global string default package, usually "default"
  690.      */
  691.     function processChild(&$render,$class,$file,$furb false)
  692.     {
  693.         global $phpDocumentor_DefaultPackageName;
  694.         if (isset($this->classesbyfile[$file][$class]->processed))
  695.             return;
  696.         $this->potentialclassconflicts[$class][$file;
  697.         if ($furb)
  698.             phpDocumentor_out("Processing $class in file $file\n");
  699.         flush();
  700.         $this->classesbyfile[$file][$class]->processed true;
  701.  
  702.         $db $this->classesbyfile[$file][$class];
  703.         $render->addUses($db$file);
  704.         if (!$render->parsePrivate{
  705.             /*
  706.              * if this class has an @access private, 
  707.              * and parse private is disabled, remove it
  708.              */
  709.             if ($db->docblock->hasaccess{
  710.                 $aaa $db->docblock->getKeyword('access');
  711.                 if (is_object($aaa&& $aaa->getString(== 'private'{
  712.                     if (isset($this->varsbyfile[$file]
  713.                         && isset($this->varsbyfile[$file][$class])) {
  714.                         unset($this->varsbyfile[$file][$class]);
  715.                     }
  716.                     if (isset($this->methodsbyfile[$file]
  717.                         && isset($this->methodsbyfile[$file][$class])) {
  718.                         unset($this->methodsbyfile[$file][$class]);
  719.                     }
  720.                     if (isset($this->constsbyfile[$file]
  721.                         && isset($this->constsbyfile[$file][$class])) {
  722.                         unset($this->constsbyfile[$file][$class]);
  723.                     }
  724.                     $this->classesbyfile[$file][$class]->ignore true;
  725.                     // if this is a root class, remove it from the roots array
  726.                     if (isset($this->roots[$class])) {
  727.                         foreach ($this->roots[$classas $i => $files{
  728.                             // find the file key and unset
  729.                             if ($files == $file
  730.                                 unset($this->roots[$class][$i]);
  731.                         }
  732.                     }
  733.                     /*
  734.                      * if this is a child, remove it from the list 
  735.                      * of child classes of its parent
  736.                      */
  737.                     if ($db->getExtends()) 
  738.                         unset($this->classchildrenbyfile[$db->getExtends()][$file]);
  739.                     return;
  740.                 }
  741.             }
  742.         }
  743.         if ($render->packageoutput{
  744.             if (!in_array($db->docblock->package$render->packageoutput)) {
  745.                 if (isset($this->varsbyfile[$file]
  746.                     && isset($this->varsbyfile[$file][$class])) {
  747.                     unset($this->varsbyfile[$file][$class]);
  748.                 }
  749.                 if (isset($this->methodsbyfile[$file]
  750.                     && isset($this->methodsbyfile[$file][$class])) {
  751.                     unset($this->methodsbyfile[$file][$class]);
  752.                 }
  753.                 if (isset($this->constsbyfile[$file]
  754.                     && isset($this->constsbyfile[$file][$class])) {
  755.                     unset($this->constsbyfile[$file][$class]);
  756.                 }
  757.                 $this->classesbyfile[$file][$class]->ignore true;
  758.                 if (isset($this->roots[$class])) {
  759.                     foreach ($this->roots[$classas $i => $files{
  760.                         if ($files == $fileunset($this->roots[$class][$i]);
  761.                     }
  762.                 }
  763.                 if ($db->getExtends()) 
  764.                     unset($this->classchildrenbyfile[$db->getExtends()][$file]);
  765.                 return;
  766.             }
  767.         }
  768.         $this->setClassParent($class$file);
  769.         $db $this->classesbyfile[$file][$class];
  770.         if ($furb && !is_array($db->parent)) {
  771.             // debug("furb adding $class $file to roots");
  772.             $this->specialRoots[$db->parent][array($class$file);
  773.         }
  774.         // fix for 591396
  775.         if (!$db->docblock->getExplicitPackage()) {
  776.             $a $render->proceduralpages->pagepackages[$file];
  777.             if ($a[0!= $phpDocumentor_DefaultPackageName{
  778.                 // inherit page package
  779.                 $this->classesbyfile[$file][$class]->docblock->package $a[0];
  780.             }
  781.         }
  782.         if ($this->classesbyfile[$file][$class]->docblock->package 
  783.             == $render->proceduralpages->pagepackages[$file][0]{
  784.             if ($this->classesbyfile[$file][$class]->docblock->subpackage == ''{
  785.                 $this->classesbyfile[$file][$class]->docblock->subpackage 
  786.                     = $render->proceduralpages->pagepackages[$file][1];
  787.             }
  788.         }
  789.         $db $this->classesbyfile[$file][$class];
  790.         $render->addPackageParent($db);
  791.         $render->addPageIfNecessary($file$db);
  792.         if ($access $db->docblock->getKeyword('access')) {
  793.             if (!is_string($access&& is_object($access)) 
  794.                 $access $access->getString();
  795.             if (!is_string($access)) 
  796.                 $access 'public';
  797.             if (($access == 'private'&& (!$render->parsePrivate)) {
  798.                 if (isset($this->varsbyfile[$file]
  799.                     && isset($this->varsbyfile[$file][$class])) {
  800.                     foreach ($this->varsbyfile[$file][$classas $i => $vr{
  801.                         $vr->docblock->addKeyword('access''private');
  802.                         $this->varsbyfile[$file][$class][$i$vr;
  803.                     }
  804.                 }
  805.                 if (isset($this->methodsbyfile[$file]
  806.                     && isset($this->methodsbyfile[$file][$class])) {
  807.                     foreach ($this->methodsbyfile[$file][$classas $i => $vr{
  808.                         $vr->docblock->addKeyword('access''private');
  809.                         $this->methodsbyfile[$file][$class][$i$vr;
  810.                     }
  811.                 }
  812.                 if (isset($this->constsbyfile[$file]
  813.                     && isset($this->constsbyfile[$file][$class])) {
  814.                     foreach ($this->constsbyfile[$file][$classas $i => $vr{
  815.                         $vr->docblock->addKeyword('access''private');
  816.                         $this->constsbyfile[$file][$class][$i$vr;
  817.                     }
  818.                 }
  819.             }
  820.         }
  821.         $this->classpathpackages[$class][$file
  822.             = array($db->docblock->package,$db->docblock->subpackage);
  823.         if ($db->docblock->getExplicitPackage()) {
  824.             $render->proceduralpages->
  825.                 addClassPackageToFile($file
  826.                     $db->docblock->package$db->docblock->subpackage);
  827.         }
  828.         $render->addElementToPage($db$file);
  829.         if (isset($this->varsbyfile[$file]
  830.             && isset($this->varsbyfile[$file][$class])) {
  831.             foreach ($this->varsbyfile[$file][$classas $i => $vr{
  832.                 $vr->docblock->package    $db->docblock->package;
  833.                 $vr->docblock->subpackage $db->docblock->subpackage;
  834.                 $render->addElementToPage($vr$file);
  835.                 $render->addUses($vr$file);
  836.                 $this->varsbyfile[$file][$class][$i]                        $vr;
  837.                 $this->vars[$db->docblock->package][$class][$vr->getName()$vr;
  838.             }
  839.         }
  840.         if (isset($this->methodsbyfile[$file]
  841.             && isset($this->methodsbyfile[$file][$class])) {
  842.             foreach ($this->methodsbyfile[$file][$classas $i => $vr{
  843.                 $vr->docblock->package    $db->docblock->package;
  844.                 $vr->docblock->subpackage $db->docblock->subpackage;
  845.                 $render->addElementToPage($vr$file);
  846.                 $render->addUses($vr$file);
  847.                 $this->methodsbyfile[$file][$class][$i]                        $vr;
  848.                 $this->methods[$db->docblock->package][$class][$vr->getName()$vr;
  849.             }
  850.         }
  851.         if (isset($this->constsbyfile[$file]
  852.             && isset($this->constsbyfile[$file][$class])) {
  853.             foreach ($this->constsbyfile[$file][$classas $i => $vr{
  854.                 $vr->docblock->package    $db->docblock->package;
  855.                 $vr->docblock->subpackage $db->docblock->subpackage;
  856.                 $render->addElementToPage($vr$file);
  857.                 $render->addUses($vr$file);
  858.                 $this->constsbyfile[$file][$class][$i]                         $vr;
  859.                 $this->methods[$db->docblock->package][$class][$vr->getName()$vr;
  860.             }
  861.         }
  862.         $this->classpackages[$class][
  863.             = array($db->docblock->package,$db->docblock->subpackage);
  864.         if (is_array($db->parent))
  865.             $this->classparents[$db->docblock->package][$class$db->parent[1];
  866.         else
  867.             $this->classparents[$db->docblock->package][$class$db->getExtends();
  868.         if (is_array($db->parent)) {
  869.             $z $this->getClass($db->parent[1]$db->parent[0]);
  870.  
  871.             $this->classchildren[$z->docblock->package][$db->parent[1]][$db;
  872.         }
  873.         if (isset($this->classchildrenbyfile[$class])) {
  874.             foreach ($this->classchildrenbyfile[$classas $childfile => $other{
  875.                 // test 1, inherits in same file (must be same package)
  876.                 if ($childfile == $file{
  877.                     foreach ($other as $child => $packages{
  878.                         // debug("parent $class same file $child");
  879.                         $this->processChild($render$child$childfile);
  880.                         $x $this->getClass($child$childfile);
  881.                         if ($x->docblock->package 
  882.                             != $GLOBALS['phpDocumentor_DefaultPackageName']{
  883.                             // child package need root for class trees
  884.                             if ($x->docblock->package != $db->docblock->package{
  885.                                 // debug("adding $child in $childfile 1");
  886.                                 $this->roots[$child][$childfile;
  887.                             }
  888.                         }
  889.                     }
  890.                 else {
  891.                     // test 2, different file, same package
  892.                     foreach ($other as $child => $packages{
  893.                         for ($j=0$j<count($packages)$j++{
  894.                             if ($this->classesbyfile[$file][$class]->
  895.                                     docblock->package == $packages[$j]{
  896.                                 $this->processChild($render$child$childfile);
  897.                                 // debug("$childfile diff file $child, parent $class,
  898.                                 //     same package ".$packages[$j]);
  899.                             else {
  900.                                 /*
  901.                                  * test 3, different file, different package, 
  902.                                  * only 1 parent is possible
  903.                                  */
  904.                                 if (isset($this->classesbynamefile[$child])) {
  905.                                     // 1 possible parent
  906.                                     if (count($this->classesbynamefile[$class]
  907.                                         == 1{
  908.                                         // debug("$childfile diff file $child, 
  909.                                         //        diff package, 
  910.                                         //        1 possible parent root $class");
  911.                                         $this->processChild($render
  912.                                             $child$childfile);
  913.                                         $x $this->getClass($child$childfile);
  914.                                         if ($x->docblock->package 
  915.                                           != $GLOBALS
  916.                                           ['phpDocumentor_DefaultPackageName']{
  917.                                             // child package need root 
  918.                                             //for class trees
  919.                                             if ($x->docblock->package 
  920.                                                 != $db->docblock->package{
  921.                                                 // debug("adding roots 
  922.                                                 // $child in $childfile 2");
  923.                                                 $this->roots[$child][$childfile;
  924.                                             }
  925.                                         }
  926.                                     }
  927.                                 }
  928.                             }
  929.                         }
  930.                     }
  931.                 }
  932.             }
  933.         }
  934.     }
  935.     
  936.     /**
  937.      * Get the parserClass representation of a class from its name and file
  938.      *
  939.      * @param string $class classname
  940.      * @param string $file  file classname is located in
  941.      *
  942.      * @return parserClass 
  943.      */
  944.     function &getClass($class$file)
  945.     {
  946.         // debug("getClass called with class $class file $file");
  947.         return $this->classesbyfile[$file][$class];
  948.     }
  949.     
  950.     /**
  951.      * Used by {@link parserData::getClasses()}
  952.      * to retrieve classes defined in file $path
  953.      *
  954.      * retrieves the array entry from {@link $classesbyfile} for $path
  955.      *
  956.      * @param string $path full path to filename
  957.      *
  958.      * @return mixed returns false if no classes defined in the file,
  959.      *                otherwise returns an array of {@link parserClass}es
  960.      */
  961.     function getClassesInPath($path)
  962.     {
  963.         if (!isset($this->classesbyfile[$path])) return false;
  964.         return $this->classesbyfile[$path];
  965.     }
  966.     
  967.     /**
  968.      * called by {@link parserClass::hasMethods()}.  Should not be directly called
  969.      *
  970.      * @param string $file  file classname is located in
  971.      * @param string $class classname
  972.      *
  973.      * @return bool 
  974.      * @access private
  975.      */
  976.     function hasMethods($file$class)
  977.     {
  978.         return isset($this->methodsbyfile[$file][$class]);
  979.     }
  980.     
  981.     /**
  982.      * called by {@link parserClass::hasConsts()}.
  983.      * Should not be directly called
  984.      *
  985.      * @param string $file  file classname is located in
  986.      * @param string $class classname
  987.      *
  988.      * @return bool 
  989.      * @access private
  990.      */
  991.     function hasConsts($file,$class)
  992.     {
  993.         return isset($this->constsbyfile[$file][$class]);
  994.     }
  995.     
  996.     /**
  997.      * called by {@link parserClass::hasVars()}.  Should not be directly called
  998.      *
  999.      * @param string $file  file classname is located in
  1000.      * @param string $class classname
  1001.      *
  1002.      * @return bool 
  1003.      * @access private
  1004.      */
  1005.     function hasVars($file$class)
  1006.     {
  1007.         return isset($this->varsbyfile[$file][$class]);
  1008.     }
  1009.     
  1010.     /**
  1011.      * called by {@link parserClass::hasMethod()}.  Should not be directly called
  1012.      *
  1013.      * @param string $class classname
  1014.      * @param string $file  file classname is located in
  1015.      * @param string $name  method name
  1016.      *
  1017.      * @return bool 
  1018.      * @access private
  1019.      */
  1020.     function hasMethod($class$file$name)
  1021.     {
  1022.         if (!$this->hasMethods($file$class)) return false;
  1023.         for ($i=0$i<count($this->methodsbyfile[$file][$class])$i++{
  1024.             if ($this->methodsbyfile[$file][$class][$i]->getName(== $name
  1025.                return true;
  1026.         }
  1027.         return false;
  1028.     }
  1029.     
  1030.     /**
  1031.      * called by {@link parserClass::hasVar()}.  Should not be directly called
  1032.      *
  1033.      * @param string $class classname
  1034.      * @param string $file  file classname is located in
  1035.      * @param string $name  var name
  1036.      *
  1037.      * @return bool 
  1038.      * @access private
  1039.      */
  1040.     function hasVar($class$file$name)
  1041.     {
  1042.         if (!$this->hasVars($file$class)) return false;
  1043.         for ($i=0$i<count($this->varsbyfile[$file][$class])$i++{
  1044.             if ($this->varsbyfile[$file][$class][$i]->getName(== $name
  1045.                 return true;
  1046.         }
  1047.         return false;
  1048.     }
  1049.     
  1050.     /**
  1051.      * called by {@link parserClass::hasConst()}.  Should not be directly called
  1052.      *
  1053.      * @param string $class classname
  1054.      * @param string $file  file classname is located in
  1055.      * @param string $name  constant name
  1056.      *
  1057.      * @return bool 
  1058.      * @access private
  1059.      */
  1060.     function hasConst($class$file$name)
  1061.     {
  1062.         if (!$this->hasConsts($file$class)) return false;
  1063.         for ($i=0$i<count($this->constsbyfile[$file][$class])$i++{
  1064.             if ($this->constsbyfile[$file][$class][$i]->getName(== $name
  1065.                 return true;
  1066.         }
  1067.         return false;
  1068.     }
  1069.     
  1070.     /**
  1071.      * called by {@link parserClass::getMethods()}.  Should not be directly called
  1072.      *
  1073.      * @param string $class classname
  1074.      * @param string $file  file classname is located in
  1075.      *
  1076.      * @return mixed 
  1077.      * @access private
  1078.      */
  1079.     function &getMethods($class$file)
  1080.     {
  1081.         if (!isset($this->methodsbyfile[$file][$class])) {
  1082.             $flag false;
  1083.             return $flag;
  1084.         }
  1085.         return $this->methodsbyfile[$file][$class];
  1086.     }
  1087.     
  1088.     /**
  1089.      * called by {@link parserClass::getVars()}.  Should not be directly called
  1090.      *
  1091.      * @param string $class classname
  1092.      * @param string $file  file classname is located in
  1093.      *
  1094.      * @return mixed 
  1095.      * @access private
  1096.      */
  1097.     function &getVars($class$file)
  1098.     {
  1099.         if (!isset($this->varsbyfile[$file][$class])) {
  1100.             $flag false;
  1101.             return $flag;
  1102.         }
  1103.         return $this->varsbyfile[$file][$class];
  1104.     }
  1105.     
  1106.     /**
  1107.      * called by {@link parserClass::getConsts()}.  Should not be directly called
  1108.      *
  1109.      * @param string $class classname
  1110.      * @param string $file  file classname is located in
  1111.      *
  1112.      * @return mixed 
  1113.      * @access private
  1114.      */
  1115.     function &getConsts($class$file)
  1116.     {
  1117.         if (!isset($this->constsbyfile[$file][$class])) {
  1118.             $flag false;
  1119.             return $flag;
  1120.         }
  1121.         return $this->constsbyfile[$file][$class];
  1122.     }
  1123.     
  1124.     /**
  1125.      * called by {@link parserClass::getMethod()}.  Should not be directly called
  1126.      *
  1127.      * @param string $class classname
  1128.      * @param string $file  file classname is located in
  1129.      * @param string $name  method name
  1130.      *
  1131.      * @return mixed 
  1132.      * @access private
  1133.      */
  1134.     function getMethod($class$file$name)
  1135.     {
  1136.         if (!$this->hasMethod($class$file$name)) return false;
  1137.         for ($i=0$i<count($this->methodsbyfile[$file][$class])$i++{
  1138.             if ($this->methodsbyfile[$file][$class][$i]->getName(== $name
  1139.                 return $this->methodsbyfile[$file][$class][$i];
  1140.         }
  1141.     }
  1142.     
  1143.     /**
  1144.      * called by {@link parserClass::getVar()}.  Should not be directly called
  1145.      *
  1146.      * @param string $class classname
  1147.      * @param string $file  file classname is located in
  1148.      * @param string $name  var name
  1149.      *
  1150.      * @return mixed 
  1151.      * @access private
  1152.      */
  1153.     function getVar($class$file$name)
  1154.     {
  1155.         if (!$this->hasVar($class$file$name)) return false;
  1156.         for ($i=0$i<count($this->varsbyfile[$file][$class])$i++{
  1157.             if ($this->varsbyfile[$file][$class][$i]->getName(== $name
  1158.                 return $this->varsbyfile[$file][$class][$i];
  1159.         }
  1160.     }
  1161.     
  1162.     /**
  1163.      * called by {@link parserClass::getConst()}.  Should not be directly called
  1164.      *
  1165.      * @param string $class classname
  1166.      * @param string $file  file classname is located in
  1167.      * @param string $name  const name
  1168.      *
  1169.      * @return mixed 
  1170.      * @access private
  1171.      */
  1172.     function getConst($class$file$name)
  1173.     {
  1174.         if (!$this->hasConst($class$file$name)) return false;
  1175.         for ($i=0$i<count($this->constsbyfile[$file][$class])$i++{
  1176.             if ($this->constsbyfile[$file][$class][$i]->getName(== $name
  1177.                 return $this->constsbyfile[$file][$class][$i];
  1178.         }
  1179.     }
  1180.     
  1181.     /**
  1182.      * Search for a class in a package
  1183.      *
  1184.      * @param string $class   classname
  1185.      * @param string $package package classname is in
  1186.      *
  1187.      * @return mixed returns false if no class in $package,
  1188.      *                otherwise returns a {@link parserClass}
  1189.      */
  1190.     function &getClassByPackage($class$package)
  1191.     {
  1192.         if (!isset($this->classesbynamefile[$class])) {
  1193.             // removed, too many warnings, not very useful
  1194.             // addWarning(PDERROR_CLASS_NOT_IN_PACKAGE,$class,$package); 
  1195.  
  1196.             $flag false;
  1197.             return $flag;
  1198.         }
  1199.         for ($i=0$i count($this->classesbynamefile[$class])$i++{
  1200.             $cls 
  1201.                 $this->classesbyfile[$this->classesbynamefile[$class][$i]][$class];
  1202.             $pkg $cls->getPackage();
  1203.             if ($pkg == $package)
  1204.                 return $cls;
  1205.         }
  1206.         // addWarning(PDERROR_CLASS_NOT_IN_PACKAGE,$class,$package);
  1207.  
  1208.         $flag false;
  1209.         return $flag;
  1210.     }
  1211.     
  1212.     /**
  1213.      * Find the parent class of a class in file $file
  1214.      * uses 3 tests to find the parent classname:
  1215.      * <ol>
  1216.      *    <li>only one class with the parent classname</li>
  1217.      *    <li>more than one class, but only one in the same file as the child</li>
  1218.      *    <li>only one parent class in the same package as the child</li>
  1219.      * </ol>
  1220.      *
  1221.      * @param string $class classname
  1222.      * @param string $file  file classname is located in
  1223.      *
  1224.      * @return mixed false if no parent class,
  1225.      *                a string if no parent class found by that name,
  1226.      *                and an array(file parentclass is in, parentclassname)
  1227.      */
  1228.     function getParentClass($class,$file)
  1229.     {
  1230.         if (!isset($this->classesbyfile[$file][$class])) {
  1231.             return false;
  1232.         }
  1233.         $element $this->classesbyfile[$file][$class];
  1234.         if (!($ex $element->getExtends())) return false;
  1235.         // first check to see if there is one and only one 
  1236.         // class with the parent class's name
  1237.         if (isset($this->classesbynamefile[$ex])) {
  1238.             if (count($this->classesbynamefile[$ex]== 1{
  1239.                 if ($this->classesbyfile
  1240.                     [$this->classesbynamefile[$ex][0]][$ex]->ignore{
  1241.                     return $ex;
  1242.                 }
  1243.                 return array($this->classesbynamefile[$ex][0],$ex);
  1244.             else {
  1245.                 // next check to see if there is a parent class in the same file
  1246.                 if (isset($this->classesbyfile[$file][$ex])) {
  1247.                     if ($this->classesbyfile[$file][$ex]->ignore{
  1248.                         return $ex;
  1249.                     }
  1250.                     return array($file,$ex);
  1251.                 }
  1252.                 // next check to see if there is only one package 
  1253.                 // used in the file, try to resolve it that way
  1254.                 if (isset($this->classpackagebyfile[$file])) {
  1255.                     if (count($this->classpackagebyfile[$file]== 1{
  1256.                         for ($i=0;$i<count($this->classesbynamefile[$ex]);$i++{
  1257.                             if ($this->classesbyfile
  1258.                               [$this->classesbynamefile[$ex][$i]][$ex]->getPackage(
  1259.                                == $this->classpackagebyfile[$file][0]{
  1260.                                 if ($this->classesbyfile
  1261.                                    [$this->classesbynamefile[$ex][$i]][$ex]->ignore
  1262.                                     return $ex;
  1263.                                 return array($this->classesbynamefile[$ex][$i],$ex);
  1264.                             }
  1265.                         }
  1266.                     }
  1267.                 }
  1268.                 // name conflict
  1269.                 addWarning(PDERROR_INHERITANCE_CONFLICT$class$file$ex);
  1270.                 return $ex;
  1271.             }
  1272.         else {
  1273.             if (class_exists('ReflectionClass'&& class_exists($ex)) {
  1274.                 $r new ReflectionClass($ex);
  1275.                 if ($r->isInternal()) {
  1276.                     return $ex// no warning
  1277.                 }
  1278.             }
  1279.             addWarning(PDERROR_PARENT_NOT_FOUND$class$ex);
  1280.             return $ex;
  1281.         }
  1282.     }
  1283.     
  1284.     /**
  1285.      * Get a list of all root classes indexed by package.  Used to generate
  1286.      * class trees by {@link Converter}
  1287.      *
  1288.      * @param boolean $all [since phpDocumentor 1.3.0RC6] determines whether to
  1289.      *                      return class trees that extend non-parsed classes
  1290.      *
  1291.      * @return array array(package => array(rootclassname, rootclassname,...),...)
  1292.      */
  1293.     function getRoots($all false)
  1294.     {
  1295.         $roots     array();
  1296.         $temproots $this->roots;
  1297.         if (!$all{
  1298.             foreach ($this->specialRoots as $package => $root{
  1299.                 foreach ($root as $parent => $info{
  1300.                     $temproots[$info[0]][$info[1];
  1301.                 }
  1302.             }
  1303.         }
  1304.         foreach ($temproots as $class => $files{
  1305.             if (count($files)) {
  1306.                 foreach ($files as $i => $boofou{
  1307.                     $x $this->getClass($class$files[$i]);
  1308.  
  1309.                     $roots[$x->getPackage()][$class;
  1310.                 }
  1311.             }
  1312.         }
  1313.         foreach ($roots as $package => $root{
  1314.             usort($roots[$package]"strnatcasecmp");
  1315.         }
  1316.         if ($all{
  1317.             $specialRoots array();
  1318.             foreach ($this->specialRoots as $parent => $classinfo{
  1319.                 if (count($classinfo)) {
  1320.                     foreach ($classinfo as $i => $info{
  1321.                         $x $this->getClass($info[0]$info[1]);
  1322.  
  1323.                         $specialRoots[$x->getPackage()][$parent][$info[0];
  1324.                     }
  1325.                 }
  1326.             }
  1327.             foreach ($specialRoots as $package => $root{
  1328.                 uksort($specialRoots[$package]"strnatcasecmp");
  1329.                 foreach ($specialRoots[$packageas $parent => $classes{
  1330.                     usort($specialRoots[$package][$parent]'strnatcasecmp');
  1331.                 }
  1332.             }
  1333.             return array('special' => $specialRoots'normal' => $roots);
  1334.         }
  1335.         return $roots;
  1336.     }
  1337.     
  1338.     /**
  1339.      * Get all classes confirmed in parsing
  1340.      * to be descended class $parclass in file $file
  1341.      *
  1342.      * @param string $parclass name of parent class
  1343.      * @param string $file     file parent class is found in
  1344.      *
  1345.      * @return mixed either false if no children, or array of format
  1346.      *          array(childname => childfile,childname2 => childfile2,...)
  1347.      * @see parserClass::getChildClassList()
  1348.      * @uses $definitechild
  1349.      */
  1350.     function getDefiniteChildren($parclass$file)
  1351.     {
  1352.         if (isset($this->definitechild[$parclass][$file])) 
  1353.             return $this->definitechild[$parclass][$file];
  1354.         return false;
  1355.     }
  1356. }
  1357. ?>

Documentation generated on Tue, 06 Dec 2011 07:16:52 -0600 by phpDocumentor 1.4.4