|
| 1 | +<!--lint disable no-html--> |
| 2 | + |
| 3 | +# [![esast][logo]][site] |
| 4 | + |
| 5 | +**E**CMA**S**cript **A**bstract **S**yntax **T**ree format. |
| 6 | + |
| 7 | +*** |
| 8 | + |
| 9 | +**esast** is a specification for representing [JavaScript][] as an abstract |
| 10 | +[syntax tree][syntax-tree]. |
| 11 | +It implements the [**unist**][unist] spec. |
| 12 | + |
| 13 | +This document may not be released. |
| 14 | +See [releases][] for released documents. |
| 15 | +The latest released version is [`0.0.0`][latest]. |
| 16 | + |
| 17 | +## Contents |
| 18 | + |
| 19 | +* [Introduction](#introduction) |
| 20 | + * [Where this specification fits](#where-this-specification-fits) |
| 21 | + * [ESTree](#estree) |
| 22 | +* [Nodes](#nodes) |
| 23 | + * [`Node`](#node) |
| 24 | + * [`RegExpLiteral`](#regexpliteral) |
| 25 | + * [`BigIntLiteral`](#bigintliteral) |
| 26 | +* [Recommendations](#recommendations) |
| 27 | +* [Glossary](#glossary) |
| 28 | +* [List of utilities](#list-of-utilities) |
| 29 | +* [References](#references) |
| 30 | +* [Security](#security) |
| 31 | +* [Related](#related) |
| 32 | +* [Contribute](#contribute) |
| 33 | +* [Acknowledgments](#acknowledgments) |
| 34 | +* [License](#license) |
| 35 | + |
| 36 | +## Introduction |
| 37 | + |
| 38 | +This document defines a format for representing ECMAScript as an [abstract |
| 39 | +syntax tree][syntax-tree]. |
| 40 | +Development of esast started in February 2021. |
| 41 | +This specification is written in a [Web IDL][webidl]-like grammar. |
| 42 | + |
| 43 | +### Where this specification fits |
| 44 | + |
| 45 | +esast extends [unist][], a format for syntax trees, to benefit from its |
| 46 | +[ecosystem of utilities][utilities]. |
| 47 | +There is one important difference with other implementations of unist: children |
| 48 | +are added at fields other than the `children` array and the `children` field is |
| 49 | +not used. |
| 50 | + |
| 51 | +esast relates to [ESTree][] in that the first is a superset of the latter. |
| 52 | +Any tool that accepts an ESTree also supports esast. |
| 53 | + |
| 54 | +esast relates to [JavaScript][], other than that it represents it, in that it |
| 55 | +has an [ecosystem of utilities][list-of-utilities] for working with compliant |
| 56 | +syntax trees in JavaScript. |
| 57 | +However, esast is not limited to JavaScript and can be used in other programming |
| 58 | +languages. |
| 59 | + |
| 60 | +esast relates to the [unified][] project in that esast syntax trees are used |
| 61 | +throughout its ecosystem. |
| 62 | + |
| 63 | +### ESTree |
| 64 | + |
| 65 | +ESTree is great but it is missing some things: |
| 66 | + |
| 67 | +* Trees can’t be roundtripped through `JSON.parse(JSON.stringify(s))`, |
| 68 | + leading to cache troubles |
| 69 | +* Columns are 0-indexed, whereas most text editors display 1-indexed |
| 70 | + columns, leading to a tiny discrepancy or some math to display warnings |
| 71 | +* There is no recommendation for range-based positional info, |
| 72 | + leading implementations to scatter them in different places |
| 73 | +* There is no safe space for metadata, |
| 74 | + leading implementations to scatter them in different places |
| 75 | +* There are no recommendations for how to handle JSX, comments, or raw values |
| 76 | + |
| 77 | +These are minor nits, which is why esast is a superset. |
| 78 | + |
| 79 | +## Nodes |
| 80 | + |
| 81 | +### `Node` |
| 82 | + |
| 83 | +```idl |
| 84 | +extend interface Node <: UnistNode {} |
| 85 | +``` |
| 86 | + |
| 87 | +All esast nodes inherit from unist’s [Node][unist-node] and are otherwise the |
| 88 | +same as their ESTree counterparts, with the exception of `RegExpLiteral` and |
| 89 | +`BigIntLiteral`. |
| 90 | + |
| 91 | +### `RegExpLiteral` |
| 92 | + |
| 93 | +The `regex` field on |
| 94 | +[`RegExpLiteral`](https://github.com/estree/estree/blob/master/es5.md#regexpliteral) |
| 95 | +must be used whereas the `value` field of such literals should be `null` and |
| 96 | +must be ignored. |
| 97 | + |
| 98 | +### `BigIntLiteral` |
| 99 | + |
| 100 | +The `bigint` field on |
| 101 | +[`BigIntLiteral`](https://github.com/estree/estree/blob/master/es2020.md#bigintliteral) |
| 102 | +must be used whereas the `value` field of such literals should be `null` and |
| 103 | +must be ignored. |
| 104 | + |
| 105 | +## Recommendations |
| 106 | + |
| 107 | +For JSX, follow the |
| 108 | +[JSX extension](https://github.com/facebook/jsx/blob/master/AST.md) |
| 109 | +maintained in `facebook/jsx`. |
| 110 | + |
| 111 | +For type annotations, follow the |
| 112 | +[Type annotations extension](https://github.com/estree/estree/blob/master/extensions/type-annotations.md) |
| 113 | +maintained in `estree/estree`. |
| 114 | + |
| 115 | +`raw` fields (added by most parsers) should not be used: they create an extra |
| 116 | +source of truth, which is often not maintained. |
| 117 | + |
| 118 | +`start`, `end`, and `range` fields should not be used. |
| 119 | + |
| 120 | +`comments` should not be added on nodes other that `Program`. |
| 121 | +When adding comments, use the `'Block'` (for `/**/`) or `'Line'` (for `//`) |
| 122 | +types. |
| 123 | +Do not use `leading` or `trailing` fields on comment nodes. |
| 124 | + |
| 125 | +`tokens` should not be used. |
| 126 | + |
| 127 | +## Glossary |
| 128 | + |
| 129 | +See the [unist glossary][glossary] but note of the following deviating terms. |
| 130 | + |
| 131 | +###### Child |
| 132 | + |
| 133 | +Node X is **child** of node Y, if X is either referenced directly or referenced |
| 134 | +in an array at a field on node Y. |
| 135 | + |
| 136 | +###### Sibling |
| 137 | + |
| 138 | +Node X is a **sibling** of node Y, if X and Y have the same parent (if any) and |
| 139 | +X and Y are both referenced in an array at a field on node Y. |
| 140 | + |
| 141 | +## List of utilities |
| 142 | + |
| 143 | +See the [unist list of utilities][utilities] for more utilities. |
| 144 | + |
| 145 | +* [`estree-util-build-jsx`](https://github.com/wooorm/estree-util-build-jsx) |
| 146 | + — Transform JSX to function calls |
| 147 | +* [`estree-util-is-identifier-name`](https://github.com/wooorm/estree-util-is-identifier-name) |
| 148 | + — Check if something can be an identifier name |
| 149 | + |
| 150 | +Please use either `estree-util-` (if it works with all ESTrees, preferred) |
| 151 | +or `esast-util-` (if it uses on esast specific features) as a prefix. |
| 152 | + |
| 153 | +See also the [`estree`](https://github.com/search?q=topic%3Aestree\&s=stars\&o=desc) |
| 154 | +topic on GitHub. |
| 155 | + |
| 156 | +## References |
| 157 | + |
| 158 | +* **unist**: |
| 159 | + [Universal Syntax Tree][unist]. |
| 160 | + T. Wormer; et al. |
| 161 | +* **JavaScript**: |
| 162 | + [ECMAScript Language Specification][javascript]. |
| 163 | + Ecma International. |
| 164 | +* **JSON** |
| 165 | + [The JavaScript Object Notation (JSON) Data Interchange Format][json], |
| 166 | + T. Bray. |
| 167 | + IETF. |
| 168 | +* **Web IDL**: |
| 169 | + [Web IDL][webidl], |
| 170 | + C. McCormack. |
| 171 | + W3C. |
| 172 | + |
| 173 | +## Security |
| 174 | + |
| 175 | +As esast represents JS, and JS can open you up to a bunch of problems, esast is |
| 176 | +also unsafe. |
| 177 | +Always be careful with user input. |
| 178 | + |
| 179 | +## Related |
| 180 | + |
| 181 | +* [hast](https://github.com/syntax-tree/hast) — HTML |
| 182 | +* [mdast](https://github.com/syntax-tree/mdast) — Markdown |
| 183 | +* [nlcst](https://github.com/syntax-tree/nlcst) — Natural language |
| 184 | +* [xast](https://github.com/syntax-tree/xast) — XML |
| 185 | + |
| 186 | +## Contribute |
| 187 | + |
| 188 | +See [`contributing.md`][contributing] in [`syntax-tree/.github`][health] for |
| 189 | +ways to get started. |
| 190 | +See [`support.md`][support] for ways to get help. |
| 191 | +Ideas for new utilities and tools can be posted in [`syntax-tree/ideas`][ideas]. |
| 192 | + |
| 193 | +A curated list of awesome syntax-tree, unist, mdast, esast, xast, and nlcst |
| 194 | +resources can be found in [awesome syntax-tree][awesome]. |
| 195 | + |
| 196 | +This project has a [code of conduct][coc]. |
| 197 | +By interacting with this repository, organization, or community you agree to |
| 198 | +abide by its terms. |
| 199 | + |
| 200 | +## Acknowledgments |
| 201 | + |
| 202 | +The initial release of this project was authored by |
| 203 | +[**@wooorm**](https://github.com/wooorm). |
| 204 | + |
| 205 | +## License |
| 206 | + |
| 207 | +[CC-BY-4.0][license] © [Titus Wormer][author] |
| 208 | + |
| 209 | +<!-- Definitions --> |
| 210 | + |
| 211 | +[health]: https://github.com/syntax-tree/.github |
| 212 | + |
| 213 | +[contributing]: https://github.com/syntax-tree/.github/blob/HEAD/contributing.md |
| 214 | + |
| 215 | +[support]: https://github.com/syntax-tree/.github/blob/HEAD/support.md |
| 216 | + |
| 217 | +[coc]: https://github.com/syntax-tree/.github/blob/HEAD/code-of-conduct.md |
| 218 | + |
| 219 | +[awesome]: https://github.com/syntax-tree/awesome-syntax-tree |
| 220 | + |
| 221 | +[ideas]: https://github.com/syntax-tree/ideas |
| 222 | + |
| 223 | +[license]: https://creativecommons.org/licenses/by/4.0/ |
| 224 | + |
| 225 | +[author]: https://wooorm.com |
| 226 | + |
| 227 | +[logo]: https://raw.githubusercontent.com/syntax-tree/esast/0000000/logo.svg?sanitize=true |
| 228 | + |
| 229 | +[site]: https://unifiedjs.com |
| 230 | + |
| 231 | +[releases]: https://github.com/syntax-tree/esast/releases |
| 232 | + |
| 233 | +[latest]: https://github.com/syntax-tree/esast/releases/tag/2.3.0 |
| 234 | + |
| 235 | +[list-of-utilities]: #list-of-utilities |
| 236 | + |
| 237 | +[unist]: https://github.com/syntax-tree/unist |
| 238 | + |
| 239 | +[syntax-tree]: https://github.com/syntax-tree/unist#syntax-tree |
| 240 | + |
| 241 | +[javascript]: https://www.ecma-international.org/ecma-262/9.0/index.html |
| 242 | + |
| 243 | +[json]: https://tools.ietf.org/html/rfc7159 |
| 244 | + |
| 245 | +[webidl]: https://heycam.github.io/webidl/ |
| 246 | + |
| 247 | +[glossary]: https://github.com/syntax-tree/unist#glossary |
| 248 | + |
| 249 | +[utilities]: https://github.com/syntax-tree/unist#list-of-utilities |
| 250 | + |
| 251 | +[unified]: https://github.com/unifiedjs/unified |
| 252 | + |
| 253 | +[estree]: https://github.com/estree/estree |
| 254 | + |
| 255 | +[unist-node]: https://github.com/syntax-tree/unist#node |
0 commit comments