From dce335e7666a153b2ad3c2ecbd842efecc75c479 Mon Sep 17 00:00:00 2001 From: pjh456 <147148383@qq.com> Date: Wed, 5 Aug 2026 15:04:44 +0800 Subject: [PATCH] =?UTF-8?q?fix:=20=E9=80=90=E4=B8=AA=E6=8C=89=E9=A1=BA?= =?UTF-8?q?=E5=BA=8F=E5=A4=84=E7=90=86=20field=20=E4=B8=8E=20block=20?= =?UTF-8?q?=E4=BB=A5=E7=AC=A6=E5=90=88=20JS=20=E7=B1=BB=E5=85=83=E7=B4=A0?= =?UTF-8?q?=E6=BA=90=E7=A0=81=E9=A1=BA=E5=BA=8F=E8=AF=AD=E4=B9=89?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- crates/oxide_compiler/src/class/emit.rs | 3 +- crates/oxide_compiler/src/class/field.rs | 36 +++++++++++++------ crates/oxide_compiler/src/class/mod.rs | 1 - .../oxide_compiler/src/class/static_block.rs | 22 ------------ 4 files changed, 26 insertions(+), 36 deletions(-) delete mode 100644 crates/oxide_compiler/src/class/static_block.rs diff --git a/crates/oxide_compiler/src/class/emit.rs b/crates/oxide_compiler/src/class/emit.rs index 1958812a..5b918f6d 100644 --- a/crates/oxide_compiler/src/class/emit.rs +++ b/crates/oxide_compiler/src/class/emit.rs @@ -156,8 +156,7 @@ impl Compiler { self.emit_class_prototype(ctor_reg, proto_reg, super_reg, ctx.sub_modules.len() as u32, ctx)?; self.emit_class_methods(&class.body.body, ctor_reg, proto_reg, &self_binding, ctx)?; - self.emit_class_static_fields(&class.body.body, ctor_reg, ctx)?; - self.emit_class_static_blocks(&class.body.body, ctor_reg, ctx)?; + self.emit_class_static_elements(&class.body.body, ctor_reg, ctx)?; ctx.scopes.private_name_map = saved_private_names; Ok(ctor_reg) diff --git a/crates/oxide_compiler/src/class/field.rs b/crates/oxide_compiler/src/class/field.rs index 26e30978..ad0715b3 100644 --- a/crates/oxide_compiler/src/class/field.rs +++ b/crates/oxide_compiler/src/class/field.rs @@ -2,24 +2,38 @@ use crate::compiler::{CompileCtx, Compiler}; use oxide_parser::{ClassElement, PropertyKey}; impl Compiler { - pub(crate) fn emit_class_static_fields( + /// Emit static field initializers and static blocks in source order. + /// JS class semantics interleave them (e.g. `static x = 1; static { + /// this.y = 1 } static z = this.y + 1` must run in that order). Emitting + /// all fields before all blocks would make `z` read `y` before it is set. + pub(crate) fn emit_class_static_elements( &self, elements: &[ClassElement], ctor_reg: u8, ctx: &mut CompileCtx, ) -> Result<(), String> { + let saved_static_this = ctx.static_block_this_reg; + ctx.static_block_this_reg = Some(ctor_reg); for element in elements { - if let ClassElement::PropertyDefinition(prop) = element { - let prop = prop.as_ref(); - if prop.r#static { - let saved_static_this = ctx.static_block_this_reg; - ctx.static_block_this_reg = Some(ctor_reg); - if let PropertyKey::PrivateIdentifier(private) = &prop.key { - self.emit_private_field_init(ctor_reg, private.name.as_str(), prop.value.as_ref(), ctx)?; - } else { - self.emit_public_field_init(ctor_reg, &prop.key, prop.computed, prop.value.as_ref(), ctx)?; + match element { + ClassElement::PropertyDefinition(prop) => { + let prop = prop.as_ref(); + if prop.r#static { + if let PropertyKey::PrivateIdentifier(private) = &prop.key { + self.emit_private_field_init(ctor_reg, private.name.as_str(), prop.value.as_ref(), ctx)?; + } else { + self.emit_public_field_init(ctor_reg, &prop.key, prop.computed, prop.value.as_ref(), ctx)?; + } } - ctx.static_block_this_reg = saved_static_this; } + ClassElement::StaticBlock(block) => { + ctx.push_scope(); + for stmt in &block.body { + self.emit_statement(stmt, ctx)?; + } + ctx.pop_scope(); + } + _ => {} } } + ctx.static_block_this_reg = saved_static_this; Ok(()) } } diff --git a/crates/oxide_compiler/src/class/mod.rs b/crates/oxide_compiler/src/class/mod.rs index e418e299..51027cee 100644 --- a/crates/oxide_compiler/src/class/mod.rs +++ b/crates/oxide_compiler/src/class/mod.rs @@ -4,4 +4,3 @@ pub mod field; pub mod header; pub mod method; pub mod prototype; -pub mod static_block; diff --git a/crates/oxide_compiler/src/class/static_block.rs b/crates/oxide_compiler/src/class/static_block.rs deleted file mode 100644 index ffe79f79..00000000 --- a/crates/oxide_compiler/src/class/static_block.rs +++ /dev/null @@ -1,22 +0,0 @@ -use crate::compiler::{CompileCtx, Compiler}; -use oxide_parser::ClassElement; - -impl Compiler { - pub(crate) fn emit_class_static_blocks( - &self, elements: &[ClassElement], ctor_reg: u8, ctx: &mut CompileCtx, - ) -> Result<(), String> { - for element in elements { - if let ClassElement::StaticBlock(block) = element { - let saved_static_this = ctx.static_block_this_reg; - ctx.static_block_this_reg = Some(ctor_reg); - ctx.push_scope(); - for stmt in &block.body { - self.emit_statement(stmt, ctx)?; - } - ctx.pop_scope(); - ctx.static_block_this_reg = saved_static_this; - } - } - Ok(()) - } -}