mirror of
https://github.com/danbulant/oxc
synced 2026-05-24 12:21:58 +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),
|
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)]
|
#[derive(Debug)]
|
||||||
#[cfg_attr(feature = "serialize", derive(Serialize, Tsify))]
|
#[cfg_attr(feature = "serialize", derive(Serialize, Tsify))]
|
||||||
#[cfg_attr(feature = "serialize", serde(tag = "type", rename_all = "camelCase"))]
|
#[cfg_attr(feature = "serialize", serde(tag = "type", rename_all = "camelCase"))]
|
||||||
|
|
|
||||||
|
|
@ -153,6 +153,10 @@ impl<'a> TSModuleDeclaration<'a> {
|
||||||
) -> Self {
|
) -> Self {
|
||||||
Self { span, id, body, kind, declare, scope_id: Cell::default() }
|
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> {
|
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> {
|
impl<'a> Decorator<'a> {
|
||||||
/// Get the name of the decorator
|
/// Get the name of the decorator
|
||||||
/// ```ts
|
/// ```ts
|
||||||
|
|
|
||||||
|
|
@ -2647,7 +2647,13 @@ pub mod walk {
|
||||||
TSModuleDeclarationName::Identifier(ident) => visitor.visit_identifier_name(ident),
|
TSModuleDeclarationName::Identifier(ident) => visitor.visit_identifier_name(ident),
|
||||||
TSModuleDeclarationName::StringLiteral(lit) => visitor.visit_string_literal(lit),
|
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 {
|
match &decl.body {
|
||||||
Some(TSModuleDeclarationBody::TSModuleDeclaration(decl)) => {
|
Some(TSModuleDeclarationBody::TSModuleDeclaration(decl)) => {
|
||||||
visitor.visit_ts_module_declaration(decl);
|
visitor.visit_ts_module_declaration(decl);
|
||||||
|
|
|
||||||
|
|
@ -2727,7 +2727,13 @@ pub mod walk_mut {
|
||||||
TSModuleDeclarationName::Identifier(ident) => visitor.visit_identifier_name(ident),
|
TSModuleDeclarationName::Identifier(ident) => visitor.visit_identifier_name(ident),
|
||||||
TSModuleDeclarationName::StringLiteral(lit) => visitor.visit_string_literal(lit),
|
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 {
|
match &mut decl.body {
|
||||||
Some(TSModuleDeclarationBody::TSModuleDeclaration(decl)) => {
|
Some(TSModuleDeclarationBody::TSModuleDeclaration(decl)) => {
|
||||||
visitor.visit_ts_module_declaration(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);
|
let parent_scope_flags = self.scope.get_flags(parent_scope_id);
|
||||||
|
|
||||||
if !strict_mode
|
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()
|
&& parent_scope_flags.is_strict_mode()
|
||||||
{
|
{
|
||||||
strict_mode = true;
|
strict_mode = true;
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue