oxc-project / oxc-project/backlog
AST: Remove Elision type.
Nobody has claimed this yet.
- Dominant language
- No language data
- Stars
- 7
- Forks
- 0
- PR merge metrics
- No merged PRs in 30d
Description
Summary
Represent array holes as None entries in ArrayExpression::elements and remove the synthetic Elision AST node and enum variant.
An elision is the absence of an array element between commas. Modeling absence as a boxed node gives it identity, span, visitor callbacks, and builder APIs that do not correspond to an ESTree node or a runtime expression.
Motivation
Sparse arrays contain holes:
[,]
[1, , 3]
[1, ,]
Oxc currently creates ArrayExpressionElement::Elision(Box<Elision>) for each hole.
The current representation permits artificial states and unnecessary work:
- an
Elisionvalue can be constructed outside an array; - a hole owns a
NodeIdeven though there is no syntax node to reference semantically; - visitors and transforms must handle an otherwise empty node;
- consumers repeatedly call
is_elision()and branch inside the element enum; - every hole requires a boxed arena allocation.
A trailing comma is not itself an extra hole. The vector representation must continue to distinguish [1,] from [1,,] using the parser's delimiter/trailing-comma tracking.
Current AST Shape
pub struct ArrayExpression<'a> {
pub node_id: Cell<NodeId>,
pub span: Span,
pub elements: Vec<'a, ArrayExpressionElement<'a>>,
}
pub enum ArrayExpressionElement<'a> {
SpreadElement(Box<'a, SpreadElement<'a>>) = 64,
Elision(Box<'a, Elision>) = 65,
INHERIT(Expression<'a>),
}
#[estree(via = Null)]
pub struct Elision {
pub node_id: Cell<NodeId>,
pub span: Span,
}
The parser creates an Elision when the current token is a comma inside an array element list.
Proposed AST Shape
pub struct ArrayExpression<'a> {
pub node_id: Cell<NodeId>,
pub span: Span,
pub elements: Vec<'a, Option<ArrayExpressionElement<'a>>>,
}
pub enum ArrayExpressionElement<'a> {
SpreadElement(Box<'a, SpreadElement<'a>>) = 64,
INHERIT(Expression<'a>),
}
The parser pushes None for a comma that denotes a hole and Some(element) for expressions and spreads. Delimiter logic remains responsible for trailing commas so [1,] produces one Some entry while [1,,] produces Some(1), None.
ESTree serialization maps None to null in the elements array. Visitors skip None. Formatter and codegen use element indexes and delimiter metadata rather than an elision span; comments remain attached to surrounding tokens/nodes according to the existing comment model.
Syntax Mapping
| Source form | Current representation | Proposed representation |
|---|---|---|
[] |
Empty vector | Empty vector |
[1] |
[NumericLiteral(1)] |
[Some(NumericLiteral(1))] |
[,] |
[Elision] |
[None] |
[1, , 3] |
[1, Elision, 3] |
[Some(1), None, Some(3)] |
[1,] |
[1] plus trailing-comma metadata |
[Some(1)] plus trailing-comma metadata |
[...xs] |
[SpreadElement] |
[Some(SpreadElement)] |
Guaranteed Invariants
- A hole is represented as the absence of an array element, not a standalone AST node.
ArrayExpressionElementalways contains an actual expression or spread.- Trailing commas remain distinct from holes.
- ESTree
nullentries map directly toNone. - Traversal does not allocate IDs or invoke callbacks for nonexistent elements.
Contributor guide
No contributing guide indexed for this repository
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
Research direction
Start at the parser's array-element handling and trace the ArrayExpressionElement consumers named in the issue: ESTree serialization, visitors, formatter, and codegen. Replace elision entries with None while preserving delimiter and trailing-comma behavior, then verify the listed syntax mappings and invariants, including null ESTree entries and skipped visitor callbacks.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- rust
- Domain
- compilers
- Issue type
- Refactor
- Difficulty
- 4/5
- Estimated time
- 3-5 days
- Activity status
- Active
- Clarity
- Clearly specified
- Newbie friendliness
- 50/100