Skip to content

Commit 1079de7

Browse files
chore: 🤖 update
1 parent 17597d7 commit 1079de7

File tree

5 files changed

+501
-574
lines changed

5 files changed

+501
-574
lines changed

‎crates/oxc_semantic/src/builder.rs‎

Lines changed: 37 additions & 172 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ use num_bigint::BigInt;
1010
use rustc_hash::FxHashMap;
1111

1212
use oxc_allocator::Address;
13-
use oxc_ast::{AstKind, ast::*};
13+
use oxc_ast::{AstBuilder, AstKind, ast::*};
1414
use oxc_ast_visit::Visit;
1515
#[cfg(feature = "cfg")]
1616
use oxc_cfg::{
@@ -29,18 +29,24 @@ use oxc_syntax::{
2929
#[cfg(feature = "linter")]
3030
use crate::jsdoc::JSDocBuilder;
3131
use crate::{
32-
const_enum::{ConstEnumTable, ConstEnumMemberValue, ConstEnumMemberInfo, ConstEnumInfo},
3332
Semantic,
3433
binder::{Binder, ModuleInstanceState},
3534
checker,
3635
class::ClassTableBuilder,
36+
const_enum::{
37+
ConstEnumInfo, ConstEnumMemberInfo, ConstEnumTable, ConstantEnumCtx,
38+
NormalizedConstEnumInfo, NormalizedConstEnumMemberInfo,
39+
},
3740
diagnostics::redeclaration,
3841
label::UnusedLabels,
3942
node::AstNodes,
4043
scoping::{Bindings, Scoping},
4144
stats::Stats,
4245
unresolved_stack::UnresolvedReferencesStack,
4346
};
47+
use oxc_ecmascript::constant_evaluation::{
48+
ConstantEvaluation, ConstantEvaluationCtx, ConstantValue,
49+
};
4450

4551
#[cfg(feature = "cfg")]
4652
macro_rules! control_flow {
@@ -112,7 +118,7 @@ pub struct SemanticBuilder<'a> {
112118
pub(crate) class_table_builder: ClassTableBuilder<'a>,
113119

114120
/// Table for storing const enum information
115-
pub(crate) const_enum_table: ConstEnumTable<'a>,
121+
pub(crate) const_enum_table: ConstEnumTable,
116122

117123
#[cfg(feature = "cfg")]
118124
ast_node_records: Vec<NodeId>,
@@ -2154,11 +2160,6 @@ impl<'a> SemanticBuilder<'a> {
21542160
}
21552161
AstKind::TSEnumDeclaration(enum_declaration) => {
21562162
enum_declaration.bind(self);
2157-
2158-
// Process const enums
2159-
if enum_declaration.r#const {
2160-
self.process_const_enum(enum_declaration);
2161-
}
21622163
}
21632164
AstKind::TSEnumMember(enum_member) => {
21642165
enum_member.bind(self);
@@ -2223,6 +2224,11 @@ impl<'a> SemanticBuilder<'a> {
22232224
// Clear the reference flags that may have been set when entering the node.
22242225
self.current_reference_flags = ReferenceFlags::empty();
22252226
}
2227+
AstKind::TSEnumDeclaration(enum_declaration) => {
2228+
if enum_declaration.r#const {
2229+
self.process_const_enum(enum_declaration);
2230+
}
2231+
}
22262232
_ => {}
22272233
}
22282234
}
@@ -2248,9 +2254,11 @@ impl<'a> SemanticBuilder<'a> {
22482254
/// Process a const enum declaration and evaluate its members
22492255
fn process_const_enum(&mut self, enum_declaration: &TSEnumDeclaration<'a>) {
22502256
// Get the symbol ID for this enum
2251-
let symbol_id = enum_declaration.id.symbol_id.get().expect("enum should have symbol ID");
2252-
2253-
let mut members = std::collections::HashMap::new();
2257+
let symbol_id = enum_declaration.id.symbol_id();
2258+
let current_scope = enum_declaration.scope_id();
2259+
let allocator = oxc_allocator::Allocator::default();
2260+
let ast_builder = AstBuilder::new(&allocator);
2261+
let mut members = FxHashMap::default();
22542262
let mut current_value: f64 = -1.0; // Start at -1, first auto-increment will make it 0
22552263

22562264
for member in &enum_declaration.body.members {
@@ -2260,7 +2268,7 @@ impl<'a> SemanticBuilder<'a> {
22602268
TSEnumMemberName::ComputedString(string) => string.value.as_str(),
22612269
TSEnumMemberName::ComputedTemplateString(template) => {
22622270
// For computed template strings, we need to evaluate them
2263-
if template.expressions.is_empty() {
2271+
let v = if template.expressions.is_empty() {
22642272
if let Some(quasi) = template.quasis.first() {
22652273
quasi.value.raw.as_str()
22662274
} else {
@@ -2269,184 +2277,41 @@ impl<'a> SemanticBuilder<'a> {
22692277
} else {
22702278
// Skip template literals with expressions for now
22712279
continue;
2272-
}
2280+
};
2281+
v
22732282
}
22742283
};
2275-
2284+
let Some(member_symbol_id) = self.scoping.get_binding(current_scope, member_name)
2285+
else {
2286+
continue;
2287+
};
22762288
let value = if let Some(initializer) = &member.initializer {
2277-
// Evaluate the initializer expression
2278-
let mut visited = std::vec::Vec::new();
2279-
if let Some(evaluated_value) = self.evaluate_const_enum_member(initializer, Some(symbol_id), &mut visited) {
2280-
// Update current_value based on the evaluated value
2281-
match &evaluated_value {
2282-
ConstEnumMemberValue::Number(n) => current_value = *n,
2283-
_ => {} // Don't change current_value for non-numeric values
2284-
}
2285-
evaluated_value
2286-
} else {
2287-
// If evaluation fails, fall back to current_value + 1
2288-
current_value += 1.0;
2289-
ConstEnumMemberValue::Number(current_value)
2290-
}
2289+
let ctx = ConstantEnumCtx::new(&members, &self.scoping, ast_builder);
2290+
initializer.evaluate_value(&ctx).unwrap_or(ConstantValue::Undefined)
22912291
} else {
22922292
// Auto-increment the value
22932293
current_value += 1.0;
2294-
ConstEnumMemberValue::Number(current_value)
2294+
ConstantValue::Number(current_value)
22952295
};
2296+
dbg!(&value);
22962297

22972298
let member_info = ConstEnumMemberInfo {
22982299
name: member_name,
22992300
value,
23002301
span: member.span,
23012302
has_initializer: member.initializer.is_some(),
2303+
symbol_id: member_symbol_id,
23022304
};
23032305

2304-
members.insert(member_name, member_info);
2306+
members.insert(member_symbol_id, member_info);
23052307
}
23062308

2307-
let enum_info = ConstEnumInfo {
2308-
symbol_id,
2309-
members,
2310-
span: enum_declaration.span,
2311-
};
2309+
let members = members
2310+
.into_iter()
2311+
.map(|(symbol_id, member)| (symbol_id, member.into()))
2312+
.collect::<FxHashMap<SymbolId, NormalizedConstEnumMemberInfo>>();
2313+
let enum_info = NormalizedConstEnumInfo { symbol_id, members, span: enum_declaration.span };
23122314

23132315
self.const_enum_table.add_enum(symbol_id, enum_info);
23142316
}
2315-
2316-
/// Evaluate a const enum member's value with improved JavaScript semantics
2317-
fn evaluate_const_enum_member(
2318-
&self,
2319-
expression: &Expression<'a>,
2320-
current_enum: Option<SymbolId>,
2321-
_visited: &mut std::vec::Vec<&'a str>,
2322-
) -> Option<ConstEnumMemberValue<'a>> {
2323-
match expression {
2324-
Expression::StringLiteral(string) => Some(ConstEnumMemberValue::String(string.value.as_str())),
2325-
Expression::NumericLiteral(number) => Some(ConstEnumMemberValue::Number(number.value)),
2326-
Expression::BooleanLiteral(boolean) => Some(ConstEnumMemberValue::Boolean(boolean.value)),
2327-
Expression::BigIntLiteral(bigint) => {
2328-
bigint.value.parse::<BigInt>().ok().map(ConstEnumMemberValue::BigInt)
2329-
}
2330-
Expression::UnaryExpression(unary) => {
2331-
if let Some(argument) = self.evaluate_const_enum_member(&unary.argument, current_enum, _visited) {
2332-
self.evaluate_unary_operation(unary, argument)
2333-
} else {
2334-
None
2335-
}
2336-
}
2337-
Expression::BinaryExpression(binary) => {
2338-
if let (Some(left), Some(right)) = (
2339-
self.evaluate_const_enum_member(&binary.left, current_enum, _visited),
2340-
self.evaluate_const_enum_member(&binary.right, current_enum, _visited),
2341-
) {
2342-
self.evaluate_binary_operation(binary, left, right)
2343-
} else {
2344-
None
2345-
}
2346-
}
2347-
Expression::Identifier(ident) => {
2348-
// Try to resolve this as a reference to another const enum member
2349-
let name = ident.name.as_str();
2350-
2351-
if let Some(current_enum_id) = current_enum {
2352-
if let Some(enum_info) = self.const_enum_table.get_enum(current_enum_id) {
2353-
if let Some(member_info) = enum_info.members.get(name) {
2354-
return Some(member_info.value.clone());
2355-
}
2356-
}
2357-
}
2358-
None
2359-
}
2360-
_ => None,
2361-
}
2362-
}
2363-
2364-
/// Evaluate unary operations with proper JavaScript semantics
2365-
fn evaluate_unary_operation(
2366-
&self,
2367-
unary: &UnaryExpression<'a>,
2368-
argument: ConstEnumMemberValue<'a>,
2369-
) -> Option<ConstEnumMemberValue<'a>> {
2370-
match unary.operator {
2371-
UnaryOperator::UnaryNegation => {
2372-
match argument {
2373-
ConstEnumMemberValue::Number(n) => Some(ConstEnumMemberValue::Number(-n)),
2374-
_ => None,
2375-
}
2376-
}
2377-
UnaryOperator::UnaryPlus => {
2378-
match argument {
2379-
ConstEnumMemberValue::Number(n) => Some(ConstEnumMemberValue::Number(n)),
2380-
_ => None,
2381-
}
2382-
}
2383-
UnaryOperator::LogicalNot => {
2384-
match argument {
2385-
ConstEnumMemberValue::Boolean(b) => Some(ConstEnumMemberValue::Boolean(!b)),
2386-
_ => None,
2387-
}
2388-
}
2389-
_ => None,
2390-
}
2391-
}
2392-
2393-
/// Evaluate binary operations with proper JavaScript semantics
2394-
fn evaluate_binary_operation(
2395-
&self,
2396-
binary: &BinaryExpression<'a>,
2397-
left: ConstEnumMemberValue<'a>,
2398-
right: ConstEnumMemberValue<'a>,
2399-
) -> Option<ConstEnumMemberValue<'a>> {
2400-
match binary.operator {
2401-
BinaryOperator::Addition => {
2402-
match (&left, &right) {
2403-
(ConstEnumMemberValue::Number(l), ConstEnumMemberValue::Number(r)) => {
2404-
Some(ConstEnumMemberValue::Number(l + r))
2405-
}
2406-
_ => None,
2407-
}
2408-
}
2409-
BinaryOperator::Subtraction => {
2410-
match (&left, &right) {
2411-
(ConstEnumMemberValue::Number(l), ConstEnumMemberValue::Number(r)) => {
2412-
Some(ConstEnumMemberValue::Number(l - r))
2413-
}
2414-
_ => None,
2415-
}
2416-
}
2417-
BinaryOperator::Multiplication => {
2418-
match (&left, &right) {
2419-
(ConstEnumMemberValue::Number(l), ConstEnumMemberValue::Number(r)) => {
2420-
Some(ConstEnumMemberValue::Number(l * r))
2421-
}
2422-
_ => None,
2423-
}
2424-
}
2425-
BinaryOperator::Division => {
2426-
match (&left, &right) {
2427-
(ConstEnumMemberValue::Number(l), ConstEnumMemberValue::Number(r)) => {
2428-
if *r == 0.0 { None } else { Some(ConstEnumMemberValue::Number(l / r)) }
2429-
}
2430-
_ => None,
2431-
}
2432-
}
2433-
BinaryOperator::ShiftLeft => {
2434-
match (&left, &right) {
2435-
(ConstEnumMemberValue::Number(l), ConstEnumMemberValue::Number(r)) => {
2436-
Some(ConstEnumMemberValue::Number(((*l as i64) << (*r as i64)) as f64))
2437-
}
2438-
_ => None,
2439-
}
2440-
}
2441-
BinaryOperator::BitwiseOR => {
2442-
match (&left, &right) {
2443-
(ConstEnumMemberValue::Number(l), ConstEnumMemberValue::Number(r)) => {
2444-
Some(ConstEnumMemberValue::Number(((*l as i64) | (*r as i64)) as f64))
2445-
}
2446-
_ => None,
2447-
}
2448-
}
2449-
_ => None,
2450-
}
2451-
}
24522317
}

0 commit comments

Comments
 (0)