Skip to content

Commit

Permalink
"use strict" only works in module/function bodies
Browse files Browse the repository at this point in the history
  • Loading branch information
evanw committed Dec 4, 2021
1 parent 54c0eae commit ff6c050
Show file tree
Hide file tree
Showing 2 changed files with 24 additions and 12 deletions.
30 changes: 18 additions & 12 deletions internal/js_parser/js_parser.go
Expand Up @@ -5800,15 +5800,16 @@ const (
)

type parseStmtOpts struct {
tsDecorators *deferredTSDecorators
lexicalDecl lexicalDecl
isModuleScope bool
isNamespaceScope bool
isExport bool
isNameOptional bool // For "export default" pseudo-statements
isTypeScriptDeclare bool
isForLoopInit bool
isForAwaitLoopInit bool
tsDecorators *deferredTSDecorators
lexicalDecl lexicalDecl
isModuleScope bool
isNamespaceScope bool
isExport bool
isNameOptional bool // For "export default" pseudo-statements
isTypeScriptDeclare bool
isForLoopInit bool
isForAwaitLoopInit bool
allowDirectivePrologue bool
}

func (p *parser) parseStmt(opts parseStmtOpts) js_ast.Stmt {
Expand Down Expand Up @@ -6958,7 +6959,9 @@ func (p *parser) parseFnBody(data fnOrArrowDataParse) js_ast.FnBody {
defer p.popScope()

p.lexer.Expect(js_lexer.TOpenBrace)
stmts := p.parseStmtsUpTo(js_lexer.TCloseBrace, parseStmtOpts{})
stmts := p.parseStmtsUpTo(js_lexer.TCloseBrace, parseStmtOpts{
allowDirectivePrologue: true,
})
p.lexer.Next()

p.allowIn = oldAllowIn
Expand All @@ -6975,7 +6978,7 @@ func (p *parser) parseStmtsUpTo(end js_lexer.T, opts parseStmtOpts) []js_ast.Stm
stmts := []js_ast.Stmt{}
returnWithoutSemicolonStart := int32(-1)
opts.lexicalDecl = lexicalDeclAllowAll
isDirectivePrologue := true
isDirectivePrologue := opts.allowDirectivePrologue

for {
// Preserve some statement-level comments
Expand Down Expand Up @@ -14493,7 +14496,10 @@ func Parse(log logger.Log, source logger.Source, options Options) (result js_ast
p.fnOrArrowDataParse.isTopLevel = true

// Parse the file in the first pass, but do not bind symbols
stmts := p.parseStmtsUpTo(js_lexer.TEndOfFile, parseStmtOpts{isModuleScope: true})
stmts := p.parseStmtsUpTo(js_lexer.TEndOfFile, parseStmtOpts{
isModuleScope: true,
allowDirectivePrologue: true,
})
p.prepareForVisitPass()

// Strip off a leading "use strict" directive when not bundling
Expand Down
6 changes: 6 additions & 0 deletions internal/js_parser/js_parser_test.go
Expand Up @@ -432,6 +432,12 @@ func TestStrictMode(t *testing.T) {
expectPrinted(t, "class f {} with (x) y", "class f {\n}\nwith (x)\n y;\n")
expectPrinted(t, "with (x) y; class f {}", "with (x)\n y;\nclass f {\n}\n")
expectPrinted(t, "`use strict`; with (x) y", "`use strict`;\nwith (x)\n y;\n")
expectPrinted(t, "{ 'use strict'; with (x) y }", "{\n \"use strict\";\n with (x)\n y;\n}\n")
expectPrinted(t, "if (0) { 'use strict'; with (x) y }", "if (0) {\n \"use strict\";\n with (x)\n y;\n}\n")
expectPrinted(t, "while (0) { 'use strict'; with (x) y }", "while (0) {\n \"use strict\";\n with (x)\n y;\n}\n")
expectPrinted(t, "try { 'use strict'; with (x) y } catch {}", "try {\n \"use strict\";\n with (x)\n y;\n} catch {\n}\n")
expectPrinted(t, "try {} catch { 'use strict'; with (x) y }", "try {\n} catch {\n \"use strict\";\n with (x)\n y;\n}\n")
expectPrinted(t, "try {} finally { 'use strict'; with (x) y }", "try {\n} finally {\n \"use strict\";\n with (x)\n y;\n}\n")
expectParseError(t, "\"use strict\"; with (x) y", "<stdin>: ERROR: With statements cannot be used in strict mode\n"+useStrict)
expectParseError(t, "function f() { 'use strict'; with (x) y }", "<stdin>: ERROR: With statements cannot be used in strict mode\n"+useStrict)
expectParseError(t, "function f() { 'use strict'; function y() { with (x) y } }", "<stdin>: ERROR: With statements cannot be used in strict mode\n"+useStrict)
Expand Down

0 comments on commit ff6c050

Please sign in to comment.