public function parseReturn(Tokenizer $tokens) { if ($tokens->valid()) { $return = $this->parseExpression($tokens->next()); dump("{$return}"); if ($return->isScalar()) { switch ($return->type) { case Types::BOOLEAN: return $return->value ? "RETURN_TRUE;" : "RETURN_FALSE;"; case Types::DOUBLE: return "RETURN_DOUBLE({$return->value});"; case Types::INT: return "RETURN_LONG({$return->value});"; case Types::NIL: return "RETURN_NULL();"; case Types::STRING: return "RETURN_STRINGL(\"" . addslashes($return->value) . "\", " . strlen($return->value) . ");"; default: drop("unknown type " . Types::getTypeCode($return->type)); } } else { return "RETURN_ZVAL({$return}, 1);"; } } else { return "return;"; } }
public function setScalar($value) { $this->type = Types::detectType($value); $this->value = $value; $this->is_const = true; $this->is_var = false; $this->is_mixed = false; return $this; }
/** * * @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); } }
public function dump($tab = "") { $args = []; foreach ($this->arguments as $arg) { $args[] = $arg->dump(); } return static::$entity_type . " {$this->name}(" . ($args ? implode(', ', $args) : '') . '):' . ($this->return_type == -1 ? 'void' : Types::getTypeCode($this->return_type)); }
/** * @param object $object * @return bool * @throws \InvalidArgumentException */ public static function configure($object) { $options = self::_parse(); $class = new \ReflectionClass(get_class($object)); $ce = new EntityClass(get_class($object)); if (isset($options['help'])) { echo "Usage: " . $_SERVER['argv'][0] . " [OPTIONS ...]\nOptions:\n"; foreach ($class->getMethods(\ReflectionMethod::IS_PUBLIC) as $method) { if (strpos($method->name, 'set') === 0) { $name = substr($method->name, 3); } elseif (strpos($method->name, 'get') === 0) { $name = substr($method->name, 3); } elseif (strpos($method->name, 'add') === 0) { $name = $method->name; } else { continue; } $name = self::toCLIName($name); // $about = (new EntityMethod($ce->name.'::'.$method->name))->setClass($ce)->scan(); $about = new EntityMethod($ce->name . '::' . $method->name); EntityFile::parseCallable($about, $about->setClass($ce)->getReflection()); $req = []; if ($about->arguments) { $first = true; // if($about->required == 0) { // printf(" --%-25s %s\n", $name, $about->description); // $req[] = $name; // } foreach ($about->arguments as $argument) { $description = $argument->description . ($req ? " (required --" . implode(", --", $req) . ")" : ""); /* @var EntityArgument $argument */ if ($argument->isOptional()) { if ($first) { $first = false; $arg_name = $name . "[=" . strtoupper($argument->name) . "]"; $description = $about->description . sprintf("\n %-27s %s — %s", "", strtoupper($argument->name), $argument->description); } else { $arg_name = $name . "." . $argument->name . "=" . strtoupper(Types::getTypeCode($argument->type)); } printf(" --%-25s %s\n", $arg_name, $description); } else { // $arg_name = $name.".".$argument->name; if ($first) { $first = false; $arg_name = $name . "=" . strtoupper($argument->name); $description = $about->description . sprintf("\n %-27s %s — %s\n", "", strtoupper($argument->name), $argument->description); } else { $arg_name = $name . "." . $argument->name . "=" . strtoupper(Types::getTypeCode($argument->type)); } $req[] = $arg_name; printf(" --%-25s %s\n", $arg_name, $description); } } } else { printf(" --%-25s %s\n", $name, $about->description); } } echo "\nKoda " . \Koda::VERSION_STRING . " by Ivan [Bzick] Shalganov\n"; return false; } foreach ($options as $option => $values) { $method = str_replace('-', '', $option); if (strpos($method, 'add') === 0) { self::_call([$object, $method], $values, $option); } elseif (method_exists($object, 'set' . $method)) { self::_call([$object, 'set' . $method], $values, $option); } elseif (method_exists($object, 'get' . $method)) { echo self::_call([$object, 'get' . $method], $values, $option) . "\n"; return false; } else { throw new \InvalidArgumentException("Unknown option --{$option}"); } } return true; }
/** * @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; }