From 7449faaa76a5b4008fd51a6562cca2e0a852ea6b Mon Sep 17 00:00:00 2001 From: Laria Carolin Chabowski Date: Fri, 1 May 2020 17:33:13 +0200 Subject: Clean up code and improve documentation This switches the code documentation genarator (we're now using phpdoc instead of NaturalDoc). Also various small code cleanup tasks: - Remove unused code - Get rid of `and` / `or`, we're using `&&` / `||` now - Adding missing return values - Helping PhpStorm to detect some dynamically called functions (mark_builtin_callable in Transcompiler) - Reword transcompiling => compiling in documentation --- src/ste/ASTNode.php | 8 ++ src/ste/Calc.php | 48 ++++++++-- src/ste/CantLoadTemplate.php | 8 +- src/ste/CantSaveTemplate.php | 8 +- src/ste/FatalRuntimeError.php | 6 +- src/ste/FilesystemStorageAccess.php | 28 +++--- src/ste/Misc.php | 4 + src/ste/ParseCompileError.php | 8 +- src/ste/Parser.php | 114 +++++++++++++++++++---- src/ste/RuntimeError.php | 8 +- src/ste/STECore.php | 177 +++++++++++++++++++++-------------- src/ste/STEStandardLibrary.php | 74 +++++++++++++++ src/ste/Scope.php | 39 ++++++++ src/ste/StorageAccess.php | 51 ++++------ src/ste/TagNode.php | 11 +++ src/ste/TextNode.php | 7 ++ src/ste/Transcompiler.php | 181 +++++++++++++++++++++++++++++------- src/ste/VariableNode.php | 13 ++- 18 files changed, 593 insertions(+), 200 deletions(-) (limited to 'src') diff --git a/src/ste/ASTNode.php b/src/ste/ASTNode.php index 2163161..3e74635 100644 --- a/src/ste/ASTNode.php +++ b/src/ste/ASTNode.php @@ -4,8 +4,16 @@ namespace kch42\ste; abstract class ASTNode { + /** @var string */ public $tpl; + + /** @var int */ public $offset; + + /** + * @param string $tpl + * @param int $off + */ public function __construct($tpl, $off) { $this->tpl = $tpl; diff --git a/src/ste/Calc.php b/src/ste/Calc.php index 64d2b7a..2f2d09d 100644 --- a/src/ste/Calc.php +++ b/src/ste/Calc.php @@ -2,15 +2,25 @@ namespace kch42\ste; -/* Class Calc contains static methods needed by */ +/** + * Class Calc contains static methods needed by + */ class Calc { private function __construct() { } - /* We could also just eval() the $infix_math code, but this is much cooler :-D (Parser inception) */ - public static function shunting_yard($infix_math) + /** + * Parse a mathematical expression with the shunting yard algorithm (https://en.wikipedia.org/wiki/Shunting-yard_algorithm) + * + * We could also just eval() the $infix_math code, but this is much cooler :-D (Parser inception) + + * @param string $infix_math + * @return array + * @throws RuntimeError + */ + private static function shunting_yard($infix_math) { $operators = array( "+" => array("l", 2), @@ -68,11 +78,17 @@ class Calc } else { $priority = $operators[$token][1]; if ($operators[$token][0] == "l") { - while ((!empty($op_stack)) and ($priority <= $operators[$op_stack[count($op_stack)-1]][1])) { + while ( + !empty($op_stack) + && $priority <= $operators[$op_stack[count($op_stack)-1]][1] + ) { $output_queue[] = array_pop($op_stack); } } else { - while ((!empty($op_stack)) and ($priority < $operators[$op_stack[count($op_stack)-1]][1])) { + while ( + !empty($op_stack) + && $priority < $operators[$op_stack[count($op_stack)-1]][1] + ) { $output_queue[] = array_pop($op_stack); } } @@ -91,7 +107,12 @@ class Calc return $output_queue; } - public static function pop2(&$array) + /** + * @param array $array + * @return array + * @throws RuntimeError + */ + private static function pop2(&$array) { $rv = array(array_pop($array), array_pop($array)); if (array_search(null, $rv, true) !== false) { @@ -100,7 +121,12 @@ class Calc return $rv; } - public static function calc_rpn($rpn) + /** + * @param array $rpn A mathematical expression in reverse polish notation + * @return int|float + * @throws RuntimeError + */ + private static function calc_rpn($rpn) { $stack = array(); foreach ($rpn as $token) { @@ -140,6 +166,14 @@ class Calc return array_pop($stack); } + /** + * Calculate a simple mathematical expression. Supported operators are +, -, *, /, ^. + * You can use ( and ) to group expressions together. + * + * @param string $expr + * @return float|int + * @throws RuntimeError + */ public static function calc($expr) { return self::calc_rpn(self::shunting_yard($expr)); diff --git a/src/ste/CantLoadTemplate.php b/src/ste/CantLoadTemplate.php index 20200d6..92604cc 100644 --- a/src/ste/CantLoadTemplate.php +++ b/src/ste/CantLoadTemplate.php @@ -1,13 +1,9 @@ implementation can throw, if it is unable to load a template. +/** + * An exception that a {@see StorageAccess} implementation can throw, if it is unable to load a template. */ class CantLoadTemplate extends StorageAccessFailure { diff --git a/src/ste/CantSaveTemplate.php b/src/ste/CantSaveTemplate.php index edbb93e..92cdfe7 100644 --- a/src/ste/CantSaveTemplate.php +++ b/src/ste/CantSaveTemplate.php @@ -1,13 +1,9 @@ implementation can throw, if it is unable to save a template. +/** + * An exception that a {@see StorageAccess} implementation can throw, if it is unable to save a template. */ class CantSaveTemplate extends StorageAccessFailure { diff --git a/src/ste/FatalRuntimeError.php b/src/ste/FatalRuntimeError.php index ab40af5..3f5183f 100644 --- a/src/ste/FatalRuntimeError.php +++ b/src/ste/FatalRuntimeError.php @@ -1,12 +1,8 @@ implementation for loading / saving templates into a directory structure. +/** + * The default {@see StorageAccess} implementation for loading / saving templates into a directory structure. */ class FilesystemStorageAccess implements StorageAccess { + /** @var string */ protected $sourcedir; + + /** @var string */ protected $transcompileddir; - /* - * Constructor: __construct - * - * Parameters: - * $src - The directory with the sources (Writing permissions are not mandatory, because STE does not save template sources). - * $transc - The directory with the transcompiled templates (the PHP instance / the HTTP Server needs writing permissions to this directory). + /** + * @param string $src - The directory with the sources (Writing permissions are not mandatory, because STE does not save template sources). + * @param string $transc - The directory with the compiled templates (the PHP instance / the HTTP Server needs writing permissions to this directory). */ public function __construct($src, $transc) { @@ -43,13 +39,16 @@ class FilesystemStorageAccess implements StorageAccess $src_stat = @stat($src_fn); $transc_stat = @stat($transc_fn); - if (($src_stat === false) and ($transc_stat === false)) { + if ($src_stat === false && $transc_stat === false) { throw new CantLoadTemplate("Template not found."); } elseif ($transc_stat === false) { $mode = StorageAccess::MODE_SOURCE; return file_get_contents($src_fn); } elseif ($src_stat === false) { include($transc_fn); + if (!isset($transcompile_fx)) { + throw new CantLoadTemplate("Compiled template file $transc_fn does not set \$transcompile_fx"); + } return $transcompile_fx; } else { if ($src_stat["mtime"] > $transc_stat["mtime"]) { @@ -57,6 +56,9 @@ class FilesystemStorageAccess implements StorageAccess return file_get_contents($src_fn); } else { include($transc_fn); + if (!isset($transcompile_fx)) { + throw new CantLoadTemplate("Compiled template file $transc_fn does not set \$transcompile_fx"); + } return $transcompile_fx; } } diff --git a/src/ste/Misc.php b/src/ste/Misc.php index d017ee3..330b3d2 100644 --- a/src/ste/Misc.php +++ b/src/ste/Misc.php @@ -4,6 +4,10 @@ namespace kch42\ste; class Misc { + /** + * @param string $text + * @return string + */ public static function escape_text($text) { return addcslashes($text, "\r\n\t\$\0..\x1f\\\"\x7f..\xff"); diff --git a/src/ste/ParseCompileError.php b/src/ste/ParseCompileError.php index f5f0272..29590da 100644 --- a/src/ste/ParseCompileError.php +++ b/src/ste/ParseCompileError.php @@ -2,6 +2,9 @@ namespace kch42\ste; +/** + * An exception thrown by the parser or compiler + */ class ParseCompileError extends \Exception { public $msg; @@ -16,10 +19,13 @@ class ParseCompileError extends \Exception $this->message = "$msg (Template $tpl, Offset $offset)"; } + /** + * Update the message to include a human readable offset. + * @param string $code + */ public function rewrite($code) { $line = substr_count(str_replace("\r\n", "\n", substr($code, 0, $this->off)), "\n") + 1; $this->message = "{$this->msg} (Template {$this->tpl}, Line $line)"; - $this->is_rewritten = true; } } diff --git a/src/ste/Parser.php b/src/ste/Parser.php index 40f5f20..0280f6d 100644 --- a/src/ste/Parser.php +++ b/src/ste/Parser.php @@ -1,20 +1,25 @@ text = $text; @@ -30,6 +39,10 @@ class Parser $this->len = mb_strlen($text); } + /** + * @param int $n + * @return string + */ private function next($n = 1) { if ($n <= 0) { @@ -40,11 +53,17 @@ class Parser return $c; } + /** + * @return bool + */ private function eof() { return ($this->off == $this->len); } + /** + * @param int $n + */ private function back($n = 1) { if ($n <= 0) { @@ -53,11 +72,19 @@ class Parser $this->off = max($this->off - $n, 0); } + /** + * @param string $needle + * @return false|int + */ private function search_off($needle) { return mb_strpos($this->text, $needle, $this->off); } + /** + * @param string[] $needles + * @return array 4-tuple of found key, offset, text preceding offset, old offset + */ private function search_multi($needles) { $oldoff = $this->off; @@ -81,6 +108,10 @@ class Parser return array($which, $minoff, mb_substr($this->text, $oldoff, $minoff - $oldoff), $oldoff); } + /** + * @param string $needle + * @return array 3-tuple of offset (or false), text preceding offset, old offset + */ private function search($needle) { $oldoff = $this->off; @@ -95,7 +126,11 @@ class Parser return array($off, mb_substr($this->text, $oldoff, $off - $oldoff), $oldoff); } - private function take_while($cb) + /** + * @param callable $cb + * @return string + */ + private function take_while(callable $cb) { $s = ""; while (($c = $this->next()) !== "") { @@ -113,6 +148,10 @@ class Parser $this->take_while("ctype_space"); } + /** + * @return string + * @throws ParseCompileError + */ private function get_name() { $off = $this->off; @@ -125,21 +164,16 @@ class Parser return $name; } - /* - * Function: parse + /** * Parses the input into an AST. * - * You only need this function, if you want to manually trnascompile a template. + * You only need this function, if you want to manually compile a template. * - * Parameters: - * $text - The input code. - * $name - The name of the template. + * @param string $text The input code. + * @param string $name The name of the template. * - * Returns: - * An array of objects. - * - * Throws: - * + * @return ASTNode[] + * @throws ParseCompileError */ public static function parse($text, $name) { @@ -151,10 +185,15 @@ class Parser return self::tidyup_ast($res[0]); } + /** + * @param ASTNode[] $ast + * @return ASTNode[] + */ private static function tidyup_ast($ast) { $out = array(); + /** @var TextNode|null $prevtext */ $prevtext = null; $first = true; @@ -206,6 +245,17 @@ class Parser return $out; } + /** + * @param string $escapes + * @param int $flags + * @param string|null $breakon + * @param string|null $separator + * @param null $nullaction + * @param string|null $opentag + * @param int $openedat + * @return ASTNode[][] + * @throws ParseCompileError + */ private function parse_text($escapes, $flags, $breakon = null, $separator = null, $nullaction = null, $opentag = null, $openedat = -1) { $elems = array(); @@ -250,14 +300,14 @@ class Parser } break; case "commentopen": - list($off, $before, $offbefore) = $this->search(""); + list($off, , $offbefore) = $this->search(""); if ($off === false) { throw new ParseCompileError("ste:comment was not closed", $this->name, $offbefore); } break; case "rawopen": $off_start = $off; - list($off, $before, $offbefore) = $this->search(""); + list($off, $before, ) = $this->search(""); if ($off === false) { throw new ParseCompileError("ste:rawtext was not closed", $this->name, $off_start); } @@ -352,6 +402,12 @@ class Parser return $elems; } + /** + * @param string $shortname + * @param int $openedat + * @return ASTNode[][] + * @throws ParseCompileError + */ private function parse_short($shortname, $openedat) { $tplname = $this->name; @@ -369,6 +425,12 @@ class Parser ); } + /** + * @param int $openedat + * @param bool $curly + * @return VariableNode + * @throws ParseCompileError + */ private function parse_var($openedat, $curly) { $varnode = new VariableNode($this->name, $openedat); @@ -377,12 +439,16 @@ class Parser $varnode->arrayfields = $this->parse_array(); } - if (($curly) && ($this->next() != "}")) { + if ($curly && ($this->next() != "}")) { throw new ParseCompileError("Unclosed '\${'", $this->name, $openedat); } return $varnode; } + /** + * @return ASTNode[] + * @throws ParseCompileError + */ private function parse_array() { $tplname = $this->name; @@ -409,6 +475,11 @@ class Parser return $arrayfields; } + /** + * @param int $openedat + * @return TagNode + * @throws ParseCompileError + */ private function parse_tag($openedat) { $tplname = $this->name; @@ -475,5 +546,8 @@ class Parser $tag->params[$param] = $paramval[0]; } } + + // Help PhpStorm detect that we shouldn't be here + throw new LogicException("Somehow we left the infinite loop?"); } } diff --git a/src/ste/RuntimeError.php b/src/ste/RuntimeError.php index dace1d4..51fd29d 100644 --- a/src/ste/RuntimeError.php +++ b/src/ste/RuntimeError.php @@ -1,14 +1,10 @@ is false, this will generate a error message instead of the tag's output. + * By default this will return in no output at all. But if {@see STECore::$mute_runtime_errors} is false, this will generate a error message instead of the tag's output. */ class RuntimeError extends \Exception { diff --git a/src/ste/STECore.php b/src/ste/STECore.php index 13fb2f6..40d680a 100644 --- a/src/ste/STECore.php +++ b/src/ste/STECore.php @@ -1,43 +1,64 @@ exception will result in no output from the tag, if false a error message will be written to output. - * $fatal_error_on_missing_tag - If true, STE will throw a if a tag was called that was not registered, otherwise (default) a regular will be thrown and automatically handled by STE (see <$mute_runtime_errors>). - * $vars - Variables in the top scope of the template. + /** + * @var array + * Associative array of blocks (see the language definition). */ public $blocks; + + /** + * @var array + * The order of the blocks (an array) + */ public $blockorder; + + /** + * @var bool + * If true (default) a {@see RuntimeError} exception will result in no + * output from the tag, if false a error message will be written to output. + */ public $mute_runtime_errors = true; + + /** + * @var bool + * If true, STE will throw a {@see FatalRuntimeError} if a tag was called + * that was not registered, otherwise (default) a regular + * {@see RuntimeError} will be thrown and automatically handled by STE + * (see {@see STECore::$mute_runtime_errors}). + */ public $fatal_error_on_missing_tag = false; + + /** + * @var array + * Variables in the top scope of the template. + */ public $vars; - /* - * Constructor: __construct - * - * Parameters: - * $storage_access - An Instance of a implementation. + /** + * @param StorageAccess $storage_access */ - public function __construct($storage_access) + public function __construct(StorageAccess $storage_access) { $this->storage_access = $storage_access; $this->cur_tpl_dir = "/"; @@ -50,42 +71,47 @@ class STECore $this->scope->vars =& $this->vars; } - /* - * Function: register_tag + /** * Register a custom tag. * * Parameters: - * $name - The name of the tag. - * $callback - A callable function (This must take three parameters: The instance, an associative array of parameters, and a function representing the tags content(This expects the instance as its only parameter and returns its text result, i.e to get the text, you neeed to call this function with the instance as a parameter)). + * @param string $name The name of the tag. + * @param callable $callback A callable function + * Must take three parameters: * - * Throws: - * An Exception if the tag could not be registered (if $callback is not callable or if $name is empty) + * The {@see STECore} instance, + * an associative array of parameters, + * and a function representing the tags content + * (This expects the {@see STECore} instance as + * its only parameter and returns its text result, + * i.e to get the text, you need to call this + * function with the {@see STECore} instance as a + * parameter). + * + * @throws Exception If the tag could not be registered (if $callback is not callable or if $name is empty) */ public function register_tag($name, $callback) { if (!is_callable($callback)) { - throw new \Exception("Can not register tag \"$name\", not callable."); + throw new Exception("Can not register tag \"$name\", not callable."); } if (empty($name)) { - throw new \Exception("Can not register tag, empty name."); + throw new Exception("Can not register tag, empty name."); } $this->tags[$name] = $callback; } - /* - * Function: call_tag + /** * Calling a custom tag (builtin ones can not be called) * - * Parameters: - * $name - The Tag's name - * $params - Associative array of parameters - * $sub - A callable function (expecting an instance as it's parameter) that represents the tag's content. + * @param string $name The Tag's name + * @param array $params Associative array of parameters + * @param callable $sub A callable function (expecting an {@see STECore} instance as it's parameter) that represents the tag's content. * - * Throws: - * Might throw a (see <$fatal_error_on_missing_tag>. + * @throws FatalRuntimeError see {@see STECore::$fatal_error_on_missing_tag}. * - * Returns: - * The output of the tag or, if a was thrown, the appropiate result (see <$mute_runtime_errors>). + * @return string The output of the tag or, if a {@see RuntimeError} was thrown, the appropriate result + * (see {@see STECore::$mute_runtime_errors}). */ public function call_tag($name, $params, $sub) { @@ -103,28 +129,37 @@ class STECore return "RuntimeError occurred on tag '$name': " . $e->getMessage(); } } + + return ""; } + /** + * {@see Calc::calc()} + * + * @param string $expression + * @return float|int + * @throws RuntimeError + */ public function calc($expression) { return Calc::calc($expression); } - /* - * Function: exectemplate - * Executes a template and returns the result. The huge difference to is that this function will also output all blocks. + /** + * Executes a template and returns the result. * - * Parameters: - * $tpl - The name of the template to execute. + * The huge difference to {@see STECore::load()} is that this function will also output all blocks. * - * Throws: - * * A exception if the template could not be loaded. - * * A if the template could not be parsed or transcompiled. - * * A if a tag threw it or if a tag was not found and <$fatal_error_on_missing_tag> is true. - * * Might also throw different exceptions, if a external tag threw it (but they should use or to make it possible for STE to handle them correctly). + * @param string $tpl The name of the template to execute. * - * Returns: - * The output of the template. + * @throws CantLoadTemplate If the template could not be loaded. + * @throws ParseCompileError If the template could not be parsed or compiled. + * @throws FatalRuntimeError If a tag threw it or if a tag was not found and <$fatal_error_on_missing_tag> is true. + * + * Might also throw different exceptions, if a external tag threw it + * (but they should use {@see RuntimeError} or {@see FatalRuntimeError} to make it possible for STE to handle them correctly). + * + * @return string The output of the template. */ public function exectemplate($tpl) { @@ -211,22 +246,21 @@ class STECore return $this->scope->get_var_by_name($name); } - /* - * Function: load - * Load a template and return its result (blocks not included, use for this). + /** + * Load a template and return its result (blocks not included, use {@see STECore::exectemplate} for this). * - * Parameters: - * $tpl - The name of the template to be loaded. - * $quiet - If true, do not output anything and do not modify the blocks. This can be useful to load custom tags that are programmed in the STE Template Language. Default: false. + * @param string $tpl The name of the template to be loaded. + * @param bool $quiet If true, do not output anything and do not modify the blocks. This can be useful to load custom tags that are programmed in the STE Template Language. Default: false. * - * Throws: - * * A exception if the template could not be loaded. - * * A if the template could not be parsed or transcompiled. - * * A if a tag threw it or if a tag was not found and <$fatal_error_on_missing_tag> is true. - * * Might also throw different exceptions, if a external tag threw it (but they should use or to make it possible for STE to handle them correctly). + * @throws CantLoadTemplate If the template could not be loaded. + * @throws CantSaveTemplate If the template could not be saved. + * @throws ParseCompileError If the template could not be parsed or compiled. + * @throws FatalRuntimeError If a tag threw it or if a tag was not found and {@see STECore::$fatal_error_on_missing_tag} is true. * - * Returns: - * The result of the template (if $quiet == false). + * Might also throw different exceptions, if a external tag threw it + * (but they should use {@see RuntimeError} or {@see FatalRuntimeError} to make it possible for STE to handle them correctly). + * + * @return string|null The result of the template (if $quiet == false). */ public function load($tpl, $quiet = false) { @@ -238,7 +272,7 @@ class STECore $tpl = $this->cur_tpl_dir . "/" . $tpl; } $pathex = array_filter(explode("/", $tpl), function ($s) { - return ($s != ".") and (!empty($s)); + return $s != "." && !empty($s); }); $pathex = array_merge($pathex); while (($i = array_search("..", $pathex)) !== false) { @@ -277,26 +311,31 @@ class STECore if ($quiet) { $this->blocks = $blocks_back; $this->blockorder = $blockorder_back; + + return null; } else { return $output; } } /* - * Function: evalbool * Test, if a text represents false (an empty / only whitespace text) or true (everything else). * - * Parameters: - * $txt - The text to test. + * @param string $txt The text to test. * - * Returns: - * true/false. + * @return bool */ public function evalbool($txt) { return trim(@(string)$txt) != ""; } + /** + * Internal function for implementing tag content and custom tags. + * + * @param callable $fx + * @return \Closure + */ public function make_closure($fx) { $bound_scope = $this->scope; @@ -312,7 +351,7 @@ class STECore $result = call_user_func_array($fx, $args); $ste->scope = $prev; return $result; - } catch (\Exception $e) { + } catch (Exception $e) { $ste->scope = $prev; throw $e; } diff --git a/src/ste/STEStandardLibrary.php b/src/ste/STEStandardLibrary.php index 9850afe..e39b7af 100644 --- a/src/ste/STEStandardLibrary.php +++ b/src/ste/STEStandardLibrary.php @@ -13,6 +13,12 @@ class STEStandardLibrary } } + /** + * @param STECore $ste + * @param array $params + * @param callable $sub + * @return string + */ public static function escape($ste, $params, $sub) { if ($ste->evalbool(@$params["lines"])) { @@ -22,11 +28,24 @@ class STEStandardLibrary } } + /** + * @param STECore $ste + * @param array $params + * @param callable $sub + * @return string + */ public static function strlen($ste, $params, $sub) { return strlen($sub($ste)); } + /** + * @param STECore $ste + * @param array $params + * @param callable $sub + * @return string + * @throws RuntimeError + */ public static function arraylen($ste, $params, $sub) { if (empty($params["array"])) { @@ -36,6 +55,13 @@ class STEStandardLibrary return (is_array($a)) ? count($a) : ""; } + /** + * @param STECore $ste + * @param array $params + * @param callable $sub + * @return string + * @throws RuntimeError + */ public static function inc($ste, $params, $sub) { if (empty($params["var"])) { @@ -45,6 +71,13 @@ class STEStandardLibrary $ref++; } + /** + * @param STECore $ste + * @param array $params + * @param callable $sub + * @return string + * @throws RuntimeError + */ public static function dec($ste, $params, $sub) { if (empty($params["var"])) { @@ -54,11 +87,24 @@ class STEStandardLibrary $ref--; } + /** + * @param STECore $ste + * @param array $params + * @param callable $sub + * @return string + */ public static function date($ste, $params, $sub) { return @strftime($sub($ste), empty($params["timestamp"]) ? @time() : (int) $params["timestamp"]); } + /** + * @param STECore $ste + * @param array $params + * @param callable $sub + * @return string + * @throws RuntimeError + */ public static function in_array($ste, $params, $sub) { if (empty($params["array"])) { @@ -71,6 +117,13 @@ class STEStandardLibrary return in_array($sub($ste), $ar) ? "y" : ""; } + /** + * @param STECore $ste + * @param array $params + * @param callable $sub + * @return string + * @throws RuntimeError + */ public static function join($ste, $params, $sub) { if (empty($params["array"])) { @@ -79,6 +132,13 @@ class STEStandardLibrary return implode($sub($ste), $ste->get_var_by_name($params["array"])); } + /** + * @param STECore $ste + * @param array $params + * @param callable $sub + * @return string + * @throws RuntimeError + */ public static function split($ste, $params, $sub) { if (empty($params["array"])) { @@ -90,6 +150,13 @@ class STEStandardLibrary $ste->set_var_by_name($params["array"], explode($params["delim"], $sub($ste))); } + /** + * @param STECore $ste + * @param array $params + * @param callable $sub + * @return string + * @throws RuntimeError + */ public static function array_add($ste, $params, $sub) { if (empty($params["array"])) { @@ -104,6 +171,13 @@ class STEStandardLibrary } } + /** + * @param STECore $ste + * @param array $params + * @param callable $sub + * @return string + * @throws RuntimeError + */ public static function array_filter($ste, $params, $sub) { if (empty($params["array"])) { diff --git a/src/ste/Scope.php b/src/ste/Scope.php index e312876..afb2bfc 100644 --- a/src/ste/Scope.php +++ b/src/ste/Scope.php @@ -4,9 +4,17 @@ namespace kch42\ste; class Scope implements \ArrayAccess { + /** @var self|null */ private $parent = null; + + /** @var array */ public $vars = array(); + /** + * @param string $name + * @return string[] + * @throws RuntimeError + */ private static function parse_name($name) { $remain = $name; @@ -44,6 +52,12 @@ class Scope implements \ArrayAccess return $fields; } + /** + * @param string $name + * @param bool $localonly + * @return mixed A reference to the resolved variable + * @throws VarNotInScope + */ private function &get_topvar_reference($name, $localonly) { if (array_key_exists($name, $this->vars)) { @@ -59,6 +73,13 @@ class Scope implements \ArrayAccess throw new VarNotInScope(); } + /** + * @param string $name + * @param bool $create_if_not_exist + * @param bool $localonly + * @return mixed A reference to the resolved variable + * @throws RuntimeError + */ public function &get_var_reference($name, $create_if_not_exist, $localonly=false) { $nullref = null; @@ -107,24 +128,42 @@ class Scope implements \ArrayAccess return $ref; } + /** + * @param string $name + * @param mixed $val + * @throws RuntimeError + */ public function set_var_by_name($name, $val) { $ref = &$this->get_var_reference($name, true); $ref = $val; } + /** + * @param string $name + * @param mixed $val + * @throws RuntimeError + */ public function set_local_var($name, $val) { $ref = &$this->get_var_reference($name, true, true); $ref = $val; } + /** + * @param string $name + * @return mixed Returns an empty string, if not found or unset + * @throws RuntimeError + */ public function get_var_by_name($name) { $ref = $this->get_var_reference($name, false); return $ref === null ? "" : $ref; } + /** + * @return self + */ public function new_subscope() { $o = new self(); diff --git a/src/ste/StorageAccess.php b/src/ste/StorageAccess.php index e2e8727..38dea7e 100644 --- a/src/ste/StorageAccess.php +++ b/src/ste/StorageAccess.php @@ -1,56 +1,45 @@ . - * If , the raw sourcecode is expected, if the transcompiled template *as a callable function* (expecting an instance as first parameter) is expected. - * If the transcompiled version is not available or older than the source, you can set this parameter to and return the source. + * @param string $tpl The name of the template. + * @param string &$mode Which mode is preferred? One of the MODE_* constants. + * If {@see StorageAccess::MODE_SOURCE}, the raw sourcecode is expected, + * if {@see StorageAccess::MODE_TRANSCOMPILED} the compiled template + * *as a callable function* (expecting an {@see STECore} instance as first parameter) is expected. + * + * If the compiled version is not available or older than the source, you can set this + * parameter to {@see StorageAccess::MODE_SOURCE} and return the source. * - * Throws: - * A exception if the template could not be loaded. + * @throws CantLoadTemplate If the template could not be loaded. * - * Returns: - * Either the sourcecode or a callable function (first, and only parameter: an instance). + * @return string|callable Either the sourcecode or a callable function (first, and only parameter: an {@see STECore} instance). */ public function load($tpl, &$mode); - /* - * Function: save + /** * Saves a template. * - * Throws: - * A exception if the template could not be saved. + * @param string $tpl -The name of the template. + * @param string $data - The data to be saved. + * @param int $mode - One of the MODE_* constants. * - * Parameters: - * $tpl -The name of the template. - * $data - The data to be saved. - * $mode - A