rollup 3.4.0 → 3.5.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 CHANGED
@@ -2,8 +2,8 @@
2
2
 
3
3
  /*
4
4
  @license
5
- Rollup.js v3.4.0
6
- Tue, 22 Nov 2022 05:15:54 GMT - commit 780e3421e8a498f3248fd7d8506e97fcee8dd1e6
5
+ Rollup.js v3.5.0
6
+ Sun, 27 Nov 2022 06:34:25 GMT - commit 290b07d3685e8d4b4f3f5d3d673d41995d504239
7
7
 
8
8
  https://github.com/rollup/rollup
9
9
 
@@ -27,7 +27,7 @@ require('node:events');
27
27
  require('tty');
28
28
  require('node:url');
29
29
 
30
- const help = "rollup version __VERSION__\n=====================================\n\nUsage: rollup [options] <entry file>\n\nBasic options:\n\n-c, --config <filename> Use this config file (if argument is used but value\n is unspecified, defaults to rollup.config.js)\n-d, --dir <dirname> Directory for chunks (if absent, prints to stdout)\n-e, --external <ids> Comma-separate list of module IDs to exclude\n-f, --format <format> Type of output (amd, cjs, es, iife, umd, system)\n-g, --globals <pairs> Comma-separate list of `moduleID:Global` pairs\n-h, --help Show this help message\n-i, --input <filename> Input (alternative to <entry file>)\n-m, --sourcemap Generate sourcemap (`-m inline` for inline map)\n-n, --name <name> Name for UMD export\n-o, --file <output> Single output file (if absent, prints to stdout)\n-p, --plugin <plugin> Use the plugin specified (may be repeated)\n-v, --version Show version number\n-w, --watch Watch files in bundle and rebuild on changes\n--amd.id <id> ID for AMD module (default is anonymous)\n--amd.autoId Generate the AMD ID based off the chunk name\n--amd.basePath <prefix> Path to prepend to auto generated AMD ID\n--amd.define <name> Function to use in place of `define`\n--amd.forceJsExtensionForImports Use `.js` extension in AMD imports\n--assetFileNames <pattern> Name pattern for emitted assets\n--banner <text> Code to insert at top of bundle (outside wrapper)\n--chunkFileNames <pattern> Name pattern for emitted secondary chunks\n--compact Minify wrapper code\n--context <variable> Specify top-level `this` value\n--no-dynamicImportInCjs Write external dynamic CommonJS imports as require\n--entryFileNames <pattern> Name pattern for emitted entry chunks\n--environment <values> Settings passed to config file (see example)\n--no-esModule Do not add __esModule property\n--exports <mode> Specify export mode (auto, default, named, none)\n--extend Extend global variable defined by --name\n--no-externalLiveBindings Do not generate code to support live bindings\n--no-externalImportAssertions Omit import assertions in \"es\" output\n--failAfterWarnings Exit with an error if the build produced warnings\n--footer <text> Code to insert at end of bundle (outside wrapper)\n--no-freeze Do not freeze namespace objects\n--generatedCode <preset> Which code features to use (es5/es2015)\n--no-hoistTransitiveImports Do not hoist transitive imports into entry chunks\n--no-indent Don't indent result\n--no-interop Do not include interop block\n--inlineDynamicImports Create single bundle when using dynamic imports\n--intro <text> Code to insert at top of bundle (inside wrapper)\n--no-makeAbsoluteExternalsRelative Prevent normalization of external imports\n--maxParallelFileOps <value> How many files to read in parallel\n--minifyInternalExports Force or disable minification of internal exports\n--noConflict Generate a noConflict method for UMD globals\n--outro <text> Code to insert at end of bundle (inside wrapper)\n--perf Display performance timings\n--no-preserveEntrySignatures Avoid facade chunks for entry points\n--preserveModules Preserve module structure\n--preserveModulesRoot Put preserved modules under this path at root level\n--preserveSymlinks Do not follow symlinks when resolving files\n--no-sanitizeFileName Do not replace invalid characters in file names\n--shimMissingExports Create shim variables for missing exports\n--silent Don't print warnings\n--sourcemapBaseUrl <url> Emit absolute sourcemap URLs with given base\n--sourcemapExcludeSources Do not include source code in source maps\n--sourcemapFile <file> Specify bundle position for source maps\n--stdin=ext Specify file extension used for stdin input\n--no-stdin Do not read \"-\" from stdin\n--no-strict Don't emit `\"use strict\";` in the generated modules\n--strictDeprecations Throw errors for deprecated features\n--no-systemNullSetters Do not replace empty SystemJS setters with `null`\n--no-treeshake Disable tree-shaking optimisations\n--no-treeshake.annotations Ignore pure call annotations\n--no-treeshake.moduleSideEffects Assume modules have no side effects\n--no-treeshake.propertyReadSideEffects Ignore property access side effects\n--no-treeshake.tryCatchDeoptimization Do not turn off try-catch-tree-shaking\n--no-treeshake.unknownGlobalSideEffects Assume unknown globals do not throw\n--waitForBundleInput Wait for bundle input files\n--watch.buildDelay <number> Throttle watch rebuilds\n--no-watch.clearScreen Do not clear the screen when rebuilding\n--watch.skipWrite Do not write files to disk when watching\n--watch.exclude <files> Exclude files from being watched\n--watch.include <files> Limit watching to specified files\n--watch.onStart <cmd> Shell command to run on `\"START\"` event\n--watch.onBundleStart <cmd> Shell command to run on `\"BUNDLE_START\"` event\n--watch.onBundleEnd <cmd> Shell command to run on `\"BUNDLE_END\"` event\n--watch.onEnd <cmd> Shell command to run on `\"END\"` event\n--watch.onError <cmd> Shell command to run on `\"ERROR\"` event\n--validate Validate output\n\nExamples:\n\n# use settings in config file\nrollup -c\n\n# in config file, process.env.INCLUDE_DEPS === 'true'\n# and process.env.BUILD === 'production'\nrollup -c --environment INCLUDE_DEPS,BUILD:production\n\n# create CommonJS bundle.js from src/main.js\nrollup --format=cjs --file=bundle.js -- src/main.js\n\n# create self-executing IIFE using `window.jQuery`\n# and `window._` as external globals\nrollup -f iife --globals jquery:jQuery,lodash:_ \\\n -i src/app.js -o build/app.js -m build/app.js.map\n\nNotes:\n\n* When piping to stdout, only inline sourcemaps are permitted\n\nFor more information visit https://rollupjs.org\n";
30
+ const help = "rollup version __VERSION__\n=====================================\n\nUsage: rollup [options] <entry file>\n\nBasic options:\n\n-c, --config <filename> Use this config file (if argument is used but value\n is unspecified, defaults to rollup.config.js)\n-d, --dir <dirname> Directory for chunks (if absent, prints to stdout)\n-e, --external <ids> Comma-separate list of module IDs to exclude\n-f, --format <format> Type of output (amd, cjs, es, iife, umd, system)\n-g, --globals <pairs> Comma-separate list of `moduleID:Global` pairs\n-h, --help Show this help message\n-i, --input <filename> Input (alternative to <entry file>)\n-m, --sourcemap Generate sourcemap (`-m inline` for inline map)\n-n, --name <name> Name for UMD export\n-o, --file <output> Single output file (if absent, prints to stdout)\n-p, --plugin <plugin> Use the plugin specified (may be repeated)\n-v, --version Show version number\n-w, --watch Watch files in bundle and rebuild on changes\n--amd.autoId Generate the AMD ID based off the chunk name\n--amd.basePath <prefix> Path to prepend to auto generated AMD ID\n--amd.define <name> Function to use in place of `define`\n--amd.forceJsExtensionForImports Use `.js` extension in AMD imports\n--amd.id <id> ID for AMD module (default is anonymous)\n--assetFileNames <pattern> Name pattern for emitted assets\n--banner <text> Code to insert at top of bundle (outside wrapper)\n--chunkFileNames <pattern> Name pattern for emitted secondary chunks\n--compact Minify wrapper code\n--context <variable> Specify top-level `this` value\n--no-dynamicImportInCjs Write external dynamic CommonJS imports as require\n--entryFileNames <pattern> Name pattern for emitted entry chunks\n--environment <values> Settings passed to config file (see example)\n--no-esModule Do not add __esModule property\n--exports <mode> Specify export mode (auto, default, named, none)\n--extend Extend global variable defined by --name\n--no-externalImportAssertions Omit import assertions in \"es\" output\n--no-externalLiveBindings Do not generate code to support live bindings\n--failAfterWarnings Exit with an error if the build produced warnings\n--footer <text> Code to insert at end of bundle (outside wrapper)\n--no-freeze Do not freeze namespace objects\n--generatedCode <preset> Which code features to use (es5/es2015)\n--generatedCode.arrowFunctions Use arrow functions in generated code\n--generatedCode.constBindings Use \"const\" in generated code\n--generatedCode.objectShorthand Use shorthand properties in generated code\n--no-generatedCode.reservedNamesAsProps Always quote reserved names as props\n--generatedCode.symbols Use symbols in generated code\n--no-hoistTransitiveImports Do not hoist transitive imports into entry chunks\n--no-indent Don't indent result\n--inlineDynamicImports Create single bundle when using dynamic imports\n--no-interop Do not include interop block\n--intro <text> Code to insert at top of bundle (inside wrapper)\n--no-makeAbsoluteExternalsRelative Prevent normalization of external imports\n--maxParallelFileOps <value> How many files to read in parallel\n--minifyInternalExports Force or disable minification of internal exports\n--noConflict Generate a noConflict method for UMD globals\n--outro <text> Code to insert at end of bundle (inside wrapper)\n--perf Display performance timings\n--no-preserveEntrySignatures Avoid facade chunks for entry points\n--preserveModules Preserve module structure\n--preserveModulesRoot Put preserved modules under this path at root level\n--preserveSymlinks Do not follow symlinks when resolving files\n--no-sanitizeFileName Do not replace invalid characters in file names\n--shimMissingExports Create shim variables for missing exports\n--silent Don't print warnings\n--sourcemapBaseUrl <url> Emit absolute sourcemap URLs with given base\n--sourcemapExcludeSources Do not include source code in source maps\n--sourcemapFile <file> Specify bundle position for source maps\n--stdin=ext Specify file extension used for stdin input\n--no-stdin Do not read \"-\" from stdin\n--no-strict Don't emit `\"use strict\";` in the generated modules\n--strictDeprecations Throw errors for deprecated features\n--no-systemNullSetters Do not replace empty SystemJS setters with `null`\n--no-treeshake Disable tree-shaking optimisations\n--no-treeshake.annotations Ignore pure call annotations\n--treeshake.correctVarValueBeforeDeclaration Deoptimize variables until declared\n--treeshake.manualPureFunctions <names> Manually declare functions as pure\n--no-treeshake.moduleSideEffects Assume modules have no side effects\n--no-treeshake.propertyReadSideEffects Ignore property access side effects\n--no-treeshake.tryCatchDeoptimization Do not turn off try-catch-tree-shaking\n--no-treeshake.unknownGlobalSideEffects Assume unknown globals do not throw\n--validate Validate output\n--waitForBundleInput Wait for bundle input files\n--watch.buildDelay <number> Throttle watch rebuilds\n--no-watch.clearScreen Do not clear the screen when rebuilding\n--watch.exclude <files> Exclude files from being watched\n--watch.include <files> Limit watching to specified files\n--watch.onBundleEnd <cmd> Shell command to run on `\"BUNDLE_END\"` event\n--watch.onBundleStart <cmd> Shell command to run on `\"BUNDLE_START\"` event\n--watch.onEnd <cmd> Shell command to run on `\"END\"` event\n--watch.onError <cmd> Shell command to run on `\"ERROR\"` event\n--watch.onStart <cmd> Shell command to run on `\"START\"` event\n--watch.skipWrite Do not write files to disk when watching\n\nExamples:\n\n# use settings in config file\nrollup -c\n\n# in config file, process.env.INCLUDE_DEPS === 'true'\n# and process.env.BUILD === 'production'\nrollup -c --environment INCLUDE_DEPS,BUILD:production\n\n# create CommonJS bundle.js from src/main.js\nrollup --format=cjs --file=bundle.js -- src/main.js\n\n# create self-executing IIFE using `window.jQuery`\n# and `window._` as external globals\nrollup -f iife --globals jquery:jQuery,lodash:_ \\\n -i src/app.js -o build/app.js -m build/app.js.map\n\nNotes:\n\n* When piping to stdout, only inline sourcemaps are permitted\n\nFor more information visit https://rollupjs.org\n";
31
31
 
32
32
  /**
33
33
  * @license
package/dist/es/rollup.js CHANGED
@@ -1,7 +1,7 @@
1
1
  /*
2
2
  @license
3
- Rollup.js v3.4.0
4
- Tue, 22 Nov 2022 05:15:54 GMT - commit 780e3421e8a498f3248fd7d8506e97fcee8dd1e6
3
+ Rollup.js v3.5.0
4
+ Sun, 27 Nov 2022 06:34:25 GMT - commit 290b07d3685e8d4b4f3f5d3d673d41995d504239
5
5
 
6
6
  https://github.com/rollup/rollup
7
7
 
@@ -1,7 +1,7 @@
1
1
  /*
2
2
  @license
3
- Rollup.js v3.4.0
4
- Tue, 22 Nov 2022 05:15:54 GMT - commit 780e3421e8a498f3248fd7d8506e97fcee8dd1e6
3
+ Rollup.js v3.5.0
4
+ Sun, 27 Nov 2022 06:34:25 GMT - commit 290b07d3685e8d4b4f3f5d3d673d41995d504239
5
5
 
6
6
  https://github.com/rollup/rollup
7
7
 
@@ -16,7 +16,7 @@ import { promises } from 'node:fs';
16
16
  import { EventEmitter } from 'node:events';
17
17
  import * as tty from 'tty';
18
18
 
19
- var version$1 = "3.4.0";
19
+ var version$1 = "3.5.0";
20
20
 
21
21
  var charToInteger = {};
22
22
  var chars$1 = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=';
@@ -1776,7 +1776,7 @@ class ExpressionEntity {
1776
1776
  return UnknownValue;
1777
1777
  }
1778
1778
  getReturnExpressionWhenCalledAtPath(_path, _interaction, _recursionTracker, _origin) {
1779
- return UNKNOWN_EXPRESSION;
1779
+ return UNKNOWN_RETURN_EXPRESSION;
1780
1780
  }
1781
1781
  hasEffectsOnInteractionAtPath(_path, _interaction, _context) {
1782
1782
  return true;
@@ -1795,6 +1795,10 @@ class ExpressionEntity {
1795
1795
  }
1796
1796
  const UNKNOWN_EXPRESSION = new (class UnknownExpression extends ExpressionEntity {
1797
1797
  })();
1798
+ const UNKNOWN_RETURN_EXPRESSION = [
1799
+ UNKNOWN_EXPRESSION,
1800
+ false
1801
+ ];
1798
1802
 
1799
1803
  const INTERACTION_ACCESSED = 0;
1800
1804
  const INTERACTION_ASSIGNED = 1;
@@ -4930,7 +4934,7 @@ const UNKNOWN_LITERAL_BOOLEAN = new (class UnknownBoolean extends ExpressionEnti
4930
4934
  if (path.length === 1) {
4931
4935
  return getMemberReturnExpressionWhenCalled(literalBooleanMembers, path[0]);
4932
4936
  }
4933
- return UNKNOWN_EXPRESSION;
4937
+ return UNKNOWN_RETURN_EXPRESSION;
4934
4938
  }
4935
4939
  hasEffectsOnInteractionAtPath(path, interaction, context) {
4936
4940
  if (interaction.type === INTERACTION_ACCESSED) {
@@ -4953,7 +4957,7 @@ const UNKNOWN_LITERAL_NUMBER = new (class UnknownNumber extends ExpressionEntity
4953
4957
  if (path.length === 1) {
4954
4958
  return getMemberReturnExpressionWhenCalled(literalNumberMembers, path[0]);
4955
4959
  }
4956
- return UNKNOWN_EXPRESSION;
4960
+ return UNKNOWN_RETURN_EXPRESSION;
4957
4961
  }
4958
4962
  hasEffectsOnInteractionAtPath(path, interaction, context) {
4959
4963
  if (interaction.type === INTERACTION_ACCESSED) {
@@ -4976,7 +4980,7 @@ const UNKNOWN_LITERAL_STRING = new (class UnknownString extends ExpressionEntity
4976
4980
  if (path.length === 1) {
4977
4981
  return getMemberReturnExpressionWhenCalled(literalStringMembers, path[0]);
4978
4982
  }
4979
- return UNKNOWN_EXPRESSION;
4983
+ return UNKNOWN_RETURN_EXPRESSION;
4980
4984
  }
4981
4985
  hasEffectsOnInteractionAtPath(path, interaction, context) {
4982
4986
  if (interaction.type === INTERACTION_ACCESSED) {
@@ -5097,8 +5101,8 @@ function hasMemberEffectWhenCalled(members, memberName, interaction, context) {
5097
5101
  }
5098
5102
  function getMemberReturnExpressionWhenCalled(members, memberName) {
5099
5103
  if (typeof memberName !== 'string' || !members[memberName])
5100
- return UNKNOWN_EXPRESSION;
5101
- return members[memberName].returns;
5104
+ return UNKNOWN_RETURN_EXPRESSION;
5105
+ return [members[memberName].returns, false];
5102
5106
  }
5103
5107
 
5104
5108
  // AST walker module for Mozilla Parser API compatible trees
@@ -5748,12 +5752,15 @@ class Method extends ExpressionEntity {
5748
5752
  }
5749
5753
  getReturnExpressionWhenCalledAtPath(path, { thisArg }) {
5750
5754
  if (path.length > 0) {
5751
- return UNKNOWN_EXPRESSION;
5755
+ return UNKNOWN_RETURN_EXPRESSION;
5752
5756
  }
5753
- return (this.description.returnsPrimitive ||
5754
- (this.description.returns === 'self'
5755
- ? thisArg || UNKNOWN_EXPRESSION
5756
- : this.description.returns()));
5757
+ return [
5758
+ this.description.returnsPrimitive ||
5759
+ (this.description.returns === 'self'
5760
+ ? thisArg || UNKNOWN_EXPRESSION
5761
+ : this.description.returns()),
5762
+ false
5763
+ ];
5757
5764
  }
5758
5765
  hasEffectsOnInteractionAtPath(path, interaction, context) {
5759
5766
  const { type } = interaction;
@@ -5996,7 +6003,7 @@ class ObjectEntity extends ExpressionEntity {
5996
6003
  }
5997
6004
  getReturnExpressionWhenCalledAtPath(path, interaction, recursionTracker, origin) {
5998
6005
  if (path.length === 0) {
5999
- return UNKNOWN_EXPRESSION;
6006
+ return UNKNOWN_RETURN_EXPRESSION;
6000
6007
  }
6001
6008
  const [key, ...subPath] = path;
6002
6009
  const expressionAtPath = this.getMemberExpressionAndTrackDeopt(key, origin);
@@ -6006,7 +6013,7 @@ class ObjectEntity extends ExpressionEntity {
6006
6013
  if (this.prototypeExpression) {
6007
6014
  return this.prototypeExpression.getReturnExpressionWhenCalledAtPath(path, interaction, recursionTracker, origin);
6008
6015
  }
6009
- return UNKNOWN_EXPRESSION;
6016
+ return UNKNOWN_RETURN_EXPRESSION;
6010
6017
  }
6011
6018
  hasEffectsOnInteractionAtPath(path, interaction, context) {
6012
6019
  const [key, ...subPath] = path;
@@ -6478,12 +6485,12 @@ class LocalVariable extends Variable {
6478
6485
  }
6479
6486
  getReturnExpressionWhenCalledAtPath(path, interaction, recursionTracker, origin) {
6480
6487
  if (this.isReassigned || !this.init) {
6481
- return UNKNOWN_EXPRESSION;
6488
+ return UNKNOWN_RETURN_EXPRESSION;
6482
6489
  }
6483
6490
  return recursionTracker.withTrackedEntityAtPath(path, this.init, () => {
6484
6491
  this.expressionsToBeDeoptimized.push(origin);
6485
6492
  return this.init.getReturnExpressionWhenCalledAtPath(path, interaction, recursionTracker, origin);
6486
- }, UNKNOWN_EXPRESSION);
6493
+ }, UNKNOWN_RETURN_EXPRESSION);
6487
6494
  }
6488
6495
  hasEffectsOnInteractionAtPath(path, interaction, context) {
6489
6496
  switch (interaction.type) {
@@ -6840,6 +6847,19 @@ function is_reference (node, parent) {
6840
6847
  return false;
6841
6848
  }
6842
6849
 
6850
+ const PureFunctionKey = Symbol('PureFunction');
6851
+ const getPureFunctions = ({ treeshake }) => {
6852
+ const pureFunctions = Object.create(null);
6853
+ for (const functionName of treeshake ? treeshake.manualPureFunctions : []) {
6854
+ let currentFunctions = pureFunctions;
6855
+ for (const pathSegment of functionName.split('.')) {
6856
+ currentFunctions = currentFunctions[pathSegment] || (currentFunctions[pathSegment] = Object.create(null));
6857
+ }
6858
+ currentFunctions[PureFunctionKey] = true;
6859
+ }
6860
+ return pureFunctions;
6861
+ };
6862
+
6843
6863
  /* eslint sort-keys: "off" */
