From a6f7839b0c0126d0f4f236fac5d62bb6bfca4d86 Mon Sep 17 00:00:00 2001 From: Pavel Shevaev Date: Wed, 19 Feb 2025 15:57:50 +0300 Subject: [PATCH] Adding further optimizations for content without any macros and type hints --- jsm.inc.php | 97 ++++++++++++++++++++++++++++++++--------------------- 1 file changed, 59 insertions(+), 38 deletions(-) diff --git a/jsm.inc.php b/jsm.inc.php index 6ef6ac2..125349f 100644 --- a/jsm.inc.php +++ b/jsm.inc.php @@ -43,7 +43,7 @@ class JSM throw new Exception("Module for '$file' not found"); } - function _extractModule($file) + function _extractModule($file) : JSM_Module { $txt = file_get_contents($file); if($txt === false) @@ -54,11 +54,12 @@ class JSM $m->node = new JSM_MacroDefNode($file/*using file as name*/); $this->_pushCurrentModule($m); - $txt = $this->_fixJunk($txt); - $txt = $this->_removeBlockComments($txt); - $txt = $this->_removeLineComments($txt); + $txt = self::_fixJunk($txt); + $txt = self::_removeBlockComments($txt); + $txt = self::_removeLineComments($txt); $txt = $this->_processIncludes($file, $txt); $txt = $this->_extractScriptDefs($file, $txt); + $this->_parseDefBody($m->node, $file, $txt); $this->_popCurrentModule(); @@ -92,7 +93,8 @@ class JSM return $this->_currentModule(); } - function process() + //NOTE: returns [json, module] + function process() : array { $m = $this->_extractModule($this->file); @@ -102,9 +104,17 @@ class JSM $this->defs = $m->defs; $this->includes = $m->includes; - $this->_pushBuffer(); - $m->node->call($this); - $res = $this->_popBuffer(); + $res = ''; + if($m->node->raw_text_node) + { + $res = $m->node->raw_text_node->txt; + } + else + { + $this->_pushBuffer(); + $m->node->call($this); + $res = $this->_popBuffer(); + } if($this->buffers) throw new Exception("Non closed buffers " . sizeof($this->buffers)); @@ -233,14 +243,14 @@ class JSM throw new Exception("Var '$name' not resolved"); } - private function _fixJunk($txt) + private static function _fixJunk(string $txt) : string { //windows eol $txt = str_replace("\r\n", "\n", $txt); return $txt; } - private function _removeBlockComments($txt) + private static function _removeBlockComments(string $txt) : string { if(strpos($txt, '/*') === false) return $txt; @@ -253,14 +263,14 @@ class JSM return $txt; } - private function _removeLineComments($txt) + private static function _removeLineComments(string $txt) : string { //TODO: it's not robust enough, note a hack for URL addresses $txt = preg_replace("~\s*(?base_dirs, $curr_file, $inc_path); @@ -313,11 +323,11 @@ class JSM if(!isset(self::$modules[$file])) { - if($this->_hasExtension($file, '.js')) + if(self::_hasExtension($file, '.js')) { self::$modules[$file] = $this->_extractModule($file); } - else if($this->_hasExtension($file, '.php')) + else if(self::_hasExtension($file, '.php')) { include_once($file); //special mark for PHP include @@ -353,7 +363,7 @@ class JSM return $need_include_macro ? "<%INC($file)%>" : ''; } - private function _processIncludes($file, $txt) + private function _processIncludes(string $file, string $txt) : string { if(strpos($txt, 'INC') !== false) { @@ -367,25 +377,25 @@ class JSM return $txt; } - function _isIncluded($file) + function _isIncluded(string $file) : bool { $file = jsm_normalize_path($file); return isset($this->includes[$file]); } - function _hasExtension($file, $ext) + static function _hasExtension(string $file, string $ext) : bool { return strpos($file, $ext, strlen($file) - strlen($ext) - 1) !== false; } - static function getDeps(array $base_dirs, $file) + static function getDeps(array $base_dirs, string $file) : array { $deps = array(); self::_getDeps($base_dirs, $file, $deps); return $deps; } - static private function _extractDeps($txt) + static private function _extractDeps(string $txt) : array { $dep_files = array(); if(preg_match_all('~<%\s*INC\s*\(\s*"([^\n]+)~', $txt, $ms)) @@ -399,7 +409,7 @@ class JSM return array_keys($dep_files); } - static private function _getDeps(array $base_dirs, $file, &$deps) + static private function _getDeps(array $base_dirs, string $file, array &$deps) { static $cache = array(); @@ -441,7 +451,7 @@ class JSM } } - private function _extractDefNameAndArgs($full_name) + private function _extractDefNameAndArgs(string $full_name) : array { $pos = strpos($full_name, '('); if($pos == -1) @@ -454,14 +464,14 @@ class JSM return array($name, $args); } - private function _parseMacroDefArgs($args_str) + private function _parseMacroDefArgs(string $args_str) { if(!$args_str) return array(); return $this->args_parser->parseDef($args_str); } - function nodes2str($nodes_or_str) + function nodes2str($nodes_or_str) : string { $str = ''; if(is_array($nodes_or_str)) @@ -478,13 +488,13 @@ class JSM return $str; } - function _processMacroArgs($arg_nodes_or_str) + function _processMacroArgs($arg_nodes_or_str) : array { $str = $this->nodes2str($arg_nodes_or_str); return $this->_parseMacroArgsStr($str); } - function _parseMacroArgsStr($orig_args_str) + function _parseMacroArgsStr($orig_args_str) : array { static $cache = array(); @@ -496,8 +506,8 @@ class JSM if($may_cache && isset($cache[$orig_args_str])) return $cache[$orig_args_str]; - $args_str = $this->_removeBlockComments($orig_args_str); - $args_str = $this->_removeLineComments($args_str); + $args_str = self::_removeBlockComments($orig_args_str); + $args_str = self::_removeLineComments($args_str); $args_str = rtrim($args_str, ','); $res = $this->args_parser->parseInvoke($args_str); @@ -508,7 +518,7 @@ class JSM return $res; } - private function _extractScriptDefs($file, $txt) + private function _extractScriptDefs(string $file, string $txt) : string { if(strpos($txt, 'def') === false) return $txt; @@ -549,8 +559,11 @@ class JSM return $txt; } - private function _replaceVarsWithMacro($file, $txt) + private function _replaceVarsWithMacro(string $file, string $txt) : string { + if(strpos($txt, '$') === false) + return $txt; + //simple vals $txt = preg_replace( '~\{(\$[a-zA-Z0-9_]+)\}~', @@ -566,14 +579,16 @@ class JSM return $txt; } - private function _parseDefBody(JSM_MacroDefNode $node, $file, $txt) + private function _parseDefBody(JSM_MacroDefNode $node, string $file, string $txt) { $txt = $this->_replaceVarsWithMacro($file, $txt); //let's exit early if there are no macro calls if(strpos($txt, '<%') === false) { - $node->addChild(new JSM_TextNode($txt)); + $raw_text_node = new JSM_TextNode($txt); + $node->raw_text_node = $raw_text_node; + $node->addChild($raw_text_node); return; } @@ -629,7 +644,7 @@ class JSM $this->_popNode(); } - function _newCall($name) + function _newCall(string $name) { $func = "macro_ex_{$name}"; if(is_callable($func)) @@ -642,7 +657,7 @@ class JSM } } - function _getMacro($name) + function _getMacro(string $name) : JSM_MacroUserNode { if(isset($this->defs[$name])) return $this->defs[$name]; @@ -686,6 +701,11 @@ interface JSM_MacroNode function call(JSM $jsm); } +interface JSM_MacroUserNode extends JSM_MacroNode +{ + function setUserArgs(array $args); +} + interface JSM_MacroInternalNode extends JSM_MacroNode { function addChild(JSM_MacroNode $node); @@ -745,7 +765,7 @@ class JSM_MacroCallNode implements JSM_MacroInternalNode } } -class JSM_MacroPHPNode implements JSM_MacroNode +class JSM_MacroPHPNode implements JSM_MacroUserNode { var $func; @@ -857,13 +877,14 @@ class JSM_MacroPHPNode implements JSM_MacroNode } } -class JSM_MacroDefNode implements JSM_MacroInternalNode +class JSM_MacroDefNode implements JSM_MacroInternalNode,JSM_MacroUserNode { var $name = ''; var $file = ''; var $decl_args = array(); var $node_args = array(); var $children = array(); + var $raw_text_node = null; function __construct($name, $decl_args = array(), $file = '') {