Skip to content

Commit

Permalink
feat: optimize referenced objects
Browse files Browse the repository at this point in the history
  • Loading branch information
merceyz committed Dec 27, 2019
1 parent dceb1e8 commit 20575e9
Show file tree
Hide file tree
Showing 5 changed files with 69 additions and 3 deletions.
21 changes: 18 additions & 3 deletions src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ import { combineStringLiterals } from './visitors/combineStringLiterals';
import { createConditionalExpression } from './visitors/createConditionalExpression';
import { removeUnnecessaryCalls } from './visitors/removeUnnecessaryCalls';
import { createObjectKeyLookups } from './visitors/createObjectKeyLookups';
import { referencedObjects } from './visitors/referencedObjects';

const visitors = [
collectCalls,
Expand All @@ -28,6 +29,7 @@ const visitors = [
createConditionalExpression,
removeUnnecessaryCalls,
createObjectKeyLookups,
referencedObjects,
];

export default (): babel.PluginObj<{ opts?: Partial<PluginOptions>; filename: string }> => ({
Expand All @@ -43,14 +45,18 @@ export default (): babel.PluginObj<{ opts?: Partial<PluginOptions>; filename: st

const internalState = new Map<string, any>();

const runVisitors = (expression: babel.NodePath<t.CallExpression>) => {
const runVisitors = (
expression: babel.NodePath<t.CallExpression>,
pushToQueue: (expression: babel.NodePath<t.CallExpression>) => void,
) => {
for (const visitor of visitors) {
visitor({
program: path,
expression,
state: internalState,
options,
filename: state.filename,
pushToQueue,
});

if (!expression.isCallExpression()) {
Expand All @@ -64,7 +70,12 @@ export default (): babel.PluginObj<{ opts?: Partial<PluginOptions>; filename: st

if (isImportMap(item)) {
for (let y = 0; y < item.expressions.length; y++) {
if (runVisitors(item.expressions[y]) === false) {
if (
runVisitors(item.expressions[y], newExpression => {
item.expressions.push(newExpression);
item.referenceCount += 1;
}) === false
) {
item.expressions.splice(y, 1);
item.referenceCount -= 1;
y -= 1;
Expand All @@ -77,7 +88,11 @@ export default (): babel.PluginObj<{ opts?: Partial<PluginOptions>; filename: st
break;
}
}
} else if (runVisitors(item) === false) {
} else if (
runVisitors(item, newExpression => {
expressions.push(newExpression);
}) === false
) {
expressions.splice(x, 1);
x -= 1;
}
Expand Down
1 change: 1 addition & 0 deletions src/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,4 +8,5 @@ export type VisitorFunction = (params: {
options: PluginOptions;
state: Map<string, any>;
filename: string;
pushToQueue: (expression: babel.NodePath<t.CallExpression>) => void;
}) => void;
29 changes: 29 additions & 0 deletions src/visitors/referencedObjects.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
import * as t from '@babel/types';
import { VisitorFunction } from '../types';

export const referencedObjects: VisitorFunction = ({ expression, pushToQueue }) => {
const args = expression.get('arguments');

for (const nodePath of args) {
if (!nodePath.isIdentifier()) {
continue;
}

const binding = nodePath.scope.getBinding(nodePath.node.name);
if (!binding) {
continue;
}

if (
binding.references === 1 &&
binding.constant &&
binding.path.isVariableDeclarator() &&
t.isObjectExpression(binding.path.node.init)
) {
const init = binding.path.get('init');

init.replaceWith(t.callExpression(expression.node.callee, [binding.path.node.init]));
pushToQueue(init as babel.NodePath<t.CallExpression>);
}
}
};
11 changes: 11 additions & 0 deletions test/fixtures/referenced-object/code.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
// https://github.com/DestinyItemManager/DIM/blob/a441eff6be8cbdd48477baa9ac30d9147153a08e/src/app/inventory/InventoryItem.tsx#L84-L89

const itemStyles = {
[styles.searchHidden]: searchHidden,
[styles.subclassPathTop]: subclassPath && subclassPath.position === 'top',
[styles.subclassPathMiddle]: subclassPath && subclassPath.position === 'middle',
[styles.subclassPathBottom]: subclassPath && subclassPath.position === 'bottom',
};

// https://github.com/DestinyItemManager/DIM/blob/a441eff6be8cbdd48477baa9ac30d9147153a08e/src/app/inventory/InventoryItem.tsx#L102
clsx('foo', itemStyles);
10 changes: 10 additions & 0 deletions test/fixtures/referenced-object/output.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
const itemStyles = clsx(
subclassPath &&
{
top: styles.subclassPathTop,
middle: styles.subclassPathMiddle,
bottom: styles.subclassPathBottom,
}[subclassPath.position],
searchHidden && styles.searchHidden,
);
clsx('foo', itemStyles);

0 comments on commit 20575e9

Please sign in to comment.