|
| 1 | +(ns marick.midje |
| 2 | + (:require [clj-kondo.hooks-api :as hooks] |
| 3 | + [clojure.string :as string])) |
| 4 | + |
| 5 | +(def arrows '#{=> |
| 6 | + =not=> |
| 7 | + =deny=> |
| 8 | + =expands-to=> |
| 9 | + =future=> |
| 10 | + =contains=> |
| 11 | + =streams=> |
| 12 | + =throws=> |
| 13 | + =test=> |
| 14 | + =throw-parse-exception=>}) |
| 15 | + |
| 16 | +(defn ^:private let-form [body bindings] |
| 17 | + (let [new-bindings (vec (reduce (fn [acc i] |
| 18 | + (concat acc [i (hooks/token-node 'identity)])) |
| 19 | + [] bindings))] |
| 20 | + (hooks/list-node |
| 21 | + [(hooks/token-node 'let) |
| 22 | + (hooks/vector-node new-bindings) |
| 23 | + body]))) |
| 24 | + |
| 25 | +(defn ^:private do-form [forms] |
| 26 | + (hooks/list-node |
| 27 | + (concat [(hooks/token-node 'do)] |
| 28 | + forms))) |
| 29 | + |
| 30 | +(defn ^:private table-variable? [node] |
| 31 | + (let [sexpr (hooks/sexpr node)] |
| 32 | + (and (symbol? sexpr) |
| 33 | + (string/starts-with? (str sexpr) "?")))) |
| 34 | + |
| 35 | +(defn ^:private tabular-node [first-bindings bindings body] |
| 36 | + (if (hooks/vector-node? first-bindings) |
| 37 | + {:node (->> (hooks/sexpr first-bindings) |
| 38 | + (map hooks/token-node) |
| 39 | + (let-form body))} |
| 40 | + {:node (->> bindings |
| 41 | + (filter table-variable?) |
| 42 | + (let-form body))})) |
| 43 | + |
| 44 | +(defn ^:private handle-fact-outside-tabular [children arrow] |
| 45 | + (let [body (do-form children) |
| 46 | + bindings (->> children |
| 47 | + (drop-while #(not (= arrow %))) |
| 48 | + rest |
| 49 | + (drop 1))] |
| 50 | + (tabular-node (first bindings) bindings body))) |
| 51 | + |
| 52 | +(defn fact-tabular [fact vec-bindings bindings] |
| 53 | + (let [body (do-form (cons fact bindings))] |
| 54 | + (tabular-node vec-bindings (cons vec-bindings bindings) body))) |
| 55 | + |
| 56 | +(defn ^:private handle-fact-inside-tabular [children] |
| 57 | + (if (hooks/string-node? (first children)) |
| 58 | + (let [[_name fact vec-bindings & bindings] children] |
| 59 | + (fact-tabular fact vec-bindings bindings)) |
| 60 | + (let [[fact vec-bindings & bindings] children] |
| 61 | + (fact-tabular fact vec-bindings bindings)))) |
| 62 | + |
| 63 | +(defn tabular [{:keys [node]}] |
| 64 | + (let [children (rest (:children node)) |
| 65 | + fact-outside (first (filter #(contains? arrows (hooks/sexpr %)) children))] |
| 66 | + (if fact-outside |
| 67 | + (handle-fact-outside-tabular children fact-outside) |
| 68 | + (handle-fact-inside-tabular children)))) |
0 commit comments