formatting-stack icon indicating copy to clipboard operation
formatting-stack copied to clipboard

Namespaced keyword usage linter

Open vemv opened this issue 6 years ago • 4 comments

Context

Some codebases use ns-qualifed keywords heavily, including cross-ns keyword references.

Such a pattern is subject to bugs:

  • Consumers making typos
  • Producers renaming keywords

Task

Create a linter that fails when consumed keywords don't exist in the producer side.

vemv avatar Aug 21 '19 14:08 vemv

How would one determine the 'existence' of a keyword in a certain ns? Just as a spec (using #'clojure.spec.alpha/get-spec for example)?

thumbnail avatar Dec 28 '19 21:12 thumbnail

No, I wouldn't couple the linter to Spec in any way

Given a ns reference such as a.b.c, one can obtain its source non-mutatively (i.e. no require performed, which is a side-effect) with this snippet.

Armed with that source, one can perform a simple scan of keywords with tools.reader.

vemv avatar Dec 28 '19 21:12 vemv

played around with this a bit. The bit from file -> keywords.

(->> (str "[" (slurp source) "]")
     (tools.reader/read-string {:read-cond :preserve
                                :features  #{:clj :cljs}})
     (flatten)
     (filter #(and (keyword? %)
                   (= (str *ns*)
                      (namespace %))))
     (map name))
=>
'("local-name"
  "binding-form"
  "local-name"
  "seq-binding-form"
  "map-binding-form"
  "seq-binding-form"
  "binding-form"
  ...)

still need to figure out how to resolve :clojure.core.specs.alpha/rename -> ["clojure/core/specs/alpha.clj", :rename].

thumbnail avatar Jan 06 '20 18:01 thumbnail

still need to figure out how to resolve :clojure.core.specs.alpha/rename -> ["clojure/core/specs/alpha.clj", :rename].

I guess part of the difficuly lies in that you cannot know in advance if the filename is .clj, .cljs, .cljc or multiple of those; particularly without performing a require (a limitation which I'd find clean).

Perhaps one can try the three extensions sequentially, build a set out of each maybe-file, and finally merge those sets.

vemv avatar Jan 06 '20 18:01 vemv