oxc-project / oxc

⚓ A collection of JavaScript tools written in Rust.

Home Page:https://oxc.rs

Repository from Github https://github.comoxc-project/oxcRepository from Github https://github.comoxc-project/oxc

ComputedMemberExpression node is missing.

JasithC opened this issue · comments

If a node type is AssignExpression and its left child node type is ComputedMemberExpression, then when I use the enter_expression method in Traverse, I am unable to locate a node of type ComputedMemberExpression.

Image

Image

Image

ComputedMemberExpression can be an Expression, but in this position it isn't.

The left side of an AssignmentExpression is an AssignmentTarget:

pub struct AssignmentExpression<'a> {
pub span: Span,
pub operator: AssignmentOperator,
pub left: AssignmentTarget<'a>,
pub right: Expression<'a>,
}

And AssignmentTarget is either a SimpleAssignmentTarget or a AssignmentTargetPattern:

pub enum AssignmentTarget<'a> {
// `SimpleAssignmentTarget` variants added here by `inherit_variants!` macro
@inherit SimpleAssignmentTarget
// `AssignmentTargetPattern` variants added here by `inherit_variants!` macro
@inherit AssignmentTargetPattern
}

SimpleAssignmentTarget can be a MemberExpression:

pub enum SimpleAssignmentTarget<'a> {
AssignmentTargetIdentifier(Box<'a, IdentifierReference<'a>>) = 0,
TSAsExpression(Box<'a, TSAsExpression<'a>>) = 1,
TSSatisfiesExpression(Box<'a, TSSatisfiesExpression<'a>>) = 2,
TSNonNullExpression(Box<'a, TSNonNullExpression<'a>>) = 3,
TSTypeAssertion(Box<'a, TSTypeAssertion<'a>>) = 4,
TSInstantiationExpression(Box<'a, TSInstantiationExpression<'a>>) = 5,
// `MemberExpression` variants added here by `inherit_variants!` macro
@inherit MemberExpression
}

And (finally!) MemberExpression can be a ComputedMemberExpression:

pub enum MemberExpression<'a> {
/// `ar[0]` in `const ar = [1, 2]; ar[0];`
ComputedMemberExpression(Box<'a, ComputedMemberExpression<'a>>) = 48,
/// `console.log` in `console.log('Hello, World!');`
StaticMemberExpression(Box<'a, StaticMemberExpression<'a>>) = 49,
/// `c.#a` in `class C { #a = 1; }; const c = new C(); c.#a;`
PrivateFieldExpression(Box<'a, PrivateFieldExpression<'a>>) = 50,
}

So... to visit the ComputedMemberExpression in this position, use one of:

  • enter_computed_member_expression
  • enter_member_expression
  • enter_simple_assignment_target
  • enter_assignment_target

Which is the best choice depends on what you want to do with the node (replace it with what?) and what other nodes are you interested in (do you also want to visit e.g. StaticMemberExpression?)

Note: The @inherits syntax is not standard Rust - it's a (somewhat ugly) extension we've created ourselves. You can read about "enum inheritance" here: https://docs.rs/oxc_ast/latest/oxc_ast/ast/index.html

Closing because I don't believe this to be a bug (though I understand why you thought it was - it's not obvious).

Thanks very much. I've also noticed an issue since updating to the latest version of OXC. Is this something that can only be resolved by upgrading to the Nightly build?

Image