greglook / cljstyle

A tool for formatting Clojure code
Eclipse Public License 1.0
293 stars 39 forks source link

NPE on namespaced map with relative key namespaced map value #13

Closed drewinglis closed 3 years ago

drewinglis commented 5 years ago
$ cat foo.clj
#:foo{:foo #::bar{}}
$ cljfmt check -v foo.clj
,,,
java.lang.NullPointerException: null                                                                    
 at java.util.concurrent.ConcurrentHashMap.get (ConcurrentHashMap.java:936)                             
    clojure.lang.Namespace.find (Namespace.java:188)                                                    
    clojure.core$find_ns.invokeStatic (core.clj:4096)                                                   
    clojure.core$the_ns.invokeStatic (core.clj:4126)                                                    
    clojure.core$ns_name.invokeStatic (core.clj:4130)                                                   
    clojure.core$ns_name.invoke (core.clj:4130)                                                         
    rewrite_clj.node.seq.NamespacedMapNode.sexpr (seq.clj:57)                                           
    rewrite_clj.node.protocols$fn__271$fn__315$G__277__317.invoke (protocols.clj:9)
    rewrite_clj.node.protocols$fn__271$fn__315$G__276__320.invoke (protocols.clj:9)                     
    clojure.core$map$fn__5587.invoke (core.clj:2747)                                                    
    clojure.lang.LazySeq.sval (LazySeq.java:40)                                                         
    clojure.lang.LazySeq.seq (LazySeq.java:49)                                                          
    clojure.lang.Cons.next (Cons.java:39)                                                               
    clojure.lang.RT.boundedLength (RT.java:1785)                                                        
    clojure.lang.RestFn.applyTo (RestFn.java:130)                                                       
    clojure.core$apply.invokeStatic (core.clj:657)                                                      
    clojure.core$apply.invoke (core.clj:652)                                                            
    rewrite_clj.node.seq$map_node$fn__1794.invoke (seq.clj:110)                                         
    rewrite_clj.node.seq.SeqNode.sexpr (seq.clj:16)                                                     
    rewrite_clj.node.protocols$fn__271$fn__315$G__277__317.invoke (protocols.clj:9)                     
    rewrite_clj.node.protocols$fn__271$fn__315$G__276__320.invoke (protocols.clj:9)                     
,,,

Note that it only happens if the value namespaced map is a relative namespaced key. This file checks okay, for example:

$ cat foo.clj
#:foo{:foo #:bar{}}
greglook commented 4 years ago

This appears to be an issue with auto-resolved keywords and rewrite-clj. When the namespace of the map is something like ::foo, it has a non-nil namespace somehow but there is obviously no matching namespace alias loaded in cljstyle.

https://github.com/xsc/rewrite-clj/issues/21 https://github.com/xsc/rewrite-clj/issues/54

drewinglis commented 4 years ago

Looks like the second one is more directly relevant.

csakoda commented 4 years ago

Bumped into this, what's the currently accepted workaround? use full specification on the inner maps?

e.g. #:foo{:foo {:bar/bar nil}}

greglook commented 4 years ago

Yes, you can work around this by not using a nested namespaced map and using namespaced keywords instead. Namespace aliased keys do still work in the nested data structure.