Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Namespaced keyword usage linter #89

Open
vemv opened this issue Aug 21, 2019 · 4 comments
Open

Namespaced keyword usage linter #89

vemv opened this issue Aug 21, 2019 · 4 comments

Comments

@vemv
Copy link
Contributor

vemv commented Aug 21, 2019

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.

@thumbnail
Copy link
Member

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)?

@vemv
Copy link
Contributor Author

vemv commented Dec 28, 2019

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.

@thumbnail
Copy link
Member

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].

@vemv
Copy link
Contributor Author

vemv commented Jan 6, 2020

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.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants