/** * * @param EntityFunction $callable * @param \ReflectionFunctionAbstract $reflection * @return $this */ public static function parseCallable(EntityFunction $callable, \ReflectionFunctionAbstract $reflection) { $doc = $reflection->getDocComment(); $params = []; if ($doc) { $info = ToolKit::parseDoc($doc); $callable->setDescription($info['desc']); $callable->setReturnInfo($info['return']['type'], $reflection->returnsReference(), $info['return']['desc']); $callable->setOptions($info['options']); $params = $info["params"]; } else { $info = []; } /* @var \ReflectionParameter[] $params */ foreach ($reflection->getParameters() as $param) { $argument = new EntityArgument($param->name); if (isset($params[$param->name]["desc"])) { $argument->description = $params[$param->name]["desc"]; } if ($callable->getLine()) { $argument->setLine($callable->getLine()); } $argument->setOptional($param->isOptional()); $argument->setNullAllowed($param->allowsNull()); $argument->setValue($param->isDefaultValueAvailable() ? $param->getDefaultValue() : null, $param->isPassedByReference()); $argument->setByRef($param->isPassedByReference()); /** @var \ReflectionParameter $param */ if ($param->isArray()) { $argument->setCast(Types::ARR); } if ($c = $param->getClass()) { $argument->setCast(Types::OBJECT, $c->name); } elseif (isset($info['params'][$param->name])) { $_type = $info['params'][$param->name]["type"]; if (strpos($_type, "|") || $_type === "mixed") { // multiple types or mixed $argument->setCast(Types::MIXED); } else { if (strpos($_type, "[]")) { $argument->setCast(Types::ARR, rtrim($_type, '[]')); } if (isset(Types::$codes[$_type])) { $argument->setCast(Types::getType($_type)); } else { $argument->setCast(Types::OBJECT, ltrim($_type, '\\')); } } } else { $argument->warning("not documented"); } $callable->pushArgument($argument); } }
/** * @param string $doc * @return array */ public static function parseDoc($doc) { $doc = preg_replace('/^\\s*(\\*\\s*)+/mS', '', trim($doc, "*/ \t\n\r")); $info = ["desc" => "", "return" => ['type' => -1, 'desc' => ''], "options" => []]; $params = []; if (strpos($doc, "@") !== false) { $doc = explode("@", $doc, 2); if ($doc[0] = trim($doc[0])) { $info["desc"] = $doc[0]; } if ($doc[1]) { foreach (preg_split('/\\r?\\n@/Sm', $doc[1]) as $param) { $param = preg_split('/\\s+/', $param, 2); if (!isset($param[1])) { $param[1] = ""; } switch (strtolower($param[0])) { case 'desc': case 'description': if (empty($info["desc"])) { $info["desc"] = $param[1]; } break; case 'param': if (preg_match('/^(.*?)\\s*\\$(\\w+)\\s*?/Sm', $param[1], $matches)) { $params[$matches[2]] = array("type" => $matches[1], "desc" => trim(substr($param[1], strlen($matches[0])))); } break; case 'return': if (preg_match('/^(.*?)\\s*$/Sm', $param[1], $matches)) { $info["return"]["type"] = Types::getType($matches[1]); $info["return"]["desc"] = isset($matches[2]) ? $matches[2] : ''; } break; default: if (isset($info["options"][$param[0]])) { if (!is_array($params["options"][$param[0]])) { $info["options"][$param[0]] = array($info["options"][$param[0]]); } $info["options"][$param[0]][] = $param[1]; } else { $info["options"][$param[0]] = $param[1]; } } } } } else { $info["desc"] = $doc; } $info['params'] = $params; return $info; }