6844
6864
  const ValueProperties = Symbol('Value Properties');
6845
6865
  const getTruthyLiteralValue = () => UnknownTruthyValue;
@@ -7818,7 +7838,8 @@ class Identifier extends NodeBase {
7818
7838
  return this.getVariableRespectingTDZ().getLiteralValueAtPath(path, recursionTracker, origin);
7819
7839
  }
7820
7840
  getReturnExpressionWhenCalledAtPath(path, interaction, recursionTracker, origin) {
7821
- return this.getVariableRespectingTDZ().getReturnExpressionWhenCalledAtPath(path, interaction, recursionTracker, origin);
7841
+ const [expression, isPure] = this.getVariableRespectingTDZ().getReturnExpressionWhenCalledAtPath(path, interaction, recursionTracker, origin);
7842
+ return [expression, isPure || this.isPureFunction(path)];
7822
7843
  }
7823
7844
  hasEffects(context) {
7824
7845
  if (!this.deoptimized)
@@ -7828,19 +7849,22 @@ class Identifier extends NodeBase {
7828
7849
  }
7829
7850
  return (this.context.options.treeshake.unknownGlobalSideEffects &&
7830
7851
  this.variable instanceof GlobalVariable &&
7852
+ !this.isPureFunction(EMPTY_PATH) &&
7831
7853
  this.variable.hasEffectsOnInteractionAtPath(EMPTY_PATH, NODE_INTERACTION_UNKNOWN_ACCESS, context));
7832
7854
  }
