-
-
Notifications
You must be signed in to change notification settings - Fork 715
feat(oxc_semantic): collect const enum information with basic const eval #15192
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
base: main
Are you sure you want to change the base?
Conversation
How to use the Graphite Merge QueueAdd either label to this PR to merge it via the merge queue:
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. |
b624b36 to
c99de44
Compare
CodSpeed Performance ReportMerging #15192 will not alter performanceComparing Summary
|
1079de7 to
ea11c5f
Compare
73371d7 to
0653e9f
Compare
| continue; | ||
| }; | ||
| let value = if let Some(initializer) = &member.initializer { | ||
| let ctx = ConstantEnumCtx::new(&members, scoping, ast_builder); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Cannot reuse allocator in scoping since Trait
oxc/crates/oxc_semantic/src/const_enum.rs
Lines 188 to 192 in 0653e9f
| impl<'a> ConstantEvaluationCtx<'a> for ConstantEnumCtx<'_, 'a> { | |
| fn ast(&self) -> oxc_ast::AstBuilder<'a> { | |
| self.builder | |
| } | |
| } |
self reference; we can't access Allocator inside scoping without a mutable reference. If we create an AstBuilder with an arena inside a scope, that would violate Rustc's borrow rules.
| let symbol_id = enum_declaration.id.symbol_id(); | ||
| let current_scope = enum_declaration.scope_id(); | ||
| let allocator = oxc_allocator::Allocator::default(); | ||
| let ast_builder = AstBuilder::new(&allocator); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Use a temp AstBuilder to satisfy ConstantEvaluationCtx
oxc/crates/oxc_semantic/src/const_enum.rs
Lines 188 to 192 in 0653e9f
| impl<'a> ConstantEvaluationCtx<'a> for ConstantEnumCtx<'_, 'a> { | |
| fn ast(&self) -> oxc_ast::AstBuilder<'a> { | |
| self.builder | |
| } | |
| } |
ConstValue into a heap-allocated version finally.
0653e9f to
d8881ae
Compare
| assert_const_enum_value(&d_member.value, "3"); | ||
|
|
||
| // E: Currently "Computed" because C and D are computed values | ||
| // TODO: Should be "6" (C + D = 3 + 3) when full constant propagation is implemented |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is because the current
oxc/crates/oxc_ecmascript/src/constant_evaluation/mod.rs
Lines 212 to 236 in d8881ae
| BinaryOperator::Addition => { | |
| use crate::to_primitive::ToPrimitive; | |
| let left_to_primitive = left.to_primitive(ctx); | |
| let right_to_primitive = right.to_primitive(ctx); | |
| if left_to_primitive.is_string() == Some(true) | |
| || right_to_primitive.is_string() == Some(true) | |
| { | |
| let lval = left.evaluate_value_to_string(ctx)?; | |
| let rval = right.evaluate_value_to_string(ctx)?; | |
| return Some(ConstantValue::String(lval + rval)); | |
| } | |
| let left_to_numeric_type = left_to_primitive.to_numeric(ctx); | |
| let right_to_numeric_type = right_to_primitive.to_numeric(ctx); | |
| if left_to_numeric_type.is_number() || right_to_numeric_type.is_number() { | |
| let lval = left.evaluate_value_to_number(ctx)?; | |
| let rval = right.evaluate_value_to_number(ctx)?; | |
| return Some(ConstantValue::Number(lval + rval)); | |
| } | |
| if left_to_numeric_type.is_bigint() && right_to_numeric_type.is_bigint() { | |
| let lval = left.evaluate_value_to_bigint(ctx)?; | |
| let rval = right.evaluate_value_to_bigint(ctx)?; | |
| return Some(ConstantValue::BigInt(lval + rval)); | |
| } | |
| None | |
| } |
| assert_eq!(enum_info.members.len(), 4); | ||
|
|
||
| // A: Currently "Computed" because cross-enum member access isn't implemented yet | ||
| // TODO: Should be "10" (Base.X) when cross-enum constant propagation is implemented |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is because the current constEval did not support resolving a memberExpr
d8881ae to
59793f6
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Pull Request Overview
This PR adds support for const enum value evaluation and storage during semantic analysis. Const enums are a TypeScript feature where enum members are compiled away and inlined as literal values at compile time.
- Adds a new
ConstEnumTableto store evaluated const enum member values - Implements constant evaluation logic for enum members including auto-increment, literals, and expressions
- Integrates const enum processing into the semantic analysis phase
Reviewed Changes
Copilot reviewed 6 out of 7 changed files in this pull request and generated 1 comment.
Show a summary per file
| File | Description |
|---|---|
| crates/oxc_semantic/tests/integration/main.rs | Adds const_enum module to test suite |
| crates/oxc_semantic/tests/integration/const_enum.rs | Comprehensive test suite for const enum evaluation including simple enums, explicit values, mixed values, literals, binary expressions, and constant propagation |
| crates/oxc_semantic/src/lib.rs | Exposes const enum types and adds const_enums field to Semantic struct with accessor methods |
| crates/oxc_semantic/src/const_enum.rs | Core implementation of const enum evaluation logic and storage structures |
| crates/oxc_semantic/src/builder.rs | Integrates const enum processing into the semantic builder's AST traversal |
| crates/oxc_semantic/Cargo.toml | Adds num-bigint dependency for BigInt support |
| Cargo.lock | Updates lock file with num-bigint dependency |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
2d9837c to
936983b
Compare
Dunqing
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Const enum evaluation is relatively simple because all member values should be a constant expression, such that these expressions can be evaluated at compile time. Therefore, I don't think we need to use ConstantEvaluationCtx here, as it leads to more complexity and is not suitable for the semantics.
Instead, we can reuse the current enum transformation in the https://github.com/oxc-project/oxc/blob/936983b7e60118c1090ab817cc49a9d6855a5b64/crates/oxc_transformer/src/typescript/enum.rs#L350-L65, which is a port version of TypeScript's implementation, so that we can keep consistent, and this implementation can solve the problems you mentioned.
Thanks, I don't even know that exists, it solved my issue. |
936983b to
9bd8d7d
Compare
f714d4f to
5a62bca
Compare
Co-authored-by: Copilot <[email protected]> Signed-off-by: IWANABETHATGUY <[email protected]>
5a62bca to
a9c163a
Compare

related to #11844, #6073