From 393ee28fb01abee2c7ad07e5c8a028d6aebb6b35 Mon Sep 17 00:00:00 2001 From: Ron Buckton Date: Mon, 27 Jun 2016 13:48:47 -0700 Subject: [PATCH] Move 'use strict' directive out of generator for async function. --- src/compiler/transformers/generators.ts | 11 ++++++---- src/compiler/transformers/ts.ts | 10 +++++---- .../baselines/reference/asyncUseStrict_es6.js | 15 +++++++++++++ .../reference/asyncUseStrict_es6.symbols | 18 +++++++++++++++ .../reference/asyncUseStrict_es6.types | 22 +++++++++++++++++++ .../async/es6/asyncUseStrict_es6.ts | 8 +++++++ 6 files changed, 76 insertions(+), 8 deletions(-) create mode 100644 tests/baselines/reference/asyncUseStrict_es6.js create mode 100644 tests/baselines/reference/asyncUseStrict_es6.symbols create mode 100644 tests/baselines/reference/asyncUseStrict_es6.types create mode 100644 tests/cases/conformance/async/es6/asyncUseStrict_es6.ts diff --git a/src/compiler/transformers/generators.ts b/src/compiler/transformers/generators.ts index e11804bd467..234f39550a7 100644 --- a/src/compiler/transformers/generators.ts +++ b/src/compiler/transformers/generators.ts @@ -572,10 +572,12 @@ namespace ts { operationLocations = undefined; state = createTempVariable(/*recordTempVariable*/ undefined); + const statementOffset = addPrologueDirectives(statements, body.statements); + // Build the generator startLexicalEnvironment(); - transformAndEmitStatements(body.statements); + transformAndEmitStatements(body.statements, statementOffset); const buildResult = build(); addNodes(statements, endLexicalEnvironment()); @@ -1117,9 +1119,10 @@ namespace ts { return visitEachChild(node, visitor, context); } - function transformAndEmitStatements(statements: Statement[]) { - for (const statement of statements) { - transformAndEmitStatement(statement); + function transformAndEmitStatements(statements: Statement[], start = 0) { + const numStatements = statements.length; + for (let i = start; i < numStatements; i++) { + transformAndEmitStatement(statements[i]); } } diff --git a/src/compiler/transformers/ts.ts b/src/compiler/transformers/ts.ts index 788791bfe74..f2157e5a5c0 100644 --- a/src/compiler/transformers/ts.ts +++ b/src/compiler/transformers/ts.ts @@ -2181,11 +2181,13 @@ namespace ts { return transformFunctionBodyWorker(node.body); } - function transformFunctionBodyWorker(body: Block) { + function transformFunctionBodyWorker(body: Block, start = 0) { const savedCurrentScope = currentScope; currentScope = body; startLexicalEnvironment(); - const visited = visitEachChild(body, visitor, context); + + const statements = visitNodes(body.statements, visitor, isStatement, start); + const visited = updateBlock(body, statements); const declarations = endLexicalEnvironment(); currentScope = savedCurrentScope; return mergeFunctionBodyLexicalEnvironment(visited, declarations); @@ -2233,14 +2235,14 @@ namespace ts { if (!isArrowFunction) { const statements: Statement[] = []; - + const statementOffset = addPrologueDirectives(statements, (node.body).statements); statements.push( createReturn( createAwaiterHelper( currentSourceFileExternalHelpersModuleName, hasLexicalArguments, promiseConstructor, - transformFunctionBodyWorker(node.body) + transformFunctionBodyWorker(node.body, statementOffset) ) ) ); diff --git a/tests/baselines/reference/asyncUseStrict_es6.js b/tests/baselines/reference/asyncUseStrict_es6.js new file mode 100644 index 00000000000..5475a71102a --- /dev/null +++ b/tests/baselines/reference/asyncUseStrict_es6.js @@ -0,0 +1,15 @@ +//// [asyncUseStrict_es6.ts] +declare var a: boolean; +declare var p: Promise; +async function func(): Promise { + "use strict"; + var b = await p || a; +} + +//// [asyncUseStrict_es6.js] +function func() { + "use strict"; + return __awaiter(this, void 0, void 0, function* () { + var b = (yield p) || a; + }); +} diff --git a/tests/baselines/reference/asyncUseStrict_es6.symbols b/tests/baselines/reference/asyncUseStrict_es6.symbols new file mode 100644 index 00000000000..f94c16664e7 --- /dev/null +++ b/tests/baselines/reference/asyncUseStrict_es6.symbols @@ -0,0 +1,18 @@ +=== tests/cases/conformance/async/es6/asyncUseStrict_es6.ts === +declare var a: boolean; +>a : Symbol(a, Decl(asyncUseStrict_es6.ts, 0, 11)) + +declare var p: Promise; +>p : Symbol(p, Decl(asyncUseStrict_es6.ts, 1, 11)) +>Promise : Symbol(Promise, Decl(lib.es2015.symbol.wellknown.d.ts, --, --), Decl(lib.es2015.promise.d.ts, --, --), Decl(lib.es2015.promise.d.ts, --, --), Decl(lib.es2015.iterable.d.ts, --, --)) + +async function func(): Promise { +>func : Symbol(func, Decl(asyncUseStrict_es6.ts, 1, 32)) +>Promise : Symbol(Promise, Decl(lib.es2015.symbol.wellknown.d.ts, --, --), Decl(lib.es2015.promise.d.ts, --, --), Decl(lib.es2015.promise.d.ts, --, --), Decl(lib.es2015.iterable.d.ts, --, --)) + + "use strict"; + var b = await p || a; +>b : Symbol(b, Decl(asyncUseStrict_es6.ts, 4, 7)) +>p : Symbol(p, Decl(asyncUseStrict_es6.ts, 1, 11)) +>a : Symbol(a, Decl(asyncUseStrict_es6.ts, 0, 11)) +} diff --git a/tests/baselines/reference/asyncUseStrict_es6.types b/tests/baselines/reference/asyncUseStrict_es6.types new file mode 100644 index 00000000000..7e6fd872081 --- /dev/null +++ b/tests/baselines/reference/asyncUseStrict_es6.types @@ -0,0 +1,22 @@ +=== tests/cases/conformance/async/es6/asyncUseStrict_es6.ts === +declare var a: boolean; +>a : boolean + +declare var p: Promise; +>p : Promise +>Promise : Promise + +async function func(): Promise { +>func : () => Promise +>Promise : Promise + + "use strict"; +>"use strict" : string + + var b = await p || a; +>b : boolean +>await p || a : boolean +>await p : boolean +>p : Promise +>a : boolean +} diff --git a/tests/cases/conformance/async/es6/asyncUseStrict_es6.ts b/tests/cases/conformance/async/es6/asyncUseStrict_es6.ts new file mode 100644 index 00000000000..b3948daf384 --- /dev/null +++ b/tests/cases/conformance/async/es6/asyncUseStrict_es6.ts @@ -0,0 +1,8 @@ +// @target: ES6 +// @noEmitHelpers: true +declare var a: boolean; +declare var p: Promise; +async function func(): Promise { + "use strict"; + var b = await p || a; +} \ No newline at end of file