diff --git a/.eslintrc b/.eslintrc index 7798a50..589e174 100644 --- a/.eslintrc +++ b/.eslintrc @@ -14,3 +14,4 @@ rules: max-len: 1 arrow-body-style: 1 + no-param-reassign: 0 diff --git a/src/index.js b/src/index.js index a47d402..36fa437 100644 --- a/src/index.js +++ b/src/index.js @@ -1,52 +1,63 @@ -// private +// target const defineName = 'Promise'; +const methods = [ + 'resolve', + 'reject', + 'all', + 'race', +]; /** * @module babel-plugin-transform-bluebird * @returns {babelPlugin} unknown */ -export default ({ template }) => { - return ({ - visitor: { - Program: { - exit(path) { - let injectBluebird = false; - for (const node of path.node.body) { - const expression = node.expression || {}; - const specifiers = node.specifiers || []; - const declarations = node.declarations || []; +export default () => ({ + visitor: { + Program: { + enter(path, file) { + file.__UNUSE_BLUEBIRD__ = false; + for (const node of path.node.body) { + // found "import Promise" + const specifiers = node.specifiers || []; + const localNames = specifiers.map((specifier) => specifier.local.name); + if (localNames.indexOf(defineName) > -1) { + file.__UNUSE_BLUEBIRD__ = true; + return; + } - // found "new Promise" or "Promise.method()" - const calleeName = expression.callee && (expression.callee.name || expression.callee.object.name); - if (calleeName === defineName) { - injectBluebird = true; - } + // found "var Promise" + const declarations = node.declarations || []; + const declarationIds = declarations.map((declaration) => declaration.id.name); + if (declarationIds.indexOf(defineName) > -1) { + file.__UNUSE_BLUEBIRD__ = true; + return; + } + } + }, + }, - // found "var foo = new Promise" or "var foo = Promise.resolve()" - const declarationInits = declarations.map((declaration) => declaration.init.callee.name || declaration.init.callee.object.name); - if (declarationInits.indexOf(defineName) > -1) { - injectBluebird = true; - } + // found "new Promise" + NewExpression(path, file) { + if (file.__UNUSE_BLUEBIRD__) { + return; + } - // found "import Promise" - const localNames = specifiers.map((specifier) => specifier.local.name); - if (localNames.indexOf(defineName) > -1) { - return; - } + if (path.get('callee').node.name === defineName) { + path.node.callee = file.addImport('bluebird', 'default'); + } + }, - // found "var Promise" - const declarationIds = declarations.map((declaration) => declaration.id.name); - if (declarationIds.indexOf(defineName) > -1) { - return; - } - } + // found "Promise.methods()" + CallExpression(path, file) { + if (file.__UNUSE_BLUEBIRD__) { + return; + } - if (injectBluebird) { - const topNodes = [template(`var ${defineName} = require("bluebird")`)()]; - path.unshiftContainer('body', topNodes); - } - }, - }, + methods.forEach((method) => { + if (path.get('callee').matchesPattern(`${defineName}.${method}`)) { + path.node.callee = file.addImport('bluebird', method); + } + }); }, - }); -}; + }, +}); diff --git a/test/specs.js b/test/specs.js index ba9190b..f8df245 100644 --- a/test/specs.js +++ b/test/specs.js @@ -4,6 +4,13 @@ import q from 'q'; const Q = q.resolve().constructor; export default [ + { + description: 'should be injected if called built-in `Promise.resolve` in iife', + code: ` + (() => Promise.resolve())() + `, + expected: Bluebird, + }, { description: 'should be injected if called built-in `Promise.resolve`', code: 'Promise.resolve()', @@ -32,18 +39,44 @@ export default [ expected: Bluebird, }, { - description: 'should be injected if assigned built-in `Promise`', + description: 'should be injected if assigned built-in `Promise.resolve` in iife', code: ` - var hoge = new Promise((resolve)=> resolve()) - hoge + (() => { + var foo = Promise.resolve() + return foo + })() `, expected: Bluebird, }, { description: 'should be injected if assigned built-in `Promise.resolve`', code: ` - var hoge = Promise.resolve() - hoge + var foo = Promise.resolve() + foo + `, + expected: Bluebird, + }, + { + description: 'should be injected if assigned built-in `Promise.race`', + code: ` + var foo = Promise.race([]) + foo + `, + expected: Bluebird, + }, + { + description: 'should be injected if assigned built-in `Promise.all`', + code: ` + var foo = Promise.all([]) + foo + `, + expected: Bluebird, + }, + { + description: 'should be injected if assigned built-in `Promise`', + code: ` + var foo = new Promise((resolve)=> resolve()) + foo `, expected: Bluebird, },