Skip to content

Commit 7be41cb

Browse files
feat: improve get literal value for conditional expression (#6000)
* feat: improve get literal value for conditional expression * more tests * Remove unnecessary comparison --------- Co-authored-by: Lukas Taegert-Atkinson <lukastaegert@users.noreply.github.com> Co-authored-by: Lukas Taegert-Atkinson <lukas.taegert-atkinson@tngtech.com>
1 parent 1923218 commit 7be41cb

File tree

3 files changed

+31
-2
lines changed

3 files changed

+31
-2
lines changed

src/ast/nodes/ConditionalExpression.ts

Lines changed: 13 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ import { tryCastLiteralValueToBoolean } from '../utils/tryCastLiteralValueToBool
1616
import type * as NodeType from './NodeType';
1717
import { Flag, isFlagSet, setFlag } from './shared/BitFlags';
1818
import type { ExpressionEntity, LiteralValueOrUnknown } from './shared/Expression';
19-
import { UnknownValue } from './shared/Expression';
19+
import { UnknownFalsyValue, UnknownTruthyValue, UnknownValue } from './shared/Expression';
2020
import { MultiExpression } from './shared/MultiExpression';
2121
import type { ExpressionNode, IncludeChildren } from './shared/Node';
2222
import { doNotDeoptimize, NodeBase, onlyIncludeSelfNoDeoptimize } from './shared/Node';
@@ -78,7 +78,18 @@ export default class ConditionalExpression extends NodeBase implements Deoptimiz
7878
origin: DeoptimizableEntity
7979
): LiteralValueOrUnknown {
8080
const usedBranch = this.getUsedBranch();
81-
if (!usedBranch) return UnknownValue;
81+
if (!usedBranch) {
82+
const consequentValue = this.consequent.getLiteralValueAtPath(path, recursionTracker, origin);
83+
const castedConsequentValue = tryCastLiteralValueToBoolean(consequentValue);
84+
if (castedConsequentValue === UnknownValue) return UnknownValue;
85+
const alternateValue = this.alternate.getLiteralValueAtPath(path, recursionTracker, origin);
86+
const castedAlternateValue = tryCastLiteralValueToBoolean(alternateValue);
87+
if (castedConsequentValue !== castedAlternateValue) return UnknownValue;
88+
this.expressionsToBeDeoptimized.push(origin);
89+
if (consequentValue !== alternateValue)
90+
return castedConsequentValue ? UnknownTruthyValue : UnknownFalsyValue;
91+
return consequentValue;
92+
}
8293
this.expressionsToBeDeoptimized.push(origin);
8394
return usedBranch.getLiteralValueAtPath(path, recursionTracker, origin);
8495
}

test/form/samples/treeshake-if-statement/_expected.js

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,3 +5,9 @@
55
if (typeof parseInt === 'function' ?? 'a' === 'a') {
66
assert.ok(true);
77
}
8+
9+
if (!(unknownGlobal ? 'asdf' : true)) ;
10+
11+
if (unknownGlobal ? 0 : false) ;
12+
13+
if (!(unknownGlobal ? 'a' === 'a' : true)) ;

test/form/samples/treeshake-if-statement/main.js

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,3 +9,15 @@ if (typeof parseInt === 'function' || 'a' === 'a') {
99
if (typeof parseInt === 'function' ?? 'a' === 'a') {
1010
assert.ok(true);
1111
}
12+
13+
if (!(unknownGlobal ? 'asdf' : true)) {
14+
assert.ok(false);
15+
}
16+
17+
if (unknownGlobal ? 0 : false) {
18+
assert.ok(false);
19+
}
20+
21+
if (!(unknownGlobal ? 'a' === 'a' : true)) {
22+
assert.ok(false);
23+
}

0 commit comments

Comments
 (0)