From 1486849ec2cca0fc991d2977e7e5945dc6eb76ba Mon Sep 17 00:00:00 2001 From: Boshen <1430279+Boshen@users.noreply.github.com> Date: Wed, 4 Dec 2024 05:33:04 +0000 Subject: [PATCH] fix(semantic): syntax error for undeclared private field access (#7635) closes #7582 --- crates/oxc_semantic/src/checker/javascript.rs | 14 +++++--------- crates/oxc_semantic/src/class/table.rs | 9 ++++----- crates/oxc_semantic/tests/integration/util/mod.rs | 3 ++- tasks/coverage/misc/fail/oxc-7582.js | 6 ++++++ tasks/coverage/snapshots/parser_misc.snap | 10 +++++++++- 5 files changed, 26 insertions(+), 16 deletions(-) create mode 100644 tasks/coverage/misc/fail/oxc-7582.js diff --git a/crates/oxc_semantic/src/checker/javascript.rs b/crates/oxc_semantic/src/checker/javascript.rs index a1457ef6f88ae..2e3cb6a6308ab 100644 --- a/crates/oxc_semantic/src/checker/javascript.rs +++ b/crates/oxc_semantic/src/checker/javascript.rs @@ -195,17 +195,13 @@ fn private_field_undeclared(x0: &str, span1: Span) -> OxcDiagnostic { fn check_private_identifier(ctx: &SemanticBuilder<'_>) { if let Some(class_id) = ctx.class_table_builder.current_class_id { - ctx.class_table_builder.classes.iter_private_identifiers(class_id).for_each(|reference| { - if reference.element_ids.is_empty() - && !ctx.class_table_builder.classes.ancestors(class_id).skip(1).any(|class_id| { - ctx.class_table_builder - .classes - .has_private_definition(class_id, &reference.name) - }) - { + for reference in ctx.class_table_builder.classes.iter_private_identifiers(class_id) { + if !ctx.class_table_builder.classes.ancestors(class_id).any(|class_id| { + ctx.class_table_builder.classes.has_private_definition(class_id, &reference.name) + }) { ctx.error(private_field_undeclared(&reference.name, reference.span)); } - }); + } } } diff --git a/crates/oxc_semantic/src/class/table.rs b/crates/oxc_semantic/src/class/table.rs index 654ff5b012362..e190154132597 100644 --- a/crates/oxc_semantic/src/class/table.rs +++ b/crates/oxc_semantic/src/class/table.rs @@ -49,8 +49,7 @@ pub struct ClassTable { pub parent_ids: FxHashMap, pub declarations: IndexVec, pub elements: IndexVec>, - // PrivateIdentifier reference - pub private_identifiers: IndexVec>, + pub private_identifier_references: IndexVec>, } impl ClassTable { @@ -70,7 +69,7 @@ impl ClassTable { &self, class_id: ClassId, ) -> impl Iterator + '_ { - self.private_identifiers[class_id].iter() + self.private_identifier_references[class_id].iter() } pub fn get_node_id(&self, class_id: ClassId) -> NodeId { @@ -108,7 +107,7 @@ impl ClassTable { self.parent_ids.insert(class_id, parent_id); }; self.elements.push(IndexVec::default()); - self.private_identifiers.push(Vec::new()); + self.private_identifier_references.push(Vec::new()); class_id } @@ -121,6 +120,6 @@ impl ClassTable { class_id: ClassId, private_identifier_reference: PrivateIdentifierReference, ) { - self.private_identifiers[class_id].push(private_identifier_reference); + self.private_identifier_references[class_id].push(private_identifier_reference); } } diff --git a/crates/oxc_semantic/tests/integration/util/mod.rs b/crates/oxc_semantic/tests/integration/util/mod.rs index ac53740f5175b..cc87ca60c462c 100644 --- a/crates/oxc_semantic/tests/integration/util/mod.rs +++ b/crates/oxc_semantic/tests/integration/util/mod.rs @@ -133,7 +133,8 @@ impl<'a> SemanticTester<'a> { match (self.expect_errors, semantic_ret.errors.is_empty()) { (true, true) => panic!("Expected errors, but none were produced"), (false, false) => panic!( - "Semantic analysis failed:\n\n{}", + "Semantic analysis failed:\n\n{}\n\n{}", + self.source_text, semantic_ret .errors .iter() diff --git a/tasks/coverage/misc/fail/oxc-7582.js b/tasks/coverage/misc/fail/oxc-7582.js new file mode 100644 index 0000000000000..86960dbcce235 --- /dev/null +++ b/tasks/coverage/misc/fail/oxc-7582.js @@ -0,0 +1,6 @@ +class C { + x = 1; + method() { + obj.#x; + } +} diff --git a/tasks/coverage/snapshots/parser_misc.snap b/tasks/coverage/snapshots/parser_misc.snap index a6e8189eebb46..75662028a5ff2 100644 --- a/tasks/coverage/snapshots/parser_misc.snap +++ b/tasks/coverage/snapshots/parser_misc.snap @@ -1,7 +1,7 @@ parser_misc Summary: AST Parsed : 30/30 (100.00%) Positive Passed: 30/30 (100.00%) -Negative Passed: 25/25 (100.00%) +Negative Passed: 26/26 (100.00%) × Unexpected token ╭─[misc/fail/oxc-169.js:2:1] @@ -264,6 +264,14 @@ Negative Passed: 25/25 (100.00%) 3 │ } ╰──── + × Private field 'x' must be declared in an enclosing class + ╭─[misc/fail/oxc-7582.js:4:9] + 3 │ method() { + 4 │ obj.#x; + · ── + 5 │ } + ╰──── + × The keyword 'let' is reserved ╭─[misc/fail/oxc.js:3:1] 2 │