@putout/plugin-extract-object-properties
Version:
🐊Putout plugin adds ability to extract object properties into variable
73 lines (55 loc) • 1.96 kB
JavaScript
import {operator, types} from 'putout';
const {objectProperty} = types;
const {replaceWith, compare} = operator;
const SHORTHAND = true;
const COMPUTED = false;
export const report = () => `Extract object properties into variables`;
export const fix = ({path, expandPath, property}) => {
const newProperty = objectProperty(property, property, COMPUTED, SHORTHAND);
expandPath.node.properties.push(newProperty);
replaceWith(path, property);
};
export const traverse = ({listStore, push}) => ({
'const __object = __a.__b': save({
listStore,
}),
'const __object = __a(__args)': save({
listStore,
}),
'Program': {
exit: exit({
push,
listStore,
}),
},
});
const save = ({listStore}) => (path) => {
const idPath = path.get('declarations.0.id');
const initPath = path.get('declarations.0.init');
listStore([initPath, idPath]);
};
const exit = ({push, listStore}) => () => {
const items = listStore();
for (const [initPath] of items) {
for (const [currentPath, expandPath] of items) {
const objectPath = initPath.get('object');
if (!objectPath.isMemberExpression() && !objectPath.isCallExpression())
continue;
const propertyPath = initPath.get('property');
const property = propertyPath.node;
const current = currentPath.node;
const {object} = initPath.node;
const {name} = property;
if (expandPath.scope.bindings[name])
continue;
if (expandPath.scope.uid !== initPath.scope.uid)
continue;
if (compare(object, current))
push({
expandPath,
path: initPath,
property,
});
}
}
};