| FazBrowse GitHub Viewer | Trending | | Home |
| Tools: [Download Repo ZIP] [Original HTTPS Page] |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -56,6 +56,7 @@ | |||
| 56 | 56 | "dependencies": { | |
| 57 | 57 | "@yuku-toolchain/types": "^0.8.3", | |
| 58 | 58 | "magic-string-ast": "^2.1.1", | |
| 59 | + "rolldown-string": "^0.3.1", | ||
| 59 | 60 | "unplugin": "^3.3.0", | |
| 60 | 61 | "yuku-ast": "^0.8.3", | |
| 61 | 62 | "yuku-codegen": "^0.8.3", | |
@@ -68,6 +69,7 @@ | |||
| 68 | 69 | "@antfu/utils": "^9.3.0", | |
| 69 | 70 | "@sxzz/eslint-config": "^8.4.0", | |
| 70 | 71 | "@sxzz/prettier-config": "^2.3.2", | |
| 72 | + "@sxzz/test-utils": "^0.5.18", | ||
| 71 | 73 | "@types/node": "^26.1.2", | |
| 72 | 74 | "@typescript/native-preview": "7.0.0-dev.20260707.2", | |
| 73 | 75 | "bumpp": "^12.1.1", | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -29,6 +29,6 @@ export function resolveOptions(options: Options): OptionsResolved { | |||
| 29 | 29 | exclude: options.exclude || undefined, | |
| 30 | 30 | enforce: options.enforce || undefined, | |
| 31 | 31 | parserOptions: options.parserOptions || {}, | |
| 32 | - transformer: options.transformer ? toArray(options.transformer) : [], | ||
| 32 | + transformer: toArray(options.transformer), | ||
| 33 | 33 | } | |
| 34 | 34 | } | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -1,8 +1,4 @@ | |||
| 1 | - import { | ||
| 2 | - generateTransform, | ||
| 3 | - MagicStringAST, | ||
| 4 | - type CodeTransform, | ||
| 5 | - } from 'magic-string-ast' | ||
| 1 | + import { MagicString, MagicStringAST } from 'magic-string-ast' | ||
| 6 | 2 | import { walkAsync } from 'yuku-ast' | |
| 7 | 3 | import { | |
| 8 | 4 | langFromPath, | |
@@ -15,6 +11,7 @@ import { | |||
| 15 | 11 | import { useNodeRef } from './utils.ts' | |
| 16 | 12 | import type { OptionsResolved } from './options.ts' | |
| 17 | 13 | import type { Transformer, TransformerParsed } from './types.ts' | |
| 14 | + import type { RolldownString } from 'rolldown-string' | ||
| 18 | 15 | ||
| 19 | 16 | function parseProgram(code: string, id: string, parserOptions: ParseOptions) { | |
| 20 | 17 | const path = id.replace(/[?#].*$/, '') | |
@@ -66,17 +63,17 @@ async function getTransformersByFile(transformer: Transformer[], id: string) { | |||
| 66 | 63 | } | |
| 67 | 64 | ||
| 68 | 65 | export async function transform( | |
| 69 | - code: string, | ||
| 66 | + source: string | RolldownString, | ||
| 70 | 67 | id: string, | |
| 71 | 68 | options: Pick<OptionsResolved, 'parserOptions' | 'transformer'>, | |
| 72 | - ): Promise<CodeTransform | undefined> { | ||
| 73 | - const { getNodeRef } = useNodeRef() | ||
| 74 | - | ||
| 69 | + ): Promise<RolldownString | undefined> { | ||
| 75 | 70 | const transformers = await getTransformersByFile(options.transformer, id) | |
| 76 | 71 | if (!transformers.length) return | |
| 77 | 72 | ||
| 73 | + const code = source.toString() | ||
| 78 | 74 | const program = parseProgram(code, id, options.parserOptions) | |
| 79 | 75 | ||
| 76 | + const getNodeRef = useNodeRef() | ||
| 80 | 77 | await walkAsync(program, { | |
| 81 | 78 | async enter(node, context) { | |
| 82 | 79 | for (const { transformer, nodes } of transformers) { | |
@@ -93,7 +90,11 @@ export async function transform( | |||
| 93 | 90 | }, | |
| 94 | 91 | }) | |
| 95 | 92 | ||
| 96 | - const s = new MagicStringAST(code) | ||
| 93 | + const s = | ||
| 94 | + typeof source === 'string' | ||
| 95 | + ? new MagicString(source, { filename: id }) | ||
| 96 | + : source | ||
| 97 | + const msa = new MagicStringAST(s as MagicString) | ||
| 97 | 98 | for (const { transformer, nodes } of transformers) { | |
| 98 | 99 | for (const node of nodes) { | |
| 99 | 100 | const value = node.value | |
@@ -103,7 +104,7 @@ export async function transform( | |||
| 103 | 104 | if (result) { | |
| 104 | 105 | let newAST: Node | |
| 105 | 106 | if (typeof result === 'string') { | |
| 106 | - s.overwriteNode(value, result) | ||
| 107 | + msa.overwriteNode(value, result) | ||
| 107 | 108 | newAST = parseReplacement(result, id, options.parserOptions) | |
| 108 | 109 | if (newAST.type === 'ExpressionStatement') { | |
| 109 | 110 | newAST = newAST.expression | |
@@ -115,7 +116,7 @@ export async function transform( | |||
| 115 | 116 | const generated = generate(result as Program) | |
| 116 | 117 | let code = generated.code | |
| 117 | 118 | if (result.type.endsWith('Expression')) code = `(${code})` | |
| 118 | - s.overwriteNode(value, code) | ||
| 119 | + msa.overwriteNode(value, code) | ||
| 119 | 120 | newAST = { | |
| 120 | 121 | ...result, | |
| 121 | 122 | start: value.start, | |
@@ -127,14 +128,14 @@ export async function transform( | |||
| 127 | 128 | } else if (result === false) { | |
| 128 | 129 | // removes node | |
| 129 | 130 | node.set(undefined) | |
| 130 | - s.removeNode(value) | ||
| 131 | + msa.removeNode(value) | ||
| 131 | 132 | } | |
| 132 | 133 | } | |
| 133 | 134 | } | |
| 134 | 135 | ||
| 135 | 136 | for (const { transformer } of transformers) { | |
| 136 | - await transformer.finalize?.(s) | ||
| 137 | + await transformer.finalize?.(msa) | ||
| 137 | 138 | } | |
| 138 | 139 | ||
| 139 | - return generateTransform(s, id) | ||
| 140 | + return s | ||
| 140 | 141 | } | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -1,10 +1,7 @@ | |||
| 1 | 1 | import type { NodeRef } from './types.ts' | |
| 2 | 2 | import type { Node } from 'yuku-parser' | |
| 3 | 3 | ||
| 4 | - export function useNodeRef(): { | ||
| 5 | - nodeRefs: Map<Node, NodeRef<Node | undefined>> | ||
| 6 | - getNodeRef: (node: Node) => NodeRef<Node | undefined> | ||
| 7 | - } { | ||
| 4 | + export function useNodeRef(): (node: Node) => NodeRef<Node | undefined> { | ||
| 8 | 5 | const nodeRefs: Map<Node, NodeRef<Node | undefined>> = new Map() | |
| 9 | 6 | ||
| 10 | 7 | function getNodeRef(node: Node): NodeRef<Node | undefined> { | |
@@ -19,8 +16,5 @@ export function useNodeRef(): { | |||
| 19 | 16 | return ref | |
| 20 | 17 | } | |
| 21 | 18 | ||
| 22 | - return { | ||
| 23 | - nodeRefs, | ||
| 24 | - getNodeRef, | ||
| 25 | - } | ||
| 19 | + return getNodeRef | ||
| 26 | 20 | } | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -1,3 +1,4 @@ | |||
| 1 | + import { withMagicString } from 'rolldown-string' | ||
| 1 | 2 | import { createUnplugin, type UnpluginInstance } from 'unplugin' | |
| 2 | 3 | import { resolveOptions, type Options } from './core/options.ts' | |
| 3 | 4 | import { transform } from './core/transform.ts' | |
@@ -13,7 +14,7 @@ export const AST: UnpluginInstance<Options | undefined, false> = createUnplugin( | |||
| 13 | 14 | enforce, | |
| 14 | 15 | transform: { | |
| 15 | 16 | filter: { id: { include, exclude } }, | |
| 16 | - handler: (code, id) => transform(code, id, options), | ||
| 17 | + handler: withMagicString((code, id) => transform(code, id, options)), | ||
| 17 | 18 | }, | |
| 18 | 19 | } | |
| 19 | 20 | }, | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -0,0 +1,9 @@ | |||
| 1 | + // Vitest Snapshot v1, https://vitest.dev/guide/snapshot.html | ||
| 2 | + | ||
| 3 | + exports[`rolldown build 1`] = ` | ||
| 4 | + "// basic.js | ||
| 5 | + const config = { test: {} }; | ||
| 6 | + //#endregion | ||
| 7 | + export { config as default }; | ||
| 8 | + " | ||
| 9 | + `; | ||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -1,3 +1,4 @@ | |||
| 1 | + import { MagicString } from 'magic-string-ast' | ||
| 1 | 2 | import { expect, test } from 'vitest' | |
| 2 | 3 | import { transform } from '../src/core/transform.ts' | |
| 3 | 4 | import { RemoveWrapperFunction } from '../src/transformers.ts' | |
@@ -55,25 +56,25 @@ test('basic', async () => { | |||
| 55 | 56 | transformer: [], | |
| 56 | 57 | parserOptions: {}, | |
| 57 | 58 | } | |
| 58 | - let code = (await transform(source, 'foo.js', options))?.code | ||
| 59 | + let code = (await transform(source, 'foo.js', options))?.toString() | ||
| 59 | 60 | expect(code).toMatchInlineSnapshot('undefined') | |
| 60 | 61 | ||
| 61 | 62 | options.transformer = [changeString] | |
| 62 | - code = (await transform(source, 'foo.js', options))?.code | ||
| 63 | + code = (await transform(source, 'foo.js', options))?.toString() | ||
| 63 | 64 | expect(code).toMatchInlineSnapshot(` | |
| 64 | 65 | "const foo = 'Hello' | |
| 65 | 66 | let i = 10" | |
| 66 | 67 | `) | |
| 67 | 68 | ||
| 68 | 69 | options.transformer = [changeVarName] | |
| 69 | - code = (await transform(source, 'foo.js', options))?.code | ||
| 70 | + code = (await transform(source, 'foo.js', options))?.toString() | ||
| 70 | 71 | expect(code).toMatchInlineSnapshot(` | |
| 71 | 72 | "const newName = 'string' | |
| 72 | 73 | let i = 10" | |
| 73 | 74 | `) | |
| 74 | 75 | ||
| 75 | 76 | options.transformer = [changeString, changeVarName] | |
| 76 | - code = (await transform(source, 'foo.js', options))?.code | ||
| 77 | + code = (await transform(source, 'foo.js', options))?.toString() | ||
| 77 | 78 | expect(code).toMatchInlineSnapshot(` | |
| 78 | 79 | "const newName = 'Hello' | |
| 79 | 80 | let i = 10" | |
@@ -87,14 +88,14 @@ test('change twice', async () => { | |||
| 87 | 88 | parserOptions: {}, | |
| 88 | 89 | } | |
| 89 | 90 | options.transformer = [changeString, changeVarName, overwriteVarName] | |
| 90 | - let code = (await transform(source, 'foo.js', options))?.code | ||
| 91 | + let code = (await transform(source, 'foo.js', options))?.toString() | ||
| 91 | 92 | expect(code).toMatchInlineSnapshot(` | |
| 92 | 93 | "const overwrite_newName = 'Hello' | |
| 93 | 94 | let overwrite_i = 10" | |
| 94 | 95 | `) | |
| 95 | 96 | ||
| 96 | 97 | options.transformer = [timesTen, timesTen, timesTen] | |
| 97 | - code = (await transform(source, 'foo.js', options))?.code | ||
| 98 | + code = (await transform(source, 'foo.js', options))?.toString() | ||
| 98 | 99 | expect(code).toMatchInlineSnapshot(` | |
| 99 | 100 | "const foo = 'string' | |
| 100 | 101 | let i = 10000" | |
@@ -108,7 +109,7 @@ test('remove node', async () => { | |||
| 108 | 109 | parserOptions: {}, | |
| 109 | 110 | } | |
| 110 | 111 | options.transformer = [removeFirstStatement] | |
| 111 | - const code = (await transform(source, 'foo.js', options))?.code | ||
| 112 | + const code = (await transform(source, 'foo.js', options))?.toString() | ||
| 112 | 113 | expect(code).toMatchInlineSnapshot(` | |
| 113 | 114 | " | |
| 114 | 115 | let i = 10;{}" | |
@@ -147,7 +148,7 @@ test('transform with Yuku AST', async () => { | |||
| 147 | 148 | ], | |
| 148 | 149 | parserOptions: {}, | |
| 149 | 150 | } | |
| 150 | - const code = (await transform(source, 'foo.js', options))?.code | ||
| 151 | + const code = (await transform(source, 'foo.js', options))?.toString() | ||
| 151 | 152 | expect(code).toBe('const overwrite_renamed = 1') | |
| 152 | 153 | }) | |
| 153 | 154 | ||
@@ -157,7 +158,7 @@ test('handles Unicode offsets', async () => { | |||
| 157 | 158 | transformer: [changeVarName], | |
| 158 | 159 | parserOptions: {}, | |
| 159 | 160 | } | |
| 160 | - const code = (await transform(source, 'foo.js', options))?.code | ||
| 161 | + const code = (await transform(source, 'foo.js', options))?.toString() | ||
| 161 | 162 | expect(code).toBe(`const 文 = '值'\nconst newName = 'string'`) | |
| 162 | 163 | }) | |
| 163 | 164 | ||
@@ -168,7 +169,7 @@ test('detects language through query parameters', async () => { | |||
| 168 | 169 | parserOptions: {}, | |
| 169 | 170 | } | |
| 170 | 171 | for (const id of ['foo.ts?raw', 'foo.vue?vue&type=script&lang.ts']) { | |
| 171 | - const code = (await transform(source, id, options))?.code | ||
| 172 | + const code = (await transform(source, id, options))?.toString() | ||
| 172 | 173 | expect(code).toBe(`const foo: string = 'Hello'`) | |
| 173 | 174 | } | |
| 174 | 175 | }) | |
@@ -190,7 +191,7 @@ test.fails('overwrite part', async () => { | |||
| 190 | 191 | parserOptions: {}, | |
| 191 | 192 | } | |
| 192 | 193 | expect( | |
| 193 | - (await transform(source, 'foo.js', options))?.code, | ||
| 194 | + (await transform(source, 'foo.js', options))?.toString(), | ||
| 194 | 195 | ).toMatchInlineSnapshot('undefined') | |
| 195 | 196 | }) | |
| 196 | 197 | ||
@@ -209,7 +210,7 @@ test('rewrite statement', async () => { | |||
| 209 | 210 | }, | |
| 210 | 211 | }, | |
| 211 | 212 | ] | |
| 212 | - const code = (await transform(source, 'foo.js', options))?.code | ||
| 213 | + const code = (await transform(source, 'foo.js', options))?.toString() | ||
| 213 | 214 | expect(code).toMatchInlineSnapshot(` | |
| 214 | 215 | "const foo = 'bar'; const bar = 'foo' | |
| 215 | 216 | let i = 10;{i++}" | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -0,0 +1,9 @@ | |||
| 1 | + function defineConfig(config: any) { | ||
| 2 | + return config | ||
| 3 | + } | ||
| 4 | + | ||
| 5 | + const config: any = defineConfig({ | ||
| 6 | + test: {}, | ||
| 7 | + }) | ||
| 8 | + | ||
| 9 | + export default config | ||
| Back | FazBrowse Home | New Git URL |
0 commit comments