diff --git a/crates/oxc_semantic/src/checker/javascript.rs b/crates/oxc_semantic/src/checker/javascript.rs index 7c3cb018c85d3..b41feb24f179f 100644 --- a/crates/oxc_semantic/src/checker/javascript.rs +++ b/crates/oxc_semantic/src/checker/javascript.rs @@ -13,7 +13,7 @@ use oxc_syntax::{ number::NumberBase, operator::{AssignmentOperator, UnaryOperator}, scope::{ScopeFlags, ScopeId}, - symbol::SymbolFlags, + symbol::{SymbolFlags, SymbolId}, }; use crate::{IsGlobalReference, builder::SemanticBuilder, diagnostics::redeclaration}; @@ -98,9 +98,15 @@ pub const STRICT_MODE_NAMES: Set<&'static str> = phf_set! { "yield", }; -pub fn check_identifier(name: &str, span: Span, ctx: &SemanticBuilder<'_>) { - // ts module block allows revered keywords - if ctx.current_scope_flags().is_ts_module_block() { +pub fn check_identifier( + name: &str, + span: Span, + symbol_id: Option, + ctx: &SemanticBuilder<'_>, +) { + // reserved keywords are allowed in ambient contexts + if ctx.source_type.is_typescript_definition() || is_current_node_ambient_binding(symbol_id, ctx) + { return; } if name == "await" { @@ -120,6 +126,24 @@ pub fn check_identifier(name: &str, span: Span, ctx: &SemanticBuilder<'_>) { } } +fn is_current_node_ambient_binding(symbol_id: Option, ctx: &SemanticBuilder<'_>) -> bool { + if ctx.current_scope_flags().is_ts_module_block() { + return true; + } + + if let Some(symbol_id) = symbol_id + && ctx.scoping.symbol_flags(symbol_id).contains(SymbolFlags::Ambient) + { + true + } else if let AstKind::BindingIdentifier(id) = ctx.nodes.kind(ctx.current_node_id) + && let Some(symbol_id) = id.symbol_id.get() + { + ctx.scoping.symbol_flags(symbol_id).contains(SymbolFlags::Ambient) + } else { + false + } +} + fn unexpected_identifier_assign(x0: &str, span1: Span) -> OxcDiagnostic { OxcDiagnostic::error(format!("Cannot assign to '{x0}' in strict mode")).with_label(span1) } diff --git a/crates/oxc_semantic/src/checker/mod.rs b/crates/oxc_semantic/src/checker/mod.rs index 95be2ae897cf1..a3b811782930c 100644 --- a/crates/oxc_semantic/src/checker/mod.rs +++ b/crates/oxc_semantic/src/checker/mod.rs @@ -16,14 +16,14 @@ pub fn check<'a>(kind: AstKind<'a>, ctx: &SemanticBuilder<'a>) { js::check_unresolved_exports(program, ctx); } AstKind::BindingIdentifier(ident) => { - js::check_identifier(&ident.name, ident.span, ctx); + js::check_identifier(&ident.name, ident.span, ident.symbol_id.get(), ctx); js::check_binding_identifier(ident, ctx); } AstKind::IdentifierReference(ident) => { - js::check_identifier(&ident.name, ident.span, ctx); + js::check_identifier(&ident.name, ident.span, None, ctx); js::check_identifier_reference(ident, ctx); } - AstKind::LabelIdentifier(ident) => js::check_identifier(&ident.name, ident.span, ctx), + AstKind::LabelIdentifier(ident) => js::check_identifier(&ident.name, ident.span, None, ctx), AstKind::PrivateIdentifier(ident) => js::check_private_identifier_outside_class(ident, ctx), AstKind::NumericLiteral(lit) => js::check_number_literal(lit, ctx), AstKind::StringLiteral(lit) => js::check_string_literal(lit, ctx), diff --git a/tasks/coverage/misc/pass/declare-let-private.ts b/tasks/coverage/misc/pass/declare-let-private.ts new file mode 100644 index 0000000000000..07b90fed2240c --- /dev/null +++ b/tasks/coverage/misc/pass/declare-let-private.ts @@ -0,0 +1,3 @@ +declare let private: number; + +export {}; diff --git a/tasks/coverage/snapshots/codegen_misc.snap b/tasks/coverage/snapshots/codegen_misc.snap index c3c0ff020993f..8feb2c6d0afa2 100644 --- a/tasks/coverage/snapshots/codegen_misc.snap +++ b/tasks/coverage/snapshots/codegen_misc.snap @@ -1,3 +1,3 @@ codegen_misc Summary: -AST Parsed : 50/50 (100.00%) -Positive Passed: 50/50 (100.00%) +AST Parsed : 51/51 (100.00%) +Positive Passed: 51/51 (100.00%) diff --git a/tasks/coverage/snapshots/formatter_misc.snap b/tasks/coverage/snapshots/formatter_misc.snap index 224a087461ff5..8bbe756a122b5 100644 --- a/tasks/coverage/snapshots/formatter_misc.snap +++ b/tasks/coverage/snapshots/formatter_misc.snap @@ -1,3 +1,3 @@ formatter_misc Summary: -AST Parsed : 50/50 (100.00%) -Positive Passed: 50/50 (100.00%) +AST Parsed : 51/51 (100.00%) +Positive Passed: 51/51 (100.00%) diff --git a/tasks/coverage/snapshots/parser_misc.snap b/tasks/coverage/snapshots/parser_misc.snap index 16e9a1e6eeb87..e5d9e5d5f6406 100644 --- a/tasks/coverage/snapshots/parser_misc.snap +++ b/tasks/coverage/snapshots/parser_misc.snap @@ -1,6 +1,6 @@ parser_misc Summary: -AST Parsed : 50/50 (100.00%) -Positive Passed: 50/50 (100.00%) +AST Parsed : 51/51 (100.00%) +Positive Passed: 51/51 (100.00%) Negative Passed: 118/118 (100.00%) × Cannot assign to 'arguments' in strict mode diff --git a/tasks/coverage/snapshots/parser_typescript.snap b/tasks/coverage/snapshots/parser_typescript.snap index 3eec8c321d7e2..9d4ddf973a962 100644 --- a/tasks/coverage/snapshots/parser_typescript.snap +++ b/tasks/coverage/snapshots/parser_typescript.snap @@ -2,7 +2,7 @@ commit: cc2610fd parser_typescript Summary: AST Parsed : 9821/9822 (99.99%) -Positive Passed: 9809/9822 (99.87%) +Positive Passed: 9810/9822 (99.88%) Negative Passed: 1455/2545 (57.17%) Expect Syntax Error: tasks/coverage/typescript/tests/cases/compiler/ExportAssignment7.ts @@ -2365,23 +2365,6 @@ Expect to Parse: tasks/coverage/typescript/tests/cases/conformance/es6/moduleExp 65 │ var y = _; ╰──── -Expect to Parse: tasks/coverage/typescript/tests/cases/conformance/externalModules/topLevelAwait.3.ts - - × The keyword 'await' is reserved - ╭─[typescript/tests/cases/conformance/externalModules/topLevelAwait.3.ts:3:15] - 2 │ export {}; - 3 │ declare const await: any; - · ────────── - 4 │ declare class C extends await {} - ╰──── - - × The keyword 'await' is reserved - ╭─[typescript/tests/cases/conformance/externalModules/topLevelAwait.3.ts:4:25] - 3 │ declare const await: any; - 4 │ declare class C extends await {} - · ───── - ╰──── - Expect to Parse: tasks/coverage/typescript/tests/cases/conformance/parser/ecmascript5/ComputedPropertyNames/parserES5ComputedPropertyName11.ts × Function implementation is missing or not immediately following the declaration. diff --git a/tasks/coverage/snapshots/semantic_misc.snap b/tasks/coverage/snapshots/semantic_misc.snap index 7e1b0bbe202ea..647dbd803fd94 100644 --- a/tasks/coverage/snapshots/semantic_misc.snap +++ b/tasks/coverage/snapshots/semantic_misc.snap @@ -1,6 +1,11 @@ semantic_misc Summary: -AST Parsed : 50/50 (100.00%) -Positive Passed: 32/50 (64.00%) +AST Parsed : 51/51 (100.00%) +Positive Passed: 32/51 (62.75%) +semantic Error: tasks/coverage/misc/pass/declare-let-private.ts +Bindings mismatch: +after transform: ScopeId(0): ["private"] +rebuilt : ScopeId(0): [] + semantic Error: tasks/coverage/misc/pass/oxc-11593.ts Scope children mismatch: after transform: ScopeId(0): [ScopeId(1)] diff --git a/tasks/coverage/snapshots/semantic_typescript.snap b/tasks/coverage/snapshots/semantic_typescript.snap index 869ddaf2ea3cc..10ad7ec05ea82 100644 --- a/tasks/coverage/snapshots/semantic_typescript.snap +++ b/tasks/coverage/snapshots/semantic_typescript.snap @@ -2,7 +2,7 @@ commit: cc2610fd semantic_typescript Summary: AST Parsed : 6148/6148 (100.00%) -Positive Passed: 2661/6148 (43.28%) +Positive Passed: 2662/6148 (43.30%) semantic Error: tasks/coverage/typescript/tests/cases/compiler/2dArrays.ts Symbol reference IDs mismatch for "Cell": after transform: SymbolId(0): [ReferenceId(1)] @@ -42824,10 +42824,6 @@ Scope children mismatch: after transform: ScopeId(0): [ScopeId(1)] rebuilt : ScopeId(0): [] -semantic Error: tasks/coverage/typescript/tests/cases/conformance/externalModules/topLevelAwait.3.ts -The keyword 'await' is reserved -The keyword 'await' is reserved - semantic Error: tasks/coverage/typescript/tests/cases/conformance/externalModules/typeAndNamespaceExportMerge.ts Scope children mismatch: after transform: ScopeId(0): [ScopeId(1)] diff --git a/tasks/coverage/snapshots/transformer_misc.snap b/tasks/coverage/snapshots/transformer_misc.snap index 5228cd7b67ef4..955d1ad269bd5 100644 --- a/tasks/coverage/snapshots/transformer_misc.snap +++ b/tasks/coverage/snapshots/transformer_misc.snap @@ -1,3 +1,3 @@ transformer_misc Summary: -AST Parsed : 50/50 (100.00%) -Positive Passed: 50/50 (100.00%) +AST Parsed : 51/51 (100.00%) +Positive Passed: 51/51 (100.00%)