[Transforms] fix _this = this capture emitted before "use strict" directives in AMD module output (#7953)

* Fix 7913: emit prologue directives as a first statement in emitted AMD module

* Do not ensure that prologue-directive is added when using it when transforming function body

* Address PR: preserve prologue directives location and make sure it is the first statement in the result statements array

* Address PR: fix comment
This commit is contained in:
Yui 2016-04-14 09:41:12 -07:00
parent c21ff6421c
commit d56ac44a27
3 changed files with 21 additions and 3 deletions

View File

@ -1252,7 +1252,18 @@ namespace ts {
return (node.expression as StringLiteral).text === "use strict";
}
/**
* Add any necessary prologue-directives into target statement-array.
* The function needs to be called during each transformation step.
* This function needs to be called whenever we transform the statement
* list of a source file, namespace, or function-like body.
*
* @param target: result statements array
* @param source: origin statements array
* @param ensureUseStrict: boolean determining whether the function need to add prologue-directives
*/
export function addPrologueDirectives(target: Statement[], source: Statement[], ensureUseStrict?: boolean): number {
Debug.assert(target.length === 0, "PrologueDirectives should be at the first statement in the target statements array");
let foundUseStrict = false;
for (let i = 0; i < source.length; i++) {
if (isPrologueDirective(source[i])) {

View File

@ -1211,7 +1211,15 @@ namespace ts {
let statementsLocation: TextRange;
const statements: Statement[] = [];
const body = node.body;
let statementOffset: number;
startLexicalEnvironment();
if (isBlock(body)) {
// ensureUseStrict is false because no new prologue-directive should be added.
// addPrologueDirectives will simply put already-existing directives at the beginning of the target statement-array
statementOffset = addPrologueDirectives(statements, body.statements, /*ensureUseStrict*/ false);
}
addCaptureThisForNodeIfNeeded(statements, node);
addDefaultValueAssignmentsIfNeeded(statements, node);
addRestParameterIfNeeded(statements, node, /*inConstructorWithSynthesizedSuper*/ false);
@ -1221,10 +1229,9 @@ namespace ts {
multiLine = true;
}
const body = node.body;
if (isBlock(body)) {
statementsLocation = body.statements;
addRange(statements, visitNodes(body.statements, visitor, isStatement));
addRange(statements, visitNodes(body.statements, visitor, isStatement, statementOffset));
// If the original body was a multi-line block, this must be a multi-line block.
if (!multiLine && body.multiLine) {

View File

@ -193,7 +193,7 @@ namespace ts {
startLexicalEnvironment();
// Add any prologue directives.
const statementOffset = addPrologueDirectives(statements, node.statements, !compilerOptions.noImplicitUseStrict);
const statementOffset = addPrologueDirectives(statements, node.statements, /*ensureUseStrict*/ !compilerOptions.noImplicitUseStrict);
// var __moduleName = context_1 && context_1.id;
addNode(statements,