Skip to content

Commit

Permalink
Do visit deduplication in our walk helpers
Browse files Browse the repository at this point in the history
  • Loading branch information
crisptrutski authored and tsmacdonald committed Feb 28, 2024
1 parent 0ee4eae commit 321fd4f
Show file tree
Hide file tree
Showing 2 changed files with 14 additions and 7 deletions.
8 changes: 3 additions & 5 deletions src/macaw/rewrite.clj
Original file line number Diff line number Diff line change
Expand Up @@ -55,12 +55,10 @@
replace-name (fn [->s]
(fn [acc ^ASTNodeAccess visitable]
(let [node (.getASTNode visitable)]
;; work around ast walker repeatedly visiting the same expressions (bug ?!)
;; also not sure why sometimes we get a phantom visitable without an underlying node
(if (or (nil? node) (contains? @seen visitable))
;; not sure why sometimes we get a phantom visitable without an underlying node
(if (nil? node)
acc
(do (vswap! seen conj visitable)
(conj acc [(node->idx-range node sql) (->s visitable)]))))))]
(conj acc [(node->idx-range node sql) (->s visitable)])))))]
(splice-replacements
sql
(mw/fold-query
Expand Down
13 changes: 11 additions & 2 deletions src/macaw/walk.clj
Original file line number Diff line number Diff line change
Expand Up @@ -17,17 +17,26 @@
(f v)
acc))

;; work around ast walker repeatedly visiting the same expressions (bug ?!)
(defn- deduplicate-visits [f]
(let [seen (volatile! #{})]
(fn [acc visitable]
(if (contains? @seen visitable)
acc
(do (vswap! seen conj visitable)
(f acc visitable))))))

(defn- update-keys-vals [m key-f val-f]
(into {} (map (fn [[k v]] [(key-f k) (val-f v)])) m))

(defn walk-query
"Walk over the query's AST, using the callbacks for their side-effects, for example to mutate the AST itself."
[parsed-query callbacks]
(let [callbacks (update-keys-vals callbacks ->callback-key preserve)]
(let [callbacks (update-keys-vals callbacks ->callback-key (comp deduplicate-visits preserve))]
(.walk (AstWalker. callbacks ::ignored) parsed-query)))

(defn fold-query
"Fold over the query's AST, using the callbacks to update the accumulator."
[parsed-query callbacks init-val]
(let [callbacks (update-keys callbacks ->callback-key)]
(let [callbacks (update-keys-vals callbacks ->callback-key deduplicate-visits)]
(.fold (AstWalker. callbacks init-val) parsed-query)))

0 comments on commit 321fd4f

Please sign in to comment.