From 3fa32f74ef7e23973b5de9c5dee59a7762c587af Mon Sep 17 00:00:00 2001 From: Rizumu Ayaka Date: Thu, 7 Dec 2023 17:46:42 +0800 Subject: [PATCH 1/5] feat: basic and shorthand syntax --- packages/compiler-vapor/src/transforms/vBind.ts | 16 +++++++++++++++- 1 file changed, 15 insertions(+), 1 deletion(-) diff --git a/packages/compiler-vapor/src/transforms/vBind.ts b/packages/compiler-vapor/src/transforms/vBind.ts index 6bd4cc939..41f69c9af 100644 --- a/packages/compiler-vapor/src/transforms/vBind.ts +++ b/packages/compiler-vapor/src/transforms/vBind.ts @@ -2,13 +2,14 @@ import { createCompilerError, createSimpleExpression, ErrorCodes, + NodeTypes, } from '@vue/compiler-core' import { camelize } from '@vue/shared' import { IRNodeTypes } from '../ir' import type { DirectiveTransform } from '../transform' export const transformVBind: DirectiveTransform = (dir, node, context) => { - let { arg, exp, loc } = dir + let { arg, exp, loc, modifiers } = dir if (!arg) { // TODO support v-bind="{}" @@ -21,6 +22,19 @@ export const transformVBind: DirectiveTransform = (dir, node, context) => { exp.ast = null } + if (modifiers.includes('camel')) { + if (arg.type === NodeTypes.SIMPLE_EXPRESSION) { + if (arg.isStatic) { + arg.content = camelize(arg.content) + } else { + // arg.content = `${context.helperString('camelize')}(${arg.content})` + } + } else { + // arg.children.unshift(`${context.helperString('camelize')}(`) + // arg.children.push(`)`) + } + } + if (!exp.content.trim()) { context.options.onError( createCompilerError(ErrorCodes.X_V_BIND_NO_EXPRESSION, loc), From 5569395868ce0055ce7c0f14645acf9ddcf1ff89 Mon Sep 17 00:00:00 2001 From: Rizumu Ayaka Date: Fri, 8 Dec 2023 18:37:56 +0800 Subject: [PATCH 2/5] feat: dynamic arg --- packages/compiler-vapor/src/generate.ts | 6 +++++- packages/compiler-vapor/src/ir.ts | 1 + packages/compiler-vapor/src/transforms/vBind.ts | 15 ++++++--------- 3 files changed, 12 insertions(+), 10 deletions(-) diff --git a/packages/compiler-vapor/src/generate.ts b/packages/compiler-vapor/src/generate.ts index d92def7fe..b8a4578b9 100644 --- a/packages/compiler-vapor/src/generate.ts +++ b/packages/compiler-vapor/src/generate.ts @@ -11,6 +11,8 @@ import { walkIdentifiers, advancePositionWithClone, isSimpleIdentifier, + CAMELIZE, + helperNameMap, } from '@vue/compiler-dom' import { type IRDynamicChildren, @@ -370,9 +372,11 @@ function genOperation(oper: OperationNode, context: CodegenContext) { } function genSetProp(oper: SetPropIRNode, context: CodegenContext) { - const { push, pushWithNewline, vaporHelper } = context + const { push, pushWithNewline, vaporHelper, helper } = context pushWithNewline(`${vaporHelper('setAttr')}(n${oper.element}, `) + if (oper.camel) push(`${helper(helperNameMap[CAMELIZE])}(`) genExpression(oper.key, context) + if (oper.camel) push(`)`) push(`, undefined, `) genExpression(oper.value, context) push(')') diff --git a/packages/compiler-vapor/src/ir.ts b/packages/compiler-vapor/src/ir.ts index 172f32fd7..e3957430d 100644 --- a/packages/compiler-vapor/src/ir.ts +++ b/packages/compiler-vapor/src/ir.ts @@ -60,6 +60,7 @@ export interface SetPropIRNode extends BaseIRNode { element: number key: IRExpression value: IRExpression + camel: boolean } export interface SetTextIRNode extends BaseIRNode { diff --git a/packages/compiler-vapor/src/transforms/vBind.ts b/packages/compiler-vapor/src/transforms/vBind.ts index 41f69c9af..dd3a49895 100644 --- a/packages/compiler-vapor/src/transforms/vBind.ts +++ b/packages/compiler-vapor/src/transforms/vBind.ts @@ -2,7 +2,6 @@ import { createCompilerError, createSimpleExpression, ErrorCodes, - NodeTypes, } from '@vue/compiler-core' import { camelize } from '@vue/shared' import { IRNodeTypes } from '../ir' @@ -22,16 +21,13 @@ export const transformVBind: DirectiveTransform = (dir, node, context) => { exp.ast = null } + let camel = false if (modifiers.includes('camel')) { - if (arg.type === NodeTypes.SIMPLE_EXPRESSION) { - if (arg.isStatic) { - arg.content = camelize(arg.content) - } else { - // arg.content = `${context.helperString('camelize')}(${arg.content})` - } + console.log('arg:', arg) + if (arg.isStatic) { + arg.content = camelize(arg.content) } else { - // arg.children.unshift(`${context.helperString('camelize')}(`) - // arg.children.push(`)`) + camel = true } } @@ -52,6 +48,7 @@ export const transformVBind: DirectiveTransform = (dir, node, context) => { element: context.reference(), key: arg, value: exp, + camel, }, ], ) From ae512ef054690b415006ca390e6c4ba585046f7b Mon Sep 17 00:00:00 2001 From: Rizumu Ayaka Date: Sat, 9 Dec 2023 09:33:36 +0800 Subject: [PATCH 3/5] fix: correct according to code review --- packages/compiler-vapor/src/generate.ts | 6 ++---- packages/compiler-vapor/src/ir.ts | 2 +- packages/compiler-vapor/src/transforms/vBind.ts | 3 +-- 3 files changed, 4 insertions(+), 7 deletions(-) diff --git a/packages/compiler-vapor/src/generate.ts b/packages/compiler-vapor/src/generate.ts index b8a4578b9..4bce56044 100644 --- a/packages/compiler-vapor/src/generate.ts +++ b/packages/compiler-vapor/src/generate.ts @@ -11,8 +11,6 @@ import { walkIdentifiers, advancePositionWithClone, isSimpleIdentifier, - CAMELIZE, - helperNameMap, } from '@vue/compiler-dom' import { type IRDynamicChildren, @@ -374,9 +372,9 @@ function genOperation(oper: OperationNode, context: CodegenContext) { function genSetProp(oper: SetPropIRNode, context: CodegenContext) { const { push, pushWithNewline, vaporHelper, helper } = context pushWithNewline(`${vaporHelper('setAttr')}(n${oper.element}, `) - if (oper.camel) push(`${helper(helperNameMap[CAMELIZE])}(`) + if (oper.runtimeCamelize) push(`${helper('camelize')}(`) genExpression(oper.key, context) - if (oper.camel) push(`)`) + if (oper.runtimeCamelize) push(`)`) push(`, undefined, `) genExpression(oper.value, context) push(')') diff --git a/packages/compiler-vapor/src/ir.ts b/packages/compiler-vapor/src/ir.ts index e3957430d..979536af8 100644 --- a/packages/compiler-vapor/src/ir.ts +++ b/packages/compiler-vapor/src/ir.ts @@ -60,7 +60,7 @@ export interface SetPropIRNode extends BaseIRNode { element: number key: IRExpression value: IRExpression - camel: boolean + runtimeCamelize: boolean } export interface SetTextIRNode extends BaseIRNode { diff --git a/packages/compiler-vapor/src/transforms/vBind.ts b/packages/compiler-vapor/src/transforms/vBind.ts index dd3a49895..84fd1ac43 100644 --- a/packages/compiler-vapor/src/transforms/vBind.ts +++ b/packages/compiler-vapor/src/transforms/vBind.ts @@ -23,7 +23,6 @@ export const transformVBind: DirectiveTransform = (dir, node, context) => { let camel = false if (modifiers.includes('camel')) { - console.log('arg:', arg) if (arg.isStatic) { arg.content = camelize(arg.content) } else { @@ -48,7 +47,7 @@ export const transformVBind: DirectiveTransform = (dir, node, context) => { element: context.reference(), key: arg, value: exp, - camel, + runtimeCamelize: camel, }, ], ) From 1a3d51c05f17465daca515c818b6c9e1983ed453 Mon Sep 17 00:00:00 2001 From: Rizumu Ayaka Date: Sat, 9 Dec 2023 10:25:27 +0800 Subject: [PATCH 4/5] test: complete the unit tests --- .../transforms/__snapshots__/vBind.spec.ts.snap | 2 +- .../__tests__/transforms/vBind.spec.ts | 12 ++++++------ 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/packages/compiler-vapor/__tests__/transforms/__snapshots__/vBind.spec.ts.snap b/packages/compiler-vapor/__tests__/transforms/__snapshots__/vBind.spec.ts.snap index 335280313..0c115735c 100644 --- a/packages/compiler-vapor/__tests__/transforms/__snapshots__/vBind.spec.ts.snap +++ b/packages/compiler-vapor/__tests__/transforms/__snapshots__/vBind.spec.ts.snap @@ -8,7 +8,7 @@ export function render(_ctx) { const n0 = t0() const { 0: [n1],} = _children(n0) _effect(() => { - _setAttr(n1, "foo-bar", undefined, _ctx.id) + _setAttr(n1, "fooBar", undefined, _ctx.id) }) return n0 }" diff --git a/packages/compiler-vapor/__tests__/transforms/vBind.spec.ts b/packages/compiler-vapor/__tests__/transforms/vBind.spec.ts index fbaf2b089..eed0d3fd3 100644 --- a/packages/compiler-vapor/__tests__/transforms/vBind.spec.ts +++ b/packages/compiler-vapor/__tests__/transforms/vBind.spec.ts @@ -165,8 +165,9 @@ describe('compiler: transform v-bind', () => { }) }) - test.fails('.camel modifier', () => { + test('.camel modifier', () => { const node = parseWithVBind(`
`) + console.log('node.effect[0].operations[0]', node.effect[0].operations[0]) expect(node.effect[0].operations[0]).toMatchObject({ key: { content: `fooBar`, @@ -179,7 +180,7 @@ describe('compiler: transform v-bind', () => { }) }) - test.fails('.camel modifier w/ no expression', () => { + test('.camel modifier w/ no expression', () => { const node = parseWithVBind(`
`) expect(node.effect[0].operations[0]).toMatchObject({ key: { @@ -193,13 +194,13 @@ describe('compiler: transform v-bind', () => { }) }) - test.fails('.camel modifier w/ dynamic arg', () => { + test('.camel modifier w/ dynamic arg', () => { const node = parseWithVBind(`
`) expect(node.effect[0].operations[0]).toMatchObject({ + runtimeCamelize: true, key: { content: `foo`, isStatic: false, - somethingShouldBeTrue: true, }, value: { content: `id`, @@ -289,8 +290,7 @@ describe('compiler: codegen v-bind', () => { expect(code).contains('_setAttr(n1, _ctx.id, undefined, _ctx.id)') }) - // TODO: camel modifier for v-bind - test.fails('.camel modifier', () => { + test('.camel modifier', () => { const code = compile(`
`) expect(code).matchSnapshot() From 2ecbfe2cbf24615f0cde8c8006f413868b667740 Mon Sep 17 00:00:00 2001 From: Rizumu Ayaka Date: Sat, 9 Dec 2023 10:27:06 +0800 Subject: [PATCH 5/5] chore: remove console --- packages/compiler-vapor/__tests__/transforms/vBind.spec.ts | 1 - 1 file changed, 1 deletion(-) diff --git a/packages/compiler-vapor/__tests__/transforms/vBind.spec.ts b/packages/compiler-vapor/__tests__/transforms/vBind.spec.ts index eed0d3fd3..416f65c4e 100644 --- a/packages/compiler-vapor/__tests__/transforms/vBind.spec.ts +++ b/packages/compiler-vapor/__tests__/transforms/vBind.spec.ts @@ -167,7 +167,6 @@ describe('compiler: transform v-bind', () => { test('.camel modifier', () => { const node = parseWithVBind(`
`) - console.log('node.effect[0].operations[0]', node.effect[0].operations[0]) expect(node.effect[0].operations[0]).toMatchObject({ key: { content: `fooBar`,