diff --git a/src/compiler/transformers/ts.ts b/src/compiler/transformers/ts.ts index cc3da23d2067b..4e880e67c205d 100644 --- a/src/compiler/transformers/ts.ts +++ b/src/compiler/transformers/ts.ts @@ -1722,7 +1722,7 @@ export function transformTypeScript(context: TransformationContext): Transformer } function visitNonNullExpression(node: NonNullExpression): Expression { - const expression = visitNode(node.expression, visitor, isLeftHandSideExpression); + const expression = visitNode(node.expression, visitor, isExpression); Debug.assert(expression); return factory.createPartiallyEmittedExpression(expression, node); } diff --git a/tests/baselines/reference/awaitNonNullAssertion.js b/tests/baselines/reference/awaitNonNullAssertion.js new file mode 100644 index 0000000000000..36ac41400a670 --- /dev/null +++ b/tests/baselines/reference/awaitNonNullAssertion.js @@ -0,0 +1,67 @@ +//// [tests/cases/compiler/awaitNonNullAssertion.ts] //// + +//// [awaitNonNullAssertion.ts] +// Test for await expression followed by non-null assertion +async function test() { + const result1 = (await null as any)!; + const result2 = (await Promise.resolve(42))!; + const result3 = (await null)!; +} + +//// [awaitNonNullAssertion.js] +var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) { + function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); } + 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) : adopt(result.value).then(fulfilled, rejected); } + step((generator = generator.apply(thisArg, _arguments || [])).next()); + }); +}; +var __generator = (this && this.__generator) || function (thisArg, body) { + var _ = { label: 0, sent: function() { if (t[0] & 1) throw t[1]; return t[1]; }, trys: [], ops: [] }, f, y, t, g = Object.create((typeof Iterator === "function" ? Iterator : Object).prototype); + return g.next = verb(0), g["throw"] = verb(1), g["return"] = verb(2), typeof Symbol === "function" && (g[Symbol.iterator] = function() { return this; }), g; + function verb(n) { return function (v) { return step([n, v]); }; } + function step(op) { + if (f) throw new TypeError("Generator is already executing."); + while (g && (g = 0, op[0] && (_ = 0)), _) try { + if (f = 1, y && (t = op[0] & 2 ? y["return"] : op[0] ? y["throw"] || ((t = y["return"]) && t.call(y), 0) : y.next) && !(t = t.call(y, op[1])).done) return t; + if (y = 0, t) op = [op[0] & 2, t.value]; + switch (op[0]) { + case 0: case 1: t = op; break; + case 4: _.label++; return { value: op[1], done: false }; + case 5: _.label++; y = op[1]; op = [0]; continue; + case 7: op = _.ops.pop(); _.trys.pop(); continue; + default: + if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) { _ = 0; continue; } + if (op[0] === 3 && (!t || (op[1] > t[0] && op[1] < t[3]))) { _.label = op[1]; break; } + if (op[0] === 6 && _.label < t[1]) { _.label = t[1]; t = op; break; } + if (t && _.label < t[2]) { _.label = t[2]; _.ops.push(op); break; } + if (t[2]) _.ops.pop(); + _.trys.pop(); continue; + } + op = body.call(thisArg, _); + } catch (e) { op = [6, e]; y = 0; } finally { f = t = 0; } + if (op[0] & 5) throw op[1]; return { value: op[0] ? op[1] : void 0, done: true }; + } +}; +// Test for await expression followed by non-null assertion +function test() { + return __awaiter(this, void 0, void 0, function () { + var result1, result2, result3; + return __generator(this, function (_a) { + switch (_a.label) { + case 0: return [4 /*yield*/, null]; + case 1: + result1 = _a.sent(); + return [4 /*yield*/, Promise.resolve(42)]; + case 2: + result2 = (_a.sent()); + return [4 /*yield*/, null]; + case 3: + result3 = (_a.sent()); + return [2 /*return*/]; + } + }); + }); +} diff --git a/tests/baselines/reference/awaitNonNullAssertion.symbols b/tests/baselines/reference/awaitNonNullAssertion.symbols new file mode 100644 index 0000000000000..062feb3f6405a --- /dev/null +++ b/tests/baselines/reference/awaitNonNullAssertion.symbols @@ -0,0 +1,19 @@ +//// [tests/cases/compiler/awaitNonNullAssertion.ts] //// + +=== awaitNonNullAssertion.ts === +// Test for await expression followed by non-null assertion +async function test() { +>test : Symbol(test, Decl(awaitNonNullAssertion.ts, 0, 0)) + + const result1 = (await null as any)!; +>result1 : Symbol(result1, Decl(awaitNonNullAssertion.ts, 2, 9)) + + const result2 = (await Promise.resolve(42))!; +>result2 : Symbol(result2, Decl(awaitNonNullAssertion.ts, 3, 9)) +>Promise.resolve : Symbol(PromiseConstructor.resolve, Decl(lib.es2015.promise.d.ts, --, --), Decl(lib.es2015.promise.d.ts, --, --), Decl(lib.es2015.promise.d.ts, --, --)) +>Promise : Symbol(Promise, Decl(lib.es5.d.ts, --, --), Decl(lib.es2015.iterable.d.ts, --, --), Decl(lib.es2015.promise.d.ts, --, --), Decl(lib.es2015.symbol.wellknown.d.ts, --, --)) +>resolve : Symbol(PromiseConstructor.resolve, Decl(lib.es2015.promise.d.ts, --, --), Decl(lib.es2015.promise.d.ts, --, --), Decl(lib.es2015.promise.d.ts, --, --)) + + const result3 = (await null)!; +>result3 : Symbol(result3, Decl(awaitNonNullAssertion.ts, 4, 9)) +} diff --git a/tests/baselines/reference/awaitNonNullAssertion.types b/tests/baselines/reference/awaitNonNullAssertion.types new file mode 100644 index 0000000000000..bbf713c58d5da --- /dev/null +++ b/tests/baselines/reference/awaitNonNullAssertion.types @@ -0,0 +1,45 @@ +//// [tests/cases/compiler/awaitNonNullAssertion.ts] //// + +=== awaitNonNullAssertion.ts === +// Test for await expression followed by non-null assertion +async function test() { +>test : () => Promise +> : ^^^^^^^^^^^^^^^^^^^ + + const result1 = (await null as any)!; +>result1 : any +>(await null as any)! : any +>(await null as any) : any +>await null as any : any +>await null : null +> : ^^^^ + + const result2 = (await Promise.resolve(42))!; +>result2 : number +> : ^^^^^^ +>(await Promise.resolve(42))! : number +> : ^^^^^^ +>(await Promise.resolve(42)) : number +> : ^^^^^^ +>await Promise.resolve(42) : number +> : ^^^^^^ +>Promise.resolve(42) : Promise +> : ^^^^^^^^^^^^^^^ +>Promise.resolve : { (): Promise; (value: T): Promise>; (value: T | PromiseLike): Promise>; } +> : ^^^^^^ ^^^ ^^ ^^ ^^^ ^^^ ^^ ^^ ^^^ ^^^ +>Promise : PromiseConstructor +> : ^^^^^^^^^^^^^^^^^^ +>resolve : { (): Promise; (value: T): Promise>; (value: T | PromiseLike): Promise>; } +> : ^^^^^^ ^^^ ^^ ^^ ^^^ ^^^ ^^ ^^ ^^^ ^^^ +>42 : 42 +> : ^^ + + const result3 = (await null)!; +>result3 : any +>(await null)! : null +> : ^^^^ +>(await null) : null +> : ^^^^ +>await null : null +> : ^^^^ +} diff --git a/tests/cases/compiler/awaitNonNullAssertion.ts b/tests/cases/compiler/awaitNonNullAssertion.ts new file mode 100644 index 0000000000000..d168094cdb780 --- /dev/null +++ b/tests/cases/compiler/awaitNonNullAssertion.ts @@ -0,0 +1,7 @@ +// @lib: es2015 +// Test for await expression followed by non-null assertion +async function test() { + const result1 = (await null as any)!; + const result2 = (await Promise.resolve(42))!; + const result3 = (await null)!; +} \ No newline at end of file