diff --git a/src/compiler/utilitiesPublic.ts b/src/compiler/utilitiesPublic.ts index 36eba18db07..36a178eafb3 100644 --- a/src/compiler/utilitiesPublic.ts +++ b/src/compiler/utilitiesPublic.ts @@ -1990,11 +1990,11 @@ export function isTemplateLiteral(node: Node): node is TemplateLiteral { || kind === SyntaxKind.NoSubstitutionTemplateLiteral; } -export function isLeftHandSideExpression(node: Node): node is LeftHandSideExpression { - return isLeftHandSideExpressionKind(skipPartiallyEmittedExpressions(node).kind); +export function isLeftHandSideExpression(node: Node): node is LeftHandSideExpression { + return isLeftHandSideExpressionKind(skipPartiallyEmittedExpressions(node).kind); } -function isLeftHandSideExpressionKind(kind: SyntaxKind): boolean { +function isLeftHandSideExpressionKind(kind: SyntaxKind): boolean { switch (kind) { case SyntaxKind.PropertyAccessExpression: case SyntaxKind.ElementAccessExpression: @@ -2022,11 +2022,13 @@ function isLeftHandSideExpressionKind(kind: SyntaxKind): boolean { case SyntaxKind.ThisKeyword: case SyntaxKind.TrueKeyword: case SyntaxKind.SuperKeyword: - case SyntaxKind.NonNullExpression: - case SyntaxKind.ExpressionWithTypeArguments: - case SyntaxKind.MetaProperty: - case SyntaxKind.ImportKeyword: // technically this is only an Expression if it's in a CallExpression - case SyntaxKind.MissingDeclaration: + case SyntaxKind.NonNullExpression: + case SyntaxKind.ExpressionWithTypeArguments: + case SyntaxKind.MetaProperty: + case SyntaxKind.ImportKeyword: // technically this is only an Expression if it's in a CallExpression + case SyntaxKind.MissingDeclaration: + case SyntaxKind.PartiallyEmittedExpression: + case SyntaxKind.AwaitExpression: return true; default: return false; diff --git a/tests/baselines/reference/partiallyEmittedExpressionLeftHandSide.js b/tests/baselines/reference/partiallyEmittedExpressionLeftHandSide.js new file mode 100644 index 00000000000..4f358450adc --- /dev/null +++ b/tests/baselines/reference/partiallyEmittedExpressionLeftHandSide.js @@ -0,0 +1,24 @@ +//// [tests/cases/compiler/partiallyEmittedExpressionLeftHandSide.ts] //// + +//// [partiallyEmittedExpressionLeftHandSide.ts] +async function testNonNullWithAwait() { + const result = (await null as any)!; + return result; +} + +async function testNonNullWithComplexExpression() { + const obj = { prop: Promise.resolve("test") }; + const result = (await obj.prop as string)!; + return result; +} + +//// [partiallyEmittedExpressionLeftHandSide.js] +async function testNonNullWithAwait() { + const result = await null; + return result; +} +async function testNonNullWithComplexExpression() { + const obj = { prop: Promise.resolve("test") }; + const result = await obj.prop; + return result; +} diff --git a/tests/baselines/reference/partiallyEmittedExpressionLeftHandSide.symbols b/tests/baselines/reference/partiallyEmittedExpressionLeftHandSide.symbols new file mode 100644 index 00000000000..6f7746bab1e --- /dev/null +++ b/tests/baselines/reference/partiallyEmittedExpressionLeftHandSide.symbols @@ -0,0 +1,32 @@ +//// [tests/cases/compiler/partiallyEmittedExpressionLeftHandSide.ts] //// + +=== partiallyEmittedExpressionLeftHandSide.ts === +async function testNonNullWithAwait() { +>testNonNullWithAwait : Symbol(testNonNullWithAwait, Decl(partiallyEmittedExpressionLeftHandSide.ts, 0, 0)) + + const result = (await null as any)!; +>result : Symbol(result, Decl(partiallyEmittedExpressionLeftHandSide.ts, 1, 9)) + + return result; +>result : Symbol(result, Decl(partiallyEmittedExpressionLeftHandSide.ts, 1, 9)) +} + +async function testNonNullWithComplexExpression() { +>testNonNullWithComplexExpression : Symbol(testNonNullWithComplexExpression, Decl(partiallyEmittedExpressionLeftHandSide.ts, 3, 1)) + + const obj = { prop: Promise.resolve("test") }; +>obj : Symbol(obj, Decl(partiallyEmittedExpressionLeftHandSide.ts, 6, 9)) +>prop : Symbol(prop, Decl(partiallyEmittedExpressionLeftHandSide.ts, 6, 17)) +>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, --, --), Decl(lib.es2018.promise.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 result = (await obj.prop as string)!; +>result : Symbol(result, Decl(partiallyEmittedExpressionLeftHandSide.ts, 7, 9)) +>obj.prop : Symbol(prop, Decl(partiallyEmittedExpressionLeftHandSide.ts, 6, 17)) +>obj : Symbol(obj, Decl(partiallyEmittedExpressionLeftHandSide.ts, 6, 9)) +>prop : Symbol(prop, Decl(partiallyEmittedExpressionLeftHandSide.ts, 6, 17)) + + return result; +>result : Symbol(result, Decl(partiallyEmittedExpressionLeftHandSide.ts, 7, 9)) +} diff --git a/tests/baselines/reference/partiallyEmittedExpressionLeftHandSide.types b/tests/baselines/reference/partiallyEmittedExpressionLeftHandSide.types new file mode 100644 index 00000000000..e24d20eaf3b --- /dev/null +++ b/tests/baselines/reference/partiallyEmittedExpressionLeftHandSide.types @@ -0,0 +1,63 @@ +//// [tests/cases/compiler/partiallyEmittedExpressionLeftHandSide.ts] //// + +=== partiallyEmittedExpressionLeftHandSide.ts === +async function testNonNullWithAwait() { +>testNonNullWithAwait : () => Promise +> : ^^^^^^^^^^^^^^^^^^ + + const result = (await null as any)!; +>result : any +>(await null as any)! : any +>(await null as any) : any +>await null as any : any +>await null : null +> : ^^^^ + + return result; +>result : any +} + +async function testNonNullWithComplexExpression() { +>testNonNullWithComplexExpression : () => Promise +> : ^^^^^^^^^^^^^^^^^^^^^ + + const obj = { prop: Promise.resolve("test") }; +>obj : { prop: Promise; } +> : ^^^^^^^^^^^^^^^^^^^^^^^^^^ +>{ prop: Promise.resolve("test") } : { prop: Promise; } +> : ^^^^^^^^^^^^^^^^^^^^^^^^^^ +>prop : Promise +> : ^^^^^^^^^^^^^^^ +>Promise.resolve("test") : Promise +> : ^^^^^^^^^^^^^^^ +>Promise.resolve : { (): Promise; (value: T): Promise>; (value: T | PromiseLike): Promise>; } +> : ^^^^^^ ^^^ ^^ ^^ ^^^ ^^^ ^^ ^^ ^^^ ^^^ +>Promise : PromiseConstructor +> : ^^^^^^^^^^^^^^^^^^ +>resolve : { (): Promise; (value: T): Promise>; (value: T | PromiseLike): Promise>; } +> : ^^^^^^ ^^^ ^^ ^^ ^^^ ^^^ ^^ ^^ ^^^ ^^^ +>"test" : "test" +> : ^^^^^^ + + const result = (await obj.prop as string)!; +>result : string +> : ^^^^^^ +>(await obj.prop as string)! : string +> : ^^^^^^ +>(await obj.prop as string) : string +> : ^^^^^^ +>await obj.prop as string : string +> : ^^^^^^ +>await obj.prop : string +> : ^^^^^^ +>obj.prop : Promise +> : ^^^^^^^^^^^^^^^ +>obj : { prop: Promise; } +> : ^^^^^^^^^^^^^^^^^^^^^^^^^^ +>prop : Promise +> : ^^^^^^^^^^^^^^^ + + return result; +>result : string +> : ^^^^^^ +} diff --git a/tests/cases/compiler/partiallyEmittedExpressionLeftHandSide.ts b/tests/cases/compiler/partiallyEmittedExpressionLeftHandSide.ts new file mode 100644 index 00000000000..a0212f60ee5 --- /dev/null +++ b/tests/cases/compiler/partiallyEmittedExpressionLeftHandSide.ts @@ -0,0 +1,12 @@ +// @target: es2018 + +async function testNonNullWithAwait() { + const result = (await null as any)!; + return result; +} + +async function testNonNullWithComplexExpression() { + const obj = { prop: Promise.resolve("test") }; + const result = (await obj.prop as string)!; + return result; +} \ No newline at end of file