mirror of
https://github.com/danbulant/oxc
synced 2026-05-19 12:19:15 +00:00
fix(semantic): apply strict mode scope flag for strict mode TS Modules (#3861)
#3830 added a `directives` field to `TSModuleBlock`. Make semantic apply strict mode scope flag if directives include `'use strict'`.
This commit is contained in:
parent
acf69fa1b6
commit
8c9fc6347d
5 changed files with 36 additions and 4 deletions
|
|
@ -782,7 +782,11 @@ pub enum TSTypePredicateName<'a> {
|
|||
This(TSThisType),
|
||||
}
|
||||
|
||||
#[visited_node(scope(ScopeFlags::TsModuleBlock), enter_scope_before(body))]
|
||||
#[visited_node(
|
||||
scope(ScopeFlags::TsModuleBlock),
|
||||
enter_scope_before(body),
|
||||
strict_if(self.body.as_ref().is_some_and(|body| body.is_strict()))
|
||||
)]
|
||||
#[derive(Debug)]
|
||||
#[cfg_attr(feature = "serialize", derive(Serialize, Tsify))]
|
||||
#[cfg_attr(feature = "serialize", serde(tag = "type", rename_all = "camelCase"))]
|
||||
|
|
|
|||
|
|
@ -153,6 +153,10 @@ impl<'a> TSModuleDeclaration<'a> {
|
|||
) -> Self {
|
||||
Self { span, id, body, kind, declare, scope_id: Cell::default() }
|
||||
}
|
||||
|
||||
pub fn is_strict(&self) -> bool {
|
||||
self.body.as_ref().is_some_and(TSModuleDeclarationBody::is_strict)
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a> Hash for TSModuleDeclaration<'a> {
|
||||
|
|
@ -177,6 +181,18 @@ impl<'a> TSModuleDeclarationName<'a> {
|
|||
}
|
||||
}
|
||||
|
||||
impl<'a> TSModuleDeclarationBody<'a> {
|
||||
pub fn is_strict(&self) -> bool {
|
||||
matches!(self, Self::TSModuleBlock(block) if block.is_strict())
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a> TSModuleBlock<'a> {
|
||||
pub fn is_strict(&self) -> bool {
|
||||
self.directives.iter().any(Directive::is_use_strict)
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a> Decorator<'a> {
|
||||
/// Get the name of the decorator
|
||||
/// ```ts
|
||||
|
|
|
|||
|
|
@ -2647,7 +2647,13 @@ pub mod walk {
|
|||
TSModuleDeclarationName::Identifier(ident) => visitor.visit_identifier_name(ident),
|
||||
TSModuleDeclarationName::StringLiteral(lit) => visitor.visit_string_literal(lit),
|
||||
}
|
||||
visitor.enter_scope(ScopeFlags::TsModuleBlock);
|
||||
visitor.enter_scope({
|
||||
let mut flags = ScopeFlags::TsModuleBlock;
|
||||
if decl.is_strict() {
|
||||
flags |= ScopeFlags::StrictMode;
|
||||
}
|
||||
flags
|
||||
});
|
||||
match &decl.body {
|
||||
Some(TSModuleDeclarationBody::TSModuleDeclaration(decl)) => {
|
||||
visitor.visit_ts_module_declaration(decl);
|
||||
|
|
|
|||
|
|
@ -2727,7 +2727,13 @@ pub mod walk_mut {
|
|||
TSModuleDeclarationName::Identifier(ident) => visitor.visit_identifier_name(ident),
|
||||
TSModuleDeclarationName::StringLiteral(lit) => visitor.visit_string_literal(lit),
|
||||
}
|
||||
visitor.enter_scope(ScopeFlags::TsModuleBlock);
|
||||
visitor.enter_scope({
|
||||
let mut flags = ScopeFlags::TsModuleBlock;
|
||||
if decl.is_strict() {
|
||||
flags |= ScopeFlags::StrictMode;
|
||||
}
|
||||
flags
|
||||
});
|
||||
match &mut decl.body {
|
||||
Some(TSModuleDeclarationBody::TSModuleDeclaration(decl)) => {
|
||||
visitor.visit_ts_module_declaration(decl);
|
||||
|
|
|
|||
|
|
@ -424,7 +424,7 @@ impl<'a> Visit<'a> for SemanticBuilder<'a> {
|
|||
let parent_scope_flags = self.scope.get_flags(parent_scope_id);
|
||||
|
||||
if !strict_mode
|
||||
&& parent_scope_flags.is_function()
|
||||
&& (parent_scope_flags.is_function() || parent_scope_flags.is_ts_module_block())
|
||||
&& parent_scope_flags.is_strict_mode()
|
||||
{
|
||||
strict_mode = true;
|
||||
|
|
|
|||
Loading…
Reference in a new issue