Skip to content

Commit a594c6a

Browse files
committed
Reuse computed type of condition expressions
1 parent 1260081 commit a594c6a

File tree

5 files changed

+120
-7
lines changed

5 files changed

+120
-7
lines changed

src/compiler/checker.ts

Lines changed: 8 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -33920,7 +33920,7 @@ namespace ts {
3392033920
if (operator === SyntaxKind.AmpersandAmpersandToken || operator === SyntaxKind.BarBarToken || operator === SyntaxKind.QuestionQuestionToken) {
3392133921
if (operator === SyntaxKind.AmpersandAmpersandToken) {
3392233922
const parent = walkUpParenthesizedExpressions(node.parent);
33923-
checkTestingKnownTruthyCallableOrAwaitableType(node.left, isIfStatement(parent) ? parent.thenStatement : undefined);
33923+
checkTestingKnownTruthyCallableOrAwaitableType(node.left, leftType, isIfStatement(parent) ? parent.thenStatement : undefined);
3392433924
}
3392533925
checkTruthinessOfType(leftType, node.left);
3392633926
}
@@ -34504,8 +34504,8 @@ namespace ts {
3450434504
}
3450534505

3450634506
function checkConditionalExpression(node: ConditionalExpression, checkMode?: CheckMode): Type {
34507-
checkTruthinessExpression(node.condition);
34508-
checkTestingKnownTruthyCallableOrAwaitableType(node.condition, node.whenTrue);
34507+
const type = checkTruthinessExpression(node.condition);
34508+
checkTestingKnownTruthyCallableOrAwaitableType(node.condition, type, node.whenTrue);
3450934509
const type1 = checkExpression(node.whenTrue, checkMode);
3451034510
const type2 = checkExpression(node.whenFalse, checkMode);
3451134511
return getUnionType([type1, type2], UnionReduction.Subtype);
@@ -38206,8 +38206,8 @@ namespace ts {
3820638206
function checkIfStatement(node: IfStatement) {
3820738207
// Grammar checking
3820838208
checkGrammarStatementInAmbientContext(node);
38209-
checkTruthinessExpression(node.expression);
38210-
checkTestingKnownTruthyCallableOrAwaitableType(node.expression, node.thenStatement);
38209+
const type = checkTruthinessExpression(node.expression);
38210+
checkTestingKnownTruthyCallableOrAwaitableType(node.expression, type, node.thenStatement);
3821138211
checkSourceElement(node.thenStatement);
3821238212

3821338213
if (node.thenStatement.kind === SyntaxKind.EmptyStatement) {
@@ -38217,8 +38217,9 @@ namespace ts {
3821738217
checkSourceElement(node.elseStatement);
3821838218
}
3821938219

38220-
function checkTestingKnownTruthyCallableOrAwaitableType(condExpr: Expression, body?: Statement | Expression) {
38220+
function checkTestingKnownTruthyCallableOrAwaitableType(condExpr: Expression, condType: Type, body?: Statement | Expression) {
3822138221
if (!strictNullChecks) return;
38222+
if (!(getTypeFacts(condType) & TypeFacts.Truthy)) return;
3822238223

3822338224
helper(condExpr, body);
3822438225
while (isBinaryExpression(condExpr) && condExpr.operatorToken.kind === SyntaxKind.BarBarToken) {
@@ -38232,7 +38233,7 @@ namespace ts {
3823238233
? condExpr.right
3823338234
: condExpr;
3823438235
if (isModuleExportsAccessExpression(location)) return;
38235-
const type = checkTruthinessExpression(location);
38236+
const type = location === condExpr ? condType : checkTruthinessExpression(location);
3823638237
const isPropertyExpressionCast = isPropertyAccessExpression(location) && isTypeAssertion(location.expression);
3823738238
if (!(getTypeFacts(type) & TypeFacts.Truthy) || isPropertyExpressionCast) return;
3823838239

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
//// [uncalledFunctionChecksInConditionalPerf.ts]
2+
declare const b: boolean;
3+
4+
((((((((((((((((((((((b) && b) && b) && b) && b) && b) && b) && b) && b) && b) && b) && b) && b) && b) && b) && b) && b) && b) && b) && b) && b) && b);
5+
6+
7+
//// [uncalledFunctionChecksInConditionalPerf.js]
8+
((((((((((((((((((((((b) && b) && b) && b) && b) && b) && b) && b) && b) && b) && b) && b) && b) && b) && b) && b) && b) && b) && b) && b) && b) && b);
Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
=== tests/cases/compiler/uncalledFunctionChecksInConditionalPerf.ts ===
2+
declare const b: boolean;
3+
>b : Symbol(b, Decl(uncalledFunctionChecksInConditionalPerf.ts, 0, 13))
4+
5+
((((((((((((((((((((((b) && b) && b) && b) && b) && b) && b) && b) && b) && b) && b) && b) && b) && b) && b) && b) && b) && b) && b) && b) && b) && b);
6+
>b : Symbol(b, Decl(uncalledFunctionChecksInConditionalPerf.ts, 0, 13))
7+
>b : Symbol(b, Decl(uncalledFunctionChecksInConditionalPerf.ts, 0, 13))
8+
>b : Symbol(b, Decl(uncalledFunctionChecksInConditionalPerf.ts, 0, 13))
9+
>b : Symbol(b, Decl(uncalledFunctionChecksInConditionalPerf.ts, 0, 13))
10+
>b : Symbol(b, Decl(uncalledFunctionChecksInConditionalPerf.ts, 0, 13))
11+
>b : Symbol(b, Decl(uncalledFunctionChecksInConditionalPerf.ts, 0, 13))
12+
>b : Symbol(b, Decl(uncalledFunctionChecksInConditionalPerf.ts, 0, 13))
13+
>b : Symbol(b, Decl(uncalledFunctionChecksInConditionalPerf.ts, 0, 13))
14+
>b : Symbol(b, Decl(uncalledFunctionChecksInConditionalPerf.ts, 0, 13))
15+
>b : Symbol(b, Decl(uncalledFunctionChecksInConditionalPerf.ts, 0, 13))
16+
>b : Symbol(b, Decl(uncalledFunctionChecksInConditionalPerf.ts, 0, 13))
17+
>b : Symbol(b, Decl(uncalledFunctionChecksInConditionalPerf.ts, 0, 13))
18+
>b : Symbol(b, Decl(uncalledFunctionChecksInConditionalPerf.ts, 0, 13))
19+
>b : Symbol(b, Decl(uncalledFunctionChecksInConditionalPerf.ts, 0, 13))
20+
>b : Symbol(b, Decl(uncalledFunctionChecksInConditionalPerf.ts, 0, 13))
21+
>b : Symbol(b, Decl(uncalledFunctionChecksInConditionalPerf.ts, 0, 13))
22+
>b : Symbol(b, Decl(uncalledFunctionChecksInConditionalPerf.ts, 0, 13))
23+
>b : Symbol(b, Decl(uncalledFunctionChecksInConditionalPerf.ts, 0, 13))
24+
>b : Symbol(b, Decl(uncalledFunctionChecksInConditionalPerf.ts, 0, 13))
25+
>b : Symbol(b, Decl(uncalledFunctionChecksInConditionalPerf.ts, 0, 13))
26+
>b : Symbol(b, Decl(uncalledFunctionChecksInConditionalPerf.ts, 0, 13))
27+
>b : Symbol(b, Decl(uncalledFunctionChecksInConditionalPerf.ts, 0, 13))
28+
Lines changed: 71 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,71 @@
1+
=== tests/cases/compiler/uncalledFunctionChecksInConditionalPerf.ts ===
2+
declare const b: boolean;
3+
>b : boolean
4+
5+
((((((((((((((((((((((b) && b) && b) && b) && b) && b) && b) && b) && b) && b) && b) && b) && b) && b) && b) && b) && b) && b) && b) && b) && b) && b);
6+
>((((((((((((((((((((((b) && b) && b) && b) && b) && b) && b) && b) && b) && b) && b) && b) && b) && b) && b) && b) && b) && b) && b) && b) && b) && b) : boolean
7+
>(((((((((((((((((((((b) && b) && b) && b) && b) && b) && b) && b) && b) && b) && b) && b) && b) && b) && b) && b) && b) && b) && b) && b) && b) && b : boolean
8+
>(((((((((((((((((((((b) && b) && b) && b) && b) && b) && b) && b) && b) && b) && b) && b) && b) && b) && b) && b) && b) && b) && b) && b) && b) : boolean
9+
>((((((((((((((((((((b) && b) && b) && b) && b) && b) && b) && b) && b) && b) && b) && b) && b) && b) && b) && b) && b) && b) && b) && b) && b : boolean
10+
>((((((((((((((((((((b) && b) && b) && b) && b) && b) && b) && b) && b) && b) && b) && b) && b) && b) && b) && b) && b) && b) && b) && b) : boolean
11+
>(((((((((((((((((((b) && b) && b) && b) && b) && b) && b) && b) && b) && b) && b) && b) && b) && b) && b) && b) && b) && b) && b) && b : boolean
12+
>(((((((((((((((((((b) && b) && b) && b) && b) && b) && b) && b) && b) && b) && b) && b) && b) && b) && b) && b) && b) && b) && b) : boolean
13+
>((((((((((((((((((b) && b) && b) && b) && b) && b) && b) && b) && b) && b) && b) && b) && b) && b) && b) && b) && b) && b) && b : boolean
14+
>((((((((((((((((((b) && b) && b) && b) && b) && b) && b) && b) && b) && b) && b) && b) && b) && b) && b) && b) && b) && b) : boolean
15+
>(((((((((((((((((b) && b) && b) && b) && b) && b) && b) && b) && b) && b) && b) && b) && b) && b) && b) && b) && b) && b : boolean
16+
>(((((((((((((((((b) && b) && b) && b) && b) && b) && b) && b) && b) && b) && b) && b) && b) && b) && b) && b) && b) : boolean
17+
>((((((((((((((((b) && b) && b) && b) && b) && b) && b) && b) && b) && b) && b) && b) && b) && b) && b) && b) && b : boolean
18+
>((((((((((((((((b) && b) && b) && b) && b) && b) && b) && b) && b) && b) && b) && b) && b) && b) && b) && b) : boolean
19+
>(((((((((((((((b) && b) && b) && b) && b) && b) && b) && b) && b) && b) && b) && b) && b) && b) && b) && b : boolean
20+
>(((((((((((((((b) && b) && b) && b) && b) && b) && b) && b) && b) && b) && b) && b) && b) && b) && b) : boolean
21+
>((((((((((((((b) && b) && b) && b) && b) && b) && b) && b) && b) && b) && b) && b) && b) && b) && b : boolean
22+
>((((((((((((((b) && b) && b) && b) && b) && b) && b) && b) && b) && b) && b) && b) && b) && b) : boolean
23+
>(((((((((((((b) && b) && b) && b) && b) && b) && b) && b) && b) && b) && b) && b) && b) && b : boolean
24+
>(((((((((((((b) && b) && b) && b) && b) && b) && b) && b) && b) && b) && b) && b) && b) : boolean
25+
>((((((((((((b) && b) && b) && b) && b) && b) && b) && b) && b) && b) && b) && b) && b : boolean
26+
>((((((((((((b) && b) && b) && b) && b) && b) && b) && b) && b) && b) && b) && b) : boolean
27+
>(((((((((((b) && b) && b) && b) && b) && b) && b) && b) && b) && b) && b) && b : boolean
28+
>(((((((((((b) && b) && b) && b) && b) && b) && b) && b) && b) && b) && b) : boolean
29+
>((((((((((b) && b) && b) && b) && b) && b) && b) && b) && b) && b) && b : boolean
30+
>((((((((((b) && b) && b) && b) && b) && b) && b) && b) && b) && b) : boolean
31+
>(((((((((b) && b) && b) && b) && b) && b) && b) && b) && b) && b : boolean
32+
>(((((((((b) && b) && b) && b) && b) && b) && b) && b) && b) : boolean
33+
>((((((((b) && b) && b) && b) && b) && b) && b) && b) && b : boolean
34+
>((((((((b) && b) && b) && b) && b) && b) && b) && b) : boolean
35+
>(((((((b) && b) && b) && b) && b) && b) && b) && b : boolean
36+
>(((((((b) && b) && b) && b) && b) && b) && b) : boolean
37+
>((((((b) && b) && b) && b) && b) && b) && b : boolean
38+
>((((((b) && b) && b) && b) && b) && b) : boolean
39+
>(((((b) && b) && b) && b) && b) && b : boolean
40+
>(((((b) && b) && b) && b) && b) : boolean
41+
>((((b) && b) && b) && b) && b : boolean
42+
>((((b) && b) && b) && b) : boolean
43+
>(((b) && b) && b) && b : boolean
44+
>(((b) && b) && b) : boolean
45+
>((b) && b) && b : boolean
46+
>((b) && b) : boolean
47+
>(b) && b : boolean
48+
>(b) : boolean
49+
>b : boolean
50+
>b : true
51+
>b : true
52+
>b : true
53+
>b : true
54+
>b : true
55+
>b : true
56+
>b : true
57+
>b : true
58+
>b : true
59+
>b : true
60+
>b : true
61+
>b : true
62+
>b : true
63+
>b : true
64+
>b : true
65+
>b : true
66+
>b : true
67+
>b : true
68+
>b : true
69+
>b : true
70+
>b : true
71+
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
// @strictNullChecks: true
2+
3+
declare const b: boolean;
4+
5+
((((((((((((((((((((((b) && b) && b) && b) && b) && b) && b) && b) && b) && b) && b) && b) && b) && b) && b) && b) && b) && b) && b) && b) && b) && b);

0 commit comments

Comments
 (0)