Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[Suggestion] Consider TypeScript over Custom AST Format #256

Closed
sinclairzx81 opened this issue Sep 13, 2021 · 7 comments
Closed

[Suggestion] Consider TypeScript over Custom AST Format #256

sinclairzx81 opened this issue Sep 13, 2021 · 7 comments

Comments

@sinclairzx81
Copy link

Hi. Just wanted make a suggestion for potentially leveraging TypeScript interface and type definitions over the existing custom format used to describe AST nodes.

Looking at #208, perhaps instead of offering a single up to date normalized specification, maybe a potential exists to use TypeScript definitions for the AST Nodes in each specification, and linking dependent nodes via import. The TypeScript team do something similar for the various JavaScript ES revisions here, so had been wondering if a similar approach could be taken for ESTree. Allowing for something like....

import * as AST from './es2022'

// or...

import * as AST from './es5'

Appreciate it's a bit of change, But there would be a few immediate wins by leveraging TypeScript over the existing format.

  • Easy navigation of nodes in the spec. Users could leverage TypeScript's Language Service (built into vscode) to "Go to Definition" for nodes within the imported specification.
  • Auto documentation of .md files (derived by the TypeScript definitions)
  • Ability to generate language agnostic JSON AST to allow non TypeScript languages to consume the specification.
  • Ability for TypeScript projects to implement parsers that emit to known AST in the specification provided by ESTree.
  • TypeScript compiler / type assertions for Nodes across each specification.

I'm currently considering doing this for a local project (specifically TypeScript), so just wanted to put this suggestion on the table in case there is value in considering this for the ESTree project itself.

Also, Thanks for all the hard work on ESTree over the years.

@sinclairzx81
Copy link
Author

sinclairzx81 commented Sep 13, 2021

@bradzacher Hey thanks for the response, and for the link, I actually hadn't seen that before, but I shouldn't be too surprised downstream projects are expressing nodes directly in TypeScript (given how similar the formats are).

But from this, do you suppose there would be much value in having ESTree consider TypeScript given that downstream projects (like eslint) are essentially replicating the AST Nodes downstream, and that the formats are so similar?

Actually, I'm not sure if eslint uses some codegen pass to generate the types from ESTree, but the thought had also crossed my mind that if ESTree were to define Nodes in a language agnostic format (such as JSON or XML); then downstream projects (such as eslint) would have an easy path to generating Nodes on each iteration of the spec. Of course, this would be an alternative to TypeScript specifically, and probably a bit more useful for other languages to consume.

Happy to close off this issue if TypeScript is just not on the table, but would be cool to get some thoughts on expressing the specification in JSON as an alternative.

Thanks again

@bradzacher
Copy link

Note: I am not on the team here, just a downstream maintainer.


Actually, I'm not sure if eslint uses some codegen pass to generate the types from ESTree

ESLint has no types. It is pure JS. Its default parser (espree) is the same.


Note that there is also the community maintained https://github.com/DefinitelyTyped/DefinitelyTyped/tree/master/types/estree (published to npm as @types/estree).

It is maintained by hand as the community wants types. It only implements the nodes from this repo.

For typescript-eslint we support TS syntax, meaning our representation is actually the "ts-estree" ast (estree with extensions for TS syntax).

We define all the types locally in ts-estree instead of augmenting @types/estree because TS does not do union type augmentation at all - only interface extension via declaration merging with module augmentation.

So we would need a format which allows us to not only generate the base types and their unions, but also extend the base types with new properties, and augment the unions with new nodes. Possible, but likely would be.. difficult.

Note that I've worked with defining flow types for flow-estree and the same issues and requirements exist (doubly so as flow has no augmentation features).

@sinclairzx81
Copy link
Author

@bradzacher Thanks for the insights.

TS does not do union type augmentation at all - only interface extension via declaration merging with module augmentation.

I guess declaration merging would be quite awkward, and I guess augmenting nodes via & and type aliases would be against the grain.

interface A { a: number }
interface B { b: string }
interface C { c: boolean }

type T0 =  A | B  & C // default:   A | (B & C)
type T1 = (A | B) & C // override: (A | B) & C

Still quite curious with respect to a metadata representation of these Nodes though. That would at least yield easier downstream codegen vs manually creating these types in some target language. Quite curious to see if the ESTree contributors have any thoughts on this. Notable as it would allow them to generate the current .md files while also providing machine readable metadata for downstream implementations.

@j-f1
Copy link
Contributor

j-f1 commented Sep 13, 2021

Check out my related PR: #232

@sinclairzx81
Copy link
Author

Going to close this issue. The more I think about it, the more I tend to think that expressing each AST node in some language agnostic format is probably the way to go. While the ESTree nodes are expressed by way of the current format (which could be argued is language agnostic), it's not necessarily a easily digestible data format that downstream implementers could map to their respective languages.

This said, considering TypeScript for the AST representation would only really be useful to JavaScript / TypeScript programmers, and thus is a bit of a non-starter.

Would still be interested to hear from the ESTree contributors on perhaps considering a JSON representation of each Node. I'm not entirely sure what form such a representation would take, but possibly JSON Schema Draft 2019-09 (or above) could service as a reasonable starting point.

Thanks all.

@RReverser
Copy link
Member

Note that you might want to take a look at https://github.com/estree/formal which has parser for ESTree specs, produces an AST that can be saved to JSON and can even generate TypeScript definitions (although I haven't updated it in a while, because community-based definitions are better anyway as they can express more constraints).

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

4 participants