浏览代码

refactor: add some debugging statements

Sam Jaffe 2 周之前
父节点
当前提交
6d97c85da3

+ 66 - 0
include/jvalidate/detail/debug.h

@@ -0,0 +1,66 @@
+#pragma once
+#if !defined(NDEBUG) && defined(JVALIDATE_TRACE)
+#include <iostream>
+#include <map>
+#include <source_location>
+#include <string_view>
+
+#include <jvalidate/_macro.h>
+#include <jvalidate/detail/on_block_exit.h>
+
+namespace jvalidate::detail {
+template <typename K, typename V>
+std::ostream & operator<<(std::ostream & os, std::map<K, V> const & value) {
+  os << '{';
+  std::string_view div;
+  for (auto const & [k, v] : value) {
+    os << std::exchange(div, ", ") << k << ':' << ' ' << v;
+  }
+  return os << '}';
+}
+
+template <typename V> std::ostream & operator<<(std::ostream & os, std::vector<V> const & value) {
+  os << '[';
+  std::string_view div;
+  for (auto const & v : value) {
+    os << std::exchange(div, ", ") << v;
+  }
+  return os << ']';
+}
+
+template <typename V> std::ostream & operator<<(std::ostream & os, std::set<V> const & value) {
+  os << '[';
+  std::string_view div;
+  for (auto const & v : value) {
+    os << std::exchange(div, ", ") << v;
+  }
+  return os << ']';
+}
+}
+
+namespace jvalidate::detail {
+inline size_t g_debug_trace_depth = 0;
+}
+
+#define JVALIDATE_NAME(x) JVALIDATE_CONCAT(__, JVALIDATE_CONCAT(x, __LINE__))
+
+#define JVALIDATE_DEBUG(expression)                                                                \
+  do {                                                                                             \
+    using ::jvalidate::detail::operator<<;                                                         \
+    auto JVALIDATE_NAME(here) = std::source_location::current();                                   \
+    std::string_view JVALIDATE_NAME(fname) = JVALIDATE_NAME(here).file_name();                     \
+    JVALIDATE_NAME(fname).remove_prefix(JVALIDATE_NAME(fname).find_last_of('/') + 1);              \
+    std::cerr << std::string(2 * ::jvalidate::detail::g_depth, ' ') << JVALIDATE_NAME(fname)       \
+              << ':' << JVALIDATE_NAME(here).line() << ' ' << expression << std::endl;             \
+  } while (false)
+
+#define JVALIDATE_DEBUG_INDENTED_SCOPE()                                                           \
+  ::jvalidate::detail::OnBlockExit JVALIDATE_NAME(indent_scope) =                                  \
+      (++::jvalidate::detail::g_debug_trace_depth,                                                 \
+       []() { --::jvalidate::detail::g_debug_trace_depth; })
+#else
+
+#define JVALIDATE_DEBUG(...)
+#define JVALIDATE_DEBUG_INDENTED_SCOPE()
+
+#endif

+ 2 - 0
include/jvalidate/detail/dynamic_reference_context.h

@@ -5,6 +5,7 @@
 #include <optional>
 
 #include <jvalidate/detail/anchor.h>
+#include <jvalidate/detail/debug.h>
 #include <jvalidate/detail/on_block_exit.h>
 #include <jvalidate/detail/reference.h>
 #include <jvalidate/uri.h>
@@ -42,6 +43,7 @@ public:
       return nullptr;
     }
 
+    JVALIDATE_DEBUG("scope " << source << ": " << frame);
     sources_.push_back(source);
     for (auto const & [k, v] : frame) {
       // If we have not currently registered this anchor, use the input

+ 9 - 0
include/jvalidate/detail/reference_manager.h

@@ -1,10 +1,12 @@
 #pragma once
 
+#include <ios>
 #include <map>
 #include <unordered_set>
 
 #include <jvalidate/compat/enumerate.h>
 #include <jvalidate/detail/anchor.h>
+#include <jvalidate/detail/debug.h>
 #include <jvalidate/detail/dynamic_reference_context.h>
 #include <jvalidate/detail/expect.h>
 #include <jvalidate/detail/on_block_exit.h>
@@ -166,6 +168,7 @@ public:
    * resolutions from the stack when it exits scope.
    */
   auto dynamic_scope(Reference const & ref) {
+    JVALIDATE_DEBUG("dynamic_scope " << ref);
     URI const uri =
         ref.pointer().empty() ? ref.uri() : references_.relative_to_nearest_anchor(ref).uri();
     return active_dynamic_anchors_.scope(uri, dynamic_anchors_[uri]);
@@ -228,6 +231,8 @@ public:
    */
   Reference canonicalize(Reference const & ref, Reference const & parent,
                          inout<bool> dynamic_reference) {
+    JVALIDATE_DEBUG("canonicalize " << ref << ", parent=" << parent);
+    JVALIDATE_DEBUG_INDENTED_SCOPE();
     URI const uri = [this, &ref, &parent]() {
       // If there are no URIs involed (root schema does not set "$id")
       // then we don't need to do anything clever
@@ -298,6 +303,8 @@ private:
    */
   std::optional<Reference> dynamic(URI const & uri, Reference const & ref,
                                    inout<bool> dynamic_reference) {
+    JVALIDATE_DEBUG("dynamic " << uri << ", ref=" << ref << ", dynamic=" << std::boolalpha
+                               << dynamic_reference);
     bool const anchor_is_dynamic = active_dynamic_anchors_.contains(ref.anchor());
     if (not dynamic_reference) {
       // A normal $ref to an $anchor that matches a $dynamicAnchor breaks the
@@ -433,6 +440,7 @@ private:
 
       if (Reference & dynamic = dynamic_anchors_[root.uri()][anchor];
           dynamic == Reference() || where < dynamic) {
+        JVALIDATE_DEBUG("adding $recursiveAnchor " << root.uri() << "#" << anchor << " " << where);
         dynamic = where;
       }
     }
@@ -446,6 +454,7 @@ private:
 
       if (Reference & dynamic = dynamic_anchors_[root.uri()][anchor];
           dynamic == Reference() || where < dynamic) {
+        JVALIDATE_DEBUG("adding $dynamicAnchor " << root.uri() << "#" << anchor << " " << where);
         dynamic = where;
       }
     }