Open lread opened 3 years ago
Issue comments from rewrite-cljc-playground:
@lread:
Was chatting with @borkdude on Slack and type came up again. Perhaps a (type node)
might a good addition. @borkdude said that such a feature would allow him to avoid code like this.
@lread: More chats on Slack, @SevereOverfl0w was wondering about querying node types.
We agreed the existing granularity provided by (rewrite-cljc.node/tag n)
is coarser than we'd like.
@borkdude chimed in with examples of what he uses for his custom version of rewrite-clj in clj-kondo:
(defn boolean-token? [node]
(boolean? (:value node)))
(defn char-token? [node]
(char? (:value node)))
(defn string-from-token [node]
(when-let [lines (:lines node)]
(str/join "\n" lines)))
(defn number-token? [node]
(number? (:value node)))
(defn symbol-token? [node]
(symbol? (:value node)))
(defn symbol-from-token [node]
(when-let [?sym (:value node)]
(when (symbol? ?sym)
?sym)))
And then @borkdude also shared another idea:
a function that returned some keyword could also be handy if you want to dispatch on something:
(defn tag+ [node] (if (symbol? (:value node)) :symbol) ...) (case (tag+ node) :symbol ...)
I think I have something like that too in clj-kondo this could also go into some extra utils lib or utils ns
I think I like the idea of a tag+
(or maybe node-type
) to avoid littering our already wide node and zip APIs with a bunch of new little functions.
One idea is to also use (isa? :rewrite-clj/symbol :rewrite-clj/token)
, possibly.
One idea is to also use
(isa? :rewrite-clj/symbol :rewrite-clj/token)
, possibly.
Directly related: https://github.com/clj-commons/rewrite-clj/issues/131#issuecomment-1006716628
I already wondered where I left that comment, thanks.
Ha! Yeah, I was searching for it yesterday, oddly enough!
Draft 0 of hierarchy: tag+ name, example/desc, current tag, node record
rewrite-clj.tag/forms
top-level forms holder :forms
FormsNode
rewrite-clj.tag/token
(classifier)
rewrite-clj.tag/symbol
foo
:token
SymbolNode
rewrite-clj.tag/string
"foo"
:token
StringNode
rewrite-clj.tag/string-multi-line
"foo
bar"
:multi-line
StringNode
rewrite-clj.tag/keyword
:mykw
:token
KeywordNode
rewrite-clj.tag/boolean
false
:token
TokenNode
rewrite-clj.tag/number
42
:token
TokenNode
rewrite-clj.tag/character-literal
\newline
:token
TokenNode
rewrite-clj.tag/regex
#"\d+"
:regex
RegexNode
rewrite-clj.tag/clojure-whitespace
(classifier)
rewrite-clj.tag/horizontal-whitespace
tab(s), space(s) :whitespace
WhitespaceNode
rewrite-clj.tag/newline
carriage return(s), linefeed(s) :newline
NewlineNode
rewrite-clj.tag/comma
,
:comma
CommaNode
rewrite-clj.tag/sequence
(classifier)
rewrite-clj.tag/map
{:a 1 :b 2}
:map
SeqNode
rewrite-clj.tag/namespace-map
#:prefix{:a 1 :b 2}
:namespaced-map
NamespacedMapNode
rewrite-clj.tag/vector
[1 2 3]
:vector
SeqNode
rewrite-clj.tag/set
#{1 2 3}
:set
SeqNode
rewrite-clj.tag/map-qualifier
qualifier for namespace map :map-qualifier
MapQualifierNode
rewrite-clj.tag/meta
^foo []
:meta
MetaNode
rewrite.clj.tag/legacy-meta
#^foo []``:meta*
MetaNode
rewrite-clj.tag/comment
; foo
:comment
CommentNode
rewrite-clj.tag/uneval
#_ ignore-me
:uneval
UnevalNode
rewrite-clj.tag/reader-macro
#my-macro 42
:reader-macro
ReaderMacroNode
|rewrite-clj.tag/var-quote
#'my-var
:var
ReaderNode
rewrite-clj.tag/eval
#=(inc 1)
:eval
ReaderNode
rewrite-clj.tag/quote
'sym
:quote
QuoteNode
rewrite-clj.tag/syntax-quote
`map
:syntax-quote
QuoteNode
rewrite-clj.tag/unquote
~mysym
:unquote
QuoteNode
rewrite-clj.tag/unquote-splicing
~@body
:unquote-splicing
QuoteNode
Thoughts:
rewrite-clj.tag+
? I think rewrite-clj.tag
is fine, it is a new thing and doesn't need the +
.#_
is a rewrite-clj-ism, I like the name but Cloure docs call this "discard" I suppose we could make a discard parent and have uneval as a child to fashion a synonym#foo 42
and reader conditionals. If we did that, would we still need reader-macro? rewrtite-clj.tag/sequence
is probably not great, as a map is not really a sequence. Maybe instead rewrite-clj.tag/collection
?Among the "reader-macro" things, here's a fun construct I didn't know about for a long time [1] [2]:
#user.Fun[1 2]
#user.Fun{:a 1 :b 2}
Haven't seen it very much in the wild (^^;
[1] There are even some docs.
[2] Here is where I struggled with naming...
Hi @sogaiu! Thanks so much for sharing! :heart:
I did not know about that syntax, thanks! I'll compare my list above with the elements that tree-sitter-clojure recognizes and look for anything else I might have missed.
If you see anything missing or amiss in tree-sitter-clojure, please mention!
Originally raised by me as https://github.com/lread/rewrite-cljc-playground/issues/5
Related to #113 - capturing valuable feedback from @sogaiu so I don't lose it. Need to review and evaluate more type related helpers.
Snippit from @sogaiu
Also: pointer to similar can be found within clj-kondo fork of rewrite-clj.