Skip to content

Commit 95236e9

Browse files
authoredFeb 7, 2024
fix(es/parser): Fix detection of use strict directive (#8617)
**Description:** Directives should be at the start of the file, and this PR changes the parser to match only at the start of a file. **Related issue:** - Closes #8616.
1 parent f7baf24 commit 95236e9

File tree

8 files changed

+78
-33
lines changed

8 files changed

+78
-33
lines changed
 
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
2+
var Module = (() => {
3+
var _scriptDir = typeof document !== 'undefined' && document.currentScript ? document.currentScript.src : undefined;
4+
if (typeof __filename !== 'undefined') _scriptDir ||= __filename;
5+
return (
6+
function (moduleArg = {}) {
7+
var Module = moduleArg;
8+
var readyPromiseResolve, readyPromiseReject; Module["ready"] = new Promise((resolve, reject) => { readyPromiseResolve = resolve; readyPromiseReject = reject }); "use strict";
9+
10+
11+
return moduleArg
12+
}
13+
);
14+
})()();
15+
if (typeof exports === 'object' && typeof module === 'object')
16+
module.exports = Module;
17+
else if (typeof define === 'function' && define['amd'])
18+
define([], () => Module);
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
var Module = (function() {
2+
var _scriptDir = typeof document !== "undefined" && document.currentScript ? document.currentScript.src : undefined;
3+
if (typeof __filename !== "undefined") _scriptDir || (_scriptDir = __filename);
4+
return function() {
5+
var moduleArg = arguments.length > 0 && arguments[0] !== void 0 ? arguments[0] : {};
6+
var Module = moduleArg;
7+
var readyPromiseResolve, readyPromiseReject;
8+
Module["ready"] = new Promise(function(resolve, reject) {
9+
readyPromiseResolve = resolve;
10+
readyPromiseReject = reject;
11+
});
12+
"use strict";
13+
return moduleArg;
14+
};
15+
})()();
16+
if (typeof exports === "object" && typeof module === "object") module.exports = Module;
17+
else if (typeof define === "function" && define["amd"]) define([], function() {
18+
return Module;
19+
});

‎crates/swc_ecma_ast/src/stmt.rs

+24-1
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ use crate::{
66
expr::Expr,
77
ident::Ident,
88
pat::Pat,
9-
UsingDecl,
9+
Lit, Str, UsingDecl,
1010
};
1111

1212
/// Use when only block statements are allowed.
@@ -106,6 +106,29 @@ pub enum Stmt {
106106
Expr(ExprStmt),
107107
}
108108

109+
impl Stmt {
110+
pub fn is_use_strict(&self) -> bool {
111+
match self {
112+
Stmt::Expr(expr) => match *expr.expr {
113+
Expr::Lit(Lit::Str(Str { ref raw, .. })) => {
114+
matches!(raw, Some(value) if value == "\"use strict\"" || value == "'use strict'")
115+
}
116+
_ => false,
117+
},
118+
_ => false,
119+
}
120+
}
121+
122+
/// Returns true if the statement does not prevent the directives below
123+
/// `self` from being directives.
124+
pub fn can_precede_directive(&self) -> bool {
125+
match self {
126+
Stmt::Expr(expr) => matches!(*expr.expr, Expr::Lit(Lit::Str(_))),
127+
_ => false,
128+
}
129+
}
130+
}
131+
109132
// Memory layout depedns on the version of rustc.
110133
// #[cfg(target_pointer_width = "64")]
111134
// assert_eq_size!(Stmt, [u8; 56]);

‎crates/swc_ecma_compat_es2015/src/classes/mod.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ use swc_ecma_transforms_macros::fast_path;
1212
use swc_ecma_utils::{
1313
alias_if_required, contains_this_expr, default_constructor, is_valid_ident,
1414
is_valid_prop_ident, prepend_stmt, private_ident, prop_name_to_expr, quote_expr, quote_ident,
15-
quote_str, replace_ident, ExprFactory, IdentExt, IsDirective, ModuleItemLike, StmtLike,
15+
quote_str, replace_ident, ExprFactory, IdentExt, ModuleItemLike, StmtLike,
1616
};
1717
use swc_ecma_visit::{
1818
as_folder, noop_visit_mut_type, noop_visit_type, Fold, Visit, VisitMut, VisitMutWith, VisitWith,

‎crates/swc_ecma_parser/src/parser/class_and_fn.rs

+12-5
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
use swc_common::{Spanned, SyntaxContext};
22

33
use super::*;
4-
use crate::{error::SyntaxError, lexer::TokenContext, parser::stmt::IsDirective, Tokens};
4+
use crate::{error::SyntaxError, lexer::TokenContext, Tokens};
55

66
/// Parser for function expression and function declaration.
77
impl<I: Tokens> Parser<I> {
@@ -1615,10 +1615,17 @@ pub(super) trait FnBodyParser<Body> {
16151615
fn parse_fn_body_inner(&mut self, is_simple_parameter_list: bool) -> PResult<Body>;
16161616
}
16171617
fn has_use_strict(block: &BlockStmt) -> Option<Span> {
1618-
match block.stmts.iter().find(|stmt| stmt.is_use_strict()) {
1619-
Some(Stmt::Expr(ExprStmt { span, expr: _ })) => Some(*span),
1620-
_ => None,
1621-
}
1618+
block
1619+
.stmts
1620+
.iter()
1621+
.take_while(|s| s.can_precede_directive())
1622+
.find_map(|s| {
1623+
if s.is_use_strict() {
1624+
Some(s.span())
1625+
} else {
1626+
None
1627+
}
1628+
})
16221629
}
16231630
impl<I: Tokens> FnBodyParser<Box<BlockStmtOrExpr>> for Parser<I> {
16241631
fn parse_fn_body_inner(

‎crates/swc_ecma_parser/src/parser/stmt.rs

+1-9
Original file line numberDiff line numberDiff line change
@@ -1394,15 +1394,7 @@ enum TempForHead {
13941394
pub(super) trait IsDirective {
13951395
fn as_ref(&self) -> Option<&Stmt>;
13961396
fn is_use_strict(&self) -> bool {
1397-
match self.as_ref() {
1398-
Some(Stmt::Expr(expr)) => match *expr.expr {
1399-
Expr::Lit(Lit::Str(Str { ref raw, .. })) => {
1400-
matches!(raw, Some(value) if value == "\"use strict\"" || value == "'use strict'")
1401-
}
1402-
_ => false,
1403-
},
1404-
_ => false,
1405-
}
1397+
self.as_ref().map_or(false, Stmt::is_use_strict)
14061398
}
14071399
}
14081400

‎crates/swc_ecma_transforms_base/src/resolver/mod.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ use swc_common::{
55
Mark, Span, SyntaxContext,
66
};
77
use swc_ecma_ast::*;
8-
use swc_ecma_utils::{find_pat_ids, IsDirective};
8+
use swc_ecma_utils::find_pat_ids;
99
use swc_ecma_visit::{
1010
as_folder, noop_visit_mut_type, visit_mut_obj_and_computed, Fold, VisitMut, VisitMutWith,
1111
};

‎crates/swc_ecma_utils/src/lib.rs

+2-16
Original file line numberDiff line numberDiff line change
@@ -2306,24 +2306,10 @@ pub trait IsDirective {
23062306
}
23072307
}
23082308
fn directive_continue(&self) -> bool {
2309-
match self.as_ref() {
2310-
Some(Stmt::Expr(expr)) => match &*expr.expr {
2311-
Expr::Lit(Lit::Str(..)) => true,
2312-
_ => false,
2313-
},
2314-
_ => false,
2315-
}
2309+
self.as_ref().map_or(false, Stmt::can_precede_directive)
23162310
}
23172311
fn is_use_strict(&self) -> bool {
2318-
match self.as_ref() {
2319-
Some(Stmt::Expr(expr)) => match *expr.expr {
2320-
Expr::Lit(Lit::Str(Str { ref raw, .. })) => {
2321-
matches!(raw, Some(value) if value == "\"use strict\"" || value == "'use strict'")
2322-
}
2323-
_ => false,
2324-
},
2325-
_ => false,
2326-
}
2312+
self.as_ref().map_or(false, Stmt::is_use_strict)
23272313
}
23282314
}
23292315

0 commit comments

Comments
 (0)
Please sign in to comment.