clojure-emacs / refactor-nrepl Goto Github PK
View Code? Open in Web Editor NEWnREPL middleware to support refactorings in an editor agnostic way
License: Eclipse Public License 1.0
nREPL middleware to support refactorings in an editor agnostic way
License: Eclipse Public License 1.0
<!
is a function and is removed by the surrounding go
macro so it doesn't show up in the AST. As it's not a macro we're not checking for it in the 'macro pass' either.
When an error is return in this manner cider can display it to the user.
We should return unexpected errors to the client in this manner so we can get a proper stacktrace as a starting point for debugging.
Expected errors should not be handled in this manner. e.g. when the user calls find-symbol
on a project which is in a bad state we should let the user know we couldn't build an AST and not return the enormous stacktrace produced by tools.analyzer
.
Nothing needs to be done on the client side to add this functionality, nrepl-client
takes care of everything.
if you use require rather than :require in your ns definition, no cleanup is suggested.
pprint.clj might be one of the culprits ?
running clean-ns on:
(ns gargamel.core
(:gen-class)
(:require [leiningen.gargamel :as grg]
[leiningen.gargamel-lr :as grg-lr]
[gargamel.bower :as bower]
[clojure.tools.cli :as cli]
[clojure.string :as str]))
results in a broken ns decl:
(ns gargamel.core
(:gen-class
(:require [clojure.tools.cli :as cli]
[gargamel.bower :as bower]
[leiningen [gargamel :as grg] [gargamel-lr :as grg-lr]]))
if i remove the genclass part, then the last line is still does not have a linebreak but it is valid.
We now have a single op refactor
in this namespace but then we branch on refactor-fn
too. It would be much better if we had 3 distinct ops. This would make it possible to have a more meaningful descriptor
, making refactor-nrepl
more self-documenting, as well as making it possible to return more semantically meaningful return values than value
, e.g. :occurrences
.
I'm trying to use this feature:
pf: promote function literal or fn, or fn to defn
Either I don't understand it, or it is not doing what it should be.
If I have this:
#(println "hello")
Shouldn't the pf
change it to this:
(fn [] (println "hello"))
And if I then did it again, it would do this:
(defn ??? [] (println "hello"))
For me, all it does is report this:
Can't find definition of anonymous function!
I think the most valuable refactoring we haven't tackled yet is that of renaming stuff. Does anyone have any thoughts on how this should work? What happens if you try to analyze source that is invalid? I'm thinking it might be easy to get into a situation where we can find 99% of the occurrences of an identifier but miss one or two due to syntax errors in the file.
We've previously talked a bit about how we're going to tackle undo when we're doing refactoring in the middlewere and this might be difficult for this feature. I propose we just do like ternjs
does: drop undo and instead just let the user rename it once again to undo the operation. When you rename something using tern it will give just prompt your for the new name instead of letting you edit inline with multiple cursors or whatever.
@AlexBaranosky any interest in continuing your explorations?
This op now works on all clj files in the project but it should only consider those on the classpath
I'm not 100% when this started, but it happens both in Snapshot-18 and 19.
When I start a new repl session (through Light Table that is) and then try to invoke the op artifact-list it croaks with this exception.
Subsequent calls seems to work though.
ERROR: Unhandled REPL handler exception processing message {:id c5792790-eac1-407c-99ca-849edf7bb4d5, :op artifact-list} java.lang.NullPointerException at clojure.lang.Reflector.invokeNoArgInstanceMember(Reflector.java:301) at refactor_nrepl.artifacts$stale_cache_QMARK_.invoke(artifacts.clj:36) at refactor_nrepl.artifacts$artifacts_list.invoke(artifacts.clj:89) at refactor_nrepl.artifacts$wrap_artifacts$fn__13260.invoke(artifacts.clj:122) at clojure.tools.nrepl.middleware$wrap_conj_descriptor$fn__414.invoke(middleware.clj:17) at clojure.tools.nrepl.server$handle_STAR_.invoke(server.clj:18) at clojure.tools.nrepl.server$handle$fn__769.invoke(server.clj:27) at clojure.core$binding_conveyor_fn$fn__4145.invoke(core.clj:1910) at clojure.lang.AFn.call(AFn.java:18) at java.util.concurrent.FutureTask.run(FutureTask.java:266) at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142) at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617) at java.lang.Thread.run(Thread.java:745)
Hi !
First of all thx for a great lib and super initiative. @magnars demonstrated some cool refactoring stuff in Emacs and through that I discovered this lib. I'm currently working on utilizing some of the features from this for adding clojure refactoring support to Light Table :)
Anyways, I've managed to get some stuff working using the 0.2.2 version. However the readme documents some features that aren't part of 0.2.2 so I hoped I might be able to try them out by using the snapshot version. However it seems to croak.
I just added :plugins [[refactor-nrepl "0.3.0-SNAPSHOT"]]
to my ~/.lein/profiles.clj
and then tried to do lein repl
on a project. And I got the below.
Maybe there has been introduced an (implicit) dependency on cider ?
Error loading refactor-nrepl.ns.clean-ns: java.io.FileNotFoundException: Could not locate cider/nrepl/middleware/info__init.class or cider/nrepl/middleware/info.clj on classpath: , compiling:(refactor_nrepl/ns/dependencies.clj:1:1)
Exception in thread "main" java.lang.RuntimeException: Unable to resolve var: refactor-nrepl.ns.clean-ns/wrap-clean-ns in this context, compiling:(/private/var/folders/c7/_w_4f1617dvbdkcx17ppnpfw0000gn/T/form-init7033284104408479432.clj:1:2749)
at clojure.lang.Compiler.analyzeSeq(Compiler.java:6651)
at clojure.lang.Compiler.analyze(Compiler.java:6445)
at clojure.lang.Compiler.analyze(Compiler.java:6406)
at clojure.lang.Compiler$InvokeExpr.parse(Compiler.java:3719)
at clojure.lang.Compiler.analyzeSeq(Compiler.java:6646)
at clojure.lang.Compiler.analyze(Compiler.java:6445)
at clojure.lang.Compiler.analyze(Compiler.java:6406)
at clojure.lang.Compiler$InvokeExpr.parse(Compiler.java:3719)
at clojure.lang.Compiler.analyzeSeq(Compiler.java:6646)
at clojure.lang.Compiler.analyze(Compiler.java:6445)
at clojure.lang.Compiler.access$100(Compiler.java:38)
at clojure.lang.Compiler$LetExpr$Parser.parse(Compiler.java:6050)
at clojure.lang.Compiler.analyzeSeq(Compiler.java:6644)
at clojure.lang.Compiler.analyze(Compiler.java:6445)
at clojure.lang.Compiler.analyze(Compiler.java:6406)
at clojure.lang.Compiler$BodyExpr$Parser.parse(Compiler.java:5782)
at clojure.lang.Compiler$FnMethod.parse(Compiler.java:5217)
at clojure.lang.Compiler$FnExpr.parse(Compiler.java:3846)
at clojure.lang.Compiler.analyzeSeq(Compiler.java:6642)
at clojure.lang.Compiler.analyze(Compiler.java:6445)
at clojure.lang.Compiler.eval(Compiler.java:6700)
at clojure.lang.Compiler.eval(Compiler.java:6693)
at clojure.lang.Compiler.eval(Compiler.java:6693)
at clojure.lang.Compiler.load(Compiler.java:7130)
at clojure.lang.Compiler.loadFile(Compiler.java:7086)
at clojure.main$load_script.invoke(main.clj:274)
at clojure.main$init_opt.invoke(main.clj:279)
at clojure.main$initialize.invoke(main.clj:307)
at clojure.main$null_opt.invoke(main.clj:342)
at clojure.main$main.doInvoke(main.clj:420)
at clojure.lang.RestFn.invoke(RestFn.java:421)
at clojure.lang.Var.invoke(Var.java:383)
at clojure.lang.AFn.applyToHelper(AFn.java:156)
at clojure.lang.Var.applyTo(Var.java:700)
at clojure.main.main(main.java:37)
Caused by: java.lang.RuntimeException: Unable to resolve var: refactor-nrepl.ns.clean-ns/wrap-clean-ns in this context
at clojure.lang.Util.runtimeException(Util.java:221)
at clojure.lang.Compiler$TheVarExpr$Parser.parse(Compiler.java:659)
at clojure.lang.Compiler.analyzeSeq(Compiler.java:6644)
... 34 more
I'm having a hard time finding a use-case for find-local-symbol
on its own. Is there any point in providing this?
Now that we're depending on cider-nrepl, is there any reason to keep the rather anemic var-info
around?
would make sense with a properly parsed ns declaration
two candidates so far:
both of them seem to do a proper classloader level isolation for dependencies (this is a very generic statement) while mranderson simply munges ns declarations
this snippet, from slamhound.regrow
trips clean-ns
up:
(proxy [FilenameFilter] []
(accept [d n] (jar? (file n))))
Not sure what's special here, but @rundis found this, where |
indicates the cursor:
(ns acme-auth.store
(:require [clojure.java.jdbc :as jdbc]))
(defn- find-user-roles [conn user-id]
(let [id (|jdbc/query conn "select sysdate from dual")]
(map (fn [row] {:role-id (:id row) :application-id (:application_id row)})
(jdbc/query conn ["select r.id, r.application_id
from role r
inner join user_role ur on r.id = ur.role_id
where ur.user_id = ?" user-id]))))
This results in unbound of [conn user-id]
but only conn
is used.
Version 1.0.2
Contents of profiles.clj:
{:user {:plugins [[cider/cider-nrepl "0.9.0-SNAPSHOT"]
[lein-cloverage "1.0.2"]
[refactor-nrepl "1.0.2"] ]}}
Error:
Error loading refactor-nrepl.middleware: java.io.FileNotFoundException: Could not locate clojure/java/classpath__init.class or clojure/java/classpath.clj on classpath: , compiling:(refactor_nrepl/ns/slam/hound/search.clj:1:1)
Exception in thread "Thread-3" java.lang.RuntimeException: Unable to resolve var: refactor-nrepl.middleware/wrap-refactor in this context, compiling:(NO_SOURCE_PATH:0:0)
at clojure.lang.Compiler.analyzeSeq(Compiler.java:6651)
at clojure.lang.Compiler.analyze(Compiler.java:6445)
at clojure.lang.Compiler.analyze(Compiler.java:6406)
at clojure.lang.Compiler$InvokeExpr.parse(Compiler.java:3719)
at clojure.lang.Compiler.analyzeSeq(Compiler.java:6646)
at clojure.lang.Compiler.analyze(Compiler.java:6445)
at clojure.lang.Compiler.analyze(Compiler.java:6406)
at clojure.lang.Compiler$InvokeExpr.parse(Compiler.java:3719)
at clojure.lang.Compiler.analyzeSeq(Compiler.java:6646)
at clojure.lang.Compiler.analyze(Compiler.java:6445)
at clojure.lang.Compiler.access$100(Compiler.java:38)
at clojure.lang.Compiler$LetExpr$Parser.parse(Compiler.java:6050)
at clojure.lang.Compiler.analyzeSeq(Compiler.java:6644)
at clojure.lang.Compiler.analyze(Compiler.java:6445)
at clojure.lang.Compiler.analyze(Compiler.java:6406)
at clojure.lang.Compiler$BodyExpr$Parser.parse(Compiler.java:5782)
at clojure.lang.Compiler$FnMethod.parse(Compiler.java:5217)
at clojure.lang.Compiler$FnExpr.parse(Compiler.java:3846)
at clojure.lang.Compiler.analyzeSeq(Compiler.java:6642)
at clojure.lang.Compiler.analyze(Compiler.java:6445)
at clojure.lang.Compiler.eval(Compiler.java:6700)
at clojure.lang.Compiler.eval(Compiler.java:6693)
at clojure.lang.Compiler.eval(Compiler.java:6693)
at clojure.lang.Compiler.eval(Compiler.java:6666)
at clojure.core$eval.invoke(core.clj:2927)
at leiningen.core.eval$fn__6742.invoke(eval.clj:314)
at clojure.lang.MultiFn.invoke(MultiFn.java:231)
at leiningen.core.eval$eval_in_project.invoke(eval.clj:337)
at leiningen.repl$server$fn__10685.invoke(repl.clj:229)
at clojure.lang.AFn.applyToHelper(AFn.java:152)
at clojure.lang.AFn.applyTo(AFn.java:144)
at clojure.core$apply.invoke(core.clj:624)
at clojure.core$with_bindings_STAR_.doInvoke(core.clj:1862)
at clojure.lang.RestFn.invoke(RestFn.java:425)
at clojure.lang.AFn.applyToHelper(AFn.java:156)
at clojure.lang.RestFn.applyTo(RestFn.java:132)
at clojure.core$apply.invoke(core.clj:628)
at clojure.core$bound_fn_STAR_$fn__4140.doInvoke(core.clj:1884)
at clojure.lang.RestFn.invoke(RestFn.java:397)
at clojure.lang.AFn.run(AFn.java:22)
at java.lang.Thread.run(Thread.java:745)
Caused by: java.lang.RuntimeException: Unable to resolve var: refactor-nrepl.middleware/wrap-refactor in this context
at clojure.lang.Util.runtimeException(Util.java:221)
at clojure.lang.Compiler$TheVarExpr$Parser.parse(Compiler.java:659)
at clojure.lang.Compiler.analyzeSeq(Compiler.java:6644)
... 40 more
The LT
plugin is currently filtering these out but we should do it in the middleware as it's affecting all clients.
I think the old name hints too much at the intended usage and I'd like something more general like find-usages-bulk
if there's time before 1.0.
Before running find-usages on a freshly connected project the following snippet returns sane file references:
(doseq [v (vals (ns-interns `acme-auth.store))]
(println (meta v)))
After running the find-usages op the file references for the above snippet returns the location of a temp file. Alone the lines of:
{:ns #<Namespace acme-auth.store>, :name invalidate-token!, :file /private/var/folders/c7/_w_4f1617dvbdkcx17ppnpfw0000gn/T/form-init8517234393706252752.clj, :end-column 66, :column 1, :line 57, :end-line 64, :arglists ([conn id] [conn user-id issued])}
Evaling the file put things right, or using tools.namespace.repl/refresh also get things back to normality.
I believe @benedekfazekas verified this in a repl session as well.
The result of scanning the classpath is cached in resolve-missing
, the cache has to be invalidated after hotload-dependency
runs.
This dependency is causing too many problems.
Resolve missing is assuming that everything that starts with a capital letter is a class. When using prismatic/schema
I noticed that this is a terrible assumption.
For the same reason it isn't handling defrecords correctly. These are being looked up as classes, but they have to be looked up with type
:refer
in slamhound/candidates
.
Trying out the latest snapshot as of now (.20 version), and the artifact-versions op now results empty when results are expected.
Context:
I invoke something like this from LT:
(do (require 'refactor-nrepl.client) (require 'clojure.tools.nrepl) (require 'lighttable.nrepl.eval) (def z-ns 'acme-auth.store) (def tr (refactor-nrepl.client/connect)) (refactor-nrepl.client/rename-symbol :transport tr :ns z-ns :name "add-user!" :new-name "dill"))
When I call find symbol I don't go through the refactor-nrepl.client
, but that works like a charm with error messages and the whole sheebang.
Maybe there is something I'm missing ?
It should only act on files present on classpath
I was going through the commit history and saw commit messages like:
adds ...
added ...
Add ...
Clearly the project is not employing a consistent style for the commit messages - pretty much every contributor uses a different style for those. Compare this with the commit history of RuboCop.
I believe that all projects can benefit from more descriptive commit messages and a consistent style for them, so I'd like to propose adopting the widely respected guidelines suggested here. Maybe we can add a note about this in the CONTRIBUTING.md
(I'd suggest just copying the one from cider-nrepl
)?
Thinking the fix to this issue should be a re-implementation using a proper parser.
If a symbol is referred into an ns and only used in a syntax quoted macro body it's removed by clean-ns
.
StringReader
arity changed due to CLJ-1424. This broke instaparse, which in turn means that any project using refactor-nrepl breaks:
~/P/icecap: lein repl 10:14:30
Error loading refactor-nrepl.ns.clean-ns: clojure.lang.ArityException: Wrong number of args (2) passed to: StringReader, compiling:(abnf.clj:189:28)
Exception in thread "main" java.lang.RuntimeException: Unable to resolve var: refactor-nrepl.ns.clean-ns/wrap-clean-ns in this context, compiling:(/private/var/folders/2w/kffqc_pj6m38rgrxlhk8z6nr0000gn/T/form-init8283120416933906915.clj:1:9388)
at clojure.lang.Compiler.analyzeSeq(Compiler.java:6740)
at clojure.lang.Compiler.analyze(Compiler.java:6524)
at clojure.lang.Compiler.analyze(Compiler.java:6485)
at clojure.lang.Compiler$InvokeExpr.parse(Compiler.java:3791)
at clojure.lang.Compiler.analyzeSeq(Compiler.java:6735)
at clojure.lang.Compiler.analyze(Compiler.java:6524)
at clojure.lang.Compiler.analyze(Compiler.java:6485)
at clojure.lang.Compiler$InvokeExpr.parse(Compiler.java:3791)
at clojure.lang.Compiler.analyzeSeq(Compiler.java:6735)
at clojure.lang.Compiler.analyze(Compiler.java:6524)
at clojure.lang.Compiler.access$300(Compiler.java:38)
at clojure.lang.Compiler$LetExpr$Parser.parse(Compiler.java:6129)
at clojure.lang.Compiler.analyzeSeq(Compiler.java:6733)
at clojure.lang.Compiler.analyze(Compiler.java:6524)
at clojure.lang.Compiler.analyze(Compiler.java:6485)
at clojure.lang.Compiler$BodyExpr$Parser.parse(Compiler.java:5861)
at clojure.lang.Compiler$FnMethod.parse(Compiler.java:5296)
at clojure.lang.Compiler$FnExpr.parse(Compiler.java:3925)
at clojure.lang.Compiler.analyzeSeq(Compiler.java:6731)
at clojure.lang.Compiler.analyze(Compiler.java:6524)
at clojure.lang.Compiler.eval(Compiler.java:6789)
at clojure.lang.Compiler.eval(Compiler.java:6782)
at clojure.lang.Compiler.eval(Compiler.java:6782)
at clojure.lang.Compiler.load(Compiler.java:7237)
at clojure.lang.Compiler.loadFile(Compiler.java:7175)
at clojure.main$load_script.invoke(main.clj:275)
at clojure.main$init_opt.invoke(main.clj:280)
at clojure.main$initialize.invoke(main.clj:308)
at clojure.main$null_opt.invoke(main.clj:343)
at clojure.main$main.doInvoke(main.clj:421)
at clojure.lang.RestFn.invoke(RestFn.java:421)
at clojure.lang.Var.invoke(Var.java:383)
at clojure.lang.AFn.applyToHelper(AFn.java:156)
at clojure.lang.Var.applyTo(Var.java:700)
at clojure.main.main(main.java:37)
Caused by: java.lang.RuntimeException: Unable to resolve var: refactor-nrepl.ns.clean-ns/wrap-clean-ns in this context
at clojure.lang.Util.runtimeException(Util.java:221)
at clojure.lang.Compiler$TheVarExpr$Parser.parse(Compiler.java:698)
at clojure.lang.Compiler.analyzeSeq(Compiler.java:6733)
... 34 more
Fortunately instaparse has already fixed this upstream in 1.3.6. I'd recommend upgrading both dependencies.
(defn- artifacts-list [{:keys [transport force] :as msg}]
(when (or (= force "true") (stale-cache?))
(update-artifact-cache!))
(let [names (->> @artifacts
keys
(interpose " ")
(apply str))]
(transport/send transport (response-for msg :value names :status :done))))
if I try to find usages for transport
or names
I just get could not resolve symbol. Please load your namespace.
What is your workflow like when working on refactor-nrepl?
To test refactor-nrepl
, from clj-refactor
I've been installing the refactor-nrepl
middlewere using lein-localrepo
and then restarting the cider repl. This is extremely cumbersome. Is there some better way to do this?
Ref the following gist
pretty sure this worked fine in 1.0.0, but now doesn't work correctly in 1.0.1
With a source file containing
(ns my-source.file
(:require [cider.nrepl.middleware.util.misc :refer [err-info]]))
(defmacro tt []
`(err-info))
Running clean-ns
will result in
(ns my-source.file
(:require cider.nrepl.middleware.util.misc]))
(defmacro tt []
`(err-info))
I thought you might like to see this issue:
I had this in my lein plugins:
:plugins [[refactor-nrepl "0.3.0-SNAPSHOT"]]
As soon as I removed it, the Java error disappeared and my app started working again. I was not actually using the refactor tools when the crash happens.
I'd like to keep using the refactor functionality, so if you have advice on what might have cause this, I'm all ears.
If you subset and repackage slamhound, please also prefix it with you own namespace.
As it stands, slamhound cannot be used in parallel with refactor-nrepl.
(require 'slam.hound) throws slam.hound.regrow/regrow var not found.
thanks
I tried renaming one of the keys in an options map earlier today and that didn't work.
Renaming a regular destructured map works fine. Renaming bar
below also works fine:
(defn foo [& {:keys [bar]}]
bar)
but renaming bar
doesn't work in this case:
(defn foo [& {:keys [bar] :or {bar "bar"}}]
bar)
This borders on #wontfix
(defn as-request-handler
"Take a WebService component and return a Ring handler."
[service not-found-handler]
(assert (satisfies? RouteProvider service))
(some-fn
(make-handler
(cond
(satisfies? RouteProvider service)
(bidi/routes service)
#_(satisfies? WebService service)
#_[(or (uri-context service) "")
(->KeywordToHandler [(routes service)]
(request-handlers service))]))
not-found-handler))
All mentions of WebService
are wrongly eliminated.
The reader removes these so they're nowhere to be found in the AST.
If clean-ns
is run on an unparseable buffer the parse exception is swallowed, in ns-ast
, leading the op to conclude that the ns doesn't have any external dependencies and the ns form is emptied.
It would be better if the parse exception bubbled up to the user and we don't do the wrong thing.
I noticed you use the :value
slot in every middleware op's response. Guess you saw this in cider-nrepl's middlewares, but it is something that's considered a bad practice. We had to do it cider-nrepl, because of limitations in the elisp client that no longer exist. Generally the response slots should have descriptive names like :artifacts
, :occurrences
, etc.
I've also noticed that you typically send :status :done
as a separate message. This is a bit inefficient, so I'd recommend sending combining the status with the payload. Having this as a separate message makes sense only for ops like eval
that can produce multiple messages as part of their response.
Have a look at the current state of the cider-nrepl middlewares for more details.
refactor-nrepl 1.0.2-SNAPSHOT
clj-refactor 20150406
ERROR: Unhandled REPL handler exception processing message {:op configure, :opts {:prefix-rewriting true}, :id 7}
java.lang.IllegalArgumentException: No implementation of method: :send of protocol: #'clojure.tools.nrepl.transport/Transport found for class: clojure.lang.Keyword
at clojure.core$_cache_protocol_fn.invoke(core_deftype.clj:544)
at clojure.tools.nrepl.transport$eval156$fn__157$G__145__164.invoke(transport.clj:16)
at refactor_nrepl.middleware$config_reply.invoke(middleware.clj:66)
at refactor_nrepl.middleware$wrap_refactor$fn__10499.invoke(middleware.clj:84)
at clojure.tools.nrepl.middleware$wrap_conj_descriptor$fn__406.invoke(middleware.clj:17)
at cider.nrepl.middleware.ns$wrap_ns$fn__2819.invoke(ns.clj:61)
at clojure.tools.nrepl.middleware$wrap_conj_descriptor$fn__406.invoke(middleware.clj:17)
at cider.nrepl.middleware.macroexpand$wrap_macroexpand$fn__2783.invoke(macroexpand.clj:79)
at clojure.tools.nrepl.middleware$wrap_conj_descriptor$fn__406.invoke(middleware.clj:17)
at cider.nrepl.middleware.info$wrap_info$fn__2573.invoke(info.clj:262)
at clojure.tools.nrepl.middleware$wrap_conj_descriptor$fn__406.invoke(middleware.clj:17)
at cider.nrepl.middleware.classpath$wrap_classpath$fn__1245.invoke(classpath.clj:25)
at clojure.tools.nrepl.middleware$wrap_conj_descriptor$fn__406.invoke(middleware.clj:17)
at cider.nrepl.middleware.apropos$wrap_apropos$fn__1178.invoke(apropos.clj:102)
at clojure.tools.nrepl.middleware$wrap_conj_descriptor$fn__406.invoke(middleware.clj:17)
at cider.nrepl.middleware.complete$wrap_complete$fn__2070.invoke(complete.clj:47)
at clojure.tools.nrepl.middleware$wrap_conj_descriptor$fn__406.invoke(middleware.clj:17)
at cider.nrepl.middleware.resource$wrap_resource$fn__2845.invoke(resource.clj:25)
at clojure.tools.nrepl.middleware$wrap_conj_descriptor$fn__406.invoke(middleware.clj:17)
at cider.nrepl.middleware.undef$wrap_undef$fn__3298.invoke(undef.clj:30)
at clojure.tools.nrepl.middleware$wrap_conj_descriptor$fn__406.invoke(middleware.clj:17)
at clojure.tools.nrepl.server$handle_STAR_.invoke(server.clj:19)
at clojure.tools.nrepl.server$handle$fn__760.invoke(server.clj:28)
at clojure.core$binding_conveyor_fn$fn__4145.invoke(core.clj:1910)
at clojure.lang.AFn.call(AFn.java:18)
at java.util.concurrent.FutureTask.run(FutureTask.java:266)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617)
at java.lang.Thread.run(Thread.java:745)
This doesn't appear to be used in the current version of clj-refactor
, can we just delete it?
The readme states that it was added as a temporary performance fix for clj-remove-unused-requires
and is likely to get deleted.
I was refactoring dependencies.clj
earlier today and ran into this:
(defn extract-dependencies [path ns-form]
(let [libspecs (get-libspecs ns-form)
file-content (slurp path)
symbols-from-ast (-> file-content ns-ast used-vars set)
symbols-used-in-macros (get-symbols-used-in-macros file-content)
symbols-from-refer (remove nil? (map (partial adorn-with-name-and-alias
(second ns-form))
(used-symbols-from-refer libspecs
symbols-used-in-macros)))
imports (get-imports ns-form)
imports-used-in-macros (filter-imports imports (map :suffix symbols-used-in-macros))
fully-qualified-macros (map #(assoc {} :name %)
(find-fully-qualified-macros file-content))
imports-used-in-typehints (filter-imports imports
(get-classes-used-in-typehints file-content))]
{:require (->> libspecs
(remove-unused-requires
(set (concat symbols-from-refer symbols-from-ast
fully-qualified-macros)))
(filter (complement nil?)))
:import (->> | ns-form
get-imports
(remove-unused-imports (concat symbols-from-ast
imports-used-in-typehints
imports-used-in-macros)))}))
The extacted fn is missing symbols-from-ast
imports-used-in-typehints
and imports-used-in-macros
as paramters:
(defn- foo
[ns-form]
(->> ns-form
get-imports
(remove-unused-imports (concat symbols-from-ast
imports-used-in-typehints
imports-used-in-macros))))
When the ns contains this:
[clojure.string :as str :refer [join split]]
and I change all references to join
and split
to str/join
and str/split
I expect clean-ns
to remove the :refer
clause.
I have a project with a profiles section containing:
:profiles {:dev {:plugins [[lein-ring "0.8.13"]
[drift "1.5.2"]]
:source-paths ["dev"]
:test-paths ^:replace []}
:test {:dependencies [[midje "1.6.3"]]
:plugins [[lein-midje "3.1.3"]]
:test-paths ["test"]
:resource-paths ["test/resources"]}}
Might be a user error from my side, but I would have thought that since test namepaces aren't part of my classpath they shouldn't be analyzed either ?
[clojure-agent-send-off-pool-92] ERROR clojure.tools.nrepl.server - Unhandled REPL handler exception processing message {:id d94991e8-087b-4aa4-a99d-2bf90f439fd1, :name check-produsent, :ns helsegris-api.produsent.domain, :op refactor, :refactor-fn find-symbol}
java.lang.AssertionError: Assert failed: Can't find helsegris-api.core-test in classpath
res
at deps.toolsanalyzerjvm.v0v6v5.clojure.tools.analyzer.jvm$analyze_ns.invoke(jvm.clj:535)
at deps.toolsanalyzerjvm.v0v6v5.clojure.tools.analyzer.jvm$analyze_ns.invoke(jvm.clj:531)
at deps.toolsanalyzerjvm.v0v6v5.clojure.tools.analyzer.jvm$analyze_ns.invoke(jvm.clj:530)
at refactor_nrepl.analyzer$build_ast.invoke(analyzer.clj:52)
at refactor_nrepl.analyzer$cachable_ast.invoke(analyzer.clj:59)
at refactor_nrepl.analyzer$ns_ast.invoke(analyzer.clj:65)
at refactor_nrepl.refactor$find_symbol_in_file.invoke(refactor.clj:97)
at clojure.lang.AFn.applyToHelper(AFn.java:156)
at clojure.lang.AFn.applyTo(AFn.java:144)
at clojure.core$apply.invoke(core.clj:626)
at clojure.core$partial$fn__4228.doInvoke(core.clj:2468)
at clojure.lang.RestFn.invoke(RestFn.java:408)
at clojure.core$map$fn__4245.invoke(core.clj:2559)
at clojure.lang.LazySeq.sval(LazySeq.java:40)
at clojure.lang.LazySeq.seq(LazySeq.java:49)
at clojure.lang.Cons.next(Cons.java:39)
at clojure.lang.RT.next(RT.java:598)
at clojure.core$next.invoke(core.clj:64)
at clojure.core$concat$cat__3957$fn__3958.invoke(core.clj:701)
at clojure.lang.LazySeq.sval(LazySeq.java:40)
at clojure.lang.LazySeq.seq(LazySeq.java:56)
at clojure.lang.RT.seq(RT.java:484)
at clojure.core$seq.invoke(core.clj:133)
at clojure.core$map$fn__4245.invoke(core.clj:2551)
at clojure.lang.LazySeq.sval(LazySeq.java:40)
at clojure.lang.LazySeq.seq(LazySeq.java:49)
at clojure.lang.Cons.next(Cons.java:39)
at clojure.lang.RT.next(RT.java:598)
at clojure.core$next.invoke(core.clj:64)
at refactor_nrepl.refactor$find_symbol_reply.invoke(refactor.clj:145)
at refactor_nrepl.refactor$wrap_refactor$fn__10247.invoke(refactor.clj:190)
at clojure.tools.nrepl.middleware$wrap_conj_descriptor$fn__431.invoke(middleware.clj:17)
at cider.nrepl.middleware.apropos$wrap_apropos$fn__14222.invoke(apropos.clj:102)
at clojure.tools.nrepl.middleware$wrap_conj_descriptor$fn__431.invoke(middleware.clj:17)
at refactor_nrepl.find_unbound$wrap_find_unbound$fn__13560.invoke(find_unbound.clj:24)
at clojure.tools.nrepl.middleware$wrap_conj_descriptor$fn__431.invoke(middleware.clj:17)
at cider.nrepl.middleware.classpath$wrap_classpath$fn__14249.invoke(classpath.clj:25)
at clojure.tools.nrepl.middleware$wrap_conj_descriptor$fn__431.invoke(middleware.clj:17)
at refactor_nrepl.artifacts$wrap_artifacts$fn__14184.invoke(artifacts.clj:126)
at clojure.tools.nrepl.middleware$wrap_conj_descriptor$fn__431.invoke(middleware.clj:17)
at clojure.tools.nrepl.server$handle_STAR_.invoke(server.clj:18)
at clojure.tools.nrepl.server$handle$fn__787.invoke(server.clj:27)
at clojure.core$binding_conveyor_fn$fn__4145.invoke(core.clj:1910)
at clojure.lang.AFn.call(AFn.java:18)
at java.util.concurrent.FutureTask.run(FutureTask.java:266)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617)
at java.lang.Thread.run(Thread.java:745)
A declarative, efficient, and flexible JavaScript library for building user interfaces.
๐ Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. ๐๐๐
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google โค๏ธ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.