@rollup/wasm-node 4.30.0 → 4.31.0-0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/bin/rollup +2 -2
- package/dist/es/getLogFilter.js +2 -2
- package/dist/es/parseAst.js +2 -2
- package/dist/es/rollup.js +2 -2
- package/dist/es/shared/node-entry.js +1510 -686
- package/dist/es/shared/parseAst.js +3 -3
- package/dist/es/shared/watch.js +6 -6
- package/dist/getLogFilter.js +2 -2
- package/dist/loadConfigFile.js +2 -2
- package/dist/parseAst.js +2 -2
- package/dist/rollup.js +2 -2
- package/dist/shared/fsevents-importer.js +2 -2
- package/dist/shared/index.js +6 -6
- package/dist/shared/loadConfigFile.js +2 -2
- package/dist/shared/parseAst.js +2 -2
- package/dist/shared/rollup.js +1506 -682
- package/dist/shared/watch-cli.js +4 -20
- package/dist/shared/watch.js +3 -3
- package/dist/wasm-node/bindings_wasm_bg.wasm +0 -0
- package/package.json +1 -1
package/dist/shared/rollup.js
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
/*
|
|
2
2
|
@license
|
|
3
|
-
Rollup.js v4.
|
|
4
|
-
|
|
3
|
+
Rollup.js v4.31.0-0
|
|
4
|
+
Tue, 14 Jan 2025 05:57:11 GMT - commit 8c80d5f657f0777d14bd75d446fee3fa4b7639fc
|
|
5
5
|
|
|
6
6
|
https://github.com/rollup/rollup
|
|
7
7
|
|
|
@@ -17,7 +17,7 @@ const native_js = require('../native.js');
|
|
|
17
17
|
const node_perf_hooks = require('node:perf_hooks');
|
|
18
18
|
const promises = require('node:fs/promises');
|
|
19
19
|
|
|
20
|
-
var version = "4.
|
|
20
|
+
var version = "4.31.0-0";
|
|
21
21
|
|
|
22
22
|
function ensureArray$1(items) {
|
|
23
23
|
if (Array.isArray(items)) {
|
|
@@ -3491,71 +3491,6 @@ function renderSystemExportSequenceBeforeExpression(exportedVariable, expression
|
|
|
3491
3491
|
}
|
|
3492
3492
|
}
|
|
3493
3493
|
|
|
3494
|
-
/** @import { Node } from 'estree' */
|
|
3495
|
-
|
|
3496
|
-
/**
|
|
3497
|
-
* @param {Node} node
|
|
3498
|
-
* @param {Node} parent
|
|
3499
|
-
* @returns {boolean}
|
|
3500
|
-
*/
|
|
3501
|
-
function is_reference(node, parent) {
|
|
3502
|
-
if (node.type === 'MemberExpression') {
|
|
3503
|
-
return !node.computed && is_reference(node.object, node);
|
|
3504
|
-
}
|
|
3505
|
-
|
|
3506
|
-
if (node.type !== 'Identifier') return false;
|
|
3507
|
-
|
|
3508
|
-
switch (parent?.type) {
|
|
3509
|
-
// disregard `bar` in `foo.bar`
|
|
3510
|
-
case 'MemberExpression':
|
|
3511
|
-
return parent.computed || node === parent.object;
|
|
3512
|
-
|
|
3513
|
-
// disregard the `foo` in `class {foo(){}}` but keep it in `class {[foo](){}}`
|
|
3514
|
-
case 'MethodDefinition':
|
|
3515
|
-
return parent.computed;
|
|
3516
|
-
|
|
3517
|
-
// disregard the `meta` in `import.meta`
|
|
3518
|
-
case 'MetaProperty':
|
|
3519
|
-
return parent.meta === node;
|
|
3520
|
-
|
|
3521
|
-
// disregard the `foo` in `class {foo=bar}` but keep it in `class {[foo]=bar}` and `class {bar=foo}`
|
|
3522
|
-
case 'PropertyDefinition':
|
|
3523
|
-
return parent.computed || node === parent.value;
|
|
3524
|
-
|
|
3525
|
-
// disregard the `bar` in `{ bar: foo }`, but keep it in `{ [bar]: foo }`
|
|
3526
|
-
case 'Property':
|
|
3527
|
-
return parent.computed || node === parent.value;
|
|
3528
|
-
|
|
3529
|
-
// disregard the `bar` in `export { foo as bar }` or
|
|
3530
|
-
// the foo in `import { foo as bar }`
|
|
3531
|
-
case 'ExportSpecifier':
|
|
3532
|
-
case 'ImportSpecifier':
|
|
3533
|
-
return node === parent.local;
|
|
3534
|
-
|
|
3535
|
-
// disregard the `foo` in `foo: while (...) { ... break foo; ... continue foo;}`
|
|
3536
|
-
case 'LabeledStatement':
|
|
3537
|
-
case 'BreakStatement':
|
|
3538
|
-
case 'ContinueStatement':
|
|
3539
|
-
return false;
|
|
3540
|
-
|
|
3541
|
-
default:
|
|
3542
|
-
return true;
|
|
3543
|
-
}
|
|
3544
|
-
}
|
|
3545
|
-
|
|
3546
|
-
const PureFunctionKey = Symbol('PureFunction');
|
|
3547
|
-
const getPureFunctions = ({ treeshake }) => {
|
|
3548
|
-
const pureFunctions = Object.create(null);
|
|
3549
|
-
for (const functionName of treeshake ? treeshake.manualPureFunctions : []) {
|
|
3550
|
-
let currentFunctions = pureFunctions;
|
|
3551
|
-
for (const pathSegment of functionName.split('.')) {
|
|
3552
|
-
currentFunctions = currentFunctions[pathSegment] ||= Object.create(null);
|
|
3553
|
-
}
|
|
3554
|
-
currentFunctions[PureFunctionKey] = true;
|
|
3555
|
-
}
|
|
3556
|
-
return pureFunctions;
|
|
3557
|
-
};
|
|
3558
|
-
|
|
3559
3494
|
const UnknownKey = Symbol('Unknown Key');
|
|
3560
3495
|
const UnknownNonAccessorKey = Symbol('Unknown Non-Accessor Key');
|
|
3561
3496
|
const UnknownInteger = Symbol('Unknown Integer');
|
|
@@ -3570,7 +3505,7 @@ const UNKNOWN_PATH = [UnknownKey];
|
|
|
3570
3505
|
const UNKNOWN_NON_ACCESSOR_PATH = [UnknownNonAccessorKey];
|
|
3571
3506
|
const UNKNOWN_INTEGER_PATH = [UnknownInteger];
|
|
3572
3507
|
const EntitiesKey = Symbol('Entities');
|
|
3573
|
-
class
|
|
3508
|
+
class EntityPathTracker {
|
|
3574
3509
|
constructor() {
|
|
3575
3510
|
this.entityPaths = Object.create(null, {
|
|
3576
3511
|
[EntitiesKey]: { value: new Set() }
|
|
@@ -3595,14 +3530,14 @@ class PathTracker {
|
|
|
3595
3530
|
getEntities(path) {
|
|
3596
3531
|
let currentPaths = this.entityPaths;
|
|
3597
3532
|
for (const pathSegment of path) {
|
|
3598
|
-
currentPaths = currentPaths[pathSegment]
|
|
3599
|
-
|
|
3600
|
-
|
|
3533
|
+
currentPaths = currentPaths[pathSegment] ||= Object.create(null, {
|
|
3534
|
+
[EntitiesKey]: { value: new Set() }
|
|
3535
|
+
});
|
|
3601
3536
|
}
|
|
3602
3537
|
return currentPaths[EntitiesKey];
|
|
3603
3538
|
}
|
|
3604
3539
|
}
|
|
3605
|
-
const SHARED_RECURSION_TRACKER = new
|
|
3540
|
+
const SHARED_RECURSION_TRACKER = new EntityPathTracker();
|
|
3606
3541
|
class DiscriminatedPathTracker {
|
|
3607
3542
|
constructor() {
|
|
3608
3543
|
this.entityPaths = Object.create(null, {
|
|
@@ -3612,9 +3547,9 @@ class DiscriminatedPathTracker {
|
|
|
3612
3547
|
trackEntityAtPathAndGetIfTracked(path, discriminator, entity) {
|
|
3613
3548
|
let currentPaths = this.entityPaths;
|
|
3614
3549
|
for (const pathSegment of path) {
|
|
3615
|
-
currentPaths = currentPaths[pathSegment]
|
|
3616
|
-
|
|
3617
|
-
|
|
3550
|
+
currentPaths = currentPaths[pathSegment] ||= Object.create(null, {
|
|
3551
|
+
[EntitiesKey]: { value: new Map() }
|
|
3552
|
+
});
|
|
3618
3553
|
}
|
|
3619
3554
|
const trackedEntities = getOrCreate(currentPaths[EntitiesKey], discriminator, (getNewSet));
|
|
3620
3555
|
if (trackedEntities.has(entity))
|
|
@@ -3623,6 +3558,137 @@ class DiscriminatedPathTracker {
|
|
|
3623
3558
|
return false;
|
|
3624
3559
|
}
|
|
3625
3560
|
}
|
|
3561
|
+
const UNKNOWN_INCLUDED_PATH = Object.freeze({ [UnknownKey]: parseAst_js.EMPTY_OBJECT });
|
|
3562
|
+
class IncludedPathTracker {
|
|
3563
|
+
constructor() {
|
|
3564
|
+
this.includedPaths = null;
|
|
3565
|
+
}
|
|
3566
|
+
includePathAndGetIfIncluded(path) {
|
|
3567
|
+
let included = true;
|
|
3568
|
+
let parent = this;
|
|
3569
|
+
let parentSegment = 'includedPaths';
|
|
3570
|
+
let currentPaths = (this.includedPaths ||=
|
|
3571
|
+
((included = false), Object.create(null)));
|
|
3572
|
+
for (const pathSegment of path) {
|
|
3573
|
+
// This means from here, all paths are included
|
|
3574
|
+
if (currentPaths[UnknownKey]) {
|
|
3575
|
+
return true;
|
|
3576
|
+
}
|
|
3577
|
+
// Including UnknownKey automatically includes all nested paths.
|
|
3578
|
+
// From above, we know that UnknownKey is not included yet.
|
|
3579
|
+
if (typeof pathSegment === 'symbol') {
|
|
3580
|
+
// Hopefully, this saves some memory over just setting
|
|
3581
|
+
// currentPaths[UnknownKey] = EMPTY_OBJECT
|
|
3582
|
+
parent[parentSegment] = UNKNOWN_INCLUDED_PATH;
|
|
3583
|
+
return false;
|
|
3584
|
+
}
|
|
3585
|
+
parent = currentPaths;
|
|
3586
|
+
parentSegment = pathSegment;
|
|
3587
|
+
currentPaths = currentPaths[pathSegment] ||= ((included = false), Object.create(null));
|
|
3588
|
+
}
|
|
3589
|
+
return included;
|
|
3590
|
+
}
|
|
3591
|
+
includeAllPaths(entity, context, basePath) {
|
|
3592
|
+
const { includedPaths } = this;
|
|
3593
|
+
if (includedPaths) {
|
|
3594
|
+
includeAllPaths(entity, context, basePath, includedPaths);
|
|
3595
|
+
}
|
|
3596
|
+
}
|
|
3597
|
+
}
|
|
3598
|
+
function includeAllPaths(entity, context, basePath, currentPaths) {
|
|
3599
|
+
if (currentPaths[UnknownKey]) {
|
|
3600
|
+
return entity.includePath([...basePath, UnknownKey], context);
|
|
3601
|
+
}
|
|
3602
|
+
const keys = Object.keys(currentPaths);
|
|
3603
|
+
if (keys.length === 0) {
|
|
3604
|
+
return entity.includePath(basePath, context);
|
|
3605
|
+
}
|
|
3606
|
+
for (const key of keys) {
|
|
3607
|
+
includeAllPaths(entity, context, [...basePath, key], currentPaths[key]);
|
|
3608
|
+
}
|
|
3609
|
+
}
|
|
3610
|
+
|
|
3611
|
+
/** @import { Node } from 'estree' */
|
|
3612
|
+
|
|
3613
|
+
/**
|
|
3614
|
+
* @param {Node} node
|
|
3615
|
+
* @param {Node} parent
|
|
3616
|
+
* @returns {boolean}
|
|
3617
|
+
*/
|
|
3618
|
+
function is_reference(node, parent) {
|
|
3619
|
+
if (node.type === 'MemberExpression') {
|
|
3620
|
+
return !node.computed && is_reference(node.object, node);
|
|
3621
|
+
}
|
|
3622
|
+
|
|
3623
|
+
if (node.type !== 'Identifier') return false;
|
|
3624
|
+
|
|
3625
|
+
switch (parent?.type) {
|
|
3626
|
+
// disregard `bar` in `foo.bar`
|
|
3627
|
+
case 'MemberExpression':
|
|
3628
|
+
return parent.computed || node === parent.object;
|
|
3629
|
+
|
|
3630
|
+
// disregard the `foo` in `class {foo(){}}` but keep it in `class {[foo](){}}`
|
|
3631
|
+
case 'MethodDefinition':
|
|
3632
|
+
return parent.computed;
|
|
3633
|
+
|
|
3634
|
+
// disregard the `meta` in `import.meta`
|
|
3635
|
+
case 'MetaProperty':
|
|
3636
|
+
return parent.meta === node;
|
|
3637
|
+
|
|
3638
|
+
// disregard the `foo` in `class {foo=bar}` but keep it in `class {[foo]=bar}` and `class {bar=foo}`
|
|
3639
|
+
case 'PropertyDefinition':
|
|
3640
|
+
return parent.computed || node === parent.value;
|
|
3641
|
+
|
|
3642
|
+
// disregard the `bar` in `{ bar: foo }`, but keep it in `{ [bar]: foo }`
|
|
3643
|
+
case 'Property':
|
|
3644
|
+
return parent.computed || node === parent.value;
|
|
3645
|
+
|
|
3646
|
+
// disregard the `bar` in `export { foo as bar }` or
|
|
3647
|
+
// the foo in `import { foo as bar }`
|
|
3648
|
+
case 'ExportSpecifier':
|
|
3649
|
+
case 'ImportSpecifier':
|
|
3650
|
+
return node === parent.local;
|
|
3651
|
+
|
|
3652
|
+
// disregard the `foo` in `foo: while (...) { ... break foo; ... continue foo;}`
|
|
3653
|
+
case 'LabeledStatement':
|
|
3654
|
+
case 'BreakStatement':
|
|
3655
|
+
case 'ContinueStatement':
|
|
3656
|
+
return false;
|
|
3657
|
+
|
|
3658
|
+
default:
|
|
3659
|
+
return true;
|
|
3660
|
+
}
|
|
3661
|
+
}
|
|
3662
|
+
|
|
3663
|
+
function createInclusionContext() {
|
|
3664
|
+
return {
|
|
3665
|
+
brokenFlow: false,
|
|
3666
|
+
hasBreak: false,
|
|
3667
|
+
hasContinue: false,
|
|
3668
|
+
includedCallArguments: new Set(),
|
|
3669
|
+
includedLabels: new Set()
|
|
3670
|
+
};
|
|
3671
|
+
}
|
|
3672
|
+
function createHasEffectsContext() {
|
|
3673
|
+
return {
|
|
3674
|
+
accessed: new EntityPathTracker(),
|
|
3675
|
+
assigned: new EntityPathTracker(),
|
|
3676
|
+
brokenFlow: false,
|
|
3677
|
+
called: new DiscriminatedPathTracker(),
|
|
3678
|
+
hasBreak: false,
|
|
3679
|
+
hasContinue: false,
|
|
3680
|
+
ignore: {
|
|
3681
|
+
breaks: false,
|
|
3682
|
+
continues: false,
|
|
3683
|
+
labels: new Set(),
|
|
3684
|
+
returnYield: false,
|
|
3685
|
+
this: false
|
|
3686
|
+
},
|
|
3687
|
+
includedLabels: new Set(),
|
|
3688
|
+
instantiated: new DiscriminatedPathTracker(),
|
|
3689
|
+
replacedVariableInits: new Map()
|
|
3690
|
+
};
|
|
3691
|
+
}
|
|
3626
3692
|
|
|
3627
3693
|
function isFlagSet(flags, flag) {
|
|
3628
3694
|
return (flags & flag) !== 0;
|
|
@@ -3662,12 +3728,25 @@ class ExpressionEntity {
|
|
|
3662
3728
|
hasEffectsOnInteractionAtPath(_path, _interaction, _context) {
|
|
3663
3729
|
return true;
|
|
3664
3730
|
}
|
|
3665
|
-
include(
|
|
3731
|
+
include(context, _includeChildrenRecursively, _options) {
|
|
3732
|
+
if (!this.included)
|
|
3733
|
+
this.includeNode(context);
|
|
3734
|
+
}
|
|
3735
|
+
includeNode(_context) {
|
|
3666
3736
|
this.included = true;
|
|
3667
3737
|
}
|
|
3668
|
-
|
|
3669
|
-
|
|
3670
|
-
|
|
3738
|
+
includePath(_path, context) {
|
|
3739
|
+
if (!this.included)
|
|
3740
|
+
this.includeNode(context);
|
|
3741
|
+
}
|
|
3742
|
+
/* We are both including and including an unknown path here as the former
|
|
3743
|
+
* ensures that nested nodes are included while the latter ensures that all
|
|
3744
|
+
* paths of the expression are included.
|
|
3745
|
+
* */
|
|
3746
|
+
includeCallArguments(context, interaction) {
|
|
3747
|
+
for (const argument of interaction.args) {
|
|
3748
|
+
argument?.includePath(UNKNOWN_PATH, context);
|
|
3749
|
+
argument?.include(context, false);
|
|
3671
3750
|
}
|
|
3672
3751
|
}
|
|
3673
3752
|
shouldBeIncluded(_context) {
|
|
@@ -3706,6 +3785,19 @@ const NODE_INTERACTION_UNKNOWN_CALL = {
|
|
|
3706
3785
|
withNew: false
|
|
3707
3786
|
};
|
|
3708
3787
|
|
|
3788
|
+
const PureFunctionKey = Symbol('PureFunction');
|
|
3789
|
+
const getPureFunctions = ({ treeshake }) => {
|
|
3790
|
+
const pureFunctions = Object.create(null);
|
|
3791
|
+
for (const functionName of treeshake ? treeshake.manualPureFunctions : []) {
|
|
3792
|
+
let currentFunctions = pureFunctions;
|
|
3793
|
+
for (const pathSegment of functionName.split('.')) {
|
|
3794
|
+
currentFunctions = currentFunctions[pathSegment] ||= Object.create(null);
|
|
3795
|
+
}
|
|
3796
|
+
currentFunctions[PureFunctionKey] = true;
|
|
3797
|
+
}
|
|
3798
|
+
return pureFunctions;
|
|
3799
|
+
};
|
|
3800
|
+
|
|
3709
3801
|
class Variable extends ExpressionEntity {
|
|
3710
3802
|
markReassigned() {
|
|
3711
3803
|
this.isReassigned = true;
|
|
@@ -3782,9 +3874,9 @@ class Variable extends ExpressionEntity {
|
|
|
3782
3874
|
* has not been included previously. Once a variable is included, it should
|
|
3783
3875
|
* take care all its declarations are included.
|
|
3784
3876
|
*/
|
|
3785
|
-
|
|
3877
|
+
includePath(path, context) {
|
|
3786
3878
|
this.included = true;
|
|
3787
|
-
this.renderedLikeHoisted?.
|
|
3879
|
+
this.renderedLikeHoisted?.includePath(path, context);
|
|
3788
3880
|
}
|
|
3789
3881
|
/**
|
|
3790
3882
|
* Links the rendered name of this variable to another variable and includes
|
|
@@ -3816,8 +3908,8 @@ class ExternalVariable extends Variable {
|
|
|
3816
3908
|
hasEffectsOnInteractionAtPath(path, { type }) {
|
|
3817
3909
|
return type !== INTERACTION_ACCESSED || path.length > (this.isNamespace ? 1 : 0);
|
|
3818
3910
|
}
|
|
3819
|
-
|
|
3820
|
-
super.
|
|
3911
|
+
includePath(path, context) {
|
|
3912
|
+
super.includePath(path, context);
|
|
3821
3913
|
this.module.used = true;
|
|
3822
3914
|
}
|
|
3823
3915
|
}
|
|
@@ -4116,36 +4208,6 @@ const childNodeKeys = {
|
|
|
4116
4208
|
YieldExpression: ['argument']
|
|
4117
4209
|
};
|
|
4118
4210
|
|
|
4119
|
-
function createInclusionContext() {
|
|
4120
|
-
return {
|
|
4121
|
-
brokenFlow: false,
|
|
4122
|
-
hasBreak: false,
|
|
4123
|
-
hasContinue: false,
|
|
4124
|
-
includedCallArguments: new Set(),
|
|
4125
|
-
includedLabels: new Set()
|
|
4126
|
-
};
|
|
4127
|
-
}
|
|
4128
|
-
function createHasEffectsContext() {
|
|
4129
|
-
return {
|
|
4130
|
-
accessed: new PathTracker(),
|
|
4131
|
-
assigned: new PathTracker(),
|
|
4132
|
-
brokenFlow: false,
|
|
4133
|
-
called: new DiscriminatedPathTracker(),
|
|
4134
|
-
hasBreak: false,
|
|
4135
|
-
hasContinue: false,
|
|
4136
|
-
ignore: {
|
|
4137
|
-
breaks: false,
|
|
4138
|
-
continues: false,
|
|
4139
|
-
labels: new Set(),
|
|
4140
|
-
returnYield: false,
|
|
4141
|
-
this: false
|
|
4142
|
-
},
|
|
4143
|
-
includedLabels: new Set(),
|
|
4144
|
-
instantiated: new DiscriminatedPathTracker(),
|
|
4145
|
-
replacedVariableInits: new Map()
|
|
4146
|
-
};
|
|
4147
|
-
}
|
|
4148
|
-
|
|
4149
4211
|
const INCLUDE_PARAMETERS = 'variables';
|
|
4150
4212
|
const IS_SKIPPED_CHAIN = Symbol('IS_SKIPPED_CHAIN');
|
|
4151
4213
|
class NodeBase extends ExpressionEntity {
|
|
@@ -4215,9 +4277,8 @@ class NodeBase extends ExpressionEntity {
|
|
|
4215
4277
|
this.hasEffectsOnInteractionAtPath(EMPTY_PATH, this.assignmentInteraction, context));
|
|
4216
4278
|
}
|
|
4217
4279
|
include(context, includeChildrenRecursively, _options) {
|
|
4218
|
-
if (!this.
|
|
4219
|
-
this.
|
|
4220
|
-
this.included = true;
|
|
4280
|
+
if (!this.included)
|
|
4281
|
+
this.includeNode(context);
|
|
4221
4282
|
for (const key of childNodeKeys[this.type]) {
|
|
4222
4283
|
const value = this[key];
|
|
4223
4284
|
if (value === null)
|
|
@@ -4232,6 +4293,24 @@ class NodeBase extends ExpressionEntity {
|
|
|
4232
4293
|
}
|
|
4233
4294
|
}
|
|
4234
4295
|
}
|
|
4296
|
+
includeNode(context) {
|
|
4297
|
+
this.included = true;
|
|
4298
|
+
if (!this.deoptimized)
|
|
4299
|
+
this.applyDeoptimizations();
|
|
4300
|
+
for (const key of childNodeKeys[this.type]) {
|
|
4301
|
+
const value = this[key];
|
|
4302
|
+
if (value === null)
|
|
4303
|
+
continue;
|
|
4304
|
+
if (Array.isArray(value)) {
|
|
4305
|
+
for (const child of value) {
|
|
4306
|
+
child?.includePath(UNKNOWN_PATH, context);
|
|
4307
|
+
}
|
|
4308
|
+
}
|
|
4309
|
+
else {
|
|
4310
|
+
value.includePath(UNKNOWN_PATH, context);
|
|
4311
|
+
}
|
|
4312
|
+
}
|
|
4313
|
+
}
|
|
4235
4314
|
includeAsAssignmentTarget(context, includeChildrenRecursively, _deoptimizeAccess) {
|
|
4236
4315
|
this.include(context, includeChildrenRecursively);
|
|
4237
4316
|
}
|
|
@@ -4335,6 +4414,17 @@ class NodeBase extends ExpressionEntity {
|
|
|
4335
4414
|
function createChildNodeKeysForNode(esTreeNode) {
|
|
4336
4415
|
return Object.keys(esTreeNode).filter(key => typeof esTreeNode[key] === 'object' && key.charCodeAt(0) !== 95 /* _ */);
|
|
4337
4416
|
}
|
|
4417
|
+
function onlyIncludeSelf() {
|
|
4418
|
+
this.included = true;
|
|
4419
|
+
if (!this.deoptimized)
|
|
4420
|
+
this.applyDeoptimizations();
|
|
4421
|
+
}
|
|
4422
|
+
function onlyIncludeSelfNoDeoptimize() {
|
|
4423
|
+
this.included = true;
|
|
4424
|
+
}
|
|
4425
|
+
function doNotDeoptimize() {
|
|
4426
|
+
this.deoptimized = true;
|
|
4427
|
+
}
|
|
4338
4428
|
|
|
4339
4429
|
function isObjectExpressionNode(node) {
|
|
4340
4430
|
return node instanceof NodeBase && node.type === parseAst_js.ObjectExpression;
|
|
@@ -4347,8 +4437,8 @@ function assembleMemberDescriptions(memberDescriptions, inheritedDescriptions =
|
|
|
4347
4437
|
return Object.create(inheritedDescriptions, memberDescriptions);
|
|
4348
4438
|
}
|
|
4349
4439
|
const UNDEFINED_EXPRESSION = new (class UndefinedExpression extends ExpressionEntity {
|
|
4350
|
-
getLiteralValueAtPath() {
|
|
4351
|
-
return undefined;
|
|
4440
|
+
getLiteralValueAtPath(path) {
|
|
4441
|
+
return path.length > 0 ? UnknownValue : undefined;
|
|
4352
4442
|
}
|
|
4353
4443
|
})();
|
|
4354
4444
|
const returnsUnknown = {
|
|
@@ -4545,31 +4635,6 @@ function getMemberReturnExpressionWhenCalled(members, memberName) {
|
|
|
4545
4635
|
return [members[memberName].returns, false];
|
|
4546
4636
|
}
|
|
4547
4637
|
|
|
4548
|
-
class SpreadElement extends NodeBase {
|
|
4549
|
-
deoptimizeArgumentsOnInteractionAtPath(interaction, path, recursionTracker) {
|
|
4550
|
-
if (path.length > 0) {
|
|
4551
|
-
this.argument.deoptimizeArgumentsOnInteractionAtPath(interaction, UNKNOWN_PATH, recursionTracker);
|
|
4552
|
-
}
|
|
4553
|
-
}
|
|
4554
|
-
hasEffects(context) {
|
|
4555
|
-
if (!this.deoptimized)
|
|
4556
|
-
this.applyDeoptimizations();
|
|
4557
|
-
const { propertyReadSideEffects } = this.scope.context.options
|
|
4558
|
-
.treeshake;
|
|
4559
|
-
return (this.argument.hasEffects(context) ||
|
|
4560
|
-
(propertyReadSideEffects &&
|
|
4561
|
-
(propertyReadSideEffects === 'always' ||
|
|
4562
|
-
this.argument.hasEffectsOnInteractionAtPath(UNKNOWN_PATH, NODE_INTERACTION_UNKNOWN_ACCESS, context))));
|
|
4563
|
-
}
|
|
4564
|
-
applyDeoptimizations() {
|
|
4565
|
-
this.deoptimized = true;
|
|
4566
|
-
// Only properties of properties of the argument could become subject to reassignment
|
|
4567
|
-
// This will also reassign the return values of iterators
|
|
4568
|
-
this.argument.deoptimizePath([UnknownKey, UnknownKey]);
|
|
4569
|
-
this.scope.context.requestTreeshakingPass();
|
|
4570
|
-
}
|
|
4571
|
-
}
|
|
4572
|
-
|
|
4573
4638
|
class Method extends ExpressionEntity {
|
|
4574
4639
|
constructor(description) {
|
|
4575
4640
|
super();
|
|
@@ -4695,6 +4760,7 @@ class ObjectEntity extends ExpressionEntity {
|
|
|
4695
4760
|
this.unknownIntegerProps = [];
|
|
4696
4761
|
this.unmatchableGetters = [];
|
|
4697
4762
|
this.unmatchablePropertiesAndGetters = [];
|
|
4763
|
+
this.unmatchablePropertiesAndSetters = [];
|
|
4698
4764
|
this.unmatchableSetters = [];
|
|
4699
4765
|
if (Array.isArray(properties)) {
|
|
4700
4766
|
this.buildPropertyMaps(properties);
|
|
@@ -4851,7 +4917,12 @@ class ObjectEntity extends ExpressionEntity {
|
|
|
4851
4917
|
}
|
|
4852
4918
|
getLiteralValueAtPath(path, recursionTracker, origin) {
|
|
4853
4919
|
if (path.length === 0) {
|
|
4854
|
-
|
|
4920
|
+
// This should actually be "UnknownTruthyValue". However, this currently
|
|
4921
|
+
// causes an issue with TypeScript enums in files with moduleSideEffects:
|
|
4922
|
+
// false because we cannot properly track whether a "var" has been
|
|
4923
|
+
// initialized. This should be reverted once we can properly track this.
|
|
4924
|
+
// return UnknownTruthyValue;
|
|
4925
|
+
return UnknownValue;
|
|
4855
4926
|
}
|
|
4856
4927
|
const key = path[0];
|
|
4857
4928
|
const expressionAtPath = this.getMemberExpressionAndTrackDeopt(key, origin);
|
|
@@ -4929,9 +5000,38 @@ class ObjectEntity extends ExpressionEntity {
|
|
|
4929
5000
|
}
|
|
4930
5001
|
return false;
|
|
4931
5002
|
}
|
|
5003
|
+
include(context, includeChildrenRecursively) {
|
|
5004
|
+
this.included = true;
|
|
5005
|
+
for (const property of this.allProperties) {
|
|
5006
|
+
if (includeChildrenRecursively || property.shouldBeIncluded(context)) {
|
|
5007
|
+
property.include(context, includeChildrenRecursively);
|
|
5008
|
+
}
|
|
5009
|
+
}
|
|
5010
|
+
this.prototypeExpression?.include(context, includeChildrenRecursively);
|
|
5011
|
+
}
|
|
5012
|
+
includePath(path, context) {
|
|
5013
|
+
this.included = true;
|
|
5014
|
+
if (path.length === 0)
|
|
5015
|
+
return;
|
|
5016
|
+
const [key, ...subPath] = path;
|
|
5017
|
+
const [includedMembers, includedPath] = typeof key === 'string'
|
|
5018
|
+
? [
|
|
5019
|
+
[
|
|
5020
|
+
...new Set([
|
|
5021
|
+
...(this.propertiesAndGettersByKey[key] || this.unmatchablePropertiesAndGetters),
|
|
5022
|
+
...(this.propertiesAndSettersByKey[key] || this.unmatchablePropertiesAndSetters)
|
|
5023
|
+
])
|
|
5024
|
+
],
|
|
5025
|
+
subPath
|
|
5026
|
+
]
|
|
5027
|
+
: [this.allProperties, UNKNOWN_PATH];
|
|
5028
|
+
for (const property of includedMembers) {
|
|
5029
|
+
property.includePath(includedPath, context);
|
|
5030
|
+
}
|
|
5031
|
+
this.prototypeExpression?.includePath(path, context);
|
|
5032
|
+
}
|
|
4932
5033
|
buildPropertyMaps(properties) {
|
|
4933
|
-
const { allProperties, propertiesAndGettersByKey, propertiesAndSettersByKey, settersByKey, gettersByKey, unknownIntegerProps, unmatchablePropertiesAndGetters, unmatchableGetters, unmatchableSetters } = this;
|
|
4934
|
-
const unmatchablePropertiesAndSetters = [];
|
|
5034
|
+
const { allProperties, propertiesAndGettersByKey, propertiesAndSettersByKey, settersByKey, gettersByKey, unknownIntegerProps, unmatchablePropertiesAndGetters, unmatchablePropertiesAndSetters, unmatchableGetters, unmatchableSetters } = this;
|
|
4935
5035
|
for (let index = properties.length - 1; index >= 0; index--) {
|
|
4936
5036
|
const { key, kind, property } = properties[index];
|
|
4937
5037
|
allProperties.push(property);
|
|
@@ -5201,6 +5301,37 @@ const ARRAY_PROTOTYPE = new ObjectEntity({
|
|
|
5201
5301
|
values: METHOD_DEOPTS_SELF_RETURNS_UNKNOWN
|
|
5202
5302
|
}, OBJECT_PROTOTYPE, true);
|
|
5203
5303
|
|
|
5304
|
+
class SpreadElement extends NodeBase {
|
|
5305
|
+
deoptimizeArgumentsOnInteractionAtPath(interaction, path, recursionTracker) {
|
|
5306
|
+
if (path.length > 0) {
|
|
5307
|
+
this.argument.deoptimizeArgumentsOnInteractionAtPath(interaction, UNKNOWN_PATH, recursionTracker);
|
|
5308
|
+
}
|
|
5309
|
+
}
|
|
5310
|
+
hasEffects(context) {
|
|
5311
|
+
if (!this.deoptimized)
|
|
5312
|
+
this.applyDeoptimizations();
|
|
5313
|
+
const { propertyReadSideEffects } = this.scope.context.options
|
|
5314
|
+
.treeshake;
|
|
5315
|
+
return (this.argument.hasEffects(context) ||
|
|
5316
|
+
(propertyReadSideEffects &&
|
|
5317
|
+
(propertyReadSideEffects === 'always' ||
|
|
5318
|
+
this.argument.hasEffectsOnInteractionAtPath(UNKNOWN_PATH, NODE_INTERACTION_UNKNOWN_ACCESS, context))));
|
|
5319
|
+
}
|
|
5320
|
+
includeNode(context) {
|
|
5321
|
+
this.included = true;
|
|
5322
|
+
if (!this.deoptimized)
|
|
5323
|
+
this.applyDeoptimizations();
|
|
5324
|
+
this.argument.includePath(UNKNOWN_PATH, context);
|
|
5325
|
+
}
|
|
5326
|
+
applyDeoptimizations() {
|
|
5327
|
+
this.deoptimized = true;
|
|
5328
|
+
// Only properties of properties of the argument could become subject to reassignment
|
|
5329
|
+
// This will also reassign the return values of iterators
|
|
5330
|
+
this.argument.deoptimizePath([UnknownKey, UnknownKey]);
|
|
5331
|
+
this.scope.context.requestTreeshakingPass();
|
|
5332
|
+
}
|
|
5333
|
+
}
|
|
5334
|
+
|
|
5204
5335
|
class ArrayExpression extends NodeBase {
|
|
5205
5336
|
constructor() {
|
|
5206
5337
|
super(...arguments);
|
|
@@ -5221,6 +5352,16 @@ class ArrayExpression extends NodeBase {
|
|
|
5221
5352
|
hasEffectsOnInteractionAtPath(path, interaction, context) {
|
|
5222
5353
|
return this.getObjectEntity().hasEffectsOnInteractionAtPath(path, interaction, context);
|
|
5223
5354
|
}
|
|
5355
|
+
includeNode(context) {
|
|
5356
|
+
this.included = true;
|
|
5357
|
+
if (!this.deoptimized)
|
|
5358
|
+
this.applyDeoptimizations();
|
|
5359
|
+
for (const element of this.elements) {
|
|
5360
|
+
if (element) {
|
|
5361
|
+
element?.includePath(UNKNOWN_PATH, context);
|
|
5362
|
+
}
|
|
5363
|
+
}
|
|
5364
|
+
}
|
|
5224
5365
|
applyDeoptimizations() {
|
|
5225
5366
|
this.deoptimized = true;
|
|
5226
5367
|
let hasSpread = false;
|
|
@@ -6288,17 +6429,37 @@ class GlobalVariable extends Variable {
|
|
|
6288
6429
|
}
|
|
6289
6430
|
}
|
|
6290
6431
|
|
|
6432
|
+
// To avoid infinite recursions
|
|
6433
|
+
const MAX_PATH_DEPTH = 6;
|
|
6434
|
+
// If a path is longer than MAX_PATH_DEPTH, it is truncated so that it is at
|
|
6435
|
+
// most MAX_PATH_DEPTH long. The last element is always UnknownKey
|
|
6436
|
+
const limitConcatenatedPathDepth = (path1, path2) => {
|
|
6437
|
+
const { length: length1 } = path1;
|
|
6438
|
+
const { length: length2 } = path2;
|
|
6439
|
+
return length1 === 0
|
|
6440
|
+
? path2
|
|
6441
|
+
: length2 === 0
|
|
6442
|
+
? path1
|
|
6443
|
+
: length1 + length2 > MAX_PATH_DEPTH
|
|
6444
|
+
? [...path1, ...path2.slice(0, MAX_PATH_DEPTH - 1 - path1.length), 'UnknownKey']
|
|
6445
|
+
: [...path1, ...path2];
|
|
6446
|
+
};
|
|
6447
|
+
|
|
6291
6448
|
class LocalVariable extends Variable {
|
|
6292
|
-
constructor(name, declarator, init,
|
|
6449
|
+
constructor(name, declarator, init,
|
|
6450
|
+
/** if this is non-empty, the actual init is this path of this.init */
|
|
6451
|
+
initPath, context, kind) {
|
|
6293
6452
|
super(name);
|
|
6294
6453
|
this.init = init;
|
|
6454
|
+
this.initPath = initPath;
|
|
6455
|
+
this.kind = kind;
|
|
6295
6456
|
this.calledFromTryStatement = false;
|
|
6296
6457
|
this.additionalInitializers = null;
|
|
6458
|
+
this.includedPathTracker = new IncludedPathTracker();
|
|
6297
6459
|
this.expressionsToBeDeoptimized = [];
|
|
6298
6460
|
this.declarations = declarator ? [declarator] : [];
|
|
6299
6461
|
this.deoptimizationTracker = context.deoptimizationTracker;
|
|
6300
6462
|
this.module = context.module;
|
|
6301
|
-
this.kind = kind;
|
|
6302
6463
|
}
|
|
6303
6464
|
addDeclaration(identifier, init) {
|
|
6304
6465
|
this.declarations.push(identifier);
|
|
@@ -6309,15 +6470,16 @@ class LocalVariable extends Variable {
|
|
|
6309
6470
|
for (const initializer of this.additionalInitializers) {
|
|
6310
6471
|
initializer.deoptimizePath(UNKNOWN_PATH);
|
|
6311
6472
|
}
|
|
6312
|
-
this.additionalInitializers = null;
|
|
6313
6473
|
}
|
|
6314
6474
|
}
|
|
6315
6475
|
deoptimizeArgumentsOnInteractionAtPath(interaction, path, recursionTracker) {
|
|
6316
|
-
if (this.isReassigned) {
|
|
6476
|
+
if (this.isReassigned || path.length + this.initPath.length > MAX_PATH_DEPTH) {
|
|
6317
6477
|
deoptimizeInteraction(interaction);
|
|
6318
6478
|
return;
|
|
6319
6479
|
}
|
|
6320
|
-
recursionTracker.withTrackedEntityAtPath(path, this.init, () =>
|
|
6480
|
+
recursionTracker.withTrackedEntityAtPath(path, this.init, () => {
|
|
6481
|
+
this.init.deoptimizeArgumentsOnInteractionAtPath(interaction, [...this.initPath, ...path], recursionTracker);
|
|
6482
|
+
}, undefined);
|
|
6321
6483
|
}
|
|
6322
6484
|
deoptimizePath(path) {
|
|
6323
6485
|
if (this.isReassigned ||
|
|
@@ -6331,37 +6493,40 @@ class LocalVariable extends Variable {
|
|
|
6331
6493
|
for (const expression of expressionsToBeDeoptimized) {
|
|
6332
6494
|
expression.deoptimizeCache();
|
|
6333
6495
|
}
|
|
6334
|
-
this.init.deoptimizePath(
|
|
6496
|
+
this.init.deoptimizePath([...this.initPath, UnknownKey]);
|
|
6335
6497
|
}
|
|
6336
6498
|
else {
|
|
6337
|
-
this.init.deoptimizePath(path);
|
|
6499
|
+
this.init.deoptimizePath(limitConcatenatedPathDepth(this.initPath, path));
|
|
6338
6500
|
}
|
|
6339
6501
|
}
|
|
6340
6502
|
getLiteralValueAtPath(path, recursionTracker, origin) {
|
|
6341
|
-
if (this.isReassigned) {
|
|
6503
|
+
if (this.isReassigned || path.length + this.initPath.length > MAX_PATH_DEPTH) {
|
|
6342
6504
|
return UnknownValue;
|
|
6343
6505
|
}
|
|
6344
6506
|
return recursionTracker.withTrackedEntityAtPath(path, this.init, () => {
|
|
6345
6507
|
this.expressionsToBeDeoptimized.push(origin);
|
|
6346
|
-
return this.init.getLiteralValueAtPath(path, recursionTracker, origin);
|
|
6508
|
+
return this.init.getLiteralValueAtPath([...this.initPath, ...path], recursionTracker, origin);
|
|
6347
6509
|
}, UnknownValue);
|
|
6348
6510
|
}
|
|
6349
6511
|
getReturnExpressionWhenCalledAtPath(path, interaction, recursionTracker, origin) {
|
|
6350
|
-
if (this.isReassigned) {
|
|
6512
|
+
if (this.isReassigned || path.length + this.initPath.length > MAX_PATH_DEPTH) {
|
|
6351
6513
|
return UNKNOWN_RETURN_EXPRESSION;
|
|
6352
6514
|
}
|
|
6353
6515
|
return recursionTracker.withTrackedEntityAtPath(path, this.init, () => {
|
|
6354
6516
|
this.expressionsToBeDeoptimized.push(origin);
|
|
6355
|
-
return this.init.getReturnExpressionWhenCalledAtPath(path, interaction, recursionTracker, origin);
|
|
6517
|
+
return this.init.getReturnExpressionWhenCalledAtPath([...this.initPath, ...path], interaction, recursionTracker, origin);
|
|
6356
6518
|
}, UNKNOWN_RETURN_EXPRESSION);
|
|
6357
6519
|
}
|
|
6358
6520
|
hasEffectsOnInteractionAtPath(path, interaction, context) {
|
|
6521
|
+
if (path.length + this.initPath.length > MAX_PATH_DEPTH) {
|
|
6522
|
+
return true;
|
|
6523
|
+
}
|
|
6359
6524
|
switch (interaction.type) {
|
|
6360
6525
|
case INTERACTION_ACCESSED: {
|
|
6361
6526
|
if (this.isReassigned)
|
|
6362
6527
|
return true;
|
|
6363
6528
|
return (!context.accessed.trackEntityAtPathAndGetIfTracked(path, this) &&
|
|
6364
|
-
this.init.hasEffectsOnInteractionAtPath(path, interaction, context));
|
|
6529
|
+
this.init.hasEffectsOnInteractionAtPath([...this.initPath, ...path], interaction, context));
|
|
6365
6530
|
}
|
|
6366
6531
|
case INTERACTION_ASSIGNED: {
|
|
6367
6532
|
if (this.included)
|
|
@@ -6371,44 +6536,63 @@ class LocalVariable extends Variable {
|
|
|
6371
6536
|
if (this.isReassigned)
|
|
6372
6537
|
return true;
|
|
6373
6538
|
return (!context.assigned.trackEntityAtPathAndGetIfTracked(path, this) &&
|
|
6374
|
-
this.init.hasEffectsOnInteractionAtPath(path, interaction, context));
|
|
6539
|
+
this.init.hasEffectsOnInteractionAtPath([...this.initPath, ...path], interaction, context));
|
|
6375
6540
|
}
|
|
6376
6541
|
case INTERACTION_CALLED: {
|
|
6377
6542
|
if (this.isReassigned)
|
|
6378
6543
|
return true;
|
|
6379
6544
|
return (!(interaction.withNew ? context.instantiated : context.called).trackEntityAtPathAndGetIfTracked(path, interaction.args, this) &&
|
|
6380
|
-
this.init.hasEffectsOnInteractionAtPath(path, interaction, context));
|
|
6545
|
+
this.init.hasEffectsOnInteractionAtPath([...this.initPath, ...path], interaction, context));
|
|
6381
6546
|
}
|
|
6382
6547
|
}
|
|
6383
6548
|
}
|
|
6384
|
-
|
|
6385
|
-
if (!this.
|
|
6386
|
-
|
|
6549
|
+
includePath(path, context) {
|
|
6550
|
+
if (!this.includedPathTracker.includePathAndGetIfIncluded(path)) {
|
|
6551
|
+
this.module.scope.context.requestTreeshakingPass();
|
|
6552
|
+
if (!this.included) {
|
|
6553
|
+
// This will reduce the number of tree-shaking passes by eagerly
|
|
6554
|
+
// including inits. By pushing this here instead of directly including
|
|
6555
|
+
// we avoid deep call stacks.
|
|
6556
|
+
this.module.scope.context.newlyIncludedVariableInits.add(this.init);
|
|
6557
|
+
}
|
|
6558
|
+
super.includePath(path, context);
|
|
6387
6559
|
for (const declaration of this.declarations) {
|
|
6388
6560
|
// If node is a default export, it can save a tree-shaking run to include the full declaration now
|
|
6389
6561
|
if (!declaration.included)
|
|
6390
|
-
declaration.include(
|
|
6562
|
+
declaration.include(context, false);
|
|
6391
6563
|
let node = declaration.parent;
|
|
6392
6564
|
while (!node.included) {
|
|
6393
6565
|
// We do not want to properly include parents in case they are part of a dead branch
|
|
6394
6566
|
// in which case .include() might pull in more dead code
|
|
6395
|
-
node.
|
|
6567
|
+
node.includeNode(context);
|
|
6396
6568
|
if (node.type === parseAst_js.Program)
|
|
6397
6569
|
break;
|
|
6398
6570
|
node = node.parent;
|
|
6399
6571
|
}
|
|
6400
6572
|
}
|
|
6573
|
+
// We need to make sure we include the correct path of the init
|
|
6574
|
+
if (path.length > 0) {
|
|
6575
|
+
this.init.includePath(limitConcatenatedPathDepth(this.initPath, path), context);
|
|
6576
|
+
this.additionalInitializers?.forEach(initializer => initializer.includePath(UNKNOWN_PATH, context));
|
|
6577
|
+
}
|
|
6401
6578
|
}
|
|
6402
6579
|
}
|
|
6403
|
-
includeCallArguments(context,
|
|
6404
|
-
if (this.isReassigned ||
|
|
6405
|
-
|
|
6406
|
-
|
|
6580
|
+
includeCallArguments(context, interaction) {
|
|
6581
|
+
if (this.isReassigned ||
|
|
6582
|
+
context.includedCallArguments.has(this.init) ||
|
|
6583
|
+
// This can be removed again once we can include arguments when called at
|
|
6584
|
+
// a specific path
|
|
6585
|
+
this.initPath.length > 0) {
|
|
6586
|
+
for (const argument of interaction.args) {
|
|
6587
|
+
if (argument) {
|
|
6588
|
+
argument.includePath(UNKNOWN_PATH, context);
|
|
6589
|
+
argument.include(context, false);
|
|
6590
|
+
}
|
|
6407
6591
|
}
|
|
6408
6592
|
}
|
|
6409
6593
|
else {
|
|
6410
6594
|
context.includedCallArguments.add(this.init);
|
|
6411
|
-
this.init.includeCallArguments(context,
|
|
6595
|
+
this.init.includeCallArguments(context, interaction);
|
|
6412
6596
|
context.includedCallArguments.delete(this.init);
|
|
6413
6597
|
}
|
|
6414
6598
|
}
|
|
@@ -6488,18 +6672,31 @@ class IdentifierBase extends NodeBase {
|
|
|
6488
6672
|
}
|
|
6489
6673
|
}
|
|
6490
6674
|
}
|
|
6491
|
-
include() {
|
|
6675
|
+
include(context) {
|
|
6676
|
+
if (!this.included)
|
|
6677
|
+
this.includeNode(context);
|
|
6678
|
+
}
|
|
6679
|
+
includeNode(context) {
|
|
6680
|
+
this.included = true;
|
|
6492
6681
|
if (!this.deoptimized)
|
|
6493
6682
|
this.applyDeoptimizations();
|
|
6683
|
+
if (this.variable !== null) {
|
|
6684
|
+
this.scope.context.includeVariableInModule(this.variable, EMPTY_PATH, context);
|
|
6685
|
+
}
|
|
6686
|
+
}
|
|
6687
|
+
includePath(path, context) {
|
|
6494
6688
|
if (!this.included) {
|
|
6495
6689
|
this.included = true;
|
|
6496
6690
|
if (this.variable !== null) {
|
|
6497
|
-
this.scope.context.includeVariableInModule(this.variable);
|
|
6691
|
+
this.scope.context.includeVariableInModule(this.variable, path, context);
|
|
6498
6692
|
}
|
|
6499
6693
|
}
|
|
6694
|
+
else if (path.length > 0) {
|
|
6695
|
+
this.variable?.includePath(path, context);
|
|
6696
|
+
}
|
|
6500
6697
|
}
|
|
6501
|
-
includeCallArguments(context,
|
|
6502
|
-
this.variable.includeCallArguments(context,
|
|
6698
|
+
includeCallArguments(context, interaction) {
|
|
6699
|
+
this.variable.includeCallArguments(context, interaction);
|
|
6503
6700
|
}
|
|
6504
6701
|
isPossibleTDZ() {
|
|
6505
6702
|
// return cached value to avoid issues with the next tree-shaking pass
|
|
@@ -6582,11 +6779,40 @@ function closestParentFunctionOrProgram(node) {
|
|
|
6582
6779
|
return node;
|
|
6583
6780
|
}
|
|
6584
6781
|
|
|
6782
|
+
class ObjectMember extends ExpressionEntity {
|
|
6783
|
+
constructor(object, path) {
|
|
6784
|
+
super();
|
|
6785
|
+
this.object = object;
|
|
6786
|
+
this.path = path;
|
|
6787
|
+
}
|
|
6788
|
+
deoptimizeArgumentsOnInteractionAtPath(interaction, path, recursionTracker) {
|
|
6789
|
+
this.object.deoptimizeArgumentsOnInteractionAtPath(interaction, [...this.path, ...path], recursionTracker);
|
|
6790
|
+
}
|
|
6791
|
+
deoptimizePath(path) {
|
|
6792
|
+
this.object.deoptimizePath([...this.path, ...path]);
|
|
6793
|
+
}
|
|
6794
|
+
getLiteralValueAtPath(path, recursionTracker, origin) {
|
|
6795
|
+
return this.object.getLiteralValueAtPath([...this.path, ...path], recursionTracker, origin);
|
|
6796
|
+
}
|
|
6797
|
+
getReturnExpressionWhenCalledAtPath(path, interaction, recursionTracker, origin) {
|
|
6798
|
+
return this.object.getReturnExpressionWhenCalledAtPath([...this.path, ...path], interaction, recursionTracker, origin);
|
|
6799
|
+
}
|
|
6800
|
+
hasEffectsOnInteractionAtPath(path, interaction, context) {
|
|
6801
|
+
return this.object.hasEffectsOnInteractionAtPath([...this.path, ...path], interaction, context);
|
|
6802
|
+
}
|
|
6803
|
+
}
|
|
6804
|
+
|
|
6585
6805
|
class Identifier extends IdentifierBase {
|
|
6586
6806
|
constructor() {
|
|
6587
6807
|
super(...arguments);
|
|
6588
6808
|
this.variable = null;
|
|
6589
6809
|
}
|
|
6810
|
+
get isDestructuringDeoptimized() {
|
|
6811
|
+
return isFlagSet(this.flags, 16777216 /* Flag.destructuringDeoptimized */);
|
|
6812
|
+
}
|
|
6813
|
+
set isDestructuringDeoptimized(value) {
|
|
6814
|
+
this.flags = setFlag(this.flags, 16777216 /* Flag.destructuringDeoptimized */, value);
|
|
6815
|
+
}
|
|
6590
6816
|
addExportedVariables(variables, exportNamesByVariable) {
|
|
6591
6817
|
if (exportNamesByVariable.has(this.variable)) {
|
|
6592
6818
|
variables.push(this.variable);
|
|
@@ -6599,43 +6825,53 @@ class Identifier extends IdentifierBase {
|
|
|
6599
6825
|
this.isVariableReference = true;
|
|
6600
6826
|
}
|
|
6601
6827
|
}
|
|
6602
|
-
declare(kind, init) {
|
|
6603
|
-
let variable;
|
|
6604
|
-
const { treeshake } = this.scope.context.options;
|
|
6605
|
-
|
|
6606
|
-
|
|
6607
|
-
|
|
6608
|
-
|
|
6609
|
-
|
|
6610
|
-
|
|
6611
|
-
|
|
6612
|
-
|
|
6613
|
-
}
|
|
6614
|
-
case 'function': {
|
|
6615
|
-
// in strict mode, functions are only hoisted within a scope but not across block scopes
|
|
6616
|
-
variable = this.scope.addDeclaration(this, this.scope.context, init, kind);
|
|
6617
|
-
break;
|
|
6618
|
-
}
|
|
6619
|
-
case 'let':
|
|
6620
|
-
case 'const':
|
|
6621
|
-
case 'using':
|
|
6622
|
-
case 'await using':
|
|
6623
|
-
case 'class': {
|
|
6624
|
-
variable = this.scope.addDeclaration(this, this.scope.context, init, kind);
|
|
6625
|
-
break;
|
|
6626
|
-
}
|
|
6627
|
-
case 'parameter': {
|
|
6628
|
-
variable = this.scope.addParameterDeclaration(this);
|
|
6629
|
-
break;
|
|
6630
|
-
}
|
|
6631
|
-
/* istanbul ignore next */
|
|
6632
|
-
default: {
|
|
6633
|
-
/* istanbul ignore next */
|
|
6634
|
-
throw new Error(`Internal Error: Unexpected identifier kind ${kind}.`);
|
|
6828
|
+
declare(kind, destructuredInitPath, init) {
|
|
6829
|
+
let variable;
|
|
6830
|
+
const { treeshake } = this.scope.context.options;
|
|
6831
|
+
if (kind === 'parameter') {
|
|
6832
|
+
variable = this.scope.addParameterDeclaration(this, destructuredInitPath);
|
|
6833
|
+
}
|
|
6834
|
+
else {
|
|
6835
|
+
variable = this.scope.addDeclaration(this, this.scope.context, init, destructuredInitPath, kind);
|
|
6836
|
+
if (kind === 'var' && treeshake && treeshake.correctVarValueBeforeDeclaration) {
|
|
6837
|
+
// Necessary to make sure the init is deoptimized. We cannot call deoptimizePath here.
|
|
6838
|
+
variable.markInitializersForDeoptimization();
|
|
6635
6839
|
}
|
|
6636
6840
|
}
|
|
6637
6841
|
return [(this.variable = variable)];
|
|
6638
6842
|
}
|
|
6843
|
+
deoptimizeAssignment(destructuredInitPath, init) {
|
|
6844
|
+
this.deoptimizePath(EMPTY_PATH);
|
|
6845
|
+
init.deoptimizePath([...destructuredInitPath, UnknownKey]);
|
|
6846
|
+
}
|
|
6847
|
+
hasEffectsWhenDestructuring(context, destructuredInitPath, init) {
|
|
6848
|
+
return (destructuredInitPath.length > 0 &&
|
|
6849
|
+
init.hasEffectsOnInteractionAtPath(destructuredInitPath, NODE_INTERACTION_UNKNOWN_ACCESS, context));
|
|
6850
|
+
}
|
|
6851
|
+
includeDestructuredIfNecessary(context, destructuredInitPath, init) {
|
|
6852
|
+
if (destructuredInitPath.length > 0 && !this.isDestructuringDeoptimized) {
|
|
6853
|
+
this.isDestructuringDeoptimized = true;
|
|
6854
|
+
init.deoptimizeArgumentsOnInteractionAtPath({
|
|
6855
|
+
args: [new ObjectMember(init, destructuredInitPath.slice(0, -1))],
|
|
6856
|
+
type: INTERACTION_ACCESSED
|
|
6857
|
+
}, destructuredInitPath, SHARED_RECURSION_TRACKER);
|
|
6858
|
+
}
|
|
6859
|
+
const { propertyReadSideEffects } = this.scope.context.options
|
|
6860
|
+
.treeshake;
|
|
6861
|
+
if ((this.included ||=
|
|
6862
|
+
destructuredInitPath.length > 0 &&
|
|
6863
|
+
!context.brokenFlow &&
|
|
6864
|
+
propertyReadSideEffects &&
|
|
6865
|
+
(propertyReadSideEffects === 'always' ||
|
|
6866
|
+
init.hasEffectsOnInteractionAtPath(destructuredInitPath, NODE_INTERACTION_UNKNOWN_ACCESS, createHasEffectsContext())))) {
|
|
6867
|
+
if (this.variable && !this.variable.included) {
|
|
6868
|
+
this.scope.context.includeVariableInModule(this.variable, EMPTY_PATH, context);
|
|
6869
|
+
}
|
|
6870
|
+
init.includePath(destructuredInitPath, context);
|
|
6871
|
+
return true;
|
|
6872
|
+
}
|
|
6873
|
+
return false;
|
|
6874
|
+
}
|
|
6639
6875
|
markDeclarationReached() {
|
|
6640
6876
|
this.variable.initReached = true;
|
|
6641
6877
|
}
|
|
@@ -6688,18 +6924,17 @@ class Scope {
|
|
|
6688
6924
|
- then the variable is still declared in the hoisted outer scope, but the initializer is assigned to the parameter
|
|
6689
6925
|
- const, let, class, and function except in the cases above cannot redeclare anything
|
|
6690
6926
|
*/
|
|
6691
|
-
addDeclaration(identifier, context, init, kind) {
|
|
6927
|
+
addDeclaration(identifier, context, init, destructuredInitPath, kind) {
|
|
6692
6928
|
const name = identifier.name;
|
|
6693
6929
|
const existingVariable = this.hoistedVariables?.get(name) || this.variables.get(name);
|
|
6694
6930
|
if (existingVariable) {
|
|
6695
|
-
|
|
6696
|
-
if (kind === 'var' && existingKind === 'var') {
|
|
6931
|
+
if (kind === 'var' && existingVariable.kind === 'var') {
|
|
6697
6932
|
existingVariable.addDeclaration(identifier, init);
|
|
6698
6933
|
return existingVariable;
|
|
6699
6934
|
}
|
|
6700
6935
|
context.error(parseAst_js.logRedeclarationError(name), identifier.start);
|
|
6701
6936
|
}
|
|
6702
|
-
const newVariable = new LocalVariable(identifier.name, identifier, init, context, kind);
|
|
6937
|
+
const newVariable = new LocalVariable(identifier.name, identifier, init, destructuredInitPath, context, kind);
|
|
6703
6938
|
this.variables.set(name, newVariable);
|
|
6704
6939
|
return newVariable;
|
|
6705
6940
|
}
|
|
@@ -6875,7 +7110,6 @@ class MethodBase extends NodeBase {
|
|
|
6875
7110
|
}
|
|
6876
7111
|
return this.getAccessedValue()[0].hasEffectsOnInteractionAtPath(path, interaction, context);
|
|
6877
7112
|
}
|
|
6878
|
-
applyDeoptimizations() { }
|
|
6879
7113
|
getAccessedValue() {
|
|
6880
7114
|
if (this.accessedValue === null) {
|
|
6881
7115
|
if (this.kind === 'get') {
|
|
@@ -6889,19 +7123,20 @@ class MethodBase extends NodeBase {
|
|
|
6889
7123
|
return this.accessedValue;
|
|
6890
7124
|
}
|
|
6891
7125
|
}
|
|
7126
|
+
MethodBase.prototype.includeNode = onlyIncludeSelfNoDeoptimize;
|
|
7127
|
+
MethodBase.prototype.applyDeoptimizations = doNotDeoptimize;
|
|
6892
7128
|
|
|
6893
7129
|
class MethodDefinition extends MethodBase {
|
|
6894
7130
|
hasEffects(context) {
|
|
6895
7131
|
return super.hasEffects(context) || checkEffectForNodes(this.decorators, context);
|
|
6896
7132
|
}
|
|
6897
|
-
applyDeoptimizations() { }
|
|
6898
7133
|
}
|
|
6899
7134
|
|
|
6900
7135
|
class BlockScope extends ChildScope {
|
|
6901
7136
|
constructor(parent) {
|
|
6902
7137
|
super(parent, parent.context);
|
|
6903
7138
|
}
|
|
6904
|
-
addDeclaration(identifier, context, init, kind) {
|
|
7139
|
+
addDeclaration(identifier, context, init, destructuredInitPath, kind) {
|
|
6905
7140
|
if (kind === 'var') {
|
|
6906
7141
|
const name = identifier.name;
|
|
6907
7142
|
const existingVariable = this.hoistedVariables?.get(name) || this.variables.get(name);
|
|
@@ -6913,7 +7148,7 @@ class BlockScope extends ChildScope {
|
|
|
6913
7148
|
}
|
|
6914
7149
|
return context.error(parseAst_js.logRedeclarationError(name), identifier.start);
|
|
6915
7150
|
}
|
|
6916
|
-
const declaredVariable = this.parent.addDeclaration(identifier, context, init, kind);
|
|
7151
|
+
const declaredVariable = this.parent.addDeclaration(identifier, context, init, destructuredInitPath, kind);
|
|
6917
7152
|
// Necessary to make sure the init is deoptimized for conditional declarations.
|
|
6918
7153
|
// We cannot call deoptimizePath here.
|
|
6919
7154
|
declaredVariable.markInitializersForDeoptimization();
|
|
@@ -6921,7 +7156,7 @@ class BlockScope extends ChildScope {
|
|
|
6921
7156
|
this.addHoistedVariable(name, declaredVariable);
|
|
6922
7157
|
return declaredVariable;
|
|
6923
7158
|
}
|
|
6924
|
-
return super.addDeclaration(identifier, context, init, kind);
|
|
7159
|
+
return super.addDeclaration(identifier, context, init, destructuredInitPath, kind);
|
|
6925
7160
|
}
|
|
6926
7161
|
}
|
|
6927
7162
|
|
|
@@ -6953,33 +7188,12 @@ class StaticBlock extends NodeBase {
|
|
|
6953
7188
|
}
|
|
6954
7189
|
}
|
|
6955
7190
|
}
|
|
7191
|
+
StaticBlock.prototype.includeNode = onlyIncludeSelfNoDeoptimize;
|
|
7192
|
+
StaticBlock.prototype.applyDeoptimizations = doNotDeoptimize;
|
|
6956
7193
|
function isStaticBlock(statement) {
|
|
6957
7194
|
return statement.type === parseAst_js.StaticBlock;
|
|
6958
7195
|
}
|
|
6959
7196
|
|
|
6960
|
-
class ObjectMember extends ExpressionEntity {
|
|
6961
|
-
constructor(object, key) {
|
|
6962
|
-
super();
|
|
6963
|
-
this.object = object;
|
|
6964
|
-
this.key = key;
|
|
6965
|
-
}
|
|
6966
|
-
deoptimizeArgumentsOnInteractionAtPath(interaction, path, recursionTracker) {
|
|
6967
|
-
this.object.deoptimizeArgumentsOnInteractionAtPath(interaction, [this.key, ...path], recursionTracker);
|
|
6968
|
-
}
|
|
6969
|
-
deoptimizePath(path) {
|
|
6970
|
-
this.object.deoptimizePath([this.key, ...path]);
|
|
6971
|
-
}
|
|
6972
|
-
getLiteralValueAtPath(path, recursionTracker, origin) {
|
|
6973
|
-
return this.object.getLiteralValueAtPath([this.key, ...path], recursionTracker, origin);
|
|
6974
|
-
}
|
|
6975
|
-
getReturnExpressionWhenCalledAtPath(path, interaction, recursionTracker, origin) {
|
|
6976
|
-
return this.object.getReturnExpressionWhenCalledAtPath([this.key, ...path], interaction, recursionTracker, origin);
|
|
6977
|
-
}
|
|
6978
|
-
hasEffectsOnInteractionAtPath(path, interaction, context) {
|
|
6979
|
-
return this.object.hasEffectsOnInteractionAtPath([this.key, ...path], interaction, context);
|
|
6980
|
-
}
|
|
6981
|
-
}
|
|
6982
|
-
|
|
6983
7197
|
class ClassNode extends NodeBase {
|
|
6984
7198
|
constructor() {
|
|
6985
7199
|
super(...arguments);
|
|
@@ -7020,21 +7234,20 @@ class ClassNode extends NodeBase {
|
|
|
7020
7234
|
: this.getObjectEntity().hasEffectsOnInteractionAtPath(path, interaction, context);
|
|
7021
7235
|
}
|
|
7022
7236
|
include(context, includeChildrenRecursively) {
|
|
7023
|
-
if (!this.
|
|
7024
|
-
this.
|
|
7025
|
-
this.included = true;
|
|
7237
|
+
if (!this.included)
|
|
7238
|
+
this.includeNode(context);
|
|
7026
7239
|
this.superClass?.include(context, includeChildrenRecursively);
|
|
7027
7240
|
this.body.include(context, includeChildrenRecursively);
|
|
7028
7241
|
for (const decorator of this.decorators)
|
|
7029
7242
|
decorator.include(context, includeChildrenRecursively);
|
|
7030
7243
|
if (this.id) {
|
|
7031
7244
|
this.id.markDeclarationReached();
|
|
7032
|
-
this.id.include();
|
|
7245
|
+
this.id.include(context);
|
|
7033
7246
|
}
|
|
7034
7247
|
}
|
|
7035
7248
|
initialise() {
|
|
7036
7249
|
super.initialise();
|
|
7037
|
-
this.id?.declare('class', this);
|
|
7250
|
+
this.id?.declare('class', EMPTY_PATH, this);
|
|
7038
7251
|
for (const method of this.body.body) {
|
|
7039
7252
|
if (method instanceof MethodDefinition && method.kind === 'constructor') {
|
|
7040
7253
|
this.classConstructor = method;
|
|
@@ -7092,11 +7305,12 @@ class ClassNode extends NodeBase {
|
|
|
7092
7305
|
staticProperties.unshift({
|
|
7093
7306
|
key: 'prototype',
|
|
7094
7307
|
kind: 'init',
|
|
7095
|
-
property: new ObjectEntity(dynamicMethods, this.superClass ? new ObjectMember(this.superClass, 'prototype') : OBJECT_PROTOTYPE)
|
|
7308
|
+
property: new ObjectEntity(dynamicMethods, this.superClass ? new ObjectMember(this.superClass, ['prototype']) : OBJECT_PROTOTYPE)
|
|
7096
7309
|
});
|
|
7097
7310
|
return (this.objectEntity = new ObjectEntity(staticProperties, this.superClass || OBJECT_PROTOTYPE));
|
|
7098
7311
|
}
|
|
7099
7312
|
}
|
|
7313
|
+
ClassNode.prototype.includeNode = onlyIncludeSelf;
|
|
7100
7314
|
|
|
7101
7315
|
class ClassDeclaration extends ClassNode {
|
|
7102
7316
|
initialise() {
|
|
@@ -7149,7 +7363,7 @@ class ClassDeclaration extends ClassNode {
|
|
|
7149
7363
|
|
|
7150
7364
|
class ArgumentsVariable extends LocalVariable {
|
|
7151
7365
|
constructor(context) {
|
|
7152
|
-
super('arguments', null, UNKNOWN_EXPRESSION, context, 'other');
|
|
7366
|
+
super('arguments', null, UNKNOWN_EXPRESSION, EMPTY_PATH, context, 'other');
|
|
7153
7367
|
this.deoptimizedArguments = [];
|
|
7154
7368
|
}
|
|
7155
7369
|
addArgumentToBeDeoptimized(argument) {
|
|
@@ -7163,8 +7377,8 @@ class ArgumentsVariable extends LocalVariable {
|
|
|
7163
7377
|
hasEffectsOnInteractionAtPath(path, { type }) {
|
|
7164
7378
|
return type !== INTERACTION_ACCESSED || path.length > 1;
|
|
7165
7379
|
}
|
|
7166
|
-
|
|
7167
|
-
super.
|
|
7380
|
+
includePath(path, context) {
|
|
7381
|
+
super.includePath(path, context);
|
|
7168
7382
|
for (const argument of this.deoptimizedArguments) {
|
|
7169
7383
|
argument.deoptimizePath(UNKNOWN_PATH);
|
|
7170
7384
|
}
|
|
@@ -7172,30 +7386,31 @@ class ArgumentsVariable extends LocalVariable {
|
|
|
7172
7386
|
}
|
|
7173
7387
|
}
|
|
7174
7388
|
|
|
7175
|
-
const MAX_TRACKED_INTERACTIONS =
|
|
7389
|
+
const MAX_TRACKED_INTERACTIONS = 10;
|
|
7390
|
+
const MAX_DEOPTIMIZED_FIELDS = 5;
|
|
7176
7391
|
const NO_INTERACTIONS = parseAst_js.EMPTY_ARRAY;
|
|
7177
7392
|
const UNKNOWN_DEOPTIMIZED_FIELD = new Set([UnknownKey]);
|
|
7178
|
-
const EMPTY_PATH_TRACKER = new
|
|
7393
|
+
const EMPTY_PATH_TRACKER = new EntityPathTracker();
|
|
7179
7394
|
const UNKNOWN_DEOPTIMIZED_ENTITY = new Set([UNKNOWN_EXPRESSION]);
|
|
7180
7395
|
class ParameterVariable extends LocalVariable {
|
|
7181
|
-
constructor(name, declarator, context) {
|
|
7182
|
-
super(name, declarator, UNKNOWN_EXPRESSION, context, 'parameter');
|
|
7396
|
+
constructor(name, declarator, argumentPath, context) {
|
|
7397
|
+
super(name, declarator, UNKNOWN_EXPRESSION, argumentPath, context, 'parameter');
|
|
7398
|
+
this.argumentsToBeDeoptimized = new Set();
|
|
7183
7399
|
this.deoptimizationInteractions = [];
|
|
7184
|
-
this.deoptimizations = new
|
|
7400
|
+
this.deoptimizations = new EntityPathTracker();
|
|
7185
7401
|
this.deoptimizedFields = new Set();
|
|
7186
|
-
this.
|
|
7187
|
-
this.expressionsUseTheKnownValue = [];
|
|
7402
|
+
this.expressionsDependingOnKnownValue = [];
|
|
7188
7403
|
this.knownValue = null;
|
|
7189
7404
|
this.knownValueLiteral = UnknownValue;
|
|
7190
|
-
this.frozenValue = null;
|
|
7191
7405
|
}
|
|
7192
|
-
|
|
7406
|
+
addArgumentValue(entity) {
|
|
7407
|
+
this.updateKnownValue(entity);
|
|
7193
7408
|
if (entity === UNKNOWN_EXPRESSION) {
|
|
7194
7409
|
// As unknown expressions fully deoptimize all interactions, we can clear
|
|
7195
7410
|
// the interaction cache at this point provided we keep this optimization
|
|
7196
7411
|
// in mind when adding new interactions
|
|
7197
|
-
if (!this.
|
|
7198
|
-
this.
|
|
7412
|
+
if (!this.argumentsToBeDeoptimized.has(UNKNOWN_EXPRESSION)) {
|
|
7413
|
+
this.argumentsToBeDeoptimized.add(UNKNOWN_EXPRESSION);
|
|
7199
7414
|
for (const { interaction } of this.deoptimizationInteractions) {
|
|
7200
7415
|
deoptimizeInteraction(interaction);
|
|
7201
7416
|
}
|
|
@@ -7205,27 +7420,30 @@ class ParameterVariable extends LocalVariable {
|
|
|
7205
7420
|
else if (this.deoptimizedFields.has(UnknownKey)) {
|
|
7206
7421
|
// This means that we already deoptimized all interactions and no longer
|
|
7207
7422
|
// track them
|
|
7208
|
-
entity.deoptimizePath(
|
|
7423
|
+
entity.deoptimizePath([...this.initPath, UnknownKey]);
|
|
7209
7424
|
}
|
|
7210
|
-
else if (!this.
|
|
7211
|
-
this.
|
|
7425
|
+
else if (!this.argumentsToBeDeoptimized.has(entity)) {
|
|
7426
|
+
this.argumentsToBeDeoptimized.add(entity);
|
|
7212
7427
|
for (const field of this.deoptimizedFields) {
|
|
7213
|
-
entity.deoptimizePath([field]);
|
|
7428
|
+
entity.deoptimizePath([...this.initPath, field]);
|
|
7214
7429
|
}
|
|
7215
7430
|
for (const { interaction, path } of this.deoptimizationInteractions) {
|
|
7216
|
-
entity.deoptimizeArgumentsOnInteractionAtPath(interaction, path, SHARED_RECURSION_TRACKER);
|
|
7431
|
+
entity.deoptimizeArgumentsOnInteractionAtPath(interaction, [...this.initPath, ...path], SHARED_RECURSION_TRACKER);
|
|
7217
7432
|
}
|
|
7218
7433
|
}
|
|
7219
7434
|
}
|
|
7435
|
+
/** This says we should not make assumptions about the value of the parameter.
|
|
7436
|
+
* This is different from deoptimization that will also cause argument values
|
|
7437
|
+
* to be deoptimized. */
|
|
7220
7438
|
markReassigned() {
|
|
7221
7439
|
if (this.isReassigned) {
|
|
7222
7440
|
return;
|
|
7223
7441
|
}
|
|
7224
7442
|
super.markReassigned();
|
|
7225
|
-
for (const expression of this.
|
|
7443
|
+
for (const expression of this.expressionsDependingOnKnownValue) {
|
|
7226
7444
|
expression.deoptimizeCache();
|
|
7227
7445
|
}
|
|
7228
|
-
this.
|
|
7446
|
+
this.expressionsDependingOnKnownValue = parseAst_js.EMPTY_ARRAY;
|
|
7229
7447
|
}
|
|
7230
7448
|
deoptimizeCache() {
|
|
7231
7449
|
this.markReassigned();
|
|
@@ -7242,7 +7460,7 @@ class ParameterVariable extends LocalVariable {
|
|
|
7242
7460
|
}
|
|
7243
7461
|
if (this.knownValue === null) {
|
|
7244
7462
|
this.knownValue = argument;
|
|
7245
|
-
this.knownValueLiteral = argument.getLiteralValueAtPath(
|
|
7463
|
+
this.knownValueLiteral = argument.getLiteralValueAtPath(this.initPath, SHARED_RECURSION_TRACKER, this);
|
|
7246
7464
|
return;
|
|
7247
7465
|
}
|
|
7248
7466
|
// the same literal or identifier, do nothing
|
|
@@ -7252,14 +7470,10 @@ class ParameterVariable extends LocalVariable {
|
|
|
7252
7470
|
this.knownValue.variable === argument.variable)) {
|
|
7253
7471
|
return;
|
|
7254
7472
|
}
|
|
7255
|
-
const
|
|
7256
|
-
if (typeof
|
|
7257
|
-
this.
|
|
7258
|
-
|
|
7259
|
-
}
|
|
7260
|
-
// add tracking for the new argument
|
|
7261
|
-
const newValue = argument.getLiteralValueAtPath(EMPTY_PATH, SHARED_RECURSION_TRACKER, this);
|
|
7262
|
-
if (newValue !== oldValue) {
|
|
7473
|
+
const { knownValueLiteral } = this;
|
|
7474
|
+
if (typeof knownValueLiteral === 'symbol' ||
|
|
7475
|
+
argument.getLiteralValueAtPath(this.initPath, SHARED_RECURSION_TRACKER, this) !==
|
|
7476
|
+
knownValueLiteral) {
|
|
7263
7477
|
this.markReassigned();
|
|
7264
7478
|
}
|
|
7265
7479
|
}
|
|
@@ -7270,42 +7484,47 @@ class ParameterVariable extends LocalVariable {
|
|
|
7270
7484
|
* @returns the frozen value
|
|
7271
7485
|
*/
|
|
7272
7486
|
getKnownValue() {
|
|
7273
|
-
|
|
7274
|
-
this.frozenValue = this.knownValue || UNKNOWN_EXPRESSION;
|
|
7275
|
-
}
|
|
7276
|
-
return this.frozenValue;
|
|
7487
|
+
return this.knownValue || UNKNOWN_EXPRESSION;
|
|
7277
7488
|
}
|
|
7278
7489
|
getLiteralValueAtPath(path, recursionTracker, origin) {
|
|
7279
|
-
if (this.isReassigned) {
|
|
7490
|
+
if (this.isReassigned || path.length + this.initPath.length > MAX_PATH_DEPTH) {
|
|
7280
7491
|
return UnknownValue;
|
|
7281
7492
|
}
|
|
7282
7493
|
const knownValue = this.getKnownValue();
|
|
7283
|
-
this.
|
|
7284
|
-
return recursionTracker.withTrackedEntityAtPath(path, knownValue, () => knownValue.getLiteralValueAtPath(path, recursionTracker, origin), UnknownValue);
|
|
7494
|
+
this.expressionsDependingOnKnownValue.push(origin);
|
|
7495
|
+
return recursionTracker.withTrackedEntityAtPath(path, knownValue, () => knownValue.getLiteralValueAtPath([...this.initPath, ...path], recursionTracker, origin), UnknownValue);
|
|
7285
7496
|
}
|
|
7286
7497
|
hasEffectsOnInteractionAtPath(path, interaction, context) {
|
|
7287
|
-
|
|
7498
|
+
const { type } = interaction;
|
|
7499
|
+
if (this.isReassigned ||
|
|
7500
|
+
type === INTERACTION_ASSIGNED ||
|
|
7501
|
+
path.length + this.initPath.length > MAX_PATH_DEPTH) {
|
|
7288
7502
|
return super.hasEffectsOnInteractionAtPath(path, interaction, context);
|
|
7289
7503
|
}
|
|
7290
|
-
|
|
7291
|
-
|
|
7504
|
+
return (!(type === INTERACTION_CALLED
|
|
7505
|
+
? (interaction.withNew
|
|
7506
|
+
? context.instantiated
|
|
7507
|
+
: context.called).trackEntityAtPathAndGetIfTracked(path, interaction.args, this)
|
|
7508
|
+
: context.accessed.trackEntityAtPathAndGetIfTracked(path, this)) &&
|
|
7509
|
+
this.getKnownValue().hasEffectsOnInteractionAtPath([...this.initPath, ...path], interaction, context));
|
|
7292
7510
|
}
|
|
7293
7511
|
deoptimizeArgumentsOnInteractionAtPath(interaction, path) {
|
|
7294
7512
|
// For performance reasons, we fully deoptimize all deeper interactions
|
|
7295
7513
|
if (path.length >= 2 ||
|
|
7296
|
-
this.
|
|
7514
|
+
this.argumentsToBeDeoptimized.has(UNKNOWN_EXPRESSION) ||
|
|
7297
7515
|
this.deoptimizationInteractions.length >= MAX_TRACKED_INTERACTIONS ||
|
|
7298
7516
|
(path.length === 1 &&
|
|
7299
7517
|
(this.deoptimizedFields.has(UnknownKey) ||
|
|
7300
|
-
(interaction.type === INTERACTION_CALLED && this.deoptimizedFields.has(path[0]))))
|
|
7518
|
+
(interaction.type === INTERACTION_CALLED && this.deoptimizedFields.has(path[0])))) ||
|
|
7519
|
+
this.initPath.length + path.length > MAX_PATH_DEPTH) {
|
|
7301
7520
|
deoptimizeInteraction(interaction);
|
|
7302
7521
|
return;
|
|
7303
7522
|
}
|
|
7304
7523
|
if (!this.deoptimizations.trackEntityAtPathAndGetIfTracked(path, interaction.args)) {
|
|
7305
|
-
for (const entity of this.
|
|
7306
|
-
entity.deoptimizeArgumentsOnInteractionAtPath(interaction, path, SHARED_RECURSION_TRACKER);
|
|
7524
|
+
for (const entity of this.argumentsToBeDeoptimized) {
|
|
7525
|
+
entity.deoptimizeArgumentsOnInteractionAtPath(interaction, [...this.initPath, ...path], SHARED_RECURSION_TRACKER);
|
|
7307
7526
|
}
|
|
7308
|
-
if (!this.
|
|
7527
|
+
if (!this.argumentsToBeDeoptimized.has(UNKNOWN_EXPRESSION)) {
|
|
7309
7528
|
this.deoptimizationInteractions.push({
|
|
7310
7529
|
interaction,
|
|
7311
7530
|
path
|
|
@@ -7321,22 +7540,27 @@ class ParameterVariable extends LocalVariable {
|
|
|
7321
7540
|
if (this.deoptimizedFields.has(UnknownKey)) {
|
|
7322
7541
|
return;
|
|
7323
7542
|
}
|
|
7324
|
-
|
|
7543
|
+
let key = path[0];
|
|
7325
7544
|
if (this.deoptimizedFields.has(key)) {
|
|
7326
7545
|
return;
|
|
7327
7546
|
}
|
|
7328
|
-
this.deoptimizedFields.
|
|
7329
|
-
|
|
7547
|
+
if (this.deoptimizedFields.size > MAX_DEOPTIMIZED_FIELDS) {
|
|
7548
|
+
key = UnknownKey;
|
|
7549
|
+
}
|
|
7550
|
+
else {
|
|
7551
|
+
this.deoptimizedFields.add(key);
|
|
7552
|
+
}
|
|
7553
|
+
for (const entity of this.argumentsToBeDeoptimized) {
|
|
7330
7554
|
// We do not need a recursion tracker here as we already track whether
|
|
7331
7555
|
// this field is deoptimized
|
|
7332
|
-
entity.deoptimizePath([key]);
|
|
7556
|
+
entity.deoptimizePath([...this.initPath, key]);
|
|
7333
7557
|
}
|
|
7334
7558
|
if (key === UnknownKey) {
|
|
7335
7559
|
// save some memory
|
|
7336
7560
|
this.deoptimizationInteractions = NO_INTERACTIONS;
|
|
7337
7561
|
this.deoptimizations = EMPTY_PATH_TRACKER;
|
|
7338
7562
|
this.deoptimizedFields = UNKNOWN_DEOPTIMIZED_FIELD;
|
|
7339
|
-
this.
|
|
7563
|
+
this.argumentsToBeDeoptimized = UNKNOWN_DEOPTIMIZED_ENTITY;
|
|
7340
7564
|
}
|
|
7341
7565
|
}
|
|
7342
7566
|
getReturnExpressionWhenCalledAtPath(path) {
|
|
@@ -7351,11 +7575,14 @@ class ParameterVariable extends LocalVariable {
|
|
|
7351
7575
|
}
|
|
7352
7576
|
return UNKNOWN_RETURN_EXPRESSION;
|
|
7353
7577
|
}
|
|
7578
|
+
includeArgumentPaths(entity, context) {
|
|
7579
|
+
this.includedPathTracker.includeAllPaths(entity, context, this.initPath);
|
|
7580
|
+
}
|
|
7354
7581
|
}
|
|
7355
7582
|
|
|
7356
7583
|
class ThisVariable extends ParameterVariable {
|
|
7357
7584
|
constructor(context) {
|
|
7358
|
-
super('this', null, context);
|
|
7585
|
+
super('this', null, EMPTY_PATH, context);
|
|
7359
7586
|
}
|
|
7360
7587
|
hasEffectsOnInteractionAtPath(path, interaction, context) {
|
|
7361
7588
|
return (context.replacedVariableInits.get(this) || UNKNOWN_EXPRESSION).hasEffectsOnInteractionAtPath(path, interaction, context);
|
|
@@ -7367,7 +7594,7 @@ class CatchBodyScope extends ChildScope {
|
|
|
7367
7594
|
super(parent, parent.context);
|
|
7368
7595
|
this.parent = parent;
|
|
7369
7596
|
}
|
|
7370
|
-
addDeclaration(identifier, context, init, kind) {
|
|
7597
|
+
addDeclaration(identifier, context, init, destructuredInitPath, kind) {
|
|
7371
7598
|
if (kind === 'var') {
|
|
7372
7599
|
const name = identifier.name;
|
|
7373
7600
|
const existingVariable = this.hoistedVariables?.get(name) || this.variables.get(name);
|
|
@@ -7380,7 +7607,7 @@ class CatchBodyScope extends ChildScope {
|
|
|
7380
7607
|
// the assignment actually goes to the parameter and the var is
|
|
7381
7608
|
// hoisted without assignment. Locally, it is shadowed by the
|
|
7382
7609
|
// parameter
|
|
7383
|
-
const declaredVariable = this.parent.parent.addDeclaration(identifier, context, UNDEFINED_EXPRESSION, kind);
|
|
7610
|
+
const declaredVariable = this.parent.parent.addDeclaration(identifier, context, UNDEFINED_EXPRESSION, destructuredInitPath, kind);
|
|
7384
7611
|
// To avoid the need to rewrite the declaration, we link the variable
|
|
7385
7612
|
// names. If we ever implement a logic that splits initialization and
|
|
7386
7613
|
// assignment for hoisted vars, the "renderLikeHoisted" logic can be
|
|
@@ -7399,7 +7626,7 @@ class CatchBodyScope extends ChildScope {
|
|
|
7399
7626
|
return context.error(parseAst_js.logRedeclarationError(name), identifier.start);
|
|
7400
7627
|
}
|
|
7401
7628
|
// We only add parameters to parameter scopes
|
|
7402
|
-
const declaredVariable = this.parent.parent.addDeclaration(identifier, context, init, kind);
|
|
7629
|
+
const declaredVariable = this.parent.parent.addDeclaration(identifier, context, init, destructuredInitPath, kind);
|
|
7403
7630
|
// Necessary to make sure the init is deoptimized for conditional declarations.
|
|
7404
7631
|
// We cannot call deoptimizePath here.
|
|
7405
7632
|
declaredVariable.markInitializersForDeoptimization();
|
|
@@ -7407,7 +7634,7 @@ class CatchBodyScope extends ChildScope {
|
|
|
7407
7634
|
this.addHoistedVariable(name, declaredVariable);
|
|
7408
7635
|
return declaredVariable;
|
|
7409
7636
|
}
|
|
7410
|
-
return super.addDeclaration(identifier, context, init, kind);
|
|
7637
|
+
return super.addDeclaration(identifier, context, init, destructuredInitPath, kind);
|
|
7411
7638
|
}
|
|
7412
7639
|
}
|
|
7413
7640
|
|
|
@@ -7417,7 +7644,7 @@ class FunctionBodyScope extends ChildScope {
|
|
|
7417
7644
|
}
|
|
7418
7645
|
// There is stuff that is only allowed in function scopes, i.e. functions can
|
|
7419
7646
|
// be redeclared, functions and var can redeclare each other
|
|
7420
|
-
addDeclaration(identifier, context, init, kind) {
|
|
7647
|
+
addDeclaration(identifier, context, init, destructuredInitPath, kind) {
|
|
7421
7648
|
const name = identifier.name;
|
|
7422
7649
|
const existingVariable = this.hoistedVariables?.get(name) || this.variables.get(name);
|
|
7423
7650
|
if (existingVariable) {
|
|
@@ -7429,7 +7656,7 @@ class FunctionBodyScope extends ChildScope {
|
|
|
7429
7656
|
}
|
|
7430
7657
|
context.error(parseAst_js.logRedeclarationError(name), identifier.start);
|
|
7431
7658
|
}
|
|
7432
|
-
const newVariable = new LocalVariable(identifier.name, identifier, init, context, kind);
|
|
7659
|
+
const newVariable = new LocalVariable(identifier.name, identifier, init, destructuredInitPath, context, kind);
|
|
7433
7660
|
this.variables.set(name, newVariable);
|
|
7434
7661
|
return newVariable;
|
|
7435
7662
|
}
|
|
@@ -7438,21 +7665,21 @@ class FunctionBodyScope extends ChildScope {
|
|
|
7438
7665
|
class ParameterScope extends ChildScope {
|
|
7439
7666
|
constructor(parent, isCatchScope) {
|
|
7440
7667
|
super(parent, parent.context);
|
|
7441
|
-
this.parameters = [];
|
|
7442
7668
|
this.hasRest = false;
|
|
7669
|
+
this.parameters = [];
|
|
7443
7670
|
this.bodyScope = isCatchScope ? new CatchBodyScope(this) : new FunctionBodyScope(this);
|
|
7444
7671
|
}
|
|
7445
7672
|
/**
|
|
7446
7673
|
* Adds a parameter to this scope. Parameters must be added in the correct
|
|
7447
7674
|
* order, i.e. from left to right.
|
|
7448
7675
|
*/
|
|
7449
|
-
addParameterDeclaration(identifier) {
|
|
7676
|
+
addParameterDeclaration(identifier, argumentPath) {
|
|
7450
7677
|
const { name, start } = identifier;
|
|
7451
7678
|
const existingParameter = this.variables.get(name);
|
|
7452
7679
|
if (existingParameter) {
|
|
7453
7680
|
return this.context.error(parseAst_js.logDuplicateArgumentNameError(name), start);
|
|
7454
7681
|
}
|
|
7455
|
-
const variable = new ParameterVariable(name, identifier, this.context);
|
|
7682
|
+
const variable = new ParameterVariable(name, identifier, argumentPath, this.context);
|
|
7456
7683
|
this.variables.set(name, variable);
|
|
7457
7684
|
// We also add it to the body scope to detect name conflicts with local
|
|
7458
7685
|
// variables. We still need the intermediate scope, though, as parameter
|
|
@@ -7470,42 +7697,56 @@ class ParameterScope extends ChildScope {
|
|
|
7470
7697
|
}
|
|
7471
7698
|
this.hasRest = hasRest;
|
|
7472
7699
|
}
|
|
7473
|
-
includeCallArguments(context,
|
|
7700
|
+
includeCallArguments(context, interaction) {
|
|
7474
7701
|
let calledFromTryStatement = false;
|
|
7475
7702
|
let argumentIncluded = false;
|
|
7476
7703
|
const restParameter = this.hasRest && this.parameters[this.parameters.length - 1];
|
|
7477
|
-
|
|
7478
|
-
|
|
7479
|
-
|
|
7480
|
-
|
|
7481
|
-
|
|
7482
|
-
|
|
7704
|
+
const { args } = interaction;
|
|
7705
|
+
let lastExplicitlyIncludedIndex = args.length - 1;
|
|
7706
|
+
// If there is a SpreadElement, we need to include all arguments after it
|
|
7707
|
+
// because we no longer know which argument corresponds to which parameter.
|
|
7708
|
+
for (let argumentIndex = 1; argumentIndex < args.length; argumentIndex++) {
|
|
7709
|
+
const argument = args[argumentIndex];
|
|
7710
|
+
if (argument instanceof SpreadElement && !argumentIncluded) {
|
|
7711
|
+
argumentIncluded = true;
|
|
7712
|
+
lastExplicitlyIncludedIndex = argumentIndex - 1;
|
|
7713
|
+
}
|
|
7714
|
+
if (argumentIncluded) {
|
|
7715
|
+
argument.includePath(UNKNOWN_PATH, context);
|
|
7716
|
+
argument.include(context, false);
|
|
7483
7717
|
}
|
|
7484
7718
|
}
|
|
7485
|
-
|
|
7486
|
-
|
|
7487
|
-
|
|
7719
|
+
// Now we go backwards either starting from the last argument or before the
|
|
7720
|
+
// first SpreadElement to ensure all arguments before are included as needed
|
|
7721
|
+
for (let index = lastExplicitlyIncludedIndex; index >= 1; index--) {
|
|
7722
|
+
const parameterVariables = this.parameters[index - 1] || restParameter;
|
|
7723
|
+
const argument = args[index];
|
|
7488
7724
|
if (parameterVariables) {
|
|
7489
7725
|
calledFromTryStatement = false;
|
|
7490
7726
|
if (parameterVariables.length === 0) {
|
|
7491
|
-
// handle empty destructuring
|
|
7727
|
+
// handle empty destructuring to avoid destructuring undefined
|
|
7492
7728
|
argumentIncluded = true;
|
|
7493
7729
|
}
|
|
7494
7730
|
else {
|
|
7495
7731
|
for (const variable of parameterVariables) {
|
|
7496
|
-
if (variable.included) {
|
|
7497
|
-
argumentIncluded = true;
|
|
7498
|
-
}
|
|
7499
7732
|
if (variable.calledFromTryStatement) {
|
|
7500
7733
|
calledFromTryStatement = true;
|
|
7501
7734
|
}
|
|
7735
|
+
if (variable.included) {
|
|
7736
|
+
argumentIncluded = true;
|
|
7737
|
+
if (calledFromTryStatement) {
|
|
7738
|
+
argument.include(context, true);
|
|
7739
|
+
}
|
|
7740
|
+
else {
|
|
7741
|
+
variable.includeArgumentPaths(argument, context);
|
|
7742
|
+
argument.include(context, false);
|
|
7743
|
+
}
|
|
7744
|
+
}
|
|
7502
7745
|
}
|
|
7503
7746
|
}
|
|
7504
7747
|
}
|
|
7505
|
-
if (!
|
|
7748
|
+
if (!argument.included && (argumentIncluded || argument.shouldBeIncluded(context))) {
|
|
7506
7749
|
argumentIncluded = true;
|
|
7507
|
-
}
|
|
7508
|
-
if (argumentIncluded) {
|
|
7509
7750
|
argument.include(context, calledFromTryStatement);
|
|
7510
7751
|
}
|
|
7511
7752
|
}
|
|
@@ -7521,11 +7762,62 @@ class ReturnValueScope extends ParameterScope {
|
|
|
7521
7762
|
addReturnExpression(expression) {
|
|
7522
7763
|
this.returnExpressions.push(expression);
|
|
7523
7764
|
}
|
|
7765
|
+
deoptimizeArgumentsOnCall(interaction) {
|
|
7766
|
+
const { parameters } = this;
|
|
7767
|
+
const { args } = interaction;
|
|
7768
|
+
let position = 0;
|
|
7769
|
+
for (; position < args.length - 1; position++) {
|
|
7770
|
+
// Only the "this" argument arg[0] can be null
|
|
7771
|
+
const argument = args[position + 1];
|
|
7772
|
+
if (argument instanceof SpreadElement) {
|
|
7773
|
+
// This deoptimizes the current and remaining parameters and arguments
|
|
7774
|
+
for (; position < parameters.length; position++) {
|
|
7775
|
+
args[position + 1]?.deoptimizePath(UNKNOWN_PATH);
|
|
7776
|
+
parameters[position].forEach(variable => variable.markReassigned());
|
|
7777
|
+
}
|
|
7778
|
+
break;
|
|
7779
|
+
}
|
|
7780
|
+
if (this.hasRest && position >= parameters.length - 1) {
|
|
7781
|
+
argument.deoptimizePath(UNKNOWN_PATH);
|
|
7782
|
+
}
|
|
7783
|
+
else {
|
|
7784
|
+
const variables = parameters[position];
|
|
7785
|
+
if (variables) {
|
|
7786
|
+
for (const variable of variables) {
|
|
7787
|
+
variable.addArgumentValue(argument);
|
|
7788
|
+
}
|
|
7789
|
+
}
|
|
7790
|
+
this.addArgumentToBeDeoptimized(argument);
|
|
7791
|
+
}
|
|
7792
|
+
}
|
|
7793
|
+
const nonRestParameterLength = this.hasRest ? parameters.length - 1 : parameters.length;
|
|
7794
|
+
for (; position < nonRestParameterLength; position++) {
|
|
7795
|
+
for (const variable of parameters[position]) {
|
|
7796
|
+
variable.addArgumentValue(UNDEFINED_EXPRESSION);
|
|
7797
|
+
}
|
|
7798
|
+
}
|
|
7799
|
+
}
|
|
7524
7800
|
getReturnExpression() {
|
|
7525
7801
|
if (this.returnExpression === null)
|
|
7526
7802
|
this.updateReturnExpression();
|
|
7527
7803
|
return this.returnExpression;
|
|
7528
7804
|
}
|
|
7805
|
+
deoptimizeAllParameters() {
|
|
7806
|
+
for (const parameter of this.parameters) {
|
|
7807
|
+
for (const variable of parameter) {
|
|
7808
|
+
variable.deoptimizePath(UNKNOWN_PATH);
|
|
7809
|
+
variable.markReassigned();
|
|
7810
|
+
}
|
|
7811
|
+
}
|
|
7812
|
+
}
|
|
7813
|
+
reassignAllParameters() {
|
|
7814
|
+
for (const parameter of this.parameters) {
|
|
7815
|
+
for (const variable of parameter) {
|
|
7816
|
+
variable.markReassigned();
|
|
7817
|
+
}
|
|
7818
|
+
}
|
|
7819
|
+
}
|
|
7820
|
+
addArgumentToBeDeoptimized(_argument) { }
|
|
7529
7821
|
updateReturnExpression() {
|
|
7530
7822
|
if (this.returnExpressions.length === 1) {
|
|
7531
7823
|
this.returnExpression = this.returnExpressions[0];
|
|
@@ -7541,24 +7833,30 @@ class ReturnValueScope extends ParameterScope {
|
|
|
7541
7833
|
|
|
7542
7834
|
class FunctionScope extends ReturnValueScope {
|
|
7543
7835
|
constructor(parent) {
|
|
7544
|
-
const { context } = parent;
|
|
7545
7836
|
super(parent, false);
|
|
7837
|
+
const { context } = parent;
|
|
7546
7838
|
this.variables.set('arguments', (this.argumentsVariable = new ArgumentsVariable(context)));
|
|
7547
7839
|
this.variables.set('this', (this.thisVariable = new ThisVariable(context)));
|
|
7548
7840
|
}
|
|
7549
7841
|
findLexicalBoundary() {
|
|
7550
7842
|
return this;
|
|
7551
7843
|
}
|
|
7552
|
-
includeCallArguments(context,
|
|
7553
|
-
super.includeCallArguments(context,
|
|
7844
|
+
includeCallArguments(context, interaction) {
|
|
7845
|
+
super.includeCallArguments(context, interaction);
|
|
7554
7846
|
if (this.argumentsVariable.included) {
|
|
7555
|
-
|
|
7556
|
-
|
|
7847
|
+
const { args } = interaction;
|
|
7848
|
+
for (let argumentIndex = 1; argumentIndex < args.length; argumentIndex++) {
|
|
7849
|
+
const argument = args[argumentIndex];
|
|
7850
|
+
if (argument) {
|
|
7851
|
+
argument.includePath(UNKNOWN_PATH, context);
|
|
7557
7852
|
argument.include(context, false);
|
|
7558
7853
|
}
|
|
7559
7854
|
}
|
|
7560
7855
|
}
|
|
7561
7856
|
}
|
|
7857
|
+
addArgumentToBeDeoptimized(argument) {
|
|
7858
|
+
this.argumentsVariable.addArgumentToBeDeoptimized(argument);
|
|
7859
|
+
}
|
|
7562
7860
|
}
|
|
7563
7861
|
|
|
7564
7862
|
class ExpressionStatement extends NodeBase {
|
|
@@ -7586,8 +7884,9 @@ class ExpressionStatement extends NodeBase {
|
|
|
7586
7884
|
return this.parent.type !== parseAst_js.Program;
|
|
7587
7885
|
return super.shouldBeIncluded(context);
|
|
7588
7886
|
}
|
|
7589
|
-
applyDeoptimizations() { }
|
|
7590
7887
|
}
|
|
7888
|
+
ExpressionStatement.prototype.includeNode = onlyIncludeSelfNoDeoptimize;
|
|
7889
|
+
ExpressionStatement.prototype.applyDeoptimizations = doNotDeoptimize;
|
|
7591
7890
|
|
|
7592
7891
|
class BlockStatement extends NodeBase {
|
|
7593
7892
|
get deoptimizeBody() {
|
|
@@ -7652,6 +7951,8 @@ class BlockStatement extends NodeBase {
|
|
|
7652
7951
|
}
|
|
7653
7952
|
}
|
|
7654
7953
|
}
|
|
7954
|
+
BlockStatement.prototype.includeNode = onlyIncludeSelfNoDeoptimize;
|
|
7955
|
+
BlockStatement.prototype.applyDeoptimizations = doNotDeoptimize;
|
|
7655
7956
|
|
|
7656
7957
|
class RestElement extends NodeBase {
|
|
7657
7958
|
constructor() {
|
|
@@ -7661,9 +7962,12 @@ class RestElement extends NodeBase {
|
|
|
7661
7962
|
addExportedVariables(variables, exportNamesByVariable) {
|
|
7662
7963
|
this.argument.addExportedVariables(variables, exportNamesByVariable);
|
|
7663
7964
|
}
|
|
7664
|
-
declare(kind, init) {
|
|
7965
|
+
declare(kind, destructuredInitPath, init) {
|
|
7665
7966
|
this.declarationInit = init;
|
|
7666
|
-
return this.argument.declare(kind,
|
|
7967
|
+
return this.argument.declare(kind, getIncludedPatternPath$1(destructuredInitPath), init);
|
|
7968
|
+
}
|
|
7969
|
+
deoptimizeAssignment(destructuredInitPath, init) {
|
|
7970
|
+
this.argument.deoptimizeAssignment(getIncludedPatternPath$1(destructuredInitPath), init);
|
|
7667
7971
|
}
|
|
7668
7972
|
deoptimizePath(path) {
|
|
7669
7973
|
if (path.length === 0) {
|
|
@@ -7674,6 +7978,20 @@ class RestElement extends NodeBase {
|
|
|
7674
7978
|
return (path.length > 0 ||
|
|
7675
7979
|
this.argument.hasEffectsOnInteractionAtPath(EMPTY_PATH, interaction, context));
|
|
7676
7980
|
}
|
|
7981
|
+
hasEffectsWhenDestructuring(context, destructuredInitPath, init) {
|
|
7982
|
+
return this.argument.hasEffectsWhenDestructuring(context, getIncludedPatternPath$1(destructuredInitPath), init);
|
|
7983
|
+
}
|
|
7984
|
+
includeDestructuredIfNecessary(context, destructuredInitPath, init) {
|
|
7985
|
+
return (this.included =
|
|
7986
|
+
this.argument.includeDestructuredIfNecessary(context, getIncludedPatternPath$1(destructuredInitPath), init) || this.included);
|
|
7987
|
+
}
|
|
7988
|
+
include(context, includeChildrenRecursively) {
|
|
7989
|
+
if (!this.included)
|
|
7990
|
+
this.includeNode(context);
|
|
7991
|
+
// This should just include the identifier, its properties should be
|
|
7992
|
+
// included where the variable is used.
|
|
7993
|
+
this.argument.include(context, includeChildrenRecursively);
|
|
7994
|
+
}
|
|
7677
7995
|
markDeclarationReached() {
|
|
7678
7996
|
this.argument.markDeclarationReached();
|
|
7679
7997
|
}
|
|
@@ -7685,12 +8003,16 @@ class RestElement extends NodeBase {
|
|
|
7685
8003
|
}
|
|
7686
8004
|
}
|
|
7687
8005
|
}
|
|
8006
|
+
RestElement.prototype.includeNode = onlyIncludeSelf;
|
|
8007
|
+
const getIncludedPatternPath$1 = (destructuredInitPath) => destructuredInitPath.at(-1) === UnknownKey
|
|
8008
|
+
? destructuredInitPath
|
|
8009
|
+
: [...destructuredInitPath, UnknownKey];
|
|
7688
8010
|
|
|
7689
8011
|
class FunctionBase extends NodeBase {
|
|
7690
8012
|
constructor() {
|
|
7691
8013
|
super(...arguments);
|
|
7692
|
-
this.objectEntity = null;
|
|
7693
8014
|
this.parameterVariableValuesDeoptimized = false;
|
|
8015
|
+
this.includeCallArguments = this.scope.includeCallArguments.bind(this.scope);
|
|
7694
8016
|
}
|
|
7695
8017
|
get async() {
|
|
7696
8018
|
return isFlagSet(this.flags, 256 /* Flag.async */);
|
|
@@ -7710,53 +8032,15 @@ class FunctionBase extends NodeBase {
|
|
|
7710
8032
|
set generator(value) {
|
|
7711
8033
|
this.flags = setFlag(this.flags, 4194304 /* Flag.generator */, value);
|
|
7712
8034
|
}
|
|
7713
|
-
|
|
7714
|
-
|
|
7715
|
-
const parameter = this.params[position];
|
|
7716
|
-
if (!(parameter instanceof Identifier)) {
|
|
7717
|
-
continue;
|
|
7718
|
-
}
|
|
7719
|
-
const parameterVariable = parameter.variable;
|
|
7720
|
-
const argument = _arguments[position + 1] ?? UNDEFINED_EXPRESSION;
|
|
7721
|
-
parameterVariable.updateKnownValue(argument);
|
|
7722
|
-
}
|
|
8035
|
+
get hasCachedEffects() {
|
|
8036
|
+
return isFlagSet(this.flags, 67108864 /* Flag.hasEffects */);
|
|
7723
8037
|
}
|
|
7724
|
-
|
|
7725
|
-
|
|
7726
|
-
if (parameter instanceof Identifier) {
|
|
7727
|
-
const parameterVariable = parameter.variable;
|
|
7728
|
-
parameterVariable.markReassigned();
|
|
7729
|
-
}
|
|
7730
|
-
}
|
|
8038
|
+
set hasCachedEffects(value) {
|
|
8039
|
+
this.flags = setFlag(this.flags, 67108864 /* Flag.hasEffects */, value);
|
|
7731
8040
|
}
|
|
7732
8041
|
deoptimizeArgumentsOnInteractionAtPath(interaction, path, recursionTracker) {
|
|
7733
|
-
if (interaction.type === INTERACTION_CALLED) {
|
|
7734
|
-
|
|
7735
|
-
const { args } = interaction;
|
|
7736
|
-
let hasRest = false;
|
|
7737
|
-
for (let position = 0; position < args.length - 1; position++) {
|
|
7738
|
-
const parameter = this.params[position];
|
|
7739
|
-
// Only the "this" argument arg[0] can be null
|
|
7740
|
-
const argument = args[position + 1];
|
|
7741
|
-
if (argument instanceof SpreadElement) {
|
|
7742
|
-
this.deoptimizeParameterVariableValues();
|
|
7743
|
-
}
|
|
7744
|
-
if (hasRest || parameter instanceof RestElement) {
|
|
7745
|
-
hasRest = true;
|
|
7746
|
-
argument.deoptimizePath(UNKNOWN_PATH);
|
|
7747
|
-
}
|
|
7748
|
-
else if (parameter instanceof Identifier) {
|
|
7749
|
-
parameters[position][0].addEntityToBeDeoptimized(argument);
|
|
7750
|
-
this.addArgumentToBeDeoptimized(argument);
|
|
7751
|
-
}
|
|
7752
|
-
else if (parameter) {
|
|
7753
|
-
argument.deoptimizePath(UNKNOWN_PATH);
|
|
7754
|
-
}
|
|
7755
|
-
else {
|
|
7756
|
-
this.addArgumentToBeDeoptimized(argument);
|
|
7757
|
-
}
|
|
7758
|
-
}
|
|
7759
|
-
this.updateParameterVariableValues(args);
|
|
8042
|
+
if (interaction.type === INTERACTION_CALLED && path.length === 0) {
|
|
8043
|
+
this.scope.deoptimizeArgumentsOnCall(interaction);
|
|
7760
8044
|
}
|
|
7761
8045
|
else {
|
|
7762
8046
|
this.getObjectEntity().deoptimizeArgumentsOnInteractionAtPath(interaction, path, recursionTracker);
|
|
@@ -7768,12 +8052,7 @@ class FunctionBase extends NodeBase {
|
|
|
7768
8052
|
// A reassignment of UNKNOWN_PATH is considered equivalent to having lost track
|
|
7769
8053
|
// which means the return expression and parameters need to be reassigned
|
|
7770
8054
|
this.scope.getReturnExpression().deoptimizePath(UNKNOWN_PATH);
|
|
7771
|
-
|
|
7772
|
-
for (const parameter of parameterList) {
|
|
7773
|
-
parameter.deoptimizePath(UNKNOWN_PATH);
|
|
7774
|
-
parameter.markReassigned();
|
|
7775
|
-
}
|
|
7776
|
-
}
|
|
8055
|
+
this.scope.deoptimizeAllParameters();
|
|
7777
8056
|
}
|
|
7778
8057
|
}
|
|
7779
8058
|
getLiteralValueAtPath(path, recursionTracker, origin) {
|
|
@@ -7797,8 +8076,8 @@ class FunctionBase extends NodeBase {
|
|
|
7797
8076
|
if (path.length > 0 || interaction.type !== INTERACTION_CALLED) {
|
|
7798
8077
|
return this.getObjectEntity().hasEffectsOnInteractionAtPath(path, interaction, context);
|
|
7799
8078
|
}
|
|
7800
|
-
if (this.
|
|
7801
|
-
return
|
|
8079
|
+
if (this.hasCachedEffects) {
|
|
8080
|
+
return true;
|
|
7802
8081
|
}
|
|
7803
8082
|
if (this.async) {
|
|
7804
8083
|
const { propertyReadSideEffects } = this.scope.context.options
|
|
@@ -7808,12 +8087,20 @@ class FunctionBase extends NodeBase {
|
|
|
7808
8087
|
(propertyReadSideEffects &&
|
|
7809
8088
|
(propertyReadSideEffects === 'always' ||
|
|
7810
8089
|
returnExpression.hasEffectsOnInteractionAtPath(['then'], NODE_INTERACTION_UNKNOWN_ACCESS, context)))) {
|
|
8090
|
+
this.hasCachedEffects = true;
|
|
7811
8091
|
return true;
|
|
7812
8092
|
}
|
|
7813
8093
|
}
|
|
7814
|
-
|
|
7815
|
-
|
|
8094
|
+
const { propertyReadSideEffects } = this.scope.context.options
|
|
8095
|
+
.treeshake;
|
|
8096
|
+
for (let index = 0; index < this.params.length; index++) {
|
|
8097
|
+
const parameter = this.params[index];
|
|
8098
|
+
if (parameter.hasEffects(context) ||
|
|
8099
|
+
(propertyReadSideEffects &&
|
|
8100
|
+
parameter.hasEffectsWhenDestructuring(context, EMPTY_PATH, interaction.args[index + 1] || UNDEFINED_EXPRESSION))) {
|
|
8101
|
+
this.hasCachedEffects = true;
|
|
7816
8102
|
return true;
|
|
8103
|
+
}
|
|
7817
8104
|
}
|
|
7818
8105
|
return false;
|
|
7819
8106
|
}
|
|
@@ -7831,21 +8118,17 @@ class FunctionBase extends NodeBase {
|
|
|
7831
8118
|
return variable?.getOnlyFunctionCallUsed() ?? false;
|
|
7832
8119
|
}
|
|
7833
8120
|
include(context, includeChildrenRecursively) {
|
|
7834
|
-
if (!this.
|
|
8121
|
+
if (!this.included)
|
|
8122
|
+
this.includeNode(context);
|
|
8123
|
+
if (!(this.parameterVariableValuesDeoptimized || this.onlyFunctionCallUsed())) {
|
|
7835
8124
|
this.parameterVariableValuesDeoptimized = true;
|
|
7836
|
-
this.
|
|
8125
|
+
this.scope.reassignAllParameters();
|
|
7837
8126
|
}
|
|
7838
|
-
if (!this.deoptimized)
|
|
7839
|
-
this.applyDeoptimizations();
|
|
7840
|
-
this.included = true;
|
|
7841
8127
|
const { brokenFlow } = context;
|
|
7842
8128
|
context.brokenFlow = false;
|
|
7843
8129
|
this.body.include(context, includeChildrenRecursively);
|
|
7844
8130
|
context.brokenFlow = brokenFlow;
|
|
7845
8131
|
}
|
|
7846
|
-
includeCallArguments(context, parameters) {
|
|
7847
|
-
this.scope.includeCallArguments(context, parameters);
|
|
7848
|
-
}
|
|
7849
8132
|
initialise() {
|
|
7850
8133
|
super.initialise();
|
|
7851
8134
|
if (this.body instanceof BlockStatement) {
|
|
@@ -7867,14 +8150,14 @@ class FunctionBase extends NodeBase {
|
|
|
7867
8150
|
// so that the scope already knows all parameters and can detect conflicts
|
|
7868
8151
|
// when parsing the body.
|
|
7869
8152
|
const parameters = (this.params = params.map((parameter) => new (context.getNodeConstructor(parameter.type))(this, scope).parseNode(parameter)));
|
|
7870
|
-
scope.addParameterVariables(parameters.map(parameter => parameter.declare('parameter', UNKNOWN_EXPRESSION)), parameters[parameters.length - 1] instanceof RestElement);
|
|
8153
|
+
scope.addParameterVariables(parameters.map(parameter => parameter.declare('parameter', EMPTY_PATH, UNKNOWN_EXPRESSION)), parameters[parameters.length - 1] instanceof RestElement);
|
|
7871
8154
|
this.body = new (context.getNodeConstructor(body.type))(this, bodyScope).parseNode(body);
|
|
7872
8155
|
return super.parseNode(esTreeNode);
|
|
7873
8156
|
}
|
|
7874
|
-
addArgumentToBeDeoptimized(_argument) { }
|
|
7875
|
-
applyDeoptimizations() { }
|
|
7876
8157
|
}
|
|
7877
8158
|
FunctionBase.prototype.preventChildBlockScope = true;
|
|
8159
|
+
FunctionBase.prototype.includeNode = onlyIncludeSelfNoDeoptimize;
|
|
8160
|
+
FunctionBase.prototype.applyDeoptimizations = doNotDeoptimize;
|
|
7878
8161
|
|
|
7879
8162
|
class FunctionNode extends FunctionBase {
|
|
7880
8163
|
constructor() {
|
|
@@ -7886,30 +8169,31 @@ class FunctionNode extends FunctionBase {
|
|
|
7886
8169
|
this.constructedEntity = new ObjectEntity(Object.create(null), OBJECT_PROTOTYPE);
|
|
7887
8170
|
// This makes sure that all deoptimizations of "this" are applied to the
|
|
7888
8171
|
// constructed entity.
|
|
7889
|
-
this.scope.thisVariable.
|
|
8172
|
+
this.scope.thisVariable.addArgumentValue(this.constructedEntity);
|
|
7890
8173
|
}
|
|
7891
8174
|
deoptimizeArgumentsOnInteractionAtPath(interaction, path, recursionTracker) {
|
|
7892
8175
|
super.deoptimizeArgumentsOnInteractionAtPath(interaction, path, recursionTracker);
|
|
7893
8176
|
if (interaction.type === INTERACTION_CALLED && path.length === 0 && interaction.args[0]) {
|
|
7894
8177
|
// args[0] is the "this" argument
|
|
7895
|
-
this.scope.thisVariable.
|
|
8178
|
+
this.scope.thisVariable.addArgumentValue(interaction.args[0]);
|
|
7896
8179
|
}
|
|
7897
8180
|
}
|
|
7898
8181
|
hasEffects(context) {
|
|
7899
|
-
if (!this.deoptimized)
|
|
7900
|
-
this.applyDeoptimizations();
|
|
7901
8182
|
if (this.annotationNoSideEffects) {
|
|
7902
8183
|
return false;
|
|
7903
8184
|
}
|
|
7904
8185
|
return !!this.id?.hasEffects(context);
|
|
7905
8186
|
}
|
|
7906
8187
|
hasEffectsOnInteractionAtPath(path, interaction, context) {
|
|
7907
|
-
if (
|
|
7908
|
-
|
|
7909
|
-
|
|
8188
|
+
if (this.annotationNoSideEffects &&
|
|
8189
|
+
path.length === 0 &&
|
|
8190
|
+
interaction.type === INTERACTION_CALLED) {
|
|
7910
8191
|
return false;
|
|
7911
8192
|
}
|
|
7912
|
-
if (
|
|
8193
|
+
if (super.hasEffectsOnInteractionAtPath(path, interaction, context)) {
|
|
8194
|
+
return true;
|
|
8195
|
+
}
|
|
8196
|
+
if (path.length === 0 && interaction.type === INTERACTION_CALLED) {
|
|
7913
8197
|
const thisInit = context.replacedVariableInits.get(this.scope.thisVariable);
|
|
7914
8198
|
context.replacedVariableInits.set(this.scope.thisVariable, interaction.withNew ? this.constructedEntity : UNKNOWN_EXPRESSION);
|
|
7915
8199
|
const { brokenFlow, ignore, replacedVariableInits } = context;
|
|
@@ -7920,8 +8204,10 @@ class FunctionNode extends FunctionBase {
|
|
|
7920
8204
|
returnYield: true,
|
|
7921
8205
|
this: interaction.withNew
|
|
7922
8206
|
};
|
|
7923
|
-
if (this.body.hasEffects(context))
|
|
8207
|
+
if (this.body.hasEffects(context)) {
|
|
8208
|
+
this.hasCachedEffects = true;
|
|
7924
8209
|
return true;
|
|
8210
|
+
}
|
|
7925
8211
|
context.brokenFlow = brokenFlow;
|
|
7926
8212
|
if (thisInit) {
|
|
7927
8213
|
replacedVariableInits.set(this.scope.thisVariable, thisInit);
|
|
@@ -7935,7 +8221,7 @@ class FunctionNode extends FunctionBase {
|
|
|
7935
8221
|
}
|
|
7936
8222
|
include(context, includeChildrenRecursively) {
|
|
7937
8223
|
super.include(context, includeChildrenRecursively);
|
|
7938
|
-
this.id?.include();
|
|
8224
|
+
this.id?.include(context);
|
|
7939
8225
|
const hasArguments = this.scope.argumentsVariable.included;
|
|
7940
8226
|
for (const parameter of this.params) {
|
|
7941
8227
|
if (!(parameter instanceof Identifier) || hasArguments) {
|
|
@@ -7943,12 +8229,18 @@ class FunctionNode extends FunctionBase {
|
|
|
7943
8229
|
}
|
|
7944
8230
|
}
|
|
7945
8231
|
}
|
|
8232
|
+
includeNode(context) {
|
|
8233
|
+
this.included = true;
|
|
8234
|
+
const hasArguments = this.scope.argumentsVariable.included;
|
|
8235
|
+
for (const parameter of this.params) {
|
|
8236
|
+
if (!(parameter instanceof Identifier) || hasArguments) {
|
|
8237
|
+
parameter.includePath(UNKNOWN_PATH, context);
|
|
8238
|
+
}
|
|
8239
|
+
}
|
|
8240
|
+
}
|
|
7946
8241
|
initialise() {
|
|
7947
8242
|
super.initialise();
|
|
7948
|
-
this.id?.declare('function', this);
|
|
7949
|
-
}
|
|
7950
|
-
addArgumentToBeDeoptimized(argument) {
|
|
7951
|
-
this.scope.argumentsVariable.addArgumentToBeDeoptimized(argument);
|
|
8243
|
+
this.id?.declare('function', EMPTY_PATH, this);
|
|
7952
8244
|
}
|
|
7953
8245
|
getObjectEntity() {
|
|
7954
8246
|
if (this.objectEntity !== null) {
|
|
@@ -7998,11 +8290,16 @@ function getFunctionIdInsertPosition(code, start) {
|
|
|
7998
8290
|
}
|
|
7999
8291
|
class ExportDefaultDeclaration extends NodeBase {
|
|
8000
8292
|
include(context, includeChildrenRecursively) {
|
|
8001
|
-
|
|
8293
|
+
this.included = true;
|
|
8294
|
+
this.declaration.include(context, includeChildrenRecursively);
|
|
8002
8295
|
if (includeChildrenRecursively) {
|
|
8003
|
-
this.scope.context.includeVariableInModule(this.variable);
|
|
8296
|
+
this.scope.context.includeVariableInModule(this.variable, UNKNOWN_PATH, context);
|
|
8004
8297
|
}
|
|
8005
8298
|
}
|
|
8299
|
+
includePath(path, context) {
|
|
8300
|
+
this.included = true;
|
|
8301
|
+
this.declaration.includePath(path, context);
|
|
8302
|
+
}
|
|
8006
8303
|
initialise() {
|
|
8007
8304
|
super.initialise();
|
|
8008
8305
|
const declaration = this.declaration;
|
|
@@ -8047,7 +8344,6 @@ class ExportDefaultDeclaration extends NodeBase {
|
|
|
8047
8344
|
}
|
|
8048
8345
|
this.declaration.render(code, options);
|
|
8049
8346
|
}
|
|
8050
|
-
applyDeoptimizations() { }
|
|
8051
8347
|
renderNamedDeclaration(code, declarationStart, idInsertPosition, options) {
|
|
8052
8348
|
const { exportNamesByVariable, format, snippets: { getPropertyAccess } } = options;
|
|
8053
8349
|
const name = this.variable.getName(getPropertyAccess);
|
|
@@ -8078,6 +8374,8 @@ class ExportDefaultDeclaration extends NodeBase {
|
|
|
8078
8374
|
}
|
|
8079
8375
|
}
|
|
8080
8376
|
ExportDefaultDeclaration.prototype.needsBoundaries = true;
|
|
8377
|
+
ExportDefaultDeclaration.prototype.includeNode = onlyIncludeSelfNoDeoptimize;
|
|
8378
|
+
ExportDefaultDeclaration.prototype.applyDeoptimizations = doNotDeoptimize;
|
|
8081
8379
|
|
|
8082
8380
|
const needsEscapeRegEx = /[\n\r'\\\u2028\u2029]/;
|
|
8083
8381
|
const quoteNewlineRegEx = /([\n\r'\u2028\u2029])/g;
|
|
@@ -8347,6 +8645,7 @@ class Literal extends NodeBase {
|
|
|
8347
8645
|
}
|
|
8348
8646
|
}
|
|
8349
8647
|
}
|
|
8648
|
+
Literal.prototype.includeNode = onlyIncludeSelf;
|
|
8350
8649
|
|
|
8351
8650
|
function getChainElementLiteralValueAtPath(element, object, path, recursionTracker, origin) {
|
|
8352
8651
|
if ('getLiteralValueAtPathAsChainElement' in object) {
|
|
@@ -8362,8 +8661,6 @@ function getChainElementLiteralValueAtPath(element, object, path, recursionTrack
|
|
|
8362
8661
|
return element.getLiteralValueAtPath(path, recursionTracker, origin);
|
|
8363
8662
|
}
|
|
8364
8663
|
|
|
8365
|
-
// To avoid infinite recursions
|
|
8366
|
-
const MAX_PATH_DEPTH = 7;
|
|
8367
8664
|
function getResolvablePropertyKey(memberExpression) {
|
|
8368
8665
|
return memberExpression.computed
|
|
8369
8666
|
? getResolvableComputedPropertyKey(memberExpression.property)
|
|
@@ -8462,18 +8759,27 @@ class MemberExpression extends NodeBase {
|
|
|
8462
8759
|
}
|
|
8463
8760
|
else if (!this.isUndefined) {
|
|
8464
8761
|
if (path.length < MAX_PATH_DEPTH) {
|
|
8465
|
-
this.object.deoptimizeArgumentsOnInteractionAtPath(interaction, [this.
|
|
8762
|
+
this.object.deoptimizeArgumentsOnInteractionAtPath(interaction, this.propertyKey === UnknownKey ? UNKNOWN_PATH : [this.propertyKey, ...path], recursionTracker);
|
|
8466
8763
|
}
|
|
8467
8764
|
else {
|
|
8468
8765
|
deoptimizeInteraction(interaction);
|
|
8469
8766
|
}
|
|
8470
8767
|
}
|
|
8471
8768
|
}
|
|
8769
|
+
deoptimizeAssignment(destructuredInitPath, init) {
|
|
8770
|
+
this.deoptimizePath(EMPTY_PATH);
|
|
8771
|
+
init.deoptimizePath([...destructuredInitPath, UnknownKey]);
|
|
8772
|
+
}
|
|
8472
8773
|
deoptimizeCache() {
|
|
8774
|
+
if (this.propertyKey === this.dynamicPropertyKey)
|
|
8775
|
+
return;
|
|
8473
8776
|
const { expressionsToBeDeoptimized, object } = this;
|
|
8474
8777
|
this.expressionsToBeDeoptimized = parseAst_js.EMPTY_ARRAY;
|
|
8475
|
-
this.
|
|
8778
|
+
this.dynamicPropertyKey = this.propertyKey;
|
|
8476
8779
|
object.deoptimizePath(UNKNOWN_PATH);
|
|
8780
|
+
if (this.included) {
|
|
8781
|
+
object.includePath(UNKNOWN_PATH, createInclusionContext());
|
|
8782
|
+
}
|
|
8477
8783
|
for (const expression of expressionsToBeDeoptimized) {
|
|
8478
8784
|
expression.deoptimizeCache();
|
|
8479
8785
|
}
|
|
@@ -8484,11 +8790,13 @@ class MemberExpression extends NodeBase {
|
|
|
8484
8790
|
if (this.variable) {
|
|
8485
8791
|
this.variable.deoptimizePath(path);
|
|
8486
8792
|
}
|
|
8487
|
-
else if (!this.isUndefined
|
|
8488
|
-
const propertyKey = this
|
|
8793
|
+
else if (!this.isUndefined) {
|
|
8794
|
+
const { propertyKey } = this;
|
|
8489
8795
|
this.object.deoptimizePath([
|
|
8490
8796
|
propertyKey === UnknownKey ? UnknownNonAccessorKey : propertyKey,
|
|
8491
|
-
...path
|
|
8797
|
+
...(path.length < MAX_PATH_DEPTH
|
|
8798
|
+
? path
|
|
8799
|
+
: [...path.slice(0, MAX_PATH_DEPTH), UnknownKey])
|
|
8492
8800
|
]);
|
|
8493
8801
|
}
|
|
8494
8802
|
}
|
|
@@ -8499,9 +8807,11 @@ class MemberExpression extends NodeBase {
|
|
|
8499
8807
|
if (this.isUndefined) {
|
|
8500
8808
|
return undefined;
|
|
8501
8809
|
}
|
|
8502
|
-
|
|
8503
|
-
|
|
8504
|
-
|
|
8810
|
+
const propertyKey = this.getDynamicPropertyKey();
|
|
8811
|
+
if (propertyKey !== UnknownKey && path.length < MAX_PATH_DEPTH) {
|
|
8812
|
+
if (propertyKey !== this.propertyKey)
|
|
8813
|
+
this.expressionsToBeDeoptimized.push(origin);
|
|
8814
|
+
return this.object.getLiteralValueAtPath([propertyKey, ...path], recursionTracker, origin);
|
|
8505
8815
|
}
|
|
8506
8816
|
return UnknownValue;
|
|
8507
8817
|
}
|
|
@@ -8521,9 +8831,11 @@ class MemberExpression extends NodeBase {
|
|
|
8521
8831
|
if (this.isUndefined) {
|
|
8522
8832
|
return [UNDEFINED_EXPRESSION, false];
|
|
8523
8833
|
}
|
|
8524
|
-
|
|
8525
|
-
|
|
8526
|
-
|
|
8834
|
+
const propertyKey = this.getDynamicPropertyKey();
|
|
8835
|
+
if (propertyKey !== UnknownKey && path.length < MAX_PATH_DEPTH) {
|
|
8836
|
+
if (propertyKey !== this.propertyKey)
|
|
8837
|
+
this.expressionsToBeDeoptimized.push(origin);
|
|
8838
|
+
return this.object.getReturnExpressionWhenCalledAtPath([propertyKey, ...path], interaction, recursionTracker, origin);
|
|
8527
8839
|
}
|
|
8528
8840
|
return UNKNOWN_RETURN_EXPRESSION;
|
|
8529
8841
|
}
|
|
@@ -8569,14 +8881,45 @@ class MemberExpression extends NodeBase {
|
|
|
8569
8881
|
return true;
|
|
8570
8882
|
}
|
|
8571
8883
|
if (path.length < MAX_PATH_DEPTH) {
|
|
8572
|
-
return this.object.hasEffectsOnInteractionAtPath([this.
|
|
8884
|
+
return this.object.hasEffectsOnInteractionAtPath([this.getDynamicPropertyKey(), ...path], interaction, context);
|
|
8573
8885
|
}
|
|
8574
8886
|
return true;
|
|
8575
8887
|
}
|
|
8888
|
+
hasEffectsWhenDestructuring(context, destructuredInitPath, init) {
|
|
8889
|
+
return (destructuredInitPath.length > 0 &&
|
|
8890
|
+
init.hasEffectsOnInteractionAtPath(destructuredInitPath, NODE_INTERACTION_UNKNOWN_ACCESS, context));
|
|
8891
|
+
}
|
|
8576
8892
|
include(context, includeChildrenRecursively) {
|
|
8893
|
+
if (!this.included)
|
|
8894
|
+
this.includeNode(context);
|
|
8895
|
+
this.object.include(context, includeChildrenRecursively);
|
|
8896
|
+
this.property.include(context, includeChildrenRecursively);
|
|
8897
|
+
}
|
|
8898
|
+
includeNode(context) {
|
|
8899
|
+
this.included = true;
|
|
8577
8900
|
if (!this.deoptimized)
|
|
8578
8901
|
this.applyDeoptimizations();
|
|
8579
|
-
this.
|
|
8902
|
+
if (this.variable) {
|
|
8903
|
+
this.scope.context.includeVariableInModule(this.variable, EMPTY_PATH, context);
|
|
8904
|
+
}
|
|
8905
|
+
else if (!this.isUndefined) {
|
|
8906
|
+
this.object.includePath([this.propertyKey], context);
|
|
8907
|
+
}
|
|
8908
|
+
}
|
|
8909
|
+
includePath(path, context) {
|
|
8910
|
+
if (!this.included)
|
|
8911
|
+
this.includeNode(context);
|
|
8912
|
+
if (this.variable) {
|
|
8913
|
+
this.variable?.includePath(path, context);
|
|
8914
|
+
}
|
|
8915
|
+
else if (!this.isUndefined) {
|
|
8916
|
+
this.object.includePath([
|
|
8917
|
+
this.propertyKey,
|
|
8918
|
+
...(path.length < MAX_PATH_DEPTH
|
|
8919
|
+
? path
|
|
8920
|
+
: [...path.slice(0, MAX_PATH_DEPTH), UnknownKey])
|
|
8921
|
+
], context);
|
|
8922
|
+
}
|
|
8580
8923
|
}
|
|
8581
8924
|
includeAsAssignmentTarget(context, includeChildrenRecursively, deoptimizeAccess) {
|
|
8582
8925
|
if (!this.assignmentDeoptimized)
|
|
@@ -8585,20 +8928,34 @@ class MemberExpression extends NodeBase {
|
|
|
8585
8928
|
this.include(context, includeChildrenRecursively);
|
|
8586
8929
|
}
|
|
8587
8930
|
else {
|
|
8588
|
-
this.
|
|
8931
|
+
if (!this.included)
|
|
8932
|
+
this.includeNode(context);
|
|
8933
|
+
this.object.include(context, includeChildrenRecursively);
|
|
8934
|
+
this.property.include(context, includeChildrenRecursively);
|
|
8589
8935
|
}
|
|
8590
8936
|
}
|
|
8591
|
-
includeCallArguments(context,
|
|
8937
|
+
includeCallArguments(context, interaction) {
|
|
8592
8938
|
if (this.variable) {
|
|
8593
|
-
this.variable.includeCallArguments(context,
|
|
8939
|
+
this.variable.includeCallArguments(context, interaction);
|
|
8594
8940
|
}
|
|
8595
8941
|
else {
|
|
8596
|
-
super.includeCallArguments(context,
|
|
8942
|
+
super.includeCallArguments(context, interaction);
|
|
8943
|
+
}
|
|
8944
|
+
}
|
|
8945
|
+
includeDestructuredIfNecessary(context, destructuredInitPath, init) {
|
|
8946
|
+
if ((this.included ||=
|
|
8947
|
+
destructuredInitPath.length > 0 &&
|
|
8948
|
+
!context.brokenFlow &&
|
|
8949
|
+
init.hasEffectsOnInteractionAtPath(destructuredInitPath, NODE_INTERACTION_UNKNOWN_ACCESS, createHasEffectsContext()))) {
|
|
8950
|
+
init.include(context, false);
|
|
8951
|
+
return true;
|
|
8597
8952
|
}
|
|
8953
|
+
return false;
|
|
8598
8954
|
}
|
|
8599
8955
|
initialise() {
|
|
8600
8956
|
super.initialise();
|
|
8601
|
-
this.
|
|
8957
|
+
this.dynamicPropertyKey = getResolvablePropertyKey(this);
|
|
8958
|
+
this.propertyKey = this.dynamicPropertyKey === null ? UnknownKey : this.dynamicPropertyKey;
|
|
8602
8959
|
this.accessInteraction = { args: [this.object], type: INTERACTION_ACCESSED };
|
|
8603
8960
|
}
|
|
8604
8961
|
render(code, options, { renderedParentType, isCalleeOfRenderedParent, renderedSurroundingElement } = parseAst_js.BLANK) {
|
|
@@ -8635,8 +8992,7 @@ class MemberExpression extends NodeBase {
|
|
|
8635
8992
|
this.bound &&
|
|
8636
8993
|
propertyReadSideEffects &&
|
|
8637
8994
|
!(this.variable || this.isUndefined)) {
|
|
8638
|
-
|
|
8639
|
-
this.object.deoptimizeArgumentsOnInteractionAtPath(this.accessInteraction, [propertyKey], SHARED_RECURSION_TRACKER);
|
|
8995
|
+
this.object.deoptimizeArgumentsOnInteractionAtPath(this.accessInteraction, [this.propertyKey], SHARED_RECURSION_TRACKER);
|
|
8640
8996
|
this.scope.context.requestTreeshakingPass();
|
|
8641
8997
|
}
|
|
8642
8998
|
if (this.variable) {
|
|
@@ -8653,7 +9009,7 @@ class MemberExpression extends NodeBase {
|
|
|
8653
9009
|
this.bound &&
|
|
8654
9010
|
propertyReadSideEffects &&
|
|
8655
9011
|
!(this.variable || this.isUndefined)) {
|
|
8656
|
-
this.object.deoptimizeArgumentsOnInteractionAtPath(this.assignmentInteraction, [this.
|
|
9012
|
+
this.object.deoptimizeArgumentsOnInteractionAtPath(this.assignmentInteraction, [this.propertyKey], SHARED_RECURSION_TRACKER);
|
|
8657
9013
|
this.scope.context.requestTreeshakingPass();
|
|
8658
9014
|
}
|
|
8659
9015
|
}
|
|
@@ -8662,24 +9018,24 @@ class MemberExpression extends NodeBase {
|
|
|
8662
9018
|
const variable = this.scope.findVariable(this.object.name);
|
|
8663
9019
|
if (variable.isNamespace) {
|
|
8664
9020
|
if (this.variable) {
|
|
8665
|
-
this.scope.context.includeVariableInModule(this.variable);
|
|
9021
|
+
this.scope.context.includeVariableInModule(this.variable, UNKNOWN_PATH, createInclusionContext());
|
|
8666
9022
|
}
|
|
8667
9023
|
this.scope.context.log(parseAst_js.LOGLEVEL_WARN, parseAst_js.logIllegalImportReassignment(this.object.name, this.scope.context.module.id), this.start);
|
|
8668
9024
|
}
|
|
8669
9025
|
}
|
|
8670
9026
|
}
|
|
8671
|
-
|
|
8672
|
-
if (this.
|
|
8673
|
-
this.
|
|
9027
|
+
getDynamicPropertyKey() {
|
|
9028
|
+
if (this.dynamicPropertyKey === null) {
|
|
9029
|
+
this.dynamicPropertyKey = this.propertyKey;
|
|
8674
9030
|
const value = this.property.getLiteralValueAtPath(EMPTY_PATH, SHARED_RECURSION_TRACKER, this);
|
|
8675
|
-
return (this.
|
|
9031
|
+
return (this.dynamicPropertyKey =
|
|
8676
9032
|
value === SymbolToStringTag
|
|
8677
9033
|
? value
|
|
8678
9034
|
: typeof value === 'symbol'
|
|
8679
9035
|
? UnknownKey
|
|
8680
9036
|
: String(value));
|
|
8681
9037
|
}
|
|
8682
|
-
return this.
|
|
9038
|
+
return this.dynamicPropertyKey;
|
|
8683
9039
|
}
|
|
8684
9040
|
hasAccessEffect(context) {
|
|
8685
9041
|
const { propertyReadSideEffects } = this.scope.context.options
|
|
@@ -8687,17 +9043,7 @@ class MemberExpression extends NodeBase {
|
|
|
8687
9043
|
return (!(this.variable || this.isUndefined) &&
|
|
8688
9044
|
propertyReadSideEffects &&
|
|
8689
9045
|
(propertyReadSideEffects === 'always' ||
|
|
8690
|
-
this.object.hasEffectsOnInteractionAtPath([this.
|
|
8691
|
-
}
|
|
8692
|
-
includeProperties(context, includeChildrenRecursively) {
|
|
8693
|
-
if (!this.included) {
|
|
8694
|
-
this.included = true;
|
|
8695
|
-
if (this.variable) {
|
|
8696
|
-
this.scope.context.includeVariableInModule(this.variable);
|
|
8697
|
-
}
|
|
8698
|
-
}
|
|
8699
|
-
this.object.include(context, includeChildrenRecursively);
|
|
8700
|
-
this.property.include(context, includeChildrenRecursively);
|
|
9046
|
+
this.object.hasEffectsOnInteractionAtPath([this.getDynamicPropertyKey()], this.accessInteraction, context)));
|
|
8701
9047
|
}
|
|
8702
9048
|
}
|
|
8703
9049
|
function resolveNamespaceVariables(baseVariable, path, astContext) {
|
|
@@ -8741,18 +9087,20 @@ class MetaProperty extends NodeBase {
|
|
|
8741
9087
|
return path.length > 1 || type !== INTERACTION_ACCESSED;
|
|
8742
9088
|
}
|
|
8743
9089
|
include() {
|
|
8744
|
-
if (!this.included)
|
|
8745
|
-
this.
|
|
8746
|
-
|
|
8747
|
-
|
|
8748
|
-
|
|
8749
|
-
|
|
8750
|
-
|
|
8751
|
-
|
|
8752
|
-
|
|
8753
|
-
|
|
8754
|
-
|
|
8755
|
-
|
|
9090
|
+
if (!this.included)
|
|
9091
|
+
this.includeNode();
|
|
9092
|
+
}
|
|
9093
|
+
includeNode() {
|
|
9094
|
+
this.included = true;
|
|
9095
|
+
if (this.meta.name === IMPORT) {
|
|
9096
|
+
this.scope.context.addImportMeta(this);
|
|
9097
|
+
const parent = this.parent;
|
|
9098
|
+
const metaProperty = (this.metaProperty =
|
|
9099
|
+
parent instanceof MemberExpression && typeof parent.propertyKey === 'string'
|
|
9100
|
+
? parent.propertyKey
|
|
9101
|
+
: null);
|
|
9102
|
+
if (metaProperty?.startsWith(FILE_PREFIX)) {
|
|
9103
|
+
this.referenceId = metaProperty.slice(FILE_PREFIX.length);
|
|
8756
9104
|
}
|
|
8757
9105
|
}
|
|
8758
9106
|
}
|
|
@@ -8859,7 +9207,7 @@ class UndefinedVariable extends Variable {
|
|
|
8859
9207
|
|
|
8860
9208
|
class ExportDefaultVariable extends LocalVariable {
|
|
8861
9209
|
constructor(name, exportDefaultDeclaration, context) {
|
|
8862
|
-
super(name, exportDefaultDeclaration, exportDefaultDeclaration.declaration, context, 'other');
|
|
9210
|
+
super(name, exportDefaultDeclaration, exportDefaultDeclaration.declaration, EMPTY_PATH, context, 'other');
|
|
8863
9211
|
this.hasId = false;
|
|
8864
9212
|
this.originalId = null;
|
|
8865
9213
|
this.originalVariable = null;
|
|
@@ -9008,8 +9356,8 @@ class NamespaceVariable extends Variable {
|
|
|
9008
9356
|
return (!memberVariable ||
|
|
9009
9357
|
memberVariable.hasEffectsOnInteractionAtPath(path.slice(1), interaction, context));
|
|
9010
9358
|
}
|
|
9011
|
-
|
|
9012
|
-
super.
|
|
9359
|
+
includePath(path, context) {
|
|
9360
|
+
super.includePath(path, context);
|
|
9013
9361
|
this.context.includeAllExports();
|
|
9014
9362
|
}
|
|
9015
9363
|
prepare(accessedGlobalsByScope) {
|
|
@@ -9102,9 +9450,9 @@ class SyntheticNamedExportVariable extends Variable {
|
|
|
9102
9450
|
getName(getPropertyAccess) {
|
|
9103
9451
|
return `${this.syntheticNamespace.getName(getPropertyAccess)}${getPropertyAccess(this.name)}`;
|
|
9104
9452
|
}
|
|
9105
|
-
|
|
9106
|
-
super.
|
|
9107
|
-
this.context.includeVariableInModule(this.syntheticNamespace);
|
|
9453
|
+
includePath(path, context) {
|
|
9454
|
+
super.includePath(path, context);
|
|
9455
|
+
this.context.includeVariableInModule(this.syntheticNamespace, path, context);
|
|
9108
9456
|
}
|
|
9109
9457
|
setRenderNames(baseName, name) {
|
|
9110
9458
|
super.setRenderNames(baseName, name);
|
|
@@ -12280,21 +12628,37 @@ class ArrayPattern extends NodeBase {
|
|
|
12280
12628
|
element?.addExportedVariables(variables, exportNamesByVariable);
|
|
12281
12629
|
}
|
|
12282
12630
|
}
|
|
12283
|
-
declare(kind) {
|
|
12631
|
+
declare(kind, destructuredInitPath, init) {
|
|
12284
12632
|
const variables = [];
|
|
12633
|
+
const includedPatternPath = getIncludedPatternPath(destructuredInitPath);
|
|
12285
12634
|
for (const element of this.elements) {
|
|
12286
12635
|
if (element !== null) {
|
|
12287
|
-
variables.push(...element.declare(kind,
|
|
12636
|
+
variables.push(...element.declare(kind, includedPatternPath, init));
|
|
12288
12637
|
}
|
|
12289
12638
|
}
|
|
12290
12639
|
return variables;
|
|
12291
12640
|
}
|
|
12641
|
+
deoptimizeAssignment(destructuredInitPath, init) {
|
|
12642
|
+
const includedPatternPath = getIncludedPatternPath(destructuredInitPath);
|
|
12643
|
+
for (const element of this.elements) {
|
|
12644
|
+
element?.deoptimizeAssignment(includedPatternPath, init);
|
|
12645
|
+
}
|
|
12646
|
+
}
|
|
12292
12647
|
// Patterns can only be deoptimized at the empty path at the moment
|
|
12293
12648
|
deoptimizePath() {
|
|
12294
12649
|
for (const element of this.elements) {
|
|
12295
12650
|
element?.deoptimizePath(EMPTY_PATH);
|
|
12296
12651
|
}
|
|
12297
12652
|
}
|
|
12653
|
+
hasEffectsWhenDestructuring(context, destructuredInitPath, init) {
|
|
12654
|
+
const includedPatternPath = getIncludedPatternPath(destructuredInitPath);
|
|
12655
|
+
for (const element of this.elements) {
|
|
12656
|
+
if (element?.hasEffectsWhenDestructuring(context, includedPatternPath, init)) {
|
|
12657
|
+
return true;
|
|
12658
|
+
}
|
|
12659
|
+
}
|
|
12660
|
+
return false;
|
|
12661
|
+
}
|
|
12298
12662
|
// Patterns are only checked at the empty path at the moment
|
|
12299
12663
|
hasEffectsOnInteractionAtPath(_path, interaction, context) {
|
|
12300
12664
|
for (const element of this.elements) {
|
|
@@ -12303,12 +12667,38 @@ class ArrayPattern extends NodeBase {
|
|
|
12303
12667
|
}
|
|
12304
12668
|
return false;
|
|
12305
12669
|
}
|
|
12670
|
+
includeDestructuredIfNecessary(context, destructuredInitPath, init) {
|
|
12671
|
+
let included = false;
|
|
12672
|
+
const includedPatternPath = getIncludedPatternPath(destructuredInitPath);
|
|
12673
|
+
for (const element of this.elements) {
|
|
12674
|
+
if (element) {
|
|
12675
|
+
element.included ||= included;
|
|
12676
|
+
included =
|
|
12677
|
+
element.includeDestructuredIfNecessary(context, includedPatternPath, init) || included;
|
|
12678
|
+
}
|
|
12679
|
+
}
|
|
12680
|
+
if (included) {
|
|
12681
|
+
// This is necessary so that if any pattern element is included, all are
|
|
12682
|
+
// included for proper deconflicting
|
|
12683
|
+
for (const element of this.elements) {
|
|
12684
|
+
if (element && !element.included) {
|
|
12685
|
+
element.included = true;
|
|
12686
|
+
element.includeDestructuredIfNecessary(context, includedPatternPath, init);
|
|
12687
|
+
}
|
|
12688
|
+
}
|
|
12689
|
+
}
|
|
12690
|
+
return (this.included ||= included);
|
|
12691
|
+
}
|
|
12306
12692
|
markDeclarationReached() {
|
|
12307
12693
|
for (const element of this.elements) {
|
|
12308
12694
|
element?.markDeclarationReached();
|
|
12309
12695
|
}
|
|
12310
12696
|
}
|
|
12311
12697
|
}
|
|
12698
|
+
ArrayPattern.prototype.includeNode = onlyIncludeSelf;
|
|
12699
|
+
const getIncludedPatternPath = (destructuredInitPath) => destructuredInitPath.at(-1) === UnknownKey
|
|
12700
|
+
? destructuredInitPath
|
|
12701
|
+
: [...destructuredInitPath, UnknownInteger];
|
|
12312
12702
|
|
|
12313
12703
|
class ArrowFunctionExpression extends FunctionBase {
|
|
12314
12704
|
constructor() {
|
|
@@ -12325,17 +12715,17 @@ class ArrowFunctionExpression extends FunctionBase {
|
|
|
12325
12715
|
this.scope = new ReturnValueScope(parentScope, false);
|
|
12326
12716
|
}
|
|
12327
12717
|
hasEffects() {
|
|
12328
|
-
if (!this.deoptimized)
|
|
12329
|
-
this.applyDeoptimizations();
|
|
12330
12718
|
return false;
|
|
12331
12719
|
}
|
|
12332
12720
|
hasEffectsOnInteractionAtPath(path, interaction, context) {
|
|
12721
|
+
if (this.annotationNoSideEffects &&
|
|
12722
|
+
path.length === 0 &&
|
|
12723
|
+
interaction.type === INTERACTION_CALLED) {
|
|
12724
|
+
return false;
|
|
12725
|
+
}
|
|
12333
12726
|
if (super.hasEffectsOnInteractionAtPath(path, interaction, context)) {
|
|
12334
12727
|
return true;
|
|
12335
12728
|
}
|
|
12336
|
-
if (this.annotationNoSideEffects) {
|
|
12337
|
-
return false;
|
|
12338
|
-
}
|
|
12339
12729
|
if (interaction.type === INTERACTION_CALLED) {
|
|
12340
12730
|
const { ignore, brokenFlow } = context;
|
|
12341
12731
|
context.ignore = {
|
|
@@ -12365,6 +12755,15 @@ class ArrowFunctionExpression extends FunctionBase {
|
|
|
12365
12755
|
}
|
|
12366
12756
|
}
|
|
12367
12757
|
}
|
|
12758
|
+
includeNode(context) {
|
|
12759
|
+
this.included = true;
|
|
12760
|
+
this.body.includePath(UNKNOWN_PATH, context);
|
|
12761
|
+
for (const parameter of this.params) {
|
|
12762
|
+
if (!(parameter instanceof Identifier)) {
|
|
12763
|
+
parameter.includePath(UNKNOWN_PATH, context);
|
|
12764
|
+
}
|
|
12765
|
+
}
|
|
12766
|
+
}
|
|
12368
12767
|
getObjectEntity() {
|
|
12369
12768
|
if (this.objectEntity !== null) {
|
|
12370
12769
|
return this.objectEntity;
|
|
@@ -12384,13 +12783,18 @@ class ObjectPattern extends NodeBase {
|
|
|
12384
12783
|
}
|
|
12385
12784
|
}
|
|
12386
12785
|
}
|
|
12387
|
-
declare(kind, init) {
|
|
12786
|
+
declare(kind, destructuredInitPath, init) {
|
|
12388
12787
|
const variables = [];
|
|
12389
12788
|
for (const property of this.properties) {
|
|
12390
|
-
variables.push(...property.declare(kind, init));
|
|
12789
|
+
variables.push(...property.declare(kind, destructuredInitPath, init));
|
|
12391
12790
|
}
|
|
12392
12791
|
return variables;
|
|
12393
12792
|
}
|
|
12793
|
+
deoptimizeAssignment(destructuredInitPath, init) {
|
|
12794
|
+
for (const property of this.properties) {
|
|
12795
|
+
property.deoptimizeAssignment(destructuredInitPath, init);
|
|
12796
|
+
}
|
|
12797
|
+
}
|
|
12394
12798
|
deoptimizePath(path) {
|
|
12395
12799
|
if (path.length === 0) {
|
|
12396
12800
|
for (const property of this.properties) {
|
|
@@ -12408,12 +12812,46 @@ class ObjectPattern extends NodeBase {
|
|
|
12408
12812
|
}
|
|
12409
12813
|
return false;
|
|
12410
12814
|
}
|
|
12815
|
+
hasEffectsWhenDestructuring(context, destructuredInitPath, init) {
|
|
12816
|
+
for (const property of this.properties) {
|
|
12817
|
+
if (property.hasEffectsWhenDestructuring(context, destructuredInitPath, init))
|
|
12818
|
+
return true;
|
|
12819
|
+
}
|
|
12820
|
+
return false;
|
|
12821
|
+
}
|
|
12822
|
+
includeDestructuredIfNecessary(context, destructuredInitPath, init) {
|
|
12823
|
+
let included = false;
|
|
12824
|
+
for (const property of this.properties) {
|
|
12825
|
+
included =
|
|
12826
|
+
property.includeDestructuredIfNecessary(context, destructuredInitPath, init) || included;
|
|
12827
|
+
}
|
|
12828
|
+
return (this.included ||= included);
|
|
12829
|
+
}
|
|
12411
12830
|
markDeclarationReached() {
|
|
12412
12831
|
for (const property of this.properties) {
|
|
12413
12832
|
property.markDeclarationReached();
|
|
12414
12833
|
}
|
|
12415
12834
|
}
|
|
12835
|
+
render(code, options) {
|
|
12836
|
+
if (this.properties.length > 0) {
|
|
12837
|
+
const separatedNodes = getCommaSeparatedNodesWithBoundaries(this.properties, code, this.start + 1, this.end - 1);
|
|
12838
|
+
let lastSeparatorPos = null;
|
|
12839
|
+
for (const { node, separator, start, end } of separatedNodes) {
|
|
12840
|
+
if (!node.included) {
|
|
12841
|
+
treeshakeNode(node, code, start, end);
|
|
12842
|
+
continue;
|
|
12843
|
+
}
|
|
12844
|
+
lastSeparatorPos = separator;
|
|
12845
|
+
node.render(code, options);
|
|
12846
|
+
}
|
|
12847
|
+
if (lastSeparatorPos) {
|
|
12848
|
+
code.remove(lastSeparatorPos, this.end - 1);
|
|
12849
|
+
}
|
|
12850
|
+
}
|
|
12851
|
+
}
|
|
12416
12852
|
}
|
|
12853
|
+
ObjectPattern.prototype.includeNode = onlyIncludeSelfNoDeoptimize;
|
|
12854
|
+
ObjectPattern.prototype.applyDeoptimizations = doNotDeoptimize;
|
|
12417
12855
|
|
|
12418
12856
|
class AssignmentExpression extends NodeBase {
|
|
12419
12857
|
hasEffects(context) {
|
|
@@ -12422,7 +12860,9 @@ class AssignmentExpression extends NodeBase {
|
|
|
12422
12860
|
this.applyDeoptimizations();
|
|
12423
12861
|
// MemberExpressions do not access the property before assignments if the
|
|
12424
12862
|
// operator is '='.
|
|
12425
|
-
return (right.hasEffects(context) ||
|
|
12863
|
+
return (right.hasEffects(context) ||
|
|
12864
|
+
left.hasEffectsAsAssignmentTarget(context, operator !== '=') ||
|
|
12865
|
+
this.left.hasEffectsWhenDestructuring?.(context, EMPTY_PATH, right));
|
|
12426
12866
|
}
|
|
12427
12867
|
hasEffectsOnInteractionAtPath(path, interaction, context) {
|
|
12428
12868
|
return this.right.hasEffectsOnInteractionAtPath(path, interaction, context);
|
|
@@ -12431,15 +12871,24 @@ class AssignmentExpression extends NodeBase {
|
|
|
12431
12871
|
const { deoptimized, left, right, operator } = this;
|
|
12432
12872
|
if (!deoptimized)
|
|
12433
12873
|
this.applyDeoptimizations();
|
|
12434
|
-
this.included
|
|
12874
|
+
if (!this.included)
|
|
12875
|
+
this.includeNode(context);
|
|
12876
|
+
const hasEffectsContext = createHasEffectsContext();
|
|
12435
12877
|
if (includeChildrenRecursively ||
|
|
12436
12878
|
operator !== '=' ||
|
|
12437
12879
|
left.included ||
|
|
12438
|
-
left.hasEffectsAsAssignmentTarget(
|
|
12880
|
+
left.hasEffectsAsAssignmentTarget(hasEffectsContext, false) ||
|
|
12881
|
+
left.hasEffectsWhenDestructuring?.(hasEffectsContext, EMPTY_PATH, right)) {
|
|
12439
12882
|
left.includeAsAssignmentTarget(context, includeChildrenRecursively, operator !== '=');
|
|
12440
12883
|
}
|
|
12441
12884
|
right.include(context, includeChildrenRecursively);
|
|
12442
12885
|
}
|
|
12886
|
+
includeNode(context) {
|
|
12887
|
+
this.included = true;
|
|
12888
|
+
if (!this.deoptimized)
|
|
12889
|
+
this.applyDeoptimizations();
|
|
12890
|
+
this.right.includePath(UNKNOWN_PATH, context);
|
|
12891
|
+
}
|
|
12443
12892
|
initialise() {
|
|
12444
12893
|
super.initialise();
|
|
12445
12894
|
if (this.left instanceof Identifier) {
|
|
@@ -12500,8 +12949,7 @@ class AssignmentExpression extends NodeBase {
|
|
|
12500
12949
|
}
|
|
12501
12950
|
applyDeoptimizations() {
|
|
12502
12951
|
this.deoptimized = true;
|
|
12503
|
-
this.left.
|
|
12504
|
-
this.right.deoptimizePath(UNKNOWN_PATH);
|
|
12952
|
+
this.left.deoptimizeAssignment(EMPTY_PATH, this.right);
|
|
12505
12953
|
this.scope.context.requestTreeshakingPass();
|
|
12506
12954
|
}
|
|
12507
12955
|
}
|
|
@@ -12510,8 +12958,11 @@ class AssignmentPattern extends NodeBase {
|
|
|
12510
12958
|
addExportedVariables(variables, exportNamesByVariable) {
|
|
12511
12959
|
this.left.addExportedVariables(variables, exportNamesByVariable);
|
|
12512
12960
|
}
|
|
12513
|
-
declare(kind, init) {
|
|
12514
|
-
return this.left.declare(kind, init);
|
|
12961
|
+
declare(kind, destructuredInitPath, init) {
|
|
12962
|
+
return this.left.declare(kind, destructuredInitPath, init);
|
|
12963
|
+
}
|
|
12964
|
+
deoptimizeAssignment(destructuredInitPath, init) {
|
|
12965
|
+
this.left.deoptimizeAssignment(destructuredInitPath, init);
|
|
12515
12966
|
}
|
|
12516
12967
|
deoptimizePath(path) {
|
|
12517
12968
|
if (path.length === 0) {
|
|
@@ -12521,6 +12972,29 @@ class AssignmentPattern extends NodeBase {
|
|
|
12521
12972
|
hasEffectsOnInteractionAtPath(path, interaction, context) {
|
|
12522
12973
|
return (path.length > 0 || this.left.hasEffectsOnInteractionAtPath(EMPTY_PATH, interaction, context));
|
|
12523
12974
|
}
|
|
12975
|
+
hasEffectsWhenDestructuring(context, destructuredInitPath, init) {
|
|
12976
|
+
return this.left.hasEffectsWhenDestructuring(context, destructuredInitPath, init);
|
|
12977
|
+
}
|
|
12978
|
+
includeDestructuredIfNecessary(context, destructuredInitPath, init) {
|
|
12979
|
+
let included = this.left.includeDestructuredIfNecessary(context, destructuredInitPath, init) ||
|
|
12980
|
+
this.included;
|
|
12981
|
+
if ((included ||= this.right.shouldBeIncluded(context))) {
|
|
12982
|
+
this.right.include(context, false);
|
|
12983
|
+
if (!this.left.included) {
|
|
12984
|
+
this.left.included = true;
|
|
12985
|
+
// Unfortunately, we need to include the left side again now, so that
|
|
12986
|
+
// any declared variables are properly included.
|
|
12987
|
+
this.left.includeDestructuredIfNecessary(context, destructuredInitPath, init);
|
|
12988
|
+
}
|
|
12989
|
+
}
|
|
12990
|
+
return (this.included = included);
|
|
12991
|
+
}
|
|
12992
|
+
includeNode(context) {
|
|
12993
|
+
this.included = true;
|
|
12994
|
+
if (!this.deoptimized)
|
|
12995
|
+
this.applyDeoptimizations();
|
|
12996
|
+
this.right.includePath(UNKNOWN_PATH, context);
|
|
12997
|
+
}
|
|
12524
12998
|
markDeclarationReached() {
|
|
12525
12999
|
this.left.markDeclarationReached();
|
|
12526
13000
|
}
|
|
@@ -12543,22 +13017,34 @@ class AwaitExpression extends NodeBase {
|
|
|
12543
13017
|
return true;
|
|
12544
13018
|
}
|
|
12545
13019
|
include(context, includeChildrenRecursively) {
|
|
13020
|
+
if (!this.included)
|
|
13021
|
+
this.includeNode(context);
|
|
13022
|
+
this.argument.include(context, includeChildrenRecursively);
|
|
13023
|
+
}
|
|
13024
|
+
includeNode(context) {
|
|
13025
|
+
this.included = true;
|
|
12546
13026
|
if (!this.deoptimized)
|
|
12547
13027
|
this.applyDeoptimizations();
|
|
12548
|
-
if (!this.
|
|
12549
|
-
|
|
12550
|
-
|
|
12551
|
-
|
|
12552
|
-
|
|
12553
|
-
|
|
12554
|
-
|
|
12555
|
-
} while ((parent = parent.parent));
|
|
12556
|
-
this.scope.context.usesTopLevelAwait = true;
|
|
12557
|
-
}
|
|
13028
|
+
checkTopLevelAwait: if (!this.scope.context.usesTopLevelAwait) {
|
|
13029
|
+
let parent = this.parent;
|
|
13030
|
+
do {
|
|
13031
|
+
if (parent instanceof FunctionNode || parent instanceof ArrowFunctionExpression)
|
|
13032
|
+
break checkTopLevelAwait;
|
|
13033
|
+
} while ((parent = parent.parent));
|
|
13034
|
+
this.scope.context.usesTopLevelAwait = true;
|
|
12558
13035
|
}
|
|
12559
|
-
|
|
13036
|
+
// Thenables need to be included
|
|
13037
|
+
this.argument.includePath(THEN_PATH, context);
|
|
13038
|
+
}
|
|
13039
|
+
includePath(path, context) {
|
|
13040
|
+
if (!this.deoptimized)
|
|
13041
|
+
this.applyDeoptimizations();
|
|
13042
|
+
if (!this.included)
|
|
13043
|
+
this.includeNode(context);
|
|
13044
|
+
this.argument.includePath(path, context);
|
|
12560
13045
|
}
|
|
12561
13046
|
}
|
|
13047
|
+
const THEN_PATH = ['then'];
|
|
12562
13048
|
|
|
12563
13049
|
const binaryOperators = {
|
|
12564
13050
|
'!=': (left, right) => left != right,
|
|
@@ -12614,6 +13100,12 @@ class BinaryExpression extends NodeBase {
|
|
|
12614
13100
|
hasEffectsOnInteractionAtPath(path, { type }) {
|
|
12615
13101
|
return type !== INTERACTION_ACCESSED || path.length > 1;
|
|
12616
13102
|
}
|
|
13103
|
+
includeNode(context) {
|
|
13104
|
+
this.included = true;
|
|
13105
|
+
if (this.operator === 'in') {
|
|
13106
|
+
this.right.includePath(UNKNOWN_PATH, context);
|
|
13107
|
+
}
|
|
13108
|
+
}
|
|
12617
13109
|
removeAnnotations(code) {
|
|
12618
13110
|
this.left.removeAnnotations(code);
|
|
12619
13111
|
}
|
|
@@ -12622,6 +13114,7 @@ class BinaryExpression extends NodeBase {
|
|
|
12622
13114
|
this.right.render(code, options);
|
|
12623
13115
|
}
|
|
12624
13116
|
}
|
|
13117
|
+
BinaryExpression.prototype.applyDeoptimizations = doNotDeoptimize;
|
|
12625
13118
|
|
|
12626
13119
|
class BreakStatement extends NodeBase {
|
|
12627
13120
|
hasEffects(context) {
|
|
@@ -12641,7 +13134,7 @@ class BreakStatement extends NodeBase {
|
|
|
12641
13134
|
include(context) {
|
|
12642
13135
|
this.included = true;
|
|
12643
13136
|
if (this.label) {
|
|
12644
|
-
this.label.include();
|
|
13137
|
+
this.label.include(context);
|
|
12645
13138
|
context.includedLabels.add(this.label.name);
|
|
12646
13139
|
}
|
|
12647
13140
|
else {
|
|
@@ -12650,6 +13143,8 @@ class BreakStatement extends NodeBase {
|
|
|
12650
13143
|
context.brokenFlow = true;
|
|
12651
13144
|
}
|
|
12652
13145
|
}
|
|
13146
|
+
BreakStatement.prototype.includeNode = onlyIncludeSelfNoDeoptimize;
|
|
13147
|
+
BreakStatement.prototype.applyDeoptimizations = doNotDeoptimize;
|
|
12653
13148
|
|
|
12654
13149
|
function renderCallArguments(code, options, node) {
|
|
12655
13150
|
if (node.arguments.length > 0) {
|
|
@@ -12836,10 +13331,14 @@ class CallExpression extends CallExpressionBase {
|
|
|
12836
13331
|
this.callee.hasEffectsOnInteractionAtPath(EMPTY_PATH, this.interaction, context)));
|
|
12837
13332
|
}
|
|
12838
13333
|
include(context, includeChildrenRecursively) {
|
|
12839
|
-
if (!this.
|
|
12840
|
-
this.
|
|
13334
|
+
if (!this.included)
|
|
13335
|
+
this.includeNode(context);
|
|
12841
13336
|
if (includeChildrenRecursively) {
|
|
12842
|
-
|
|
13337
|
+
this.callee.include(context, true);
|
|
13338
|
+
for (const argument of this.arguments) {
|
|
13339
|
+
argument.includePath(UNKNOWN_PATH, context);
|
|
13340
|
+
argument.include(context, true);
|
|
13341
|
+
}
|
|
12843
13342
|
if (includeChildrenRecursively === INCLUDE_PARAMETERS &&
|
|
12844
13343
|
this.callee instanceof Identifier &&
|
|
12845
13344
|
this.callee.variable) {
|
|
@@ -12847,10 +13346,24 @@ class CallExpression extends CallExpressionBase {
|
|
|
12847
13346
|
}
|
|
12848
13347
|
}
|
|
12849
13348
|
else {
|
|
12850
|
-
|
|
12851
|
-
|
|
13349
|
+
// If the callee is a member expression and does not have a variable, its
|
|
13350
|
+
// object will already be included via the first argument of the
|
|
13351
|
+
// interaction in includeCallArguments. Including it again can lead to
|
|
13352
|
+
// severe performance problems.
|
|
13353
|
+
if (this.callee instanceof MemberExpression && !this.callee.variable) {
|
|
13354
|
+
this.callee.property.include(context, false);
|
|
13355
|
+
}
|
|
13356
|
+
else {
|
|
13357
|
+
this.callee.include(context, false);
|
|
13358
|
+
}
|
|
13359
|
+
this.callee.includeCallArguments(context, this.interaction);
|
|
12852
13360
|
}
|
|
12853
|
-
|
|
13361
|
+
}
|
|
13362
|
+
includeNode(context) {
|
|
13363
|
+
this.included = true;
|
|
13364
|
+
if (!this.deoptimized)
|
|
13365
|
+
this.applyDeoptimizations();
|
|
13366
|
+
this.callee.includePath(UNKNOWN_PATH, context);
|
|
12854
13367
|
}
|
|
12855
13368
|
initialise() {
|
|
12856
13369
|
super.initialise();
|
|
@@ -12889,13 +13402,14 @@ class CatchClause extends NodeBase {
|
|
|
12889
13402
|
this.type = type;
|
|
12890
13403
|
if (param) {
|
|
12891
13404
|
this.param = new (this.scope.context.getNodeConstructor(param.type))(this, this.scope).parseNode(param);
|
|
12892
|
-
this.param.declare('parameter', UNKNOWN_EXPRESSION);
|
|
13405
|
+
this.param.declare('parameter', EMPTY_PATH, UNKNOWN_EXPRESSION);
|
|
12893
13406
|
}
|
|
12894
13407
|
this.body = new BlockStatement(this, this.scope.bodyScope).parseNode(body);
|
|
12895
13408
|
return super.parseNode(esTreeNode);
|
|
12896
13409
|
}
|
|
12897
13410
|
}
|
|
12898
13411
|
CatchClause.prototype.preventChildBlockScope = true;
|
|
13412
|
+
CatchClause.prototype.includeNode = onlyIncludeSelf;
|
|
12899
13413
|
|
|
12900
13414
|
class ChainExpression extends NodeBase {
|
|
12901
13415
|
// deoptimizations are not relevant as we are not caching values
|
|
@@ -12907,17 +13421,22 @@ class ChainExpression extends NodeBase {
|
|
|
12907
13421
|
hasEffects(context) {
|
|
12908
13422
|
return this.expression.hasEffectsAsChainElement(context) === true;
|
|
12909
13423
|
}
|
|
13424
|
+
includePath(path, context) {
|
|
13425
|
+
this.included = true;
|
|
13426
|
+
this.expression.includePath(path, context);
|
|
13427
|
+
}
|
|
12910
13428
|
removeAnnotations(code) {
|
|
12911
13429
|
this.expression.removeAnnotations(code);
|
|
12912
13430
|
}
|
|
12913
|
-
applyDeoptimizations() { }
|
|
12914
13431
|
}
|
|
13432
|
+
ChainExpression.prototype.includeNode = onlyIncludeSelfNoDeoptimize;
|
|
13433
|
+
ChainExpression.prototype.applyDeoptimizations = doNotDeoptimize;
|
|
12915
13434
|
|
|
12916
13435
|
class ClassBodyScope extends ChildScope {
|
|
12917
13436
|
constructor(parent, classNode) {
|
|
12918
13437
|
const { context } = parent;
|
|
12919
13438
|
super(parent, context);
|
|
12920
|
-
this.variables.set('this', (this.thisVariable = new LocalVariable('this', null, classNode, context, 'other')));
|
|
13439
|
+
this.variables.set('this', (this.thisVariable = new LocalVariable('this', null, classNode, EMPTY_PATH, context, 'other')));
|
|
12921
13440
|
this.instanceScope = new ChildScope(this, context);
|
|
12922
13441
|
this.instanceScope.variables.set('this', new ThisVariable(context));
|
|
12923
13442
|
}
|
|
@@ -12932,7 +13451,7 @@ class ClassBody extends NodeBase {
|
|
|
12932
13451
|
}
|
|
12933
13452
|
include(context, includeChildrenRecursively) {
|
|
12934
13453
|
this.included = true;
|
|
12935
|
-
this.scope.context.includeVariableInModule(this.scope.thisVariable);
|
|
13454
|
+
this.scope.context.includeVariableInModule(this.scope.thisVariable, UNKNOWN_PATH, context);
|
|
12936
13455
|
for (const definition of this.body) {
|
|
12937
13456
|
definition.include(context, includeChildrenRecursively);
|
|
12938
13457
|
}
|
|
@@ -12945,8 +13464,9 @@ class ClassBody extends NodeBase {
|
|
|
12945
13464
|
}
|
|
12946
13465
|
return super.parseNode(esTreeNode);
|
|
12947
13466
|
}
|
|
12948
|
-
applyDeoptimizations() { }
|
|
12949
13467
|
}
|
|
13468
|
+
ClassBody.prototype.includeNode = onlyIncludeSelfNoDeoptimize;
|
|
13469
|
+
ClassBody.prototype.applyDeoptimizations = doNotDeoptimize;
|
|
12950
13470
|
|
|
12951
13471
|
class ClassExpression extends ClassNode {
|
|
12952
13472
|
render(code, options, { renderedSurroundingElement } = parseAst_js.BLANK) {
|
|
@@ -13017,6 +13537,9 @@ class ConditionalExpression extends NodeBase {
|
|
|
13017
13537
|
const unusedBranch = this.usedBranch === this.consequent ? this.alternate : this.consequent;
|
|
13018
13538
|
this.usedBranch = null;
|
|
13019
13539
|
unusedBranch.deoptimizePath(UNKNOWN_PATH);
|
|
13540
|
+
if (this.included) {
|
|
13541
|
+
unusedBranch.includePath(UNKNOWN_PATH, createInclusionContext());
|
|
13542
|
+
}
|
|
13020
13543
|
const { expressionsToBeDeoptimized } = this;
|
|
13021
13544
|
this.expressionsToBeDeoptimized = parseAst_js.EMPTY_ARRAY;
|
|
13022
13545
|
for (const expression of expressionsToBeDeoptimized) {
|
|
@@ -13074,7 +13597,7 @@ class ConditionalExpression extends NodeBase {
|
|
|
13074
13597
|
include(context, includeChildrenRecursively) {
|
|
13075
13598
|
this.included = true;
|
|
13076
13599
|
const usedBranch = this.getUsedBranch();
|
|
13077
|
-
if (includeChildrenRecursively || this.test.shouldBeIncluded(context)
|
|
13600
|
+
if (usedBranch === null || includeChildrenRecursively || this.test.shouldBeIncluded(context)) {
|
|
13078
13601
|
this.test.include(context, includeChildrenRecursively);
|
|
13079
13602
|
this.consequent.include(context, includeChildrenRecursively);
|
|
13080
13603
|
this.alternate.include(context, includeChildrenRecursively);
|
|
@@ -13083,27 +13606,38 @@ class ConditionalExpression extends NodeBase {
|
|
|
13083
13606
|
usedBranch.include(context, includeChildrenRecursively);
|
|
13084
13607
|
}
|
|
13085
13608
|
}
|
|
13086
|
-
|
|
13609
|
+
includePath(path, context) {
|
|
13610
|
+
this.included = true;
|
|
13611
|
+
const usedBranch = this.getUsedBranch();
|
|
13612
|
+
if (usedBranch === null || this.test.shouldBeIncluded(context)) {
|
|
13613
|
+
this.consequent.includePath(path, context);
|
|
13614
|
+
this.alternate.includePath(path, context);
|
|
13615
|
+
}
|
|
13616
|
+
else {
|
|
13617
|
+
usedBranch.includePath(path, context);
|
|
13618
|
+
}
|
|
13619
|
+
}
|
|
13620
|
+
includeCallArguments(context, interaction) {
|
|
13087
13621
|
const usedBranch = this.getUsedBranch();
|
|
13088
13622
|
if (usedBranch) {
|
|
13089
|
-
usedBranch.includeCallArguments(context,
|
|
13623
|
+
usedBranch.includeCallArguments(context, interaction);
|
|
13090
13624
|
}
|
|
13091
13625
|
else {
|
|
13092
|
-
this.consequent.includeCallArguments(context,
|
|
13093
|
-
this.alternate.includeCallArguments(context,
|
|
13626
|
+
this.consequent.includeCallArguments(context, interaction);
|
|
13627
|
+
this.alternate.includeCallArguments(context, interaction);
|
|
13094
13628
|
}
|
|
13095
13629
|
}
|
|
13096
13630
|
removeAnnotations(code) {
|
|
13097
13631
|
this.test.removeAnnotations(code);
|
|
13098
13632
|
}
|
|
13099
13633
|
render(code, options, { isCalleeOfRenderedParent, preventASI, renderedParentType, renderedSurroundingElement } = parseAst_js.BLANK) {
|
|
13100
|
-
const usedBranch = this.getUsedBranch();
|
|
13101
13634
|
if (this.test.included) {
|
|
13102
13635
|
this.test.render(code, options, { renderedSurroundingElement });
|
|
13103
13636
|
this.consequent.render(code, options);
|
|
13104
13637
|
this.alternate.render(code, options);
|
|
13105
13638
|
}
|
|
13106
13639
|
else {
|
|
13640
|
+
const usedBranch = this.getUsedBranch();
|
|
13107
13641
|
const colonPos = findFirstOccurrenceOutsideComment(code.original, ':', this.consequent.end);
|
|
13108
13642
|
const inclusionStart = findNonWhiteSpace(code.original, (this.consequent.included
|
|
13109
13643
|
? findFirstOccurrenceOutsideComment(code.original, '?', this.test.end)
|
|
@@ -13135,6 +13669,8 @@ class ConditionalExpression extends NodeBase {
|
|
|
13135
13669
|
: (this.usedBranch = testValue ? this.consequent : this.alternate);
|
|
13136
13670
|
}
|
|
13137
13671
|
}
|
|
13672
|
+
ConditionalExpression.prototype.includeNode = onlyIncludeSelfNoDeoptimize;
|
|
13673
|
+
ConditionalExpression.prototype.applyDeoptimizations = doNotDeoptimize;
|
|
13138
13674
|
|
|
13139
13675
|
class ContinueStatement extends NodeBase {
|
|
13140
13676
|
hasEffects(context) {
|
|
@@ -13154,7 +13690,7 @@ class ContinueStatement extends NodeBase {
|
|
|
13154
13690
|
include(context) {
|
|
13155
13691
|
this.included = true;
|
|
13156
13692
|
if (this.label) {
|
|
13157
|
-
this.label.include();
|
|
13693
|
+
this.label.include(context);
|
|
13158
13694
|
context.includedLabels.add(this.label.name);
|
|
13159
13695
|
}
|
|
13160
13696
|
else {
|
|
@@ -13163,12 +13699,15 @@ class ContinueStatement extends NodeBase {
|
|
|
13163
13699
|
context.brokenFlow = true;
|
|
13164
13700
|
}
|
|
13165
13701
|
}
|
|
13702
|
+
ContinueStatement.prototype.includeNode = onlyIncludeSelfNoDeoptimize;
|
|
13703
|
+
ContinueStatement.prototype.applyDeoptimizations = doNotDeoptimize;
|
|
13166
13704
|
|
|
13167
13705
|
class DebuggerStatement extends NodeBase {
|
|
13168
13706
|
hasEffects() {
|
|
13169
13707
|
return true;
|
|
13170
13708
|
}
|
|
13171
13709
|
}
|
|
13710
|
+
DebuggerStatement.prototype.includeNode = onlyIncludeSelf;
|
|
13172
13711
|
|
|
13173
13712
|
class Decorator extends NodeBase {
|
|
13174
13713
|
hasEffects(context) {
|
|
@@ -13176,6 +13715,7 @@ class Decorator extends NodeBase {
|
|
|
13176
13715
|
this.expression.hasEffectsOnInteractionAtPath(EMPTY_PATH, NODE_INTERACTION_UNKNOWN_CALL, context));
|
|
13177
13716
|
}
|
|
13178
13717
|
}
|
|
13718
|
+
Decorator.prototype.includeNode = onlyIncludeSelf;
|
|
13179
13719
|
|
|
13180
13720
|
function hasLoopBodyEffects(context, body) {
|
|
13181
13721
|
const { brokenFlow, hasBreak, hasContinue, ignore } = context;
|
|
@@ -13215,12 +13755,15 @@ class DoWhileStatement extends NodeBase {
|
|
|
13215
13755
|
includeLoopBody(context, this.body, includeChildrenRecursively);
|
|
13216
13756
|
}
|
|
13217
13757
|
}
|
|
13758
|
+
DoWhileStatement.prototype.includeNode = onlyIncludeSelfNoDeoptimize;
|
|
13759
|
+
DoWhileStatement.prototype.applyDeoptimizations = doNotDeoptimize;
|
|
13218
13760
|
|
|
13219
13761
|
class EmptyStatement extends NodeBase {
|
|
13220
13762
|
hasEffects() {
|
|
13221
13763
|
return false;
|
|
13222
13764
|
}
|
|
13223
13765
|
}
|
|
13766
|
+
EmptyStatement.prototype.includeNode = onlyIncludeSelf;
|
|
13224
13767
|
|
|
13225
13768
|
class ExportAllDeclaration extends NodeBase {
|
|
13226
13769
|
hasEffects() {
|
|
@@ -13233,9 +13776,10 @@ class ExportAllDeclaration extends NodeBase {
|
|
|
13233
13776
|
render(code, _options, nodeRenderOptions) {
|
|
13234
13777
|
code.remove(nodeRenderOptions.start, nodeRenderOptions.end);
|
|
13235
13778
|
}
|
|
13236
|
-
applyDeoptimizations() { }
|
|
13237
13779
|
}
|
|
13238
13780
|
ExportAllDeclaration.prototype.needsBoundaries = true;
|
|
13781
|
+
ExportAllDeclaration.prototype.includeNode = onlyIncludeSelfNoDeoptimize;
|
|
13782
|
+
ExportAllDeclaration.prototype.applyDeoptimizations = doNotDeoptimize;
|
|
13239
13783
|
|
|
13240
13784
|
class ExportNamedDeclaration extends NodeBase {
|
|
13241
13785
|
bind() {
|
|
@@ -13262,13 +13806,15 @@ class ExportNamedDeclaration extends NodeBase {
|
|
|
13262
13806
|
this.declaration.render(code, options, { end, start });
|
|
13263
13807
|
}
|
|
13264
13808
|
}
|
|
13265
|
-
applyDeoptimizations() { }
|
|
13266
13809
|
}
|
|
13267
13810
|
ExportNamedDeclaration.prototype.needsBoundaries = true;
|
|
13811
|
+
ExportNamedDeclaration.prototype.includeNode = onlyIncludeSelfNoDeoptimize;
|
|
13812
|
+
ExportNamedDeclaration.prototype.applyDeoptimizations = doNotDeoptimize;
|
|
13268
13813
|
|
|
13269
13814
|
class ExportSpecifier extends NodeBase {
|
|
13270
|
-
applyDeoptimizations() { }
|
|
13271
13815
|
}
|
|
13816
|
+
ExportSpecifier.prototype.includeNode = onlyIncludeSelfNoDeoptimize;
|
|
13817
|
+
ExportSpecifier.prototype.applyDeoptimizations = doNotDeoptimize;
|
|
13272
13818
|
|
|
13273
13819
|
class ForInStatement extends NodeBase {
|
|
13274
13820
|
createScope(parentScope) {
|
|
@@ -13286,11 +13832,18 @@ class ForInStatement extends NodeBase {
|
|
|
13286
13832
|
const { body, deoptimized, left, right } = this;
|
|
13287
13833
|
if (!deoptimized)
|
|
13288
13834
|
this.applyDeoptimizations();
|
|
13289
|
-
this.included
|
|
13835
|
+
if (!this.included)
|
|
13836
|
+
this.includeNode(context);
|
|
13290
13837
|
left.includeAsAssignmentTarget(context, includeChildrenRecursively || true, false);
|
|
13291
13838
|
right.include(context, includeChildrenRecursively);
|
|
13292
13839
|
includeLoopBody(context, body, includeChildrenRecursively);
|
|
13293
13840
|
}
|
|
13841
|
+
includeNode(context) {
|
|
13842
|
+
this.included = true;
|
|
13843
|
+
if (!this.deoptimized)
|
|
13844
|
+
this.applyDeoptimizations();
|
|
13845
|
+
this.right.includePath(UNKNOWN_PATH, context);
|
|
13846
|
+
}
|
|
13294
13847
|
initialise() {
|
|
13295
13848
|
super.initialise();
|
|
13296
13849
|
this.left.setAssignedValue(UNKNOWN_EXPRESSION);
|
|
@@ -13331,11 +13884,18 @@ class ForOfStatement extends NodeBase {
|
|
|
13331
13884
|
const { body, deoptimized, left, right } = this;
|
|
13332
13885
|
if (!deoptimized)
|
|
13333
13886
|
this.applyDeoptimizations();
|
|
13334
|
-
this.included
|
|
13887
|
+
if (!this.included)
|
|
13888
|
+
this.includeNode(context);
|
|
13335
13889
|
left.includeAsAssignmentTarget(context, includeChildrenRecursively || true, false);
|
|
13336
13890
|
right.include(context, includeChildrenRecursively);
|
|
13337
13891
|
includeLoopBody(context, body, includeChildrenRecursively);
|
|
13338
13892
|
}
|
|
13893
|
+
includeNode(context) {
|
|
13894
|
+
this.included = true;
|
|
13895
|
+
if (!this.deoptimized)
|
|
13896
|
+
this.applyDeoptimizations();
|
|
13897
|
+
this.right.includePath(UNKNOWN_PATH, context);
|
|
13898
|
+
}
|
|
13339
13899
|
initialise() {
|
|
13340
13900
|
super.initialise();
|
|
13341
13901
|
this.left.setAssignedValue(UNKNOWN_EXPRESSION);
|
|
@@ -13371,7 +13931,9 @@ class ForStatement extends NodeBase {
|
|
|
13371
13931
|
}
|
|
13372
13932
|
include(context, includeChildrenRecursively) {
|
|
13373
13933
|
this.included = true;
|
|
13374
|
-
this.init?.include(context, includeChildrenRecursively, {
|
|
13934
|
+
this.init?.include(context, includeChildrenRecursively, {
|
|
13935
|
+
asSingleStatement: true
|
|
13936
|
+
});
|
|
13375
13937
|
this.test?.include(context, includeChildrenRecursively);
|
|
13376
13938
|
this.update?.include(context, includeChildrenRecursively);
|
|
13377
13939
|
includeLoopBody(context, this.body, includeChildrenRecursively);
|
|
@@ -13383,6 +13945,8 @@ class ForStatement extends NodeBase {
|
|
|
13383
13945
|
this.body.render(code, options);
|
|
13384
13946
|
}
|
|
13385
13947
|
}
|
|
13948
|
+
ForStatement.prototype.includeNode = onlyIncludeSelfNoDeoptimize;
|
|
13949
|
+
ForStatement.prototype.applyDeoptimizations = doNotDeoptimize;
|
|
13386
13950
|
|
|
13387
13951
|
class FunctionExpression extends FunctionNode {
|
|
13388
13952
|
createScope(parentScope) {
|
|
@@ -13414,9 +13978,9 @@ class TrackingScope extends BlockScope {
|
|
|
13414
13978
|
super(...arguments);
|
|
13415
13979
|
this.hoistedDeclarations = [];
|
|
13416
13980
|
}
|
|
13417
|
-
addDeclaration(identifier, context, init, kind) {
|
|
13981
|
+
addDeclaration(identifier, context, init, destructuredInitPath, kind) {
|
|
13418
13982
|
this.hoistedDeclarations.push(identifier);
|
|
13419
|
-
return super.addDeclaration(identifier, context, init, kind);
|
|
13983
|
+
return super.addDeclaration(identifier, context, init, destructuredInitPath, kind);
|
|
13420
13984
|
}
|
|
13421
13985
|
}
|
|
13422
13986
|
|
|
@@ -13515,7 +14079,6 @@ class IfStatement extends NodeBase {
|
|
|
13515
14079
|
}
|
|
13516
14080
|
this.renderHoistedDeclarations(hoistedDeclarations, code, getPropertyAccess);
|
|
13517
14081
|
}
|
|
13518
|
-
applyDeoptimizations() { }
|
|
13519
14082
|
getTestValue() {
|
|
13520
14083
|
if (this.testValue === unset) {
|
|
13521
14084
|
return (this.testValue = tryCastLiteralValueToBoolean(this.test.getLiteralValueAtPath(EMPTY_PATH, SHARED_RECURSION_TRACKER, this)));
|
|
@@ -13584,6 +14147,8 @@ class IfStatement extends NodeBase {
|
|
|
13584
14147
|
return false;
|
|
13585
14148
|
}
|
|
13586
14149
|
}
|
|
14150
|
+
IfStatement.prototype.includeNode = onlyIncludeSelfNoDeoptimize;
|
|
14151
|
+
IfStatement.prototype.applyDeoptimizations = doNotDeoptimize;
|
|
13587
14152
|
|
|
13588
14153
|
class ImportAttribute extends NodeBase {
|
|
13589
14154
|
}
|
|
@@ -13601,13 +14166,15 @@ class ImportDeclaration extends NodeBase {
|
|
|
13601
14166
|
render(code, _options, nodeRenderOptions) {
|
|
13602
14167
|
code.remove(nodeRenderOptions.start, nodeRenderOptions.end);
|
|
13603
14168
|
}
|
|
13604
|
-
applyDeoptimizations() { }
|
|
13605
14169
|
}
|
|
13606
14170
|
ImportDeclaration.prototype.needsBoundaries = true;
|
|
14171
|
+
ImportDeclaration.prototype.includeNode = onlyIncludeSelfNoDeoptimize;
|
|
14172
|
+
ImportDeclaration.prototype.applyDeoptimizations = doNotDeoptimize;
|
|
13607
14173
|
|
|
13608
14174
|
class ImportDefaultSpecifier extends NodeBase {
|
|
13609
|
-
applyDeoptimizations() { }
|
|
13610
14175
|
}
|
|
14176
|
+
ImportDefaultSpecifier.prototype.includeNode = onlyIncludeSelfNoDeoptimize;
|
|
14177
|
+
ImportDefaultSpecifier.prototype.applyDeoptimizations = doNotDeoptimize;
|
|
13611
14178
|
|
|
13612
14179
|
function isReassignedExportsMember(variable, exportNamesByVariable) {
|
|
13613
14180
|
return (variable.renderBaseName !== null && exportNamesByVariable.has(variable) && variable.isReassigned);
|
|
@@ -13616,28 +14183,33 @@ function isReassignedExportsMember(variable, exportNamesByVariable) {
|
|
|
13616
14183
|
class VariableDeclarator extends NodeBase {
|
|
13617
14184
|
declareDeclarator(kind, isUsingDeclaration) {
|
|
13618
14185
|
this.isUsingDeclaration = isUsingDeclaration;
|
|
13619
|
-
this.id.declare(kind, this.init || UNDEFINED_EXPRESSION);
|
|
14186
|
+
this.id.declare(kind, EMPTY_PATH, this.init || UNDEFINED_EXPRESSION);
|
|
13620
14187
|
}
|
|
13621
14188
|
deoptimizePath(path) {
|
|
13622
14189
|
this.id.deoptimizePath(path);
|
|
13623
14190
|
}
|
|
13624
14191
|
hasEffects(context) {
|
|
13625
|
-
if (!this.deoptimized)
|
|
13626
|
-
this.applyDeoptimizations();
|
|
13627
14192
|
const initEffect = this.init?.hasEffects(context);
|
|
13628
14193
|
this.id.markDeclarationReached();
|
|
13629
|
-
return initEffect ||
|
|
14194
|
+
return (initEffect ||
|
|
14195
|
+
this.isUsingDeclaration ||
|
|
14196
|
+
this.id.hasEffects(context) ||
|
|
14197
|
+
(this.scope.context.options.treeshake
|
|
14198
|
+
.propertyReadSideEffects &&
|
|
14199
|
+
this.id.hasEffectsWhenDestructuring(context, EMPTY_PATH, this.init || UNDEFINED_EXPRESSION)));
|
|
13630
14200
|
}
|
|
13631
14201
|
include(context, includeChildrenRecursively) {
|
|
13632
|
-
const {
|
|
13633
|
-
if (!
|
|
13634
|
-
this.
|
|
13635
|
-
this.included = true;
|
|
14202
|
+
const { id, init } = this;
|
|
14203
|
+
if (!this.included)
|
|
14204
|
+
this.includeNode();
|
|
13636
14205
|
init?.include(context, includeChildrenRecursively);
|
|
13637
14206
|
id.markDeclarationReached();
|
|
13638
|
-
if (includeChildrenRecursively
|
|
14207
|
+
if (includeChildrenRecursively) {
|
|
13639
14208
|
id.include(context, includeChildrenRecursively);
|
|
13640
14209
|
}
|
|
14210
|
+
else {
|
|
14211
|
+
id.includeDestructuredIfNecessary(context, EMPTY_PATH, init || UNDEFINED_EXPRESSION);
|
|
14212
|
+
}
|
|
13641
14213
|
}
|
|
13642
14214
|
removeAnnotations(code) {
|
|
13643
14215
|
this.init?.removeAnnotations(code);
|
|
@@ -13667,8 +14239,8 @@ class VariableDeclarator extends NodeBase {
|
|
|
13667
14239
|
code.appendLeft(end, `${_}=${_}void 0`);
|
|
13668
14240
|
}
|
|
13669
14241
|
}
|
|
13670
|
-
|
|
13671
|
-
this.
|
|
14242
|
+
includeNode() {
|
|
14243
|
+
this.included = true;
|
|
13672
14244
|
const { id, init } = this;
|
|
13673
14245
|
if (init && id instanceof Identifier && init instanceof ClassExpression && !init.id) {
|
|
13674
14246
|
const { name, variable } = id;
|
|
@@ -13680,11 +14252,14 @@ class VariableDeclarator extends NodeBase {
|
|
|
13680
14252
|
}
|
|
13681
14253
|
}
|
|
13682
14254
|
}
|
|
14255
|
+
VariableDeclarator.prototype.applyDeoptimizations = doNotDeoptimize;
|
|
13683
14256
|
|
|
13684
14257
|
class ImportExpression extends NodeBase {
|
|
13685
14258
|
constructor() {
|
|
13686
14259
|
super(...arguments);
|
|
13687
14260
|
this.inlineNamespace = null;
|
|
14261
|
+
this.hasUnknownAccessedKey = false;
|
|
14262
|
+
this.accessedPropKey = new Set();
|
|
13688
14263
|
this.attributes = null;
|
|
13689
14264
|
this.mechanism = null;
|
|
13690
14265
|
this.namespaceExportName = undefined;
|
|
@@ -13717,12 +14292,15 @@ class ImportExpression extends NodeBase {
|
|
|
13717
14292
|
if (parent2 instanceof ExpressionStatement) {
|
|
13718
14293
|
return parseAst_js.EMPTY_ARRAY;
|
|
13719
14294
|
}
|
|
13720
|
-
// Case 1: const { foo } = await import('bar')
|
|
14295
|
+
// Case 1: const { foo } / module = await import('bar')
|
|
13721
14296
|
if (parent2 instanceof VariableDeclarator) {
|
|
13722
14297
|
const declaration = parent2.id;
|
|
13723
|
-
|
|
13724
|
-
?
|
|
13725
|
-
|
|
14298
|
+
if (declaration instanceof Identifier) {
|
|
14299
|
+
return this.hasUnknownAccessedKey ? undefined : [...this.accessedPropKey];
|
|
14300
|
+
}
|
|
14301
|
+
if (declaration instanceof ObjectPattern) {
|
|
14302
|
+
return getDeterministicObjectDestructure(declaration);
|
|
14303
|
+
}
|
|
13726
14304
|
}
|
|
13727
14305
|
// Case 2: (await import('bar')).foo
|
|
13728
14306
|
if (parent2 instanceof MemberExpression) {
|
|
@@ -13772,13 +14350,30 @@ class ImportExpression extends NodeBase {
|
|
|
13772
14350
|
return true;
|
|
13773
14351
|
}
|
|
13774
14352
|
include(context, includeChildrenRecursively) {
|
|
13775
|
-
if (!this.included)
|
|
13776
|
-
this.
|
|
13777
|
-
this.scope.context.includeDynamicImport(this);
|
|
13778
|
-
this.scope.addAccessedDynamicImport(this);
|
|
13779
|
-
}
|
|
14353
|
+
if (!this.included)
|
|
14354
|
+
this.includeNode();
|
|
13780
14355
|
this.source.include(context, includeChildrenRecursively);
|
|
13781
14356
|
}
|
|
14357
|
+
includeNode() {
|
|
14358
|
+
this.included = true;
|
|
14359
|
+
this.scope.context.includeDynamicImport(this);
|
|
14360
|
+
this.scope.addAccessedDynamicImport(this);
|
|
14361
|
+
}
|
|
14362
|
+
includePath(path) {
|
|
14363
|
+
if (!this.included)
|
|
14364
|
+
this.includeNode();
|
|
14365
|
+
// Technically, this is not correct as dynamic imports return a Promise.
|
|
14366
|
+
if (this.hasUnknownAccessedKey)
|
|
14367
|
+
return;
|
|
14368
|
+
if (path[0] === UnknownKey) {
|
|
14369
|
+
this.hasUnknownAccessedKey = true;
|
|
14370
|
+
}
|
|
14371
|
+
else if (typeof path[0] === 'string') {
|
|
14372
|
+
this.accessedPropKey.add(path[0]);
|
|
14373
|
+
}
|
|
14374
|
+
// Update included paths
|
|
14375
|
+
this.scope.context.includeDynamicImport(this);
|
|
14376
|
+
}
|
|
13782
14377
|
initialise() {
|
|
13783
14378
|
super.initialise();
|
|
13784
14379
|
this.scope.context.addDynamicImport(this);
|
|
@@ -13847,7 +14442,6 @@ class ImportExpression extends NodeBase {
|
|
|
13847
14442
|
setInternalResolution(inlineNamespace) {
|
|
13848
14443
|
this.inlineNamespace = inlineNamespace;
|
|
13849
14444
|
}
|
|
13850
|
-
applyDeoptimizations() { }
|
|
13851
14445
|
getDynamicImportMechanismAndHelper(resolution, exportMode, { compact, dynamicImportInCjs, format, generatedCode: { arrowFunctions }, interop }, { _, getDirectReturnFunction, getDirectReturnIifeLeft }, pluginDriver) {
|
|
13852
14446
|
const mechanism = pluginDriver.hookFirstSync('renderDynamicImport', [
|
|
13853
14447
|
{
|
|
@@ -13937,6 +14531,7 @@ class ImportExpression extends NodeBase {
|
|
|
13937
14531
|
return { helper: null, mechanism: null };
|
|
13938
14532
|
}
|
|
13939
14533
|
}
|
|
14534
|
+
ImportExpression.prototype.applyDeoptimizations = doNotDeoptimize;
|
|
13940
14535
|
function getInteropHelper(resolution, exportMode, interop) {
|
|
13941
14536
|
return exportMode === 'external'
|
|
13942
14537
|
? namespaceInteropHelpersByInteropType[interop(resolution instanceof ExternalModule ? resolution.id : null)]
|
|
@@ -13960,12 +14555,14 @@ function getDeterministicObjectDestructure(objectPattern) {
|
|
|
13960
14555
|
}
|
|
13961
14556
|
|
|
13962
14557
|
class ImportNamespaceSpecifier extends NodeBase {
|
|
13963
|
-
applyDeoptimizations() { }
|
|
13964
14558
|
}
|
|
14559
|
+
ImportNamespaceSpecifier.prototype.includeNode = onlyIncludeSelfNoDeoptimize;
|
|
14560
|
+
ImportNamespaceSpecifier.prototype.applyDeoptimizations = doNotDeoptimize;
|
|
13965
14561
|
|
|
13966
14562
|
class ImportSpecifier extends NodeBase {
|
|
13967
|
-
applyDeoptimizations() { }
|
|
13968
14563
|
}
|
|
14564
|
+
ImportSpecifier.prototype.includeNode = onlyIncludeSelfNoDeoptimize;
|
|
14565
|
+
ImportSpecifier.prototype.applyDeoptimizations = doNotDeoptimize;
|
|
13969
14566
|
|
|
13970
14567
|
class JSXIdentifier extends IdentifierBase {
|
|
13971
14568
|
constructor() {
|
|
@@ -13982,6 +14579,29 @@ class JSXIdentifier extends IdentifierBase {
|
|
|
13982
14579
|
this.isNativeElement = true;
|
|
13983
14580
|
}
|
|
13984
14581
|
}
|
|
14582
|
+
include(context) {
|
|
14583
|
+
if (!this.included)
|
|
14584
|
+
this.includeNode(context);
|
|
14585
|
+
}
|
|
14586
|
+
includeNode(context) {
|
|
14587
|
+
this.included = true;
|
|
14588
|
+
if (!this.deoptimized)
|
|
14589
|
+
this.applyDeoptimizations();
|
|
14590
|
+
if (this.variable !== null) {
|
|
14591
|
+
this.scope.context.includeVariableInModule(this.variable, EMPTY_PATH, context);
|
|
14592
|
+
}
|
|
14593
|
+
}
|
|
14594
|
+
includePath(path, context) {
|
|
14595
|
+
if (!this.included) {
|
|
14596
|
+
this.included = true;
|
|
14597
|
+
if (this.variable !== null) {
|
|
14598
|
+
this.scope.context.includeVariableInModule(this.variable, path, context);
|
|
14599
|
+
}
|
|
14600
|
+
}
|
|
14601
|
+
else if (path.length > 0) {
|
|
14602
|
+
this.variable?.includePath(path, context);
|
|
14603
|
+
}
|
|
14604
|
+
}
|
|
13985
14605
|
render(code, { snippets: { getPropertyAccess }, useOriginalName }) {
|
|
13986
14606
|
if (this.variable) {
|
|
13987
14607
|
const name = this.variable.getName(getPropertyAccess, useOriginalName);
|
|
@@ -14043,6 +14663,7 @@ class JSXAttribute extends NodeBase {
|
|
|
14043
14663
|
}
|
|
14044
14664
|
}
|
|
14045
14665
|
}
|
|
14666
|
+
JSXAttribute.prototype.includeNode = onlyIncludeSelf;
|
|
14046
14667
|
|
|
14047
14668
|
class JSXClosingBase extends NodeBase {
|
|
14048
14669
|
render(code, options) {
|
|
@@ -14055,6 +14676,7 @@ class JSXClosingBase extends NodeBase {
|
|
|
14055
14676
|
}
|
|
14056
14677
|
}
|
|
14057
14678
|
}
|
|
14679
|
+
JSXClosingBase.prototype.includeNode = onlyIncludeSelf;
|
|
14058
14680
|
|
|
14059
14681
|
class JSXClosingElement extends JSXClosingBase {
|
|
14060
14682
|
}
|
|
@@ -14075,8 +14697,15 @@ class JSXSpreadAttribute extends NodeBase {
|
|
|
14075
14697
|
|
|
14076
14698
|
class JSXEmptyExpression extends NodeBase {
|
|
14077
14699
|
}
|
|
14700
|
+
JSXEmptyExpression.prototype.includeNode = onlyIncludeSelf;
|
|
14078
14701
|
|
|
14079
14702
|
class JSXExpressionContainer extends NodeBase {
|
|
14703
|
+
includeNode(context) {
|
|
14704
|
+
this.included = true;
|
|
14705
|
+
if (!this.deoptimized)
|
|
14706
|
+
this.applyDeoptimizations();
|
|
14707
|
+
this.expression.includePath(UNKNOWN_PATH, context);
|
|
14708
|
+
}
|
|
14080
14709
|
render(code, options) {
|
|
14081
14710
|
const { mode } = this.scope.context.options.jsx;
|
|
14082
14711
|
if (mode !== 'preserve') {
|
|
@@ -14097,7 +14726,7 @@ function getRenderedJsxChildren(children) {
|
|
|
14097
14726
|
return renderedChildren;
|
|
14098
14727
|
}
|
|
14099
14728
|
|
|
14100
|
-
function getAndIncludeFactoryVariable(factory, preserve, importSource, node) {
|
|
14729
|
+
function getAndIncludeFactoryVariable(factory, preserve, importSource, node, context) {
|
|
14101
14730
|
const [baseName, nestedName] = factory.split('.');
|
|
14102
14731
|
let factoryVariable;
|
|
14103
14732
|
if (importSource) {
|
|
@@ -14105,7 +14734,7 @@ function getAndIncludeFactoryVariable(factory, preserve, importSource, node) {
|
|
|
14105
14734
|
if (preserve) {
|
|
14106
14735
|
// This pretends we are accessing an included global variable of the same name
|
|
14107
14736
|
const globalVariable = node.scope.findGlobal(baseName);
|
|
14108
|
-
globalVariable.
|
|
14737
|
+
globalVariable.includePath(UNKNOWN_PATH, context);
|
|
14109
14738
|
// This excludes this variable from renaming
|
|
14110
14739
|
factoryVariable.globalName = baseName;
|
|
14111
14740
|
}
|
|
@@ -14113,7 +14742,7 @@ function getAndIncludeFactoryVariable(factory, preserve, importSource, node) {
|
|
|
14113
14742
|
else {
|
|
14114
14743
|
factoryVariable = node.scope.findGlobal(baseName);
|
|
14115
14744
|
}
|
|
14116
|
-
node.scope.context.includeVariableInModule(factoryVariable);
|
|
14745
|
+
node.scope.context.includeVariableInModule(factoryVariable, UNKNOWN_PATH, context);
|
|
14117
14746
|
if (factoryVariable instanceof LocalVariable) {
|
|
14118
14747
|
factoryVariable.consolidateInitializers();
|
|
14119
14748
|
factoryVariable.addUsedPlace(node);
|
|
@@ -14136,16 +14765,20 @@ class JSXElementBase extends NodeBase {
|
|
|
14136
14765
|
}
|
|
14137
14766
|
}
|
|
14138
14767
|
include(context, includeChildrenRecursively) {
|
|
14139
|
-
if (!this.included)
|
|
14140
|
-
|
|
14141
|
-
|
|
14142
|
-
|
|
14143
|
-
|
|
14144
|
-
|
|
14768
|
+
if (!this.included)
|
|
14769
|
+
this.includeNode(context);
|
|
14770
|
+
for (const child of this.children) {
|
|
14771
|
+
child.include(context, includeChildrenRecursively);
|
|
14772
|
+
}
|
|
14773
|
+
}
|
|
14774
|
+
includeNode(context) {
|
|
14775
|
+
this.included = true;
|
|
14776
|
+
const { factory, importSource, mode } = this.jsxMode;
|
|
14777
|
+
if (factory) {
|
|
14778
|
+
this.factory = factory;
|
|
14779
|
+
this.factoryVariable = getAndIncludeFactoryVariable(factory, mode === 'preserve', importSource, this, context);
|
|
14145
14780
|
}
|
|
14146
|
-
super.include(context, includeChildrenRecursively);
|
|
14147
14781
|
}
|
|
14148
|
-
applyDeoptimizations() { }
|
|
14149
14782
|
getRenderingMode() {
|
|
14150
14783
|
const jsx = this.scope.context.options.jsx;
|
|
14151
14784
|
const { mode, factory, importSource } = jsx;
|
|
@@ -14183,8 +14816,14 @@ class JSXElementBase extends NodeBase {
|
|
|
14183
14816
|
return { childrenEnd, firstChild, hasMultipleChildren };
|
|
14184
14817
|
}
|
|
14185
14818
|
}
|
|
14819
|
+
JSXElementBase.prototype.applyDeoptimizations = doNotDeoptimize;
|
|
14186
14820
|
|
|
14187
14821
|
class JSXElement extends JSXElementBase {
|
|
14822
|
+
include(context, includeChildrenRecursively) {
|
|
14823
|
+
super.include(context, includeChildrenRecursively);
|
|
14824
|
+
this.openingElement.include(context, includeChildrenRecursively);
|
|
14825
|
+
this.closingElement?.include(context, includeChildrenRecursively);
|
|
14826
|
+
}
|
|
14188
14827
|
render(code, options) {
|
|
14189
14828
|
switch (this.jsxMode.mode) {
|
|
14190
14829
|
case 'classic': {
|
|
@@ -14336,6 +14975,11 @@ class JSXElement extends JSXElementBase {
|
|
|
14336
14975
|
}
|
|
14337
14976
|
|
|
14338
14977
|
class JSXFragment extends JSXElementBase {
|
|
14978
|
+
include(context, includeChildrenRecursively) {
|
|
14979
|
+
super.include(context, includeChildrenRecursively);
|
|
14980
|
+
this.openingFragment.include(context, includeChildrenRecursively);
|
|
14981
|
+
this.closingFragment.include(context, includeChildrenRecursively);
|
|
14982
|
+
}
|
|
14339
14983
|
render(code, options) {
|
|
14340
14984
|
switch (this.jsxMode.mode) {
|
|
14341
14985
|
case 'classic': {
|
|
@@ -14385,10 +15029,22 @@ class JSXFragment extends JSXElementBase {
|
|
|
14385
15029
|
}
|
|
14386
15030
|
|
|
14387
15031
|
class JSXMemberExpression extends NodeBase {
|
|
15032
|
+
includeNode(context) {
|
|
15033
|
+
this.included = true;
|
|
15034
|
+
if (!this.deoptimized)
|
|
15035
|
+
this.applyDeoptimizations();
|
|
15036
|
+
this.object.includePath([this.property.name], context);
|
|
15037
|
+
}
|
|
15038
|
+
includePath(path, context) {
|
|
15039
|
+
if (!this.included)
|
|
15040
|
+
this.includeNode(context);
|
|
15041
|
+
this.object.includePath([this.property.name, ...path], context);
|
|
15042
|
+
}
|
|
14388
15043
|
}
|
|
14389
15044
|
|
|
14390
15045
|
class JSXNamespacedName extends NodeBase {
|
|
14391
15046
|
}
|
|
15047
|
+
JSXNamespacedName.prototype.includeNode = onlyIncludeSelf;
|
|
14392
15048
|
|
|
14393
15049
|
class JSXOpeningElement extends NodeBase {
|
|
14394
15050
|
render(code, options, { jsxMode = this.scope.context.options.jsx.mode } = {}) {
|
|
@@ -14398,6 +15054,7 @@ class JSXOpeningElement extends NodeBase {
|
|
|
14398
15054
|
}
|
|
14399
15055
|
}
|
|
14400
15056
|
}
|
|
15057
|
+
JSXOpeningElement.prototype.includeNode = onlyIncludeSelf;
|
|
14401
15058
|
|
|
14402
15059
|
class JSXOpeningFragment extends NodeBase {
|
|
14403
15060
|
constructor() {
|
|
@@ -14405,22 +15062,22 @@ class JSXOpeningFragment extends NodeBase {
|
|
|
14405
15062
|
this.fragment = null;
|
|
14406
15063
|
this.fragmentVariable = null;
|
|
14407
15064
|
}
|
|
14408
|
-
|
|
14409
|
-
|
|
14410
|
-
|
|
14411
|
-
|
|
14412
|
-
|
|
14413
|
-
|
|
14414
|
-
|
|
14415
|
-
|
|
14416
|
-
|
|
14417
|
-
|
|
14418
|
-
|
|
14419
|
-
|
|
14420
|
-
|
|
15065
|
+
includeNode(context) {
|
|
15066
|
+
this.included = true;
|
|
15067
|
+
if (!this.deoptimized)
|
|
15068
|
+
this.applyDeoptimizations();
|
|
15069
|
+
const jsx = this.scope.context.options.jsx;
|
|
15070
|
+
if (jsx.mode === 'automatic') {
|
|
15071
|
+
this.fragment = 'Fragment';
|
|
15072
|
+
this.fragmentVariable = getAndIncludeFactoryVariable('Fragment', false, jsx.jsxImportSource, this, context);
|
|
15073
|
+
}
|
|
15074
|
+
else {
|
|
15075
|
+
const { fragment, importSource, mode } = jsx;
|
|
15076
|
+
if (fragment != null) {
|
|
15077
|
+
this.fragment = fragment;
|
|
15078
|
+
this.fragmentVariable = getAndIncludeFactoryVariable(fragment, mode === 'preserve', importSource, this, context);
|
|
14421
15079
|
}
|
|
14422
15080
|
}
|
|
14423
|
-
super.include(context, includeChildrenRecursively);
|
|
14424
15081
|
}
|
|
14425
15082
|
render(code, options) {
|
|
14426
15083
|
const { mode } = this.scope.context.options.jsx;
|
|
@@ -14457,6 +15114,7 @@ class JSXText extends NodeBase {
|
|
|
14457
15114
|
}
|
|
14458
15115
|
}
|
|
14459
15116
|
}
|
|
15117
|
+
JSXText.prototype.includeNode = onlyIncludeSelf;
|
|
14460
15118
|
|
|
14461
15119
|
class LabeledStatement extends NodeBase {
|
|
14462
15120
|
hasEffects(context) {
|
|
@@ -14478,17 +15136,22 @@ class LabeledStatement extends NodeBase {
|
|
|
14478
15136
|
return bodyHasEffects;
|
|
14479
15137
|
}
|
|
14480
15138
|
include(context, includeChildrenRecursively) {
|
|
14481
|
-
this.included
|
|
15139
|
+
if (!this.included)
|
|
15140
|
+
this.includeNode(context);
|
|
14482
15141
|
const { brokenFlow, includedLabels } = context;
|
|
14483
15142
|
context.includedLabels = new Set();
|
|
14484
15143
|
this.body.include(context, includeChildrenRecursively);
|
|
14485
15144
|
if (includeChildrenRecursively || context.includedLabels.has(this.label.name)) {
|
|
14486
|
-
this.label.include();
|
|
15145
|
+
this.label.include(context);
|
|
14487
15146
|
context.includedLabels.delete(this.label.name);
|
|
14488
15147
|
context.brokenFlow = brokenFlow;
|
|
14489
15148
|
}
|
|
14490
15149
|
context.includedLabels = new Set([...includedLabels, ...context.includedLabels]);
|
|
14491
15150
|
}
|
|
15151
|
+
includeNode(context) {
|
|
15152
|
+
this.included = true;
|
|
15153
|
+
this.body.includePath(UNKNOWN_PATH, context);
|
|
15154
|
+
}
|
|
14492
15155
|
render(code, options) {
|
|
14493
15156
|
if (this.label.included) {
|
|
14494
15157
|
this.label.render(code, options);
|
|
@@ -14499,6 +15162,7 @@ class LabeledStatement extends NodeBase {
|
|
|
14499
15162
|
this.body.render(code, options);
|
|
14500
15163
|
}
|
|
14501
15164
|
}
|
|
15165
|
+
LabeledStatement.prototype.applyDeoptimizations = doNotDeoptimize;
|
|
14502
15166
|
|
|
14503
15167
|
class LogicalExpression extends NodeBase {
|
|
14504
15168
|
constructor() {
|
|
@@ -14515,10 +15179,10 @@ class LogicalExpression extends NodeBase {
|
|
|
14515
15179
|
this.flags = setFlag(this.flags, 65536 /* Flag.isBranchResolutionAnalysed */, value);
|
|
14516
15180
|
}
|
|
14517
15181
|
get hasDeoptimizedCache() {
|
|
14518
|
-
return isFlagSet(this.flags,
|
|
15182
|
+
return isFlagSet(this.flags, 33554432 /* Flag.hasDeoptimizedCache */);
|
|
14519
15183
|
}
|
|
14520
15184
|
set hasDeoptimizedCache(value) {
|
|
14521
|
-
this.flags = setFlag(this.flags,
|
|
15185
|
+
this.flags = setFlag(this.flags, 33554432 /* Flag.hasDeoptimizedCache */, value);
|
|
14522
15186
|
}
|
|
14523
15187
|
deoptimizeArgumentsOnInteractionAtPath(interaction, path, recursionTracker) {
|
|
14524
15188
|
this.left.deoptimizeArgumentsOnInteractionAtPath(interaction, path, recursionTracker);
|
|
@@ -14531,6 +15195,10 @@ class LogicalExpression extends NodeBase {
|
|
|
14531
15195
|
const unusedBranch = this.usedBranch === this.left ? this.right : this.left;
|
|
14532
15196
|
this.usedBranch = null;
|
|
14533
15197
|
unusedBranch.deoptimizePath(UNKNOWN_PATH);
|
|
15198
|
+
if (this.included) {
|
|
15199
|
+
// As we are not tracking inclusions, we just include everything
|
|
15200
|
+
unusedBranch.includePath(UNKNOWN_PATH, createInclusionContext());
|
|
15201
|
+
}
|
|
14534
15202
|
}
|
|
14535
15203
|
const { scope: { context }, expressionsToBeDeoptimized } = this;
|
|
14536
15204
|
this.expressionsToBeDeoptimized = parseAst_js.EMPTY_ARRAY;
|
|
@@ -14576,16 +15244,17 @@ class LogicalExpression extends NodeBase {
|
|
|
14576
15244
|
}
|
|
14577
15245
|
getReturnExpressionWhenCalledAtPath(path, interaction, recursionTracker, origin) {
|
|
14578
15246
|
const usedBranch = this.getUsedBranch();
|
|
14579
|
-
if (
|
|
14580
|
-
|
|
14581
|
-
|
|
14582
|
-
|
|
14583
|
-
|
|
14584
|
-
|
|
14585
|
-
|
|
14586
|
-
|
|
14587
|
-
|
|
14588
|
-
|
|
15247
|
+
if (usedBranch) {
|
|
15248
|
+
this.expressionsToBeDeoptimized.push(origin);
|
|
15249
|
+
return usedBranch.getReturnExpressionWhenCalledAtPath(path, interaction, recursionTracker, origin);
|
|
15250
|
+
}
|
|
15251
|
+
return [
|
|
15252
|
+
new MultiExpression([
|
|
15253
|
+
this.left.getReturnExpressionWhenCalledAtPath(path, interaction, recursionTracker, origin)[0],
|
|
15254
|
+
this.right.getReturnExpressionWhenCalledAtPath(path, interaction, recursionTracker, origin)[0]
|
|
15255
|
+
]),
|
|
15256
|
+
false
|
|
15257
|
+
];
|
|
14589
15258
|
}
|
|
14590
15259
|
hasEffects(context) {
|
|
14591
15260
|
if (this.left.hasEffects(context)) {
|
|
@@ -14598,18 +15267,18 @@ class LogicalExpression extends NodeBase {
|
|
|
14598
15267
|
}
|
|
14599
15268
|
hasEffectsOnInteractionAtPath(path, interaction, context) {
|
|
14600
15269
|
const usedBranch = this.getUsedBranch();
|
|
14601
|
-
if (
|
|
14602
|
-
return
|
|
14603
|
-
this.right.hasEffectsOnInteractionAtPath(path, interaction, context));
|
|
15270
|
+
if (usedBranch) {
|
|
15271
|
+
return usedBranch.hasEffectsOnInteractionAtPath(path, interaction, context);
|
|
14604
15272
|
}
|
|
14605
|
-
return
|
|
15273
|
+
return (this.left.hasEffectsOnInteractionAtPath(path, interaction, context) ||
|
|
15274
|
+
this.right.hasEffectsOnInteractionAtPath(path, interaction, context));
|
|
14606
15275
|
}
|
|
14607
15276
|
include(context, includeChildrenRecursively) {
|
|
14608
15277
|
this.included = true;
|
|
14609
15278
|
const usedBranch = this.getUsedBranch();
|
|
14610
15279
|
if (includeChildrenRecursively ||
|
|
14611
|
-
|
|
14612
|
-
|
|
15280
|
+
!usedBranch ||
|
|
15281
|
+
(usedBranch === this.right && this.left.shouldBeIncluded(context))) {
|
|
14613
15282
|
this.left.include(context, includeChildrenRecursively);
|
|
14614
15283
|
this.right.include(context, includeChildrenRecursively);
|
|
14615
15284
|
}
|
|
@@ -14617,6 +15286,17 @@ class LogicalExpression extends NodeBase {
|
|
|
14617
15286
|
usedBranch.include(context, includeChildrenRecursively);
|
|
14618
15287
|
}
|
|
14619
15288
|
}
|
|
15289
|
+
includePath(path, context) {
|
|
15290
|
+
this.included = true;
|
|
15291
|
+
const usedBranch = this.getUsedBranch();
|
|
15292
|
+
if (!usedBranch || (usedBranch === this.right && this.left.shouldBeIncluded(context))) {
|
|
15293
|
+
this.left.includePath(path, context);
|
|
15294
|
+
this.right.includePath(path, context);
|
|
15295
|
+
}
|
|
15296
|
+
else {
|
|
15297
|
+
usedBranch.includePath(path, context);
|
|
15298
|
+
}
|
|
15299
|
+
}
|
|
14620
15300
|
removeAnnotations(code) {
|
|
14621
15301
|
this.left.removeAnnotations(code);
|
|
14622
15302
|
}
|
|
@@ -14669,6 +15349,8 @@ class LogicalExpression extends NodeBase {
|
|
|
14669
15349
|
return this.usedBranch;
|
|
14670
15350
|
}
|
|
14671
15351
|
}
|
|
15352
|
+
LogicalExpression.prototype.includeNode = onlyIncludeSelfNoDeoptimize;
|
|
15353
|
+
LogicalExpression.prototype.applyDeoptimizations = doNotDeoptimize;
|
|
14672
15354
|
|
|
14673
15355
|
class NewExpression extends NodeBase {
|
|
14674
15356
|
hasEffects(context) {
|
|
@@ -14688,16 +15370,21 @@ class NewExpression extends NodeBase {
|
|
|
14688
15370
|
return path.length > 0 || type !== INTERACTION_ACCESSED;
|
|
14689
15371
|
}
|
|
14690
15372
|
include(context, includeChildrenRecursively) {
|
|
14691
|
-
if (!this.deoptimized)
|
|
14692
|
-
this.applyDeoptimizations();
|
|
14693
15373
|
if (includeChildrenRecursively) {
|
|
14694
15374
|
super.include(context, includeChildrenRecursively);
|
|
14695
15375
|
}
|
|
14696
15376
|
else {
|
|
14697
|
-
this.included
|
|
15377
|
+
if (!this.included)
|
|
15378
|
+
this.includeNode(context);
|
|
14698
15379
|
this.callee.include(context, false);
|
|
14699
15380
|
}
|
|
14700
|
-
this.callee.includeCallArguments(context, this.
|
|
15381
|
+
this.callee.includeCallArguments(context, this.interaction);
|
|
15382
|
+
}
|
|
15383
|
+
includeNode(context) {
|
|
15384
|
+
this.included = true;
|
|
15385
|
+
if (!this.deoptimized)
|
|
15386
|
+
this.applyDeoptimizations();
|
|
15387
|
+
this.callee.includePath(UNKNOWN_PATH, context);
|
|
14701
15388
|
}
|
|
14702
15389
|
initialise() {
|
|
14703
15390
|
super.initialise();
|
|
@@ -14726,6 +15413,7 @@ class ObjectExpression extends NodeBase {
|
|
|
14726
15413
|
constructor() {
|
|
14727
15414
|
super(...arguments);
|
|
14728
15415
|
this.objectEntity = null;
|
|
15416
|
+
this.protoProp = null;
|
|
14729
15417
|
}
|
|
14730
15418
|
deoptimizeArgumentsOnInteractionAtPath(interaction, path, recursionTracker) {
|
|
14731
15419
|
this.getObjectEntity().deoptimizeArgumentsOnInteractionAtPath(interaction, path, recursionTracker);
|
|
@@ -14745,15 +15433,43 @@ class ObjectExpression extends NodeBase {
|
|
|
14745
15433
|
hasEffectsOnInteractionAtPath(path, interaction, context) {
|
|
14746
15434
|
return this.getObjectEntity().hasEffectsOnInteractionAtPath(path, interaction, context);
|
|
14747
15435
|
}
|
|
15436
|
+
include(context, includeChildrenRecursively) {
|
|
15437
|
+
if (!this.included)
|
|
15438
|
+
this.includeNode(context);
|
|
15439
|
+
this.getObjectEntity().include(context, includeChildrenRecursively);
|
|
15440
|
+
this.protoProp?.include(context, includeChildrenRecursively);
|
|
15441
|
+
}
|
|
15442
|
+
includeNode(context) {
|
|
15443
|
+
this.included = true;
|
|
15444
|
+
this.protoProp?.includePath(UNKNOWN_PATH, context);
|
|
15445
|
+
}
|
|
15446
|
+
includePath(path, context) {
|
|
15447
|
+
if (!this.included)
|
|
15448
|
+
this.includeNode(context);
|
|
15449
|
+
this.getObjectEntity().includePath(path, context);
|
|
15450
|
+
}
|
|
14748
15451
|
render(code, options, { renderedSurroundingElement } = parseAst_js.BLANK) {
|
|
14749
|
-
super.render(code, options);
|
|
14750
15452
|
if (renderedSurroundingElement === parseAst_js.ExpressionStatement ||
|
|
14751
15453
|
renderedSurroundingElement === parseAst_js.ArrowFunctionExpression) {
|
|
14752
15454
|
code.appendRight(this.start, '(');
|
|
14753
15455
|
code.prependLeft(this.end, ')');
|
|
14754
15456
|
}
|
|
15457
|
+
if (this.properties.length > 0) {
|
|
15458
|
+
const separatedNodes = getCommaSeparatedNodesWithBoundaries(this.properties, code, this.start + 1, this.end - 1);
|
|
15459
|
+
let lastSeparatorPos = null;
|
|
15460
|
+
for (const { node, separator, start, end } of separatedNodes) {
|
|
15461
|
+
if (!node.included) {
|
|
15462
|
+
treeshakeNode(node, code, start, end);
|
|
15463
|
+
continue;
|
|
15464
|
+
}
|
|
15465
|
+
lastSeparatorPos = separator;
|
|
15466
|
+
node.render(code, options);
|
|
15467
|
+
}
|
|
15468
|
+
if (lastSeparatorPos) {
|
|
15469
|
+
code.remove(lastSeparatorPos, this.end - 1);
|
|
15470
|
+
}
|
|
15471
|
+
}
|
|
14755
15472
|
}
|
|
14756
|
-
applyDeoptimizations() { }
|
|
14757
15473
|
getObjectEntity() {
|
|
14758
15474
|
if (this.objectEntity !== null) {
|
|
14759
15475
|
return this.objectEntity;
|
|
@@ -14782,6 +15498,7 @@ class ObjectExpression extends NodeBase {
|
|
|
14782
15498
|
? property.key.name
|
|
14783
15499
|
: String(property.key.value);
|
|
14784
15500
|
if (key === '__proto__' && property.kind === 'init') {
|
|
15501
|
+
this.protoProp = property;
|
|
14785
15502
|
prototype =
|
|
14786
15503
|
property.value instanceof Literal && property.value.value === null
|
|
14787
15504
|
? null
|
|
@@ -14794,6 +15511,7 @@ class ObjectExpression extends NodeBase {
|
|
|
14794
15511
|
return (this.objectEntity = new ObjectEntity(properties, prototype));
|
|
14795
15512
|
}
|
|
14796
15513
|
}
|
|
15514
|
+
ObjectExpression.prototype.applyDeoptimizations = doNotDeoptimize;
|
|
14797
15515
|
|
|
14798
15516
|
class PanicError extends NodeBase {
|
|
14799
15517
|
initialise() {
|
|
@@ -14820,6 +15538,7 @@ class ParseError extends NodeBase {
|
|
|
14820
15538
|
|
|
14821
15539
|
class PrivateIdentifier extends NodeBase {
|
|
14822
15540
|
}
|
|
15541
|
+
PrivateIdentifier.prototype.includeNode = onlyIncludeSelf;
|
|
14823
15542
|
|
|
14824
15543
|
class Program extends NodeBase {
|
|
14825
15544
|
constructor() {
|
|
@@ -14887,14 +15606,11 @@ class Program extends NodeBase {
|
|
|
14887
15606
|
super.render(code, options);
|
|
14888
15607
|
}
|
|
14889
15608
|
}
|
|
14890
|
-
applyDeoptimizations() { }
|
|
14891
15609
|
}
|
|
15610
|
+
Program.prototype.includeNode = onlyIncludeSelfNoDeoptimize;
|
|
15611
|
+
Program.prototype.applyDeoptimizations = doNotDeoptimize;
|
|
14892
15612
|
|
|
14893
15613
|
class Property extends MethodBase {
|
|
14894
|
-
constructor() {
|
|
14895
|
-
super(...arguments);
|
|
14896
|
-
this.declarationInit = null;
|
|
14897
|
-
}
|
|
14898
15614
|
//declare method: boolean;
|
|
14899
15615
|
get method() {
|
|
14900
15616
|
return isFlagSet(this.flags, 262144 /* Flag.method */);
|
|
@@ -14909,17 +15625,41 @@ class Property extends MethodBase {
|
|
|
14909
15625
|
set shorthand(value) {
|
|
14910
15626
|
this.flags = setFlag(this.flags, 524288 /* Flag.shorthand */, value);
|
|
14911
15627
|
}
|
|
14912
|
-
declare(kind, init) {
|
|
14913
|
-
this.
|
|
14914
|
-
|
|
15628
|
+
declare(kind, destructuredInitPath, init) {
|
|
15629
|
+
return this.value.declare(kind, this.getPathInProperty(destructuredInitPath), init);
|
|
15630
|
+
}
|
|
15631
|
+
deoptimizeAssignment(destructuredInitPath, init) {
|
|
15632
|
+
this.value.deoptimizeAssignment?.(this.getPathInProperty(destructuredInitPath), init);
|
|
14915
15633
|
}
|
|
14916
15634
|
hasEffects(context) {
|
|
14917
|
-
|
|
14918
|
-
|
|
14919
|
-
|
|
14920
|
-
return
|
|
14921
|
-
|
|
14922
|
-
|
|
15635
|
+
return this.key.hasEffects(context) || this.value.hasEffects(context);
|
|
15636
|
+
}
|
|
15637
|
+
hasEffectsWhenDestructuring(context, destructuredInitPath, init) {
|
|
15638
|
+
return this.value.hasEffectsWhenDestructuring?.(context, this.getPathInProperty(destructuredInitPath), init);
|
|
15639
|
+
}
|
|
15640
|
+
includeDestructuredIfNecessary(context, destructuredInitPath, init) {
|
|
15641
|
+
const path = this.getPathInProperty(destructuredInitPath);
|
|
15642
|
+
let included = this.value.includeDestructuredIfNecessary(context, path, init) ||
|
|
15643
|
+
this.included;
|
|
15644
|
+
if ((included ||= this.key.hasEffects(createHasEffectsContext()))) {
|
|
15645
|
+
this.key.include(context, false);
|
|
15646
|
+
if (!this.value.included) {
|
|
15647
|
+
this.value.included = true;
|
|
15648
|
+
// Unfortunately, we need to include the value again now, so that any
|
|
15649
|
+
// declared variables are properly included.
|
|
15650
|
+
this.value.includeDestructuredIfNecessary(context, path, init);
|
|
15651
|
+
}
|
|
15652
|
+
}
|
|
15653
|
+
return (this.included = included);
|
|
15654
|
+
}
|
|
15655
|
+
include(context, includeChildrenRecursively) {
|
|
15656
|
+
this.included = true;
|
|
15657
|
+
this.key.include(context, includeChildrenRecursively);
|
|
15658
|
+
this.value.include(context, includeChildrenRecursively);
|
|
15659
|
+
}
|
|
15660
|
+
includePath(path, context) {
|
|
15661
|
+
this.included = true;
|
|
15662
|
+
this.value.includePath(path, context);
|
|
14923
15663
|
}
|
|
14924
15664
|
markDeclarationReached() {
|
|
14925
15665
|
this.value.markDeclarationReached();
|
|
@@ -14930,14 +15670,20 @@ class Property extends MethodBase {
|
|
|
14930
15670
|
}
|
|
14931
15671
|
this.value.render(code, options, { isShorthandProperty: this.shorthand });
|
|
14932
15672
|
}
|
|
14933
|
-
|
|
14934
|
-
|
|
14935
|
-
|
|
14936
|
-
|
|
14937
|
-
|
|
14938
|
-
|
|
15673
|
+
getPathInProperty(destructuredInitPath) {
|
|
15674
|
+
return destructuredInitPath.at(-1) === UnknownKey
|
|
15675
|
+
? destructuredInitPath
|
|
15676
|
+
: // For now, we only consider static paths as we do not know how to
|
|
15677
|
+
// deoptimize the path in the dynamic case.
|
|
15678
|
+
this.computed
|
|
15679
|
+
? [...destructuredInitPath, UnknownKey]
|
|
15680
|
+
: this.key instanceof Identifier
|
|
15681
|
+
? [...destructuredInitPath, this.key.name]
|
|
15682
|
+
: [...destructuredInitPath, String(this.key.value)];
|
|
14939
15683
|
}
|
|
14940
15684
|
}
|
|
15685
|
+
Property.prototype.includeNode = onlyIncludeSelfNoDeoptimize;
|
|
15686
|
+
Property.prototype.applyDeoptimizations = doNotDeoptimize;
|
|
14941
15687
|
|
|
14942
15688
|
class PropertyDefinition extends NodeBase {
|
|
14943
15689
|
get computed() {
|
|
@@ -14970,8 +15716,15 @@ class PropertyDefinition extends NodeBase {
|
|
|
14970
15716
|
hasEffectsOnInteractionAtPath(path, interaction, context) {
|
|
14971
15717
|
return !this.value || this.value.hasEffectsOnInteractionAtPath(path, interaction, context);
|
|
14972
15718
|
}
|
|
14973
|
-
|
|
15719
|
+
includeNode(context) {
|
|
15720
|
+
this.included = true;
|
|
15721
|
+
this.value?.includePath(UNKNOWN_PATH, context);
|
|
15722
|
+
for (const decorator of this.decorators) {
|
|
15723
|
+
decorator.includePath(UNKNOWN_PATH, context);
|
|
15724
|
+
}
|
|
15725
|
+
}
|
|
14974
15726
|
}
|
|
15727
|
+
PropertyDefinition.prototype.applyDeoptimizations = doNotDeoptimize;
|
|
14975
15728
|
|
|
14976
15729
|
class ReturnStatement extends NodeBase {
|
|
14977
15730
|
hasEffects(context) {
|
|
@@ -14981,10 +15734,15 @@ class ReturnStatement extends NodeBase {
|
|
|
14981
15734
|
return false;
|
|
14982
15735
|
}
|
|
14983
15736
|
include(context, includeChildrenRecursively) {
|
|
14984
|
-
this.included
|
|
15737
|
+
if (!this.included)
|
|
15738
|
+
this.includeNode(context);
|
|
14985
15739
|
this.argument?.include(context, includeChildrenRecursively);
|
|
14986
15740
|
context.brokenFlow = true;
|
|
14987
15741
|
}
|
|
15742
|
+
includeNode(context) {
|
|
15743
|
+
this.included = true;
|
|
15744
|
+
this.argument?.includePath(UNKNOWN_PATH, context);
|
|
15745
|
+
}
|
|
14988
15746
|
initialise() {
|
|
14989
15747
|
super.initialise();
|
|
14990
15748
|
this.scope.addReturnExpression(this.argument || UNKNOWN_EXPRESSION);
|
|
@@ -14998,6 +15756,7 @@ class ReturnStatement extends NodeBase {
|
|
|
14998
15756
|
}
|
|
14999
15757
|
}
|
|
15000
15758
|
}
|
|
15759
|
+
ReturnStatement.prototype.applyDeoptimizations = doNotDeoptimize;
|
|
15001
15760
|
|
|
15002
15761
|
class SequenceExpression extends NodeBase {
|
|
15003
15762
|
deoptimizeArgumentsOnInteractionAtPath(interaction, path, recursionTracker) {
|
|
@@ -15025,10 +15784,15 @@ class SequenceExpression extends NodeBase {
|
|
|
15025
15784
|
for (const expression of this.expressions) {
|
|
15026
15785
|
if (includeChildrenRecursively ||
|
|
15027
15786
|
(expression === lastExpression && !(this.parent instanceof ExpressionStatement)) ||
|
|
15028
|
-
expression.shouldBeIncluded(context))
|
|
15787
|
+
expression.shouldBeIncluded(context)) {
|
|
15029
15788
|
expression.include(context, includeChildrenRecursively);
|
|
15789
|
+
}
|
|
15030
15790
|
}
|
|
15031
15791
|
}
|
|
15792
|
+
includePath(path, context) {
|
|
15793
|
+
this.included = true;
|
|
15794
|
+
this.expressions[this.expressions.length - 1].includePath(path, context);
|
|
15795
|
+
}
|
|
15032
15796
|
removeAnnotations(code) {
|
|
15033
15797
|
this.expressions[0].removeAnnotations(code);
|
|
15034
15798
|
}
|
|
@@ -15063,6 +15827,8 @@ class SequenceExpression extends NodeBase {
|
|
|
15063
15827
|
}
|
|
15064
15828
|
}
|
|
15065
15829
|
}
|
|
15830
|
+
SequenceExpression.prototype.includeNode = onlyIncludeSelfNoDeoptimize;
|
|
15831
|
+
SequenceExpression.prototype.applyDeoptimizations = doNotDeoptimize;
|
|
15066
15832
|
|
|
15067
15833
|
class Super extends NodeBase {
|
|
15068
15834
|
bind() {
|
|
@@ -15074,11 +15840,15 @@ class Super extends NodeBase {
|
|
|
15074
15840
|
deoptimizePath(path) {
|
|
15075
15841
|
this.variable.deoptimizePath(path);
|
|
15076
15842
|
}
|
|
15077
|
-
include() {
|
|
15078
|
-
if (!this.included)
|
|
15079
|
-
this.
|
|
15080
|
-
|
|
15081
|
-
|
|
15843
|
+
include(context) {
|
|
15844
|
+
if (!this.included)
|
|
15845
|
+
this.includeNode(context);
|
|
15846
|
+
}
|
|
15847
|
+
includeNode(context) {
|
|
15848
|
+
this.included = true;
|
|
15849
|
+
if (!this.deoptimized)
|
|
15850
|
+
this.applyDeoptimizations();
|
|
15851
|
+
this.scope.context.includeVariableInModule(this.variable, EMPTY_PATH, context);
|
|
15082
15852
|
}
|
|
15083
15853
|
}
|
|
15084
15854
|
|
|
@@ -15103,22 +15873,24 @@ class SwitchCase extends NodeBase {
|
|
|
15103
15873
|
}
|
|
15104
15874
|
}
|
|
15105
15875
|
render(code, options, nodeRenderOptions) {
|
|
15106
|
-
if (this.
|
|
15107
|
-
|
|
15108
|
-
|
|
15876
|
+
if (this.test) {
|
|
15877
|
+
this.test.render(code, options);
|
|
15878
|
+
if (this.test.start === this.start + 4) {
|
|
15879
|
+
code.prependLeft(this.test.start, ' ');
|
|
15109
15880
|
}
|
|
15881
|
+
}
|
|
15882
|
+
if (this.consequent.length > 0) {
|
|
15110
15883
|
const testEnd = this.test
|
|
15111
15884
|
? this.test.end
|
|
15112
15885
|
: findFirstOccurrenceOutsideComment(code.original, 'default', this.start) + 7;
|
|
15113
15886
|
const consequentStart = findFirstOccurrenceOutsideComment(code.original, ':', testEnd) + 1;
|
|
15114
15887
|
renderStatementList(this.consequent, code, consequentStart, nodeRenderOptions.end, options);
|
|
15115
15888
|
}
|
|
15116
|
-
else {
|
|
15117
|
-
super.render(code, options);
|
|
15118
|
-
}
|
|
15119
15889
|
}
|
|
15120
15890
|
}
|
|
15121
15891
|
SwitchCase.prototype.needsBoundaries = true;
|
|
15892
|
+
SwitchCase.prototype.includeNode = onlyIncludeSelfNoDeoptimize;
|
|
15893
|
+
SwitchCase.prototype.applyDeoptimizations = doNotDeoptimize;
|
|
15122
15894
|
|
|
15123
15895
|
class SwitchStatement extends NodeBase {
|
|
15124
15896
|
createScope(parentScope) {
|
|
@@ -15201,6 +15973,8 @@ class SwitchStatement extends NodeBase {
|
|
|
15201
15973
|
}
|
|
15202
15974
|
}
|
|
15203
15975
|
}
|
|
15976
|
+
SwitchStatement.prototype.includeNode = onlyIncludeSelfNoDeoptimize;
|
|
15977
|
+
SwitchStatement.prototype.applyDeoptimizations = doNotDeoptimize;
|
|
15204
15978
|
|
|
15205
15979
|
class TaggedTemplateExpression extends CallExpressionBase {
|
|
15206
15980
|
bind() {
|
|
@@ -15224,8 +15998,8 @@ class TaggedTemplateExpression extends CallExpressionBase {
|
|
|
15224
15998
|
this.tag.hasEffectsOnInteractionAtPath(EMPTY_PATH, this.interaction, context));
|
|
15225
15999
|
}
|
|
15226
16000
|
include(context, includeChildrenRecursively) {
|
|
15227
|
-
if (!this.
|
|
15228
|
-
this.
|
|
16001
|
+
if (!this.included)
|
|
16002
|
+
this.includeNode(context);
|
|
15229
16003
|
if (includeChildrenRecursively) {
|
|
15230
16004
|
super.include(context, includeChildrenRecursively);
|
|
15231
16005
|
}
|
|
@@ -15234,7 +16008,7 @@ class TaggedTemplateExpression extends CallExpressionBase {
|
|
|
15234
16008
|
this.tag.include(context, includeChildrenRecursively);
|
|
15235
16009
|
this.quasi.include(context, includeChildrenRecursively);
|
|
15236
16010
|
}
|
|
15237
|
-
this.tag.includeCallArguments(context, this.
|
|
16011
|
+
this.tag.includeCallArguments(context, this.interaction);
|
|
15238
16012
|
const [returnExpression] = this.getReturnExpression();
|
|
15239
16013
|
if (!returnExpression.included) {
|
|
15240
16014
|
returnExpression.include(context, false);
|
|
@@ -15269,6 +16043,7 @@ class TaggedTemplateExpression extends CallExpressionBase {
|
|
|
15269
16043
|
return this.returnExpression;
|
|
15270
16044
|
}
|
|
15271
16045
|
}
|
|
16046
|
+
TaggedTemplateExpression.prototype.includeNode = onlyIncludeSelf;
|
|
15272
16047
|
|
|
15273
16048
|
class TemplateElement extends NodeBase {
|
|
15274
16049
|
get tail() {
|
|
@@ -15282,15 +16057,13 @@ class TemplateElement extends NodeBase {
|
|
|
15282
16057
|
hasEffects() {
|
|
15283
16058
|
return false;
|
|
15284
16059
|
}
|
|
15285
|
-
include() {
|
|
15286
|
-
this.included = true;
|
|
15287
|
-
}
|
|
15288
16060
|
parseNode(esTreeNode) {
|
|
15289
16061
|
this.value = esTreeNode.value;
|
|
15290
16062
|
return super.parseNode(esTreeNode);
|
|
15291
16063
|
}
|
|
15292
16064
|
render() { }
|
|
15293
16065
|
}
|
|
16066
|
+
TemplateElement.prototype.includeNode = onlyIncludeSelf;
|
|
15294
16067
|
|
|
15295
16068
|
class TemplateLiteral extends NodeBase {
|
|
15296
16069
|
deoptimizeArgumentsOnInteractionAtPath() { }
|
|
@@ -15315,6 +16088,14 @@ class TemplateLiteral extends NodeBase {
|
|
|
15315
16088
|
}
|
|
15316
16089
|
return true;
|
|
15317
16090
|
}
|
|
16091
|
+
includeNode(context) {
|
|
16092
|
+
this.included = true;
|
|
16093
|
+
if (!this.deoptimized)
|
|
16094
|
+
this.applyDeoptimizations();
|
|
16095
|
+
for (const node of this.expressions) {
|
|
16096
|
+
node.includePath(UNKNOWN_PATH, context);
|
|
16097
|
+
}
|
|
16098
|
+
}
|
|
15318
16099
|
render(code, options) {
|
|
15319
16100
|
code.indentExclusionRanges.push([this.start, this.end]);
|
|
15320
16101
|
super.render(code, options);
|
|
@@ -15324,13 +16105,13 @@ class TemplateLiteral extends NodeBase {
|
|
|
15324
16105
|
class ModuleScope extends ChildScope {
|
|
15325
16106
|
constructor(parent, context) {
|
|
15326
16107
|
super(parent, context);
|
|
15327
|
-
this.variables.set('this', new LocalVariable('this', null, UNDEFINED_EXPRESSION, context, 'other'));
|
|
16108
|
+
this.variables.set('this', new LocalVariable('this', null, UNDEFINED_EXPRESSION, EMPTY_PATH, context, 'other'));
|
|
15328
16109
|
}
|
|
15329
|
-
addDeclaration(identifier, context, init, kind) {
|
|
16110
|
+
addDeclaration(identifier, context, init, destructuredInitPath, kind) {
|
|
15330
16111
|
if (this.context.module.importDescriptions.has(identifier.name)) {
|
|
15331
16112
|
context.error(parseAst_js.logRedeclarationError(identifier.name), identifier.start);
|
|
15332
16113
|
}
|
|
15333
|
-
return super.addDeclaration(identifier, context, init, kind);
|
|
16114
|
+
return super.addDeclaration(identifier, context, init, destructuredInitPath, kind);
|
|
15334
16115
|
}
|
|
15335
16116
|
addExportDefaultDeclaration(name, exportDefaultDeclaration, context) {
|
|
15336
16117
|
const variable = new ExportDefaultVariable(name, exportDefaultDeclaration, context);
|
|
@@ -15375,10 +16156,23 @@ class ThisExpression extends NodeBase {
|
|
|
15375
16156
|
}
|
|
15376
16157
|
return this.variable.hasEffectsOnInteractionAtPath(path, interaction, context);
|
|
15377
16158
|
}
|
|
15378
|
-
include() {
|
|
16159
|
+
include(context) {
|
|
16160
|
+
if (!this.included)
|
|
16161
|
+
this.includeNode(context);
|
|
16162
|
+
}
|
|
16163
|
+
includeNode(context) {
|
|
16164
|
+
this.included = true;
|
|
16165
|
+
if (!this.deoptimized)
|
|
16166
|
+
this.applyDeoptimizations();
|
|
16167
|
+
this.scope.context.includeVariableInModule(this.variable, EMPTY_PATH, context);
|
|
16168
|
+
}
|
|
16169
|
+
includePath(path, context) {
|
|
15379
16170
|
if (!this.included) {
|
|
15380
16171
|
this.included = true;
|
|
15381
|
-
this.scope.context.includeVariableInModule(this.variable);
|
|
16172
|
+
this.scope.context.includeVariableInModule(this.variable, path, context);
|
|
16173
|
+
}
|
|
16174
|
+
else if (path.length > 0) {
|
|
16175
|
+
this.variable.includePath(path, context);
|
|
15382
16176
|
}
|
|
15383
16177
|
}
|
|
15384
16178
|
initialise() {
|
|
@@ -15406,7 +16200,8 @@ class ThrowStatement extends NodeBase {
|
|
|
15406
16200
|
return true;
|
|
15407
16201
|
}
|
|
15408
16202
|
include(context, includeChildrenRecursively) {
|
|
15409
|
-
this.included
|
|
16203
|
+
if (!this.included)
|
|
16204
|
+
this.includeNode(context);
|
|
15410
16205
|
this.argument.include(context, includeChildrenRecursively);
|
|
15411
16206
|
context.brokenFlow = true;
|
|
15412
16207
|
}
|
|
@@ -15417,6 +16212,7 @@ class ThrowStatement extends NodeBase {
|
|
|
15417
16212
|
}
|
|
15418
16213
|
}
|
|
15419
16214
|
}
|
|
16215
|
+
ThrowStatement.prototype.includeNode = onlyIncludeSelf;
|
|
15420
16216
|
|
|
15421
16217
|
class TryStatement extends NodeBase {
|
|
15422
16218
|
constructor() {
|
|
@@ -15453,6 +16249,8 @@ class TryStatement extends NodeBase {
|
|
|
15453
16249
|
this.finalizer?.include(context, includeChildrenRecursively);
|
|
15454
16250
|
}
|
|
15455
16251
|
}
|
|
16252
|
+
TryStatement.prototype.includeNode = onlyIncludeSelfNoDeoptimize;
|
|
16253
|
+
TryStatement.prototype.applyDeoptimizations = doNotDeoptimize;
|
|
15456
16254
|
|
|
15457
16255
|
const unaryOperators = {
|
|
15458
16256
|
'!': value => !value,
|
|
@@ -15510,7 +16308,7 @@ class UnaryExpression extends NodeBase {
|
|
|
15510
16308
|
return this.renderedLiteralValue;
|
|
15511
16309
|
return (this.renderedLiteralValue = includeChildrenRecursively
|
|
15512
16310
|
? UnknownValue
|
|
15513
|
-
:
|
|
16311
|
+
: getRenderedLiteralValue(this.getLiteralValueAtPath(EMPTY_PATH, SHARED_RECURSION_TRACKER, this)));
|
|
15514
16312
|
}
|
|
15515
16313
|
include(context, includeChildrenRecursively, _options) {
|
|
15516
16314
|
if (!this.deoptimized)
|
|
@@ -15527,11 +16325,16 @@ class UnaryExpression extends NodeBase {
|
|
|
15527
16325
|
super.render(code, options);
|
|
15528
16326
|
}
|
|
15529
16327
|
else {
|
|
15530
|
-
|
|
16328
|
+
let value = this.renderedLiteralValue;
|
|
16329
|
+
if (!CHARACTERS_THAT_DO_NOT_REQUIRE_SPACE.test(code.original[this.start - 1])) {
|
|
16330
|
+
value = ` ${value}`;
|
|
16331
|
+
}
|
|
16332
|
+
code.overwrite(this.start, this.end, value);
|
|
15531
16333
|
}
|
|
15532
16334
|
}
|
|
15533
16335
|
}
|
|
15534
|
-
|
|
16336
|
+
const CHARACTERS_THAT_DO_NOT_REQUIRE_SPACE = /[\s([=%&*+-/<>^|,?:;]/;
|
|
16337
|
+
function getRenderedLiteralValue(value) {
|
|
15535
16338
|
if (value === undefined || typeof value === 'boolean') {
|
|
15536
16339
|
return String(value);
|
|
15537
16340
|
}
|
|
@@ -15554,6 +16357,7 @@ function getSimplifiedNumber(value) {
|
|
|
15554
16357
|
const stringifiedValue = String(value).replace('+', '');
|
|
15555
16358
|
return finalizedExp.length < stringifiedValue.length ? finalizedExp : stringifiedValue;
|
|
15556
16359
|
}
|
|
16360
|
+
UnaryExpression.prototype.includeNode = onlyIncludeSelf;
|
|
15557
16361
|
|
|
15558
16362
|
class UpdateExpression extends NodeBase {
|
|
15559
16363
|
hasEffects(context) {
|
|
@@ -15565,9 +16369,8 @@ class UpdateExpression extends NodeBase {
|
|
|
15565
16369
|
return path.length > 1 || type !== INTERACTION_ACCESSED;
|
|
15566
16370
|
}
|
|
15567
16371
|
include(context, includeChildrenRecursively) {
|
|
15568
|
-
if (!this.
|
|
15569
|
-
this.
|
|
15570
|
-
this.included = true;
|
|
16372
|
+
if (!this.included)
|
|
16373
|
+
this.includeNode(context);
|
|
15571
16374
|
this.argument.includeAsAssignmentTarget(context, includeChildrenRecursively, true);
|
|
15572
16375
|
}
|
|
15573
16376
|
initialise() {
|
|
@@ -15606,6 +16409,7 @@ class UpdateExpression extends NodeBase {
|
|
|
15606
16409
|
this.scope.context.requestTreeshakingPass();
|
|
15607
16410
|
}
|
|
15608
16411
|
}
|
|
16412
|
+
UpdateExpression.prototype.includeNode = onlyIncludeSelf;
|
|
15609
16413
|
|
|
15610
16414
|
function areAllDeclarationsIncludedAndNotExported(declarations, exportNamesByVariable) {
|
|
15611
16415
|
for (const declarator of declarations) {
|
|
@@ -15636,8 +16440,9 @@ class VariableDeclaration extends NodeBase {
|
|
|
15636
16440
|
include(context, includeChildrenRecursively, { asSingleStatement } = parseAst_js.BLANK) {
|
|
15637
16441
|
this.included = true;
|
|
15638
16442
|
for (const declarator of this.declarations) {
|
|
15639
|
-
if (includeChildrenRecursively || declarator.shouldBeIncluded(context))
|
|
16443
|
+
if (includeChildrenRecursively || declarator.shouldBeIncluded(context)) {
|
|
15640
16444
|
declarator.include(context, includeChildrenRecursively);
|
|
16445
|
+
}
|
|
15641
16446
|
const { id, init } = declarator;
|
|
15642
16447
|
if (asSingleStatement) {
|
|
15643
16448
|
id.include(context, includeChildrenRecursively);
|
|
@@ -15675,7 +16480,6 @@ class VariableDeclaration extends NodeBase {
|
|
|
15675
16480
|
this.renderReplacedDeclarations(code, options);
|
|
15676
16481
|
}
|
|
15677
16482
|
}
|
|
15678
|
-
applyDeoptimizations() { }
|
|
15679
16483
|
renderDeclarationEnd(code, separatorString, lastSeparatorPos, actualContentEnd, renderedContentEnd, systemPatternExports, options) {
|
|
15680
16484
|
if (code.original.charCodeAt(this.end - 1) === 59 /*";"*/) {
|
|
15681
16485
|
code.remove(this.end - 1, this.end);
|
|
@@ -15718,8 +16522,7 @@ class VariableDeclaration extends NodeBase {
|
|
|
15718
16522
|
const singleSystemExport = gatherSystemExportsAndGetSingleExport(separatedNodes, options, aggregatedSystemExports);
|
|
15719
16523
|
for (const { node, start, separator, contentEnd, end } of separatedNodes) {
|
|
15720
16524
|
if (!node.included) {
|
|
15721
|
-
code
|
|
15722
|
-
node.removeAnnotations(code);
|
|
16525
|
+
treeshakeNode(node, code, start, end);
|
|
15723
16526
|
continue;
|
|
15724
16527
|
}
|
|
15725
16528
|
node.render(code, options);
|
|
@@ -15789,6 +16592,8 @@ function gatherSystemExportsAndGetSingleExport(separatedNodes, options, aggregat
|
|
|
15789
16592
|
}
|
|
15790
16593
|
return singleSystemExport;
|
|
15791
16594
|
}
|
|
16595
|
+
VariableDeclaration.prototype.includeNode = onlyIncludeSelfNoDeoptimize;
|
|
16596
|
+
VariableDeclaration.prototype.applyDeoptimizations = doNotDeoptimize;
|
|
15792
16597
|
|
|
15793
16598
|
class WhileStatement extends NodeBase {
|
|
15794
16599
|
hasEffects(context) {
|
|
@@ -15802,13 +16607,25 @@ class WhileStatement extends NodeBase {
|
|
|
15802
16607
|
includeLoopBody(context, this.body, includeChildrenRecursively);
|
|
15803
16608
|
}
|
|
15804
16609
|
}
|
|
16610
|
+
WhileStatement.prototype.includeNode = onlyIncludeSelfNoDeoptimize;
|
|
16611
|
+
WhileStatement.prototype.applyDeoptimizations = doNotDeoptimize;
|
|
15805
16612
|
|
|
15806
16613
|
class YieldExpression extends NodeBase {
|
|
16614
|
+
applyDeoptimizations() {
|
|
16615
|
+
this.deoptimized = true;
|
|
16616
|
+
this.argument?.deoptimizePath(UNKNOWN_PATH);
|
|
16617
|
+
}
|
|
15807
16618
|
hasEffects(context) {
|
|
15808
16619
|
if (!this.deoptimized)
|
|
15809
16620
|
this.applyDeoptimizations();
|
|
15810
16621
|
return !(context.ignore.returnYield && !this.argument?.hasEffects(context));
|
|
15811
16622
|
}
|
|
16623
|
+
includeNode(context) {
|
|
16624
|
+
this.included = true;
|
|
16625
|
+
if (!this.deoptimized)
|
|
16626
|
+
this.applyDeoptimizations();
|
|
16627
|
+
this.argument?.includePath(UNKNOWN_PATH, context);
|
|
16628
|
+
}
|
|
15812
16629
|
render(code, options) {
|
|
15813
16630
|
if (this.argument) {
|
|
15814
16631
|
this.argument.render(code, options, { preventASI: true });
|
|
@@ -16042,7 +16859,7 @@ const bufferParsers = [
|
|
|
16042
16859
|
const annotations = (node.annotations = parseAst_js.convertAnnotations(buffer[position + 1], buffer));
|
|
16043
16860
|
node.annotationNoSideEffects = annotations.some(comment => comment.type === 'noSideEffects');
|
|
16044
16861
|
const parameters = (node.params = convertNodeList(node, scope, buffer[position + 2], buffer));
|
|
16045
|
-
scope.addParameterVariables(parameters.map(parameter => parameter.declare('parameter', UNKNOWN_EXPRESSION)), parameters[parameters.length - 1] instanceof RestElement);
|
|
16862
|
+
scope.addParameterVariables(parameters.map(parameter => parameter.declare('parameter', EMPTY_PATH, UNKNOWN_EXPRESSION)), parameters[parameters.length - 1] instanceof RestElement);
|
|
16046
16863
|
node.body = convertNode(node, scope.bodyScope, buffer[position + 3], buffer);
|
|
16047
16864
|
},
|
|
16048
16865
|
function assignmentExpression(node, position, buffer) {
|
|
@@ -16088,7 +16905,7 @@ const bufferParsers = [
|
|
|
16088
16905
|
const parameterPosition = buffer[position];
|
|
16089
16906
|
const parameter = (node.param =
|
|
16090
16907
|
parameterPosition === 0 ? null : convertNode(node, scope, parameterPosition, buffer));
|
|
16091
|
-
parameter?.declare('parameter', UNKNOWN_EXPRESSION);
|
|
16908
|
+
parameter?.declare('parameter', EMPTY_PATH, UNKNOWN_EXPRESSION);
|
|
16092
16909
|
node.body = convertNode(node, scope.bodyScope, buffer[position + 1], buffer);
|
|
16093
16910
|
},
|
|
16094
16911
|
function chainExpression(node, position, buffer) {
|
|
@@ -16226,7 +17043,7 @@ const bufferParsers = [
|
|
|
16226
17043
|
node.id =
|
|
16227
17044
|
idPosition === 0 ? null : convertNode(node, scope.parent, idPosition, buffer);
|
|
16228
17045
|
const parameters = (node.params = convertNodeList(node, scope, buffer[position + 3], buffer));
|
|
16229
|
-
scope.addParameterVariables(parameters.map(parameter => parameter.declare('parameter', UNKNOWN_EXPRESSION)), parameters[parameters.length - 1] instanceof RestElement);
|
|
17046
|
+
scope.addParameterVariables(parameters.map(parameter => parameter.declare('parameter', EMPTY_PATH, UNKNOWN_EXPRESSION)), parameters[parameters.length - 1] instanceof RestElement);
|
|
16230
17047
|
node.body = convertNode(node, scope.bodyScope, buffer[position + 4], buffer);
|
|
16231
17048
|
},
|
|
16232
17049
|
function functionExpression(node, position, buffer) {
|
|
@@ -16239,7 +17056,7 @@ const bufferParsers = [
|
|
|
16239
17056
|
const idPosition = buffer[position + 2];
|
|
16240
17057
|
node.id = idPosition === 0 ? null : convertNode(node, node.idScope, idPosition, buffer);
|
|
16241
17058
|
const parameters = (node.params = convertNodeList(node, scope, buffer[position + 3], buffer));
|
|
16242
|
-
scope.addParameterVariables(parameters.map(parameter => parameter.declare('parameter', UNKNOWN_EXPRESSION)), parameters[parameters.length - 1] instanceof RestElement);
|
|
17059
|
+
scope.addParameterVariables(parameters.map(parameter => parameter.declare('parameter', EMPTY_PATH, UNKNOWN_EXPRESSION)), parameters[parameters.length - 1] instanceof RestElement);
|
|
16243
17060
|
node.body = convertNode(node, scope.bodyScope, buffer[position + 4], buffer);
|
|
16244
17061
|
},
|
|
16245
17062
|
function identifier(node, position, buffer) {
|
|
@@ -16703,8 +17520,8 @@ class ExportShimVariable extends Variable {
|
|
|
16703
17520
|
super(MISSING_EXPORT_SHIM_VARIABLE);
|
|
16704
17521
|
this.module = module;
|
|
16705
17522
|
}
|
|
16706
|
-
|
|
16707
|
-
super.
|
|
17523
|
+
includePath(path, context) {
|
|
17524
|
+
super.includePath(path, context);
|
|
16708
17525
|
this.module.needsExportShim = true;
|
|
16709
17526
|
}
|
|
16710
17527
|
}
|
|
@@ -17395,16 +18212,15 @@ class Module {
|
|
|
17395
18212
|
markModuleAndImpureDependenciesAsExecuted(this);
|
|
17396
18213
|
this.graph.needsTreeshakingPass = true;
|
|
17397
18214
|
}
|
|
18215
|
+
const inclusionContext = createInclusionContext();
|
|
17398
18216
|
for (const exportName of this.exports.keys()) {
|
|
17399
18217
|
if (includeNamespaceMembers || exportName !== this.info.syntheticNamedExports) {
|
|
17400
18218
|
const variable = this.getVariableForExportName(exportName)[0];
|
|
17401
18219
|
if (!variable) {
|
|
17402
18220
|
return parseAst_js.error(parseAst_js.logMissingEntryExport(exportName, this.id));
|
|
17403
18221
|
}
|
|
18222
|
+
this.includeVariable(variable, UNKNOWN_PATH, inclusionContext);
|
|
17404
18223
|
variable.deoptimizePath(UNKNOWN_PATH);
|
|
17405
|
-
if (!variable.included) {
|
|
17406
|
-
this.includeVariable(variable);
|
|
17407
|
-
}
|
|
17408
18224
|
}
|
|
17409
18225
|
}
|
|
17410
18226
|
for (const name of this.getReexports()) {
|
|
@@ -17412,7 +18228,7 @@ class Module {
|
|
|
17412
18228
|
if (variable) {
|
|
17413
18229
|
variable.deoptimizePath(UNKNOWN_PATH);
|
|
17414
18230
|
if (!variable.included) {
|
|
17415
|
-
this.includeVariable(variable);
|
|
18231
|
+
this.includeVariable(variable, UNKNOWN_PATH, inclusionContext);
|
|
17416
18232
|
}
|
|
17417
18233
|
if (variable instanceof ExternalVariable) {
|
|
17418
18234
|
variable.module.reexported = true;
|
|
@@ -17433,13 +18249,12 @@ class Module {
|
|
|
17433
18249
|
this.graph.needsTreeshakingPass = true;
|
|
17434
18250
|
}
|
|
17435
18251
|
let includeNamespaceMembers = false;
|
|
18252
|
+
const inclusionContext = createInclusionContext();
|
|
17436
18253
|
for (const name of names) {
|
|
17437
18254
|
const variable = this.getVariableForExportName(name)[0];
|
|
17438
18255
|
if (variable) {
|
|
17439
18256
|
variable.deoptimizePath(UNKNOWN_PATH);
|
|
17440
|
-
|
|
17441
|
-
this.includeVariable(variable);
|
|
17442
|
-
}
|
|
18257
|
+
this.includeVariable(variable, UNKNOWN_PATH, inclusionContext);
|
|
17443
18258
|
}
|
|
17444
18259
|
if (!this.exports.has(name) && !this.reexportDescriptions.has(name)) {
|
|
17445
18260
|
includeNamespaceMembers = true;
|
|
@@ -17540,6 +18355,7 @@ class Module {
|
|
|
17540
18355
|
manualPureFunctions: this.graph.pureFunctions,
|
|
17541
18356
|
module: this,
|
|
17542
18357
|
moduleContext: this.context,
|
|
18358
|
+
newlyIncludedVariableInits: this.graph.newlyIncludedVariableInits,
|
|
17543
18359
|
options: this.options,
|
|
17544
18360
|
requestTreeshakingPass: () => (this.graph.needsTreeshakingPass = true),
|
|
17545
18361
|
traceExport: (name) => this.getVariableForExportName(name)[0],
|
|
@@ -17880,13 +18696,13 @@ class Module {
|
|
|
17880
18696
|
for (const module of [this, ...this.exportAllModules]) {
|
|
17881
18697
|
if (module instanceof ExternalModule) {
|
|
17882
18698
|
const [externalVariable] = module.getVariableForExportName('*');
|
|
17883
|
-
externalVariable.
|
|
18699
|
+
externalVariable.includePath(UNKNOWN_PATH, createInclusionContext());
|
|
17884
18700
|
this.includedImports.add(externalVariable);
|
|
17885
18701
|
externalNamespaces.add(externalVariable);
|
|
17886
18702
|
}
|
|
17887
18703
|
else if (module.info.syntheticNamedExports) {
|
|
17888
18704
|
const syntheticNamespace = module.getSyntheticNamespace();
|
|
17889
|
-
syntheticNamespace.
|
|
18705
|
+
syntheticNamespace.includePath(UNKNOWN_PATH, createInclusionContext());
|
|
17890
18706
|
this.includedImports.add(syntheticNamespace);
|
|
17891
18707
|
syntheticNamespaces.add(syntheticNamespace);
|
|
17892
18708
|
}
|
|
@@ -17896,7 +18712,9 @@ class Module {
|
|
|
17896
18712
|
includeDynamicImport(node) {
|
|
17897
18713
|
const resolution = this.dynamicImports.find(dynamicImport => dynamicImport.node === node).resolution;
|
|
17898
18714
|
if (resolution instanceof Module) {
|
|
17899
|
-
resolution.includedDynamicImporters.
|
|
18715
|
+
if (!resolution.includedDynamicImporters.includes(this)) {
|
|
18716
|
+
resolution.includedDynamicImporters.push(this);
|
|
18717
|
+
}
|
|
17900
18718
|
const importedNames = this.options.treeshake
|
|
17901
18719
|
? node.getDeterministicImportedNames()
|
|
17902
18720
|
: undefined;
|
|
@@ -17908,15 +18726,15 @@ class Module {
|
|
|
17908
18726
|
}
|
|
17909
18727
|
}
|
|
17910
18728
|
}
|
|
17911
|
-
includeVariable(variable) {
|
|
17912
|
-
const variableModule = variable
|
|
17913
|
-
|
|
18729
|
+
includeVariable(variable, path, context) {
|
|
18730
|
+
const { included, module: variableModule } = variable;
|
|
18731
|
+
variable.includePath(path, context);
|
|
18732
|
+
if (included) {
|
|
17914
18733
|
if (variableModule instanceof Module && variableModule !== this) {
|
|
17915
18734
|
getAndExtendSideEffectModules(variable, this);
|
|
17916
18735
|
}
|
|
17917
18736
|
}
|
|
17918
18737
|
else {
|
|
17919
|
-
variable.include();
|
|
17920
18738
|
this.graph.needsTreeshakingPass = true;
|
|
17921
18739
|
if (variableModule instanceof Module) {
|
|
17922
18740
|
if (!variableModule.isExecuted) {
|
|
@@ -17933,8 +18751,8 @@ class Module {
|
|
|
17933
18751
|
}
|
|
17934
18752
|
}
|
|
17935
18753
|
}
|
|
17936
|
-
includeVariableInModule(variable) {
|
|
17937
|
-
this.includeVariable(variable);
|
|
18754
|
+
includeVariableInModule(variable, path, context) {
|
|
18755
|
+
this.includeVariable(variable, path, context);
|
|
17938
18756
|
const variableModule = variable.module;
|
|
17939
18757
|
if (variableModule && variableModule !== this) {
|
|
17940
18758
|
this.includedImports.add(variable);
|
|
@@ -21439,10 +22257,11 @@ class Graph {
|
|
|
21439
22257
|
this.options = options;
|
|
21440
22258
|
this.astLru = flru(5);
|
|
21441
22259
|
this.cachedModules = new Map();
|
|
21442
|
-
this.deoptimizationTracker = new
|
|
22260
|
+
this.deoptimizationTracker = new EntityPathTracker();
|
|
21443
22261
|
this.entryModules = [];
|
|
21444
22262
|
this.modulesById = new Map();
|
|
21445
22263
|
this.needsTreeshakingPass = false;
|
|
22264
|
+
this.newlyIncludedVariableInits = new Set();
|
|
21446
22265
|
this.phase = BuildPhase.LOAD_AND_PARSE;
|
|
21447
22266
|
this.scope = new GlobalScope();
|
|
21448
22267
|
this.watchFiles = Object.create(null);
|
|
@@ -21536,6 +22355,7 @@ class Graph {
|
|
|
21536
22355
|
}
|
|
21537
22356
|
if (this.options.treeshake) {
|
|
21538
22357
|
let treeshakingPass = 1;
|
|
22358
|
+
this.newlyIncludedVariableInits.clear();
|
|
21539
22359
|
do {
|
|
21540
22360
|
timeStart(`treeshaking pass ${treeshakingPass}`, 3);
|
|
21541
22361
|
this.needsTreeshakingPass = false;
|
|
@@ -21548,6 +22368,10 @@ class Graph {
|
|
|
21548
22368
|
else {
|
|
21549
22369
|
module.include();
|
|
21550
22370
|
}
|
|
22371
|
+
for (const entity of this.newlyIncludedVariableInits) {
|
|
22372
|
+
this.newlyIncludedVariableInits.delete(entity);
|
|
22373
|
+
entity.include(createInclusionContext(), false);
|
|
22374
|
+
}
|
|
21551
22375
|
}
|
|
21552
22376
|
}
|
|
21553
22377
|
if (treeshakingPass === 1) {
|