Skip to content

Commit

Permalink
fix(semantic): apply strict mode scope flag for strict mode TS Modules (
Browse files Browse the repository at this point in the history
#3861)

#3830 added a `directives` field to `TSModuleBlock`. Make semantic apply strict mode scope flag if directives include `'use strict'`.
  • Loading branch information
overlookmotel committed Jun 24, 2024
1 parent acf69fa commit 8c9fc63
Show file tree
Hide file tree
Showing 5 changed files with 36 additions and 4 deletions.
6 changes: 5 additions & 1 deletion crates/oxc_ast/src/ast/ts.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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"))]
Expand Down
16 changes: 16 additions & 0 deletions crates/oxc_ast/src/ast_impl/ts.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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> {
Expand All @@ -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
Expand Down
8 changes: 7 additions & 1 deletion crates/oxc_ast/src/visit/visit.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand Down
8 changes: 7 additions & 1 deletion crates/oxc_ast/src/visit/visit_mut.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand Down
2 changes: 1 addition & 1 deletion crates/oxc_semantic/src/builder.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down

0 comments on commit 8c9fc63

Please sign in to comment.