diff --git a/codemods/xtend/index.js b/codemods/xtend/index.js index 3fcf4b85..c3eb4dd7 100644 --- a/codemods/xtend/index.js +++ b/codemods/xtend/index.js @@ -1,5 +1,8 @@ -import jscodeshift from 'jscodeshift'; -import { removeImport } from '../shared.js'; +import { ts } from '@ast-grep/napi'; +import { + computeCallReplacementEdits, + removeImport, +} from '../shared-ast-grep.js'; /** * @typedef {import('../../types.js').Codemod} Codemod @@ -15,25 +18,27 @@ export default function (options) { name: 'xtend', to: 'native', transform: ({ file }) => { - const j = jscodeshift; - const root = j(file.source); + const ast = ts.parse(file.source); + const root = ast.root(); - const { identifier } = removeImport('xtend', root, j); + const { edits, localNames } = removeImport(root, 'xtend'); - root - .find(j.CallExpression, { - callee: { - name: identifier, - }, - }) - .replaceWith(({ node }) => { - return j.objectExpression( - //@ts-ignore - node.arguments.map((arg) => j.spreadElement(arg)), - ); - }); + if (localNames.length === 0) { + return file.source; + } - return root.toSource(options); + const identifierName = localNames[0]; + const callEdits = computeCallReplacementEdits( + root, + identifierName, + (args) => { + const spreadArgs = args.map((a) => `...${a}`); + return `{ ${spreadArgs.join(', ')} }`; + }, + ); + edits.push(...callEdits); + + return edits.length > 0 ? root.commitEdits(edits) : file.source; }, }; } diff --git a/test/fixtures/xtend/case-1/after.js b/test/fixtures/xtend/case-1/after.js index 955879bb..bac0e0a1 100644 --- a/test/fixtures/xtend/case-1/after.js +++ b/test/fixtures/xtend/case-1/after.js @@ -1,3 +1,4 @@ + const assert = require('assert'); const objectA = { @@ -11,7 +12,4 @@ const objectB = { d: 40, }; -assert.equal({ - ...objectA, - ...objectB -}, { a: 20, b: 2, c: 3, d: 40 }); \ No newline at end of file +assert.equal({ ...objectA, ...objectB }, { a: 20, b: 2, c: 3, d: 40 }); diff --git a/test/fixtures/xtend/case-1/before.js b/test/fixtures/xtend/case-1/before.js index 23eca1bf..a37ed01c 100644 --- a/test/fixtures/xtend/case-1/before.js +++ b/test/fixtures/xtend/case-1/before.js @@ -12,4 +12,4 @@ const objectB = { d: 40, }; -assert.equal(extend(objectA, objectB), { a: 20, b: 2, c: 3, d: 40 }); \ No newline at end of file +assert.equal(extend(objectA, objectB), { a: 20, b: 2, c: 3, d: 40 }); diff --git a/test/fixtures/xtend/case-1/result.js b/test/fixtures/xtend/case-1/result.js index 955879bb..bac0e0a1 100644 --- a/test/fixtures/xtend/case-1/result.js +++ b/test/fixtures/xtend/case-1/result.js @@ -1,3 +1,4 @@ + const assert = require('assert'); const objectA = { @@ -11,7 +12,4 @@ const objectB = { d: 40, }; -assert.equal({ - ...objectA, - ...objectB -}, { a: 20, b: 2, c: 3, d: 40 }); \ No newline at end of file +assert.equal({ ...objectA, ...objectB }, { a: 20, b: 2, c: 3, d: 40 });