🧊

JavaScriptのASTにおける、コメントの扱いについて

ちょっと調べる機会があったので、まとめておく。

JavaScriptのAST

まず前提のおさらい。

JSにおけるASTは、言語自体のSpecにそういうのがあるわけではなく、コミュニティによって形成されたデファクトがあるというだけ。

それがESTreeって呼ばれてるやつ。

estree/estree: The ESTree Spec https://github.com/estree/estree

ただお察しの通り、これは有志の同意がなんとなく寄り集まって形になってるだけで、たとえばJSXみたいなものは含まれてなかったりする。

あくまでESTreeのスコープとしては、ES5とかES2022とかそういう本質的なものだけ。

Define scope of this project · Issue #219 · estree/estree https://github.com/estree/estree/issues/219

(まぁスコープも何も、そんな責任境界を求められてもな・・・感はあると思うけど)

そういうわけで、たとえばJSXなんかは独自に拡張された結果であり、言い出しっぺがその仕様を公開して、

https://github.com/facebook/jsx/blob/main/AST.md

それをまた有志のパーサー各位が、実装したりしてなかったりする。

ESTree 互換っぽい AST を出力する JavaScript のパーサーまとめ https://zenn.dev/sosukesuzuki/scraps/fa4d48f9098d66

という結果がそこにあるだけ。

ESTreeのリポジトリのIssueを見てると、そういう数多の葛藤が浮き沈みしてるのがわかって趣深い。

ESTreeにおけるコメント

で、本題。

そもそもコメントは、ESTreeのASTには含まれてない。

Standardize Comment Types · Issue #201 · estree/estree https://github.com/estree/estree/issues/201

その理由をざっくりまとめると・・・、

  • 既にいろんなコンテキストで使われててエコシステムもあり、今さら感
    • JSDoc, Flow, Prettier, etc…
  • コメントはどこにでも書けるので、どう解釈したいかは、実装側がよしなにするほうがいい

って感じか。

実際のところ、

  • 行コメント
  • 複数行コメント

みたいなタイプを追加するだけなら簡単で、実際にそれをやってくれてるパーサーもある。

けど、結局はJSDocのそれみたく「何に対するコメント?」ってのが本当に知りたいものであるはず。

なのに肝心のその表現は、実装・コンテキストごとに異なるという。

// JSDocは後に
/** @type {number} */ const tsTyped = something();

// Flowは前に
const flowTyped /*: number*/ = something();

これをまとめるのはまあ・・難しいよな・・。

そのほか

ASTツーリング界隈は奥深い。