1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268
|
<?php
/**
* Analyses parsing data.
*
* Analyse means:
* - update @brother/@sister
* - update @access/@return
* - inherit elements
* - inherit information
*
*/
class PhpdocAnalyser extends PhpdocObject {
/**
* Flag indicating that getModule/getClass was called.
* @var boolean
*/
var $flag_get = false;
/**
* Starts the analysing of the raw parsing data.
*
* @access public
* @abstract
*/
function analyse() {
} // end func analyse
/**
* Handles @brother and @sister.
* @abstract
* @see updateBrotherSister
*/
function updateBrothersSisters() {
} // end func updateBrothersSisters
/**
* Updates certain elements that use @brother and @sister.
*
* @return boolean $ok
*/
function updateBrotherSisterElements() {
return false;
} // end func updateBrotherSisterElements
/**
* Updates the @access and @return tag values.
*
* @see updateAccessReturnElements(), updateAccessElements()
* @abstract
*/
function updateAccessReturn() {
} // end func updateAccessReturn
/**
* Updates @access and @return for certain elements.
*
* This function should only be used to update functions.
* Functions that have the same name as the class (constructors)
* get @return void and @access public. Functions without
* @access get @access public and functions without @return get
* @return void.
*
* @return boolean $ok
* @see updateAccessReturn()
* @abstract
*/
function updateAccessReturnElements() {
return false;
} // end func updateAccessReturnElements
/**
* Updates @access tags.
*
* @see updateAccessReturnElements()
* @abstract
*/
function updateAccessElements() {
} // end func updateAccessElements
/**
* Compares the @param tags with the function head found.
* @abstract
*/
function checkFunctionArgs() {
} // end func checkFunctionArgs
/**
* Looks for undocumented elements and adds a warning if neccessary.
* @abstract
*/
function findUndocumented() {
} // end func findUndocumented
/**
* Compares the argument list generated from the function head with the @param tags found.
*
* PHPDoc is able to recognize these documentation mistakes:
* - too few or too many @param tags
* - name does not match or is missing
* - type does not match or is missing
* - trouble with inherited elements
*
* @param array Function arguments found by the parser
* @param array Paramarray
* @param string Functionname
* @param string Filename
* @param boolean Param tags inherited?
* @return array $params Param array
*/
function checkArgDocs($args, $params, $elname, $elfile, $inherited=false) {
// "args" contains the informations the parser found in the function head.
// "param" contains the information from the @param tags.
$num_args = count($args);
$num_params = count($params);
// no args? return...
if (0==$num_args && 0==$num_params) {
return array();
}
// no args but @param used
if (0==$num_args && $num_params>0) {
if (!$inherited) {
$msg = "Function head shows no parameters, remove all @param tags.";
$this->warn->addDocWarning($elfile, "function", $elname, $msg, "mismatch");
} else {
if ("void"!=$params[0]["type"]) {
$msg = "The function inherited some parameter documentation from it's parentclass but PHPDoc could not find
arguments in the function head. Add @param void to the doc comment to avoid confusion.";
$this->warn->addDocWarning($elfile, "function", $elname, $msg, "mismatch");
}
}
return array();
}
// compare the informations from the parser with the @param tags
reset($args);
while (list($k, $arg)=each($args)) {
if (isset($params[$k])) {
if ($arg["optional"])
$params[$k]["default"] = $arg["default"];
if (!$inherited) {
if (""!=$arg["type"] && ""!=$params[$k]["type"] && strtolower($arg["type"])!=strtolower($params[$k]["type"])) {
$type = $arg["type"];
$msg = sprintf("%dth parameter type '%s' does match the the documented type '%s', possible error consider an update to '@param %s %s %s' or '@param %s %s', the variable name is optional.",
$k+1,
$arg["name"],
$params[$k]["type"],
$type,
$arg["name"],
(isset($params[$k]["desc"])) ? $params[$k]["desc"] : "(description)",
$type,
(isset($params[$k]["desc"])) ? $params[$k]["desc"] : "(description)"
);
$this->warn->addDocWarning($elfile, "function", $elname, $msg, "mismatch");
} else if (""!=$params[$k]["type"]) {
$type = $params[$k]["type"];
} else {
$msg = sprintf('Type missing for the %dth parameter, "mixed" assumed.', $k);
$this->warn->addDocWarning($elfile, "function", $elname, $msg, "missing");
$type = "mixed";
}
$params[$k]["type"] = $type;
} else {
if (""!=$params[$k]["type"] && strtolower($arg["type"])!=strtolower($params[$k]["type"])) {
$type = (""!=$args["type"]) ? $arg["type"] : $params[$k]["type"];
$msg = sprintf("Possible documentation error due to inherited information.
The type of the %dth parameter '%s' does not match the documented type '%s'.
Override the inherited documentation if neccessary.",
$k,
$arg["type"],
$params[$k]["type"]
);
$this->warn->addDocWarning($elfile, "function", $elname, $msg, "mismatch");
} else if (""!=$params[$k]["type"]) {
$type = $params[$k]["type"];
} else {
$type = "mixed";
$msg = sprintf('Type missing for the %d parameter, "mixed" assumed. Override the inherited documentation if neccessary.', $k);
$this->warn->addDocWarning($elfile, "function", $elname, $msg, "mismatch");
}
$params[$k]["type"] = $type;
}
if (""!=$params[$k]["name"] && $arg["name"]!=$params[$k]["name"]) {
$msg = sprintf("%dth parameter '%s' does not match the documented name '%s', update the tag to '@param %s %s %s' or '@param %s %s', the variable name is optional.",
$k+1,
$arg["name"],
$params[$k]["name"],
$type,
$arg["name"],
(isset($params[$k]["desc"])) ? $params[$k]["desc"] : "(description)",
$type,
(isset($params[$k]["desc"])) ? $params[$k]["desc"] : "(description)"
);
$this->warn->addDocWarning($elfile, "function", $elname, $msg, "mismatch");
$params[$k]["name"] = $arg["name"];
} else if (""==$params[$k]["name"]) {
$params[$k]["name"] = $arg["name"];
}
} else {
$msg = sprintf("%dth parameter '%s' is not documented add '@param %s [description]' to the end of the @param[eter] list.",
$k+1,
$arg["name"],
(""==$arg["type"]) ? "(object objectname|type)" : $arg["type"]
);
$params[$k]["name"] = $arg["name"];
$params[$k]["undoc"] = true;
if (""!=$arg["type"])
$params[$k]["type"] = $arg["type"];
$this->warn->addDocWarning($elfile, "function", $elname, $msg, "missing");
}
}
// more @params specified than variables where found in the function head, delete them
if ($num_params>$num_args) {
$msg = "The parser found '$num_args' parameter but '$num_params' @param[eter] tags. You should update the @param[eter] list.";
$this->warn->addDocWarning($elfile, "function", $elname, $msg, "mismatch");
for ($i=$k+1; $i<$num_params; $i++)
unset($params[$i]);
}
return $params;
} // end func checkArgDocs
} // end func PhpdocAnalyser
?>
|