Skip to content

Commit 6aefc1d

Browse files
authored
More fixes to uncalled function checks in && expressions (#49868)
1 parent 4e23f51 commit 6aefc1d

6 files changed

+534
-1
lines changed

src/compiler/checker.ts

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -33955,7 +33955,11 @@ namespace ts {
3395533955
const operator = operatorToken.kind;
3395633956
if (operator === SyntaxKind.AmpersandAmpersandToken || operator === SyntaxKind.BarBarToken || operator === SyntaxKind.QuestionQuestionToken) {
3395733957
if (operator === SyntaxKind.AmpersandAmpersandToken) {
33958-
const parent = walkUpParenthesizedExpressions(node.parent);
33958+
let parent = node.parent;
33959+
while (parent.kind === SyntaxKind.ParenthesizedExpression
33960+
|| isBinaryExpression(parent) && (parent.operatorToken.kind === SyntaxKind.AmpersandAmpersandToken || parent.operatorToken.kind === SyntaxKind.BarBarToken)) {
33961+
parent = parent.parent;
33962+
}
3395933963
checkTestingKnownTruthyCallableOrAwaitableType(node.left, isIfStatement(parent) ? parent.thenStatement : undefined);
3396033964
}
3396133965
checkTruthinessOfType(leftType, node.left);
Lines changed: 58 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,58 @@
1+
tests/cases/compiler/uncalledFunctionChecksInConditional2.ts(20,5): error TS2774: This condition will always return true since this function is always defined. Did you mean to call it instead?
2+
tests/cases/compiler/uncalledFunctionChecksInConditional2.ts(38,5): error TS2774: This condition will always return true since this function is always defined. Did you mean to call it instead?
3+
4+
5+
==== tests/cases/compiler/uncalledFunctionChecksInConditional2.ts (2 errors) ====
6+
{
7+
const perf = window.performance
8+
9+
// Simplified
10+
if (
11+
perf &&
12+
perf.measure &&
13+
perf.clearMarks &&
14+
perf.clearMeasures
15+
) {
16+
perf.measure("");
17+
perf.clearMarks("")
18+
perf.clearMeasures("")
19+
}
20+
21+
// With ||
22+
if (
23+
perf &&
24+
perf.mark &&
25+
perf.measure || !!true
26+
~~~~~~~~~~~~
27+
!!! error TS2774: This condition will always return true since this function is always defined. Did you mean to call it instead?
28+
) {
29+
perf.mark("");
30+
}
31+
};
32+
33+
// Original #49192
34+
declare let inBrowser: boolean;
35+
{
36+
let mark;
37+
let measure;
38+
const perf = inBrowser && window.performance
39+
/* istanbul ignore if */
40+
if (
41+
perf &&
42+
perf.mark &&
43+
perf.measure &&
44+
perf.clearMarks &&
45+
perf.clearMeasures
46+
~~~~~~~~~~~~~~~~~~
47+
!!! error TS2774: This condition will always return true since this function is always defined. Did you mean to call it instead?
48+
) {
49+
mark = (tag) => perf.mark(tag)
50+
measure = (name, startTag, endTag) => {
51+
perf.measure(name, startTag, endTag)
52+
perf.clearMarks(startTag)
53+
perf.clearMarks(endTag)
54+
// perf.clearMeasures(name)
55+
}
56+
}
57+
};
58+
Lines changed: 91 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,91 @@
1+
//// [uncalledFunctionChecksInConditional2.ts]
2+
{
3+
const perf = window.performance
4+
5+
// Simplified
6+
if (
7+
perf &&
8+
perf.measure &&
9+
perf.clearMarks &&
10+
perf.clearMeasures
11+
) {
12+
perf.measure("");
13+
perf.clearMarks("")
14+
perf.clearMeasures("")
15+
}
16+
17+
// With ||
18+
if (
19+
perf &&
20+
perf.mark &&
21+
perf.measure || !!true
22+
) {
23+
perf.mark("");
24+
}
25+
};
26+
27+
// Original #49192
28+
declare let inBrowser: boolean;
29+
{
30+
let mark;
31+
let measure;
32+
const perf = inBrowser && window.performance
33+
/* istanbul ignore if */
34+
if (
35+
perf &&
36+
perf.mark &&
37+
perf.measure &&
38+
perf.clearMarks &&
39+
perf.clearMeasures
40+
) {
41+
mark = (tag) => perf.mark(tag)
42+
measure = (name, startTag, endTag) => {
43+
perf.measure(name, startTag, endTag)
44+
perf.clearMarks(startTag)
45+
perf.clearMarks(endTag)
46+
// perf.clearMeasures(name)
47+
}
48+
}
49+
};
50+
51+
52+
//// [uncalledFunctionChecksInConditional2.js]
53+
{
54+
var perf = window.performance;
55+
// Simplified
56+
if (perf &&
57+
perf.measure &&
58+
perf.clearMarks &&
59+
perf.clearMeasures) {
60+
perf.measure("");
61+
perf.clearMarks("");
62+
perf.clearMeasures("");
63+
}
64+
// With ||
65+
if (perf &&
66+
perf.mark &&
67+
perf.measure || !!true) {
68+
perf.mark("");
69+
}
70+
}
71+
;
72+
{
73+
var mark = void 0;
74+
var measure = void 0;
75+
var perf_1 = inBrowser && window.performance;
76+
/* istanbul ignore if */
77+
if (perf_1 &&
78+
perf_1.mark &&
79+
perf_1.measure &&
80+
perf_1.clearMarks &&
81+
perf_1.clearMeasures) {
82+
mark = function (tag) { return perf_1.mark(tag); };
83+
measure = function (name, startTag, endTag) {
84+
perf_1.measure(name, startTag, endTag);
85+
perf_1.clearMarks(startTag);
86+
perf_1.clearMarks(endTag);
87+
// perf.clearMeasures(name)
88+
};
89+
}
90+
}
91+
;
Lines changed: 150 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,150 @@
1+
=== tests/cases/compiler/uncalledFunctionChecksInConditional2.ts ===
2+
{
3+
const perf = window.performance
4+
>perf : Symbol(perf, Decl(uncalledFunctionChecksInConditional2.ts, 1, 7))
5+
>window.performance : Symbol(performance, Decl(lib.dom.d.ts, --, --), Decl(lib.dom.d.ts, --, --))
6+
>window : Symbol(window, Decl(lib.dom.d.ts, --, --))
7+
>performance : Symbol(performance, Decl(lib.dom.d.ts, --, --), Decl(lib.dom.d.ts, --, --))
8+
9+
// Simplified
10+
if (
11+
perf &&
12+
>perf : Symbol(perf, Decl(uncalledFunctionChecksInConditional2.ts, 1, 7))
13+
14+
perf.measure &&
15+
>perf.measure : Symbol(Performance.measure, Decl(lib.dom.d.ts, --, --))
16+
>perf : Symbol(perf, Decl(uncalledFunctionChecksInConditional2.ts, 1, 7))
17+
>measure : Symbol(Performance.measure, Decl(lib.dom.d.ts, --, --))
18+
19+
perf.clearMarks &&
20+
>perf.clearMarks : Symbol(Performance.clearMarks, Decl(lib.dom.d.ts, --, --))
21+
>perf : Symbol(perf, Decl(uncalledFunctionChecksInConditional2.ts, 1, 7))
22+
>clearMarks : Symbol(Performance.clearMarks, Decl(lib.dom.d.ts, --, --))
23+
24+
perf.clearMeasures
25+
>perf.clearMeasures : Symbol(Performance.clearMeasures, Decl(lib.dom.d.ts, --, --))
26+
>perf : Symbol(perf, Decl(uncalledFunctionChecksInConditional2.ts, 1, 7))
27+
>clearMeasures : Symbol(Performance.clearMeasures, Decl(lib.dom.d.ts, --, --))
28+
29+
) {
30+
perf.measure("");
31+
>perf.measure : Symbol(Performance.measure, Decl(lib.dom.d.ts, --, --))
32+
>perf : Symbol(perf, Decl(uncalledFunctionChecksInConditional2.ts, 1, 7))
33+
>measure : Symbol(Performance.measure, Decl(lib.dom.d.ts, --, --))
34+
35+
perf.clearMarks("")
36+
>perf.clearMarks : Symbol(Performance.clearMarks, Decl(lib.dom.d.ts, --, --))
37+
>perf : Symbol(perf, Decl(uncalledFunctionChecksInConditional2.ts, 1, 7))
38+
>clearMarks : Symbol(Performance.clearMarks, Decl(lib.dom.d.ts, --, --))
39+
40+
perf.clearMeasures("")
41+
>perf.clearMeasures : Symbol(Performance.clearMeasures, Decl(lib.dom.d.ts, --, --))
42+
>perf : Symbol(perf, Decl(uncalledFunctionChecksInConditional2.ts, 1, 7))
43+
>clearMeasures : Symbol(Performance.clearMeasures, Decl(lib.dom.d.ts, --, --))
44+
}
45+
46+
// With ||
47+
if (
48+
perf &&
49+
>perf : Symbol(perf, Decl(uncalledFunctionChecksInConditional2.ts, 1, 7))
50+
51+
perf.mark &&
52+
>perf.mark : Symbol(Performance.mark, Decl(lib.dom.d.ts, --, --))
53+
>perf : Symbol(perf, Decl(uncalledFunctionChecksInConditional2.ts, 1, 7))
54+
>mark : Symbol(Performance.mark, Decl(lib.dom.d.ts, --, --))
55+
56+
perf.measure || !!true
57+
>perf.measure : Symbol(Performance.measure, Decl(lib.dom.d.ts, --, --))
58+
>perf : Symbol(perf, Decl(uncalledFunctionChecksInConditional2.ts, 1, 7))
59+
>measure : Symbol(Performance.measure, Decl(lib.dom.d.ts, --, --))
60+
61+
) {
62+
perf.mark("");
63+
>perf.mark : Symbol(Performance.mark, Decl(lib.dom.d.ts, --, --))
64+
>perf : Symbol(perf, Decl(uncalledFunctionChecksInConditional2.ts, 1, 7))
65+
>mark : Symbol(Performance.mark, Decl(lib.dom.d.ts, --, --))
66+
}
67+
};
68+
69+
// Original #49192
70+
declare let inBrowser: boolean;
71+
>inBrowser : Symbol(inBrowser, Decl(uncalledFunctionChecksInConditional2.ts, 26, 11))
72+
{
73+
let mark;
74+
>mark : Symbol(mark, Decl(uncalledFunctionChecksInConditional2.ts, 28, 5))
75+
76+
let measure;
77+
>measure : Symbol(measure, Decl(uncalledFunctionChecksInConditional2.ts, 29, 5))
78+
79+
const perf = inBrowser && window.performance
80+
>perf : Symbol(perf, Decl(uncalledFunctionChecksInConditional2.ts, 30, 7))
81+
>inBrowser : Symbol(inBrowser, Decl(uncalledFunctionChecksInConditional2.ts, 26, 11))
82+
>window.performance : Symbol(performance, Decl(lib.dom.d.ts, --, --), Decl(lib.dom.d.ts, --, --))
83+
>window : Symbol(window, Decl(lib.dom.d.ts, --, --))
84+
>performance : Symbol(performance, Decl(lib.dom.d.ts, --, --), Decl(lib.dom.d.ts, --, --))
85+
86+
/* istanbul ignore if */
87+
if (
88+
perf &&
89+
>perf : Symbol(perf, Decl(uncalledFunctionChecksInConditional2.ts, 30, 7))
90+
91+
perf.mark &&
92+
>perf.mark : Symbol(Performance.mark, Decl(lib.dom.d.ts, --, --))
93+
>perf : Symbol(perf, Decl(uncalledFunctionChecksInConditional2.ts, 30, 7))
94+
>mark : Symbol(Performance.mark, Decl(lib.dom.d.ts, --, --))
95+
96+
perf.measure &&
97+
>perf.measure : Symbol(Performance.measure, Decl(lib.dom.d.ts, --, --))
98+
>perf : Symbol(perf, Decl(uncalledFunctionChecksInConditional2.ts, 30, 7))
99+
>measure : Symbol(Performance.measure, Decl(lib.dom.d.ts, --, --))
100+
101+
perf.clearMarks &&
102+
>perf.clearMarks : Symbol(Performance.clearMarks, Decl(lib.dom.d.ts, --, --))
103+
>perf : Symbol(perf, Decl(uncalledFunctionChecksInConditional2.ts, 30, 7))
104+
>clearMarks : Symbol(Performance.clearMarks, Decl(lib.dom.d.ts, --, --))
105+
106+
perf.clearMeasures
107+
>perf.clearMeasures : Symbol(Performance.clearMeasures, Decl(lib.dom.d.ts, --, --))
108+
>perf : Symbol(perf, Decl(uncalledFunctionChecksInConditional2.ts, 30, 7))
109+
>clearMeasures : Symbol(Performance.clearMeasures, Decl(lib.dom.d.ts, --, --))
110+
111+
) {
112+
mark = (tag) => perf.mark(tag)
113+
>mark : Symbol(mark, Decl(uncalledFunctionChecksInConditional2.ts, 28, 5))
114+
>tag : Symbol(tag, Decl(uncalledFunctionChecksInConditional2.ts, 39, 12))
115+
>perf.mark : Symbol(Performance.mark, Decl(lib.dom.d.ts, --, --))
116+
>perf : Symbol(perf, Decl(uncalledFunctionChecksInConditional2.ts, 30, 7))
117+
>mark : Symbol(Performance.mark, Decl(lib.dom.d.ts, --, --))
118+
>tag : Symbol(tag, Decl(uncalledFunctionChecksInConditional2.ts, 39, 12))
119+
120+
measure = (name, startTag, endTag) => {
121+
>measure : Symbol(measure, Decl(uncalledFunctionChecksInConditional2.ts, 29, 5))
122+
>name : Symbol(name, Decl(uncalledFunctionChecksInConditional2.ts, 40, 15))
123+
>startTag : Symbol(startTag, Decl(uncalledFunctionChecksInConditional2.ts, 40, 20))
124+
>endTag : Symbol(endTag, Decl(uncalledFunctionChecksInConditional2.ts, 40, 30))
125+
126+
perf.measure(name, startTag, endTag)
127+
>perf.measure : Symbol(Performance.measure, Decl(lib.dom.d.ts, --, --))
128+
>perf : Symbol(perf, Decl(uncalledFunctionChecksInConditional2.ts, 30, 7))
129+
>measure : Symbol(Performance.measure, Decl(lib.dom.d.ts, --, --))
130+
>name : Symbol(name, Decl(uncalledFunctionChecksInConditional2.ts, 40, 15))
131+
>startTag : Symbol(startTag, Decl(uncalledFunctionChecksInConditional2.ts, 40, 20))
132+
>endTag : Symbol(endTag, Decl(uncalledFunctionChecksInConditional2.ts, 40, 30))
133+
134+
perf.clearMarks(startTag)
135+
>perf.clearMarks : Symbol(Performance.clearMarks, Decl(lib.dom.d.ts, --, --))
136+
>perf : Symbol(perf, Decl(uncalledFunctionChecksInConditional2.ts, 30, 7))
137+
>clearMarks : Symbol(Performance.clearMarks, Decl(lib.dom.d.ts, --, --))
138+
>startTag : Symbol(startTag, Decl(uncalledFunctionChecksInConditional2.ts, 40, 20))
139+
140+
perf.clearMarks(endTag)
141+
>perf.clearMarks : Symbol(Performance.clearMarks, Decl(lib.dom.d.ts, --, --))
142+
>perf : Symbol(perf, Decl(uncalledFunctionChecksInConditional2.ts, 30, 7))
143+
>clearMarks : Symbol(Performance.clearMarks, Decl(lib.dom.d.ts, --, --))
144+
>endTag : Symbol(endTag, Decl(uncalledFunctionChecksInConditional2.ts, 40, 30))
145+
146+
// perf.clearMeasures(name)
147+
}
148+
}
149+
};
150+

0 commit comments

Comments
 (0)