Skip to content

Fix 10472: Invalid emitted code for await expression #10483

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 5 commits into from
Aug 22, 2016
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions src/compiler/emitter.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1817,6 +1817,10 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge
else if (node.parent.kind === SyntaxKind.ConditionalExpression && (<ConditionalExpression>node.parent).condition === node) {
return true;
}
else if (node.parent.kind === SyntaxKind.PrefixUnaryExpression || node.parent.kind === SyntaxKind.DeleteExpression ||
node.parent.kind === SyntaxKind.TypeOfExpression || node.parent.kind === SyntaxKind.VoidExpression) {
return true;
}

return false;
}
Expand Down
11 changes: 5 additions & 6 deletions src/compiler/parser.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3381,10 +3381,6 @@ namespace ts {
*
*/
function parseUnaryExpressionOrHigher(): UnaryExpression | BinaryExpression {
if (isAwaitExpression()) {
return parseAwaitExpression();
}

/**
* ES7 UpdateExpression:
* 1) LeftHandSideExpression[?Yield]
Expand Down Expand Up @@ -3452,13 +3448,15 @@ namespace ts {
return parseTypeOfExpression();
case SyntaxKind.VoidKeyword:
return parseVoidExpression();
case SyntaxKind.AwaitKeyword:
return parseAwaitExpression();
case SyntaxKind.LessThanToken:
// This is modified UnaryExpression grammar in TypeScript
// UnaryExpression (modified):
// < type > UnaryExpression
return parseTypeAssertion();
case SyntaxKind.AwaitKeyword:
if (isAwaitExpression()) {
return parseAwaitExpression();
}
default:
return parseIncrementExpression();
}
Expand All @@ -3485,6 +3483,7 @@ namespace ts {
case SyntaxKind.DeleteKeyword:
case SyntaxKind.TypeOfKeyword:
case SyntaxKind.VoidKeyword:
case SyntaxKind.AwaitKeyword:
return false;
case SyntaxKind.LessThanToken:
// If we are not in JSX context, we are parsing TypeAssertion which is an UnaryExpression
Expand Down
47 changes: 47 additions & 0 deletions tests/baselines/reference/await_unaryExpression_es6.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
//// [await_unaryExpression_es6.ts]

async function bar() {
!await 42; // OK
}

async function bar1() {
+await 42; // OK
}

async function bar3() {
-await 42; // OK
}

async function bar4() {
~await 42; // OK
}

//// [await_unaryExpression_es6.js]
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
return new (P || (P = Promise))(function (resolve, reject) {
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
function rejected(value) { try { step(generator.throw(value)); } catch (e) { reject(e); } }
function step(result) { result.done ? resolve(result.value) : new P(function (resolve) { resolve(result.value); }).then(fulfilled, rejected); }
step((generator = generator.apply(thisArg, _arguments)).next());
});
};
function bar() {
return __awaiter(this, void 0, void 0, function* () {
!(yield 42); // OK
});
}
function bar1() {
return __awaiter(this, void 0, void 0, function* () {
+(yield 42); // OK
});
}
function bar3() {
return __awaiter(this, void 0, void 0, function* () {
-(yield 42); // OK
});
}
function bar4() {
return __awaiter(this, void 0, void 0, function* () {
~(yield 42); // OK
});
}
25 changes: 25 additions & 0 deletions tests/baselines/reference/await_unaryExpression_es6.symbols
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
=== tests/cases/conformance/async/es6/await_unaryExpression_es6.ts ===

async function bar() {
>bar : Symbol(bar, Decl(await_unaryExpression_es6.ts, 0, 0))

!await 42; // OK
}

async function bar1() {
>bar1 : Symbol(bar1, Decl(await_unaryExpression_es6.ts, 3, 1))

+await 42; // OK
}

async function bar3() {
>bar3 : Symbol(bar3, Decl(await_unaryExpression_es6.ts, 7, 1))

-await 42; // OK
}

async function bar4() {
>bar4 : Symbol(bar4, Decl(await_unaryExpression_es6.ts, 11, 1))

~await 42; // OK
}
37 changes: 37 additions & 0 deletions tests/baselines/reference/await_unaryExpression_es6.types
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
=== tests/cases/conformance/async/es6/await_unaryExpression_es6.ts ===

async function bar() {
>bar : () => Promise<void>

!await 42; // OK
>!await 42 : boolean
>await 42 : number
>42 : number
}

async function bar1() {
>bar1 : () => Promise<void>

+await 42; // OK
>+await 42 : number
>await 42 : number
>42 : number
}

async function bar3() {
>bar3 : () => Promise<void>

-await 42; // OK
>-await 42 : number
>await 42 : number
>42 : number
}

async function bar4() {
>bar4 : () => Promise<void>

~await 42; // OK
>~await 42 : number
>await 42 : number
>42 : number
}
56 changes: 56 additions & 0 deletions tests/baselines/reference/await_unaryExpression_es6_1.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
//// [await_unaryExpression_es6_1.ts]

async function bar() {
!await 42; // OK
}

async function bar1() {
delete await 42; // OK
}

async function bar2() {
delete await 42; // OK
}

async function bar3() {
void await 42;
}

async function bar4() {
+await 42;
}

//// [await_unaryExpression_es6_1.js]
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
return new (P || (P = Promise))(function (resolve, reject) {
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
function rejected(value) { try { step(generator.throw(value)); } catch (e) { reject(e); } }
function step(result) { result.done ? resolve(result.value) : new P(function (resolve) { resolve(result.value); }).then(fulfilled, rejected); }
step((generator = generator.apply(thisArg, _arguments)).next());
});
};
function bar() {
return __awaiter(this, void 0, void 0, function* () {
!(yield 42); // OK
});
}
function bar1() {
return __awaiter(this, void 0, void 0, function* () {
delete (yield 42); // OK
});
}
function bar2() {
return __awaiter(this, void 0, void 0, function* () {
delete (yield 42); // OK
});
}
function bar3() {
return __awaiter(this, void 0, void 0, function* () {
void (yield 42);
});
}
function bar4() {
return __awaiter(this, void 0, void 0, function* () {
+(yield 42);
});
}
31 changes: 31 additions & 0 deletions tests/baselines/reference/await_unaryExpression_es6_1.symbols
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
=== tests/cases/conformance/async/es6/await_unaryExpression_es6_1.ts ===

async function bar() {
>bar : Symbol(bar, Decl(await_unaryExpression_es6_1.ts, 0, 0))

!await 42; // OK
}

async function bar1() {
>bar1 : Symbol(bar1, Decl(await_unaryExpression_es6_1.ts, 3, 1))

delete await 42; // OK
}

async function bar2() {
>bar2 : Symbol(bar2, Decl(await_unaryExpression_es6_1.ts, 7, 1))

delete await 42; // OK
}

async function bar3() {
>bar3 : Symbol(bar3, Decl(await_unaryExpression_es6_1.ts, 11, 1))

void await 42;
}

async function bar4() {
>bar4 : Symbol(bar4, Decl(await_unaryExpression_es6_1.ts, 15, 1))

+await 42;
}
46 changes: 46 additions & 0 deletions tests/baselines/reference/await_unaryExpression_es6_1.types
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
=== tests/cases/conformance/async/es6/await_unaryExpression_es6_1.ts ===

async function bar() {
>bar : () => Promise<void>

!await 42; // OK
>!await 42 : boolean
>await 42 : number
>42 : number
}

async function bar1() {
>bar1 : () => Promise<void>

delete await 42; // OK
>delete await 42 : boolean
>await 42 : number
>42 : number
}

async function bar2() {
>bar2 : () => Promise<void>

delete await 42; // OK
>delete await 42 : boolean
>await 42 : number
>42 : number
}

async function bar3() {
>bar3 : () => Promise<void>

void await 42;
>void await 42 : undefined
>await 42 : number
>42 : number
}

async function bar4() {
>bar4 : () => Promise<void>

+await 42;
>+await 42 : number
>await 42 : number
>42 : number
}
38 changes: 38 additions & 0 deletions tests/baselines/reference/await_unaryExpression_es6_2.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
//// [await_unaryExpression_es6_2.ts]

async function bar1() {
delete await 42;
}

async function bar2() {
delete await 42;
}

async function bar3() {
void await 42;
}

//// [await_unaryExpression_es6_2.js]
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
return new (P || (P = Promise))(function (resolve, reject) {
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
function rejected(value) { try { step(generator.throw(value)); } catch (e) { reject(e); } }
function step(result) { result.done ? resolve(result.value) : new P(function (resolve) { resolve(result.value); }).then(fulfilled, rejected); }
step((generator = generator.apply(thisArg, _arguments)).next());
});
};
function bar1() {
return __awaiter(this, void 0, void 0, function* () {
delete (yield 42);
});
}
function bar2() {
return __awaiter(this, void 0, void 0, function* () {
delete (yield 42);
});
}
function bar3() {
return __awaiter(this, void 0, void 0, function* () {
void (yield 42);
});
}
19 changes: 19 additions & 0 deletions tests/baselines/reference/await_unaryExpression_es6_2.symbols
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
=== tests/cases/conformance/async/es6/await_unaryExpression_es6_2.ts ===

async function bar1() {
>bar1 : Symbol(bar1, Decl(await_unaryExpression_es6_2.ts, 0, 0))

delete await 42;
}

async function bar2() {
>bar2 : Symbol(bar2, Decl(await_unaryExpression_es6_2.ts, 3, 1))

delete await 42;
}

async function bar3() {
>bar3 : Symbol(bar3, Decl(await_unaryExpression_es6_2.ts, 7, 1))

void await 42;
}
28 changes: 28 additions & 0 deletions tests/baselines/reference/await_unaryExpression_es6_2.types
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
=== tests/cases/conformance/async/es6/await_unaryExpression_es6_2.ts ===

async function bar1() {
>bar1 : () => Promise<void>

delete await 42;
>delete await 42 : boolean
>await 42 : number
>42 : number
}

async function bar2() {
>bar2 : () => Promise<void>

delete await 42;
>delete await 42 : boolean
>await 42 : number
>42 : number
}

async function bar3() {
>bar3 : () => Promise<void>

void await 42;
>void await 42 : undefined
>await 42 : number
>42 : number
}
Loading