Merge pull request #41312 from weswigham/maybe-bind-comma-lhs

Bind comma expression LHS call expressions
This commit is contained in:
Wesley Wigham 2020-10-28 15:12:03 -07:00 committed by GitHub
commit 3de6ed08a9
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
5 changed files with 90 additions and 3 deletions

View File

@ -1337,10 +1337,14 @@ namespace ts {
function bindExpressionStatement(node: ExpressionStatement): void {
bind(node.expression);
// A top level call expression with a dotted function name and at least one argument
maybeBindExpressionFlowIfCall(node.expression);
}
function maybeBindExpressionFlowIfCall(node: Expression) {
// A top level or LHS of comma expression call expression with a dotted function name and at least one argument
// is potentially an assertion and is therefore included in the control flow.
if (node.expression.kind === SyntaxKind.CallExpression) {
const call = <CallExpression>node.expression;
if (node.kind === SyntaxKind.CallExpression) {
const call = <CallExpression>node;
if (isDottedName(call.expression) && call.expression.kind !== SyntaxKind.SuperKeyword) {
currentFlow = createFlowCall(currentFlow, call);
}
@ -1511,6 +1515,9 @@ namespace ts {
break;
}
case BindBinaryExpressionFlowState.BindToken: {
if (node.operatorToken.kind === SyntaxKind.CommaToken) {
maybeBindExpressionFlowIfCall(node.left);
}
advanceState(BindBinaryExpressionFlowState.BindRight);
maybeBind(node.operatorToken);
break;

View File

@ -0,0 +1,16 @@
//// [controlFlowCommaExpressionAssertionWithinTernary.ts]
declare function assert(value: any): asserts value;
function foo2(param: number | null | undefined): number | null {
const val = param !== undefined;
return val ? (assert(param !== undefined), param) : null;
// ^^^^^ Still typed as number | null | undefined
}
//// [controlFlowCommaExpressionAssertionWithinTernary.js]
"use strict";
function foo2(param) {
var val = param !== undefined;
return val ? (assert(param !== undefined), param) : null;
// ^^^^^ Still typed as number | null | undefined
}

View File

@ -0,0 +1,24 @@
=== tests/cases/compiler/controlFlowCommaExpressionAssertionWithinTernary.ts ===
declare function assert(value: any): asserts value;
>assert : Symbol(assert, Decl(controlFlowCommaExpressionAssertionWithinTernary.ts, 0, 0))
>value : Symbol(value, Decl(controlFlowCommaExpressionAssertionWithinTernary.ts, 0, 24))
>value : Symbol(value, Decl(controlFlowCommaExpressionAssertionWithinTernary.ts, 0, 24))
function foo2(param: number | null | undefined): number | null {
>foo2 : Symbol(foo2, Decl(controlFlowCommaExpressionAssertionWithinTernary.ts, 0, 51))
>param : Symbol(param, Decl(controlFlowCommaExpressionAssertionWithinTernary.ts, 2, 14))
const val = param !== undefined;
>val : Symbol(val, Decl(controlFlowCommaExpressionAssertionWithinTernary.ts, 3, 9))
>param : Symbol(param, Decl(controlFlowCommaExpressionAssertionWithinTernary.ts, 2, 14))
>undefined : Symbol(undefined)
return val ? (assert(param !== undefined), param) : null;
>val : Symbol(val, Decl(controlFlowCommaExpressionAssertionWithinTernary.ts, 3, 9))
>assert : Symbol(assert, Decl(controlFlowCommaExpressionAssertionWithinTernary.ts, 0, 0))
>param : Symbol(param, Decl(controlFlowCommaExpressionAssertionWithinTernary.ts, 2, 14))
>undefined : Symbol(undefined)
>param : Symbol(param, Decl(controlFlowCommaExpressionAssertionWithinTernary.ts, 2, 14))
// ^^^^^ Still typed as number | null | undefined
}

View File

@ -0,0 +1,32 @@
=== tests/cases/compiler/controlFlowCommaExpressionAssertionWithinTernary.ts ===
declare function assert(value: any): asserts value;
>assert : (value: any) => asserts value
>value : any
function foo2(param: number | null | undefined): number | null {
>foo2 : (param: number | null | undefined) => number | null
>param : number | null | undefined
>null : null
>null : null
const val = param !== undefined;
>val : boolean
>param !== undefined : boolean
>param : number | null | undefined
>undefined : undefined
return val ? (assert(param !== undefined), param) : null;
>val ? (assert(param !== undefined), param) : null : number | null
>val : boolean
>(assert(param !== undefined), param) : number | null
>assert(param !== undefined), param : number | null
>assert(param !== undefined) : void
>assert : (value: any) => asserts value
>param !== undefined : boolean
>param : number | null | undefined
>undefined : undefined
>param : number | null
>null : null
// ^^^^^ Still typed as number | null | undefined
}

View File

@ -0,0 +1,8 @@
// @strict: true
declare function assert(value: any): asserts value;
function foo2(param: number | null | undefined): number | null {
const val = param !== undefined;
return val ? (assert(param !== undefined), param) : null;
// ^^^^^ Still typed as number | null | undefined
}