From 6e829e3f22f8b9b9e49a5ed3453a2b782a0a8b27 Mon Sep 17 00:00:00 2001 From: Ichthyostega Date: Sun, 7 Aug 2016 01:58:26 +0200 Subject: [PATCH] guard applicability by selector predicate OMG ... this can't possibly work???! --- src/lib/diff/test-mutation-target.hpp | 8 +- .../diff/tree-mutator-collection-binding.hpp | 118 ++++++++++++------ src/lib/diff/tree-mutator.hpp | 7 +- .../diff-virtualised-application-test.cpp | 2 +- .../diff/tree-mutator-binding-test.cpp | 12 +- wiki/thinkPad.ichthyo.mm | 85 ++++++++----- 6 files changed, 144 insertions(+), 88 deletions(-) diff --git a/src/lib/diff/test-mutation-target.hpp b/src/lib/diff/test-mutation-target.hpp index f820130f7..fcc19449c 100644 --- a/src/lib/diff/test-mutation-target.hpp +++ b/src/lib/diff/test-mutation-target.hpp @@ -387,7 +387,7 @@ namespace diff{ * against this internal copy. This allows to verify what's going on */ virtual void - skipSrc () override + skipSrc (GenNode const& n) override { if (pos_) { @@ -395,7 +395,7 @@ namespace diff{ ++pos_; target_.logSkip (skippedElm); } - PAR::skipSrc(); + PAR::skipSrc(n); } /** record in the test target @@ -430,8 +430,8 @@ namespace diff{ virtual bool acceptSrc (GenNode const& n) override { - bool isSrcMatch = TestWireTap::matchSrc(n); //////TODO this is wrong: we must invoke *only* our own match, but no chained match of lower layers - if (isSrcMatch) // NOTE: important to call our own method here, not the virtual function + bool isSrcMatch = pos_ and n.matches(*pos_); + if (isSrcMatch) // NOTE: important to invoke our own match here { target_.inject (move(*pos_), "acceptSrc"); ++pos_; diff --git a/src/lib/diff/tree-mutator-collection-binding.hpp b/src/lib/diff/tree-mutator-collection-binding.hpp index 3a8b8cb93..60870a18b 100644 --- a/src/lib/diff/tree-mutator-collection-binding.hpp +++ b/src/lib/diff/tree-mutator-collection-binding.hpp @@ -204,10 +204,15 @@ * causing this element to be discarded */ virtual void - skipSrc () override + skipSrc (GenNode const& n) override { - if (pos_) - ++pos_; + if (binding_.isApplicable(n)) + { + if (pos_) + ++pos_; + } + else + PAR::skipSrc (n); } /** fabricate a new element, based on @@ -218,8 +223,13 @@ virtual bool injectNew (GenNode const& n) override { - binding_.inject (binding_.construct(n)); - return true; /////////////////////////////////////////////////////////TODO with all these operations: need to invoke selector and possibly delegate to parent.... + if (binding_.isApplicable(n)) + { + binding_.inject (binding_.construct(n)); + return true; + } + else + return PAR::injectNew (n); } virtual bool @@ -233,60 +243,78 @@ virtual bool matchSrc (GenNode const& spec) override { - return pos_? binding_.matches (spec, *pos_) - : false; + if (binding_.isApplicable(spec)) + return pos_? binding_.matches (spec, *pos_) + : false; + else + return PAR::matchSrc (spec); } /** accept existing element, when matching the given spec */ virtual bool acceptSrc (GenNode const& n) override { - bool isSrcMatch = ChildCollectionMutator::matchSrc(n); //////TODO this is wrong: we must invoke *only* our own match, but no chained match of lower layers - if (isSrcMatch) // NOTE: crucial to call our own method here, not the virtual function + if (binding_.isApplicable(n)) { - binding_.inject (move(*pos_)); - ++pos_; + bool isSrcMatch = pos_ and binding_.matches (n, *pos_); + if (isSrcMatch) // NOTE: crucial to perform only our own match check here + { + binding_.inject (move(*pos_)); + ++pos_; + } + return isSrcMatch; } - return isSrcMatch; + else + return PAR::acceptSrc (n); } /** locate designated element and accept it at current position */ virtual bool findSrc (GenNode const& refSpec) override { - Iter found = binding_.search (refSpec, pos_); - if (found) + if (binding_.isApplicable(refSpec)) { - binding_.inject (move(*found)); + Iter found = binding_.search (refSpec, pos_); + if (found) + { + binding_.inject (move(*found)); + } + return found; } - return found; + else + return PAR::findSrc (refSpec); } /** repeatedly accept, until after the designated location */ virtual bool accept_until (GenNode const& spec) { - bool foundTarget = true; - if (spec.matches (Ref::END)) - for ( ; pos_; ++pos_) - binding_.inject (move(*pos_)); - else { - while (pos_ and not ChildCollectionMutator::matchSrc(spec)) - { - binding_.inject (move(*pos_)); - ++pos_; - } - if (ChildCollectionMutator::matchSrc(spec)) - { - binding_.inject (move(*pos_)); - ++pos_; - } - else - foundTarget = false; + for ( ; pos_; ++pos_) + binding_.inject (move(*pos_)); + return true; } - return foundTarget; + else + if (binding_.isApplicable(spec)) + { + bool foundTarget = true; + while (pos_ and not ChildCollectionMutator::matchSrc(spec)) + { + binding_.inject (move(*pos_)); + ++pos_; + } + if (ChildCollectionMutator::matchSrc(spec)) + { + binding_.inject (move(*pos_)); + ++pos_; + } + else + foundTarget = false; + return foundTarget; + } + else + return PAR::accept_until (spec); } /** locate element already accepted into the target sequence @@ -294,9 +322,14 @@ virtual bool assignElm (GenNode const& spec) { - Iter target_found = binding_.locate (spec); - return target_found? binding_.assign (*target_found, spec) - : false; + if (binding_.isApplicable(spec)) + { + Iter target_found = binding_.locate (spec); + return target_found? binding_.assign (*target_found, spec) + : false; + } + else + return PAR::assignElm (spec); } /** locate the designated target element and build a suitable @@ -304,9 +337,14 @@ virtual bool mutateChild (GenNode const& spec, TreeMutator::Handle targetBuff) { - Iter target_found = binding_.locate (spec); - return target_found? binding_.openSub (*target_found, spec.idi, targetBuff) - : false; + if (binding_.isApplicable(spec)) + { + Iter target_found = binding_.locate (spec); + return target_found? binding_.openSub (*target_found, spec.idi, targetBuff) + : false; + } + else + return PAR::mutateChild (spec, targetBuff); } /** verify all our pending (old) source elements where mentioned. diff --git a/src/lib/diff/tree-mutator.hpp b/src/lib/diff/tree-mutator.hpp index 59e4ddc3c..54858ea85 100644 --- a/src/lib/diff/tree-mutator.hpp +++ b/src/lib/diff/tree-mutator.hpp @@ -204,15 +204,16 @@ namespace diff{ /* ==== operation API ==== */ virtual bool - hasSrc () + hasSrc () ////////////////////////////////////TODO questionable if we need it. Can not be sensibly implemented on multiple onion-layers! { return false; // do nothing by default } - /** skip next src element and advance abstract source position */ + /** skip next src element and advance abstract source position. + * The argument shall be used to determine applicability */ virtual void - skipSrc () + skipSrc (GenNode const&) { // do nothing by default } diff --git a/tests/library/diff/diff-virtualised-application-test.cpp b/tests/library/diff/diff-virtualised-application-test.cpp index 6b059d070..e2d964389 100644 --- a/tests/library/diff/diff-virtualised-application-test.cpp +++ b/tests/library/diff/diff-virtualised-application-test.cpp @@ -137,7 +137,7 @@ namespace test{ % beta_ % gamma_ % delta_ - % join (nestedObj_, "\n......|") + % join (nestedObj_, "\n........|") % join (nestedData_) ; } diff --git a/tests/library/diff/tree-mutator-binding-test.cpp b/tests/library/diff/tree-mutator-binding-test.cpp index 5795aa2be..4f54a6a36 100644 --- a/tests/library/diff/tree-mutator-binding-test.cpp +++ b/tests/library/diff/tree-mutator-binding-test.cpp @@ -226,7 +226,7 @@ namespace test{ CHECK (target.showContent() == "γ = 3.45, α = 1"); CHECK (mutator2.hasSrc()); // next we have to clean up waste - mutator2.skipSrc(); // left behind by the findSrc() operation // skipSrc + mutator2.skipSrc (ATTRIB3); // left behind by the findSrc() operation // skipSrc CHECK (target.showContent() == "γ = 3.45, α = 1"); mutator2.injectNew (ATTRIB2); // injectNew @@ -239,7 +239,7 @@ namespace test{ // NOTE: the TestWireTap / TestMutationTarget does not enforce the attribute / children distinction! CHECK (mutator2.hasSrc()); CHECK (mutator2.matchSrc (CHILD_B)); // first child waiting in src is CHILD_B - mutator2.skipSrc(); // ...which will be skipped (and thus discarded) // skipSrc + mutator2.skipSrc (CHILD_B); // ...which will be skipped (and thus discarded) // skipSrc mutator2.injectNew (SUB_NODE); // inject a new nested sub-structure here // injectNew CHECK (mutator2.matchSrc (CHILD_B)); // yet another B-child is waiting CHECK (not mutator2.findSrc (CHILD_A)); // unsuccessful find operation won't do anything @@ -463,14 +463,14 @@ namespace test{ CHECK (mutator2.matchSrc (ATTRIB1)); // element at head of src is still ATTRIB1 (as before) CHECK (mutator2.acceptSrc (ATTRIB1)); // now pick and accept this src element // acceptSrc - mutator2.skipSrc(); // next we have to clean up waste left over by findSrc() // skipSrc + mutator2.skipSrc (ATTRIB3); // next we have to clean up waste left over by findSrc() // skipSrc mutator2.injectNew (ATTRIB2); // injectNew CHECK (mutator2.matchSrc (ATTRIB3)); CHECK (mutator2.acceptSrc (ATTRIB3)); // acceptSrc CHECK (mutator2.matchSrc (CHILD_B)); // first child waiting in src is CHILD_B - mutator2.skipSrc(); // ...which will be skipped (and thus discarded) // skipSrc + mutator2.skipSrc (CHILD_B); // ...which will be skipped (and thus discarded) // skipSrc mutator2.injectNew (SUB_NODE); // inject a nested sub-structure (implementation defined) // injectNew CHECK (mutator2.matchSrc (CHILD_B)); // yet another B-child is waiting CHECK (not mutator2.findSrc (CHILD_A)); // unsuccessful find operation won't do anything @@ -789,7 +789,7 @@ namespace test{ CHECK (mutator2.matchSrc (ATTRIB1)); // behaviour of the binding remains unaffected CHECK (mutator2.acceptSrc (ATTRIB1)); // now pick and "accept" this src element (also a NOP) // acceptSrc - mutator2.skipSrc(); // and 'skip' likewise is just not implemented for attributes // skipSrc + mutator2.skipSrc (ATTRIB1); // and 'skip' likewise is just not implemented for attributes // skipSrc CHECK ( 1 == alpha); CHECK (-1 == beta); CHECK (3.45 == gamma); // all these non-operations actually didn't change anything... @@ -807,7 +807,7 @@ namespace test{ // but since all those operations are not relevant for our attribute binding, they will be passed on // to lower binding layers. And since, moreover, there /are no lower binding layers/ in our setup, // they will just do nothing and return false - mutator2.skipSrc(); // skipSrc + mutator2.skipSrc (ATTRIB3); // skipSrc CHECK (not mutator2.injectNew (SUB_NODE));// ...no setter binding, thus no effect // injectNew CHECK (not mutator2.matchSrc (CHILD_B)); CHECK (not mutator2.acceptSrc (CHILD_B)); // acceptSrc diff --git a/wiki/thinkPad.ichthyo.mm b/wiki/thinkPad.ichthyo.mm index 7668ccf7f..3e11ada62 100644 --- a/wiki/thinkPad.ichthyo.mm +++ b/wiki/thinkPad.ichthyo.mm @@ -900,7 +900,7 @@ - + @@ -909,8 +909,9 @@ - - + + + @@ -975,10 +976,30 @@ + + + + + + +

+ of questionable use +

+

+ with multiple layers +

+ + +
+ +
+ + + @@ -2031,7 +2052,7 @@ - + @@ -2346,7 +2367,7 @@ - + @@ -2358,7 +2379,7 @@ - + @@ -2533,7 +2554,7 @@ - + @@ -4213,8 +4234,9 @@ - + + @@ -4434,8 +4456,7 @@ Client soll direkt mutatorBinding bieten

- - +
@@ -4463,8 +4484,7 @@ nicht generisch: mutatorBinding

- - +
@@ -4478,8 +4498,7 @@ Lösungsversuch: extern template

- - + @@ -4538,8 +4557,7 @@ - - +
@@ -4559,8 +4577,7 @@ intern: eingebaute initDiffApplication()

- - + @@ -4570,8 +4587,7 @@ ...wird automatisch vor Konsumieren eines Diff aufgerufen

- -
+
@@ -4583,8 +4599,7 @@ Widerspruch: TreeMutator ist Wegwerf-Objekt

- -
+
@@ -4603,8 +4618,7 @@ Lösungsversuch: doppelte Hülle

- - + @@ -4636,8 +4650,7 @@ kann daher TreeMutator konstruieren

- - +
@@ -4649,8 +4662,7 @@ ...und zwar per mutatorBinding

- -
+
@@ -4662,8 +4674,7 @@ implementiert somit initDiffApplication()

- -
+
@@ -4677,8 +4688,7 @@ TODO: Namensgebung

- - + @@ -4770,8 +4780,15 @@
- - + + + + + + + + +