Skip to content

Commit ffa30a7

Browse files
Split "use strict" into separate transformer, fix bugs with prologues (#2028)
Co-authored-by: Sheetal Nandi <shkamat@microsoft.com>
1 parent db968bc commit ffa30a7

File tree

1,182 files changed

+1669
-6232
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

1,182 files changed

+1669
-6232
lines changed

internal/compiler/emitter.go

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -125,6 +125,8 @@ func getScriptTransformers(emitContext *printer.EmitContext, host printer.EmitHo
125125
tx = append(tx, downleveler)
126126
}
127127

128+
tx = append(tx, estransforms.NewUseStrictTransformer(&opts))
129+
128130
// transform module syntax
129131
tx = append(tx, getModuleTransformer(&opts))
130132

internal/execute/tsctests/tscbuild_test.go

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1949,6 +1949,7 @@ func TestBuildProgramUpdates(t *testing.T) {
19491949
sys.writeFileNoError("/user/username/projects/project/project2.tsconfig.json", stringtestutil.Dedent(`
19501950
{
19511951
"extends": "./alpha.tsconfig.json",
1952+
"files": ["other.ts"]
19521953
}`), false)
19531954
},
19541955
},

internal/printer/factory.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -399,7 +399,7 @@ func (f *NodeFactory) SplitStandardPrologue(source []*ast.Statement) (prologue [
399399
return source[:i], source[i:]
400400
}
401401
}
402-
return nil, source
402+
return source, nil
403403
}
404404

405405
// Splits a slice of statements into two parts: custom prologue statements (e.g., with `EFCustomPrologue` set) and the rest of the statements

internal/printer/printer.go

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1558,10 +1558,10 @@ func (p *Printer) emitFunctionBody(body *ast.Block) {
15581558

15591559
if p.shouldEmitBlockFunctionBodyOnSingleLine(body) && statementOffset == 0 && pos == p.writer.GetTextPos() {
15601560
p.decreaseIndent()
1561-
p.emitList((*Printer).emitStatement, body.AsNode(), body.Statements, LFSingleLineFunctionBodyStatements)
1561+
p.emitListRange((*Printer).emitStatement, body.AsNode(), body.Statements, LFSingleLineFunctionBodyStatements, statementOffset, -1)
15621562
p.increaseIndent()
15631563
} else {
1564-
p.emitList((*Printer).emitStatement, body.AsNode(), body.Statements, LFMultiLineFunctionBodyStatements)
1564+
p.emitListRange((*Printer).emitStatement, body.AsNode(), body.Statements, LFMultiLineFunctionBodyStatements, statementOffset, -1)
15651565
}
15661566

15671567
p.emitDetachedCommentsAfterStatementList(body.AsNode(), body.Statements.Loc, detachedState)
Lines changed: 55 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,55 @@
1+
package estransforms
2+
3+
import (
4+
"github.com/microsoft/typescript-go/internal/ast"
5+
"github.com/microsoft/typescript-go/internal/core"
6+
"github.com/microsoft/typescript-go/internal/transformers"
7+
)
8+
9+
func NewUseStrictTransformer(opts *transformers.TransformOptions) *transformers.Transformer {
10+
tx := &useStrictTransformer{
11+
compilerOptions: opts.CompilerOptions,
12+
getEmitModuleFormatOfFile: opts.GetEmitModuleFormatOfFile,
13+
}
14+
return tx.NewTransformer(tx.visit, opts.Context)
15+
}
16+
17+
type useStrictTransformer struct {
18+
transformers.Transformer
19+
compilerOptions *core.CompilerOptions
20+
getEmitModuleFormatOfFile func(file ast.HasFileName) core.ModuleKind
21+
}
22+
23+
func (tx *useStrictTransformer) visit(node *ast.Node) *ast.Node {
24+
if node.Kind != ast.KindSourceFile {
25+
return node
26+
}
27+
return tx.visitSourceFile(node.AsSourceFile())
28+
}
29+
30+
func (tx *useStrictTransformer) visitSourceFile(node *ast.SourceFile) *ast.Node {
31+
if node.ScriptKind == core.ScriptKindJSON {
32+
return node.AsNode()
33+
}
34+
35+
if tx.compilerOptions.GetEmitModuleKind() == core.ModuleKindPreserve {
36+
return node.AsNode()
37+
}
38+
39+
isExternalModule := ast.IsExternalModule(node)
40+
format := tx.getEmitModuleFormatOfFile(node)
41+
42+
if isExternalModule && format >= core.ModuleKindES2015 {
43+
return node.AsNode()
44+
}
45+
46+
if isExternalModule ||
47+
tx.compilerOptions.AlwaysStrict.DefaultIfUnknown(tx.compilerOptions.Strict).IsTrue() {
48+
statements := tx.Factory().EnsureUseStrict(node.Statements.Nodes)
49+
statementList := tx.Factory().NewNodeList(statements)
50+
statementList.Loc = node.Statements.Loc
51+
return tx.Factory().UpdateSourceFile(node, statementList, node.EndOfFileToken).AsSourceFile().AsNode()
52+
}
53+
54+
return node.AsNode()
55+
}

internal/transformers/moduletransforms/commonjsmodule.go

Lines changed: 0 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -297,12 +297,6 @@ func (tx *CommonJSModuleTransformer) transformCommonJSModule(node *ast.SourceFil
297297
prologue, rest := tx.Factory().SplitStandardPrologue(node.Statements.Nodes)
298298
statements := slices.Clone(prologue)
299299

300-
// ensure "use strict" if not present
301-
if ast.IsExternalModule(tx.currentSourceFile) ||
302-
tx.compilerOptions.AlwaysStrict.DefaultIfUnknown(tx.compilerOptions.Strict).IsTrue() {
303-
statements = tx.Factory().EnsureUseStrict(statements)
304-
}
305-
306300
// emit custom prologues from other transformations
307301
custom, rest := tx.Factory().SplitCustomPrologue(rest)
308302
statements = append(statements, core.FirstResult(tx.topLevelVisitor.VisitSlice(custom))...)

testdata/baselines/reference/compiler/jsxNestedIndentation.js

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ function Test() {
1313

1414

1515
//// [jsxNestedIndentation.js]
16+
"use strict";
1617
function Test() {
1718
return React.createElement(Child, null,
1819
React.createElement(Child, null,

testdata/baselines/reference/conformance/deepElementAccessExpressionInJS.js

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@ function calculatePropertyName(index) {
1616

1717

1818
//// [elementAccessExpressionInJS.js]
19+
"use strict";
1920
if (module[calculatePropertyName(1)]) {
2021
}
2122
function calculatePropertyName(index) {

testdata/baselines/reference/submodule/compiler/abstractIdentifierNameStrict.js

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,6 @@ function foo() {
1111
//// [abstractIdentifierNameStrict.js]
1212
var abstract = true;
1313
function foo() {
14-
"use strict";
1514
"use strict";
1615
var abstract = true;
1716
}

testdata/baselines/reference/submodule/compiler/abstractIdentifierNameStrict.js.diff

Lines changed: 0 additions & 9 deletions
This file was deleted.

0 commit comments

Comments
 (0)