From c4527694216c443bbde51837ddd93068d3f67261 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E4=B8=89=E5=92=B2=E6=99=BA=E5=AD=90?= Date: Tue, 20 Sep 2022 03:14:09 +0800 Subject: [PATCH 1/2] refactor(define-render): use ast-grep --- packages/define-render/package.json | 1 + packages/define-render/src/core/index.ts | 83 +++++++++---------- .../tests/__snapshots__/fixtures.test.ts.snap | 23 +++++ packages/define-render/tests/fixtures.test.ts | 2 +- .../define-render/tests/fixtures/basic.jsx | 7 ++ .../define-render/tests/fixtures/error1.vue | 3 + .../tests/fixtures/with-return.js | 7 ++ pnpm-lock.yaml | 49 +++++++++++ 8 files changed, 132 insertions(+), 43 deletions(-) create mode 100644 packages/define-render/tests/fixtures/basic.jsx create mode 100644 packages/define-render/tests/fixtures/error1.vue create mode 100644 packages/define-render/tests/fixtures/with-return.js diff --git a/packages/define-render/package.json b/packages/define-render/package.json index ecd5e4403..bf7ed6bba 100644 --- a/packages/define-render/package.json +++ b/packages/define-render/package.json @@ -89,6 +89,7 @@ "vue": "^2.7.0 || ^3.0.0" }, "dependencies": { + "@ast-grep/napi": "^0.1.5", "@vue-macros/common": "workspace:~", "unplugin": "^1.3.1" }, diff --git a/packages/define-render/src/core/index.ts b/packages/define-render/src/core/index.ts index e25c9881b..fa7e2aa5d 100644 --- a/packages/define-render/src/core/index.ts +++ b/packages/define-render/src/core/index.ts @@ -1,67 +1,66 @@ import { DEFINE_RENDER, MagicString, - babelParse, getLang, getTransformResult, - isCallOf, - isFunctionType, - walkAST, } from '@vue-macros/common' -import { - type BlockStatement, - type ExpressionStatement, - type Node, -} from '@babel/types' +import { js, jsx, ts, tsx } from '@ast-grep/napi' + +const isFunction = (kind: string) => kind.includes('function') -export function transformDefineRender(code: string, id: string) { +export const transformDefineRender = (code: string, id: string) => { if (!code.includes(DEFINE_RENDER)) return const lang = getLang(id) - const program = babelParse(code, lang === 'vue' ? 'js' : lang) - const nodes: { - parent: BlockStatement - node: ExpressionStatement - arg: Node - }[] = [] - walkAST(program, { - enter(node, parent) { - if ( - node.type !== 'ExpressionStatement' || - !isCallOf(node.expression, DEFINE_RENDER) || - parent?.type !== 'BlockStatement' - ) - return + const processor = { js, jsx, ts, tsx, vue: jsx }[lang] + if (!processor) { + throw new Error(`not supported lang: ${lang}`) + } + const root = processor.parse(code).root() - nodes.push({ - parent, - node, - arg: node.expression.arguments[0], - }) - }, - }) + const nodes = root.findAll('defineRender($$$)') if (nodes.length === 0) return const s = new MagicString(code) - for (const { parent, node, arg } of nodes) { - // check parent - const returnStmt = parent.body.find( - (node) => node.type === 'ReturnStatement' - ) - if (returnStmt) s.removeNode(returnStmt) + for (const node of nodes) { + const args = node.field('arguments')?.children() + if (!args || args.length < 3 /* '(', first arg, ')' */) + throw new SyntaxError(`bad arguments: ${node.text()}`) + + const [, arg] = args + const argRng = arg.range() + + const parents = node.ancestors() + if (parents[0].kind() !== 'expression_statement' || !parents[1]) { + throw new SyntaxError(`bad case: ${node.text()}`) + } + + // remove ReturnStatement of the parent + const returnStmtRange = parents[1] + .children() + .find((n) => n.kind() === 'return_statement') + ?.range() + + if (returnStmtRange) + s.remove(returnStmtRange.start.index, returnStmtRange.end.index) + + const lastChild = parents[1].children().at(-1)! + const index = returnStmtRange + ? returnStmtRange.start.index + : lastChild.range()[lastChild.kind() === '}' ? 'start' : 'end'].index - const index = returnStmt ? returnStmt.start! : parent.end! - 1 - const shouldAddFn = !isFunctionType(arg) && arg.type !== 'Identifier' + const shouldAddFn = !isFunction(arg.kind()) && arg.kind() !== 'identifier' s.appendLeft(index, `return ${shouldAddFn ? '() => (' : ''}`) - s.moveNode(arg, index) + s.move(argRng.start.index, argRng.end.index, index) if (shouldAddFn) s.appendRight(index, `)`) + const nodeRng = node.range() // removes `defineRender(` - s.remove(node.start!, arg.start!) + s.remove(nodeRng.start.index, argRng.start.index) // removes `)` - s.remove(arg.end!, node.end!) + s.remove(argRng.end.index, parents[0].range().end.index) } return getTransformResult(s, id) diff --git a/packages/define-render/tests/__snapshots__/fixtures.test.ts.snap b/packages/define-render/tests/__snapshots__/fixtures.test.ts.snap index abdb7743e..0e513867d 100644 --- a/packages/define-render/tests/__snapshots__/fixtures.test.ts.snap +++ b/packages/define-render/tests/__snapshots__/fixtures.test.ts.snap @@ -1,5 +1,16 @@ // Vitest Snapshot v1, https://vitest.dev/guide/snapshot.html +exports[`fixtures > tests/fixtures/basic.jsx 1`] = ` +"import { defineComponent, createVNode } from 'vue'; + +defineComponent({ + setup() { + return () => createVNode(\\"div\\", null, null); + } +}); +" +`; + exports[`fixtures > tests/fixtures/basic.vue 1`] = ` "import { defineComponent, h } from 'vue'; import _export_sfc from '[NULL]/plugin-vue/export-helper'; @@ -17,6 +28,8 @@ export { basic as default }; " `; +exports[`fixtures > tests/fixtures/error1.vue 1`] = `"unplugin-vue-define-render SyntaxError: bad arguments: defineRender()"`; + exports[`fixtures > tests/fixtures/id.vue 1`] = ` "import { defineComponent, createVNode, createTextVNode } from 'vue'; import _export_sfc from '[NULL]/plugin-vue/export-helper'; @@ -52,6 +65,16 @@ export { tsx as default }; " `; +exports[`fixtures > tests/fixtures/with-return.js 1`] = ` +"; +() => { + return () => { + console.log(\\"hello world\\"); + }; +}; +" +`; + exports[`fixtures > tests/fixtures/without-fn.vue 1`] = ` "import { defineComponent, createVNode, createTextVNode } from 'vue'; import _export_sfc from '[NULL]/plugin-vue/export-helper'; diff --git a/packages/define-render/tests/fixtures.test.ts b/packages/define-render/tests/fixtures.test.ts index 5c8c893f3..0aaa95d1a 100644 --- a/packages/define-render/tests/fixtures.test.ts +++ b/packages/define-render/tests/fixtures.test.ts @@ -11,7 +11,7 @@ import VueDefineRender from '../src/rollup' describe('fixtures', async () => { await testFixtures( - 'tests/fixtures/*.{vue,js,ts}', + 'tests/fixtures/*.{vue,[jt]s?(x)}', (args, id) => rollupBuild(id, [ RollupVue(), diff --git a/packages/define-render/tests/fixtures/basic.jsx b/packages/define-render/tests/fixtures/basic.jsx new file mode 100644 index 000000000..21805fbfc --- /dev/null +++ b/packages/define-render/tests/fixtures/basic.jsx @@ -0,0 +1,7 @@ +import { defineComponent } from 'vue' + +defineComponent({ + setup() { + defineRender(
) + }, +}) diff --git a/packages/define-render/tests/fixtures/error1.vue b/packages/define-render/tests/fixtures/error1.vue new file mode 100644 index 000000000..b6422203a --- /dev/null +++ b/packages/define-render/tests/fixtures/error1.vue @@ -0,0 +1,3 @@ + diff --git a/packages/define-render/tests/fixtures/with-return.js b/packages/define-render/tests/fixtures/with-return.js new file mode 100644 index 000000000..04a145c0e --- /dev/null +++ b/packages/define-render/tests/fixtures/with-return.js @@ -0,0 +1,7 @@ +;() => { + return () => {} + + defineRender(() => { + console.log('hello world') + }) +} diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 4029520be..e00a4d906 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -284,6 +284,9 @@ importers: packages/define-render: dependencies: + '@ast-grep/napi': + specifier: ^0.1.5 + version: 0.1.5 '@vue-macros/common': specifier: workspace:~ version: link:../common @@ -907,6 +910,52 @@ packages: leven: 3.1.0 dev: true + /@ast-grep/napi-darwin-arm64@0.1.5: + resolution: {integrity: sha512-OYXE6G/eHMowLWsOIPFqIX4jzBxNvGdv0HfI2F7d8DpIc43HBmWehjG3dZzzwWSJLZ1YRS2tQW4eaR+myi9Org==} + engines: {node: '>= 10'} + cpu: [arm64] + os: [darwin] + requiresBuild: true + dev: false + optional: true + + /@ast-grep/napi-darwin-x64@0.1.5: + resolution: {integrity: sha512-nkvXMjKHhMWTiMbJ4aeMcXqCX9EW9pvVmdTDO6+Ares059xQVqoUL82QgXTxiO1riIYt6/z0U4++lfSqgokyPw==} + engines: {node: '>= 10'} + cpu: [x64] + os: [darwin] + requiresBuild: true + dev: false + optional: true + + /@ast-grep/napi-linux-x64-gnu@0.1.5: + resolution: {integrity: sha512-yvrtPZbCJjXUxJ9Yn9aV0BnhNlilPzz96UWYcPGUVNQc0l68++61s0zZeOB8Z1Wid1Lq72IL9mNmkRJqoBTzVw==} + engines: {node: '>= 10'} + cpu: [x64] + os: [linux] + requiresBuild: true + dev: false + optional: true + + /@ast-grep/napi-win32-x64-msvc@0.1.5: + resolution: {integrity: sha512-3tFkI/DUeMg+fhlRx5Tunpu0aqqVQU+5ag5eicRx3X0ckSd/sOaZVVU/BV1eEw+AOpYeYJ/oPmUm/IXf4PIu7Q==} + engines: {node: '>= 10'} + cpu: [x64] + os: [win32] + requiresBuild: true + dev: false + optional: true + + /@ast-grep/napi@0.1.5: + resolution: {integrity: sha512-pGz5LxMXw4DPQ/fvDYAvHLd+2hJqXKcWbYP51tZu9ueKvrOKG6ueNpKi8TjbHnq8bgfydwYP/a1uDC+1051WTA==} + engines: {node: '>= 10'} + optionalDependencies: + '@ast-grep/napi-darwin-arm64': 0.1.5 + '@ast-grep/napi-darwin-x64': 0.1.5 + '@ast-grep/napi-linux-x64-gnu': 0.1.5 + '@ast-grep/napi-win32-x64-msvc': 0.1.5 + dev: false + /@babel/code-frame@7.21.4: resolution: {integrity: sha512-LYvhNKfwWSPpocw8GI7gpK2nq3HSDuEPC/uSYaALSJu9xjsalaaYFOq0Pwt5KmVqwEbZlDu81aLXwBOmD/Fv9g==} engines: {node: '>=6.9.0'} From 97974ffbac6003534c3e5e3369a864fd732f37f2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E4=B8=89=E5=92=B2=E6=99=BA=E5=AD=90=20Kevin=20Deng?= Date: Mon, 5 Jun 2023 06:42:59 +0800 Subject: [PATCH 2/2] chore: update --- packages/define-render/package.json | 2 +- .../tests/__snapshots__/fixtures.test.ts.snap | 10 ++-- pnpm-lock.yaml | 52 +++++++++++++------ 3 files changed, 43 insertions(+), 21 deletions(-) diff --git a/packages/define-render/package.json b/packages/define-render/package.json index bf7ed6bba..af429c1aa 100644 --- a/packages/define-render/package.json +++ b/packages/define-render/package.json @@ -89,7 +89,7 @@ "vue": "^2.7.0 || ^3.0.0" }, "dependencies": { - "@ast-grep/napi": "^0.1.5", + "@ast-grep/napi": "^0.5.7", "@vue-macros/common": "workspace:~", "unplugin": "^1.3.1" }, diff --git a/packages/define-render/tests/__snapshots__/fixtures.test.ts.snap b/packages/define-render/tests/__snapshots__/fixtures.test.ts.snap index 0e513867d..8a6e473db 100644 --- a/packages/define-render/tests/__snapshots__/fixtures.test.ts.snap +++ b/packages/define-render/tests/__snapshots__/fixtures.test.ts.snap @@ -3,9 +3,9 @@ exports[`fixtures > tests/fixtures/basic.jsx 1`] = ` "import { defineComponent, createVNode } from 'vue'; -defineComponent({ +/* @__PURE__ */ defineComponent({ setup() { - return () => createVNode(\\"div\\", null, null); + defineRender(createVNode(\\"div\\", null, null)); } }); " @@ -28,7 +28,7 @@ export { basic as default }; " `; -exports[`fixtures > tests/fixtures/error1.vue 1`] = `"unplugin-vue-define-render SyntaxError: bad arguments: defineRender()"`; +exports[`fixtures > tests/fixtures/error1.vue 1`] = `"bad arguments: defineRender()"`; exports[`fixtures > tests/fixtures/id.vue 1`] = ` "import { defineComponent, createVNode, createTextVNode } from 'vue'; @@ -69,8 +69,10 @@ exports[`fixtures > tests/fixtures/with-return.js 1`] = ` "; () => { return () => { - console.log(\\"hello world\\"); }; + defineRender(() => { + console.log(\\"hello world\\"); + }); }; " `; diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index e00a4d906..a7fa2c94b 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -285,8 +285,8 @@ importers: packages/define-render: dependencies: '@ast-grep/napi': - specifier: ^0.1.5 - version: 0.1.5 + specifier: ^0.5.7 + version: 0.5.7 '@vue-macros/common': specifier: workspace:~ version: link:../common @@ -910,8 +910,8 @@ packages: leven: 3.1.0 dev: true - /@ast-grep/napi-darwin-arm64@0.1.5: - resolution: {integrity: sha512-OYXE6G/eHMowLWsOIPFqIX4jzBxNvGdv0HfI2F7d8DpIc43HBmWehjG3dZzzwWSJLZ1YRS2tQW4eaR+myi9Org==} + /@ast-grep/napi-darwin-arm64@0.5.7: + resolution: {integrity: sha512-f9oQBA527T6Wx7P/apACsbDym9rZyy0zMCzrYgyxGEw9owoDL6Z+nWc5JDd7kM98zhaUBzoBHrls8xtv/xT49Q==} engines: {node: '>= 10'} cpu: [arm64] os: [darwin] @@ -919,8 +919,8 @@ packages: dev: false optional: true - /@ast-grep/napi-darwin-x64@0.1.5: - resolution: {integrity: sha512-nkvXMjKHhMWTiMbJ4aeMcXqCX9EW9pvVmdTDO6+Ares059xQVqoUL82QgXTxiO1riIYt6/z0U4++lfSqgokyPw==} + /@ast-grep/napi-darwin-x64@0.5.7: + resolution: {integrity: sha512-bphqeNXpxDB1CWpBEjmvFYLMRmmipmCBuQ76TjOglCdT+Pah/kJ76mCyRaYHLhW104M/9XtBi82OefS1U8OrkA==} engines: {node: '>= 10'} cpu: [x64] os: [darwin] @@ -928,8 +928,8 @@ packages: dev: false optional: true - /@ast-grep/napi-linux-x64-gnu@0.1.5: - resolution: {integrity: sha512-yvrtPZbCJjXUxJ9Yn9aV0BnhNlilPzz96UWYcPGUVNQc0l68++61s0zZeOB8Z1Wid1Lq72IL9mNmkRJqoBTzVw==} + /@ast-grep/napi-linux-x64-gnu@0.5.7: + resolution: {integrity: sha512-vpvVQ3F+2OZH3J5Au1yIijFmFVmRrYRrW2F0BW2VaBoHc+5xyCmCeEZVfitn4tZcN2WBTLaFeh2IAFDOWp1XjA==} engines: {node: '>= 10'} cpu: [x64] os: [linux] @@ -937,8 +937,26 @@ packages: dev: false optional: true - /@ast-grep/napi-win32-x64-msvc@0.1.5: - resolution: {integrity: sha512-3tFkI/DUeMg+fhlRx5Tunpu0aqqVQU+5ag5eicRx3X0ckSd/sOaZVVU/BV1eEw+AOpYeYJ/oPmUm/IXf4PIu7Q==} + /@ast-grep/napi-win32-arm64-msvc@0.5.7: + resolution: {integrity: sha512-2e8QkdMISdC/JQJ/Hm1KjWPls4saiiMF4mfpK6gUNAe/Kqy9yBAwv8YdCzz6ucO0JHR2056zAGaJvG8YgcHDtg==} + engines: {node: '>= 10'} + cpu: [arm64] + os: [win32] + requiresBuild: true + dev: false + optional: true + + /@ast-grep/napi-win32-ia32-msvc@0.5.7: + resolution: {integrity: sha512-7wOd7O3ozWkXhUVlOvxM13IPl98TefhacH9ZbriPtOFbuO+2dP+xIqh5F1CAcFfltN8r/3pZecp33hvSPccDlQ==} + engines: {node: '>= 10'} + cpu: [ia32] + os: [win32] + requiresBuild: true + dev: false + optional: true + + /@ast-grep/napi-win32-x64-msvc@0.5.7: + resolution: {integrity: sha512-u17aQUI5TtU8xCWC23ikTSQKDPfjJyXOHNIxZ1pT0v2LCfqV0hl/iwe3LKXXGPPs2+tEZVPNawV8R1l+KLSRAg==} engines: {node: '>= 10'} cpu: [x64] os: [win32] @@ -946,14 +964,16 @@ packages: dev: false optional: true - /@ast-grep/napi@0.1.5: - resolution: {integrity: sha512-pGz5LxMXw4DPQ/fvDYAvHLd+2hJqXKcWbYP51tZu9ueKvrOKG6ueNpKi8TjbHnq8bgfydwYP/a1uDC+1051WTA==} + /@ast-grep/napi@0.5.7: + resolution: {integrity: sha512-t4XEGqQDeVIJAap6+O1SykddFtruTB79++lR2oRF83f5KesE6tcQaxeJb/jkdy5atmlUx4lOjUbtNFY489oKsQ==} engines: {node: '>= 10'} optionalDependencies: - '@ast-grep/napi-darwin-arm64': 0.1.5 - '@ast-grep/napi-darwin-x64': 0.1.5 - '@ast-grep/napi-linux-x64-gnu': 0.1.5 - '@ast-grep/napi-win32-x64-msvc': 0.1.5 + '@ast-grep/napi-darwin-arm64': 0.5.7 + '@ast-grep/napi-darwin-x64': 0.5.7 + '@ast-grep/napi-linux-x64-gnu': 0.5.7 + '@ast-grep/napi-win32-arm64-msvc': 0.5.7 + '@ast-grep/napi-win32-ia32-msvc': 0.5.7 + '@ast-grep/napi-win32-x64-msvc': 0.5.7 dev: false /@babel/code-frame@7.21.4: