|
1 | 1 | (ns nextjournal.clerk.analyzer
|
2 | 2 | {:nextjournal.clerk/no-cache true}
|
3 |
| - (:refer-clojure :exclude [hash read-string]) |
| 3 | + (:refer-clojure :exclude [hash]) |
4 | 4 | (:require [babashka.fs :as fs]
|
5 |
| - [edamame.core :as edamame] |
6 | 5 | [clojure.core :as core]
|
7 | 6 | [clojure.java.io :as io]
|
8 | 7 | [clojure.set :as set]
|
9 | 8 | [clojure.string :as str]
|
10 |
| - [clojure.tools.reader :as tools.reader] |
11 | 9 | [clojure.tools.analyzer :as ana]
|
12 | 10 | [clojure.tools.analyzer.ast :as ana-ast]
|
13 | 11 | [clojure.tools.analyzer.jvm :as ana-jvm]
|
|
85 | 83 |
|
86 | 84 | #_(rewrite-defcached '(nextjournal.clerk/defcached foo :bar))
|
87 | 85 |
|
88 |
| -(defn auto-resolves [ns] |
89 |
| - (as-> (ns-aliases ns) $ |
90 |
| - (assoc $ :current (ns-name *ns*)) |
91 |
| - (zipmap (keys $) |
92 |
| - (map ns-name (vals $))))) |
93 |
| - |
94 |
| -#_(auto-resolves (find-ns 'nextjournal.clerk.parser)) |
95 |
| -#_(auto-resolves (find-ns 'cards)) |
96 |
| - |
97 |
| -(defn read-string [s] |
98 |
| - (edamame/parse-string s {:all true |
99 |
| - :syntax-quote {:resolve-symbol tools.reader/resolve-symbol} |
100 |
| - :readers *data-readers* |
101 |
| - :read-cond :allow |
102 |
| - :regex #(list `re-pattern %) |
103 |
| - :features #{:clj} |
104 |
| - :end-location false |
105 |
| - :row-key :line |
106 |
| - :col-key :column |
107 |
| - :auto-resolve (auto-resolves (or *ns* (find-ns 'user)))})) |
108 |
| - |
109 |
| -#_(read-string "(ns rule-30 (:require [nextjournal.clerk.viewer :as v]))") |
110 |
| - |
111 | 86 | (defn unresolvable-symbol-handler [ns sym ast-node]
|
112 | 87 | ast-node)
|
113 | 88 |
|
|
297 | 272 | (filter (comp #{:code} :type)
|
298 | 273 | blocks)))))
|
299 | 274 |
|
300 |
| -(defn get-block-id [!id->count {:as block :keys [var form type doc]}] |
301 |
| - (let [id->count @!id->count |
302 |
| - id (if var |
303 |
| - var |
304 |
| - (let [hash-fn #(-> % nippy/fast-freeze sha1-base58)] |
305 |
| - (symbol (str *ns*) |
306 |
| - (case type |
307 |
| - :code (str "anon-expr-" (hash-fn (cond-> form (instance? clojure.lang.IObj form) (with-meta {})))) |
308 |
| - :markdown (str "markdown-" (hash-fn doc))))))] |
309 |
| - (swap! !id->count update id (fnil inc 0)) |
310 |
| - (if (id->count id) |
311 |
| - (symbol (str *ns*) (str (name id) "#" (inc (id->count id)))) |
312 |
| - id))) |
313 |
| - |
314 | 275 | (defn ^:private internal-proxy-name?
|
315 | 276 | "Returns true if `sym` represents a var name interned by `clojure.core/proxy`."
|
316 | 277 | [sym]
|
|
377 | 338 | (analyze-doc {:doc? true} doc))
|
378 | 339 | ([{:as state :keys [doc?]} doc]
|
379 | 340 | (binding [*ns* *ns*]
|
380 |
| - (let [!id->count (atom {})] |
| 341 | + (let [add-block-id (partial parser/add-block-id (atom {}))] |
381 | 342 | (cond-> (reduce (fn [{:as state notebook-ns :ns} {:as block :keys [type text loc]}]
|
382 | 343 | (if (not= type :code)
|
383 |
| - (update state :blocks conj (assoc block :id (get-block-id !id->count block))) |
384 |
| - (let [form (try (read-string text) |
385 |
| - (catch Exception e |
386 |
| - (throw (ex-info (str "Clerk analysis failed reading block: " |
387 |
| - (ex-message e)) |
388 |
| - {:block block |
389 |
| - :file (:file doc)} |
390 |
| - e)))) |
391 |
| - form+loc (cond-> form |
392 |
| - (instance? clojure.lang.IObj form) |
393 |
| - (vary-meta merge (cond-> loc |
394 |
| - (:file doc) (assoc :clojure.core/eval-file |
395 |
| - (str (cond-> (:file doc) |
396 |
| - (instance? java.net.URL (:file doc)) extract-file)))))) |
397 |
| - {:as analyzed :keys [ns-effect?]} (cond-> (analyze form+loc) |
398 |
| - (:file doc) (assoc :file (:file doc))) |
399 |
| - _ (when ns-effect? ;; needs to run before setting doc `:ns` via `*ns*` |
400 |
| - (eval form)) |
401 |
| - block-id (get-block-id !id->count (merge analyzed block)) |
402 |
| - analyzed (assoc analyzed :id block-id)] |
403 |
| - |
| 344 | + (update state :blocks conj (add-block-id block)) |
| 345 | + (let [{:as form-analysis :keys [ns-effect? form]} (cond-> (analyze (:form block)) |
| 346 | + (:file doc) (assoc :file (:file doc))) |
| 347 | + block+analysis (add-block-id (merge block form-analysis))] |
| 348 | + (when ns-effect? ;; needs to run before setting doc `:ns` via `*ns*` |
| 349 | + (eval form)) |
404 | 350 | (-> state
|
405 |
| - (store-info analyzed) |
406 |
| - (track-var->block+redefs analyzed) |
407 |
| - (update :blocks conj (-> block |
408 |
| - (merge (dissoc analyzed :deps :no-cache? :ns-effect?)) |
409 |
| - (cond-> |
410 |
| - (parser/ns? form) (assoc :ns? true) |
411 |
| - doc? (assoc :text-without-meta (parser/text-with-clerk-metadata-removed text (ns-resolver notebook-ns)))))) |
412 |
| - (cond-> |
413 |
| - (and doc? (not (contains? state :ns))) |
414 |
| - (merge (parser/->doc-settings form) {:ns *ns*})))))) |
| 351 | + (store-info block+analysis) |
| 352 | + (track-var->block+redefs block+analysis) |
| 353 | + (update :blocks conj (cond-> (dissoc block+analysis :deps :no-cache? :ns-effect?) |
| 354 | + (parser/ns? form) (assoc :ns? true) |
| 355 | + doc? (assoc :text-without-meta (parser/text-with-clerk-metadata-removed text (ns-resolver notebook-ns))))))))) |
415 | 356 |
|
416 | 357 | (-> state
|
417 | 358 | (cond-> doc? (merge doc))
|
|
421 | 362 | (:blocks doc))
|
422 | 363 |
|
423 | 364 | true (dissoc :doc?)
|
424 |
| - doc? (-> parser/add-block-settings |
425 |
| - parser/add-open-graph-metadata |
426 |
| - parser/filter-code-blocks-without-form)))))) |
| 365 | + doc? parser/filter-code-blocks-without-form))))) |
427 | 366 |
|
428 |
| -#_(let [parsed (nextjournal.clerk.parser/parse-clojure-string "clojure.core/dec")] |
| 367 | +#_(let [parsed (parser/parse-clojure-string "clojure.core/dec")] |
429 | 368 | (build-graph (analyze-doc parsed)))
|
430 | 369 |
|
431 | 370 | (defonce !file->analysis-cache
|
|
603 | 542 | analyze-doc-deps
|
604 | 543 | set-no-cache-on-redefs
|
605 | 544 | make-deps-inherit-no-cache
|
606 |
| - (dissoc :analyzed-file-set :counter)))))) |
| 545 | + (dissoc :analyzed-file-set :counter)))))) |
607 | 546 |
|
608 | 547 | (comment
|
609 | 548 | (reset! !file->analysis-cache {})
|
|
0 commit comments