From 21359858ed67929bdacb2d041fc9de9073a80fcd Mon Sep 17 00:00:00 2001 From: Ulysse Buonomo Date: Sun, 23 Jul 2017 23:17:39 -0400 Subject: [PATCH 1/2] first step, basic case --- .../basic-case.input.js | 1 + .../basic-case.output.js | 1 + .../different-names.input.js | 1 + .../different-names.output.js | 1 + ...e-lib-func-to-import-func-from-lib-test.js | 17 +++++ ...equire-lib-func-to-import-func-from-lib.js | 75 +++++++++++++++++++ .../variable-require-to-import-default.js | 3 +- 7 files changed, 97 insertions(+), 2 deletions(-) create mode 100644 transforms/__testfixtures__/require-lib-func-to-import-func-from-lib/basic-case.input.js create mode 100644 transforms/__testfixtures__/require-lib-func-to-import-func-from-lib/basic-case.output.js create mode 100644 transforms/__testfixtures__/require-lib-func-to-import-func-from-lib/different-names.input.js create mode 100644 transforms/__testfixtures__/require-lib-func-to-import-func-from-lib/different-names.output.js create mode 100644 transforms/__tests__/require-lib-func-to-import-func-from-lib-test.js create mode 100644 transforms/require-lib-func-to-import-func-from-lib.js diff --git a/transforms/__testfixtures__/require-lib-func-to-import-func-from-lib/basic-case.input.js b/transforms/__testfixtures__/require-lib-func-to-import-func-from-lib/basic-case.input.js new file mode 100644 index 0000000..f7083be --- /dev/null +++ b/transforms/__testfixtures__/require-lib-func-to-import-func-from-lib/basic-case.input.js @@ -0,0 +1 @@ +const func = require('lib').func; \ No newline at end of file diff --git a/transforms/__testfixtures__/require-lib-func-to-import-func-from-lib/basic-case.output.js b/transforms/__testfixtures__/require-lib-func-to-import-func-from-lib/basic-case.output.js new file mode 100644 index 0000000..7b9a567 --- /dev/null +++ b/transforms/__testfixtures__/require-lib-func-to-import-func-from-lib/basic-case.output.js @@ -0,0 +1 @@ +import { func } from 'lib'; \ No newline at end of file diff --git a/transforms/__testfixtures__/require-lib-func-to-import-func-from-lib/different-names.input.js b/transforms/__testfixtures__/require-lib-func-to-import-func-from-lib/different-names.input.js new file mode 100644 index 0000000..21f8565 --- /dev/null +++ b/transforms/__testfixtures__/require-lib-func-to-import-func-from-lib/different-names.input.js @@ -0,0 +1 @@ +const myFunc = require('lib').func; \ No newline at end of file diff --git a/transforms/__testfixtures__/require-lib-func-to-import-func-from-lib/different-names.output.js b/transforms/__testfixtures__/require-lib-func-to-import-func-from-lib/different-names.output.js new file mode 100644 index 0000000..e3ff58c --- /dev/null +++ b/transforms/__testfixtures__/require-lib-func-to-import-func-from-lib/different-names.output.js @@ -0,0 +1 @@ +import {func as myFunc} from 'lib'; \ No newline at end of file diff --git a/transforms/__tests__/require-lib-func-to-import-func-from-lib-test.js b/transforms/__tests__/require-lib-func-to-import-func-from-lib-test.js new file mode 100644 index 0000000..19987ac --- /dev/null +++ b/transforms/__tests__/require-lib-func-to-import-func-from-lib-test.js @@ -0,0 +1,17 @@ +import {defineTest} from 'jscodeshift/dist/testUtils' + +const tests = [ + 'basic-case', + 'different-names', +] + +describe('require-lib-func-to-import-func-from-lib', () => { + tests.forEach(test => { + defineTest( + __dirname, + 'require-lib-func-to-import-func-from-lib', + null, + `require-lib-func-to-import-func-from-lib/${test}` + ) + }) +}) diff --git a/transforms/require-lib-func-to-import-func-from-lib.js b/transforms/require-lib-func-to-import-func-from-lib.js new file mode 100644 index 0000000..41a158d --- /dev/null +++ b/transforms/require-lib-func-to-import-func-from-lib.js @@ -0,0 +1,75 @@ +/** + * Transform + * + * const Lib = require('lib'); + * + * to + * + * import Lib from 'lib'; + * + * Only on global context + */ + +// on https://astexplorer.net: Press ctrl+space for code completion + +import Logger from './utils/logger' +import {isTopNode} from './utils/filters' + +function transformer(file, api, options) { + const j = api.jscodeshift + const logger = new Logger(file, options) + + // ------------------------------------------------------------------ SEARCH + const nodes = j(file.source) + .find(j.VariableDeclaration, { + declarations: [{ + init: { + type: 'MemberExpression', + object: { + callee: { + name: 'require' + } + } + } + }] + }).filter(isTopNode) + + logger.log(`${nodes.length} nodes will be transformed`) + + // ----------------------------------------------------------------- REPLACE + return nodes.replaceWith(path => { + const rest = [] + const imports = [] + for (const declaration of path.node.declarations) { + if (j.MemberExpression.check(declaration.init) + && declaration.init.object.callee.name === 'require'){ + const importSpecifier = j.importSpecifier(declaration.id) + + const sourcePath = declaration.init.object.arguments.shift() + + if (declaration.init.object.arguments.length) { + logger.error(`${logger.lines(declaration)} too many arguments.` + + 'Aborting transformation') + return file.source + } + if (!j.Literal.check(sourcePath)) { + logger.error(`${logger.lines(declaration)} bad argument.` + + 'Expecting a string literal, got ' + + j(sourcePath).toSource() + + '`. Aborting transformation') + return file.source + } + imports.push(j.importDeclaration([importSpecifier], sourcePath)) + } else { + rest.push(declaration) + } + } + if (rest.length > 0) { + logger.warn(`${logger.lines(path.node)} introduced leftover`) + return [...imports, j.variableDeclaration(path.node.kind, rest)] + } + return imports + }).toSource() +} + +export default transformer diff --git a/transforms/variable-require-to-import-default.js b/transforms/variable-require-to-import-default.js index c9ff7af..5b2f063 100644 --- a/transforms/variable-require-to-import-default.js +++ b/transforms/variable-require-to-import-default.js @@ -39,8 +39,7 @@ function transformer(file, api, options) { const rest = [] const imports = [] for (const declaration of path.node.declarations) { - if (declaration.init !== null - && declaration.init.type === 'CallExpression' + if (j.CallExpression.check(declaration.init) && declaration.init.callee.name === 'require'){ const importSpecifier = j.importDefaultSpecifier(declaration.id) From 4ed8e17f223ad71ee7bc6d4973363ecb359f68e4 Mon Sep 17 00:00:00 2001 From: Ulysse Buonomo Date: Sun, 23 Jul 2017 23:26:37 -0400 Subject: [PATCH 2/2] add different name in scope than in module handling --- .../different-names.input.js | 2 +- .../different-names.output.js | 2 +- transforms/require-lib-func-to-import-func-from-lib.js | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/transforms/__testfixtures__/require-lib-func-to-import-func-from-lib/different-names.input.js b/transforms/__testfixtures__/require-lib-func-to-import-func-from-lib/different-names.input.js index 21f8565..bbea2d2 100644 --- a/transforms/__testfixtures__/require-lib-func-to-import-func-from-lib/different-names.input.js +++ b/transforms/__testfixtures__/require-lib-func-to-import-func-from-lib/different-names.input.js @@ -1 +1 @@ -const myFunc = require('lib').func; \ No newline at end of file +const myFunc = require('lib').func; diff --git a/transforms/__testfixtures__/require-lib-func-to-import-func-from-lib/different-names.output.js b/transforms/__testfixtures__/require-lib-func-to-import-func-from-lib/different-names.output.js index e3ff58c..9d9a3f4 100644 --- a/transforms/__testfixtures__/require-lib-func-to-import-func-from-lib/different-names.output.js +++ b/transforms/__testfixtures__/require-lib-func-to-import-func-from-lib/different-names.output.js @@ -1 +1 @@ -import {func as myFunc} from 'lib'; \ No newline at end of file +import { func as myFunc } from 'lib'; diff --git a/transforms/require-lib-func-to-import-func-from-lib.js b/transforms/require-lib-func-to-import-func-from-lib.js index 41a158d..72fbb15 100644 --- a/transforms/require-lib-func-to-import-func-from-lib.js +++ b/transforms/require-lib-func-to-import-func-from-lib.js @@ -43,7 +43,7 @@ function transformer(file, api, options) { for (const declaration of path.node.declarations) { if (j.MemberExpression.check(declaration.init) && declaration.init.object.callee.name === 'require'){ - const importSpecifier = j.importSpecifier(declaration.id) + const importSpecifier = j.importSpecifier(declaration.init.property, declaration.id) const sourcePath = declaration.init.object.arguments.shift()