oxc-project / oxc-project/backlog
Replace `Ancestor` methods with fields
Nobody has claimed this yet.
- Dominant language
- No language data
- Stars
- 7
- Forks
- 0
- PR merge metrics
- No merged PRs in 30d
Description
Ancestor types in oxc_traverse currently require field access via methods:
fn enter_expression(&mut self, expr: &Expression<'a>, ctx: &mut TraverseCtx<'a> {
if let Ancestor::BinaryExpressionLeft(bin_expr) = ctx.parent() {
let right = bin_expr.right(); // Method call
}
}
This is a bit unnatural. Would be more ergonomic to use field accesses:
fn enter_expression(&mut self, expr: &Expression<'a>, ctx: &mut TraverseCtx<'a> {
if let Ancestor::BinaryExpressionLeft(bin_expr) = ctx.parent() {
let right = &bin_expr.right; // Field access
}
}
Current implementation:
pub struct BinaryExpressionWithoutLeft<'a>(pub(crate) *const BinaryExpression<'a>);
impl<'a> BinaryExpressionWithoutLeft<'a> {
pub fn span(&self) -> &Span {
unsafe { &*((self.0 as *const u8).add(OFFSET_BINARY_EXPRESSION_SPAN) as *const Span) }
}
pub fn operator(&self) -> &BinaryOperator {
unsafe { &*((self.0 as *const u8).add(OFFSET_BINARY_EXPRESSION_OPERATOR) as *const BinaryOperator) }
}
pub fn right(&self) -> &Expression<'a> {
unsafe { &*((self.0 as *const u8).add(OFFSET_BINARY_EXPRESSION_RIGHT) as *const Expression<'a>) }
}
}
With field accesses:
pub struct BinaryExpressionWithoutLeft<'a>(pub(crate) *const BinaryExpression<'a>);
impl<'a> Deref for BinaryExpressionWithoutLeft<'a> {
type Target = BinaryExpressionWithoutLeftInner<'a>;
fn deref(&self) -> &Self::Target {
unsafe { &*(self.0 as *const Self::Target) }
}
}
pub struct BinaryExpressionWithoutLeftInner {
pub span: Span,
_left: MaybeUninit<Expression<'a>>,
pub operator: BinaryOperator,
pub right: Expression<'a>,
}
Same as current implementation, access to left is made statically impossible, but without the methods.
Would require that BinaryExpression and BinaryExpressionWithoutLeftInner are both #[repr(C)] so that transmuting from one to the other is valid.
I am not sure if this would be sound or not, as it creates a reference from pointer of node which has been travelled through in current traverse "branch". But maybe it's OK!
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 by reading the current Ancestor wrappers, BinaryExpressionWithoutLeft implementation, and the ctx.parent() usage shown in oxc_traverse. Investigate whether the proposed #[repr(C)] and Deref layout preserves soundness for traversed nodes. Done means field access replaces the relevant methods while keeping access to left statically impossible and the unsafe references sound.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- rust
- Domain
- compilers
- Issue type
- Refactor
- Difficulty
- 5/5
- Estimated time
- Over a week
- Activity status
- Stale
- Clarity
- Needs clarification
- Newbie friendliness
- 30/100