Highlights:
- Give "_upname" the visible name "type_identifier". Name stolen
shamelessly from tree-sitter-rust.
- Remove "record_name" in favor of "type_identifier".
- Remote "function_name" in favor of "identifier".
- Surface names for several nodes, mostly using "type_identifier".
- Remove "remote_" variants of several nodes. Essentially we needed to
give these nodes "names" anyhow, and having the name encapsulate the
local vs remote information proved wildly efficient.
In a previous commit, I removed several encapsulating nodes such as
"parameters" or "arguments" where they were not absolutely necessary.
While reviewing tree-sitter-rust, I noticed that they always
incorporated these encapsulating nodes. This likely helps with AST-based
code navigation, and so I introduced or re-introduced them here.
This commit primarily introduces the ability to parse custom types and
type aliases. The tests for these constructs are contained in the
subsequent commit, because they were written against the "cleaned up"
AST.
- Combine "type" and "type_constructor" across the board into
"type". These two had represented the same thing for a while, with the
latter simply being a "generic" type that has parameters, but now the
difference is exactly that; the presence of parameters. Also the name
"type_constructor" was needed for inside custom type definitions.
- Remove the "parameter" field for functions that do not have them.
- Correct mistaken usages of "type" when "type_name" was meant.
- Correct mistaken usages of "type_argument" when "type_parameter" was
meant.
The Gleam parser contains a function called `parse_bit_string_segment`
that contains the logic for how to parse bit_strings for constants,
patterns, and expression units by allowing callers to pass functions to
parse the values and arguments. After much trial-and-error, I managed to
functionally replicate this function within the tree-sitter grammar.
Types for constants are more restricted than types for other parts of
the language. The way that the Gleam parser handles this is by having
the `parse_type` function pass along a `for_const` boolean, which is
used to limit valid subnodes. I tried replicating this functionality in
tree-sitter by creating a `parse_type($, for_const)` function, and
calling that instead of `$.type`. tree-sitter did not like this, saying
that the call stack became too deep.
Thus, I arrived at my current solution, which is simply to have
largely duplicate type rules for constants vs not-constants.
Another possible approach would be to _generate_ the type rules via a
`gen_types($, for_const)` function, which could be embedded into the
rules list like so:
```
/* Special constant types */
...gen_types($, true),
// other stuff
/* Types */
...types($, false),
```
I may try that later.