Merge pull request #24768 from Microsoft/fix24722

Fix prologue order in async function
This commit is contained in:
Ron Buckton
2018-06-07 15:05:09 -07:00
committed by GitHub
6 changed files with 156 additions and 13 deletions

View File

@@ -1832,6 +1832,7 @@ namespace ts {
let statementsLocation: TextRange;
let closeBraceLocation: TextRange | undefined;
const leadingStatements: Statement[] = [];
const statements: Statement[] = [];
const body = node.body!;
let statementOffset: number | undefined;
@@ -1840,21 +1841,16 @@ namespace ts {
if (isBlock(body)) {
// ensureUseStrict is false because no new prologue-directive should be added.
// addStandardPrologue will put already-existing directives at the beginning of the target statement-array
statementOffset = addStandardPrologue(statements, body.statements, /*ensureUseStrict*/ false);
statementOffset = addStandardPrologue(leadingStatements, body.statements, /*ensureUseStrict*/ false);
}
addCaptureThisForNodeIfNeeded(statements, node);
addDefaultValueAssignmentsIfNeeded(statements, node);
addRestParameterIfNeeded(statements, node, /*inConstructorWithSynthesizedSuper*/ false);
// If we added any generated statements, this must be a multi-line block.
if (!multiLine && statements.length > 0) {
multiLine = true;
}
addCaptureThisForNodeIfNeeded(leadingStatements, node);
addDefaultValueAssignmentsIfNeeded(leadingStatements, node);
addRestParameterIfNeeded(leadingStatements, node, /*inConstructorWithSynthesizedSuper*/ false);
if (isBlock(body)) {
// addCustomPrologue puts already-existing directives at the beginning of the target statement-array
statementOffset = addCustomPrologue(statements, body.statements, statementOffset, visitor);
statementOffset = addCustomPrologue(leadingStatements, body.statements, statementOffset, visitor);
statementsLocation = body.statements;
addRange(statements, visitNodes(body.statements, visitor, isStatement, statementOffset));
@@ -1897,15 +1893,14 @@ namespace ts {
const lexicalEnvironment = context.endLexicalEnvironment();
prependStatements(statements, lexicalEnvironment);
prependCaptureNewTargetIfNeeded(statements, node, /*copyOnWrite*/ false);
// If we added any final generated statements, this must be a multi-line block
if (!multiLine && lexicalEnvironment && lexicalEnvironment.length) {
if (some(leadingStatements) || some(lexicalEnvironment)) {
multiLine = true;
}
const block = createBlock(setTextRange(createNodeArray(statements), statementsLocation), multiLine);
const block = createBlock(setTextRange(createNodeArray([...leadingStatements, ...statements]), statementsLocation), multiLine);
setTextRange(block, node.body);
if (!multiLine && singleLine) {
setEmitFlags(block, EmitFlags.SingleLine);

View File

@@ -0,0 +1,18 @@
describe("asyncArrowEvaluation", () => {
// https://github.com/Microsoft/TypeScript/issues/24722
it("this capture (es5)", async () => {
const result = evaluator.evaluateTypeScript(`
export class A {
b = async (...args: any[]) => {
await Promise.resolve();
output.push({ ["a"]: () => this }); // computed property name after 'await' triggers case
};
}
export const output: any[] = [];
export async function main() {
await new A().b();
}`);
await result.main();
assert.instanceOf(result.output[0].a(), result.A);
});
});