2024 State of Clojure 调查!中分享您的想法。

欢迎!请查看关于页面以了解更多关于这是如何工作的信息。

+1
错误

var Deployment 不存在的ns将产生此错误

user> (def foo/bar 1) 语法错误编译 def at (REPL:1:1)。不能在当前的ns外创建def

原因: Compiler.lookupVar() 如果在已命名的变量中类不存在,则返回null。

建议: 通过命名符号并抛出带有文件/行/列信息的CompilerException,错误消息将得到改进。这并不明显,但这可能是在此错误发生的情况下。如果是这样,错误信息可以更具体地指出ns部分是不存在的。

补丁: clj-1400-4.diff

审核者: Alex Miller

14 回答

0

由: scottbale 评论

在我看来,这似乎是一块相对低垂的果实,除非我遗漏了什么;正在为自己分配。

0

由: scottbale 评论

Patch {{clj-1400-1.diff}} to {{Compiler.java}}.

使用此补丁,示例现在看起来像

user> (def foo/bar 1) CompilerException java.lang.RuntimeException: Qualified symbol foo/bar refers to nonexistent namespace: foo, compiling:(NO_SOURCE_PATH:1:1)

我不确定{{if(namesStaticMember(sym))}} (link: see below) 和第二个分支是否真的有必要。只是通过检查,我怀疑它不是。

(link: 脚注)

`
public static boolean namesStaticMember(Symbol sym){

return sym.ns != null && namespaceFor(sym) == null;

}
`

0

由: scottbale 评论

补丁:代码和测试

0

由: scottbale 评论

我在实际的源文件上进行了测试,异常信息中包含了文件/行/列信息,符合预期

user=> CompilerException java.lang.RuntimeException: Qualified symbol goo/bar refers to nonexistent namespace: goo, compiling:(/home/scott/dev/foo.clj:3:1)

0

评论者:jafingerhut

2014年6月26日创建的补丁 clj-1400-1.diff 在2014年8月29日对Clojure进行了某些提交后,已不再干净地应用于最新的master。在那一天之前它是干净的。

我还没有检查更新这个补丁的难易程度。请参阅本维基页面上的“更新过时的补丁”部分,了解有关更新补丁的一些建议:http://dev.clojure.org/display/community/Developing Patches

0

由: scottbale 评论

附上一个更新后的补丁:“clj-1400-2.diff”。我删除了过时的补丁。

0

评论者:alexmiller

只有少数评论要处理
- 编译器diff使用的是空格,而不是制表符,这使得diff更困难。我附上了一个-3.diff来修复这个问题。
- namesStaticMember的调用看起来很奇怪。这个方法的名字对这种使用来说很令人困惑。除此之外,我认为它在做比你需要的更多的事情。这个方法将尝试以当前ns为单位解决限定名称,但我想你可能根本不想这样做。你只需要知道sym是否有ns(sym.ns != null) - 这不就足够了吗?
- 在什么情况下会发生其他错误“变量不存在”?换句话说,在什么情况下lookupVar不会在这里创建新的变量?如果没有这种情况,则删除此情况。如果有这种情况,则添加一个测试。

0

由: scottbale 评论

同意你提出的三个要点。附件是一个更新的补丁,clj-1400-4.diff。
我在Compiler.java中使用了制表符 在仔细检查lookupVar(...)的调用后,我认为只有在恰好这个工单(符号拥有尚未加载的非null命名空间)的情况下才会返回null。因此,我已经去掉条件判断和第二个分支。
* (测试没有改变)

0

由: scottbale 评论

(补丁命名正确)

0

评论者:alexmiller

你可以(如工单说明中建议的那样)抛出一个带有问题位置的CompilerException。

0

由: scottbale 评论

抱歉,我应该提到这一点,因为这对我也不是很明显(实际上我直到刚才才意识到):RuntimeException已经被捕获,并封装在CompilerException中。

我不确定这是在Compiler.java中的哪个try-catch块中发生的,因为这里有几个。但在输出中你可以看到异常是CompilerException,并且有文件|行|列信息。

在Repl...

user> (def foo/bar 1) CompilerException java.lang.RuntimeException: Qualified symbol foo/bar refers to nonexistent namespace: foo, compiling:(NO_SOURCE_PATH:1:1)

...或者在一个源文件中

user=> CompilerException java.lang.RuntimeException: Qualified symbol goo/bar refers to nonexistent namespace: goo, compiling:(/home/scott/dev/foo.clj:3:1)

此外,在这个补丁抛出的RuntimeException点上,CompilerException的source、line和col参数不可用,或者至少据我所知如此。

0

评论者:alexmiller

我稍后将对这个补丁进行跟进 - Rich认为它做了太多的假设。我认为我们已经验证了许多这些假设,但需要再次核实。

0

评论者:alexmiller

从Clojure 1.10开始更新了错误结果。现在它正在抛出带有file/line/col的:compile-syntax错误阶段的异常。

0
参考:https://clojure.atlassian.net/browse/CLJ-1400 (hlewisship 报告)
...