From 27149f3c88969b18cfbc4d60d2e83a044517d98f Mon Sep 17 00:00:00 2001 From: Wesley Wigham Date: Tue, 24 Nov 2015 13:31:30 -0800 Subject: [PATCH] only emit use strict if a use strict prologue isnt found --- src/compiler/emitter.ts | 38 ++++++++++++------- .../reference/downlevelLetConst13.js | 2 +- .../baselines/reference/modulePrologueAMD.js | 1 - .../reference/modulePrologueCommonjs.js | 2 +- .../reference/modulePrologueSystem.js | 1 - .../baselines/reference/modulePrologueUmd.js | 1 - tests/baselines/reference/parser509546_2.js | 2 +- ...odeReservedWordInImportEqualDeclaration.js | 2 +- 8 files changed, 28 insertions(+), 21 deletions(-) diff --git a/src/compiler/emitter.ts b/src/compiler/emitter.ts index e4d685597e7..ca44be8bf71 100644 --- a/src/compiler/emitter.ts +++ b/src/compiler/emitter.ts @@ -7383,8 +7383,7 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, Promi write(`], function(${exportFunctionForFile}) {`); writeLine(); increaseIndent(); - emitUseStrictPrologueDirective(); - const startIndex = emitDirectivePrologues(node.statements, /*startWithNewLine*/ true); + const startIndex = emitDirectivePrologues(node.statements, /*startWithNewLine*/ true, /*ensureUseStrict*/ true); emitEmitHelpers(node); emitCaptureThisForNodeIfNecessary(node); emitSystemModuleBody(node, dependencyGroups, startIndex); @@ -7494,8 +7493,7 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, Promi writeModuleName(node, emitRelativePathAsModuleName); emitAMDDependencies(node, /*includeNonAmdDependencies*/ true, emitRelativePathAsModuleName); increaseIndent(); - emitUseStrictPrologueDirective(); - const startIndex = emitDirectivePrologues(node.statements, /*startWithNewLine*/ true); + const startIndex = emitDirectivePrologues(node.statements, /*startWithNewLine*/ true, /*ensureUseStrict*/ true); emitExportStarHelper(); emitCaptureThisForNodeIfNecessary(node); emitLinesStartingAt(node.statements, startIndex); @@ -7507,8 +7505,7 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, Promi } function emitCommonJSModule(node: SourceFile) { - emitUseStrictPrologueDirective(); - const startIndex = emitDirectivePrologues(node.statements, /*startWithNewLine*/ false); + const startIndex = emitDirectivePrologues(node.statements, /*startWithNewLine*/ false, /*ensureUseStrict*/ true); emitEmitHelpers(node); collectExternalModuleInfo(node); emitExportStarHelper(); @@ -7518,11 +7515,6 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, Promi emitExportEquals(/*emitAsReturn*/ false); } - function emitUseStrictPrologueDirective() { - writeLine(); - write("\"use strict\";"); - } - function emitUMDModule(node: SourceFile) { emitEmitHelpers(node); collectExternalModuleInfo(node); @@ -7542,8 +7534,7 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, Promi })(`); emitAMDFactoryHeader(dependencyNames); increaseIndent(); - emitUseStrictPrologueDirective(); - const startIndex = emitDirectivePrologues(node.statements, /*startWithNewLine*/ true); + const startIndex = emitDirectivePrologues(node.statements, /*startWithNewLine*/ true, /*ensureUseStrict*/ true); emitExportStarHelper(); emitCaptureThisForNodeIfNecessary(node); emitLinesStartingAt(node.statements, startIndex); @@ -7685,19 +7676,38 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, Promi } } - function emitDirectivePrologues(statements: Node[], startWithNewLine: boolean): number { + function isUseStrictPrologue(node: ExpressionStatement): boolean { + return !!(node.expression as StringLiteral).text.match(/use strict/); + } + + function ensureUseStrictPrologue(startWithNewLine: boolean, writeUseStrict: boolean) { + if (writeUseStrict) { + if (startWithNewLine) { + writeLine(); + } + write("\"use strict\";"); + } + } + + function emitDirectivePrologues(statements: Node[], startWithNewLine: boolean, ensureUseStrict?: boolean): number { + let foundUseStrict = false; for (let i = 0; i < statements.length; ++i) { if (isPrologueDirective(statements[i])) { + if (isUseStrictPrologue(statements[i] as ExpressionStatement)) { + foundUseStrict = true; + } if (startWithNewLine || i > 0) { writeLine(); } emit(statements[i]); } else { + ensureUseStrictPrologue(startWithNewLine || i > 0, !foundUseStrict && ensureUseStrict); // return index of the first non prologue directive return i; } } + ensureUseStrictPrologue(startWithNewLine, !foundUseStrict && ensureUseStrict); return statements.length; } diff --git a/tests/baselines/reference/downlevelLetConst13.js b/tests/baselines/reference/downlevelLetConst13.js index 08e83e7d056..b6baf850800 100644 --- a/tests/baselines/reference/downlevelLetConst13.js +++ b/tests/baselines/reference/downlevelLetConst13.js @@ -20,7 +20,7 @@ export module M { } //// [downlevelLetConst13.js] -"use strict";'use strict'; +'use strict'; // exported let\const bindings should not be renamed exports.foo = 10; exports.bar = "123"; diff --git a/tests/baselines/reference/modulePrologueAMD.js b/tests/baselines/reference/modulePrologueAMD.js index a701defdc68..904808b9f6b 100644 --- a/tests/baselines/reference/modulePrologueAMD.js +++ b/tests/baselines/reference/modulePrologueAMD.js @@ -5,7 +5,6 @@ export class Foo {} //// [modulePrologueAMD.js] define(["require", "exports"], function (require, exports) { - "use strict"; "use strict"; var Foo = (function () { function Foo() { diff --git a/tests/baselines/reference/modulePrologueCommonjs.js b/tests/baselines/reference/modulePrologueCommonjs.js index 86df3f3b504..67b704a3650 100644 --- a/tests/baselines/reference/modulePrologueCommonjs.js +++ b/tests/baselines/reference/modulePrologueCommonjs.js @@ -4,7 +4,7 @@ export class Foo {} //// [modulePrologueCommonjs.js] -"use strict";"use strict"; +"use strict"; var Foo = (function () { function Foo() { } diff --git a/tests/baselines/reference/modulePrologueSystem.js b/tests/baselines/reference/modulePrologueSystem.js index 93af4afd31f..91703d1c7fb 100644 --- a/tests/baselines/reference/modulePrologueSystem.js +++ b/tests/baselines/reference/modulePrologueSystem.js @@ -5,7 +5,6 @@ export class Foo {} //// [modulePrologueSystem.js] System.register([], function(exports_1) { - "use strict"; "use strict"; var Foo; return { diff --git a/tests/baselines/reference/modulePrologueUmd.js b/tests/baselines/reference/modulePrologueUmd.js index aab9e8368ad..65803af6cad 100644 --- a/tests/baselines/reference/modulePrologueUmd.js +++ b/tests/baselines/reference/modulePrologueUmd.js @@ -12,7 +12,6 @@ export class Foo {} define(["require", "exports"], factory); } })(function (require, exports) { - "use strict"; "use strict"; var Foo = (function () { function Foo() { diff --git a/tests/baselines/reference/parser509546_2.js b/tests/baselines/reference/parser509546_2.js index caeb714c617..976bbd1e471 100644 --- a/tests/baselines/reference/parser509546_2.js +++ b/tests/baselines/reference/parser509546_2.js @@ -7,7 +7,7 @@ export class Logger { //// [parser509546_2.js] -"use strict";"use strict"; +"use strict"; var Logger = (function () { function Logger() { } diff --git a/tests/baselines/reference/strictModeReservedWordInImportEqualDeclaration.js b/tests/baselines/reference/strictModeReservedWordInImportEqualDeclaration.js index 7044d4a61b1..50ed1b4d755 100644 --- a/tests/baselines/reference/strictModeReservedWordInImportEqualDeclaration.js +++ b/tests/baselines/reference/strictModeReservedWordInImportEqualDeclaration.js @@ -4,4 +4,4 @@ import public = require("1"); //// [strictModeReservedWordInImportEqualDeclaration.js] -"use strict";"use strict"; +"use strict";