Skip to content

refactor(ast): Remove AstKind for MemberExpression and replace with StaticMemberExpression and PrivateFieldExpression #11767

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged

Conversation

camchenry
Copy link
Member

@camchenry camchenry commented Jun 17, 2025

Replaces the current AstKind::MemberExpression with StaticMemberExpresion and PrivateFieldExpression.

To make this change a little bit more ergonomic I've a new MemberExpressionKind which represents this subset of kinds.

@github-actions github-actions bot added A-ast Area - AST A-ast-tools Area - AST tools A-formatter Area - Formatter C-cleanup Category - technical debt or refactoring. Solution not expected to change behavior labels Jun 17, 2025
Copy link
Member Author

camchenry commented Jun 17, 2025


How to use the Graphite Merge Queue

Add either label to this PR to merge it via the merge queue:

  • 0-merge - adds this PR to the back of the merge queue
  • hotfix - for urgent hot fixes, skip the queue and merge this PR next

You must have a Graphite account in order to use the merge queue. Sign up using this link.

An organization admin has enabled the Graphite Merge Queue in this repository.

Please do not merge from GitHub as this will restart CI on PRs being processed by the merge queue.

This stack of pull requests is managed by Graphite. Learn more about stacking.

Copy link

codspeed-hq bot commented Jun 17, 2025

CodSpeed Instrumentation Performance Report

Merging #11767 will degrade performances by 13.21%

Comparing 06-17-refactor_ast_add_astkind_for_staticmemberexpression_ (87b8496) with main (e840680)

Summary

❌ 1 regressions
✅ 37 untouched benchmarks

⚠️ Please fix the performance issues or acknowledge them on CodSpeed.

Benchmarks breakdown

Benchmark BASE HEAD Change
mangler[cal.com.tsx] 3.1 ms 3.5 ms -13.21%

@camchenry camchenry force-pushed the 06-16-refactor_ast_add_astkind_for_computedmemberexpression_ branch from f4ef54b to c424ef3 Compare June 17, 2025 19:02
@camchenry camchenry force-pushed the 06-17-refactor_ast_add_astkind_for_staticmemberexpression_ branch from be74684 to 929c466 Compare June 19, 2025 01:22
@github-actions github-actions bot added A-linter Area - Linter A-semantic Area - Semantic labels Jun 19, 2025
@camchenry camchenry changed the title refactor(ast): add AstKind for StaticMemberExpression refactor(ast): Remove AstKind for MemberExpression and replace with StaticMemberExpression and PrivateFieldExpression Jun 19, 2025
@camchenry camchenry force-pushed the 06-17-refactor_ast_add_astkind_for_staticmemberexpression_ branch from 929c466 to c9918bc Compare June 19, 2025 14:49
@camchenry camchenry marked this pull request as ready for review June 19, 2025 14:56
Copy link
Contributor

@camc314 camc314 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

should we introduce a MemberExpression enum so that we can go from AstKind to MemberExpression? it's such a common pattern in the ;linter

@overlookmotel
Copy link
Member

overlookmotel commented Jun 20, 2025

should we introduce a MemberExpression enum so that we can go from AstKind to MemberExpression? it's such a common pattern in the ;linter

You mean something like?

enum MemberExpressionKind<'a> {
    ComputedMemberExpression(&'a ComputedMemberExpression<'a>),
    StaticMemberExpression(&'a StaticMemberExpression<'a>),
    PrivateFieldExpression(&'a PrivateFieldExpression<'a>),
}

This kind of "enum narrowing" pattern could also be useful in many places. There's lots of code all over Oxc which checks somewhere that an Expression is e.g. a literal, and then later on somewhere else there'll be a match on the same Expression with an _ => unreachable!() branch for all the variants which aren't literals.

That's both unperformant (unnecessary checks) and error-prone - we learn about mistakes when there's a panic, rather than getting a compile-time error.

It'd be ideal if you could do something like:

let expr: &Expression = get_expression_somehow();
if let Some(expr_literal) = expr.as_literal() {
    // `expr_literal` is an `&ExpressionLiteral` enum which only has variants
    // for `BooleanLiteral`, `StringLiteral` etc.
    // Pass `expr_literal` to the next function, instead of passing `expr`.
}

Like with the "enum inheritance" schema in AST, we could codegen these conversions and make them very cheap (just a check and transmute).

@overlookmotel
Copy link
Member

I've written up the broader "enum narrowing" feature in oxc-project/backlog#166. But it'd be pretty simple to hand-code MemberExpressionKind in meantime if that's the type where this pattern is most common.

@camchenry camchenry force-pushed the 06-16-refactor_ast_add_astkind_for_computedmemberexpression_ branch 2 times, most recently from 6e099bb to 3616da5 Compare June 21, 2025 21:45
@camchenry camchenry force-pushed the 06-17-refactor_ast_add_astkind_for_staticmemberexpression_ branch from c9918bc to eff56f2 Compare June 21, 2025 21:45
@camchenry camchenry force-pushed the 06-17-refactor_ast_add_astkind_for_staticmemberexpression_ branch 2 times, most recently from 1a880a3 to 3934a58 Compare June 21, 2025 23:10
@camchenry
Copy link
Member Author

