but did you not observe that?
That is what I expected.
No
Here’s what comes out:
{:name stub-test,
:publics ({:name normal-def, :type :var}
{:name normal-defn, :arglists ([]), :type :var}
{:name hidden-defmacro2, :arglists ([]), :doc "Doc", :type :macro}
{:name gen-clj-stuff, :arglists ([]), :type :macro}
{:name NormalProtocol, :type :protocol, :members ({:name normal-method, :arglists ([this]), :type :var})}
{:name hidden-defmacro5, :arglists ([foo__2589__auto__]), :type :macro}
{:name gen-stuff, :arglists ([]), :type :macro}
{:name hidden-defmacro6, :arglists ([foo__2589__auto__] [foo__2589__auto__ bar__2590__auto__]), :type :macro}
{:name normal-multimethod, :type :multimethod}
{:name hidden-defmacro4, :arglists ([]), :doc "Moar doc", :type :macro}
{:name normal-method, :arglists ([this]), :type :var}
{:name hidden-defmacro3, :arglists ([]), :type :macro}
{:name hidden-defmacro, :arglists ([]), :type :macro}
{:name normal-macro, :arglists ([]), :type :macro})}
normal-macro
does appear there.
ok so let me try to reproduce that with really basic analysis - and leave the other parts for later
I'm not going to use the specific stuff you have, just standard analyze-file
Sounds good.
The repro contains a bunch of fiddling required to make helix.dom
analyse, related to npm deps.
(normal-def normal-defn normal-multimethod NormalProtocol normal-method)
this is the result of analyze-file
of the first 8 lines
the keys of the :defs
for that namespace
I don't see normal-macro
in there
which would have been very surprising because it's behind a reader conditional
That’s why I was very surprised 🙂
Let me try just analyze-file on that.
to be clear this was cljs.analyzer/analyze-file
, let me try the api one - which is the right one to use
same result for api one
Here’s what I’m using:
(let [state (cljs.env/default-compiler-env)
resource (io/resource "stub_test.cljc")]
(comp/with-core-cljs state nil #(ana/analyze-file state resource nil))
(mapv :name (vals (ana/ns-publics state 'stub-test))))
With that, I get:
[stub-test/normal-def
stub-test/normal-defn
stub-test/hidden-defmacro2
stub-test/gen-clj-stuff
stub-test/NormalProtocol
stub-test/hidden-defmacro5
stub-test/gen-stuff
stub-test/hidden-defmacro6
stub-test/normal-multimethod
stub-test/hidden-defmacro4
stub-test/normal-method
stub-test/hidden-defmacro3
stub-test/hidden-defmacro
stub-test/normal-macro]
Am I using the API wrong?
ns-publics is probably what's sending you down the wrong path - let me read over that
yes I would read over ns-publics
🙂
so the reasoning behind this behavior is that really for self-referencing files, the defs and the macros are the ns-publics of that file
just like Clojure
because for end users, you're going to want to know about defs and macros because these can all be :refer
ed
so doing it this way is more like Clojure, and it would let an autodoc tool get everything at once instead of doing something special to get at the macros provided by a library
if you want the true :defs
I would say get those yourself and skip ns-publics
as to whether or not we should have a public api for just that - I'm a bit skeptical and honestly I don't see the compiler state representation changing - not worth the hassle
Ok, so I think I understand why the macro problem occurs. I still don’t understand why the elements generated by gen-stuff
are not. Is that because analysis doesn’t actually execute top-level forms?
Yeah, I think that is reasonable (re; the public API).
ok so we've sorted out the first half of your problem - on to the next half
so first question
I do not understand the last line
you're using a macro that's only defined in Clojure but you didn't put it behind a reader conditional
This may be my superficial knowledge of CLJS macros showing. My understanding was that macros were defined in CLJ but used in CLJS. Is that not correct?
but you didn't refer the macro
Argh
you cannot just use it because you self-referenced via :require-macros
- you need to refer
or use an aliased reference
Indeed, (stub-test/gen-stuff)
works!
BOOM!
Great, thank you - that was very enlightening 🙂
no problem
How does data readers work on clojurescript? They seem to be executed in java, which means that objects won't be converted to clojurescript. Should they return a code form?
yeah they’re similar to macros
How can I create a reader which works in clojure and cljs? I should have mentioned my actual question :)
In Clojure, I return the object.
Just peeking at what #uuid does, it seems it creates a java.util.UUID, and then defines https://github.com/clojure/clojurescript/blob/b68f0a0de19384f736ab10912001519249737e56/src/main/clojure/cljs/compiler.cljc#L423-L425 Not sure if that's something user-space should do.
I think this is more illustrative of how to write a tag handler for cljs: https://github.com/clojure/clojurescript/blob/master/src/main/clojure/cljs/tagged_literals.cljc#L21
takes in the form after the tag, returns another form for the compiler