From bc5947507f98a6bcec53888791271e08e0680a2b Mon Sep 17 00:00:00 2001 From: gnosygnu Date: Sun, 8 Dec 2019 08:30:28 -0500 Subject: [PATCH] XomwTemplateParser: Start porting over newChild [#632] --- .../src/gplx/xowa/mediawiki/XophpArray.java | 3 +- .../preprocessors/XomwPPDStackElement.java | 183 ---------------- .../parsers/preprocessors/XomwPPFrame.java | 2 +- .../preprocessors/XomwPPFrame_Hash.java | 108 +++++----- .../parsers/preprocessors/XomwPPNode.java | 2 +- .../preprocessors/XomwPPNode_Hash_Tree.java | 6 +- .../XomwPPTemplateFrame_Hash.java | 198 ++++++++++++++++++ 7 files changed, 263 insertions(+), 239 deletions(-) create mode 100644 400_xowa/src/gplx/xowa/mediawiki/includes/parsers/preprocessors/XomwPPTemplateFrame_Hash.java diff --git a/400_xowa/src/gplx/xowa/mediawiki/XophpArray.java b/400_xowa/src/gplx/xowa/mediawiki/XophpArray.java index ff4a5f419..eaaa54593 100644 --- a/400_xowa/src/gplx/xowa/mediawiki/XophpArray.java +++ b/400_xowa/src/gplx/xowa/mediawiki/XophpArray.java @@ -96,7 +96,8 @@ public class XophpArray implements Bry_bfr_able { public boolean Has(String key) { return hash.Has(key); } - public boolean is_set(String key) {return hash.Has(key);} + public boolean isset(String key) {return hash.Has(key);} + public boolean isset(int idx) {return idx >= 0 && idx < hash.Count();} public XophpArrayItm[] To_ary() { return (XophpArrayItm[])hash.To_ary(XophpArrayItm.class); } diff --git a/400_xowa/src/gplx/xowa/mediawiki/includes/parsers/preprocessors/XomwPPDStackElement.java b/400_xowa/src/gplx/xowa/mediawiki/includes/parsers/preprocessors/XomwPPDStackElement.java index ddcd479ec..3f7a4cde2 100644 --- a/400_xowa/src/gplx/xowa/mediawiki/includes/parsers/preprocessors/XomwPPDStackElement.java +++ b/400_xowa/src/gplx/xowa/mediawiki/includes/parsers/preprocessors/XomwPPDStackElement.java @@ -1781,189 +1781,6 @@ public class XomwPPDStackElement { //} // ///** -// * Expansion frame with template arguments -// * @ingroup Parser -// */ -//// @codingStandardsIgnoreStart Squiz.Classes.ValidClassName.NotCamelCaps -//class PPTemplateFrame_Hash extends PPFrame_Hash { -// // @codingStandardsIgnoreEnd -// -// public $numberedArgs, $namedArgs, $parent; -// public $numberedExpansionCache, $namedExpansionCache; -// -// /** -// * @param Preprocessor $preprocessor -// * @param boolean|PPFrame $parent -// * @param array $numberedArgs -// * @param array $namedArgs -// * @param boolean|Title $title -// */ -// public function __construct($preprocessor, $parent = false, $numberedArgs = [], -// $namedArgs = [], $title = false -// ) { -// parent::__construct($preprocessor); -// -// this.parent = $parent; -// this.numberedArgs = $numberedArgs; -// this.namedArgs = $namedArgs; -// this.title = $title; -// $pdbk = $title ? $title.getPrefixedDBkey() : false; -// this.titleCache = $parent.titleCache; -// this.titleCache[] = $pdbk; -// this.loopCheckHash = /*clone*/ $parent.loopCheckHash; -// if ($pdbk !== false) { -// this.loopCheckHash[$pdbk] = true; -// } -// this.depth = $parent.depth + 1; -// this.numberedExpansionCache = this.namedExpansionCache = []; -// } -// -// public function __toString() { -// $s = 'tplframe{'; -// $first = true; -// $args = this.numberedArgs + this.namedArgs; -// for each ($args as $name => $value) { -// if ($first) { -// $first = false; -// } else { -// $s .= ', '; -// } -// $s .= "\"$name\":\"" . -// str_replace('"', '\\"', $value.__toString()) . '"'; -// } -// $s .= '}'; -// return $s; -// } -// -// /** -// * @throws MWException -// * @param String|int $key -// * @param String|PPNode $root -// * @param int $flags -// * @return String -// */ -// public function cachedExpand($key, $root, $flags = 0) { -// if (isset(this.parent.childExpansionCache[$key])) { -// return this.parent.childExpansionCache[$key]; -// } -// $retval = this.expand($root, $flags); -// if (!this.isVolatile()) { -// this.parent.childExpansionCache[$key] = $retval; -// } -// return $retval; -// } -// -// /** -// * Returns true if there are no arguments in this frame -// * -// * @return boolean -// */ -// public function isEmpty() { -// return !count(this.numberedArgs) && !count(this.namedArgs); -// } -// -// /** -// * @return array -// */ -// public function getArguments() { -// $arguments = []; -// for each (array_merge( -// array_keys(this.numberedArgs), -// array_keys(this.namedArgs)) as $key) { -// $arguments[$key] = this.getArgument($key); -// } -// return $arguments; -// } -// -// /** -// * @return array -// */ -// public function getNumberedArguments() { -// $arguments = []; -// for each (array_keys(this.numberedArgs) as $key) { -// $arguments[$key] = this.getArgument($key); -// } -// return $arguments; -// } -// -// /** -// * @return array -// */ -// public function getNamedArguments() { -// $arguments = []; -// for each (array_keys(this.namedArgs) as $key) { -// $arguments[$key] = this.getArgument($key); -// } -// return $arguments; -// } -// -// /** -// * @param int $index -// * @return String|boolean -// */ -// public function getNumberedArgument($index) { -// if (!isset(this.numberedArgs[$index])) { -// return false; -// } -// if (!isset(this.numberedExpansionCache[$index])) { -// # No trimming for unnamed arguments -// this.numberedExpansionCache[$index] = this.parent.expand( -// this.numberedArgs[$index], -// PPFrame::STRIP_COMMENTS -// ); -// } -// return this.numberedExpansionCache[$index]; -// } -// -// /** -// * @param String $name -// * @return String|boolean -// */ -// public function getNamedArgument($name) { -// if (!isset(this.namedArgs[$name])) { -// return false; -// } -// if (!isset(this.namedExpansionCache[$name])) { -// # Trim named arguments post-expand, for backwards compatibility -// this.namedExpansionCache[$name] = trim( -// this.parent.expand(this.namedArgs[$name], PPFrame::STRIP_COMMENTS)); -// } -// return this.namedExpansionCache[$name]; -// } -// -// /** -// * @param int|String $name -// * @return String|boolean -// */ -// public function getArgument($name) { -// $text = this.getNumberedArgument($name); -// if ($text === false) { -// $text = this.getNamedArgument($name); -// } -// return $text; -// } -// -// /** -// * Return true if the frame is a template frame -// * -// * @return boolean -// */ -// public function isTemplate() { -// return true; -// } -// -// public function setVolatile($flag = true) { -// parent::setVolatile($flag); -// this.parent.setVolatile($flag); -// } -// -// public function setTTL($ttl) { -// parent::setTTL($ttl); -// this.parent.setTTL($ttl); -// } -//} -// -///** // * Expansion frame with custom arguments // * @ingroup Parser // */ diff --git a/400_xowa/src/gplx/xowa/mediawiki/includes/parsers/preprocessors/XomwPPFrame.java b/400_xowa/src/gplx/xowa/mediawiki/includes/parsers/preprocessors/XomwPPFrame.java index c7f27c3c1..ebcd4dd30 100644 --- a/400_xowa/src/gplx/xowa/mediawiki/includes/parsers/preprocessors/XomwPPFrame.java +++ b/400_xowa/src/gplx/xowa/mediawiki/includes/parsers/preprocessors/XomwPPFrame.java @@ -41,7 +41,7 @@ public abstract class XomwPPFrame { * * @return PPFrame */ - @gplx.Virtual public XomwPPFrame newChild(XophpArray args, XomwTitle title, int indexOffset) {return null;} + @gplx.Virtual public XomwPPFrame newChild(Object args, XomwTitle title, int indexOffset) {return null;} /** * Expand a document tree node, caching the result on its parent with the given key diff --git a/400_xowa/src/gplx/xowa/mediawiki/includes/parsers/preprocessors/XomwPPFrame_Hash.java b/400_xowa/src/gplx/xowa/mediawiki/includes/parsers/preprocessors/XomwPPFrame_Hash.java index 74ae0ccc2..71bf8b404 100644 --- a/400_xowa/src/gplx/xowa/mediawiki/includes/parsers/preprocessors/XomwPPFrame_Hash.java +++ b/400_xowa/src/gplx/xowa/mediawiki/includes/parsers/preprocessors/XomwPPFrame_Hash.java @@ -70,59 +70,67 @@ class XomwPPFrame_Hash extends XomwPPFrame { /** this.childExpansionCache = XophpArray.New(); } -// /** -// * Create a new child frame -// * $args is optionally a multi-root PPNode or array containing the template arguments -// * -// * @param array|boolean|PPNode_Hash_Array $args -// * @param Title|boolean $title -// * @param int $indexOffset -// * @throws MWException -// * @return PPTemplateFrame_Hash -// */ -// public function newChild($args = false, $title = false, $indexOffset = 0) { -// $namedArgs = []; -// $numberedArgs = []; -// if ($title === false) { -// $title = this.title; -// } -// if ($args !== false) { -// if ($args instanceof PPNode_Hash_Array) { -// $args = $args.value; -// } else if (!is_array($args)) { -// throw new MWException(__METHOD__ . ': $args must be array or PPNode_Hash_Array'); -// } -// foreach ($args as $arg) { -// $bits = $arg.splitArg(); -// if ($bits['index'] !== '') { -// // Numbered parameter -// $index = $bits['index'] - $indexOffset; -// if (isset($namedArgs[$index]) || isset($numberedArgs[$index])) { + /** + * Create a new child frame + * $args is optionally a multi-root PPNode or array containing the template arguments + * + * @param array|boolean|PPNode_Hash_Array $args + * @param Title|boolean $title + * @param int $indexOffset + * @throws MWException + * @return PPTemplateFrame_Hash + */ + @Override public XomwPPFrame newChild(Object argsObj, XomwTitle title, int indexOffset) { + XophpArray namedArgs = XophpArray.New(); + XophpArray numberedArgs = XophpArray.New(); + if (title == XophpObject.False) { + title = this.title; + } + if (argsObj != XophpObject.False) { + XophpArray args = null; + if (Type_.Eq_by_obj(argsObj, XomwPPNode_Hash_Array.class)) { + args = ((XomwPPNode_Hash_Array)argsObj).value; + } else if (!XophpArray.is_array(argsObj)) { + throw XomwMWException.New_by_method(XomwPPFrame_Hash.class, "newChild", ": args must be array or PPNode_Hash_Array"); + } + else { + args = (XophpArray)argsObj; + } + + int argsLen = args.Len(); + for (int i = 0; i < argsLen; i++) { + XomwPPNode arg = (XomwPPNode)args.Get_at(i); + XophpArray bits = arg.splitArg(); + if (bits.Has("index")) { + // Numbered parameter + int index = bits.Get_by_int("index") - indexOffset; + if (namedArgs.isset(index) || numberedArgs.isset(index)) { // this.parser.getOutput().addWarning(wfMessage('duplicate-args-warning', // wfEscapeWikiText(this.title), -// wfEscapeWikiText($title), -// wfEscapeWikiText($index)).text()); +// wfEscapeWikiText(title), +// wfEscapeWikiText(index)).text()); // this.parser.addTrackingCategory('duplicate-args-category'); -// } -// $numberedArgs[$index] = $bits['value']; -// unset($namedArgs[$index]); -// } else { -// // Named parameter -// $name = trim(this.expand($bits['name'], PPFrame.STRIP_COMMENTS)); -// if (isset($namedArgs[$name]) || isset($numberedArgs[$name])) { + } + numberedArgs.Set(index, bits.Get_by("value")); +// XophpArrayUtl.unset_by_idx(namedArgs, index); + } else { + // Named parameter + String name = String_.Trim(this.expand(bits.Get_by("name"), XomwPPFrame.STRIP_COMMENTS)); + if (namedArgs.isset(name) || numberedArgs.isset(name)) { // this.parser.getOutput().addWarning(wfMessage('duplicate-args-warning', // wfEscapeWikiText(this.title), -// wfEscapeWikiText($title), -// wfEscapeWikiText($name)).text()); +// wfEscapeWikiText(title), +// wfEscapeWikiText(name)).text()); // this.parser.addTrackingCategory('duplicate-args-category'); -// } -// $namedArgs[$name] = $bits['value']; -// unset($numberedArgs[$name]); -// } -// } -// } -// return new PPTemplateFrame_Hash(this.preprocessor, $this, $numberedArgs, $namedArgs, $title); -// } + } +// namedArgs.Set(name, bits.Get_by("value")); +// XophpArrayUtl.unset(numberedArgs, name); + } + } + } +// return new PPTemplateFrame_Hash(this.preprocessor, this, numberedArgs, namedArgs, title); + return null; + } /** * @throws MWException @@ -252,7 +260,7 @@ class XomwPPFrame_Hash extends XomwPPFrame { /** ); } else { XophpArray ret = this.parser.braceSubstitution(bits, this); - if (ret.is_set(Object_.Cls_val_name)) {// NOTE: using Cls_val_name b/c of transpilation and Object . Object + if (ret.isset(Object_.Cls_val_name)) {// NOTE: using Cls_val_name b/c of transpilation and Object . Object newIterator = ret.Get_by(Object_.Cls_val_name); } else { outItm += ret.Get_by_str("text"); @@ -269,7 +277,7 @@ class XomwPPFrame_Hash extends XomwPPFrame { /** ); } else { XophpArray ret = this.parser.argSubstitution(bits, this); - if (ret.is_set(Object_.Cls_val_name)) {// NOTE: using Cls_val_name b/c of transpilation and Object . Object + if (ret.isset(Object_.Cls_val_name)) {// NOTE: using Cls_val_name b/c of transpilation and Object . Object newIterator = ret.Get_by("Object"); } else { outItm += ret.Get_by_str("text"); @@ -565,7 +573,7 @@ class XomwPPFrame_Hash extends XomwPPFrame { /** * @return boolean */ @Override public boolean loopCheck(XomwTitle title) { - return !this.loopCheckHash.is_set(title.getPrefixedDBkeyStr()); + return !this.loopCheckHash.isset(title.getPrefixedDBkeyStr()); } /** diff --git a/400_xowa/src/gplx/xowa/mediawiki/includes/parsers/preprocessors/XomwPPNode.java b/400_xowa/src/gplx/xowa/mediawiki/includes/parsers/preprocessors/XomwPPNode.java index 438d95d5b..7cceb9055 100644 --- a/400_xowa/src/gplx/xowa/mediawiki/includes/parsers/preprocessors/XomwPPNode.java +++ b/400_xowa/src/gplx/xowa/mediawiki/includes/parsers/preprocessors/XomwPPNode.java @@ -91,7 +91,7 @@ public abstract class XomwPPNode { * value PPNode value * @return array */ -// public abstract Hash_adp splitArg(); + @gplx.Virtual public XophpArray splitArg() {return null;} /** * Split an "" node into an associative array containing name, attr, inner and close diff --git a/400_xowa/src/gplx/xowa/mediawiki/includes/parsers/preprocessors/XomwPPNode_Hash_Tree.java b/400_xowa/src/gplx/xowa/mediawiki/includes/parsers/preprocessors/XomwPPNode_Hash_Tree.java index 664fe162e..94ab62301 100644 --- a/400_xowa/src/gplx/xowa/mediawiki/includes/parsers/preprocessors/XomwPPNode_Hash_Tree.java +++ b/400_xowa/src/gplx/xowa/mediawiki/includes/parsers/preprocessors/XomwPPNode_Hash_Tree.java @@ -296,7 +296,7 @@ public class XomwPPNode_Hash_Tree extends XomwPPNode { public final String na bits.Add("close", new XomwPPNode_Hash_Tree(children, i)); } } - if (!bits.is_set("name")) { + if (!bits.isset("name")) { throw new XomwMWException("Invalid ext node passed to " + "splitRawExt"); } return bits; @@ -335,7 +335,7 @@ public class XomwPPNode_Hash_Tree extends XomwPPNode { public final String na bits.Add("level", childChildren.Get_at(0)); } } - if (!bits.is_set("i")) { + if (!bits.isset("i")) { throw new XomwMWException("Invalid h node passed to " + "splitRawHeading"); } return bits; @@ -374,7 +374,7 @@ public class XomwPPNode_Hash_Tree extends XomwPPNode { public final String na bits.Add("lineStart", "1"); } } - if (!bits.is_set("title")) { + if (!bits.isset("title")) { throw new XomwMWException("Invalid node passed to " + "splitRawTemplate"); } bits.Add("parts", new XomwPPNode_Hash_Array(parts)); diff --git a/400_xowa/src/gplx/xowa/mediawiki/includes/parsers/preprocessors/XomwPPTemplateFrame_Hash.java b/400_xowa/src/gplx/xowa/mediawiki/includes/parsers/preprocessors/XomwPPTemplateFrame_Hash.java new file mode 100644 index 000000000..d919535ea --- /dev/null +++ b/400_xowa/src/gplx/xowa/mediawiki/includes/parsers/preprocessors/XomwPPTemplateFrame_Hash.java @@ -0,0 +1,198 @@ +/* +XOWA: the XOWA Offline Wiki Application +Copyright (C) 2012-2017 gnosygnu@gmail.com + +XOWA is licensed under the terms of the General Public License (GPL) Version 3, +or alternatively under the terms of the Apache License Version 2.0. + +You may use XOWA according to either of these licenses as is most appropriate +for your project on a case-by-case basis. + +The terms of each license can be found in the source code repository: + +GPLv3 License: https://github.com/gnosygnu/xowa/blob/master/LICENSE-GPLv3.txt +Apache License: https://github.com/gnosygnu/xowa/blob/master/LICENSE-APACHE2.txt +*/ +package gplx.xowa.mediawiki.includes.parsers.preprocessors; import gplx.*; import gplx.xowa.*; import gplx.xowa.mediawiki.*; import gplx.xowa.mediawiki.includes.*; import gplx.xowa.mediawiki.includes.parsers.*; +///** +// * Expansion frame with template arguments +// * @ingroup Parser +// */ +//// @codingStandardsIgnoreStart Squiz.Classes.ValidClassName.NotCamelCaps +// extends PPFrame_Hash +class XomwPPTemplateFrame_Hash extends XomwPPFrame { // // @codingStandardsIgnoreEnd +// +// public $numberedArgs, $namedArgs, $parent; +// public $numberedExpansionCache, $namedExpansionCache; +// +// /** +// * @param Preprocessor $preprocessor +// * @param boolean|PPFrame $parent +// * @param array $numberedArgs +// * @param array $namedArgs +// * @param boolean|Title $title +// */ +// public function __construct($preprocessor, $parent = false, $numberedArgs = [], +// $namedArgs = [], $title = false +// ) { +// parent::__construct($preprocessor); +// +// this.parent = $parent; +// this.numberedArgs = $numberedArgs; +// this.namedArgs = $namedArgs; +// this.title = $title; +// $pdbk = $title ? $title.getPrefixedDBkey() : false; +// this.titleCache = $parent.titleCache; +// this.titleCache[] = $pdbk; +// this.loopCheckHash = /*clone*/ $parent.loopCheckHash; +// if ($pdbk !== false) { +// this.loopCheckHash[$pdbk] = true; +// } +// this.depth = $parent.depth + 1; +// this.numberedExpansionCache = this.namedExpansionCache = []; +// } +// +// public function __toString() { +// $s = 'tplframe{'; +// $first = true; +// $args = this.numberedArgs + this.namedArgs; +// for each ($args as $name => $value) { +// if ($first) { +// $first = false; +// } else { +// $s .= ', '; +// } +// $s .= "\"$name\":\"" . +// str_replace('"', '\\"', $value.__toString()) . '"'; +// } +// $s .= '}'; +// return $s; +// } +// +// /** +// * @throws MWException +// * @param String|int $key +// * @param String|PPNode $root +// * @param int $flags +// * @return String +// */ +// public function cachedExpand($key, $root, $flags = 0) { +// if (isset(this.parent.childExpansionCache[$key])) { +// return this.parent.childExpansionCache[$key]; +// } +// $retval = this.expand($root, $flags); +// if (!this.isVolatile()) { +// this.parent.childExpansionCache[$key] = $retval; +// } +// return $retval; +// } +// +// /** +// * Returns true if there are no arguments in this frame +// * +// * @return boolean +// */ +// public function isEmpty() { +// return !count(this.numberedArgs) && !count(this.namedArgs); +// } +// +// /** +// * @return array +// */ +// public function getArguments() { +// $arguments = []; +// for each (array_merge( +// array_keys(this.numberedArgs), +// array_keys(this.namedArgs)) as $key) { +// $arguments[$key] = this.getArgument($key); +// } +// return $arguments; +// } +// +// /** +// * @return array +// */ +// public function getNumberedArguments() { +// $arguments = []; +// for each (array_keys(this.numberedArgs) as $key) { +// $arguments[$key] = this.getArgument($key); +// } +// return $arguments; +// } +// +// /** +// * @return array +// */ +// public function getNamedArguments() { +// $arguments = []; +// for each (array_keys(this.namedArgs) as $key) { +// $arguments[$key] = this.getArgument($key); +// } +// return $arguments; +// } +// +// /** +// * @param int $index +// * @return String|boolean +// */ +// public function getNumberedArgument($index) { +// if (!isset(this.numberedArgs[$index])) { +// return false; +// } +// if (!isset(this.numberedExpansionCache[$index])) { +// # No trimming for unnamed arguments +// this.numberedExpansionCache[$index] = this.parent.expand( +// this.numberedArgs[$index], +// PPFrame::STRIP_COMMENTS +// ); +// } +// return this.numberedExpansionCache[$index]; +// } +// +// /** +// * @param String $name +// * @return String|boolean +// */ +// public function getNamedArgument($name) { +// if (!isset(this.namedArgs[$name])) { +// return false; +// } +// if (!isset(this.namedExpansionCache[$name])) { +// # Trim named arguments post-expand, for backwards compatibility +// this.namedExpansionCache[$name] = trim( +// this.parent.expand(this.namedArgs[$name], PPFrame::STRIP_COMMENTS)); +// } +// return this.namedExpansionCache[$name]; +// } +// +// /** +// * @param int|String $name +// * @return String|boolean +// */ +// public function getArgument($name) { +// $text = this.getNumberedArgument($name); +// if ($text === false) { +// $text = this.getNamedArgument($name); +// } +// return $text; +// } +// +// /** +// * Return true if the frame is a template frame +// * +// * @return boolean +// */ +// public function isTemplate() { +// return true; +// } +// +// public function setVolatile($flag = true) { +// parent::setVolatile($flag); +// this.parent.setVolatile($flag); +// } +// +// public function setTTL($ttl) { +// parent::setTTL($ttl); +// this.parent.setTTL($ttl); +// } +}