@rollup/wasm-node 4.32.0 → 4.33.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 +1539 -684
- 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 +1535 -680
- package/dist/shared/watch-cli.js +4 -20
- package/dist/shared/watch.js +3 -3
- 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.33.0-0
|
|
4
|
+
Tue, 28 Jan 2025 08:29:38 GMT - commit f854e1988542d09f9691923eddd80888e92240d3
|
|
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.33.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,174 @@ class DiscriminatedPathTracker {
|
|
|
3623
3558
|
return false;
|
|
3624
3559
|
}
|
|
3625
3560
|
}
|
|
3561
|
+
const UNKNOWN_INCLUDED_PATH = Object.freeze({ [UnknownKey]: parseAst_js.EMPTY_OBJECT });
|
|
3562
|
+
class IncludedFullPathTracker {
|
|
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
|
+
}
|
|
3592
|
+
const UNKNOWN_INCLUDED_TOP_LEVEL_PATH = Object.freeze({
|
|
3593
|
+
[UnknownKey]: true
|
|
3594
|
+
});
|
|
3595
|
+
class IncludedTopLevelPathTracker {
|
|
3596
|
+
constructor() {
|
|
3597
|
+
this.includedPaths = null;
|
|
3598
|
+
}
|
|
3599
|
+
includePathAndGetIfIncluded(path) {
|
|
3600
|
+
let included = true;
|
|
3601
|
+
const includedPaths = (this.includedPaths ||=
|
|
3602
|
+
((included = false), Object.create(null)));
|
|
3603
|
+
if (includedPaths[UnknownKey]) {
|
|
3604
|
+
return true;
|
|
3605
|
+
}
|
|
3606
|
+
const [firstPathSegment, secondPathSegment] = path;
|
|
3607
|
+
if (!firstPathSegment) {
|
|
3608
|
+
return included;
|
|
3609
|
+
}
|
|
3610
|
+
if (typeof firstPathSegment === 'symbol') {
|
|
3611
|
+
this.includedPaths = UNKNOWN_INCLUDED_TOP_LEVEL_PATH;
|
|
3612
|
+
return false;
|
|
3613
|
+
}
|
|
3614
|
+
if (secondPathSegment) {
|
|
3615
|
+
if (includedPaths[firstPathSegment] === UnknownKey) {
|
|
3616
|
+
return true;
|
|
3617
|
+
}
|
|
3618
|
+
includedPaths[firstPathSegment] = UnknownKey;
|
|
3619
|
+
return false;
|
|
3620
|
+
}
|
|
3621
|
+
if (includedPaths[firstPathSegment]) {
|
|
3622
|
+
return true;
|
|
3623
|
+
}
|
|
3624
|
+
includedPaths[firstPathSegment] = true;
|
|
3625
|
+
return false;
|
|
3626
|
+
}
|
|
3627
|
+
includeAllPaths(entity, context, basePath) {
|
|
3628
|
+
const { includedPaths } = this;
|
|
3629
|
+
if (includedPaths) {
|
|
3630
|
+
if (includedPaths[UnknownKey]) {
|
|
3631
|
+
entity.includePath([...basePath, UnknownKey], context);
|
|
3632
|
+
}
|
|
3633
|
+
else {
|
|
3634
|
+
const inclusionEntries = Object.entries(includedPaths);
|
|
3635
|
+
if (inclusionEntries.length === 0) {
|
|
3636
|
+
entity.includePath(basePath, context);
|
|
3637
|
+
}
|
|
3638
|
+
else {
|
|
3639
|
+
for (const [key, value] of inclusionEntries) {
|
|
3640
|
+
entity.includePath(value === UnknownKey ? [...basePath, key, UnknownKey] : [...basePath, key], context);
|
|
3641
|
+
}
|
|
3642
|
+
}
|
|
3643
|
+
}
|
|
3644
|
+
}
|
|
3645
|
+
}
|
|
3646
|
+
}
|
|
3647
|
+
|
|
3648
|
+
/** @import { Node } from 'estree' */
|
|
3649
|
+
|
|
3650
|
+
/**
|
|
3651
|
+
* @param {Node} node
|
|
3652
|
+
* @param {Node} parent
|
|
3653
|
+
* @returns {boolean}
|
|
3654
|
+
*/
|
|
3655
|
+
function is_reference(node, parent) {
|
|
3656
|
+
if (node.type === 'MemberExpression') {
|
|
3657
|
+
return !node.computed && is_reference(node.object, node);
|
|
3658
|
+
}
|
|
3659
|
+
|
|
3660
|
+
if (node.type !== 'Identifier') return false;
|
|
3661
|
+
|
|
3662
|
+
switch (parent?.type) {
|
|
3663
|
+
// disregard `bar` in `foo.bar`
|
|
3664
|
+
case 'MemberExpression':
|
|
3665
|
+
return parent.computed || node === parent.object;
|
|
3666
|
+
|
|
3667
|
+
// disregard the `foo` in `class {foo(){}}` but keep it in `class {[foo](){}}`
|
|
3668
|
+
case 'MethodDefinition':
|
|
3669
|
+
return parent.computed;
|
|
3670
|
+
|
|
3671
|
+
// disregard the `meta` in `import.meta`
|
|
3672
|
+
case 'MetaProperty':
|
|
3673
|
+
return parent.meta === node;
|
|
3674
|
+
|
|
3675
|
+
// disregard the `foo` in `class {foo=bar}` but keep it in `class {[foo]=bar}` and `class {bar=foo}`
|
|
3676
|
+
case 'PropertyDefinition':
|
|
3677
|
+
return parent.computed || node === parent.value;
|
|
3678
|
+
|
|
3679
|
+
// disregard the `bar` in `{ bar: foo }`, but keep it in `{ [bar]: foo }`
|
|
3680
|
+
case 'Property':
|
|
3681
|
+
return parent.computed || node === parent.value;
|
|
3682
|
+
|
|
3683
|
+
// disregard the `bar` in `export { foo as bar }` or
|
|
3684
|
+
// the foo in `import { foo as bar }`
|
|
3685
|
+
case 'ExportSpecifier':
|
|
3686
|
+
case 'ImportSpecifier':
|
|
3687
|
+
return node === parent.local;
|
|
3688
|
+
|
|
3689
|
+
// disregard the `foo` in `foo: while (...) { ... break foo; ... continue foo;}`
|
|
3690
|
+
case 'LabeledStatement':
|
|
3691
|
+
case 'BreakStatement':
|
|
3692
|
+
case 'ContinueStatement':
|
|
3693
|
+
return false;
|
|
3694
|
+
|
|
3695
|
+
default:
|
|
3696
|
+
return true;
|
|
3697
|
+
}
|
|
3698
|
+
}
|
|
3699
|
+
|
|
3700
|
+
function createInclusionContext() {
|
|
3701
|
+
return {
|
|
3702
|
+
brokenFlow: false,
|
|
3703
|
+
hasBreak: false,
|
|
3704
|
+
hasContinue: false,
|
|
3705
|
+
includedCallArguments: new Set(),
|
|
3706
|
+
includedLabels: new Set()
|
|
3707
|
+
};
|
|
3708
|
+
}
|
|
3709
|
+
function createHasEffectsContext() {
|
|
3710
|
+
return {
|
|
3711
|
+
accessed: new EntityPathTracker(),
|
|
3712
|
+
assigned: new EntityPathTracker(),
|
|
3713
|
+
brokenFlow: false,
|
|
3714
|
+
called: new DiscriminatedPathTracker(),
|
|
3715
|
+
hasBreak: false,
|
|
3716
|
+
hasContinue: false,
|
|
3717
|
+
ignore: {
|
|
3718
|
+
breaks: false,
|
|
3719
|
+
continues: false,
|
|
3720
|
+
labels: new Set(),
|
|
3721
|
+
returnYield: false,
|
|
3722
|
+
this: false
|
|
3723
|
+
},
|
|
3724
|
+
includedLabels: new Set(),
|
|
3725
|
+
instantiated: new DiscriminatedPathTracker(),
|
|
3726
|
+
replacedVariableInits: new Map()
|
|
3727
|
+
};
|
|
3728
|
+
}
|
|
3626
3729
|
|
|
3627
3730
|
function isFlagSet(flags, flag) {
|
|
3628
3731
|
return (flags & flag) !== 0;
|
|
@@ -3662,12 +3765,25 @@ class ExpressionEntity {
|
|
|
3662
3765
|
hasEffectsOnInteractionAtPath(_path, _interaction, _context) {
|
|
3663
3766
|
return true;
|
|
3664
3767
|
}
|
|
3665
|
-
include(
|
|
3768
|
+
include(context, _includeChildrenRecursively, _options) {
|
|
3769
|
+
if (!this.included)
|
|
3770
|
+
this.includeNode(context);
|
|
3771
|
+
}
|
|
3772
|
+
includeNode(_context) {
|
|
3666
3773
|
this.included = true;
|
|
3667
3774
|
}
|
|
3668
|
-
|
|
3669
|
-
|
|
3670
|
-
|
|
3775
|
+
includePath(_path, context) {
|
|
3776
|
+
if (!this.included)
|
|
3777
|
+
this.includeNode(context);
|
|
3778
|
+
}
|
|
3779
|
+
/* We are both including and including an unknown path here as the former
|
|
3780
|
+
* ensures that nested nodes are included while the latter ensures that all
|
|
3781
|
+
* paths of the expression are included.
|
|
3782
|
+
* */
|
|
3783
|
+
includeCallArguments(context, interaction) {
|
|
3784
|
+
for (const argument of interaction.args) {
|
|
3785
|
+
argument?.includePath(UNKNOWN_PATH, context);
|
|
3786
|
+
argument?.include(context, false);
|
|
3671
3787
|
}
|
|
3672
3788
|
}
|
|
3673
3789
|
shouldBeIncluded(_context) {
|
|
@@ -3706,6 +3822,19 @@ const NODE_INTERACTION_UNKNOWN_CALL = {
|
|
|
3706
3822
|
withNew: false
|
|
3707
3823
|
};
|
|
3708
3824
|
|
|
3825
|
+
const PureFunctionKey = Symbol('PureFunction');
|
|
3826
|
+
const getPureFunctions = ({ treeshake }) => {
|
|
3827
|
+
const pureFunctions = Object.create(null);
|
|
3828
|
+
for (const functionName of treeshake ? treeshake.manualPureFunctions : []) {
|
|
3829
|
+
let currentFunctions = pureFunctions;
|
|
3830
|
+
for (const pathSegment of functionName.split('.')) {
|
|
3831
|
+
currentFunctions = currentFunctions[pathSegment] ||= Object.create(null);
|
|
3832
|
+
}
|
|
3833
|
+
currentFunctions[PureFunctionKey] = true;
|
|
3834
|
+
}
|
|
3835
|
+
return pureFunctions;
|
|
3836
|
+
};
|
|
3837
|
+
|
|
3709
3838
|
class Variable extends ExpressionEntity {
|
|
3710
3839
|
markReassigned() {
|
|
3711
3840
|
this.isReassigned = true;
|
|
@@ -3782,9 +3911,9 @@ class Variable extends ExpressionEntity {
|
|
|
3782
3911
|
* has not been included previously. Once a variable is included, it should
|
|
3783
3912
|
* take care all its declarations are included.
|
|
3784
3913
|
*/
|
|
3785
|
-
|
|
3914
|
+
includePath(path, context) {
|
|
3786
3915
|
this.included = true;
|
|
3787
|
-
this.renderedLikeHoisted?.
|
|
3916
|
+
this.renderedLikeHoisted?.includePath(path, context);
|
|
3788
3917
|
}
|
|
3789
3918
|
/**
|
|
3790
3919
|
* Links the rendered name of this variable to another variable and includes
|
|
@@ -3816,8 +3945,8 @@ class ExternalVariable extends Variable {
|
|
|
3816
3945
|
hasEffectsOnInteractionAtPath(path, { type }) {
|
|
3817
3946
|
return type !== INTERACTION_ACCESSED || path.length > (this.isNamespace ? 1 : 0);
|
|
3818
3947
|
}
|
|
3819
|
-
|
|
3820
|
-
super.
|
|
3948
|
+
includePath(path, context) {
|
|
3949
|
+
super.includePath(path, context);
|
|
3821
3950
|
this.module.used = true;
|
|
3822
3951
|
}
|
|
3823
3952
|
}
|
|
@@ -4116,36 +4245,6 @@ const childNodeKeys = {
|
|
|
4116
4245
|
YieldExpression: ['argument']
|
|
4117
4246
|
};
|
|
4118
4247
|
|
|
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
4248
|
const INCLUDE_PARAMETERS = 'variables';
|
|
4150
4249
|
const IS_SKIPPED_CHAIN = Symbol('IS_SKIPPED_CHAIN');
|
|
4151
4250
|
class NodeBase extends ExpressionEntity {
|
|
@@ -4215,9 +4314,8 @@ class NodeBase extends ExpressionEntity {
|
|
|
4215
4314
|
this.hasEffectsOnInteractionAtPath(EMPTY_PATH, this.assignmentInteraction, context));
|
|
4216
4315
|
}
|
|
4217
4316
|
include(context, includeChildrenRecursively, _options) {
|
|
4218
|
-
if (!this.
|
|
4219
|
-
this.
|
|
4220
|
-
this.included = true;
|
|
4317
|
+
if (!this.included)
|
|
4318
|
+
this.includeNode(context);
|
|
4221
4319
|
for (const key of childNodeKeys[this.type]) {
|
|
4222
4320
|
const value = this[key];
|
|
4223
4321
|
if (value === null)
|
|
@@ -4232,6 +4330,24 @@ class NodeBase extends ExpressionEntity {
|
|
|
4232
4330
|
}
|
|
4233
4331
|
}
|
|
4234
4332
|
}
|
|
4333
|
+
includeNode(context) {
|
|
4334
|
+
this.included = true;
|
|
4335
|
+
if (!this.deoptimized)
|
|
4336
|
+
this.applyDeoptimizations();
|
|
4337
|
+
for (const key of childNodeKeys[this.type]) {
|
|
4338
|
+
const value = this[key];
|
|
4339
|
+
if (value === null)
|
|
4340
|
+
continue;
|
|
4341
|
+
if (Array.isArray(value)) {
|
|
4342
|
+
for (const child of value) {
|
|
4343
|
+
child?.includePath(UNKNOWN_PATH, context);
|
|
4344
|
+
}
|
|
4345
|
+
}
|
|
4346
|
+
else {
|
|
4347
|
+
value.includePath(UNKNOWN_PATH, context);
|
|
4348
|
+
}
|
|
4349
|
+
}
|
|
4350
|
+
}
|
|
4235
4351
|
includeAsAssignmentTarget(context, includeChildrenRecursively, _deoptimizeAccess) {
|
|
4236
4352
|
this.include(context, includeChildrenRecursively);
|
|
4237
4353
|
}
|
|
@@ -4335,6 +4451,17 @@ class NodeBase extends ExpressionEntity {
|
|
|
4335
4451
|
function createChildNodeKeysForNode(esTreeNode) {
|
|
4336
4452
|
return Object.keys(esTreeNode).filter(key => typeof esTreeNode[key] === 'object' && key.charCodeAt(0) !== 95 /* _ */);
|
|
4337
4453
|
}
|
|
4454
|
+
function onlyIncludeSelf() {
|
|
4455
|
+
this.included = true;
|
|
4456
|
+
if (!this.deoptimized)
|
|
4457
|
+
this.applyDeoptimizations();
|
|
4458
|
+
}
|
|
4459
|
+
function onlyIncludeSelfNoDeoptimize() {
|
|
4460
|
+
this.included = true;
|
|
4461
|
+
}
|
|
4462
|
+
function doNotDeoptimize() {
|
|
4463
|
+
this.deoptimized = true;
|
|
4464
|
+
}
|
|
4338
4465
|
|
|
4339
4466
|
function isObjectExpressionNode(node) {
|
|
4340
4467
|
return node instanceof NodeBase && node.type === parseAst_js.ObjectExpression;
|
|
@@ -4347,8 +4474,8 @@ function assembleMemberDescriptions(memberDescriptions, inheritedDescriptions =
|
|
|
4347
4474
|
return Object.create(inheritedDescriptions, memberDescriptions);
|
|
4348
4475
|
}
|
|
4349
4476
|
const UNDEFINED_EXPRESSION = new (class UndefinedExpression extends ExpressionEntity {
|
|
4350
|
-
getLiteralValueAtPath() {
|
|
4351
|
-
return undefined;
|
|
4477
|
+
getLiteralValueAtPath(path) {
|
|
4478
|
+
return path.length > 0 ? UnknownValue : undefined;
|
|
4352
4479
|
}
|
|
4353
4480
|
})();
|
|
4354
4481
|
const returnsUnknown = {
|
|
@@ -4545,31 +4672,6 @@ function getMemberReturnExpressionWhenCalled(members, memberName) {
|
|
|
4545
4672
|
return [members[memberName].returns, false];
|
|
4546
4673
|
}
|
|
4547
4674
|
|
|
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
4675
|
class Method extends ExpressionEntity {
|
|
4574
4676
|
constructor(description) {
|
|
4575
4677
|
super();
|
|
@@ -4695,6 +4797,7 @@ class ObjectEntity extends ExpressionEntity {
|
|
|
4695
4797
|
this.unknownIntegerProps = [];
|
|
4696
4798
|
this.unmatchableGetters = [];
|
|
4697
4799
|
this.unmatchablePropertiesAndGetters = [];
|
|
4800
|
+
this.unmatchablePropertiesAndSetters = [];
|
|
4698
4801
|
this.unmatchableSetters = [];
|
|
4699
4802
|
if (Array.isArray(properties)) {
|
|
4700
4803
|
this.buildPropertyMaps(properties);
|
|
@@ -4851,7 +4954,12 @@ class ObjectEntity extends ExpressionEntity {
|
|
|
4851
4954
|
}
|
|
4852
4955
|
getLiteralValueAtPath(path, recursionTracker, origin) {
|
|
4853
4956
|
if (path.length === 0) {
|
|
4854
|
-
|
|
4957
|
+
// This should actually be "UnknownTruthyValue". However, this currently
|
|
4958
|
+
// causes an issue with TypeScript enums in files with moduleSideEffects:
|
|
4959
|
+
// false because we cannot properly track whether a "var" has been
|
|
4960
|
+
// initialized. This should be reverted once we can properly track this.
|
|
4961
|
+
// return UnknownTruthyValue;
|
|
4962
|
+
return UnknownValue;
|
|
4855
4963
|
}
|
|
4856
4964
|
const key = path[0];
|
|
4857
4965
|
const expressionAtPath = this.getMemberExpressionAndTrackDeopt(key, origin);
|
|
@@ -4929,9 +5037,36 @@ class ObjectEntity extends ExpressionEntity {
|
|
|
4929
5037
|
}
|
|
4930
5038
|
return false;
|
|
4931
5039
|
}
|
|
5040
|
+
include(context, includeChildrenRecursively) {
|
|
5041
|
+
this.included = true;
|
|
5042
|
+
for (const property of this.allProperties) {
|
|
5043
|
+
if (includeChildrenRecursively || property.shouldBeIncluded(context)) {
|
|
5044
|
+
property.include(context, includeChildrenRecursively);
|
|
5045
|
+
}
|
|
5046
|
+
}
|
|
5047
|
+
this.prototypeExpression?.include(context, includeChildrenRecursively);
|
|
5048
|
+
}
|
|
5049
|
+
includePath(path, context) {
|
|
5050
|
+
this.included = true;
|
|
5051
|
+
if (path.length === 0)
|
|
5052
|
+
return;
|
|
5053
|
+
const [key, ...subPath] = path;
|
|
5054
|
+
const [includedMembers, includedPath] = typeof key === 'string'
|
|
5055
|
+
? [
|
|
5056
|
+
new Set([
|
|
5057
|
+
...(this.propertiesAndGettersByKey[key] || this.unmatchablePropertiesAndGetters),
|
|
5058
|
+
...(this.propertiesAndSettersByKey[key] || this.unmatchablePropertiesAndSetters)
|
|
5059
|
+
]),
|
|
5060
|
+
subPath
|
|
5061
|
+
]
|
|
5062
|
+
: [this.allProperties, UNKNOWN_PATH];
|
|
5063
|
+
for (const property of includedMembers) {
|
|
5064
|
+
property.includePath(includedPath, context);
|
|
5065
|
+
}
|
|
5066
|
+
this.prototypeExpression?.includePath(path, context);
|
|
5067
|
+
}
|
|
4932
5068
|
buildPropertyMaps(properties) {
|
|
4933
|
-
const { allProperties, propertiesAndGettersByKey, propertiesAndSettersByKey, settersByKey, gettersByKey, unknownIntegerProps, unmatchablePropertiesAndGetters, unmatchableGetters, unmatchableSetters } = this;
|
|
4934
|
-
const unmatchablePropertiesAndSetters = [];
|
|
5069
|
+
const { allProperties, propertiesAndGettersByKey, propertiesAndSettersByKey, settersByKey, gettersByKey, unknownIntegerProps, unmatchablePropertiesAndGetters, unmatchablePropertiesAndSetters, unmatchableGetters, unmatchableSetters } = this;
|
|
4935
5070
|
for (let index = properties.length - 1; index >= 0; index--) {
|
|
4936
5071
|
const { key, kind, property } = properties[index];
|
|
4937
5072
|
allProperties.push(property);
|
|
@@ -5201,6 +5336,37 @@ const ARRAY_PROTOTYPE = new ObjectEntity({
|
|
|
5201
5336
|
values: METHOD_DEOPTS_SELF_RETURNS_UNKNOWN
|
|
5202
5337
|
}, OBJECT_PROTOTYPE, true);
|
|
5203
5338
|
|
|
5339
|
+
class SpreadElement extends NodeBase {
|
|
5340
|
+
deoptimizeArgumentsOnInteractionAtPath(interaction, path, recursionTracker) {
|
|
5341
|
+
if (path.length > 0) {
|
|
5342
|
+
this.argument.deoptimizeArgumentsOnInteractionAtPath(interaction, UNKNOWN_PATH, recursionTracker);
|
|
5343
|
+
}
|
|
5344
|
+
}
|
|
5345
|
+
hasEffects(context) {
|
|
5346
|
+
if (!this.deoptimized)
|
|
5347
|
+
this.applyDeoptimizations();
|
|
5348
|
+
const { propertyReadSideEffects } = this.scope.context.options
|
|
5349
|
+
.treeshake;
|
|
5350
|
+
return (this.argument.hasEffects(context) ||
|
|
5351
|
+
(propertyReadSideEffects &&
|
|
5352
|
+
(propertyReadSideEffects === 'always' ||
|
|
5353
|
+
this.argument.hasEffectsOnInteractionAtPath(UNKNOWN_PATH, NODE_INTERACTION_UNKNOWN_ACCESS, context))));
|
|
5354
|
+
}
|
|
5355
|
+
includeNode(context) {
|
|
5356
|
+
this.included = true;
|
|
5357
|
+
if (!this.deoptimized)
|
|
5358
|
+
this.applyDeoptimizations();
|
|
5359
|
+
this.argument.includePath(UNKNOWN_PATH, context);
|
|
5360
|
+
}
|
|
5361
|
+
applyDeoptimizations() {
|
|
5362
|
+
this.deoptimized = true;
|
|
5363
|
+
// Only properties of properties of the argument could become subject to reassignment
|
|
5364
|
+
// This will also reassign the return values of iterators
|
|
5365
|
+
this.argument.deoptimizePath([UnknownKey, UnknownKey]);
|
|
5366
|
+
this.scope.context.requestTreeshakingPass();
|
|
5367
|
+
}
|
|
5368
|
+
}
|
|
5369
|
+
|
|
5204
5370
|
class ArrayExpression extends NodeBase {
|
|
5205
5371
|
constructor() {
|
|
5206
5372
|
super(...arguments);
|
|
@@ -5221,6 +5387,16 @@ class ArrayExpression extends NodeBase {
|
|
|
5221
5387
|
hasEffectsOnInteractionAtPath(path, interaction, context) {
|
|
5222
5388
|
return this.getObjectEntity().hasEffectsOnInteractionAtPath(path, interaction, context);
|
|
5223
5389
|
}
|
|
5390
|
+
includeNode(context) {
|
|
5391
|
+
this.included = true;
|
|
5392
|
+
if (!this.deoptimized)
|
|
5393
|
+
this.applyDeoptimizations();
|
|
5394
|
+
for (const element of this.elements) {
|
|
5395
|
+
if (element) {
|
|
5396
|
+
element?.includePath(UNKNOWN_PATH, context);
|
|
5397
|
+
}
|
|
5398
|
+
}
|
|
5399
|
+
}
|
|
5224
5400
|
applyDeoptimizations() {
|
|
5225
5401
|
this.deoptimized = true;
|
|
5226
5402
|
let hasSpread = false;
|
|
@@ -6288,17 +6464,37 @@ class GlobalVariable extends Variable {
|
|
|
6288
6464
|
}
|
|
6289
6465
|
}
|
|
6290
6466
|
|
|
6467
|
+
// To avoid infinite recursions
|
|
6468
|
+
const MAX_PATH_DEPTH = 6;
|
|
6469
|
+
// If a path is longer than MAX_PATH_DEPTH, it is truncated so that it is at
|
|
6470
|
+
// most MAX_PATH_DEPTH long. The last element is always UnknownKey
|
|
6471
|
+
const limitConcatenatedPathDepth = (path1, path2) => {
|
|
6472
|
+
const { length: length1 } = path1;
|
|
6473
|
+
const { length: length2 } = path2;
|
|
6474
|
+
return length1 === 0
|
|
6475
|
+
? path2
|
|
6476
|
+
: length2 === 0
|
|
6477
|
+
? path1
|
|
6478
|
+
: length1 + length2 > MAX_PATH_DEPTH
|
|
6479
|
+
? [...path1, ...path2.slice(0, MAX_PATH_DEPTH - 1 - path1.length), 'UnknownKey']
|
|
6480
|
+
: [...path1, ...path2];
|
|
6481
|
+
};
|
|
6482
|
+
|
|
6291
6483
|
class LocalVariable extends Variable {
|
|
6292
|
-
constructor(name, declarator, init,
|
|
6484
|
+
constructor(name, declarator, init,
|
|
6485
|
+
/** if this is non-empty, the actual init is this path of this.init */
|
|
6486
|
+
initPath, context, kind) {
|
|
6293
6487
|
super(name);
|
|
6294
6488
|
this.init = init;
|
|
6489
|
+
this.initPath = initPath;
|
|
6490
|
+
this.kind = kind;
|
|
6295
6491
|
this.calledFromTryStatement = false;
|
|
6296
6492
|
this.additionalInitializers = null;
|
|
6493
|
+
this.includedPathTracker = new IncludedFullPathTracker();
|
|
6297
6494
|
this.expressionsToBeDeoptimized = [];
|
|
6298
6495
|
this.declarations = declarator ? [declarator] : [];
|
|
6299
6496
|
this.deoptimizationTracker = context.deoptimizationTracker;
|
|
6300
6497
|
this.module = context.module;
|
|
6301
|
-
this.kind = kind;
|
|
6302
6498
|
}
|
|
6303
6499
|
addDeclaration(identifier, init) {
|
|
6304
6500
|
this.declarations.push(identifier);
|
|
@@ -6309,15 +6505,16 @@ class LocalVariable extends Variable {
|
|
|
6309
6505
|
for (const initializer of this.additionalInitializers) {
|
|
6310
6506
|
initializer.deoptimizePath(UNKNOWN_PATH);
|
|
6311
6507
|
}
|
|
6312
|
-
this.additionalInitializers = null;
|
|
6313
6508
|
}
|
|
6314
6509
|
}
|
|
6315
6510
|
deoptimizeArgumentsOnInteractionAtPath(interaction, path, recursionTracker) {
|
|
6316
|
-
if (this.isReassigned) {
|
|
6511
|
+
if (this.isReassigned || path.length + this.initPath.length > MAX_PATH_DEPTH) {
|
|
6317
6512
|
deoptimizeInteraction(interaction);
|
|
6318
6513
|
return;
|
|
6319
6514
|
}
|
|
6320
|
-
recursionTracker.withTrackedEntityAtPath(path, this.init, () =>
|
|
6515
|
+
recursionTracker.withTrackedEntityAtPath(path, this.init, () => {
|
|
6516
|
+
this.init.deoptimizeArgumentsOnInteractionAtPath(interaction, [...this.initPath, ...path], recursionTracker);
|
|
6517
|
+
}, undefined);
|
|
6321
6518
|
}
|
|
6322
6519
|
deoptimizePath(path) {
|
|
6323
6520
|
if (this.isReassigned ||
|
|
@@ -6331,37 +6528,40 @@ class LocalVariable extends Variable {
|
|
|
6331
6528
|
for (const expression of expressionsToBeDeoptimized) {
|
|
6332
6529
|
expression.deoptimizeCache();
|
|
6333
6530
|
}
|
|
6334
|
-
this.init.deoptimizePath(
|
|
6531
|
+
this.init.deoptimizePath([...this.initPath, UnknownKey]);
|
|
6335
6532
|
}
|
|
6336
6533
|
else {
|
|
6337
|
-
this.init.deoptimizePath(path);
|
|
6534
|
+
this.init.deoptimizePath(limitConcatenatedPathDepth(this.initPath, path));
|
|
6338
6535
|
}
|
|
6339
6536
|
}
|
|
6340
6537
|
getLiteralValueAtPath(path, recursionTracker, origin) {
|
|
6341
|
-
if (this.isReassigned) {
|
|
6538
|
+
if (this.isReassigned || path.length + this.initPath.length > MAX_PATH_DEPTH) {
|
|
6342
6539
|
return UnknownValue;
|
|
6343
6540
|
}
|
|
6344
6541
|
return recursionTracker.withTrackedEntityAtPath(path, this.init, () => {
|
|
6345
6542
|
this.expressionsToBeDeoptimized.push(origin);
|
|
6346
|
-
return this.init.getLiteralValueAtPath(path, recursionTracker, origin);
|
|
6543
|
+
return this.init.getLiteralValueAtPath([...this.initPath, ...path], recursionTracker, origin);
|
|
6347
6544
|
}, UnknownValue);
|
|
6348
6545
|
}
|
|
6349
6546
|
getReturnExpressionWhenCalledAtPath(path, interaction, recursionTracker, origin) {
|
|
6350
|
-
if (this.isReassigned) {
|
|
6547
|
+
if (this.isReassigned || path.length + this.initPath.length > MAX_PATH_DEPTH) {
|
|
6351
6548
|
return UNKNOWN_RETURN_EXPRESSION;
|
|
6352
6549
|
}
|
|
6353
6550
|
return recursionTracker.withTrackedEntityAtPath(path, this.init, () => {
|
|
6354
6551
|
this.expressionsToBeDeoptimized.push(origin);
|
|
6355
|
-
return this.init.getReturnExpressionWhenCalledAtPath(path, interaction, recursionTracker, origin);
|
|
6552
|
+
return this.init.getReturnExpressionWhenCalledAtPath([...this.initPath, ...path], interaction, recursionTracker, origin);
|
|
6356
6553
|
}, UNKNOWN_RETURN_EXPRESSION);
|
|
6357
6554
|
}
|
|
6358
6555
|
hasEffectsOnInteractionAtPath(path, interaction, context) {
|
|
6556
|
+
if (path.length + this.initPath.length > MAX_PATH_DEPTH) {
|
|
6557
|
+
return true;
|
|
6558
|
+
}
|
|
6359
6559
|
switch (interaction.type) {
|
|
6360
6560
|
case INTERACTION_ACCESSED: {
|
|
6361
6561
|
if (this.isReassigned)
|
|
6362
6562
|
return true;
|
|
6363
6563
|
return (!context.accessed.trackEntityAtPathAndGetIfTracked(path, this) &&
|
|
6364
|
-
this.init.hasEffectsOnInteractionAtPath(path, interaction, context));
|
|
6564
|
+
this.init.hasEffectsOnInteractionAtPath([...this.initPath, ...path], interaction, context));
|
|
6365
6565
|
}
|
|
6366
6566
|
case INTERACTION_ASSIGNED: {
|
|
6367
6567
|
if (this.included)
|
|
@@ -6371,44 +6571,63 @@ class LocalVariable extends Variable {
|
|
|
6371
6571
|
if (this.isReassigned)
|
|
6372
6572
|
return true;
|
|
6373
6573
|
return (!context.assigned.trackEntityAtPathAndGetIfTracked(path, this) &&
|
|
6374
|
-
this.init.hasEffectsOnInteractionAtPath(path, interaction, context));
|
|
6574
|
+
this.init.hasEffectsOnInteractionAtPath([...this.initPath, ...path], interaction, context));
|
|
6375
6575
|
}
|
|
6376
6576
|
case INTERACTION_CALLED: {
|
|
6377
6577
|
if (this.isReassigned)
|
|
6378
6578
|
return true;
|
|
6379
6579
|
return (!(interaction.withNew ? context.instantiated : context.called).trackEntityAtPathAndGetIfTracked(path, interaction.args, this) &&
|
|
6380
|
-
this.init.hasEffectsOnInteractionAtPath(path, interaction, context));
|
|
6580
|
+
this.init.hasEffectsOnInteractionAtPath([...this.initPath, ...path], interaction, context));
|
|
6381
6581
|
}
|
|
6382
6582
|
}
|
|
6383
6583
|
}
|
|
6384
|
-
|
|
6385
|
-
if (!this.
|
|
6386
|
-
|
|
6584
|
+
includePath(path, context) {
|
|
6585
|
+
if (!this.includedPathTracker.includePathAndGetIfIncluded(path)) {
|
|
6586
|
+
this.module.scope.context.requestTreeshakingPass();
|
|
6587
|
+
if (!this.included) {
|
|
6588
|
+
// This will reduce the number of tree-shaking passes by eagerly
|
|
6589
|
+
// including inits. By pushing this here instead of directly including
|
|
6590
|
+
// we avoid deep call stacks.
|
|
6591
|
+
this.module.scope.context.newlyIncludedVariableInits.add(this.init);
|
|
6592
|
+
}
|
|
6593
|
+
super.includePath(path, context);
|
|
6387
6594
|
for (const declaration of this.declarations) {
|
|
6388
6595
|
// If node is a default export, it can save a tree-shaking run to include the full declaration now
|
|
6389
6596
|
if (!declaration.included)
|
|
6390
|
-
declaration.include(
|
|
6597
|
+
declaration.include(context, false);
|
|
6391
6598
|
let node = declaration.parent;
|
|
6392
6599
|
while (!node.included) {
|
|
6393
6600
|
// We do not want to properly include parents in case they are part of a dead branch
|
|
6394
6601
|
// in which case .include() might pull in more dead code
|
|
6395
|
-
node.
|
|
6602
|
+
node.includeNode(context);
|
|
6396
6603
|
if (node.type === parseAst_js.Program)
|
|
6397
6604
|
break;
|
|
6398
6605
|
node = node.parent;
|
|
6399
6606
|
}
|
|
6400
6607
|
}
|
|
6608
|
+
// We need to make sure we include the correct path of the init
|
|
6609
|
+
if (path.length > 0) {
|
|
6610
|
+
this.init.includePath(limitConcatenatedPathDepth(this.initPath, path), context);
|
|
6611
|
+
this.additionalInitializers?.forEach(initializer => initializer.includePath(UNKNOWN_PATH, context));
|
|
6612
|
+
}
|
|
6401
6613
|
}
|
|
6402
6614
|
}
|
|
6403
|
-
includeCallArguments(context,
|
|
6404
|
-
if (this.isReassigned ||
|
|
6405
|
-
|
|
6406
|
-
|
|
6615
|
+
includeCallArguments(context, interaction) {
|
|
6616
|
+
if (this.isReassigned ||
|
|
6617
|
+
context.includedCallArguments.has(this.init) ||
|
|
6618
|
+
// This can be removed again once we can include arguments when called at
|
|
6619
|
+
// a specific path
|
|
6620
|
+
this.initPath.length > 0) {
|
|
6621
|
+
for (const argument of interaction.args) {
|
|
6622
|
+
if (argument) {
|
|
6623
|
+
argument.includePath(UNKNOWN_PATH, context);
|
|
6624
|
+
argument.include(context, false);
|
|
6625
|
+
}
|
|
6407
6626
|
}
|
|
6408
6627
|
}
|
|
6409
6628
|
else {
|
|
6410
6629
|
context.includedCallArguments.add(this.init);
|
|
6411
|
-
this.init.includeCallArguments(context,
|
|
6630
|
+
this.init.includeCallArguments(context, interaction);
|
|
6412
6631
|
context.includedCallArguments.delete(this.init);
|
|
6413
6632
|
}
|
|
6414
6633
|
}
|
|
@@ -6488,18 +6707,31 @@ class IdentifierBase extends NodeBase {
|
|
|
6488
6707
|
}
|
|
6489
6708
|
}
|
|
6490
6709
|
}
|
|
6491
|
-
include() {
|
|
6710
|
+
include(context) {
|
|
6711
|
+
if (!this.included)
|
|
6712
|
+
this.includeNode(context);
|
|
6713
|
+
}
|
|
6714
|
+
includeNode(context) {
|
|
6715
|
+
this.included = true;
|
|
6492
6716
|
if (!this.deoptimized)
|
|
6493
6717
|
this.applyDeoptimizations();
|
|
6718
|
+
if (this.variable !== null) {
|
|
6719
|
+
this.scope.context.includeVariableInModule(this.variable, EMPTY_PATH, context);
|
|
6720
|
+
}
|
|
6721
|
+
}
|
|
6722
|
+
includePath(path, context) {
|
|
6494
6723
|
if (!this.included) {
|
|
6495
6724
|
this.included = true;
|
|
6496
6725
|
if (this.variable !== null) {
|
|
6497
|
-
this.scope.context.includeVariableInModule(this.variable);
|
|
6726
|
+
this.scope.context.includeVariableInModule(this.variable, path, context);
|
|
6498
6727
|
}
|
|
6499
6728
|
}
|
|
6729
|
+
else if (path.length > 0) {
|
|
6730
|
+
this.variable?.includePath(path, context);
|
|
6731
|
+
}
|
|
6500
6732
|
}
|
|
6501
|
-
includeCallArguments(context,
|
|
6502
|
-
this.variable.includeCallArguments(context,
|
|
6733
|
+
includeCallArguments(context, interaction) {
|
|
6734
|
+
this.variable.includeCallArguments(context, interaction);
|
|
6503
6735
|
}
|
|
6504
6736
|
isPossibleTDZ() {
|
|
6505
6737
|
// return cached value to avoid issues with the next tree-shaking pass
|
|
@@ -6582,11 +6814,40 @@ function closestParentFunctionOrProgram(node) {
|
|
|
6582
6814
|
return node;
|
|
6583
6815
|
}
|
|
6584
6816
|
|
|
6817
|
+
class ObjectMember extends ExpressionEntity {
|
|
6818
|
+
constructor(object, path) {
|
|
6819
|
+
super();
|
|
6820
|
+
this.object = object;
|
|
6821
|
+
this.path = path;
|
|
6822
|
+
}
|
|
6823
|
+
deoptimizeArgumentsOnInteractionAtPath(interaction, path, recursionTracker) {
|
|
6824
|
+
this.object.deoptimizeArgumentsOnInteractionAtPath(interaction, [...this.path, ...path], recursionTracker);
|
|
6825
|
+
}
|
|
6826
|
+
deoptimizePath(path) {
|
|
6827
|
+
this.object.deoptimizePath([...this.path, ...path]);
|
|
6828
|
+
}
|
|
6829
|
+
getLiteralValueAtPath(path, recursionTracker, origin) {
|
|
6830
|
+
return this.object.getLiteralValueAtPath([...this.path, ...path], recursionTracker, origin);
|
|
6831
|
+
}
|
|
6832
|
+
getReturnExpressionWhenCalledAtPath(path, interaction, recursionTracker, origin) {
|
|
6833
|
+
return this.object.getReturnExpressionWhenCalledAtPath([...this.path, ...path], interaction, recursionTracker, origin);
|
|
6834
|
+
}
|
|
6835
|
+
hasEffectsOnInteractionAtPath(path, interaction, context) {
|
|
6836
|
+
return this.object.hasEffectsOnInteractionAtPath([...this.path, ...path], interaction, context);
|
|
6837
|
+
}
|
|
6838
|
+
}
|
|
6839
|
+
|
|
6585
6840
|
class Identifier extends IdentifierBase {
|
|
6586
6841
|
constructor() {
|
|
6587
6842
|
super(...arguments);
|
|
6588
6843
|
this.variable = null;
|
|
6589
6844
|
}
|
|
6845
|
+
get isDestructuringDeoptimized() {
|
|
6846
|
+
return isFlagSet(this.flags, 16777216 /* Flag.destructuringDeoptimized */);
|
|
6847
|
+
}
|
|
6848
|
+
set isDestructuringDeoptimized(value) {
|
|
6849
|
+
this.flags = setFlag(this.flags, 16777216 /* Flag.destructuringDeoptimized */, value);
|
|
6850
|
+
}
|
|
6590
6851
|
addExportedVariables(variables, exportNamesByVariable) {
|
|
6591
6852
|
if (exportNamesByVariable.has(this.variable)) {
|
|
6592
6853
|
variables.push(this.variable);
|
|
@@ -6599,43 +6860,53 @@ class Identifier extends IdentifierBase {
|
|
|
6599
6860
|
this.isVariableReference = true;
|
|
6600
6861
|
}
|
|
6601
6862
|
}
|
|
6602
|
-
declare(kind, init) {
|
|
6863
|
+
declare(kind, destructuredInitPath, init) {
|
|
6603
6864
|
let variable;
|
|
6604
6865
|
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}.`);
|
|
6866
|
+
if (kind === 'parameter') {
|
|
6867
|
+
variable = this.scope.addParameterDeclaration(this, destructuredInitPath);
|
|
6868
|
+
}
|
|
6869
|
+
else {
|
|
6870
|
+
variable = this.scope.addDeclaration(this, this.scope.context, init, destructuredInitPath, kind);
|
|
6871
|
+
if (kind === 'var' && treeshake && treeshake.correctVarValueBeforeDeclaration) {
|
|
6872
|
+
// Necessary to make sure the init is deoptimized. We cannot call deoptimizePath here.
|
|
6873
|
+
variable.markInitializersForDeoptimization();
|
|
6635
6874
|
}
|
|
6636
6875
|
}
|
|
6637
6876
|
return [(this.variable = variable)];
|
|
6638
6877
|
}
|
|
6878
|
+
deoptimizeAssignment(destructuredInitPath, init) {
|
|
6879
|
+
this.deoptimizePath(EMPTY_PATH);
|
|
6880
|
+
init.deoptimizePath([...destructuredInitPath, UnknownKey]);
|
|
6881
|
+
}
|
|
6882
|
+
hasEffectsWhenDestructuring(context, destructuredInitPath, init) {
|
|
6883
|
+
return (destructuredInitPath.length > 0 &&
|
|
6884
|
+
init.hasEffectsOnInteractionAtPath(destructuredInitPath, NODE_INTERACTION_UNKNOWN_ACCESS, context));
|
|
6885
|
+
}
|
|
6886
|
+
includeDestructuredIfNecessary(context, destructuredInitPath, init) {
|
|
6887
|
+
if (destructuredInitPath.length > 0 && !this.isDestructuringDeoptimized) {
|
|
6888
|
+
this.isDestructuringDeoptimized = true;
|
|
6889
|
+
init.deoptimizeArgumentsOnInteractionAtPath({
|
|
6890
|
+
args: [new ObjectMember(init, destructuredInitPath.slice(0, -1))],
|
|
6891
|
+
type: INTERACTION_ACCESSED
|
|
6892
|
+
}, destructuredInitPath, SHARED_RECURSION_TRACKER);
|
|
6893
|
+
}
|
|
6894
|
+
const { propertyReadSideEffects } = this.scope.context.options
|
|
6895
|
+
.treeshake;
|
|
6896
|
+
if ((this.included ||=
|
|
6897
|
+
destructuredInitPath.length > 0 &&
|
|
6898
|
+
!context.brokenFlow &&
|
|
6899
|
+
propertyReadSideEffects &&
|
|
6900
|
+
(propertyReadSideEffects === 'always' ||
|
|
6901
|
+
init.hasEffectsOnInteractionAtPath(destructuredInitPath, NODE_INTERACTION_UNKNOWN_ACCESS, createHasEffectsContext())))) {
|
|
6902
|
+
if (this.variable && !this.variable.included) {
|
|
6903
|
+
this.scope.context.includeVariableInModule(this.variable, EMPTY_PATH, context);
|
|
6904
|
+
}
|
|
6905
|
+
init.includePath(destructuredInitPath, context);
|
|
6906
|
+
return true;
|
|
6907
|
+
}
|
|
6908
|
+
return false;
|
|
6909
|
+
}
|
|
6639
6910
|
markDeclarationReached() {
|
|
6640
6911
|
this.variable.initReached = true;
|
|
6641
6912
|
}
|
|
@@ -6688,18 +6959,17 @@ class Scope {
|
|
|
6688
6959
|
- then the variable is still declared in the hoisted outer scope, but the initializer is assigned to the parameter
|
|
6689
6960
|
- const, let, class, and function except in the cases above cannot redeclare anything
|
|
6690
6961
|
*/
|
|
6691
|
-
addDeclaration(identifier, context, init, kind) {
|
|
6962
|
+
addDeclaration(identifier, context, init, destructuredInitPath, kind) {
|
|
6692
6963
|
const name = identifier.name;
|
|
6693
6964
|
const existingVariable = this.hoistedVariables?.get(name) || this.variables.get(name);
|
|
6694
6965
|
if (existingVariable) {
|
|
6695
|
-
|
|
6696
|
-
if (kind === 'var' && existingKind === 'var') {
|
|
6966
|
+
if (kind === 'var' && existingVariable.kind === 'var') {
|
|
6697
6967
|
existingVariable.addDeclaration(identifier, init);
|
|
6698
6968
|
return existingVariable;
|
|
6699
6969
|
}
|
|
6700
6970
|
context.error(parseAst_js.logRedeclarationError(name), identifier.start);
|
|
6701
6971
|
}
|
|
6702
|
-
const newVariable = new LocalVariable(identifier.name, identifier, init, context, kind);
|
|
6972
|
+
const newVariable = new LocalVariable(identifier.name, identifier, init, destructuredInitPath, context, kind);
|
|
6703
6973
|
this.variables.set(name, newVariable);
|
|
6704
6974
|
return newVariable;
|
|
6705
6975
|
}
|
|
@@ -6875,7 +7145,6 @@ class MethodBase extends NodeBase {
|
|
|
6875
7145
|
}
|
|
6876
7146
|
return this.getAccessedValue()[0].hasEffectsOnInteractionAtPath(path, interaction, context);
|
|
6877
7147
|
}
|
|
6878
|
-
applyDeoptimizations() { }
|
|
6879
7148
|
getAccessedValue() {
|
|
6880
7149
|
if (this.accessedValue === null) {
|
|
6881
7150
|
if (this.kind === 'get') {
|
|
@@ -6889,19 +7158,20 @@ class MethodBase extends NodeBase {
|
|
|
6889
7158
|
return this.accessedValue;
|
|
6890
7159
|
}
|
|
6891
7160
|
}
|
|
7161
|
+
MethodBase.prototype.includeNode = onlyIncludeSelfNoDeoptimize;
|
|
7162
|
+
MethodBase.prototype.applyDeoptimizations = doNotDeoptimize;
|
|
6892
7163
|
|
|
6893
7164
|
class MethodDefinition extends MethodBase {
|
|
6894
7165
|
hasEffects(context) {
|
|
6895
7166
|
return super.hasEffects(context) || checkEffectForNodes(this.decorators, context);
|
|
6896
7167
|
}
|
|
6897
|
-
applyDeoptimizations() { }
|
|
6898
7168
|
}
|
|
6899
7169
|
|
|
6900
7170
|
class BlockScope extends ChildScope {
|
|
6901
7171
|
constructor(parent) {
|
|
6902
7172
|
super(parent, parent.context);
|
|
6903
7173
|
}
|
|
6904
|
-
addDeclaration(identifier, context, init, kind) {
|
|
7174
|
+
addDeclaration(identifier, context, init, destructuredInitPath, kind) {
|
|
6905
7175
|
if (kind === 'var') {
|
|
6906
7176
|
const name = identifier.name;
|
|
6907
7177
|
const existingVariable = this.hoistedVariables?.get(name) || this.variables.get(name);
|
|
@@ -6913,7 +7183,7 @@ class BlockScope extends ChildScope {
|
|
|
6913
7183
|
}
|
|
6914
7184
|
return context.error(parseAst_js.logRedeclarationError(name), identifier.start);
|
|
6915
7185
|
}
|
|
6916
|
-
const declaredVariable = this.parent.addDeclaration(identifier, context, init, kind);
|
|
7186
|
+
const declaredVariable = this.parent.addDeclaration(identifier, context, init, destructuredInitPath, kind);
|
|
6917
7187
|
// Necessary to make sure the init is deoptimized for conditional declarations.
|
|
6918
7188
|
// We cannot call deoptimizePath here.
|
|
6919
7189
|
declaredVariable.markInitializersForDeoptimization();
|
|
@@ -6921,7 +7191,7 @@ class BlockScope extends ChildScope {
|
|
|
6921
7191
|
this.addHoistedVariable(name, declaredVariable);
|
|
6922
7192
|
return declaredVariable;
|
|
6923
7193
|
}
|
|
6924
|
-
return super.addDeclaration(identifier, context, init, kind);
|
|
7194
|
+
return super.addDeclaration(identifier, context, init, destructuredInitPath, kind);
|
|
6925
7195
|
}
|
|
6926
7196
|
}
|
|
6927
7197
|
|
|
@@ -6953,33 +7223,12 @@ class StaticBlock extends NodeBase {
|
|
|
6953
7223
|
}
|
|
6954
7224
|
}
|
|
6955
7225
|
}
|
|
7226
|
+
StaticBlock.prototype.includeNode = onlyIncludeSelfNoDeoptimize;
|
|
7227
|
+
StaticBlock.prototype.applyDeoptimizations = doNotDeoptimize;
|
|
6956
7228
|
function isStaticBlock(statement) {
|
|
6957
7229
|
return statement.type === parseAst_js.StaticBlock;
|
|
6958
7230
|
}
|
|
6959
7231
|
|
|
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
7232
|
class ClassNode extends NodeBase {
|
|
6984
7233
|
constructor() {
|
|
6985
7234
|
super(...arguments);
|
|
@@ -7020,21 +7269,20 @@ class ClassNode extends NodeBase {
|
|
|
7020
7269
|
: this.getObjectEntity().hasEffectsOnInteractionAtPath(path, interaction, context);
|
|
7021
7270
|
}
|
|
7022
7271
|
include(context, includeChildrenRecursively) {
|
|
7023
|
-
if (!this.
|
|
7024
|
-
this.
|
|
7025
|
-
this.included = true;
|
|
7272
|
+
if (!this.included)
|
|
7273
|
+
this.includeNode(context);
|
|
7026
7274
|
this.superClass?.include(context, includeChildrenRecursively);
|
|
7027
7275
|
this.body.include(context, includeChildrenRecursively);
|
|
7028
7276
|
for (const decorator of this.decorators)
|
|
7029
7277
|
decorator.include(context, includeChildrenRecursively);
|
|
7030
7278
|
if (this.id) {
|
|
7031
7279
|
this.id.markDeclarationReached();
|
|
7032
|
-
this.id.include();
|
|
7280
|
+
this.id.include(context);
|
|
7033
7281
|
}
|
|
7034
7282
|
}
|
|
7035
7283
|
initialise() {
|
|
7036
7284
|
super.initialise();
|
|
7037
|
-
this.id?.declare('class', this);
|
|
7285
|
+
this.id?.declare('class', EMPTY_PATH, this);
|
|
7038
7286
|
for (const method of this.body.body) {
|
|
7039
7287
|
if (method instanceof MethodDefinition && method.kind === 'constructor') {
|
|
7040
7288
|
this.classConstructor = method;
|
|
@@ -7092,11 +7340,12 @@ class ClassNode extends NodeBase {
|
|
|
7092
7340
|
staticProperties.unshift({
|
|
7093
7341
|
key: 'prototype',
|
|
7094
7342
|
kind: 'init',
|
|
7095
|
-
property: new ObjectEntity(dynamicMethods, this.superClass ? new ObjectMember(this.superClass, 'prototype') : OBJECT_PROTOTYPE)
|
|
7343
|
+
property: new ObjectEntity(dynamicMethods, this.superClass ? new ObjectMember(this.superClass, ['prototype']) : OBJECT_PROTOTYPE)
|
|
7096
7344
|
});
|
|
7097
7345
|
return (this.objectEntity = new ObjectEntity(staticProperties, this.superClass || OBJECT_PROTOTYPE));
|
|
7098
7346
|
}
|
|
7099
7347
|
}
|
|
7348
|
+
ClassNode.prototype.includeNode = onlyIncludeSelf;
|
|
7100
7349
|
|
|
7101
7350
|
class ClassDeclaration extends ClassNode {
|
|
7102
7351
|
initialise() {
|
|
@@ -7149,53 +7398,60 @@ class ClassDeclaration extends ClassNode {
|
|
|
7149
7398
|
|
|
7150
7399
|
class ArgumentsVariable extends LocalVariable {
|
|
7151
7400
|
constructor(context) {
|
|
7152
|
-
super('arguments', null, UNKNOWN_EXPRESSION, context, 'other');
|
|
7153
|
-
this.deoptimizedArguments = [];
|
|
7401
|
+
super('arguments', null, UNKNOWN_EXPRESSION, EMPTY_PATH, context, 'other');
|
|
7154
7402
|
}
|
|
7155
|
-
addArgumentToBeDeoptimized(
|
|
7156
|
-
|
|
7157
|
-
|
|
7158
|
-
|
|
7159
|
-
|
|
7160
|
-
|
|
7161
|
-
}
|
|
7403
|
+
addArgumentToBeDeoptimized(_argument) { }
|
|
7404
|
+
// Only If there is at least one reference, then we need to track all
|
|
7405
|
+
// arguments in order to be able to deoptimize them.
|
|
7406
|
+
addReference() {
|
|
7407
|
+
this.deoptimizedArguments = [];
|
|
7408
|
+
this.addArgumentToBeDeoptimized = addArgumentToBeDeoptimized;
|
|
7162
7409
|
}
|
|
7163
7410
|
hasEffectsOnInteractionAtPath(path, { type }) {
|
|
7164
7411
|
return type !== INTERACTION_ACCESSED || path.length > 1;
|
|
7165
7412
|
}
|
|
7166
|
-
|
|
7167
|
-
super.
|
|
7413
|
+
includePath(path, context) {
|
|
7414
|
+
super.includePath(path, context);
|
|
7168
7415
|
for (const argument of this.deoptimizedArguments) {
|
|
7169
7416
|
argument.deoptimizePath(UNKNOWN_PATH);
|
|
7170
7417
|
}
|
|
7171
7418
|
this.deoptimizedArguments.length = 0;
|
|
7172
7419
|
}
|
|
7173
7420
|
}
|
|
7421
|
+
function addArgumentToBeDeoptimized(argument) {
|
|
7422
|
+
if (this.included) {
|
|
7423
|
+
argument.deoptimizePath(UNKNOWN_PATH);
|
|
7424
|
+
}
|
|
7425
|
+
else {
|
|
7426
|
+
this.deoptimizedArguments?.push(argument);
|
|
7427
|
+
}
|
|
7428
|
+
}
|
|
7174
7429
|
|
|
7175
7430
|
const MAX_TRACKED_INTERACTIONS = 20;
|
|
7176
7431
|
const NO_INTERACTIONS = parseAst_js.EMPTY_ARRAY;
|
|
7177
7432
|
const UNKNOWN_DEOPTIMIZED_FIELD = new Set([UnknownKey]);
|
|
7178
|
-
const EMPTY_PATH_TRACKER = new
|
|
7433
|
+
const EMPTY_PATH_TRACKER = new EntityPathTracker();
|
|
7179
7434
|
const UNKNOWN_DEOPTIMIZED_ENTITY = new Set([UNKNOWN_EXPRESSION]);
|
|
7180
7435
|
class ParameterVariable extends LocalVariable {
|
|
7181
|
-
constructor(name, declarator, context) {
|
|
7182
|
-
super(name, declarator, UNKNOWN_EXPRESSION, context, 'parameter');
|
|
7436
|
+
constructor(name, declarator, argumentPath, context) {
|
|
7437
|
+
super(name, declarator, UNKNOWN_EXPRESSION, argumentPath, context, 'parameter');
|
|
7438
|
+
this.includedPathTracker = new IncludedTopLevelPathTracker();
|
|
7439
|
+
this.argumentsToBeDeoptimized = new Set();
|
|
7183
7440
|
this.deoptimizationInteractions = [];
|
|
7184
|
-
this.deoptimizations = new
|
|
7441
|
+
this.deoptimizations = new EntityPathTracker();
|
|
7185
7442
|
this.deoptimizedFields = new Set();
|
|
7186
|
-
this.
|
|
7187
|
-
this.expressionsUseTheKnownValue = [];
|
|
7443
|
+
this.expressionsDependingOnKnownValue = [];
|
|
7188
7444
|
this.knownValue = null;
|
|
7189
7445
|
this.knownValueLiteral = UnknownValue;
|
|
7190
|
-
this.frozenValue = null;
|
|
7191
7446
|
}
|
|
7192
|
-
|
|
7447
|
+
addArgumentValue(entity) {
|
|
7448
|
+
this.updateKnownValue(entity);
|
|
7193
7449
|
if (entity === UNKNOWN_EXPRESSION) {
|
|
7194
7450
|
// As unknown expressions fully deoptimize all interactions, we can clear
|
|
7195
7451
|
// the interaction cache at this point provided we keep this optimization
|
|
7196
7452
|
// in mind when adding new interactions
|
|
7197
|
-
if (!this.
|
|
7198
|
-
this.
|
|
7453
|
+
if (!this.argumentsToBeDeoptimized.has(UNKNOWN_EXPRESSION)) {
|
|
7454
|
+
this.argumentsToBeDeoptimized.add(UNKNOWN_EXPRESSION);
|
|
7199
7455
|
for (const { interaction } of this.deoptimizationInteractions) {
|
|
7200
7456
|
deoptimizeInteraction(interaction);
|
|
7201
7457
|
}
|
|
@@ -7205,27 +7461,30 @@ class ParameterVariable extends LocalVariable {
|
|
|
7205
7461
|
else if (this.deoptimizedFields.has(UnknownKey)) {
|
|
7206
7462
|
// This means that we already deoptimized all interactions and no longer
|
|
7207
7463
|
// track them
|
|
7208
|
-
entity.deoptimizePath(
|
|
7464
|
+
entity.deoptimizePath([...this.initPath, UnknownKey]);
|
|
7209
7465
|
}
|
|
7210
|
-
else if (!this.
|
|
7211
|
-
this.
|
|
7466
|
+
else if (!this.argumentsToBeDeoptimized.has(entity)) {
|
|
7467
|
+
this.argumentsToBeDeoptimized.add(entity);
|
|
7212
7468
|
for (const field of this.deoptimizedFields) {
|
|
7213
|
-
entity.deoptimizePath([field]);
|
|
7469
|
+
entity.deoptimizePath([...this.initPath, field]);
|
|
7214
7470
|
}
|
|
7215
7471
|
for (const { interaction, path } of this.deoptimizationInteractions) {
|
|
7216
|
-
entity.deoptimizeArgumentsOnInteractionAtPath(interaction, path, SHARED_RECURSION_TRACKER);
|
|
7472
|
+
entity.deoptimizeArgumentsOnInteractionAtPath(interaction, [...this.initPath, ...path], SHARED_RECURSION_TRACKER);
|
|
7217
7473
|
}
|
|
7218
7474
|
}
|
|
7219
7475
|
}
|
|
7476
|
+
/** This says we should not make assumptions about the value of the parameter.
|
|
7477
|
+
* This is different from deoptimization that will also cause argument values
|
|
7478
|
+
* to be deoptimized. */
|
|
7220
7479
|
markReassigned() {
|
|
7221
7480
|
if (this.isReassigned) {
|
|
7222
7481
|
return;
|
|
7223
7482
|
}
|
|
7224
7483
|
super.markReassigned();
|
|
7225
|
-
for (const expression of this.
|
|
7484
|
+
for (const expression of this.expressionsDependingOnKnownValue) {
|
|
7226
7485
|
expression.deoptimizeCache();
|
|
7227
7486
|
}
|
|
7228
|
-
this.
|
|
7487
|
+
this.expressionsDependingOnKnownValue = parseAst_js.EMPTY_ARRAY;
|
|
7229
7488
|
}
|
|
7230
7489
|
deoptimizeCache() {
|
|
7231
7490
|
this.markReassigned();
|
|
@@ -7242,7 +7501,7 @@ class ParameterVariable extends LocalVariable {
|
|
|
7242
7501
|
}
|
|
7243
7502
|
if (this.knownValue === null) {
|
|
7244
7503
|
this.knownValue = argument;
|
|
7245
|
-
this.knownValueLiteral = argument.getLiteralValueAtPath(
|
|
7504
|
+
this.knownValueLiteral = argument.getLiteralValueAtPath(this.initPath, SHARED_RECURSION_TRACKER, this);
|
|
7246
7505
|
return;
|
|
7247
7506
|
}
|
|
7248
7507
|
// the same literal or identifier, do nothing
|
|
@@ -7252,14 +7511,10 @@ class ParameterVariable extends LocalVariable {
|
|
|
7252
7511
|
this.knownValue.variable === argument.variable)) {
|
|
7253
7512
|
return;
|
|
7254
7513
|
}
|
|
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) {
|
|
7514
|
+
const { knownValueLiteral } = this;
|
|
7515
|
+
if (typeof knownValueLiteral === 'symbol' ||
|
|
7516
|
+
argument.getLiteralValueAtPath(this.initPath, SHARED_RECURSION_TRACKER, this) !==
|
|
7517
|
+
knownValueLiteral) {
|
|
7263
7518
|
this.markReassigned();
|
|
7264
7519
|
}
|
|
7265
7520
|
}
|
|
@@ -7270,42 +7525,47 @@ class ParameterVariable extends LocalVariable {
|
|
|
7270
7525
|
* @returns the frozen value
|
|
7271
7526
|
*/
|
|
7272
7527
|
getKnownValue() {
|
|
7273
|
-
|
|
7274
|
-
this.frozenValue = this.knownValue || UNKNOWN_EXPRESSION;
|
|
7275
|
-
}
|
|
7276
|
-
return this.frozenValue;
|
|
7528
|
+
return this.knownValue || UNKNOWN_EXPRESSION;
|
|
7277
7529
|
}
|
|
7278
7530
|
getLiteralValueAtPath(path, recursionTracker, origin) {
|
|
7279
|
-
if (this.isReassigned) {
|
|
7531
|
+
if (this.isReassigned || path.length + this.initPath.length > MAX_PATH_DEPTH) {
|
|
7280
7532
|
return UnknownValue;
|
|
7281
7533
|
}
|
|
7282
7534
|
const knownValue = this.getKnownValue();
|
|
7283
|
-
this.
|
|
7284
|
-
return recursionTracker.withTrackedEntityAtPath(path, knownValue, () => knownValue.getLiteralValueAtPath(path, recursionTracker, origin), UnknownValue);
|
|
7535
|
+
this.expressionsDependingOnKnownValue.push(origin);
|
|
7536
|
+
return recursionTracker.withTrackedEntityAtPath(path, knownValue, () => knownValue.getLiteralValueAtPath([...this.initPath, ...path], recursionTracker, origin), UnknownValue);
|
|
7285
7537
|
}
|
|
7286
7538
|
hasEffectsOnInteractionAtPath(path, interaction, context) {
|
|
7287
|
-
|
|
7539
|
+
const { type } = interaction;
|
|
7540
|
+
if (this.isReassigned ||
|
|
7541
|
+
type === INTERACTION_ASSIGNED ||
|
|
7542
|
+
path.length + this.initPath.length > MAX_PATH_DEPTH) {
|
|
7288
7543
|
return super.hasEffectsOnInteractionAtPath(path, interaction, context);
|
|
7289
7544
|
}
|
|
7290
|
-
|
|
7291
|
-
|
|
7545
|
+
return (!(type === INTERACTION_CALLED
|
|
7546
|
+
? (interaction.withNew
|
|
7547
|
+
? context.instantiated
|
|
7548
|
+
: context.called).trackEntityAtPathAndGetIfTracked(path, interaction.args, this)
|
|
7549
|
+
: context.accessed.trackEntityAtPathAndGetIfTracked(path, this)) &&
|
|
7550
|
+
this.getKnownValue().hasEffectsOnInteractionAtPath([...this.initPath, ...path], interaction, context));
|
|
7292
7551
|
}
|
|
7293
7552
|
deoptimizeArgumentsOnInteractionAtPath(interaction, path) {
|
|
7294
7553
|
// For performance reasons, we fully deoptimize all deeper interactions
|
|
7295
7554
|
if (path.length >= 2 ||
|
|
7296
|
-
this.
|
|
7555
|
+
this.argumentsToBeDeoptimized.has(UNKNOWN_EXPRESSION) ||
|
|
7297
7556
|
this.deoptimizationInteractions.length >= MAX_TRACKED_INTERACTIONS ||
|
|
7298
7557
|
(path.length === 1 &&
|
|
7299
7558
|
(this.deoptimizedFields.has(UnknownKey) ||
|
|
7300
|
-
(interaction.type === INTERACTION_CALLED && this.deoptimizedFields.has(path[0]))))
|
|
7559
|
+
(interaction.type === INTERACTION_CALLED && this.deoptimizedFields.has(path[0])))) ||
|
|
7560
|
+
this.initPath.length + path.length > MAX_PATH_DEPTH) {
|
|
7301
7561
|
deoptimizeInteraction(interaction);
|
|
7302
7562
|
return;
|
|
7303
7563
|
}
|
|
7304
7564
|
if (!this.deoptimizations.trackEntityAtPathAndGetIfTracked(path, interaction.args)) {
|
|
7305
|
-
for (const entity of this.
|
|
7306
|
-
entity.deoptimizeArgumentsOnInteractionAtPath(interaction, path, SHARED_RECURSION_TRACKER);
|
|
7565
|
+
for (const entity of this.argumentsToBeDeoptimized) {
|
|
7566
|
+
entity.deoptimizeArgumentsOnInteractionAtPath(interaction, [...this.initPath, ...path], SHARED_RECURSION_TRACKER);
|
|
7307
7567
|
}
|
|
7308
|
-
if (!this.
|
|
7568
|
+
if (!this.argumentsToBeDeoptimized.has(UNKNOWN_EXPRESSION)) {
|
|
7309
7569
|
this.deoptimizationInteractions.push({
|
|
7310
7570
|
interaction,
|
|
7311
7571
|
path
|
|
@@ -7326,17 +7586,17 @@ class ParameterVariable extends LocalVariable {
|
|
|
7326
7586
|
return;
|
|
7327
7587
|
}
|
|
7328
7588
|
this.deoptimizedFields.add(key);
|
|
7329
|
-
for (const entity of this.
|
|
7589
|
+
for (const entity of this.argumentsToBeDeoptimized) {
|
|
7330
7590
|
// We do not need a recursion tracker here as we already track whether
|
|
7331
7591
|
// this field is deoptimized
|
|
7332
|
-
entity.deoptimizePath([key]);
|
|
7592
|
+
entity.deoptimizePath([...this.initPath, key]);
|
|
7333
7593
|
}
|
|
7334
7594
|
if (key === UnknownKey) {
|
|
7335
7595
|
// save some memory
|
|
7336
7596
|
this.deoptimizationInteractions = NO_INTERACTIONS;
|
|
7337
7597
|
this.deoptimizations = EMPTY_PATH_TRACKER;
|
|
7338
7598
|
this.deoptimizedFields = UNKNOWN_DEOPTIMIZED_FIELD;
|
|
7339
|
-
this.
|
|
7599
|
+
this.argumentsToBeDeoptimized = UNKNOWN_DEOPTIMIZED_ENTITY;
|
|
7340
7600
|
}
|
|
7341
7601
|
}
|
|
7342
7602
|
getReturnExpressionWhenCalledAtPath(path) {
|
|
@@ -7351,11 +7611,14 @@ class ParameterVariable extends LocalVariable {
|
|
|
7351
7611
|
}
|
|
7352
7612
|
return UNKNOWN_RETURN_EXPRESSION;
|
|
7353
7613
|
}
|
|
7614
|
+
includeArgumentPaths(entity, context) {
|
|
7615
|
+
this.includedPathTracker.includeAllPaths(entity, context, this.initPath);
|
|
7616
|
+
}
|
|
7354
7617
|
}
|
|
7355
7618
|
|
|
7356
7619
|
class ThisVariable extends ParameterVariable {
|
|
7357
7620
|
constructor(context) {
|
|
7358
|
-
super('this', null, context);
|
|
7621
|
+
super('this', null, EMPTY_PATH, context);
|
|
7359
7622
|
}
|
|
7360
7623
|
hasEffectsOnInteractionAtPath(path, interaction, context) {
|
|
7361
7624
|
return (context.replacedVariableInits.get(this) || UNKNOWN_EXPRESSION).hasEffectsOnInteractionAtPath(path, interaction, context);
|
|
@@ -7367,7 +7630,7 @@ class CatchBodyScope extends ChildScope {
|
|
|
7367
7630
|
super(parent, parent.context);
|
|
7368
7631
|
this.parent = parent;
|
|
7369
7632
|
}
|
|
7370
|
-
addDeclaration(identifier, context, init, kind) {
|
|
7633
|
+
addDeclaration(identifier, context, init, destructuredInitPath, kind) {
|
|
7371
7634
|
if (kind === 'var') {
|
|
7372
7635
|
const name = identifier.name;
|
|
7373
7636
|
const existingVariable = this.hoistedVariables?.get(name) || this.variables.get(name);
|
|
@@ -7380,7 +7643,7 @@ class CatchBodyScope extends ChildScope {
|
|
|
7380
7643
|
// the assignment actually goes to the parameter and the var is
|
|
7381
7644
|
// hoisted without assignment. Locally, it is shadowed by the
|
|
7382
7645
|
// parameter
|
|
7383
|
-
const declaredVariable = this.parent.parent.addDeclaration(identifier, context, UNDEFINED_EXPRESSION, kind);
|
|
7646
|
+
const declaredVariable = this.parent.parent.addDeclaration(identifier, context, UNDEFINED_EXPRESSION, destructuredInitPath, kind);
|
|
7384
7647
|
// To avoid the need to rewrite the declaration, we link the variable
|
|
7385
7648
|
// names. If we ever implement a logic that splits initialization and
|
|
7386
7649
|
// assignment for hoisted vars, the "renderLikeHoisted" logic can be
|
|
@@ -7399,7 +7662,7 @@ class CatchBodyScope extends ChildScope {
|
|
|
7399
7662
|
return context.error(parseAst_js.logRedeclarationError(name), identifier.start);
|
|
7400
7663
|
}
|
|
7401
7664
|
// We only add parameters to parameter scopes
|
|
7402
|
-
const declaredVariable = this.parent.parent.addDeclaration(identifier, context, init, kind);
|
|
7665
|
+
const declaredVariable = this.parent.parent.addDeclaration(identifier, context, init, destructuredInitPath, kind);
|
|
7403
7666
|
// Necessary to make sure the init is deoptimized for conditional declarations.
|
|
7404
7667
|
// We cannot call deoptimizePath here.
|
|
7405
7668
|
declaredVariable.markInitializersForDeoptimization();
|
|
@@ -7407,7 +7670,7 @@ class CatchBodyScope extends ChildScope {
|
|
|
7407
7670
|
this.addHoistedVariable(name, declaredVariable);
|
|
7408
7671
|
return declaredVariable;
|
|
7409
7672
|
}
|
|
7410
|
-
return super.addDeclaration(identifier, context, init, kind);
|
|
7673
|
+
return super.addDeclaration(identifier, context, init, destructuredInitPath, kind);
|
|
7411
7674
|
}
|
|
7412
7675
|
}
|
|
7413
7676
|
|
|
@@ -7417,7 +7680,7 @@ class FunctionBodyScope extends ChildScope {
|
|
|
7417
7680
|
}
|
|
7418
7681
|
// There is stuff that is only allowed in function scopes, i.e. functions can
|
|
7419
7682
|
// be redeclared, functions and var can redeclare each other
|
|
7420
|
-
addDeclaration(identifier, context, init, kind) {
|
|
7683
|
+
addDeclaration(identifier, context, init, destructuredInitPath, kind) {
|
|
7421
7684
|
const name = identifier.name;
|
|
7422
7685
|
const existingVariable = this.hoistedVariables?.get(name) || this.variables.get(name);
|
|
7423
7686
|
if (existingVariable) {
|
|
@@ -7429,7 +7692,7 @@ class FunctionBodyScope extends ChildScope {
|
|
|
7429
7692
|
}
|
|
7430
7693
|
context.error(parseAst_js.logRedeclarationError(name), identifier.start);
|
|
7431
7694
|
}
|
|
7432
|
-
const newVariable = new LocalVariable(identifier.name, identifier, init, context, kind);
|
|
7695
|
+
const newVariable = new LocalVariable(identifier.name, identifier, init, destructuredInitPath, context, kind);
|
|
7433
7696
|
this.variables.set(name, newVariable);
|
|
7434
7697
|
return newVariable;
|
|
7435
7698
|
}
|
|
@@ -7438,21 +7701,21 @@ class FunctionBodyScope extends ChildScope {
|
|
|
7438
7701
|
class ParameterScope extends ChildScope {
|
|
7439
7702
|
constructor(parent, isCatchScope) {
|
|
7440
7703
|
super(parent, parent.context);
|
|
7441
|
-
this.parameters = [];
|
|
7442
7704
|
this.hasRest = false;
|
|
7705
|
+
this.parameters = [];
|
|
7443
7706
|
this.bodyScope = isCatchScope ? new CatchBodyScope(this) : new FunctionBodyScope(this);
|
|
7444
7707
|
}
|
|
7445
7708
|
/**
|
|
7446
7709
|
* Adds a parameter to this scope. Parameters must be added in the correct
|
|
7447
7710
|
* order, i.e. from left to right.
|
|
7448
7711
|
*/
|
|
7449
|
-
addParameterDeclaration(identifier) {
|
|
7712
|
+
addParameterDeclaration(identifier, argumentPath) {
|
|
7450
7713
|
const { name, start } = identifier;
|
|
7451
7714
|
const existingParameter = this.variables.get(name);
|
|
7452
7715
|
if (existingParameter) {
|
|
7453
7716
|
return this.context.error(parseAst_js.logDuplicateArgumentNameError(name), start);
|
|
7454
7717
|
}
|
|
7455
|
-
const variable = new ParameterVariable(name, identifier, this.context);
|
|
7718
|
+
const variable = new ParameterVariable(name, identifier, argumentPath, this.context);
|
|
7456
7719
|
this.variables.set(name, variable);
|
|
7457
7720
|
// We also add it to the body scope to detect name conflicts with local
|
|
7458
7721
|
// variables. We still need the intermediate scope, though, as parameter
|
|
@@ -7470,42 +7733,56 @@ class ParameterScope extends ChildScope {
|
|
|
7470
7733
|
}
|
|
7471
7734
|
this.hasRest = hasRest;
|
|
7472
7735
|
}
|
|
7473
|
-
includeCallArguments(context,
|
|
7736
|
+
includeCallArguments(context, interaction) {
|
|
7474
7737
|
let calledFromTryStatement = false;
|
|
7475
7738
|
let argumentIncluded = false;
|
|
7476
7739
|
const restParameter = this.hasRest && this.parameters[this.parameters.length - 1];
|
|
7477
|
-
|
|
7478
|
-
|
|
7479
|
-
|
|
7480
|
-
|
|
7481
|
-
|
|
7482
|
-
|
|
7740
|
+
const { args } = interaction;
|
|
7741
|
+
let lastExplicitlyIncludedIndex = args.length - 1;
|
|
7742
|
+
// If there is a SpreadElement, we need to include all arguments after it
|
|
7743
|
+
// because we no longer know which argument corresponds to which parameter.
|
|
7744
|
+
for (let argumentIndex = 1; argumentIndex < args.length; argumentIndex++) {
|
|
7745
|
+
const argument = args[argumentIndex];
|
|
7746
|
+
if (argument instanceof SpreadElement && !argumentIncluded) {
|
|
7747
|
+
argumentIncluded = true;
|
|
7748
|
+
lastExplicitlyIncludedIndex = argumentIndex - 1;
|
|
7749
|
+
}
|
|
7750
|
+
if (argumentIncluded) {
|
|
7751
|
+
argument.includePath(UNKNOWN_PATH, context);
|
|
7752
|
+
argument.include(context, false);
|
|
7483
7753
|
}
|
|
7484
7754
|
}
|
|
7485
|
-
|
|
7486
|
-
|
|
7487
|
-
|
|
7755
|
+
// Now we go backwards either starting from the last argument or before the
|
|
7756
|
+
// first SpreadElement to ensure all arguments before are included as needed
|
|
7757
|
+
for (let index = lastExplicitlyIncludedIndex; index >= 1; index--) {
|
|
7758
|
+
const parameterVariables = this.parameters[index - 1] || restParameter;
|
|
7759
|
+
const argument = args[index];
|
|
7488
7760
|
if (parameterVariables) {
|
|
7489
7761
|
calledFromTryStatement = false;
|
|
7490
7762
|
if (parameterVariables.length === 0) {
|
|
7491
|
-
// handle empty destructuring
|
|
7763
|
+
// handle empty destructuring to avoid destructuring undefined
|
|
7492
7764
|
argumentIncluded = true;
|
|
7493
7765
|
}
|
|
7494
7766
|
else {
|
|
7495
|
-
for (const
|
|
7496
|
-
if (
|
|
7497
|
-
argumentIncluded = true;
|
|
7498
|
-
}
|
|
7499
|
-
if (variable.calledFromTryStatement) {
|
|
7767
|
+
for (const parameterVariable of parameterVariables) {
|
|
7768
|
+
if (parameterVariable.calledFromTryStatement) {
|
|
7500
7769
|
calledFromTryStatement = true;
|
|
7501
7770
|
}
|
|
7771
|
+
if (parameterVariable.included) {
|
|
7772
|
+
argumentIncluded = true;
|
|
7773
|
+
if (calledFromTryStatement) {
|
|
7774
|
+
argument.include(context, true);
|
|
7775
|
+
}
|
|
7776
|
+
else {
|
|
7777
|
+
parameterVariable.includeArgumentPaths(argument, context);
|
|
7778
|
+
argument.include(context, false);
|
|
7779
|
+
}
|
|
7780
|
+
}
|
|
7502
7781
|
}
|
|
7503
7782
|
}
|
|
7504
7783
|
}
|
|
7505
|
-
if (!
|
|
7784
|
+
if (!argument.included && (argumentIncluded || argument.shouldBeIncluded(context))) {
|
|
7506
7785
|
argumentIncluded = true;
|
|
7507
|
-
}
|
|
7508
|
-
if (argumentIncluded) {
|
|
7509
7786
|
argument.include(context, calledFromTryStatement);
|
|
7510
7787
|
}
|
|
7511
7788
|
}
|
|
@@ -7521,11 +7798,62 @@ class ReturnValueScope extends ParameterScope {
|
|
|
7521
7798
|
addReturnExpression(expression) {
|
|
7522
7799
|
this.returnExpressions.push(expression);
|
|
7523
7800
|
}
|
|
7801
|
+
deoptimizeArgumentsOnCall(interaction) {
|
|
7802
|
+
const { parameters } = this;
|
|
7803
|
+
const { args } = interaction;
|
|
7804
|
+
let position = 0;
|
|
7805
|
+
for (; position < args.length - 1; position++) {
|
|
7806
|
+
// Only the "this" argument arg[0] can be null
|
|
7807
|
+
const argument = args[position + 1];
|
|
7808
|
+
if (argument instanceof SpreadElement) {
|
|
7809
|
+
// This deoptimizes the current and remaining parameters and arguments
|
|
7810
|
+
for (; position < parameters.length; position++) {
|
|
7811
|
+
args[position + 1]?.deoptimizePath(UNKNOWN_PATH);
|
|
7812
|
+
parameters[position].forEach(variable => variable.markReassigned());
|
|
7813
|
+
}
|
|
7814
|
+
break;
|
|
7815
|
+
}
|
|
7816
|
+
if (this.hasRest && position >= parameters.length - 1) {
|
|
7817
|
+
argument.deoptimizePath(UNKNOWN_PATH);
|
|
7818
|
+
}
|
|
7819
|
+
else {
|
|
7820
|
+
const variables = parameters[position];
|
|
7821
|
+
if (variables) {
|
|
7822
|
+
for (const variable of variables) {
|
|
7823
|
+
variable.addArgumentValue(argument);
|
|
7824
|
+
}
|
|
7825
|
+
}
|
|
7826
|
+
this.addArgumentToBeDeoptimized(argument);
|
|
7827
|
+
}
|
|
7828
|
+
}
|
|
7829
|
+
const nonRestParameterLength = this.hasRest ? parameters.length - 1 : parameters.length;
|
|
7830
|
+
for (; position < nonRestParameterLength; position++) {
|
|
7831
|
+
for (const variable of parameters[position]) {
|
|
7832
|
+
variable.addArgumentValue(UNDEFINED_EXPRESSION);
|
|
7833
|
+
}
|
|
7834
|
+
}
|
|
7835
|
+
}
|
|
7524
7836
|
getReturnExpression() {
|
|
7525
7837
|
if (this.returnExpression === null)
|
|
7526
7838
|
this.updateReturnExpression();
|
|
7527
7839
|
return this.returnExpression;
|
|
7528
7840
|
}
|
|
7841
|
+
deoptimizeAllParameters() {
|
|
7842
|
+
for (const parameter of this.parameters) {
|
|
7843
|
+
for (const variable of parameter) {
|
|
7844
|
+
variable.deoptimizePath(UNKNOWN_PATH);
|
|
7845
|
+
variable.markReassigned();
|
|
7846
|
+
}
|
|
7847
|
+
}
|
|
7848
|
+
}
|
|
7849
|
+
reassignAllParameters() {
|
|
7850
|
+
for (const parameter of this.parameters) {
|
|
7851
|
+
for (const variable of parameter) {
|
|
7852
|
+
variable.markReassigned();
|
|
7853
|
+
}
|
|
7854
|
+
}
|
|
7855
|
+
}
|
|
7856
|
+
addArgumentToBeDeoptimized(_argument) { }
|
|
7529
7857
|
updateReturnExpression() {
|
|
7530
7858
|
if (this.returnExpressions.length === 1) {
|
|
7531
7859
|
this.returnExpression = this.returnExpressions[0];
|
|
@@ -7541,24 +7869,30 @@ class ReturnValueScope extends ParameterScope {
|
|
|
7541
7869
|
|
|
7542
7870
|
class FunctionScope extends ReturnValueScope {
|
|
7543
7871
|
constructor(parent) {
|
|
7544
|
-
const { context } = parent;
|
|
7545
7872
|
super(parent, false);
|
|
7873
|
+
const { context } = parent;
|
|
7546
7874
|
this.variables.set('arguments', (this.argumentsVariable = new ArgumentsVariable(context)));
|
|
7547
7875
|
this.variables.set('this', (this.thisVariable = new ThisVariable(context)));
|
|
7548
7876
|
}
|
|
7549
7877
|
findLexicalBoundary() {
|
|
7550
7878
|
return this;
|
|
7551
7879
|
}
|
|
7552
|
-
includeCallArguments(context,
|
|
7553
|
-
super.includeCallArguments(context,
|
|
7880
|
+
includeCallArguments(context, interaction) {
|
|
7881
|
+
super.includeCallArguments(context, interaction);
|
|
7554
7882
|
if (this.argumentsVariable.included) {
|
|
7555
|
-
|
|
7556
|
-
|
|
7883
|
+
const { args } = interaction;
|
|
7884
|
+
for (let argumentIndex = 1; argumentIndex < args.length; argumentIndex++) {
|
|
7885
|
+
const argument = args[argumentIndex];
|
|
7886
|
+
if (argument) {
|
|
7887
|
+
argument.includePath(UNKNOWN_PATH, context);
|
|
7557
7888
|
argument.include(context, false);
|
|
7558
7889
|
}
|
|
7559
7890
|
}
|
|
7560
7891
|
}
|
|
7561
7892
|
}
|
|
7893
|
+
addArgumentToBeDeoptimized(argument) {
|
|
7894
|
+
this.argumentsVariable.addArgumentToBeDeoptimized(argument);
|
|
7895
|
+
}
|
|
7562
7896
|
}
|
|
7563
7897
|
|
|
7564
7898
|
class ExpressionStatement extends NodeBase {
|
|
@@ -7586,8 +7920,9 @@ class ExpressionStatement extends NodeBase {
|
|
|
7586
7920
|
return this.parent.type !== parseAst_js.Program;
|
|
7587
7921
|
return super.shouldBeIncluded(context);
|
|
7588
7922
|
}
|
|
7589
|
-
applyDeoptimizations() { }
|
|
7590
7923
|
}
|
|
7924
|
+
ExpressionStatement.prototype.includeNode = onlyIncludeSelfNoDeoptimize;
|
|
7925
|
+
ExpressionStatement.prototype.applyDeoptimizations = doNotDeoptimize;
|
|
7591
7926
|
|
|
7592
7927
|
class BlockStatement extends NodeBase {
|
|
7593
7928
|
get deoptimizeBody() {
|
|
@@ -7652,6 +7987,8 @@ class BlockStatement extends NodeBase {
|
|
|
7652
7987
|
}
|
|
7653
7988
|
}
|
|
7654
7989
|
}
|
|
7990
|
+
BlockStatement.prototype.includeNode = onlyIncludeSelfNoDeoptimize;
|
|
7991
|
+
BlockStatement.prototype.applyDeoptimizations = doNotDeoptimize;
|
|
7655
7992
|
|
|
7656
7993
|
class RestElement extends NodeBase {
|
|
7657
7994
|
constructor() {
|
|
@@ -7661,9 +7998,12 @@ class RestElement extends NodeBase {
|
|
|
7661
7998
|
addExportedVariables(variables, exportNamesByVariable) {
|
|
7662
7999
|
this.argument.addExportedVariables(variables, exportNamesByVariable);
|
|
7663
8000
|
}
|
|
7664
|
-
declare(kind, init) {
|
|
8001
|
+
declare(kind, destructuredInitPath, init) {
|
|
7665
8002
|
this.declarationInit = init;
|
|
7666
|
-
return this.argument.declare(kind,
|
|
8003
|
+
return this.argument.declare(kind, getIncludedPatternPath$1(destructuredInitPath), init);
|
|
8004
|
+
}
|
|
8005
|
+
deoptimizeAssignment(destructuredInitPath, init) {
|
|
8006
|
+
this.argument.deoptimizeAssignment(getIncludedPatternPath$1(destructuredInitPath), init);
|
|
7667
8007
|
}
|
|
7668
8008
|
deoptimizePath(path) {
|
|
7669
8009
|
if (path.length === 0) {
|
|
@@ -7674,6 +8014,20 @@ class RestElement extends NodeBase {
|
|
|
7674
8014
|
return (path.length > 0 ||
|
|
7675
8015
|
this.argument.hasEffectsOnInteractionAtPath(EMPTY_PATH, interaction, context));
|
|
7676
8016
|
}
|
|
8017
|
+
hasEffectsWhenDestructuring(context, destructuredInitPath, init) {
|
|
8018
|
+
return this.argument.hasEffectsWhenDestructuring(context, getIncludedPatternPath$1(destructuredInitPath), init);
|
|
8019
|
+
}
|
|
8020
|
+
includeDestructuredIfNecessary(context, destructuredInitPath, init) {
|
|
8021
|
+
return (this.included =
|
|
8022
|
+
this.argument.includeDestructuredIfNecessary(context, getIncludedPatternPath$1(destructuredInitPath), init) || this.included);
|
|
8023
|
+
}
|
|
8024
|
+
include(context, includeChildrenRecursively) {
|
|
8025
|
+
if (!this.included)
|
|
8026
|
+
this.includeNode(context);
|
|
8027
|
+
// This should just include the identifier, its properties should be
|
|
8028
|
+
// included where the variable is used.
|
|
8029
|
+
this.argument.include(context, includeChildrenRecursively);
|
|
8030
|
+
}
|
|
7677
8031
|
markDeclarationReached() {
|
|
7678
8032
|
this.argument.markDeclarationReached();
|
|
7679
8033
|
}
|
|
@@ -7685,12 +8039,16 @@ class RestElement extends NodeBase {
|
|
|
7685
8039
|
}
|
|
7686
8040
|
}
|
|
7687
8041
|
}
|
|
8042
|
+
RestElement.prototype.includeNode = onlyIncludeSelf;
|
|
8043
|
+
const getIncludedPatternPath$1 = (destructuredInitPath) => destructuredInitPath.at(-1) === UnknownKey
|
|
8044
|
+
? destructuredInitPath
|
|
8045
|
+
: [...destructuredInitPath, UnknownKey];
|
|
7688
8046
|
|
|
7689
8047
|
class FunctionBase extends NodeBase {
|
|
7690
8048
|
constructor() {
|
|
7691
8049
|
super(...arguments);
|
|
7692
|
-
this.objectEntity = null;
|
|
7693
8050
|
this.parameterVariableValuesDeoptimized = false;
|
|
8051
|
+
this.includeCallArguments = this.scope.includeCallArguments.bind(this.scope);
|
|
7694
8052
|
}
|
|
7695
8053
|
get async() {
|
|
7696
8054
|
return isFlagSet(this.flags, 256 /* Flag.async */);
|
|
@@ -7710,53 +8068,15 @@ class FunctionBase extends NodeBase {
|
|
|
7710
8068
|
set generator(value) {
|
|
7711
8069
|
this.flags = setFlag(this.flags, 4194304 /* Flag.generator */, value);
|
|
7712
8070
|
}
|
|
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
|
-
}
|
|
8071
|
+
get hasCachedEffects() {
|
|
8072
|
+
return isFlagSet(this.flags, 67108864 /* Flag.hasEffects */);
|
|
7723
8073
|
}
|
|
7724
|
-
|
|
7725
|
-
|
|
7726
|
-
if (parameter instanceof Identifier) {
|
|
7727
|
-
const parameterVariable = parameter.variable;
|
|
7728
|
-
parameterVariable.markReassigned();
|
|
7729
|
-
}
|
|
7730
|
-
}
|
|
8074
|
+
set hasCachedEffects(value) {
|
|
8075
|
+
this.flags = setFlag(this.flags, 67108864 /* Flag.hasEffects */, value);
|
|
7731
8076
|
}
|
|
7732
8077
|
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);
|
|
8078
|
+
if (interaction.type === INTERACTION_CALLED && path.length === 0) {
|
|
8079
|
+
this.scope.deoptimizeArgumentsOnCall(interaction);
|
|
7760
8080
|
}
|
|
7761
8081
|
else {
|
|
7762
8082
|
this.getObjectEntity().deoptimizeArgumentsOnInteractionAtPath(interaction, path, recursionTracker);
|
|
@@ -7768,12 +8088,7 @@ class FunctionBase extends NodeBase {
|
|
|
7768
8088
|
// A reassignment of UNKNOWN_PATH is considered equivalent to having lost track
|
|
7769
8089
|
// which means the return expression and parameters need to be reassigned
|
|
7770
8090
|
this.scope.getReturnExpression().deoptimizePath(UNKNOWN_PATH);
|
|
7771
|
-
|
|
7772
|
-
for (const parameter of parameterList) {
|
|
7773
|
-
parameter.deoptimizePath(UNKNOWN_PATH);
|
|
7774
|
-
parameter.markReassigned();
|
|
7775
|
-
}
|
|
7776
|
-
}
|
|
8091
|
+
this.scope.deoptimizeAllParameters();
|
|
7777
8092
|
}
|
|
7778
8093
|
}
|
|
7779
8094
|
getLiteralValueAtPath(path, recursionTracker, origin) {
|
|
@@ -7797,8 +8112,8 @@ class FunctionBase extends NodeBase {
|
|
|
7797
8112
|
if (path.length > 0 || interaction.type !== INTERACTION_CALLED) {
|
|
7798
8113
|
return this.getObjectEntity().hasEffectsOnInteractionAtPath(path, interaction, context);
|
|
7799
8114
|
}
|
|
7800
|
-
if (this.
|
|
7801
|
-
return
|
|
8115
|
+
if (this.hasCachedEffects) {
|
|
8116
|
+
return true;
|
|
7802
8117
|
}
|
|
7803
8118
|
if (this.async) {
|
|
7804
8119
|
const { propertyReadSideEffects } = this.scope.context.options
|
|
@@ -7808,12 +8123,20 @@ class FunctionBase extends NodeBase {
|
|
|
7808
8123
|
(propertyReadSideEffects &&
|
|
7809
8124
|
(propertyReadSideEffects === 'always' ||
|
|
7810
8125
|
returnExpression.hasEffectsOnInteractionAtPath(['then'], NODE_INTERACTION_UNKNOWN_ACCESS, context)))) {
|
|
8126
|
+
this.hasCachedEffects = true;
|
|
7811
8127
|
return true;
|
|
7812
8128
|
}
|
|
7813
8129
|
}
|
|
7814
|
-
|
|
7815
|
-
|
|
8130
|
+
const { propertyReadSideEffects } = this.scope.context.options
|
|
8131
|
+
.treeshake;
|
|
8132
|
+
for (let index = 0; index < this.params.length; index++) {
|
|
8133
|
+
const parameter = this.params[index];
|
|
8134
|
+
if (parameter.hasEffects(context) ||
|
|
8135
|
+
(propertyReadSideEffects &&
|
|
8136
|
+
parameter.hasEffectsWhenDestructuring(context, EMPTY_PATH, interaction.args[index + 1] || UNDEFINED_EXPRESSION))) {
|
|
8137
|
+
this.hasCachedEffects = true;
|
|
7816
8138
|
return true;
|
|
8139
|
+
}
|
|
7817
8140
|
}
|
|
7818
8141
|
return false;
|
|
7819
8142
|
}
|
|
@@ -7831,21 +8154,17 @@ class FunctionBase extends NodeBase {
|
|
|
7831
8154
|
return variable?.getOnlyFunctionCallUsed() ?? false;
|
|
7832
8155
|
}
|
|
7833
8156
|
include(context, includeChildrenRecursively) {
|
|
7834
|
-
if (!this.
|
|
8157
|
+
if (!this.included)
|
|
8158
|
+
this.includeNode(context);
|
|
8159
|
+
if (!(this.parameterVariableValuesDeoptimized || this.onlyFunctionCallUsed())) {
|
|
7835
8160
|
this.parameterVariableValuesDeoptimized = true;
|
|
7836
|
-
this.
|
|
8161
|
+
this.scope.reassignAllParameters();
|
|
7837
8162
|
}
|
|
7838
|
-
if (!this.deoptimized)
|
|
7839
|
-
this.applyDeoptimizations();
|
|
7840
|
-
this.included = true;
|
|
7841
8163
|
const { brokenFlow } = context;
|
|
7842
8164
|
context.brokenFlow = false;
|
|
7843
8165
|
this.body.include(context, includeChildrenRecursively);
|
|
7844
8166
|
context.brokenFlow = brokenFlow;
|
|
7845
8167
|
}
|
|
7846
|
-
includeCallArguments(context, parameters) {
|
|
7847
|
-
this.scope.includeCallArguments(context, parameters);
|
|
7848
|
-
}
|
|
7849
8168
|
initialise() {
|
|
7850
8169
|
super.initialise();
|
|
7851
8170
|
if (this.body instanceof BlockStatement) {
|
|
@@ -7867,14 +8186,14 @@ class FunctionBase extends NodeBase {
|
|
|
7867
8186
|
// so that the scope already knows all parameters and can detect conflicts
|
|
7868
8187
|
// when parsing the body.
|
|
7869
8188
|
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);
|
|
8189
|
+
scope.addParameterVariables(parameters.map(parameter => parameter.declare('parameter', EMPTY_PATH, UNKNOWN_EXPRESSION)), parameters[parameters.length - 1] instanceof RestElement);
|
|
7871
8190
|
this.body = new (context.getNodeConstructor(body.type))(this, bodyScope).parseNode(body);
|
|
7872
8191
|
return super.parseNode(esTreeNode);
|
|
7873
8192
|
}
|
|
7874
|
-
addArgumentToBeDeoptimized(_argument) { }
|
|
7875
|
-
applyDeoptimizations() { }
|
|
7876
8193
|
}
|
|
7877
8194
|
FunctionBase.prototype.preventChildBlockScope = true;
|
|
8195
|
+
FunctionBase.prototype.includeNode = onlyIncludeSelfNoDeoptimize;
|
|
8196
|
+
FunctionBase.prototype.applyDeoptimizations = doNotDeoptimize;
|
|
7878
8197
|
|
|
7879
8198
|
class FunctionNode extends FunctionBase {
|
|
7880
8199
|
constructor() {
|
|
@@ -7886,30 +8205,31 @@ class FunctionNode extends FunctionBase {
|
|
|
7886
8205
|
this.constructedEntity = new ObjectEntity(Object.create(null), OBJECT_PROTOTYPE);
|
|
7887
8206
|
// This makes sure that all deoptimizations of "this" are applied to the
|
|
7888
8207
|
// constructed entity.
|
|
7889
|
-
this.scope.thisVariable.
|
|
8208
|
+
this.scope.thisVariable.addArgumentValue(this.constructedEntity);
|
|
7890
8209
|
}
|
|
7891
8210
|
deoptimizeArgumentsOnInteractionAtPath(interaction, path, recursionTracker) {
|
|
7892
8211
|
super.deoptimizeArgumentsOnInteractionAtPath(interaction, path, recursionTracker);
|
|
7893
8212
|
if (interaction.type === INTERACTION_CALLED && path.length === 0 && interaction.args[0]) {
|
|
7894
8213
|
// args[0] is the "this" argument
|
|
7895
|
-
this.scope.thisVariable.
|
|
8214
|
+
this.scope.thisVariable.addArgumentValue(interaction.args[0]);
|
|
7896
8215
|
}
|
|
7897
8216
|
}
|
|
7898
8217
|
hasEffects(context) {
|
|
7899
|
-
if (!this.deoptimized)
|
|
7900
|
-
this.applyDeoptimizations();
|
|
7901
8218
|
if (this.annotationNoSideEffects) {
|
|
7902
8219
|
return false;
|
|
7903
8220
|
}
|
|
7904
8221
|
return !!this.id?.hasEffects(context);
|
|
7905
8222
|
}
|
|
7906
8223
|
hasEffectsOnInteractionAtPath(path, interaction, context) {
|
|
7907
|
-
if (
|
|
7908
|
-
|
|
7909
|
-
|
|
8224
|
+
if (this.annotationNoSideEffects &&
|
|
8225
|
+
path.length === 0 &&
|
|
8226
|
+
interaction.type === INTERACTION_CALLED) {
|
|
7910
8227
|
return false;
|
|
7911
8228
|
}
|
|
7912
|
-
if (
|
|
8229
|
+
if (super.hasEffectsOnInteractionAtPath(path, interaction, context)) {
|
|
8230
|
+
return true;
|
|
8231
|
+
}
|
|
8232
|
+
if (path.length === 0 && interaction.type === INTERACTION_CALLED) {
|
|
7913
8233
|
const thisInit = context.replacedVariableInits.get(this.scope.thisVariable);
|
|
7914
8234
|
context.replacedVariableInits.set(this.scope.thisVariable, interaction.withNew ? this.constructedEntity : UNKNOWN_EXPRESSION);
|
|
7915
8235
|
const { brokenFlow, ignore, replacedVariableInits } = context;
|
|
@@ -7920,8 +8240,10 @@ class FunctionNode extends FunctionBase {
|
|
|
7920
8240
|
returnYield: true,
|
|
7921
8241
|
this: interaction.withNew
|
|
7922
8242
|
};
|
|
7923
|
-
if (this.body.hasEffects(context))
|
|
8243
|
+
if (this.body.hasEffects(context)) {
|
|
8244
|
+
this.hasCachedEffects = true;
|
|
7924
8245
|
return true;
|
|
8246
|
+
}
|
|
7925
8247
|
context.brokenFlow = brokenFlow;
|
|
7926
8248
|
if (thisInit) {
|
|
7927
8249
|
replacedVariableInits.set(this.scope.thisVariable, thisInit);
|
|
@@ -7935,7 +8257,7 @@ class FunctionNode extends FunctionBase {
|
|
|
7935
8257
|
}
|
|
7936
8258
|
include(context, includeChildrenRecursively) {
|
|
7937
8259
|
super.include(context, includeChildrenRecursively);
|
|
7938
|
-
this.id?.include();
|
|
8260
|
+
this.id?.include(context);
|
|
7939
8261
|
const hasArguments = this.scope.argumentsVariable.included;
|
|
7940
8262
|
for (const parameter of this.params) {
|
|
7941
8263
|
if (!(parameter instanceof Identifier) || hasArguments) {
|
|
@@ -7943,12 +8265,18 @@ class FunctionNode extends FunctionBase {
|
|
|
7943
8265
|
}
|
|
7944
8266
|
}
|
|
7945
8267
|
}
|
|
8268
|
+
includeNode(context) {
|
|
8269
|
+
this.included = true;
|
|
8270
|
+
const hasArguments = this.scope.argumentsVariable.included;
|
|
8271
|
+
for (const parameter of this.params) {
|
|
8272
|
+
if (!(parameter instanceof Identifier) || hasArguments) {
|
|
8273
|
+
parameter.includePath(UNKNOWN_PATH, context);
|
|
8274
|
+
}
|
|
8275
|
+
}
|
|
8276
|
+
}
|
|
7946
8277
|
initialise() {
|
|
7947
8278
|
super.initialise();
|
|
7948
|
-
this.id?.declare('function', this);
|
|
7949
|
-
}
|
|
7950
|
-
addArgumentToBeDeoptimized(argument) {
|
|
7951
|
-
this.scope.argumentsVariable.addArgumentToBeDeoptimized(argument);
|
|
8279
|
+
this.id?.declare('function', EMPTY_PATH, this);
|
|
7952
8280
|
}
|
|
7953
8281
|
getObjectEntity() {
|
|
7954
8282
|
if (this.objectEntity !== null) {
|
|
@@ -7998,11 +8326,16 @@ function getFunctionIdInsertPosition(code, start) {
|
|
|
7998
8326
|
}
|
|
7999
8327
|
class ExportDefaultDeclaration extends NodeBase {
|
|
8000
8328
|
include(context, includeChildrenRecursively) {
|
|
8001
|
-
|
|
8329
|
+
this.included = true;
|
|
8330
|
+
this.declaration.include(context, includeChildrenRecursively);
|
|
8002
8331
|
if (includeChildrenRecursively) {
|
|
8003
|
-
this.scope.context.includeVariableInModule(this.variable);
|
|
8332
|
+
this.scope.context.includeVariableInModule(this.variable, UNKNOWN_PATH, context);
|
|
8004
8333
|
}
|
|
8005
8334
|
}
|
|
8335
|
+
includePath(path, context) {
|
|
8336
|
+
this.included = true;
|
|
8337
|
+
this.declaration.includePath(path, context);
|
|
8338
|
+
}
|
|
8006
8339
|
initialise() {
|
|
8007
8340
|
super.initialise();
|
|
8008
8341
|
const declaration = this.declaration;
|
|
@@ -8047,7 +8380,6 @@ class ExportDefaultDeclaration extends NodeBase {
|
|
|
8047
8380
|
}
|
|
8048
8381
|
this.declaration.render(code, options);
|
|
8049
8382
|
}
|
|
8050
|
-
applyDeoptimizations() { }
|
|
8051
8383
|
renderNamedDeclaration(code, declarationStart, idInsertPosition, options) {
|
|
8052
8384
|
const { exportNamesByVariable, format, snippets: { getPropertyAccess } } = options;
|
|
8053
8385
|
const name = this.variable.getName(getPropertyAccess);
|
|
@@ -8078,6 +8410,8 @@ class ExportDefaultDeclaration extends NodeBase {
|
|
|
8078
8410
|
}
|
|
8079
8411
|
}
|
|
8080
8412
|
ExportDefaultDeclaration.prototype.needsBoundaries = true;
|
|
8413
|
+
ExportDefaultDeclaration.prototype.includeNode = onlyIncludeSelfNoDeoptimize;
|
|
8414
|
+
ExportDefaultDeclaration.prototype.applyDeoptimizations = doNotDeoptimize;
|
|
8081
8415
|
|
|
8082
8416
|
const needsEscapeRegEx = /[\n\r'\\\u2028\u2029]/;
|
|
8083
8417
|
const quoteNewlineRegEx = /([\n\r'\u2028\u2029])/g;
|
|
@@ -8347,6 +8681,7 @@ class Literal extends NodeBase {
|
|
|
8347
8681
|
}
|
|
8348
8682
|
}
|
|
8349
8683
|
}
|
|
8684
|
+
Literal.prototype.includeNode = onlyIncludeSelf;
|
|
8350
8685
|
|
|
8351
8686
|
function getChainElementLiteralValueAtPath(element, object, path, recursionTracker, origin) {
|
|
8352
8687
|
if ('getLiteralValueAtPathAsChainElement' in object) {
|
|
@@ -8362,8 +8697,6 @@ function getChainElementLiteralValueAtPath(element, object, path, recursionTrack
|
|
|
8362
8697
|
return element.getLiteralValueAtPath(path, recursionTracker, origin);
|
|
8363
8698
|
}
|
|
8364
8699
|
|
|
8365
|
-
// To avoid infinite recursions
|
|
8366
|
-
const MAX_PATH_DEPTH = 7;
|
|
8367
8700
|
function getResolvablePropertyKey(memberExpression) {
|
|
8368
8701
|
return memberExpression.computed
|
|
8369
8702
|
? getResolvableComputedPropertyKey(memberExpression.property)
|
|
@@ -8462,18 +8795,27 @@ class MemberExpression extends NodeBase {
|
|
|
8462
8795
|
}
|
|
8463
8796
|
else if (!this.isUndefined) {
|
|
8464
8797
|
if (path.length < MAX_PATH_DEPTH) {
|
|
8465
|
-
this.object.deoptimizeArgumentsOnInteractionAtPath(interaction, [this.
|
|
8798
|
+
this.object.deoptimizeArgumentsOnInteractionAtPath(interaction, this.propertyKey === UnknownKey ? UNKNOWN_PATH : [this.propertyKey, ...path], recursionTracker);
|
|
8466
8799
|
}
|
|
8467
8800
|
else {
|
|
8468
8801
|
deoptimizeInteraction(interaction);
|
|
8469
8802
|
}
|
|
8470
8803
|
}
|
|
8471
8804
|
}
|
|
8805
|
+
deoptimizeAssignment(destructuredInitPath, init) {
|
|
8806
|
+
this.deoptimizePath(EMPTY_PATH);
|
|
8807
|
+
init.deoptimizePath([...destructuredInitPath, UnknownKey]);
|
|
8808
|
+
}
|
|
8472
8809
|
deoptimizeCache() {
|
|
8810
|
+
if (this.propertyKey === this.dynamicPropertyKey)
|
|
8811
|
+
return;
|
|
8473
8812
|
const { expressionsToBeDeoptimized, object } = this;
|
|
8474
8813
|
this.expressionsToBeDeoptimized = parseAst_js.EMPTY_ARRAY;
|
|
8475
|
-
this.
|
|
8814
|
+
this.dynamicPropertyKey = this.propertyKey;
|
|
8476
8815
|
object.deoptimizePath(UNKNOWN_PATH);
|
|
8816
|
+
if (this.included) {
|
|
8817
|
+
object.includePath(UNKNOWN_PATH, createInclusionContext());
|
|
8818
|
+
}
|
|
8477
8819
|
for (const expression of expressionsToBeDeoptimized) {
|
|
8478
8820
|
expression.deoptimizeCache();
|
|
8479
8821
|
}
|
|
@@ -8484,11 +8826,13 @@ class MemberExpression extends NodeBase {
|
|
|
8484
8826
|
if (this.variable) {
|
|
8485
8827
|
this.variable.deoptimizePath(path);
|
|
8486
8828
|
}
|
|
8487
|
-
else if (!this.isUndefined
|
|
8488
|
-
const propertyKey = this
|
|
8829
|
+
else if (!this.isUndefined) {
|
|
8830
|
+
const { propertyKey } = this;
|
|
8489
8831
|
this.object.deoptimizePath([
|
|
8490
8832
|
propertyKey === UnknownKey ? UnknownNonAccessorKey : propertyKey,
|
|
8491
|
-
...path
|
|
8833
|
+
...(path.length < MAX_PATH_DEPTH
|
|
8834
|
+
? path
|
|
8835
|
+
: [...path.slice(0, MAX_PATH_DEPTH), UnknownKey])
|
|
8492
8836
|
]);
|
|
8493
8837
|
}
|
|
8494
8838
|
}
|
|
@@ -8499,9 +8843,11 @@ class MemberExpression extends NodeBase {
|
|
|
8499
8843
|
if (this.isUndefined) {
|
|
8500
8844
|
return undefined;
|
|
8501
8845
|
}
|
|
8502
|
-
|
|
8503
|
-
|
|
8504
|
-
|
|
8846
|
+
const propertyKey = this.getDynamicPropertyKey();
|
|
8847
|
+
if (propertyKey !== UnknownKey && path.length < MAX_PATH_DEPTH) {
|
|
8848
|
+
if (propertyKey !== this.propertyKey)
|
|
8849
|
+
this.expressionsToBeDeoptimized.push(origin);
|
|
8850
|
+
return this.object.getLiteralValueAtPath([propertyKey, ...path], recursionTracker, origin);
|
|
8505
8851
|
}
|
|
8506
8852
|
return UnknownValue;
|
|
8507
8853
|
}
|
|
@@ -8521,9 +8867,11 @@ class MemberExpression extends NodeBase {
|
|
|
8521
8867
|
if (this.isUndefined) {
|
|
8522
8868
|
return [UNDEFINED_EXPRESSION, false];
|
|
8523
8869
|
}
|
|
8524
|
-
|
|
8525
|
-
|
|
8526
|
-
|
|
8870
|
+
const propertyKey = this.getDynamicPropertyKey();
|
|
8871
|
+
if (propertyKey !== UnknownKey && path.length < MAX_PATH_DEPTH) {
|
|
8872
|
+
if (propertyKey !== this.propertyKey)
|
|
8873
|
+
this.expressionsToBeDeoptimized.push(origin);
|
|
8874
|
+
return this.object.getReturnExpressionWhenCalledAtPath([propertyKey, ...path], interaction, recursionTracker, origin);
|
|
8527
8875
|
}
|
|
8528
8876
|
return UNKNOWN_RETURN_EXPRESSION;
|
|
8529
8877
|
}
|
|
@@ -8569,14 +8917,45 @@ class MemberExpression extends NodeBase {
|
|
|
8569
8917
|
return true;
|
|
8570
8918
|
}
|
|
8571
8919
|
if (path.length < MAX_PATH_DEPTH) {
|
|
8572
|
-
return this.object.hasEffectsOnInteractionAtPath([this.
|
|
8920
|
+
return this.object.hasEffectsOnInteractionAtPath([this.getDynamicPropertyKey(), ...path], interaction, context);
|
|
8573
8921
|
}
|
|
8574
8922
|
return true;
|
|
8575
8923
|
}
|
|
8924
|
+
hasEffectsWhenDestructuring(context, destructuredInitPath, init) {
|
|
8925
|
+
return (destructuredInitPath.length > 0 &&
|
|
8926
|
+
init.hasEffectsOnInteractionAtPath(destructuredInitPath, NODE_INTERACTION_UNKNOWN_ACCESS, context));
|
|
8927
|
+
}
|
|
8576
8928
|
include(context, includeChildrenRecursively) {
|
|
8929
|
+
if (!this.included)
|
|
8930
|
+
this.includeNode(context);
|
|
8931
|
+
this.object.include(context, includeChildrenRecursively);
|
|
8932
|
+
this.property.include(context, includeChildrenRecursively);
|
|
8933
|
+
}
|
|
8934
|
+
includeNode(context) {
|
|
8935
|
+
this.included = true;
|
|
8577
8936
|
if (!this.deoptimized)
|
|
8578
8937
|
this.applyDeoptimizations();
|
|
8579
|
-
this.
|
|
8938
|
+
if (this.variable) {
|
|
8939
|
+
this.scope.context.includeVariableInModule(this.variable, EMPTY_PATH, context);
|
|
8940
|
+
}
|
|
8941
|
+
else if (!this.isUndefined) {
|
|
8942
|
+
this.object.includePath([this.propertyKey], context);
|
|
8943
|
+
}
|
|
8944
|
+
}
|
|
8945
|
+
includePath(path, context) {
|
|
8946
|
+
if (!this.included)
|
|
8947
|
+
this.includeNode(context);
|
|
8948
|
+
if (this.variable) {
|
|
8949
|
+
this.variable?.includePath(path, context);
|
|
8950
|
+
}
|
|
8951
|
+
else if (!this.isUndefined) {
|
|
8952
|
+
this.object.includePath([
|
|
8953
|
+
this.propertyKey,
|
|
8954
|
+
...(path.length < MAX_PATH_DEPTH
|
|
8955
|
+
? path
|
|
8956
|
+
: [...path.slice(0, MAX_PATH_DEPTH), UnknownKey])
|
|
8957
|
+
], context);
|
|
8958
|
+
}
|
|
8580
8959
|
}
|
|
8581
8960
|
includeAsAssignmentTarget(context, includeChildrenRecursively, deoptimizeAccess) {
|
|
8582
8961
|
if (!this.assignmentDeoptimized)
|
|
@@ -8585,20 +8964,34 @@ class MemberExpression extends NodeBase {
|
|
|
8585
8964
|
this.include(context, includeChildrenRecursively);
|
|
8586
8965
|
}
|
|
8587
8966
|
else {
|
|
8588
|
-
this.
|
|
8967
|
+
if (!this.included)
|
|
8968
|
+
this.includeNode(context);
|
|
8969
|
+
this.object.include(context, includeChildrenRecursively);
|
|
8970
|
+
this.property.include(context, includeChildrenRecursively);
|
|
8589
8971
|
}
|
|
8590
8972
|
}
|
|
8591
|
-
includeCallArguments(context,
|
|
8973
|
+
includeCallArguments(context, interaction) {
|
|
8592
8974
|
if (this.variable) {
|
|
8593
|
-
this.variable.includeCallArguments(context,
|
|
8975
|
+
this.variable.includeCallArguments(context, interaction);
|
|
8594
8976
|
}
|
|
8595
8977
|
else {
|
|
8596
|
-
super.includeCallArguments(context,
|
|
8978
|
+
super.includeCallArguments(context, interaction);
|
|
8979
|
+
}
|
|
8980
|
+
}
|
|
8981
|
+
includeDestructuredIfNecessary(context, destructuredInitPath, init) {
|
|
8982
|
+
if ((this.included ||=
|
|
8983
|
+
destructuredInitPath.length > 0 &&
|
|
8984
|
+
!context.brokenFlow &&
|
|
8985
|
+
init.hasEffectsOnInteractionAtPath(destructuredInitPath, NODE_INTERACTION_UNKNOWN_ACCESS, createHasEffectsContext()))) {
|
|
8986
|
+
init.include(context, false);
|
|
8987
|
+
return true;
|
|
8597
8988
|
}
|
|
8989
|
+
return false;
|
|
8598
8990
|
}
|
|
8599
8991
|
initialise() {
|
|
8600
8992
|
super.initialise();
|
|
8601
|
-
this.
|
|
8993
|
+
this.dynamicPropertyKey = getResolvablePropertyKey(this);
|
|
8994
|
+
this.propertyKey = this.dynamicPropertyKey === null ? UnknownKey : this.dynamicPropertyKey;
|
|
8602
8995
|
this.accessInteraction = { args: [this.object], type: INTERACTION_ACCESSED };
|
|
8603
8996
|
}
|
|
8604
8997
|
render(code, options, { renderedParentType, isCalleeOfRenderedParent, renderedSurroundingElement } = parseAst_js.BLANK) {
|
|
@@ -8635,8 +9028,7 @@ class MemberExpression extends NodeBase {
|
|
|
8635
9028
|
this.bound &&
|
|
8636
9029
|
propertyReadSideEffects &&
|
|
8637
9030
|
!(this.variable || this.isUndefined)) {
|
|
8638
|
-
|
|
8639
|
-
this.object.deoptimizeArgumentsOnInteractionAtPath(this.accessInteraction, [propertyKey], SHARED_RECURSION_TRACKER);
|
|
9031
|
+
this.object.deoptimizeArgumentsOnInteractionAtPath(this.accessInteraction, [this.propertyKey], SHARED_RECURSION_TRACKER);
|
|
8640
9032
|
this.scope.context.requestTreeshakingPass();
|
|
8641
9033
|
}
|
|
8642
9034
|
if (this.variable) {
|
|
@@ -8653,7 +9045,7 @@ class MemberExpression extends NodeBase {
|
|
|
8653
9045
|
this.bound &&
|
|
8654
9046
|
propertyReadSideEffects &&
|
|
8655
9047
|
!(this.variable || this.isUndefined)) {
|
|
8656
|
-
this.object.deoptimizeArgumentsOnInteractionAtPath(this.assignmentInteraction, [this.
|
|
9048
|
+
this.object.deoptimizeArgumentsOnInteractionAtPath(this.assignmentInteraction, [this.propertyKey], SHARED_RECURSION_TRACKER);
|
|
8657
9049
|
this.scope.context.requestTreeshakingPass();
|
|
8658
9050
|
}
|
|
8659
9051
|
}
|
|
@@ -8662,24 +9054,24 @@ class MemberExpression extends NodeBase {
|
|
|
8662
9054
|
const variable = this.scope.findVariable(this.object.name);
|
|
8663
9055
|
if (variable.isNamespace) {
|
|
8664
9056
|
if (this.variable) {
|
|
8665
|
-
this.scope.context.includeVariableInModule(this.variable);
|
|
9057
|
+
this.scope.context.includeVariableInModule(this.variable, UNKNOWN_PATH, createInclusionContext());
|
|
8666
9058
|
}
|
|
8667
9059
|
this.scope.context.log(parseAst_js.LOGLEVEL_WARN, parseAst_js.logIllegalImportReassignment(this.object.name, this.scope.context.module.id), this.start);
|
|
8668
9060
|
}
|
|
8669
9061
|
}
|
|
8670
9062
|
}
|
|
8671
|
-
|
|
8672
|
-
if (this.
|
|
8673
|
-
this.
|
|
9063
|
+
getDynamicPropertyKey() {
|
|
9064
|
+
if (this.dynamicPropertyKey === null) {
|
|
9065
|
+
this.dynamicPropertyKey = this.propertyKey;
|
|
8674
9066
|
const value = this.property.getLiteralValueAtPath(EMPTY_PATH, SHARED_RECURSION_TRACKER, this);
|
|
8675
|
-
return (this.
|
|
9067
|
+
return (this.dynamicPropertyKey =
|
|
8676
9068
|
value === SymbolToStringTag
|
|
8677
9069
|
? value
|
|
8678
9070
|
: typeof value === 'symbol'
|
|
8679
9071
|
? UnknownKey
|
|
8680
9072
|
: String(value));
|
|
8681
9073
|
}
|
|
8682
|
-
return this.
|
|
9074
|
+
return this.dynamicPropertyKey;
|
|
8683
9075
|
}
|
|
8684
9076
|
hasAccessEffect(context) {
|
|
8685
9077
|
const { propertyReadSideEffects } = this.scope.context.options
|
|
@@ -8687,17 +9079,7 @@ class MemberExpression extends NodeBase {
|
|
|
8687
9079
|
return (!(this.variable || this.isUndefined) &&
|
|
8688
9080
|
propertyReadSideEffects &&
|
|
8689
9081
|
(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);
|
|
9082
|
+
this.object.hasEffectsOnInteractionAtPath([this.getDynamicPropertyKey()], this.accessInteraction, context)));
|
|
8701
9083
|
}
|
|
8702
9084
|
}
|
|
8703
9085
|
function resolveNamespaceVariables(baseVariable, path, astContext) {
|
|
@@ -8741,18 +9123,20 @@ class MetaProperty extends NodeBase {
|
|
|
8741
9123
|
return path.length > 1 || type !== INTERACTION_ACCESSED;
|
|
8742
9124
|
}
|
|
8743
9125
|
include() {
|
|
8744
|
-
if (!this.included)
|
|
8745
|
-
this.
|
|
8746
|
-
|
|
8747
|
-
|
|
8748
|
-
|
|
8749
|
-
|
|
8750
|
-
|
|
8751
|
-
|
|
8752
|
-
|
|
8753
|
-
|
|
8754
|
-
|
|
8755
|
-
|
|
9126
|
+
if (!this.included)
|
|
9127
|
+
this.includeNode();
|
|
9128
|
+
}
|
|
9129
|
+
includeNode() {
|
|
9130
|
+
this.included = true;
|
|
9131
|
+
if (this.meta.name === IMPORT) {
|
|
9132
|
+
this.scope.context.addImportMeta(this);
|
|
9133
|
+
const parent = this.parent;
|
|
9134
|
+
const metaProperty = (this.metaProperty =
|
|
9135
|
+
parent instanceof MemberExpression && typeof parent.propertyKey === 'string'
|
|
9136
|
+
? parent.propertyKey
|
|
9137
|
+
: null);
|
|
9138
|
+
if (metaProperty?.startsWith(FILE_PREFIX)) {
|
|
9139
|
+
this.referenceId = metaProperty.slice(FILE_PREFIX.length);
|
|
8756
9140
|
}
|
|
8757
9141
|
}
|
|
8758
9142
|
}
|
|
@@ -8859,7 +9243,7 @@ class UndefinedVariable extends Variable {
|
|
|
8859
9243
|
|
|
8860
9244
|
class ExportDefaultVariable extends LocalVariable {
|
|
8861
9245
|
constructor(name, exportDefaultDeclaration, context) {
|
|
8862
|
-
super(name, exportDefaultDeclaration, exportDefaultDeclaration.declaration, context, 'other');
|
|
9246
|
+
super(name, exportDefaultDeclaration, exportDefaultDeclaration.declaration, EMPTY_PATH, context, 'other');
|
|
8863
9247
|
this.hasId = false;
|
|
8864
9248
|
this.originalId = null;
|
|
8865
9249
|
this.originalVariable = null;
|
|
@@ -9008,8 +9392,8 @@ class NamespaceVariable extends Variable {
|
|
|
9008
9392
|
return (!memberVariable ||
|
|
9009
9393
|
memberVariable.hasEffectsOnInteractionAtPath(path.slice(1), interaction, context));
|
|
9010
9394
|
}
|
|
9011
|
-
|
|
9012
|
-
super.
|
|
9395
|
+
includePath(path, context) {
|
|
9396
|
+
super.includePath(path, context);
|
|
9013
9397
|
this.context.includeAllExports();
|
|
9014
9398
|
}
|
|
9015
9399
|
prepare(accessedGlobalsByScope) {
|
|
@@ -9102,9 +9486,9 @@ class SyntheticNamedExportVariable extends Variable {
|
|
|
9102
9486
|
getName(getPropertyAccess) {
|
|
9103
9487
|
return `${this.syntheticNamespace.getName(getPropertyAccess)}${getPropertyAccess(this.name)}`;
|
|
9104
9488
|
}
|
|
9105
|
-
|
|
9106
|
-
super.
|
|
9107
|
-
this.context.includeVariableInModule(this.syntheticNamespace);
|
|
9489
|
+
includePath(path, context) {
|
|
9490
|
+
super.includePath(path, context);
|
|
9491
|
+
this.context.includeVariableInModule(this.syntheticNamespace, path, context);
|
|
9108
9492
|
}
|
|
9109
9493
|
setRenderNames(baseName, name) {
|
|
9110
9494
|
super.setRenderNames(baseName, name);
|
|
@@ -12280,21 +12664,37 @@ class ArrayPattern extends NodeBase {
|
|
|
12280
12664
|
element?.addExportedVariables(variables, exportNamesByVariable);
|
|
12281
12665
|
}
|
|
12282
12666
|
}
|
|
12283
|
-
declare(kind) {
|
|
12667
|
+
declare(kind, destructuredInitPath, init) {
|
|
12284
12668
|
const variables = [];
|
|
12669
|
+
const includedPatternPath = getIncludedPatternPath(destructuredInitPath);
|
|
12285
12670
|
for (const element of this.elements) {
|
|
12286
12671
|
if (element !== null) {
|
|
12287
|
-
variables.push(...element.declare(kind,
|
|
12672
|
+
variables.push(...element.declare(kind, includedPatternPath, init));
|
|
12288
12673
|
}
|
|
12289
12674
|
}
|
|
12290
12675
|
return variables;
|
|
12291
12676
|
}
|
|
12677
|
+
deoptimizeAssignment(destructuredInitPath, init) {
|
|
12678
|
+
const includedPatternPath = getIncludedPatternPath(destructuredInitPath);
|
|
12679
|
+
for (const element of this.elements) {
|
|
12680
|
+
element?.deoptimizeAssignment(includedPatternPath, init);
|
|
12681
|
+
}
|
|
12682
|
+
}
|
|
12292
12683
|
// Patterns can only be deoptimized at the empty path at the moment
|
|
12293
12684
|
deoptimizePath() {
|
|
12294
12685
|
for (const element of this.elements) {
|
|
12295
12686
|
element?.deoptimizePath(EMPTY_PATH);
|
|
12296
12687
|
}
|
|
12297
12688
|
}
|
|
12689
|
+
hasEffectsWhenDestructuring(context, destructuredInitPath, init) {
|
|
12690
|
+
const includedPatternPath = getIncludedPatternPath(destructuredInitPath);
|
|
12691
|
+
for (const element of this.elements) {
|
|
12692
|
+
if (element?.hasEffectsWhenDestructuring(context, includedPatternPath, init)) {
|
|
12693
|
+
return true;
|
|
12694
|
+
}
|
|
12695
|
+
}
|
|
12696
|
+
return false;
|
|
12697
|
+
}
|
|
12298
12698
|
// Patterns are only checked at the empty path at the moment
|
|
12299
12699
|
hasEffectsOnInteractionAtPath(_path, interaction, context) {
|
|
12300
12700
|
for (const element of this.elements) {
|
|
@@ -12303,12 +12703,38 @@ class ArrayPattern extends NodeBase {
|
|
|
12303
12703
|
}
|
|
12304
12704
|
return false;
|
|
12305
12705
|
}
|
|
12706
|
+
includeDestructuredIfNecessary(context, destructuredInitPath, init) {
|
|
12707
|
+
let included = false;
|
|
12708
|
+
const includedPatternPath = getIncludedPatternPath(destructuredInitPath);
|
|
12709
|
+
for (const element of this.elements) {
|
|
12710
|
+
if (element) {
|
|
12711
|
+
element.included ||= included;
|
|
12712
|
+
included =
|
|
12713
|
+
element.includeDestructuredIfNecessary(context, includedPatternPath, init) || included;
|
|
12714
|
+
}
|
|
12715
|
+
}
|
|
12716
|
+
if (included) {
|
|
12717
|
+
// This is necessary so that if any pattern element is included, all are
|
|
12718
|
+
// included for proper deconflicting
|
|
12719
|
+
for (const element of this.elements) {
|
|
12720
|
+
if (element && !element.included) {
|
|
12721
|
+
element.included = true;
|
|
12722
|
+
element.includeDestructuredIfNecessary(context, includedPatternPath, init);
|
|
12723
|
+
}
|
|
12724
|
+
}
|
|
12725
|
+
}
|
|
12726
|
+
return (this.included ||= included);
|
|
12727
|
+
}
|
|
12306
12728
|
markDeclarationReached() {
|
|
12307
12729
|
for (const element of this.elements) {
|
|
12308
12730
|
element?.markDeclarationReached();
|
|
12309
12731
|
}
|
|
12310
12732
|
}
|
|
12311
12733
|
}
|
|
12734
|
+
ArrayPattern.prototype.includeNode = onlyIncludeSelf;
|
|
12735
|
+
const getIncludedPatternPath = (destructuredInitPath) => destructuredInitPath.at(-1) === UnknownKey
|
|
12736
|
+
? destructuredInitPath
|
|
12737
|
+
: [...destructuredInitPath, UnknownInteger];
|
|
12312
12738
|
|
|
12313
12739
|
class ArrowFunctionExpression extends FunctionBase {
|
|
12314
12740
|
constructor() {
|
|
@@ -12325,17 +12751,17 @@ class ArrowFunctionExpression extends FunctionBase {
|
|
|
12325
12751
|
this.scope = new ReturnValueScope(parentScope, false);
|
|
12326
12752
|
}
|
|
12327
12753
|
hasEffects() {
|
|
12328
|
-
if (!this.deoptimized)
|
|
12329
|
-
this.applyDeoptimizations();
|
|
12330
12754
|
return false;
|
|
12331
12755
|
}
|
|
12332
12756
|
hasEffectsOnInteractionAtPath(path, interaction, context) {
|
|
12757
|
+
if (this.annotationNoSideEffects &&
|
|
12758
|
+
path.length === 0 &&
|
|
12759
|
+
interaction.type === INTERACTION_CALLED) {
|
|
12760
|
+
return false;
|
|
12761
|
+
}
|
|
12333
12762
|
if (super.hasEffectsOnInteractionAtPath(path, interaction, context)) {
|
|
12334
12763
|
return true;
|
|
12335
12764
|
}
|
|
12336
|
-
if (this.annotationNoSideEffects) {
|
|
12337
|
-
return false;
|
|
12338
|
-
}
|
|
12339
12765
|
if (interaction.type === INTERACTION_CALLED) {
|
|
12340
12766
|
const { ignore, brokenFlow } = context;
|
|
12341
12767
|
context.ignore = {
|
|
@@ -12365,6 +12791,15 @@ class ArrowFunctionExpression extends FunctionBase {
|
|
|
12365
12791
|
}
|
|
12366
12792
|
}
|
|
12367
12793
|
}
|
|
12794
|
+
includeNode(context) {
|
|
12795
|
+
this.included = true;
|
|
12796
|
+
this.body.includePath(UNKNOWN_PATH, context);
|
|
12797
|
+
for (const parameter of this.params) {
|
|
12798
|
+
if (!(parameter instanceof Identifier)) {
|
|
12799
|
+
parameter.includePath(UNKNOWN_PATH, context);
|
|
12800
|
+
}
|
|
12801
|
+
}
|
|
12802
|
+
}
|
|
12368
12803
|
getObjectEntity() {
|
|
12369
12804
|
if (this.objectEntity !== null) {
|
|
12370
12805
|
return this.objectEntity;
|
|
@@ -12384,13 +12819,18 @@ class ObjectPattern extends NodeBase {
|
|
|
12384
12819
|
}
|
|
12385
12820
|
}
|
|
12386
12821
|
}
|
|
12387
|
-
declare(kind, init) {
|
|
12822
|
+
declare(kind, destructuredInitPath, init) {
|
|
12388
12823
|
const variables = [];
|
|
12389
12824
|
for (const property of this.properties) {
|
|
12390
|
-
variables.push(...property.declare(kind, init));
|
|
12825
|
+
variables.push(...property.declare(kind, destructuredInitPath, init));
|
|
12391
12826
|
}
|
|
12392
12827
|
return variables;
|
|
12393
12828
|
}
|
|
12829
|
+
deoptimizeAssignment(destructuredInitPath, init) {
|
|
12830
|
+
for (const property of this.properties) {
|
|
12831
|
+
property.deoptimizeAssignment(destructuredInitPath, init);
|
|
12832
|
+
}
|
|
12833
|
+
}
|
|
12394
12834
|
deoptimizePath(path) {
|
|
12395
12835
|
if (path.length === 0) {
|
|
12396
12836
|
for (const property of this.properties) {
|
|
@@ -12408,12 +12848,46 @@ class ObjectPattern extends NodeBase {
|
|
|
12408
12848
|
}
|
|
12409
12849
|
return false;
|
|
12410
12850
|
}
|
|
12851
|
+
hasEffectsWhenDestructuring(context, destructuredInitPath, init) {
|
|
12852
|
+
for (const property of this.properties) {
|
|
12853
|
+
if (property.hasEffectsWhenDestructuring(context, destructuredInitPath, init))
|
|
12854
|
+
return true;
|
|
12855
|
+
}
|
|
12856
|
+
return false;
|
|
12857
|
+
}
|
|
12858
|
+
includeDestructuredIfNecessary(context, destructuredInitPath, init) {
|
|
12859
|
+
let included = false;
|
|
12860
|
+
for (const property of this.properties) {
|
|
12861
|
+
included =
|
|
12862
|
+
property.includeDestructuredIfNecessary(context, destructuredInitPath, init) || included;
|
|
12863
|
+
}
|
|
12864
|
+
return (this.included ||= included);
|
|
12865
|
+
}
|
|
12411
12866
|
markDeclarationReached() {
|
|
12412
12867
|
for (const property of this.properties) {
|
|
12413
12868
|
property.markDeclarationReached();
|
|
12414
12869
|
}
|
|
12415
12870
|
}
|
|
12871
|
+
render(code, options) {
|
|
12872
|
+
if (this.properties.length > 0) {
|
|
12873
|
+
const separatedNodes = getCommaSeparatedNodesWithBoundaries(this.properties, code, this.start + 1, this.end - 1);
|
|
12874
|
+
let lastSeparatorPos = null;
|
|
12875
|
+
for (const { node, separator, start, end } of separatedNodes) {
|
|
12876
|
+
if (!node.included) {
|
|
12877
|
+
treeshakeNode(node, code, start, end);
|
|
12878
|
+
continue;
|
|
12879
|
+
}
|
|
12880
|
+
lastSeparatorPos = separator;
|
|
12881
|
+
node.render(code, options);
|
|
12882
|
+
}
|
|
12883
|
+
if (lastSeparatorPos) {
|
|
12884
|
+
code.remove(lastSeparatorPos, this.end - 1);
|
|
12885
|
+
}
|
|
12886
|
+
}
|
|
12887
|
+
}
|
|
12416
12888
|
}
|
|
12889
|
+
ObjectPattern.prototype.includeNode = onlyIncludeSelfNoDeoptimize;
|
|
12890
|
+
ObjectPattern.prototype.applyDeoptimizations = doNotDeoptimize;
|
|
12417
12891
|
|
|
12418
12892
|
class AssignmentExpression extends NodeBase {
|
|
12419
12893
|
hasEffects(context) {
|
|
@@ -12422,7 +12896,9 @@ class AssignmentExpression extends NodeBase {
|
|
|
12422
12896
|
this.applyDeoptimizations();
|
|
12423
12897
|
// MemberExpressions do not access the property before assignments if the
|
|
12424
12898
|
// operator is '='.
|
|
12425
|
-
return (right.hasEffects(context) ||
|
|
12899
|
+
return (right.hasEffects(context) ||
|
|
12900
|
+
left.hasEffectsAsAssignmentTarget(context, operator !== '=') ||
|
|
12901
|
+
this.left.hasEffectsWhenDestructuring?.(context, EMPTY_PATH, right));
|
|
12426
12902
|
}
|
|
12427
12903
|
hasEffectsOnInteractionAtPath(path, interaction, context) {
|
|
12428
12904
|
return this.right.hasEffectsOnInteractionAtPath(path, interaction, context);
|
|
@@ -12431,15 +12907,24 @@ class AssignmentExpression extends NodeBase {
|
|
|
12431
12907
|
const { deoptimized, left, right, operator } = this;
|
|
12432
12908
|
if (!deoptimized)
|
|
12433
12909
|
this.applyDeoptimizations();
|
|
12434
|
-
this.included
|
|
12910
|
+
if (!this.included)
|
|
12911
|
+
this.includeNode(context);
|
|
12912
|
+
const hasEffectsContext = createHasEffectsContext();
|
|
12435
12913
|
if (includeChildrenRecursively ||
|
|
12436
12914
|
operator !== '=' ||
|
|
12437
12915
|
left.included ||
|
|
12438
|
-
left.hasEffectsAsAssignmentTarget(
|
|
12916
|
+
left.hasEffectsAsAssignmentTarget(hasEffectsContext, false) ||
|
|
12917
|
+
left.hasEffectsWhenDestructuring?.(hasEffectsContext, EMPTY_PATH, right)) {
|
|
12439
12918
|
left.includeAsAssignmentTarget(context, includeChildrenRecursively, operator !== '=');
|
|
12440
12919
|
}
|
|
12441
12920
|
right.include(context, includeChildrenRecursively);
|
|
12442
12921
|
}
|
|
12922
|
+
includeNode(context) {
|
|
12923
|
+
this.included = true;
|
|
12924
|
+
if (!this.deoptimized)
|
|
12925
|
+
this.applyDeoptimizations();
|
|
12926
|
+
this.right.includePath(UNKNOWN_PATH, context);
|
|
12927
|
+
}
|
|
12443
12928
|
initialise() {
|
|
12444
12929
|
super.initialise();
|
|
12445
12930
|
if (this.left instanceof Identifier) {
|
|
@@ -12499,9 +12984,8 @@ class AssignmentExpression extends NodeBase {
|
|
|
12499
12984
|
}
|
|
12500
12985
|
}
|
|
12501
12986
|
applyDeoptimizations() {
|
|
12502
|
-
this.deoptimized = true;
|
|
12503
|
-
this.left.
|
|
12504
|
-
this.right.deoptimizePath(UNKNOWN_PATH);
|
|
12987
|
+
this.deoptimized = true;
|
|
12988
|
+
this.left.deoptimizeAssignment(EMPTY_PATH, this.right);
|
|
12505
12989
|
this.scope.context.requestTreeshakingPass();
|
|
12506
12990
|
}
|
|
12507
12991
|
}
|
|
@@ -12510,8 +12994,11 @@ class AssignmentPattern extends NodeBase {
|
|
|
12510
12994
|
addExportedVariables(variables, exportNamesByVariable) {
|
|
12511
12995
|
this.left.addExportedVariables(variables, exportNamesByVariable);
|
|
12512
12996
|
}
|
|
12513
|
-
declare(kind, init) {
|
|
12514
|
-
return this.left.declare(kind, init);
|
|
12997
|
+
declare(kind, destructuredInitPath, init) {
|
|
12998
|
+
return this.left.declare(kind, destructuredInitPath, init);
|
|
12999
|
+
}
|
|
13000
|
+
deoptimizeAssignment(destructuredInitPath, init) {
|
|
13001
|
+
this.left.deoptimizeAssignment(destructuredInitPath, init);
|
|
12515
13002
|
}
|
|
12516
13003
|
deoptimizePath(path) {
|
|
12517
13004
|
if (path.length === 0) {
|
|
@@ -12521,6 +13008,29 @@ class AssignmentPattern extends NodeBase {
|
|
|
12521
13008
|
hasEffectsOnInteractionAtPath(path, interaction, context) {
|
|
12522
13009
|
return (path.length > 0 || this.left.hasEffectsOnInteractionAtPath(EMPTY_PATH, interaction, context));
|
|
12523
13010
|
}
|
|
13011
|
+
hasEffectsWhenDestructuring(context, destructuredInitPath, init) {
|
|
13012
|
+
return this.left.hasEffectsWhenDestructuring(context, destructuredInitPath, init);
|
|
13013
|
+
}
|
|
13014
|
+
includeDestructuredIfNecessary(context, destructuredInitPath, init) {
|
|
13015
|
+
let included = this.left.includeDestructuredIfNecessary(context, destructuredInitPath, init) ||
|
|
13016
|
+
this.included;
|
|
13017
|
+
if ((included ||= this.right.shouldBeIncluded(context))) {
|
|
13018
|
+
this.right.include(context, false);
|
|
13019
|
+
if (!this.left.included) {
|
|
13020
|
+
this.left.included = true;
|
|
13021
|
+
// Unfortunately, we need to include the left side again now, so that
|
|
13022
|
+
// any declared variables are properly included.
|
|
13023
|
+
this.left.includeDestructuredIfNecessary(context, destructuredInitPath, init);
|
|
13024
|
+
}
|
|
13025
|
+
}
|
|
13026
|
+
return (this.included = included);
|
|
13027
|
+
}
|
|
13028
|
+
includeNode(context) {
|
|
13029
|
+
this.included = true;
|
|
13030
|
+
if (!this.deoptimized)
|
|
13031
|
+
this.applyDeoptimizations();
|
|
13032
|
+
this.right.includePath(UNKNOWN_PATH, context);
|
|
13033
|
+
}
|
|
12524
13034
|
markDeclarationReached() {
|
|
12525
13035
|
this.left.markDeclarationReached();
|
|
12526
13036
|
}
|
|
@@ -12543,22 +13053,34 @@ class AwaitExpression extends NodeBase {
|
|
|
12543
13053
|
return true;
|
|
12544
13054
|
}
|
|
12545
13055
|
include(context, includeChildrenRecursively) {
|
|
13056
|
+
if (!this.included)
|
|
13057
|
+
this.includeNode(context);
|
|
13058
|
+
this.argument.include(context, includeChildrenRecursively);
|
|
13059
|
+
}
|
|
13060
|
+
includeNode(context) {
|
|
13061
|
+
this.included = true;
|
|
12546
13062
|
if (!this.deoptimized)
|
|
12547
13063
|
this.applyDeoptimizations();
|
|
12548
|
-
if (!this.
|
|
12549
|
-
|
|
12550
|
-
|
|
12551
|
-
|
|
12552
|
-
|
|
12553
|
-
|
|
12554
|
-
|
|
12555
|
-
} while ((parent = parent.parent));
|
|
12556
|
-
this.scope.context.usesTopLevelAwait = true;
|
|
12557
|
-
}
|
|
13064
|
+
checkTopLevelAwait: if (!this.scope.context.usesTopLevelAwait) {
|
|
13065
|
+
let parent = this.parent;
|
|
13066
|
+
do {
|
|
13067
|
+
if (parent instanceof FunctionNode || parent instanceof ArrowFunctionExpression)
|
|
13068
|
+
break checkTopLevelAwait;
|
|
13069
|
+
} while ((parent = parent.parent));
|
|
13070
|
+
this.scope.context.usesTopLevelAwait = true;
|
|
12558
13071
|
}
|
|
12559
|
-
|
|
13072
|
+
// Thenables need to be included
|
|
13073
|
+
this.argument.includePath(THEN_PATH, context);
|
|
13074
|
+
}
|
|
13075
|
+
includePath(path, context) {
|
|
13076
|
+
if (!this.deoptimized)
|
|
13077
|
+
this.applyDeoptimizations();
|
|
13078
|
+
if (!this.included)
|
|
13079
|
+
this.includeNode(context);
|
|
13080
|
+
this.argument.includePath(path, context);
|
|
12560
13081
|
}
|
|
12561
13082
|
}
|
|
13083
|
+
const THEN_PATH = ['then'];
|
|
12562
13084
|
|
|
12563
13085
|
const binaryOperators = {
|
|
12564
13086
|
'!=': (left, right) => left != right,
|
|
@@ -12614,6 +13136,12 @@ class BinaryExpression extends NodeBase {
|
|
|
12614
13136
|
hasEffectsOnInteractionAtPath(path, { type }) {
|
|
12615
13137
|
return type !== INTERACTION_ACCESSED || path.length > 1;
|
|
12616
13138
|
}
|
|
13139
|
+
includeNode(context) {
|
|
13140
|
+
this.included = true;
|
|
13141
|
+
if (this.operator === 'in') {
|
|
13142
|
+
this.right.includePath(UNKNOWN_PATH, context);
|
|
13143
|
+
}
|
|
13144
|
+
}
|
|
12617
13145
|
removeAnnotations(code) {
|
|
12618
13146
|
this.left.removeAnnotations(code);
|
|
12619
13147
|
}
|
|
@@ -12622,6 +13150,7 @@ class BinaryExpression extends NodeBase {
|
|
|
12622
13150
|
this.right.render(code, options);
|
|
12623
13151
|
}
|
|
12624
13152
|
}
|
|
13153
|
+
BinaryExpression.prototype.applyDeoptimizations = doNotDeoptimize;
|
|
12625
13154
|
|
|
12626
13155
|
class BreakStatement extends NodeBase {
|
|
12627
13156
|
hasEffects(context) {
|
|
@@ -12641,7 +13170,7 @@ class BreakStatement extends NodeBase {
|
|
|
12641
13170
|
include(context) {
|
|
12642
13171
|
this.included = true;
|
|
12643
13172
|
if (this.label) {
|
|
12644
|
-
this.label.include();
|
|
13173
|
+
this.label.include(context);
|
|
12645
13174
|
context.includedLabels.add(this.label.name);
|
|
12646
13175
|
}
|
|
12647
13176
|
else {
|
|
@@ -12650,6 +13179,8 @@ class BreakStatement extends NodeBase {
|
|
|
12650
13179
|
context.brokenFlow = true;
|
|
12651
13180
|
}
|
|
12652
13181
|
}
|
|
13182
|
+
BreakStatement.prototype.includeNode = onlyIncludeSelfNoDeoptimize;
|
|
13183
|
+
BreakStatement.prototype.applyDeoptimizations = doNotDeoptimize;
|
|
12653
13184
|
|
|
12654
13185
|
function renderCallArguments(code, options, node) {
|
|
12655
13186
|
if (node.arguments.length > 0) {
|
|
@@ -12836,10 +13367,14 @@ class CallExpression extends CallExpressionBase {
|
|
|
12836
13367
|
this.callee.hasEffectsOnInteractionAtPath(EMPTY_PATH, this.interaction, context)));
|
|
12837
13368
|
}
|
|
12838
13369
|
include(context, includeChildrenRecursively) {
|
|
12839
|
-
if (!this.
|
|
12840
|
-
this.
|
|
13370
|
+
if (!this.included)
|
|
13371
|
+
this.includeNode(context);
|
|
12841
13372
|
if (includeChildrenRecursively) {
|
|
12842
|
-
|
|
13373
|
+
this.callee.include(context, true);
|
|
13374
|
+
for (const argument of this.arguments) {
|
|
13375
|
+
argument.includePath(UNKNOWN_PATH, context);
|
|
13376
|
+
argument.include(context, true);
|
|
13377
|
+
}
|
|
12843
13378
|
if (includeChildrenRecursively === INCLUDE_PARAMETERS &&
|
|
12844
13379
|
this.callee instanceof Identifier &&
|
|
12845
13380
|
this.callee.variable) {
|
|
@@ -12847,10 +13382,24 @@ class CallExpression extends CallExpressionBase {
|
|
|
12847
13382
|
}
|
|
12848
13383
|
}
|
|
12849
13384
|
else {
|
|
12850
|
-
|
|
12851
|
-
|
|
13385
|
+
// If the callee is a member expression and does not have a variable, its
|
|
13386
|
+
// object will already be included via the first argument of the
|
|
13387
|
+
// interaction in includeCallArguments. Including it again can lead to
|
|
13388
|
+
// severe performance problems.
|
|
13389
|
+
if (this.callee instanceof MemberExpression && !this.callee.variable) {
|
|
13390
|
+
this.callee.property.include(context, false);
|
|
13391
|
+
}
|
|
13392
|
+
else {
|
|
13393
|
+
this.callee.include(context, false);
|
|
13394
|
+
}
|
|
13395
|
+
this.callee.includeCallArguments(context, this.interaction);
|
|
12852
13396
|
}
|
|
12853
|
-
|
|
13397
|
+
}
|
|
13398
|
+
includeNode(context) {
|
|
13399
|
+
this.included = true;
|
|
13400
|
+
if (!this.deoptimized)
|
|
13401
|
+
this.applyDeoptimizations();
|
|
13402
|
+
this.callee.includePath(UNKNOWN_PATH, context);
|
|
12854
13403
|
}
|
|
12855
13404
|
initialise() {
|
|
12856
13405
|
super.initialise();
|
|
@@ -12889,13 +13438,14 @@ class CatchClause extends NodeBase {
|
|
|
12889
13438
|
this.type = type;
|
|
12890
13439
|
if (param) {
|
|
12891
13440
|
this.param = new (this.scope.context.getNodeConstructor(param.type))(this, this.scope).parseNode(param);
|
|
12892
|
-
this.param.declare('parameter', UNKNOWN_EXPRESSION);
|
|
13441
|
+
this.param.declare('parameter', EMPTY_PATH, UNKNOWN_EXPRESSION);
|
|
12893
13442
|
}
|
|
12894
13443
|
this.body = new BlockStatement(this, this.scope.bodyScope).parseNode(body);
|
|
12895
13444
|
return super.parseNode(esTreeNode);
|
|
12896
13445
|
}
|
|
12897
13446
|
}
|
|
12898
13447
|
CatchClause.prototype.preventChildBlockScope = true;
|
|
13448
|
+
CatchClause.prototype.includeNode = onlyIncludeSelf;
|
|
12899
13449
|
|
|
12900
13450
|
class ChainExpression extends NodeBase {
|
|
12901
13451
|
// deoptimizations are not relevant as we are not caching values
|
|
@@ -12907,17 +13457,22 @@ class ChainExpression extends NodeBase {
|
|
|
12907
13457
|
hasEffects(context) {
|
|
12908
13458
|
return this.expression.hasEffectsAsChainElement(context) === true;
|
|
12909
13459
|
}
|
|
13460
|
+
includePath(path, context) {
|
|
13461
|
+
this.included = true;
|
|
13462
|
+
this.expression.includePath(path, context);
|
|
13463
|
+
}
|
|
12910
13464
|
removeAnnotations(code) {
|
|
12911
13465
|
this.expression.removeAnnotations(code);
|
|
12912
13466
|
}
|
|
12913
|
-
applyDeoptimizations() { }
|
|
12914
13467
|
}
|
|
13468
|
+
ChainExpression.prototype.includeNode = onlyIncludeSelfNoDeoptimize;
|
|
13469
|
+
ChainExpression.prototype.applyDeoptimizations = doNotDeoptimize;
|
|
12915
13470
|
|
|
12916
13471
|
class ClassBodyScope extends ChildScope {
|
|
12917
13472
|
constructor(parent, classNode) {
|
|
12918
13473
|
const { context } = parent;
|
|
12919
13474
|
super(parent, context);
|
|
12920
|
-
this.variables.set('this', (this.thisVariable = new LocalVariable('this', null, classNode, context, 'other')));
|
|
13475
|
+
this.variables.set('this', (this.thisVariable = new LocalVariable('this', null, classNode, EMPTY_PATH, context, 'other')));
|
|
12921
13476
|
this.instanceScope = new ChildScope(this, context);
|
|
12922
13477
|
this.instanceScope.variables.set('this', new ThisVariable(context));
|
|
12923
13478
|
}
|
|
@@ -12932,7 +13487,7 @@ class ClassBody extends NodeBase {
|
|
|
12932
13487
|
}
|
|
12933
13488
|
include(context, includeChildrenRecursively) {
|
|
12934
13489
|
this.included = true;
|
|
12935
|
-
this.scope.context.includeVariableInModule(this.scope.thisVariable);
|
|
13490
|
+
this.scope.context.includeVariableInModule(this.scope.thisVariable, UNKNOWN_PATH, context);
|
|
12936
13491
|
for (const definition of this.body) {
|
|
12937
13492
|
definition.include(context, includeChildrenRecursively);
|
|
12938
13493
|
}
|
|
@@ -12945,8 +13500,9 @@ class ClassBody extends NodeBase {
|
|
|
12945
13500
|
}
|
|
12946
13501
|
return super.parseNode(esTreeNode);
|
|
12947
13502
|
}
|
|
12948
|
-
applyDeoptimizations() { }
|
|
12949
13503
|
}
|
|
13504
|
+
ClassBody.prototype.includeNode = onlyIncludeSelfNoDeoptimize;
|
|
13505
|
+
ClassBody.prototype.applyDeoptimizations = doNotDeoptimize;
|
|
12950
13506
|
|
|
12951
13507
|
class ClassExpression extends ClassNode {
|
|
12952
13508
|
render(code, options, { renderedSurroundingElement } = parseAst_js.BLANK) {
|
|
@@ -13017,6 +13573,9 @@ class ConditionalExpression extends NodeBase {
|
|
|
13017
13573
|
const unusedBranch = this.usedBranch === this.consequent ? this.alternate : this.consequent;
|
|
13018
13574
|
this.usedBranch = null;
|
|
13019
13575
|
unusedBranch.deoptimizePath(UNKNOWN_PATH);
|
|
13576
|
+
if (this.included) {
|
|
13577
|
+
unusedBranch.includePath(UNKNOWN_PATH, createInclusionContext());
|
|
13578
|
+
}
|
|
13020
13579
|
const { expressionsToBeDeoptimized } = this;
|
|
13021
13580
|
this.expressionsToBeDeoptimized = parseAst_js.EMPTY_ARRAY;
|
|
13022
13581
|
for (const expression of expressionsToBeDeoptimized) {
|
|
@@ -13074,7 +13633,7 @@ class ConditionalExpression extends NodeBase {
|
|
|
13074
13633
|
include(context, includeChildrenRecursively) {
|
|
13075
13634
|
this.included = true;
|
|
13076
13635
|
const usedBranch = this.getUsedBranch();
|
|
13077
|
-
if (includeChildrenRecursively || this.test.shouldBeIncluded(context)
|
|
13636
|
+
if (usedBranch === null || includeChildrenRecursively || this.test.shouldBeIncluded(context)) {
|
|
13078
13637
|
this.test.include(context, includeChildrenRecursively);
|
|
13079
13638
|
this.consequent.include(context, includeChildrenRecursively);
|
|
13080
13639
|
this.alternate.include(context, includeChildrenRecursively);
|
|
@@ -13083,27 +13642,38 @@ class ConditionalExpression extends NodeBase {
|
|
|
13083
13642
|
usedBranch.include(context, includeChildrenRecursively);
|
|
13084
13643
|
}
|
|
13085
13644
|
}
|
|
13086
|
-
|
|
13645
|
+
includePath(path, context) {
|
|
13646
|
+
this.included = true;
|
|
13647
|
+
const usedBranch = this.getUsedBranch();
|
|
13648
|
+
if (usedBranch === null || this.test.shouldBeIncluded(context)) {
|
|
13649
|
+
this.consequent.includePath(path, context);
|
|
13650
|
+
this.alternate.includePath(path, context);
|
|
13651
|
+
}
|
|
13652
|
+
else {
|
|
13653
|
+
usedBranch.includePath(path, context);
|
|
13654
|
+
}
|
|
13655
|
+
}
|
|
13656
|
+
includeCallArguments(context, interaction) {
|
|
13087
13657
|
const usedBranch = this.getUsedBranch();
|
|
13088
13658
|
if (usedBranch) {
|
|
13089
|
-
usedBranch.includeCallArguments(context,
|
|
13659
|
+
usedBranch.includeCallArguments(context, interaction);
|
|
13090
13660
|
}
|
|
13091
13661
|
else {
|
|
13092
|
-
this.consequent.includeCallArguments(context,
|
|
13093
|
-
this.alternate.includeCallArguments(context,
|
|
13662
|
+
this.consequent.includeCallArguments(context, interaction);
|
|
13663
|
+
this.alternate.includeCallArguments(context, interaction);
|
|
13094
13664
|
}
|
|
13095
13665
|
}
|
|
13096
13666
|
removeAnnotations(code) {
|
|
13097
13667
|
this.test.removeAnnotations(code);
|
|
13098
13668
|
}
|
|
13099
13669
|
render(code, options, { isCalleeOfRenderedParent, preventASI, renderedParentType, renderedSurroundingElement } = parseAst_js.BLANK) {
|
|
13100
|
-
const usedBranch = this.getUsedBranch();
|
|
13101
13670
|
if (this.test.included) {
|
|
13102
13671
|
this.test.render(code, options, { renderedSurroundingElement });
|
|
13103
13672
|
this.consequent.render(code, options);
|
|
13104
13673
|
this.alternate.render(code, options);
|
|
13105
13674
|
}
|
|
13106
13675
|
else {
|
|
13676
|
+
const usedBranch = this.getUsedBranch();
|
|
13107
13677
|
const colonPos = findFirstOccurrenceOutsideComment(code.original, ':', this.consequent.end);
|
|
13108
13678
|
const inclusionStart = findNonWhiteSpace(code.original, (this.consequent.included
|
|
13109
13679
|
? findFirstOccurrenceOutsideComment(code.original, '?', this.test.end)
|
|
@@ -13135,6 +13705,8 @@ class ConditionalExpression extends NodeBase {
|
|
|
13135
13705
|
: (this.usedBranch = testValue ? this.consequent : this.alternate);
|
|
13136
13706
|
}
|
|
13137
13707
|
}
|
|
13708
|
+
ConditionalExpression.prototype.includeNode = onlyIncludeSelfNoDeoptimize;
|
|
13709
|
+
ConditionalExpression.prototype.applyDeoptimizations = doNotDeoptimize;
|
|
13138
13710
|
|
|
13139
13711
|
class ContinueStatement extends NodeBase {
|
|
13140
13712
|
hasEffects(context) {
|
|
@@ -13154,7 +13726,7 @@ class ContinueStatement extends NodeBase {
|
|
|
13154
13726
|
include(context) {
|
|
13155
13727
|
this.included = true;
|
|
13156
13728
|
if (this.label) {
|
|
13157
|
-
this.label.include();
|
|
13729
|
+
this.label.include(context);
|
|
13158
13730
|
context.includedLabels.add(this.label.name);
|
|
13159
13731
|
}
|
|
13160
13732
|
else {
|
|
@@ -13163,12 +13735,15 @@ class ContinueStatement extends NodeBase {
|
|
|
13163
13735
|
context.brokenFlow = true;
|
|
13164
13736
|
}
|
|
13165
13737
|
}
|
|
13738
|
+
ContinueStatement.prototype.includeNode = onlyIncludeSelfNoDeoptimize;
|
|
13739
|
+
ContinueStatement.prototype.applyDeoptimizations = doNotDeoptimize;
|
|
13166
13740
|
|
|
13167
13741
|
class DebuggerStatement extends NodeBase {
|
|
13168
13742
|
hasEffects() {
|
|
13169
13743
|
return true;
|
|
13170
13744
|
}
|
|
13171
13745
|
}
|
|
13746
|
+
DebuggerStatement.prototype.includeNode = onlyIncludeSelf;
|
|
13172
13747
|
|
|
13173
13748
|
class Decorator extends NodeBase {
|
|
13174
13749
|
hasEffects(context) {
|
|
@@ -13176,6 +13751,7 @@ class Decorator extends NodeBase {
|
|
|
13176
13751
|
this.expression.hasEffectsOnInteractionAtPath(EMPTY_PATH, NODE_INTERACTION_UNKNOWN_CALL, context));
|
|
13177
13752
|
}
|
|
13178
13753
|
}
|
|
13754
|
+
Decorator.prototype.includeNode = onlyIncludeSelf;
|
|
13179
13755
|
|
|
13180
13756
|
function hasLoopBodyEffects(context, body) {
|
|
13181
13757
|
const { brokenFlow, hasBreak, hasContinue, ignore } = context;
|
|
@@ -13215,12 +13791,15 @@ class DoWhileStatement extends NodeBase {
|
|
|
13215
13791
|
includeLoopBody(context, this.body, includeChildrenRecursively);
|
|
13216
13792
|
}
|
|
13217
13793
|
}
|
|
13794
|
+
DoWhileStatement.prototype.includeNode = onlyIncludeSelfNoDeoptimize;
|
|
13795
|
+
DoWhileStatement.prototype.applyDeoptimizations = doNotDeoptimize;
|
|
13218
13796
|
|
|
13219
13797
|
class EmptyStatement extends NodeBase {
|
|
13220
13798
|
hasEffects() {
|
|
13221
13799
|
return false;
|
|
13222
13800
|
}
|
|
13223
13801
|
}
|
|
13802
|
+
EmptyStatement.prototype.includeNode = onlyIncludeSelf;
|
|
13224
13803
|
|
|
13225
13804
|
class ExportAllDeclaration extends NodeBase {
|
|
13226
13805
|
hasEffects() {
|
|
@@ -13233,9 +13812,10 @@ class ExportAllDeclaration extends NodeBase {
|
|
|
13233
13812
|
render(code, _options, nodeRenderOptions) {
|
|
13234
13813
|
code.remove(nodeRenderOptions.start, nodeRenderOptions.end);
|
|
13235
13814
|
}
|
|
13236
|
-
applyDeoptimizations() { }
|
|
13237
13815
|
}
|
|
13238
13816
|
ExportAllDeclaration.prototype.needsBoundaries = true;
|
|
13817
|
+
ExportAllDeclaration.prototype.includeNode = onlyIncludeSelfNoDeoptimize;
|
|
13818
|
+
ExportAllDeclaration.prototype.applyDeoptimizations = doNotDeoptimize;
|
|
13239
13819
|
|
|
13240
13820
|
class ExportNamedDeclaration extends NodeBase {
|
|
13241
13821
|
bind() {
|
|
@@ -13262,13 +13842,15 @@ class ExportNamedDeclaration extends NodeBase {
|
|
|
13262
13842
|
this.declaration.render(code, options, { end, start });
|
|
13263
13843
|
}
|
|
13264
13844
|
}
|
|
13265
|
-
applyDeoptimizations() { }
|
|
13266
13845
|
}
|
|
13267
13846
|
ExportNamedDeclaration.prototype.needsBoundaries = true;
|
|
13847
|
+
ExportNamedDeclaration.prototype.includeNode = onlyIncludeSelfNoDeoptimize;
|
|
13848
|
+
ExportNamedDeclaration.prototype.applyDeoptimizations = doNotDeoptimize;
|
|
13268
13849
|
|
|
13269
13850
|
class ExportSpecifier extends NodeBase {
|
|
13270
|
-
applyDeoptimizations() { }
|
|
13271
13851
|
}
|
|
13852
|
+
ExportSpecifier.prototype.includeNode = onlyIncludeSelfNoDeoptimize;
|
|
13853
|
+
ExportSpecifier.prototype.applyDeoptimizations = doNotDeoptimize;
|
|
13272
13854
|
|
|
13273
13855
|
class ForInStatement extends NodeBase {
|
|
13274
13856
|
createScope(parentScope) {
|
|
@@ -13286,11 +13868,18 @@ class ForInStatement extends NodeBase {
|
|
|
13286
13868
|
const { body, deoptimized, left, right } = this;
|
|
13287
13869
|
if (!deoptimized)
|
|
13288
13870
|
this.applyDeoptimizations();
|
|
13289
|
-
this.included
|
|
13871
|
+
if (!this.included)
|
|
13872
|
+
this.includeNode(context);
|
|
13290
13873
|
left.includeAsAssignmentTarget(context, includeChildrenRecursively || true, false);
|
|
13291
13874
|
right.include(context, includeChildrenRecursively);
|
|
13292
13875
|
includeLoopBody(context, body, includeChildrenRecursively);
|
|
13293
13876
|
}
|
|
13877
|
+
includeNode(context) {
|
|
13878
|
+
this.included = true;
|
|
13879
|
+
if (!this.deoptimized)
|
|
13880
|
+
this.applyDeoptimizations();
|
|
13881
|
+
this.right.includePath(UNKNOWN_PATH, context);
|
|
13882
|
+
}
|
|
13294
13883
|
initialise() {
|
|
13295
13884
|
super.initialise();
|
|
13296
13885
|
this.left.setAssignedValue(UNKNOWN_EXPRESSION);
|
|
@@ -13331,11 +13920,18 @@ class ForOfStatement extends NodeBase {
|
|
|
13331
13920
|
const { body, deoptimized, left, right } = this;
|
|
13332
13921
|
if (!deoptimized)
|
|
13333
13922
|
this.applyDeoptimizations();
|
|
13334
|
-
this.included
|
|
13923
|
+
if (!this.included)
|
|
13924
|
+
this.includeNode(context);
|
|
13335
13925
|
left.includeAsAssignmentTarget(context, includeChildrenRecursively || true, false);
|
|
13336
13926
|
right.include(context, includeChildrenRecursively);
|
|
13337
13927
|
includeLoopBody(context, body, includeChildrenRecursively);
|
|
13338
13928
|
}
|
|
13929
|
+
includeNode(context) {
|
|
13930
|
+
this.included = true;
|
|
13931
|
+
if (!this.deoptimized)
|
|
13932
|
+
this.applyDeoptimizations();
|
|
13933
|
+
this.right.includePath(UNKNOWN_PATH, context);
|
|
13934
|
+
}
|
|
13339
13935
|
initialise() {
|
|
13340
13936
|
super.initialise();
|
|
13341
13937
|
this.left.setAssignedValue(UNKNOWN_EXPRESSION);
|
|
@@ -13371,7 +13967,9 @@ class ForStatement extends NodeBase {
|
|
|
13371
13967
|
}
|
|
13372
13968
|
include(context, includeChildrenRecursively) {
|
|
13373
13969
|
this.included = true;
|
|
13374
|
-
this.init?.include(context, includeChildrenRecursively, {
|
|
13970
|
+
this.init?.include(context, includeChildrenRecursively, {
|
|
13971
|
+
asSingleStatement: true
|
|
13972
|
+
});
|
|
13375
13973
|
this.test?.include(context, includeChildrenRecursively);
|
|
13376
13974
|
this.update?.include(context, includeChildrenRecursively);
|
|
13377
13975
|
includeLoopBody(context, this.body, includeChildrenRecursively);
|
|
@@ -13383,6 +13981,8 @@ class ForStatement extends NodeBase {
|
|
|
13383
13981
|
this.body.render(code, options);
|
|
13384
13982
|
}
|
|
13385
13983
|
}
|
|
13984
|
+
ForStatement.prototype.includeNode = onlyIncludeSelfNoDeoptimize;
|
|
13985
|
+
ForStatement.prototype.applyDeoptimizations = doNotDeoptimize;
|
|
13386
13986
|
|
|
13387
13987
|
class FunctionExpression extends FunctionNode {
|
|
13388
13988
|
createScope(parentScope) {
|
|
@@ -13414,9 +14014,9 @@ class TrackingScope extends BlockScope {
|
|
|
13414
14014
|
super(...arguments);
|
|
13415
14015
|
this.hoistedDeclarations = [];
|
|
13416
14016
|
}
|
|
13417
|
-
addDeclaration(identifier, context, init, kind) {
|
|
14017
|
+
addDeclaration(identifier, context, init, destructuredInitPath, kind) {
|
|
13418
14018
|
this.hoistedDeclarations.push(identifier);
|
|
13419
|
-
return super.addDeclaration(identifier, context, init, kind);
|
|
14019
|
+
return super.addDeclaration(identifier, context, init, destructuredInitPath, kind);
|
|
13420
14020
|
}
|
|
13421
14021
|
}
|
|
13422
14022
|
|
|
@@ -13515,7 +14115,6 @@ class IfStatement extends NodeBase {
|
|
|
13515
14115
|
}
|
|
13516
14116
|
this.renderHoistedDeclarations(hoistedDeclarations, code, getPropertyAccess);
|
|
13517
14117
|
}
|
|
13518
|
-
applyDeoptimizations() { }
|
|
13519
14118
|
getTestValue() {
|
|
13520
14119
|
if (this.testValue === unset) {
|
|
13521
14120
|
return (this.testValue = tryCastLiteralValueToBoolean(this.test.getLiteralValueAtPath(EMPTY_PATH, SHARED_RECURSION_TRACKER, this)));
|
|
@@ -13584,6 +14183,8 @@ class IfStatement extends NodeBase {
|
|
|
13584
14183
|
return false;
|
|
13585
14184
|
}
|
|
13586
14185
|
}
|
|
14186
|
+
IfStatement.prototype.includeNode = onlyIncludeSelfNoDeoptimize;
|
|
14187
|
+
IfStatement.prototype.applyDeoptimizations = doNotDeoptimize;
|
|
13587
14188
|
|
|
13588
14189
|
class ImportAttribute extends NodeBase {
|
|
13589
14190
|
}
|
|
@@ -13601,13 +14202,15 @@ class ImportDeclaration extends NodeBase {
|
|
|
13601
14202
|
render(code, _options, nodeRenderOptions) {
|
|
13602
14203
|
code.remove(nodeRenderOptions.start, nodeRenderOptions.end);
|
|
13603
14204
|
}
|
|
13604
|
-
applyDeoptimizations() { }
|
|
13605
14205
|
}
|
|
13606
14206
|
ImportDeclaration.prototype.needsBoundaries = true;
|
|
14207
|
+
ImportDeclaration.prototype.includeNode = onlyIncludeSelfNoDeoptimize;
|
|
14208
|
+
ImportDeclaration.prototype.applyDeoptimizations = doNotDeoptimize;
|
|
13607
14209
|
|
|
13608
14210
|
class ImportDefaultSpecifier extends NodeBase {
|
|
13609
|
-
applyDeoptimizations() { }
|
|
13610
14211
|
}
|
|
14212
|
+
ImportDefaultSpecifier.prototype.includeNode = onlyIncludeSelfNoDeoptimize;
|
|
14213
|
+
ImportDefaultSpecifier.prototype.applyDeoptimizations = doNotDeoptimize;
|
|
13611
14214
|
|
|
13612
14215
|
function isReassignedExportsMember(variable, exportNamesByVariable) {
|
|
13613
14216
|
return (variable.renderBaseName !== null && exportNamesByVariable.has(variable) && variable.isReassigned);
|
|
@@ -13616,28 +14219,33 @@ function isReassignedExportsMember(variable, exportNamesByVariable) {
|
|
|
13616
14219
|
class VariableDeclarator extends NodeBase {
|
|
13617
14220
|
declareDeclarator(kind, isUsingDeclaration) {
|
|
13618
14221
|
this.isUsingDeclaration = isUsingDeclaration;
|
|
13619
|
-
this.id.declare(kind, this.init || UNDEFINED_EXPRESSION);
|
|
14222
|
+
this.id.declare(kind, EMPTY_PATH, this.init || UNDEFINED_EXPRESSION);
|
|
13620
14223
|
}
|
|
13621
14224
|
deoptimizePath(path) {
|
|
13622
14225
|
this.id.deoptimizePath(path);
|
|
13623
14226
|
}
|
|
13624
14227
|
hasEffects(context) {
|
|
13625
|
-
if (!this.deoptimized)
|
|
13626
|
-
this.applyDeoptimizations();
|
|
13627
14228
|
const initEffect = this.init?.hasEffects(context);
|
|
13628
14229
|
this.id.markDeclarationReached();
|
|
13629
|
-
return initEffect ||
|
|
14230
|
+
return (initEffect ||
|
|
14231
|
+
this.isUsingDeclaration ||
|
|
14232
|
+
this.id.hasEffects(context) ||
|
|
14233
|
+
(this.scope.context.options.treeshake
|
|
14234
|
+
.propertyReadSideEffects &&
|
|
14235
|
+
this.id.hasEffectsWhenDestructuring(context, EMPTY_PATH, this.init || UNDEFINED_EXPRESSION)));
|
|
13630
14236
|
}
|
|
13631
14237
|
include(context, includeChildrenRecursively) {
|
|
13632
|
-
const {
|
|
13633
|
-
if (!
|
|
13634
|
-
this.
|
|
13635
|
-
this.included = true;
|
|
14238
|
+
const { id, init } = this;
|
|
14239
|
+
if (!this.included)
|
|
14240
|
+
this.includeNode();
|
|
13636
14241
|
init?.include(context, includeChildrenRecursively);
|
|
13637
14242
|
id.markDeclarationReached();
|
|
13638
|
-
if (includeChildrenRecursively
|
|
14243
|
+
if (includeChildrenRecursively) {
|
|
13639
14244
|
id.include(context, includeChildrenRecursively);
|
|
13640
14245
|
}
|
|
14246
|
+
else {
|
|
14247
|
+
id.includeDestructuredIfNecessary(context, EMPTY_PATH, init || UNDEFINED_EXPRESSION);
|
|
14248
|
+
}
|
|
13641
14249
|
}
|
|
13642
14250
|
removeAnnotations(code) {
|
|
13643
14251
|
this.init?.removeAnnotations(code);
|
|
@@ -13667,8 +14275,8 @@ class VariableDeclarator extends NodeBase {
|
|
|
13667
14275
|
code.appendLeft(end, `${_}=${_}void 0`);
|
|
13668
14276
|
}
|
|
13669
14277
|
}
|
|
13670
|
-
|
|
13671
|
-
this.
|
|
14278
|
+
includeNode() {
|
|
14279
|
+
this.included = true;
|
|
13672
14280
|
const { id, init } = this;
|
|
13673
14281
|
if (init && id instanceof Identifier && init instanceof ClassExpression && !init.id) {
|
|
13674
14282
|
const { name, variable } = id;
|
|
@@ -13680,11 +14288,14 @@ class VariableDeclarator extends NodeBase {
|
|
|
13680
14288
|
}
|
|
13681
14289
|
}
|
|
13682
14290
|
}
|
|
14291
|
+
VariableDeclarator.prototype.applyDeoptimizations = doNotDeoptimize;
|
|
13683
14292
|
|
|
13684
14293
|
class ImportExpression extends NodeBase {
|
|
13685
14294
|
constructor() {
|
|
13686
14295
|
super(...arguments);
|
|
13687
14296
|
this.inlineNamespace = null;
|
|
14297
|
+
this.hasUnknownAccessedKey = false;
|
|
14298
|
+
this.accessedPropKey = new Set();
|
|
13688
14299
|
this.attributes = null;
|
|
13689
14300
|
this.mechanism = null;
|
|
13690
14301
|
this.namespaceExportName = undefined;
|
|
@@ -13717,12 +14328,15 @@ class ImportExpression extends NodeBase {
|
|
|
13717
14328
|
if (parent2 instanceof ExpressionStatement) {
|
|
13718
14329
|
return parseAst_js.EMPTY_ARRAY;
|
|
13719
14330
|
}
|
|
13720
|
-
// Case 1: const { foo } = await import('bar')
|
|
14331
|
+
// Case 1: const { foo } / module = await import('bar')
|
|
13721
14332
|
if (parent2 instanceof VariableDeclarator) {
|
|
13722
14333
|
const declaration = parent2.id;
|
|
13723
|
-
|
|
13724
|
-
?
|
|
13725
|
-
|
|
14334
|
+
if (declaration instanceof Identifier) {
|
|
14335
|
+
return this.hasUnknownAccessedKey ? undefined : [...this.accessedPropKey];
|
|
14336
|
+
}
|
|
14337
|
+
if (declaration instanceof ObjectPattern) {
|
|
14338
|
+
return getDeterministicObjectDestructure(declaration);
|
|
14339
|
+
}
|
|
13726
14340
|
}
|
|
13727
14341
|
// Case 2: (await import('bar')).foo
|
|
13728
14342
|
if (parent2 instanceof MemberExpression) {
|
|
@@ -13772,13 +14386,30 @@ class ImportExpression extends NodeBase {
|
|
|
13772
14386
|
return true;
|
|
13773
14387
|
}
|
|
13774
14388
|
include(context, includeChildrenRecursively) {
|
|
13775
|
-
if (!this.included)
|
|
13776
|
-
this.
|
|
13777
|
-
this.scope.context.includeDynamicImport(this);
|
|
13778
|
-
this.scope.addAccessedDynamicImport(this);
|
|
13779
|
-
}
|
|
14389
|
+
if (!this.included)
|
|
14390
|
+
this.includeNode();
|
|
13780
14391
|
this.source.include(context, includeChildrenRecursively);
|
|
13781
14392
|
}
|
|
14393
|
+
includeNode() {
|
|
14394
|
+
this.included = true;
|
|
14395
|
+
this.scope.context.includeDynamicImport(this);
|
|
14396
|
+
this.scope.addAccessedDynamicImport(this);
|
|
14397
|
+
}
|
|
14398
|
+
includePath(path) {
|
|
14399
|
+
if (!this.included)
|
|
14400
|
+
this.includeNode();
|
|
14401
|
+
// Technically, this is not correct as dynamic imports return a Promise.
|
|
14402
|
+
if (this.hasUnknownAccessedKey)
|
|
14403
|
+
return;
|
|
14404
|
+
if (path[0] === UnknownKey) {
|
|
14405
|
+
this.hasUnknownAccessedKey = true;
|
|
14406
|
+
}
|
|
14407
|
+
else if (typeof path[0] === 'string') {
|
|
14408
|
+
this.accessedPropKey.add(path[0]);
|
|
14409
|
+
}
|
|
14410
|
+
// Update included paths
|
|
14411
|
+
this.scope.context.includeDynamicImport(this);
|
|
14412
|
+
}
|
|
13782
14413
|
initialise() {
|
|
13783
14414
|
super.initialise();
|
|
13784
14415
|
this.scope.context.addDynamicImport(this);
|
|
@@ -13847,7 +14478,6 @@ class ImportExpression extends NodeBase {
|
|
|
13847
14478
|
setInternalResolution(inlineNamespace) {
|
|
13848
14479
|
this.inlineNamespace = inlineNamespace;
|
|
13849
14480
|
}
|
|
13850
|
-
applyDeoptimizations() { }
|
|
13851
14481
|
getDynamicImportMechanismAndHelper(resolution, exportMode, { compact, dynamicImportInCjs, format, generatedCode: { arrowFunctions }, interop }, { _, getDirectReturnFunction, getDirectReturnIifeLeft }, pluginDriver) {
|
|
13852
14482
|
const mechanism = pluginDriver.hookFirstSync('renderDynamicImport', [
|
|
13853
14483
|
{
|
|
@@ -13937,6 +14567,7 @@ class ImportExpression extends NodeBase {
|
|
|
13937
14567
|
return { helper: null, mechanism: null };
|
|
13938
14568
|
}
|
|
13939
14569
|
}
|
|
14570
|
+
ImportExpression.prototype.applyDeoptimizations = doNotDeoptimize;
|
|
13940
14571
|
function getInteropHelper(resolution, exportMode, interop) {
|
|
13941
14572
|
return exportMode === 'external'
|
|
13942
14573
|
? namespaceInteropHelpersByInteropType[interop(resolution instanceof ExternalModule ? resolution.id : null)]
|
|
@@ -13960,12 +14591,14 @@ function getDeterministicObjectDestructure(objectPattern) {
|
|
|
13960
14591
|
}
|
|
13961
14592
|
|
|
13962
14593
|
class ImportNamespaceSpecifier extends NodeBase {
|
|
13963
|
-
applyDeoptimizations() { }
|
|
13964
14594
|
}
|
|
14595
|
+
ImportNamespaceSpecifier.prototype.includeNode = onlyIncludeSelfNoDeoptimize;
|
|
14596
|
+
ImportNamespaceSpecifier.prototype.applyDeoptimizations = doNotDeoptimize;
|
|
13965
14597
|
|
|
13966
14598
|
class ImportSpecifier extends NodeBase {
|
|
13967
|
-
applyDeoptimizations() { }
|
|
13968
14599
|
}
|
|
14600
|
+
ImportSpecifier.prototype.includeNode = onlyIncludeSelfNoDeoptimize;
|
|
14601
|
+
ImportSpecifier.prototype.applyDeoptimizations = doNotDeoptimize;
|
|
13969
14602
|
|
|
13970
14603
|
class JSXIdentifier extends IdentifierBase {
|
|
13971
14604
|
constructor() {
|
|
@@ -13982,6 +14615,29 @@ class JSXIdentifier extends IdentifierBase {
|
|
|
13982
14615
|
this.isNativeElement = true;
|
|
13983
14616
|
}
|
|
13984
14617
|
}
|
|
14618
|
+
include(context) {
|
|
14619
|
+
if (!this.included)
|
|
14620
|
+
this.includeNode(context);
|
|
14621
|
+
}
|
|
14622
|
+
includeNode(context) {
|
|
14623
|
+
this.included = true;
|
|
14624
|
+
if (!this.deoptimized)
|
|
14625
|
+
this.applyDeoptimizations();
|
|
14626
|
+
if (this.variable !== null) {
|
|
14627
|
+
this.scope.context.includeVariableInModule(this.variable, EMPTY_PATH, context);
|
|
14628
|
+
}
|
|
14629
|
+
}
|
|
14630
|
+
includePath(path, context) {
|
|
14631
|
+
if (!this.included) {
|
|
14632
|
+
this.included = true;
|
|
14633
|
+
if (this.variable !== null) {
|
|
14634
|
+
this.scope.context.includeVariableInModule(this.variable, path, context);
|
|
14635
|
+
}
|
|
14636
|
+
}
|
|
14637
|
+
else if (path.length > 0) {
|
|
14638
|
+
this.variable?.includePath(path, context);
|
|
14639
|
+
}
|
|
14640
|
+
}
|
|
13985
14641
|
render(code, { snippets: { getPropertyAccess }, useOriginalName }) {
|
|
13986
14642
|
if (this.variable) {
|
|
13987
14643
|
const name = this.variable.getName(getPropertyAccess, useOriginalName);
|
|
@@ -14043,6 +14699,7 @@ class JSXAttribute extends NodeBase {
|
|
|
14043
14699
|
}
|
|
14044
14700
|
}
|
|
14045
14701
|
}
|
|
14702
|
+
JSXAttribute.prototype.includeNode = onlyIncludeSelf;
|
|
14046
14703
|
|
|
14047
14704
|
class JSXClosingBase extends NodeBase {
|
|
14048
14705
|
render(code, options) {
|
|
@@ -14055,6 +14712,7 @@ class JSXClosingBase extends NodeBase {
|
|
|
14055
14712
|
}
|
|
14056
14713
|
}
|
|
14057
14714
|
}
|
|
14715
|
+
JSXClosingBase.prototype.includeNode = onlyIncludeSelf;
|
|
14058
14716
|
|
|
14059
14717
|
class JSXClosingElement extends JSXClosingBase {
|
|
14060
14718
|
}
|
|
@@ -14075,8 +14733,15 @@ class JSXSpreadAttribute extends NodeBase {
|
|
|
14075
14733
|
|
|
14076
14734
|
class JSXEmptyExpression extends NodeBase {
|
|
14077
14735
|
}
|
|
14736
|
+
JSXEmptyExpression.prototype.includeNode = onlyIncludeSelf;
|
|
14078
14737
|
|
|
14079
14738
|
class JSXExpressionContainer extends NodeBase {
|
|
14739
|
+
includeNode(context) {
|
|
14740
|
+
this.included = true;
|
|
14741
|
+
if (!this.deoptimized)
|
|
14742
|
+
this.applyDeoptimizations();
|
|
14743
|
+
this.expression.includePath(UNKNOWN_PATH, context);
|
|
14744
|
+
}
|
|
14080
14745
|
render(code, options) {
|
|
14081
14746
|
const { mode } = this.scope.context.options.jsx;
|
|
14082
14747
|
if (mode !== 'preserve') {
|
|
@@ -14097,7 +14762,7 @@ function getRenderedJsxChildren(children) {
|
|
|
14097
14762
|
return renderedChildren;
|
|
14098
14763
|
}
|
|
14099
14764
|
|
|
14100
|
-
function getAndIncludeFactoryVariable(factory, preserve, importSource, node) {
|
|
14765
|
+
function getAndIncludeFactoryVariable(factory, preserve, importSource, node, context) {
|
|
14101
14766
|
const [baseName, nestedName] = factory.split('.');
|
|
14102
14767
|
let factoryVariable;
|
|
14103
14768
|
if (importSource) {
|
|
@@ -14105,7 +14770,7 @@ function getAndIncludeFactoryVariable(factory, preserve, importSource, node) {
|
|
|
14105
14770
|
if (preserve) {
|
|
14106
14771
|
// This pretends we are accessing an included global variable of the same name
|
|
14107
14772
|
const globalVariable = node.scope.findGlobal(baseName);
|
|
14108
|
-
globalVariable.
|
|
14773
|
+
globalVariable.includePath(UNKNOWN_PATH, context);
|
|
14109
14774
|
// This excludes this variable from renaming
|
|
14110
14775
|
factoryVariable.globalName = baseName;
|
|
14111
14776
|
}
|
|
@@ -14113,7 +14778,7 @@ function getAndIncludeFactoryVariable(factory, preserve, importSource, node) {
|
|
|
14113
14778
|
else {
|
|
14114
14779
|
factoryVariable = node.scope.findGlobal(baseName);
|
|
14115
14780
|
}
|
|
14116
|
-
node.scope.context.includeVariableInModule(factoryVariable);
|
|
14781
|
+
node.scope.context.includeVariableInModule(factoryVariable, UNKNOWN_PATH, context);
|
|
14117
14782
|
if (factoryVariable instanceof LocalVariable) {
|
|
14118
14783
|
factoryVariable.consolidateInitializers();
|
|
14119
14784
|
factoryVariable.addUsedPlace(node);
|
|
@@ -14136,16 +14801,20 @@ class JSXElementBase extends NodeBase {
|
|
|
14136
14801
|
}
|
|
14137
14802
|
}
|
|
14138
14803
|
include(context, includeChildrenRecursively) {
|
|
14139
|
-
if (!this.included)
|
|
14140
|
-
|
|
14141
|
-
|
|
14142
|
-
|
|
14143
|
-
|
|
14144
|
-
|
|
14804
|
+
if (!this.included)
|
|
14805
|
+
this.includeNode(context);
|
|
14806
|
+
for (const child of this.children) {
|
|
14807
|
+
child.include(context, includeChildrenRecursively);
|
|
14808
|
+
}
|
|
14809
|
+
}
|
|
14810
|
+
includeNode(context) {
|
|
14811
|
+
this.included = true;
|
|
14812
|
+
const { factory, importSource, mode } = this.jsxMode;
|
|
14813
|
+
if (factory) {
|
|
14814
|
+
this.factory = factory;
|
|
14815
|
+
this.factoryVariable = getAndIncludeFactoryVariable(factory, mode === 'preserve', importSource, this, context);
|
|
14145
14816
|
}
|
|
14146
|
-
super.include(context, includeChildrenRecursively);
|
|
14147
14817
|
}
|
|
14148
|
-
applyDeoptimizations() { }
|
|
14149
14818
|
getRenderingMode() {
|
|
14150
14819
|
const jsx = this.scope.context.options.jsx;
|
|
14151
14820
|
const { mode, factory, importSource } = jsx;
|
|
@@ -14183,8 +14852,14 @@ class JSXElementBase extends NodeBase {
|
|
|
14183
14852
|
return { childrenEnd, firstChild, hasMultipleChildren };
|
|
14184
14853
|
}
|
|
14185
14854
|
}
|
|
14855
|
+
JSXElementBase.prototype.applyDeoptimizations = doNotDeoptimize;
|
|
14186
14856
|
|
|
14187
14857
|
class JSXElement extends JSXElementBase {
|
|
14858
|
+
include(context, includeChildrenRecursively) {
|
|
14859
|
+
super.include(context, includeChildrenRecursively);
|
|
14860
|
+
this.openingElement.include(context, includeChildrenRecursively);
|
|
14861
|
+
this.closingElement?.include(context, includeChildrenRecursively);
|
|
14862
|
+
}
|
|
14188
14863
|
render(code, options) {
|
|
14189
14864
|
switch (this.jsxMode.mode) {
|
|
14190
14865
|
case 'classic': {
|
|
@@ -14336,6 +15011,11 @@ class JSXElement extends JSXElementBase {
|
|
|
14336
15011
|
}
|
|
14337
15012
|
|
|
14338
15013
|
class JSXFragment extends JSXElementBase {
|
|
15014
|
+
include(context, includeChildrenRecursively) {
|
|
15015
|
+
super.include(context, includeChildrenRecursively);
|
|
15016
|
+
this.openingFragment.include(context, includeChildrenRecursively);
|
|
15017
|
+
this.closingFragment.include(context, includeChildrenRecursively);
|
|
15018
|
+
}
|
|
14339
15019
|
render(code, options) {
|
|
14340
15020
|
switch (this.jsxMode.mode) {
|
|
14341
15021
|
case 'classic': {
|
|
@@ -14385,10 +15065,22 @@ class JSXFragment extends JSXElementBase {
|
|
|
14385
15065
|
}
|
|
14386
15066
|
|
|
14387
15067
|
class JSXMemberExpression extends NodeBase {
|
|
15068
|
+
includeNode(context) {
|
|
15069
|
+
this.included = true;
|
|
15070
|
+
if (!this.deoptimized)
|
|
15071
|
+
this.applyDeoptimizations();
|
|
15072
|
+
this.object.includePath([this.property.name], context);
|
|
15073
|
+
}
|
|
15074
|
+
includePath(path, context) {
|
|
15075
|
+
if (!this.included)
|
|
15076
|
+
this.includeNode(context);
|
|
15077
|
+
this.object.includePath([this.property.name, ...path], context);
|
|
15078
|
+
}
|
|
14388
15079
|
}
|
|
14389
15080
|
|
|
14390
15081
|
class JSXNamespacedName extends NodeBase {
|
|
14391
15082
|
}
|
|
15083
|
+
JSXNamespacedName.prototype.includeNode = onlyIncludeSelf;
|
|
14392
15084
|
|
|
14393
15085
|
class JSXOpeningElement extends NodeBase {
|
|
14394
15086
|
render(code, options, { jsxMode = this.scope.context.options.jsx.mode } = {}) {
|
|
@@ -14398,6 +15090,7 @@ class JSXOpeningElement extends NodeBase {
|
|
|
14398
15090
|
}
|
|
14399
15091
|
}
|
|
14400
15092
|
}
|
|
15093
|
+
JSXOpeningElement.prototype.includeNode = onlyIncludeSelf;
|
|
14401
15094
|
|
|
14402
15095
|
class JSXOpeningFragment extends NodeBase {
|
|
14403
15096
|
constructor() {
|
|
@@ -14405,22 +15098,22 @@ class JSXOpeningFragment extends NodeBase {
|
|
|
14405
15098
|
this.fragment = null;
|
|
14406
15099
|
this.fragmentVariable = null;
|
|
14407
15100
|
}
|
|
14408
|
-
|
|
14409
|
-
|
|
14410
|
-
|
|
14411
|
-
|
|
14412
|
-
|
|
14413
|
-
|
|
14414
|
-
|
|
14415
|
-
|
|
14416
|
-
|
|
14417
|
-
|
|
14418
|
-
|
|
14419
|
-
|
|
14420
|
-
|
|
15101
|
+
includeNode(context) {
|
|
15102
|
+
this.included = true;
|
|
15103
|
+
if (!this.deoptimized)
|
|
15104
|
+
this.applyDeoptimizations();
|
|
15105
|
+
const jsx = this.scope.context.options.jsx;
|
|
15106
|
+
if (jsx.mode === 'automatic') {
|
|
15107
|
+
this.fragment = 'Fragment';
|
|
15108
|
+
this.fragmentVariable = getAndIncludeFactoryVariable('Fragment', false, jsx.jsxImportSource, this, context);
|
|
15109
|
+
}
|
|
15110
|
+
else {
|
|
15111
|
+
const { fragment, importSource, mode } = jsx;
|
|
15112
|
+
if (fragment != null) {
|
|
15113
|
+
this.fragment = fragment;
|
|
15114
|
+
this.fragmentVariable = getAndIncludeFactoryVariable(fragment, mode === 'preserve', importSource, this, context);
|
|
14421
15115
|
}
|
|
14422
15116
|
}
|
|
14423
|
-
super.include(context, includeChildrenRecursively);
|
|
14424
15117
|
}
|
|
14425
15118
|
render(code, options) {
|
|
14426
15119
|
const { mode } = this.scope.context.options.jsx;
|
|
@@ -14457,6 +15150,7 @@ class JSXText extends NodeBase {
|
|
|
14457
15150
|
}
|
|
14458
15151
|
}
|
|
14459
15152
|
}
|
|
15153
|
+
JSXText.prototype.includeNode = onlyIncludeSelf;
|
|
14460
15154
|
|
|
14461
15155
|
class LabeledStatement extends NodeBase {
|
|
14462
15156
|
hasEffects(context) {
|
|
@@ -14478,17 +15172,22 @@ class LabeledStatement extends NodeBase {
|
|
|
14478
15172
|
return bodyHasEffects;
|
|
14479
15173
|
}
|
|
14480
15174
|
include(context, includeChildrenRecursively) {
|
|
14481
|
-
this.included
|
|
15175
|
+
if (!this.included)
|
|
15176
|
+
this.includeNode(context);
|
|
14482
15177
|
const { brokenFlow, includedLabels } = context;
|
|
14483
15178
|
context.includedLabels = new Set();
|
|
14484
15179
|
this.body.include(context, includeChildrenRecursively);
|
|
14485
15180
|
if (includeChildrenRecursively || context.includedLabels.has(this.label.name)) {
|
|
14486
|
-
this.label.include();
|
|
15181
|
+
this.label.include(context);
|
|
14487
15182
|
context.includedLabels.delete(this.label.name);
|
|
14488
15183
|
context.brokenFlow = brokenFlow;
|
|
14489
15184
|
}
|
|
14490
15185
|
context.includedLabels = new Set([...includedLabels, ...context.includedLabels]);
|
|
14491
15186
|
}
|
|
15187
|
+
includeNode(context) {
|
|
15188
|
+
this.included = true;
|
|
15189
|
+
this.body.includePath(UNKNOWN_PATH, context);
|
|
15190
|
+
}
|
|
14492
15191
|
render(code, options) {
|
|
14493
15192
|
if (this.label.included) {
|
|
14494
15193
|
this.label.render(code, options);
|
|
@@ -14499,6 +15198,7 @@ class LabeledStatement extends NodeBase {
|
|
|
14499
15198
|
this.body.render(code, options);
|
|
14500
15199
|
}
|
|
14501
15200
|
}
|
|
15201
|
+
LabeledStatement.prototype.applyDeoptimizations = doNotDeoptimize;
|
|
14502
15202
|
|
|
14503
15203
|
class LogicalExpression extends NodeBase {
|
|
14504
15204
|
constructor() {
|
|
@@ -14515,10 +15215,10 @@ class LogicalExpression extends NodeBase {
|
|
|
14515
15215
|
this.flags = setFlag(this.flags, 65536 /* Flag.isBranchResolutionAnalysed */, value);
|
|
14516
15216
|
}
|
|
14517
15217
|
get hasDeoptimizedCache() {
|
|
14518
|
-
return isFlagSet(this.flags,
|
|
15218
|
+
return isFlagSet(this.flags, 33554432 /* Flag.hasDeoptimizedCache */);
|
|
14519
15219
|
}
|
|
14520
15220
|
set hasDeoptimizedCache(value) {
|
|
14521
|
-
this.flags = setFlag(this.flags,
|
|
15221
|
+
this.flags = setFlag(this.flags, 33554432 /* Flag.hasDeoptimizedCache */, value);
|
|
14522
15222
|
}
|
|
14523
15223
|
deoptimizeArgumentsOnInteractionAtPath(interaction, path, recursionTracker) {
|
|
14524
15224
|
this.left.deoptimizeArgumentsOnInteractionAtPath(interaction, path, recursionTracker);
|
|
@@ -14527,10 +15227,15 @@ class LogicalExpression extends NodeBase {
|
|
|
14527
15227
|
deoptimizeCache() {
|
|
14528
15228
|
if (this.hasDeoptimizedCache)
|
|
14529
15229
|
return;
|
|
15230
|
+
this.hasDeoptimizedCache = true;
|
|
14530
15231
|
if (this.usedBranch) {
|
|
14531
15232
|
const unusedBranch = this.usedBranch === this.left ? this.right : this.left;
|
|
14532
15233
|
this.usedBranch = null;
|
|
14533
15234
|
unusedBranch.deoptimizePath(UNKNOWN_PATH);
|
|
15235
|
+
if (this.included) {
|
|
15236
|
+
// As we are not tracking inclusions, we just include everything
|
|
15237
|
+
unusedBranch.includePath(UNKNOWN_PATH, createInclusionContext());
|
|
15238
|
+
}
|
|
14534
15239
|
}
|
|
14535
15240
|
const { scope: { context }, expressionsToBeDeoptimized } = this;
|
|
14536
15241
|
this.expressionsToBeDeoptimized = parseAst_js.EMPTY_ARRAY;
|
|
@@ -14540,7 +15245,6 @@ class LogicalExpression extends NodeBase {
|
|
|
14540
15245
|
// Request another pass because we need to ensure "include" runs again if
|
|
14541
15246
|
// it is rendered
|
|
14542
15247
|
context.requestTreeshakingPass();
|
|
14543
|
-
this.hasDeoptimizedCache = true;
|
|
14544
15248
|
}
|
|
14545
15249
|
deoptimizePath(path) {
|
|
14546
15250
|
const usedBranch = this.getUsedBranch();
|
|
@@ -14576,16 +15280,17 @@ class LogicalExpression extends NodeBase {
|
|
|
14576
15280
|
}
|
|
14577
15281
|
getReturnExpressionWhenCalledAtPath(path, interaction, recursionTracker, origin) {
|
|
14578
15282
|
const usedBranch = this.getUsedBranch();
|
|
14579
|
-
if (
|
|
14580
|
-
|
|
14581
|
-
|
|
14582
|
-
|
|
14583
|
-
|
|
14584
|
-
|
|
14585
|
-
|
|
14586
|
-
|
|
14587
|
-
|
|
14588
|
-
|
|
15283
|
+
if (usedBranch) {
|
|
15284
|
+
this.expressionsToBeDeoptimized.push(origin);
|
|
15285
|
+
return usedBranch.getReturnExpressionWhenCalledAtPath(path, interaction, recursionTracker, origin);
|
|
15286
|
+
}
|
|
15287
|
+
return [
|
|
15288
|
+
new MultiExpression([
|
|
15289
|
+
this.left.getReturnExpressionWhenCalledAtPath(path, interaction, recursionTracker, origin)[0],
|
|
15290
|
+
this.right.getReturnExpressionWhenCalledAtPath(path, interaction, recursionTracker, origin)[0]
|
|
15291
|
+
]),
|
|
15292
|
+
false
|
|
15293
|
+
];
|
|
14589
15294
|
}
|
|
14590
15295
|
hasEffects(context) {
|
|
14591
15296
|
if (this.left.hasEffects(context)) {
|
|
@@ -14598,18 +15303,18 @@ class LogicalExpression extends NodeBase {
|
|
|
14598
15303
|
}
|
|
14599
15304
|
hasEffectsOnInteractionAtPath(path, interaction, context) {
|
|
14600
15305
|
const usedBranch = this.getUsedBranch();
|
|
14601
|
-
if (
|
|
14602
|
-
return
|
|
14603
|
-
this.right.hasEffectsOnInteractionAtPath(path, interaction, context));
|
|
15306
|
+
if (usedBranch) {
|
|
15307
|
+
return usedBranch.hasEffectsOnInteractionAtPath(path, interaction, context);
|
|
14604
15308
|
}
|
|
14605
|
-
return
|
|
15309
|
+
return (this.left.hasEffectsOnInteractionAtPath(path, interaction, context) ||
|
|
15310
|
+
this.right.hasEffectsOnInteractionAtPath(path, interaction, context));
|
|
14606
15311
|
}
|
|
14607
15312
|
include(context, includeChildrenRecursively) {
|
|
14608
15313
|
this.included = true;
|
|
14609
15314
|
const usedBranch = this.getUsedBranch();
|
|
14610
15315
|
if (includeChildrenRecursively ||
|
|
14611
|
-
|
|
14612
|
-
|
|
15316
|
+
!usedBranch ||
|
|
15317
|
+
(usedBranch === this.right && this.left.shouldBeIncluded(context))) {
|
|
14613
15318
|
this.left.include(context, includeChildrenRecursively);
|
|
14614
15319
|
this.right.include(context, includeChildrenRecursively);
|
|
14615
15320
|
}
|
|
@@ -14617,6 +15322,17 @@ class LogicalExpression extends NodeBase {
|
|
|
14617
15322
|
usedBranch.include(context, includeChildrenRecursively);
|
|
14618
15323
|
}
|
|
14619
15324
|
}
|
|
15325
|
+
includePath(path, context) {
|
|
15326
|
+
this.included = true;
|
|
15327
|
+
const usedBranch = this.getUsedBranch();
|
|
15328
|
+
if (!usedBranch || (usedBranch === this.right && this.left.shouldBeIncluded(context))) {
|
|
15329
|
+
this.left.includePath(path, context);
|
|
15330
|
+
this.right.includePath(path, context);
|
|
15331
|
+
}
|
|
15332
|
+
else {
|
|
15333
|
+
usedBranch.includePath(path, context);
|
|
15334
|
+
}
|
|
15335
|
+
}
|
|
14620
15336
|
removeAnnotations(code) {
|
|
14621
15337
|
this.left.removeAnnotations(code);
|
|
14622
15338
|
}
|
|
@@ -14669,6 +15385,8 @@ class LogicalExpression extends NodeBase {
|
|
|
14669
15385
|
return this.usedBranch;
|
|
14670
15386
|
}
|
|
14671
15387
|
}
|
|
15388
|
+
LogicalExpression.prototype.includeNode = onlyIncludeSelfNoDeoptimize;
|
|
15389
|
+
LogicalExpression.prototype.applyDeoptimizations = doNotDeoptimize;
|
|
14672
15390
|
|
|
14673
15391
|
class NewExpression extends NodeBase {
|
|
14674
15392
|
hasEffects(context) {
|
|
@@ -14688,16 +15406,21 @@ class NewExpression extends NodeBase {
|
|
|
14688
15406
|
return path.length > 0 || type !== INTERACTION_ACCESSED;
|
|
14689
15407
|
}
|
|
14690
15408
|
include(context, includeChildrenRecursively) {
|
|
14691
|
-
if (!this.deoptimized)
|
|
14692
|
-
this.applyDeoptimizations();
|
|
14693
15409
|
if (includeChildrenRecursively) {
|
|
14694
15410
|
super.include(context, includeChildrenRecursively);
|
|
14695
15411
|
}
|
|
14696
15412
|
else {
|
|
14697
|
-
this.included
|
|
15413
|
+
if (!this.included)
|
|
15414
|
+
this.includeNode(context);
|
|
14698
15415
|
this.callee.include(context, false);
|
|
14699
15416
|
}
|
|
14700
|
-
this.callee.includeCallArguments(context, this.
|
|
15417
|
+
this.callee.includeCallArguments(context, this.interaction);
|
|
15418
|
+
}
|
|
15419
|
+
includeNode(context) {
|
|
15420
|
+
this.included = true;
|
|
15421
|
+
if (!this.deoptimized)
|
|
15422
|
+
this.applyDeoptimizations();
|
|
15423
|
+
this.callee.includePath(UNKNOWN_PATH, context);
|
|
14701
15424
|
}
|
|
14702
15425
|
initialise() {
|
|
14703
15426
|
super.initialise();
|
|
@@ -14726,6 +15449,7 @@ class ObjectExpression extends NodeBase {
|
|
|
14726
15449
|
constructor() {
|
|
14727
15450
|
super(...arguments);
|
|
14728
15451
|
this.objectEntity = null;
|
|
15452
|
+
this.protoProp = null;
|
|
14729
15453
|
}
|
|
14730
15454
|
deoptimizeArgumentsOnInteractionAtPath(interaction, path, recursionTracker) {
|
|
14731
15455
|
this.getObjectEntity().deoptimizeArgumentsOnInteractionAtPath(interaction, path, recursionTracker);
|
|
@@ -14745,15 +15469,43 @@ class ObjectExpression extends NodeBase {
|
|
|
14745
15469
|
hasEffectsOnInteractionAtPath(path, interaction, context) {
|
|
14746
15470
|
return this.getObjectEntity().hasEffectsOnInteractionAtPath(path, interaction, context);
|
|
14747
15471
|
}
|
|
15472
|
+
include(context, includeChildrenRecursively) {
|
|
15473
|
+
if (!this.included)
|
|
15474
|
+
this.includeNode(context);
|
|
15475
|
+
this.getObjectEntity().include(context, includeChildrenRecursively);
|
|
15476
|
+
this.protoProp?.include(context, includeChildrenRecursively);
|
|
15477
|
+
}
|
|
15478
|
+
includeNode(context) {
|
|
15479
|
+
this.included = true;
|
|
15480
|
+
this.protoProp?.includePath(UNKNOWN_PATH, context);
|
|
15481
|
+
}
|
|
15482
|
+
includePath(path, context) {
|
|
15483
|
+
if (!this.included)
|
|
15484
|
+
this.includeNode(context);
|
|
15485
|
+
this.getObjectEntity().includePath(path, context);
|
|
15486
|
+
}
|
|
14748
15487
|
render(code, options, { renderedSurroundingElement } = parseAst_js.BLANK) {
|
|
14749
|
-
super.render(code, options);
|
|
14750
15488
|
if (renderedSurroundingElement === parseAst_js.ExpressionStatement ||
|
|
14751
15489
|
renderedSurroundingElement === parseAst_js.ArrowFunctionExpression) {
|
|
14752
15490
|
code.appendRight(this.start, '(');
|
|
14753
15491
|
code.prependLeft(this.end, ')');
|
|
14754
15492
|
}
|
|
15493
|
+
if (this.properties.length > 0) {
|
|
15494
|
+
const separatedNodes = getCommaSeparatedNodesWithBoundaries(this.properties, code, this.start + 1, this.end - 1);
|
|
15495
|
+
let lastSeparatorPos = null;
|
|
15496
|
+
for (const { node, separator, start, end } of separatedNodes) {
|
|
15497
|
+
if (!node.included) {
|
|
15498
|
+
treeshakeNode(node, code, start, end);
|
|
15499
|
+
continue;
|
|
15500
|
+
}
|
|
15501
|
+
lastSeparatorPos = separator;
|
|
15502
|
+
node.render(code, options);
|
|
15503
|
+
}
|
|
15504
|
+
if (lastSeparatorPos) {
|
|
15505
|
+
code.remove(lastSeparatorPos, this.end - 1);
|
|
15506
|
+
}
|
|
15507
|
+
}
|
|
14755
15508
|
}
|
|
14756
|
-
applyDeoptimizations() { }
|
|
14757
15509
|
getObjectEntity() {
|
|
14758
15510
|
if (this.objectEntity !== null) {
|
|
14759
15511
|
return this.objectEntity;
|
|
@@ -14782,6 +15534,7 @@ class ObjectExpression extends NodeBase {
|
|
|
14782
15534
|
? property.key.name
|
|
14783
15535
|
: String(property.key.value);
|
|
14784
15536
|
if (key === '__proto__' && property.kind === 'init') {
|
|
15537
|
+
this.protoProp = property;
|
|
14785
15538
|
prototype =
|
|
14786
15539
|
property.value instanceof Literal && property.value.value === null
|
|
14787
15540
|
? null
|
|
@@ -14794,6 +15547,7 @@ class ObjectExpression extends NodeBase {
|
|
|
14794
15547
|
return (this.objectEntity = new ObjectEntity(properties, prototype));
|
|
14795
15548
|
}
|
|
14796
15549
|
}
|
|
15550
|
+
ObjectExpression.prototype.applyDeoptimizations = doNotDeoptimize;
|
|
14797
15551
|
|
|
14798
15552
|
class PanicError extends NodeBase {
|
|
14799
15553
|
initialise() {
|
|
@@ -14820,6 +15574,7 @@ class ParseError extends NodeBase {
|
|
|
14820
15574
|
|
|
14821
15575
|
class PrivateIdentifier extends NodeBase {
|
|
14822
15576
|
}
|
|
15577
|
+
PrivateIdentifier.prototype.includeNode = onlyIncludeSelf;
|
|
14823
15578
|
|
|
14824
15579
|
class Program extends NodeBase {
|
|
14825
15580
|
constructor() {
|
|
@@ -14887,14 +15642,11 @@ class Program extends NodeBase {
|
|
|
14887
15642
|
super.render(code, options);
|
|
14888
15643
|
}
|
|
14889
15644
|
}
|
|
14890
|
-
applyDeoptimizations() { }
|
|
14891
15645
|
}
|
|
15646
|
+
Program.prototype.includeNode = onlyIncludeSelfNoDeoptimize;
|
|
15647
|
+
Program.prototype.applyDeoptimizations = doNotDeoptimize;
|
|
14892
15648
|
|
|
14893
15649
|
class Property extends MethodBase {
|
|
14894
|
-
constructor() {
|
|
14895
|
-
super(...arguments);
|
|
14896
|
-
this.declarationInit = null;
|
|
14897
|
-
}
|
|
14898
15650
|
//declare method: boolean;
|
|
14899
15651
|
get method() {
|
|
14900
15652
|
return isFlagSet(this.flags, 262144 /* Flag.method */);
|
|
@@ -14909,17 +15661,41 @@ class Property extends MethodBase {
|
|
|
14909
15661
|
set shorthand(value) {
|
|
14910
15662
|
this.flags = setFlag(this.flags, 524288 /* Flag.shorthand */, value);
|
|
14911
15663
|
}
|
|
14912
|
-
declare(kind, init) {
|
|
14913
|
-
this.
|
|
14914
|
-
|
|
15664
|
+
declare(kind, destructuredInitPath, init) {
|
|
15665
|
+
return this.value.declare(kind, this.getPathInProperty(destructuredInitPath), init);
|
|
15666
|
+
}
|
|
15667
|
+
deoptimizeAssignment(destructuredInitPath, init) {
|
|
15668
|
+
this.value.deoptimizeAssignment?.(this.getPathInProperty(destructuredInitPath), init);
|
|
14915
15669
|
}
|
|
14916
15670
|
hasEffects(context) {
|
|
14917
|
-
|
|
14918
|
-
|
|
14919
|
-
|
|
14920
|
-
return
|
|
14921
|
-
|
|
14922
|
-
|
|
15671
|
+
return this.key.hasEffects(context) || this.value.hasEffects(context);
|
|
15672
|
+
}
|
|
15673
|
+
hasEffectsWhenDestructuring(context, destructuredInitPath, init) {
|
|
15674
|
+
return this.value.hasEffectsWhenDestructuring?.(context, this.getPathInProperty(destructuredInitPath), init);
|
|
15675
|
+
}
|
|
15676
|
+
includeDestructuredIfNecessary(context, destructuredInitPath, init) {
|
|
15677
|
+
const path = this.getPathInProperty(destructuredInitPath);
|
|
15678
|
+
let included = this.value.includeDestructuredIfNecessary(context, path, init) ||
|
|
15679
|
+
this.included;
|
|
15680
|
+
if ((included ||= this.key.hasEffects(createHasEffectsContext()))) {
|
|
15681
|
+
this.key.include(context, false);
|
|
15682
|
+
if (!this.value.included) {
|
|
15683
|
+
this.value.included = true;
|
|
15684
|
+
// Unfortunately, we need to include the value again now, so that any
|
|
15685
|
+
// declared variables are properly included.
|
|
15686
|
+
this.value.includeDestructuredIfNecessary(context, path, init);
|
|
15687
|
+
}
|
|
15688
|
+
}
|
|
15689
|
+
return (this.included = included);
|
|
15690
|
+
}
|
|
15691
|
+
include(context, includeChildrenRecursively) {
|
|
15692
|
+
this.included = true;
|
|
15693
|
+
this.key.include(context, includeChildrenRecursively);
|
|
15694
|
+
this.value.include(context, includeChildrenRecursively);
|
|
15695
|
+
}
|
|
15696
|
+
includePath(path, context) {
|
|
15697
|
+
this.included = true;
|
|
15698
|
+
this.value.includePath(path, context);
|
|
14923
15699
|
}
|
|
14924
15700
|
markDeclarationReached() {
|
|
14925
15701
|
this.value.markDeclarationReached();
|
|
@@ -14930,14 +15706,20 @@ class Property extends MethodBase {
|
|
|
14930
15706
|
}
|
|
14931
15707
|
this.value.render(code, options, { isShorthandProperty: this.shorthand });
|
|
14932
15708
|
}
|
|
14933
|
-
|
|
14934
|
-
|
|
14935
|
-
|
|
14936
|
-
|
|
14937
|
-
|
|
14938
|
-
|
|
15709
|
+
getPathInProperty(destructuredInitPath) {
|
|
15710
|
+
return destructuredInitPath.at(-1) === UnknownKey
|
|
15711
|
+
? destructuredInitPath
|
|
15712
|
+
: // For now, we only consider static paths as we do not know how to
|
|
15713
|
+
// deoptimize the path in the dynamic case.
|
|
15714
|
+
this.computed
|
|
15715
|
+
? [...destructuredInitPath, UnknownKey]
|
|
15716
|
+
: this.key instanceof Identifier
|
|
15717
|
+
? [...destructuredInitPath, this.key.name]
|
|
15718
|
+
: [...destructuredInitPath, String(this.key.value)];
|
|
14939
15719
|
}
|
|
14940
15720
|
}
|
|
15721
|
+
Property.prototype.includeNode = onlyIncludeSelfNoDeoptimize;
|
|
15722
|
+
Property.prototype.applyDeoptimizations = doNotDeoptimize;
|
|
14941
15723
|
|
|
14942
15724
|
class PropertyDefinition extends NodeBase {
|
|
14943
15725
|
get computed() {
|
|
@@ -14970,8 +15752,15 @@ class PropertyDefinition extends NodeBase {
|
|
|
14970
15752
|
hasEffectsOnInteractionAtPath(path, interaction, context) {
|
|
14971
15753
|
return !this.value || this.value.hasEffectsOnInteractionAtPath(path, interaction, context);
|
|
14972
15754
|
}
|
|
14973
|
-
|
|
15755
|
+
includeNode(context) {
|
|
15756
|
+
this.included = true;
|
|
15757
|
+
this.value?.includePath(UNKNOWN_PATH, context);
|
|
15758
|
+
for (const decorator of this.decorators) {
|
|
15759
|
+
decorator.includePath(UNKNOWN_PATH, context);
|
|
15760
|
+
}
|
|
15761
|
+
}
|
|
14974
15762
|
}
|
|
15763
|
+
PropertyDefinition.prototype.applyDeoptimizations = doNotDeoptimize;
|
|
14975
15764
|
|
|
14976
15765
|
class ReturnStatement extends NodeBase {
|
|
14977
15766
|
hasEffects(context) {
|
|
@@ -14981,10 +15770,15 @@ class ReturnStatement extends NodeBase {
|
|
|
14981
15770
|
return false;
|
|
14982
15771
|
}
|
|
14983
15772
|
include(context, includeChildrenRecursively) {
|
|
14984
|
-
this.included
|
|
15773
|
+
if (!this.included)
|
|
15774
|
+
this.includeNode(context);
|
|
14985
15775
|
this.argument?.include(context, includeChildrenRecursively);
|
|
14986
15776
|
context.brokenFlow = true;
|
|
14987
15777
|
}
|
|
15778
|
+
includeNode(context) {
|
|
15779
|
+
this.included = true;
|
|
15780
|
+
this.argument?.includePath(UNKNOWN_PATH, context);
|
|
15781
|
+
}
|
|
14988
15782
|
initialise() {
|
|
14989
15783
|
super.initialise();
|
|
14990
15784
|
this.scope.addReturnExpression(this.argument || UNKNOWN_EXPRESSION);
|
|
@@ -14998,6 +15792,7 @@ class ReturnStatement extends NodeBase {
|
|
|
14998
15792
|
}
|
|
14999
15793
|
}
|
|
15000
15794
|
}
|
|
15795
|
+
ReturnStatement.prototype.applyDeoptimizations = doNotDeoptimize;
|
|
15001
15796
|
|
|
15002
15797
|
class SequenceExpression extends NodeBase {
|
|
15003
15798
|
deoptimizeArgumentsOnInteractionAtPath(interaction, path, recursionTracker) {
|
|
@@ -15025,10 +15820,15 @@ class SequenceExpression extends NodeBase {
|
|
|
15025
15820
|
for (const expression of this.expressions) {
|
|
15026
15821
|
if (includeChildrenRecursively ||
|
|
15027
15822
|
(expression === lastExpression && !(this.parent instanceof ExpressionStatement)) ||
|
|
15028
|
-
expression.shouldBeIncluded(context))
|
|
15823
|
+
expression.shouldBeIncluded(context)) {
|
|
15029
15824
|
expression.include(context, includeChildrenRecursively);
|
|
15825
|
+
}
|
|
15030
15826
|
}
|
|
15031
15827
|
}
|
|
15828
|
+
includePath(path, context) {
|
|
15829
|
+
this.included = true;
|
|
15830
|
+
this.expressions[this.expressions.length - 1].includePath(path, context);
|
|
15831
|
+
}
|
|
15032
15832
|
removeAnnotations(code) {
|
|
15033
15833
|
this.expressions[0].removeAnnotations(code);
|
|
15034
15834
|
}
|
|
@@ -15063,6 +15863,8 @@ class SequenceExpression extends NodeBase {
|
|
|
15063
15863
|
}
|
|
15064
15864
|
}
|
|
15065
15865
|
}
|
|
15866
|
+
SequenceExpression.prototype.includeNode = onlyIncludeSelfNoDeoptimize;
|
|
15867
|
+
SequenceExpression.prototype.applyDeoptimizations = doNotDeoptimize;
|
|
15066
15868
|
|
|
15067
15869
|
class Super extends NodeBase {
|
|
15068
15870
|
bind() {
|
|
@@ -15074,11 +15876,15 @@ class Super extends NodeBase {
|
|
|
15074
15876
|
deoptimizePath(path) {
|
|
15075
15877
|
this.variable.deoptimizePath(path);
|
|
15076
15878
|
}
|
|
15077
|
-
include() {
|
|
15078
|
-
if (!this.included)
|
|
15079
|
-
this.
|
|
15080
|
-
|
|
15081
|
-
|
|
15879
|
+
include(context) {
|
|
15880
|
+
if (!this.included)
|
|
15881
|
+
this.includeNode(context);
|
|
15882
|
+
}
|
|
15883
|
+
includeNode(context) {
|
|
15884
|
+
this.included = true;
|
|
15885
|
+
if (!this.deoptimized)
|
|
15886
|
+
this.applyDeoptimizations();
|
|
15887
|
+
this.scope.context.includeVariableInModule(this.variable, EMPTY_PATH, context);
|
|
15082
15888
|
}
|
|
15083
15889
|
}
|
|
15084
15890
|
|
|
@@ -15119,6 +15925,8 @@ class SwitchCase extends NodeBase {
|
|
|
15119
15925
|
}
|
|
15120
15926
|
}
|
|
15121
15927
|
SwitchCase.prototype.needsBoundaries = true;
|
|
15928
|
+
SwitchCase.prototype.includeNode = onlyIncludeSelfNoDeoptimize;
|
|
15929
|
+
SwitchCase.prototype.applyDeoptimizations = doNotDeoptimize;
|
|
15122
15930
|
|
|
15123
15931
|
class SwitchStatement extends NodeBase {
|
|
15124
15932
|
createScope(parentScope) {
|
|
@@ -15201,6 +16009,8 @@ class SwitchStatement extends NodeBase {
|
|
|
15201
16009
|
}
|
|
15202
16010
|
}
|
|
15203
16011
|
}
|
|
16012
|
+
SwitchStatement.prototype.includeNode = onlyIncludeSelfNoDeoptimize;
|
|
16013
|
+
SwitchStatement.prototype.applyDeoptimizations = doNotDeoptimize;
|
|
15204
16014
|
|
|
15205
16015
|
class TaggedTemplateExpression extends CallExpressionBase {
|
|
15206
16016
|
bind() {
|
|
@@ -15224,8 +16034,8 @@ class TaggedTemplateExpression extends CallExpressionBase {
|
|
|
15224
16034
|
this.tag.hasEffectsOnInteractionAtPath(EMPTY_PATH, this.interaction, context));
|
|
15225
16035
|
}
|
|
15226
16036
|
include(context, includeChildrenRecursively) {
|
|
15227
|
-
if (!this.
|
|
15228
|
-
this.
|
|
16037
|
+
if (!this.included)
|
|
16038
|
+
this.includeNode(context);
|
|
15229
16039
|
if (includeChildrenRecursively) {
|
|
15230
16040
|
super.include(context, includeChildrenRecursively);
|
|
15231
16041
|
}
|
|
@@ -15234,7 +16044,7 @@ class TaggedTemplateExpression extends CallExpressionBase {
|
|
|
15234
16044
|
this.tag.include(context, includeChildrenRecursively);
|
|
15235
16045
|
this.quasi.include(context, includeChildrenRecursively);
|
|
15236
16046
|
}
|
|
15237
|
-
this.tag.includeCallArguments(context, this.
|
|
16047
|
+
this.tag.includeCallArguments(context, this.interaction);
|
|
15238
16048
|
const [returnExpression] = this.getReturnExpression();
|
|
15239
16049
|
if (!returnExpression.included) {
|
|
15240
16050
|
returnExpression.include(context, false);
|
|
@@ -15269,6 +16079,7 @@ class TaggedTemplateExpression extends CallExpressionBase {
|
|
|
15269
16079
|
return this.returnExpression;
|
|
15270
16080
|
}
|
|
15271
16081
|
}
|
|
16082
|
+
TaggedTemplateExpression.prototype.includeNode = onlyIncludeSelf;
|
|
15272
16083
|
|
|
15273
16084
|
class TemplateElement extends NodeBase {
|
|
15274
16085
|
get tail() {
|
|
@@ -15282,15 +16093,13 @@ class TemplateElement extends NodeBase {
|
|
|
15282
16093
|
hasEffects() {
|
|
15283
16094
|
return false;
|
|
15284
16095
|
}
|
|
15285
|
-
include() {
|
|
15286
|
-
this.included = true;
|
|
15287
|
-
}
|
|
15288
16096
|
parseNode(esTreeNode) {
|
|
15289
16097
|
this.value = esTreeNode.value;
|
|
15290
16098
|
return super.parseNode(esTreeNode);
|
|
15291
16099
|
}
|
|
15292
16100
|
render() { }
|
|
15293
16101
|
}
|
|
16102
|
+
TemplateElement.prototype.includeNode = onlyIncludeSelf;
|
|
15294
16103
|
|
|
15295
16104
|
class TemplateLiteral extends NodeBase {
|
|
15296
16105
|
deoptimizeArgumentsOnInteractionAtPath() { }
|
|
@@ -15315,6 +16124,14 @@ class TemplateLiteral extends NodeBase {
|
|
|
15315
16124
|
}
|
|
15316
16125
|
return true;
|
|
15317
16126
|
}
|
|
16127
|
+
includeNode(context) {
|
|
16128
|
+
this.included = true;
|
|
16129
|
+
if (!this.deoptimized)
|
|
16130
|
+
this.applyDeoptimizations();
|
|
16131
|
+
for (const node of this.expressions) {
|
|
16132
|
+
node.includePath(UNKNOWN_PATH, context);
|
|
16133
|
+
}
|
|
16134
|
+
}
|
|
15318
16135
|
render(code, options) {
|
|
15319
16136
|
code.indentExclusionRanges.push([this.start, this.end]);
|
|
15320
16137
|
super.render(code, options);
|
|
@@ -15324,13 +16141,13 @@ class TemplateLiteral extends NodeBase {
|
|
|
15324
16141
|
class ModuleScope extends ChildScope {
|
|
15325
16142
|
constructor(parent, context) {
|
|
15326
16143
|
super(parent, context);
|
|
15327
|
-
this.variables.set('this', new LocalVariable('this', null, UNDEFINED_EXPRESSION, context, 'other'));
|
|
16144
|
+
this.variables.set('this', new LocalVariable('this', null, UNDEFINED_EXPRESSION, EMPTY_PATH, context, 'other'));
|
|
15328
16145
|
}
|
|
15329
|
-
addDeclaration(identifier, context, init, kind) {
|
|
16146
|
+
addDeclaration(identifier, context, init, destructuredInitPath, kind) {
|
|
15330
16147
|
if (this.context.module.importDescriptions.has(identifier.name)) {
|
|
15331
16148
|
context.error(parseAst_js.logRedeclarationError(identifier.name), identifier.start);
|
|
15332
16149
|
}
|
|
15333
|
-
return super.addDeclaration(identifier, context, init, kind);
|
|
16150
|
+
return super.addDeclaration(identifier, context, init, destructuredInitPath, kind);
|
|
15334
16151
|
}
|
|
15335
16152
|
addExportDefaultDeclaration(name, exportDefaultDeclaration, context) {
|
|
15336
16153
|
const variable = new ExportDefaultVariable(name, exportDefaultDeclaration, context);
|
|
@@ -15375,10 +16192,23 @@ class ThisExpression extends NodeBase {
|
|
|
15375
16192
|
}
|
|
15376
16193
|
return this.variable.hasEffectsOnInteractionAtPath(path, interaction, context);
|
|
15377
16194
|
}
|
|
15378
|
-
include() {
|
|
16195
|
+
include(context) {
|
|
16196
|
+
if (!this.included)
|
|
16197
|
+
this.includeNode(context);
|
|
16198
|
+
}
|
|
16199
|
+
includeNode(context) {
|
|
16200
|
+
this.included = true;
|
|
16201
|
+
if (!this.deoptimized)
|
|
16202
|
+
this.applyDeoptimizations();
|
|
16203
|
+
this.scope.context.includeVariableInModule(this.variable, EMPTY_PATH, context);
|
|
16204
|
+
}
|
|
16205
|
+
includePath(path, context) {
|
|
15379
16206
|
if (!this.included) {
|
|
15380
16207
|
this.included = true;
|
|
15381
|
-
this.scope.context.includeVariableInModule(this.variable);
|
|
16208
|
+
this.scope.context.includeVariableInModule(this.variable, path, context);
|
|
16209
|
+
}
|
|
16210
|
+
else if (path.length > 0) {
|
|
16211
|
+
this.variable.includePath(path, context);
|
|
15382
16212
|
}
|
|
15383
16213
|
}
|
|
15384
16214
|
initialise() {
|
|
@@ -15406,7 +16236,8 @@ class ThrowStatement extends NodeBase {
|
|
|
15406
16236
|
return true;
|
|
15407
16237
|
}
|
|
15408
16238
|
include(context, includeChildrenRecursively) {
|
|
15409
|
-
this.included
|
|
16239
|
+
if (!this.included)
|
|
16240
|
+
this.includeNode(context);
|
|
15410
16241
|
this.argument.include(context, includeChildrenRecursively);
|
|
15411
16242
|
context.brokenFlow = true;
|
|
15412
16243
|
}
|
|
@@ -15417,6 +16248,7 @@ class ThrowStatement extends NodeBase {
|
|
|
15417
16248
|
}
|
|
15418
16249
|
}
|
|
15419
16250
|
}
|
|
16251
|
+
ThrowStatement.prototype.includeNode = onlyIncludeSelf;
|
|
15420
16252
|
|
|
15421
16253
|
class TryStatement extends NodeBase {
|
|
15422
16254
|
constructor() {
|
|
@@ -15453,6 +16285,8 @@ class TryStatement extends NodeBase {
|
|
|
15453
16285
|
this.finalizer?.include(context, includeChildrenRecursively);
|
|
15454
16286
|
}
|
|
15455
16287
|
}
|
|
16288
|
+
TryStatement.prototype.includeNode = onlyIncludeSelfNoDeoptimize;
|
|
16289
|
+
TryStatement.prototype.applyDeoptimizations = doNotDeoptimize;
|
|
15456
16290
|
|
|
15457
16291
|
const unaryOperators = {
|
|
15458
16292
|
'!': value => !value,
|
|
@@ -15559,6 +16393,7 @@ function getSimplifiedNumber(value) {
|
|
|
15559
16393
|
const stringifiedValue = String(value).replace('+', '');
|
|
15560
16394
|
return finalizedExp.length < stringifiedValue.length ? finalizedExp : stringifiedValue;
|
|
15561
16395
|
}
|
|
16396
|
+
UnaryExpression.prototype.includeNode = onlyIncludeSelf;
|
|
15562
16397
|
|
|
15563
16398
|
class UpdateExpression extends NodeBase {
|
|
15564
16399
|
hasEffects(context) {
|
|
@@ -15570,9 +16405,8 @@ class UpdateExpression extends NodeBase {
|
|
|
15570
16405
|
return path.length > 1 || type !== INTERACTION_ACCESSED;
|
|
15571
16406
|
}
|
|
15572
16407
|
include(context, includeChildrenRecursively) {
|
|
15573
|
-
if (!this.
|
|
15574
|
-
this.
|
|
15575
|
-
this.included = true;
|
|
16408
|
+
if (!this.included)
|
|
16409
|
+
this.includeNode(context);
|
|
15576
16410
|
this.argument.includeAsAssignmentTarget(context, includeChildrenRecursively, true);
|
|
15577
16411
|
}
|
|
15578
16412
|
initialise() {
|
|
@@ -15611,6 +16445,7 @@ class UpdateExpression extends NodeBase {
|
|
|
15611
16445
|
this.scope.context.requestTreeshakingPass();
|
|
15612
16446
|
}
|
|
15613
16447
|
}
|
|
16448
|
+
UpdateExpression.prototype.includeNode = onlyIncludeSelf;
|
|
15614
16449
|
|
|
15615
16450
|
function areAllDeclarationsIncludedAndNotExported(declarations, exportNamesByVariable) {
|
|
15616
16451
|
for (const declarator of declarations) {
|
|
@@ -15641,8 +16476,9 @@ class VariableDeclaration extends NodeBase {
|
|
|
15641
16476
|
include(context, includeChildrenRecursively, { asSingleStatement } = parseAst_js.BLANK) {
|
|
15642
16477
|
this.included = true;
|
|
15643
16478
|
for (const declarator of this.declarations) {
|
|
15644
|
-
if (includeChildrenRecursively || declarator.shouldBeIncluded(context))
|
|
16479
|
+
if (includeChildrenRecursively || declarator.shouldBeIncluded(context)) {
|
|
15645
16480
|
declarator.include(context, includeChildrenRecursively);
|
|
16481
|
+
}
|
|
15646
16482
|
const { id, init } = declarator;
|
|
15647
16483
|
if (asSingleStatement) {
|
|
15648
16484
|
id.include(context, includeChildrenRecursively);
|
|
@@ -15680,7 +16516,6 @@ class VariableDeclaration extends NodeBase {
|
|
|
15680
16516
|
this.renderReplacedDeclarations(code, options);
|
|
15681
16517
|
}
|
|
15682
16518
|
}
|
|
15683
|
-
applyDeoptimizations() { }
|
|
15684
16519
|
renderDeclarationEnd(code, separatorString, lastSeparatorPos, actualContentEnd, renderedContentEnd, systemPatternExports, options) {
|
|
15685
16520
|
if (code.original.charCodeAt(this.end - 1) === 59 /*";"*/) {
|
|
15686
16521
|
code.remove(this.end - 1, this.end);
|
|
@@ -15723,8 +16558,7 @@ class VariableDeclaration extends NodeBase {
|
|
|
15723
16558
|
const singleSystemExport = gatherSystemExportsAndGetSingleExport(separatedNodes, options, aggregatedSystemExports);
|
|
15724
16559
|
for (const { node, start, separator, contentEnd, end } of separatedNodes) {
|
|
15725
16560
|
if (!node.included) {
|
|
15726
|
-
code
|
|
15727
|
-
node.removeAnnotations(code);
|
|
16561
|
+
treeshakeNode(node, code, start, end);
|
|
15728
16562
|
continue;
|
|
15729
16563
|
}
|
|
15730
16564
|
node.render(code, options);
|
|
@@ -15794,6 +16628,8 @@ function gatherSystemExportsAndGetSingleExport(separatedNodes, options, aggregat
|
|
|
15794
16628
|
}
|
|
15795
16629
|
return singleSystemExport;
|
|
15796
16630
|
}
|
|
16631
|
+
VariableDeclaration.prototype.includeNode = onlyIncludeSelfNoDeoptimize;
|
|
16632
|
+
VariableDeclaration.prototype.applyDeoptimizations = doNotDeoptimize;
|
|
15797
16633
|
|
|
15798
16634
|
class WhileStatement extends NodeBase {
|
|
15799
16635
|
hasEffects(context) {
|
|
@@ -15807,13 +16643,25 @@ class WhileStatement extends NodeBase {
|
|
|
15807
16643
|
includeLoopBody(context, this.body, includeChildrenRecursively);
|
|
15808
16644
|
}
|
|
15809
16645
|
}
|
|
16646
|
+
WhileStatement.prototype.includeNode = onlyIncludeSelfNoDeoptimize;
|
|
16647
|
+
WhileStatement.prototype.applyDeoptimizations = doNotDeoptimize;
|
|
15810
16648
|
|
|
15811
16649
|
class YieldExpression extends NodeBase {
|
|
16650
|
+
applyDeoptimizations() {
|
|
16651
|
+
this.deoptimized = true;
|
|
16652
|
+
this.argument?.deoptimizePath(UNKNOWN_PATH);
|
|
16653
|
+
}
|
|
15812
16654
|
hasEffects(context) {
|
|
15813
16655
|
if (!this.deoptimized)
|
|
15814
16656
|
this.applyDeoptimizations();
|
|
15815
16657
|
return !(context.ignore.returnYield && !this.argument?.hasEffects(context));
|
|
15816
16658
|
}
|
|
16659
|
+
includeNode(context) {
|
|
16660
|
+
this.included = true;
|
|
16661
|
+
if (!this.deoptimized)
|
|
16662
|
+
this.applyDeoptimizations();
|
|
16663
|
+
this.argument?.includePath(UNKNOWN_PATH, context);
|
|
16664
|
+
}
|
|
15817
16665
|
render(code, options) {
|
|
15818
16666
|
if (this.argument) {
|
|
15819
16667
|
this.argument.render(code, options, { preventASI: true });
|
|
@@ -16047,7 +16895,7 @@ const bufferParsers = [
|
|
|
16047
16895
|
const annotations = (node.annotations = parseAst_js.convertAnnotations(buffer[position + 1], buffer));
|
|
16048
16896
|
node.annotationNoSideEffects = annotations.some(comment => comment.type === 'noSideEffects');
|
|
16049
16897
|
const parameters = (node.params = convertNodeList(node, scope, buffer[position + 2], buffer));
|
|
16050
|
-
scope.addParameterVariables(parameters.map(parameter => parameter.declare('parameter', UNKNOWN_EXPRESSION)), parameters[parameters.length - 1] instanceof RestElement);
|
|
16898
|
+
scope.addParameterVariables(parameters.map(parameter => parameter.declare('parameter', EMPTY_PATH, UNKNOWN_EXPRESSION)), parameters[parameters.length - 1] instanceof RestElement);
|
|
16051
16899
|
node.body = convertNode(node, scope.bodyScope, buffer[position + 3], buffer);
|
|
16052
16900
|
},
|
|
16053
16901
|
function assignmentExpression(node, position, buffer) {
|
|
@@ -16093,7 +16941,7 @@ const bufferParsers = [
|
|
|
16093
16941
|
const parameterPosition = buffer[position];
|
|
16094
16942
|
const parameter = (node.param =
|
|
16095
16943
|
parameterPosition === 0 ? null : convertNode(node, scope, parameterPosition, buffer));
|
|
16096
|
-
parameter?.declare('parameter', UNKNOWN_EXPRESSION);
|
|
16944
|
+
parameter?.declare('parameter', EMPTY_PATH, UNKNOWN_EXPRESSION);
|
|
16097
16945
|
node.body = convertNode(node, scope.bodyScope, buffer[position + 1], buffer);
|
|
16098
16946
|
},
|
|
16099
16947
|
function chainExpression(node, position, buffer) {
|
|
@@ -16231,7 +17079,7 @@ const bufferParsers = [
|
|
|
16231
17079
|
node.id =
|
|
16232
17080
|
idPosition === 0 ? null : convertNode(node, scope.parent, idPosition, buffer);
|
|
16233
17081
|
const parameters = (node.params = convertNodeList(node, scope, buffer[position + 3], buffer));
|
|
16234
|
-
scope.addParameterVariables(parameters.map(parameter => parameter.declare('parameter', UNKNOWN_EXPRESSION)), parameters[parameters.length - 1] instanceof RestElement);
|
|
17082
|
+
scope.addParameterVariables(parameters.map(parameter => parameter.declare('parameter', EMPTY_PATH, UNKNOWN_EXPRESSION)), parameters[parameters.length - 1] instanceof RestElement);
|
|
16235
17083
|
node.body = convertNode(node, scope.bodyScope, buffer[position + 4], buffer);
|
|
16236
17084
|
},
|
|
16237
17085
|
function functionExpression(node, position, buffer) {
|
|
@@ -16244,7 +17092,7 @@ const bufferParsers = [
|
|
|
16244
17092
|
const idPosition = buffer[position + 2];
|
|
16245
17093
|
node.id = idPosition === 0 ? null : convertNode(node, node.idScope, idPosition, buffer);
|
|
16246
17094
|
const parameters = (node.params = convertNodeList(node, scope, buffer[position + 3], buffer));
|
|
16247
|
-
scope.addParameterVariables(parameters.map(parameter => parameter.declare('parameter', UNKNOWN_EXPRESSION)), parameters[parameters.length - 1] instanceof RestElement);
|
|
17095
|
+
scope.addParameterVariables(parameters.map(parameter => parameter.declare('parameter', EMPTY_PATH, UNKNOWN_EXPRESSION)), parameters[parameters.length - 1] instanceof RestElement);
|
|
16248
17096
|
node.body = convertNode(node, scope.bodyScope, buffer[position + 4], buffer);
|
|
16249
17097
|
},
|
|
16250
17098
|
function identifier(node, position, buffer) {
|
|
@@ -16708,8 +17556,8 @@ class ExportShimVariable extends Variable {
|
|
|
16708
17556
|
super(MISSING_EXPORT_SHIM_VARIABLE);
|
|
16709
17557
|
this.module = module;
|
|
16710
17558
|
}
|
|
16711
|
-
|
|
16712
|
-
super.
|
|
17559
|
+
includePath(path, context) {
|
|
17560
|
+
super.includePath(path, context);
|
|
16713
17561
|
this.module.needsExportShim = true;
|
|
16714
17562
|
}
|
|
16715
17563
|
}
|
|
@@ -17400,16 +18248,15 @@ class Module {
|
|
|
17400
18248
|
markModuleAndImpureDependenciesAsExecuted(this);
|
|
17401
18249
|
this.graph.needsTreeshakingPass = true;
|
|
17402
18250
|
}
|
|
18251
|
+
const inclusionContext = createInclusionContext();
|
|
17403
18252
|
for (const exportName of this.exports.keys()) {
|
|
17404
18253
|
if (includeNamespaceMembers || exportName !== this.info.syntheticNamedExports) {
|
|
17405
18254
|
const variable = this.getVariableForExportName(exportName)[0];
|
|
17406
18255
|
if (!variable) {
|
|
17407
18256
|
return parseAst_js.error(parseAst_js.logMissingEntryExport(exportName, this.id));
|
|
17408
18257
|
}
|
|
18258
|
+
this.includeVariable(variable, UNKNOWN_PATH, inclusionContext);
|
|
17409
18259
|
variable.deoptimizePath(UNKNOWN_PATH);
|
|
17410
|
-
if (!variable.included) {
|
|
17411
|
-
this.includeVariable(variable);
|
|
17412
|
-
}
|
|
17413
18260
|
}
|
|
17414
18261
|
}
|
|
17415
18262
|
for (const name of this.getReexports()) {
|
|
@@ -17417,7 +18264,7 @@ class Module {
|
|
|
17417
18264
|
if (variable) {
|
|
17418
18265
|
variable.deoptimizePath(UNKNOWN_PATH);
|
|
17419
18266
|
if (!variable.included) {
|
|
17420
|
-
this.includeVariable(variable);
|
|
18267
|
+
this.includeVariable(variable, UNKNOWN_PATH, inclusionContext);
|
|
17421
18268
|
}
|
|
17422
18269
|
if (variable instanceof ExternalVariable) {
|
|
17423
18270
|
variable.module.reexported = true;
|
|
@@ -17438,13 +18285,12 @@ class Module {
|
|
|
17438
18285
|
this.graph.needsTreeshakingPass = true;
|
|
17439
18286
|
}
|
|
17440
18287
|
let includeNamespaceMembers = false;
|
|
18288
|
+
const inclusionContext = createInclusionContext();
|
|
17441
18289
|
for (const name of names) {
|
|
17442
18290
|
const variable = this.getVariableForExportName(name)[0];
|
|
17443
18291
|
if (variable) {
|
|
17444
18292
|
variable.deoptimizePath(UNKNOWN_PATH);
|
|
17445
|
-
|
|
17446
|
-
this.includeVariable(variable);
|
|
17447
|
-
}
|
|
18293
|
+
this.includeVariable(variable, UNKNOWN_PATH, inclusionContext);
|
|
17448
18294
|
}
|
|
17449
18295
|
if (!this.exports.has(name) && !this.reexportDescriptions.has(name)) {
|
|
17450
18296
|
includeNamespaceMembers = true;
|
|
@@ -17545,6 +18391,7 @@ class Module {
|
|
|
17545
18391
|
manualPureFunctions: this.graph.pureFunctions,
|
|
17546
18392
|
module: this,
|
|
17547
18393
|
moduleContext: this.context,
|
|
18394
|
+
newlyIncludedVariableInits: this.graph.newlyIncludedVariableInits,
|
|
17548
18395
|
options: this.options,
|
|
17549
18396
|
requestTreeshakingPass: () => (this.graph.needsTreeshakingPass = true),
|
|
17550
18397
|
traceExport: (name) => this.getVariableForExportName(name)[0],
|
|
@@ -17885,13 +18732,13 @@ class Module {
|
|
|
17885
18732
|
for (const module of [this, ...this.exportAllModules]) {
|
|
17886
18733
|
if (module instanceof ExternalModule) {
|
|
17887
18734
|
const [externalVariable] = module.getVariableForExportName('*');
|
|
17888
|
-
externalVariable.
|
|
18735
|
+
externalVariable.includePath(UNKNOWN_PATH, createInclusionContext());
|
|
17889
18736
|
this.includedImports.add(externalVariable);
|
|
17890
18737
|
externalNamespaces.add(externalVariable);
|
|
17891
18738
|
}
|
|
17892
18739
|
else if (module.info.syntheticNamedExports) {
|
|
17893
18740
|
const syntheticNamespace = module.getSyntheticNamespace();
|
|
17894
|
-
syntheticNamespace.
|
|
18741
|
+
syntheticNamespace.includePath(UNKNOWN_PATH, createInclusionContext());
|
|
17895
18742
|
this.includedImports.add(syntheticNamespace);
|
|
17896
18743
|
syntheticNamespaces.add(syntheticNamespace);
|
|
17897
18744
|
}
|
|
@@ -17901,7 +18748,9 @@ class Module {
|
|
|
17901
18748
|
includeDynamicImport(node) {
|
|
17902
18749
|
const resolution = this.dynamicImports.find(dynamicImport => dynamicImport.node === node).resolution;
|
|
17903
18750
|
if (resolution instanceof Module) {
|
|
17904
|
-
resolution.includedDynamicImporters.
|
|
18751
|
+
if (!resolution.includedDynamicImporters.includes(this)) {
|
|
18752
|
+
resolution.includedDynamicImporters.push(this);
|
|
18753
|
+
}
|
|
17905
18754
|
const importedNames = this.options.treeshake
|
|
17906
18755
|
? node.getDeterministicImportedNames()
|
|
17907
18756
|
: undefined;
|
|
@@ -17913,15 +18762,15 @@ class Module {
|
|
|
17913
18762
|
}
|
|
17914
18763
|
}
|
|
17915
18764
|
}
|
|
17916
|
-
includeVariable(variable) {
|
|
17917
|
-
const variableModule = variable
|
|
17918
|
-
|
|
18765
|
+
includeVariable(variable, path, context) {
|
|
18766
|
+
const { included, module: variableModule } = variable;
|
|
18767
|
+
variable.includePath(path, context);
|
|
18768
|
+
if (included) {
|
|
17919
18769
|
if (variableModule instanceof Module && variableModule !== this) {
|
|
17920
18770
|
getAndExtendSideEffectModules(variable, this);
|
|
17921
18771
|
}
|
|
17922
18772
|
}
|
|
17923
18773
|
else {
|
|
17924
|
-
variable.include();
|
|
17925
18774
|
this.graph.needsTreeshakingPass = true;
|
|
17926
18775
|
if (variableModule instanceof Module) {
|
|
17927
18776
|
if (!variableModule.isExecuted) {
|
|
@@ -17938,8 +18787,8 @@ class Module {
|
|
|
17938
18787
|
}
|
|
17939
18788
|
}
|
|
17940
18789
|
}
|
|
17941
|
-
includeVariableInModule(variable) {
|
|
17942
|
-
this.includeVariable(variable);
|
|
18790
|
+
includeVariableInModule(variable, path, context) {
|
|
18791
|
+
this.includeVariable(variable, path, context);
|
|
17943
18792
|
const variableModule = variable.module;
|
|
17944
18793
|
if (variableModule && variableModule !== this) {
|
|
17945
18794
|
this.includedImports.add(variable);
|
|
@@ -21448,10 +22297,11 @@ class Graph {
|
|
|
21448
22297
|
this.options = options;
|
|
21449
22298
|
this.astLru = flru(5);
|
|
21450
22299
|
this.cachedModules = new Map();
|
|
21451
|
-
this.deoptimizationTracker = new
|
|
22300
|
+
this.deoptimizationTracker = new EntityPathTracker();
|
|
21452
22301
|
this.entryModules = [];
|
|
21453
22302
|
this.modulesById = new Map();
|
|
21454
22303
|
this.needsTreeshakingPass = false;
|
|
22304
|
+
this.newlyIncludedVariableInits = new Set();
|
|
21455
22305
|
this.phase = BuildPhase.LOAD_AND_PARSE;
|
|
21456
22306
|
this.scope = new GlobalScope();
|
|
21457
22307
|
this.watchFiles = Object.create(null);
|
|
@@ -21545,6 +22395,7 @@ class Graph {
|
|
|
21545
22395
|
}
|
|
21546
22396
|
if (this.options.treeshake) {
|
|
21547
22397
|
let treeshakingPass = 1;
|
|
22398
|
+
this.newlyIncludedVariableInits.clear();
|
|
21548
22399
|
do {
|
|
21549
22400
|
timeStart(`treeshaking pass ${treeshakingPass}`, 3);
|
|
21550
22401
|
this.needsTreeshakingPass = false;
|
|
@@ -21557,6 +22408,10 @@ class Graph {
|
|
|
21557
22408
|
else {
|
|
21558
22409
|
module.include();
|
|
21559
22410
|
}
|
|
22411
|
+
for (const entity of this.newlyIncludedVariableInits) {
|
|
22412
|
+
this.newlyIncludedVariableInits.delete(entity);
|
|
22413
|
+
entity.include(createInclusionContext(), false);
|
|
22414
|
+
}
|
|
21560
22415
|
}
|
|
21561
22416
|
}
|
|
21562
22417
|
if (treeshakingPass === 1) {
|