Add JS-CATCH-FALLBACK-01 rule and update npm packages

Add PHP-ALIAS-01 rule: prohibit field aliasing in serialization

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
root
2025-12-23 07:36:18 +00:00
parent 3cc590186a
commit 3ce82a924a
1256 changed files with 6491 additions and 3989 deletions

View File

@@ -1,7 +1,7 @@
/*
@license
Rollup.js v4.53.4
Mon, 15 Dec 2025 12:00:59 GMT - commit 7df7947fdb51ead87b71d38ece3752796bd0249c
Rollup.js v4.54.0
Sat, 20 Dec 2025 09:28:12 GMT - commit 88f1430c42fe76db421623106546e50627271952
https://github.com/rollup/rollup
@@ -27,7 +27,7 @@ function _mergeNamespaces(n, m) {
return Object.defineProperty(n, Symbol.toStringTag, { value: 'Module' });
}
var version = "4.53.4";
var version = "4.54.0";
// src/vlq.ts
var comma = ",".charCodeAt(0);
@@ -2001,11 +2001,22 @@ function getNewArray() {
const UnknownKey = Symbol('Unknown Key');
const UnknownNonAccessorKey = Symbol('Unknown Non-Accessor Key');
const UnknownInteger = Symbol('Unknown Integer');
const UnknownWellKnown = Symbol('Unknown Well-Known');
const SymbolToStringTag = Symbol('Symbol.toStringTag');
const SymbolDispose = Symbol('Symbol.asyncDispose');
const SymbolAsyncDispose = Symbol('Symbol.dispose');
const WELL_KNOWN_SYMBOLS_LIST = [SymbolToStringTag, SymbolDispose, SymbolAsyncDispose];
const SymbolHasInstance = Symbol('Symbol.hasInstance');
const WELL_KNOWN_SYMBOLS_LIST = [
SymbolToStringTag,
SymbolDispose,
SymbolAsyncDispose,
SymbolHasInstance
];
const WELL_KNOWN_SYMBOLS = new Set(WELL_KNOWN_SYMBOLS_LIST);
const isAnyWellKnown = (v) => WELL_KNOWN_SYMBOLS.has(v) || v === UnknownWellKnown;
const TREE_SHAKEABLE_SYMBOLS_LIST = [SymbolHasInstance, SymbolDispose, SymbolAsyncDispose];
const TREE_SHAKEABLE_SYMBOLS = new Set(TREE_SHAKEABLE_SYMBOLS_LIST);
const isConcreteKey = (v) => typeof v === 'string' || WELL_KNOWN_SYMBOLS.has(v);
const EMPTY_PATH = [];
const UNKNOWN_PATH = [UnknownKey];
// For deoptimizations, this means we are modifying an unknown property but did
@@ -2015,6 +2026,7 @@ const UNKNOWN_PATH = [UnknownKey];
// Object.defineProperty
const UNKNOWN_NON_ACCESSOR_PATH = [UnknownNonAccessorKey];
const UNKNOWN_INTEGER_PATH = [UnknownInteger];
const INSTANCEOF_PATH = [SymbolHasInstance];
const EntitiesKey = Symbol('Entities');
class EntityPathTracker {
constructor() {
@@ -2087,7 +2099,7 @@ class IncludedFullPathTracker {
}
// Including UnknownKey automatically includes all nested paths.
// From above, we know that UnknownKey is not included yet.
if (typeof pathSegment === 'symbol') {
if (!isConcreteKey(pathSegment)) {
// Hopefully, this saves some memory over just setting
// currentPaths[UnknownKey] = EMPTY_OBJECT
parent[parentSegment] = UNKNOWN_INCLUDED_PATH;
@@ -2118,7 +2130,7 @@ class IncludedTopLevelPathTracker {
if (!firstPathSegment) {
return included;
}
if (typeof firstPathSegment === 'symbol') {
if (!isConcreteKey(firstPathSegment)) {
this.includedPaths = UNKNOWN_INCLUDED_TOP_LEVEL_PATH;
return false;
}
@@ -3341,12 +3353,13 @@ class ObjectEntity extends ExpressionEntity {
this.immutable = immutable;
this.additionalExpressionsToBeDeoptimized = new Set();
this.allProperties = [];
this.deoptimizedPaths = Object.create(null);
this.expressionsToBeDeoptimizedByKey = Object.create(null);
this.gettersByKey = Object.create(null);
this.propertiesAndGettersByKey = Object.create(null);
this.propertiesAndSettersByKey = Object.create(null);
this.settersByKey = Object.create(null);
this.alwaysIncludedProperties = new Set();
this.deoptimizedPaths = new Map();
this.expressionsToBeDeoptimizedByKey = new Map();
this.gettersByKey = new Map();
this.propertiesAndGettersByKey = new Map();
this.propertiesAndSettersByKey = new Map();
this.settersByKey = new Map();
this.unknownIntegerProps = [];
this.unmatchableGetters = [];
this.unmatchablePropertiesAndGetters = [];
@@ -3357,7 +3370,7 @@ class ObjectEntity extends ExpressionEntity {
}
else {
this.propertiesAndGettersByKey = this.propertiesAndSettersByKey = properties;
for (const propertiesForKey of Object.values(properties)) {
for (const propertiesForKey of properties.values()) {
this.allProperties.push(...propertiesForKey);
}
}
@@ -3374,8 +3387,8 @@ class ObjectEntity extends ExpressionEntity {
return;
}
for (const properties of [
...Object.values(this.propertiesAndGettersByKey),
...Object.values(this.settersByKey)
...this.propertiesAndGettersByKey.values(),
...this.settersByKey.values()
]) {
for (const property of properties) {
property.deoptimizePath(UNKNOWN_PATH);
@@ -3392,7 +3405,7 @@ class ObjectEntity extends ExpressionEntity {
// single paths that are deoptimized will not become getters or setters
((type === INTERACTION_CALLED || path.length > 1) &&
(this.hasUnknownDeoptimizedProperty ||
(typeof key === 'string' && this.deoptimizedPaths[key])))) {
(isConcreteKey(key) && this.deoptimizedPaths.get(key))))) {
deoptimizeInteraction(interaction);
return;
}
@@ -3405,9 +3418,9 @@ class ObjectEntity extends ExpressionEntity {
: type === INTERACTION_ACCESSED
? [this.propertiesAndGettersByKey, this.gettersByKey, this.unmatchableGetters]
: [this.propertiesAndSettersByKey, this.settersByKey, this.unmatchableSetters];
if (typeof key === 'string') {
if (propertiesForExactMatchByKey[key]) {
const properties = relevantPropertiesByKey[key];
if (isConcreteKey(key)) {
if (propertiesForExactMatchByKey.get(key)) {
const properties = relevantPropertiesByKey.get(key);
if (properties) {
for (const property of properties) {
property.deoptimizeArgumentsOnInteractionAtPath(interaction, subPath, recursionTracker);
@@ -3425,7 +3438,7 @@ class ObjectEntity extends ExpressionEntity {
for (const property of relevantUnmatchableProperties) {
property.deoptimizeArgumentsOnInteractionAtPath(interaction, subPath, recursionTracker);
}
if (INTEGER_REG_EXP.test(key)) {
if (typeof key === 'string' && INTEGER_REG_EXP.test(key)) {
for (const property of this.unknownIntegerProps) {
property.deoptimizeArgumentsOnInteractionAtPath(interaction, subPath, recursionTracker);
}
@@ -3433,7 +3446,7 @@ class ObjectEntity extends ExpressionEntity {
}
else {
for (const properties of [
...Object.values(relevantPropertiesByKey),
...relevantPropertiesByKey.values(),
relevantUnmatchableProperties
]) {
for (const property of properties) {
@@ -3460,8 +3473,9 @@ class ObjectEntity extends ExpressionEntity {
return;
}
this.hasUnknownDeoptimizedInteger = true;
for (const [key, propertiesAndGetters] of Object.entries(this.propertiesAndGettersByKey)) {
if (INTEGER_REG_EXP.test(key)) {
// Omits symbol keys but that's unimportant here
for (const [key, propertiesAndGetters] of this.propertiesAndGettersByKey.entries()) {
if (typeof key === 'string' && INTEGER_REG_EXP.test(key)) {
for (const property of propertiesAndGetters) {
property.deoptimizePath(UNKNOWN_PATH);
}
@@ -3479,14 +3493,14 @@ class ObjectEntity extends ExpressionEntity {
if (key === UnknownInteger) {
return this.deoptimizeIntegerProperties();
}
else if (typeof key !== 'string') {
else if (!isConcreteKey(key)) {
return this.deoptimizeAllProperties(key === UnknownNonAccessorKey);
}
if (!this.deoptimizedPaths[key]) {
this.deoptimizedPaths[key] = true;
if (!this.deoptimizedPaths.get(key)) {
this.deoptimizedPaths.set(key, true);
// we only deoptimizeCache exact matches as in all other cases,
// we do not return a literal value or return expression
const expressionsToBeDeoptimized = this.expressionsToBeDeoptimizedByKey[key];
const expressionsToBeDeoptimized = this.expressionsToBeDeoptimizedByKey.get(key);
if (expressionsToBeDeoptimized) {
for (const expression of expressionsToBeDeoptimized) {
expression.deoptimizeCache();
@@ -3495,10 +3509,10 @@ class ObjectEntity extends ExpressionEntity {
}
}
const subPath = path.length === 1 ? UNKNOWN_PATH : path.slice(1);
for (const property of typeof key === 'string'
for (const property of isConcreteKey(key)
? [
...(this.propertiesAndGettersByKey[key] || this.unmatchablePropertiesAndGetters),
...(this.settersByKey[key] || this.unmatchableSetters)
...(this.propertiesAndGettersByKey.get(key) || this.unmatchablePropertiesAndGetters),
...(this.settersByKey.get(key) || this.unmatchableSetters)
]
: this.allProperties) {
property.deoptimizePath(subPath);
@@ -3560,9 +3574,9 @@ class ObjectEntity extends ExpressionEntity {
const [propertiesAndAccessorsByKey, accessorsByKey, unmatchableAccessors] = interaction.type === INTERACTION_ACCESSED
? [this.propertiesAndGettersByKey, this.gettersByKey, this.unmatchableGetters]
: [this.propertiesAndSettersByKey, this.settersByKey, this.unmatchableSetters];
if (typeof key === 'string') {
if (propertiesAndAccessorsByKey[key]) {
const accessors = accessorsByKey[key];
if (isConcreteKey(key)) {
if (propertiesAndAccessorsByKey.get(key)) {
const accessors = accessorsByKey.get(key);
if (accessors) {
for (const accessor of accessors) {
if (accessor.hasEffectsOnInteractionAtPath(subPath, interaction, context))
@@ -3578,7 +3592,7 @@ class ObjectEntity extends ExpressionEntity {
}
}
else {
for (const accessors of [...Object.values(accessorsByKey), unmatchableAccessors]) {
for (const accessors of [...accessorsByKey.values(), unmatchableAccessors]) {
for (const accessor of accessors) {
if (accessor.hasEffectsOnInteractionAtPath(subPath, interaction, context))
return true;
@@ -3593,7 +3607,9 @@ class ObjectEntity extends ExpressionEntity {
include(context, includeChildrenRecursively) {
this.included = true;
for (const property of this.allProperties) {
if (includeChildrenRecursively || property.shouldBeIncluded(context)) {
if (includeChildrenRecursively ||
property.shouldBeIncluded(context) ||
this.alwaysIncludedProperties.has(property)) {
property.include(context, includeChildrenRecursively);
}
}
@@ -3601,14 +3617,17 @@ class ObjectEntity extends ExpressionEntity {
}
includePath(path, context) {
this.included = true;
for (const property of this.alwaysIncludedProperties) {
property.includePath(UNKNOWN_PATH, context);
}
if (path.length === 0)
return;
const [key, ...subPath] = path;
const [includedMembers, includedPath] = typeof key === 'string'
const [includedMembers, includedPath] = isConcreteKey(key)
? [
new Set([
...(this.propertiesAndGettersByKey[key] || this.unmatchablePropertiesAndGetters),
...(this.propertiesAndSettersByKey[key] || this.unmatchablePropertiesAndSetters)
...(this.propertiesAndGettersByKey.get(key) || this.unmatchablePropertiesAndGetters),
...(this.propertiesAndSettersByKey.get(key) || this.unmatchablePropertiesAndSetters)
]),
subPath
]
@@ -3619,29 +3638,36 @@ class ObjectEntity extends ExpressionEntity {
this.prototypeExpression?.includePath(path, context);
}
buildPropertyMaps(properties) {
const { allProperties, propertiesAndGettersByKey, propertiesAndSettersByKey, settersByKey, gettersByKey, unknownIntegerProps, unmatchablePropertiesAndGetters, unmatchablePropertiesAndSetters, unmatchableGetters, unmatchableSetters } = this;
const { allProperties, alwaysIncludedProperties, propertiesAndGettersByKey, propertiesAndSettersByKey, settersByKey, gettersByKey, unknownIntegerProps, unmatchablePropertiesAndGetters, unmatchablePropertiesAndSetters, unmatchableGetters, unmatchableSetters } = this;
for (let index = properties.length - 1; index >= 0; index--) {
const { key, kind, property } = properties[index];
allProperties.push(property);
if (typeof key === 'string') {
if (isAnyWellKnown(key) && !TREE_SHAKEABLE_SYMBOLS.has(key)) {
// Never treeshake well-known symbols (unless Rollup can optimize them)
// They are most likely called implicitly by language semantics, don't get rid of them
alwaysIncludedProperties.add(property);
if (key === UnknownWellKnown)
continue;
}
if (isConcreteKey(key)) {
if (kind === 'set') {
if (!propertiesAndSettersByKey[key]) {
propertiesAndSettersByKey[key] = [property, ...unmatchablePropertiesAndSetters];
settersByKey[key] = [property, ...unmatchableSetters];
if (!propertiesAndSettersByKey.has(key)) {
propertiesAndSettersByKey.set(key, [property, ...unmatchablePropertiesAndSetters]);
settersByKey.set(key, [property, ...unmatchableSetters]);
}
}
else if (kind === 'get') {
if (!propertiesAndGettersByKey[key]) {
propertiesAndGettersByKey[key] = [property, ...unmatchablePropertiesAndGetters];
gettersByKey[key] = [property, ...unmatchableGetters];
if (!propertiesAndGettersByKey.has(key)) {
propertiesAndGettersByKey.set(key, [property, ...unmatchablePropertiesAndGetters]);
gettersByKey.set(key, [property, ...unmatchableGetters]);
}
}
else {
if (!propertiesAndSettersByKey[key]) {
propertiesAndSettersByKey[key] = [property, ...unmatchablePropertiesAndSetters];
if (!propertiesAndSettersByKey.has(key)) {
propertiesAndSettersByKey.set(key, [property, ...unmatchablePropertiesAndSetters]);
}
if (!propertiesAndGettersByKey[key]) {
propertiesAndGettersByKey[key] = [property, ...unmatchablePropertiesAndGetters];
if (!propertiesAndGettersByKey.has(key)) {
propertiesAndGettersByKey.set(key, [property, ...unmatchablePropertiesAndGetters]);
}
}
}
@@ -3662,7 +3688,7 @@ class ObjectEntity extends ExpressionEntity {
}
}
deoptimizeCachedEntities() {
for (const expressionsToBeDeoptimized of Object.values(this.expressionsToBeDeoptimizedByKey)) {
for (const expressionsToBeDeoptimized of this.expressionsToBeDeoptimizedByKey.values()) {
for (const expression of expressionsToBeDeoptimized) {
expression.deoptimizeCache();
}
@@ -3672,8 +3698,8 @@ class ObjectEntity extends ExpressionEntity {
}
}
deoptimizeCachedIntegerEntities() {
for (const [key, expressionsToBeDeoptimized] of Object.entries(this.expressionsToBeDeoptimizedByKey)) {
if (INTEGER_REG_EXP.test(key)) {
for (const [key, expressionsToBeDeoptimized] of this.expressionsToBeDeoptimizedByKey.entries()) {
if (typeof key === 'string' && INTEGER_REG_EXP.test(key)) {
for (const expression of expressionsToBeDeoptimized) {
expression.deoptimizeCache();
}
@@ -3686,30 +3712,32 @@ class ObjectEntity extends ExpressionEntity {
getMemberExpression(key) {
if (this.hasLostTrack ||
this.hasUnknownDeoptimizedProperty ||
typeof key !== 'string' ||
(this.hasUnknownDeoptimizedInteger && INTEGER_REG_EXP.test(key)) ||
this.deoptimizedPaths[key]) {
!isConcreteKey(key) ||
(this.hasUnknownDeoptimizedInteger && typeof key === 'string' && INTEGER_REG_EXP.test(key)) ||
this.deoptimizedPaths.get(key)) {
return UNKNOWN_EXPRESSION;
}
const properties = this.propertiesAndGettersByKey[key];
const properties = this.propertiesAndGettersByKey.get(key);
if (properties?.length === 1) {
return properties[0];
}
if (properties ||
this.unmatchablePropertiesAndGetters.length > 0 ||
(this.unknownIntegerProps.length > 0 && INTEGER_REG_EXP.test(key))) {
(this.unknownIntegerProps.length > 0 && typeof key === 'string' && INTEGER_REG_EXP.test(key))) {
return UNKNOWN_EXPRESSION;
}
return null;
}
getMemberExpressionAndTrackDeopt(key, origin) {
if (typeof key !== 'string') {
if (!isConcreteKey(key)) {
return UNKNOWN_EXPRESSION;
}
const expression = this.getMemberExpression(key);
if (!(expression === UNKNOWN_EXPRESSION || this.immutable)) {
const expressionsToBeDeoptimized = (this.expressionsToBeDeoptimizedByKey[key] =
this.expressionsToBeDeoptimizedByKey[key] || []);
let expressionsToBeDeoptimized = this.expressionsToBeDeoptimizedByKey.get(key);
if (!expressionsToBeDeoptimized) {
this.expressionsToBeDeoptimizedByKey.set(key, (expressionsToBeDeoptimized = []));
}
expressionsToBeDeoptimized.push(origin);
}
return expression;
@@ -3737,15 +3765,14 @@ const OBJECT_PROTOTYPE_FALLBACK = new (class ObjectPrototypeFallbackExpression e
return path.length > 1 || type === INTERACTION_CALLED;
}
})();
const OBJECT_PROTOTYPE = new ObjectEntity({
__proto__: null,
hasOwnProperty: METHOD_RETURNS_BOOLEAN,
isPrototypeOf: METHOD_RETURNS_BOOLEAN,
propertyIsEnumerable: METHOD_RETURNS_BOOLEAN,
toLocaleString: METHOD_RETURNS_STRING,
toString: METHOD_RETURNS_STRING,
valueOf: METHOD_RETURNS_UNKNOWN
}, OBJECT_PROTOTYPE_FALLBACK, true);
const OBJECT_PROTOTYPE = new ObjectEntity(new Map([
['hasOwnProperty', METHOD_RETURNS_BOOLEAN],
['isPrototypeOf', METHOD_RETURNS_BOOLEAN],
['propertyIsEnumerable', METHOD_RETURNS_BOOLEAN],
['toLocaleString', METHOD_RETURNS_STRING],
['toString', METHOD_RETURNS_STRING],
['valueOf', METHOD_RETURNS_UNKNOWN]
]), OBJECT_PROTOTYPE_FALLBACK, true);
const NEW_ARRAY_PROPERTIES = [
{ key: UnknownInteger, kind: 'init', property: UNKNOWN_EXPRESSION },
@@ -3850,44 +3877,43 @@ const METHOD_CALLS_ARG_MUTATES_SELF_RETURNS_SELF = [
returnsPrimitive: null
})
];
const ARRAY_PROTOTYPE = new ObjectEntity({
__proto__: null,
const ARRAY_PROTOTYPE = new ObjectEntity(new Map([
// We assume that accessors have effects as we do not track the accessed value afterwards
at: METHOD_DEOPTS_SELF_RETURNS_UNKNOWN,
concat: METHOD_DEOPTS_SELF_RETURNS_NEW_ARRAY,
copyWithin: METHOD_MUTATES_SELF_RETURNS_SELF,
entries: METHOD_DEOPTS_SELF_RETURNS_NEW_ARRAY,
every: METHOD_CALLS_ARG_DEOPTS_SELF_RETURNS_BOOLEAN,
fill: METHOD_MUTATES_SELF_RETURNS_SELF,
filter: METHOD_CALLS_ARG_DEOPTS_SELF_RETURNS_NEW_ARRAY,
find: METHOD_CALLS_ARG_DEOPTS_SELF_RETURNS_UNKNOWN,
findIndex: METHOD_CALLS_ARG_DEOPTS_SELF_RETURNS_NUMBER,
findLast: METHOD_CALLS_ARG_DEOPTS_SELF_RETURNS_UNKNOWN,
findLastIndex: METHOD_CALLS_ARG_DEOPTS_SELF_RETURNS_NUMBER,
flat: METHOD_DEOPTS_SELF_RETURNS_NEW_ARRAY,
flatMap: METHOD_CALLS_ARG_DEOPTS_SELF_RETURNS_NEW_ARRAY,
forEach: METHOD_CALLS_ARG_DEOPTS_SELF_RETURNS_UNKNOWN,
includes: METHOD_RETURNS_BOOLEAN,
indexOf: METHOD_RETURNS_NUMBER,
join: METHOD_RETURNS_STRING,
keys: METHOD_RETURNS_UNKNOWN,
lastIndexOf: METHOD_RETURNS_NUMBER,
map: METHOD_CALLS_ARG_DEOPTS_SELF_RETURNS_NEW_ARRAY,
pop: METHOD_MUTATES_SELF_RETURNS_UNKNOWN,
push: METHOD_MUTATES_SELF_AND_ARGS_RETURNS_NUMBER,
reduce: METHOD_CALLS_ARG_DEOPTS_SELF_RETURNS_UNKNOWN,
reduceRight: METHOD_CALLS_ARG_DEOPTS_SELF_RETURNS_UNKNOWN,
reverse: METHOD_MUTATES_SELF_RETURNS_SELF,
shift: METHOD_MUTATES_SELF_RETURNS_UNKNOWN,
slice: METHOD_DEOPTS_SELF_RETURNS_NEW_ARRAY,
some: METHOD_CALLS_ARG_DEOPTS_SELF_RETURNS_BOOLEAN,
sort: METHOD_CALLS_ARG_MUTATES_SELF_RETURNS_SELF,
splice: METHOD_MUTATES_SELF_RETURNS_NEW_ARRAY,
toLocaleString: METHOD_RETURNS_STRING,
toString: METHOD_RETURNS_STRING,
unshift: METHOD_MUTATES_SELF_AND_ARGS_RETURNS_NUMBER,
values: METHOD_DEOPTS_SELF_RETURNS_UNKNOWN
}, OBJECT_PROTOTYPE, true);
['at', METHOD_DEOPTS_SELF_RETURNS_UNKNOWN],
['concat', METHOD_DEOPTS_SELF_RETURNS_NEW_ARRAY],
['copyWithin', METHOD_MUTATES_SELF_RETURNS_SELF],
['entries', METHOD_DEOPTS_SELF_RETURNS_NEW_ARRAY],
['every', METHOD_CALLS_ARG_DEOPTS_SELF_RETURNS_BOOLEAN],
['fill', METHOD_MUTATES_SELF_RETURNS_SELF],
['filter', METHOD_CALLS_ARG_DEOPTS_SELF_RETURNS_NEW_ARRAY],
['find', METHOD_CALLS_ARG_DEOPTS_SELF_RETURNS_UNKNOWN],
['findIndex', METHOD_CALLS_ARG_DEOPTS_SELF_RETURNS_NUMBER],
['findLast', METHOD_CALLS_ARG_DEOPTS_SELF_RETURNS_UNKNOWN],
['findLastIndex', METHOD_CALLS_ARG_DEOPTS_SELF_RETURNS_NUMBER],
['flat', METHOD_DEOPTS_SELF_RETURNS_NEW_ARRAY],
['flatMap', METHOD_CALLS_ARG_DEOPTS_SELF_RETURNS_NEW_ARRAY],
['forEach', METHOD_CALLS_ARG_DEOPTS_SELF_RETURNS_UNKNOWN],
['includes', METHOD_RETURNS_BOOLEAN],
['indexOf', METHOD_RETURNS_NUMBER],
['join', METHOD_RETURNS_STRING],
['keys', METHOD_RETURNS_UNKNOWN],
['lastIndexOf', METHOD_RETURNS_NUMBER],
['map', METHOD_CALLS_ARG_DEOPTS_SELF_RETURNS_NEW_ARRAY],
['pop', METHOD_MUTATES_SELF_RETURNS_UNKNOWN],
['push', METHOD_MUTATES_SELF_AND_ARGS_RETURNS_NUMBER],
['reduce', METHOD_CALLS_ARG_DEOPTS_SELF_RETURNS_UNKNOWN],
['reduceRight', METHOD_CALLS_ARG_DEOPTS_SELF_RETURNS_UNKNOWN],
['reverse', METHOD_MUTATES_SELF_RETURNS_SELF],
['shift', METHOD_MUTATES_SELF_RETURNS_UNKNOWN],
['slice', METHOD_DEOPTS_SELF_RETURNS_NEW_ARRAY],
['some', METHOD_CALLS_ARG_DEOPTS_SELF_RETURNS_BOOLEAN],
['sort', METHOD_CALLS_ARG_MUTATES_SELF_RETURNS_SELF],
['splice', METHOD_MUTATES_SELF_RETURNS_NEW_ARRAY],
['toLocaleString', METHOD_RETURNS_STRING],
['toString', METHOD_RETURNS_STRING],
['unshift', METHOD_MUTATES_SELF_AND_ARGS_RETURNS_NUMBER],
['values', METHOD_DEOPTS_SELF_RETURNS_UNKNOWN]
]), OBJECT_PROTOTYPE, true);
class SpreadElement extends NodeBase {
deoptimizeArgumentsOnInteractionAtPath(interaction, path, recursionTracker) {
@@ -3994,6 +4020,14 @@ const ValueProperties = Symbol('Value Properties');
const getUnknownValue = () => UnknownValue;
const returnFalse = () => false;
const returnTrue = () => true;
const getWellKnownSymbol = (symbol) => ({
__proto__: null,
[ValueProperties]: {
deoptimizeArgumentsOnCall: doNothing,
getLiteralValue: () => symbol,
hasEffectsWhenCalled: returnTrue
}
});
const PURE = {
deoptimizeArgumentsOnCall: doNothing,
getLiteralValue: getUnknownValue,
@@ -4079,6 +4113,11 @@ const INTL_MEMBER = {
[ValueProperties]: PURE,
supportedLocalesOf: PC
};
const UNKNOWN_WELL_KNOWN = {
deoptimizeArgumentsOnCall: doNothing,
getLiteralValue: () => UnknownWellKnown,
hasEffectsWhenCalled: returnTrue
};
const knownGlobals = {
// Placeholders for global objects to avoid shape mutations
global: O,
@@ -4274,37 +4313,10 @@ const knownGlobals = {
for: PF,
keyFor: PF,
prototype: O,
asyncDispose: {
__proto__: null,
[ValueProperties]: {
deoptimizeArgumentsOnCall: doNothing,
getLiteralValue() {
return SymbolAsyncDispose;
},
// This might not be needed, but then we need to check a few more cases
hasEffectsWhenCalled: returnTrue
}
},
dispose: {
__proto__: null,
[ValueProperties]: {
deoptimizeArgumentsOnCall: doNothing,
getLiteralValue() {
return SymbolDispose;
},
hasEffectsWhenCalled: returnTrue
}
},
toStringTag: {
__proto__: null,
[ValueProperties]: {
deoptimizeArgumentsOnCall: doNothing,
getLiteralValue() {
return SymbolToStringTag;
},
hasEffectsWhenCalled: returnTrue
}
}
asyncDispose: getWellKnownSymbol(SymbolAsyncDispose),
dispose: getWellKnownSymbol(SymbolDispose),
hasInstance: getWellKnownSymbol(SymbolHasInstance),
toStringTag: getWellKnownSymbol(SymbolToStringTag)
},
SyntaxError: PC,
toLocaleString: O,
@@ -4978,7 +4990,9 @@ function getGlobalAtPath(path) {
}
currentGlobal = currentGlobal[pathSegment];
if (!currentGlobal) {
return null;
// Well-known symbols very often have a complex meaning and are invoked implicitly by the language.
// Resolve them to a special value so they can be distinguished and excluded from treeshaking.
return path[0] === 'Symbol' && path.length === 2 ? UNKNOWN_WELL_KNOWN : null;
}
}
return currentGlobal[ValueProperties];
@@ -5924,7 +5938,11 @@ class ClassNode extends NodeBase {
if (definition.computed) {
const keyValue = definition.key.getLiteralValueAtPath(EMPTY_PATH, SHARED_RECURSION_TRACKER, this);
if (typeof keyValue === 'symbol') {
properties.push({ key: UnknownKey, kind, property: definition });
properties.push({
key: isAnyWellKnown(keyValue) ? keyValue : UnknownKey,
kind,
property: definition
});
continue;
}
else {
@@ -6515,7 +6533,7 @@ class ExpressionStatement extends NodeBase {
render(code, options) {
super.render(code, options);
if (code.original[this.end - 1] !== ';') {
code.appendLeft(this.end, ';');
code.appendRight(this.end, ';');
}
}
shouldBeIncluded(context) {
@@ -6809,7 +6827,7 @@ class FunctionNode extends FunctionBase {
}
createScope(parentScope) {
this.scope = new FunctionScope(parentScope, this);
this.constructedEntity = new ObjectEntity(Object.create(null), OBJECT_PROTOTYPE);
this.constructedEntity = new ObjectEntity(new Map(), OBJECT_PROTOTYPE);
// This makes sure that all deoptimizations of "this" are applied to the
// constructed entity.
this.scope.thisVariable.addArgumentForDeoptimization(this.constructedEntity);
@@ -7544,6 +7562,9 @@ class MemberExpression extends NodeBase {
this.includeNode(context);
this.object.include(context, includeChildrenRecursively);
this.property.include(context, includeChildrenRecursively);
if (includeChildrenRecursively) {
this.variable?.includePath(UNKNOWN_PATH, context);
}
}
includeNode(context) {
this.included = true;
@@ -11959,6 +11980,9 @@ class BinaryExpression extends NodeBase {
if (typeof this.getRenderedLiteralValue() === 'symbol') {
this.left.include(context, includeChildrenRecursively, options);
this.right.include(context, includeChildrenRecursively, options);
// `instanceof` will attempt to call RHS's `Symbol.hasInstance` if it exists.
if (this.operator === 'instanceof')
this.right.includePath(INSTANCEOF_PATH, context);
}
}
includeNode(context) {
@@ -14458,7 +14482,11 @@ class ObjectExpression extends NodeBase {
if (property.computed) {
const keyValue = property.key.getLiteralValueAtPath(EMPTY_PATH, SHARED_RECURSION_TRACKER, this);
if (typeof keyValue === 'symbol') {
properties.push({ key: UnknownKey, kind: property.kind, property });
properties.push({
key: isAnyWellKnown(keyValue) ? keyValue : UnknownKey,
kind: property.kind,
property
});
continue;
}
else {
@@ -20300,11 +20328,16 @@ function collapseSourcemaps(file, map, modules, bundleSourcemapChain, excludeCon
sources = sources.map((source) => relative(directory, source));
file = basename(file);
}
sourcesContent = (excludeContent ? null : sourcesContent);
for (const module of modules) {
resetSourcemapCache(module.originalSourcemap, module.sourcemapChain);
}
return new SourceMap({ file, mappings, names, sources, sourcesContent });
return new SourceMap({
file,
mappings,
names,
sources,
sourcesContent: excludeContent ? undefined : sourcesContent
});
}
function collapseSourcemap(id, originalCode, originalSourcemap, sourcemapChain, log) {
if (sourcemapChain.length === 0) {