Skip to content

Commit

Permalink
tree shake Object.entries/values
Browse files Browse the repository at this point in the history
  • Loading branch information
sapphi-red committed Jul 26, 2023
1 parent db8fd44 commit 704845c
Show file tree
Hide file tree
Showing 5 changed files with 69 additions and 17 deletions.
33 changes: 29 additions & 4 deletions src/ast/nodes/shared/knownGlobals.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,10 @@
import { doNothing } from '../../../utils/doNothing';
import type { HasEffectsContext } from '../../ExecutionContext';
import type { NodeInteractionCalled } from '../../NodeInteractions';
import { NODE_INTERACTION_UNKNOWN_ASSIGNMENT } from '../../NodeInteractions';
import {
NODE_INTERACTION_UNKNOWN_ACCESS,
NODE_INTERACTION_UNKNOWN_ASSIGNMENT
} from '../../NodeInteractions';
import type { ObjectPath } from '../../utils/PathTracker';
import {
SymbolToStringTag,
Expand All @@ -12,7 +15,7 @@ import {
} from '../../utils/PathTracker';
import ArrayExpression from '../ArrayExpression';
import type { LiteralValueOrUnknown } from './Expression';
import { UnknownTruthyValue } from './Expression';
import { ExpressionEntity, UnknownTruthyValue } from './Expression';

const ValueProperties = Symbol('Value Properties');

Expand Down Expand Up @@ -52,6 +55,22 @@ const PURE_WITH_ARRAY: ValueDescription = {
}
};

const GETTER_ACCESS: ValueDescription = {
deoptimizeArgumentsOnCall: doNothing,
getLiteralValue: getTruthyLiteralValue,
hasEffectsWhenCalled({ args }, context) {
const [_thisArgument, firstArgument] = args;
return (
!(firstArgument instanceof ExpressionEntity) ||
firstArgument.hasEffectsOnInteractionAtPath(
UNKNOWN_PATH,
NODE_INTERACTION_UNKNOWN_ACCESS,
context
)
);
}
};

// We use shortened variables to reduce file size here
/* OBJECT */
const O: GlobalDescription = {
Expand All @@ -65,6 +84,12 @@ const PF: GlobalDescription = {
[ValueProperties]: PURE
};

/* PURE FUNCTION IF FIRST ARG DOES NOT CONTAIN A GETTER */
const PF_NO_GETTER: GlobalDescription = {
__proto__: null,
[ValueProperties]: GETTER_ACCESS
};

/* FUNCTION THAT MUTATES FIRST ARG WITHOUT TRIGGERING ACCESSORS */
const MUTATES_ARG_WITHOUT_ACCESSOR: GlobalDescription = {
__proto__: null,
Expand Down Expand Up @@ -253,8 +278,8 @@ const knownGlobals: GlobalDescription = {
isSealed: PF,
keys: PF,
fromEntries: O,
entries: O,
values: O,
entries: PF_NO_GETTER,
values: PF_NO_GETTER,
prototype: O
},
parseFloat: PF,
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
let effects = 0;

const objWithEffect = {
get foo() {
effects++;
return 'foo';
}
};

Object.values(objWithEffect);
Object.entries(objWithEffect);

assert.equal(effects, 2);
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
let effects = 0;

const objWithEffect = {
get foo() {
effects++;
return 'foo';
}
};

const objWithoutEffect1 = {
get foo() {
return 'foo';
}
};
const objWithoutEffect2 = {
foo: 'foo'
};

Object.values(objWithEffect);
Object.entries(objWithEffect);

Object.values(objWithoutEffect1);
Object.entries(objWithoutEffect1);
Object.values(objWithoutEffect2);
Object.entries(objWithoutEffect2);

assert.equal(effects, 2);

This file was deleted.

0 comments on commit 704845c

Please sign in to comment.