7833
7855
  hasEffectsOnInteractionAtPath(path, interaction, context) {
7834
7856
  switch (interaction.type) {
7835
7857
  case INTERACTION_ACCESSED: {
7836
7858
  return (this.variable !== null &&
7859
+ !this.isPureFunction(path) &&
7837
7860
  this.getVariableRespectingTDZ().hasEffectsOnInteractionAtPath(path, interaction, context));
7838
7861
  }
7839
7862
  case INTERACTION_ASSIGNED: {
7840
7863
  return (path.length > 0 ? this.getVariableRespectingTDZ() : this.variable).hasEffectsOnInteractionAtPath(path, interaction, context);
7841
7864
  }
7842
7865
  case INTERACTION_CALLED: {
7843
- return this.getVariableRespectingTDZ().hasEffectsOnInteractionAtPath(path, interaction, context);
7866
+ return (!this.isPureFunction(path) &&
7867
+ this.getVariableRespectingTDZ().hasEffectsOnInteractionAtPath(path, interaction, context));
7844
7868
  }
7845
7869
  }
7846
7870
  }
@@ -7922,6 +7946,21 @@ class Identifier extends NodeBase {
7922
7946
  }
7923
7947
  return this.variable;
7924
7948
  }
7949
+ isPureFunction(path) {
7950
+ let currentPureFunction = this.context.manualPureFunctions[this.name];
7951
+ for (const segment of path) {
7952
+ if (currentPureFunction) {
7953
+ if (currentPureFunction[PureFunctionKey]) {
7954
+ return true;
7955
+ }
7956
+ currentPureFunction = currentPureFunction[segment];
7957
+ }
7958
+ else {
7959
+ return false;
7960
+ }
7961
+ }
7962
+ return currentPureFunction?.[PureFunctionKey];
7963
+ }
7925
7964
  }
7926
7965
  function closestParentFunctionOrProgram(node) {
7927
7966
  while (node && !/^Program|Function/.test(node.type)) {
@@ -8243,9 +8282,9 @@ class FunctionBase extends NodeBase {
8243
8282
  this.scope.getReturnExpression().deoptimizePath(UNKNOWN_PATH);
8244
8283
  this.context.requestTreeshakingPass();
8245
8284
  }
8246
- return UNKNOWN_EXPRESSION;
8285
+ return UNKNOWN_RETURN_EXPRESSION;
8247
8286
  }
8248
- return this.scope.getReturnExpression();
8287
+ return [this.scope.getReturnExpression(), false];
8249
8288
  }
