<< Back to previous view

[TANAL-42] Document the AST nodes && the passes Created: 03/Jan/14  Updated: 03/Jun/14

Status: Open
Project: tools.analyzer
Component/s: None
Affects Version/s: None
Fix Version/s: None

Type: Task Priority: Critical
Reporter: Nicola Mometto Assignee: Nicola Mometto
Resolution: Unresolved Votes: 0
Labels: None

Comment by Max Kreminski [ 19/Apr/14 5:11 PM ]

I put together a quick reference to the AST node structures a few days ago when trying to identify discrepancies between the tools.analyzer AST format and the internal AST format used by the ClojureScript compiler. It's nowhere near as complete as it could be, but I figured I'd post it here just in case it winds up being useful when writing official docs.


Comment by Nicola Mometto [ 19/Apr/14 5:36 PM ]

At first glance it looks really well done.
I'll take some time to review it and contribute if necessary, in the mean time if you want you can add a link pointing at your quickref in the tools.analyzer wiki.


Comment by Ian Tegebo [ 29/May/14 12:59 AM ]

It appears incomplete, e.g. :static-call is missing. This appears to be because it's added not by tools.analyzer but by tools.analyzer.jvm; is the intention that platform-specific AST nodes are to be considered hidden implementation details?

If not, should a separate issue requesting documentation be filed with the "concrete" platforms, e.g. jvm.tools.analyzer?

Comment by Max Kreminski [ 02/Jun/14 11:49 AM ]

I haven't yet had time to document the platform-specific node types added by tools.analyzer.{jvm,js}, although I do intend to add them to the quickref in the near future.

jvm.tools.analyzer appears to use a similar but incompatible AST format, which I currently don't plan on trying to document in the quickref. Filing a separate issue on that project might be the best way to move forward there.

Comment by Andy Fingerhut [ 03/Jun/14 11:21 AM ]

jvm.tools.analyzer is probably not worth documenting at this time, except for historical purposes. tools.analyzer.{jvm,js} are far more likely to be maintained and enhanced in the future.

Comment by Ian Tegebo [ 03/Jun/14 11:58 AM ]

Oops, I think I introduced some confusion when I mistakenly referenced jvm.tools.analyzer. I did so because I didn't see a JIRA project for tools.analyzer.jvm.

On 29/May14 12:59 AM, I meant "... the 'concrete' platforms, e.g. tools.analyzer.{jvm,js} ...".

As an aside, had anyone considered a slight rewrite of the code so that AST (reference) documentation can be extracted rather than separately maintained?

[TANAL-24] clojure.tools.analyzer.passes.jvm/validate throws an exception when :tag metadata cannot be resolved to a Class Created: 04/Dec/13  Updated: 02/Apr/14

Status: Reopened
Project: tools.analyzer
Component/s: None
Affects Version/s: None
Fix Version/s: None

Type: Defect Priority: Minor
Reporter: Andy Fingerhut Assignee: Nicola Mometto
Resolution: Unresolved Votes: 1
Labels: None


While the Clojure Compiler silently ignores :tag metadata in some forms when it cannot be resolved to a class, c.t.a.passes.jvm/validate throws an exception every time.

Some libraries (test.generators) use :tag metadata to store instructions for generating test input data, those can be everything, from symbols to quoted clojure expressions – the Clojure Compiler allows for this but validate throws an exception.

Generally however, when :tag cannot be resolved to a class it's not beacause of a design choice, but because of a Clojure bug or a user-code bug.

Some examples are:

  • tagging a defn form in the fn name with a primitive type hint:
    user=> (defn ^long x [] 1)
    user=> (:tag (meta #'x))
    #<core$long clojure.core$long@6596f6ef>
  • using extend-type with a run-time resolved class http://dev.clojure.org/jira/browse/CLJ-1308
    user=> (defprotocol p (f [_]))
    user=> (binding [*print-meta* true] (pr (macroexpand-1 '(extend-type (class 1) p (f [_])))))
    (clojure.core/extend (class 1) p {:f (fn ([^(class 1) _]))})
  • type hinting a form in a namespace with an imported class doesn't qualify the class in :tag http://dev.clojure.org/jira/browse/CLJ-1232
    user=> (ns foo (:import clojure.lang.RT))
    foo=> (defn x ^RT [])
    foo=> (ns bar (:use foo))
    bar=> (:tag (meta #'x))
    bar=> (.hashCode (x))
    CompilerException java.lang.IllegalArgumentException: Unable to resolve classname: RT, compiling:(NO_SOURCE_PATH:5:1)

A clojure-dev post has been opened asking whether tools.analyzer.jvm is correct in assuming that non class-resolvible tags are an error and thus an exception could be thrown, or if the current behaviour of the Cloure implementation of throwing in some special places and silently ignoring malformed :tag values is by design. It hasn't have received an official reply yet. https://groups.google.com/d/msg/clojure-dev/hRZFuaiB_50/mzKLirgZWmUJ

Comment by Nicola Mometto [ 05/Dec/13 9:23 AM ]

This is somewhat an undefined behaviour in clojure, it's not clear to me from the documentation wether tagging elements with things that cannot be resolved to a class should work or not.

I'll ask the clojure-dev ML about this before doing anything.


Comment by Nicola Mometto [ 05/Dec/13 2:00 PM ]

clojure-dev post: https://groups.google.com/d/msg/clojure-dev/hRZFuaiB_50/mzKLirgZWmUJ

Comment by Andy Fingerhut [ 02/Apr/14 1:24 PM ]

Ticket TGEN-5 was created on test.generative as a result of this issue, too, with a suggested patch so that test.generative no longer 'leaks' such tag values.

Generated at Wed Jul 23 18:50:30 CDT 2014 using JIRA 4.4#649-r158309.