From aa5d87b39449e95b3b0260dea7e022cec3b4015f 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: Sun, 28 Apr 2024 03:34:21 +0900 Subject: [PATCH] refactor(compiler-vapor): extract segments of `genMulti` --- .../transformTemplateRef.spec.ts.snap | 51 +++++++++++++++++++ ...f.spec.ts => transformTemplateRef.spec.ts} | 12 ++--- packages/compiler-vapor/src/compile.ts | 4 +- .../compiler-vapor/src/generators/block.ts | 5 +- .../src/generators/component.ts | 12 ++--- .../src/generators/directive.ts | 12 +++-- .../compiler-vapor/src/generators/event.ts | 9 +--- .../src/generators/operation.ts | 6 +-- .../compiler-vapor/src/generators/prop.ts | 13 +++-- .../src/generators/{ref.ts => templateRef.ts} | 8 +-- .../compiler-vapor/src/generators/text.ts | 10 +++- .../compiler-vapor/src/generators/utils.ts | 30 +++++++---- packages/compiler-vapor/src/index.ts | 2 +- packages/compiler-vapor/src/ir.ts | 8 +-- ...ransformRef.ts => transformTemplateRef.ts} | 4 +- 15 files changed, 128 insertions(+), 58 deletions(-) create mode 100644 packages/compiler-vapor/__tests__/transforms/__snapshots__/transformTemplateRef.spec.ts.snap rename packages/compiler-vapor/__tests__/transforms/{transformRef.spec.ts => transformTemplateRef.spec.ts} (93%) rename packages/compiler-vapor/src/generators/{ref.ts => templateRef.ts} (73%) rename packages/compiler-vapor/src/transforms/{transformRef.ts => transformTemplateRef.ts} (88%) diff --git a/packages/compiler-vapor/__tests__/transforms/__snapshots__/transformTemplateRef.spec.ts.snap b/packages/compiler-vapor/__tests__/transforms/__snapshots__/transformTemplateRef.spec.ts.snap new file mode 100644 index 000000000..ba867bd75 --- /dev/null +++ b/packages/compiler-vapor/__tests__/transforms/__snapshots__/transformTemplateRef.spec.ts.snap @@ -0,0 +1,51 @@ +// Vitest Snapshot v1, https://vitest.dev/guide/snapshot.html + +exports[`compiler: template ref transform > dynamic ref 1`] = ` +"import { setRef as _setRef, template as _template } from 'vue/vapor'; +const t0 = _template("
") + +export function render(_ctx) { + const n0 = t0() + _setRef(n0, _ctx.foo) + return n0 +}" +`; + +exports[`compiler: template ref transform > ref + v-for 1`] = ` +"import { setRef as _setRef, createFor as _createFor, template as _template } from 'vue/vapor'; +const t0 = _template("
") + +export function render(_ctx) { + const n0 = _createFor(() => ([1,2,3]), (_block) => { + const n2 = t0() + _setRef(n2, "foo", true) + return [n2, () => {}] + }) + return n0 +}" +`; + +exports[`compiler: template ref transform > ref + v-if 1`] = ` +"import { setRef as _setRef, createIf as _createIf, template as _template } from 'vue/vapor'; +const t0 = _template("
") + +export function render(_ctx) { + const n0 = _createIf(() => (true), () => { + const n2 = t0() + _setRef(n2, "foo") + return n2 + }) + return n0 +}" +`; + +exports[`compiler: template ref transform > static ref 1`] = ` +"import { setRef as _setRef, template as _template } from 'vue/vapor'; +const t0 = _template("
") + +export function render(_ctx) { + const n0 = t0() + _setRef(n0, "foo") + return n0 +}" +`; diff --git a/packages/compiler-vapor/__tests__/transforms/transformRef.spec.ts b/packages/compiler-vapor/__tests__/transforms/transformTemplateRef.spec.ts similarity index 93% rename from packages/compiler-vapor/__tests__/transforms/transformRef.spec.ts rename to packages/compiler-vapor/__tests__/transforms/transformTemplateRef.spec.ts index 78b7694ad..eeee1adfa 100644 --- a/packages/compiler-vapor/__tests__/transforms/transformRef.spec.ts +++ b/packages/compiler-vapor/__tests__/transforms/transformTemplateRef.spec.ts @@ -5,7 +5,7 @@ import { type IfIRNode, transformChildren, transformElement, - transformRef, + transformTemplateRef, transformVFor, transformVIf, } from '../../src' @@ -15,7 +15,7 @@ const compileWithTransformRef = makeCompile({ nodeTransforms: [ transformVIf, transformVFor, - transformRef, + transformTemplateRef, transformElement, transformChildren, ], @@ -32,7 +32,7 @@ describe('compiler: template ref transform', () => { expect(ir.template).toEqual(['
']) expect(ir.block.operation).lengthOf(1) expect(ir.block.operation[0]).toMatchObject({ - type: IRNodeTypes.SET_REF, + type: IRNodeTypes.SET_TEMPLATE_REF, element: 0, value: { content: 'foo', @@ -58,7 +58,7 @@ describe('compiler: template ref transform', () => { expect(ir.template).toEqual(['
']) expect(ir.block.operation).lengthOf(1) expect(ir.block.operation[0]).toMatchObject({ - type: IRNodeTypes.SET_REF, + type: IRNodeTypes.SET_TEMPLATE_REF, element: 0, value: { content: 'foo', @@ -85,7 +85,7 @@ describe('compiler: template ref transform', () => { expect(positive.operation).lengthOf(1) expect(positive.operation[0]).toMatchObject({ - type: IRNodeTypes.SET_REF, + type: IRNodeTypes.SET_TEMPLATE_REF, element: 2, value: { content: 'foo', @@ -109,7 +109,7 @@ describe('compiler: template ref transform', () => { const { render } = ir.block.operation[0] as ForIRNode expect(render.operation).lengthOf(1) expect(render.operation[0]).toMatchObject({ - type: IRNodeTypes.SET_REF, + type: IRNodeTypes.SET_TEMPLATE_REF, element: 2, value: { content: 'foo', diff --git a/packages/compiler-vapor/src/compile.ts b/packages/compiler-vapor/src/compile.ts index 41a4541e5..7d07bb60d 100644 --- a/packages/compiler-vapor/src/compile.ts +++ b/packages/compiler-vapor/src/compile.ts @@ -21,7 +21,7 @@ import { transformVText } from './transforms/vText' import { transformVBind } from './transforms/vBind' import { transformVOn } from './transforms/vOn' import { transformVShow } from './transforms/vShow' -import { transformRef } from './transforms/transformRef' +import { transformTemplateRef } from './transforms/transformTemplateRef' import { transformText } from './transforms/transformText' import { transformVModel } from './transforms/vModel' import { transformVIf } from './transforms/vIf' @@ -103,7 +103,7 @@ export function getBaseTransformPreset( transformOnce, transformVIf, transformVFor, - transformRef, + transformTemplateRef, transformText, transformElement, transformComment, diff --git a/packages/compiler-vapor/src/generators/block.ts b/packages/compiler-vapor/src/generators/block.ts index 8a5e43923..ddf42ef82 100644 --- a/packages/compiler-vapor/src/generators/block.ts +++ b/packages/compiler-vapor/src/generators/block.ts @@ -4,13 +4,14 @@ import { INDENT_END, INDENT_START, NEWLINE, + SEGMENTS_ARRAY, buildCodeFragment, genCall, + genMulti, } from './utils' import type { CodegenContext } from '../generate' import { genEffects, genOperations } from './operation' import { genChildren } from './template' -import { genMulti } from './utils' export function genBlock( oper: BlockIRNode, @@ -68,7 +69,7 @@ export function genBlockContent( const returnsCode: CodeFragment[] = returns.length > 1 - ? genMulti(['[', ']', ', '], ...returns.map(n => `n${n}`)) + ? genMulti(SEGMENTS_ARRAY, ...returns.map(n => `n${n}`)) : [`n${returns[0]}`] push(...(customReturns ? customReturns(returnsCode) : returnsCode)) diff --git a/packages/compiler-vapor/src/generators/component.ts b/packages/compiler-vapor/src/generators/component.ts index 8ab455a70..5f3d060b8 100644 --- a/packages/compiler-vapor/src/generators/component.ts +++ b/packages/compiler-vapor/src/generators/component.ts @@ -3,9 +3,9 @@ import type { CodegenContext } from '../generate' import type { CreateComponentIRNode, IRProp } from '../ir' import { type CodeFragment, - INDENT_END, - INDENT_START, NEWLINE, + SEGMENTS_ARRAY, + SEGMENTS_OBJECT_NEWLINE, genCall, genMulti, } from './utils' @@ -64,17 +64,13 @@ export function genCreateComponent( }) .filter(Boolean) if (props.length) { - return genMulti(['[', ']', ', '], ...props) + return genMulti(SEGMENTS_ARRAY, ...props) } } function genStaticProps(props: IRProp[]) { return genMulti( - [ - ['{', INDENT_START, NEWLINE], - [INDENT_END, NEWLINE, '}'], - [', ', NEWLINE], - ], + SEGMENTS_OBJECT_NEWLINE, ...props.map(prop => { return [ ...genPropKey(prop, context), diff --git a/packages/compiler-vapor/src/generators/directive.ts b/packages/compiler-vapor/src/generators/directive.ts index 9c6468b76..17ba01c9d 100644 --- a/packages/compiler-vapor/src/generators/directive.ts +++ b/packages/compiler-vapor/src/generators/directive.ts @@ -2,7 +2,13 @@ import { createSimpleExpression, isSimpleIdentifier } from '@vue/compiler-dom' import { camelize } from '@vue/shared' import { genExpression } from './expression' import type { CodegenContext } from '../generate' -import { type CodeFragment, NEWLINE, genCall, genMulti } from './utils' +import { + type CodeFragment, + NEWLINE, + SEGMENTS_ARRAY, + genCall, + genMulti, +} from './utils' import { IRNodeTypes, type OperationNode, @@ -22,7 +28,7 @@ export function genWithDirective( const element = `n${opers[0].element}` const directiveItems = opers.map(genDirective) - const directives = genMulti(['[', ']', ', '], ...directiveItems) + const directives = genMulti(SEGMENTS_ARRAY, ...directiveItems) return [ NEWLINE, @@ -47,7 +53,7 @@ export function genWithDirective( ? ['{ ', genDirectiveModifiers(dir.modifiers), ' }'] : false - return genMulti(['[', ']', ', '], directive, value, argument, modifiers) + return genMulti(SEGMENTS_ARRAY, directive, value, argument, modifiers) function genDirective() { const { diff --git a/packages/compiler-vapor/src/generators/event.ts b/packages/compiler-vapor/src/generators/event.ts index e135410d1..c4cc94257 100644 --- a/packages/compiler-vapor/src/generators/event.ts +++ b/packages/compiler-vapor/src/generators/event.ts @@ -8,9 +8,8 @@ import type { SetDynamicEventsIRNode, SetEventIRNode } from '../ir' import { genExpression } from './expression' import { type CodeFragment, - INDENT_END, - INDENT_START, NEWLINE, + SEGMENTS_OBJECT_NEWLINE, genCall, genMulti, } from './utils' @@ -60,11 +59,7 @@ export function genSetEvent( if (!options.length && !nonKeys.length && !keys.length && !effect) return return genMulti( - [ - ['{', INDENT_START, NEWLINE], - [INDENT_END, NEWLINE, '}'], - [', ', NEWLINE], - ], + SEGMENTS_OBJECT_NEWLINE, !!nonKeys.length && ['modifiers: ', genArrayExpression(nonKeys)], !!keys.length && ['keys: ', genArrayExpression(keys)], effect && ['effect: true'], diff --git a/packages/compiler-vapor/src/generators/operation.ts b/packages/compiler-vapor/src/generators/operation.ts index 59b0816d4..224c1fadf 100644 --- a/packages/compiler-vapor/src/generators/operation.ts +++ b/packages/compiler-vapor/src/generators/operation.ts @@ -7,7 +7,7 @@ import { genSetHtml } from './html' import { genIf } from './if' import { genSetModelValue } from './modelValue' import { genDynamicProps, genSetProp } from './prop' -import { genSetRef } from './ref' +import { genSetTemplateRef } from './templateRef' import { genCreateTextNode, genSetText } from './text' import { type CodeFragment, @@ -43,8 +43,8 @@ export function genOperation( return genSetDynamicEvents(oper, context) case IRNodeTypes.SET_HTML: return genSetHtml(oper, context) - case IRNodeTypes.SET_REF: - return genSetRef(oper, context) + case IRNodeTypes.SET_TEMPLATE_REF: + return genSetTemplateRef(oper, context) case IRNodeTypes.SET_MODEL_VALUE: return genSetModelValue(oper, context) case IRNodeTypes.CREATE_TEXT_NODE: diff --git a/packages/compiler-vapor/src/generators/prop.ts b/packages/compiler-vapor/src/generators/prop.ts index f6ea045b1..1f31e4ceb 100644 --- a/packages/compiler-vapor/src/generators/prop.ts +++ b/packages/compiler-vapor/src/generators/prop.ts @@ -11,7 +11,14 @@ import type { VaporHelper, } from '../ir' import { genExpression } from './expression' -import { type CodeFragment, NEWLINE, genCall, genMulti } from './utils' +import { + type CodeFragment, + NEWLINE, + SEGMENTS_ARRAY, + SEGMENTS_OBJECT, + genCall, + genMulti, +} from './utils' import { toHandlerKey } from '@vue/shared' // only the static key prop will reach here @@ -77,7 +84,7 @@ function genLiteralObjectProps( context: CodegenContext, ): CodeFragment[] { return genMulti( - ['{ ', ' }', ', '], + SEGMENTS_OBJECT, ...props.map(prop => [ ...genPropKey(prop, context), `: `, @@ -120,7 +127,7 @@ function genPropValue(values: SimpleExpressionNode[], context: CodegenContext) { return genExpression(values[0], context) } return genMulti( - ['[', ']', ', '], + SEGMENTS_ARRAY, ...values.map(expr => genExpression(expr, context)), ) } diff --git a/packages/compiler-vapor/src/generators/ref.ts b/packages/compiler-vapor/src/generators/templateRef.ts similarity index 73% rename from packages/compiler-vapor/src/generators/ref.ts rename to packages/compiler-vapor/src/generators/templateRef.ts index 248221844..8c1022d6e 100644 --- a/packages/compiler-vapor/src/generators/ref.ts +++ b/packages/compiler-vapor/src/generators/templateRef.ts @@ -1,10 +1,10 @@ import { genExpression } from './expression' import type { CodegenContext } from '../generate' -import type { SetRefIRNode } from '../ir' +import type { SetTemplateRefIRNode } from '../ir' import { type CodeFragment, NEWLINE, genCall } from './utils' -export function genSetRef( - oper: SetRefIRNode, +export function genSetTemplateRef( + oper: SetTemplateRefIRNode, context: CodegenContext, ): CodeFragment[] { const { vaporHelper } = context @@ -12,7 +12,7 @@ export function genSetRef( NEWLINE, ...genCall( vaporHelper('setRef'), - [`n${oper.element}`], + `n${oper.element}`, genExpression(oper.value, context), oper.refFor && 'true', ), diff --git a/packages/compiler-vapor/src/generators/text.ts b/packages/compiler-vapor/src/generators/text.ts index 75894be10..fe723bdc5 100644 --- a/packages/compiler-vapor/src/generators/text.ts +++ b/packages/compiler-vapor/src/generators/text.ts @@ -1,7 +1,13 @@ import type { CodegenContext } from '../generate' import type { CreateTextNodeIRNode, SetTextIRNode } from '../ir' import { genExpression } from './expression' -import { type CodeFragment, NEWLINE, genCall, genMulti } from './utils' +import { + type CodeFragment, + NEWLINE, + SEGMENTS_ARRAY, + genCall, + genMulti, +} from './utils' export function genSetText( oper: SetTextIRNode, @@ -31,7 +37,7 @@ export function genCreateTextNode( ...genCall(vaporHelper('createTextNode'), [ effect && '() => ', ...genMulti( - ['[', ']', ', '], + SEGMENTS_ARRAY, ...values.map(value => genExpression(value, context)), ), ]), diff --git a/packages/compiler-vapor/src/generators/utils.ts b/packages/compiler-vapor/src/generators/utils.ts index 206c43e2b..c2e71630a 100644 --- a/packages/compiler-vapor/src/generators/utils.ts +++ b/packages/compiler-vapor/src/generators/utils.ts @@ -30,22 +30,23 @@ export function buildCodeFragment(...frag: CodeFragment[]) { return [frag, push] as const } +type Segments = [ + left: CodeFragments, + right: CodeFragments, + segment: CodeFragments, +] export function genMulti( - [left, right, seg]: [ - left: CodeFragments, - right: CodeFragments, - segment: CodeFragments, - ], - ...fns: CodeFragments[] + [left, right, seg]: Segments, + ...frags: CodeFragments[] ): CodeFragment[] { const frag: CodeFragment[] = [] - fns = fns.filter(Boolean) + frags = frags.filter(Boolean) push(left) for (let [i, fn] of ( - fns as Array> + frags as Array> ).entries()) { push(fn) - if (i < fns.length - 1) push(seg) + if (i < frags.length - 1) push(seg) } push(right) return frag @@ -55,12 +56,19 @@ export function genMulti( frag.push(...fn) } } +export const SEGMENTS_ARRAY: Segments = ['[', ']', ', '] +export const SEGMENTS_OBJECT: Segments = ['{ ', ' }', ', '] +export const SEGMENTS_OBJECT_NEWLINE: Segments = [ + ['{', INDENT_START, NEWLINE], + [INDENT_END, NEWLINE, '}'], + [', ', NEWLINE], +] export function genCall( name: string, - ...args: CodeFragments[] + ...frags: CodeFragments[] ): CodeFragment[] { - return [name, ...genMulti(['(', ')', ', '], ...args)] + return [name, ...genMulti(['(', ')', ', '], ...frags)] } export function genCodeFragment(context: CodegenContext) { diff --git a/packages/compiler-vapor/src/index.ts b/packages/compiler-vapor/src/index.ts index c97e5a2ab..225834afc 100644 --- a/packages/compiler-vapor/src/index.ts +++ b/packages/compiler-vapor/src/index.ts @@ -36,7 +36,7 @@ export { export { transformElement } from './transforms/transformElement' export { transformChildren } from './transforms/transformChildren' -export { transformRef } from './transforms/transformRef' +export { transformTemplateRef } from './transforms/transformTemplateRef' export { transformText } from './transforms/transformText' export { transformVBind } from './transforms/vBind' export { transformVHtml } from './transforms/vHtml' diff --git a/packages/compiler-vapor/src/ir.ts b/packages/compiler-vapor/src/ir.ts index 40ccf3bf1..e5ba223d7 100644 --- a/packages/compiler-vapor/src/ir.ts +++ b/packages/compiler-vapor/src/ir.ts @@ -23,7 +23,7 @@ export enum IRNodeTypes { SET_EVENT, SET_DYNAMIC_EVENTS, SET_HTML, - SET_REF, + SET_TEMPLATE_REF, SET_MODEL_VALUE, INSERT_NODE, @@ -140,8 +140,8 @@ export interface SetHtmlIRNode extends BaseIRNode { value: SimpleExpressionNode } -export interface SetRefIRNode extends BaseIRNode { - type: IRNodeTypes.SET_REF +export interface SetTemplateRefIRNode extends BaseIRNode { + type: IRNodeTypes.SET_TEMPLATE_REF element: number value: SimpleExpressionNode refFor: boolean @@ -202,7 +202,7 @@ export type OperationNode = | SetEventIRNode | SetDynamicEventsIRNode | SetHtmlIRNode - | SetRefIRNode + | SetTemplateRefIRNode | SetModelValueIRNode | CreateTextNodeIRNode | InsertNodeIRNode diff --git a/packages/compiler-vapor/src/transforms/transformRef.ts b/packages/compiler-vapor/src/transforms/transformTemplateRef.ts similarity index 88% rename from packages/compiler-vapor/src/transforms/transformRef.ts rename to packages/compiler-vapor/src/transforms/transformTemplateRef.ts index 7da99ebfc..fd0cc0fc8 100644 --- a/packages/compiler-vapor/src/transforms/transformRef.ts +++ b/packages/compiler-vapor/src/transforms/transformTemplateRef.ts @@ -9,7 +9,7 @@ import { normalizeBindShorthand } from './vBind' import { findProp } from '../utils' import { EMPTY_EXPRESSION } from './utils' -export const transformRef: NodeTransform = (node, context) => { +export const transformTemplateRef: NodeTransform = (node, context) => { if (node.type !== NodeTypes.ELEMENT) return const dir = findProp(node, 'ref', false, true) @@ -26,7 +26,7 @@ export const transformRef: NodeTransform = (node, context) => { return () => context.registerOperation({ - type: IRNodeTypes.SET_REF, + type: IRNodeTypes.SET_TEMPLATE_REF, element: context.reference(), value, refFor: !!context.inVFor,