Skip to content

Instantly share code, notes, and snippets.

@jnwng
Created September 28, 2015 05:24
Show Gist options
  • Save jnwng/1b1b33bcf4d8438f41cd to your computer and use it in GitHub Desktop.
Save jnwng/1b1b33bcf4d8438f41cd to your computer and use it in GitHub Desktop.
Origami Codemod
module.exports = function(file, api) {
const j = api.jscodeshift;
const b = j.types.builders;
const {astNodesAreEquivalent} = j.types;
var root = j(file.source);
const keys = ['to', 'initialize'];
const getRequireCall = (path, moduleName) => {
const call = path
.find(j.CallExpression, {callee: {name: 'require'}})
.filter(p => {
return astNodesAreEquivalent(
p.value.arguments[0],
b.literal(moduleName)
);
});
return call.size() === 1 ? call.get() : null;
};
const createRequireCall = moduleName => {
const topLevelRequire = getRequireCall(root, moduleName);
if (topLevelRequire) {
if (j.VariableDeclarator.check(topLevelRequire.parentPath.value)) {
return topLevelRequire.parentPath.value.id;
} else {
return topLevelRequire.value;
}
} else {
var requireCall = j.callExpression(
j.identifier('require'), [
j.literal(`lazy!${moduleName}`)
]
);
return requireCall;
}
};
const updateObjectExpression = (path, moduleName) => {
const moduleProp = j.property(
'init',
j.identifier('module'),
createRequireCall(moduleName)
);
j(path).replaceWith(
j.objectExpression(
path.value.properties.concat(moduleProp)
)
);
};
return root
.find(j.ObjectExpression)
.filter(p => {
var hasKeys = j(p.value.properties)
.filter(p1 => {
return keys.indexOf(p1.value.key.name) >= 0;
})
.size() >= 1;
return hasKeys;
})
.forEach(p => {
var moduleName;
if (j.AssignmentExpression.check(p.parentPath.value)) {
// Defined as an object
moduleName = p.parentPath.value.left.property.value;
} else if (j.Property.check(p.parentPath.value)) {
// defined with Origami.region.open as a value to a key.
moduleName = p.parentPath.value.key.value;
} else if (j.CallExpression.check(p.parentPath.parentPath.value)) {
// defined within Origami.region.append
if (j.Identifier.check(p.parentPath.value[0])) {
var declaration = root
.findVariableDeclarators(p.parentPath.value[0].name)
.get();
moduleName = declaration.value.init.arguments[0].value;
} else if (j.Literal.check(p.parentPath.value[0])) {
moduleName = p.parentPath.value[0].value;
}
}
// Find if there was a require call
var declarator = getRequireCall(
root,
moduleName
);
updateObjectExpression(p, moduleName);
// We don't want to remove existing variable declarations.
if (declarator &&
!j.VariableDeclarator.check(declarator.parentPath.value)) {
j(declarator).remove();
}
})
.toSource({quote: 'single'});
};
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment