rollup 4.62.4 → 4.63.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.
@@ -1,7 +1,7 @@
1
1
  /*
2
2
  @license
3
- Rollup.js v4.62.4
4
- Sat, 01 Aug 2026 05:20:25 GMT - commit ddc4ffab628944e45dbb8d66d58aae818015440f
3
+ Rollup.js v4.63.0
4
+ Tue, 25 Aug 2026 13:03:35 GMT - commit 34b8b924c815ec9413d7821f6fd54cc615584a51
5
5
 
6
6
  https://github.com/rollup/rollup
7
7
 
@@ -42,7 +42,7 @@ function _mergeNamespaces(n, m) {
42
42
 
43
43
  const promises__namespace = /*#__PURE__*/_interopNamespaceDefault(promises);
44
44
 
45
- var version = "4.62.4";
45
+ var version = "4.63.0";
46
46
  const package_ = {
47
47
  version: version};
48
48
 
@@ -2188,33 +2188,9 @@ function requireParse () {
2188
2188
  };
2189
2189
 
2190
2190
  const extglobClose = token => {
2191
- const literal = input.slice(token.startIndex, state.index + 1);
2191
+ input.slice(token.startIndex, state.index + 1);
2192
2192
  const body = input.slice(token.startIndex + 2, state.index);
2193
- const analysis = analyzeRepeatedExtglob(body, opts);
2194
-
2195
- if ((token.type === 'plus' || token.type === 'star') && analysis.risky) {
2196
- const safeOutput = analysis.safeOutput
2197
- ? (token.output ? '' : ONE_CHAR) + (opts.capture ? `(${analysis.safeOutput})` : analysis.safeOutput)
2198
- : undefined;
2199
- const open = tokens[token.tokensIndex];
2200
-
2201
- open.type = 'text';
2202
- open.value = literal;
2203
- open.output = safeOutput || utils.escapeRegex(literal);
2204
-
2205
- for (let i = token.tokensIndex + 1; i < tokens.length; i++) {
2206
- tokens[i].value = '';
2207
- tokens[i].output = '';
2208
- delete tokens[i].suffix;
2209
- }
2210
-
2211
- state.output = token.output + open.output;
2212
- state.backtrack = true;
2213
-
2214
- push({ type: 'paren', extglob: true, value, output: '' });
2215
- decrement('parens');
2216
- return;
2217
- }
2193
+ analyzeRepeatedExtglob(body, opts);
2218
2194
 
2219
2195
  let output = token.close + (opts.capture ? ')' : '');
2220
2196
  let rest;
@@ -4513,13 +4489,27 @@ var Chunk$1 = class Chunk {
4513
4489
  }
4514
4490
  };
4515
4491
  //#endregion
4492
+ //#region src/MagicStringError.ts
4493
+ /**
4494
+ * The single error type thrown by MagicString.
4495
+ *
4496
+ * Every message is prefixed with `[MagicString]` so its source is obvious at a
4497
+ * glance, and is kept short and consistent in tone.
4498
+ */
4499
+ var MagicStringError = class extends Error {
4500
+ name = "MagicStringError";
4501
+ constructor(message, options) {
4502
+ super(`[MagicString] ${message}`, options);
4503
+ }
4504
+ };
4505
+ //#endregion
4516
4506
  //#region src/SourceMap.ts
4517
4507
  function getBtoa() {
4518
4508
  if (typeof globalThis !== "undefined" && typeof globalThis.btoa === "function") return (str) => globalThis.btoa(unescape(encodeURIComponent(str)));
4519
4509
  const buffer = globalThis["Buffer"];
4520
4510
  if (buffer) return (str) => buffer.from(str, "utf-8").toString("base64");
4521
4511
  return () => {
4522
- throw new Error("Unsupported environment: `window.btoa` or `Buffer` should be supported.");
4512
+ throw new MagicStringError("unsupported environment: `btoa` or `Buffer` is required");
4523
4513
  };
4524
4514
  }
4525
4515
  const btoa = /* #__PURE__ */ getBtoa();
@@ -4748,11 +4738,11 @@ var MagicString = class MagicString {
4748
4738
  },
4749
4739
  byStart: {
4750
4740
  writable: true,
4751
- value: {}
4741
+ value: /* @__PURE__ */ new Map([[0, chunk]])
4752
4742
  },
4753
4743
  byEnd: {
4754
4744
  writable: true,
4755
- value: {}
4745
+ value: /* @__PURE__ */ new Map([[string.length, chunk]])
4756
4746
  },
4757
4747
  filename: {
4758
4748
  writable: true,
@@ -4781,10 +4771,12 @@ var MagicString = class MagicString {
4781
4771
  offset: {
4782
4772
  writable: true,
4783
4773
  value: options.offset || 0
4774
+ },
4775
+ hasMovedChunks: {
4776
+ writable: true,
4777
+ value: false
4784
4778
  }
4785
4779
  });
4786
- this.byStart = /* @__PURE__ */ new Map([[0, chunk]]);
4787
- this.byEnd = /* @__PURE__ */ new Map([[string.length, chunk]]);
4788
4780
  }
4789
4781
  /**
4790
4782
  * Adds the specified character index (with respect to the original string) to sourcemap mappings, if `hires` is false.
@@ -4796,7 +4788,7 @@ var MagicString = class MagicString {
4796
4788
  * Appends the specified content to the end of the string.
4797
4789
  */
4798
4790
  append(content) {
4799
- if (typeof content !== "string") throw new TypeError("outro content must be a string");
4791
+ if (typeof content !== "string") throw new MagicStringError(`content must be a string, got ${typeof content}`);
4800
4792
  this.outro += content;
4801
4793
  return this;
4802
4794
  }
@@ -4807,7 +4799,7 @@ var MagicString = class MagicString {
4807
4799
  */
4808
4800
  appendLeft(index, content) {
4809
4801
  index = index + this.offset;
4810
- if (typeof content !== "string") throw new TypeError("inserted content must be a string");
4802
+ if (typeof content !== "string") throw new MagicStringError(`content must be a string, got ${typeof content}`);
4811
4803
  this._split(index);
4812
4804
  const chunk = this.byEnd.get(index);
4813
4805
  if (chunk) chunk.appendLeft(content);
@@ -4821,7 +4813,7 @@ var MagicString = class MagicString {
4821
4813
  */
4822
4814
  appendRight(index, content) {
4823
4815
  index = index + this.offset;
4824
- if (typeof content !== "string") throw new TypeError("inserted content must be a string");
4816
+ if (typeof content !== "string") throw new MagicStringError(`content must be a string, got ${typeof content}`);
4825
4817
  this._split(index);
4826
4818
  const chunk = this.byStart.get(index);
4827
4819
  if (chunk) chunk.appendRight(content);
@@ -4834,6 +4826,7 @@ var MagicString = class MagicString {
4834
4826
  clone() {
4835
4827
  const cloned = new MagicString(this.original, {
4836
4828
  filename: this.filename,
4829
+ ignoreList: this.ignoreList,
4837
4830
  offset: this.offset
4838
4831
  });
4839
4832
  let originalChunk = this.firstChunk;
@@ -4853,8 +4846,10 @@ var MagicString = class MagicString {
4853
4846
  cloned.lastChunk = clonedChunk;
4854
4847
  if (this.indentExclusionRanges) cloned.indentExclusionRanges = this.indentExclusionRanges.slice();
4855
4848
  cloned.sourcemapLocations = new BitSet(this.sourcemapLocations);
4849
+ cloned.storedNames = { ...this.storedNames };
4856
4850
  cloned.intro = this.intro;
4857
4851
  cloned.outro = this.outro;
4852
+ cloned.hasMovedChunks = this.hasMovedChunks;
4858
4853
  return cloned;
4859
4854
  }
4860
4855
  /**
@@ -4983,7 +4978,7 @@ var MagicString = class MagicString {
4983
4978
  }
4984
4979
  /** @internal */
4985
4980
  insert() {
4986
- throw new Error("magicString.insert(...) is deprecated. Use prependRight(...) or appendLeft(...)");
4981
+ throw new MagicStringError("insert() is deprecated, use appendLeft() or prependRight()");
4987
4982
  }
4988
4983
  /** @internal */
4989
4984
  insertLeft(index, content) {
@@ -5009,12 +5004,19 @@ var MagicString = class MagicString {
5009
5004
  end = end + this.offset;
5010
5005
  index = index + this.offset;
5011
5006
  if (start === end) return this;
5012
- if (index >= start && index <= end) throw new Error("Cannot move a selection inside itself");
5007
+ if (index >= start && index <= end) throw new MagicStringError("cannot move a selection inside itself");
5013
5008
  this._split(start);
5014
5009
  this._split(end);
5015
5010
  this._split(index);
5016
5011
  const first = this.byStart.get(start);
5017
5012
  const last = this.byEnd.get(end);
5013
+ if (this.hasMovedChunks) {
5014
+ let cursor = first;
5015
+ while (cursor !== last) {
5016
+ cursor = cursor.next;
5017
+ if (!cursor || cursor.start < start || cursor.end > end) throw new MagicStringError(`cannot move ${start} to ${end} because an earlier move split that range`);
5018
+ }
5019
+ }
5018
5020
  const oldLeft = first.previous;
5019
5021
  const oldRight = last.next;
5020
5022
  const newRight = this.byStart.get(index);
@@ -5033,6 +5035,7 @@ var MagicString = class MagicString {
5033
5035
  last.next = newRight || null;
5034
5036
  if (!newLeft) this.firstChunk = first;
5035
5037
  if (!newRight) this.lastChunk = last;
5038
+ this.hasMovedChunks = true;
5036
5039
  return this;
5037
5040
  }
5038
5041
  /**
@@ -5062,13 +5065,15 @@ var MagicString = class MagicString {
5062
5065
  update(start, end, content, options) {
5063
5066
  start = start + this.offset;
5064
5067
  end = end + this.offset;
5065
- if (typeof content !== "string") throw new TypeError("replacement content must be a string");
5068
+ if (typeof content !== "string") throw new MagicStringError(`content must be a string, got ${typeof content}`);
5066
5069
  if (this.original.length !== 0) {
5067
5070
  while (start < 0) start += this.original.length;
5068
5071
  while (end < 0) end += this.original.length;
5069
5072
  }
5070
- if (end > this.original.length) throw new Error("end is out of bounds");
5071
- if (start === end) throw new Error("Cannot overwrite a zero-length range – use appendLeft or prependRight instead");
5073
+ if (start < 0) throw new MagicStringError(`start ${start} is out of bounds`);
5074
+ if (end > this.original.length) throw new MagicStringError(`end ${end} is out of bounds`);
5075
+ if (start === end) throw new MagicStringError(`cannot overwrite a zero-length range at ${start}, use appendLeft() or prependRight()`);
5076
+ if (start > end) throw new MagicStringError(`end must be greater than start (start: ${start}, end: ${end})`);
5072
5077
  this._split(start);
5073
5078
  this._split(end);
5074
5079
  if (options === true) {
@@ -5094,7 +5099,7 @@ var MagicString = class MagicString {
5094
5099
  if (first) {
5095
5100
  let chunk = first;
5096
5101
  while (chunk !== last) {
5097
- if (chunk.next !== this.byStart.get(chunk.end)) throw new Error("Cannot overwrite across a split point");
5102
+ if (chunk.next !== this.byStart.get(chunk.end)) throw new MagicStringError("cannot overwrite across a split point");
5098
5103
  chunk = chunk.next;
5099
5104
  chunk.edit("", false);
5100
5105
  }
@@ -5110,7 +5115,7 @@ var MagicString = class MagicString {
5110
5115
  * Prepends the string with the specified content.
5111
5116
  */
5112
5117
  prepend(content) {
5113
- if (typeof content !== "string") throw new TypeError("outro content must be a string");
5118
+ if (typeof content !== "string") throw new MagicStringError(`content must be a string, got ${typeof content}`);
5114
5119
  this.intro = content + this.intro;
5115
5120
  return this;
5116
5121
  }
@@ -5119,7 +5124,7 @@ var MagicString = class MagicString {
5119
5124
  */
5120
5125
  prependLeft(index, content) {
5121
5126
  index = index + this.offset;
5122
- if (typeof content !== "string") throw new TypeError("inserted content must be a string");
5127
+ if (typeof content !== "string") throw new MagicStringError(`content must be a string, got ${typeof content}`);
5123
5128
  this._split(index);
5124
5129
  const chunk = this.byEnd.get(index);
5125
5130
  if (chunk) chunk.prependLeft(content);
@@ -5131,7 +5136,7 @@ var MagicString = class MagicString {
5131
5136
  */
5132
5137
  prependRight(index, content) {
5133
5138
  index = index + this.offset;
5134
- if (typeof content !== "string") throw new TypeError("inserted content must be a string");
5139
+ if (typeof content !== "string") throw new MagicStringError(`content must be a string, got ${typeof content}`);
5135
5140
  this._split(index);
5136
5141
  const chunk = this.byStart.get(index);
5137
5142
  if (chunk) chunk.prependRight(content);
@@ -5150,8 +5155,8 @@ var MagicString = class MagicString {
5150
5155
  while (end < 0) end += this.original.length;
5151
5156
  }
5152
5157
  if (start === end) return this;
5153
- if (start < 0 || end > this.original.length) throw new Error("Character is out of bounds");
5154
- if (start > end) throw new Error("end must be greater than start");
5158
+ if (start < 0 || end > this.original.length) throw new MagicStringError(`range ${start}–${end} is out of bounds`);
5159
+ if (start > end) throw new MagicStringError(`end must be greater than start (start: ${start}, end: ${end})`);
5155
5160
  this._split(start);
5156
5161
  this._split(end);
5157
5162
  let chunk = this.byStart.get(start);
@@ -5174,8 +5179,8 @@ var MagicString = class MagicString {
5174
5179
  while (end < 0) end += this.original.length;
5175
5180
  }
5176
5181
  if (start === end) return this;
5177
- if (start < 0 || end > this.original.length) throw new Error("Character is out of bounds");
5178
- if (start > end) throw new Error("end must be greater than start");
5182
+ if (start < 0 || end > this.original.length) throw new MagicStringError(`range ${start}–${end} is out of bounds`);
5183
+ if (start > end) throw new MagicStringError(`end must be greater than start (start: ${start}, end: ${end})`);
5179
5184
  this._split(start);
5180
5185
  this._split(end);
5181
5186
  let chunk = this.byStart.get(start);
@@ -5241,12 +5246,12 @@ var MagicString = class MagicString {
5241
5246
  if (chunk.start < end && chunk.end >= end) return result;
5242
5247
  chunk = chunk.next;
5243
5248
  }
5244
- if (chunk && chunk.edited && chunk.start !== start) throw new Error(`Cannot use replaced character ${start} as slice start anchor.`);
5249
+ if (chunk && chunk.edited && chunk.start !== start) throw new MagicStringError(`cannot use edited character ${start} as slice start anchor`);
5245
5250
  const startChunk = chunk;
5246
5251
  while (chunk) {
5247
5252
  if (chunk.intro && (startChunk !== chunk || chunk.start === start)) result += chunk.intro;
5248
5253
  const containsEnd = chunk.start < end && chunk.end >= end;
5249
- if (containsEnd && chunk.edited && chunk.end !== end) throw new Error(`Cannot use replaced character ${end} as slice end anchor.`);
5254
+ if (containsEnd && chunk.edited && chunk.end !== end) throw new MagicStringError(`cannot use edited character ${end} as slice end anchor`);
5250
5255
  const sliceStart = startChunk === chunk ? start - chunk.start : 0;
5251
5256
  const sliceEnd = containsEnd ? chunk.content.length + end - chunk.end : chunk.content.length;
5252
5257
  result += chunk.content.slice(sliceStart, sliceEnd);
@@ -5282,7 +5287,7 @@ var MagicString = class MagicString {
5282
5287
  _splitChunk(chunk, index) {
5283
5288
  if (chunk.edited && chunk.content.length) {
5284
5289
  const loc = getLocator(this.original)(index);
5285
- throw new Error(`Cannot split a chunk that has already been edited (${loc.line}:${loc.column} – "${chunk.original}")`);
5290
+ throw new MagicStringError(`cannot split a chunk that has already been edited (${loc.line}:${loc.column} – "${chunk.original}")`);
5286
5291
  }
5287
5292
  const newChunk = chunk.split(index);
5288
5293
  this.byEnd.set(index, chunk);
@@ -5394,7 +5399,19 @@ var MagicString = class MagicString {
5394
5399
  * Indicates if the string has been changed.
5395
5400
  */
5396
5401
  hasChanged() {
5397
- return this.original !== this.toString();
5402
+ if (this.intro || this.outro) return true;
5403
+ let outputIndex = 0;
5404
+ let chunk = this.firstChunk;
5405
+ while (chunk) {
5406
+ if (chunk.intro || chunk.outro) return true;
5407
+ if (!chunk.edited && chunk.start === outputIndex) outputIndex = chunk.end;
5408
+ else {
5409
+ if (!this.original.startsWith(chunk.content, outputIndex)) return true;
5410
+ outputIndex += chunk.content.length;
5411
+ }
5412
+ chunk = chunk.next;
5413
+ }
5414
+ return outputIndex !== this.original.length;
5398
5415
  }
5399
5416
  /** @internal */
5400
5417
  _replaceRegexp(searchValue, replacement) {
@@ -5464,7 +5481,7 @@ var MagicString = class MagicString {
5464
5481
  */
5465
5482
  replaceAll(searchValue, replacement) {
5466
5483
  if (typeof searchValue === "string") return this._replaceAllString(searchValue, replacement);
5467
- if (!searchValue.global) throw new TypeError("MagicString.prototype.replaceAll called with a non-global RegExp argument");
5484
+ if (!searchValue.global) throw new MagicStringError("replaceAll() requires a global RegExp");
5468
5485
  return this._replaceRegexp(searchValue, replacement);
5469
5486
  }
5470
5487
  };
@@ -5495,7 +5512,7 @@ var Bundle$1 = class Bundle {
5495
5512
  filename: source.filename,
5496
5513
  separator: this.separator
5497
5514
  });
5498
- if (!isObject(source) || !source.content) throw new Error("bundle.addSource() takes an object with a `content` property, which should be an instance of MagicString, and an optional `filename`");
5515
+ if (!isObject(source) || !source.content) throw new MagicStringError("addSource() requires a `content` property that is a MagicString");
5499
5516
  [
5500
5517
  "filename",
5501
5518
  "ignoreList",
@@ -5513,7 +5530,7 @@ var Bundle$1 = class Bundle {
5513
5530
  });
5514
5531
  } else {
5515
5532
  const uniqueSource = this.uniqueSources[this.uniqueSourceIndexByFilename[source.filename]];
5516
- if (source.content.original !== uniqueSource.content) throw new Error(`Illegal source: same filename (${source.filename}), different contents`);
5533
+ if (source.content.original !== uniqueSource.content) throw new MagicStringError(`duplicate filename "${source.filename}" with different content, use unique filenames`);
5517
5534
  }
5518
5535
  this.sources.push(source);
5519
5536
  return this;
@@ -5534,6 +5551,8 @@ var Bundle$1 = class Bundle {
5534
5551
  bundle.addSource({
5535
5552
  filename: source.filename,
5536
5553
  content: source.content.clone(),
5554
+ ignoreList: source.ignoreList,
5555
+ indentExclusionRanges: source.indentExclusionRanges,
5537
5556
  separator: source.separator
5538
5557
  });
5539
5558
  });
@@ -5550,7 +5569,7 @@ var Bundle$1 = class Bundle {
5550
5569
  const mappings = new Mappings(options.hires);
5551
5570
  if (this.intro) mappings.advance(this.intro);
5552
5571
  this.sources.forEach((source, i) => {
5553
- if (i > 0) mappings.advance(this.separator);
5572
+ if (i > 0) mappings.advance(source.separator !== void 0 ? source.separator : this.separator);
5554
5573
  const sourceIndex = source.filename ? this.uniqueSourceIndexByFilename[source.filename] : -1;
5555
5574
  const magicString = source.content;
5556
5575
  const locate = getLocator(magicString.original);
@@ -5628,11 +5647,17 @@ var Bundle$1 = class Bundle {
5628
5647
  }
5629
5648
  isEmpty() {
5630
5649
  if (this.intro.length && this.intro.trim()) return false;
5631
- if (this.sources.some((source) => !source.content.isEmpty())) return false;
5650
+ if (this.sources.some((source, i) => {
5651
+ const separator = source.separator !== void 0 ? source.separator : this.separator;
5652
+ return i > 0 && separator.trim() !== "" || !source.content.isEmpty();
5653
+ })) return false;
5632
5654
  return true;
5633
5655
  }
5634
5656
  length() {
5635
- return this.sources.reduce((length, source) => length + source.content.length(), this.intro.length);
5657
+ return this.sources.reduce((length, source, i) => {
5658
+ const separator = source.separator !== void 0 ? source.separator : this.separator;
5659
+ return length + (i > 0 ? separator.length : 0) + source.content.length();
5660
+ }, this.intro.length);
5636
5661
  }
5637
5662
  trimLines() {
5638
5663
  return this.trim("[\\r\\n]");
@@ -6177,8 +6202,17 @@ class ExpressionEntity {
6177
6202
  return true;
6178
6203
  }
6179
6204
  }
6180
- const UNKNOWN_EXPRESSION = new (class UnknownExpression extends ExpressionEntity {
6181
- })();
6205
+ class LiteralExpression extends ExpressionEntity {
6206
+ constructor(value, parent) {
6207
+ super();
6208
+ this.value = value;
6209
+ this.parent = parent;
6210
+ }
6211
+ getLiteralValueAtPath(path) {
6212
+ return path.length > 0 ? UnknownValue : this.value;
6213
+ }
6214
+ }
6215
+ const UNKNOWN_EXPRESSION = new LiteralExpression(UnknownValue);
6182
6216
  const UNKNOWN_RETURN_EXPRESSION = [
6183
6217
  UNKNOWN_EXPRESSION,
6184
6218
  false
@@ -6908,11 +6942,7 @@ function isExpressionStatementNode(node) {
6908
6942
  function assembleMemberDescriptions(memberDescriptions, inheritedDescriptions = null) {
6909
6943
  return Object.create(inheritedDescriptions, memberDescriptions);
6910
6944
  }
6911
- const UNDEFINED_EXPRESSION = new (class UndefinedExpression extends ExpressionEntity {
6912
- getLiteralValueAtPath(path) {
6913
- return path.length > 0 ? UnknownValue : undefined;
6914
- }
6915
- })();
6945
+ const UNDEFINED_EXPRESSION = new LiteralExpression(undefined);
6916
6946
  const returnsUnknown = {
6917
6947
  value: {
6918
6948
  hasEffectsWhenCalled: null,
@@ -7093,7 +7123,7 @@ function getLiteralMembersForValue(value) {
7093
7123
  return literalStringMembers;
7094
7124
  }
7095
7125
  }
7096
- return Object.create(null);
7126
+ return parseAst_js.BLANK;
7097
7127
  }
7098
7128
  function hasMemberEffectWhenCalled(members, memberName, interaction, context) {
7099
7129
  if (typeof memberName !== 'string' || !members[memberName]) {
@@ -7393,6 +7423,8 @@ class ObjectEntity extends ExpressionEntity {
7393
7423
  // causes an issue with TypeScript enums in files with moduleSideEffects:
7394
7424
  // false because we cannot properly track whether a "var" has been
7395
7425
  // initialized. This should be reverted once we can properly track this.
7426
+ // ALSO needs to be updated once this is resolved:
7427
+ // - literals-from-return-expressions-branches/main.js
7396
7428
  // return UnknownTruthyValue;
7397
7429
  return UnknownValue;
7398
7430
  }
@@ -10093,6 +10125,156 @@ class ThisVariable extends ParameterVariable {
10093
10125
  }
10094
10126
  }
10095
10127
 
10128
+ const UNASSIGNED = Symbol('unassigned');
10129
+
10130
+ class ReturnStatement extends NodeBase {
10131
+ constructor() {
10132
+ super(...arguments);
10133
+ this.expressionsToBeDeoptimized = [];
10134
+ }
10135
+ checkReached(origin) {
10136
+ if (this.deoptimized)
10137
+ return true;
10138
+ this.expressionsToBeDeoptimized.push(origin);
10139
+ return false;
10140
+ }
10141
+ applyDeoptimizations() {
10142
+ this.deoptimized = true;
10143
+ const { expressionsToBeDeoptimized } = this;
10144
+ if (expressionsToBeDeoptimized.length) {
10145
+ this.expressionsToBeDeoptimized = parseAst_js.EMPTY_ARRAY;
10146
+ for (const expression of expressionsToBeDeoptimized) {
10147
+ expression.deoptimizeCache();
10148
+ }
10149
+ this.scope.context.requestTreeshakingPass();
10150
+ }
10151
+ }
10152
+ hasEffects(context) {
10153
+ if (!this.deoptimized)
10154
+ this.applyDeoptimizations();
10155
+ if (!context.ignore.returnYield || this.argument?.hasEffects(context))
10156
+ return true;
10157
+ context.brokenFlow = true;
10158
+ return false;
10159
+ }
10160
+ include(context, includeChildrenRecursively) {
10161
+ if (!this.included)
10162
+ this.includeNode(context);
10163
+ this.argument?.include(context, includeChildrenRecursively);
10164
+ context.brokenFlow = true;
10165
+ }
10166
+ includeNode(context) {
10167
+ this.included = true;
10168
+ if (!this.deoptimized)
10169
+ this.applyDeoptimizations();
10170
+ this.argument?.includePath(UNKNOWN_PATH, context);
10171
+ }
10172
+ initialise() {
10173
+ super.initialise();
10174
+ this.scope.addReturnExpression(this.argument || new LiteralExpression(undefined, this));
10175
+ }
10176
+ render(code, options) {
10177
+ if (this.argument) {
10178
+ this.argument.render(code, options, { preventASI: true });
10179
+ if (this.argument.start === this.start + 6 /* 'return'.length */) {
10180
+ code.prependLeft(this.start + 6, ' ');
10181
+ }
10182
+ }
10183
+ }
10184
+ }
10185
+
10186
+ function mergeValues(a, b) {
10187
+ if (a === b)
10188
+ return a;
10189
+ if (a === UnknownTruthyValue) {
10190
+ if (b && b !== UnknownFalsyValue)
10191
+ return UnknownTruthyValue;
10192
+ return UnknownValue;
10193
+ }
10194
+ if (a === UnknownFalsyValue) {
10195
+ if (!b || b === UnknownFalsyValue)
10196
+ return UnknownFalsyValue;
10197
+ return UnknownValue;
10198
+ }
10199
+ if (a && b)
10200
+ return UnknownTruthyValue;
10201
+ if (!a && !b)
10202
+ return UnknownFalsyValue;
10203
+ return UnknownValue;
10204
+ }
10205
+ class MultiExpression extends ExpressionEntity {
10206
+ constructor(expressions) {
10207
+ super();
10208
+ this.expressions = expressions;
10209
+ this.literalValue = UNASSIGNED;
10210
+ this.dependantEntities = new Set();
10211
+ }
10212
+ deoptimizeCache() {
10213
+ if (this.literalValue !== UNASSIGNED) {
10214
+ const { dependantEntities } = this;
10215
+ this.literalValue = UNASSIGNED;
10216
+ this.dependantEntities = new Set();
10217
+ for (const entity of dependantEntities) {
10218
+ entity.deoptimizeCache();
10219
+ }
10220
+ }
10221
+ }
10222
+ deoptimizePath(path) {
10223
+ for (const expression of this.expressions) {
10224
+ expression.deoptimizePath(path);
10225
+ }
10226
+ }
10227
+ getLiteralValueAtPath(path, recursionTracker, origin) {
10228
+ if (path.length === 0) {
10229
+ if (this.literalValue === UNASSIGNED)
10230
+ this.literalValue = this.doGetLiteralValueAtPath(path, recursionTracker, this);
10231
+ this.dependantEntities.add(origin);
10232
+ return this.literalValue;
10233
+ }
10234
+ return this.doGetLiteralValueAtPath(path, recursionTracker, origin);
10235
+ }
10236
+ doGetLiteralValueAtPath(path, recursionTracker, origin) {
10237
+ let value = UnknownValue;
10238
+ for (const expression of this.expressions) {
10239
+ if (this.isTreeshaken(expression))
10240
+ continue;
10241
+ const expressionValue = expression.getLiteralValueAtPath(path, recursionTracker, origin);
10242
+ if (expressionValue === UnknownValue)
10243
+ return UnknownValue;
10244
+ if (value === UnknownValue) {
10245
+ value = expressionValue;
10246
+ continue;
10247
+ }
10248
+ value = mergeValues(value, expressionValue);
10249
+ if (value === UnknownValue)
10250
+ return UnknownValue;
10251
+ }
10252
+ return value;
10253
+ }
10254
+ getReturnExpressionWhenCalledAtPath(path, interaction, recursionTracker, origin) {
10255
+ const returnExpressions = this.expressions.map(expression => expression.getReturnExpressionWhenCalledAtPath(path, interaction, recursionTracker, origin));
10256
+ let pure = true;
10257
+ return [
10258
+ new MultiExpression(returnExpressions.map(expression => ((pure &&= expression[1]), expression[0]))),
10259
+ pure
10260
+ ];
10261
+ }
10262
+ hasEffectsOnInteractionAtPath(path, interaction, context) {
10263
+ for (const expression of this.expressions) {
10264
+ if (!this.isTreeshaken(expression) &&
10265
+ expression.hasEffectsOnInteractionAtPath(path, interaction, context))
10266
+ return true;
10267
+ }
10268
+ return false;
10269
+ }
10270
+ isTreeshaken(expression) {
10271
+ if ('parent' in expression && expression.parent instanceof ReturnStatement) {
10272
+ return !expression.parent.checkReached(this);
10273
+ }
10274
+ return false;
10275
+ }
10276
+ }
10277
+
10096
10278
  class CatchBodyScope extends ChildScope {
10097
10279
  constructor(parent) {
10098
10280
  super(parent, parent.context);
@@ -10302,8 +10484,12 @@ class ReturnValueScope extends ParameterScope {
10302
10484
  }
10303
10485
  }
10304
10486
  getReturnExpression() {
10305
- if (this.returnExpression === null)
10306
- this.updateReturnExpression();
10487
+ if (!this.returnExpression) {
10488
+ this.returnExpression =
10489
+ this.returnExpressions.length === 1
10490
+ ? this.returnExpressions[0]
10491
+ : new MultiExpression(this.returnExpressions);
10492
+ }
10307
10493
  return this.returnExpression;
10308
10494
  }
10309
10495
  deoptimizeAllParameters() {
@@ -10322,17 +10508,6 @@ class ReturnValueScope extends ParameterScope {
10322
10508
  }
10323
10509
  }
10324
10510
  addArgumentToBeDeoptimized(_argument) { }
10325
- updateReturnExpression() {
10326
- if (this.returnExpressions.length === 1) {
10327
- this.returnExpression = this.returnExpressions[0];
10328
- }
10329
- else {
10330
- this.returnExpression = UNKNOWN_EXPRESSION;
10331
- for (const expression of this.returnExpressions) {
10332
- expression.deoptimizePath(UNKNOWN_PATH);
10333
- }
10334
- }
10335
- }
10336
10511
  }
10337
10512
 
10338
10513
  class FunctionScope extends ReturnValueScope {
@@ -10394,6 +10569,10 @@ ExpressionStatement.prototype.includeNode = onlyIncludeSelfNoDeoptimize;
10394
10569
  ExpressionStatement.prototype.applyDeoptimizations = doNotDeoptimize;
10395
10570
 
10396
10571
  class BlockStatement extends NodeBase {
10572
+ constructor() {
10573
+ super(...arguments);
10574
+ this.virtualReturnStatement = null;
10575
+ }
10397
10576
  get deoptimizeBody() {
10398
10577
  return isFlagSet(this.flags, 32768 /* Flag.deoptimizeBody */);
10399
10578
  }
@@ -10409,7 +10588,13 @@ class BlockStatement extends NodeBase {
10409
10588
  addImplicitReturnExpressionToScope() {
10410
10589
  const lastStatement = this.body[this.body.length - 1];
10411
10590
  if (!lastStatement || lastStatement.type !== parseAst_js.ReturnStatement) {
10412
- this.scope.addReturnExpression(UNKNOWN_EXPRESSION);
10591
+ const virtualReturnStatement = new ReturnStatement(this, this.scope);
10592
+ virtualReturnStatement.type = parseAst_js.ReturnStatement;
10593
+ virtualReturnStatement.argument = null;
10594
+ virtualReturnStatement.initialise();
10595
+ if (this.deoptimizeBody)
10596
+ virtualReturnStatement.includeNode(createInclusionContext());
10597
+ this.virtualReturnStatement = virtualReturnStatement;
10413
10598
  }
10414
10599
  }
10415
10600
  createScope(parentScope) {
@@ -10420,13 +10605,15 @@ class BlockStatement extends NodeBase {
10420
10605
  hasEffects(context) {
10421
10606
  if (this.deoptimizeBody)
10422
10607
  return true;
10608
+ let hasEffect = false;
10423
10609
  for (const node of this.body) {
10424
- if (context.brokenFlow)
10610
+ if (context.brokenFlow || (hasEffect = node.hasEffects(context)))
10425
10611
  break;
10426
- if (node.hasEffects(context))
10427
- return true;
10428
10612
  }
10429
- return false;
10613
+ if (!context.brokenFlow) {
10614
+ hasEffect ||= !!this.virtualReturnStatement?.hasEffects(context);
10615
+ }
10616
+ return hasEffect;
10430
10617
  }
10431
10618
  include(context, includeChildrenRecursively) {
10432
10619
  if (!(this.deoptimizeBody && this.directlyIncluded)) {
@@ -10438,6 +10625,8 @@ class BlockStatement extends NodeBase {
10438
10625
  if (includeChildrenRecursively || node.shouldBeIncluded(context))
10439
10626
  node.include(context, includeChildrenRecursively);
10440
10627
  }
10628
+ if (includeChildrenRecursively || !context.brokenFlow)
10629
+ this.virtualReturnStatement?.include(context, includeChildrenRecursively);
10441
10630
  }
10442
10631
  }
10443
10632
  initialise() {
@@ -10830,6 +11019,7 @@ class ExportDefaultDeclaration extends NodeBase {
10830
11019
  render(code, options, nodeRenderOptions) {
10831
11020
  const { start, end } = nodeRenderOptions;
10832
11021
  const declarationStart = getDeclarationStart(code.original, this.start);
11022
+ let needsTrailingSemicolon = false;
10833
11023
  if (this.declaration instanceof FunctionDeclaration) {
10834
11024
  this.renderNamedDeclaration(code, declarationStart, this.declaration.id === null
10835
11025
  ? getFunctionIdInsertPosition(code.original, declarationStart)
@@ -10846,7 +11036,7 @@ class ExportDefaultDeclaration extends NodeBase {
10846
11036
  return;
10847
11037
  }
10848
11038
  else if (this.variable.included) {
10849
- this.renderVariableDeclaration(code, declarationStart, options);
11039
+ needsTrailingSemicolon = this.renderVariableDeclaration(code, declarationStart, options);
10850
11040
  }
10851
11041
  else {
10852
11042
  code.remove(this.start, declarationStart);
@@ -10859,6 +11049,12 @@ class ExportDefaultDeclaration extends NodeBase {
10859
11049
  return;
10860
11050
  }
10861
11051
  this.declaration.render(code, options);
11052
+ if (needsTrailingSemicolon) {
11053
+ // This needs to happen after the declaration was rendered as rendering can
11054
+ // replace the entire declaration, which would drop anything appended to the
11055
+ // left of its end.
11056
+ code.appendLeft(this.end, ';');
11057
+ }
10862
11058
  }
10863
11059
  renderNamedDeclaration(code, declarationStart, idInsertPosition, options) {
10864
11060
  const { exportNamesByVariable, format, snippets: { getPropertyAccess } } = options;
@@ -10874,19 +11070,18 @@ class ExportDefaultDeclaration extends NodeBase {
10874
11070
  code.appendLeft(this.end, ` ${getSystemExportStatement([this.variable], options)};`);
10875
11071
  }
10876
11072
  }
11073
+ // Returns whether a semicolon still needs to be appended after the declaration
11074
+ // was rendered.
10877
11075
  renderVariableDeclaration(code, declarationStart, { format, exportNamesByVariable, snippets: { cnst, getPropertyAccess } }) {
10878
11076
  const hasTrailingSemicolon = code.original.charCodeAt(this.end - 1) === 59; /*";"*/
10879
11077
  const systemExportNames = format === 'system' && exportNamesByVariable.get(this.variable);
10880
11078
  if (systemExportNames) {
10881
11079
  code.overwrite(this.start, declarationStart, `${cnst} ${this.variable.getName(getPropertyAccess)} = exports(${JSON.stringify(systemExportNames[0])}, `);
10882
11080
  code.appendRight(hasTrailingSemicolon ? this.end - 1 : this.end, ')' + (hasTrailingSemicolon ? '' : ';'));
11081
+ return false;
10883
11082
  }
10884
- else {
10885
- code.overwrite(this.start, declarationStart, `${cnst} ${this.variable.getName(getPropertyAccess)} = `);
10886
- if (!hasTrailingSemicolon) {
10887
- code.appendLeft(this.end, ';');
10888
- }
10889
- }
11083
+ code.overwrite(this.start, declarationStart, `${cnst} ${this.variable.getName(getPropertyAccess)} = `);
11084
+ return !hasTrailingSemicolon;
10890
11085
  }
10891
11086
  }
10892
11087
  ExportDefaultDeclaration.prototype.needsBoundaries = true;
@@ -11444,7 +11639,7 @@ class MemberExpression extends NodeBase {
11444
11639
  if (!this.included)
11445
11640
  this.includeNode(context);
11446
11641
  if (this.variable) {
11447
- this.variable?.includePath(path, context);
11642
+ this.variable.includePath(path, context);
11448
11643
  }
11449
11644
  else if (!this.isUndefined) {
11450
11645
  this.object.includePath([
@@ -13652,11 +13847,10 @@ const binaryOperators = {
13652
13847
  // in: () => UnknownValue,
13653
13848
  // instanceof: () => UnknownValue,
13654
13849
  };
13655
- const UNASSIGNED$1 = Symbol('Unassigned');
13656
13850
  class BinaryExpression extends NodeBase {
13657
13851
  constructor() {
13658
13852
  super(...arguments);
13659
- this.renderedLiteralValue = UNASSIGNED$1;
13853
+ this.renderedLiteralValue = UNASSIGNED;
13660
13854
  }
13661
13855
  deoptimizeCache() {
13662
13856
  this.renderedLiteralValue = UnknownValue;
@@ -13689,7 +13883,7 @@ class BinaryExpression extends NodeBase {
13689
13883
  if (this.operator !== 'in' || !(this.right.variable instanceof NamespaceVariable)) {
13690
13884
  return UnknownValue;
13691
13885
  }
13692
- if (this.renderedLiteralValue !== UNASSIGNED$1)
13886
+ if (this.renderedLiteralValue !== UNASSIGNED)
13693
13887
  return this.renderedLiteralValue;
13694
13888
  return (this.renderedLiteralValue = getRenderedLiteralValue(this.getLiteralValueAtPath(EMPTY_PATH, SHARED_RECURSION_TRACKER, this)));
13695
13889
  }
@@ -13824,10 +14018,10 @@ class CallExpressionBase extends NodeBase {
13824
14018
  }
13825
14019
  deoptimizeCache() {
13826
14020
  if (this.returnExpression?.[0] !== UNKNOWN_EXPRESSION) {
13827
- this.returnExpression = UNKNOWN_RETURN_EXPRESSION;
14021
+ this.returnExpression = null;
13828
14022
  const { deoptimizableDependentExpressions, expressionsToBeDeoptimized } = this;
13829
- this.expressionsToBeDeoptimized = parseAst_js.EMPTY_SET;
13830
- this.deoptimizableDependentExpressions = parseAst_js.EMPTY_ARRAY;
14023
+ this.expressionsToBeDeoptimized = new Set();
14024
+ this.deoptimizableDependentExpressions = [];
13831
14025
  for (const expression of deoptimizableDependentExpressions) {
13832
14026
  expression.deoptimizeCache();
13833
14027
  }
@@ -13853,7 +14047,7 @@ class CallExpressionBase extends NodeBase {
13853
14047
  }
13854
14048
  return recursionTracker.withTrackedEntityAtPath(path, returnExpression, () => {
13855
14049
  this.deoptimizableDependentExpressions.push(origin);
13856
- return returnExpression.getLiteralValueAtPath(path, recursionTracker, origin);
14050
+ return returnExpression.getLiteralValueAtPath(path, recursionTracker, this);
13857
14051
  }, UnknownValue);
13858
14052
  }
13859
14053
  getReturnExpressionWhenCalledAtPath(path, interaction, recursionTracker, origin) {
@@ -13965,11 +14159,6 @@ class CallExpression extends CallExpressionBase {
13965
14159
  this.callee.includeCallArguments(this.interaction, context);
13966
14160
  }
13967
14161
  }
13968
- includeNode(_context) {
13969
- this.included = true;
13970
- if (!this.deoptimized)
13971
- this.applyDeoptimizations();
13972
- }
13973
14162
  initialise() {
13974
14163
  super.initialise();
13975
14164
  if (this.annotations &&
@@ -14001,12 +14190,13 @@ class CallExpression extends CallExpressionBase {
14001
14190
  }
14002
14191
  getReturnExpression(recursionTracker = SHARED_RECURSION_TRACKER) {
14003
14192
  if (this.returnExpression === null) {
14004
- this.returnExpression = UNKNOWN_RETURN_EXPRESSION;
14005
- return (this.returnExpression = this.callee.getReturnExpressionWhenCalledAtPath(EMPTY_PATH, this.interaction, recursionTracker, this));
14193
+ this.returnExpression = UNKNOWN_RETURN_EXPRESSION; // In case of recursion
14194
+ this.returnExpression = this.callee.getReturnExpressionWhenCalledAtPath(EMPTY_PATH, this.interaction, recursionTracker, this);
14006
14195
  }
14007
14196
  return this.returnExpression;
14008
14197
  }
14009
14198
  }
14199
+ CallExpression.prototype.includeNode = onlyIncludeSelf;
14010
14200
 
14011
14201
  class CatchClause extends NodeBase {
14012
14202
  createScope(parentScope) {
@@ -14106,31 +14296,6 @@ function tryCastLiteralValueToBoolean(literalValue) {
14106
14296
  return !!literalValue;
14107
14297
  }
14108
14298
 
14109
- class MultiExpression extends ExpressionEntity {
14110
- constructor(expressions) {
14111
- super();
14112
- this.expressions = expressions;
14113
- }
14114
- deoptimizePath(path) {
14115
- for (const expression of this.expressions) {
14116
- expression.deoptimizePath(path);
14117
- }
14118
- }
14119
- getReturnExpressionWhenCalledAtPath(path, interaction, recursionTracker, origin) {
14120
- return [
14121
- new MultiExpression(this.expressions.map(expression => expression.getReturnExpressionWhenCalledAtPath(path, interaction, recursionTracker, origin)[0])),
14122
- false
14123
- ];
14124
- }
14125
- hasEffectsOnInteractionAtPath(path, interaction, context) {
14126
- for (const expression of this.expressions) {
14127
- if (expression.hasEffectsOnInteractionAtPath(path, interaction, context))
14128
- return true;
14129
- }
14130
- return false;
14131
- }
14132
- }
14133
-
14134
14299
  class ConditionalExpression extends NodeBase {
14135
14300
  constructor() {
14136
14301
  super(...arguments);
@@ -14634,14 +14799,13 @@ class TrackingScope extends BlockScope {
14634
14799
  }
14635
14800
  }
14636
14801
 
14637
- const unset = Symbol('unset');
14638
14802
  class IfStatement extends NodeBase {
14639
14803
  constructor() {
14640
14804
  super(...arguments);
14641
- this.testValue = unset;
14805
+ this.testValue = UNASSIGNED;
14642
14806
  }
14643
14807
  deoptimizeCache() {
14644
- this.testValue = UnknownValue;
14808
+ this.testValue = UNASSIGNED;
14645
14809
  }
14646
14810
  hasEffects(context) {
14647
14811
  if (this.test.hasEffects(context)) {
@@ -14730,8 +14894,8 @@ class IfStatement extends NodeBase {
14730
14894
  this.renderHoistedDeclarations(hoistedDeclarations, code, getPropertyAccess);
14731
14895
  }
14732
14896
  getTestValue() {
14733
- if (this.testValue === unset) {
14734
- return (this.testValue = tryCastLiteralValueToBoolean(this.test.getLiteralValueAtPath(EMPTY_PATH, SHARED_RECURSION_TRACKER, this)));
14897
+ if (this.testValue === UNASSIGNED) {
14898
+ this.testValue = tryCastLiteralValueToBoolean(this.test.getLiteralValueAtPath(EMPTY_PATH, SHARED_RECURSION_TRACKER, this));
14735
14899
  }
14736
14900
  return this.testValue;
14737
14901
  }
@@ -16385,38 +16549,6 @@ class PropertyDefinition extends NodeBase {
16385
16549
  }
16386
16550
  PropertyDefinition.prototype.applyDeoptimizations = doNotDeoptimize;
16387
16551
 
16388
- class ReturnStatement extends NodeBase {
16389
- hasEffects(context) {
16390
- if (!context.ignore.returnYield || this.argument?.hasEffects(context))
16391
- return true;
16392
- context.brokenFlow = true;
16393
- return false;
16394
- }
16395
- include(context, includeChildrenRecursively) {
16396
- if (!this.included)
16397
- this.includeNode(context);
16398
- this.argument?.include(context, includeChildrenRecursively);
16399
- context.brokenFlow = true;
16400
- }
16401
- includeNode(context) {
16402
- this.included = true;
16403
- this.argument?.includePath(UNKNOWN_PATH, context);
16404
- }
16405
- initialise() {
16406
- super.initialise();
16407
- this.scope.addReturnExpression(this.argument || UNKNOWN_EXPRESSION);
16408
- }
16409
- render(code, options) {
16410
- if (this.argument) {
16411
- this.argument.render(code, options, { preventASI: true });
16412
- if (this.argument.start === this.start + 6 /* 'return'.length */) {
16413
- code.prependLeft(this.start + 6, ' ');
16414
- }
16415
- }
16416
- }
16417
- }
16418
- ReturnStatement.prototype.applyDeoptimizations = doNotDeoptimize;
16419
-
16420
16552
  class SequenceExpression extends NodeBase {
16421
16553
  deoptimizeArgumentsOnInteractionAtPath(interaction, path, recursionTracker) {
16422
16554
  this.expressions[this.expressions.length - 1].deoptimizeArgumentsOnInteractionAtPath(interaction, path, recursionTracker);
@@ -16940,7 +17072,6 @@ const unaryOperators = {
16940
17072
  void: () => undefined,
16941
17073
  '~': value => ~value
16942
17074
  };
16943
- const UNASSIGNED = Symbol('Unassigned');
16944
17075
  class UnaryExpression extends NodeBase {
16945
17076
  constructor() {
16946
17077
  super(...arguments);
@@ -20789,7 +20920,6 @@ class Chunk {
20789
20920
  const usedModules = [];
20790
20921
  let hoistedSource = '';
20791
20922
  const accessedGlobals = new Set();
20792
- const renderedModuleSources = new Map();
20793
20923
  const renderOptions = {
20794
20924
  accessedDocumentCurrentScript: false,
20795
20925
  exportNamesByVariable,
@@ -20819,7 +20949,6 @@ class Chunk {
20819
20949
  if (renderedLength) {
20820
20950
  if (compact && source.lastLine().includes('//'))
20821
20951
  source.append('\n');
20822
- renderedModuleSources.set(module, source);
20823
20952
  magicString.addSource(source);
20824
20953
  usedModules.push(module);
20825
20954
  }