+++ /dev/null
-<?php\r
-/**\r
-* "Main" class of the Parser collection.\r
-* \r
-* Note that a lot of communication is done using shared instance variables.\r
-* \r
-* @version $Id: PhpdocParser.php,v 1.2 2000/12/03 22:37:37 uw Exp $\r
-*/\r
-class PhpdocParser extends PhpdocClassParser {\r
-\r
- /**\r
- * Name of the file currently parsed. \r
- * \r
- * Instead of passing the name of the current file by argument\r
- * PHPDoc uses this slot to communicate. Yeah I know, it's\r
- * the way methods should communicate, but it saves me a lot \r
- * a lot of work.\r
- * @var string Name of the file currently parsed.\r
- */\r
- var $currentFile = "";\r
- \r
- /**\r
- * Array of PHP Sourcecode Files to examine.\r
- *\r
- * The array keys hold the filenames, the array values the file content.\r
- *\r
- * @var array \r
- * @see parse()\r
- */ \r
- var $phpfiles = array(); \r
- \r
- /**\r
- * Mapping from classnames to filenames\r
- *\r
- * @var array\r
- */\r
- var $classnamesToFilenames = array();\r
- \r
- /**\r
- * Hash with the data of the current class tree (one parentclass with all children).\r
- *\r
- * @var array\r
- * @see $modules\r
- */\r
- var $classes = array();\r
- \r
- /**\r
- * List of all parentclasses found.\r
- * @var array\r
- */\r
- var $baseclasses = array();\r
-\r
- /**\r
- * List of all files containing classes.\r
- *\r
- * @var array\r
- */ \r
- var $classfiles = array();\r
- \r
- /**\r
- * Hash of all class trees. \r
- *\r
- * @var array\r
- */\r
- var $classtree = array();\r
-\r
- /**\r
- * List of all files containing modules.\r
- *\r
- * @var array\r
- */ \r
- var $modulefiles = array();\r
- \r
- /**\r
- * List of all module groups.\r
- *\r
- * @var array\r
- */\r
- var $modulegroups = array();\r
- \r
- /**\r
- * Hash with the data of the current module group.\r
- *\r
- * @var array\r
- * @see $classes\r
- */\r
- var $modules = array();\r
-\r
- /**\r
- * Hash of all packages found.\r
- *\r
- * @var array\r
- */ \r
- var $packages = array();\r
-\r
- /**\r
- * Flag indicating that getClassTree() was called.\r
- *\r
- * @var boolean \r
- * @see getClassTree()\r
- */\r
- var $flag_classtree = false;\r
- \r
- /**\r
- * Flag indicating that getModulegroup was called.\r
- *\r
- * @var boolean\r
- * @see getModulegroup()\r
- */\r
- var $flag_modulegroup = false; \r
- \r
- /**\r
- * Name of the base class of the current class tree.\r
- *\r
- * @var string\r
- * @see getClassTree()\r
- */\r
- var $current_baseclass = "";\r
- \r
- /**\r
- * Creates an instance of PhpdocWarning and calls buildComplexRegExps() to initialize the object.\r
- *\r
- * @param boolean If true the parser prints status messages.\r
- * @see $warn, buildComplexRegExps()\r
- */\r
- function PhpdocParser($flag_output = false) {\r
- \r
- if ($flag_output)\r
- $this->setFlagOutput(true);\r
- else \r
- $this->setFlagOutput(false);\r
- \r
- $this->buildComplexRegExps();\r
- \r
- } // end constructor\r
- \r
- /**\r
- * Central parsing function.\r
- *\r
- * With version 0.3alpha PHPdoc changed the way the parser works. It does now\r
- * 1 1/2 parsing runs. One prescan to build the class trees and a list of module\r
- * groups and one deep scan to extract the information. This reduces the memory \r
- * consumption.\r
- * \r
- * @return boolean $ok\r
- * @access public \r
- * @see findModulegroups(), findClassTrees(), getModulesAndClasses()\r
- */\r
- function preparse() {\r
-\r
- if (0 == count($this->phpfiles)) {\r
- $this->err[] = new PHPDocError("Can't parse - no files defined.", __FILE__, __LINE__);\r
- return false;\r
- }\r
- \r
- $para = array();\r
- reset($this->phpfiles);\r
- while (list($filename, $phpcode) = each($this->phpfiles))\r
- $para[$filename] = $this->getModulesAndClasses($phpcode);\r
- \r
- $this->findModulegroups($para);\r
- $this->findClassTrees($para); \r
- \r
- return true; \r
- } // end func preparse\r
- \r
- /**\r
- * Returns the data of one parentclass and all it's subclasses or false.\r
- *\r
- * Use this function to loop through the class trees. The loop should look somewhat like: \r
- * <code>while ( $classtree = $parser->getClassTree() ) ...</code>\r
- * \r
- * @return mixed $classes Hash with the data of the current class tree or false.\r
- * @access public\r
- * @see getModulegroup(), $baseclasses\r
- */\r
- function getClassTree() {\r
- \r
- // first call, reset the baseclass array pointer\r
- if (!$this->flag_classtree) {\r
- reset($this->baseclasses);\r
- $this->flag_classtree = true;\r
- }\r
- \r
- if (list($classname, $filename) = each($this->baseclasses)) {\r
- \r
- $this->classes = array();\r
- $this->current_baseclass = $classname;\r
- \r
- $this->addClass($classname, $filename);\r
-\r
- return $this->classes;\r
- \r
- } else {\r
- \r
- return false;\r
- \r
- }\r
- \r
- } // end func getClassTree\r
- \r
- /**\r
- * Returns the data of one module group.\r
- * \r
- * Use this function to loop through the module groups. The loop should look somewhat like:\r
- * <code>while ( $modulegroup = $parser->getModulegroup() ) ...</code>.\r
- *\r
- * @return mixed $modulegroup Hash with the data of the current class tree or false.\r
- * @access public\r
- * @see getClassTree(), addModule(), $modulegroups\r
- */\r
- function getModulegroup() {\r
- \r
- if (!$this->flag_modulegroup) {\r
- reset($this->modulegroups);\r
- $this->flag_modulegroup = true;\r
- }\r
- \r
- if (list($group, $modules) = each($this->modulegroups)) {\r
- \r
- $this->modules = array();\r
- while (list($modulename, $files) = each($modules)) {\r
- reset($files);\r
- while (list($k, $filename) = each($files))\r
- $this->addModule($group, $filename); \r
- }\r
- \r
- return $this->modules;\r
- \r
- } else {\r
- \r
- return false;\r
- \r
- }\r
- \r
- } // end func getModulegroup\r
- \r
- /**\r
- * Analyses the given file and adds the result to the module list.\r
- * \r
- * The function analyses the given file, unsets the file in the \r
- * file list, adds the result of the parser to the module list and \r
- * if necessary it adds some data to the package list.\r
- *\r
- * @param string Name of the module group the parsing result gets added.\r
- * @param string Name of the file to scan.\r
- * @see getPhpdocParagraphs(), analyseModule()\r
- */ \r
- function addModule($group, $filename) {\r
-\r
- $data = $this->getPhpdocParagraphs($this->phpfiles[$filename], array("classes", "variables") ); \r
- // free memory as soon as possible...\r
- unset($this->phpfiles[$filename]);\r
- \r
- // note: not passed by argument\r
- $this->currentFile = $filename;\r
- $result = $this->analyseModule($data);\r
- $result["filename"] = $filename;\r
- \r
- $this->modules[$group][$result["name"]] = $result;\r
- \r
- if (isset($result["package"]))\r
- $this->packages[$result["package"]]["modules"][] = array (\r
- "name" => $result["name"],\r
- "group" => $result["group"],\r
- "filename" => $filename\r
- );\r
- \r
- } // end func addModule\r
- \r
- /**\r
- * Analyses the given file and adds the result to the class list.\r
- * \r
- * The first parameter (classname) comes from the prescan done \r
- * by findClassTrees()\r
- *\r
- * @param string Name of the class that gets added.\r
- * @param string Name of the file to scan.\r
- * @see addSubclasses(), analyseClass(), $classes\r
- */\r
- function addClass($classname, $filename) {\r
- \r
- $data = $this->getPhpdocParagraphs($this->phpfiles[$filename], array("modules") );\r
- // free memory as soon as possible...\r
- unset($this->phpfiles[$filename]);\r
- \r
- $this->currentFile = $filename;\r
- $result = $this->analyseClass($data);\r
-\r
- // Add some informations from the classtree that was build by the prescan to the class.\r
- $fields = array("subclasses", "noparent", "path", "baseclass"); \r
- reset($fields);\r
- while (list($k, $field) = each($fields))\r
- if (isset($this->classtree[$filename][$classname][$field]))\r
- $result[$field] = $this->classtree[$filename][$classname][$field];\r
-\r
- $result["filename"] = $filename; \r
- \r
- $this->classes[$classname] = $result; \r
- $this->addSubclasses($classname);\r
- \r
- if (isset($result["package"]))\r
- $this->packages[$result["package"]]["classes"][] = $classname;\r
- \r
- } // end func addClass\r
- \r
- /**\r
- * Adds recursively subclasses to the specified class.\r
- *\r
- * @param string Name of the class that might contain subclasses\r
- * @see addClass()\r
- */\r
- function addSubclasses($classname) {\r
- \r
- if (isset($this->classes[$classname]["subclasses"])) {\r
- \r
- $subclasses = $this->classes[$classname]["subclasses"];\r
- while (list($subclass, $v) = each($subclasses)) \r
- $this->addClass($subclass, $this->classnamesToFilenames[$subclass]);\r
- \r
- }\r
- \r
- } // end func addSubclasses\r
- \r
- /**\r
- * Builds the hash of module groups and the module file list.\r
- *\r
- * @param array Hash with the result of getClassesAndModules() of all files\r
- * @see parse(), findClassTree(), $modulegroups, $modulefiles\r
- */\r
- function findModulegroups($para) {\r
- \r
- reset($para);\r
- while (list($filename, $data) = each($para)) {\r
-\r
- if (isset($data["modules"]["name"])) {\r
- \r
- $name = ("" != $data["modules"]["name"]) ? $data["modules"]["name"] : $filename;\r
- $group = ("" != $data["modules"]["group"]) ? $data["modules"]["group"] : $name; \r
- \r
- if (0 != count($data["classes"])) {\r
- // As we do not have a real parser that returns a parsing tree we can't \r
- // handle modules and classes in one file. Drop a note to the user.\r
- $this->warn->addDocWarning( $filename, "module", $name, "PHPDoc is confused: module files must not contain classes. Doc will probably be broken, module gets ignored.", "collision" );\r
- continue;\r
- }\r
-\r
- if (isset($this->modulegroups[$group][$name])) \r
- $this->warn->addDocWarning($filename, "module", $name, "Warning: there's more than one module '$name' (file: '$filename) in the module group '$group'.", "warning");\r
-\r
- $this->modulegroups[$group][$name][] = $filename; \r
- $this->modulefiles[] = $filename; \r
- \r
- }\r
- \r
- }\r
-\r
- } // end func findModulegroups\r
- \r
- /**\r
- * Builds a hash of all class trees.\r
- *\r
- * @param array Hash with the result of getClassesAndModules() of all files\r
- * @see parse(), findModulegroups(), $classnamesToFilenames, $classtree, $classfiles, $baseclasses\r
- */\r
- function findClassTrees($para) {\r
- \r
- reset($para);\r
- while(list($filename, $data) = each($para)) {\r
- \r
- if (0!=count($data["classes"])) {\r
-\r
- $classname = $data["classes"][0]["name"];\r
- \r
- if (1<count($data["classes"]))\r
- $this->warn->addDocWarning($filename, "class", $classname , "PHPDoc is confused: there is more than one class in this file. Doc will probably be broken, first class '$classname' gets used, file '$filename' get ignored.", "collision");\r
- \r
- if (isset($data["modules"]["name"]))\r
- $this->warn->addDocWarning($filename, "class", "", "Warning: found a module comment in a class file. Module comment gets ignored, doc might be broken.", "collision");\r
- \r
- $this->classnamesToFilenames[$classname] = $filename;\r
- $this->classtree[$filename][$classname] = $data["classes"][0];\r
- $this->classfiles[] = $filename;\r
- \r
- }\r
- \r
- }\r
- \r
- reset($this->classnamesToFilenames);\r
- while (list($classname, $filename)=each($this->classnamesToFilenames)) {\r
-\r
- $path = array();\r
- $baseclass = $classname;\r
- $basefile = $filename;\r
- $flag_noparent = false;\r
- \r
- while ($extends = $this->classtree[$basefile][$baseclass]["extends"]) {\r
- if (!isset($this->classnamesToFilenames[$extends])) {\r
- $flag_noparent = true;\r
- break;\r
- }\r
-\r
- $this->classtree[$this->classnamesToFilenames[$extends]][$extends]["subclasses"][$baseclass] = true;\r
- $path[] = $extends;\r
- $baseclass = $extends;\r
- $basefile = $this->classnamesToFilenames[$baseclass];\r
- }\r
- \r
- if ($flag_noparent)\r
- $this->classtree[$filename][$classname]["noparent"] = $flag_noparent;\r
- \r
- $base = (0 == count($path)) ? true : false;\r
- if ($base) \r
- $this->baseclasses[$classname] = $filename;\r
- else \r
- $this->classtree[$filename][$classname]["path"] = $path;\r
- \r
- if ($baseclass != $classname)\r
- $this->classtree[$filename][$classname]["baseclass"] = $baseclass;\r
- }\r
- \r
- } // end func findClassTrees\r
-\r
- /**\r
- * Returns the mapping array from classnames to filenames\r
- *\r
- * @return array \r
- * @see $classnamesToFilenames\r
- */\r
- function getClassnamesToFilenames() {\r
- return $this->classnamesToFilenames;\r
- } // end func getClassnamesToFilenames\r
-\r
- \r
- /**\r
- * Sets the list of PHP Soucecode Files to examine.\r
- * @param array $phpfiles\r
- * @return bool $ok\r
- * @access public\r
- */\r
- function setPhpSourcecodeFiles($phpfiles) {\r
- if (!is_array($phpfiles) || 0 == count($phpfiles)) \r
- return false;\r
- \r
- $this->phpfiles = $phpfiles;\r
- return true; \r
- } // end func setPhpSourcecodeFiles\r
- \r
-} // end class PhpdocParser\r
-?>
\ No newline at end of file