forked from enviPath/enviPy
192 lines
5.7 KiB
JavaScript
192 lines
5.7 KiB
JavaScript
'use strict';
|
|
|
|
Object.defineProperty(exports, "__esModule", {
|
|
value: true
|
|
});
|
|
|
|
var _get2 = require('lodash/get');
|
|
|
|
var _get3 = _interopRequireDefault(_get2);
|
|
|
|
var _sortBy2 = require('lodash/sortBy');
|
|
|
|
var _sortBy3 = _interopRequireDefault(_sortBy2);
|
|
|
|
var _each2 = require('lodash/each');
|
|
|
|
var _each3 = _interopRequireDefault(_each2);
|
|
|
|
var _assign3 = require('lodash/assign');
|
|
|
|
var _assign4 = _interopRequireDefault(_assign3);
|
|
|
|
exports.default = lodash;
|
|
|
|
var _config = require('./config');
|
|
|
|
var _config2 = _interopRequireDefault(_config);
|
|
|
|
var _importModule3 = require('./importModule');
|
|
|
|
var _importModule4 = _interopRequireDefault(_importModule3);
|
|
|
|
var _mapping = require('./mapping');
|
|
|
|
var _mapping2 = _interopRequireDefault(_mapping);
|
|
|
|
var _Store = require('./Store');
|
|
|
|
var _Store2 = _interopRequireDefault(_Store);
|
|
|
|
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
|
|
|
|
/** The error message used when chain sequences are detected. */
|
|
var CHAIN_ERROR = ['Lodash chain sequences are not supported by babel-plugin-lodash.', 'Consider substituting chain sequences with composition patterns.', 'See https://medium.com/making-internets/why-using-chain-is-a-mistake-9bc1f80d51ba'].join('\n');
|
|
|
|
/*----------------------------------------------------------------------------*/
|
|
|
|
function lodash(_ref) {
|
|
var types = _ref.types;
|
|
|
|
|
|
var identifiers = {
|
|
'PLACEHOLDER': types.identifier('placeholder'),
|
|
'UNDEFINED': types.identifier('undefined')
|
|
};
|
|
|
|
/**
|
|
* Used to track variables built during the AST pass. We instantiate these in
|
|
* the `Program` visitor in order to support running the plugin in watch mode
|
|
* or on multiple files.
|
|
*
|
|
* @type Store
|
|
*/
|
|
var store = new _Store2.default();
|
|
|
|
function getCallee(_ref2) {
|
|
var parentPath = _ref2.parentPath;
|
|
|
|
// Trace curried calls to their origin, e.g. `fp.partial(func)([fp, 2])(1)`.
|
|
while (!parentPath.isStatement()) {
|
|
if (parentPath.isCallExpression()) {
|
|
var result = parentPath.node.callee;
|
|
while (types.isCallExpression(result)) {
|
|
result = result.callee;
|
|
}
|
|
return result;
|
|
}
|
|
parentPath = parentPath.parentPath;
|
|
}
|
|
}
|
|
|
|
/*--------------------------------------------------------------------------*/
|
|
|
|
var visitor = {
|
|
Program(path, state) {
|
|
var _assign2 = (0, _assign4.default)(_mapping2.default, (0, _config2.default)(state.opts)),
|
|
ids = _assign2.ids;
|
|
|
|
var file = path.hub.file;
|
|
|
|
// Clear tracked method imports.
|
|
|
|
_importModule4.default.cache.clear();
|
|
store.clear();
|
|
|
|
// Populate module paths per package.
|
|
(0, _each3.default)(ids, function (id) {
|
|
store.set(id);
|
|
_mapping2.default.modules.get(id).forEach(function (value, key) {
|
|
store.set(id + '/' + key);
|
|
});
|
|
});
|
|
|
|
// Replace old members with their method imports.
|
|
(0, _each3.default)(file.metadata.modules.imports, function (module) {
|
|
var pkgStore = store.get(module.source);
|
|
if (!pkgStore) {
|
|
return;
|
|
}
|
|
var isLodash = pkgStore.isLodash();
|
|
var specs = (0, _sortBy3.default)(module.specifiers, function (spec) {
|
|
return spec.imported == 'default';
|
|
});
|
|
|
|
(0, _each3.default)(specs, function (spec) {
|
|
var imported = spec.imported,
|
|
local = spec.local;
|
|
|
|
var binding = file.scope.getBinding(local);
|
|
var _binding$path$parent$ = binding.path.parent.importKind,
|
|
importKind = _binding$path$parent$ === undefined ? 'value' : _binding$path$parent$;
|
|
|
|
// Skip type annotation specifiers.
|
|
|
|
if (importKind != 'value') {
|
|
return;
|
|
}
|
|
var isChain = isLodash && imported == 'chain';
|
|
|
|
(0, _each3.default)(binding.referencePaths, function (refPath) {
|
|
var node = refPath.node,
|
|
parentPath = refPath.parentPath;
|
|
var type = node.type;
|
|
|
|
|
|
if (imported && imported != 'default') {
|
|
if (isChain && refPath.parentPath.isCallExpression()) {
|
|
throw refPath.buildCodeFrameError(CHAIN_ERROR);
|
|
}
|
|
|
|
var _importModule = (0, _importModule4.default)(pkgStore, imported, refPath),
|
|
name = _importModule.name;
|
|
|
|
refPath.replaceWith({ type, name });
|
|
} else if (parentPath.isMemberExpression()) {
|
|
var key = refPath.parent.property.name;
|
|
if (isLodash && key == 'chain' && parentPath.parentPath.isCallExpression()) {
|
|
throw refPath.buildCodeFrameError(CHAIN_ERROR);
|
|
}
|
|
|
|
var _importModule2 = (0, _importModule4.default)(pkgStore, key, refPath),
|
|
_name = _importModule2.name;
|
|
|
|
parentPath.replaceWith({ type, name: _name });
|
|
} else if (isLodash) {
|
|
var callee = getCallee(refPath);
|
|
if (callee && callee.name == local) {
|
|
throw refPath.buildCodeFrameError(CHAIN_ERROR);
|
|
}
|
|
refPath.replaceWith(callee ? types.memberExpression(callee, identifiers.PLACEHOLDER) : identifiers.UNDEFINED);
|
|
}
|
|
});
|
|
});
|
|
});
|
|
},
|
|
|
|
ImportDeclaration(path) {
|
|
if (store.get(path.node.source.value)) {
|
|
// Remove old import.
|
|
path.remove();
|
|
}
|
|
},
|
|
|
|
ExportNamedDeclaration(path) {
|
|
var node = path.node;
|
|
|
|
var pkgPath = (0, _get3.default)(node, 'source.value');
|
|
var pkgStore = store.get(pkgPath);
|
|
|
|
if (!pkgStore) {
|
|
return;
|
|
}
|
|
node.source = null;
|
|
(0, _each3.default)(node.specifiers, function (spec) {
|
|
spec.local = (0, _importModule4.default)(pkgStore, spec.local.name, path);
|
|
});
|
|
}
|
|
};
|
|
|
|
return { visitor };
|
|
};
|
|
module.exports = exports['default']; |