Допустим, у меня есть макрос, который заменяет все вхождения 'transact' на '\', вот так:
(defmacro transmuting-macro [& body]
(let [transmuted-body (clojure.walk/postwalk
#(if (and (list? %) (= 'transact (first %)))
(-> % rest (conj `/)) %) body)]
transmuted-body))
Теперь я могу сделать это:
(defn generate-error []
(transmuting-macro (let [x 1
b (transact 1 3)]
(transact 3 0))))
Но трассировка стека исключения не может отследить, что находится внутри, она останавливается при вызове макроса (строка 2), а затем сразу же переходит к делению без предоставления какого-либо значащего номера строки (в данном случае строка 4).
Если я поставлю просто body
вместо transmuted-body
в последней строке определения макроса стек сохраняется. Итак, я считаю, что где-то есть скрытая информация, которая позволяет компилятору анализировать некоторые макросы, но не другие. Я попытался посмотреть на мета, а также специальные переменные & form и & env, но безрезультатно. Поскольку моя трансмутация ничего не меняет в номерах строк, достаточно просто скопировать эту информацию. Как заставить это работать?