8250
8289
  hasEffectsOnInteractionAtPath(path, interaction, context) {
8251
8290
  if (path.length > 0 || interaction.type !== INTERACTION_CALLED) {
@@ -8844,7 +8883,7 @@ class Literal extends NodeBase {
8844
8883
  }
8845
8884
  getReturnExpressionWhenCalledAtPath(path) {
8846
8885
  if (path.length !== 1)
8847
- return UNKNOWN_EXPRESSION;
8886
+ return UNKNOWN_RETURN_EXPRESSION;
8848
8887
  return getMemberReturnExpressionWhenCalled(this.members, path[0]);
8849
8888
  }
8850
8889
  hasEffectsOnInteractionAtPath(path, interaction, context) {
@@ -8997,13 +9036,13 @@ class MemberExpression extends NodeBase {
8997
9036
  return this.variable.getReturnExpressionWhenCalledAtPath(path, interaction, recursionTracker, origin);
8998
9037
  }
8999
9038
  if (this.isUndefined) {
9000
- return UNDEFINED_EXPRESSION;
9039
+ return [UNDEFINED_EXPRESSION, false];
9001
9040
  }
9002
9041
  this.expressionsToBeDeoptimized.push(origin);
9003
9042
  if (path.length < MAX_PATH_DEPTH) {
9004
9043
  return this.object.getReturnExpressionWhenCalledAtPath([this.getPropertyKey(), ...path], interaction, recursionTracker, origin);
9005
9044
  }
9006
- return UNKNOWN_EXPRESSION;
9045
+ return UNKNOWN_RETURN_EXPRESSION;
9007
9046
  }
9008
9047
  hasEffects(context) {
9009
9048
  if (!this.deoptimized)
@@ -9180,8 +9219,8 @@ class CallExpressionBase extends NodeBase {
9180
9219
  this.expressionsToBeDeoptimized = new Set();
9181
9220
  }
9182
9221
  deoptimizeCache() {
9183
- if (this.returnExpression !== UNKNOWN_EXPRESSION) {
9184
- this.returnExpression = UNKNOWN_EXPRESSION;
9222
+ if (this.returnExpression?.[0] !== UNKNOWN_EXPRESSION) {
9223
+ this.returnExpression = UNKNOWN_RETURN_EXPRESSION;
9185
9224
  for (const expression of this.deoptimizableDependentExpressions) {
9186
9225
  expression.deoptimizeCache();
9187
9226
  }
@@ -9195,13 +9234,15 @@ class CallExpressionBase extends NodeBase {
9195
9234
  this.context.deoptimizationTracker.trackEntityAtPathAndGetIfTracked(path, this)) {
9196
9235
  return;
9197
9236
  }
9198
- const returnExpression = this.getReturnExpression();
9237
+ const [returnExpression] = this.getReturnExpression();
9199
9238
  if (returnExpression !== UNKNOWN_EXPRESSION) {
9200
9239
  returnExpression.deoptimizePath(path);
9201
9240
  }
9202
9241
  }
9203
9242
  deoptimizeThisOnInteractionAtPath(interaction, path, recursionTracker) {
9204
- const returnExpression = this.getReturnExpression(recursionTracker);
9243
+ const [returnExpression, isPure] = this.getReturnExpression(recursionTracker);
9244
+ if (isPure)
9245
+ return;
9205
9246
  if (returnExpression === UNKNOWN_EXPRESSION) {
9206
9247
  interaction.thisArg.deoptimizePath(UNKNOWN_PATH);
9207
9248
  }
@@ -9213,7 +9254,7 @@ class CallExpressionBase extends NodeBase {
9213
9254
  }
9214
9255
  }
9215
9256
  getLiteralValueAtPath(path, recursionTracker, origin) {
9216
- const returnExpression = this.getReturnExpression(recursionTracker);
9257
+ const [returnExpression] = this.getReturnExpression(recursionTracker);
9217
9258
  if (returnExpression === UNKNOWN_EXPRESSION) {
9218
9259
  return UnknownValue;
9219
9260
  }
@@ -9224,13 +9265,14 @@ class CallExpressionBase extends NodeBase {
9224
9265
  }
9225
9266
  getReturnExpressionWhenCalledAtPath(path, interaction, recursionTracker, origin) {
9226
9267
  const returnExpression = this.getReturnExpression(recursionTracker);
9227
- if (this.returnExpression === UNKNOWN_EXPRESSION) {
9228
- return UNKNOWN_EXPRESSION;
9268
+ if (returnExpression[0] === UNKNOWN_EXPRESSION) {
9269
+ return returnExpression;
9229
9270
  }
9230
9271
  return recursionTracker.withTrackedEntityAtPath(path, returnExpression, () => {
9231
9272
  this.deoptimizableDependentExpressions.push(origin);
9232
- return returnExpression.getReturnExpressionWhenCalledAtPath(path, interaction, recursionTracker, origin);
9233
- }, UNKNOWN_EXPRESSION);
9273
+ const [expression, isPure] = returnExpression[0].getReturnExpressionWhenCalledAtPath(path, interaction, recursionTracker, origin);
9274
+ return [expression, isPure || returnExpression[1]];
9275
+ }, UNKNOWN_RETURN_EXPRESSION);
9234
9276
  }
9235
9277
  hasEffectsOnInteractionAtPath(path, interaction, context) {
9236
9278
  const { type } = interaction;
@@ -9245,7 +9287,9 @@ class CallExpressionBase extends NodeBase {
9245
9287
  : context.accessed).trackEntityAtPathAndGetIfTracked(path, this)) {
9246
9288
  return false;
9247
9289
  }
9248
- return this.getReturnExpression().hasEffectsOnInteractionAtPath(path, interaction, context);
9290
+ const [returnExpression, isPure] = this.getReturnExpression();
9291
+ return ((type === INTERACTION_ASSIGNED || !isPure) &&
9292
+ returnExpression.hasEffectsOnInteractionAtPath(path, interaction, context));
9249
9293
  }
9250
9294
  }
9251
9295
 
@@ -9324,7 +9368,7 @@ class CallExpression extends CallExpressionBase {
9324
9368
  }
9325
9369
  getReturnExpression(recursionTracker = SHARED_RECURSION_TRACKER) {
9326
9370
  if (this.returnExpression === null) {
9327
- this.returnExpression = UNKNOWN_EXPRESSION;
9371
+ this.returnExpression = UNKNOWN_RETURN_EXPRESSION;
9328
9372
  return (this.returnExpression = this.callee.getReturnExpressionWhenCalledAtPath(EMPTY_PATH, this.interaction, recursionTracker, this));
9329
9373
  }
9330
9374
  return this.returnExpression;
@@ -9408,7 +9452,7 @@ class MethodBase extends NodeBase {
9408
9452
  // expressions, there is no known situation where a getter is deoptimized.
9409
9453
  deoptimizeCache() { }
9410
9454
  deoptimizePath(path) {
9411
- this.getAccessedValue().deoptimizePath(path);
9455
+ this.getAccessedValue()[0].deoptimizePath(path);
9412
9456
  }
9413
9457
  deoptimizeThisOnInteractionAtPath(interaction, path, recursionTracker) {
9414
9458
  if (interaction.type === INTERACTION_ACCESSED && this.kind === 'get' && path.length === 0) {
@@ -9427,13 +9471,13 @@ class MethodBase extends NodeBase {
9427
9471
  withNew: false
9428
9472
  }, EMPTY_PATH, recursionTracker);
9429
9473
  }
9430
- this.getAccessedValue().deoptimizeThisOnInteractionAtPath(interaction, path, recursionTracker);
9474
+ this.getAccessedValue()[0].deoptimizeThisOnInteractionAtPath(interaction, path, recursionTracker);
9431
9475
  }
9432
9476
  getLiteralValueAtPath(path, recursionTracker, origin) {
9433
- return this.getAccessedValue().getLiteralValueAtPath(path, recursionTracker, origin);
9477
+ return this.getAccessedValue()[0].getLiteralValueAtPath(path, recursionTracker, origin);
9434
9478
  }
9435
9479
  getReturnExpressionWhenCalledAtPath(path, interaction, recursionTracker, origin) {
9436
- return this.getAccessedValue().getReturnExpressionWhenCalledAtPath(path, interaction, recursionTracker, origin);
9480
+ return this.getAccessedValue()[0].getReturnExpressionWhenCalledAtPath(path, interaction, recursionTracker, origin);
9437
9481
  }
9438
9482
  hasEffects(context) {
9439
9483
  return this.key.hasEffects(context);
@@ -9456,17 +9500,17 @@ class MethodBase extends NodeBase {
9456
9500
  withNew: false
9457
9501
  }, context);
9458
9502
  }
9459
- return this.getAccessedValue().hasEffectsOnInteractionAtPath(path, interaction, context);
9503
+ return this.getAccessedValue()[0].hasEffectsOnInteractionAtPath(path, interaction, context);
9460
9504
  }
9461
9505
  applyDeoptimizations() { }
9462
9506
  getAccessedValue() {
9463
9507
  if (this.accessedValue === null) {
9464
9508
  if (this.kind === 'get') {
9465
- this.accessedValue = UNKNOWN_EXPRESSION;
9509
+ this.accessedValue = UNKNOWN_RETURN_EXPRESSION;
9466
9510
  return (this.accessedValue = this.value.getReturnExpressionWhenCalledAtPath(EMPTY_PATH, NODE_INTERACTION_UNKNOWN_CALL, SHARED_RECURSION_TRACKER, this));
9467
9511
  }
9468
9512
  else {
9469
- return (this.accessedValue = this.value);
9513
+ return (this.accessedValue = [this.value, false]);
9470
9514
  }
9471
9515
  }
9472
9516
  return this.accessedValue;
@@ -9679,7 +9723,10 @@ class MultiExpression extends ExpressionEntity {
9679
9723
  }
9680
9724
  }
9681
9725
  getReturnExpressionWhenCalledAtPath(path, interaction, recursionTracker, origin) {
9682
- return new MultiExpression(this.expressions.map(expression => expression.getReturnExpressionWhenCalledAtPath(path, interaction, recursionTracker, origin)));
9726
+ return [
9727
+ new MultiExpression(this.expressions.map(expression => expression.getReturnExpressionWhenCalledAtPath(path, interaction, recursionTracker, origin)[0])),
9728
+ false
9729
+ ];
9683
9730
  }
9684
9731
  hasEffectsOnInteractionAtPath(path, interaction, context) {
9685
9732
  for (const expression of this.expressions) {
@@ -9731,10 +9778,13 @@ class ConditionalExpression extends NodeBase {
9731
9778
  getReturnExpressionWhenCalledAtPath(path, interaction, recursionTracker, origin) {
9732
9779
  const usedBranch = this.getUsedBranch();
9733
9780
  if (!usedBranch)
9734
- return new MultiExpression([
9735
- this.consequent.getReturnExpressionWhenCalledAtPath(path, interaction, recursionTracker, origin),
9736
- this.alternate.getReturnExpressionWhenCalledAtPath(path, interaction, recursionTracker, origin)
9737
- ]);
9781
+ return [
9782
+ new MultiExpression([
9783
+ this.consequent.getReturnExpressionWhenCalledAtPath(path, interaction, recursionTracker, origin)[0],
9784
+ this.alternate.getReturnExpressionWhenCalledAtPath(path, interaction, recursionTracker, origin)[0]
9785
+ ]),
9786
+ false
9787
+ ];
9738
9788
  this.expressionsToBeDeoptimized.push(origin);
9739
9789
  return usedBranch.getReturnExpressionWhenCalledAtPath(path, interaction, recursionTracker, origin);
9740
9790
  }
@@ -10859,10 +10909,13 @@ class LogicalExpression extends NodeBase {
10859
10909
  getReturnExpressionWhenCalledAtPath(path, interaction, recursionTracker, origin) {
10860
10910
  const usedBranch = this.getUsedBranch();
10861
10911
  if (!usedBranch)
10862
- return new MultiExpression([
10863
- this.left.getReturnExpressionWhenCalledAtPath(path, interaction, recursionTracker, origin),
10864
- this.right.getReturnExpressionWhenCalledAtPath(path, interaction, recursionTracker, origin)
10865
- ]);
10912
+ return [
10913
+ new MultiExpression([
10914
+ this.left.getReturnExpressionWhenCalledAtPath(path, interaction, recursionTracker, origin)[0],
10915
+ this.right.getReturnExpressionWhenCalledAtPath(path, interaction, recursionTracker, origin)[0]
10916
+ ]),
10917
+ false
10918
+ ];
10866
10919
  this.expressionsToBeDeoptimized.push(origin);
10867
10920
  return usedBranch.getReturnExpressionWhenCalledAtPath(path, interaction, recursionTracker, origin);
10868
10921
  }
@@ -11288,7 +11341,7 @@ class PropertyDefinition extends NodeBase {
11288
11341
  getReturnExpressionWhenCalledAtPath(path, interaction, recursionTracker, origin) {
11289
11342
  return this.value
11290
11343
  ? this.value.getReturnExpressionWhenCalledAtPath(path, interaction, recursionTracker, origin)
11291
- : UNKNOWN_EXPRESSION;
11344
+ : UNKNOWN_RETURN_EXPRESSION;
11292
11345
  }
11293
11346
  hasEffects(context) {
11294
11347
  return this.key.hasEffects(context) || (this.static && !!this.value?.hasEffects(context));
@@ -11579,7 +11632,7 @@ class TaggedTemplateExpression extends CallExpressionBase {
11579
11632
  this.quasi.include(context, includeChildrenRecursively);
11580
11633
  }
11581
11634
  this.tag.includeCallArguments(context, this.interaction.args);
11582
- const returnExpression = this.getReturnExpression();
11635
+ const [returnExpression] = this.getReturnExpression();
11583
11636
  if (!returnExpression.included) {
11584
11637
  returnExpression.include(context, false);
11585
11638
  }
@@ -11609,7 +11662,7 @@ class TaggedTemplateExpression extends CallExpressionBase {
11609
11662
  }
11610
11663
  getReturnExpression(recursionTracker = SHARED_RECURSION_TRACKER) {
11611
11664
  if (this.returnExpression === null) {
11612
- this.returnExpression = UNKNOWN_EXPRESSION;
11665
+ this.returnExpression = UNKNOWN_RETURN_EXPRESSION;
11613
11666
  return (this.returnExpression = this.tag.getReturnExpressionWhenCalledAtPath(EMPTY_PATH, this.interaction, recursionTracker, this));
11614
11667
  }
11615
11668
  return this.returnExpression;
@@ -11642,7 +11695,7 @@ class TemplateLiteral extends NodeBase {
11642
11695
  }
11643
11696
  getReturnExpressionWhenCalledAtPath(path) {
11644
11697
  if (path.length !== 1) {
11645
- return UNKNOWN_EXPRESSION;
11698
+ return UNKNOWN_RETURN_EXPRESSION;
11646
11699
  }
11647
11700
  return getMemberReturnExpressionWhenCalled(literalStringMembers, path[0]);
11648
11701
  }
@@ -13086,7 +13139,9 @@ class Module {
13086
13139
  this.includeAllExports(false);
13087
13140
  }
13088
13141
  isIncluded() {
13089
- return this.ast.included || this.namespace.included || this.importedFromNotTreeshaken;
13142
+ // Modules where this.ast is missing have been loaded via this.load and are
13143
+ // not yet fully processed, hence they cannot be included.
13144
+ return (this.ast && (this.ast.included || this.namespace.included || this.importedFromNotTreeshaken));
13090
13145
  }
13091
13146
  linkImports() {
13092
13147
  this.addModulesToImportDescriptions(this.importDescriptions);
@@ -13156,6 +13211,7 @@ class Module {
13156
13211
  includeDynamicImport: this.includeDynamicImport.bind(this),
13157
13212
  includeVariableInModule: this.includeVariableInModule.bind(this),
13158
13213
  magicString: this.magicString,
13214
+ manualPureFunctions: this.graph.pureFunctions,
13159
13215
  module: this,
13160
13216
  moduleContext: this.context,
13161
13217
  options: this.options,
@@ -23477,6 +23533,7 @@ class Graph {
23477
23533
  this.acornParser = Parser.extend(...options.acornInjectPlugins);
23478
23534
  this.moduleLoader = new ModuleLoader(this, this.modulesById, this.options, this.pluginDriver);
23479
23535
  this.fileOperationQueue = new Queue(options.maxParallelFileOps);
23536
+ this.pureFunctions = getPureFunctions(options);
23480
23537
  }
23481
23538
  async build() {
23482
23539
  timeStart('generate module graph', 2);
@@ -23976,6 +24033,7 @@ const treeshakePresets = {
23976
24033
  recommended: {
23977
24034
  annotations: true,
23978
24035
  correctVarValueBeforeDeclaration: false,
24036
+ manualPureFunctions: EMPTY_ARRAY,
23979
24037
  moduleSideEffects: () => true,
23980
24038
  propertyReadSideEffects: true,
23981
24039
  tryCatchDeoptimization: true,
@@ -23984,6 +24042,7 @@ const treeshakePresets = {
23984
24042
  safest: {
23985
24043
  annotations: true,
23986
24044
  correctVarValueBeforeDeclaration: true,
24045
+ manualPureFunctions: EMPTY_ARRAY,
23987
24046
  moduleSideEffects: () => true,
23988
24047
  propertyReadSideEffects: true,
23989
24048
  tryCatchDeoptimization: true,
@@ -23992,6 +24051,7 @@ const treeshakePresets = {
23992
24051
  smallest: {
23993
24052
  annotations: true,
23994
24053
  correctVarValueBeforeDeclaration: false,
24054
+ manualPureFunctions: EMPTY_ARRAY,
23995
24055
  moduleSideEffects: () => false,
23996
24056
  propertyReadSideEffects: false,
23997
24057
  tryCatchDeoptimization: false,
@@ -24188,6 +24248,7 @@ const getTreeshake = (config) => {
24188
24248
  return {
24189
24249
  annotations: configWithPreset.annotations !== false,
24190
24250
  correctVarValueBeforeDeclaration: configWithPreset.correctVarValueBeforeDeclaration === true,
24251
+ manualPureFunctions: configWithPreset.manualPureFunctions ?? EMPTY_ARRAY,
24191
24252
  moduleSideEffects: getHasModuleSideEffects(configWithPreset.moduleSideEffects),
24192
24253
  propertyReadSideEffects: configWithPreset.propertyReadSideEffects === 'always'
24193
24254
  ? 'always'
@@ -1,7 +1,7 @@
1
1
  /*
2
2
  @license
3
- Rollup.js v3.4.0
4
- Tue, 22 Nov 2022 05:15:54 GMT - commit 780e3421e8a498f3248fd7d8506e97fcee8dd1e6
3
+ Rollup.js v3.5.0
4
+ Sun, 27 Nov 2022 06:34:25 GMT - commit 290b07d3685e8d4b4f3f5d3d673d41995d504239
5
5
 
6
6
  https://github.com/rollup/rollup
7
7
 
@@ -1,7 +1,7 @@
1
1
  /*
2
2
  @license
3
- Rollup.js v3.4.0
4
- Tue, 22 Nov 2022 05:15:54 GMT - commit 780e3421e8a498f3248fd7d8506e97fcee8dd1e6
3
+ Rollup.js v3.5.0
4
+ Sun, 27 Nov 2022 06:34:25 GMT - commit 290b07d3685e8d4b4f3f5d3d673d41995d504239
5
5
 
6
6
  https://github.com/rollup/rollup
7
7
 
package/dist/rollup.d.ts CHANGED
@@ -466,6 +466,7 @@ type TreeshakingPreset = 'smallest' | 'safest' | 'recommended';
466
466
  export interface NormalizedTreeshakingOptions {
467
467
  annotations: boolean;
468
468
  correctVarValueBeforeDeclaration: boolean;
469
+ manualPureFunctions: readonly string[];
469
470
  moduleSideEffects: HasModuleSideEffects;
470
471
  propertyReadSideEffects: boolean | 'always';
471
472
  tryCatchDeoptimization: boolean;
package/dist/rollup.js CHANGED
@@ -1,7 +1,7 @@
1
1
  /*
2
2
  @license
3
- Rollup.js v3.4.0
4
- Tue, 22 Nov 2022 05:15:54 GMT - commit 780e3421e8a498f3248fd7d8506e97fcee8dd1e6
3
+ Rollup.js v3.5.0
4
+ Sun, 27 Nov 2022 06:34:25 GMT - commit 290b07d3685e8d4b4f3f5d3d673d41995d504239
5
5
 
6
6
  https://github.com/rollup/rollup
7
7
 
@@ -1,7 +1,7 @@
1
1
  /*
2
2
  @license
3
- Rollup.js v3.4.0
4
- Tue, 22 Nov 2022 05:15:54 GMT - commit 780e3421e8a498f3248fd7d8506e97fcee8dd1e6
3
+ Rollup.js v3.5.0
4
+ Sun, 27 Nov 2022 06:34:25 GMT - commit 290b07d3685e8d4b4f3f5d3d673d41995d504239
5
5
 
6
6
  https://github.com/rollup/rollup
7
7
 
@@ -1,7 +1,7 @@
1
1
  /*
2
2
  @license
3
- Rollup.js v3.4.0
4
- Tue, 22 Nov 2022 05:15:54 GMT - commit 780e3421e8a498f3248fd7d8506e97fcee8dd1e6
3
+ Rollup.js v3.5.0
4
+ Sun, 27 Nov 2022 06:34:25 GMT - commit 290b07d3685e8d4b4f3f5d3d673d41995d504239
5
5
 
6
6
  https://github.com/rollup/rollup
7
7
 
@@ -1,7 +1,7 @@
1
1
  /*
2
2
  @license
3
- Rollup.js v3.4.0
4
- Tue, 22 Nov 2022 05:15:54 GMT - commit 780e3421e8a498f3248fd7d8506e97fcee8dd1e6
3
+ Rollup.js v3.5.0
4
+ Sun, 27 Nov 2022 06:34:25 GMT - commit 290b07d3685e8d4b4f3f5d3d673d41995d504239
5
5
 
6
6
  https://github.com/rollup/rollup
7
7
 
@@ -31,7 +31,7 @@ function _interopNamespaceDefault(e) {
31
31
 
32
32
  const tty__namespace = /*#__PURE__*/_interopNamespaceDefault(tty);
33
33
 
34
- var version$1 = "3.4.0";
34
+ var version$1 = "3.5.0";
35
35
 
36
36
  function ensureArray$1(items) {
37
37
  if (Array.isArray(items)) {
@@ -50,6 +50,10 @@ async function asyncFlatten(array) {
50
50
  return array;
51
51
  }
52
52
 
53
+ const BLANK = Object.freeze(Object.create(null));
54
+ const EMPTY_OBJECT = Object.freeze({});
55
+ const EMPTY_ARRAY = Object.freeze([]);
56
+
53
57
  function getLocator$1(source, options) {
54
58
  if (options === void 0) { options = {}; }
55
59
  var offsetLine = options.offsetLine || 0;
@@ -814,6 +818,7 @@ const treeshakePresets = {
814
818
  recommended: {
815
819
  annotations: true,
816
820
  correctVarValueBeforeDeclaration: false,
821
+ manualPureFunctions: EMPTY_ARRAY,
817
822
  moduleSideEffects: () => true,
818
823
  propertyReadSideEffects: true,
819
824
  tryCatchDeoptimization: true,
@@ -822,6 +827,7 @@ const treeshakePresets = {
822
827
  safest: {
823
828
  annotations: true,
824
829
  correctVarValueBeforeDeclaration: true,
830
+ manualPureFunctions: EMPTY_ARRAY,
825
831
  moduleSideEffects: () => true,
826
832
  propertyReadSideEffects: true,
827
833
  tryCatchDeoptimization: true,
@@ -830,6 +836,7 @@ const treeshakePresets = {
830
836
  smallest: {
831
837
  annotations: true,
832
838
  correctVarValueBeforeDeclaration: false,
839
+ manualPureFunctions: EMPTY_ARRAY,
833
840
  moduleSideEffects: () => false,
834
841
  propertyReadSideEffects: false,
835
842
  tryCatchDeoptimization: false,
@@ -2916,7 +2923,7 @@ class ExpressionEntity {
2916
2923
  return UnknownValue;
2917
2924
  }
2918
2925
  getReturnExpressionWhenCalledAtPath(_path, _interaction, _recursionTracker, _origin) {
2919
- return UNKNOWN_EXPRESSION;
2926
+ return UNKNOWN_RETURN_EXPRESSION;
2920
2927
  }
2921
2928
  hasEffectsOnInteractionAtPath(_path, _interaction, _context) {
2922
2929
  return true;
@@ -2935,6 +2942,10 @@ class ExpressionEntity {
2935
2942
  }
2936
2943
  const UNKNOWN_EXPRESSION = new (class UnknownExpression extends ExpressionEntity {
2937
2944
  })();
2945
+ const UNKNOWN_RETURN_EXPRESSION = [
2946
+ UNKNOWN_EXPRESSION,
2947
+ false
2948
+ ];
2938
2949
 
2939
2950
  const INTERACTION_ACCESSED = 0;
2940
2951
  const INTERACTION_ASSIGNED = 1;
@@ -3035,10 +3046,6 @@ class ExternalVariable extends Variable {
3035
3046
  }
3036
3047
  }
3037
3048
 
3038
- const BLANK = Object.freeze(Object.create(null));
3039
- const EMPTY_OBJECT = Object.freeze({});
3040
- const EMPTY_ARRAY = Object.freeze([]);
3041
-
3042
3049
  const RESERVED_NAMES = new Set([
3043
3050
  'await',
3044
3051
  'break',
@@ -5442,7 +5449,7 @@ const UNKNOWN_LITERAL_BOOLEAN = new (class UnknownBoolean extends ExpressionEnti
5442
5449
  if (path.length === 1) {
5443
5450
  return getMemberReturnExpressionWhenCalled(literalBooleanMembers, path[0]);
5444
5451
  }
5445
- return UNKNOWN_EXPRESSION;
5452
+ return UNKNOWN_RETURN_EXPRESSION;
5446
5453
  }
5447
5454
  hasEffectsOnInteractionAtPath(path, interaction, context) {
5448
5455
  if (interaction.type === INTERACTION_ACCESSED) {
@@ -5465,7 +5472,7 @@ const UNKNOWN_LITERAL_NUMBER = new (class UnknownNumber extends ExpressionEntity
5465
5472
  if (path.length === 1) {
5466
5473
  return getMemberReturnExpressionWhenCalled(literalNumberMembers, path[0]);
5467
5474
  }
5468
- return UNKNOWN_EXPRESSION;
5475
+ return UNKNOWN_RETURN_EXPRESSION;
5469
5476
  }
5470
5477
  hasEffectsOnInteractionAtPath(path, interaction, context) {
5471
5478
  if (interaction.type === INTERACTION_ACCESSED) {
@@ -5488,7 +5495,7 @@ const UNKNOWN_LITERAL_STRING = new (class UnknownString extends ExpressionEntity
5488
5495
  if (path.length === 1) {
5489
5496
  return getMemberReturnExpressionWhenCalled(literalStringMembers, path[0]);
5490
5497
  }
5491
- return UNKNOWN_EXPRESSION;
5498
+ return UNKNOWN_RETURN_EXPRESSION;
5492
5499
  }
5493
5500
  hasEffectsOnInteractionAtPath(path, interaction, context) {
5494
5501
  if (interaction.type === INTERACTION_ACCESSED) {
@@ -5609,8 +5616,8 @@ function hasMemberEffectWhenCalled(members, memberName, interaction, context) {
5609
5616
  }
5610
5617
  function getMemberReturnExpressionWhenCalled(members, memberName) {
5611
5618
  if (typeof memberName !== 'string' || !members[memberName])
5612
- return UNKNOWN_EXPRESSION;
5613
- return members[memberName].returns;
5619
+ return UNKNOWN_RETURN_EXPRESSION;
5620
+ return [members[memberName].returns, false];
5614
5621
  }
5615
5622
 
5616
5623
  // AST walker module for Mozilla Parser API compatible trees
@@ -6260,12 +6267,15 @@ class Method extends ExpressionEntity {
6260
6267
  }
6261
6268
  getReturnExpressionWhenCalledAtPath(path, { thisArg }) {
6262
6269
  if (path.length > 0) {
6263
- return UNKNOWN_EXPRESSION;
6270
+ return UNKNOWN_RETURN_EXPRESSION;
6264
6271
  }
6265
- return (this.description.returnsPrimitive ||
6266
- (this.description.returns === 'self'
6267
- ? thisArg || UNKNOWN_EXPRESSION
6268
- : this.description.returns()));
6272
+ return [
6273
+ this.description.returnsPrimitive ||
6274
+ (this.description.returns === 'self'
6275
+ ? thisArg || UNKNOWN_EXPRESSION
6276
+ : this.description.returns()),
6277
+ false
6278
+ ];
6269
6279
  }
6270
6280
  hasEffectsOnInteractionAtPath(path, interaction, context) {
6271
6281
  const { type } = interaction;
@@ -6508,7 +6518,7 @@ class ObjectEntity extends ExpressionEntity {
6508
6518
  }
6509
6519
  getReturnExpressionWhenCalledAtPath(path, interaction, recursionTracker, origin) {
6510
6520
  if (path.length === 0) {
6511
- return UNKNOWN_EXPRESSION;
6521
+ return UNKNOWN_RETURN_EXPRESSION;
6512
6522
  }
6513
6523
  const [key, ...subPath] = path;
6514
6524
  const expressionAtPath = this.getMemberExpressionAndTrackDeopt(key, origin);
@@ -6518,7 +6528,7 @@ class ObjectEntity extends ExpressionEntity {
6518
6528
  if (this.prototypeExpression) {
6519
6529
  return this.prototypeExpression.getReturnExpressionWhenCalledAtPath(path, interaction, recursionTracker, origin);
6520
6530
  }
6521
- return UNKNOWN_EXPRESSION;
6531
+ return UNKNOWN_RETURN_EXPRESSION;
6522
6532
  }
6523
6533
  hasEffectsOnInteractionAtPath(path, interaction, context) {
6524
6534
  const [key, ...subPath] = path;
@@ -6990,12 +7000,12 @@ class LocalVariable extends Variable {
6990
7000
  }
6991
7001
  getReturnExpressionWhenCalledAtPath(path, interaction, recursionTracker, origin) {
6992
7002
  if (this.isReassigned || !this.init) {
6993
- return UNKNOWN_EXPRESSION;
7003
+ return UNKNOWN_RETURN_EXPRESSION;
6994
7004
  }
6995
7005
  return recursionTracker.withTrackedEntityAtPath(path, this.init, () => {
6996
7006
  this.expressionsToBeDeoptimized.push(origin);
6997
7007
  return this.init.getReturnExpressionWhenCalledAtPath(path, interaction, recursionTracker, origin);
6998
- }, UNKNOWN_EXPRESSION);
7008
+ }, UNKNOWN_RETURN_EXPRESSION);
6999
7009
  }
7000
7010
  hasEffectsOnInteractionAtPath(path, interaction, context) {
7001
7011
  switch (interaction.type) {
@@ -7352,6 +7362,19 @@ function is_reference (node, parent) {
7352
7362
  return false;
7353
7363
  }
7354
7364
 
7365
+ const PureFunctionKey = Symbol('PureFunction');
7366
+ const getPureFunctions = ({ treeshake }) => {
7367
+ const pureFunctions = Object.create(null);
7368
+ for (const functionName of treeshake ? treeshake.manualPureFunctions : []) {
7369
+ let currentFunctions = pureFunctions;
7370
+ for (const pathSegment of functionName.split('.')) {
7371
+ currentFunctions = currentFunctions[pathSegment] || (currentFunctions[pathSegment] = Object.create(null));
7372
+ }
7373
+ currentFunctions[PureFunctionKey] = true;
7374
+ }
7375
+ return pureFunctions;
7376
+ };
7377
+
7355
7378
  /* eslint sort-keys: "off" */
7356
7379
  const ValueProperties = Symbol('Value Properties');
7357
7380
  const getTruthyLiteralValue = () => UnknownTruthyValue;
@@ -8330,7 +8353,8 @@ class Identifier extends NodeBase {
8330
8353
  return this.getVariableRespectingTDZ().getLiteralValueAtPath(path, recursionTracker, origin);
8331
8354
  }
8332
8355
  getReturnExpressionWhenCalledAtPath(path, interaction, recursionTracker, origin) {
8333
- return this.getVariableRespectingTDZ().getReturnExpressionWhenCalledAtPath(path, interaction, recursionTracker, origin);
8356
+ const [expression, isPure] = this.getVariableRespectingTDZ().getReturnExpressionWhenCalledAtPath(path, interaction, recursionTracker, origin);
8357
+ return [expression, isPure || this.isPureFunction(path)];
8334
8358
  }
8335
8359
  hasEffects(context) {
8336
8360
  if (!this.deoptimized)
@@ -8340,19 +8364,22 @@ class Identifier extends NodeBase {
8340
8364
  }
8341
8365
  return (this.context.options.treeshake.unknownGlobalSideEffects &&
8342
8366
  this.variable instanceof GlobalVariable &&
8367
+ !this.isPureFunction(EMPTY_PATH) &&
8343
8368
  this.variable.hasEffectsOnInteractionAtPath(EMPTY_PATH, NODE_INTERACTION_UNKNOWN_ACCESS, context));
8344
8369
  }
8345
8370
  hasEffectsOnInteractionAtPath(path, interaction, context) {
8346
8371
  switch (interaction.type) {
8347
8372
  case INTERACTION_ACCESSED: {
8348
8373
  return (this.variable !== null &&
8374
+ !this.isPureFunction(path) &&
8349
8375
  this.getVariableRespectingTDZ().hasEffectsOnInteractionAtPath(path, interaction, context));
8350
8376
  }
8351
8377
  case INTERACTION_ASSIGNED: {
8352
8378
  return (path.length > 0 ? this.getVariableRespectingTDZ() : this.variable).hasEffectsOnInteractionAtPath(path, interaction, context);
8353
8379
  }
8354
8380
  case INTERACTION_CALLED: {
8355
- return this.getVariableRespectingTDZ().hasEffectsOnInteractionAtPath(path, interaction, context);
8381
+ return (!this.isPureFunction(path) &&
8382
+ this.getVariableRespectingTDZ().hasEffectsOnInteractionAtPath(path, interaction, context));
8356
8383
  }
8357
8384
  }
8358
8385
  }
@@ -8434,6 +8461,21 @@ class Identifier extends NodeBase {
8434
8461
  }
8435
8462
  return this.variable;
8436
8463
  }
8464
+ isPureFunction(path) {
8465
+ let currentPureFunction = this.context.manualPureFunctions[this.name];
8466
+ for (const segment of path) {
8467
+ if (currentPureFunction) {
8468
+ if (currentPureFunction[PureFunctionKey]) {
8469
+ return true;
8470
+ }
8471
+ currentPureFunction = currentPureFunction[segment];
8472
+ }
8473
+ else {
8474
+ return false;
8475
+ }
8476
+ }
8477
+ return currentPureFunction?.[PureFunctionKey];
8478
+ }
8437
8479
  }
8438
8480
  function closestParentFunctionOrProgram(node) {
8439
8481
  while (node && !/^Program|Function/.test(node.type)) {
@@ -8755,9 +8797,9 @@ class FunctionBase extends NodeBase {
8755
8797
  this.scope.getReturnExpression().deoptimizePath(UNKNOWN_PATH);
8756
8798
  this.context.requestTreeshakingPass();
8757
8799
  }
8758
- return UNKNOWN_EXPRESSION;
8800
+ return UNKNOWN_RETURN_EXPRESSION;
8759
8801
  }
8760
- return this.scope.getReturnExpression();
8802
+ return [this.scope.getReturnExpression(), false];
8761
8803
  }
8762
8804
  hasEffectsOnInteractionAtPath(path, interaction, context) {
8763
8805
  if (path.length > 0 || interaction.type !== INTERACTION_CALLED) {
@@ -9356,7 +9398,7 @@ class Literal extends NodeBase {
9356
9398
  }
9357
9399
  getReturnExpressionWhenCalledAtPath(path) {
9358
9400
  if (path.length !== 1)
9359
- return UNKNOWN_EXPRESSION;
9401
+ return UNKNOWN_RETURN_EXPRESSION;
9360
9402
  return getMemberReturnExpressionWhenCalled(this.members, path[0]);
9361
9403
  }
9362
9404
  hasEffectsOnInteractionAtPath(path, interaction, context) {
@@ -9509,13 +9551,13 @@ class MemberExpression extends NodeBase {
9509
9551
  return this.variable.getReturnExpressionWhenCalledAtPath(path, interaction, recursionTracker, origin);
9510
9552
  }
9511
9553
  if (this.isUndefined) {
9512
- return UNDEFINED_EXPRESSION;
9554
+ return [UNDEFINED_EXPRESSION, false];
9513
9555
  }
9514
9556
  this.expressionsToBeDeoptimized.push(origin);
9515
9557
  if (path.length < MAX_PATH_DEPTH) {
9516
9558
  return this.object.getReturnExpressionWhenCalledAtPath([this.getPropertyKey(), ...path], interaction, recursionTracker, origin);
9517
9559
  }
9518
- return UNKNOWN_EXPRESSION;
9560
+ return UNKNOWN_RETURN_EXPRESSION;
9519
9561
  }
9520
9562
  hasEffects(context) {
9521
9563
  if (!this.deoptimized)
@@ -9692,8 +9734,8 @@ class CallExpressionBase extends NodeBase {
9692
9734
  this.expressionsToBeDeoptimized = new Set();
9693
9735
  }
9694
9736
  deoptimizeCache() {
9695
- if (this.returnExpression !== UNKNOWN_EXPRESSION) {
9696
- this.returnExpression = UNKNOWN_EXPRESSION;
9737
+ if (this.returnExpression?.[0] !== UNKNOWN_EXPRESSION) {
9738
+ this.returnExpression = UNKNOWN_RETURN_EXPRESSION;
9697
9739
  for (const expression of this.deoptimizableDependentExpressions) {
9698
9740
  expression.deoptimizeCache();
9699
9741
  }
@@ -9707,13 +9749,15 @@ class CallExpressionBase extends NodeBase {
9707
9749
  this.context.deoptimizationTracker.trackEntityAtPathAndGetIfTracked(path, this)) {
9708
9750
  return;
9709
9751
  }
9710
- const returnExpression = this.getReturnExpression();
9752
+ const [returnExpression] = this.getReturnExpression();
9711
9753
  if (returnExpression !== UNKNOWN_EXPRESSION) {
9712
9754
  returnExpression.deoptimizePath(path);
9713
9755
  }
9714
9756
  }
9715
9757
  deoptimizeThisOnInteractionAtPath(interaction, path, recursionTracker) {
9716
- const returnExpression = this.getReturnExpression(recursionTracker);
9758
+ const [returnExpression, isPure] = this.getReturnExpression(recursionTracker);
9759
+ if (isPure)
9760
+ return;
9717
9761
  if (returnExpression === UNKNOWN_EXPRESSION) {
9718
9762
  interaction.thisArg.deoptimizePath(UNKNOWN_PATH);
9719
9763
  }
@@ -9725,7 +9769,7 @@ class CallExpressionBase extends NodeBase {
9725
9769
  }
9726
9770
  }
9727
9771
  getLiteralValueAtPath(path, recursionTracker, origin) {
9728
- const returnExpression = this.getReturnExpression(recursionTracker);
9772
+ const [returnExpression] = this.getReturnExpression(recursionTracker);
9729
9773
  if (returnExpression === UNKNOWN_EXPRESSION) {
9730
9774
  return UnknownValue;
9731
9775
  }
@@ -9736,13 +9780,14 @@ class CallExpressionBase extends NodeBase {
9736
9780
  }
9737
9781
  getReturnExpressionWhenCalledAtPath(path, interaction, recursionTracker, origin) {
9738
9782
  const returnExpression = this.getReturnExpression(recursionTracker);
9739
- if (this.returnExpression === UNKNOWN_EXPRESSION) {
9740
- return UNKNOWN_EXPRESSION;
9783
+ if (returnExpression[0] === UNKNOWN_EXPRESSION) {
9784
+ return returnExpression;
9741
9785
  }
9742
9786
  return recursionTracker.withTrackedEntityAtPath(path, returnExpression, () => {
9743
9787
  this.deoptimizableDependentExpressions.push(origin);
9744
- return returnExpression.getReturnExpressionWhenCalledAtPath(path, interaction, recursionTracker, origin);
9745
- }, UNKNOWN_EXPRESSION);
9788
+ const [expression, isPure] = returnExpression[0].getReturnExpressionWhenCalledAtPath(path, interaction, recursionTracker, origin);
9789
+ return [expression, isPure || returnExpression[1]];
9790
+ }, UNKNOWN_RETURN_EXPRESSION);
9746
9791
  }
9747
9792
  hasEffectsOnInteractionAtPath(path, interaction, context) {
9748
9793
  const { type } = interaction;
@@ -9757,7 +9802,9 @@ class CallExpressionBase extends NodeBase {
9757
9802
  : context.accessed).trackEntityAtPathAndGetIfTracked(path, this)) {
9758
9803
  return false;
9759
9804
  }
9760
- return this.getReturnExpression().hasEffectsOnInteractionAtPath(path, interaction, context);
9805
+ const [returnExpression, isPure] = this.getReturnExpression();
9806
+ return ((type === INTERACTION_ASSIGNED || !isPure) &&
9807
+ returnExpression.hasEffectsOnInteractionAtPath(path, interaction, context));
9761
9808
  }
9762
9809
  }
9763
9810
 
@@ -9836,7 +9883,7 @@ class CallExpression extends CallExpressionBase {
9836
9883
  }
9837
9884
  getReturnExpression(recursionTracker = SHARED_RECURSION_TRACKER) {
9838
9885
  if (this.returnExpression === null) {
9839
- this.returnExpression = UNKNOWN_EXPRESSION;
9886
+ this.returnExpression = UNKNOWN_RETURN_EXPRESSION;
9840
9887
  return (this.returnExpression = this.callee.getReturnExpressionWhenCalledAtPath(EMPTY_PATH, this.interaction, recursionTracker, this));
9841
9888
  }
9842
9889
  return this.returnExpression;
@@ -9920,7 +9967,7 @@ class MethodBase extends NodeBase {
9920
9967
  // expressions, there is no known situation where a getter is deoptimized.
9921
9968
  deoptimizeCache() { }
9922
9969
  deoptimizePath(path) {
9923
- this.getAccessedValue().deoptimizePath(path);
9970
+ this.getAccessedValue()[0].deoptimizePath(path);
9924
9971
  }
9925
9972
  deoptimizeThisOnInteractionAtPath(interaction, path, recursionTracker) {
9926
9973
  if (interaction.type === INTERACTION_ACCESSED && this.kind === 'get' && path.length === 0) {
@@ -9939,13 +9986,13 @@ class MethodBase extends NodeBase {
9939
9986
  withNew: false
9940
9987
  }, EMPTY_PATH, recursionTracker);
9941
9988
  }
9942
- this.getAccessedValue().deoptimizeThisOnInteractionAtPath(interaction, path, recursionTracker);
9989
+ this.getAccessedValue()[0].deoptimizeThisOnInteractionAtPath(interaction, path, recursionTracker);
9943
9990
  }
9944
9991
  getLiteralValueAtPath(path, recursionTracker, origin) {
9945
- return this.getAccessedValue().getLiteralValueAtPath(path, recursionTracker, origin);
9992
+ return this.getAccessedValue()[0].getLiteralValueAtPath(path, recursionTracker, origin);
9946
9993
  }
9947
9994
  getReturnExpressionWhenCalledAtPath(path, interaction, recursionTracker, origin) {
9948
- return this.getAccessedValue().getReturnExpressionWhenCalledAtPath(path, interaction, recursionTracker, origin);
9995
+ return this.getAccessedValue()[0].getReturnExpressionWhenCalledAtPath(path, interaction, recursionTracker, origin);
9949
9996
  }
9950
9997
  hasEffects(context) {
9951
9998
  return this.key.hasEffects(context);
@@ -9968,17 +10015,17 @@ class MethodBase extends NodeBase {
9968
10015
  withNew: false
9969
10016
  }, context);
9970
10017
  }
9971
- return this.getAccessedValue().hasEffectsOnInteractionAtPath(path, interaction, context);
10018
+ return this.getAccessedValue()[0].hasEffectsOnInteractionAtPath(path, interaction, context);
9972
10019
  }
9973
10020
  applyDeoptimizations() { }
9974
10021
  getAccessedValue() {
9975
10022
  if (this.accessedValue === null) {
9976
10023
  if (this.kind === 'get') {
9977
- this.accessedValue = UNKNOWN_EXPRESSION;
10024
+ this.accessedValue = UNKNOWN_RETURN_EXPRESSION;
9978
10025
  return (this.accessedValue = this.value.getReturnExpressionWhenCalledAtPath(EMPTY_PATH, NODE_INTERACTION_UNKNOWN_CALL, SHARED_RECURSION_TRACKER, this));
9979
10026
  }
9980
10027
  else {
9981
- return (this.accessedValue = this.value);
10028
+ return (this.accessedValue = [this.value, false]);
9982
10029
  }
9983
10030
  }
9984
10031
  return this.accessedValue;
@@ -10191,7 +10238,10 @@ class MultiExpression extends ExpressionEntity {
10191
10238
  }
10192
10239
  }
10193
10240
  getReturnExpressionWhenCalledAtPath(path, interaction, recursionTracker, origin) {
10194
- return new MultiExpression(this.expressions.map(expression => expression.getReturnExpressionWhenCalledAtPath(path, interaction, recursionTracker, origin)));
10241
+ return [
10242
+ new MultiExpression(this.expressions.map(expression => expression.getReturnExpressionWhenCalledAtPath(path, interaction, recursionTracker, origin)[0])),
10243
+ false
10244
+ ];
10195
10245
  }
10196
10246
  hasEffectsOnInteractionAtPath(path, interaction, context) {
10197
10247
  for (const expression of this.expressions) {
@@ -10243,10 +10293,13 @@ class ConditionalExpression extends NodeBase {
10243
10293
  getReturnExpressionWhenCalledAtPath(path, interaction, recursionTracker, origin) {
10244
10294
  const usedBranch = this.getUsedBranch();
10245
10295
  if (!usedBranch)
10246
- return new MultiExpression([
10247
- this.consequent.getReturnExpressionWhenCalledAtPath(path, interaction, recursionTracker, origin),
10248
- this.alternate.getReturnExpressionWhenCalledAtPath(path, interaction, recursionTracker, origin)
10249
- ]);
10296
+ return [
10297
+ new MultiExpression([
10298
+ this.consequent.getReturnExpressionWhenCalledAtPath(path, interaction, recursionTracker, origin)[0],
10299
+ this.alternate.getReturnExpressionWhenCalledAtPath(path, interaction, recursionTracker, origin)[0]
10300
+ ]),
10301
+ false
10302
+ ];
10250
10303
  this.expressionsToBeDeoptimized.push(origin);
10251
10304
  return usedBranch.getReturnExpressionWhenCalledAtPath(path, interaction, recursionTracker, origin);
10252
10305
  }
@@ -11371,10 +11424,13 @@ class LogicalExpression extends NodeBase {
11371
11424
  getReturnExpressionWhenCalledAtPath(path, interaction, recursionTracker, origin) {
11372
11425
  const usedBranch = this.getUsedBranch();
11373
11426
  if (!usedBranch)
11374
- return new MultiExpression([
11375
- this.left.getReturnExpressionWhenCalledAtPath(path, interaction, recursionTracker, origin),
11376
- this.right.getReturnExpressionWhenCalledAtPath(path, interaction, recursionTracker, origin)
11377
- ]);
11427
+ return [
11428
+ new MultiExpression([
11429
+ this.left.getReturnExpressionWhenCalledAtPath(path, interaction, recursionTracker, origin)[0],
11430
+ this.right.getReturnExpressionWhenCalledAtPath(path, interaction, recursionTracker, origin)[0]
11431
+ ]),
11432
+ false
11433
+ ];
11378
11434
  this.expressionsToBeDeoptimized.push(origin);
11379
11435
  return usedBranch.getReturnExpressionWhenCalledAtPath(path, interaction, recursionTracker, origin);
11380
11436
  }
@@ -11800,7 +11856,7 @@ class PropertyDefinition extends NodeBase {
11800
11856
  getReturnExpressionWhenCalledAtPath(path, interaction, recursionTracker, origin) {
11801
11857
  return this.value
11802
11858
  ? this.value.getReturnExpressionWhenCalledAtPath(path, interaction, recursionTracker, origin)
11803
- : UNKNOWN_EXPRESSION;
11859
+ : UNKNOWN_RETURN_EXPRESSION;
11804
11860
  }
11805
11861
  hasEffects(context) {
11806
11862
  return this.key.hasEffects(context) || (this.static && !!this.value?.hasEffects(context));
@@ -12091,7 +12147,7 @@ class TaggedTemplateExpression extends CallExpressionBase {
12091
12147
  this.quasi.include(context, includeChildrenRecursively);
12092
12148
  }
12093
12149
  this.tag.includeCallArguments(context, this.interaction.args);
12094
- const returnExpression = this.getReturnExpression();
12150
+ const [returnExpression] = this.getReturnExpression();
12095
12151
  if (!returnExpression.included) {
12096
12152
  returnExpression.include(context, false);
12097
12153
  }
@@ -12121,7 +12177,7 @@ class TaggedTemplateExpression extends CallExpressionBase {
12121
12177
  }
12122
12178
  getReturnExpression(recursionTracker = SHARED_RECURSION_TRACKER) {
12123
12179
  if (this.returnExpression === null) {
12124
- this.returnExpression = UNKNOWN_EXPRESSION;
12180
+ this.returnExpression = UNKNOWN_RETURN_EXPRESSION;
12125
12181
  return (this.returnExpression = this.tag.getReturnExpressionWhenCalledAtPath(EMPTY_PATH, this.interaction, recursionTracker, this));
12126
12182
  }
12127
12183
  return this.returnExpression;
@@ -12154,7 +12210,7 @@ class TemplateLiteral extends NodeBase {
12154
12210
  }
12155
12211
  getReturnExpressionWhenCalledAtPath(path) {
12156
12212
  if (path.length !== 1) {
12157
- return UNKNOWN_EXPRESSION;
12213
+ return UNKNOWN_RETURN_EXPRESSION;
12158
12214
  }
12159
12215
  return getMemberReturnExpressionWhenCalled(literalStringMembers, path[0]);
12160
12216
  }
@@ -13598,7 +13654,9 @@ class Module {
13598
13654
  this.includeAllExports(false);
13599
13655
  }
13600
13656
  isIncluded() {
13601
- return this.ast.included || this.namespace.included || this.importedFromNotTreeshaken;
13657
+ // Modules where this.ast is missing have been loaded via this.load and are
13658
+ // not yet fully processed, hence they cannot be included.
13659
+ return (this.ast && (this.ast.included || this.namespace.included || this.importedFromNotTreeshaken));
13602
13660
  }
13603
13661
  linkImports() {
13604
13662
  this.addModulesToImportDescriptions(this.importDescriptions);
@@ -13668,6 +13726,7 @@ class Module {
13668
13726
  includeDynamicImport: this.includeDynamicImport.bind(this),
13669
13727
  includeVariableInModule: this.includeVariableInModule.bind(this),
13670
13728
  magicString: this.magicString,
13729
+ manualPureFunctions: this.graph.pureFunctions,
13671
13730
  module: this,
13672
13731
  moduleContext: this.context,
13673
13732
  options: this.options,
@@ -23989,6 +24048,7 @@ class Graph {
23989
24048
  this.acornParser = Parser.extend(...options.acornInjectPlugins);
23990
24049
  this.moduleLoader = new ModuleLoader(this, this.modulesById, this.options, this.pluginDriver);
23991
24050
  this.fileOperationQueue = new Queue(options.maxParallelFileOps);
24051
+ this.pureFunctions = getPureFunctions(options);
23992
24052
  }
23993
24053
  async build() {
23994
24054
  timeStart('generate module graph', 2);
@@ -24606,6 +24666,7 @@ const getTreeshake = (config) => {
24606
24666
  return {
24607
24667
  annotations: configWithPreset.annotations !== false,
24608
24668
  correctVarValueBeforeDeclaration: configWithPreset.correctVarValueBeforeDeclaration === true,
24669
+ manualPureFunctions: configWithPreset.manualPureFunctions ?? EMPTY_ARRAY,
24609
24670
  moduleSideEffects: getHasModuleSideEffects(configWithPreset.moduleSideEffects),
24610
24671
  propertyReadSideEffects: configWithPreset.propertyReadSideEffects === 'always'
24611
24672
  ? 'always'
@@ -1,7 +1,7 @@
1
1
  /*
2
2
  @license
3
- Rollup.js v3.4.0
4
- Tue, 22 Nov 2022 05:15:54 GMT - commit 780e3421e8a498f3248fd7d8506e97fcee8dd1e6
3
+ Rollup.js v3.5.0
4
+ Sun, 27 Nov 2022 06:34:25 GMT - commit 290b07d3685e8d4b4f3f5d3d673d41995d504239
5
5
 
6
6
  https://github.com/rollup/rollup
7
7
 
@@ -1,7 +1,7 @@
1
1
  /*
2
2
  @license
3
- Rollup.js v3.4.0
4
- Tue, 22 Nov 2022 05:15:54 GMT - commit 780e3421e8a498f3248fd7d8506e97fcee8dd1e6
3
+ Rollup.js v3.5.0
4
+ Sun, 27 Nov 2022 06:34:25 GMT - commit 290b07d3685e8d4b4f3f5d3d673d41995d504239
5
5
 
6
6
  https://github.com/rollup/rollup
7
7
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "rollup",
3
- "version": "3.4.0",
3
+ "version": "3.5.0",
4
4
  "description": "Next-generation ES module bundler",
5
5
  "main": "dist/rollup.js",
6
6
  "module": "dist/es/rollup.js",
@@ -29,11 +29,12 @@
29
29
  "test": "npm run build && npm run test:all",
30
30
  "test:cjs": "npm run build:cjs && npm run test:only",
31
31
  "test:quick": "mocha -b test/test.js",
32
- "test:all": "concurrently --kill-others-on-fail -c green,blue,magenta,cyan,red 'npm:test:only' 'npm:test:browser' 'npm:test:typescript' 'npm:test:leak' 'npm:test:package'",
32
+ "test:all": "concurrently --kill-others-on-fail -c green,blue,magenta,cyan,red 'npm:test:only' 'npm:test:browser' 'npm:test:typescript' 'npm:test:leak' 'npm:test:package' 'npm:test:options'",
33
33
  "test:coverage": "npm run build:cjs && shx rm -rf coverage/* && nyc --reporter html mocha test/test.js",
34
34
  "test:coverage:browser": "npm run build && shx rm -rf coverage/* && nyc mocha test/browser/index.js",
35
35
  "test:leak": "node --expose-gc test/leak/index.js",
36
36
  "test:package": "node scripts/test-package.js",
37
+ "test:options": "node scripts/test-options.js",
37
38
  "test:only": "mocha test/test.js",
38
39
  "test:typescript": "shx rm -rf test/typescript/dist && shx cp -r dist test/typescript/ && tsc --noEmit -p test/typescript && tsc --noEmit",
39
40
  "test:browser": "mocha test/browser/index.js",