Also gathers these into a separate side-channel during the initial AST
construction. That way, we don't encounter these as weird extra nodes
while running yeast.
Introduces new yeast types for `Point`s and `Range`s (corresponding to
the tree-sitter equivalents), since it seemed silly to have
`swift-syntax-rs` pull in `tree-sitter` just to have those types
available.
This _does_ mean there is a slight overhead in the shared extractor when
converting between these types, but I think this is negligible.
Adds a preliminary mapping that decodes the JSON into the yeast AST. The
JSON AST itself is still very verbose, but it would be useful to see if
it actually contains all of the things we want it to contain.
Adds an initial prototype of an interface from Rust to Swift, which
enables us to use the `swift-syntax` package for parsing.
At present, the parsed AST is passed between Swift and Rust as a JSON
string.
Turns out, `(_)` would match both named and unnamed nodes, as we never
checked the value of the `match_unnamed` field. This is the real reason
why the final catch-all rule we removed in the last commit was
superfluous -- unnamed nodes were being caught by the penultimate rule
instead (and mapped to `unsupported_node`).
Having fixed the bug, we now (correctly) get errors due to unmatched
unnamed nodes in the input. To fix this, we change the catch-all rule to
match unnamed nodes as well. This restores the previous behaviour
exactly.
At some point, we should find a better way to handle unnamed nodes, as
it seems wasteful to map these to `unsupported_node` (since we in
practice only use them for their string content). Perhaps we should not
attempt to translate unnamed nodes at all?
In order to facilitate static type checking of rules (and to make it
easier for human readers as well), rust blocks at the root level (i.e.
rules of the form `... => { ... }`) must now have a type annotation in
front.
All other forms are unaffected: if the right hand side of a rule is a
tree, we can read the type of the root node directly. For interpolations
that happen inside of such a tree, we can recover the type by looking at
what field we're interpolating into, and consulting the output schema.
All existing uses have been updated to have the appropriate type
annotations, though these are of course not checked yet (and so could be
wrong).
Finally, this commit also removes the final catch-all rule `_ @node =>
{node}`. Because of the preceding rule that matches `(_) @node`, this
rule would only ever match unnamed nodes, and I think in practice it did
not match at all (at least not in our current set of tests).
To give it a proper type we would have to add some notion of an "any"
type, which I would like to avoid. If it _does_ turn out to be needed,
we can easily add it back (ideally with a test-case that shows why it's
still needed).
This macro allows the easy addition of multiple rules at the same time.
In addition, it also accepts an input and output schema, which
eventually will be used to check the validity of the rewrite rules.
For type checking rules, we need to be able to load schemas (so we know
what to check against). However, since we can't have yeast-macros
depending on yeast (where the schema-handling code currently lives) as
this would introduce a circular dependency, we instead split the
schema-related code into its own yeast-schema crate.