Inner-tracing instrumenter built on tools.analyzer.jvm.
Instead of re-reading source and hand-rewriting raw forms, this analyzes a traced function's source into a typed AST and re-emits it with capturing calls wrapped around its sub-expressions. Because macros and special forms are already expanded and enumerable in the AST, there's no per-macro special-casing
Two facts the analyzer hands us for free do the heavy lifting the legacy code reinvents by hand:
:raw-forms recovers each node's surface syntax ((+ a b), not the
lowered clojure.lang.Numbers/add), so captures show the user's code.:env marks tail position and :op marks recur, so we know exactly what
must not be wrapped to keep recur legal.Inner-tracing instrumenter built on `tools.analyzer.jvm`. Instead of re-reading source and hand-rewriting raw forms, this analyzes a traced function's source into a typed AST and re-emits it with capturing calls wrapped around its sub-expressions. Because macros and special forms are already expanded and enumerable in the AST, there's no per-macro special-casing - the thing that made the old rewriter fragile. Two facts the analyzer hands us for free do the heavy lifting the legacy code reinvents by hand: - `:raw-forms` recovers each node's *surface* syntax (`(+ a b)`, not the lowered `clojure.lang.Numbers/add`), so captures show the user's code. - `:env` marks tail position and `:op` marks `recur`, so we know exactly what must not be wrapped to keep `recur` legal.
The :children atom of the current inner-trace parent node, or nil when we're
not (yet) inside an inner-trace scope for this call.
The `:children` atom of the current inner-trace parent node, or nil when we're not (yet) inside an inner-trace scope for this call.
(analyze-in-ns ns-sym form)Analyze FORM to a tools.analyzer.jvm AST as if read in NS-SYM.
Analyze FORM to a `tools.analyzer.jvm` AST as if read in NS-SYM.
(capture form nm thunk)Record the sub-expression FORM (its surface syntax) named NM while evaluating THUNK, then return THUNK's value. Attaches a node under the current parent and binds itself as the parent for nested captures. Re-raises any exception after recording it, so the traced code's control flow (try/catch, and callers) is preserved exactly.
Record the sub-expression FORM (its surface syntax) named NM while evaluating THUNK, then return THUNK's value. Attaches a node under the current parent and binds itself as the parent for nested captures. Re-raises any exception after recording it, so the traced code's control flow (try/catch, and callers) is preserved exactly.
(composed-tracer-fn m _)Build the traced replacement for an inner-traced var: instrument it, then wrap it with the shallow tracer that records the call itself.
Build the traced replacement for an inner-traced var: instrument it, then wrap it with the shallow tracer that records the call itself.
(defn->fn-form src ns-sym)Pull the (fn* ...) form out of a defn source form, macroexpanded in NS-SYM.
Pull the `(fn* ...)` form out of a `defn` source form, macroexpanded in NS-SYM.
(inner-root-children)The children atom the top-level captures of a traced call attach to: the outer (shallow) trace node for this call. Nil when there's nothing to attach to - recording suppressed, or no outer parent - in which case captures pass through.
The children atom the top-level captures of a traced call attach to: the outer (shallow) trace node for this call. Nil when there's nothing to attach to - recording suppressed, or no outer parent - in which case captures pass through.
(inner-tracer {:keys [qual-sym ns']})Produce an inner-traced replacement for the function named by :qual-sym by analyzing its source, instrumenting the AST, and evaluating the result back in its namespace.
Produce an inner-traced replacement for the function named by :qual-sym by analyzing its source, instrumenting the AST, and evaluating the result back in its namespace.
(instrument ast)Turn a function AST into an evaluable, instrumented fn form: wrap each capturable sub-expression bottom-up, then emit. Emission is non-hygienic so the function's own (already-valid) local names are preserved consistently between the wrappers and the code they wrap.
Turn a function AST into an evaluable, instrumented fn form: wrap each capturable sub-expression bottom-up, then emit. Emission is non-hygienic so the function's own (already-valid) local names are preserved consistently between the wrappers and the code they wrap.
cljdoc builds & hosts documentation for Clojure/Script libraries
| Ctrl+k | Jump to recent docs |
| ← | Move to previous article |
| → | Move to next article |
| Ctrl+/ | Jump to the search field |