Parcourir la source

fix: final $dynamicRef issues

Sam Jaffe il y a 1 an
Parent
commit
43b55a0fcd

+ 5 - 0
include/jvalidate/detail/context_stack.h

@@ -27,6 +27,9 @@ public:
       if (not frame.contains(k)) {
         stack.push_back(std::nullopt);
       }
+      while (stack.size() < sources_.size()) {
+        stack.push_front(std::nullopt);
+      }
     }
 
     return [this]() {
@@ -42,6 +45,8 @@ public:
     };
   }
 
+  bool contains(Key const & key) const { return data_.contains(key); }
+
   std::optional<Value> lookup(Source const & source, Key const & key) const {
     if (auto it = data_.find(key); it != data_.end()) {
       return it->second.at(index_of(source));

+ 7 - 0
include/jvalidate/detail/on_block_exit.h

@@ -10,6 +10,13 @@ public:
   OnBlockExit() = default;
   template <typename F> OnBlockExit(F && callback) : callback_(callback) {}
 
+  OnBlockExit(OnBlockExit && other) { std::swap(other.callback_, callback_); }
+
+  OnBlockExit & operator=(OnBlockExit && other) {
+    std::swap(other.callback_, callback_);
+    return *this;
+  }
+
   ~OnBlockExit() {
     if (callback_) {
       callback_();

+ 9 - 1
include/jvalidate/reference_handler.h

@@ -69,7 +69,7 @@ public:
   }
 
   detail::Reference canonicalize(detail::Reference const & ref, detail::Reference const & parent,
-                                 detail::inout<bool> dynamic_reference) const {
+                                 detail::inout<bool> dynamic_reference) {
     URI const uri = [this, &ref, &parent]() {
       if (ref.uri().empty() && parent.uri().empty()) {
         return references_.actual_parent_uri(parent);
@@ -93,7 +93,15 @@ public:
       return base.parent() / uri;
     }();
 
+    // TODO(samjaffe): Clean up this block too...
     URI const dyn_uri = ref.uri().empty() ? ref.uri() : uri;
+
+    detail::OnBlockExit scope;
+    if (not ref.uri().empty() && dynamic_reference &&
+        active_dynamic_anchors_.contains(ref.anchor())) {
+      scope = dynamic_scope(detail::Reference(dyn_uri));
+    }
+
     if (std::optional dynamic = active_dynamic_anchors_.lookup(dyn_uri, ref.anchor())) {
       if (dynamic_reference) {
         return *dynamic;