uw Sun Feb 18 06:45:29 2001 EDT
Modified files:
/php4/pear/PHPDoc/parser PhpdocClassParser.php
PhpdocConstantParser.php
PhpdocFunctionParser.php
PhpdocModuleParser.php PhpdocParser.php
PhpdocParserCore.php
PhpdocParserRegExp.php
PhpdocParserTags.php PhpdocUseParser.php
PhpdocVariableParser.php
Log:
Sorry, whitespace only changes to follow the PEAR Coding conventions. Replaces tabs
with spaces.
Index: php4/pear/PHPDoc/parser/PhpdocClassParser.php
diff -u php4/pear/PHPDoc/parser/PhpdocClassParser.php:1.2
php4/pear/PHPDoc/parser/PhpdocClassParser.php:1.3
--- php4/pear/PHPDoc/parser/PhpdocClassParser.php:1.2 Sun Dec 3 14:37:37 2000
+++ php4/pear/PHPDoc/parser/PhpdocClassParser.php Sun Feb 18 06:45:27 2001
@@ -2,127 +2,127 @@
/**
* Parses phpcode to extract classes and their documentation.
*
-* @version $Id: PhpdocClassParser.php,v 1.2 2000/12/03 22:37:37 uw Exp $
+* @version $Id: PhpdocClassParser.php,v 1.3 2001/02/18 14:45:27 uw Exp $
*/
class PhpdocClassParser extends PhpdocFunctionParser {
- /**
- * Array of all classes in the given code
- *
- * The array is indexed by the classname.
- * See $emptyClass to see the internal structure.
- *
- * @var array $classes
- * @see $emptyClass
- */
- var $classes = array();
-
- /**
- * Default values of a class
- *
- * @var array $emptyClass
- */
- var $emptyClass = array (
-
"name" => "",
-
"extends" => "",
-
"undoc" => true
-
);
-
- /**
- * Array of tags that are allowed in front of the class keyword
- *
- * @var array $classTags
- * @see analyseClassParagraph()
- */
- var $classTags = array(
-
"access" => true,
-
"abstract" => true,
-
"static" => true,
-
"final" => true,
-
-
"see" => true,
-
"link" => true,
-
-
"author" => true,
-
"copyright" => true,
-
-
"version" => true,
-
"since" => true,
-
-
"deprecated" => true,
-
"deprec" => true,
-
-
"brother" => true,
-
"sister" => true,
-
-
"exclude" => true,
-
-
"package" => true,
-
-
"magic" => true,
-
"todo" => true
-
);
-
- /**
- * Analyse a class
- *
- * Calls all neccessary analyse functions.
- *
- * @param array
- * @return array
- */
- function analyseClass($para) {
+ /**
+ * Array of all classes in the given code
+ *
+ * The array is indexed by the classname.
+ * See $emptyClass to see the internal structure.
+ *
+ * @var array $classes
+ * @see $emptyClass
+ */
+ var $classes = array();
+
+ /**
+ * Default values of a class
+ *
+ * @var array $emptyClass
+ */
+ var $emptyClass = array (
+ "name" => "",
+ "extends" => "",
+ "undoc" => true
+ );
+
+ /**
+ * Array of tags that are allowed in front of the class keyword
+ *
+ * @var array $classTags
+ * @see analyseClassParagraph()
+ */
+ var $classTags = array(
+ "access" => true,
+ "abstract" => true,
+ "static" => true,
+ "final" => true,
+
+ "see" => true,
+ "link" => true,
+
+ "author" => true,
+ "copyright" => true,
+
+ "version" => true,
+ "since" => true,
+
+ "deprecated" => true,
+ "deprec" => true,
+
+ "brother" => true,
+ "sister" => true,
+
+ "exclude" => true,
+
+ "package" => true,
+
+ "magic" => true,
+ "todo" => true
+ );
+
+ /**
+ * Analyse a class
+ *
+ * Calls all neccessary analyse functions.
+ *
+ * @param array
+ * @return array
+ */
+ function analyseClass($para) {
- $class = $this->analyseClassDoc($para["classes"][0]);
-
- reset($para["functions"]);
- while (list($k, $data)=each($para["functions"]))
- $class["functions"][strtolower($data["name"])] =
$this->analyseFunction($data);
- unset($para["functions"]);
-
- reset($para["variables"]);
- while (list($k, $data)=each($para["variables"]))
- $class["variables"][strtolower($data["name"])] =
$this->analyseVariable($data);
- unset($para["variables"]);
+ $class = $this->analyseClassDoc($para["classes"][0]);
+
+ reset($para["functions"]);
+ while (list($k, $data)=each($para["functions"]))
+ $class["functions"][strtolower($data["name"])] =
+$this->analyseFunction($data);
+ unset($para["functions"]);
+
+ reset($para["variables"]);
+ while (list($k, $data)=each($para["variables"]))
+ $class["variables"][strtolower($data["name"])] =
+$this->analyseVariable($data);
+ unset($para["variables"]);
- reset($para["consts"]);
- while (list($k, $data)=each($para["consts"]))
- $class["consts"][strtolower($data["name"])] =
$this->analyseConstant($data);
- unset($para["consts"]);
-
- reset($para["uses"]);
- while (list($k, $data)=each($para["uses"]))
- $class["uses"][strtolower($data["file"])] =
$this->analyseUse($data);
-
- return $class;
- } // end func analyseClass
+ reset($para["consts"]);
+ while (list($k, $data)=each($para["consts"]))
+ $class["consts"][strtolower($data["name"])] =
+$this->analyseConstant($data);
+ unset($para["consts"]);
+
+ reset($para["uses"]);
+ while (list($k, $data)=each($para["uses"]))
+ $class["uses"][strtolower($data["file"])] = $this->analyseUse($data);
+
+ return $class;
+ } // end func analyseClass
- /**
- * Analyses a class doc comment.
- * @param array Hash returned by getPhpdocParagraph()
- * @return array
- */
- function analyseClassDoc($para) {
-
- $class = $this->emptyClass;
- $class["name"] = $para["name"];
- $class["extends"] = $para["extends"];
-
- if (""!=$para["doc"]) {
-
- $class = $this->analyseTags($this->getTags($para["doc"]),
$class, $this->classTags);
-
- list($msg, $class) = $this->checkParserErrors($class, "class");
- if (""!=$msg)
- $this->warn->addDocWarning($this->currentFile,
"class", $class["name"], $msg, "mismatch");
-
- list($class["sdesc"], $class["desc"]) =
$this->getDescription($para["doc"]);
-
- $class["undoc"] = false;
- }
-
- return $class;
- } // end func analyseClassDoc
-
+ /**
+ * Analyses a class doc comment.
+ * @param array Hash returned by getPhpdocParagraph()
+ * @return array
+ */
+ function analyseClassDoc($para) {
+
+ $class = $this->emptyClass;
+ $class["name"] = $para["name"];
+ $class["extends"] = $para["extends"];
+
+ if ("" != $para["doc"]) {
+
+ $class = $this->analyseTags($this->getTags($para["doc"]), $class,
+$this->classTags);
+
+ list($msg, $class) = $this->checkParserErrors($class, "class");
+ if ("" != $msg)
+ $this->warn->addDocWarning($this->currentFile, "class",
+$class["name"], $msg, "mismatch");
+
+ list($class["sdesc"], $class["desc"]) =
+$this->getDescription($para["doc"]);
+
+ $class["undoc"] = false;
+ }
+
+ return $class;
+ } // end func analyseClassDoc
+
} // end class PhpdocClassParser
?>
Index: php4/pear/PHPDoc/parser/PhpdocConstantParser.php
diff -u php4/pear/PHPDoc/parser/PhpdocConstantParser.php:1.4
php4/pear/PHPDoc/parser/PhpdocConstantParser.php:1.5
--- php4/pear/PHPDoc/parser/PhpdocConstantParser.php:1.4 Sun Dec 3 14:37:37
2000
+++ php4/pear/PHPDoc/parser/PhpdocConstantParser.php Sun Feb 18 06:45:27 2001
@@ -2,108 +2,108 @@
/**
* Extracts define statements and their documentation from php code.
*
-* @version $Id: PhpdocConstantParser.php,v 1.4 2000/12/03 22:37:37 uw Exp $
+* @version $Id: PhpdocConstantParser.php,v 1.5 2001/02/18 14:45:27 uw Exp $
*/
class PhpdocConstantParser extends PhpdocUseParser {
- /**
- * Internal structure use to save a constant.
- *
- * @var array
- */
- var $emptyConstant = array(
-
"name" => "",
-
"value" => "",
-
"undoc" =>
true
-
);
-
- /**
- * Doc Tags allowed with const[ant].
- *
- * @var array
- */
- var $constantTags = array(
-
"access" => true,
-
"see" => true,
-
"link" => true,
-
-
"constant" => true,
-
"const" => true,
-
-
"author" => true,
-
"copyright" => true,
-
-
"exclude" => true,
-
"magic" => true,
-
"todo" => true
-
);
-
- /**
- * Scans the given constant doc comment.
- *
- * @param array
- */
- function analyseConstant($para) {
-
- $constant = $this->emptyConstant;
- $constant["name"] = $para["name"];
- $constant["value"] = $para["value"];
-
- if ("" != $para["doc"]) {
-
- $constant = $this->analyseTags( $this->getTags($para["doc"]),
$constant, $this->constantTags);
-
- list($msg, $constant) = $this->checkParserErrors($constant,
"constant (define() keyword)");
- if ("" != $msg)
- $this->warn->addDocWarning($this->currentFile,
"constant", $constant["name"], $msg, "mismatch");
-
- list($constant["sdesc"], $constant["desc"]) =
$this->getDescription($para["doc"]);
-
- $constant["undoc"] = false;
- }
-
- $constant = $this->checkConstantDoc($constant);
-
- if (isset($para["case"]))
- $constant["case"] = $para["case"];
-
- return $constant;
- } // end func analyseConstant
-
- /**
- * Compares the data from the parser with the optional const[ant] tags
- * @param array Hash with the data of the current constant paragraph
- * @return array $constant
- */
- function checkConstantDoc($constant) {
-
- if (!isset($constant["const"])) {
-
- $msg = "The @const[ant] tag is missing. Add '@const " .
$constant["name"] . " [description]' to the tag list at the end of the doc comment.";
- $this->warn->addDocWarning($this->currentFile, "constant",
$constant["name"], $msg, "missing");
-
- } else {
-
- if ($constant["name"] != $constant["const"]["name"]) {
-
- $msg = sprintf("The name of the constant '%s' does not
match the documented name '%s', update the tag to '@const %s %s'.",
-
$constant["name"],
-
$constant["const"]["name"],
-
$constant["name"],
-
$constant["const"]["desc"]
-
);
- $this->warn->addDocWarning($this->currentFile,
"constant", $constant["name"], $msg, "mismatch");
-
- }
-
- if ("" != $constant["const"]["desc"])
- $constant["const"] = $constant["const"]["desc"];
- else
- unset($constant["const"]);
- }
-
- return $constant;
- } // end func checkConstantDoc
-
+ /**
+ * Internal structure use to save a constant.
+ *
+ * @var array
+ */
+ var $emptyConstant = array(
+ "name" => "",
+ "value" => "",
+ "undoc" => true
+ );
+
+ /**
+ * Doc Tags allowed with const[ant].
+ *
+ * @var array
+ */
+ var $constantTags = array(
+ "access" => true,
+ "see" => true,
+ "link" => true,
+
+ "constant" => true,
+ "const" => true,
+
+ "author" => true,
+ "copyright" => true,
+
+ "exclude" => true,
+ "magic" => true,
+ "todo" => true
+ );
+
+ /**
+ * Scans the given constant doc comment.
+ *
+ * @param array
+ */
+ function analyseConstant($para) {
+
+ $constant = $this->emptyConstant;
+ $constant["name"] = $para["name"];
+ $constant["value"] = $para["value"];
+
+ if ("" != $para["doc"]) {
+
+ $constant = $this->analyseTags( $this->getTags($para["doc"]), $constant,
+$this->constantTags);
+
+ list($msg, $constant) = $this->checkParserErrors($constant, "constant
+(define() keyword)");
+ if ("" != $msg)
+ $this->warn->addDocWarning($this->currentFile, "constant",
+$constant["name"], $msg, "mismatch");
+
+ list($constant["sdesc"], $constant["desc"]) =
+$this->getDescription($para["doc"]);
+
+ $constant["undoc"] = false;
+ }
+
+ $constant = $this->checkConstantDoc($constant);
+
+ if (isset($para["case"]))
+ $constant["case"] = $para["case"];
+
+ return $constant;
+ } // end func analyseConstant
+
+ /**
+ * Compares the data from the parser with the optional const[ant] tags
+ * @param array Hash with the data of the current constant paragraph
+ * @return array $constant
+ */
+ function checkConstantDoc($constant) {
+
+ if (!isset($constant["const"])) {
+
+ $msg = "The @const[ant] tag is missing. Add '@const " . $constant["name"]
+. " [description]' to the tag list at the end of the doc comment.";
+ $this->warn->addDocWarning($this->currentFile, "constant",
+$constant["name"], $msg, "missing");
+
+ } else {
+
+ if ($constant["name"] != $constant["const"]["name"]) {
+
+ $msg = sprintf("The name of the constant '%s' does not match the
+documented name '%s', update the tag to '@const %s %s'.",
+ $constant["name"],
+ $constant["const"]["name"],
+ $constant["name"],
+ $constant["const"]["desc"]
+ );
+ $this->warn->addDocWarning($this->currentFile, "constant",
+$constant["name"], $msg, "mismatch");
+
+ }
+
+ if ("" != $constant["const"]["desc"])
+ $constant["const"] = $constant["const"]["desc"];
+ else
+ unset($constant["const"]);
+ }
+
+ return $constant;
+ } // end func checkConstantDoc
+
} // end class PhpdocConstantParser
?>
Index: php4/pear/PHPDoc/parser/PhpdocFunctionParser.php
diff -u php4/pear/PHPDoc/parser/PhpdocFunctionParser.php:1.2
php4/pear/PHPDoc/parser/PhpdocFunctionParser.php:1.3
--- php4/pear/PHPDoc/parser/PhpdocFunctionParser.php:1.2 Sun Dec 3 14:37:37
2000
+++ php4/pear/PHPDoc/parser/PhpdocFunctionParser.php Sun Feb 18 06:45:27 2001
@@ -2,136 +2,137 @@
/**
* Looks for documented and undocumented functions within a block of php code.
*
-* @version $Id: PhpdocFunctionParser.php,v 1.2 2000/12/03 22:37:37 uw Exp $
+* @version $Id: PhpdocFunctionParser.php,v 1.3 2001/02/18 14:45:27 uw Exp $
*/
class PhpdocFunctionParser extends PhpdocVariableParser {
- /**
- * Internal structur of a function.
- *
- * @var array $emptyFunction
- */
- var $emptyFunction = array(
-
"name" => "",
-
"undoc" => true,
-
-
"args" => array()
-
);
-
- /**
- * Array of tags that are allowed in front of the function keyword
- * @var array $functionTags
- * @see analyseFunctionParagraph()
- */
- var $functionTags = array(
-
"parameter" => true,
-
"param" => true,
-
-
"return" => true,
-
-
"access" => true,
-
"abstract" => true,
-
"static" => true,
-
-
"throws" => true,
-
-
"see" => true,
-
"link" => true,
-
-
"global" => true,
-
-
"version" => true,
-
"since" => true,
-
-
"deprecated" => true,
-
"deprec" => true,
-
-
"brother" => true,
-
"sister" => true,
-
-
"exclude" => true,
-
"magic" => true,
-
-
"author" => true,
-
"copyright" => true,
-
-
"todo" => true
-
);
-
- /**
- * Analyses a function doc comment.
- * @param array
- * @return array
- */
- function analyseFunction($para) {
-
- $function = $this->emptyFunction;
- $function["name"] = $para["name"];
-
- if (""!=$para["doc"]) {
-
- $function = $this->analyseTags($this->getTags($para["doc"]),
$function, $this->functionTags);
-
- list($msg, $function) = $this->checkParserErrors($function,
"function");
- if (""!=$msg)
- $this->warn->addDocWarning($this->currentFile,
"function", $function["name"], $msg, "mismatch");
-
- list($function["sdesc"], $function["desc"]) =
$this->getDescription($para["doc"]);
-
- $function["undoc"] = false;
-
- }
-
- $function["args"] = $this->getFunctionArgs($para["head"]);
- return $function;
- } // end func analyseFunction
-
- /**
- * Analyses a function head and returns an array of arguments.
- * @param string PHP code to examine.
- * @return array Array of arguments: $args[] = array( optional,
default, type, name ).
- * @see getVariableTypeAndValue()
- */
- function getFunctionArgs($code) {
-
- $args = array();
- while (preg_match($this->PHP_COMPLEX["argument"], $code, $regs)) {
-
- $type = "";
- $value = "";
- $optional = false;
-
- if (!isset($regs[3])) {
-
- $len_of_value = strlen($regs[1]);
-
- } else if ("=" == $regs[3]) {
-
- $find = $regs[1].$regs[2];
- $code = substr($code, strpos($code,
$find)+strlen($find) );
-
- list ($type, $value, $raw_value) =
$this->getVariableTypeAndValue($code);
- $len_of_value = strlen($raw_value);
- $optional = true;
-
- } else {
-
- $len_of_value = strlen($regs[1].$regs[2]);
-
- }
-
- $code = substr($code, $len_of_value);
- $args[] = array(
-
"optional" => $optional,
-
"default" => $value,
-
"type" => $type,
-
"name" => $regs[1]
-
);
-
- }
-
- return $args;
- } // end func getFunctionArgs
-
+ /**
+ * Internal structur of a function.
+ *
+ * @var array $emptyFunction
+ */
+ var $emptyFunction = array(
+ "name" => "",
+ "undoc" => true,
+
+ "args" => array()
+ );
+
+ /**
+ * Array of tags that are allowed in front of the function keyword
+ *
+ * @var array $functionTags
+ * @see analyseFunctionParagraph()
+ */
+ var $functionTags = array(
+ "parameter" => true,
+ "param" => true,
+
+ "return" => true,
+
+ "access" => true,
+ "abstract" => true,
+ "static" => true,
+
+ "throws" => true,
+
+ "see" => true,
+ "link" => true,
+
+ "global" => true,
+
+ "version" => true,
+ "since" => true,
+
+ "deprecated" => true,
+ "deprec" => true,
+
+ "brother" => true,
+ "sister" => true,
+
+ "exclude" => true,
+ "magic" => true,
+
+ "author" => true,
+ "copyright" => true,
+
+ "todo" => true
+ );
+
+ /**
+ * Analyses a function doc comment.
+ * @param array
+ * @return array
+ */
+ function analyseFunction($para) {
+
+ $function = $this->emptyFunction;
+ $function["name"] = $para["name"];
+
+ if ("" != $para["doc"]) {
+
+ $function = $this->analyseTags($this->getTags($para["doc"]), $function,
+$this->functionTags);
+
+ list($msg, $function) = $this->checkParserErrors($function, "function");
+ if (""!=$msg)
+ $this->warn->addDocWarning($this->currentFile, "function",
+$function["name"], $msg, "mismatch");
+
+ list($function["sdesc"], $function["desc"]) =
+$this->getDescription($para["doc"]);
+
+ $function["undoc"] = false;
+
+ }
+
+ $function["args"] = $this->getFunctionArgs($para["head"]);
+ return $function;
+ } // end func analyseFunction
+
+ /**
+ * Analyses a function head and returns an array of arguments.
+ *
+ * @param string PHP code to examine.
+ * @return array Array of arguments: $args[] = array( optional, default, type,
+name ).
+ * @see getVariableTypeAndValue()
+ */
+ function getFunctionArgs($code) {
+
+ $args = array();
+ while (preg_match($this->PHP_COMPLEX["argument"], $code, $regs)) {
+
+ $type = "";
+ $value = "";
+ $optional = false;
+
+ if (!isset($regs[3])) {
+
+ $len_of_value = strlen($regs[1]);
+
+ } else if ("=" == $regs[3]) {
+
+ $find = $regs[1] . $regs[2];
+ $code = substr($code, strpos($code, $find) + strlen($find) );
+
+ list ($type, $value, $raw_value) =
+$this->getVariableTypeAndValue($code);
+ $len_of_value = strlen($raw_value);
+ $optional = true;
+
+ } else {
+
+ $len_of_value = strlen($regs[1] . $regs[2]);
+
+ }
+
+ $code = substr($code, $len_of_value);
+ $args[] = array(
+ "optional" => $optional,
+ "default" => $value,
+ "type" => $type,
+ "name" => $regs[1]
+ );
+
+ }
+
+ return $args;
+ } // end func getFunctionArgs
+
} // end class PhpdocFunctionParser
-?>
\ No newline at end of file
Index: php4/pear/PHPDoc/parser/PhpdocModuleParser.php
diff -u php4/pear/PHPDoc/parser/PhpdocModuleParser.php:1.1
php4/pear/PHPDoc/parser/PhpdocModuleParser.php:1.2
--- php4/pear/PHPDoc/parser/PhpdocModuleParser.php:1.1 Sun Oct 8 03:03:19 2000
+++ php4/pear/PHPDoc/parser/PhpdocModuleParser.php Sun Feb 18 06:45:27 2001
@@ -1,141 +1,142 @@
<?php
/**
* Extracts modules and their documentation from php code.
-* @author Ulf Wendel <[EMAIL PROTECTED]>
+* @author Ulf Wendel <[EMAIL PROTECTED]>
* @version 0.1alpha
*/
class PhpdocModuleParser extends PhpdocConstantParser {
- /**
- * Empty hash that shows the structure of a module.
- * @var array
- */
- var $emptyModule = array(
-
-
"name" => "",
-
"group" => "",
-
"undoc" => true,
-
-
"functions" => array(),
-
"consts" => array(),
-
"uses" => array()
-
);
-
- /**
- * List of tags allowed within a module doc comment.
- * @var array tagname => true
- */
- var $moduleTags = array(
-
"module" => true,
-
"modulegroup" => true,
-
-
"access" => true,
-
-
"see" => true,
-
"link" => true,
-
-
"author" => true,
-
"copyright" => true,
-
-
"version" => true,
-
"since" => true,
-
-
"deprecated" => true,
-
"deprec" => true,
-
-
"brother" => true,
-
"sister" => true,
-
-
"exclude" => true,
-
-
"package" => true,
-
-
"magic" => true,
-
"todo" => true
-
);
-
- /**
- * Hash of all module groups
- * @var array
- */
- var $moduleGroups = array();
-
- /**
- * Central module parsing function.
- *
- * @param array Array of parsing data
- * @return array
- * @see analyseModuleDoc()
- */
- function analyseModule($para) {
-
- $module = $this->analyseModuleDoc($para["modules"]);
- unset($para["modules"]);
-
- $this->moduleGroups[$module["group"]][] = $module["name"];
-
- reset($para["functions"]);
- while (list($k, $data)=each($para["functions"]))
- $module["functions"][strtolower($data["name"])] =
$this->analyseFunction($data);
- unset($para["functions"]);
-
- reset($para["consts"]);
- while (list($k, $data)=each($para["consts"]))
- $module["consts"][strtolower($data["name"])] =
$this->analyseConstant($data);
- unset($para["const"]);
-
- reset($para["uses"]);
- while (list($k, $data)=each($para["uses"]))
- $module["uses"][strtolower($data["file"])] =
$this->analyseUse($data);
-
- return $module;
- } // end func analyseModule
-
- /**
- * Extracts the allowed documentation tags out of a module doc comment.
- *
- * @param array Module paragraph
- * @return array
- */
- function analyseModuleDoc($para) {
-
- $module = $this->emptyModule;
- $module["name"] = (""!=$para["name"]) ? $para["name"] :
$this->currentFile;
- $module["group"] = (""!=$para["group"]) ? $para["group"] :
$this->currentFile;
-
- if ("missing" == $para["status"]) {
-
- $msg = "The file '$this->currentFile' does not contain any
classes and seems to lack a module doc comment.";
- $this->warn->addDocWarning($this->currentFile, "module",
$module["name"], $msg, "missing");
-
- } else if ("tags missing" == $para["status"]) {
-
- $msg = "The module doc comment does not contain a @module or
@modulegroup tag, the module gets names: '$this->currentFile'";
- $this->warn->addDocWarning($this->currentFile, "module",
$module["name"], $msg, "missing");
-
- }
-
- if (""!=$para["doc"]) {
-
- $tags = $this->getTags($para["doc"]);
- $module = $this->analyseTags($tags, $module,
$this->moduleTags);
-
- list($msg, $module) = $this->checkParserErrors($module,
"module");
- if (""!=$msg)
- $this->warn->addDocWarning($this->currentFile,
"module", $module["name"], $msg, "mismatch");
-
- list($shortdesc, $fulldesc) =
$this->getDescription($para["doc"]);
- $module["sdesc"] = $shortdesc;
- $module["desc"] = $fulldesc;
-
- $module["undoc"] = false;
- }
-
- unset($module["module"]);
- unset($module["modulegroup"]);
-
- return $module;
- } // end analyseModuleDoc
-
+ /**
+ * Empty hash that shows the structure of a module.
+ * @var array
+ */
+ var $emptyModule = array(
+
+ "name" => "",
+ "group" => "",
+ "undoc" => true,
+
+ "functions" => array(),
+ "consts" => array(),
+ "uses" => array()
+ );
+
+ /**
+ * List of tags allowed within a module doc comment.
+ * @var array tagname => true
+ */
+ var $moduleTags = array(
+ "module" => true,
+ "modulegroup" => true,
+
+ "access" => true,
+
+ "see" => true,
+ "link" => true,
+
+ "author" => true,
+ "copyright" => true,
+
+ "version" => true,
+ "since" => true,
+
+ "deprecated" => true,
+ "deprec" => true,
+
+ "brother" => true,
+ "sister" => true,
+
+ "exclude" => true,
+
+ "package" => true,
+
+ "magic" => true,
+ "todo" => true
+ );
+
+ /**
+ * Hash of all module groups
+ *
+ * @var array
+ */
+ var $moduleGroups = array();
+
+ /**
+ * Central module parsing function.
+ *
+ * @param array Array of parsing data
+ * @return array
+ * @see analyseModuleDoc()
+ */
+ function analyseModule($para) {
+
+ $module = $this->analyseModuleDoc($para["modules"]);
+ unset($para["modules"]);
+
+ $this->moduleGroups[$module["group"]][] = $module["name"];
+
+ reset($para["functions"]);
+ while (list($k, $data) = each($para["functions"]))
+ $module["functions"][strtolower($data["name"])] =
+$this->analyseFunction($data);
+ unset($para["functions"]);
+
+ reset($para["consts"]);
+ while (list($k, $data) = each($para["consts"]))
+ $module["consts"][strtolower($data["name"])] =
+$this->analyseConstant($data);
+ unset($para["const"]);
+
+ reset($para["uses"]);
+ while (list($k, $data) = each($para["uses"]))
+ $module["uses"][strtolower($data["file"])] = $this->analyseUse($data);
+
+ return $module;
+ } // end func analyseModule
+
+ /**
+ * Extracts the allowed documentation tags out of a module doc comment.
+ *
+ * @param array Module paragraph
+ * @return array
+ */
+ function analyseModuleDoc($para) {
+
+ $module = $this->emptyModule;
+ $module["name"] = ("" != $para["name"]) ? $para["name"] : $this->currentFile;
+ $module["group"] = ("" != $para["group"]) ? $para["group"] :
+$this->currentFile;
+
+ if ("missing" == $para["status"]) {
+
+ $msg = "The file '$this->currentFile' does not contain any classes and
+seems to lack a module doc comment.";
+ $this->warn->addDocWarning($this->currentFile, "module", $module["name"],
+$msg, "missing");
+
+ } else if ("tags missing" == $para["status"]) {
+
+ $msg = "The module doc comment does not contain a @module or @modulegroup
+tag, the module gets names: '$this->currentFile'";
+ $this->warn->addDocWarning($this->currentFile, "module", $module["name"],
+$msg, "missing");
+
+ }
+
+ if ("" != $para["doc"]) {
+
+ $tags = $this->getTags($para["doc"]);
+ $module = $this->analyseTags($tags, $module, $this->moduleTags);
+
+ list($msg, $module) = $this->checkParserErrors($module, "module");
+ if ("" != $msg)
+ $this->warn->addDocWarning($this->currentFile, "module",
+$module["name"], $msg, "mismatch");
+
+ list($shortdesc, $fulldesc) = $this->getDescription($para["doc"]);
+
+ $module["sdesc"] = $shortdesc;
+ $module["desc"] = $fulldesc;
+
+ $module["undoc"] = false;
+ }
+
+ unset($module["module"]);
+ unset($module["modulegroup"]);
+
+ return $module;
+ } // end analyseModuleDoc
+
} // end class PhpdocModuleParser
?>
Index: php4/pear/PHPDoc/parser/PhpdocParser.php
diff -u php4/pear/PHPDoc/parser/PhpdocParser.php:1.2
php4/pear/PHPDoc/parser/PhpdocParser.php:1.3
--- php4/pear/PHPDoc/parser/PhpdocParser.php:1.2 Sun Dec 3 14:37:37 2000
+++ php4/pear/PHPDoc/parser/PhpdocParser.php Sun Feb 18 06:45:27 2001
@@ -4,447 +4,447 @@
*
* Note that a lot of communication is done using shared instance variables.
*
-* @version $Id: PhpdocParser.php,v 1.2 2000/12/03 22:37:37 uw Exp $
+* @version $Id: PhpdocParser.php,v 1.3 2001/02/18 14:45:27 uw Exp $
*/
class PhpdocParser extends PhpdocClassParser {
- /**
- * Name of the file currently parsed.
- *
- * Instead of passing the name of the current file by argument
- * PHPDoc uses this slot to communicate. Yeah I know, it's
- * the way methods should communicate, but it saves me a lot
- * a lot of work.
- * @var string Name of the file currently parsed.
- */
- var $currentFile = "";
-
- /**
- * Array of PHP Sourcecode Files to examine.
- *
- * The array keys hold the filenames, the array values the file content.
- *
- * @var array
- * @see parse()
- */
- var $phpfiles = array();
-
- /**
- * Mapping from classnames to filenames
- *
- * @var array
- */
- var $classnamesToFilenames = array();
-
- /**
- * Hash with the data of the current class tree (one parentclass with all
children).
- *
- * @var array
- * @see $modules
- */
- var $classes = array();
-
- /**
- * List of all parentclasses found.
- * @var array
- */
- var $baseclasses = array();
-
- /**
- * List of all files containing classes.
- *
- * @var array
- */
- var $classfiles = array();
-
- /**
- * Hash of all class trees.
- *
- * @var array
- */
- var $classtree = array();
-
- /**
- * List of all files containing modules.
- *
- * @var array
- */
- var $modulefiles = array();
-
- /**
- * List of all module groups.
- *
- * @var array
- */
- var $modulegroups = array();
-
- /**
- * Hash with the data of the current module group.
- *
- * @var array
- * @see $classes
- */
- var $modules = array();
-
- /**
- * Hash of all packages found.
- *
- * @var array
- */
- var $packages = array();
-
- /**
- * Flag indicating that getClassTree() was called.
- *
- * @var boolean
- * @see getClassTree()
- */
- var $flag_classtree = false;
-
- /**
- * Flag indicating that getModulegroup was called.
- *
- * @var boolean
- * @see getModulegroup()
- */
- var $flag_modulegroup = false;
-
- /**
- * Name of the base class of the current class tree.
- *
- * @var string
- * @see getClassTree()
- */
- var $current_baseclass = "";
-
- /**
- * Creates an instance of PhpdocWarning and calls buildComplexRegExps() to
initialize the object.
- *
- * @param boolean If true the parser prints status messages.
- * @see $warn, buildComplexRegExps()
- */
- function PhpdocParser($flag_output = false) {
-
- if ($flag_output)
- $this->setFlagOutput(true);
- else
- $this->setFlagOutput(false);
-
- $this->buildComplexRegExps();
-
- } // end constructor
-
- /**
- * Central parsing function.
- *
- * With version 0.3alpha PHPdoc changed the way the parser works. It does now
- * 1 1/2 parsing runs. One prescan to build the class trees and a list of module
- * groups and one deep scan to extract the information. This reduces the memory
- * consumption.
- *
- * @return boolean $ok
- * @access public
- * @see findModulegroups(), findClassTrees(), getModulesAndClasses()
- */
- function preparse() {
-
- if (0 == count($this->phpfiles)) {
- $this->err[] = new PHPDocError("Can't parse - no files
defined.", __FILE__, __LINE__);
- return false;
- }
-
- $para = array();
- reset($this->phpfiles);
- while (list($filename, $phpcode) = each($this->phpfiles))
- $para[$filename] = $this->getModulesAndClasses($phpcode);
-
- $this->findModulegroups($para);
- $this->findClassTrees($para);
-
- return true;
- } // end func preparse
-
- /**
- * Returns the data of one parentclass and all it's subclasses or false.
- *
- * Use this function to loop through the class trees. The loop should look
somewhat like:
- * <code>while ( $classtree = $parser->getClassTree() ) ...</code>
- *
- * @return mixed $classes Hash with the data of the current
class tree or false.
- * @access public
- * @see getModulegroup(), $baseclasses
- */
- function getClassTree() {
-
- // first call, reset the baseclass array pointer
- if (!$this->flag_classtree) {
- reset($this->baseclasses);
- $this->flag_classtree = true;
- }
-
- if (list($classname, $filename) = each($this->baseclasses)) {
-
- $this->classes = array();
- $this->current_baseclass = $classname;
-
- $this->addClass($classname, $filename);
-
- return $this->classes;
-
- } else {
-
- return false;
-
- }
-
- } // end func getClassTree
-
- /**
- * Returns the data of one module group.
- *
- * Use this function to loop through the module groups. The loop should look
somewhat like:
- * <code>while ( $modulegroup = $parser->getModulegroup() ) ...</code>.
- *
- * @return mixed $modulegroup Hash with the data of the
current class tree or false.
- * @access public
- * @see getClassTree(), addModule(), $modulegroups
- */
- function getModulegroup() {
-
- if (!$this->flag_modulegroup) {
- reset($this->modulegroups);
- $this->flag_modulegroup = true;
- }
-
- if (list($group, $modules) = each($this->modulegroups)) {
-
- $this->modules = array();
- while (list($modulename, $files) = each($modules)) {
- reset($files);
- while (list($k, $filename) = each($files))
- $this->addModule($group, $filename);
- }
-
- return $this->modules;
-
- } else {
-
- return false;
-
- }
-
- } // end func getModulegroup
-
- /**
- * Analyses the given file and adds the result to the module list.
- *
- * The function analyses the given file, unsets the file in the
- * file list, adds the result of the parser to the module list and
- * if necessary it adds some data to the package list.
- *
- * @param string Name of the module group the parsing result gets added.
- * @param string Name of the file to scan.
- * @see getPhpdocParagraphs(), analyseModule()
- */
- function addModule($group, $filename) {
-
- $data = $this->getPhpdocParagraphs($this->phpfiles[$filename],
array("classes", "variables") );
- // free memory as soon as possible...
- unset($this->phpfiles[$filename]);
-
- // note: not passed by argument
- $this->currentFile = $filename;
- $result = $this->analyseModule($data);
- $result["filename"] = $filename;
-
- $this->modules[$group][$result["name"]] = $result;
-
- if (isset($result["package"]))
- $this->packages[$result["package"]]["modules"][] = array (
-
"name" => $result["name"],
-
"group" => $result["group"],
-
"filename" => $filename
-
);
-
- } // end func addModule
-
- /**
- * Analyses the given file and adds the result to the class list.
- *
- * The first parameter (classname) comes from the prescan done
- * by findClassTrees()
- *
- * @param string Name of the class that gets added.
- * @param string Name of the file to scan.
- * @see addSubclasses(), analyseClass(), $classes
- */
- function addClass($classname, $filename) {
-
- $data = $this->getPhpdocParagraphs($this->phpfiles[$filename],
array("modules") );
- // free memory as soon as possible...
- unset($this->phpfiles[$filename]);
-
- $this->currentFile = $filename;
- $result = $this->analyseClass($data);
-
- // Add some informations from the classtree that was build by the
prescan to the class.
- $fields = array("subclasses", "noparent", "path", "baseclass");
- reset($fields);
- while (list($k, $field) = each($fields))
- if (isset($this->classtree[$filename][$classname][$field]))
- $result[$field] =
$this->classtree[$filename][$classname][$field];
-
- $result["filename"] = $filename;
-
- $this->classes[$classname] = $result;
- $this->addSubclasses($classname);
-
- if (isset($result["package"]))
- $this->packages[$result["package"]]["classes"][] = $classname;
-
- } // end func addClass
-
- /**
- * Adds recursively subclasses to the specified class.
- *
- * @param string Name of the class that might contain subclasses
- * @see addClass()
- */
- function addSubclasses($classname) {
-
- if (isset($this->classes[$classname]["subclasses"])) {
-
- $subclasses = $this->classes[$classname]["subclasses"];
- while (list($subclass, $v) = each($subclasses))
- $this->addClass($subclass,
$this->classnamesToFilenames[$subclass]);
-
- }
-
- } // end func addSubclasses
-
- /**
- * Builds the hash of module groups and the module file list.
- *
- * @param array Hash with the result of getClassesAndModules() of all
files
- * @see parse(), findClassTree(), $modulegroups, $modulefiles
- */
- function findModulegroups($para) {
-
- reset($para);
- while (list($filename, $data) = each($para)) {
-
- if (isset($data["modules"]["name"])) {
-
- $name = ("" != $data["modules"]["name"]) ?
$data["modules"]["name"] : $filename;
- $group = ("" != $data["modules"]["group"]) ?
$data["modules"]["group"] : $name;
-
- if (0 != count($data["classes"])) {
- // As we do not have a real parser that
returns a parsing tree we can't
- // handle modules and classes in one file.
Drop a note to the user.
- $this->warn->addDocWarning( $filename,
"module", $name, "PHPDoc is confused: module files must not contain classes. Doc will
probably be broken, module gets ignored.", "collision" );
- continue;
- }
-
- if (isset($this->modulegroups[$group][$name]))
- $this->warn->addDocWarning($filename,
"module", $name, "Warning: there's more than one module '$name' (file: '$filename) in
the module group '$group'.", "warning");
-
- $this->modulegroups[$group][$name][] = $filename;
- $this->modulefiles[] = $filename;
-
- }
-
- }
-
- } // end func findModulegroups
-
- /**
- * Builds a hash of all class trees.
- *
- * @param array Hash with the result of getClassesAndModules() of all files
- * @see parse(), findModulegroups(), $classnamesToFilenames, $classtree,
$classfiles, $baseclasses
- */
- function findClassTrees($para) {
-
- reset($para);
- while(list($filename, $data) = each($para)) {
-
- if (0!=count($data["classes"])) {
-
- $classname = $data["classes"][0]["name"];
-
- if (1<count($data["classes"]))
- $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");
-
- if (isset($data["modules"]["name"]))
- $this->warn->addDocWarning($filename, "class",
"", "Warning: found a module comment in a class file. Module comment gets ignored, doc
might be broken.", "collision");
-
- $this->classnamesToFilenames[$classname] = $filename;
- $this->classtree[$filename][$classname] =
$data["classes"][0];
- $this->classfiles[] = $filename;
-
- }
-
- }
-
- reset($this->classnamesToFilenames);
- while (list($classname, $filename)=each($this->classnamesToFilenames))
{
-
- $path = array();
- $baseclass = $classname;
- $basefile = $filename;
- $flag_noparent = false;
-
- while ($extends =
$this->classtree[$basefile][$baseclass]["extends"]) {
- if (!isset($this->classnamesToFilenames[$extends])) {
- $flag_noparent = true;
- break;
- }
-
-
$this->classtree[$this->classnamesToFilenames[$extends]][$extends]["subclasses"][$baseclass]
= true;
- $path[] = $extends;
- $baseclass = $extends;
- $basefile =
$this->classnamesToFilenames[$baseclass];
- }
-
- if ($flag_noparent)
- $this->classtree[$filename][$classname]["noparent"] =
$flag_noparent;
-
- $base = (0 == count($path)) ? true : false;
- if ($base)
- $this->baseclasses[$classname] = $filename;
- else
- $this->classtree[$filename][$classname]["path"] =
$path;
-
- if ($baseclass != $classname)
- $this->classtree[$filename][$classname]["baseclass"] =
$baseclass;
- }
-
- } // end func findClassTrees
-
- /**
- * Returns the mapping array from classnames to filenames
- *
- * @return array
- * @see $classnamesToFilenames
- */
- function getClassnamesToFilenames() {
- return $this->classnamesToFilenames;
- } // end func getClassnamesToFilenames
-
-
- /**
- * Sets the list of PHP Soucecode Files to examine.
- * @param array $phpfiles
- * @return bool $ok
- * @access public
- */
- function setPhpSourcecodeFiles($phpfiles) {
- if (!is_array($phpfiles) || 0 == count($phpfiles))
- return false;
-
- $this->phpfiles = $phpfiles;
- return true;
- } // end func setPhpSourcecodeFiles
-
+ /**
+ * Name of the file currently parsed.
+ *
+ * Instead of passing the name of the current file by argument
+ * PHPDoc uses this slot to communicate. Yeah I know, it's
+ * the way methods should communicate, but it saves me a lot
+ * a lot of work.
+ * @var string Name of the file currently parsed.
+ */
+ var $currentFile = "";
+
+ /**
+ * Array of PHP Sourcecode Files to examine.
+ *
+ * The array keys hold the filenames, the array values the file content.
+ *
+ * @var array
+ * @see parse()
+ */
+ var $phpfiles = array();
+
+ /**
+ * Mapping from classnames to filenames
+ *
+ * @var array
+ */
+ var $classnamesToFilenames = array();
+
+ /**
+ * Hash with the data of the current class tree (one parentclass with all
+children).
+ *
+ * @var array
+ * @see $modules
+ */
+ var $classes = array();
+
+ /**
+ * List of all parentclasses found.
+ * @var array
+ */
+ var $baseclasses = array();
+
+ /**
+ * List of all files containing classes.
+ *
+ * @var array
+ */
+ var $classfiles = array();
+
+ /**
+ * Hash of all class trees.
+ *
+ * @var array
+ */
+ var $classtree = array();
+
+ /**
+ * List of all files containing modules.
+ *
+ * @var array
+ */
+ var $modulefiles = array();
+
+ /**
+ * List of all module groups.
+ *
+ * @var array
+ */
+ var $modulegroups = array();
+
+ /**
+ * Hash with the data of the current module group.
+ *
+ * @var array
+ * @see $classes
+ */
+ var $modules = array();
+
+ /**
+ * Hash of all packages found.
+ *
+ * @var array
+ */
+ var $packages = array();
+
+ /**
+ * Flag indicating that getClassTree() was called.
+ *
+ * @var boolean
+ * @see getClassTree()
+ */
+ var $flag_classtree = false;
+
+ /**
+ * Flag indicating that getModulegroup was called.
+ *
+ * @var boolean
+ * @see getModulegroup()
+ */
+ var $flag_modulegroup = false;
+
+ /**
+ * Name of the base class of the current class tree.
+ *
+ * @var string
+ * @see getClassTree()
+ */
+ var $current_baseclass = "";
+
+ /**
+ * Creates an instance of PhpdocWarning and calls buildComplexRegExps() to
+initialize the object.
+ *
+ * @param boolean If true the parser prints status messages.
+ * @see $warn, buildComplexRegExps()
+ */
+ function PhpdocParser($flag_output = false) {
+
+ if ($flag_output)
+ $this->setFlagOutput(true);
+ else
+ $this->setFlagOutput(false);
+
+ $this->buildComplexRegExps();
+
+ } // end constructor
+
+ /**
+ * Central parsing function.
+ *
+ * With version 0.3alpha PHPdoc changed the way the parser works. It does now
+ * 1 1/2 parsing runs. One prescan to build the class trees and a list of module
+ * groups and one deep scan to extract the information. This reduces the memory
+ * consumption.
+ *
+ * @return boolean $ok
+ * @access public
+ * @see findModulegroups(), findClassTrees(), getModulesAndClasses()
+ */
+ function preparse() {
+
+ if (0 == count($this->phpfiles)) {
+ $this->err[] = new PHPDocError("Can't parse - no files defined.",
+__FILE__, __LINE__);
+ return false;
+ }
+
+ $para = array();
+ reset($this->phpfiles);
+ while (list($filename, $phpcode) = each($this->phpfiles))
+ $para[$filename] = $this->getModulesAndClasses($phpcode);
+
+ $this->findModulegroups($para);
+ $this->findClassTrees($para);
+
+ return true;
+ } // end func preparse
+
+ /**
+ * Returns the data of one parentclass and all it's subclasses or false.
+ *
+ * Use this function to loop through the class trees. The loop should look
+somewhat like:
+ * <code>while ( $classtree = $parser->getClassTree() ) ...</code>
+ *
+ * @return mixed $classes Hash with the data of the current class tree or
+false.
+ * @access public
+ * @see getModulegroup(), $baseclasses
+ */
+ function getClassTree() {
+
+ // first call, reset the baseclass array pointer
+ if (!$this->flag_classtree) {
+ reset($this->baseclasses);
+ $this->flag_classtree = true;
+ }
+
+ if (list($classname, $filename) = each($this->baseclasses)) {
+
+ $this->classes = array();
+ $this->current_baseclass = $classname;
+
+ $this->addClass($classname, $filename);
+
+ return $this->classes;
+
+ } else {
+
+ return false;
+
+ }
+
+ } // end func getClassTree
+
+ /**
+ * Returns the data of one module group.
+ *
+ * Use this function to loop through the module groups. The loop should look
+somewhat like:
+ * <code>while ( $modulegroup = $parser->getModulegroup() ) ...</code>.
+ *
+ * @return mixed $modulegroup Hash with the data of the current class
+tree or false.
+ * @access public
+ * @see getClassTree(), addModule(), $modulegroups
+ */
+ function getModulegroup() {
+
+ if (!$this->flag_modulegroup) {
+ reset($this->modulegroups);
+ $this->flag_modulegroup = true;
+ }
+
+ if (list($group, $modules) = each($this->modulegroups)) {
+
+ $this->modules = array();
+ while (list($modulename, $files) = each($modules)) {
+ reset($files);
+ while (list($k, $filename) = each($files))
+ $this->addModule($group, $filename);
+ }
+
+ return $this->modules;
+
+ } else {
+
+ return false;
+
+ }
+
+ } // end func getModulegroup
+
+ /**
+ * Analyses the given file and adds the result to the module list.
+ *
+ * The function analyses the given file, unsets the file in the
+ * file list, adds the result of the parser to the module list and
+ * if necessary it adds some data to the package list.
+ *
+ * @param string Name of the module group the parsing result gets added.
+ * @param string Name of the file to scan.
+ * @see getPhpdocParagraphs(), analyseModule()
+ */
+ function addModule($group, $filename) {
+
+ $data = $this->getPhpdocParagraphs($this->phpfiles[$filename],
+array("classes", "variables") );
+ // free memory as soon as possible...
+ unset($this->phpfiles[$filename]);
+
+ // note: not passed by argument
+ $this->currentFile = $filename;
+ $result = $this->analyseModule($data);
+ $result["filename"] = $filename;
+
+ $this->modules[$group][$result["name"]] = $result;
+
+ if (isset($result["package"]))
+ $this->packages[$result["package"]]["modules"][] = array (
+ "name"
+=> $result["name"],
+ "group"
+=> $result["group"],
+ "filename"
+=> $filename
+ );
+
+ } // end func addModule
+
+ /**
+ * Analyses the given file and adds the result to the class list.
+ *
+ * The first parameter (classname) comes from the prescan done
+ * by findClassTrees()
+ *
+ * @param string Name of the class that gets added.
+ * @param string Name of the file to scan.
+ * @see addSubclasses(), analyseClass(), $classes
+ */
+ function addClass($classname, $filename) {
+
+ $data = $this->getPhpdocParagraphs($this->phpfiles[$filename],
+array("modules") );
+ // free memory as soon as possible...
+ unset($this->phpfiles[$filename]);
+
+ $this->currentFile = $filename;
+ $result = $this->analyseClass($data);
+
+ // Add some informations from the classtree that was build by the prescan to
+the class.
+ $fields = array("subclasses", "noparent", "path", "baseclass");
+ reset($fields);
+ while (list($k, $field) = each($fields))
+ if (isset($this->classtree[$filename][$classname][$field]))
+ $result[$field] = $this->classtree[$filename][$classname][$field];
+
+ $result["filename"] = $filename;
+
+ $this->classes[$classname] = $result;
+ $this->addSubclasses($classname);
+
+ if (isset($result["package"]))
+ $this->packages[$result["package"]]["classes"][] = $classname;
+
+ } // end func addClass
+
+ /**
+ * Adds recursively subclasses to the specified class.
+ *
+ * @param string Name of the class that might contain subclasses
+ * @see addClass()
+ */
+ function addSubclasses($classname) {
+
+ if (isset($this->classes[$classname]["subclasses"])) {
+
+ $subclasses = $this->classes[$classname]["subclasses"];
+ while (list($subclass, $v) = each($subclasses))
+ $this->addClass($subclass, $this->classnamesToFilenames[$subclass]);
+
+ }
+
+ } // end func addSubclasses
+
+ /**
+ * Builds the hash of module groups and the module file list.
+ *
+ * @param array Hash with the result of getClassesAndModules() of all files
+ * @see parse(), findClassTree(), $modulegroups, $modulefiles
+ */
+ function findModulegroups($para) {
+
+ reset($para);
+ while (list($filename, $data) = each($para)) {
+
+ if (isset($data["modules"]["name"])) {
+
+ $name = ("" != $data["modules"]["name"]) ? $data["modules"]["name"] :
+$filename;
+ $group = ("" != $data["modules"]["group"]) ?
+$data["modules"]["group"] : $name;
+
+ if (0 != count($data["classes"])) {
+ // As we do not have a real parser that returns a parsing tree we
+can't
+ // handle modules and classes in one file. Drop a note to the
+user.
+ $this->warn->addDocWarning( $filename, "module", $name,
+"PHPDoc is confused: module files must not contain classes. Doc will probably be
+broken, module gets ignored.", "collision" );
+ continue;
+ }
+
+ if (isset($this->modulegroups[$group][$name]))
+ $this->warn->addDocWarning($filename, "module", $name, "Warning:
+there's more than one module '$name' (file: '$filename) in the module group
+'$group'.", "warning");
+
+ $this->modulegroups[$group][$name][] = $filename;
+ $this->modulefiles[] = $filename;
+
+ }
+
+ }
+
+ } // end func findModulegroups
+
+ /**
+ * Builds a hash of all class trees.
+ *
+ * @param array Hash with the result of getClassesAndModules() of all files
+ * @see parse(), findModulegroups(), $classnamesToFilenames, $classtree,
+$classfiles, $baseclasses
+ */
+ function findClassTrees($para) {
+
+ reset($para);
+ while(list($filename, $data) = each($para)) {
+
+ if (0!=count($data["classes"])) {
+
+ $classname = $data["classes"][0]["name"];
+
+ if (1<count($data["classes"]))
+ $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");
+
+ if (isset($data["modules"]["name"]))
+ $this->warn->addDocWarning($filename, "class", "", "Warning:
+found a module comment in a class file. Module comment gets ignored, doc might be
+broken.", "collision");
+
+ $this->classnamesToFilenames[$classname] = $filename;
+ $this->classtree[$filename][$classname] = $data["classes"][0];
+ $this->classfiles[] = $filename;
+
+ }
+
+ }
+
+ reset($this->classnamesToFilenames);
+ while (list($classname, $filename)=each($this->classnamesToFilenames)) {
+
+ $path = array();
+ $baseclass = $classname;
+ $basefile = $filename;
+ $flag_noparent = false;
+
+ while ($extends = $this->classtree[$basefile][$baseclass]["extends"]) {
+ if (!isset($this->classnamesToFilenames[$extends])) {
+ $flag_noparent = true;
+ break;
+ }
+
+
+$this->classtree[$this->classnamesToFilenames[$extends]][$extends]["subclasses"][$baseclass]
+ = true;
+ $path[] = $extends;
+ $baseclass = $extends;
+ $basefile = $this->classnamesToFilenames[$baseclass];
+ }
+
+ if ($flag_noparent)
+ $this->classtree[$filename][$classname]["noparent"] = $flag_noparent;
+
+ $base = (0 == count($path)) ? true : false;
+ if ($base)
+ $this->baseclasses[$classname] = $filename;
+ else
+ $this->classtree[$filename][$classname]["path"] = $path;
+
+ if ($baseclass != $classname)
+ $this->classtree[$filename][$classname]["baseclass"] = $baseclass;
+ }
+
+ } // end func findClassTrees
+
+ /**
+ * Returns the mapping array from classnames to filenames
+ *
+ * @return array
+ * @see $classnamesToFilenames
+ */
+ function getClassnamesToFilenames() {
+ return $this->classnamesToFilenames;
+ } // end func getClassnamesToFilenames
+
+
+ /**
+ * Sets the list of PHP Soucecode Files to examine.
+ * @param array $phpfiles
+ * @return bool $ok
+ * @access public
+ */
+ function setPhpSourcecodeFiles($phpfiles) {
+ if (!is_array($phpfiles) || 0 == count($phpfiles))
+ return false;
+
+ $this->phpfiles = $phpfiles;
+ return true;
+ } // end func setPhpSourcecodeFiles
+
} // end class PhpdocParser
?>
Index: php4/pear/PHPDoc/parser/PhpdocParserCore.php
diff -u php4/pear/PHPDoc/parser/PhpdocParserCore.php:1.3
php4/pear/PHPDoc/parser/PhpdocParserCore.php:1.4
--- php4/pear/PHPDoc/parser/PhpdocParserCore.php:1.3 Sun Dec 3 14:37:37 2000
+++ php4/pear/PHPDoc/parser/PhpdocParserCore.php Sun Feb 18 06:45:27 2001
@@ -5,657 +5,658 @@
* Provides basic parser functions to extract doc comments, analyse tags and variable
* declarations.
*
-* @version $Id: PhpdocParserCore.php,v 1.3 2000/12/03 22:37:37 uw Exp $
+* @version $Id: PhpdocParserCore.php,v 1.4 2001/02/18 14:45:27 uw Exp $
*/
class PhpdocParserCore extends PhpdocParserTags {
-
- /**
- * Scans code for documented and undocumented phpdoc keywords (classes,
functions, class variables, uses, constants).
- *
- * This method is somewhat the heart of the phpdoc parser. It takes a string of
- * phpcode and extracts all classes, functions, class variables, uses (include
and friends),
- * and constants (define) from it. Extract does not mean that the whole class
or another element
- * gets extracted. It does not take the code from the class definition and it's
opening
- * curly brace to the closing one. PHPDoc just extracts the class definition
itself and
- * if available a trailing doc comment. This has some drawbacks: phpdoc can't
handle
- * files that contain more than one class it wouldn't know which method/class
variable belongs to
- * a certain class. It's possible to provide a workaround but phpdoc would slow
down dramatically.
- * As PHPDoc does not have a real parser but does a simple grep using a bunch
of regular expressions
- * there're indeed more limitations. Nevertheless I doubt that you'll have
problems with "normal" code.
- *
- * The search algorithm looks pretty strange but belive me it's fast. I have
tried several other ways
- * (really complex regexps >500 chars, preg_match_all + looking backwards for
comments, ...) but none was
- * faster. This one takes 13s on my machine to scan the current (14/08/2000)
code (7130 lines), the
- * big RegExp way took more than 5 Minutes, the preg_match_all + looking
backwards 52s.
- *
- * @param string PHP code to scan.
- * @param mixed String of one keyword or array of keywords not
to scan for. Known keywords are:
- *
"classes", "functions", "variables", "uses", "consts".
- * @return array Hash of phpdoc elements found, indexed by "variables",
"functions", "classes", "consts", "uses".
- * @see $PHP_BASE, $PHP_COMPLEX, $C_BASE, $C_COMPLEX, extractPhpdoc(),
getModuleDoc()
- */
- function getPhpdocParagraphs($phpcode, $keywords="none") {
-
- // what are we not looking for?
- if ( !is_array($keywords) ) {
- if ("none" == $keywords)
- $keywords = array ();
- else
- $keywords = array ( $keywords => true );
- }
-
- $start = 0;
- $paragraphs = array(
-
"classes" => array(),
-
"functions" => array(),
-
"variables" => array(),
-
"consts" => array(),
-
"uses" => array(),
-
"modules" => array()
-
);
-
-
- // remember the documented elements to be able to compare with the
list of all elements
- $variables = array();
- $functions = array();
- $variables = array();
- $constants = array();
- $uses = array();
-
- //
- // Module docs are somewhat more difficult to grep. Always
- // use this function.
- //
- if (!isset($keywords["modules"]))
- list($paragraphs["modules"], $phpcode) =
$this->getModuleDoc($phpcode);
- else
- list( , $phpcode) = $this->getModuleDoc($phpcode);
-
- //
- // Find documented elements
- //
-
- while (true) {
-
- $start = strpos($phpcode, "/**", $start);
- if (0==(int)$start && "integer" != gettype($start) )
- break;
-
- $end = strpos($phpcode, "*/", $start);
- $remaining = trim(substr($phpcode, $end+2));
-
- if ( !isset($keywords["classes"]) &&
preg_match($this->PHP_COMPLEX["class"], $remaining, $regs) ||
preg_match($this->PHP_COMPLEX["class_extends"], $remaining, $regs)) {
-
- $paragraphs["classes"][] = array(
-
"name" => $regs[1],
-
"extends" => (isset($regs[2])) ? $regs[2] : "",
-
"doc"
=> $this->extractPhpdoc(substr($phpcode, $start+3, ($end-$start)-2))
-
);
- $classes[$regs[1]] = true;
-
- } else if ( !isset($keywords["functions"]) &&
preg_match($this->PHP_COMPLEX["function"], $remaining, $regs)) {
-
- $head = substr($remaining, strpos($remaining,
$regs[0])+strlen($regs[0]));
- $head = substr( trim($this->getValue($head, array( "{"
=> true) )), 0, -1);
- $paragraphs["functions"][] = array(
-
"name" => $regs[1],
-
"doc" => $this->extractPhpdoc( substr($phpcode, $start+3, ($end-$start)-2)
),
-
"head" => $head
-
);
- $functions[$regs[1]] = true;
-
- } else if ( !isset($keywords["variables"]) &&
preg_match($this->PHP_COMPLEX["var"], $remaining, $regs)) {
-
- if ("=" == $regs[2])
- $value = trim($this->getValue(
substr($remaining, strpos($remaining, $regs[0])+strlen($regs[0]) ), array( ";" =>
true)));
- else
- $value = "";
-
- $paragraphs["variables"][] = array(
-
"name" => $regs[1],
-
"value" => $value,
-
"doc" => $this->extractPhpdoc(substr($phpcode, $start+3, ($end-$start)-2))
-
);
- $variables[$regs[1]] = true;
-
- } else if ( !isset($keywords["consts"]) &&
preg_match($this->PHP_COMPLEX["const"], $remaining, $regs) ) {
-
- $name = (""!=$regs[2]) ? substr($regs[1], 1, -1) :
$regs[1];
-
- if (isset($regs[5])) {
- if ($regs[5])
- $case = "case insensitive,
userdefined: '$regs[5]'";
- else
- $case = "case sensitive, userdefined:
'$regs[5]'";
- } else {
- $case = "default: case sensitive";
- }
-
- $paragraphs["consts"][] = array(
-
"name" => $name,
-
"value" => (""!=$regs[4]) ? substr($regs[3], 1, -1) : $regs[3],
-
"case" => $case,
-
"doc"
=> $this->extractPhpdoc(substr($phpcode, $start+3, ($end-$start)-2))
-
);
- $constants[$name] = true;
-
- } else if ( !isset($keywords["uses"]) &&
preg_match($this->PHP_COMPLEX["use"], $remaining, $regs)) {
-
- $filename = isset($regs[5]) ? $regs[5] : $regs[4];
- $paragraphs["uses"][] = array(
-
"type" =>
$regs[1],
-
"file" =>
$filename,
-
"doc"
=> $this->extractPhpdoc(substr($phpcode, $start+3, ($end-$start)-2))
-
);
- $uses[$filename] = true;
-
- }
-
- $start++;
- }
-
- //
- // Find undocumented elements
- //
- if (!isset($keywords["classes"])) {
-
- preg_match_all($this->PHP_COMPLEX["undoc_class"], $phpcode,
$regs, PREG_SET_ORDER);
- reset($regs);
- while (list($k, $data)=each($regs))
- if (!isset($classes[$data[1]]))
- $paragraphs["classes"][] = array(
-
"name" => $data[1],
-
"extends" => "",
-
"doc" => ""
-
);
-
- preg_match_all($this->PHP_COMPLEX["undoc_class_extends"],
$phpcode, $regs, PREG_SET_ORDER);
- reset($regs);
- while (list($k, $data)=each($regs))
- if (!isset($classes[$data[1]]))
- $paragraphs["classes"][] = array(
-
"name" => $data[1],
-
"extends" => $data[2],
-
"doc" => ""
-
);
-
- }
-
- if (!isset($keywords["functions"])) {
-
- preg_match_all($this->PHP_COMPLEX["undoc_function"], $phpcode,
$regs, PREG_SET_ORDER);
- reset($regs);
- while (list($k, $data)=each($regs))
- if (!isset($functions[$data[1]])) {
-
- $head = substr($phpcode, strpos($phpcode,
$data[0])+strlen($data[0]));
- $head = substr( trim( $this->getValue($head,
array( "{" => true) )), 0, -1);
- $paragraphs["functions"][] = array(
-
"name" => $data[1],
-
"doc" => "",
-
"head" => $head
-
);
- }
-
- }
-
-
- if (!isset($keywords["variables"])) {
-
- preg_match_all($this->PHP_COMPLEX["undoc_var"], $phpcode,
$regs, PREG_SET_ORDER);
- reset($regs);
- while (list($k, $data)=each($regs))
- if (!isset($variables[$data[1]])) {
-
- if ("=" == $data[2])
- $value = trim($this->getValue(
substr($phpcode, strpos($phpcode, $data[0])+strlen($data[0]) ), array( ";" => true)));
- else
- $value = "";
-
- $paragraphs["variables"][] = array(
-
"name" => $data[1],
-
"value" => $value,
-
"doc" => ""
-
);
- }
- }
-
- if (!isset($keywords["consts"])) {
-
- preg_match_all($this->PHP_COMPLEX["undoc_const"], $phpcode,
$regs, PREG_SET_ORDER);
- reset($regs);
- while (list($k, $data)=each($regs)) {
-
- $name = (""!=$data[2]) ? substr($data[1], 1, -1) :
$data[1];
- if (!isset($constants[$name])) {
-
- if (isset($data[5])) {
- if ($data[5])
- $case = "case insensitive,
userdefined: '$data[5]'";
- else
- $case = "case sensitive,
userdefined: '$data[5]'";
- } else {
- $case = "default: case sensitive";
- }
-
- $paragraphs["consts"][] = array(
-
"name" => $name,
-
"value" => (""!=$data[4]) ? substr($data[3], 1, -1) : $data[3],
-
"case" => $case,
-
"doc"
=> ""
-
);
- }
- }
- }
-
- if (!isset($keywords["uses"])) {
-
- preg_match_all($this->PHP_COMPLEX["undoc_use"], $phpcode,
$regs, PREG_SET_ORDER);
-
- reset($regs);
- while (list($k, $data)=each($regs)) {
-
- $filename = isset($data[5]) ? $data[5] : $data[4];
- if (!isset($uses[$filename])) {
-
- $paragraphs["uses"][] = array(
-
"type" => $data[1],
-
"file" => $filename,
-
"doc"
=> ""
-
);
-
- }
- }
-
- }
-
- return $paragraphs;
- } // end func getPhpdocParagraphs
-
- /**
- * Does a quick prescan to find modules an classes.
- * @param string Code to scan
- * @return array Hash of modules and classes found in the given
code
- * @access public
- * @see getPhpdocParagraphs()
- */
- function getModulesAndClasses($phpcode) {
-
- $para = array();
- list( $para["modules"], $phpdcode) = $this->getModuleDoc($phpcode);
- $para["classes"] = $this->getClasses($phpcode);
-
- return $para;
- } // end func getModulesAndClasses
-
- /**
- * Tries to extract a module doc.
- *
- * The syntax for modules is not final yet. The implementation and meaning of
"module"
- * might change at every time! Please do not ask for implementation details.
- *
- * @param string PHP Code to scan
- * @return array $module $module[0] = array with module data,
- *
$module[1] = php code without the leading module doc
- */
- function getModuleDoc($phpcode) {
-
- $module = array();
-
- if (preg_match($this->C_COMPLEX["module_doc"], $phpcode, $regs) ) {
-
- $start = strlen($regs[0]);
- $end = strpos($phpcode, "*/", $start);
- $remaining = substr($phpcode, $end+2);
- $doc_comment= substr($phpcode, $start, $end-$start);
-
- // Do we have OO Code? If not, continue.
- if ( !preg_match($this->PHP_COMPLEX["class"], $remaining) &&
!preg_match($this->PHP_COMPLEX["class_extends"], $remaining) ) {
-
- // Is there a module tag?
- if ( preg_match($this->C_COMPLEX["module_tags"],
$doc_comment) ) {
-
- $doc_comment =
$this->extractPhpDoc($doc_comment);
- $tags = $this->getTags( $doc_comment);
- $allowed = array (
-
"module" => true,
-
"modulegroup" => true
-
-
);
- $tags = $this->analyseTags( $tags, array(),
array( "module" => true, "modulegroup" => true) );
-
- $module = array (
-
"doc" => $doc_comment,
-
"status" => "ok",
-
"name" => (isset($tags["module"])) ? $tags["module"]
: "",
-
"group" => (isset($tags["modulegroup"])) ?
$tags["modulegroup"] : ""
-
);
-
- } else {
-
- // No module tag.
- // Try the remaining keywords. If one matches
it's not a module doc
- // assume that the module doc is missing. If
none matches assume that
- // it's a module doc which lacks the module
tags.
- if (
preg_match($this->PHP_COMPLEX["function"], $remaining) ||
-
preg_match($this->PHP_COMPLEX["use"], $remaining) ||
-
preg_match($this->PHP_COMPLEX["const"], $remaining) ||
-
preg_match($this->PHP_COMPLEX["var"], $remaining)
- ) {
-
- $module = array(
-
"doc" => "",
-
"status" => "missing",
-
"name" => "",
-
"group" => ""
-
);
- $remaining = $phpcode;
-
- } else {
-
- $module = array (
-
"doc" => $doc_comment,
-
"status" => "tags missing",
-
"name" => "",
-
"group" => ""
-
);
-
- }
-
- } // end if module_tags
-
- } else {
-
- $remaining = $phpcode;
-
- } // end if class
-
- } else {
-
- $remaining = $phpcode;
-
- }
-
- return array($module, $remaining);
- } // end func getModuleDoc
-
- /**
- * Returns a list of classes found in the given code.
- *
- * In early versions PHPdoc parsed all the code at once which restulted in huge
- * memory intensive hashes. Now it scans for classes, builds a classtree and
- * does the parsing step by step, writing information to the destination
- * (renderer, exporter) as soon as possible. This reduces the memory
consumption
- * dramatically. getPhpdocParagraphs() could be used to extract the class
definitions
- * as well but this specialized function is somewhat faster.
- *
- * @param string PHP code to scan.
- * @return array $classes Array of classes found in the
code. $classes[classname] = extends
- */
- function getClasses($phpcode) {
-
- $classes = array();
-
- preg_match_all($this->PHP_COMPLEX["undoc_class"], $phpcode, $regs,
PREG_SET_ORDER);
- reset($regs);
- while (list($k, $data)=each($regs))
- $classes[] = array(
-
"name" => $data[1],
-
"extends" => ""
-
);
-
- preg_match_all($this->PHP_COMPLEX["undoc_class_extends"], $phpcode,
$regs, PREG_SET_ORDER);
- reset($regs);
- while (list($k, $data)=each($regs))
- $classes[] = array(
-
"name" => $data[1],
-
"extends" => $data[2]
-
);
-
- return $classes;
- } // end func getClasses
-
- /**
- * Strips "/xx", "x/" and x from doc comments (x means asterix).
- * @param string Doc comment to clean up.
- * @return string $phpdoc
- */
- function extractPhpdoc($paragraph) {
-
- $lines = split( $this->PHP_BASE["break"], $paragraph);
- $phpdoc = "";
-
- reset($lines);
- while (list($k, $line)=each($lines)) {
-
- $line = trim($line);
- if (""==$line)
- continue;
-
- if ("*" == $line[0])
- $phpdoc.= trim(substr($line, 1))."\n";
- else
- $phpdoc.= $line."\n";
-
- }
-
- return substr($phpdoc, 0, -1);
- } // end func extractPhpdoc
-
- /**
- * Extract the description from a PHPDoc doc comment.
- *
- * Every PHPDoc doc comment has the same syntax: /xx[break][x]short description
- * [break][[x]multiple line long description[break]][[x]@list of tags[. This
function
- * returns an array of the short description and long description.
- *
- * @param string Doc comment to examine.
- * @return array $description $description[0] = short
description (first line),
- *
$description[1] = long description (second
line upto the first tag)
- */
- function getDescription($phpdoc) {
-
- // find the position of the first doc tag
- $positions = $this->getTagPos($phpdoc);
-
- if (0 == count($positions))
- $desc = trim($phpdoc); // no doc tags
- else
- $desc = trim(substr($phpdoc, 0, $positions[0]["pos"])); //
strip tags
-
- $lines = split($this->PHP_BASE["break"], $desc);
-
- if (1 == count($lines) || "" == $desc) {
-
- // only a short description but no long description - or even
none of both
- $description = array ($desc, "");
-
- } else {
-
- $sdesc = trim($lines[0]);
- unset($lines[0]);
-
- $description = array ( $sdesc, implode("", $lines) );
-
- }
-
- return $description;
- } // end func getDescription
-
- /**
- * Scans a code passage for a value.
- *
- * There some cases where you can hardly use a regex to grep a value
- * because the value might contain unescaped charaters that end the value.
- * Value means something like "array ( ";", '\;' );" or "'phpdoc; ';" where
- * the delimiter would be ";".
- *
- * @param string The php code to examine.
- * @param mixed String of one delimiter or array of delimiters.
- * @return string Value found in the code
- * @todo Racecondition: comments
- */
- function getValue($code, $delimiter) {
- if (""==$code)
- return "";
-
- if (!is_array($delimiter))
- $delimiter = array( $delimiter => true );
-
- $code = trim($code);
- $len = strlen($code);
- $enclosed = false;
- $enclosed_by = "";
-
- if ( isset($delimiter[$code[0]]) ) {
-
- $i = 1;
-
- } else {
-
- for ($i=0; $i<$len; $i++) {
-
- $char = $code[$i];
-
- if (('"'==$char || "'"==$char) && ($char ==
$enclosed_by || ""==$enclosed_by) && (0==$i || ($i>0 && "\\"!=$code[$i-1]))) {
-
- if (!$enclosed)
- $enclosed_by = $char;
- else
- $enclosed_by = "";
-
- $enclosed = !$enclosed;
-
- }
- if (!$enclosed && isset($delimiter[$char]))
- break;
-
- }
-
- }
-
- return substr($code, 0, $i);
- } // end func getValue
-
- /**
- * Analyses a code snipped and returns the type and value of the first variable
found.
- *
- * With version 0.3 PHPDoc tries to analyse variable declarations to find
- * type and value. This is used to analyse class variable declarations and
- * optional function arguments.
- *
- * Note that all regular expressions in this function start with "^". That means
- * you have to do some preparations to the code snippet you're passing to this
- * function.
- *
- * @param string PHP code to analyse
- * @param boolean Flag indicating the "type" of code to analyse.
Optional
- * function
parameters and class variables have a slightly
- * different
syntax for arrays. By default function parameters
- are
expected.
- * @return array $vartype $vartype[0] = type, $vartype[1] = value,
$vartype[2] = raw value
- */
- function getVariableTypeAndValue($code, $flag_args = true) {
-
- $type = "unknown";
- $value = "unknown";
- $raw_value = $code;
-
- //
- // Do not change the order the function tries to find out the type.
- //
-
- if (preg_match( $this->PHP_COMPLEX["type_boolean"], $code, $regs)) {
-
- $type = "boolean";
- $raw_value = $regs[0];
- $value = $regs[0];
-
- } else if (preg_match( $this->PHP_COMPLEX["type_string_enclosed"],
$code, $regs)) {
-
- $type = "string";
- $raw_value = $regs[0];
- $value = $regs[0];
-
- } else if (preg_match( $this->PHP_COMPLEX["type_int_oct"],
$code, $regs)) {
-
- $type = "integer (octal)";
- $raw_value = $regs[0];
- $value = preg_replace("@\s@", "",
$regs[0]);
- if ( (int)$value != $value )
- $type.= " [warning: out of integer range, possible
overflow trouble]";
- $value = octdec($value)." ($value)";
-
-
- } else if (preg_match( $this->PHP_COMPLEX["type_int_hex"], $code,
$regs)) {
-
- $type = "integer
(hexadecimal)";
- $raw_value = $regs[0];
- $value = preg_replace("@\s@", "",
$regs[0]);
- if ( (int)$value != $value )
- $type.= " [warning: out of integer range, possible
overflow trouble]";
- $value = hexdec($value)." ($value)";
-
- } else if (preg_match( $this->PHP_COMPLEX["type_float_exponent"],
$code, $regs)) {
-
- $type = "float";
- $raw_value = $regs[0];
- $value = (string)preg_replace("@\s@",
"", $regs[0]);
- if ( (float)$value != $value )
- $type.= " [warning: out of float range]";
- $value = (float)$value;
-
- } else if (preg_match( $this->PHP_COMPLEX["type_float"], $code,
$regs)) {
-
- $type = "float";
- $raw_value = $regs[0];
- $value = preg_replace("@\s@", "",
$regs[0]);
- if ( (float)$value != $value )
- $type.= " [warning: out of float range]";
- $value = (float)$value;
-
- } else if (preg_match( $this->PHP_COMPLEX["type_number"], $code,
$regs)) {
-
- $value = preg_replace("@\s@", "",
$regs[0]);
- $raw_value = $regs[0];
-
- if ( (int)$value == $value ) {
-
- $type = "integer";
- $value = (int)$value;
-
- } else {
-
- $type = "float";
- if ( (float)$value != $value )
- $type.=" [warning: out of float range]";
- $value = (float)$value;
-
- }
-
- } else if ($flag_args && preg_match(
$this->PHP_COMPLEX["type_empty_array"], $code, $regs)) {
-
- $value = "array()";
- $raw_value = $regs[0];
- $type = "array";
-
- } else if (!$flag_args && preg_match(
$this->PHP_COMPLEX["type_array"], $code, $regs)) {
-
- $value = $this->getValue( $code, array(";" => true));
- // strpos() is twice as fast as substr()
- if ( 0 == strpos($value, "array"))
- $type = "array";
- $raw_value == $value;
-
- } else if (preg_match( $this->PHP_COMPLEX["type_string"], $code,
$regs)) {
-
- $type = "string";
- $raw_value = $regs[0];
- $value = $regs[0];
- }
-
- return array($type, $value, $raw_value);
- } // end func getVariableTypeAndValue
-
+
+ /**
+ * Scans code for documented and undocumented phpdoc keywords (classes, functions,
+class variables, uses, constants).
+ *
+ * This method is somewhat the heart of the phpdoc parser. It takes a string of
+ * phpcode and extracts all classes, functions, class variables, uses (include and
+friends),
+ * and constants (define) from it. Extract does not mean that the whole class or
+another element
+ * gets extracted. It does not take the code from the class definition and it's
+opening
+ * curly brace to the closing one. PHPDoc just extracts the class definition
+itself and
+ * if available a trailing doc comment. This has some drawbacks: phpdoc can't
+handle
+ * files that contain more than one class it wouldn't know which method/class
+variable belongs to
+ * a certain class. It's possible to provide a workaround but phpdoc would slow
+down dramatically.
+ * As PHPDoc does not have a real parser but does a simple grep using a bunch of
+regular expressions
+ * there're indeed more limitations. Nevertheless I doubt that you'll have
+problems with "normal" code.
+ *
+ * The search algorithm looks pretty strange but belive me it's fast. I have tried
+several other ways
+ * (really complex regexps >500 chars, preg_match_all + looking backwards for
+comments, ...) but none was
+ * faster. This one takes 13s on my machine to scan the current (14/08/2000) code
+(7130 lines), the
+ * big RegExp way took more than 5 Minutes, the preg_match_all + looking backwards
+52s.
+ *
+ * @param string PHP code to scan.
+ * @param mixed String of one keyword or array of keywords not to scan for.
+Known keywords are:
+ * "classes", "functions", "variables", "uses", "consts".
+ * @return array Hash of phpdoc elements found, indexed by "variables",
+"functions", "classes", "consts", "uses".
+ * @see $PHP_BASE, $PHP_COMPLEX, $C_BASE, $C_COMPLEX, extractPhpdoc(),
+getModuleDoc()
+ */
+ function getPhpdocParagraphs($phpcode, $keywords="none") {
+
+ // what are we not looking for?
+ if ( !is_array($keywords) ) {
+ if ("none" == $keywords)
+ $keywords = array ();
+ else
+ $keywords = array ( $keywords => true );
+ }
+
+ $start = 0;
+ $paragraphs = array(
+ "classes" => array(),
+ "functions" => array(),
+ "variables" => array(),
+ "consts" => array(),
+ "uses" => array(),
+ "modules" => array()
+ );
+
+
+ // remember the documented elements to be able to compare with the list of
+all elements
+ $variables = array();
+ $functions = array();
+ $variables = array();
+ $constants = array();
+ $uses = array();
+
+ //
+ // Module docs are somewhat more difficult to grep. Always
+ // use this function.
+ //
+ if (!isset($keywords["modules"]))
+ list($paragraphs["modules"], $phpcode) = $this->getModuleDoc($phpcode);
+ else
+ list( , $phpcode) = $this->getModuleDoc($phpcode);
+
+ //
+ // Find documented elements
+ //
+
+ while (true) {
+
+ $start = strpos($phpcode, "/**", $start);
+ if (0 == (int)$start && "integer" != gettype($start) )
+ break;
+
+ $end = strpos($phpcode, "*/", $start);
+ $remaining = trim(substr($phpcode, $end + 2));
+
+ if ( !isset($keywords["classes"]) &&
+preg_match($this->PHP_COMPLEX["class"], $remaining, $regs) ||
+preg_match($this->PHP_COMPLEX["class_extends"], $remaining, $regs)) {
+
+ $paragraphs["classes"][] = array(
+ "name" => $regs[1],
+ "extends" => (isset($regs[2])) ?
+$regs[2] : "",
+ "doc" =>
+$this->extractPhpdoc(substr($phpcode, $start + 3, ($end-$start) - 2))
+ );
+ $classes[$regs[1]] = true;
+
+ } else if ( !isset($keywords["functions"]) &&
+preg_match($this->PHP_COMPLEX["function"], $remaining, $regs)) {
+
+ $head = substr($remaining, strpos($remaining, $regs[0]) +
+strlen($regs[0]));
+ $head = substr( trim($this->getValue($head, array( "{" => true) )),
+0, -1);
+ $paragraphs["functions"][] = array(
+ "name" => $regs[1],
+ "doc" => $this->extractPhpdoc(
+substr($phpcode, $start+3, ($end-$start)-2) ),
+ "head" => $head
+ );
+ $functions[$regs[1]] = true;
+
+ } else if ( !isset($keywords["variables"]) &&
+preg_match($this->PHP_COMPLEX["var"], $remaining, $regs)) {
+
+ if ("=" == $regs[2])
+ $value = trim($this->getValue( substr($remaining,
+strpos($remaining, $regs[0]) + strlen($regs[0]) ), array( ";" => true)));
+ else
+ $value = "";
+
+ $paragraphs["variables"][] = array(
+ "name" => $regs[1],
+ "value" => $value,
+ "doc" =>
+$this->extractPhpdoc(substr($phpcode, $start + 3, ($end-$start) - 2))
+ );
+ $variables[$regs[1]] = true;
+
+ } else if ( !isset($keywords["consts"]) &&
+preg_match($this->PHP_COMPLEX["const"], $remaining, $regs) ) {
+
+ $name = ("" != $regs[2]) ? substr($regs[1], 1, -1) : $regs[1];
+
+ if (isset($regs[5])) {
+ if ($regs[5])
+ $case = "case insensitive, userdefined: '$regs[5]'";
+ else
+ $case = "case sensitive, userdefined: '$regs[5]'";
+ } else {
+ $case = "default: case sensitive";
+ }
+
+ $paragraphs["consts"][] = array(
+ "name" => $name,
+ "value" => ("" != $regs[4]) ?
+substr($regs[3], 1, -1) : $regs[3],
+ "case" => $case,
+ "doc" =>
+$this->extractPhpdoc(substr($phpcode, $start + 3, ($end - $start) - 2))
+ );
+ $constants[$name] = true;
+
+ } else if ( !isset($keywords["uses"]) &&
+preg_match($this->PHP_COMPLEX["use"], $remaining, $regs)) {
+
+ $filename = isset($regs[5]) ? $regs[5] : $regs[4];
+ $paragraphs["uses"][] = array(
+ "type" => $regs[1],
+ "file" => $filename,
+ "doc" =>
+$this->extractPhpdoc(substr($phpcode, $start + 3, ($end - $start) - 2))
+ );
+ $uses[$filename] = true;
+
+ }
+
+ $start++;
+ }
+
+ //
+ // Find undocumented elements
+ //
+ if (!isset($keywords["classes"])) {
+
+ preg_match_all($this->PHP_COMPLEX["undoc_class"], $phpcode, $regs,
+PREG_SET_ORDER);
+ reset($regs);
+ while (list($k, $data) = each($regs))
+ if (!isset($classes[$data[1]]))
+ $paragraphs["classes"][] = array(
+ "name" => $data[1],
+ "extends" => "",
+ "doc" => ""
+ );
+
+ preg_match_all($this->PHP_COMPLEX["undoc_class_extends"], $phpcode,
+$regs, PREG_SET_ORDER);
+ reset($regs);
+ while (list($k, $data) = each($regs))
+ if (!isset($classes[$data[1]]))
+ $paragraphs["classes"][] = array(
+ "name" => $data[1],
+ "extends" => $data[2],
+ "doc" => ""
+ );
+
+ }
+
+ if (!isset($keywords["functions"])) {
+
+ preg_match_all($this->PHP_COMPLEX["undoc_function"], $phpcode, $regs,
+PREG_SET_ORDER);
+ reset($regs);
+ while (list($k, $data) = each($regs))
+ if (!isset($functions[$data[1]])) {
+
+ $head = substr($phpcode, strpos($phpcode, $data[0]) +
+strlen($data[0]));
+ $head = substr(trim( $this->getValue($head, array( "{" => true)
+)), 0, -1);
+ $paragraphs["functions"][] = array(
+ "name" => $data[1],
+ "doc" => "",
+ "head" => $head
+ );
+ }
+
+ }
+
+
+ if (!isset($keywords["variables"])) {
+
+ preg_match_all($this->PHP_COMPLEX["undoc_var"], $phpcode, $regs,
+PREG_SET_ORDER);
+ reset($regs);
+ while (list($k, $data) = each($regs))
+ if (!isset($variables[$data[1]])) {
+
+ if ("=" == $data[2])
+ $value = trim($this->getValue( substr($phpcode,
+strpos($phpcode, $data[0]) + strlen($data[0]) ), array( ";" => true)));
+ else
+ $value = "";
+
+ $paragraphs["variables"][] = array(
+ "name" => $data[1],
+ "value" => $value,
+ "doc" => ""
+ );
+ }
+ }
+
+ if (!isset($keywords["consts"])) {
+
+ preg_match_all($this->PHP_COMPLEX["undoc_const"], $phpcode, $regs,
+PREG_SET_ORDER);
+ reset($regs);
+ while (list($k, $data)=each($regs)) {
+
+ $name = (""!=$data[2]) ? substr($data[1], 1, -1) : $data[1];
+ if (!isset($constants[$name])) {
+
+ if (isset($data[5])) {
+ if ($data[5])
+ $case = "case insensitive, userdefined: '$data[5]'";
+ else
+ $case = "case sensitive, userdefined: '$data[5]'";
+ } else {
+ $case = "default: case sensitive";
+ }
+
+ $paragraphs["consts"][] = array(
+ "name" => $name,
+ "value" => ("" != $data[4]) ?
+substr($data[3], 1, -1) : $data[3],
+ "case" => $case,
+ "doc" => ""
+ );
+ }
+ }
+ }
+
+ if (!isset($keywords["uses"])) {
+
+ preg_match_all($this->PHP_COMPLEX["undoc_use"], $phpcode, $regs,
+PREG_SET_ORDER);
+
+ reset($regs);
+ while (list($k, $data) = each($regs)) {
+
+ $filename = isset($data[5]) ? $data[5] : $data[4];
+ if (!isset($uses[$filename])) {
+
+ $paragraphs["uses"][] = array(
+ "type" => $data[1],
+ "file" => $filename,
+ "doc" => ""
+ );
+
+ }
+ }
+
+ }
+
+ return $paragraphs;
+ } // end func getPhpdocParagraphs
+
+ /**
+ * Does a quick prescan to find modules and classes.
+ *
+ * @param string Code to scan
+ * @return array Hash of modules and classes found in the given code
+ * @access public
+ * @see getPhpdocParagraphs()
+ */
+ function getModulesAndClasses($phpcode) {
+
+ $para = array();
+ list($para["modules"], $phpdcode) = $this->getModuleDoc($phpcode);
+ $para["classes"] = $this->getClasses($phpcode);
+
+ return $para;
+ } // end func getModulesAndClasses
+
+ /**
+ * Tries to extract a module doc.
+ *
+ * The syntax for modules is not final yet. The implementation and meaning of
+"module"
+ * might change at every time! Please do not ask for implementation details.
+ *
+ * @param string PHP Code to scan
+ * @return array $module structure: $module[0] = array with module data,
+ * $module[1] = php code without the leading
+module doc
+ */
+ function getModuleDoc($phpcode) {
+
+ $module = array();
+
+ if (preg_match($this->C_COMPLEX["module_doc"], $phpcode, $regs) ) {
+
+ $start = strlen($regs[0]);
+ $end = strpos($phpcode, "*/", $start);
+ $remaining = substr($phpcode, $end + 2);
+ $doc_comment = substr($phpcode, $start, $end-$start);
+
+ // Do we have OO Code? If not, continue.
+ if ( !preg_match($this->PHP_COMPLEX["class"], $remaining) &&
+!preg_match($this->PHP_COMPLEX["class_extends"], $remaining) ) {
+
+ // Is there a module tag?
+ if ( preg_match($this->C_COMPLEX["module_tags"], $doc_comment) ) {
+
+ $doc_comment = $this->extractPhpDoc($doc_comment);
+ $tags = $this->getTags( $doc_comment);
+ $allowed = array (
+ "module" => true,
+ "modulegroup" => true
+ );
+
+ $tags = $this->analyseTags( $tags, array(), array( "module" =>
+true, "modulegroup" => true) );
+
+ $module = array (
+ "doc" => $doc_comment,
+ "status" => "ok",
+ "name" => (isset($tags["module"])) ?
+$tags["module"] : "",
+ "group" => (isset($tags["modulegroup"])) ?
+$tags["modulegroup"] : ""
+ );
+
+ } else {
+
+ // No module tag.
+ // Try the remaining keywords. If one matches it's not a module
+doc
+ // assume that the module doc is missing. If none matches assume
+that
+ // it's a module doc which lacks the module tags.
+ if ( preg_match($this->PHP_COMPLEX["function"], $remaining) ||
+ preg_match($this->PHP_COMPLEX["use"], $remaining) ||
+ preg_match($this->PHP_COMPLEX["const"], $remaining) ||
+ preg_match($this->PHP_COMPLEX["var"], $remaining)
+ ) {
+
+ $module = array(
+ "doc" => "",
+ "status" => "missing",
+ "name" => "",
+ "group" => ""
+ );
+ $remaining = $phpcode;
+
+ } else {
+
+ $module = array(
+ "doc" => $doc_comment,
+ "status" => "tags missing",
+ "name" => "",
+ "group" => ""
+ );
+
+ }
+
+ } // end if module_tags
+
+ } else {
+
+ $remaining = $phpcode;
+
+ } // end if class
+
+ } else {
+
+ $remaining = $phpcode;
+
+ }
+
+ return array($module, $remaining);
+ } // end func getModuleDoc
+
+ /**
+ * Returns a list of classes found in the given code.
+ *
+ * In early versions PHPdoc parsed all the code at once which restulted in huge
+ * memory intensive hashes. Now it scans for classes, builds a classtree and
+ * does the parsing step by step, writing information to the destination
+ * (renderer, exporter) as soon as possible. This reduces the memory consumption
+ * dramatically. getPhpdocParagraphs() could be used to extract the class
+definitions
+ * as well but this specialized function is somewhat faster.
+ *
+ * @param string PHP code to scan.
+ * @return array $classes Array of classes found in the code.
+$classes[classname] = extends
+ */
+ function getClasses($phpcode) {
+
+ $classes = array();
+
+ preg_match_all($this->PHP_COMPLEX["undoc_class"], $phpcode, $regs,
+PREG_SET_ORDER);
+ reset($regs);
+ while (list($k, $data) = each($regs))
+ $classes[] = array(
+ "name" => $data[1],
+ "extends" => ""
+ );
+
+ preg_match_all($this->PHP_COMPLEX["undoc_class_extends"], $phpcode, $regs,
+PREG_SET_ORDER);
+ reset($regs);
+ while (list($k, $data) = each($regs))
+ $classes[] = array(
+ "name" => $data[1],
+ "extends" => $data[2]
+ );
+
+ return $classes;
+ } // end func getClasses
+
+ /**
+ * Strips "/xx", "x/" and x from doc comments (x means asterix).
+ *
+ * @param string Doc comment to clean up.
+ * @return string $phpdoc
+ */
+ function extractPhpdoc($paragraph) {
+
+ $lines = split( $this->PHP_BASE["break"], $paragraph);
+ $phpdoc = "";
+
+ reset($lines);
+ while (list($k, $line)=each($lines)) {
+
+ $line = trim($line);
+ if ("" == $line)
+ continue;
+
+ if ("*" == $line[0])
+ $phpdoc.= trim(substr($line, 1)) . "\n";
+ else
+ $phpdoc.= $line . "\n";
+
+ }
+
+ return substr($phpdoc, 0, -1);
+ } // end func extractPhpdoc
+
+ /**
+ * Extract the description from a PHPDoc doc comment.
+ *
+ * Every PHPDoc doc comment has the same syntax: /xx[break][x]short description
+ * [break][[x]multiple line long description[break]][[x]@list of tags[. This
+function
+ * returns an array of the short description and long description.
+ *
+ * @param string Doc comment to examine.
+ * @return array $description $description[0] = short description (first
+line),
+ * $description[1] = long description (second
+line upto the first tag)
+ */
+ function getDescription($phpdoc) {
+
+ // find the position of the first doc tag
+ $positions = $this->getTagPos($phpdoc);
+
+ if (0 == count($positions))
+ $desc = trim($phpdoc); // no doc tags
+ else
+ $desc = trim(substr($phpdoc, 0, $positions[0]["pos"])); // strip tags
+
+ $lines = split($this->PHP_BASE["break"], $desc);
+
+ if (1 == count($lines) || "" == $desc) {
+
+ // only a short description but no long description - or even none of both
+ $description = array ($desc, "");
+
+ } else {
+
+ $sdesc = trim($lines[0]);
+ unset($lines[0]);
+
+ $description = array ($sdesc, implode("", $lines));
+
+ }
+
+ return $description;
+ } // end func getDescription
+
+ /**
+ * Scans a code passage for a value.
+ *
+ * There some cases where you can hardly use a regex to grep a value
+ * because the value might contain unescaped charaters that end the value.
+ * Value means something like "array ( ";", '\;' );" or "'phpdoc; ';" where
+ * the delimiter would be ";".
+ *
+ * @param string The php code to examine.
+ * @param mixed String of one delimiter or array of delimiters.
+ * @return string Value found in the code
+ * @todo Racecondition: comments
+ */
+ function getValue($code, $delimiter) {
+ if ("" == $code)
+ return "";
+
+ if (!is_array($delimiter))
+ $delimiter = array( $delimiter => true );
+
+ $code = trim($code);
+ $len = strlen($code);
+ $enclosed = false;
+ $enclosed_by = "";
+
+ if ( isset($delimiter[$code[0]]) ) {
+
+ $i = 1;
+
+ } else {
+
+ for ($i = 0; $i < $len; $i++) {
+
+ $char = $code[$i];
+
+ if (('"' == $char || "'" == $char) && ($char == $enclosed_by || "" ==
+$enclosed_by) && (0 == $i || ($i > 0 && "\\" != $code[$i - 1]))) {
+
+ if (!$enclosed)
+ $enclosed_by = $char;
+ else
+ $enclosed_by = "";
+
+ $enclosed = !$enclosed;
+
+ }
+ if (!$enclosed && isset($delimiter[$char]))
+ break;
+
+ }
+
+ }
+
+ return substr($code, 0, $i);
+ } // end func getValue
+
+ /**
+ * Analyses a code snipped and returns the type and value of the first variable
+found.
+ *
+ * With version 0.3 PHPDoc tries to analyse variable declarations to find
+ * type and value. This is used to analyse class variable declarations and
+ * optional function arguments.
+ *
+ * Note that all regular expressions in this function start with "^". That means
+ * you have to do some preparations to the code snippet you're passing to this
+ * function.
+ *
+ * @param string PHP code to analyse
+ * @param boolean Flag indicating the "type" of code to analyse.
+Optional
+ * function parameters and class variables have a
+slightly
+ * different syntax for arrays. By default function
+parameters are expected.
+ * @return array $vartype $vartype[0] = type, $vartype[1] = value,
+$vartype[2] = raw value
+ */
+ function getVariableTypeAndValue($code, $flag_args = true) {
+
+ $type = "unknown";
+ $value = "unknown";
+ $raw_value = $code;
+
+ //
+ // Do not change the order the function tries to find out the type.
+ //
+
+ if (preg_match($this->PHP_COMPLEX["type_boolean"], $code, $regs)) {
+
+ $type = "boolean";
+ $raw_value = $regs[0];
+ $value = $regs[0];
+
+ } else if (preg_match( $this->PHP_COMPLEX["type_string_enclosed"], $code,
+$regs)) {
+
+ $type = "string";
+ $raw_value = $regs[0];
+ $value = $regs[0];
+
+ } else if (preg_match( $this->PHP_COMPLEX["type_int_oct"], $code, $regs)) {
+
+ $type = "integer (octal)";
+ $raw_value = $regs[0];
+ $value = preg_replace("@\s@", "", $regs[0]);
+ if ((int)$value != $value)
+ $type .= " [warning: out of integer range, possible overflow
+trouble]";
+ $value = octdec($value)." ($value)";
+
+
+ } else if (preg_match( $this->PHP_COMPLEX["type_int_hex"], $code, $regs)) {
+
+ $type = "integer (hexadecimal)";
+ $raw_value = $regs[0];
+ $value = preg_replace("@\s@", "", $regs[0]);
+ if ((int)$value != $value)
+ $type .= " [warning: out of integer range, possible overflow
+trouble]";
+ $value = hexdec($value)." ($value)";
+
+ } else if (preg_match( $this->PHP_COMPLEX["type_float_exponent"], $code,
+$regs)) {
+
+ $type = "float";
+ $raw_value = $regs[0];
+ $value = (string)preg_replace("@\s@", "", $regs[0]);
+ if ( (float)$value != $value )
+ $type .= " [warning: out of float range]";
+ $value = (float)$value;
+
+ } else if (preg_match( $this->PHP_COMPLEX["type_float"], $code, $regs)) {
+
+ $type = "float";
+ $raw_value = $regs[0];
+ $value = preg_replace("@\s@", "", $regs[0]);
+ if ( (float)$value != $value )
+ $type .= " [warning: out of float range]";
+ $value = (float)$value;
+
+ } else if (preg_match( $this->PHP_COMPLEX["type_number"], $code, $regs)) {
+
+ $value = preg_replace("@\s@", "", $regs[0]);
+ $raw_value = $regs[0];
+
+ if ( (int)$value == $value ) {
+
+ $type = "integer";
+ $value = (int)$value;
+
+ } else {
+
+ $type = "float";
+ if ( (float)$value != $value )
+ $type.=" [warning: out of float range]";
+ $value = (float)$value;
+
+ }
+
+ } else if ($flag_args && preg_match( $this->PHP_COMPLEX["type_empty_array"],
+$code, $regs)) {
+
+ $value = "array()";
+ $raw_value = $regs[0];
+ $type = "array";
+
+ } else if (!$flag_args && preg_match( $this->PHP_COMPLEX["type_array"],
+$code, $regs)) {
+
+ $value = $this->getValue( $code, array(";" => true));
+ // strpos() is twice as fast as substr()
+ if ( 0 == strpos($value, "array"))
+ $type = "array";
+ $raw_value == $value;
+
+ } else if (preg_match( $this->PHP_COMPLEX["type_string"], $code, $regs)) {
+
+ $type = "string";
+ $raw_value = $regs[0];
+ $value = $regs[0];
+ }
+
+ return array($type, $value, $raw_value);
+ } // end func getVariableTypeAndValue
+
} // end class PhpdocParserObject
?>
Index: php4/pear/PHPDoc/parser/PhpdocParserRegExp.php
diff -u php4/pear/PHPDoc/parser/PhpdocParserRegExp.php:1.4
php4/pear/PHPDoc/parser/PhpdocParserRegExp.php:1.5
--- php4/pear/PHPDoc/parser/PhpdocParserRegExp.php:1.4 Sun Dec 3 14:37:37 2000
+++ php4/pear/PHPDoc/parser/PhpdocParserRegExp.php Sun Feb 18 06:45:28 2001
@@ -7,486 +7,486 @@
* possible I decided to define all regular expressions in one class.
* From a programming point of view there's no need to do so.
*
-* @version $Id: PhpdocParserRegExp.php,v 1.4 2000/12/03 22:37:37 uw Exp $
+* @version $Id: PhpdocParserRegExp.php,v 1.5 2001/02/18 14:45:28 uw Exp $
*/
class PhpdocParserRegExp extends PhpdocObject {
- /**
- * Array of phpdoc tags, indexed by the tagname.
- *
- * ... grepping information is really not a parser. Don't
- * change the order the tags are listed. If you introduce
- * new tags write the long variant of the tagname (parameter)
- * in front of the shortcut (param).
- *
- * @var array List of all PHPDoc documentation tags.
- */
- var $PHPDOC_TAGS = array(
-
"@parameter" => '@param[eter] (object
objectname|type) [$varname] [description]',
-
"@param" => '@param[eter]
(object objectname|type) [$varname] [description]',
-
-
"@return" => '@return (object
objectname|type) [$varname] [description]',
-
-
"@access" => '@access',
-
"@abstract" => '@abstract',
-
"@static" => '@static',
-
"@final" => '@final',
-
-
"@throws" => '@throws exception
[, exception]',
-
-
"@see" => '@see
(function()|$varname|(module|class)(function()|$varname)) [,
(funtion()|$varname|(module|class)(function()|$varname))]',
-
"@link" => '@link URL
[description]',
-
-
"@var" => '@var
(object objectname|type) [$varname]',
-
"@global" => '@global (object
objectname|type) $varname [description]',
-
-
"@constant" => '@const[ant] label
[description]',
-
"@const" => '@const[ant] label
[description]',
-
-
"@author" => '@author Name
[<email>] [, Name [<email>]',
-
"@copyright" => '@copyright description',
-
-
"@version" => '@version label',
-
"@since" => '@since label',
-
-
"@deprecated" => '@deprec[ated] description',
-
"@deprec" => '@deprec[ated]
description',
-
-
"@brother" => '@(brother|sister)
(function()|$varname)',
-
"@sister" => '@(brother|sister)
(function()|$varname)',
-
-
"@include" => '@include description',
-
-
"@exclude" => '@exclude label',
-
-
"@modulegroup" => '@modulegroup label',
-
"@module" => '@module label',
-
-
"@package" => '@package label',
-
-
"@magic" => '@magic
description',
-
"@todo" => '@todo description'
-
);
-
- /**
- * Basis regular expressions used to compose complex expressions to grep doc
comments.
- *
- * PHPDoc tries to compose all complex regular expressions
- * from a list of basic ones. This array contains all expressions
- * used grep complex doc comments and the surrounding keywords.
- *
- * @var array List of basic regular expressions matching parts of doc
comments:
- * module names, module
separator, vartypes, accesstypes.
- * @final
- * @see buildComplexRegExps(), $C_COMPLEX
- */
- var $C_BASE = array(
-
#"block" =>
'/\*\*((?:(?!\*).)*(?:\n(?!\s*\*/)\s*\*(?:(?!\*/).)*)*)\*/',
-
"module" =>
"[^\s]+",
-
"module_separator" => "::",
-
"module_tags" =>
"(@modulegroup|@module)",
-
-
"vartype" =>
"(string|integer|int|long|real|double|float|boolean|bool|mixed|array|object)",
-
"access" =>
"(private|public)"
-
);
-
- /**
- * List of regular expressions used to grep complex doc comments.
- *
- * As with $PHP_COMPLEX all complex expressions are build using basic
- * ones in buildComplexRegExps().
- *
- * @var array Regular expressions matching see and optional
objectnames.
- * @final
- * @see buildComplexRegexps(), $C_BASE
- */
- var $C_COMPLEX = array(
-
"objectname_optional" => "",
-
-
"see_var"
=> "",
-
"see_function" => "",
-
"see_moduleclass" => "",
-
-
"module_doc" => "",
-
"module_tags" => "",
-
"module_separator" => "",
-
"module_separator_len" => 0,
-
"module_separator_len_neg" => 0
-
-
);
-
- /**
- * Basic RegExps used to analyse PHP Code.
- *
- * PHPDoc tries to compose all complex regular expressions
- * from some basic expressions. This array contains
- * all expressions used to build $PHP_COMPLEX.
- * There're some differences to the RegExps in zend-scanner.l,
- * e.g. I decided to write "\s+" instead of "[ \n\r\t]+" which
- * should be identical as long as perl compatible regular
- * expressions are used. Another point is that I did not break
- * down numbers to LNUM/DNUM.
- *
- * @var array List of basis regular expressions matching php
code elements:
- *
spaces, optional spaces, linebreaks, labels, use (include and friends),
- *
optional argument assignment, boolean, several variable types.
- * @final
- * @see $PHP_COMPLEX
- */
- var $PHP_BASE = array (
-
-
"space" => "\s+",
-
"space_optional" => "\s*",
-
"break" => "[\n\r]",
-
-
"php_open_long" => "<\?php\s", # zend_scanner.l use
{WHITESPACE} (space in our case) eighter. Might be slightly faster.
-
"php_open_short" => "<\?",
-
"php_open_asp" => "<%",
-
"php_open_short_print" => "<\?=",
-
"php_open_asp_print" => "<%=",
-
-
# do not change the single quotes to double ones
-
"label" =>
'[a-zA-Z_\x7f-\xff][a-zA-Z0-9_\xzf-\xff]*',
-
"use" =>
"(include_once|include|require_once|require)",
-
"assignment" => "\s*([,=])\s*",
-
-
"boolean" => "(true|false)",
-
-
"string" => "[^\s]+",
-
"string_enclosed" => "(['\"])(?:\\\\\\1|[^\\1])*?\\1",
-
-
"int_oct" => "[+-]?\s*0[0-7]+",
-
"int_hex" =>
"[+-]?\s*0[xX][0-9A-Fa-f]+",
-
-
"float" => "[+-]?\s*\d*\.\d+",
-
"float_exponent" => "[+-]?\s*\d*(?:\.\d+)*[eE][+-]?\d+",
-
-
"number" => "[+-]?\s*\d+",
-
-
"array" => "array\s*\(",
-
"empty_array" => "array\s*\(\s*\)\s*"
-
);
-
- /**
- * List of regular expressions used to grep complex php code elements.
- *
- * The RegExp of the variable types is slightly changed to that
- * one in $PHP_BASE, getVariableTypeAndValue() needs this.
- * "undoc_*" is used to grep all keywords those who have a doc
- * comment in front and those without. See getPhodocParagraphs()
- * for more details on this.
- *
- * @var array RegExps to match: variablenames, functionnames, classnames,
- * class variable
declarations, function declarations,
- * class declarations, defines, uses (include and friends),
- * function arguments, several
variables types.
- * @see buildComplexRegExps(), getVariableTypeAndValue(),
getPhpdocParagraphs(), $PHP_BASE
- */
- var $PHP_COMPLEX = array (
-
"varname" => "",
-
"functionname" => "",
-
"classname" => "",
-
-
"php_open_script" => "",
-
-
"var"
=> "",
-
"undoc_var" => "",
-
-
"function" => "",
-
"undoc_function" => "",
-
-
"class" => "",
-
"undoc_class" => "",
-
-
"class_extends" => "",
-
"undoc_class_extends" => "",
-
-
"const" => "",
-
"undoc_const" => "",
-
-
"use"
=> "",
-
"undoc_use" => "",
-
-
"argument" => "",
-
-
"type_boolean" => "",
-
-
"type_string"
=> "",
-
"type_string_enclosed" => "",
-
-
"type_int_oct" => "",
-
"type_int_hex" => "",
-
-
"type_float" => "",
-
"type_float_exponent" => "",
-
-
"type_number" => "",
-
-
"type_array" => "",
-
"type_empty_array" => ""
-
);
-
- /**
- * Array of RegExp matching the syntax of several complex tags.
- *
- * The array is filled by the constructor.
- *
- * @var array Used to analyse return, var, param,
- * global, see
and to find tags in general
- * @see PhpdocParserObject()
- */
- var $TAGS = array (
-
"return" => "",
-
"var" => "", # @var, @param
-
"global" => "",
-
"access" => "",
-
-
"module" => "", # @module, @modulegroup
-
-
"const" => "", # @const, @constant
-
-
"see_var" => "", # @see
-
"see_function" => "", # @see
-
"see_class" => "", # @see
-
"see_module" => "", # @see
-
-
"link" => "@([^\s]+)(.*)@is", # @link
-
-
"brother" => "",
-
-
"author" =>
"<\s*([a-z]([-a-z0-9_.])*@([-a-z0-9_]*\.)+[a-z]{2,})\s*>", # @author <email> part
-
-
"all" => "" # list of all known tags
- );
-
- /**
- * Builds complex regular expressions for the parser.
- *
- * PHPDoc has a small set of basic regular expressions. All complex
- * regular expressions are made out of the basic ones. The composition
- * in done in this method. Note: every derived class must
- * call this method in it's constructor!
- * @see $PHP_BASE, $PHP_COMPLEX, $C_BASE, $C_COMPLEX
- */
- function buildComplexRegExps() {
-
- //
- // Do not change the order of the variable initializations there're
dependencies.
- // It starts with some php names.
- //
-
- // some names
- $this->PHP_COMPLEX["varname"] = sprintf("[&]?[$]%s",
$this->PHP_BASE["label"] );
- $this->PHP_COMPLEX["functionname"] = sprintf("[&]?%s",
$this->PHP_BASE["label"] );
- $this->PHP_COMPLEX["classname"] = $this->PHP_BASE["label"];
-
- //
- // Now build all regexps used to grep doc comment elements.
- //
-
- // optional object name
- $this->C_COMPLEX["objectname_optional"] = sprintf("(?:object%s%s)?",
-
$this->PHP_BASE["space"],
-
$this->PHP_COMPLEX["classname"]
-
);
-
- $this->C_COMPLEX["module_separator"] = sprintf("(?:%s)",
$this->C_BASE["module_separator"]);
- $this->C_COMPLEX["module_separator_len"] =
strlen($this->C_BASE["module_separator"]);
- $this->C_COMPLEX["module_separator_len_neg"] =
-1*strlen($this->C_BASE["module_separator"]);
-
- // References to other elements
- $this->C_COMPLEX["see_var"] = sprintf("(%s%s)?([$][^:]%s)",
-
$this->C_BASE["module"],
-
$this->C_COMPLEX["module_separator"],
-
$this->PHP_BASE["label"]
-
);
-
- $this->C_COMPLEX["see_function"] = sprintf("(%s%s)?([^:]%s\(%s\))",
-
$this->C_BASE["module"],
-
$this->C_COMPLEX["module_separator"],
-
$this->PHP_BASE["label"],
-
$this->PHP_BASE["space_optional"]
-
);
-
- $this->C_COMPLEX["see_moduleclass"] = sprintf("(%s)",
$this->C_BASE["module"] );
-
- //
- // RegExps used to grep certain php code elements.
- //
-
- // var statements
- $this->PHP_COMPLEX["var"] = sprintf("|^%svar%s([$]%s)%s(=?)|is",
-
$this->PHP_BASE["space_optional"],
-
$this->PHP_BASE["space"],
-
$this->PHP_BASE["label"],
-
$this->PHP_BASE["space_optional"],
-
$this->PHP_BASE["space_optional"]
-
);
- $this->PHP_COMPLEX["undoc_var"] = sprintf("|%s|isS",
substr($this->PHP_COMPLEX["var"], 2, -3) );
-
- // function statements
- $this->PHP_COMPLEX["function"] = sprintf("|^%sfunction%s(%s)%s\(|is",
-
$this->PHP_BASE["space_optional"],
-
$this->PHP_BASE["space"],
-
$this->PHP_COMPLEX["functionname"],
-
$this->PHP_BASE["space_optional"]
-
);
- $this->PHP_COMPLEX["undoc_function"] = sprintf("|%s|isS",
substr($this->PHP_COMPLEX["function"], 2, -3) );
-
- // class statements
- $this->PHP_COMPLEX["class"] = sprintf("|^%sclass%s(%s)%s{|is",
-
$this->PHP_BASE["space_optional"],
-
$this->PHP_BASE["space"],
-
$this->PHP_COMPLEX["classname"],
-
$this->PHP_BASE["space_optional"]
-
);
- $this->PHP_COMPLEX["undoc_class"] = sprintf("|%s|isS",
substr($this->PHP_COMPLEX["class"], 2, -3) );
-
- $this->PHP_COMPLEX["class_extends"] =
sprintf("|^%sclass%s(%s)%sextends%s(%s)%s{|is",
-
$this->PHP_BASE["space_optional"],
-
$this->PHP_BASE["space"],
-
$this->PHP_COMPLEX["classname"],
-
$this->PHP_BASE["space"],
-
$this->PHP_BASE["space"],
-
$this->PHP_COMPLEX["classname"],
-
$this->PHP_BASE["space_optional"]
-
);
- $this->PHP_COMPLEX["undoc_class_extends"] = sprintf("|%s|isS",
substr($this->PHP_COMPLEX["class_extends"], 2, -3) );
-
- //
- // RegExp used to grep define statements.
- // NOTE: the backticks do not allow the usage of $this->PHP_BASE
- //
- $this->PHP_COMPLEX["const"] =
sprintf("@^%sdefine%s\(%s(%s)%s,%s(%s)%s(?:,%s(%s))?%s\)%s;@is",
-
$this->PHP_BASE["space_optional"],
-
$this->PHP_BASE["space_optional"],
-
$this->PHP_BASE["space_optional"],
-
"[$]?\w[\w-_]*|(['\"])(?:\\\\\\2|[^\\2])*?\\2",
-
$this->PHP_BASE["space_optional"],
-
$this->PHP_BASE["space_optional"],
-
"(['\"])(?:\\\\\\4|[^\\4])*?\\4|(?:true|false)|[+-]?\s*0[0-7]+|[+-]?\s*0[xX][0-9A-Fa-f]+|[+-]?\s*\d*(?:\.\d+)*[eE][+-]?\d+|[+-]?\s*\d*\.\d+|[+-]?\s*\d+|&?[$]?\w[\w-_]*",
-
$this->PHP_BASE["space_optional"],
-
$this->PHP_BASE["space_optional"],
-
"(?:true|false)|[+-]?\s*0[0-7]+|[+-]?\s*0[xX][0-9A-Fa-f]+|[+-]?\s*\d*(?:\.\d+)*[eE][+-]?\d+|[+-]?\s*\d*\.\d+|[+-]?\s*\d+|&?[$]?\w[\w-_]*|(['])(?:\\\\\\6|[^\\6])*?\\6",
-
$this->PHP_BASE["space_optional"],
-
$this->PHP_BASE["space_optional"]
-
);
- $this->PHP_COMPLEX["undoc_const"] = sprintf("@%s@isS",
substr($this->PHP_COMPLEX["const"], 2, -3) );
-
- //
- // include, include_once, require, require_once and friends
- //
+ /**
+ * Array of phpdoc tags, indexed by the tagname.
+ *
+ * ... grepping information is really not a parser. Don't
+ * change the order the tags are listed. If you introduce
+ * new tags write the long variant of the tagname (parameter)
+ * in front of the shortcut (param).
+ *
+ * @var array List of all PHPDoc documentation tags.
+ */
+ var $PHPDOC_TAGS = array(
+ "@parameter" => '@param[eter] (object
+objectname|type) [$varname] [description]',
+ "@param" => '@param[eter] (object
+objectname|type) [$varname] [description]',
+
+ "@return" => '@return (object
+objectname|type) [$varname] [description]',
+
+ "@access" => '@access',
+ "@abstract" => '@abstract',
+ "@static" => '@static',
+ "@final" => '@final',
+
+ "@throws" => '@throws exception [, exception]',
+
+ "@see" => '@see
+(function()|$varname|(module|class)(function()|$varname)) [,
+(funtion()|$varname|(module|class)(function()|$varname))]',
+ "@link" => '@link URL [description]',
+
+ "@var" => '@var (object objectname|type)
+[$varname]',
+ "@global" => '@global (object objectname|type)
+$varname [description]',
+
+ "@constant" => '@const[ant] label [description]',
+ "@const" => '@const[ant] label [description]',
+
+ "@author" => '@author Name [<email>] [, Name
+[<email>]',
+ "@copyright" => '@copyright description',
+
+ "@version" => '@version label',
+ "@since" => '@since label',
+
+ "@deprecated" => '@deprec[ated] description',
+
+ "@deprec" => '@deprec[ated] description',
+
+ "@brother" => '@(brother|sister)
+(function()|$varname)',
+ "@sister" => '@(brother|sister)
+(function()|$varname)',
+
+
+ "@include" => '@include description',
+
+ "@exclude" => '@exclude label',
+
+ "@modulegroup" => '@modulegroup label',
+ "@module" => '@module label',
+
+ "@package" => '@package label',
+
+ "@magic" => '@magic description',
+ "@todo" => '@todo description'
+ );
+
+ /**
+ * Basis regular expressions used to compose complex expressions to grep doc
+comments.
+ *
+ * PHPDoc tries to compose all complex regular expressions
+ * from a list of basic ones. This array contains all expressions
+ * used grep complex doc comments and the surrounding keywords.
+ *
+ * @var array List of basic regular expressions matching parts of doc comments:
+ * module names, module separator, vartypes, accesstypes.
+ * @final
+ * @see buildComplexRegExps(), $C_COMPLEX
+ */
+ var $C_BASE = array(
+ #"block" =>
+'/\*\*((?:(?!\*).)*(?:\n(?!\s*\*/)\s*\*(?:(?!\*/).)*)*)\*/',
+ "module" => "[^\s]+",
+ "module_separator" => "::",
+ "module_tags" => "(@modulegroup|@module)",
+
+ "vartype" =>
+"(string|integer|int|long|real|double|float|boolean|bool|mixed|array|object)",
+ "access" => "(private|public)"
+ );
+
+ /**
+ * List of regular expressions used to grep complex doc comments.
+ *
+ * As with $PHP_COMPLEX all complex expressions are build using basic
+ * ones in buildComplexRegExps().
+ *
+ * @var array Regular expressions matching see and optional objectnames.
+ * @final
+ * @see buildComplexRegexps(), $C_BASE
+ */
+ var $C_COMPLEX = array(
+
+ "objectname_optional" => "",
+
+ "see_var" => "",
+ "see_function" => "",
+ "see_moduleclass" => "",
+
+ "module_doc" => "",
+ "module_tags" => "",
+ "module_separator" => "",
+ "module_separator_len" => 0,
+ "module_separator_len_neg" => 0
+
+ );
+
+ /**
+ * Basic RegExps used to analyse PHP Code.
+ *
+ * PHPDoc tries to compose all complex regular expressions
+ * from some basic expressions. This array contains
+ * all expressions used to build $PHP_COMPLEX.
+ * There're some differences to the RegExps in zend-scanner.l,
+ * e.g. I decided to write "\s+" instead of "[ \n\r\t]+" which
+ * should be identical as long as perl compatible regular
+ * expressions are used. Another point is that I did not break
+ * down numbers to LNUM/DNUM.
+ *
+ * @var array List of basis regular expressions matching php code elements:
+ * spaces, optional spaces, linebreaks, labels, use (include and
+friends),
+ * optional argument assignment, boolean, several variable types.
+ * @final
+ * @see $PHP_COMPLEX
+ */
+ var $PHP_BASE = array (
+
+ "space" => "\s+",
+ "space_optional" => "\s*",
+ "break" => "[\n\r]",
+
+ "php_open_long" => "<\?php\s", # zend_scanner.l
+use {WHITESPACE} (space in our case) eighter. Might be slightly faster.
+ "php_open_short" => "<\?",
+ "php_open_asp" => "<%",
+ "php_open_short_print" => "<\?=",
+ "php_open_asp_print" => "<%=",
+
+ # do not change the single quotes to double ones
+ "label" =>
+'[a-zA-Z_\x7f-\xff][a-zA-Z0-9_\xzf-\xff]*',
+ "use" =>
+"(include_once|include|require_once|require)",
+ "assignment" => "\s*([,=])\s*",
+
+ "boolean" => "(true|false)",
+
+ "string" => "[^\s]+",
+ "string_enclosed" =>
+"(['\"])(?:\\\\\\1|[^\\1])*?\\1",
+
+ "int_oct" => "[+-]?\s*0[0-7]+",
+ "int_hex" => "[+-]?\s*0[xX][0-9A-Fa-f]+",
+
+ "float" => "[+-]?\s*\d*\.\d+",
+ "float_exponent" =>
+"[+-]?\s*\d*(?:\.\d+)*[eE][+-]?\d+",
+
+ "number" => "[+-]?\s*\d+",
+
+ "array" => "array\s*\(",
+ "empty_array" => "array\s*\(\s*\)\s*"
+ );
+
+ /**
+ * List of regular expressions used to grep complex php code elements.
+ *
+ * The RegExp of the variable types is slightly changed to that
+ * one in $PHP_BASE, getVariableTypeAndValue() needs this.
+ * "undoc_*" is used to grep all keywords those who have a doc
+ * comment in front and those without. See getPhodocParagraphs()
+ * for more details on this.
+ *
+ * @var array RegExps to match: variablenames, functionnames, classnames,
+ * class variable declarations, function declarations,
+ * class declarations, defines, uses (include and friends),
+ * function arguments, several variables types.
+ * @see buildComplexRegExps(), getVariableTypeAndValue(),
+getPhpdocParagraphs(), $PHP_BASE
+ */
+ var $PHP_COMPLEX = array (
+ "varname" => "",
+ "functionname" => "",
+ "classname" => "",
+
+ "php_open_script" => "",
+
+ "var" => "",
+ "undoc_var" => "",
+
+ "function" => "",
+ "undoc_function" => "",
+
+ "class" => "",
+ "undoc_class" => "",
+
+ "class_extends" => "",
+ "undoc_class_extends" => "",
+
+ "const" => "",
+ "undoc_const" => "",
+
+ "use" => "",
+ "undoc_use" => "",
+
+ "argument" => "",
+
+ "type_boolean" => "",
+
+ "type_string" => "",
+ "type_string_enclosed" => "",
+
+ "type_int_oct" => "",
+ "type_int_hex" => "",
+
+ "type_float" => "",
+ "type_float_exponent" => "",
+
+ "type_number" => "",
+
+ "type_array" => "",
+ "type_empty_array" => ""
+ );
+
+
+ /**
+ * Array of RegExp matching the syntax of several complex tags.
+ *
+ * The array is filled by the constructor.
+ *
+ * @var array Used to analyse return, var, param,
+ * global, see and to find tags in general
+ * @see PhpdocParserObject()
+ */
+ var $TAGS = array (
+ "return" => "",
+ "var" => "", # @var, @param
+ "global" => "",
+ "access" => "",
+
+ "module" => "", # @module, @modulegroup
+
+ "const" => "", # @const, @constant
+
+ "see_var" => "", # @see
+ "see_function" => "", # @see
+ "see_class" => "", # @see
+ "see_module" => "", # @see
+
+ "link" => "@([^\s]+)(.*)@is", # @link
+
+ "brother" => "",
+
+ "author" =>
+"<\s*([a-z]([-a-z0-9_.])*@([-a-z0-9_]*\.)+[a-z]{2,})\s*>", # @author <email> part
+
+ "all" => "" # list of all known tags
+ );
+
+ /**
+ * Builds complex regular expressions for the parser.
+ *
+ * PHPDoc has a small set of basic regular expressions. All complex
+ * regular expressions are made out of the basic ones. The composition
+ * in done in this method. Note: every derived class must
+ * call this method in it's constructor!
+ * @see $PHP_BASE, $PHP_COMPLEX, $C_BASE, $C_COMPLEX
+ */
+ function buildComplexRegExps() {
+
+ //
+ // Do not change the order of the variable initializations there're
+dependencies.
+ // It starts with some php names.
+ //
+
+ // some names
+ $this->PHP_COMPLEX["varname"] = sprintf("[&]?[$]%s", $this->PHP_BASE["label"]
+);
+ $this->PHP_COMPLEX["functionname"] = sprintf("[&]?%s",
+$this->PHP_BASE["label"] );
+ $this->PHP_COMPLEX["classname"] = $this->PHP_BASE["label"];
+
+
+ //
+ // Now build all regexps used to grep doc comment elements.
+ //
+
+ // optional object name
+ $this->C_COMPLEX["objectname_optional"] = sprintf("(?:object%s%s)?",
+ $this->PHP_BASE["space"],
+
+$this->PHP_COMPLEX["classname"]
+ );
+
+ $this->C_COMPLEX["module_separator"] = sprintf("(?:%s)",
+$this->C_BASE["module_separator"]);
+ $this->C_COMPLEX["module_separator_len"] =
+strlen($this->C_BASE["module_separator"]);
+ $this->C_COMPLEX["module_separator_len_neg"] =
+-1*strlen($this->C_BASE["module_separator"]);
+
+ // References to other elements
+ $this->C_COMPLEX["see_var"] = sprintf("(%s%s)?([$][^:]%s)",
+ $this->C_BASE["module"],
+ $this->C_COMPLEX["module_separator"],
+ $this->PHP_BASE["label"]
+ );
+
+
+ $this->C_COMPLEX["see_function"] = sprintf("(%s%s)?([^:]%s\(%s\))",
+ $this->C_BASE["module"],
+
+$this->C_COMPLEX["module_separator"],
+ $this->PHP_BASE["label"],
+ $this->PHP_BASE["space_optional"]
+ );
+
+ $this->C_COMPLEX["see_moduleclass"] = sprintf("(%s)",
+$this->C_BASE["module"] );
+
+ //
+ // RegExps used to grep certain php code elements.
+ //
+
+ // var statements
+ $this->PHP_COMPLEX["var"] = sprintf("|^%svar%s([$]%s)%s(=?)|is",
+ $this->PHP_BASE["space_optional"],
+ $this->PHP_BASE["space"],
+ $this->PHP_BASE["label"],
+ $this->PHP_BASE["space_optional"],
+ $this->PHP_BASE["space_optional"]
+ );
+ $this->PHP_COMPLEX["undoc_var"] = sprintf("|%s|isS",
+substr($this->PHP_COMPLEX["var"], 2, -3) );
+
+ // function statements
+ $this->PHP_COMPLEX["function"] = sprintf("|^%sfunction%s(%s)%s\(|is",
+ $this->PHP_BASE["space_optional"],
+ $this->PHP_BASE["space"],
+ $this->PHP_COMPLEX["functionname"],
+ $this->PHP_BASE["space_optional"]
+ );
+
+ $this->PHP_COMPLEX["undoc_function"] = sprintf("|%s|isS",
+substr($this->PHP_COMPLEX["function"], 2, -3) );
+
+ // class statements
+ $this->PHP_COMPLEX["class"] = sprintf("|^%sclass%s(%s)%s{|is",
+ $this->PHP_BASE["space_optional"],
+ $this->PHP_BASE["space"],
+ $this->PHP_COMPLEX["classname"],
+ $this->PHP_BASE["space_optional"]
+ );
+ $this->PHP_COMPLEX["undoc_class"] = sprintf("|%s|isS",
+substr($this->PHP_COMPLEX["class"], 2, -3) );
+
+ $this->PHP_COMPLEX["class_extends"] =
+sprintf("|^%sclass%s(%s)%sextends%s(%s)%s{|is",
+
+$this->PHP_BASE["space_optional"],
+ $this->PHP_BASE["space"],
+
+$this->PHP_COMPLEX["classname"],
+ $this->PHP_BASE["space"],
+ $this->PHP_BASE["space"],
+
+$this->PHP_COMPLEX["classname"],
+
+$this->PHP_BASE["space_optional"]
+ );
+ $this->PHP_COMPLEX["undoc_class_extends"] = sprintf("|%s|isS",
+substr($this->PHP_COMPLEX["class_extends"], 2, -3) );
+
+ //
+ // RegExp used to grep define statements.
+ // NOTE: the backticks do not allow the usage of $this->PHP_BASE
+ //
+ $this->PHP_COMPLEX["const"] =
+sprintf("@^%sdefine%s\(%s(%s)%s,%s(%s)%s(?:,%s(%s))?%s\)%s;@is",
+ $this->PHP_BASE["space_optional"],
+ $this->PHP_BASE["space_optional"],
+ $this->PHP_BASE["space_optional"],
+
+"[$]?\w[\w-_]*|(['\"])(?:\\\\\\2|[^\\2])*?\\2",
+ $this->PHP_BASE["space_optional"],
+ $this->PHP_BASE["space_optional"],
+
+"(['\"])(?:\\\\\\4|[^\\4])*?\\4|(?:true|false)|[+-]?\s*0[0-7]+|[+-]?\s*0[xX][0-9A-Fa-f]+|[+-]?\s*\d*(?:\.\d+)*[eE][+-]?\d+|[+-]?\s*\d*\.\d+|[+-]?\s*\d+|&?[$]?\w[\w-_]*",
+ $this->PHP_BASE["space_optional"],
+ $this->PHP_BASE["space_optional"],
+
+"(?:true|false)|[+-]?\s*0[0-7]+|[+-]?\s*0[xX][0-9A-Fa-f]+|[+-]?\s*\d*(?:\.\d+)*[eE][+-]?\d+|[+-]?\s*\d*\.\d+|[+-]?\s*\d+|&?[$]?\w[\w-_]*|(['])(?:\\\\\\6|[^\\6])*?\\6",
+ $this->PHP_BASE["space_optional"],
+ $this->PHP_BASE["space_optional"]
+ );
+ $this->PHP_COMPLEX["undoc_const"] = sprintf("@%s@isS",
+substr($this->PHP_COMPLEX["const"], 2, -3) );
+
+ //
+ // include, include_once, require, require_once and friends
+ //
// ? removed!
- $this->PHP_COMPLEX["use"] =
sprintf("@^%s%s[\(]%s((['\"])((?:\\\\\\3|[^\\3])*?)\\3|([^\s]+))%s[\)]%s;@is",
-
$this->PHP_BASE["use"],
-
$this->PHP_BASE["space_optional"],
-
$this->PHP_BASE["space_optional"],
-
$this->PHP_BASE["space_optional"],
-
$this->PHP_BASE["space_optional"]
-
);
- $this->PHP_COMPLEX["undoc_use"] = sprintf("@%s@isS",
substr($this->PHP_COMPLEX["use"], 2, -3) );
-
- //
- // Variable name with an optional assignment operator. This one is used
- // to analyse function heads [parameter lists] as well as class
variable
- // declarations.
- //
- $this->PHP_COMPLEX["argument"] = sprintf("|(%s)(%s)?|s",
-
$this->PHP_COMPLEX["varname"],
-
$this->PHP_BASE["assignment"]
-
);
-
-
- //
- // <script language="php"> syntax
- //
- $this->PHP_COMPLEX["php_open_script"] =
sprintf("<script%slanguage%s=%s[\"']php[\"']%s>",
-
$this->PHP_BASE["space"],
-
$this->PHP_BASE["space_optional"],
-
$this->PHP_BASE["space_optional"],
-
$this->PHP_BASE["space_optional"]
-
);
-
- $this->PHP_COMPLEX["php_open_all"] = sprintf("(?:%s|%s|%s|%s|%s|%s)",
-
$this->PHP_BASE["php_open_long"],
-
$this->PHP_BASE["php_open_short"],
-
$this->PHP_BASE["php_open_asp"],
-
$this->PHP_BASE["php_open_short_print"],
-
$this->PHP_BASE["php_open_asp_print"],
-
$this->PHP_COMPLEX["php_open_script"]
-
);
-
- $this->C_COMPLEX["module_doc"] = sprintf("@^%s%s%s/\*\*@is",
-
$this->PHP_BASE["space_optional"],
-
$this->PHP_COMPLEX["php_open_all"],
-
$this->PHP_BASE["space_optional"]
-
);
-
- $this->C_COMPLEX["module_tags"] = sprintf("/%s/is",
$this->C_BASE["module_tags"] );
-
- //
- // RegExp used to grep variables types
- //
- $elements = array(
-
"boolean", "string", "string_enclosed",
-
"int_oct", "int_hex", "float", "float_exponent",
-
"number", "array", "empty_array"
- );
- reset($elements);
- while (list($key, $name)=each($elements))
- $this->PHP_COMPLEX["type_".$name] = sprintf("@^%s@",
$this->PHP_BASE[$name]);
-
- //
- // Regular expressions used to analyse phpdoc tags.
- //
- $this->TAGS["var"] = sprintf("/%s(?:%s(%s))?(?:%s(%s))?%s(.*)?/is",
-
$this->C_BASE["vartype"],
-
$this->PHP_BASE["space"],
-
$this->PHP_BASE["label"],
-
$this->PHP_BASE["space"],
-
$this->PHP_COMPLEX["varname"],
-
$this->PHP_BASE["space_optional"]
-
);
- $this->TAGS["return"] = $this->TAGS["var"];
-
- $this->TAGS["global"] = sprintf("/%s%s(%s)%s(%s)%s(.*)/is",
-
$this->C_BASE["vartype"],
-
$this->PHP_BASE["space_optional"],
-
$this->C_COMPLEX["objectname_optional"],
-
$this->PHP_BASE["space"],
-
$this->PHP_COMPLEX["varname"],
-
$this->PHP_BASE["space_optional"]
-
);
-
- $this->TAGS["brother"] = sprintf("/(%s\(\)|\$%s)/is",
-
$this->PHP_BASE["label"],
-
$this->PHP_BASE["label"]
-
);
-
- $this->TAGS["const"] = sprintf("/(%s)%s(.*)?/is",
-
$this->PHP_BASE["label"],
-
$this->PHP_BASE["space_optional"]
-
);
-
- $this->TAGS["access"] = sprintf("/%s/is", $this->C_BASE["access"]);
- $this->TAGS["module"] = sprintf("/%s/is", $this->PHP_BASE["label"]);
-
- $this->TAGS["author"] = sprintf("/%s/is", $this->TAGS["author"]);
-
- $all_tags = "";
- reset($this->PHPDOC_TAGS);
- while (list($tag, $v)=each($this->PHPDOC_TAGS))
- $all_tags.= substr($tag, 1)."|";
- $all_tags = substr($all_tags, 0, -1);
-
- $this->TAGS["all"] = "/@($all_tags)/is";
-
- $elements = array ( "see_function", "see_var", "see_moduleclass" );
- reset($elements);
- while (list($k, $index)=each($elements))
- $this->TAGS[$index] = sprintf("/%s/is",
$this->C_COMPLEX[$index]);
+ $this->PHP_COMPLEX["use"] =
+sprintf("@^%s%s[\(]%s((['\"])((?:\\\\\\3|[^\\3])*?)\\3|([^\s]+))%s[\)]%s;@is",
+ $this->PHP_BASE["use"],
+ $this->PHP_BASE["space_optional"],
+ $this->PHP_BASE["space_optional"],
+ $this->PHP_BASE["space_optional"],
+ $this->PHP_BASE["space_optional"]
+ );
+ $this->PHP_COMPLEX["undoc_use"] = sprintf("@%s@isS",
+substr($this->PHP_COMPLEX["use"], 2, -3) );
+
+ //
+ // Variable name with an optional assignment operator. This one is used
+ // to analyse function heads [parameter lists] as well as class variable
+ // declarations.
+ //
+ $this->PHP_COMPLEX["argument"] = sprintf("|(%s)(%s)?|s",
+ $this->PHP_COMPLEX["varname"],
+ $this->PHP_BASE["assignment"]
+ );
+
+
+ //
+ // <script language="php"> syntax
+ //
+ $this->PHP_COMPLEX["php_open_script"] =
+sprintf("<script%slanguage%s=%s[\"']php[\"']%s>",
+ $this->PHP_BASE["space"],
+
+$this->PHP_BASE["space_optional"],
+
+$this->PHP_BASE["space_optional"],
+
+$this->PHP_BASE["space_optional"]
+ );
+
+ $this->PHP_COMPLEX["php_open_all"] = sprintf("(?:%s|%s|%s|%s|%s|%s)",
+ $this->PHP_BASE["php_open_long"],
+ $this->PHP_BASE["php_open_short"],
+ $this->PHP_BASE["php_open_asp"],
+
+$this->PHP_BASE["php_open_short_print"],
+
+$this->PHP_BASE["php_open_asp_print"],
+
+$this->PHP_COMPLEX["php_open_script"]
+ );
+
+ $this->C_COMPLEX["module_doc"] = sprintf("@^%s%s%s/\*\*@is",
+ $this->PHP_BASE["space_optional"],
+
+$this->PHP_COMPLEX["php_open_all"],
+ $this->PHP_BASE["space_optional"]
+ );
+
+ $this->C_COMPLEX["module_tags"] = sprintf("/%s/is",
+$this->C_BASE["module_tags"] );
+
+ //
+ // RegExp used to grep variables types
+ //
+ $elements = array(
+ "boolean", "string", "string_enclosed",
+ "int_oct", "int_hex", "float", "float_exponent",
+ "number", "array", "empty_array"
+ );
+ reset($elements);
+ while (list($key, $name)=each($elements))
+ $this->PHP_COMPLEX["type_".$name] = sprintf("@^%s@",
+$this->PHP_BASE[$name]);
+
+ //
+ // Regular expressions used to analyse phpdoc tags.
+ //
+ $this->TAGS["var"] = sprintf("/%s(?:%s(%s))?(?:%s(%s))?%s(.*)?/is",
+ $this->C_BASE["vartype"],
+ $this->PHP_BASE["space"],
+ $this->PHP_BASE["label"],
+ $this->PHP_BASE["space"],
+ $this->PHP_COMPLEX["varname"],
+ $this->PHP_BASE["space_optional"]
+ );
+ $this->TAGS["return"] = $this->TAGS["var"];
+
+ $this->TAGS["global"] = sprintf("/%s%s(%s)%s(%s)%s(.*)/is",
+ $this->C_BASE["vartype"],
+ $this->PHP_BASE["space_optional"],
+ $this->C_COMPLEX["objectname_optional"],
+ $this->PHP_BASE["space"],
+ $this->PHP_COMPLEX["varname"],
+ $this->PHP_BASE["space_optional"]
+ );
+
+ $this->TAGS["brother"] = sprintf("/(%s\(\)|\$%s)/is",
+ $this->PHP_BASE["label"],
+ $this->PHP_BASE["label"]
+ );
+
+ $this->TAGS["const"] = sprintf("/(%s)%s(.*)?/is",
+ $this->PHP_BASE["label"],
+ $this->PHP_BASE["space_optional"]
+ );
+
+ $this->TAGS["access"] = sprintf("/%s/is", $this->C_BASE["access"]);
+ $this->TAGS["module"] = sprintf("/%s/is", $this->PHP_BASE["label"]);
+
+ $this->TAGS["author"] = sprintf("/%s/is", $this->TAGS["author"]);
+
+ $all_tags = "";
+ reset($this->PHPDOC_TAGS);
+
+ while (list($tag, $v)=each($this->PHPDOC_TAGS))
+ $all_tags.= substr($tag, 1)."|";
+ $all_tags = substr($all_tags, 0, -1);
+
+ $this->TAGS["all"] = "/@($all_tags)/is";
+
+ $elements = array ( "see_function", "see_var", "see_moduleclass" );
+ reset($elements);
+ while (list($k, $index)=each($elements))
+ $this->TAGS[$index] = sprintf("/%s/is", $this->C_COMPLEX[$index]);
- } // end func buildComplexRegExps
-
+ } // end func buildComplexRegExps
+
} // end class PhpdocParserRegExp
?>
Index: php4/pear/PHPDoc/parser/PhpdocParserTags.php
diff -u php4/pear/PHPDoc/parser/PhpdocParserTags.php:1.4
php4/pear/PHPDoc/parser/PhpdocParserTags.php:1.5
--- php4/pear/PHPDoc/parser/PhpdocParserTags.php:1.4 Sun Dec 3 14:37:37 2000
+++ php4/pear/PHPDoc/parser/PhpdocParserTags.php Sun Feb 18 06:45:28 2001
@@ -2,738 +2,735 @@
/**
* Functions used to parse PHPDoc Tags.
*
-* @version $Id: PhpdocParserTags.php,v 1.4 2000/12/03 22:37:37 uw Exp $
+* @version $Id: PhpdocParserTags.php,v 1.5 2001/02/18 14:45:28 uw Exp $
*/
class PhpdocParserTags extends PhpdocParserRegExp {
-
- /**
- * Extract the value from the given tags and copy the data to the $data array
if its an allowed tag
- *
- * @param array $tags array of tags returned by
getTags
- * @param array $data array where the allowed tags
and their values are copied to
- * @param array $allowed array of allowed (recognized) tags
- * @return array $data
- * @throws PhpdocError
- * @see getTags(), analyseVariableParagraphs(), analyseFunctionParagraphs(),
analyseClassParagraphs(), analyseSeeTags()
- */
- function analyseTags($tags, $data, $allowed) {
-
- if (!is_array($tags) || !is_array($data) || !is_array($allowed)) {
- $this->err[] = new PhpdocError("Illegal function call",
__FILE__, __LINE__);
- return $data;
- }
-
- reset($tags);
- while (list($k, $tag) = each($tags)) {
-
- $tagname = substr( strtolower($tag["tag"]), 1 );
- if (!isset($allowed[$tagname])) {
- $data["notallowed"][$tagname] = true;
- continue;
- }
-
- switch ($tagname) {
-
- # @tagname description
- case "exclude":
- case "package":
- case "magic":
- case "todo":
- case "version":
- case "since":
- case "include":
- case "copyright":
-
- if (isset($data[$tagname])) {
-
- $tag["msg"] = "This tag must be used
only once within a doc comment. First declaration gets used.";
- $data["syntaxerror"][] = $tag;
- break;
-
- }
-
- if ("" == $tag["value"]) {
-
- $tag["msg"] = "Description is missing,
syntax: '" . $this->PHPDOC_TAGS["@$tagname"] . "'.";
- $data["syntaxerror"][] = $tag;
- $data[$tagname] = $tag["value"];
-
- } else
- $data[$tagname] = $tag["value"];
-
- break;
-
- # @tagname [void]
- case "abstract":
- case "static":
- case "final":
-
- if (isset($data[$tagname])) {
-
- $tag["msg"] = "This tag must be used
only once within a doc comment. First declaration gets used.";
- $data["syntaxerror"][] = $tag;
- break;
-
- }
-
- if ("" != $tag["value"]) {
-
- $tag["msg"] = "Description gets
ignored, syntax: '".$this->PHPDOC_TAGS["@$tagname"]."'.";
- $data["syntaxerror"][] = $tag;
-
- }
- $data[$tagname] = true;
- break;
-
- case "var":
- case "return":
-
- if (isset($data[$tagname])) {
-
- $tag["msg"] = "This tag must be used
only once within a doc comment. First declaration gets used.";
- $data["syntaxerror"][] = $tag;
- break;
-
- }
-
- if (preg_match($this->TAGS[$tagname],
$tag["value"], $regs)) {
-
- $desc = "";
-
- if ("object" == $regs[1]) {
-
- $type = "object ";
- if ( "" == $regs[2] ) {
-
- $type .= "[unknown]";
- $tag["msg"] =
"Objectname is missing, syntax: '" . $this->PHPDOC_TAGS["@$tagname"] . "'.";
- $data["syntaxerror"][]
= $tag;
-
- } else {
-
- $type .= $regs[2];
-
- }
-
- $desc = $regs[4];
-
- } else {
-
- $type = $regs[1];
- $desc = $regs[2] . " " .
$regs[4];
-
- }
-
- $data[$tagname] = array (
-
"type" => $type,
-
"name" => $regs[3],
-
);
-
- if ("" != trim($desc))
- $data[$tagname]["desc"] =
$desc;
-
- } else {
-
- $tag["msg"] = "General syntax error,
syntax: '" . $this->PHPDOC_TAGS["@$tagname"] . "'.";
- $tag["msg"] .= $this->TAGS[$tagname];
- $data["syntaxerror"][] = $tag;
-
- }
- break;
-
- case "global":
-
- if (preg_match($this->TAGS["global"],
$tag["value"], $regs)) {
-
- if ("" == $regs[3]) {
-
- $tag["msg"] = "Variablename
ist missing, syntax: '" . $this->PHPDOC_TAGS["@$tagname"] . "'.";
- $data["syntaxerror"][] = $tag;
-
- }
-
- if ("object" == $regs[1]) {
-
- $type = "object ";
- if ( "" == $regs[2] ) {
-
- $type .= "[unknown]";
- $tag["msg"] =
"Objectname is missing, syntax: '" . $this->PHPDOC_TAGS["@$tagname"] . "'.";
- $data["syntaxerror"][]
= $tag;
-
- } else {
-
- $type .= $regs[2];
-
- }
-
- } else {
-
- $type = $regs[1];
-
- }
-
- if ("" == $regs[4]) {
- $data["global"][] = array (
-
"type" =>
$type,
-
"name" =>
$regs[3]
-
);
- } else {
- $data["global"][] = array (
-
"type" =>
$type,
-
"name" =>
$regs[3],
-
"desc" =>
$regs[4]
-
);
- }
-
- } else {
-
- $tag["msg"] = "General syntax error,
syntax: '" . $this->PHPDOC_TAGS["@$tagname"] . "'.";
- $data["syntaxerror"][] = $tag;
-
- }
-
- break;
-
- case "param":
- case "parameter":
-
- if (preg_match($this->TAGS["var"],
$tag["value"], $regs)) {
-
- if ("object" == $regs[1]) {
-
- $type = "object ";
- if ("" == $regs[2]) {
-
- $type .= "[unknown]";
- $tag["msg"] =
"Objectname is missing, syntax: '" . $this->PHPDOC_TAGS["@$tagname"] . "'.";
- $data["syntaxerror"][]
= $tag;
-
- } else {
-
- $type .= $regs[2];
-
- }
-
- } else {
-
- $type = $regs[1];
-
- }
-
- if ("" == $regs[4]) {
- $data["params"][] = array (
-
"type" => $type,
-
"name" => $regs[3]
-
);
- } else {
- $data["params"][] = array (
-
"type" => $type,
-
"name" => $regs[3],
-
"desc" => $regs[4]
-
);
- }
-
- } else {
-
- $tag["msg"] = "General syntax error,
syntax: '".$this->PHPDOC_TAGS["@$tagname"]."'.";
- $data["syntaxerror"][] = $tag;
-
- }
-
- break;
-
- case "see":
-
- if ("" != $tag["value"]) {
-
- $error = "";
- $references = explode(",",
$tag["value"] );
- reset($references);
- while (list($k, $reference) =
each($references)) {
-
- if
(preg_match($this->TAGS["see_var"], $reference, $regs)) {
-
- list($msg, $entry) =
$this->analyseSeeTagRegs($regs);
- $error .= $msg;
- if (count($entry) > 0)
-
$data["see"]["var"][] = $entry;
-
- } else if
(preg_match($this->TAGS["see_function"], $reference, $regs)) {
-
- list($msg, $entry) =
$this->analyseSeeTagRegs($regs);
- $error .= $msg;
- if (count($entry) > 0)
-
$data["see"]["function"][] = $entry;
-
- } else if
(preg_match($this->TAGS["see_moduleclass"], $reference, $regs)) {
-
- $name = $regs[1];
-
- if (substr($name, 0,
$this->C_COMPLEX["module_separator_len"]) == $this->C_BASE["module_separator"]) {
-
- $name =
substr($name, $this->C_COMPLEX["module_separator_len"]);
- if ("" ==
$name) {
-
- $error
.= "Element name is missing: '$regs[0]'. Reference gets ignored";
-
continue;
-
- } else {
-
- $error
.= "Element name starts with moduleseparator, module name forgotten '$regs[0]'?";
-
continue;
-
- }
-
- } else if
(!strstr($name, $this->C_BASE["module_separator"])) {
-
- $error .= "Use
function() to referr to functions and $var to referr to variables - don't know what
'$name' referrs to.";
- continue;
-
- }
-
-
$data["see"]["moduleclass"][] = $name;
-
- } else {
-
- $error .= "Unknown
syntax '$reference'";
-
- }
-
- }
-
- if ( "" != $error) {
-
- $tag["msg"] = sprintf("Could
not understand all references. %s. Syntax: '%s' (function), '%s' (variable), '%s'
(module or class).",
-
$error,
-
$this->C_COMPLEX["see_function"],
-
$this->C_COMPLEX["see_var"],
-
$this->C_COMPLEX["see_moduleclass"]
-
);
- $data["syntaxerror"][] = $tag;
-
- }
-
- } else {
-
- $tag["msg"] = "General syntax error,
syntax: '" . $this->PHPDOC_TAGS["@$tagname"] . "'.";
- $data["syntaxerror"][] = $tag;
-
- }
- break;
-
- case "link":
-
- if (preg_match($this->TAGS["link"],
$tag["value"], $regs)) {
-
- $desc = trim($regs[2]);
- if ("" == $desc) {
-
- $data["link"][] = array(
-
"url" => $regs[1]
-
);
-
- } else {
-
- $data["link"][] = array(
-
"url" => $regs[1],
-
"desc" => trim($regs[2])
-
);
-
- }
-
- } else {
-
- $tag["msg"] = "General syntax error,
syntax: '" . $this->PHPDOC_TAGS["@$tagname"] . "'.";
- $data["syntaxerror"][] = $tag;
-
- }
- break;
-
- case "throws":
-
- if ("" != $tag["value"]) {
-
- $exceptions = explode(",",
$tag["value"]);
- reset($exceptions);
- while (list($k, $exception) =
each($exceptions))
- $data["throws"][] =
trim($exception);
-
- } else {
-
- $tag["msg"] = "General syntax error,
syntax: '" . $this->PHPDOC_TAGS["@$tagname"] . "'.";
- $data["syntaxerror"][] = $tag;
-
- }
- break;
-
- case "access":
-
- if (preg_match($this->TAGS["access"],
$tag["value"], $regs)) {
-
- $data["access"] = $regs[1];
-
- } else {
-
- $tag["msg"] = ("" == $tag["value"]) ?
"General syntax error," : "Access modifier unknown,";
- $tag["msg"].= " '" .
$this->PHPDOC_TAGS["@$tagname"] . "'.";
- $data["syntaxerror"][] = $tag;
-
- }
-
- break;
-
- case "deprec":
- case "deprecated":
-
- if (isset($data["deprec"])) {
-
- $tag["msg"] = "This tag must be used
only once within a doc comment. First declaration gets used.";
- $data["syntaxerror"][] = $tag;
- break;
-
- }
-
- if ("" != $tag["value"]) {
-
- $data["deprec"] = $tag["value"];
-
- } else {
-
- $tag["msg"] = "Description is missing,
syntax: '" . $this->PHPDOC_TAGS["@$tagname"] . "'.";
- $data["syntaxerror"][] = $tag;
-
- }
- break;
-
- case "brother":
- case "sister":
-
- if (isset($data["brother"])) {
-
- $tag["msg"] = "This tag must be used
only once within a doc comment. First declaration gets used.";
- $data["syntaxerror"][] = $tag;
- break;
-
- }
-
- if ("" != $tag["value"]) {
-
- if (preg_match($this->TAGS["brother"],
$tag["value"], $regs)) {
-
- $data["brother"] = $regs[1];
-
- } else {
-
- $tag["msg"] = "Can't find a
function name nor a variable name, syntax: '" . $this->PHPDOC_TAGS["@$tagname"] . "'.";
- $data["syntaxerror"][] = $tag;
-
- }
-
- } else {
-
- $data["msg"] = "General syntax error,
syntax: '" . $this->PHPDOC_TAGS["@$tagname"] . "'.";
- $data["syntaxerror"][] = $tag;
-
- }
- break;
-
- case "module":
- case "modulegroup":
-
- if (isset($data[$tagname])) {
-
- $tag["msg"] = "This tag must be used
only once within a doc comment. First declaration gets used.";
- $data["syntaxerror"][] = $tag;
- break;
-
- }
-
- if ("" != $tag["value"]) {
-
- if (preg_match($this->TAGS["module"],
$tag["value"], $regs)) {
-
- $data[$tagname] = $regs[0];
-
- } else {
-
- $tag["msg"] = "Illegal label
used, syntax: '" . $this->PHPDOC_TAGS["@$tagname"] . "'.";
- $data["syntaxerror"][] = $tag;
-
- }
-
- } else {
-
- $tag["msg"] = "General syntax error,
syntax: '" . $this->PHPDOC_TAGS["@$tagname"] . "'.";
- $data["syntaxerror"][] = $tag;
-
- }
- break;
-
- case "const":
- case "constant":
-
- if (isset($data["const"])) {
-
- $tag["msg"] = "This tag must be used
only once within a doc comment. First declaration gets used.";
- $data["syntaxerror"][] = $tag;
- break;
-
- }
-
- if ("" != $tag["value"]) {
-
- if (preg_match($this->TAGS["const"],
$tag["value"], $regs)) {
-
- $data["const"] = array(
-
"name" => $regs[1],
-
"desc" =>
trim($regs[2])
-
);
-
- } else {
-
- $tag["msg"] = "General syntax
error, syntax: '" . $this->PHPDOC_TAGS["@$tagname"] . "'.";
- $data["syntaxerror"][] = $tag;
-
- }
-
- } else {
-
- $tag["msg"] = "General syntax error,
syntax: '" . $this->PHPDOC_TAGS["@$tagname"] . "'.";
- $data["syntaxerror"][] = $tag;
-
- }
- break;
-
- case "author":
-
- if ("" != $tag["value"]) {
-
- $authors = explode(",", $tag["value"]);
- reset($authors);
- while (list($k, $author) =
each($authors)) {
-
- if
(preg_match($this->TAGS["author"], $author, $regs)) {
-
- $data["author"][] =
array(
-
"name" => trim(substr($author, 0, strpos($author, $regs[0]))),
-
"mail" => trim($regs[1])
-
);
- } else if (""!=trim($author)) {
-
- $data["author"][] =
array(
-
"name" => trim($author)
-
);
-
- } else {
-
- $tag["msg"] = "Name is
missing in enumeration, syntax: '".$this->PHPDOC_TAGS["@$tagname"]."'.";
- $data["syntaxerror"][]
= $tag;
-
- }
-
- }
-
- } else {
-
- $tag["msg"] = "General syntax error,
syntax: " . $this->PHPDOC_TAGS["@$tagname"] . "'.";
- $data["syntaxerror"][] = $tag;
-
- }
-
- break;
-
- default:
- // I'm quite sure this default is obsolete,
but I don't feel like checking it.
- // Anyway this array index should get used one
fine day.
- $data["unknown"][] = $tag;
- break;
- }
-
- }
-
- return $data;
- } // end func analyseTags
-
- /**
- * Helperfunction to analyse see tags
- *
- * @param array Array return by preg_match()
- * @return array $see[0] = error, $see[1] = data
- * @see analyseTags()
- */
- function analyseSeeTagRegs($regs) {
-
- $error = "";
- $group = trim($regs[1]);
- $name = trim($regs[2]);
-
- if (substr($name, 0, $this->C_COMPLEX["module_separator_len"]) ==
$this->C_BASE["module_separator"]) {
-
- $name = substr($name,
$this->C_COMPLEX["module_separator_len"]);
- if ("" == $name) {
-
- $error = "Element name is missing '$regs[0]'.
Reference gets ignored";
- return array($error, array());
-
- } else {
-
- $error = "Element name starts with moduleseparator,
module name forgotten '$regs[0]'?";
-
- }
-
- }
-
- if ("" != $group && $this->C_BASE["module_separator"] != $group) {
-
- $group = substr($group, 0,
$this->C_COMPLEX["module_separator_len_neg"]);
- if ("" == $group) {
-
- $error = "Groupname missing '$regs[0]'.";
- $data = array( "name" => $name );
-
- } else {
-
- $data = array (
-
"group" => $group,
-
"name" => $name
-
);
-
- }
-
- } else {
-
- $data = array ( "name" => $name );
-
- }
-
- return array($error, $data);
- } // end func analyseSeeTagRegs
-
- /**
- * Extracts PHPDoc tags from a PHPDoc doc comment.
- *
- * @param string Doc comment.
- * @return array List of tags ordered by their appearance containing
the
- * tag name and
it's (unparsed) value.
- * @see getTagPos()
- */
- function getTags($phpdoc) {
-
- $positions = $this->getTagPos($phpdoc);
-
- if (0 == count($positions))
- return array();
-
- reset($positions);
- list($k, $data) = each($positions);
- $lastpos = $data["pos"];
- $lasttag = $data["tag"];
-
- while (list($k, $data) = each($positions)) {
-
- $line = substr($phpdoc, $lastpos, ($data["pos"] -
$lastpos));
- $value = trim(substr($line, strlen($lasttag)));
- $tags[] = array ("tag" => $lasttag, "value" =>
$value );
-
- $lastpos = $data["pos"];
- $lasttag = $data["tag"];
-
- }
-
- $line = substr($phpdoc, $lastpos);
- $value = trim(substr($line, strlen($lasttag)));
- $tags[] = array ("tag" => $lasttag, "value" => $value );
-
- return $tags;
- } // end func getTags
-
- /**
- * Find the position of the next phpdoc tag.
- *
- * @param string $phpdoc
- * @param integer $offset
- * @return array $tag 0 => tag, 1 => offset
- * @access private
- * @see findTags()
- */
- function getTagPos($phpdoc, $offset = 0) {
-
- $positions = array();
-
- preg_match_all($this->TAGS["all"], $phpdoc, $regs, PREG_SET_ORDER);
-
- reset($regs);
- while (list($k, $data) = each($regs)) {
-
- $pos = strpos($phpdoc, $data[0], $offset);
-
- if ($pos > 0 || $data[0] == substr($phpdoc, 0,
strlen($data[0])) ) {
- $positions[] = array ("pos" => $pos, "tag" =>
$data[0]);
- $offset = $pos+1;
- }
-
- }
-
- return $positions;
- } // end func getTagPos
-
- /**
- * Takes an array filled by analyseTags() and converts the parse errors into a
single error message.
- *
- * Checks for [syntaxerror], [notallowed] and [unknown] entries in the data
hash,
- * converts them into an error message and unsets the indizes. The function
- * returns a hash containing the aggregates error message and the modified
- * data hash.
- *
- * @param array $data
- * @param string $mode Keyword where the data hash comes from eg.
function/class...
- * @return array array( $error_msg, $data )
- */
- function checkParserErrors($data, $mode) {
-
- $msg = "";
- // tags with an incorrect syntax
- if (isset($data["syntaxerror"])) {
-
- $msg.= "PHPDoc found " . count($data["syntaxerror"]) . "
syntax error(s) in the tag list. ";
-
- reset($data["syntaxerror"]);
- while (list($k, $error) = each($data["syntaxerror"]))
- $msg.= sprintf("Tag: '%s %s' - %s.", $error["tag"],
$error["value"], $error["msg"]);
-
- unset($data["syntaxerror"]);
-
- }
-
- // tags that are not allowed in this context
- if (isset($data["notallowed"])) {
-
- $msg .= count($data["notallowed"]) . " tag[s] were used that
are not allowed in $mode doc comments: ";
-
- reset($data["notallowed"]);
- while (list($tagname, $v) = each($data["notallowed"]))
- $msg .= "$tagname, ";
-
- $msg = substr($msg, 0, -2) . ".";
- unset($data["notallowed"]);
- }
-
- // unknown tags
- if (isset($data["unknown"])) {
-
- $msg .= "PHPDoc found " . count($data["unknown"]) . " tag[s]
that are unknown: ";
-
- reset($data["unknown"]);
- while (list($k, $error) = each($data["unknown"]))
- $msg.= sprintf("%s, ", $error["tag"]);
-
- $msg = substr($msg, 0, -2) . ".";
- unset($data["unknown"]);
- }
-
- return array($msg, $data);
- } // end func checkParserErrors
-
+
+ /**
+ * Extract the value from the given tags and copy the data to the $data array if
+its an allowed tag
+ *
+ * @param array $tags array of tags returned by getTags
+ * @param array $data array where the allowed tags and their values are
+copied to
+ * @param array $allowed array of allowed (recognized) tags
+ * @return array $data
+ * @throws PhpdocError
+ * @see getTags(), analyseVariableParagraphs(), analyseFunctionParagraphs(),
+analyseClassParagraphs(), analyseSeeTags()
+ */
+ function analyseTags($tags, $data, $allowed) {
+
+ if (!is_array($tags) || !is_array($data) || !is_array($allowed)) {
+ $this->err[] = new PhpdocError("Illegal function call", __FILE__,
+__LINE__);
+ return $data;
+ }
+
+ reset($tags);
+ while (list($k, $tag) = each($tags)) {
+
+ $tagname = substr( strtolower($tag["tag"]), 1 );
+ if (!isset($allowed[$tagname])) {
+ $data["notallowed"][$tagname] = true;
+ continue;
+ }
+
+ switch ($tagname) {
+
+ # @tagname description
+ case "exclude":
+ case "package":
+ case "magic":
+ case "todo":
+ case "version":
+ case "since":
+ case "include":
+ case "copyright":
+
+ if (isset($data[$tagname])) {
+
+ $tag["msg"] = "This tag must be used only once within a doc
+comment. First declaration gets used.";
+ $data["syntaxerror"][] = $tag;
+ break;
+
+ }
+
+ if ("" == $tag["value"]) {
+
+ $tag["msg"] = "Description is missing, syntax: '" .
+$this->PHPDOC_TAGS["@$tagname"] . "'.";
+ $data["syntaxerror"][] = $tag;
+ $data[$tagname] = $tag["value"];
+
+ } else
+ $data[$tagname] = $tag["value"];
+
+ break;
+
+ # @tagname [void]
+ case "abstract":
+ case "static":
+ case "final":
+
+ if (isset($data[$tagname])) {
+
+ $tag["msg"] = "This tag must be used only once within a doc
+comment. First declaration gets used.";
+ $data["syntaxerror"][] = $tag;
+ break;
+
+ }
+
+ if ("" != $tag["value"]) {
+
+ $tag["msg"] = "Description gets ignored, syntax: '" .
+$this->PHPDOC_TAGS["@$tagname"] . "'.";
+ $data["syntaxerror"][] = $tag;
+
+ }
+ $data[$tagname] = true;
+ break;
+
+ case "var":
+ case "return":
+
+ if (isset($data[$tagname])) {
+
+ $tag["msg"] = "This tag must be used only once within a doc
+comment. First declaration gets used.";
+ $data["syntaxerror"][] = $tag;
+ break;
+
+ }
+
+ if (preg_match($this->TAGS[$tagname], $tag["value"], $regs)) {
+
+ $desc = "";
+
+ if ("object" == $regs[1]) {
+
+ $type = "object ";
+ if ( "" == $regs[2] ) {
+
+ $type .= "[unknown]";
+ $tag["msg"] = "Objectname is missing, syntax: '" .
+$this->PHPDOC_TAGS["@$tagname"] . "'.";
+ $data["syntaxerror"][] = $tag;
+
+ } else {
+
+ $type .= $regs[2];
+
+ }
+
+ $desc = $regs[4];
+
+ } else {
+
+ $type = $regs[1];
+ $desc = $regs[2] . " " . $regs[4];
+
+ }
+
+ $data[$tagname] = array (
+ "type" => $type,
+ "name" => $regs[3],
+ );
+
+ if ("" != trim($desc))
+ $data[$tagname]["desc"] = $desc;
+
+ } else {
+
+ $tag["msg"] = "General syntax error, syntax: '" .
+$this->PHPDOC_TAGS["@$tagname"] . "'.";
+ $tag["msg"] .= $this->TAGS[$tagname];
+ $data["syntaxerror"][] = $tag;
+
+ }
+ break;
+
+ case "global":
+
+ if (preg_match($this->TAGS["global"], $tag["value"], $regs)) {
+
+ if ("" == $regs[3]) {
+
+ $tag["msg"] = "Variablename ist missing, syntax: '" .
+$this->PHPDOC_TAGS["@$tagname"] . "'.";
+ $data["syntaxerror"][] = $tag;
+
+ }
+
+ if ("object" == $regs[1]) {
+
+ $type = "object ";
+ if ( "" == $regs[2] ) {
+
+ $type .= "[unknown]";
+ $tag["msg"] = "Objectname is missing, syntax: '" .
+$this->PHPDOC_TAGS["@$tagname"] . "'.";
+ $data["syntaxerror"][] = $tag;
+
+ } else {
+
+ $type .= $regs[2];
+
+ }
+
+ } else {
+
+ $type = $regs[1];
+
+ }
+
+ if ("" == $regs[4]) {
+ $data["global"][] = array (
+ "type" => $type,
+ "name" => $regs[3]
+ );
+ } else {
+ $data["global"][] = array (
+ "type" => $type,
+ "name" => $regs[3],
+ "desc" => $regs[4]
+ );
+ }
+
+ } else {
+
+ $tag["msg"] = "General syntax error, syntax: '" .
+$this->PHPDOC_TAGS["@$tagname"] . "'.";
+ $data["syntaxerror"][] = $tag;
+
+ }
+
+ break;
+
+ case "param":
+ case "parameter":
+
+ if (preg_match($this->TAGS["var"], $tag["value"], $regs)) {
+
+ if ("object" == $regs[1]) {
+
+ $type = "object ";
+ if ("" == $regs[2]) {
+
+ $type .= "[unknown]";
+ $tag["msg"] = "Objectname is missing, syntax: '" .
+$this->PHPDOC_TAGS["@$tagname"] . "'.";
+ $data["syntaxerror"][] = $tag;
+
+ } else {
+
+ $type .= $regs[2];
+
+ }
+
+ } else {
+
+ $type = $regs[1];
+
+ }
+
+ if ("" == $regs[4]) {
+ $data["params"][] = array (
+ "type" => $type,
+ "name" => $regs[3]
+ );
+ } else {
+ $data["params"][] = array (
+ "type" => $type,
+ "name" => $regs[3],
+ "desc" => $regs[4]
+ );
+ }
+
+ } else {
+
+ $tag["msg"] = "General syntax error, syntax:
+'".$this->PHPDOC_TAGS["@$tagname"]."'.";
+ $data["syntaxerror"][] = $tag;
+
+ }
+
+ break;
+
+ case "see":
+
+ if ("" != $tag["value"]) {
+
+ $error = "";
+ $references = explode(",", $tag["value"] );
+ reset($references);
+ while (list($k, $reference) = each($references)) {
+
+ if (preg_match($this->TAGS["see_var"], $reference,
+$regs)) {
+
+ list($msg, $entry) = $this->analyseSeeTagRegs($regs);
+ $error .= $msg;
+ if (count($entry) > 0)
+ $data["see"]["var"][] = $entry;
+
+ } else if (preg_match($this->TAGS["see_function"],
+$reference, $regs)) {
+
+ list($msg, $entry) = $this->analyseSeeTagRegs($regs);
+ $error .= $msg;
+ if (count($entry) > 0)
+ $data["see"]["function"][] = $entry;
+
+ } else if (preg_match($this->TAGS["see_moduleclass"],
+$reference, $regs)) {
+
+ $name = $regs[1];
+
+ if (substr($name, 0,
+$this->C_COMPLEX["module_separator_len"]) == $this->C_BASE["module_separator"]) {
+
+ $name = substr($name,
+$this->C_COMPLEX["module_separator_len"]);
+ if ("" == $name) {
+
+ $error .= "Element name is missing:
+'$regs[0]'. Reference gets ignored";
+ continue;
+
+ } else {
+
+ $error .= "Element name starts with
+moduleseparator, module name forgotten '$regs[0]'?";
+ continue;
+
+ }
+
+ } else if (!strstr($name,
+$this->C_BASE["module_separator"])) {
+
+ $error .= "Use function() to referr to functions
+and $var to referr to variables - don't know what '$name' referrs to.";
+ continue;
+
+ }
+
+ $data["see"]["moduleclass"][] = $name;
+
+ } else {
+
+ $error .= "Unknown syntax '$reference'";
+
+ }
+
+ }
+
+ if ( "" != $error) {
+
+ $tag["msg"] = sprintf("Could not understand all
+references. %s. Syntax: '%s' (function), '%s' (variable), '%s' (module or class).",
+ $error,
+ $this->C_COMPLEX["see_function"],
+ $this->C_COMPLEX["see_var"],
+
+$this->C_COMPLEX["see_moduleclass"]
+ );
+ $data["syntaxerror"][] = $tag;
+
+ }
+
+ } else {
+
+ $tag["msg"] = "General syntax error, syntax: '" .
+$this->PHPDOC_TAGS["@$tagname"] . "'.";
+ $data["syntaxerror"][] = $tag;
+
+ }
+ break;
+
+ case "link":
+
+ if (preg_match($this->TAGS["link"], $tag["value"], $regs)) {
+
+ $desc = trim($regs[2]);
+ if ("" == $desc) {
+
+ $data["link"][] = array(
+ "url"
+=> $regs[1]
+ );
+
+ } else {
+
+ $data["link"][] = array(
+ "url"
+=> $regs[1],
+ "desc" =>
+trim($regs[2])
+ );
+
+ }
+
+ } else {
+
+ $tag["msg"] = "General syntax error, syntax: '" .
+$this->PHPDOC_TAGS["@$tagname"] . "'.";
+ $data["syntaxerror"][] = $tag;
+
+ }
+ break;
+
+ case "throws":
+
+ if ("" != $tag["value"]) {
+
+ $exceptions = explode(",", $tag["value"]);
+ reset($exceptions);
+ while (list($k, $exception) = each($exceptions))
+ $data["throws"][] = trim($exception);
+
+ } else {
+
+ $tag["msg"] = "General syntax error, syntax: '" .
+$this->PHPDOC_TAGS["@$tagname"] . "'.";
+ $data["syntaxerror"][] = $tag;
+
+ }
+ break;
+
+ case "access":
+
+ if (preg_match($this->TAGS["access"], $tag["value"], $regs)) {
+
+ $data["access"] = $regs[1];
+
+ } else {
+
+ $tag["msg"] = ("" == $tag["value"]) ? "General syntax error,"
+: "Access modifier unknown,";
+ $tag["msg"].= " '" . $this->PHPDOC_TAGS["@$tagname"] . "'.";
+ $data["syntaxerror"][] = $tag;
+
+
+ }
+
+ break;
+
+ case "deprec":
+ case "deprecated":
+
+ if (isset($data["deprec"])) {
+
+ $tag["msg"] = "This tag must be used only once within a doc
+comment. First declaration gets used.";
+ $data["syntaxerror"][] = $tag;
+ break;
+
+ }
+
+ if ("" != $tag["value"]) {
+
+ $data["deprec"] = $tag["value"];
+
+ } else {
+
+ $tag["msg"] = "Description is missing, syntax: '" .
+$this->PHPDOC_TAGS["@$tagname"] . "'.";
+ $data["syntaxerror"][] = $tag;
+
+ }
+ break;
+
+ case "brother":
+ case "sister":
+
+ if (isset($data["brother"])) {
+
+ $tag["msg"] = "This tag must be used only once within a doc
+comment. First declaration gets used.";
+ $data["syntaxerror"][] = $tag;
+ break;
+
+ }
+
+ if ("" != $tag["value"]) {
+
+ if (preg_match($this->TAGS["brother"], $tag["value"], $regs))
+{
+
+ $data["brother"] = $regs[1];
+
+ } else {
+
+ $tag["msg"] = "Can't find a function name nor a variable
+name, syntax: '" . $this->PHPDOC_TAGS["@$tagname"] . "'.";
+ $data["syntaxerror"][] = $tag;
+
+ }
+
+ } else {
+
+ $data["msg"] = "General syntax error, syntax: '" .
+$this->PHPDOC_TAGS["@$tagname"] . "'.";
+ $data["syntaxerror"][] = $tag;
+
+ }
+ break;
+
+ case "module":
+ case "modulegroup":
+
+ if (isset($data[$tagname])) {
+
+ $tag["msg"] = "This tag must be used only once within a doc
+comment. First declaration gets used.";
+ $data["syntaxerror"][] = $tag;
+ break;
+
+ }
+
+ if ("" != $tag["value"]) {
+
+ if (preg_match($this->TAGS["module"], $tag["value"], $regs)) {
+
+ $data[$tagname] = $regs[0];
+
+ } else {
+
+ $tag["msg"] = "Illegal label used, syntax: '" .
+$this->PHPDOC_TAGS["@$tagname"] . "'.";
+ $data["syntaxerror"][] = $tag;
+
+ }
+
+ } else {
+
+ $tag["msg"] = "General syntax error, syntax: '" .
+$this->PHPDOC_TAGS["@$tagname"] . "'.";
+ $data["syntaxerror"][] = $tag;
+
+ }
+ break;
+
+ case "const":
+ case "constant":
+
+ if (isset($data["const"])) {
+
+ $tag["msg"] = "This tag must be used only once within a doc
+comment. First declaration gets used.";
+ $data["syntaxerror"][] = $tag;
+ break;
+
+ }
+
+ if ("" != $tag["value"]) {
+
+ if (preg_match($this->TAGS["const"], $tag["value"], $regs)) {
+
+ $data["const"] = array(
+ "name" => $regs[1],
+ "desc" => trim($regs[2])
+ );
+
+ } else {
+
+ $tag["msg"] = "General syntax error, syntax: '" .
+$this->PHPDOC_TAGS["@$tagname"] . "'.";
+ $data["syntaxerror"][] = $tag;
+
+ }
+
+ } else {
+
+ $tag["msg"] = "General syntax error, syntax: '" .
+$this->PHPDOC_TAGS["@$tagname"] . "'.";
+ $data["syntaxerror"][] = $tag;
+
+ }
+ break;
+
+ case "author":
+
+ if ("" != $tag["value"]) {
+
+ $authors = explode(",", $tag["value"]);
+ reset($authors);
+ while (list($k, $author) = each($authors)) {
+
+ if (preg_match($this->TAGS["author"], $author, $regs)) {
+
+ $data["author"][] = array(
+ "name" =>
+trim(substr($author, 0, strpos($author, $regs[0]))),
+ "mail" =>
+trim($regs[1])
+ );
+ } else if (""!=trim($author)) {
+
+ $data["author"][] = array("name" => trim($author));
+
+ } else {
+
+ $tag["msg"] = "Name is missing in enumeration,
+syntax: '" . $this->PHPDOC_TAGS["@$tagname"] . "'.";
+ $data["syntaxerror"][] = $tag;
+
+ }
+
+ }
+
+ } else {
+
+ $tag["msg"] = "General syntax error, syntax: " .
+$this->PHPDOC_TAGS["@$tagname"] . "'.";
+ $data["syntaxerror"][] = $tag;
+
+ }
+
+ break;
+
+ default:
+ // I'm quite sure this default is obsolete, but I don't feel like
+checking it.
+ // Anyway this array index should get used one fine day.
+ $data["unknown"][] = $tag;
+ break;
+ }
+
+ }
+
+ return $data;
+ } // end func analyseTags
+
+ /**
+ * Helperfunction to analyse see tags
+ *
+ * @param array Array return by preg_match()
+ * @return array $see $see[0] = error, $see[1] = data
+ * @see analyseTags()
+ */
+ function analyseSeeTagRegs($regs) {
+
+ $error = "";
+ $group = trim($regs[1]);
+ $name = trim($regs[2]);
+
+ if (substr($name, 0, $this->C_COMPLEX["module_separator_len"]) ==
+$this->C_BASE["module_separator"]) {
+
+ $name = substr($name, $this->C_COMPLEX["module_separator_len"]);
+ if ("" == $name) {
+
+ $error = "Element name is missing '$regs[0]'. Reference gets ignored";
+ return array($error, array());
+
+ } else {
+
+ $error = "Element name starts with moduleseparator, module name
+forgotten '$regs[0]'?";
+
+ }
+
+ }
+
+ if ("" != $group && $this->C_BASE["module_separator"] != $group) {
+
+ $group = substr($group, 0, $this->C_COMPLEX["module_separator_len_neg"]);
+ if ("" == $group) {
+
+ $error = "Groupname missing '$regs[0]'.";
+ $data = array( "name" => $name );
+
+ } else {
+
+ $data = array (
+ "group" => $group,
+ "name" => $name
+ );
+
+ }
+
+ } else {
+
+ $data = array ( "name" => $name );
+
+ }
+
+ return array($error, $data);
+ } // end func analyseSeeTagRegs
+
+ /**
+ * Extracts PHPDoc tags from a PHPDoc doc comment.
+ *
+ * @param string Doc comment.
+ * @return array List of tags ordered by their appearance containing the
+ * tag name and it's (unparsed) value.
+ * @see getTagPos()
+ */
+ function getTags($phpdoc) {
+
+ $positions = $this->getTagPos($phpdoc);
+
+ if (0 == count($positions))
+ return array();
+
+ reset($positions);
+ list($k, $data) = each($positions);
+ $lastpos = $data["pos"];
+ $lasttag = $data["tag"];
+
+ while (list($k, $data) = each($positions)) {
+
+ $line = substr($phpdoc, $lastpos, ($data["pos"] - $lastpos));
+ $value = trim(substr($line, strlen($lasttag)));
+ $tags[] = array ("tag" => $lasttag, "value" => $value );
+
+ $lastpos = $data["pos"];
+ $lasttag = $data["tag"];
+
+ }
+
+ $line = substr($phpdoc, $lastpos);
+ $value = trim(substr($line, strlen($lasttag)));
+ $tags[] = array ("tag" => $lasttag, "value" => $value );
+
+ return $tags;
+ } // end func getTags
+
+ /**
+ * Find the position of the next phpdoc tag.
+ *
+ * @param string $phpdoc
+ * @param integer $offset
+ * @return array $tag 0 => tag, 1 => offset
+ * @see findTags()
+ */
+ function getTagPos($phpdoc, $offset = 0) {
+
+ $positions = array();
+
+ preg_match_all($this->TAGS["all"], $phpdoc, $regs, PREG_SET_ORDER);
+
+ reset($regs);
+ while (list($k, $data) = each($regs)) {
+
+ $pos = strpos($phpdoc, $data[0], $offset);
+
+ if ($pos > 0 || $data[0] == substr($phpdoc, 0, strlen($data[0])) ) {
+ $positions[] = array ("pos" => $pos, "tag" => $data[0]);
+ $offset = $pos + 1;
+ }
+
+ }
+
+ return $positions;
+ } // end func getTagPos
+
+ /**
+ * Takes an array filled by analyseTags() and converts the parse errors into a
+single error message.
+ *
+ * Checks for [syntaxerror], [notallowed] and [unknown] entries in the data hash,
+ * converts them into an error message and unsets the indizes. The function
+ * returns a hash containing the aggregates error message and the modified
+ * data hash.
+ *
+ * @param array $data
+ * @param string $mode Keyword where the data hash comes from eg.
+function/class...
+ * @return array array( $error_msg, $data )
+ */
+ function checkParserErrors($data, $mode) {
+
+ $msg = "";
+ // tags with an incorrect syntax
+ if (isset($data["syntaxerror"])) {
+
+ $msg.= "PHPDoc found " . count($data["syntaxerror"]) . " syntax error(s)
+in the tag list. ";
+
+ reset($data["syntaxerror"]);
+ while (list($k, $error) = each($data["syntaxerror"]))
+ $msg.= sprintf("Tag: '%s %s' - %s.", $error["tag"], $error["value"],
+$error["msg"]);
+
+ unset($data["syntaxerror"]);
+
+ }
+
+ // tags that are not allowed in this context
+ if (isset($data["notallowed"])) {
+
+ $msg .= count($data["notallowed"]) . " tag[s] were used that are not
+allowed in $mode doc comments: ";
+
+ reset($data["notallowed"]);
+ while (list($tagname, $v) = each($data["notallowed"]))
+ $msg .= "$tagname, ";
+
+ $msg = substr($msg, 0, -2) . ".";
+ unset($data["notallowed"]);
+ }
+
+ // unknown tags
+ if (isset($data["unknown"])) {
+
+ $msg .= "PHPDoc found " . count($data["unknown"]) . " tag[s] that are
+unknown: ";
+
+ reset($data["unknown"]);
+ while (list($k, $error) = each($data["unknown"]))
+ $msg.= sprintf("%s, ", $error["tag"]);
+
+ $msg = substr($msg, 0, -2) . ".";
+ unset($data["unknown"]);
+ }
+
+ return array($msg, $data);
+ } // end func checkParserErrors
+
} // end class PhpdocParserTags
?>
Index: php4/pear/PHPDoc/parser/PhpdocUseParser.php
diff -u php4/pear/PHPDoc/parser/PhpdocUseParser.php:1.1
php4/pear/PHPDoc/parser/PhpdocUseParser.php:1.2
--- php4/pear/PHPDoc/parser/PhpdocUseParser.php:1.1 Sun Oct 8 03:03:19 2000
+++ php4/pear/PHPDoc/parser/PhpdocUseParser.php Sun Feb 18 06:45:28 2001
@@ -1,74 +1,78 @@
<?php
/**
* Extracts use statements (include and friends) an thheir documentation from php code.
-* @author Ulf Wendel <[EMAIL PROTECTED]>
-* @version 0.1alpha
+*
+* @author Ulf Wendel <[EMAIL PROTECTED]>
+* @version $Id: PhpdocUseParser.php,v 1.2 2001/02/18 14:45:28 uw Exp $
*/
class PhpdocUseParser extends PhpdocParserCore {
- /**
- * Structure of an empty use entry.
- * @var array
- */
- var $emptyUse = array(
-
"type" => "",
-
"file" => "",
-
"undoc" => true
-
);
-
+ /**
+ * Structure of an empty use entry.
+ *
+ * @var array
+ */
+ var $emptyUse = array(
+ "type" => "",
+ "file" => "",
+ "undoc" => true
+ );
+
- /**
- * List of allowed tags in use doc comments.
- * @var array
- */
- var $useTags = array(
-
"return" => true,
-
-
"see" => true,
-
"link" => true,
-
-
"authhor" => true,
-
"copyright" => true,
-
-
"version" => true,
-
"since" => true,
-
-
"deprecated" => true,
-
"deprec" => true,
-
-
"include" => true,
+ /**
+ * List of allowed tags in use doc comments.
+ *
+ * @var array
+ */
+ var $useTags = array(
+ "return" => true,
+
+ "see" => true,
+ "link" => true,
+
+ "authhor" => true,
+ "copyright" => true,
+
+ "version" => true,
+ "since" => true,
+
+ "deprecated" => true,
+ "deprec" => true,
+
+ "include" => true,
-
"exclude" => true,
-
"magic" => true,
-
"todo" => true
-
);
+ "exclude" => true,
+ "magic" => true,
+ "todo" => true
+ );
- /**
- * Takes the result from getPhpdocParagraphs() and interprets it.
- * @param array
- */
- function analyseUse($para) {
-
- $use = $this->emptyUse;
- $use["file"] = $para["file"];
-
- if (""!=$para["doc"]) {
-
- $use = $this->analyseTags($this->getTags($para["doc"]), $use,
$this->useTags);
-
- list($msg, $use) = $this->checkParserErrors($use, "use
(include and friends)");
- if (""!=$msg)
- $this->warn->addDocWarning($this->currentFile, "use",
$use["file"], $msg, "mismatch");
-
- list($use["sdesc"], $use["desc"]) =
$this->getDescription($para["doc"]);
-
- $use["undoc"] = false;
- }
-
- $use["type"] = $para["type"];
+ /**
+ * Takes the result from getPhpdocParagraphs() and interprets it.
+ *
+ * @param array
+ */
+ function analyseUse($para) {
+
+ $use = $this->emptyUse;
+ $use["file"] = $para["file"];
+
+ if ("" != $para["doc"]) {
+
+ $use = $this->analyseTags($this->getTags($para["doc"]), $use,
+$this->useTags);
+
+ list($msg, $use) = $this->checkParserErrors($use, "use (include and
+friends)");
+ if ("" != $msg)
+ $this->warn->addDocWarning($this->currentFile, "use", $use["file"],
+$msg, "mismatch");
+
+ list($use["sdesc"], $use["desc"]) = $this->getDescription($para["doc"]);
+
+ $use["undoc"] = false;
+ }
+
+ $use["type"] = $para["type"];
- return $use;
- } // end func analyseUse
-
+ return $use;
+ } // end func analyseUse
+
} // end class PhpdocUseParser
?>
Index: php4/pear/PHPDoc/parser/PhpdocVariableParser.php
diff -u php4/pear/PHPDoc/parser/PhpdocVariableParser.php:1.3
php4/pear/PHPDoc/parser/PhpdocVariableParser.php:1.4
--- php4/pear/PHPDoc/parser/PhpdocVariableParser.php:1.3 Sun Dec 3 14:37:37
2000
+++ php4/pear/PHPDoc/parser/PhpdocVariableParser.php Sun Feb 18 06:45:28 2001
@@ -2,126 +2,128 @@
/**
* Extract class variables and their documentation from phpcode
*
-* @version $Id: PhpdocVariableParser.php,v 1.3 2000/12/03 22:37:37 uw Exp $
+* @version $Id: PhpdocVariableParser.php,v 1.4 2001/02/18 14:45:28 uw Exp $
*/
class PhpdocVariableParser extends PhpdocModuleParser {
- /**
- * Array with default values of a variable
- *
- * @var array $emptyVariable
- */
- var $emptyVariable = array(
-
"name" => "",
-
"undoc" => true
-
);
+ /**
+ * Array with default values of a variable
+ *
+ * @var array $emptyVariable
+ */
+ var $emptyVariable = array(
+ "name" => "",
+ "undoc" => true
+ );
- /**
- * Array of tags that are allowed in front of the var keyword
- * @var array $variableTags
- * @see analyseVariableParagraph()
- */
- var $variableTags = array(
-
"access" => true,
-
"abstract" => true,
-
"static" => true,
-
"final" => true,
-
-
"see" => true,
-
"link" => true,
-
-
"var" => true,
-
-
"version" => true,
-
"since" => true,
-
-
"deprecated" => true,
-
"deprec" => true,
-
-
"brother" => true,
-
"sister" => true,
-
-
"exclude" => true,
-
"magic" => true,
-
"todo" => true
-
);
+ /**
+ * Array of tags that are allowed in front of the var keyword
+ *
+ * @var array $variableTags
+ * @see analyseVariableParagraph()
+ */
+ var $variableTags = array(
+ "access" => true,
+ "abstract" => true,
+ "static" => true,
+ "final" => true,
+
+ "see" => true,
+ "link" => true,
+
+ "var" => true,
+
+ "version" => true,
+ "since" => true,
+
+ "deprecated" => true,
+ "deprec" => true,
+
+ "brother" => true,
+ "sister" => true,
+
+ "exclude" => true,
+ "magic" => true,
+ "todo" => true
+ );
- /**
- * Analyses a variable doc comment
- * @param array Hash returned by getPhpdocParagraph()
- * @return array
- */
+ /**
+ * Analyses a variable doc comment
+ *
+ * @param array Hash returned by getPhpdocParagraph()
+ * @return array
+ */
function analyseVariable($para) {
-
- $variable = $this->emptyVariable;
- $variable["name"] = $para["name"];
-
- if ("" != $para["doc"]) {
-
- $variable = $this->analyseTags($this->getTags($para["doc"]),
$variable, $this->variableTags);
-
- list($msg, $variable) = $this->checkParserErrors($variable,
"variable");
- if ("" != $msg)
- $this->warn->addDocWarning($this->currentFile,
"variable", $variable["name"], $msg, "mismatch");
-
- list($variable["sdesc"], $variable["desc"]) =
$this->getDescription($para["doc"]);
-
- $variable["undoc"] = false;
-
- }
-
- list($type, $value, $raw_value) =
$this->getVariableTypeAndValue($para["value"], false);
- $variable["type"] = $type;
-
- if ("unknown" != $value)
- $variable["value"] = $value;
-
- $variable = $this->checkVarDocs($variable);
-
- return $variable;
- } // end func analyseVariables
-
- /**
- * Compares the var tag informations with the analyse of the source code.
- *
- * @param array $variable
- * @return array $variable
- */
- function checkVarDocs($variable) {
-
- if (!isset($variable["var"]))
- return $variable;
-
- if ("unknown" != $variable["type"] && "mixed" != $variable["type"] &&
$variable["var"]["type"] != $variable["type"]) {
-
- $msg = sprintf("The documented class variable type does not
match the type found. Update the tag to '@var %s [%s]%s'.",
-
$variable["type"],
-
$variable["name"],
-
(isset($variable["var"]["desc"])) ? " " . $variable["var"]["desc"] : ""
- );
- $this->warn->addDocWarning($this->currentFile, "variable",
$variable["name"], $msg, "mismatch");
-
- } else if ("unknown" == $variable["type"] && "" !=
$variable["var"]["type"]) {
-
- $variable["type"] = $variable["var"]["type"];
-
- }
-
- if ("" != $variable["var"]["name"] && $variable["var"]["name"] !=
$variable["name"]) {
-
- $msg = sprintf("The documented class variable name does not
match the name found. Update the tag to '@var %s [%s]%s'.",
-
("" != $variable["var"]["type"]) ? $variable["var"]["type"] :
$variable["type"],
-
$variable["name"],
-
(isset($variable["var"]["desc"])) ? " " . $variable["var"]["desc"] : ""
-
);
- $this->warn->addDocWarning($this->currentFile, "variable",
$variable["name"], $msg, "mismatch");
- }
-
-
- unset($variable["var"]);
-
- return $variable;
- } // end func checkVarDocs
+
+ $variable = $this->emptyVariable;
+ $variable["name"] = $para["name"];
+
+ if ("" != $para["doc"]) {
+
+ $variable = $this->analyseTags($this->getTags($para["doc"]), $variable,
+$this->variableTags);
+
+ list($msg, $variable) = $this->checkParserErrors($variable, "variable");
+ if ("" != $msg)
+ $this->warn->addDocWarning($this->currentFile, "variable",
+$variable["name"], $msg, "mismatch");
+
+ list($variable["sdesc"], $variable["desc"]) =
+$this->getDescription($para["doc"]);
+
+ $variable["undoc"] = false;
+
+ }
+
+ list($type, $value, $raw_value) =
+$this->getVariableTypeAndValue($para["value"], false);
+ $variable["type"] = $type;
+
+ if ("unknown" != $value)
+ $variable["value"] = $value;
+
+ $variable = $this->checkVarDocs($variable);
+
+ return $variable;
+ } // end func analyseVariables
+
+ /**
+ * Compares the var tag informations with the analyse of the source code.
+ *
+ * @param array $variable
+ * @return array $variable
+ */
+ function checkVarDocs($variable) {
+
+ if (!isset($variable["var"]))
+ return $variable;
+
+ if ("unknown" != $variable["type"] && "mixed" != $variable["type"] &&
+$variable["var"]["type"] != $variable["type"]) {
+
+ $msg = sprintf("The documented class variable type does not match the
+type found. Update the tag to '@var %s [%s]%s'.",
+ $variable["type"],
+ $variable["name"],
+ (isset($variable["var"]["desc"])) ? " " .
+$variable["var"]["desc"] : ""
+ );
+ $this->warn->addDocWarning($this->currentFile, "variable",
+$variable["name"], $msg, "mismatch");
+
+ } else if ("unknown" == $variable["type"] && "" != $variable["var"]["type"]) {
+
+ $variable["type"] = $variable["var"]["type"];
+
+ }
+
+ if ("" != $variable["var"]["name"] && $variable["var"]["name"] !=
+$variable["name"]) {
+
+ $msg = sprintf("The documented class variable name does not match the
+name found. Update the tag to '@var %s [%s]%s'.",
+ ("" != $variable["var"]["type"]) ?
+$variable["var"]["type"] : $variable["type"],
+ $variable["name"],
+ (isset($variable["var"]["desc"])) ? " " .
+$variable["var"]["desc"] : ""
+ );
+ $this->warn->addDocWarning($this->currentFile, "variable",
+$variable["name"], $msg, "mismatch");
+ }
+
+
+ unset($variable["var"]);
+
+ return $variable;
+ } // end func checkVarDocs
} // end class PhpdocVariableParser
?>
-- PHP CVS Mailing List (http://www.php.net/) To unsubscribe, e-mail: [EMAIL PROTECTED] For additional commands, e-mail: [EMAIL PROTECTED] To contact the list administrators, e-mail: [EMAIL PROTECTED]

