From: 三咲智子 Kevin Deng Date: Fri, 2 Feb 2024 21:02:07 +0000 (+0800) Subject: refactor: remove update function from compiler X-Git-Tag: v3.6.0-alpha.1~16^2~608 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=be65b98a3331ab956d5dcbf373718016e4b3ac75;p=thirdparty%2Fvuejs%2Fcore.git refactor: remove update function from compiler --- diff --git a/packages/compiler-vapor/__tests__/transforms/__snapshots__/vFor.spec.ts.snap b/packages/compiler-vapor/__tests__/transforms/__snapshots__/vFor.spec.ts.snap index ed3f049073..f0eea1022f 100644 --- a/packages/compiler-vapor/__tests__/transforms/__snapshots__/vFor.spec.ts.snap +++ b/packages/compiler-vapor/__tests__/transforms/__snapshots__/vFor.spec.ts.snap @@ -1,7 +1,7 @@ // Vitest Snapshot v1, https://vitest.dev/guide/snapshot.html exports[`compiler: v-for > basic v-for 1`] = ` -"import { template as _template, fragment as _fragment, children as _children, on as _on, setText as _setText, renderEffect as _renderEffect, createFor as _createFor, append as _append } from 'vue/vapor'; +"import { template as _template, fragment as _fragment, children as _children, on as _on, renderEffect as _renderEffect, setText as _setText, createFor as _createFor, append as _append } from 'vue/vapor'; export function render(_ctx) { const t0 = _template("
") @@ -11,19 +11,43 @@ export function render(_ctx) { const n2 = t0() const { 0: [n3],} = _children(n2) _on(n3, "click", $event => (_ctx.remove(_block.s[0]))) - const _updateEffect = () => { + _renderEffect(() => { const [item] = _block.s _setText(n3, item) - } - _renderEffect(_updateEffect) - return [n2, _updateEffect] + }) + return n2 }) _append(n0, n1) return n0 }" `; -exports[`compiler: v-for > basic v-for 2`] = ` +exports[`compiler: v-for > multi effect 1`] = ` +"import { template as _template, fragment as _fragment, children as _children, renderEffect as _renderEffect, setDynamicProp as _setDynamicProp, createFor as _createFor, append as _append } from 'vue/vapor'; + +export function render(_ctx) { + const t0 = _template("
") + const t1 = _fragment() + const n0 = t1() + const n1 = _createFor(() => (_ctx.items), (_block) => { + const n2 = t0() + const { 0: [n3],} = _children(n2) + _renderEffect(() => { + const [item, index] = _block.s + _setDynamicProp(n3, "item", item) + }) + _renderEffect(() => { + const [item, index] = _block.s + _setDynamicProp(n3, "index", index) + }) + return n2 + }) + _append(n0, n1) + return n0 +}" +`; + +exports[`compiler: v-for > w/o value 1`] = ` "import { template as _template, fragment as _fragment, createFor as _createFor, append as _append } from 'vue/vapor'; export function render(_ctx) { @@ -32,7 +56,7 @@ export function render(_ctx) { const n0 = t1() const n1 = _createFor(() => (_ctx.items), (_block) => { const n2 = t0() - return [n2, () => {}] + return n2 }) _append(n0, n1) return n0 diff --git a/packages/compiler-vapor/__tests__/transforms/vFor.spec.ts b/packages/compiler-vapor/__tests__/transforms/vFor.spec.ts index bfa31ab537..d02737a39c 100644 --- a/packages/compiler-vapor/__tests__/transforms/vFor.spec.ts +++ b/packages/compiler-vapor/__tests__/transforms/vFor.spec.ts @@ -4,6 +4,7 @@ import { IRNodeTypes, transformElement, transformInterpolation, + transformVBind, transformVFor, transformVOn, } from '../../src' @@ -11,7 +12,10 @@ import { NodeTypes } from '@vue/compiler-dom' const compileWithVFor = makeCompile({ nodeTransforms: [transformInterpolation, transformVFor, transformElement], - directiveTransforms: { on: transformVOn }, + directiveTransforms: { + bind: transformVBind, + on: transformVOn, + }, }) describe('compiler: v-for', () => { @@ -66,8 +70,22 @@ describe('compiler: v-for', () => { expect((ir.operation[0] as ForIRNode).render.effect).lengthOf(1) }) - test('basic v-for', () => { + test('multi effect', () => { + const { code } = compileWithVFor( + `
`, + ) + expect(code).matchSnapshot() + }) + + test('w/o value', () => { const { code } = compileWithVFor(`
item
`) expect(code).matchSnapshot() }) + + test.todo('object de-structured value', () => { + const { code } = compileWithVFor( + '{{ id }}{{ value }}', + ) + expect(code).matchSnapshot() + }) }) diff --git a/packages/compiler-vapor/src/generators/block.ts b/packages/compiler-vapor/src/generators/block.ts index ddae02f025..b42166a703 100644 --- a/packages/compiler-vapor/src/generators/block.ts +++ b/packages/compiler-vapor/src/generators/block.ts @@ -21,14 +21,13 @@ export function genBlockFunction( oper: BlockFunctionIRNode, context: CodegenContext, args: CodeFragment[] = [], - returnValue?: () => CodeFragment[], ): CodeFragment[] { return [ '(', ...args, ') => {', INDENT_START, - ...genBlockFunctionContent(oper, context, returnValue), + ...genBlockFunctionContent(oper, context), INDENT_END, NEWLINE, '}', @@ -38,7 +37,6 @@ export function genBlockFunction( export function genBlockFunctionContent( ir: BlockFunctionIRNode | RootIRNode, context: CodegenContext, - returnValue?: () => CodeFragment[], ): CodeFragment[] { const { vaporHelper } = context const [frag, push] = buildCodeFragment( @@ -63,13 +61,8 @@ export function genBlockFunctionContent( } push(...genOperations(ir.operation, context)) - push(...genEffects(ir.effect, context)) - - push( - NEWLINE, - 'return ', - ...(returnValue ? returnValue() : [`n${ir.dynamic.id}`]), - ) + push(...(context.genEffect || genEffects)(ir.effect, context)) + push(NEWLINE, `return n${ir.dynamic.id}`) return frag } diff --git a/packages/compiler-vapor/src/generators/for.ts b/packages/compiler-vapor/src/generators/for.ts index 9640553e83..c1446e7d9d 100644 --- a/packages/compiler-vapor/src/generators/for.ts +++ b/packages/compiler-vapor/src/generators/for.ts @@ -9,7 +9,7 @@ import { buildCodeFragment, } from '../generate' import type { ForIRNode, IREffect } from '../ir' -import { genOperations } from './operation' +import { genOperation } from './operation' import { NewlineType } from '@vue/compiler-dom' export function genFor( @@ -23,19 +23,14 @@ export function genFor( const rawKey = key && key.content const sourceExpr = ['() => (', ...genExpression(source, context), ')'] - let updateFn = '_updateEffect' context.genEffect = genEffectInFor const idMap: Record = {} if (rawValue) idMap[rawValue] = `_block.s[0]` if (rawKey) idMap[rawKey] = `_block.s[1]` - const blockRet = (): CodeFragment[] => [ - `[n${render.dynamic.id!}, ${updateFn}]`, - ] - const blockFn = context.withId( - () => genBlockFunction(render, context, ['_block'], blockRet), + () => genBlockFunction(render, context, ['_block']), idMap, ) @@ -48,15 +43,16 @@ export function genFor( ] function genEffectInFor(effects: IREffect[]): CodeFragment[] { - if (!effects.length) { - updateFn = '() => {}' - return [] - } + const [frag, push] = buildCodeFragment() - const [frag, push] = buildCodeFragment(INDENT_START) - // const [value, key] = _block.s + const idMap: Record = {} + if (value) idMap[value.content] = null + if (key) idMap[key.content] = null + + let statement: CodeFragment[] = [] if (rawValue || rawKey) { - push( + // const [value, key] = _block.s + statement = [ NEWLINE, 'const ', '[', @@ -64,28 +60,22 @@ export function genFor( rawKey && ', ', rawKey && [rawKey, NewlineType.None, key.loc], '] = _block.s', - ) + ] } - const idMap: Record = {} - if (value) idMap[value.content] = null - if (key) idMap[key.content] = null context.withId(() => { - effects.forEach(effect => - push(...genOperations(effect.operations, context)), - ) + for (const { operations } of effects) { + push( + NEWLINE, + `${vaporHelper('renderEffect')}(() => {`, + INDENT_START, + ...statement, + ) + operations.forEach(op => push(...genOperation(op, context))) + push(INDENT_END, NEWLINE, '})') + } }, idMap) - push(INDENT_END) - - return [ - NEWLINE, - `const ${updateFn} = () => {`, - ...frag, - NEWLINE, - '}', - NEWLINE, - `${vaporHelper('renderEffect')}(${updateFn})`, - ] + return frag } } diff --git a/packages/compiler-vapor/src/generators/operation.ts b/packages/compiler-vapor/src/generators/operation.ts index d1d5575702..c672281ce7 100644 --- a/packages/compiler-vapor/src/generators/operation.ts +++ b/packages/compiler-vapor/src/generators/operation.ts @@ -25,7 +25,7 @@ export function genOperations(opers: OperationNode[], context: CodegenContext) { return frag } -function genOperation( +export function genOperation( oper: OperationNode, context: CodegenContext, ): CodeFragment[] { @@ -60,9 +60,6 @@ function genOperation( } export function genEffects(effects: IREffect[], context: CodegenContext) { - if (context.genEffect) { - return context.genEffect(effects) - } const [frag, push] = buildCodeFragment() for (const effect of effects) { push(...genEffect(effect, context)) @@ -70,7 +67,7 @@ export function genEffects(effects: IREffect[], context: CodegenContext) { return frag } -function genEffect({ operations }: IREffect, context: CodegenContext) { +export function genEffect({ operations }: IREffect, context: CodegenContext) { const { vaporHelper } = context const [frag, push] = buildCodeFragment( NEWLINE, diff --git a/packages/runtime-vapor/src/for.ts b/packages/runtime-vapor/src/for.ts index ed68491ead..c486643c83 100644 --- a/packages/runtime-vapor/src/for.ts +++ b/packages/runtime-vapor/src/for.ts @@ -15,7 +15,7 @@ interface ForBlock extends Fragment { export const createFor = ( src: () => any[] | Record | Set | Map, - renderItem: (block: ForBlock) => [Block, () => void], + renderItem: (block: ForBlock) => Block, getKey: ((item: any, index: number) => any) | null, getMemo?: (item: any) => any[], hydrationNode?: Node, @@ -47,9 +47,8 @@ export const createFor = ( memo: getMemo && getMemo(item), [fragmentKey]: true, }) - const res = scope.run(() => renderItem(block))! - block.nodes = res[0] - block.update = res[1] + block.nodes = scope.run(() => renderItem(block))! + block.update = () => scope.effects.forEach(effect => effect.run()) if (getMemo) block.update() if (parent) insert(block.nodes, parent, anchor) return block