From 0b21e816e39f098f33eea98fa1b1936ccac894ce Mon Sep 17 00:00:00 2001 From: Ichthyostega Date: Fri, 16 Feb 2018 04:34:45 +0100 Subject: [PATCH] LocationSolver: implement support for elided elements (#1128) when used in a pattern for matching against the UI tree, an element marked as UIC_ELIDED = "." is treated as existentially quantified. This means, we assume / verify there *is* an element at that level, but we do not care about what this element actually is. Within the implementation, the handling is similar to a wildcard, yet such a spec is not classified as a wildcard (it *is* an explicit element, just not explicitly named). The relevant consequence is that such an element matches at a leaf position, while match on wildcards on leaf positions is prohibited, to prevent arbitrary and nonsensical wildcard matches against open ended patterns. Especially we need such an existential pattern to express a rule to create elements from scratch, but within a specific window with arbitrary (but existing) perspective. --- src/gui/interact/ui-coord-resolver.cpp | 4 +++- src/gui/interact/ui-coord-resolver.hpp | 5 ++++- 2 files changed, 7 insertions(+), 2 deletions(-) diff --git a/src/gui/interact/ui-coord-resolver.cpp b/src/gui/interact/ui-coord-resolver.cpp index ab9dcc50a..3f5540725 100644 --- a/src/gui/interact/ui-coord-resolver.cpp +++ b/src/gui/interact/ui-coord-resolver.cpp @@ -129,6 +129,7 @@ namespace interact { { return patt == Symbol::ANY or patt == Symbol::EMPTY + or patt == UIC_ELIDED // "existentially quantified" or (isAnchored() and curr == res_.anchor and depth == UIC_WINDOW); }; // transitive argument: assuming res_.anchor was computed for // the same coordinate pattern used here for patch resolution @@ -153,7 +154,8 @@ namespace interact { coverage.setAt (depth,curr); // record match rsp. interpolate wildcard into output iter.expandChildren(); // next iteration will match one level down into the tree } - return patt == curr; // only direct match counts as (partial) solution + return patt == curr // direct match counts as (partial) solution + or patt == UIC_ELIDED; // existentially quantified elements also accepted }) .filter ([&](auto& iter) { diff --git a/src/gui/interact/ui-coord-resolver.hpp b/src/gui/interact/ui-coord-resolver.hpp index 3faa4632a..ab32baac1 100644 --- a/src/gui/interact/ui-coord-resolver.hpp +++ b/src/gui/interact/ui-coord-resolver.hpp @@ -550,7 +550,9 @@ namespace interact { /** establish a trivial anchorage and coverage, if possible. * @note when the UICoord contains wildcards or is incomplete, * a full resolution with backtracking is necessary to - * determine anchorage and coverage + * determine anchorage and coverage. The same is true + * when the pattern uses an elided element, since such + * an existentially quantified item must be interpolated. */ void attempt_trivialResolution() @@ -558,6 +560,7 @@ namespace interact { res_.anchor = query_.determineAnchor (this->uic_); if (not uic_.isExplicit()) return; res_.depth = query_.determineCoverage(this->uic_); + if (util::contains (this->uic_, UIC_ELIDED)) return; // existentially quantified res_.isResolved = true; }