From 4d9582d762228d9d197cdc7bac5456fe8d9ed07e Mon Sep 17 00:00:00 2001 From: Dunqing <29533304+Dunqing@users.noreply.github.com> Date: Mon, 12 Jan 2026 10:03:42 +0000 Subject: [PATCH] fix(semantic): allow `arguments`/`eval` as binding identifier names and identifier reference names in `.d.ts` (#17910) Fixes: https://github.com/oxc-project/oxc/issues/17776 --- crates/oxc_semantic/src/checker/javascript.rs | 23 ++++++++----------- tasks/coverage/misc/pass/arguments-eval.d.ts | 5 ++++ 2 files changed, 15 insertions(+), 13 deletions(-) diff --git a/crates/oxc_semantic/src/checker/javascript.rs b/crates/oxc_semantic/src/checker/javascript.rs index 7b298c2a4c8cd..c910faa20b8fb 100644 --- a/crates/oxc_semantic/src/checker/javascript.rs +++ b/crates/oxc_semantic/src/checker/javascript.rs @@ -160,6 +160,11 @@ fn is_current_node_ambient_binding(symbol_id: Option, ctx: &SemanticBu } pub fn check_binding_identifier(ident: &BindingIdentifier, ctx: &SemanticBuilder<'_>) { + // `.d.ts` files are allowed to use `eval` and `arguments` as binding identifiers + if ctx.source_type.is_typescript_definition() { + return; + } + if ctx.strict_mode() { // In strict mode, `eval` and `arguments` are banned as identifiers. if matches!(ident.name.as_str(), "eval" | "arguments") { @@ -184,24 +189,11 @@ pub fn check_binding_identifier(ident: &BindingIdentifier, ctx: &SemanticBuilder AstKind::Function(func) => matches!(func.r#type, FunctionType::TSDeclareFunction), AstKind::FormalParameter(_) | AstKind::FormalParameterRest(_) => { is_declare_function(&ctx.nodes.parent_kind(parent.id())) - || ctx.nodes.ancestor_kinds(parent.id()).nth(1).is_some_and(|node| { - matches!( - node, - AstKind::TSFunctionType(_) | AstKind::TSMethodSignature(_) - ) - }) } AstKind::BindingRestElement(_) => { let grand_parent = ctx.nodes.parent_node(parent.id()); is_declare_function(&ctx.nodes.parent_kind(grand_parent.id())) - || ctx.nodes.ancestor_kinds(grand_parent.id()).nth(1).is_some_and(|node| { - matches!( - node, - AstKind::TSFunctionType(_) | AstKind::TSMethodSignature(_) - ) - }) } - AstKind::TSTypeAliasDeclaration(_) | AstKind::TSInterfaceDeclaration(_) => true, _ => false, }; @@ -233,6 +225,11 @@ pub fn check_binding_identifier(ident: &BindingIdentifier, ctx: &SemanticBuilder } pub fn check_identifier_reference(ident: &IdentifierReference, ctx: &SemanticBuilder<'_>) { + // `.d.ts` files are allowed to use `eval` and `arguments` as identifier references + if ctx.source_type.is_typescript_definition() { + return; + } + // Static Semantics: AssignmentTargetType // 1. If this IdentifierReference is contained in strict mode code and StringValue of Identifier is "eval" or "arguments", return invalid. if ctx.strict_mode() && matches!(ident.name.as_str(), "arguments" | "eval") { diff --git a/tasks/coverage/misc/pass/arguments-eval.d.ts b/tasks/coverage/misc/pass/arguments-eval.d.ts index ac53392bd730f..af2cbd502af4a 100644 --- a/tasks/coverage/misc/pass/arguments-eval.d.ts +++ b/tasks/coverage/misc/pass/arguments-eval.d.ts @@ -15,3 +15,8 @@ declare namespace foo2 { interface arguments {} interface eval {} } + +declare global { + function arguments(...arguments: any[]): typeof arguments; + function eval(...eval: any[]): typeof eval; +}