欢迎在 2024 年 Clojure 调查问卷! 中分享您的看法。

欢迎!有关如何使用本网站的更多信息,请参阅 关于 页面。

0 投票
ClojureScript

如果为一个 JAR 文件中的代码发出分析警告,警告信息将包括 AOT 缓存路径。

例如,使用以下代码:

`
(ns foo.core)

(inc "a")
`

在 {{foo.jar}} 中加载此代码会导致包含 AOT 缓存路径的信息的诊断

WARNING: cljs.core/+, 所有参数必须是数字,但得到了 [string number] 而不是。在行 3 /Users/mfikes/.cljs/.aot_cache/1.10.126/47C5358/foo/core.cljs

在这种情况下,可能最好只指示类路径相对于的文件名

WARNING: cljs.core/+, 所有参数必须是数字,但得到了 [string number] 而不是。在行 3 @/foo/core.cljs

如果可能的话,甚至可以使用类似这样的 JAR 文件 URL

WARNING: cljs.core/+, 所有参数必须是数字,但得到了 [string number] 而不是。在行 3 jar:file:///foo.jar!/foo/core.cljs

要重现该问题,首先使用以下命令创建 {{foo.jar}},将 {{foo.core}} 命名空间放在 {{foo/core.cljs}} 中

jar cvf foo.jar foo

然后使用 1.10.126 uberjar(在此处重命名为 {{cljs-1.10.126.jar}})来启动 Node REPL

java -cp cljs-1.10.126.jar:foo.jar clojure.main -m cljs.repl.node

然后执行

(require 'foo.core)

要 Seeing"What you get with 1.9.946,删除 {{.cljs_node_repl}} 目录,并使用 1.9.946 uberjar(在此处重命名为 {{cljs-1.9.946.jar}})

java -cp cljs-1.9.946.jar:foo.jar clojure.main -m cljs.repl.node

在这种情况下,{{(require 'foo.core)}} 仍然引用本地缓存目录

WARNING: cljs.core/+, 所有参数必须是数字,但得到了 [string number] 而不是。在行 3 .cljs_node_repl/foo/core.cljs

但这似乎比暴露共享 AOT 缓存路径的问题要小。

3 答案

0 投票
_由:mfikes_做出的评论

附件补丁

修订了几个可编译的扩展(到 {{File}}、{{URL}} 和 {{String}}),以将 {{:origin-file}} 添加到 {{opts}} 中(最后合并 {{opts}} 以保持 {{opts}} 中已存在的任何 {{:origin-file}})
添加了一个新的 {{ana/\*origin-file\*}} 动态变量,以与 {{ana/\*cljs-file\*}} 一起使用,并将其绑定到 {{(:origin-file opts)}} 的值
更新了渲染错误信息的代码,以优先使用 {{ana/\*origin-file\*}} 而不是 {{ana/\*cljs-file\*}}

这会使得错误指向原始源而不是缓存(本地或共享)中的磁盘副本。

例如,如果分析错误是从 JAR 文件中的文件开始的,你会看到


cljs.user=> (require 'foo.core)
警告:cljs.core/+,所有参数都必须是数字,而不是得到了 [字符串 数字] 的结果。在第 3 行 jar:file:/private/tmp/test-origin-file/foo.jar!/foo/core.cljs


另一个说明性示例:使用

{code:title=deps.edn}
{:deps {org.clojure/clojurescript {:mvn/version "1.10.132"}}
        com.cerner/clara-rules {:mvn/version "0.17.0"}}}


master 产生这个(省略以缩短)


clj -Srepro -m cljs.main -re node -e "(require 'clara.rules)"

警告:macroexpand 已经引用:cljs.core/macroexpand 正被 clojure.reflect/macroexpand 替换,在第 33 行 /Users/mfikes/.cljs/.aot_cache/1.10.132/3837055/clojure/reflect.cljs
警告:在行 239 使用未声明的 Var schema.core/MapEntry /Users/mfikes/.cljs/.aot_cache/1.10.132/2E9D363/schema/core.cljs
警告:向 MapEntry 传递了错误的参数数量(3),在第 759 行 /Users/mfikes/.cljs/.aot_cache/1.10.132/2E9D363/schema/core.cljs


而补丁(作为 1.10.133 构建)则生成更具体的信息来指向实际的源 JAR 而不是 AOT 缓存目录


警告:macroexpand 已经引用:cljs.core/macroexpand 正被 clojure.reflect/macroexpand 替换,在第 33 行 jar:file:/Users/mfikes/.m2/repository/org/clojure/clojurescript/1.10.133/clojurescript-1.10.133.jar!/clojure/reflect.cljs
警告:在行 239 使用未声明的 Var schema.core/MapEntry jar:file:/Users/mfikes/.m2/repository/prismatic/schema/1.1.6/schema-1.1.6.jar!/schema/core.clj
警告:向 MapEntry 传递了错误的参数数量(3),在第 759 行 jar:file:/Users/mfikes/.m2/repository/prismatic/schema/1.1.6/schema-1.1.6.jar!/schema/core.cljs
0 投票

评论者:dnolen

是的,这是一个特定于 REPL 的问题。我认为正确的处理方法是修复 REPL 编译代码的方式。目前,它们以反向顺序执行分析过程,而不仅仅是按依赖关系顺序将所有内容放入,然后按该顺序编译,就像构建一样。这将是一个清理仅由 REPL 使用的旧代码路径的好机会。

0 投票
...