宏扩展默认语法错误,将 clojure 1.9 升级到 1.12

问题描述 投票:0回答:1

从 clojure 1.9 升级到 clojure 1.12 时出现以下错误

Syntax error macroexpanding defact at (up/lib/pvm/fact.clj:23:18).
Don't know how to create ISeq from: clojure.lang.Symbol

有问题的代码是这样的:

(defmacro defact

  ([name fields] (defact &form &env name nil fields nil nil))

  ([name doc-string? fields] (defact &form &env name doc-string? fields nil nil))

  ([name fields meta-key meta-val] (defact &form &env name nil fields meta-key meta-val))

  ([name doc-string? fields meta-key meta-val & meta-data]
   (let [gname name
         kfields (into [] (map keyword fields))
         classword (str *ns* "/" gname)
         md-list (when (and meta-key meta-val)
                   [meta-key meta-val])
         md-list (if meta-data
                   (concat md-list meta-data)
                   md-list)
         md (apply hash-map md-list)
         md (if (empty? md) nil md)
         doc (or doc-string? (str "Positional factory function for map " classword "."))]
     `(do
        (def ~(symbol (str gname '-meta)) ~md)
        (def ~(symbol gname) ~classword)
        (defn ~(symbol (str gname '?))
          [m#]
          (= ~classword (:fact-type m#)))

        (defn ~(symbol (str 'map-> gname))
          ~doc
          ([m#]
           (with-meta
             (assoc m# :fact-type ~classword)
             ~md)))

        (defn ~(symbol (str '-> gname))
          ~doc
          ([& m#]
           (if (= ~(count kfields) (count m#))
             (with-meta
               (assoc
                 (zipmap ~kfields m#)
                 :fact-type ~classword)
               ~md)
             (throw (ex-info "Incorrect number of arguments" {:got (count m#) :desired ~(count kfields)}))))))))

   )

这是非常旧的遗留代码,我们需要升级 clojure 版本。由于某种原因,我仍然可以构建

uberjar
,但它在
lein check
期间失败,这是我们构建过程的一部分。

我认为这个问题与 1.9.0-alpha3 中的更改有关,但我在推荐的解决方案中找不到任何内容。这也是我们无法摆脱的低级代码。任何帮助将不胜感激

我尝试过删除和移动各种参数,但是我对 clojure 不太熟悉,这似乎利用了我不完全理解的语言的一些功能,而且我似乎找不到资源。

完整报告:

{:clojure.main/message
 "Syntax error macroexpanding defact at (up/lib/pvm/fact.clj:23:18).\nDon't know how to create ISeq from: clojure.lang.Symbol\n",
 :clojure.main/triage
 {:clojure.error/phase :macro-syntax-check,
  :clojure.error/line 23,
  :clojure.error/column 18,
  :clojure.error/source "fact.clj",
  :clojure.error/symbol defact,
  :clojure.error/path "up/lib/pvm/fact.clj",
  :clojure.error/class java.lang.IllegalArgumentException,
  :clojure.error/cause
  "Don't know how to create ISeq from: clojure.lang.Symbol"},
 :clojure.main/trace
 {:via
  [{:type clojure.lang.Compiler$CompilerException,
    :message
    "Syntax error macroexpanding defact at (up/lib/pvm/fact.clj:23:18).",
    :data
    {:clojure.error/phase :macro-syntax-check,
     :clojure.error/line 23,
     :clojure.error/column 18,
     :clojure.error/source "up/lib/pvm/fact.clj",
     :clojure.error/symbol defact},
    :at [clojure.lang.Compiler macroexpand1 "Compiler.java" 7533]}
   {:type java.lang.IllegalArgumentException,
    :message "Don't know how to create ISeq from: clojure.lang.Symbol",
    :at [clojure.lang.RT seqFrom "RT.java" 577]}],
  :trace
  [[clojure.lang.RT seqFrom "RT.java" 577]
   [clojure.lang.RT seq "RT.java" 557]
   [clojure.core$seq__5484 invokeStatic "core.clj" 139]
   [clojure.core$map$fn__5952 invoke "core.clj" 2763]
   [clojure.lang.LazySeq force "LazySeq.java" 50]
   [clojure.lang.LazySeq realize "LazySeq.java" 89]
   [clojure.lang.LazySeq seq "LazySeq.java" 106]
   [clojure.lang.RT seq "RT.java" 555]
   [clojure.core$seq__5484 invokeStatic "core.clj" 139]
   [clojure.core.protocols$seq_reduce invokeStatic "protocols.clj" 24]
   [clojure.core.protocols$fn__8258 invokeStatic "protocols.clj" 74]
   [clojure.core.protocols$fn__8258 invoke "protocols.clj" 74]
   [clojure.core.protocols$fn__8199$G__8194__8212
    invoke
    "protocols.clj"
    13]
   [clojure.core$reduce invokeStatic "core.clj" 6965]
   [clojure.core$into invokeStatic "core.clj" 7038]
   [clojure.core$into invoke "core.clj" 7029]
   [up.lib.pvm.fact$defact invokeStatic "fact.clj" 31]
   [up.lib.pvm.fact$defact doInvoke "fact.clj" 6]
   [clojure.lang.RestFn applyTo "RestFn.java" 175]
   [clojure.lang.Var applyTo "Var.java" 707]
   [clojure.lang.Compiler macroexpand1 "Compiler.java" 7516]
   [clojure.lang.Compiler analyzeSeq "Compiler.java" 7607]
   [clojure.lang.Compiler analyze "Compiler.java" 7312]
   [clojure.lang.Compiler analyze "Compiler.java" 7268]
   [clojure.lang.Compiler$BodyExpr$Parser parse "Compiler.java" 6640]
   [clojure.lang.Compiler$FnMethod parse "Compiler.java" 5982]
   [clojure.lang.Compiler$FnExpr parse "Compiler.java" 4544]
   [clojure.lang.Compiler analyzeSeq "Compiler.java" 7619]
   [clojure.lang.Compiler analyze "Compiler.java" 7312]
   [clojure.lang.Compiler analyzeSeq "Compiler.java" 7609]
   [clojure.lang.Compiler analyze "Compiler.java" 7312]
   [clojure.lang.Compiler access$200 "Compiler.java" 43]
   [clojure.lang.Compiler$DefExpr$Parser parse "Compiler.java" 589]
   [clojure.lang.Compiler analyzeSeq "Compiler.java" 7621]
   [clojure.lang.Compiler analyze "Compiler.java" 7312]
   [clojure.lang.Compiler analyze "Compiler.java" 7268]
   [clojure.lang.Compiler eval "Compiler.java" 7695]
   [clojure.lang.Compiler eval "Compiler.java" 7680]
   [clojure.lang.Compiler load "Compiler.java" 8157]
   [clojure.lang.RT loadResourceScript "RT.java" 401]
   [clojure.lang.RT loadResourceScript "RT.java" 392]
   [clojure.lang.RT load "RT.java" 479]
   [clojure.lang.RT load "RT.java" 444]
   [clojure.core$load$fn__6929 invoke "core.clj" 6189]
   [clojure.core$load invokeStatic "core.clj" 6188]
   [clojure.core$load doInvoke "core.clj" 6172]
   [clojure.lang.RestFn invoke "RestFn.java" 411]
   [user$eval52338$fn__52349
    invoke
    "form-init13786016343757455939.clj"
    1]
   [user$eval52338 invokeStatic "form-init13786016343757455939.clj" 1]
   [user$eval52338 invoke "form-init13786016343757455939.clj" 1]
   [clojure.lang.Compiler eval "Compiler.java" 7691]
   [clojure.lang.Compiler eval "Compiler.java" 7681]
   [clojure.lang.Compiler load "Compiler.java" 8157]
   [clojure.lang.Compiler loadFile "Compiler.java" 8095]
   [clojure.main$load_script invokeStatic "main.clj" 476]
   [clojure.main$init_opt invokeStatic "main.clj" 478]
   [clojure.main$init_opt invoke "main.clj" 478]
   [clojure.main$initialize invokeStatic "main.clj" 509]
   [clojure.main$null_opt invokeStatic "main.clj" 543]
   [clojure.main$null_opt invoke "main.clj" 540]
   [clojure.main$main invokeStatic "main.clj" 665]
   [clojure.main$main doInvoke "main.clj" 617]
   [clojure.lang.RestFn applyTo "RestFn.java" 140]
   [clojure.lang.Var applyTo "Var.java" 707]
   [clojure.main main "main.java" 40]],
  :cause "Don't know how to create ISeq from: clojure.lang.Symbol",
  :phase :macro-syntax-check}}

我将第一个调用修改为:

  ([name fields]
    (println (str "defact: " name "---" fields))
    (defact &form &env name nil fields nil nil))

当我运行服务器时,会打印以下内容:

defact: BasicSetReq []
defact: BasicSetResp [docs-map]
clojure upgrade leiningen
1个回答
0
投票

语法错误是由于

&form
&env
以及宏的重载方式造成的。重载函数调用:

  ([name fields] (defact &form &env name nil fields nil nil))

  ([name doc-string? fields] (defact &form &env name doc-string? fields nil nil))

  ([name fields meta-key meta-val] (defact &form &env name nil fields meta-key meta-val))

需要更改为:

  ([name fields] `(defact ~name nil ~fields nil nil))

  ([name doc-string? fields] `(defact ~name ~doc-string? ~fields nil nil))

  ([name fields meta-key meta-val] `(defact ~name nil ~fields ~meta-key ~meta-val))
© www.soinside.com 2019 - 2024. All rights reserved.