@camc314 @overlookmotel Thanks for the suggestion. I agree having the separate enum is a good idea, it makes the code a lot simpler and probably more maintainable in the future if ECMAScript should ever add more member expression types.

I've gone ahead and manually implemented an API for this, but an autogenerated one in the future would be nice.

@camc314
Copy link
Contributor

camc314 commented Jun 23, 2025

Yeah enum narrowing would definitly be nice. But for this specific case, I think it's definitly worth having a member expr enum (even if temporary) for this case due to how heavily member expresssion/static member expression is used

@overlookmotel overlookmotel force-pushed the 06-17-refactor_ast_add_astkind_for_staticmemberexpression_ branch from 3934a58 to 2d81011 Compare June 24, 2025 14:13
@overlookmotel overlookmotel changed the base branch from graphite-base/11767 to 06-16-refactor_ast_add_astkind_for_computedmemberexpression_ June 24, 2025 14:13
@overlookmotel overlookmotel force-pushed the 06-17-refactor_ast_add_astkind_for_staticmemberexpression_ branch from 2d81011 to 3075c3b Compare June 24, 2025 14:18
@graphite-app graphite-app bot changed the base branch from 06-16-refactor_ast_add_astkind_for_computedmemberexpression_ to graphite-base/11767 June 24, 2025 19:03
@graphite-app graphite-app bot force-pushed the 06-17-refactor_ast_add_astkind_for_staticmemberexpression_ branch from 3075c3b to 294664d Compare June 24, 2025 19:11
@graphite-app graphite-app bot force-pushed the graphite-base/11767 branch from 48d83ab to 190e390 Compare June 24, 2025 19:11
@graphite-app graphite-app bot changed the base branch from graphite-base/11767 to main June 24, 2025 19:12
@graphite-app graphite-app bot force-pushed the 06-17-refactor_ast_add_astkind_for_staticmemberexpression_ branch from 294664d to 00195f8 Compare June 24, 2025 19:12
@overlookmotel
Copy link
Member

I rebased this on main, and it's now broken. Looks like clash with #11790 which introduced a usage of AstKind::MemberExpression in the no-console rule.

@overlookmotel overlookmotel force-pushed the 06-17-refactor_ast_add_astkind_for_staticmemberexpression_ branch from 00195f8 to 189fc00 Compare June 24, 2025 19:28
@overlookmotel
Copy link
Member

overlookmotel commented Jun 24, 2025

I've pushed a commit to hopefully fix no-console, but I'm out of time, and now am away for the next week. @camc314 can I please hand over to you to review?

@overlookmotel
Copy link
Member

Conformance fail relates to formatter. Not sure how serious it is.

@camc314 camc314 self-assigned this Jun 25, 2025
@camc314 camc314 force-pushed the 06-17-refactor_ast_add_astkind_for_staticmemberexpression_ branch from 189fc00 to 4aa6d5a Compare June 25, 2025 11:13
@camc314 camc314 added the 0-merge Merge with Graphite Merge Queue label Jun 25, 2025
Copy link
Contributor

camc314 commented Jun 25, 2025

Merge activity

…th `StaticMemberExpression` and `PrivateFieldExpression` (#11767)

- related to #11490

Replaces the current `AstKind::MemberExpression` with `StaticMemberExpresion` and `PrivateFieldExpression`.

To make this change a little bit more ergonomic I've a new `MemberExpressionKind` which represents this subset of kinds.
@graphite-app graphite-app bot force-pushed the 06-17-refactor_ast_add_astkind_for_staticmemberexpression_ branch from 4aa6d5a to 87b8496 Compare June 25, 2025 11:22
@graphite-app graphite-app bot merged commit 87b8496 into main Jun 25, 2025
25 checks passed
@graphite-app graphite-app bot removed the 0-merge Merge with Graphite Merge Queue label Jun 25, 2025
@graphite-app graphite-app bot deleted the 06-17-refactor_ast_add_astkind_for_staticmemberexpression_ branch June 25, 2025 11:28
graphite-app bot pushed a commit that referenced this pull request Jun 26, 2025
…11904)

Follow-up after #11767.

I've checked them one by one, corresponding to the Biome's implementation. It still has a regression test, but it is not exactly related to the `AstKind::MemberExpression` change. I will fix that in another PR, but not now.
graphite-app bot pushed a commit that referenced this pull request Jul 2, 2025
Follow-on after #11767. Small optimizations.

* `PrivateFieldExpression` cannot have a static property name, so no need to test for it.

* Replace branch which can never be taken with `unwrap()`. `unwrap()` should cause compiler to backtrack and prove that this branch cannot be taken, and remove the branch.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
A-ast Area - AST A-ast-tools Area - AST tools A-formatter Area - Formatter A-linter Area - Linter A-semantic Area - Semantic C-cleanup Category - technical debt or refactoring. Solution not expected to change behavior
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants