Clojure 2024状态调查!中分享您的想法。

欢迎!请查看关于页面,以了解更多关于此网站如何工作的信息。

0
tools.analyzer
clojure.tools.analyzer.query-test自2015年11月3日起未能通过测试,它从未在CI中运行。

git bisect确定提交a61b1699c15911d17f834745521a9837a8916eec引入了此错误。

我检查了CI,最新的构建没有执行query-test,可能是因为找不到datomic.Datom。
请见https://build.clojure.org/job/tools.analyzer/728/console

预期

(let [ast (ast/prewalk (ast (defn x [] "misplaced docstring" 1))
                   index-vector-nodes)]
  (q '[:find ?docstring
       :where
      [?def :op :def]
      [?def :init ?fn]
      [?fn :methods ?method]
      [?method :body ?body]
      [?body :statements ?statement]
      [?statement :val ?docstring]
      [?statement :type :string]
      [?statement :idx 0]]
     [ast]))
#{["misplaced docstring"]}


实际


(let [ast (ast/prewalk (ast (defn x [] "misplaced docstring" 1))
                   index-vector-nodes)]
  (q '[:find ?docstring
       :where
      [?def :op :def]
      [?def :init ?fn]
      [?fn :methods ?method]
      [?method :body ?body]
      [?body :statements ?statement]
      [?statement :val ?docstring]
      [?statement :type :string]
      [?statement :idx 0]]
     [ast]))
#{}


完整repl重现

(require
  '[clojure.tools.analyzer :as ana]
  '[clojure.tools.analyzer.ast :as ast]
  '[clojure.tools.analyzer.jvm :as ana.jvm]
  '[clojure.tools.analyzer.env :refer [with-env]]
  '[clojure.tools.analyzer.ast :refer :all]
  '[clojure.test :refer [deftest is]]
  '[clojure.tools.analyzer.ast.query :refer [q]]
  '[clojure.tools.analyzer.ast :as ast]
  '[clojure.tools.analyzer.utils :refer [compile-if]]
  '[clojure.tools.analyzer.passes.index-vector-nodes :refer [index-vector-nodes]]
  '[clojure.tools.analyzer.utils :refer [resolve-sym]])
(require '[clojure.tools.analyzer.passes.elide-meta :refer [elides elide-meta]])

(ns-unmap 'user 'macroexpand-1)




(defn desugar-host-expr [[op & expr :as form]]
  (if (symbol? op)
    (let [opname (name op)]
      (cond

        (= (first opname) \.) ; (.foo bar ..)
        (let [[target & args] expr
              args (list* (symbol (subs opname 1)) args)]
          (with-meta (list '. target (if (= 1 (count args)) ;; we don't know if (.foo bar) ia
                                       (first args) args)) ;; a method call or a field access
                     (meta form)))

        (= (last opname) \.) ;; (class. ..)
        (with-meta (list* 'new (symbol (subs opname 0 (dec (count opname)))) expr)
                   (meta form))

        :else 表单))
    表单))

(defn macroexpand-1 [表单 环境]
  (if (seq? 表单)
    (let [操作 (first 表单)]
      (if (ana/specials 操作)
        表单
          (let [v (resolve-sym 操作 环境)]
            (if (and (not (-> 环境 :locals (get 操作))) ;; locals cannot be macros
                   (:macro (meta v)))
            (apply v 表单 环境 (rest 表单)) ; (m &form &env & args)
            (desugar-host-expr 表单)))))
    表单))

(defmacro foo [] 1)

(def e {:context    :ctx/expr
        :locals     {}
        :ns         'user})

(def e1 (atom {:namespaces {'user         {:mappings (into (ns-map 'clojure.core)
                                                           {'foo '#'foo})
                                           :aliases  {}
                                           :ns       'user}
                       'clojure.core {:mappings (ns-map 'clojure.core)
                                           :aliases {}
                                           :ns       'clojure.core}}}))
(defmacro ast [表单]
  `(binding [ana/macroexpand-1 macroexpand-1
             ana/create-var    ~(fn [sym 环境]
                                  (doto (intern (:ns 环境) sym)
                                    (reset-meta! (meta sym))))
             ana/parse         ana/-parse
             ana/var?          ~var?
             elides            {:all #{:line :column :file :source-span}}]
     (with-env e1
               (postwalk (ana/analyze '~表单 e) elide-meta))))

(defmacro mexpand [表单]
  `(with-env e1
             (macroexpand-1 '~表单 e)))

(let [ast (ast/prewalk (ast (defn x [] "misplaced docstring" 1))
                   index-vector-nodes)]
  (q '[:find ?docstring
       :where
      [?def :op :def]
      [?def :init ?fn]
      [?fn :methods ?method]
      [?method :body ?body]
      [?body :statements ?statement]
      [?statement :val ?docstring]
      [?statement :type :string]
      [?statement :idx 0]]
     [ast]))


数据逻辑查询似乎仍然有效。


(let [ast (ast/prewalk (ast (defn x [] "misplaced docstring" 1))
                   index-vector-nodes)]
  (q '[:find ?fn
       :where
      [?def :op :def]
       [?def :init ?fn]]
     [ast]))

#{[:op :with-meta, :env {:context :ctx/expr, :locals {}, :ns user}, :form (fn*([] "misplaced docstring" 1)), :meta {:op :map, :env {:context :ctx/expr, :locals {}, :ns user}, :keys [{:op :const, :env {:context :ctx/expr, :locals {}, :ns user}, :type :keyword, :literal? true, :val :rettag, :form :rettag, :idx 0}], :vals [{:op :const, :env {:context :ctx/expr, :locals {}, :ns user}, :type :nil, :literal? true, :val nil, :form nil, :idx 0}], :form {:rettag nil}, :children [:keys :vals]}, :expr {:op :fn, :env {:context :ctx/expr, :locals {}, :ns user}, :form (fn*([] "misplaced docstring" 1)), :variadic? false, :max-fixed-arity 0, :methods [{:children [:params :body], :loop-id loop_4101, :params [], :fixed-arity 0, :op :fn-method, :env {:context :ctx/expr, :locals {}, :ns user, :once false}, :variadic? false, :form ([] "misplaced docstring" 1)), :idx 0, :body {:op :do, :env {:context :ctx/return, :locals {}, :ns user, :once false, :loop-id loop_4101, :loop-locals 0}, :form (do "misplaced docstring" 1), :statements [{:op :const, :env {:context :ctx/statement, :locals {}, :ns user, :once false, :loop-id loop_4101, :loop-locals 0}, :type :string, :literal? true, :val "misplaced docstring", :form "misplaced docstring", :idx 0}], :ret {:op :const, :env {:context :ctx/return, :locals {}, :ns user, :once false, :loop-id loop_4101, :loop-locals 0}, :type :number, :literal? true, :val 1, :form 1}, :children [:statements :ret], :body? true}}], :once false, :children [:methods]}, :children [:meta :expr], :raw-forms ((clojure.core/fn([] "misplaced docstring" 1)))}]

2个答案

0

评论者:jlane

清理了工单。

0
参考资料:https://clojure.atlassian.net/browse/TANAL-129 (由 jlane 报告)
...