Closed bakkot closed 5 years ago
Prior art: https://github.com/babel/babel/tree/master/packages/babel-template
(Well, kind of. Towards the same end, anyway.)
One useful idea from that is that the magic syntax (in our case, the magic comment) should be configurable.
Currently, if you want to refer to a particular node in an AST which is parsed from source text, you have to encode the path to it directly. This is awkward for several reasons: it requires writing down the names of all intermediate nodes, many of which you may not care about, and it is fragile to changes in source which may add or reorder nodes.
I propose that we add a way of naming some nodes which would allow one to address those nodes by name, rather than path.
Specifically, I propose we add a tool (possibly in this repository, possibly elsewhere) which would consume source text which included comments of the form
/* shift # ExpressionStatement # foobar */
(syntax bikesheddable), whereExpressionStatement
is any terminal node type (e.g. notStatement
) andfoobar
is any identifier, and which would produce a map from those identifiers to their corresponding nodes in the AST (where "corresponding" means "immediately following").Some details:
BinaryExpression
s.ParserWithLocation
, rather than source text directly.Expression
.{
s or(
forFunctionBody
andFormalParameters
, since there is no way to put a comment in the right place when those nodes are empty. We might want to allow intervening open parentheses in general anyway; given the "if there are two nodes starting here the outermost wins" rule, I don't think this would risk much confusion.Use cases:
Templating:
In the simplest sort of template, you would just have placeholder nodes which would be replaced (possibly in a way depending on the original node). If you're willing to have mutation, you can do something like
In practice you'd probably like to be immutable and a bit more reusable; an example such templater might look like
this.
```js class SimpleTemplater { constructor(nodeMap /* MapA more advanced version of this could allow treating certain node names as positions in lists (for nodes which can have many children, like
Block
), and allow inserting or removing items at that position.Tests:
Often in our tests we want to make an assertion about some particular node in an AST which is produced from source text. We currently just path to those nodes. Given this framework, you could instead have a small helper like
which could then be used like