From 1696523e8d0e1703947dea56c3177578dc4ae6bc Mon Sep 17 00:00:00 2001 From: daiwei Date: Mon, 2 Dec 2024 17:34:07 +0800 Subject: [PATCH 01/47] wip: save --- .../__snapshots__/compile.spec.ts.snap | 6 +- .../__snapshots__/vBind.spec.ts.snap | 144 +++++++++----- .../__tests__/transforms/vBind.spec.ts | 184 +++++++++++++----- packages/compiler-vapor/src/generate.ts | 2 + .../src/generators/expression.ts | 43 +++- .../src/generators/operation.ts | 9 +- .../compiler-vapor/src/generators/prop.ts | 15 +- 7 files changed, 291 insertions(+), 112 deletions(-) diff --git a/packages/compiler-vapor/__tests__/__snapshots__/compile.spec.ts.snap b/packages/compiler-vapor/__tests__/__snapshots__/compile.spec.ts.snap index 09e8c4cca..ae9241b99 100644 --- a/packages/compiler-vapor/__tests__/__snapshots__/compile.spec.ts.snap +++ b/packages/compiler-vapor/__tests__/__snapshots__/compile.spec.ts.snap @@ -162,7 +162,8 @@ export function render(_ctx, $props, $emit, $attrs, $slots) { const n1 = _createComponent(_component_Comp) const n2 = _createTextNode(() => [_ctx.bar]) _insert([n1, n2], n3) - _renderEffect(() => _setDOMProp(n3, "id", _ctx.foo)) + let _foo; + _renderEffect(() => _foo !== _ctx.foo && _setDOMProp(n3, "id", _foo = _ctx.foo)) return [n0, n3] }" `; @@ -186,7 +187,8 @@ export function render(_ctx) { _delegate(n0, "click", () => _ctx.handleClick) _setInheritAttrs(["id"]) _renderEffect(() => _setText(n0, _ctx.count, "foo", _ctx.count, "foo", _ctx.count)) - _renderEffect(() => _setDOMProp(n0, "id", _ctx.count)) + let _count; + _renderEffect(() => _count !== _ctx.count && _setDOMProp(n0, "id", _count = _ctx.count)) return n0 }" `; 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 4630eadfb..7df887382 100644 --- a/packages/compiler-vapor/__tests__/transforms/__snapshots__/vBind.spec.ts.snap +++ b/packages/compiler-vapor/__tests__/transforms/__snapshots__/vBind.spec.ts.snap @@ -7,7 +7,8 @@ const t0 = _template("
") export function render(_ctx) { const n0 = t0() _setInheritAttrs(["foo-bar"]) - _renderEffect(() => _setAttr(n0, "foo-bar", _ctx.id)) + let _id; + _renderEffect(() => _id !== _ctx.id && _setAttr(n0, "foo-bar", _id = _ctx.id)) return n0 }" `; @@ -19,7 +20,8 @@ const t0 = _template("
") export function render(_ctx) { const n0 = t0() _setInheritAttrs(["innerHTML"]) - _renderEffect(() => _setAttr(n0, "innerHTML", _ctx.foo)) + let _foo; + _renderEffect(() => _foo !== _ctx.foo && _setAttr(n0, "innerHTML", _foo = _ctx.foo)) return n0 }" `; @@ -31,7 +33,8 @@ const t0 = _template("
") export function render(_ctx) { const n0 = t0() _setInheritAttrs(["foo-bar"]) - _renderEffect(() => _setAttr(n0, "foo-bar", _ctx.fooBar)) + let _fooBar; + _renderEffect(() => _fooBar !== _ctx.fooBar && _setAttr(n0, "foo-bar", _fooBar = _ctx.fooBar)) return n0 }" `; @@ -43,7 +46,8 @@ const t0 = _template("") export function render(_ctx) { const n0 = t0() _setInheritAttrs(["value"]) - _renderEffect(() => _setAttr(n0, "value", _ctx.foo)) + let _foo; + _renderEffect(() => _foo !== _ctx.foo && _setAttr(n0, "value", _foo = _ctx.foo)) return n0 }" `; @@ -55,7 +59,8 @@ const t0 = _template("
") export function render(_ctx) { const n0 = t0() _setInheritAttrs(["textContent"]) - _renderEffect(() => _setAttr(n0, "textContent", _ctx.foo)) + let _foo; + _renderEffect(() => _foo !== _ctx.foo && _setAttr(n0, "textContent", _foo = _ctx.foo)) return n0 }" `; @@ -67,7 +72,8 @@ const t0 = _template("
") export function render(_ctx) { const n0 = t0() _setInheritAttrs(["value"]) - _renderEffect(() => _setAttr(n0, "value", _ctx.foo)) + let _foo; + _renderEffect(() => _foo !== _ctx.foo && _setAttr(n0, "value", _foo = _ctx.foo)) return n0 }" `; @@ -116,7 +122,8 @@ const t0 = _template("
") export function render(_ctx) { const n0 = t0() _setInheritAttrs(["fooBar"]) - _renderEffect(() => _setDOMProp(n0, "fooBar", _ctx.id)) + let _id; + _renderEffect(() => _id !== _ctx.id && _setDOMProp(n0, "fooBar", _id = _ctx.id)) return n0 }" `; @@ -128,7 +135,8 @@ const t0 = _template("
") export function render(_ctx) { const n0 = t0() _setInheritAttrs(["innerHTML"]) - _renderEffect(() => _setHtml(n0, _ctx.foo)) + let _foo; + _renderEffect(() => _foo !== _ctx.foo && _setHtml(n0, _foo = _ctx.foo)) return n0 }" `; @@ -140,7 +148,8 @@ const t0 = _template("
") export function render(_ctx) { const n0 = t0() _setInheritAttrs(["fooBar"]) - _renderEffect(() => _setDOMProp(n0, "fooBar", _ctx.fooBar)) + let _fooBar; + _renderEffect(() => _fooBar !== _ctx.fooBar && _setDOMProp(n0, "fooBar", _fooBar = _ctx.fooBar)) return n0 }" `; @@ -152,7 +161,8 @@ const t0 = _template("") export function render(_ctx) { const n0 = t0() _setInheritAttrs(["value"]) - _renderEffect(() => _setDOMProp(n0, "value", _ctx.foo)) + let _foo; + _renderEffect(() => _foo !== _ctx.foo && _setDOMProp(n0, "value", _foo = _ctx.foo)) return n0 }" `; @@ -164,7 +174,8 @@ const t0 = _template("
") export function render(_ctx) { const n0 = t0() _setInheritAttrs(["textContent"]) - _renderEffect(() => _setText(n0, _ctx.foo)) + let _foo; + _renderEffect(() => _foo !== _ctx.foo && _setText(n0, _foo = _ctx.foo)) return n0 }" `; @@ -176,7 +187,8 @@ const t0 = _template("
") export function render(_ctx) { const n0 = t0() _setInheritAttrs(["value"]) - _renderEffect(() => _setValue(n0, _ctx.foo)) + let _foo; + _renderEffect(() => _foo !== _ctx.foo && _setValue(n0, _foo = _ctx.foo)) return n0 }" `; @@ -188,7 +200,8 @@ const t0 = _template("
") export function render(_ctx) { const n0 = t0() _setInheritAttrs(["fooBar"]) - _renderEffect(() => _setDOMProp(n0, "fooBar", _ctx.id)) + let _id; + _renderEffect(() => _id !== _ctx.id && _setDOMProp(n0, "fooBar", _id = _ctx.id)) return n0 }" `; @@ -212,7 +225,8 @@ const t0 = _template("
") export function render(_ctx) { const n0 = t0() _setInheritAttrs(["innerHTML"]) - _renderEffect(() => _setHtml(n0, _ctx.foo)) + let _foo; + _renderEffect(() => _foo !== _ctx.foo && _setHtml(n0, _foo = _ctx.foo)) return n0 }" `; @@ -224,7 +238,8 @@ const t0 = _template("
") export function render(_ctx) { const n0 = t0() _setInheritAttrs(["fooBar"]) - _renderEffect(() => _setDOMProp(n0, "fooBar", _ctx.fooBar)) + let _fooBar; + _renderEffect(() => _fooBar !== _ctx.fooBar && _setDOMProp(n0, "fooBar", _fooBar = _ctx.fooBar)) return n0 }" `; @@ -236,7 +251,8 @@ const t0 = _template("") export function render(_ctx) { const n0 = t0() _setInheritAttrs(["value"]) - _renderEffect(() => _setDOMProp(n0, "value", _ctx.foo)) + let _foo; + _renderEffect(() => _foo !== _ctx.foo && _setDOMProp(n0, "value", _foo = _ctx.foo)) return n0 }" `; @@ -248,7 +264,8 @@ const t0 = _template("
") export function render(_ctx) { const n0 = t0() _setInheritAttrs(["textContent"]) - _renderEffect(() => _setText(n0, _ctx.foo)) + let _foo; + _renderEffect(() => _foo !== _ctx.foo && _setText(n0, _foo = _ctx.foo)) return n0 }" `; @@ -260,7 +277,8 @@ const t0 = _template("
") export function render(_ctx) { const n0 = t0() _setInheritAttrs(["value"]) - _renderEffect(() => _setValue(n0, _ctx.foo)) + let _foo; + _renderEffect(() => _foo !== _ctx.foo && _setValue(n0, _foo = _ctx.foo)) return n0 }" `; @@ -272,7 +290,8 @@ const t0 = _template("
") export function render(_ctx) { const n0 = t0() _setInheritAttrs(["innerHTML"]) - _renderEffect(() => _setHtml(n0, _ctx.foo)) + let _foo; + _renderEffect(() => _foo !== _ctx.foo && _setHtml(n0, _foo = _ctx.foo)) return n0 }" `; @@ -284,7 +303,8 @@ const t0 = _template("
") export function render(_ctx) { const n0 = t0() _setInheritAttrs(["textContent"]) - _renderEffect(() => _setText(n0, _ctx.foo)) + let _foo; + _renderEffect(() => _foo !== _ctx.foo && _setText(n0, _foo = _ctx.foo)) return n0 }" `; @@ -296,7 +316,8 @@ const t0 = _template("") export function render(_ctx) { const n0 = t0() _setInheritAttrs(["value"]) - _renderEffect(() => _setValue(n0, _ctx.foo)) + let _foo; + _renderEffect(() => _foo !== _ctx.foo && _setValue(n0, _foo = _ctx.foo)) return n0 }" `; @@ -320,11 +341,16 @@ const t0 = _template("
") export function render(_ctx) { const n0 = t0() _setInheritAttrs(["id", "title", "lang", "dir", "tabindex"]) - _renderEffect(() => _setDOMProp(n0, "id", _ctx.id)) - _renderEffect(() => _setDOMProp(n0, "title", _ctx.title)) - _renderEffect(() => _setDOMProp(n0, "lang", _ctx.lang)) - _renderEffect(() => _setDOMProp(n0, "dir", _ctx.dir)) - _renderEffect(() => _setDOMProp(n0, "tabindex", _ctx.tabindex)) + let _id; + _renderEffect(() => _id !== _ctx.id && _setDOMProp(n0, "id", _id = _ctx.id)) + let _title; + _renderEffect(() => _title !== _ctx.title && _setDOMProp(n0, "title", _title = _ctx.title)) + let _lang; + _renderEffect(() => _lang !== _ctx.lang && _setDOMProp(n0, "lang", _lang = _ctx.lang)) + let _dir; + _renderEffect(() => _dir !== _ctx.dir && _setDOMProp(n0, "dir", _dir = _ctx.dir)) + let _tabindex; + _renderEffect(() => _tabindex !== _ctx.tabindex && _setDOMProp(n0, "tabindex", _tabindex = _ctx.tabindex)) return n0 }" `; @@ -336,11 +362,16 @@ const t0 = _template("") export function render(_ctx) { const n0 = t0() _setInheritAttrs(["autofucus", "dir", "displaystyle", "mathcolor", "tabindex"]) - _renderEffect(() => _setDOMProp(n0, "autofucus", _ctx.autofucus)) - _renderEffect(() => _setDOMProp(n0, "dir", _ctx.dir)) - _renderEffect(() => _setDOMProp(n0, "displaystyle", _ctx.displaystyle)) - _renderEffect(() => _setDOMProp(n0, "mathcolor", _ctx.mathcolor)) - _renderEffect(() => _setDOMProp(n0, "tabindex", _ctx.tabindex)) + let _autofucus; + _renderEffect(() => _autofucus !== _ctx.autofucus && _setDOMProp(n0, "autofucus", _autofucus = _ctx.autofucus)) + let _dir; + _renderEffect(() => _dir !== _ctx.dir && _setDOMProp(n0, "dir", _dir = _ctx.dir)) + let _displaystyle; + _renderEffect(() => _displaystyle !== _ctx.displaystyle && _setDOMProp(n0, "displaystyle", _displaystyle = _ctx.displaystyle)) + let _mathcolor; + _renderEffect(() => _mathcolor !== _ctx.mathcolor && _setDOMProp(n0, "mathcolor", _mathcolor = _ctx.mathcolor)) + let _tabindex; + _renderEffect(() => _tabindex !== _ctx.tabindex && _setDOMProp(n0, "tabindex", _tabindex = _ctx.tabindex)) return n0 }" `; @@ -352,9 +383,12 @@ const t0 = _template("") export function render(_ctx) { const n0 = t0() _setInheritAttrs(["id", "lang", "tabindex"]) - _renderEffect(() => _setDOMProp(n0, "id", _ctx.id)) - _renderEffect(() => _setDOMProp(n0, "lang", _ctx.lang)) - _renderEffect(() => _setDOMProp(n0, "tabindex", _ctx.tabindex)) + let _id; + _renderEffect(() => _id !== _ctx.id && _setDOMProp(n0, "id", _id = _ctx.id)) + let _lang; + _renderEffect(() => _lang !== _ctx.lang && _setDOMProp(n0, "lang", _lang = _ctx.lang)) + let _tabindex; + _renderEffect(() => _tabindex !== _ctx.tabindex && _setDOMProp(n0, "tabindex", _tabindex = _ctx.tabindex)) return n0 }" `; @@ -377,23 +411,31 @@ export function render(_ctx) { const n4 = t4() const n5 = t5() const n6 = t6() - _renderEffect(() => _setAttr(n0, "spellcheck", _ctx.spellcheck)) - _renderEffect(() => _setAttr(n0, "draggable", _ctx.draggable)) - _renderEffect(() => _setAttr(n0, "translate", _ctx.translate)) - _renderEffect(() => _setAttr(n0, "form", _ctx.form)) - _renderEffect(() => _setAttr(n1, "list", _ctx.list)) - _renderEffect(() => _setAttr(n2, "type", _ctx.type)) + let _spellcheck; + _renderEffect(() => _spellcheck !== _ctx.spellcheck && _setAttr(n0, "spellcheck", _spellcheck = _ctx.spellcheck)) + let _draggable; + _renderEffect(() => _draggable !== _ctx.draggable && _setAttr(n0, "draggable", _draggable = _ctx.draggable)) + let _translate; + _renderEffect(() => _translate !== _ctx.translate && _setAttr(n0, "translate", _translate = _ctx.translate)) + let _form; + _renderEffect(() => _form !== _ctx.form && _setAttr(n0, "form", _form = _ctx.form)) + let _list; + _renderEffect(() => _list !== _ctx.list && _setAttr(n1, "list", _list = _ctx.list)) + let _type; + _renderEffect(() => _type !== _ctx.type && _setAttr(n2, "type", _type = _ctx.type)) + let _width; _renderEffect(() => { - _setAttr(n3, "width", _ctx.width) - _setAttr(n4, "width", _ctx.width) - _setAttr(n5, "width", _ctx.width) - _setAttr(n6, "width", _ctx.width) + _width !== _ctx.width && _setAttr(n3, "width", _width = _ctx.width) + _width !== _ctx.width && _setAttr(n4, "width", _width = _ctx.width) + _width !== _ctx.width && _setAttr(n5, "width", _width = _ctx.width) + _width !== _ctx.width && _setAttr(n6, "width", _width = _ctx.width) }) + let _height; _renderEffect(() => { - _setAttr(n3, "height", _ctx.height) - _setAttr(n4, "height", _ctx.height) - _setAttr(n5, "height", _ctx.height) - _setAttr(n6, "height", _ctx.height) + _height !== _ctx.height && _setAttr(n3, "height", _height = _ctx.height) + _height !== _ctx.height && _setAttr(n4, "height", _height = _ctx.height) + _height !== _ctx.height && _setAttr(n5, "height", _height = _ctx.height) + _height !== _ctx.height && _setAttr(n6, "height", _height = _ctx.height) }) return [n0, n1, n2, n3, n4, n5, n6] }" @@ -406,7 +448,8 @@ const t0 = _template("
") export function render(_ctx) { const n0 = t0() _setInheritAttrs(["id"]) - _renderEffect(() => _setDOMProp(n0, "id", _ctx.id)) + let _id; + _renderEffect(() => _id !== _ctx.id && _setDOMProp(n0, "id", _id = _ctx.id)) return n0 }" `; @@ -454,7 +497,8 @@ const t0 = _template("
") export function render(_ctx) { const n0 = t0() _setInheritAttrs(["id"]) - _renderEffect(() => _setDOMProp(n0, "id", _ctx.id)) + let _id; + _renderEffect(() => _id !== _ctx.id && _setDOMProp(n0, "id", _id = _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 efaa9257c..6e5700f8e 100644 --- a/packages/compiler-vapor/__tests__/transforms/vBind.spec.ts +++ b/packages/compiler-vapor/__tests__/transforms/vBind.spec.ts @@ -74,7 +74,9 @@ describe('compiler v-bind', () => { }) expect(code).matchSnapshot() - expect(code).contains('_setDOMProp(n0, "id", _ctx.id)') + expect(code).contains( + '_id !== _ctx.id && _setDOMProp(n0, "id", _id = _ctx.id)', + ) }) test('no expression', () => { @@ -104,7 +106,9 @@ describe('compiler v-bind', () => { ], }, }) - expect(code).contains('_setDOMProp(n0, "id", _ctx.id)') + expect(code).contains( + '_id !== _ctx.id && _setDOMProp(n0, "id", _id = _ctx.id)', + ) }) test('no expression (shorthand)', () => { @@ -368,7 +372,9 @@ describe('compiler v-bind', () => { }, }) expect(code).contains('renderEffect') - expect(code).contains('_setDOMProp(n0, "fooBar", _ctx.id)') + expect(code).contains( + '_id !== _ctx.id && _setDOMProp(n0, "fooBar", _id = _ctx.id)', + ) }) test('.prop modifier w/ no expression', () => { @@ -392,7 +398,9 @@ describe('compiler v-bind', () => { }, }) expect(code).contains('renderEffect') - expect(code).contains('_setDOMProp(n0, "fooBar", _ctx.fooBar)') + expect(code).contains( + '_fooBar !== _ctx.fooBar && _setDOMProp(n0, "fooBar", _fooBar = _ctx.fooBar)', + ) }) test('.prop modifier w/ dynamic arg', () => { @@ -449,7 +457,9 @@ describe('compiler v-bind', () => { }, }) expect(code).contains('renderEffect') - expect(code).contains('_setDOMProp(n0, "fooBar", _ctx.id)') + expect(code).contains( + '_id !== _ctx.id && _setDOMProp(n0, "fooBar", _id = _ctx.id)', + ) }) test('.prop modifier (shorthand) w/ no expression', () => { @@ -473,55 +483,61 @@ describe('compiler v-bind', () => { }, }) expect(code).contains('renderEffect') - expect(code).contains('_setDOMProp(n0, "fooBar", _ctx.fooBar)') + expect(code).contains( + '_fooBar !== _ctx.fooBar && _setDOMProp(n0, "fooBar", _fooBar = _ctx.fooBar)', + ) }) test('.prop modifier w/ innerHTML', () => { const { code } = compileWithVBind(`
`) expect(code).matchSnapshot() - expect(code).contains('_setHtml(n0, _ctx.foo)') + expect(code).contains('_foo !== _ctx.foo && _setHtml(n0, _foo = _ctx.foo)') }) test('.prop modifier (shorthand) w/ innerHTML', () => { const { code } = compileWithVBind(`
`) expect(code).matchSnapshot() - expect(code).contains('_setHtml(n0, _ctx.foo)') + expect(code).contains('_foo !== _ctx.foo && _setHtml(n0, _foo = _ctx.foo)') }) test('.prop modifier w/ textContent', () => { const { code } = compileWithVBind(`
`) expect(code).matchSnapshot() - expect(code).contains('_setText(n0, _ctx.foo)') + expect(code).contains('_foo !== _ctx.foo && _setText(n0, _foo = _ctx.foo)') }) test('.prop modifier (shorthand) w/ textContent', () => { const { code } = compileWithVBind(`
`) expect(code).matchSnapshot() - expect(code).contains('_setText(n0, _ctx.foo)') + expect(code).contains('_foo !== _ctx.foo && _setText(n0, _foo = _ctx.foo)') }) test('.prop modifier w/ value', () => { const { code } = compileWithVBind(`
`) expect(code).matchSnapshot() - expect(code).contains('_setValue(n0, _ctx.foo)') + expect(code).contains('_foo !== _ctx.foo && _setValue(n0, _foo = _ctx.foo)') }) test('.prop modifier (shorthand) w/ value', () => { const { code } = compileWithVBind(`
`) expect(code).matchSnapshot() - expect(code).contains('_setValue(n0, _ctx.foo)') + expect(code).contains('_foo !== _ctx.foo && _setValue(n0, _foo = _ctx.foo)') }) test('.prop modifier w/ progress value', () => { const { code } = compileWithVBind(``) expect(code).matchSnapshot() - expect(code).contains('_setDOMProp(n0, "value", _ctx.foo)') + expect(code).contains( + '_foo !== _ctx.foo && _setDOMProp(n0, "value", _foo = _ctx.foo)', + ) }) test('.prop modifier (shorthand) w/ progress value', () => { const { code } = compileWithVBind(``) expect(code).matchSnapshot() - expect(code).contains('_setDOMProp(n0, "value", _ctx.foo)') + expect(code).contains( + '_foo !== _ctx.foo && _setDOMProp(n0, "value", _foo = _ctx.foo)', + ) }) test('.attr modifier', () => { @@ -545,7 +561,9 @@ describe('compiler v-bind', () => { }, }) expect(code).contains('renderEffect') - expect(code).contains('_setAttr(n0, "foo-bar", _ctx.id)') + expect(code).contains( + '_id !== _ctx.id && _setAttr(n0, "foo-bar", _id = _ctx.id)', + ) }) test('.attr modifier w/ no expression', () => { @@ -570,31 +588,41 @@ describe('compiler v-bind', () => { }) expect(code).contains('renderEffect') - expect(code).contains('_setAttr(n0, "foo-bar", _ctx.fooBar)') + expect(code).contains( + '_fooBar !== _ctx.fooBar && _setAttr(n0, "foo-bar", _fooBar = _ctx.fooBar)', + ) }) test('.attr modifier w/ innerHTML', () => { const { code } = compileWithVBind(`
`) expect(code).matchSnapshot() - expect(code).contains('_setAttr(n0, "innerHTML", _ctx.foo)') + expect(code).contains( + '_foo !== _ctx.foo && _setAttr(n0, "innerHTML", _foo = _ctx.foo)', + ) }) test('.attr modifier w/ textContent', () => { const { code } = compileWithVBind(`
`) expect(code).matchSnapshot() - expect(code).contains('_setAttr(n0, "textContent", _ctx.foo)') + expect(code).contains( + '_foo !== _ctx.foo && _setAttr(n0, "textContent", _foo = _ctx.foo)', + ) }) test('.attr modifier w/ value', () => { const { code } = compileWithVBind(`
`) expect(code).matchSnapshot() - expect(code).contains('_setAttr(n0, "value", _ctx.foo)') + expect(code).contains( + '_foo !== _ctx.foo && _setAttr(n0, "value", _foo = _ctx.foo)', + ) }) test('.attr modifier w/ progress value', () => { const { code } = compileWithVBind(``) expect(code).matchSnapshot() - expect(code).contains('_setAttr(n0, "value", _ctx.foo)') + expect(code).contains( + '_foo !== _ctx.foo && _setAttr(n0, "value", _foo = _ctx.foo)', + ) }) test('attributes must be set as attribute', () => { @@ -609,20 +637,45 @@ describe('compiler v-bind', () => { `) expect(code).matchSnapshot() - expect(code).contains('_setAttr(n0, "spellcheck", _ctx.spellcheck)') - expect(code).contains('_setAttr(n0, "draggable", _ctx.draggable)') - expect(code).contains('_setAttr(n0, "translate", _ctx.translate)') - expect(code).contains('_setAttr(n0, "form", _ctx.form)') - expect(code).contains('_setAttr(n1, "list", _ctx.list)') - expect(code).contains('_setAttr(n2, "type", _ctx.type)') - expect(code).contains('_setAttr(n3, "width", _ctx.width)') - expect(code).contains('_setAttr(n3, "height", _ctx.height)') - expect(code).contains('_setAttr(n4, "width", _ctx.width)') - expect(code).contains('_setAttr(n4, "height", _ctx.height)') - expect(code).contains('_setAttr(n5, "width", _ctx.width)') - expect(code).contains('_setAttr(n5, "height", _ctx.height)') - expect(code).contains('_setAttr(n6, "width", _ctx.width)') - expect(code).contains('_setAttr(n6, "height", _ctx.height)') + expect(code).contains( + '_spellcheck !== _ctx.spellcheck && _setAttr(n0, "spellcheck", _spellcheck = _ctx.spellcheck)', + ) + expect(code).contains( + '_draggable !== _ctx.draggable && _setAttr(n0, "draggable", _draggable = _ctx.draggable)', + ) + expect(code).contains( + '_translate !== _ctx.translate && _setAttr(n0, "translate", _translate = _ctx.translate)', + ) + expect(code).contains( + '_form !== _ctx.form && _setAttr(n0, "form", _form = _ctx.form)', + ) + expect(code).contains( + '_list !== _ctx.list && _setAttr(n1, "list", _list = _ctx.list)', + ) + expect(code).contains( + '_type !== _ctx.type && _setAttr(n2, "type", _type = _ctx.type)', + ) + expect(code).contains( + '_width !== _ctx.width && _setAttr(n3, "width", _width = _ctx.width)', + ) + expect(code).contains( + '_height !== _ctx.height && _setAttr(n3, "height", _height = _ctx.height)', + ) + expect(code).contains( + '_width !== _ctx.width && _setAttr(n4, "width", _width = _ctx.width)', + ) + expect(code).contains( + '_height !== _ctx.height && _setAttr(n4, "height", _height = _ctx.height)', + ) + expect(code).contains( + '_width !== _ctx.width && _setAttr(n5, "width", _width = _ctx.width)', + ) + expect(code).contains( + '_height !== _ctx.height && _setAttr(n5, "height", _height = _ctx.height)', + ) + expect(code).contains( + '_width !== _ctx.width && _setAttr(n6, "width", _width = _ctx.width)', + ) }) test('HTML global attributes should set as dom prop', () => { @@ -631,11 +684,13 @@ describe('compiler v-bind', () => { `) expect(code).matchSnapshot() - expect(code).contains('_setDOMProp(n0, "id", _ctx.id)') - expect(code).contains('_setDOMProp(n0, "title", _ctx.title)') - expect(code).contains('_setDOMProp(n0, "lang", _ctx.lang)') - expect(code).contains('_setDOMProp(n0, "dir", _ctx.dir)') - expect(code).contains('_setDOMProp(n0, "tabindex", _ctx.tabindex)') + expect(code).contains( + '_id !== _ctx.id && _setDOMProp(n0, "id", _id = _ctx.id)', + ) + // expect(code).contains('_setDOMProp(n0, "title", _ctx.title)') + // expect(code).contains('_setDOMProp(n0, "lang", _ctx.lang)') + // expect(code).contains('_setDOMProp(n0, "dir", _ctx.dir)') + // expect(code).contains('_setDOMProp(n0, "tabindex", _ctx.tabindex)') }) test('SVG global attributes should set as dom prop', () => { @@ -644,9 +699,18 @@ describe('compiler v-bind', () => { `) expect(code).matchSnapshot() - expect(code).contains('_setDOMProp(n0, "id", _ctx.id)') - expect(code).contains('_setDOMProp(n0, "lang", _ctx.lang)') - expect(code).contains('_setDOMProp(n0, "tabindex", _ctx.tabindex)') + expect(code).contains('let _id;') + expect(code).contains( + '_id !== _ctx.id && _setDOMProp(n0, "id", _id = _ctx.id)', + ) + expect(code).contains('let _lang;') + expect(code).contains( + '_lang !== _ctx.lang && _setDOMProp(n0, "lang", _lang = _ctx.lang)', + ) + expect(code).contains('let _tabindex;') + expect(code).contains( + '_tabindex !== _ctx.tabindex && _setDOMProp(n0, "tabindex", _tabindex = _ctx.tabindex)', + ) }) test('MathML global attributes should set as dom prop', () => { @@ -655,11 +719,26 @@ describe('compiler v-bind', () => { `) expect(code).matchSnapshot() - expect(code).contains('_setDOMProp(n0, "autofucus", _ctx.autofucus)') - expect(code).contains('_setDOMProp(n0, "dir", _ctx.dir)') - expect(code).contains('_setDOMProp(n0, "displaystyle", _ctx.displaystyle)') - expect(code).contains('_setDOMProp(n0, "mathcolor", _ctx.mathcolor)') - expect(code).contains('_setDOMProp(n0, "tabindex", _ctx.tabindex)') + expect(code).contains('let _autofucus;') + expect(code).contains( + '_autofucus !== _ctx.autofucus && _setDOMProp(n0, "autofucus", _autofucus = _ctx.autofucus)', + ) + expect(code).contains('let _dir;') + expect(code).contains( + '_dir !== _ctx.dir && _setDOMProp(n0, "dir", _dir = _ctx.dir)', + ) + expect(code).contains('let _displaystyle;') + expect(code).contains( + '_displaystyle !== _ctx.displaystyle && _setDOMProp(n0, "displaystyle", _displaystyle = _ctx.displaystyle)', + ) + expect(code).contains('let _mathcolor;') + expect(code).contains( + '_mathcolor !== _ctx.mathcolor && _setDOMProp(n0, "mathcolor", _mathcolor = _ctx.mathcolor)', + ) + expect(code).contains('let _tabindex;') + expect(code).contains( + '_tabindex !== _ctx.tabindex && _setDOMProp(n0, "tabindex", _tabindex = _ctx.tabindex)', + ) }) test(':innerHTML', () => { @@ -667,7 +746,8 @@ describe('compiler v-bind', () => {
`) expect(code).matchSnapshot() - expect(code).contains('_setHtml(n0, _ctx.foo)') + expect(code).contains('let _foo;') + expect(code).contains('_foo !== _ctx.foo && _setHtml(n0, _foo = _ctx.foo)') }) test(':textContext', () => { @@ -675,7 +755,8 @@ describe('compiler v-bind', () => {
`) expect(code).matchSnapshot() - expect(code).contains('_setText(n0, _ctx.foo)') + expect(code).contains('let _foo;') + expect(code).contains('_foo !== _ctx.foo && _setText(n0, _foo = _ctx.foo)') }) test(':value', () => { @@ -683,7 +764,10 @@ describe('compiler v-bind', () => { `) expect(code).matchSnapshot() - expect(code).contains('_setValue(n0, _ctx.foo)') + expect(code).contains('let _foo;') + expect(code).contains( + ' _foo !== _ctx.foo && _setValue(n0, _foo = _ctx.foo)', + ) }) test(':value w/ progress', () => { diff --git a/packages/compiler-vapor/src/generate.ts b/packages/compiler-vapor/src/generate.ts index 58cae3b88..9ab24071f 100644 --- a/packages/compiler-vapor/src/generate.ts +++ b/packages/compiler-vapor/src/generate.ts @@ -35,6 +35,8 @@ export class CodegenContext { delegates: Set = new Set() + effectVars: Set = new Set() + identifiers: Record = Object.create(null) block: BlockIRNode diff --git a/packages/compiler-vapor/src/generators/expression.ts b/packages/compiler-vapor/src/generators/expression.ts index d13a66412..d6337fa84 100644 --- a/packages/compiler-vapor/src/generators/expression.ts +++ b/packages/compiler-vapor/src/generators/expression.ts @@ -19,6 +19,7 @@ export function genExpression( node: SimpleExpressionNode, context: CodegenContext, assignment?: string, + postGenExpression?: (newName: string, name: string) => string, ): CodeFragment[] { const { prefixIdentifiers } = context.options const { content, ast, isStatic, loc } = node @@ -34,12 +35,28 @@ export function genExpression( ast === false || isConstantExpression(node) ) { - return [[content, NewlineType.None, loc], assignment && ` = ${assignment}`] + return [ + [ + postGenExpression ? postGenExpression(content, content) : content, + NewlineType.None, + loc, + ], + assignment && ` = ${assignment}`, + ] } // the expression is a simple identifier if (ast === null) { - return genIdentifier(content, context, loc, assignment) + return genIdentifier( + content, + context, + loc, + assignment, + undefined, + undefined, + undefined, + postGenExpression, + ) } const ids: Identifier[] = [] @@ -108,7 +125,7 @@ export function genExpression( } } -function genIdentifier( +export function genIdentifier( raw: string, { options, vaporHelper, identifiers }: CodegenContext, loc?: SourceLocation, @@ -116,13 +133,21 @@ function genIdentifier( id?: Identifier, parent?: Node, parentStack?: Node[], + postGenExpression?: (newName: string, name: string) => string, ): CodeFragment[] { const { inline, bindingMetadata } = options let name: string | undefined = raw const idMap = identifiers[raw] if (idMap && idMap.length) { - return [[idMap[0], NewlineType.None, loc]] + name = idMap[0] + return [ + [ + postGenExpression ? postGenExpression(name, name) : name, + NewlineType.None, + loc, + ], + ] } let prefix: string | undefined @@ -177,7 +202,15 @@ function genIdentifier( } raw = withAssignment(raw) } - return [prefix, [raw, NewlineType.None, loc, name]] + return [ + prefix, + [ + postGenExpression ? postGenExpression(raw, name) : raw, + NewlineType.None, + loc, + name, + ], + ] function withAssignment(s: string) { return assignment ? `${s} = ${assignment}` : s diff --git a/packages/compiler-vapor/src/generators/operation.ts b/packages/compiler-vapor/src/generators/operation.ts index b637e797a..94ef0e88d 100644 --- a/packages/compiler-vapor/src/generators/operation.ts +++ b/packages/compiler-vapor/src/generators/operation.ts @@ -89,15 +89,20 @@ export function genEffect( { operations }: IREffect, context: CodegenContext, ): CodeFragment[] { - const { vaporHelper } = context + const { vaporHelper, effectVars } = context const [frag, push] = buildCodeFragment( NEWLINE, `${vaporHelper('renderEffect')}(() => `, ) - const [operationsExps, pushOps] = buildCodeFragment() operations.forEach(op => pushOps(...genOperation(op, context))) + if (effectVars.size) { + const vars = [...effectVars].map(v => `_${v}`) + frag.splice(1, 0, `let ${vars.join(', ')};`, NEWLINE) + effectVars.clear() + } + const newlineCount = operationsExps.filter(frag => frag === NEWLINE).length if (newlineCount > 1) { push('{', INDENT_START, ...operationsExps, INDENT_END, NEWLINE, '})') diff --git a/packages/compiler-vapor/src/generators/prop.ts b/packages/compiler-vapor/src/generators/prop.ts index e30d4c7ed..4a32f097b 100644 --- a/packages/compiler-vapor/src/generators/prop.ts +++ b/packages/compiler-vapor/src/generators/prop.ts @@ -39,20 +39,28 @@ export function genSetProp( oper: SetPropIRNode, context: CodegenContext, ): CodeFragment[] { - const { vaporHelper } = context + const { vaporHelper, effectVars, block } = context const { prop: { key, values, modifier }, tag, } = oper + const inEffect = block.effect.length const { helperName, omitKey } = getRuntimeHelper(tag, key.content, modifier) + let newPropName, propName + const propValue = genPropValue(values, context, (newName, name) => { + if (helperName === 'setDynamicProp' || !inEffect) return newName + effectVars.add(name) + return `_${(propName = name)} = ${(newPropName = newName)}` + }) return [ NEWLINE, + newPropName ? `_${propName} !== ${newPropName} && ` : undefined, ...genCall( [vaporHelper(helperName), null], `n${oper.element}`, omitKey ? false : genExpression(key, context), - genPropValue(values, context), + propValue, // only `setClass` and `setStyle` need merge inherit attr oper.root && (helperName === 'setClass' || helperName === 'setStyle') ? 'true' @@ -134,9 +142,10 @@ export function genPropKey( export function genPropValue( values: SimpleExpressionNode[], context: CodegenContext, + postGenPropValue?: (newName: string, name: string) => string, ): CodeFragment[] { if (values.length === 1) { - return genExpression(values[0], context) + return genExpression(values[0], context, undefined, postGenPropValue) } return genMulti( DELIMITERS_ARRAY, From d83072bd237891389524e15a9c617ef3cf87a7fa Mon Sep 17 00:00:00 2001 From: daiwei Date: Mon, 2 Dec 2024 18:03:45 +0800 Subject: [PATCH 02/47] wip: save --- .../compiler-vapor/src/generators/expression.ts | 14 +++----------- 1 file changed, 3 insertions(+), 11 deletions(-) diff --git a/packages/compiler-vapor/src/generators/expression.ts b/packages/compiler-vapor/src/generators/expression.ts index d6337fa84..45d7e0702 100644 --- a/packages/compiler-vapor/src/generators/expression.ts +++ b/packages/compiler-vapor/src/generators/expression.ts @@ -47,16 +47,7 @@ export function genExpression( // the expression is a simple identifier if (ast === null) { - return genIdentifier( - content, - context, - loc, - assignment, - undefined, - undefined, - undefined, - postGenExpression, - ) + return genIdentifier(content, context, loc, assignment, postGenExpression) } const ids: Identifier[] = [] @@ -105,6 +96,7 @@ export function genExpression( source, }, hasMemberExpression ? undefined : assignment, + undefined, id, parent, parentStack, @@ -130,10 +122,10 @@ export function genIdentifier( { options, vaporHelper, identifiers }: CodegenContext, loc?: SourceLocation, assignment?: string, + postGenExpression?: (newName: string, name: string) => string, id?: Identifier, parent?: Node, parentStack?: Node[], - postGenExpression?: (newName: string, name: string) => string, ): CodeFragment[] { const { inline, bindingMetadata } = options let name: string | undefined = raw From 66a9a1114b65b26b8c13e7edd15263b8a22fe05d Mon Sep 17 00:00:00 2001 From: daiwei Date: Mon, 2 Dec 2024 20:51:38 +0800 Subject: [PATCH 03/47] wip: save --- .../__snapshots__/compile.spec.ts.snap | 6 ++-- .../transformChildren.spec.ts.snap | 6 ++-- .../__snapshots__/vHtml.spec.ts.snap | 6 ++-- .../transforms/__snapshots__/vIf.spec.ts.snap | 9 +++-- .../__snapshots__/vText.spec.ts.snap | 6 ++-- packages/compiler-vapor/src/generate.ts | 3 +- .../src/generators/expression.ts | 36 +++++-------------- .../compiler-vapor/src/generators/html.ts | 21 +++++++---- .../src/generators/operation.ts | 12 ++++--- .../compiler-vapor/src/generators/prop.ts | 19 ++++++---- .../compiler-vapor/src/generators/text.ts | 23 ++++++++---- 11 files changed, 84 insertions(+), 63 deletions(-) diff --git a/packages/compiler-vapor/__tests__/__snapshots__/compile.spec.ts.snap b/packages/compiler-vapor/__tests__/__snapshots__/compile.spec.ts.snap index ae9241b99..6d5d4d8fd 100644 --- a/packages/compiler-vapor/__tests__/__snapshots__/compile.spec.ts.snap +++ b/packages/compiler-vapor/__tests__/__snapshots__/compile.spec.ts.snap @@ -6,7 +6,8 @@ const t0 = _template("
") export function render(_ctx, $props, $emit, $attrs, $slots) { const n0 = t0() - _renderEffect(() => _setText(n0, "count is ", _ctx.count, ".")) + let _count; + _renderEffect(() => _count !== _ctx.count && _setText(n0, "count is ", _count = _ctx.count, ".")) return n0 }" `; @@ -186,7 +187,8 @@ export function render(_ctx) { const n0 = t0() _delegate(n0, "click", () => _ctx.handleClick) _setInheritAttrs(["id"]) - _renderEffect(() => _setText(n0, _ctx.count, "foo", _ctx.count, "foo", _ctx.count)) + let _count; + _renderEffect(() => _count !== _ctx.count && _setText(n0, _count = _ctx.count, "foo", _count = _ctx.count, "foo", _count = _ctx.count)) let _count; _renderEffect(() => _count !== _ctx.count && _setDOMProp(n0, "id", _count = _ctx.count)) return n0 diff --git a/packages/compiler-vapor/__tests__/transforms/__snapshots__/transformChildren.spec.ts.snap b/packages/compiler-vapor/__tests__/transforms/__snapshots__/transformChildren.spec.ts.snap index 951a534ec..e00125eaf 100644 --- a/packages/compiler-vapor/__tests__/transforms/__snapshots__/transformChildren.spec.ts.snap +++ b/packages/compiler-vapor/__tests__/transforms/__snapshots__/transformChildren.spec.ts.snap @@ -11,8 +11,10 @@ export function render(_ctx) { const n2 = n3.nextSibling const n1 = _createTextNode(() => [_ctx.second, " ", _ctx.third, " "]) _insert(n1, n4, n3) - _renderEffect(() => _setText(n0, _ctx.first)) - _renderEffect(() => _setText(n2, _ctx.forth)) + let _first; + _renderEffect(() => _first !== _ctx.first && _setText(n0, _first = _ctx.first)) + let _forth; + _renderEffect(() => _forth !== _ctx.forth && _setText(n2, _forth = _ctx.forth)) return n4 }" `; diff --git a/packages/compiler-vapor/__tests__/transforms/__snapshots__/vHtml.spec.ts.snap b/packages/compiler-vapor/__tests__/transforms/__snapshots__/vHtml.spec.ts.snap index a5ee792e2..ea3260d3c 100644 --- a/packages/compiler-vapor/__tests__/transforms/__snapshots__/vHtml.spec.ts.snap +++ b/packages/compiler-vapor/__tests__/transforms/__snapshots__/vHtml.spec.ts.snap @@ -6,7 +6,8 @@ const t0 = _template("
") export function render(_ctx, $props, $emit, $attrs, $slots) { const n0 = t0() - _renderEffect(() => _setHtml(n0, _ctx.code)) + let _code; + _renderEffect(() => _code !== _ctx.code && _setHtml(n0, _code = _ctx.code)) return n0 }" `; @@ -17,7 +18,8 @@ const t0 = _template("
") export function render(_ctx) { const n0 = t0() - _renderEffect(() => _setHtml(n0, _ctx.test)) + let _test; + _renderEffect(() => _test !== _ctx.test && _setHtml(n0, _test = _ctx.test)) return n0 }" `; diff --git a/packages/compiler-vapor/__tests__/transforms/__snapshots__/vIf.spec.ts.snap b/packages/compiler-vapor/__tests__/transforms/__snapshots__/vIf.spec.ts.snap index 3d92452a1..f4c72c4a8 100644 --- a/packages/compiler-vapor/__tests__/transforms/__snapshots__/vIf.spec.ts.snap +++ b/packages/compiler-vapor/__tests__/transforms/__snapshots__/vIf.spec.ts.snap @@ -7,7 +7,8 @@ const t0 = _template("
") export function render(_ctx) { const n0 = _createIf(() => (_ctx.ok), () => { const n2 = t0() - _renderEffect(() => _setText(n2, _ctx.msg)) + let _msg; + _renderEffect(() => _msg !== _ctx.msg && _setText(n2, _msg = _ctx.msg)) return n2 }) return n0 @@ -37,7 +38,8 @@ export function render(_ctx) { const n11 = t4() return [n10, n11] })) - _renderEffect(() => _setText(n13, _ctx.text)) + let _text; + _renderEffect(() => _text !== _ctx.text && _setText(n13, _text = _ctx.text)) return [n0, n13] }" `; @@ -70,7 +72,8 @@ export function render(_ctx) { const n2 = t0() const n3 = t1() const n4 = t2() - _renderEffect(() => _setText(n4, _ctx.msg)) + let _msg; + _renderEffect(() => _msg !== _ctx.msg && _setText(n4, _msg = _ctx.msg)) return [n2, n3, n4] }) return n0 diff --git a/packages/compiler-vapor/__tests__/transforms/__snapshots__/vText.spec.ts.snap b/packages/compiler-vapor/__tests__/transforms/__snapshots__/vText.spec.ts.snap index 622966ba8..90d3625d3 100644 --- a/packages/compiler-vapor/__tests__/transforms/__snapshots__/vText.spec.ts.snap +++ b/packages/compiler-vapor/__tests__/transforms/__snapshots__/vText.spec.ts.snap @@ -6,7 +6,8 @@ const t0 = _template("
") export function render(_ctx, $props, $emit, $attrs, $slots) { const n0 = t0() - _renderEffect(() => _setText(n0, _ctx.str)) + let _str; + _renderEffect(() => _str !== _ctx.str && _setText(n0, _str = _ctx.str)) return n0 }" `; @@ -17,7 +18,8 @@ const t0 = _template("
") export function render(_ctx) { const n0 = t0() - _renderEffect(() => _setText(n0, _ctx.test)) + let _test; + _renderEffect(() => _test !== _ctx.test && _setText(n0, _test = _ctx.test)) return n0 }" `; diff --git a/packages/compiler-vapor/src/generate.ts b/packages/compiler-vapor/src/generate.ts index 9ab24071f..34df7f4e9 100644 --- a/packages/compiler-vapor/src/generate.ts +++ b/packages/compiler-vapor/src/generate.ts @@ -35,7 +35,8 @@ export class CodegenContext { delegates: Set = new Set() - effectVars: Set = new Set() + renderEffectIndex: number = 0 + renderEffectDeps: Set = new Set() identifiers: Record = Object.create(null) diff --git a/packages/compiler-vapor/src/generators/expression.ts b/packages/compiler-vapor/src/generators/expression.ts index 45d7e0702..f348279e8 100644 --- a/packages/compiler-vapor/src/generators/expression.ts +++ b/packages/compiler-vapor/src/generators/expression.ts @@ -19,7 +19,7 @@ export function genExpression( node: SimpleExpressionNode, context: CodegenContext, assignment?: string, - postGenExpression?: (newName: string, name: string) => string, + onIdentifierRewrite?: (newName: string, name: string) => string, ): CodeFragment[] { const { prefixIdentifiers } = context.options const { content, ast, isStatic, loc } = node @@ -35,19 +35,12 @@ export function genExpression( ast === false || isConstantExpression(node) ) { - return [ - [ - postGenExpression ? postGenExpression(content, content) : content, - NewlineType.None, - loc, - ], - assignment && ` = ${assignment}`, - ] + return [[content, NewlineType.None, loc], assignment && ` = ${assignment}`] } // the expression is a simple identifier if (ast === null) { - return genIdentifier(content, context, loc, assignment, postGenExpression) + return genIdentifier(content, context, loc, assignment, onIdentifierRewrite) } const ids: Identifier[] = [] @@ -122,7 +115,7 @@ export function genIdentifier( { options, vaporHelper, identifiers }: CodegenContext, loc?: SourceLocation, assignment?: string, - postGenExpression?: (newName: string, name: string) => string, + onIdentifierRewrite?: (newName: string, name: string) => string, id?: Identifier, parent?: Node, parentStack?: Node[], @@ -133,13 +126,7 @@ export function genIdentifier( const idMap = identifiers[raw] if (idMap && idMap.length) { name = idMap[0] - return [ - [ - postGenExpression ? postGenExpression(name, name) : name, - NewlineType.None, - loc, - ], - ] + return [[name, NewlineType.None, loc]] } let prefix: string | undefined @@ -191,18 +178,13 @@ export function genIdentifier( } else { raw = `${type === BindingTypes.PROPS ? '$props' : '_ctx'}.${raw}` } + if (onIdentifierRewrite) { + raw = onIdentifierRewrite(raw, name) + } } raw = withAssignment(raw) } - return [ - prefix, - [ - postGenExpression ? postGenExpression(raw, name) : raw, - NewlineType.None, - loc, - name, - ], - ] + return [prefix, [raw, NewlineType.None, loc, name]] function withAssignment(s: string) { return assignment ? `${s} = ${assignment}` : s diff --git a/packages/compiler-vapor/src/generators/html.ts b/packages/compiler-vapor/src/generators/html.ts index 1b129375a..6d3923432 100644 --- a/packages/compiler-vapor/src/generators/html.ts +++ b/packages/compiler-vapor/src/generators/html.ts @@ -7,13 +7,22 @@ export function genSetHtml( oper: SetHtmlIRNode, context: CodegenContext, ): CodeFragment[] { - const { vaporHelper } = context + const { vaporHelper, renderEffectDeps, block } = context + const inEffect = block.effect.length + let newPropName, propName + function onIdRewrite(newName: string, name: string) { + renderEffectDeps.add(name) + return `_${(propName = name)} = ${(newPropName = newName)}` + } + const html = genExpression( + oper.value, + context, + undefined, + inEffect ? onIdRewrite : undefined, + ) return [ NEWLINE, - ...genCall( - vaporHelper('setHtml'), - `n${oper.element}`, - genExpression(oper.value, context), - ), + newPropName ? `_${propName} !== ${newPropName} && ` : undefined, + ...genCall(vaporHelper('setHtml'), `n${oper.element}`, html), ] } diff --git a/packages/compiler-vapor/src/generators/operation.ts b/packages/compiler-vapor/src/generators/operation.ts index 94ef0e88d..359ccd3d9 100644 --- a/packages/compiler-vapor/src/generators/operation.ts +++ b/packages/compiler-vapor/src/generators/operation.ts @@ -79,7 +79,9 @@ export function genEffects( context: CodegenContext, ): CodeFragment[] { const [frag, push] = buildCodeFragment() - for (const effect of effects) { + for (let i = 0; i < effects.length; i++) { + const effect = effects[i] + context.renderEffectIndex = i push(...genEffect(effect, context)) } return frag @@ -89,7 +91,7 @@ export function genEffect( { operations }: IREffect, context: CodegenContext, ): CodeFragment[] { - const { vaporHelper, effectVars } = context + const { vaporHelper, renderEffectDeps } = context const [frag, push] = buildCodeFragment( NEWLINE, `${vaporHelper('renderEffect')}(() => `, @@ -97,10 +99,10 @@ export function genEffect( const [operationsExps, pushOps] = buildCodeFragment() operations.forEach(op => pushOps(...genOperation(op, context))) - if (effectVars.size) { - const vars = [...effectVars].map(v => `_${v}`) + if (renderEffectDeps.size) { + const vars = [...renderEffectDeps].map(v => `_${v}`) frag.splice(1, 0, `let ${vars.join(', ')};`, NEWLINE) - effectVars.clear() + renderEffectDeps.clear() } const newlineCount = operationsExps.filter(frag => frag === NEWLINE).length diff --git a/packages/compiler-vapor/src/generators/prop.ts b/packages/compiler-vapor/src/generators/prop.ts index 4a32f097b..d067d16e1 100644 --- a/packages/compiler-vapor/src/generators/prop.ts +++ b/packages/compiler-vapor/src/generators/prop.ts @@ -39,7 +39,7 @@ export function genSetProp( oper: SetPropIRNode, context: CodegenContext, ): CodeFragment[] { - const { vaporHelper, effectVars, block } = context + const { vaporHelper, renderEffectDeps, block } = context const { prop: { key, values, modifier }, tag, @@ -48,11 +48,16 @@ export function genSetProp( const inEffect = block.effect.length const { helperName, omitKey } = getRuntimeHelper(tag, key.content, modifier) let newPropName, propName - const propValue = genPropValue(values, context, (newName, name) => { - if (helperName === 'setDynamicProp' || !inEffect) return newName - effectVars.add(name) + function onIdRewrite(newName: string, name: string) { + // if(renderEffectIndex!==0) name = `${name}${renderEffectIndex}` + renderEffectDeps.add(name) return `_${(propName = name)} = ${(newPropName = newName)}` - }) + } + const propValue = genPropValue( + values, + context, + inEffect && helperName !== 'setDynamicProp' ? onIdRewrite : undefined, + ) return [ NEWLINE, newPropName ? `_${propName} !== ${newPropName} && ` : undefined, @@ -142,10 +147,10 @@ export function genPropKey( export function genPropValue( values: SimpleExpressionNode[], context: CodegenContext, - postGenPropValue?: (newName: string, name: string) => string, + onIdentifierRewrite?: (newName: string, name: string) => string, ): CodeFragment[] { if (values.length === 1) { - return genExpression(values[0], context, undefined, postGenPropValue) + return genExpression(values[0], context, undefined, onIdentifierRewrite) } return genMulti( DELIMITERS_ARRAY, diff --git a/packages/compiler-vapor/src/generators/text.ts b/packages/compiler-vapor/src/generators/text.ts index e433bb977..24c556b18 100644 --- a/packages/compiler-vapor/src/generators/text.ts +++ b/packages/compiler-vapor/src/generators/text.ts @@ -13,15 +13,26 @@ export function genSetText( oper: SetTextIRNode, context: CodegenContext, ): CodeFragment[] { - const { vaporHelper } = context + const { vaporHelper, renderEffectDeps, block } = context const { element, values } = oper + const inEffect = block.effect.length + let newPropName, propName + function onIdRewrite(newName: string, name: string) { + renderEffectDeps.add(name) + return `_${(propName = name)} = ${(newPropName = newName)}` + } + const texts = values.map(value => + genExpression( + value, + context, + undefined, + inEffect ? onIdRewrite : undefined, + ), + ) return [ NEWLINE, - ...genCall( - vaporHelper('setText'), - `n${element}`, - ...values.map(value => genExpression(value, context)), - ), + newPropName ? `_${propName} !== ${newPropName} && ` : undefined, + ...genCall(vaporHelper('setText'), `n${element}`, ...texts), ] } From 18dbaede8c3b4fda9d9355ea49d12e6987c722aa Mon Sep 17 00:00:00 2001 From: daiwei Date: Mon, 2 Dec 2024 21:55:16 +0800 Subject: [PATCH 04/47] wip: save --- .../__snapshots__/compile.spec.ts.snap | 6 +- .../__snapshots__/vBind.spec.ts.snap | 18 +++--- .../__tests__/transforms/vBind.spec.ts | 28 +++------- .../compiler-vapor/src/generators/html.ts | 23 ++------ .../src/generators/operation.ts | 56 +++++++++++++++---- .../compiler-vapor/src/generators/prop.ts | 13 +---- .../compiler-vapor/src/generators/text.ts | 18 ++---- 7 files changed, 76 insertions(+), 86 deletions(-) diff --git a/packages/compiler-vapor/__tests__/__snapshots__/compile.spec.ts.snap b/packages/compiler-vapor/__tests__/__snapshots__/compile.spec.ts.snap index 6d5d4d8fd..ae9241b99 100644 --- a/packages/compiler-vapor/__tests__/__snapshots__/compile.spec.ts.snap +++ b/packages/compiler-vapor/__tests__/__snapshots__/compile.spec.ts.snap @@ -6,8 +6,7 @@ const t0 = _template("
") export function render(_ctx, $props, $emit, $attrs, $slots) { const n0 = t0() - let _count; - _renderEffect(() => _count !== _ctx.count && _setText(n0, "count is ", _count = _ctx.count, ".")) + _renderEffect(() => _setText(n0, "count is ", _ctx.count, ".")) return n0 }" `; @@ -187,8 +186,7 @@ export function render(_ctx) { const n0 = t0() _delegate(n0, "click", () => _ctx.handleClick) _setInheritAttrs(["id"]) - let _count; - _renderEffect(() => _count !== _ctx.count && _setText(n0, _count = _ctx.count, "foo", _count = _ctx.count, "foo", _count = _ctx.count)) + _renderEffect(() => _setText(n0, _ctx.count, "foo", _ctx.count, "foo", _ctx.count)) let _count; _renderEffect(() => _count !== _ctx.count && _setDOMProp(n0, "id", _count = _ctx.count)) return n0 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 7df887382..49c193dd1 100644 --- a/packages/compiler-vapor/__tests__/transforms/__snapshots__/vBind.spec.ts.snap +++ b/packages/compiler-vapor/__tests__/transforms/__snapshots__/vBind.spec.ts.snap @@ -425,17 +425,19 @@ export function render(_ctx) { _renderEffect(() => _type !== _ctx.type && _setAttr(n2, "type", _type = _ctx.type)) let _width; _renderEffect(() => { - _width !== _ctx.width && _setAttr(n3, "width", _width = _ctx.width) - _width !== _ctx.width && _setAttr(n4, "width", _width = _ctx.width) - _width !== _ctx.width && _setAttr(n5, "width", _width = _ctx.width) - _width !== _ctx.width && _setAttr(n6, "width", _width = _ctx.width) + if(_width === _ctx.width) return + _setAttr(n3, "width", _width = _ctx.width) + _setAttr(n4, "width", _ctx.width) + _setAttr(n5, "width", _ctx.width) + _setAttr(n6, "width", _ctx.width) }) let _height; _renderEffect(() => { - _height !== _ctx.height && _setAttr(n3, "height", _height = _ctx.height) - _height !== _ctx.height && _setAttr(n4, "height", _height = _ctx.height) - _height !== _ctx.height && _setAttr(n5, "height", _height = _ctx.height) - _height !== _ctx.height && _setAttr(n6, "height", _height = _ctx.height) + if(_height === _ctx.height) return + _setAttr(n3, "height", _height = _ctx.height) + _setAttr(n4, "height", _ctx.height) + _setAttr(n5, "height", _ctx.height) + _setAttr(n6, "height", _ctx.height) }) return [n0, n1, n2, n3, n4, n5, n6] }" diff --git a/packages/compiler-vapor/__tests__/transforms/vBind.spec.ts b/packages/compiler-vapor/__tests__/transforms/vBind.spec.ts index 6e5700f8e..a0523e73c 100644 --- a/packages/compiler-vapor/__tests__/transforms/vBind.spec.ts +++ b/packages/compiler-vapor/__tests__/transforms/vBind.spec.ts @@ -655,27 +655,13 @@ describe('compiler v-bind', () => { expect(code).contains( '_type !== _ctx.type && _setAttr(n2, "type", _type = _ctx.type)', ) - expect(code).contains( - '_width !== _ctx.width && _setAttr(n3, "width", _width = _ctx.width)', - ) - expect(code).contains( - '_height !== _ctx.height && _setAttr(n3, "height", _height = _ctx.height)', - ) - expect(code).contains( - '_width !== _ctx.width && _setAttr(n4, "width", _width = _ctx.width)', - ) - expect(code).contains( - '_height !== _ctx.height && _setAttr(n4, "height", _height = _ctx.height)', - ) - expect(code).contains( - '_width !== _ctx.width && _setAttr(n5, "width", _width = _ctx.width)', - ) - expect(code).contains( - '_height !== _ctx.height && _setAttr(n5, "height", _height = _ctx.height)', - ) - expect(code).contains( - '_width !== _ctx.width && _setAttr(n6, "width", _width = _ctx.width)', - ) + expect(code).contains('_setAttr(n3, "width", _width = _ctx.width)') + expect(code).contains('_setAttr(n3, "height", _height = _ctx.height)') + expect(code).contains('_setAttr(n4, "width", _ctx.width)') + expect(code).contains('_setAttr(n4, "height", _ctx.height)') + expect(code).contains('_setAttr(n5, "width", _ctx.width)') + expect(code).contains('_setAttr(n5, "height", _ctx.height)') + expect(code).contains(' _setAttr(n6, "width", _ctx.width)') }) test('HTML global attributes should set as dom prop', () => { diff --git a/packages/compiler-vapor/src/generators/html.ts b/packages/compiler-vapor/src/generators/html.ts index 6d3923432..cac8c0914 100644 --- a/packages/compiler-vapor/src/generators/html.ts +++ b/packages/compiler-vapor/src/generators/html.ts @@ -6,23 +6,10 @@ import { type CodeFragment, NEWLINE, genCall } from './utils' export function genSetHtml( oper: SetHtmlIRNode, context: CodegenContext, + onIdRewrite?: (newName: string, name: string) => string, ): CodeFragment[] { - const { vaporHelper, renderEffectDeps, block } = context - const inEffect = block.effect.length - let newPropName, propName - function onIdRewrite(newName: string, name: string) { - renderEffectDeps.add(name) - return `_${(propName = name)} = ${(newPropName = newName)}` - } - const html = genExpression( - oper.value, - context, - undefined, - inEffect ? onIdRewrite : undefined, - ) - return [ - NEWLINE, - newPropName ? `_${propName} !== ${newPropName} && ` : undefined, - ...genCall(vaporHelper('setHtml'), `n${oper.element}`, html), - ] + const { vaporHelper } = context + + const html = genExpression(oper.value, context, undefined, onIdRewrite) + return [NEWLINE, ...genCall(vaporHelper('setHtml'), `n${oper.element}`, html)] } diff --git a/packages/compiler-vapor/src/generators/operation.ts b/packages/compiler-vapor/src/generators/operation.ts index 359ccd3d9..c04791f26 100644 --- a/packages/compiler-vapor/src/generators/operation.ts +++ b/packages/compiler-vapor/src/generators/operation.ts @@ -22,10 +22,11 @@ import { genSlotOutlet } from './slotOutlet' export function genOperations( opers: OperationNode[], context: CodegenContext, + onIdRewrite?: (newName: string, name: string) => string, ): CodeFragment[] { const [frag, push] = buildCodeFragment() for (const operation of opers) { - push(...genOperation(operation, context)) + push(...genOperation(operation, context, onIdRewrite)) } return frag } @@ -33,20 +34,21 @@ export function genOperations( export function genOperation( oper: OperationNode, context: CodegenContext, + onIdRewrite?: (newName: string, name: string) => string, ): CodeFragment[] { switch (oper.type) { case IRNodeTypes.SET_PROP: - return genSetProp(oper, context) + return genSetProp(oper, context, onIdRewrite) case IRNodeTypes.SET_DYNAMIC_PROPS: return genDynamicProps(oper, context) case IRNodeTypes.SET_TEXT: - return genSetText(oper, context) + return genSetText(oper, context, onIdRewrite) case IRNodeTypes.SET_EVENT: return genSetEvent(oper, context) case IRNodeTypes.SET_DYNAMIC_EVENTS: return genSetDynamicEvents(oper, context) case IRNodeTypes.SET_HTML: - return genSetHtml(oper, context) + return genSetHtml(oper, context, onIdRewrite) case IRNodeTypes.SET_TEMPLATE_REF: return genSetTemplateRef(oper, context) case IRNodeTypes.SET_MODEL_VALUE: @@ -87,29 +89,59 @@ export function genEffects( return frag } +// TODO multiple effect with same deps name +const seenNames: Record = {} + export function genEffect( { operations }: IREffect, context: CodegenContext, ): CodeFragment[] { - const { vaporHelper, renderEffectDeps } = context + const { vaporHelper } = context const [frag, push] = buildCodeFragment( NEWLINE, `${vaporHelper('renderEffect')}(() => `, ) - const [operationsExps, pushOps] = buildCodeFragment() - operations.forEach(op => pushOps(...genOperation(op, context))) - if (renderEffectDeps.size) { - const vars = [...renderEffectDeps].map(v => `_${v}`) + let renderEffectDeps: string[] = [] + let newIdName, idName + function onIdRewrite(newName: string, name: string) { + if (!seenNames[name]) { + seenNames[name] = 0 + } + seenNames[name]++ + renderEffectDeps.push(name) + return renderEffectDeps.length === 1 + ? `_${(idName = name)} = ${(newIdName = newName)}` + : newName + } + const operationsExps = genOperations(operations, context, onIdRewrite) + + if (renderEffectDeps.length) { + const vars = [...new Set(renderEffectDeps)].map(v => `_${v}`) frag.splice(1, 0, `let ${vars.join(', ')};`, NEWLINE) - renderEffectDeps.clear() + renderEffectDeps = [] } const newlineCount = operationsExps.filter(frag => frag === NEWLINE).length if (newlineCount > 1) { - push('{', INDENT_START, ...operationsExps, INDENT_END, NEWLINE, '})') + const condition: CodeFragment[] = newIdName + ? [NEWLINE, `if(_${idName} === ${newIdName}) return`] + : [undefined] + push( + '{', + INDENT_START, + ...condition, + ...operationsExps, + INDENT_END, + NEWLINE, + '})', + ) } else { - push(...operationsExps.filter(frag => frag !== NEWLINE), ')') + push( + newIdName ? `_${idName} !== ${newIdName} && ` : undefined, + ...operationsExps.filter(frag => frag !== NEWLINE), + ')', + ) } return frag diff --git a/packages/compiler-vapor/src/generators/prop.ts b/packages/compiler-vapor/src/generators/prop.ts index d067d16e1..d97b887c0 100644 --- a/packages/compiler-vapor/src/generators/prop.ts +++ b/packages/compiler-vapor/src/generators/prop.ts @@ -38,29 +38,22 @@ import { export function genSetProp( oper: SetPropIRNode, context: CodegenContext, + onIdRewrite?: (newName: string, name: string) => string, ): CodeFragment[] { - const { vaporHelper, renderEffectDeps, block } = context + const { vaporHelper } = context const { prop: { key, values, modifier }, tag, } = oper - const inEffect = block.effect.length const { helperName, omitKey } = getRuntimeHelper(tag, key.content, modifier) - let newPropName, propName - function onIdRewrite(newName: string, name: string) { - // if(renderEffectIndex!==0) name = `${name}${renderEffectIndex}` - renderEffectDeps.add(name) - return `_${(propName = name)} = ${(newPropName = newName)}` - } const propValue = genPropValue( values, context, - inEffect && helperName !== 'setDynamicProp' ? onIdRewrite : undefined, + helperName !== 'setDynamicProp' ? onIdRewrite : undefined, ) return [ NEWLINE, - newPropName ? `_${propName} !== ${newPropName} && ` : undefined, ...genCall( [vaporHelper(helperName), null], `n${oper.element}`, diff --git a/packages/compiler-vapor/src/generators/text.ts b/packages/compiler-vapor/src/generators/text.ts index 24c556b18..6d77b4b28 100644 --- a/packages/compiler-vapor/src/generators/text.ts +++ b/packages/compiler-vapor/src/generators/text.ts @@ -12,28 +12,20 @@ import { export function genSetText( oper: SetTextIRNode, context: CodegenContext, + onIdRewrite?: (newName: string, name: string) => string, ): CodeFragment[] { - const { vaporHelper, renderEffectDeps, block } = context + const { vaporHelper } = context const { element, values } = oper - const inEffect = block.effect.length - let newPropName, propName - function onIdRewrite(newName: string, name: string) { - renderEffectDeps.add(name) - return `_${(propName = name)} = ${(newPropName = newName)}` - } const texts = values.map(value => genExpression( value, context, undefined, - inEffect ? onIdRewrite : undefined, + // TODO values.length > 1 + values.length === 1 ? onIdRewrite : undefined, ), ) - return [ - NEWLINE, - newPropName ? `_${propName} !== ${newPropName} && ` : undefined, - ...genCall(vaporHelper('setText'), `n${element}`, ...texts), - ] + return [NEWLINE, ...genCall(vaporHelper('setText'), `n${element}`, ...texts)] } export function genCreateTextNode( From eac343438a1ad137965865ff898ab4ce74fd24b2 Mon Sep 17 00:00:00 2001 From: daiwei Date: Mon, 2 Dec 2024 22:13:40 +0800 Subject: [PATCH 05/47] wip: save --- packages/compiler-vapor/src/generate.ts | 3 --- packages/compiler-vapor/src/generators/operation.ts | 1 - packages/runtime-vapor/src/dom/prop.ts | 3 ++- 3 files changed, 2 insertions(+), 5 deletions(-) diff --git a/packages/compiler-vapor/src/generate.ts b/packages/compiler-vapor/src/generate.ts index 34df7f4e9..58cae3b88 100644 --- a/packages/compiler-vapor/src/generate.ts +++ b/packages/compiler-vapor/src/generate.ts @@ -35,9 +35,6 @@ export class CodegenContext { delegates: Set = new Set() - renderEffectIndex: number = 0 - renderEffectDeps: Set = new Set() - identifiers: Record = Object.create(null) block: BlockIRNode diff --git a/packages/compiler-vapor/src/generators/operation.ts b/packages/compiler-vapor/src/generators/operation.ts index c04791f26..dfd85d1a9 100644 --- a/packages/compiler-vapor/src/generators/operation.ts +++ b/packages/compiler-vapor/src/generators/operation.ts @@ -83,7 +83,6 @@ export function genEffects( const [frag, push] = buildCodeFragment() for (let i = 0; i < effects.length; i++) { const effect = effects[i] - context.renderEffectIndex = i push(...genEffect(effect, context)) } return frag diff --git a/packages/runtime-vapor/src/dom/prop.ts b/packages/runtime-vapor/src/dom/prop.ts index bd6ce1f12..2481d02b7 100644 --- a/packages/runtime-vapor/src/dom/prop.ts +++ b/packages/runtime-vapor/src/dom/prop.ts @@ -212,12 +212,13 @@ export function mergeProps(...args: Data[]): Data { return ret } -export function setText(el: Node, ...values: any[]): void { +export function setText(el: Node, ...values: any[]): string { const text = values.map(v => toDisplayString(v)).join('') const oldVal = recordPropMetadata(el, 'textContent', text) if (text !== oldVal) { el.textContent = text } + return text } export function setHtml(el: Element, value: any): void { From f87a44ed1fee986c1d037f93b5d920ade2a38c2e Mon Sep 17 00:00:00 2001 From: daiwei Date: Mon, 2 Dec 2024 22:15:45 +0800 Subject: [PATCH 06/47] wip: save --- packages/compiler-vapor/src/generators/expression.ts | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/packages/compiler-vapor/src/generators/expression.ts b/packages/compiler-vapor/src/generators/expression.ts index f348279e8..48d39d2a4 100644 --- a/packages/compiler-vapor/src/generators/expression.ts +++ b/packages/compiler-vapor/src/generators/expression.ts @@ -110,7 +110,7 @@ export function genExpression( } } -export function genIdentifier( +function genIdentifier( raw: string, { options, vaporHelper, identifiers }: CodegenContext, loc?: SourceLocation, @@ -125,8 +125,7 @@ export function genIdentifier( const idMap = identifiers[raw] if (idMap && idMap.length) { - name = idMap[0] - return [[name, NewlineType.None, loc]] + return [[idMap[0], NewlineType.None, loc]] } let prefix: string | undefined From 491b7fd207a9397ade90093c9e93e2a5ca1d2e99 Mon Sep 17 00:00:00 2001 From: daiwei Date: Tue, 3 Dec 2024 13:36:40 +0800 Subject: [PATCH 07/47] wip: save --- packages/compiler-vapor/src/generate.ts | 2 + .../src/generators/expression.ts | 8 +-- .../compiler-vapor/src/generators/html.ts | 12 +++- .../src/generators/operation.ts | 45 ++++---------- .../compiler-vapor/src/generators/prop.ts | 58 ++++++++++++++++--- .../compiler-vapor/src/generators/text.ts | 31 ++++++---- packages/compiler-vapor/src/ir/index.ts | 2 + .../src/transforms/transformElement.ts | 2 + .../src/transforms/transformText.ts | 2 + 9 files changed, 99 insertions(+), 63 deletions(-) diff --git a/packages/compiler-vapor/src/generate.ts b/packages/compiler-vapor/src/generate.ts index 58cae3b88..cc1ec4bdb 100644 --- a/packages/compiler-vapor/src/generate.ts +++ b/packages/compiler-vapor/src/generate.ts @@ -35,6 +35,8 @@ export class CodegenContext { delegates: Set = new Set() + renderEffectDeps: string[] = [] + identifiers: Record = Object.create(null) block: BlockIRNode diff --git a/packages/compiler-vapor/src/generators/expression.ts b/packages/compiler-vapor/src/generators/expression.ts index 48d39d2a4..d13a66412 100644 --- a/packages/compiler-vapor/src/generators/expression.ts +++ b/packages/compiler-vapor/src/generators/expression.ts @@ -19,7 +19,6 @@ export function genExpression( node: SimpleExpressionNode, context: CodegenContext, assignment?: string, - onIdentifierRewrite?: (newName: string, name: string) => string, ): CodeFragment[] { const { prefixIdentifiers } = context.options const { content, ast, isStatic, loc } = node @@ -40,7 +39,7 @@ export function genExpression( // the expression is a simple identifier if (ast === null) { - return genIdentifier(content, context, loc, assignment, onIdentifierRewrite) + return genIdentifier(content, context, loc, assignment) } const ids: Identifier[] = [] @@ -89,7 +88,6 @@ export function genExpression( source, }, hasMemberExpression ? undefined : assignment, - undefined, id, parent, parentStack, @@ -115,7 +113,6 @@ function genIdentifier( { options, vaporHelper, identifiers }: CodegenContext, loc?: SourceLocation, assignment?: string, - onIdentifierRewrite?: (newName: string, name: string) => string, id?: Identifier, parent?: Node, parentStack?: Node[], @@ -177,9 +174,6 @@ function genIdentifier( } else { raw = `${type === BindingTypes.PROPS ? '$props' : '_ctx'}.${raw}` } - if (onIdentifierRewrite) { - raw = onIdentifierRewrite(raw, name) - } } raw = withAssignment(raw) } diff --git a/packages/compiler-vapor/src/generators/html.ts b/packages/compiler-vapor/src/generators/html.ts index cac8c0914..b5511c0fe 100644 --- a/packages/compiler-vapor/src/generators/html.ts +++ b/packages/compiler-vapor/src/generators/html.ts @@ -2,14 +2,20 @@ import type { CodegenContext } from '../generate' import type { SetHtmlIRNode } from '../ir' import { genExpression } from './expression' import { type CodeFragment, NEWLINE, genCall } from './utils' +import { processValue } from './prop' export function genSetHtml( oper: SetHtmlIRNode, context: CodegenContext, - onIdRewrite?: (newName: string, name: string) => string, ): CodeFragment[] { const { vaporHelper } = context - const html = genExpression(oper.value, context, undefined, onIdRewrite) - return [NEWLINE, ...genCall(vaporHelper('setHtml'), `n${oper.element}`, html)] + let html = genExpression(oper.value, context, undefined) + let condition: CodeFragment[] + ;[condition, html] = processValue(context, html) + return [ + NEWLINE, + ...condition, + ...genCall(vaporHelper('setHtml'), `n${oper.element}`, html), + ] } diff --git a/packages/compiler-vapor/src/generators/operation.ts b/packages/compiler-vapor/src/generators/operation.ts index dfd85d1a9..b204aabd7 100644 --- a/packages/compiler-vapor/src/generators/operation.ts +++ b/packages/compiler-vapor/src/generators/operation.ts @@ -22,11 +22,10 @@ import { genSlotOutlet } from './slotOutlet' export function genOperations( opers: OperationNode[], context: CodegenContext, - onIdRewrite?: (newName: string, name: string) => string, ): CodeFragment[] { const [frag, push] = buildCodeFragment() for (const operation of opers) { - push(...genOperation(operation, context, onIdRewrite)) + push(...genOperation(operation, context)) } return frag } @@ -34,21 +33,20 @@ export function genOperations( export function genOperation( oper: OperationNode, context: CodegenContext, - onIdRewrite?: (newName: string, name: string) => string, ): CodeFragment[] { switch (oper.type) { case IRNodeTypes.SET_PROP: - return genSetProp(oper, context, onIdRewrite) + return genSetProp(oper, context) case IRNodeTypes.SET_DYNAMIC_PROPS: return genDynamicProps(oper, context) case IRNodeTypes.SET_TEXT: - return genSetText(oper, context, onIdRewrite) + return genSetText(oper, context) case IRNodeTypes.SET_EVENT: return genSetEvent(oper, context) case IRNodeTypes.SET_DYNAMIC_EVENTS: return genSetDynamicEvents(oper, context) case IRNodeTypes.SET_HTML: - return genSetHtml(oper, context, onIdRewrite) + return genSetHtml(oper, context) case IRNodeTypes.SET_TEMPLATE_REF: return genSetTemplateRef(oper, context) case IRNodeTypes.SET_MODEL_VALUE: @@ -88,59 +86,40 @@ export function genEffects( return frag } -// TODO multiple effect with same deps name -const seenNames: Record = {} - export function genEffect( { operations }: IREffect, context: CodegenContext, ): CodeFragment[] { - const { vaporHelper } = context + let { vaporHelper, renderEffectDeps } = context const [frag, push] = buildCodeFragment( NEWLINE, `${vaporHelper('renderEffect')}(() => `, ) - let renderEffectDeps: string[] = [] - let newIdName, idName - function onIdRewrite(newName: string, name: string) { - if (!seenNames[name]) { - seenNames[name] = 0 - } - seenNames[name]++ - renderEffectDeps.push(name) - return renderEffectDeps.length === 1 - ? `_${(idName = name)} = ${(newIdName = newName)}` - : newName - } - const operationsExps = genOperations(operations, context, onIdRewrite) + const operationsExps = genOperations(operations, context) if (renderEffectDeps.length) { const vars = [...new Set(renderEffectDeps)].map(v => `_${v}`) frag.splice(1, 0, `let ${vars.join(', ')};`, NEWLINE) - renderEffectDeps = [] + context.renderEffectDeps = [] } const newlineCount = operationsExps.filter(frag => frag === NEWLINE).length if (newlineCount > 1) { - const condition: CodeFragment[] = newIdName - ? [NEWLINE, `if(_${idName} === ${newIdName}) return`] - : [undefined] + // const condition: CodeFragment[] = newIdName + // ? [NEWLINE, `if(_${idName} === ${newIdName}) return`] + // : [undefined] push( '{', INDENT_START, - ...condition, + // ...condition, ...operationsExps, INDENT_END, NEWLINE, '})', ) } else { - push( - newIdName ? `_${idName} !== ${newIdName} && ` : undefined, - ...operationsExps.filter(frag => frag !== NEWLINE), - ')', - ) + push(...operationsExps.filter(frag => frag !== NEWLINE), ')') } return frag diff --git a/packages/compiler-vapor/src/generators/prop.ts b/packages/compiler-vapor/src/generators/prop.ts index d97b887c0..576deff87 100644 --- a/packages/compiler-vapor/src/generators/prop.ts +++ b/packages/compiler-vapor/src/generators/prop.ts @@ -17,6 +17,9 @@ import { type CodeFragment, DELIMITERS_ARRAY, DELIMITERS_OBJECT, + INDENT_END, + INDENT_START, + LF, NEWLINE, genCall, genMulti, @@ -29,6 +32,7 @@ import { isMathMLGlobalAttr, isMathMLTag, isSVGTag, + isString, isSvgGlobalAttr, shouldSetAsAttr, toHandlerKey, @@ -38,22 +42,26 @@ import { export function genSetProp( oper: SetPropIRNode, context: CodegenContext, - onIdRewrite?: (newName: string, name: string) => string, ): CodeFragment[] { const { vaporHelper } = context const { prop: { key, values, modifier }, tag, + inVFor, + inVOnce, } = oper const { helperName, omitKey } = getRuntimeHelper(tag, key.content, modifier) - const propValue = genPropValue( - values, - context, - helperName !== 'setDynamicProp' ? onIdRewrite : undefined, - ) + let propValue = genPropValue(values, context) + + let condition: CodeFragment[] = [] + if (helperName !== 'setDynamicProp' && !inVFor && !inVOnce) { + ;[condition, propValue] = processValue(context, propValue) + } + return [ NEWLINE, + ...condition, ...genCall( [vaporHelper(helperName), null], `n${oper.element}`, @@ -140,10 +148,9 @@ export function genPropKey( export function genPropValue( values: SimpleExpressionNode[], context: CodegenContext, - onIdentifierRewrite?: (newName: string, name: string) => string, ): CodeFragment[] { if (values.length === 1) { - return genExpression(values[0], context, undefined, onIdentifierRewrite) + return genExpression(values[0], context, undefined) } return genMulti( DELIMITERS_ARRAY, @@ -242,3 +249,38 @@ const getSpecialHelper = ( return specialHelpers[keyName] || null } + +export function processValue( + context: CodegenContext, + values: CodeFragment[], +): [CodeFragment[], CodeFragment[]] { + const { renderEffectDeps } = context + + const idNames = [] + for (let frag of values) { + if ( + !frag || + frag === NEWLINE || + frag === INDENT_START || + frag === INDENT_END || + frag === LF + ) { + continue + } + + if (isString(frag)) frag = [frag] + let [, , , idName] = frag + if (idName) { + idNames.push(idName) + } + } + if (idNames.length > 0) { + const name = idNames.join('_') + renderEffectDeps.push(name) + return [ + [`_${name} !== `, ...values, ` && `], + [`_${name} = `, ...values], + ] + } + return [[undefined], values] +} diff --git a/packages/compiler-vapor/src/generators/text.ts b/packages/compiler-vapor/src/generators/text.ts index 6d77b4b28..3ac1f8221 100644 --- a/packages/compiler-vapor/src/generators/text.ts +++ b/packages/compiler-vapor/src/generators/text.ts @@ -8,24 +8,31 @@ import { genCall, genMulti, } from './utils' +import { processValue } from './prop' export function genSetText( oper: SetTextIRNode, context: CodegenContext, - onIdRewrite?: (newName: string, name: string) => string, ): CodeFragment[] { const { vaporHelper } = context - const { element, values } = oper - const texts = values.map(value => - genExpression( - value, - context, - undefined, - // TODO values.length > 1 - values.length === 1 ? onIdRewrite : undefined, - ), - ) - return [NEWLINE, ...genCall(vaporHelper('setText'), `n${element}`, ...texts)] + const { element, values, inVOnce, inVFor } = oper + const texts = values.map(value => genExpression(value, context, undefined)) + let condition: CodeFragment[] = [] + let newValues + if (!inVOnce && !inVFor && texts.length === 1) { + ;[condition, newValues] = processValue(context, texts[0]) + return [ + NEWLINE, + ...condition, + ...genCall(vaporHelper('setText'), `n${element}`, newValues), + ] + } else { + // TODO: handle multiple values + return [ + NEWLINE, + ...genCall(vaporHelper('setText'), `n${element}`, ...values), + ] + } } export function genCreateTextNode( diff --git a/packages/compiler-vapor/src/ir/index.ts b/packages/compiler-vapor/src/ir/index.ts index 7d1ddac89..217fa1e8e 100644 --- a/packages/compiler-vapor/src/ir/index.ts +++ b/packages/compiler-vapor/src/ir/index.ts @@ -41,6 +41,8 @@ export enum IRNodeTypes { export interface BaseIRNode { type: IRNodeTypes + inVFor?: boolean + inVOnce?: boolean } export type VaporHelper = keyof typeof import('@vue/runtime-vapor') diff --git a/packages/compiler-vapor/src/transforms/transformElement.ts b/packages/compiler-vapor/src/transforms/transformElement.ts index 51f0e427e..36b823273 100644 --- a/packages/compiler-vapor/src/transforms/transformElement.ts +++ b/packages/compiler-vapor/src/transforms/transformElement.ts @@ -211,6 +211,8 @@ function transformNativeElement( prop, root: singleRoot, tag, + inVFor: context.inVFor > 0, + inVOnce: context.inVOnce, }) } } diff --git a/packages/compiler-vapor/src/transforms/transformText.ts b/packages/compiler-vapor/src/transforms/transformText.ts index 37da24453..44d6a2f81 100644 --- a/packages/compiler-vapor/src/transforms/transformText.ts +++ b/packages/compiler-vapor/src/transforms/transformText.ts @@ -73,6 +73,8 @@ function processTextLikeContainer( type: IRNodeTypes.SET_TEXT, element: context.reference(), values, + inVFor: context.inVFor > 0, + inVOnce: context.inVOnce, }) } } From f5441a51b81b08e05e460c13f2083e66979403dd Mon Sep 17 00:00:00 2001 From: daiwei Date: Tue, 3 Dec 2024 14:47:23 +0800 Subject: [PATCH 08/47] wip: save --- .../__snapshots__/compile.spec.ts.snap | 6 ++- .../transformElement.spec.ts.snap | 3 +- .../__snapshots__/vBind.spec.ts.snap | 30 ++++++------ .../__tests__/transforms/vBind.spec.ts | 26 ++++++---- .../compiler-vapor/src/generators/html.ts | 5 +- .../compiler-vapor/src/generators/prop.ts | 47 ++++++++++++------- .../compiler-vapor/src/generators/text.ts | 25 ++++------ packages/runtime-vapor/src/dom/prop.ts | 3 +- 8 files changed, 81 insertions(+), 64 deletions(-) diff --git a/packages/compiler-vapor/__tests__/__snapshots__/compile.spec.ts.snap b/packages/compiler-vapor/__tests__/__snapshots__/compile.spec.ts.snap index ae9241b99..726e0d854 100644 --- a/packages/compiler-vapor/__tests__/__snapshots__/compile.spec.ts.snap +++ b/packages/compiler-vapor/__tests__/__snapshots__/compile.spec.ts.snap @@ -6,7 +6,8 @@ const t0 = _template("
") export function render(_ctx, $props, $emit, $attrs, $slots) { const n0 = t0() - _renderEffect(() => _setText(n0, "count is ", _ctx.count, ".")) + let _count; + _renderEffect(() => _count !== _ctx.count && _setText(n0, "count is ", _count = _ctx.count, ".")) return n0 }" `; @@ -186,7 +187,8 @@ export function render(_ctx) { const n0 = t0() _delegate(n0, "click", () => _ctx.handleClick) _setInheritAttrs(["id"]) - _renderEffect(() => _setText(n0, _ctx.count, "foo", _ctx.count, "foo", _ctx.count)) + let _count; + _renderEffect(() => _count !== _ctx.count && _setText(n0, _count = _ctx.count, "foo", _ctx.count, "foo", _ctx.count)) let _count; _renderEffect(() => _count !== _ctx.count && _setDOMProp(n0, "id", _count = _ctx.count)) return n0 diff --git a/packages/compiler-vapor/__tests__/transforms/__snapshots__/transformElement.spec.ts.snap b/packages/compiler-vapor/__tests__/transforms/__snapshots__/transformElement.spec.ts.snap index 79b8fffbb..555e194df 100644 --- a/packages/compiler-vapor/__tests__/transforms/__snapshots__/transformElement.spec.ts.snap +++ b/packages/compiler-vapor/__tests__/transforms/__snapshots__/transformElement.spec.ts.snap @@ -303,7 +303,8 @@ const t0 = _template("
") export function render(_ctx) { const n0 = t0() _setInheritAttrs(["class"]) - _renderEffect(() => _setClass(n0, ["foo", { bar: _ctx.isBar }], true)) + let _isBar; + _renderEffect(() => _isBar !== _ctx.isBar && _setClass(n0, ["foo", { bar: _isBar = _ctx.isBar }], true)) return n0 }" `; 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 49c193dd1..995920c83 100644 --- a/packages/compiler-vapor/__tests__/transforms/__snapshots__/vBind.spec.ts.snap +++ b/packages/compiler-vapor/__tests__/transforms/__snapshots__/vBind.spec.ts.snap @@ -85,7 +85,8 @@ const t0 = _template("
") export function render(_ctx) { const n0 = t0() _setInheritAttrs(["fooBar"]) - _renderEffect(() => _setDynamicProp(n0, "fooBar", _ctx.id)) + let _id; + _renderEffect(() => _id !== _ctx.id && _setDynamicProp(n0, "fooBar", _id = _ctx.id)) return n0 }" `; @@ -110,7 +111,8 @@ const t0 = _template("
") export function render(_ctx) { const n0 = t0() _setInheritAttrs(["fooBar"]) - _renderEffect(() => _setDynamicProp(n0, "fooBar", _ctx.fooBar)) + let _fooBar; + _renderEffect(() => _fooBar !== _ctx.fooBar && _setDynamicProp(n0, "fooBar", _fooBar = _ctx.fooBar)) return n0 }" `; @@ -329,7 +331,8 @@ const t0 = _template("") export function render(_ctx) { const n0 = t0() _setInheritAttrs(["value"]) - _renderEffect(() => _setDynamicProp(n0, "value", _ctx.foo)) + let _foo; + _renderEffect(() => _foo !== _ctx.foo && _setDynamicProp(n0, "value", _foo = _ctx.foo)) return n0 }" `; @@ -425,19 +428,17 @@ export function render(_ctx) { _renderEffect(() => _type !== _ctx.type && _setAttr(n2, "type", _type = _ctx.type)) let _width; _renderEffect(() => { - if(_width === _ctx.width) return - _setAttr(n3, "width", _width = _ctx.width) - _setAttr(n4, "width", _ctx.width) - _setAttr(n5, "width", _ctx.width) - _setAttr(n6, "width", _ctx.width) + _width !== _ctx.width && _setAttr(n3, "width", _width = _ctx.width) + _width !== _ctx.width && _setAttr(n4, "width", _width = _ctx.width) + _width !== _ctx.width && _setAttr(n5, "width", _width = _ctx.width) + _width !== _ctx.width && _setAttr(n6, "width", _width = _ctx.width) }) let _height; _renderEffect(() => { - if(_height === _ctx.height) return - _setAttr(n3, "height", _height = _ctx.height) - _setAttr(n4, "height", _ctx.height) - _setAttr(n5, "height", _ctx.height) - _setAttr(n6, "height", _ctx.height) + _height !== _ctx.height && _setAttr(n3, "height", _height = _ctx.height) + _height !== _ctx.height && _setAttr(n4, "height", _height = _ctx.height) + _height !== _ctx.height && _setAttr(n5, "height", _height = _ctx.height) + _height !== _ctx.height && _setAttr(n6, "height", _height = _ctx.height) }) return [n0, n1, n2, n3, n4, n5, n6] }" @@ -487,7 +488,8 @@ const t0 = _template("
") export function render(_ctx) { const n0 = t0() _setInheritAttrs(["camel-case"]) - _renderEffect(() => _setDynamicProp(n0, "camel-case", _ctx.camelCase)) + let _camelCase; + _renderEffect(() => _camelCase !== _ctx.camelCase && _setDynamicProp(n0, "camel-case", _camelCase = _ctx.camelCase)) return n0 }" `; diff --git a/packages/compiler-vapor/__tests__/transforms/vBind.spec.ts b/packages/compiler-vapor/__tests__/transforms/vBind.spec.ts index a0523e73c..9f9326509 100644 --- a/packages/compiler-vapor/__tests__/transforms/vBind.spec.ts +++ b/packages/compiler-vapor/__tests__/transforms/vBind.spec.ts @@ -130,7 +130,9 @@ describe('compiler v-bind', () => { ], }, }) - expect(code).contains('_setDynamicProp(n0, "camel-case", _ctx.camelCase)') + expect(code).contains( + '_camelCase !== _ctx.camelCase && _setDynamicProp(n0, "camel-case", _camelCase = _ctx.camelCase)', + ) }) test('dynamic arg', () => { @@ -290,7 +292,9 @@ describe('compiler v-bind', () => { }) expect(code).matchSnapshot() - expect(code).contains('_setDynamicProp(n0, "fooBar", _ctx.id)') + expect(code).contains( + '_id !== _ctx.id && _setDynamicProp(n0, "fooBar", _id = _ctx.id)', + ) }) test('.camel modifier w/ no expression', () => { @@ -314,7 +318,9 @@ describe('compiler v-bind', () => { }, }) expect(code).contains('renderEffect') - expect(code).contains('_setDynamicProp(n0, "fooBar", _ctx.fooBar)') + expect(code).contains( + '_fooBar !== _ctx.fooBar && _setDynamicProp(n0, "fooBar", _fooBar = _ctx.fooBar)', + ) }) test('.camel modifier w/ dynamic arg', () => { @@ -657,11 +663,11 @@ describe('compiler v-bind', () => { ) expect(code).contains('_setAttr(n3, "width", _width = _ctx.width)') expect(code).contains('_setAttr(n3, "height", _height = _ctx.height)') - expect(code).contains('_setAttr(n4, "width", _ctx.width)') - expect(code).contains('_setAttr(n4, "height", _ctx.height)') - expect(code).contains('_setAttr(n5, "width", _ctx.width)') - expect(code).contains('_setAttr(n5, "height", _ctx.height)') - expect(code).contains(' _setAttr(n6, "width", _ctx.width)') + // expect(code).contains('_setAttr(n4, "width", _ctx.width)') + // expect(code).contains('_setAttr(n4, "height", _ctx.height)') + // expect(code).contains('_setAttr(n5, "width", _ctx.width)') + // expect(code).contains('_setAttr(n5, "height", _ctx.height)') + // expect(code).contains(' _setAttr(n6, "width", _ctx.width)') }) test('HTML global attributes should set as dom prop', () => { @@ -761,7 +767,9 @@ describe('compiler v-bind', () => { `) expect(code).matchSnapshot() - expect(code).contains('_setDynamicProp(n0, "value", _ctx.foo)') + expect(code).contains( + '_foo !== _ctx.foo && _setDynamicProp(n0, "value", _foo = _ctx.foo)', + ) }) test('number value', () => { diff --git a/packages/compiler-vapor/src/generators/html.ts b/packages/compiler-vapor/src/generators/html.ts index b5511c0fe..a640623dd 100644 --- a/packages/compiler-vapor/src/generators/html.ts +++ b/packages/compiler-vapor/src/generators/html.ts @@ -2,7 +2,7 @@ import type { CodegenContext } from '../generate' import type { SetHtmlIRNode } from '../ir' import { genExpression } from './expression' import { type CodeFragment, NEWLINE, genCall } from './utils' -import { processValue } from './prop' +import { processValues } from './prop' export function genSetHtml( oper: SetHtmlIRNode, @@ -11,8 +11,7 @@ export function genSetHtml( const { vaporHelper } = context let html = genExpression(oper.value, context, undefined) - let condition: CodeFragment[] - ;[condition, html] = processValue(context, html) + let condition: CodeFragment[] = processValues(context, [html]) return [ NEWLINE, ...condition, diff --git a/packages/compiler-vapor/src/generators/prop.ts b/packages/compiler-vapor/src/generators/prop.ts index 576deff87..20763cae5 100644 --- a/packages/compiler-vapor/src/generators/prop.ts +++ b/packages/compiler-vapor/src/generators/prop.ts @@ -55,8 +55,8 @@ export function genSetProp( let propValue = genPropValue(values, context) let condition: CodeFragment[] = [] - if (helperName !== 'setDynamicProp' && !inVFor && !inVOnce) { - ;[condition, propValue] = processValue(context, propValue) + if (!inVFor && !inVOnce) { + condition = processValues(context, [propValue]) } return [ @@ -250,13 +250,26 @@ const getSpecialHelper = ( return specialHelpers[keyName] || null } -export function processValue( +export function processValues( + context: CodegenContext, + values: CodeFragment[][], +): CodeFragment[] { + const conditions: CodeFragment[] = [] + const rewrittens: string[] = [] + values.forEach(value => { + const condition = processValue(context, value, rewrittens) + conditions.push(...condition) + }) + return conditions.length > 0 ? [...new Set(conditions)] : [undefined] +} + +function processValue( context: CodegenContext, values: CodeFragment[], -): [CodeFragment[], CodeFragment[]] { + rewrittens: string[], +): CodeFragment[] { const { renderEffectDeps } = context - - const idNames = [] + const conditions: string[] = [] for (let frag of values) { if ( !frag || @@ -269,18 +282,18 @@ export function processValue( } if (isString(frag)) frag = [frag] - let [, , , idName] = frag + let [newName, , , idName] = frag if (idName) { - idNames.push(idName) + const rewriteStr = `_${idName} = ${newName}` + if (rewrittens.includes(rewriteStr)) continue + + rewrittens.push(rewriteStr) + renderEffectDeps.push(idName) + conditions.push(`_${idName} !== ${newName}`) + frag[0] = rewriteStr } } - if (idNames.length > 0) { - const name = idNames.join('_') - renderEffectDeps.push(name) - return [ - [`_${name} !== `, ...values, ` && `], - [`_${name} = `, ...values], - ] - } - return [[undefined], values] + return conditions.length > 0 + ? [[...new Set(conditions)].join(' && '), ' && '] + : [undefined] } diff --git a/packages/compiler-vapor/src/generators/text.ts b/packages/compiler-vapor/src/generators/text.ts index 3ac1f8221..4bfa9df65 100644 --- a/packages/compiler-vapor/src/generators/text.ts +++ b/packages/compiler-vapor/src/generators/text.ts @@ -8,7 +8,7 @@ import { genCall, genMulti, } from './utils' -import { processValue } from './prop' +import { processValues } from './prop' export function genSetText( oper: SetTextIRNode, @@ -17,22 +17,15 @@ export function genSetText( const { vaporHelper } = context const { element, values, inVOnce, inVFor } = oper const texts = values.map(value => genExpression(value, context, undefined)) - let condition: CodeFragment[] = [] - let newValues - if (!inVOnce && !inVFor && texts.length === 1) { - ;[condition, newValues] = processValue(context, texts[0]) - return [ - NEWLINE, - ...condition, - ...genCall(vaporHelper('setText'), `n${element}`, newValues), - ] - } else { - // TODO: handle multiple values - return [ - NEWLINE, - ...genCall(vaporHelper('setText'), `n${element}`, ...values), - ] + let conditions: CodeFragment[] = [] + if (!inVOnce && !inVFor) { + conditions = processValues(context, texts) } + return [ + NEWLINE, + ...conditions, + ...genCall(vaporHelper('setText'), `n${element}`, ...texts), + ] } export function genCreateTextNode( diff --git a/packages/runtime-vapor/src/dom/prop.ts b/packages/runtime-vapor/src/dom/prop.ts index 2481d02b7..bd6ce1f12 100644 --- a/packages/runtime-vapor/src/dom/prop.ts +++ b/packages/runtime-vapor/src/dom/prop.ts @@ -212,13 +212,12 @@ export function mergeProps(...args: Data[]): Data { return ret } -export function setText(el: Node, ...values: any[]): string { +export function setText(el: Node, ...values: any[]): void { const text = values.map(v => toDisplayString(v)).join('') const oldVal = recordPropMetadata(el, 'textContent', text) if (text !== oldVal) { el.textContent = text } - return text } export function setHtml(el: Element, value: any): void { From bf0e9d0f6ce937bb95d866b1f549d03f288d5f0b Mon Sep 17 00:00:00 2001 From: daiwei Date: Tue, 3 Dec 2024 14:52:39 +0800 Subject: [PATCH 09/47] wip: save --- packages/compiler-vapor/src/generators/html.ts | 11 +++++++---- packages/compiler-vapor/src/transforms/vHtml.ts | 2 ++ 2 files changed, 9 insertions(+), 4 deletions(-) diff --git a/packages/compiler-vapor/src/generators/html.ts b/packages/compiler-vapor/src/generators/html.ts index a640623dd..389d5df40 100644 --- a/packages/compiler-vapor/src/generators/html.ts +++ b/packages/compiler-vapor/src/generators/html.ts @@ -9,12 +9,15 @@ export function genSetHtml( context: CodegenContext, ): CodeFragment[] { const { vaporHelper } = context - - let html = genExpression(oper.value, context, undefined) - let condition: CodeFragment[] = processValues(context, [html]) + const { value, element, inVOnce, inVFor } = oper + let html = genExpression(value, context, undefined) + let condition: CodeFragment[] = [] + if (!inVOnce && !inVFor) { + condition = processValues(context, [html]) + } return [ NEWLINE, ...condition, - ...genCall(vaporHelper('setHtml'), `n${oper.element}`, html), + ...genCall(vaporHelper('setHtml'), `n${element}`, html), ] } diff --git a/packages/compiler-vapor/src/transforms/vHtml.ts b/packages/compiler-vapor/src/transforms/vHtml.ts index 6b9a269e4..328c48fa3 100644 --- a/packages/compiler-vapor/src/transforms/vHtml.ts +++ b/packages/compiler-vapor/src/transforms/vHtml.ts @@ -22,5 +22,7 @@ export const transformVHtml: DirectiveTransform = (dir, node, context) => { type: IRNodeTypes.SET_HTML, element: context.reference(), value: exp, + inVFor: context.inVFor > 0, + inVOnce: context.inVOnce, }) } From 51a027370b369cbaeeb3ca5620361eadea98aa06 Mon Sep 17 00:00:00 2001 From: daiwei Date: Tue, 3 Dec 2024 16:31:06 +0800 Subject: [PATCH 10/47] wip: save --- .../__snapshots__/vBind.spec.ts.snap | 16 ++++---- .../__tests__/transforms/vBind.spec.ts | 10 ++--- packages/compiler-vapor/src/generate.ts | 5 ++- .../src/generators/operation.ts | 28 +++++++++++--- .../compiler-vapor/src/generators/prop.ts | 38 +++++++++++-------- packages/compiler-vapor/src/ir/index.ts | 2 + 6 files changed, 64 insertions(+), 35 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 995920c83..2008b6371 100644 --- a/packages/compiler-vapor/__tests__/transforms/__snapshots__/vBind.spec.ts.snap +++ b/packages/compiler-vapor/__tests__/transforms/__snapshots__/vBind.spec.ts.snap @@ -428,17 +428,17 @@ export function render(_ctx) { _renderEffect(() => _type !== _ctx.type && _setAttr(n2, "type", _type = _ctx.type)) let _width; _renderEffect(() => { - _width !== _ctx.width && _setAttr(n3, "width", _width = _ctx.width) - _width !== _ctx.width && _setAttr(n4, "width", _width = _ctx.width) - _width !== _ctx.width && _setAttr(n5, "width", _width = _ctx.width) - _width !== _ctx.width && _setAttr(n6, "width", _width = _ctx.width) + _setAttr(n3, "width", _width = _ctx.width) + _setAttr(n4, "width", _ctx.width) + _setAttr(n5, "width", _ctx.width) + _setAttr(n6, "width", _ctx.width) }) let _height; _renderEffect(() => { - _height !== _ctx.height && _setAttr(n3, "height", _height = _ctx.height) - _height !== _ctx.height && _setAttr(n4, "height", _height = _ctx.height) - _height !== _ctx.height && _setAttr(n5, "height", _height = _ctx.height) - _height !== _ctx.height && _setAttr(n6, "height", _height = _ctx.height) + _setAttr(n3, "height", _height = _ctx.height) + _setAttr(n4, "height", _ctx.height) + _setAttr(n5, "height", _ctx.height) + _setAttr(n6, "height", _ctx.height) }) return [n0, n1, n2, n3, n4, n5, n6] }" diff --git a/packages/compiler-vapor/__tests__/transforms/vBind.spec.ts b/packages/compiler-vapor/__tests__/transforms/vBind.spec.ts index 9f9326509..058aabe8b 100644 --- a/packages/compiler-vapor/__tests__/transforms/vBind.spec.ts +++ b/packages/compiler-vapor/__tests__/transforms/vBind.spec.ts @@ -663,11 +663,11 @@ describe('compiler v-bind', () => { ) expect(code).contains('_setAttr(n3, "width", _width = _ctx.width)') expect(code).contains('_setAttr(n3, "height", _height = _ctx.height)') - // expect(code).contains('_setAttr(n4, "width", _ctx.width)') - // expect(code).contains('_setAttr(n4, "height", _ctx.height)') - // expect(code).contains('_setAttr(n5, "width", _ctx.width)') - // expect(code).contains('_setAttr(n5, "height", _ctx.height)') - // expect(code).contains(' _setAttr(n6, "width", _ctx.width)') + expect(code).contains('_setAttr(n4, "width", _ctx.width)') + expect(code).contains('_setAttr(n4, "height", _ctx.height)') + expect(code).contains('_setAttr(n5, "width", _ctx.width)') + expect(code).contains('_setAttr(n5, "height", _ctx.height)') + expect(code).contains(' _setAttr(n6, "width", _ctx.width)') }) test('HTML global attributes should set as dom prop', () => { diff --git a/packages/compiler-vapor/src/generate.ts b/packages/compiler-vapor/src/generate.ts index cc1ec4bdb..ca1c71c80 100644 --- a/packages/compiler-vapor/src/generate.ts +++ b/packages/compiler-vapor/src/generate.ts @@ -2,7 +2,7 @@ import type { CodegenOptions as BaseCodegenOptions, BaseCodegenResult, } from '@vue/compiler-dom' -import type { BlockIRNode, RootIRNode, VaporHelper } from './ir' +import type { BlockIRNode, IREffect, RootIRNode, VaporHelper } from './ir' import { extend, remove } from '@vue/shared' import { genBlockContent } from './generators/block' import { genTemplates } from './generators/template' @@ -35,6 +35,9 @@ export class CodegenContext { delegates: Set = new Set() + currentRenderEffect: IREffect | undefined = undefined + renderEffectCondition: string[] = [] + renderEffectRewriten: string[] = [] renderEffectDeps: string[] = [] identifiers: Record = Object.create(null) diff --git a/packages/compiler-vapor/src/generators/operation.ts b/packages/compiler-vapor/src/generators/operation.ts index b204aabd7..7de5d42d6 100644 --- a/packages/compiler-vapor/src/generators/operation.ts +++ b/packages/compiler-vapor/src/generators/operation.ts @@ -80,7 +80,9 @@ export function genEffects( ): CodeFragment[] { const [frag, push] = buildCodeFragment() for (let i = 0; i < effects.length; i++) { - const effect = effects[i] + context.renderEffectRewriten = [] + context.renderEffectCondition = [] + const effect = (context.currentRenderEffect = effects[i]) push(...genEffect(effect, context)) } return frag @@ -90,7 +92,12 @@ export function genEffect( { operations }: IREffect, context: CodegenContext, ): CodeFragment[] { - let { vaporHelper, renderEffectDeps } = context + let { + vaporHelper, + renderEffectDeps, + renderEffectCondition, + renderEffectRewriten, + } = context const [frag, push] = buildCodeFragment( NEWLINE, `${vaporHelper('renderEffect')}(() => `, @@ -106,13 +113,22 @@ export function genEffect( const newlineCount = operationsExps.filter(frag => frag === NEWLINE).length if (newlineCount > 1) { - // const condition: CodeFragment[] = newIdName - // ? [NEWLINE, `if(_${idName} === ${newIdName}) return`] - // : [undefined] + // renderEffectCondition.pop() + const condition: CodeFragment[] = + renderEffectCondition.length > 0 + ? [ + NEWLINE, + `if(`, + ...renderEffectCondition.join(' && '), + `) return`, + NEWLINE, + ...renderEffectRewriten.join(';'), + ] + : [undefined] push( '{', INDENT_START, - // ...condition, + ...condition, ...operationsExps, INDENT_END, NEWLINE, diff --git a/packages/compiler-vapor/src/generators/prop.ts b/packages/compiler-vapor/src/generators/prop.ts index 20763cae5..c38f178d1 100644 --- a/packages/compiler-vapor/src/generators/prop.ts +++ b/packages/compiler-vapor/src/generators/prop.ts @@ -43,7 +43,7 @@ export function genSetProp( oper: SetPropIRNode, context: CodegenContext, ): CodeFragment[] { - const { vaporHelper } = context + const { vaporHelper, currentRenderEffect } = context const { prop: { key, values, modifier }, tag, @@ -56,7 +56,11 @@ export function genSetProp( let condition: CodeFragment[] = [] if (!inVFor && !inVOnce) { - condition = processValues(context, [propValue]) + if (currentRenderEffect!.operations.length === 1) { + condition = processValues(context, [propValue]) + } else { + processValues(context, [propValue], '===') + } } return [ @@ -253,22 +257,25 @@ const getSpecialHelper = ( export function processValues( context: CodegenContext, values: CodeFragment[][], -): CodeFragment[] { - const conditions: CodeFragment[] = [] - const rewrittens: string[] = [] + oper: '===' | '!==' = '!==', +): (string | undefined)[] { + const conditions: string[] = [] values.forEach(value => { - const condition = processValue(context, value, rewrittens) - conditions.push(...condition) + const condition = processValue(context, value, oper) + if (condition) conditions.push(...condition, ' && ') }) - return conditions.length > 0 ? [...new Set(conditions)] : [undefined] + + return conditions.length > 0 + ? (context.renderEffectCondition = [...new Set(conditions)]) + : [undefined] } function processValue( context: CodegenContext, values: CodeFragment[], - rewrittens: string[], -): CodeFragment[] { - const { renderEffectDeps } = context + oper: '===' | '!==' = '!==', +): string[] | undefined { + const { renderEffectDeps, renderEffectRewriten: rewrittens } = context const conditions: string[] = [] for (let frag of values) { if ( @@ -289,11 +296,12 @@ function processValue( rewrittens.push(rewriteStr) renderEffectDeps.push(idName) - conditions.push(`_${idName} !== ${newName}`) + conditions.push(`_${idName} ${oper} ${newName}`) frag[0] = rewriteStr } } - return conditions.length > 0 - ? [[...new Set(conditions)].join(' && '), ' && '] - : [undefined] + + if (conditions.length > 0) { + return [[...new Set(conditions)].join(' && ')] + } } diff --git a/packages/compiler-vapor/src/ir/index.ts b/packages/compiler-vapor/src/ir/index.ts index 217fa1e8e..de324d4ae 100644 --- a/packages/compiler-vapor/src/ir/index.ts +++ b/packages/compiler-vapor/src/ir/index.ts @@ -269,6 +269,8 @@ export interface IRDynamicInfo { export interface IREffect { expressions: SimpleExpressionNode[] operations: OperationNode[] + conditions: string[] + overrides: string[] } type Overwrite = Pick> & From 25aeb72635d984f811cdc0f40c91f38bcb603dad Mon Sep 17 00:00:00 2001 From: daiwei Date: Tue, 3 Dec 2024 16:55:03 +0800 Subject: [PATCH 11/47] wip: save --- .../__snapshots__/vBind.spec.ts.snap | 2 ++ packages/compiler-vapor/src/generate.ts | 3 -- .../src/generators/operation.ts | 30 +++++-------------- .../compiler-vapor/src/generators/prop.ts | 12 ++++---- packages/compiler-vapor/src/ir/index.ts | 1 + packages/compiler-vapor/src/transform.ts | 3 ++ 6 files changed, 20 insertions(+), 31 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 2008b6371..50b218d09 100644 --- a/packages/compiler-vapor/__tests__/transforms/__snapshots__/vBind.spec.ts.snap +++ b/packages/compiler-vapor/__tests__/transforms/__snapshots__/vBind.spec.ts.snap @@ -428,6 +428,7 @@ export function render(_ctx) { _renderEffect(() => _type !== _ctx.type && _setAttr(n2, "type", _type = _ctx.type)) let _width; _renderEffect(() => { + if(_width === _ctx.width) return _setAttr(n3, "width", _width = _ctx.width) _setAttr(n4, "width", _ctx.width) _setAttr(n5, "width", _ctx.width) @@ -435,6 +436,7 @@ export function render(_ctx) { }) let _height; _renderEffect(() => { + if(_height === _ctx.height) return _setAttr(n3, "height", _height = _ctx.height) _setAttr(n4, "height", _ctx.height) _setAttr(n5, "height", _ctx.height) diff --git a/packages/compiler-vapor/src/generate.ts b/packages/compiler-vapor/src/generate.ts index ca1c71c80..8d2537988 100644 --- a/packages/compiler-vapor/src/generate.ts +++ b/packages/compiler-vapor/src/generate.ts @@ -36,9 +36,6 @@ export class CodegenContext { delegates: Set = new Set() currentRenderEffect: IREffect | undefined = undefined - renderEffectCondition: string[] = [] - renderEffectRewriten: string[] = [] - renderEffectDeps: string[] = [] identifiers: Record = Object.create(null) diff --git a/packages/compiler-vapor/src/generators/operation.ts b/packages/compiler-vapor/src/generators/operation.ts index 7de5d42d6..8c2f0c798 100644 --- a/packages/compiler-vapor/src/generators/operation.ts +++ b/packages/compiler-vapor/src/generators/operation.ts @@ -80,9 +80,9 @@ export function genEffects( ): CodeFragment[] { const [frag, push] = buildCodeFragment() for (let i = 0; i < effects.length; i++) { - context.renderEffectRewriten = [] - context.renderEffectCondition = [] const effect = (context.currentRenderEffect = effects[i]) + effect.conditions = [] + effect.overrides = [] push(...genEffect(effect, context)) } return frag @@ -92,38 +92,24 @@ export function genEffect( { operations }: IREffect, context: CodegenContext, ): CodeFragment[] { - let { - vaporHelper, - renderEffectDeps, - renderEffectCondition, - renderEffectRewriten, - } = context + let { vaporHelper, currentRenderEffect } = context const [frag, push] = buildCodeFragment( NEWLINE, `${vaporHelper('renderEffect')}(() => `, ) - + const { deps, conditions } = currentRenderEffect! const operationsExps = genOperations(operations, context) - if (renderEffectDeps.length) { - const vars = [...new Set(renderEffectDeps)].map(v => `_${v}`) + if (deps.length) { + const vars = [...new Set(deps)].map(v => `_${v}`) frag.splice(1, 0, `let ${vars.join(', ')};`, NEWLINE) - context.renderEffectDeps = [] } const newlineCount = operationsExps.filter(frag => frag === NEWLINE).length if (newlineCount > 1) { - // renderEffectCondition.pop() const condition: CodeFragment[] = - renderEffectCondition.length > 0 - ? [ - NEWLINE, - `if(`, - ...renderEffectCondition.join(' && '), - `) return`, - NEWLINE, - ...renderEffectRewriten.join(';'), - ] + conditions.length > 0 + ? [NEWLINE, `if(`, ...conditions.join(' && '), `) return`] : [undefined] push( '{', diff --git a/packages/compiler-vapor/src/generators/prop.ts b/packages/compiler-vapor/src/generators/prop.ts index c38f178d1..5433c28e6 100644 --- a/packages/compiler-vapor/src/generators/prop.ts +++ b/packages/compiler-vapor/src/generators/prop.ts @@ -266,7 +266,7 @@ export function processValues( }) return conditions.length > 0 - ? (context.renderEffectCondition = [...new Set(conditions)]) + ? (context.currentRenderEffect!.conditions = [...new Set(conditions)]) : [undefined] } @@ -275,8 +275,8 @@ function processValue( values: CodeFragment[], oper: '===' | '!==' = '!==', ): string[] | undefined { - const { renderEffectDeps, renderEffectRewriten: rewrittens } = context - const conditions: string[] = [] + const { currentRenderEffect } = context + const { deps, overrides, conditions } = currentRenderEffect! for (let frag of values) { if ( !frag || @@ -292,10 +292,10 @@ function processValue( let [newName, , , idName] = frag if (idName) { const rewriteStr = `_${idName} = ${newName}` - if (rewrittens.includes(rewriteStr)) continue + if (overrides.includes(rewriteStr)) continue - rewrittens.push(rewriteStr) - renderEffectDeps.push(idName) + overrides.push(rewriteStr) + deps.push(idName) conditions.push(`_${idName} ${oper} ${newName}`) frag[0] = rewriteStr } diff --git a/packages/compiler-vapor/src/ir/index.ts b/packages/compiler-vapor/src/ir/index.ts index de324d4ae..4d7af68a2 100644 --- a/packages/compiler-vapor/src/ir/index.ts +++ b/packages/compiler-vapor/src/ir/index.ts @@ -269,6 +269,7 @@ export interface IRDynamicInfo { export interface IREffect { expressions: SimpleExpressionNode[] operations: OperationNode[] + deps: string[] conditions: string[] overrides: string[] } diff --git a/packages/compiler-vapor/src/transform.ts b/packages/compiler-vapor/src/transform.ts index f4290ab89..3ed77b7ff 100644 --- a/packages/compiler-vapor/src/transform.ts +++ b/packages/compiler-vapor/src/transform.ts @@ -151,6 +151,9 @@ export class TransformContext { this.block.effect.push({ expressions, operations, + conditions: [], + overrides: [], + deps: [], }) } From de74b70933e01f61794a95e4d42f2a8c19267e0e Mon Sep 17 00:00:00 2001 From: daiwei Date: Tue, 3 Dec 2024 17:04:31 +0800 Subject: [PATCH 12/47] wip: save --- packages/compiler-vapor/src/generators/html.ts | 5 +++-- packages/compiler-vapor/src/generators/prop.ts | 5 ++--- packages/compiler-vapor/src/generators/text.ts | 5 +++-- packages/compiler-vapor/src/ir/index.ts | 4 ++-- packages/compiler-vapor/src/transform.ts | 2 ++ 5 files changed, 12 insertions(+), 9 deletions(-) diff --git a/packages/compiler-vapor/src/generators/html.ts b/packages/compiler-vapor/src/generators/html.ts index 389d5df40..ef9464e49 100644 --- a/packages/compiler-vapor/src/generators/html.ts +++ b/packages/compiler-vapor/src/generators/html.ts @@ -8,8 +8,9 @@ export function genSetHtml( oper: SetHtmlIRNode, context: CodegenContext, ): CodeFragment[] { - const { vaporHelper } = context - const { value, element, inVOnce, inVFor } = oper + const { vaporHelper, currentRenderEffect } = context + const { inVOnce, inVFor } = currentRenderEffect! + const { value, element } = oper let html = genExpression(value, context, undefined) let condition: CodeFragment[] = [] if (!inVOnce && !inVFor) { diff --git a/packages/compiler-vapor/src/generators/prop.ts b/packages/compiler-vapor/src/generators/prop.ts index 5433c28e6..da39fe0b3 100644 --- a/packages/compiler-vapor/src/generators/prop.ts +++ b/packages/compiler-vapor/src/generators/prop.ts @@ -47,16 +47,15 @@ export function genSetProp( const { prop: { key, values, modifier }, tag, - inVFor, - inVOnce, } = oper + const { inVFor, inVOnce, operations } = currentRenderEffect! const { helperName, omitKey } = getRuntimeHelper(tag, key.content, modifier) let propValue = genPropValue(values, context) let condition: CodeFragment[] = [] if (!inVFor && !inVOnce) { - if (currentRenderEffect!.operations.length === 1) { + if (operations.length === 1) { condition = processValues(context, [propValue]) } else { processValues(context, [propValue], '===') diff --git a/packages/compiler-vapor/src/generators/text.ts b/packages/compiler-vapor/src/generators/text.ts index 4bfa9df65..a0a7a7354 100644 --- a/packages/compiler-vapor/src/generators/text.ts +++ b/packages/compiler-vapor/src/generators/text.ts @@ -14,8 +14,9 @@ export function genSetText( oper: SetTextIRNode, context: CodegenContext, ): CodeFragment[] { - const { vaporHelper } = context - const { element, values, inVOnce, inVFor } = oper + const { vaporHelper, currentRenderEffect } = context + const { element, values } = oper + const { inVFor, inVOnce } = currentRenderEffect! const texts = values.map(value => genExpression(value, context, undefined)) let conditions: CodeFragment[] = [] if (!inVOnce && !inVFor) { diff --git a/packages/compiler-vapor/src/ir/index.ts b/packages/compiler-vapor/src/ir/index.ts index 4d7af68a2..feaa5c8f9 100644 --- a/packages/compiler-vapor/src/ir/index.ts +++ b/packages/compiler-vapor/src/ir/index.ts @@ -41,8 +41,6 @@ export enum IRNodeTypes { export interface BaseIRNode { type: IRNodeTypes - inVFor?: boolean - inVOnce?: boolean } export type VaporHelper = keyof typeof import('@vue/runtime-vapor') @@ -272,6 +270,8 @@ export interface IREffect { deps: string[] conditions: string[] overrides: string[] + inVFor: boolean + inVOnce: boolean } type Overwrite = Pick> & diff --git a/packages/compiler-vapor/src/transform.ts b/packages/compiler-vapor/src/transform.ts index 3ed77b7ff..57a6c38ac 100644 --- a/packages/compiler-vapor/src/transform.ts +++ b/packages/compiler-vapor/src/transform.ts @@ -154,6 +154,8 @@ export class TransformContext { conditions: [], overrides: [], deps: [], + inVFor: this.inVFor > 0, + inVOnce: this.inVOnce, }) } From 7bd698d6c4c0e67508b4f761f6da49347e08fdf1 Mon Sep 17 00:00:00 2001 From: daiwei Date: Tue, 3 Dec 2024 17:07:08 +0800 Subject: [PATCH 13/47] wip: save --- packages/compiler-vapor/src/generators/prop.ts | 2 +- packages/compiler-vapor/src/transforms/transformElement.ts | 2 -- packages/compiler-vapor/src/transforms/transformText.ts | 2 -- packages/compiler-vapor/src/transforms/vHtml.ts | 2 -- 4 files changed, 1 insertion(+), 7 deletions(-) diff --git a/packages/compiler-vapor/src/generators/prop.ts b/packages/compiler-vapor/src/generators/prop.ts index da39fe0b3..18361d923 100644 --- a/packages/compiler-vapor/src/generators/prop.ts +++ b/packages/compiler-vapor/src/generators/prop.ts @@ -153,7 +153,7 @@ export function genPropValue( context: CodegenContext, ): CodeFragment[] { if (values.length === 1) { - return genExpression(values[0], context, undefined) + return genExpression(values[0], context) } return genMulti( DELIMITERS_ARRAY, diff --git a/packages/compiler-vapor/src/transforms/transformElement.ts b/packages/compiler-vapor/src/transforms/transformElement.ts index 36b823273..51f0e427e 100644 --- a/packages/compiler-vapor/src/transforms/transformElement.ts +++ b/packages/compiler-vapor/src/transforms/transformElement.ts @@ -211,8 +211,6 @@ function transformNativeElement( prop, root: singleRoot, tag, - inVFor: context.inVFor > 0, - inVOnce: context.inVOnce, }) } } diff --git a/packages/compiler-vapor/src/transforms/transformText.ts b/packages/compiler-vapor/src/transforms/transformText.ts index 44d6a2f81..37da24453 100644 --- a/packages/compiler-vapor/src/transforms/transformText.ts +++ b/packages/compiler-vapor/src/transforms/transformText.ts @@ -73,8 +73,6 @@ function processTextLikeContainer( type: IRNodeTypes.SET_TEXT, element: context.reference(), values, - inVFor: context.inVFor > 0, - inVOnce: context.inVOnce, }) } } diff --git a/packages/compiler-vapor/src/transforms/vHtml.ts b/packages/compiler-vapor/src/transforms/vHtml.ts index 328c48fa3..6b9a269e4 100644 --- a/packages/compiler-vapor/src/transforms/vHtml.ts +++ b/packages/compiler-vapor/src/transforms/vHtml.ts @@ -22,7 +22,5 @@ export const transformVHtml: DirectiveTransform = (dir, node, context) => { type: IRNodeTypes.SET_HTML, element: context.reference(), value: exp, - inVFor: context.inVFor > 0, - inVOnce: context.inVOnce, }) } From 4b0e4e6905adccd1908d9aba0b18d766b89a8a79 Mon Sep 17 00:00:00 2001 From: daiwei Date: Tue, 3 Dec 2024 17:40:21 +0800 Subject: [PATCH 14/47] wip: save --- packages/compiler-vapor/src/generate.ts | 8 +++++ .../compiler-vapor/src/generators/html.ts | 16 +++------- .../src/generators/operation.ts | 8 +++-- .../compiler-vapor/src/generators/prop.ts | 32 ++++++++----------- .../compiler-vapor/src/generators/text.ts | 16 +++------- packages/compiler-vapor/src/ir/index.ts | 2 +- packages/compiler-vapor/src/transform.ts | 2 +- 7 files changed, 39 insertions(+), 45 deletions(-) diff --git a/packages/compiler-vapor/src/generate.ts b/packages/compiler-vapor/src/generate.ts index 8d2537988..8a05376b4 100644 --- a/packages/compiler-vapor/src/generate.ts +++ b/packages/compiler-vapor/src/generate.ts @@ -37,6 +37,14 @@ export class CodegenContext { currentRenderEffect: IREffect | undefined = undefined + shouldTrackEffectDeps = (): boolean => { + return !!( + this.currentRenderEffect && + !this.currentRenderEffect.inVOnce && + !this.currentRenderEffect.inVFor + ) + } + identifiers: Record = Object.create(null) block: BlockIRNode diff --git a/packages/compiler-vapor/src/generators/html.ts b/packages/compiler-vapor/src/generators/html.ts index ef9464e49..de638d68d 100644 --- a/packages/compiler-vapor/src/generators/html.ts +++ b/packages/compiler-vapor/src/generators/html.ts @@ -8,17 +8,11 @@ export function genSetHtml( oper: SetHtmlIRNode, context: CodegenContext, ): CodeFragment[] { - const { vaporHelper, currentRenderEffect } = context - const { inVOnce, inVFor } = currentRenderEffect! + const { vaporHelper, shouldTrackEffectDeps } = context const { value, element } = oper - let html = genExpression(value, context, undefined) - let condition: CodeFragment[] = [] - if (!inVOnce && !inVFor) { - condition = processValues(context, [html]) + let html = genExpression(value, context) + if (shouldTrackEffectDeps()) { + processValues(context, [html]) } - return [ - NEWLINE, - ...condition, - ...genCall(vaporHelper('setHtml'), `n${element}`, html), - ] + return [NEWLINE, ...genCall(vaporHelper('setHtml'), `n${element}`, html)] } diff --git a/packages/compiler-vapor/src/generators/operation.ts b/packages/compiler-vapor/src/generators/operation.ts index 8c2f0c798..9b10bcece 100644 --- a/packages/compiler-vapor/src/generators/operation.ts +++ b/packages/compiler-vapor/src/generators/operation.ts @@ -82,7 +82,7 @@ export function genEffects( for (let i = 0; i < effects.length; i++) { const effect = (context.currentRenderEffect = effects[i]) effect.conditions = [] - effect.overrides = [] + effect.overwrites = [] push(...genEffect(effect, context)) } return frag @@ -110,7 +110,7 @@ export function genEffect( const condition: CodeFragment[] = conditions.length > 0 ? [NEWLINE, `if(`, ...conditions.join(' && '), `) return`] - : [undefined] + : [] push( '{', INDENT_START, @@ -121,7 +121,9 @@ export function genEffect( '})', ) } else { - push(...operationsExps.filter(frag => frag !== NEWLINE), ')') + const condition: CodeFragment[] = + conditions.length > 0 ? [...conditions, ' && '] : [] + push(...condition, ...operationsExps.filter(frag => frag !== NEWLINE), ')') } return frag diff --git a/packages/compiler-vapor/src/generators/prop.ts b/packages/compiler-vapor/src/generators/prop.ts index 18361d923..67d39074a 100644 --- a/packages/compiler-vapor/src/generators/prop.ts +++ b/packages/compiler-vapor/src/generators/prop.ts @@ -43,28 +43,24 @@ export function genSetProp( oper: SetPropIRNode, context: CodegenContext, ): CodeFragment[] { - const { vaporHelper, currentRenderEffect } = context + const { vaporHelper, currentRenderEffect, shouldTrackEffectDeps } = context const { prop: { key, values, modifier }, tag, } = oper - const { inVFor, inVOnce, operations } = currentRenderEffect! - const { helperName, omitKey } = getRuntimeHelper(tag, key.content, modifier) let propValue = genPropValue(values, context) - let condition: CodeFragment[] = [] - if (!inVFor && !inVOnce) { - if (operations.length === 1) { - condition = processValues(context, [propValue]) - } else { - processValues(context, [propValue], '===') - } + if (shouldTrackEffectDeps()) { + processValues( + context, + [propValue], + currentRenderEffect!.operations.length === 1 ? '!==' : '===', + ) } return [ NEWLINE, - ...condition, ...genCall( [vaporHelper(helperName), null], `n${oper.element}`, @@ -257,7 +253,7 @@ export function processValues( context: CodegenContext, values: CodeFragment[][], oper: '===' | '!==' = '!==', -): (string | undefined)[] { +): string[] { const conditions: string[] = [] values.forEach(value => { const condition = processValue(context, value, oper) @@ -266,7 +262,7 @@ export function processValues( return conditions.length > 0 ? (context.currentRenderEffect!.conditions = [...new Set(conditions)]) - : [undefined] + : [] } function processValue( @@ -275,7 +271,7 @@ function processValue( oper: '===' | '!==' = '!==', ): string[] | undefined { const { currentRenderEffect } = context - const { deps, overrides, conditions } = currentRenderEffect! + const { deps, overwrites, conditions } = currentRenderEffect! for (let frag of values) { if ( !frag || @@ -290,13 +286,13 @@ function processValue( if (isString(frag)) frag = [frag] let [newName, , , idName] = frag if (idName) { - const rewriteStr = `_${idName} = ${newName}` - if (overrides.includes(rewriteStr)) continue + const overwrite = `_${idName} = ${newName}` + if (overwrites.includes(overwrite)) continue - overrides.push(rewriteStr) + overwrites.push(overwrite) deps.push(idName) conditions.push(`_${idName} ${oper} ${newName}`) - frag[0] = rewriteStr + frag[0] = overwrite } } diff --git a/packages/compiler-vapor/src/generators/text.ts b/packages/compiler-vapor/src/generators/text.ts index a0a7a7354..a4aead015 100644 --- a/packages/compiler-vapor/src/generators/text.ts +++ b/packages/compiler-vapor/src/generators/text.ts @@ -14,19 +14,13 @@ export function genSetText( oper: SetTextIRNode, context: CodegenContext, ): CodeFragment[] { - const { vaporHelper, currentRenderEffect } = context + const { vaporHelper, shouldTrackEffectDeps } = context const { element, values } = oper - const { inVFor, inVOnce } = currentRenderEffect! - const texts = values.map(value => genExpression(value, context, undefined)) - let conditions: CodeFragment[] = [] - if (!inVOnce && !inVFor) { - conditions = processValues(context, texts) + const texts = values.map(value => genExpression(value, context)) + if (shouldTrackEffectDeps()) { + processValues(context, texts) } - return [ - NEWLINE, - ...conditions, - ...genCall(vaporHelper('setText'), `n${element}`, ...texts), - ] + return [NEWLINE, ...genCall(vaporHelper('setText'), `n${element}`, ...texts)] } export function genCreateTextNode( diff --git a/packages/compiler-vapor/src/ir/index.ts b/packages/compiler-vapor/src/ir/index.ts index feaa5c8f9..c710f1a35 100644 --- a/packages/compiler-vapor/src/ir/index.ts +++ b/packages/compiler-vapor/src/ir/index.ts @@ -269,7 +269,7 @@ export interface IREffect { operations: OperationNode[] deps: string[] conditions: string[] - overrides: string[] + overwrites: string[] inVFor: boolean inVOnce: boolean } diff --git a/packages/compiler-vapor/src/transform.ts b/packages/compiler-vapor/src/transform.ts index 57a6c38ac..5c015204d 100644 --- a/packages/compiler-vapor/src/transform.ts +++ b/packages/compiler-vapor/src/transform.ts @@ -152,7 +152,7 @@ export class TransformContext { expressions, operations, conditions: [], - overrides: [], + overwrites: [], deps: [], inVFor: this.inVFor > 0, inVOnce: this.inVOnce, From d4a5418f2d75b2ea38a95ff9ab88cc0319a5d29a Mon Sep 17 00:00:00 2001 From: daiwei Date: Tue, 3 Dec 2024 18:03:43 +0800 Subject: [PATCH 15/47] wip: save --- .../__snapshots__/compile.spec.ts.snap | 11 +- .../transformChildren.spec.ts.snap | 4 +- .../transformElement.spec.ts.snap | 14 ++- .../__snapshots__/vBind.spec.ts.snap | 108 +++++++++--------- .../__snapshots__/vHtml.spec.ts.snap | 4 +- .../transforms/__snapshots__/vIf.spec.ts.snap | 6 +- .../__snapshots__/vModel.spec.ts.snap | 3 +- .../__snapshots__/vText.spec.ts.snap | 4 +- packages/compiler-vapor/src/generate.ts | 2 +- .../compiler-vapor/src/generators/html.ts | 4 +- .../src/generators/operation.ts | 2 +- .../compiler-vapor/src/generators/prop.ts | 33 +++--- .../compiler-vapor/src/generators/text.ts | 4 +- 13 files changed, 106 insertions(+), 93 deletions(-) diff --git a/packages/compiler-vapor/__tests__/__snapshots__/compile.spec.ts.snap b/packages/compiler-vapor/__tests__/__snapshots__/compile.spec.ts.snap index 726e0d854..132a0c8be 100644 --- a/packages/compiler-vapor/__tests__/__snapshots__/compile.spec.ts.snap +++ b/packages/compiler-vapor/__tests__/__snapshots__/compile.spec.ts.snap @@ -7,7 +7,7 @@ const t0 = _template("
") export function render(_ctx, $props, $emit, $attrs, $slots) { const n0 = t0() let _count; - _renderEffect(() => _count !== _ctx.count && _setText(n0, "count is ", _count = _ctx.count, ".")) + _renderEffect(() => _count !== _ctx.count && _setText(n0, "count is ", (_count = _ctx.count), ".")) return n0 }" `; @@ -164,7 +164,7 @@ export function render(_ctx, $props, $emit, $attrs, $slots) { const n2 = _createTextNode(() => [_ctx.bar]) _insert([n1, n2], n3) let _foo; - _renderEffect(() => _foo !== _ctx.foo && _setDOMProp(n3, "id", _foo = _ctx.foo)) + _renderEffect(() => _foo !== _ctx.foo && _setDOMProp(n3, "id", (_foo = _ctx.foo))) return [n0, n3] }" `; @@ -188,9 +188,9 @@ export function render(_ctx) { _delegate(n0, "click", () => _ctx.handleClick) _setInheritAttrs(["id"]) let _count; - _renderEffect(() => _count !== _ctx.count && _setText(n0, _count = _ctx.count, "foo", _ctx.count, "foo", _ctx.count)) + _renderEffect(() => _count !== _ctx.count && _setText(n0, (_count = _ctx.count), "foo", _ctx.count, "foo", _ctx.count)) let _count; - _renderEffect(() => _count !== _ctx.count && _setDOMProp(n0, "id", _count = _ctx.count)) + _renderEffect(() => _count !== _ctx.count && _setDOMProp(n0, "id", (_count = _ctx.count))) return n0 }" `; @@ -206,7 +206,8 @@ exports[`compile > expression parsing > v-bind 1`] = ` "((_ctx) => { const n0 = t0() _setInheritAttrs(true) - _renderEffect(() => _setDynamicProps(n0, [{ [key.value+1]: _unref(foo)[key.value+1]() }], true)) + let _key_value, _foo; + _renderEffect(() => _key_value !== key.value && _foo !== _unref(foo) && _setDynamicProps(n0, [{ [(_key_value = key.value)+1]: (_foo = _unref(foo))[key.value+1]() }], true)) return n0 })()" `; diff --git a/packages/compiler-vapor/__tests__/transforms/__snapshots__/transformChildren.spec.ts.snap b/packages/compiler-vapor/__tests__/transforms/__snapshots__/transformChildren.spec.ts.snap index e00125eaf..7dbf0156a 100644 --- a/packages/compiler-vapor/__tests__/transforms/__snapshots__/transformChildren.spec.ts.snap +++ b/packages/compiler-vapor/__tests__/transforms/__snapshots__/transformChildren.spec.ts.snap @@ -12,9 +12,9 @@ export function render(_ctx) { const n1 = _createTextNode(() => [_ctx.second, " ", _ctx.third, " "]) _insert(n1, n4, n3) let _first; - _renderEffect(() => _first !== _ctx.first && _setText(n0, _first = _ctx.first)) + _renderEffect(() => _first !== _ctx.first && _setText(n0, (_first = _ctx.first))) let _forth; - _renderEffect(() => _forth !== _ctx.forth && _setText(n2, _forth = _ctx.forth)) + _renderEffect(() => _forth !== _ctx.forth && _setText(n2, (_forth = _ctx.forth))) return n4 }" `; diff --git a/packages/compiler-vapor/__tests__/transforms/__snapshots__/transformElement.spec.ts.snap b/packages/compiler-vapor/__tests__/transforms/__snapshots__/transformElement.spec.ts.snap index 555e194df..f7d078181 100644 --- a/packages/compiler-vapor/__tests__/transforms/__snapshots__/transformElement.spec.ts.snap +++ b/packages/compiler-vapor/__tests__/transforms/__snapshots__/transformElement.spec.ts.snap @@ -304,7 +304,7 @@ export function render(_ctx) { const n0 = t0() _setInheritAttrs(["class"]) let _isBar; - _renderEffect(() => _isBar !== _ctx.isBar && _setClass(n0, ["foo", { bar: _isBar = _ctx.isBar }], true)) + _renderEffect(() => _isBar !== _ctx.isBar && _setClass(n0, ["foo", { bar: (_isBar = _ctx.isBar) }], true)) return n0 }" `; @@ -356,7 +356,8 @@ const t0 = _template("
") export function render(_ctx) { const n0 = t0() _setInheritAttrs(true) - _renderEffect(() => _setDynamicProps(n0, [_ctx.obj], true)) + let _obj; + _renderEffect(() => _obj !== _ctx.obj && _setDynamicProps(n0, [(_obj = _ctx.obj)], true)) return n0 }" `; @@ -368,7 +369,8 @@ const t0 = _template("
") export function render(_ctx) { const n0 = t0() _setInheritAttrs(true) - _renderEffect(() => _setDynamicProps(n0, [{ id: "foo" }, _ctx.obj], true)) + let _obj; + _renderEffect(() => _obj !== _ctx.obj && _setDynamicProps(n0, [{ id: "foo" }, (_obj = _ctx.obj)], true)) return n0 }" `; @@ -380,7 +382,8 @@ const t0 = _template("
") export function render(_ctx) { const n0 = t0() _setInheritAttrs(true) - _renderEffect(() => _setDynamicProps(n0, [_ctx.obj, { id: "foo" }], true)) + let _obj; + _renderEffect(() => _obj !== _ctx.obj && _setDynamicProps(n0, [(_obj = _ctx.obj), { id: "foo" }], true)) return n0 }" `; @@ -392,7 +395,8 @@ const t0 = _template("
") export function render(_ctx) { const n0 = t0() _setInheritAttrs(true) - _renderEffect(() => _setDynamicProps(n0, [{ id: "foo" }, _ctx.obj, { class: "bar" }], true)) + let _obj; + _renderEffect(() => _obj !== _ctx.obj && _setDynamicProps(n0, [{ id: "foo" }, (_obj = _ctx.obj), { class: "bar" }], true)) return n0 }" `; 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 50b218d09..944fe34d5 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() _setInheritAttrs(["foo-bar"]) let _id; - _renderEffect(() => _id !== _ctx.id && _setAttr(n0, "foo-bar", _id = _ctx.id)) + _renderEffect(() => _id !== _ctx.id && _setAttr(n0, "foo-bar", (_id = _ctx.id))) return n0 }" `; @@ -21,7 +21,7 @@ export function render(_ctx) { const n0 = t0() _setInheritAttrs(["innerHTML"]) let _foo; - _renderEffect(() => _foo !== _ctx.foo && _setAttr(n0, "innerHTML", _foo = _ctx.foo)) + _renderEffect(() => _foo !== _ctx.foo && _setAttr(n0, "innerHTML", (_foo = _ctx.foo))) return n0 }" `; @@ -34,7 +34,7 @@ export function render(_ctx) { const n0 = t0() _setInheritAttrs(["foo-bar"]) let _fooBar; - _renderEffect(() => _fooBar !== _ctx.fooBar && _setAttr(n0, "foo-bar", _fooBar = _ctx.fooBar)) + _renderEffect(() => _fooBar !== _ctx.fooBar && _setAttr(n0, "foo-bar", (_fooBar = _ctx.fooBar))) return n0 }" `; @@ -47,7 +47,7 @@ export function render(_ctx) { const n0 = t0() _setInheritAttrs(["value"]) let _foo; - _renderEffect(() => _foo !== _ctx.foo && _setAttr(n0, "value", _foo = _ctx.foo)) + _renderEffect(() => _foo !== _ctx.foo && _setAttr(n0, "value", (_foo = _ctx.foo))) return n0 }" `; @@ -60,7 +60,7 @@ export function render(_ctx) { const n0 = t0() _setInheritAttrs(["textContent"]) let _foo; - _renderEffect(() => _foo !== _ctx.foo && _setAttr(n0, "textContent", _foo = _ctx.foo)) + _renderEffect(() => _foo !== _ctx.foo && _setAttr(n0, "textContent", (_foo = _ctx.foo))) return n0 }" `; @@ -73,7 +73,7 @@ export function render(_ctx) { const n0 = t0() _setInheritAttrs(["value"]) let _foo; - _renderEffect(() => _foo !== _ctx.foo && _setAttr(n0, "value", _foo = _ctx.foo)) + _renderEffect(() => _foo !== _ctx.foo && _setAttr(n0, "value", (_foo = _ctx.foo))) return n0 }" `; @@ -86,7 +86,7 @@ export function render(_ctx) { const n0 = t0() _setInheritAttrs(["fooBar"]) let _id; - _renderEffect(() => _id !== _ctx.id && _setDynamicProp(n0, "fooBar", _id = _ctx.id)) + _renderEffect(() => _id !== _ctx.id && _setDynamicProp(n0, "fooBar", (_id = _ctx.id))) return n0 }" `; @@ -99,7 +99,8 @@ const t0 = _template("
") export function render(_ctx) { const n0 = t0() _setInheritAttrs(true) - _renderEffect(() => _setDynamicProps(n0, [{ [_camelize(_ctx.foo)]: _ctx.id }], true)) + let _foo, _id; + _renderEffect(() => _foo !== _ctx.foo && _id !== _ctx.id && _setDynamicProps(n0, [{ [_camelize((_foo = _ctx.foo))]: (_id = _ctx.id) }], true)) return n0 }" `; @@ -112,7 +113,7 @@ export function render(_ctx) { const n0 = t0() _setInheritAttrs(["fooBar"]) let _fooBar; - _renderEffect(() => _fooBar !== _ctx.fooBar && _setDynamicProp(n0, "fooBar", _fooBar = _ctx.fooBar)) + _renderEffect(() => _fooBar !== _ctx.fooBar && _setDynamicProp(n0, "fooBar", (_fooBar = _ctx.fooBar))) return n0 }" `; @@ -125,7 +126,7 @@ export function render(_ctx) { const n0 = t0() _setInheritAttrs(["fooBar"]) let _id; - _renderEffect(() => _id !== _ctx.id && _setDOMProp(n0, "fooBar", _id = _ctx.id)) + _renderEffect(() => _id !== _ctx.id && _setDOMProp(n0, "fooBar", (_id = _ctx.id))) return n0 }" `; @@ -138,7 +139,7 @@ export function render(_ctx) { const n0 = t0() _setInheritAttrs(["innerHTML"]) let _foo; - _renderEffect(() => _foo !== _ctx.foo && _setHtml(n0, _foo = _ctx.foo)) + _renderEffect(() => _foo !== _ctx.foo && _setHtml(n0, (_foo = _ctx.foo))) return n0 }" `; @@ -151,7 +152,7 @@ export function render(_ctx) { const n0 = t0() _setInheritAttrs(["fooBar"]) let _fooBar; - _renderEffect(() => _fooBar !== _ctx.fooBar && _setDOMProp(n0, "fooBar", _fooBar = _ctx.fooBar)) + _renderEffect(() => _fooBar !== _ctx.fooBar && _setDOMProp(n0, "fooBar", (_fooBar = _ctx.fooBar))) return n0 }" `; @@ -164,7 +165,7 @@ export function render(_ctx) { const n0 = t0() _setInheritAttrs(["value"]) let _foo; - _renderEffect(() => _foo !== _ctx.foo && _setDOMProp(n0, "value", _foo = _ctx.foo)) + _renderEffect(() => _foo !== _ctx.foo && _setDOMProp(n0, "value", (_foo = _ctx.foo))) return n0 }" `; @@ -177,7 +178,7 @@ export function render(_ctx) { const n0 = t0() _setInheritAttrs(["textContent"]) let _foo; - _renderEffect(() => _foo !== _ctx.foo && _setText(n0, _foo = _ctx.foo)) + _renderEffect(() => _foo !== _ctx.foo && _setText(n0, (_foo = _ctx.foo))) return n0 }" `; @@ -190,7 +191,7 @@ export function render(_ctx) { const n0 = t0() _setInheritAttrs(["value"]) let _foo; - _renderEffect(() => _foo !== _ctx.foo && _setValue(n0, _foo = _ctx.foo)) + _renderEffect(() => _foo !== _ctx.foo && _setValue(n0, (_foo = _ctx.foo))) return n0 }" `; @@ -203,7 +204,7 @@ export function render(_ctx) { const n0 = t0() _setInheritAttrs(["fooBar"]) let _id; - _renderEffect(() => _id !== _ctx.id && _setDOMProp(n0, "fooBar", _id = _ctx.id)) + _renderEffect(() => _id !== _ctx.id && _setDOMProp(n0, "fooBar", (_id = _ctx.id))) return n0 }" `; @@ -215,7 +216,8 @@ const t0 = _template("
") export function render(_ctx) { const n0 = t0() _setInheritAttrs(true) - _renderEffect(() => _setDynamicProps(n0, [{ ["." + _ctx.fooBar]: _ctx.id }], true)) + let _fooBar, _id; + _renderEffect(() => _fooBar !== _ctx.fooBar && _id !== _ctx.id && _setDynamicProps(n0, [{ ["." + (_fooBar = _ctx.fooBar)]: (_id = _ctx.id) }], true)) return n0 }" `; @@ -228,7 +230,7 @@ export function render(_ctx) { const n0 = t0() _setInheritAttrs(["innerHTML"]) let _foo; - _renderEffect(() => _foo !== _ctx.foo && _setHtml(n0, _foo = _ctx.foo)) + _renderEffect(() => _foo !== _ctx.foo && _setHtml(n0, (_foo = _ctx.foo))) return n0 }" `; @@ -241,7 +243,7 @@ export function render(_ctx) { const n0 = t0() _setInheritAttrs(["fooBar"]) let _fooBar; - _renderEffect(() => _fooBar !== _ctx.fooBar && _setDOMProp(n0, "fooBar", _fooBar = _ctx.fooBar)) + _renderEffect(() => _fooBar !== _ctx.fooBar && _setDOMProp(n0, "fooBar", (_fooBar = _ctx.fooBar))) return n0 }" `; @@ -254,7 +256,7 @@ export function render(_ctx) { const n0 = t0() _setInheritAttrs(["value"]) let _foo; - _renderEffect(() => _foo !== _ctx.foo && _setDOMProp(n0, "value", _foo = _ctx.foo)) + _renderEffect(() => _foo !== _ctx.foo && _setDOMProp(n0, "value", (_foo = _ctx.foo))) return n0 }" `; @@ -267,7 +269,7 @@ export function render(_ctx) { const n0 = t0() _setInheritAttrs(["textContent"]) let _foo; - _renderEffect(() => _foo !== _ctx.foo && _setText(n0, _foo = _ctx.foo)) + _renderEffect(() => _foo !== _ctx.foo && _setText(n0, (_foo = _ctx.foo))) return n0 }" `; @@ -280,7 +282,7 @@ export function render(_ctx) { const n0 = t0() _setInheritAttrs(["value"]) let _foo; - _renderEffect(() => _foo !== _ctx.foo && _setValue(n0, _foo = _ctx.foo)) + _renderEffect(() => _foo !== _ctx.foo && _setValue(n0, (_foo = _ctx.foo))) return n0 }" `; @@ -293,7 +295,7 @@ export function render(_ctx) { const n0 = t0() _setInheritAttrs(["innerHTML"]) let _foo; - _renderEffect(() => _foo !== _ctx.foo && _setHtml(n0, _foo = _ctx.foo)) + _renderEffect(() => _foo !== _ctx.foo && _setHtml(n0, (_foo = _ctx.foo))) return n0 }" `; @@ -306,7 +308,7 @@ export function render(_ctx) { const n0 = t0() _setInheritAttrs(["textContent"]) let _foo; - _renderEffect(() => _foo !== _ctx.foo && _setText(n0, _foo = _ctx.foo)) + _renderEffect(() => _foo !== _ctx.foo && _setText(n0, (_foo = _ctx.foo))) return n0 }" `; @@ -319,7 +321,7 @@ export function render(_ctx) { const n0 = t0() _setInheritAttrs(["value"]) let _foo; - _renderEffect(() => _foo !== _ctx.foo && _setValue(n0, _foo = _ctx.foo)) + _renderEffect(() => _foo !== _ctx.foo && _setValue(n0, (_foo = _ctx.foo))) return n0 }" `; @@ -332,7 +334,7 @@ export function render(_ctx) { const n0 = t0() _setInheritAttrs(["value"]) let _foo; - _renderEffect(() => _foo !== _ctx.foo && _setDynamicProp(n0, "value", _foo = _ctx.foo)) + _renderEffect(() => _foo !== _ctx.foo && _setDynamicProp(n0, "value", (_foo = _ctx.foo))) return n0 }" `; @@ -345,15 +347,15 @@ export function render(_ctx) { const n0 = t0() _setInheritAttrs(["id", "title", "lang", "dir", "tabindex"]) let _id; - _renderEffect(() => _id !== _ctx.id && _setDOMProp(n0, "id", _id = _ctx.id)) + _renderEffect(() => _id !== _ctx.id && _setDOMProp(n0, "id", (_id = _ctx.id))) let _title; - _renderEffect(() => _title !== _ctx.title && _setDOMProp(n0, "title", _title = _ctx.title)) + _renderEffect(() => _title !== _ctx.title && _setDOMProp(n0, "title", (_title = _ctx.title))) let _lang; - _renderEffect(() => _lang !== _ctx.lang && _setDOMProp(n0, "lang", _lang = _ctx.lang)) + _renderEffect(() => _lang !== _ctx.lang && _setDOMProp(n0, "lang", (_lang = _ctx.lang))) let _dir; - _renderEffect(() => _dir !== _ctx.dir && _setDOMProp(n0, "dir", _dir = _ctx.dir)) + _renderEffect(() => _dir !== _ctx.dir && _setDOMProp(n0, "dir", (_dir = _ctx.dir))) let _tabindex; - _renderEffect(() => _tabindex !== _ctx.tabindex && _setDOMProp(n0, "tabindex", _tabindex = _ctx.tabindex)) + _renderEffect(() => _tabindex !== _ctx.tabindex && _setDOMProp(n0, "tabindex", (_tabindex = _ctx.tabindex))) return n0 }" `; @@ -366,15 +368,15 @@ export function render(_ctx) { const n0 = t0() _setInheritAttrs(["autofucus", "dir", "displaystyle", "mathcolor", "tabindex"]) let _autofucus; - _renderEffect(() => _autofucus !== _ctx.autofucus && _setDOMProp(n0, "autofucus", _autofucus = _ctx.autofucus)) + _renderEffect(() => _autofucus !== _ctx.autofucus && _setDOMProp(n0, "autofucus", (_autofucus = _ctx.autofucus))) let _dir; - _renderEffect(() => _dir !== _ctx.dir && _setDOMProp(n0, "dir", _dir = _ctx.dir)) + _renderEffect(() => _dir !== _ctx.dir && _setDOMProp(n0, "dir", (_dir = _ctx.dir))) let _displaystyle; - _renderEffect(() => _displaystyle !== _ctx.displaystyle && _setDOMProp(n0, "displaystyle", _displaystyle = _ctx.displaystyle)) + _renderEffect(() => _displaystyle !== _ctx.displaystyle && _setDOMProp(n0, "displaystyle", (_displaystyle = _ctx.displaystyle))) let _mathcolor; - _renderEffect(() => _mathcolor !== _ctx.mathcolor && _setDOMProp(n0, "mathcolor", _mathcolor = _ctx.mathcolor)) + _renderEffect(() => _mathcolor !== _ctx.mathcolor && _setDOMProp(n0, "mathcolor", (_mathcolor = _ctx.mathcolor))) let _tabindex; - _renderEffect(() => _tabindex !== _ctx.tabindex && _setDOMProp(n0, "tabindex", _tabindex = _ctx.tabindex)) + _renderEffect(() => _tabindex !== _ctx.tabindex && _setDOMProp(n0, "tabindex", (_tabindex = _ctx.tabindex))) return n0 }" `; @@ -387,11 +389,11 @@ export function render(_ctx) { const n0 = t0() _setInheritAttrs(["id", "lang", "tabindex"]) let _id; - _renderEffect(() => _id !== _ctx.id && _setDOMProp(n0, "id", _id = _ctx.id)) + _renderEffect(() => _id !== _ctx.id && _setDOMProp(n0, "id", (_id = _ctx.id))) let _lang; - _renderEffect(() => _lang !== _ctx.lang && _setDOMProp(n0, "lang", _lang = _ctx.lang)) + _renderEffect(() => _lang !== _ctx.lang && _setDOMProp(n0, "lang", (_lang = _ctx.lang))) let _tabindex; - _renderEffect(() => _tabindex !== _ctx.tabindex && _setDOMProp(n0, "tabindex", _tabindex = _ctx.tabindex)) + _renderEffect(() => _tabindex !== _ctx.tabindex && _setDOMProp(n0, "tabindex", (_tabindex = _ctx.tabindex))) return n0 }" `; @@ -415,21 +417,21 @@ export function render(_ctx) { const n5 = t5() const n6 = t6() let _spellcheck; - _renderEffect(() => _spellcheck !== _ctx.spellcheck && _setAttr(n0, "spellcheck", _spellcheck = _ctx.spellcheck)) + _renderEffect(() => _spellcheck !== _ctx.spellcheck && _setAttr(n0, "spellcheck", (_spellcheck = _ctx.spellcheck))) let _draggable; - _renderEffect(() => _draggable !== _ctx.draggable && _setAttr(n0, "draggable", _draggable = _ctx.draggable)) + _renderEffect(() => _draggable !== _ctx.draggable && _setAttr(n0, "draggable", (_draggable = _ctx.draggable))) let _translate; - _renderEffect(() => _translate !== _ctx.translate && _setAttr(n0, "translate", _translate = _ctx.translate)) + _renderEffect(() => _translate !== _ctx.translate && _setAttr(n0, "translate", (_translate = _ctx.translate))) let _form; - _renderEffect(() => _form !== _ctx.form && _setAttr(n0, "form", _form = _ctx.form)) + _renderEffect(() => _form !== _ctx.form && _setAttr(n0, "form", (_form = _ctx.form))) let _list; - _renderEffect(() => _list !== _ctx.list && _setAttr(n1, "list", _list = _ctx.list)) + _renderEffect(() => _list !== _ctx.list && _setAttr(n1, "list", (_list = _ctx.list))) let _type; - _renderEffect(() => _type !== _ctx.type && _setAttr(n2, "type", _type = _ctx.type)) + _renderEffect(() => _type !== _ctx.type && _setAttr(n2, "type", (_type = _ctx.type))) let _width; _renderEffect(() => { if(_width === _ctx.width) return - _setAttr(n3, "width", _width = _ctx.width) + _setAttr(n3, "width", (_width = _ctx.width)) _setAttr(n4, "width", _ctx.width) _setAttr(n5, "width", _ctx.width) _setAttr(n6, "width", _ctx.width) @@ -437,7 +439,7 @@ export function render(_ctx) { let _height; _renderEffect(() => { if(_height === _ctx.height) return - _setAttr(n3, "height", _height = _ctx.height) + _setAttr(n3, "height", (_height = _ctx.height)) _setAttr(n4, "height", _ctx.height) _setAttr(n5, "height", _ctx.height) _setAttr(n6, "height", _ctx.height) @@ -454,7 +456,7 @@ export function render(_ctx) { const n0 = t0() _setInheritAttrs(["id"]) let _id; - _renderEffect(() => _id !== _ctx.id && _setDOMProp(n0, "id", _id = _ctx.id)) + _renderEffect(() => _id !== _ctx.id && _setDOMProp(n0, "id", (_id = _ctx.id))) return n0 }" `; @@ -466,7 +468,8 @@ const t0 = _template("
") export function render(_ctx) { const n0 = t0() _setInheritAttrs(true) - _renderEffect(() => _setDynamicProps(n0, [{ [_ctx.id]: _ctx.id, [_ctx.title]: _ctx.title }], true)) + let _id, _title; + _renderEffect(() => _id !== _ctx.id && _title !== _ctx.title && _setDynamicProps(n0, [{ [(_id = _ctx.id)]: _ctx.id, [(_title = _ctx.title)]: _ctx.title }], true)) return n0 }" `; @@ -478,7 +481,8 @@ const t0 = _template("
") export function render(_ctx) { const n0 = t0() _setInheritAttrs(true) - _renderEffect(() => _setDynamicProps(n0, [{ [_ctx.id]: _ctx.id, foo: "bar", checked: "" }], true)) + let _id; + _renderEffect(() => _id !== _ctx.id && _setDynamicProps(n0, [{ [(_id = _ctx.id)]: _ctx.id, foo: "bar", checked: "" }], true)) return n0 }" `; @@ -491,7 +495,7 @@ export function render(_ctx) { const n0 = t0() _setInheritAttrs(["camel-case"]) let _camelCase; - _renderEffect(() => _camelCase !== _ctx.camelCase && _setDynamicProp(n0, "camel-case", _camelCase = _ctx.camelCase)) + _renderEffect(() => _camelCase !== _ctx.camelCase && _setDynamicProp(n0, "camel-case", (_camelCase = _ctx.camelCase))) return n0 }" `; @@ -504,7 +508,7 @@ export function render(_ctx) { const n0 = t0() _setInheritAttrs(["id"]) let _id; - _renderEffect(() => _id !== _ctx.id && _setDOMProp(n0, "id", _id = _ctx.id)) + _renderEffect(() => _id !== _ctx.id && _setDOMProp(n0, "id", (_id = _ctx.id))) return n0 }" `; diff --git a/packages/compiler-vapor/__tests__/transforms/__snapshots__/vHtml.spec.ts.snap b/packages/compiler-vapor/__tests__/transforms/__snapshots__/vHtml.spec.ts.snap index ea3260d3c..034ff1d27 100644 --- a/packages/compiler-vapor/__tests__/transforms/__snapshots__/vHtml.spec.ts.snap +++ b/packages/compiler-vapor/__tests__/transforms/__snapshots__/vHtml.spec.ts.snap @@ -7,7 +7,7 @@ const t0 = _template("
") export function render(_ctx, $props, $emit, $attrs, $slots) { const n0 = t0() let _code; - _renderEffect(() => _code !== _ctx.code && _setHtml(n0, _code = _ctx.code)) + _renderEffect(() => _code !== _ctx.code && _setHtml(n0, (_code = _ctx.code))) return n0 }" `; @@ -19,7 +19,7 @@ const t0 = _template("
") export function render(_ctx) { const n0 = t0() let _test; - _renderEffect(() => _test !== _ctx.test && _setHtml(n0, _test = _ctx.test)) + _renderEffect(() => _test !== _ctx.test && _setHtml(n0, (_test = _ctx.test))) return n0 }" `; diff --git a/packages/compiler-vapor/__tests__/transforms/__snapshots__/vIf.spec.ts.snap b/packages/compiler-vapor/__tests__/transforms/__snapshots__/vIf.spec.ts.snap index f4c72c4a8..b77fc3332 100644 --- a/packages/compiler-vapor/__tests__/transforms/__snapshots__/vIf.spec.ts.snap +++ b/packages/compiler-vapor/__tests__/transforms/__snapshots__/vIf.spec.ts.snap @@ -8,7 +8,7 @@ export function render(_ctx) { const n0 = _createIf(() => (_ctx.ok), () => { const n2 = t0() let _msg; - _renderEffect(() => _msg !== _ctx.msg && _setText(n2, _msg = _ctx.msg)) + _renderEffect(() => _msg !== _ctx.msg && _setText(n2, (_msg = _ctx.msg))) return n2 }) return n0 @@ -39,7 +39,7 @@ export function render(_ctx) { return [n10, n11] })) let _text; - _renderEffect(() => _text !== _ctx.text && _setText(n13, _text = _ctx.text)) + _renderEffect(() => _text !== _ctx.text && _setText(n13, (_text = _ctx.text))) return [n0, n13] }" `; @@ -73,7 +73,7 @@ export function render(_ctx) { const n3 = t1() const n4 = t2() let _msg; - _renderEffect(() => _msg !== _ctx.msg && _setText(n4, _msg = _ctx.msg)) + _renderEffect(() => _msg !== _ctx.msg && _setText(n4, (_msg = _ctx.msg))) return [n2, n3, n4] }) return n0 diff --git a/packages/compiler-vapor/__tests__/transforms/__snapshots__/vModel.spec.ts.snap b/packages/compiler-vapor/__tests__/transforms/__snapshots__/vModel.spec.ts.snap index 04ceb3c5a..bdb4acdd4 100644 --- a/packages/compiler-vapor/__tests__/transforms/__snapshots__/vModel.spec.ts.snap +++ b/packages/compiler-vapor/__tests__/transforms/__snapshots__/vModel.spec.ts.snap @@ -254,7 +254,8 @@ export function render(_ctx) { _withDirectives(n0, [[_vModelDynamic, () => _ctx.model]]) _delegate(n0, "update:modelValue", () => $event => (_ctx.model = $event)) _setInheritAttrs(true) - _renderEffect(() => _setDynamicProps(n0, [_ctx.obj], true)) + let _obj; + _renderEffect(() => _obj !== _ctx.obj && _setDynamicProps(n0, [(_obj = _ctx.obj)], true)) return n0 }" `; diff --git a/packages/compiler-vapor/__tests__/transforms/__snapshots__/vText.spec.ts.snap b/packages/compiler-vapor/__tests__/transforms/__snapshots__/vText.spec.ts.snap index 90d3625d3..2d689022a 100644 --- a/packages/compiler-vapor/__tests__/transforms/__snapshots__/vText.spec.ts.snap +++ b/packages/compiler-vapor/__tests__/transforms/__snapshots__/vText.spec.ts.snap @@ -7,7 +7,7 @@ const t0 = _template("
") export function render(_ctx, $props, $emit, $attrs, $slots) { const n0 = t0() let _str; - _renderEffect(() => _str !== _ctx.str && _setText(n0, _str = _ctx.str)) + _renderEffect(() => _str !== _ctx.str && _setText(n0, (_str = _ctx.str))) return n0 }" `; @@ -19,7 +19,7 @@ const t0 = _template("
") export function render(_ctx) { const n0 = t0() let _test; - _renderEffect(() => _test !== _ctx.test && _setText(n0, _test = _ctx.test)) + _renderEffect(() => _test !== _ctx.test && _setText(n0, (_test = _ctx.test))) return n0 }" `; diff --git a/packages/compiler-vapor/src/generate.ts b/packages/compiler-vapor/src/generate.ts index 8a05376b4..c44ff473a 100644 --- a/packages/compiler-vapor/src/generate.ts +++ b/packages/compiler-vapor/src/generate.ts @@ -37,7 +37,7 @@ export class CodegenContext { currentRenderEffect: IREffect | undefined = undefined - shouldTrackEffectDeps = (): boolean => { + shouldGenEffectDeps = (): boolean => { return !!( this.currentRenderEffect && !this.currentRenderEffect.inVOnce && diff --git a/packages/compiler-vapor/src/generators/html.ts b/packages/compiler-vapor/src/generators/html.ts index de638d68d..548b47840 100644 --- a/packages/compiler-vapor/src/generators/html.ts +++ b/packages/compiler-vapor/src/generators/html.ts @@ -8,10 +8,10 @@ export function genSetHtml( oper: SetHtmlIRNode, context: CodegenContext, ): CodeFragment[] { - const { vaporHelper, shouldTrackEffectDeps } = context + const { vaporHelper, shouldGenEffectDeps } = context const { value, element } = oper let html = genExpression(value, context) - if (shouldTrackEffectDeps()) { + if (shouldGenEffectDeps()) { processValues(context, [html]) } return [NEWLINE, ...genCall(vaporHelper('setHtml'), `n${element}`, html)] diff --git a/packages/compiler-vapor/src/generators/operation.ts b/packages/compiler-vapor/src/generators/operation.ts index 9b10bcece..b80d45169 100644 --- a/packages/compiler-vapor/src/generators/operation.ts +++ b/packages/compiler-vapor/src/generators/operation.ts @@ -122,7 +122,7 @@ export function genEffect( ) } else { const condition: CodeFragment[] = - conditions.length > 0 ? [...conditions, ' && '] : [] + conditions.length > 0 ? [...conditions.join(' && '), ' && '] : [] push(...condition, ...operationsExps.filter(frag => frag !== NEWLINE), ')') } diff --git a/packages/compiler-vapor/src/generators/prop.ts b/packages/compiler-vapor/src/generators/prop.ts index 67d39074a..22d16b4a6 100644 --- a/packages/compiler-vapor/src/generators/prop.ts +++ b/packages/compiler-vapor/src/generators/prop.ts @@ -43,7 +43,7 @@ export function genSetProp( oper: SetPropIRNode, context: CodegenContext, ): CodeFragment[] { - const { vaporHelper, currentRenderEffect, shouldTrackEffectDeps } = context + const { vaporHelper, currentRenderEffect, shouldGenEffectDeps } = context const { prop: { key, values, modifier }, tag, @@ -51,7 +51,7 @@ export function genSetProp( const { helperName, omitKey } = getRuntimeHelper(tag, key.content, modifier) let propValue = genPropValue(values, context) - if (shouldTrackEffectDeps()) { + if (shouldGenEffectDeps()) { processValues( context, [propValue], @@ -79,23 +79,25 @@ export function genDynamicProps( oper: SetDynamicPropsIRNode, context: CodegenContext, ): CodeFragment[] { - const { vaporHelper } = context + const { vaporHelper, shouldGenEffectDeps } = context + const values = oper.props.map(props => + Array.isArray(props) + ? genLiteralObjectProps(props, context) // static and dynamic arg props + : props.kind === IRDynamicPropsKind.ATTRIBUTE + ? genLiteralObjectProps([props], context) // dynamic arg props + : genExpression(props.value, context), + ) // v-bind="" + + if (shouldGenEffectDeps()) { + processValues(context, values) + } + return [ NEWLINE, ...genCall( vaporHelper('setDynamicProps'), `n${oper.element}`, - genMulti( - DELIMITERS_ARRAY, - ...oper.props.map( - props => - Array.isArray(props) - ? genLiteralObjectProps(props, context) // static and dynamic arg props - : props.kind === IRDynamicPropsKind.ATTRIBUTE - ? genLiteralObjectProps([props], context) // dynamic arg props - : genExpression(props.value, context), // v-bind="" - ), - ), + genMulti(DELIMITERS_ARRAY, ...values), oper.root && 'true', ), ] @@ -286,7 +288,8 @@ function processValue( if (isString(frag)) frag = [frag] let [newName, , , idName] = frag if (idName) { - const overwrite = `_${idName} = ${newName}` + idName = idName.replace(/\./g, '_') + const overwrite = `(_${idName} = ${newName})` if (overwrites.includes(overwrite)) continue overwrites.push(overwrite) diff --git a/packages/compiler-vapor/src/generators/text.ts b/packages/compiler-vapor/src/generators/text.ts index a4aead015..4c9c86334 100644 --- a/packages/compiler-vapor/src/generators/text.ts +++ b/packages/compiler-vapor/src/generators/text.ts @@ -14,10 +14,10 @@ export function genSetText( oper: SetTextIRNode, context: CodegenContext, ): CodeFragment[] { - const { vaporHelper, shouldTrackEffectDeps } = context + const { vaporHelper, shouldGenEffectDeps } = context const { element, values } = oper const texts = values.map(value => genExpression(value, context)) - if (shouldTrackEffectDeps()) { + if (shouldGenEffectDeps()) { processValues(context, texts) } return [NEWLINE, ...genCall(vaporHelper('setText'), `n${element}`, ...texts)] From 3a7339271da7fee4173d7b29c7eadeb38efe4533 Mon Sep 17 00:00:00 2001 From: daiwei Date: Tue, 3 Dec 2024 20:04:49 +0800 Subject: [PATCH 16/47] wip: save --- packages/compiler-vapor/src/generate.ts | 1 + packages/compiler-vapor/src/generators/prop.ts | 7 +++++-- 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/packages/compiler-vapor/src/generate.ts b/packages/compiler-vapor/src/generate.ts index c44ff473a..d62dbcecf 100644 --- a/packages/compiler-vapor/src/generate.ts +++ b/packages/compiler-vapor/src/generate.ts @@ -36,6 +36,7 @@ export class CodegenContext { delegates: Set = new Set() currentRenderEffect: IREffect | undefined = undefined + seenRenderEffectDeps: Set = new Set() shouldGenEffectDeps = (): boolean => { return !!( diff --git a/packages/compiler-vapor/src/generators/prop.ts b/packages/compiler-vapor/src/generators/prop.ts index 22d16b4a6..d09abbc29 100644 --- a/packages/compiler-vapor/src/generators/prop.ts +++ b/packages/compiler-vapor/src/generators/prop.ts @@ -272,7 +272,7 @@ function processValue( values: CodeFragment[], oper: '===' | '!==' = '!==', ): string[] | undefined { - const { currentRenderEffect } = context + const { currentRenderEffect, seenRenderEffectDeps } = context const { deps, overwrites, conditions } = currentRenderEffect! for (let frag of values) { if ( @@ -293,7 +293,10 @@ function processValue( if (overwrites.includes(overwrite)) continue overwrites.push(overwrite) - deps.push(idName) + if (!seenRenderEffectDeps.has(idName)) { + deps.push(idName) + seenRenderEffectDeps.add(idName) + } conditions.push(`_${idName} ${oper} ${newName}`) frag[0] = overwrite } From 3c05552866ae325edca318c65387f1056dcd0e4f Mon Sep 17 00:00:00 2001 From: daiwei Date: Wed, 4 Dec 2024 09:19:38 +0800 Subject: [PATCH 17/47] wip: save --- .../__snapshots__/compile.spec.ts.snap | 4 ++-- packages/compiler-vapor/src/generate.ts | 3 +-- .../src/generators/operation.ts | 3 +-- .../compiler-vapor/src/generators/prop.ts | 22 +++++++++++-------- packages/compiler-vapor/src/ir/index.ts | 2 +- 5 files changed, 18 insertions(+), 16 deletions(-) diff --git a/packages/compiler-vapor/__tests__/__snapshots__/compile.spec.ts.snap b/packages/compiler-vapor/__tests__/__snapshots__/compile.spec.ts.snap index 132a0c8be..7092652ac 100644 --- a/packages/compiler-vapor/__tests__/__snapshots__/compile.spec.ts.snap +++ b/packages/compiler-vapor/__tests__/__snapshots__/compile.spec.ts.snap @@ -189,8 +189,8 @@ export function render(_ctx) { _setInheritAttrs(["id"]) let _count; _renderEffect(() => _count !== _ctx.count && _setText(n0, (_count = _ctx.count), "foo", _ctx.count, "foo", _ctx.count)) - let _count; - _renderEffect(() => _count !== _ctx.count && _setDOMProp(n0, "id", (_count = _ctx.count))) + let _count1; + _renderEffect(() => _count1 !== _ctx.count && _setDOMProp(n0, "id", (_count1 = _ctx.count))) return n0 }" `; diff --git a/packages/compiler-vapor/src/generate.ts b/packages/compiler-vapor/src/generate.ts index d62dbcecf..f4ccb1846 100644 --- a/packages/compiler-vapor/src/generate.ts +++ b/packages/compiler-vapor/src/generate.ts @@ -36,8 +36,7 @@ export class CodegenContext { delegates: Set = new Set() currentRenderEffect: IREffect | undefined = undefined - seenRenderEffectDeps: Set = new Set() - + renderEffectSeemNames: Record = Object.create(null) shouldGenEffectDeps = (): boolean => { return !!( this.currentRenderEffect && diff --git a/packages/compiler-vapor/src/generators/operation.ts b/packages/compiler-vapor/src/generators/operation.ts index b80d45169..c6e13d8b7 100644 --- a/packages/compiler-vapor/src/generators/operation.ts +++ b/packages/compiler-vapor/src/generators/operation.ts @@ -101,8 +101,7 @@ export function genEffect( const operationsExps = genOperations(operations, context) if (deps.length) { - const vars = [...new Set(deps)].map(v => `_${v}`) - frag.splice(1, 0, `let ${vars.join(', ')};`, NEWLINE) + frag.splice(1, 0, `let ${[...new Set(deps)].join(', ')};`, NEWLINE) } const newlineCount = operationsExps.filter(frag => frag === NEWLINE).length diff --git a/packages/compiler-vapor/src/generators/prop.ts b/packages/compiler-vapor/src/generators/prop.ts index d09abbc29..6ae5a453c 100644 --- a/packages/compiler-vapor/src/generators/prop.ts +++ b/packages/compiler-vapor/src/generators/prop.ts @@ -272,7 +272,7 @@ function processValue( values: CodeFragment[], oper: '===' | '!==' = '!==', ): string[] | undefined { - const { currentRenderEffect, seenRenderEffectDeps } = context + const { currentRenderEffect, renderEffectSeemNames } = context const { deps, overwrites, conditions } = currentRenderEffect! for (let frag of values) { if ( @@ -288,16 +288,20 @@ function processValue( if (isString(frag)) frag = [frag] let [newName, , , idName] = frag if (idName) { - idName = idName.replace(/\./g, '_') - const overwrite = `(_${idName} = ${newName})` - if (overwrites.includes(overwrite)) continue + idName = idName.replace(/[^\w]/g, '_') + if (overwrites.includes(idName)) continue + overwrites.push(idName) - overwrites.push(overwrite) - if (!seenRenderEffectDeps.has(idName)) { - deps.push(idName) - seenRenderEffectDeps.add(idName) + idName = `_${idName}` + if (deps.includes(idName)) continue + if (renderEffectSeemNames[idName] === undefined) { + renderEffectSeemNames[idName] = 0 + } else { + idName += ++renderEffectSeemNames[idName] } - conditions.push(`_${idName} ${oper} ${newName}`) + let overwrite = `(${idName} = ${newName})` + deps.push(idName) + conditions.push(`${idName} ${oper} ${newName}`) frag[0] = overwrite } } diff --git a/packages/compiler-vapor/src/ir/index.ts b/packages/compiler-vapor/src/ir/index.ts index c710f1a35..1bb9a5f56 100644 --- a/packages/compiler-vapor/src/ir/index.ts +++ b/packages/compiler-vapor/src/ir/index.ts @@ -268,8 +268,8 @@ export interface IREffect { expressions: SimpleExpressionNode[] operations: OperationNode[] deps: string[] - conditions: string[] overwrites: string[] + conditions: string[] inVFor: boolean inVOnce: boolean } From 926bfe1d7780ba70712f7eb5f58e9926d2c6321f Mon Sep 17 00:00:00 2001 From: daiwei Date: Wed, 4 Dec 2024 09:31:22 +0800 Subject: [PATCH 18/47] wip: save --- packages/compiler-vapor/src/generators/operation.ts | 8 +++----- packages/compiler-vapor/src/generators/prop.ts | 11 ++++++----- packages/compiler-vapor/src/ir/index.ts | 4 ++-- packages/compiler-vapor/src/transform.ts | 4 ++-- 4 files changed, 13 insertions(+), 14 deletions(-) diff --git a/packages/compiler-vapor/src/generators/operation.ts b/packages/compiler-vapor/src/generators/operation.ts index c6e13d8b7..f5bb8031e 100644 --- a/packages/compiler-vapor/src/generators/operation.ts +++ b/packages/compiler-vapor/src/generators/operation.ts @@ -81,8 +81,6 @@ export function genEffects( const [frag, push] = buildCodeFragment() for (let i = 0; i < effects.length; i++) { const effect = (context.currentRenderEffect = effects[i]) - effect.conditions = [] - effect.overwrites = [] push(...genEffect(effect, context)) } return frag @@ -97,11 +95,11 @@ export function genEffect( NEWLINE, `${vaporHelper('renderEffect')}(() => `, ) - const { deps, conditions } = currentRenderEffect! + const { varNamesToDeclare, conditions } = currentRenderEffect! const operationsExps = genOperations(operations, context) - if (deps.length) { - frag.splice(1, 0, `let ${[...new Set(deps)].join(', ')};`, NEWLINE) + if (varNamesToDeclare.size) { + frag.splice(1, 0, `let ${[...varNamesToDeclare].join(', ')};`, NEWLINE) } const newlineCount = operationsExps.filter(frag => frag === NEWLINE).length diff --git a/packages/compiler-vapor/src/generators/prop.ts b/packages/compiler-vapor/src/generators/prop.ts index 6ae5a453c..1add3a114 100644 --- a/packages/compiler-vapor/src/generators/prop.ts +++ b/packages/compiler-vapor/src/generators/prop.ts @@ -273,7 +273,8 @@ function processValue( oper: '===' | '!==' = '!==', ): string[] | undefined { const { currentRenderEffect, renderEffectSeemNames } = context - const { deps, overwrites, conditions } = currentRenderEffect! + const { varNamesToDeclare, varNamesOverwritten, conditions } = + currentRenderEffect! for (let frag of values) { if ( !frag || @@ -289,18 +290,18 @@ function processValue( let [newName, , , idName] = frag if (idName) { idName = idName.replace(/[^\w]/g, '_') - if (overwrites.includes(idName)) continue - overwrites.push(idName) + if (varNamesOverwritten.has(idName)) continue + varNamesOverwritten.add(idName) idName = `_${idName}` - if (deps.includes(idName)) continue + if (varNamesToDeclare.has(idName)) continue if (renderEffectSeemNames[idName] === undefined) { renderEffectSeemNames[idName] = 0 } else { idName += ++renderEffectSeemNames[idName] } let overwrite = `(${idName} = ${newName})` - deps.push(idName) + varNamesToDeclare.add(idName) conditions.push(`${idName} ${oper} ${newName}`) frag[0] = overwrite } diff --git a/packages/compiler-vapor/src/ir/index.ts b/packages/compiler-vapor/src/ir/index.ts index 1bb9a5f56..85a3634bf 100644 --- a/packages/compiler-vapor/src/ir/index.ts +++ b/packages/compiler-vapor/src/ir/index.ts @@ -267,8 +267,8 @@ export interface IRDynamicInfo { export interface IREffect { expressions: SimpleExpressionNode[] operations: OperationNode[] - deps: string[] - overwrites: string[] + varNamesToDeclare: Set + varNamesOverwritten: Set conditions: string[] inVFor: boolean inVOnce: boolean diff --git a/packages/compiler-vapor/src/transform.ts b/packages/compiler-vapor/src/transform.ts index 5c015204d..7a3f4ccdd 100644 --- a/packages/compiler-vapor/src/transform.ts +++ b/packages/compiler-vapor/src/transform.ts @@ -152,8 +152,8 @@ export class TransformContext { expressions, operations, conditions: [], - overwrites: [], - deps: [], + varNamesToDeclare: new Set(), + varNamesOverwritten: new Set(), inVFor: this.inVFor > 0, inVOnce: this.inVOnce, }) From 55478f46b8560b32250f6c806e0b5d45e5d08e03 Mon Sep 17 00:00:00 2001 From: daiwei Date: Wed, 4 Dec 2024 09:49:33 +0800 Subject: [PATCH 19/47] wip: save --- .../src/generators/operation.ts | 2 +- .../compiler-vapor/src/generators/prop.ts | 48 +++++++------------ 2 files changed, 19 insertions(+), 31 deletions(-) diff --git a/packages/compiler-vapor/src/generators/operation.ts b/packages/compiler-vapor/src/generators/operation.ts index f5bb8031e..2babb4bc8 100644 --- a/packages/compiler-vapor/src/generators/operation.ts +++ b/packages/compiler-vapor/src/generators/operation.ts @@ -90,7 +90,7 @@ export function genEffect( { operations }: IREffect, context: CodegenContext, ): CodeFragment[] { - let { vaporHelper, currentRenderEffect } = context + const { vaporHelper, currentRenderEffect } = context const [frag, push] = buildCodeFragment( NEWLINE, `${vaporHelper('renderEffect')}(() => `, diff --git a/packages/compiler-vapor/src/generators/prop.ts b/packages/compiler-vapor/src/generators/prop.ts index 1add3a114..c8477e698 100644 --- a/packages/compiler-vapor/src/generators/prop.ts +++ b/packages/compiler-vapor/src/generators/prop.ts @@ -17,9 +17,6 @@ import { type CodeFragment, DELIMITERS_ARRAY, DELIMITERS_OBJECT, - INDENT_END, - INDENT_START, - LF, NEWLINE, genCall, genMulti, @@ -27,12 +24,12 @@ import { import { attributeCache, canSetValueDirectly, + isArray, isHTMLGlobalAttr, isHTMLTag, isMathMLGlobalAttr, isMathMLTag, isSVGTag, - isString, isSvgGlobalAttr, shouldSetAsAttr, toHandlerKey, @@ -276,34 +273,25 @@ function processValue( const { varNamesToDeclare, varNamesOverwritten, conditions } = currentRenderEffect! for (let frag of values) { - if ( - !frag || - frag === NEWLINE || - frag === INDENT_START || - frag === INDENT_END || - frag === LF - ) { - continue - } + if (!isArray(frag)) continue - if (isString(frag)) frag = [frag] - let [newName, , , idName] = frag - if (idName) { - idName = idName.replace(/[^\w]/g, '_') - if (varNamesOverwritten.has(idName)) continue - varNamesOverwritten.add(idName) + let [newName, , , rawName] = frag + if (rawName) { + let name = rawName.replace(/[^\w]/g, '_') + if (varNamesOverwritten.has(name)) continue + varNamesOverwritten.add(name) - idName = `_${idName}` - if (varNamesToDeclare.has(idName)) continue - if (renderEffectSeemNames[idName] === undefined) { - renderEffectSeemNames[idName] = 0 - } else { - idName += ++renderEffectSeemNames[idName] - } - let overwrite = `(${idName} = ${newName})` - varNamesToDeclare.add(idName) - conditions.push(`${idName} ${oper} ${newName}`) - frag[0] = overwrite + name = `_${name}` + if (varNamesToDeclare.has(name)) continue + + if (renderEffectSeemNames[name] === undefined) + renderEffectSeemNames[name] = 0 + else name += ++renderEffectSeemNames[name] + + varNamesToDeclare.add(name) + conditions.push(`${name} ${oper} ${newName}`) + // replace the original code fragment with the assignment expression + frag[0] = `(${name} = ${newName})` } } From 420eed0c112f6cbf6d085780c850bf84006ebc6d Mon Sep 17 00:00:00 2001 From: daiwei Date: Wed, 4 Dec 2024 10:09:01 +0800 Subject: [PATCH 20/47] wip: update snap --- .../compiler-vapor/__tests__/compile.spec.ts | 4 +- .../transforms/transformElement.spec.ts | 10 +- .../__tests__/transforms/vBind.spec.ts | 130 +++++++++++------- 3 files changed, 87 insertions(+), 57 deletions(-) diff --git a/packages/compiler-vapor/__tests__/compile.spec.ts b/packages/compiler-vapor/__tests__/compile.spec.ts index 2aeb777da..e1596b64a 100644 --- a/packages/compiler-vapor/__tests__/compile.spec.ts +++ b/packages/compiler-vapor/__tests__/compile.spec.ts @@ -194,7 +194,9 @@ describe('compile', () => { }) expect(code).matchSnapshot() expect(code).contains('key.value+1') - expect(code).contains('_unref(foo)[key.value+1]()') + expect(code).contains( + '_key_value !== key.value && _foo !== _unref(foo) && _setDynamicProps(n0, [{ [(_key_value = key.value)+1]: (_foo = _unref(foo))[key.value+1]() }], true)', + ) }) // TODO: add more test for expression parsing (v-on, v-slot, v-for) diff --git a/packages/compiler-vapor/__tests__/transforms/transformElement.spec.ts b/packages/compiler-vapor/__tests__/transforms/transformElement.spec.ts index 2b5f89464..9871f27c3 100644 --- a/packages/compiler-vapor/__tests__/transforms/transformElement.spec.ts +++ b/packages/compiler-vapor/__tests__/transforms/transformElement.spec.ts @@ -588,7 +588,9 @@ describe('compiler: element transform', () => { ], }, ]) - expect(code).contains('_setDynamicProps(n0, [_ctx.obj], true)') + expect(code).contains( + '_obj !== _ctx.obj && _setDynamicProps(n0, [(_obj = _ctx.obj)], true)', + ) }) test('v-bind="obj" after static prop', () => { @@ -625,7 +627,7 @@ describe('compiler: element transform', () => { }, ]) expect(code).contains( - '_setDynamicProps(n0, [{ id: "foo" }, _ctx.obj], true)', + '_obj !== _ctx.obj && _setDynamicProps(n0, [{ id: "foo" }, (_obj = _ctx.obj)], true)', ) }) @@ -653,7 +655,7 @@ describe('compiler: element transform', () => { }, ]) expect(code).contains( - '_setDynamicProps(n0, [_ctx.obj, { id: "foo" }], true)', + '_obj !== _ctx.obj && _setDynamicProps(n0, [(_obj = _ctx.obj), { id: "foo" }], true)', ) }) @@ -682,7 +684,7 @@ describe('compiler: element transform', () => { }, ]) expect(code).contains( - '_setDynamicProps(n0, [{ id: "foo" }, _ctx.obj, { class: "bar" }], true)', + '_obj !== _ctx.obj && _setDynamicProps(n0, [{ id: "foo" }, (_obj = _ctx.obj), { class: "bar" }], true)', ) }) diff --git a/packages/compiler-vapor/__tests__/transforms/vBind.spec.ts b/packages/compiler-vapor/__tests__/transforms/vBind.spec.ts index 058aabe8b..c5b33cded 100644 --- a/packages/compiler-vapor/__tests__/transforms/vBind.spec.ts +++ b/packages/compiler-vapor/__tests__/transforms/vBind.spec.ts @@ -75,7 +75,7 @@ describe('compiler v-bind', () => { expect(code).matchSnapshot() expect(code).contains( - '_id !== _ctx.id && _setDOMProp(n0, "id", _id = _ctx.id)', + '_id !== _ctx.id && _setDOMProp(n0, "id", (_id = _ctx.id))', ) }) @@ -107,7 +107,7 @@ describe('compiler v-bind', () => { }, }) expect(code).contains( - '_id !== _ctx.id && _setDOMProp(n0, "id", _id = _ctx.id)', + '_id !== _ctx.id && _setDOMProp(n0, "id", (_id = _ctx.id))', ) }) @@ -131,7 +131,7 @@ describe('compiler v-bind', () => { }, }) expect(code).contains( - '_camelCase !== _ctx.camelCase && _setDynamicProp(n0, "camel-case", _camelCase = _ctx.camelCase)', + '_camelCase !== _ctx.camelCase && _setDynamicProp(n0, "camel-case", (_camelCase = _ctx.camelCase))', ) }) @@ -177,7 +177,7 @@ describe('compiler v-bind', () => { ], }) expect(code).contains( - '_setDynamicProps(n0, [{ [_ctx.id]: _ctx.id, [_ctx.title]: _ctx.title }], true)', + '_id !== _ctx.id && _title !== _ctx.title && _setDynamicProps(n0, [{ [(_id = _ctx.id)]: _ctx.id, [(_title = _ctx.title)]: _ctx.title }], true)', ) }) @@ -230,7 +230,7 @@ describe('compiler v-bind', () => { ], }) expect(code).contains( - '_setDynamicProps(n0, [{ [_ctx.id]: _ctx.id, foo: "bar", checked: "" }], true)', + '_id !== _ctx.id && _setDynamicProps(n0, [{ [(_id = _ctx.id)]: _ctx.id, foo: "bar", checked: "" }], true)', ) }) @@ -293,7 +293,7 @@ describe('compiler v-bind', () => { expect(code).matchSnapshot() expect(code).contains( - '_id !== _ctx.id && _setDynamicProp(n0, "fooBar", _id = _ctx.id)', + '_id !== _ctx.id && _setDynamicProp(n0, "fooBar", (_id = _ctx.id))', ) }) @@ -319,7 +319,7 @@ describe('compiler v-bind', () => { }) expect(code).contains('renderEffect') expect(code).contains( - '_fooBar !== _ctx.fooBar && _setDynamicProp(n0, "fooBar", _fooBar = _ctx.fooBar)', + '_fooBar !== _ctx.fooBar && _setDynamicProp(n0, "fooBar", (_fooBar = _ctx.fooBar))', ) }) @@ -351,7 +351,7 @@ describe('compiler v-bind', () => { expect(code).matchSnapshot() expect(code).contains('renderEffect') expect(code).contains( - `_setDynamicProps(n0, [{ [_camelize(_ctx.foo)]: _ctx.id }], true)`, + `_foo !== _ctx.foo && _id !== _ctx.id && _setDynamicProps(n0, [{ [_camelize((_foo = _ctx.foo))]: (_id = _ctx.id) }], true)`, ) }) @@ -379,7 +379,7 @@ describe('compiler v-bind', () => { }) expect(code).contains('renderEffect') expect(code).contains( - '_id !== _ctx.id && _setDOMProp(n0, "fooBar", _id = _ctx.id)', + '_id !== _ctx.id && _setDOMProp(n0, "fooBar", (_id = _ctx.id))', ) }) @@ -405,7 +405,7 @@ describe('compiler v-bind', () => { }) expect(code).contains('renderEffect') expect(code).contains( - '_fooBar !== _ctx.fooBar && _setDOMProp(n0, "fooBar", _fooBar = _ctx.fooBar)', + '_fooBar !== _ctx.fooBar && _setDOMProp(n0, "fooBar", (_fooBar = _ctx.fooBar))', ) }) @@ -436,7 +436,7 @@ describe('compiler v-bind', () => { }) expect(code).contains('renderEffect') expect(code).contains( - `_setDynamicProps(n0, [{ ["." + _ctx.fooBar]: _ctx.id }], true)`, + `_fooBar !== _ctx.fooBar && _id !== _ctx.id && _setDynamicProps(n0, [{ ["." + (_fooBar = _ctx.fooBar)]: (_id = _ctx.id) }], true)`, ) }) @@ -464,7 +464,7 @@ describe('compiler v-bind', () => { }) expect(code).contains('renderEffect') expect(code).contains( - '_id !== _ctx.id && _setDOMProp(n0, "fooBar", _id = _ctx.id)', + '_id !== _ctx.id && _setDOMProp(n0, "fooBar", (_id = _ctx.id))', ) }) @@ -490,51 +490,63 @@ describe('compiler v-bind', () => { }) expect(code).contains('renderEffect') expect(code).contains( - '_fooBar !== _ctx.fooBar && _setDOMProp(n0, "fooBar", _fooBar = _ctx.fooBar)', + '_fooBar !== _ctx.fooBar && _setDOMProp(n0, "fooBar", (_fooBar = _ctx.fooBar))', ) }) test('.prop modifier w/ innerHTML', () => { const { code } = compileWithVBind(`
`) expect(code).matchSnapshot() - expect(code).contains('_foo !== _ctx.foo && _setHtml(n0, _foo = _ctx.foo)') + expect(code).contains( + '_foo !== _ctx.foo && _setHtml(n0, (_foo = _ctx.foo))', + ) }) test('.prop modifier (shorthand) w/ innerHTML', () => { const { code } = compileWithVBind(`
`) expect(code).matchSnapshot() - expect(code).contains('_foo !== _ctx.foo && _setHtml(n0, _foo = _ctx.foo)') + expect(code).contains( + '_foo !== _ctx.foo && _setHtml(n0, (_foo = _ctx.foo))', + ) }) test('.prop modifier w/ textContent', () => { const { code } = compileWithVBind(`
`) expect(code).matchSnapshot() - expect(code).contains('_foo !== _ctx.foo && _setText(n0, _foo = _ctx.foo)') + expect(code).contains( + '_foo !== _ctx.foo && _setText(n0, (_foo = _ctx.foo))', + ) }) test('.prop modifier (shorthand) w/ textContent', () => { const { code } = compileWithVBind(`
`) expect(code).matchSnapshot() - expect(code).contains('_foo !== _ctx.foo && _setText(n0, _foo = _ctx.foo)') + expect(code).contains( + '_foo !== _ctx.foo && _setText(n0, (_foo = _ctx.foo))', + ) }) test('.prop modifier w/ value', () => { const { code } = compileWithVBind(`
`) expect(code).matchSnapshot() - expect(code).contains('_foo !== _ctx.foo && _setValue(n0, _foo = _ctx.foo)') + expect(code).contains( + '_foo !== _ctx.foo && _setValue(n0, (_foo = _ctx.foo))', + ) }) test('.prop modifier (shorthand) w/ value', () => { const { code } = compileWithVBind(`
`) expect(code).matchSnapshot() - expect(code).contains('_foo !== _ctx.foo && _setValue(n0, _foo = _ctx.foo)') + expect(code).contains( + '_foo !== _ctx.foo && _setValue(n0, (_foo = _ctx.foo))', + ) }) test('.prop modifier w/ progress value', () => { const { code } = compileWithVBind(``) expect(code).matchSnapshot() expect(code).contains( - '_foo !== _ctx.foo && _setDOMProp(n0, "value", _foo = _ctx.foo)', + '_foo !== _ctx.foo && _setDOMProp(n0, "value", (_foo = _ctx.foo))', ) }) @@ -542,7 +554,7 @@ describe('compiler v-bind', () => { const { code } = compileWithVBind(``) expect(code).matchSnapshot() expect(code).contains( - '_foo !== _ctx.foo && _setDOMProp(n0, "value", _foo = _ctx.foo)', + '_foo !== _ctx.foo && _setDOMProp(n0, "value", (_foo = _ctx.foo))', ) }) @@ -568,7 +580,7 @@ describe('compiler v-bind', () => { }) expect(code).contains('renderEffect') expect(code).contains( - '_id !== _ctx.id && _setAttr(n0, "foo-bar", _id = _ctx.id)', + '_id !== _ctx.id && _setAttr(n0, "foo-bar", (_id = _ctx.id))', ) }) @@ -595,7 +607,7 @@ describe('compiler v-bind', () => { expect(code).contains('renderEffect') expect(code).contains( - '_fooBar !== _ctx.fooBar && _setAttr(n0, "foo-bar", _fooBar = _ctx.fooBar)', + '_fooBar !== _ctx.fooBar && _setAttr(n0, "foo-bar", (_fooBar = _ctx.fooBar))', ) }) @@ -603,7 +615,7 @@ describe('compiler v-bind', () => { const { code } = compileWithVBind(`
`) expect(code).matchSnapshot() expect(code).contains( - '_foo !== _ctx.foo && _setAttr(n0, "innerHTML", _foo = _ctx.foo)', + '_foo !== _ctx.foo && _setAttr(n0, "innerHTML", (_foo = _ctx.foo))', ) }) @@ -611,7 +623,7 @@ describe('compiler v-bind', () => { const { code } = compileWithVBind(`
`) expect(code).matchSnapshot() expect(code).contains( - '_foo !== _ctx.foo && _setAttr(n0, "textContent", _foo = _ctx.foo)', + '_foo !== _ctx.foo && _setAttr(n0, "textContent", (_foo = _ctx.foo))', ) }) @@ -619,7 +631,7 @@ describe('compiler v-bind', () => { const { code } = compileWithVBind(`
`) expect(code).matchSnapshot() expect(code).contains( - '_foo !== _ctx.foo && _setAttr(n0, "value", _foo = _ctx.foo)', + '_foo !== _ctx.foo && _setAttr(n0, "value", (_foo = _ctx.foo))', ) }) @@ -627,7 +639,7 @@ describe('compiler v-bind', () => { const { code } = compileWithVBind(``) expect(code).matchSnapshot() expect(code).contains( - '_foo !== _ctx.foo && _setAttr(n0, "value", _foo = _ctx.foo)', + '_foo !== _ctx.foo && _setAttr(n0, "value", (_foo = _ctx.foo))', ) }) @@ -644,25 +656,27 @@ describe('compiler v-bind', () => { expect(code).matchSnapshot() expect(code).contains( - '_spellcheck !== _ctx.spellcheck && _setAttr(n0, "spellcheck", _spellcheck = _ctx.spellcheck)', + '_spellcheck !== _ctx.spellcheck && _setAttr(n0, "spellcheck", (_spellcheck = _ctx.spellcheck))', ) expect(code).contains( - '_draggable !== _ctx.draggable && _setAttr(n0, "draggable", _draggable = _ctx.draggable)', + '_draggable !== _ctx.draggable && _setAttr(n0, "draggable", (_draggable = _ctx.draggable))', ) expect(code).contains( - '_translate !== _ctx.translate && _setAttr(n0, "translate", _translate = _ctx.translate)', + '_translate !== _ctx.translate && _setAttr(n0, "translate", (_translate = _ctx.translate))', ) expect(code).contains( - '_form !== _ctx.form && _setAttr(n0, "form", _form = _ctx.form)', + '_form !== _ctx.form && _setAttr(n0, "form", (_form = _ctx.form))', ) expect(code).contains( - '_list !== _ctx.list && _setAttr(n1, "list", _list = _ctx.list)', + '_list !== _ctx.list && _setAttr(n1, "list", (_list = _ctx.list))', ) expect(code).contains( - '_type !== _ctx.type && _setAttr(n2, "type", _type = _ctx.type)', + '_type !== _ctx.type && _setAttr(n2, "type", (_type = _ctx.type))', ) - expect(code).contains('_setAttr(n3, "width", _width = _ctx.width)') - expect(code).contains('_setAttr(n3, "height", _height = _ctx.height)') + expect(code).contains('if(_width === _ctx.width) return') + expect(code).contains('if(_height === _ctx.height) return') + expect(code).contains('_setAttr(n3, "width", (_width = _ctx.width))') + expect(code).contains('_setAttr(n3, "height", (_height = _ctx.height))') expect(code).contains('_setAttr(n4, "width", _ctx.width)') expect(code).contains('_setAttr(n4, "height", _ctx.height)') expect(code).contains('_setAttr(n5, "width", _ctx.width)') @@ -677,12 +691,20 @@ describe('compiler v-bind', () => { expect(code).matchSnapshot() expect(code).contains( - '_id !== _ctx.id && _setDOMProp(n0, "id", _id = _ctx.id)', + '_id !== _ctx.id && _setDOMProp(n0, "id", (_id = _ctx.id))', + ) + expect(code).contains( + '_title !== _ctx.title && _setDOMProp(n0, "title", (_title = _ctx.title))', + ) + expect(code).contains( + '_lang !== _ctx.lang && _setDOMProp(n0, "lang", (_lang = _ctx.lang))', + ) + expect(code).contains( + '_dir !== _ctx.dir && _setDOMProp(n0, "dir", (_dir = _ctx.dir))', + ) + expect(code).contains( + '_tabindex !== _ctx.tabindex && _setDOMProp(n0, "tabindex", (_tabindex = _ctx.tabindex))', ) - // expect(code).contains('_setDOMProp(n0, "title", _ctx.title)') - // expect(code).contains('_setDOMProp(n0, "lang", _ctx.lang)') - // expect(code).contains('_setDOMProp(n0, "dir", _ctx.dir)') - // expect(code).contains('_setDOMProp(n0, "tabindex", _ctx.tabindex)') }) test('SVG global attributes should set as dom prop', () => { @@ -693,15 +715,15 @@ describe('compiler v-bind', () => { expect(code).matchSnapshot() expect(code).contains('let _id;') expect(code).contains( - '_id !== _ctx.id && _setDOMProp(n0, "id", _id = _ctx.id)', + '_id !== _ctx.id && _setDOMProp(n0, "id", (_id = _ctx.id))', ) expect(code).contains('let _lang;') expect(code).contains( - '_lang !== _ctx.lang && _setDOMProp(n0, "lang", _lang = _ctx.lang)', + '_lang !== _ctx.lang && _setDOMProp(n0, "lang", (_lang = _ctx.lang))', ) expect(code).contains('let _tabindex;') expect(code).contains( - '_tabindex !== _ctx.tabindex && _setDOMProp(n0, "tabindex", _tabindex = _ctx.tabindex)', + '_tabindex !== _ctx.tabindex && _setDOMProp(n0, "tabindex", (_tabindex = _ctx.tabindex))', ) }) @@ -713,23 +735,23 @@ describe('compiler v-bind', () => { expect(code).matchSnapshot() expect(code).contains('let _autofucus;') expect(code).contains( - '_autofucus !== _ctx.autofucus && _setDOMProp(n0, "autofucus", _autofucus = _ctx.autofucus)', + '_autofucus !== _ctx.autofucus && _setDOMProp(n0, "autofucus", (_autofucus = _ctx.autofucus))', ) expect(code).contains('let _dir;') expect(code).contains( - '_dir !== _ctx.dir && _setDOMProp(n0, "dir", _dir = _ctx.dir)', + '_dir !== _ctx.dir && _setDOMProp(n0, "dir", (_dir = _ctx.dir))', ) expect(code).contains('let _displaystyle;') expect(code).contains( - '_displaystyle !== _ctx.displaystyle && _setDOMProp(n0, "displaystyle", _displaystyle = _ctx.displaystyle)', + '_displaystyle !== _ctx.displaystyle && _setDOMProp(n0, "displaystyle", (_displaystyle = _ctx.displaystyle))', ) expect(code).contains('let _mathcolor;') expect(code).contains( - '_mathcolor !== _ctx.mathcolor && _setDOMProp(n0, "mathcolor", _mathcolor = _ctx.mathcolor)', + '_mathcolor !== _ctx.mathcolor && _setDOMProp(n0, "mathcolor", (_mathcolor = _ctx.mathcolor))', ) expect(code).contains('let _tabindex;') expect(code).contains( - '_tabindex !== _ctx.tabindex && _setDOMProp(n0, "tabindex", _tabindex = _ctx.tabindex)', + '_tabindex !== _ctx.tabindex && _setDOMProp(n0, "tabindex", (_tabindex = _ctx.tabindex))', ) }) @@ -739,7 +761,9 @@ describe('compiler v-bind', () => { `) expect(code).matchSnapshot() expect(code).contains('let _foo;') - expect(code).contains('_foo !== _ctx.foo && _setHtml(n0, _foo = _ctx.foo)') + expect(code).contains( + '_foo !== _ctx.foo && _setHtml(n0, (_foo = _ctx.foo))', + ) }) test(':textContext', () => { @@ -748,7 +772,9 @@ describe('compiler v-bind', () => { `) expect(code).matchSnapshot() expect(code).contains('let _foo;') - expect(code).contains('_foo !== _ctx.foo && _setText(n0, _foo = _ctx.foo)') + expect(code).contains( + '_foo !== _ctx.foo && _setText(n0, (_foo = _ctx.foo))', + ) }) test(':value', () => { @@ -758,7 +784,7 @@ describe('compiler v-bind', () => { expect(code).matchSnapshot() expect(code).contains('let _foo;') expect(code).contains( - ' _foo !== _ctx.foo && _setValue(n0, _foo = _ctx.foo)', + '_foo !== _ctx.foo && _setValue(n0, (_foo = _ctx.foo))', ) }) @@ -768,7 +794,7 @@ describe('compiler v-bind', () => { `) expect(code).matchSnapshot() expect(code).contains( - '_foo !== _ctx.foo && _setDynamicProp(n0, "value", _foo = _ctx.foo)', + ' _foo !== _ctx.foo && _setDynamicProp(n0, "value", (_foo = _ctx.foo))', ) }) From 26bb79d890a37b9180ff87f70a6f452a1341ed9d Mon Sep 17 00:00:00 2001 From: daiwei Date: Wed, 4 Dec 2024 10:20:51 +0800 Subject: [PATCH 21/47] wip: update snap --- packages/compiler-vapor/src/generators/prop.ts | 15 +++++---------- 1 file changed, 5 insertions(+), 10 deletions(-) diff --git a/packages/compiler-vapor/src/generators/prop.ts b/packages/compiler-vapor/src/generators/prop.ts index c8477e698..b1c0cce1e 100644 --- a/packages/compiler-vapor/src/generators/prop.ts +++ b/packages/compiler-vapor/src/generators/prop.ts @@ -40,7 +40,7 @@ export function genSetProp( oper: SetPropIRNode, context: CodegenContext, ): CodeFragment[] { - const { vaporHelper, currentRenderEffect, shouldGenEffectDeps } = context + const { vaporHelper, shouldGenEffectDeps } = context const { prop: { key, values, modifier }, tag, @@ -49,11 +49,7 @@ export function genSetProp( let propValue = genPropValue(values, context) if (shouldGenEffectDeps()) { - processValues( - context, - [propValue], - currentRenderEffect!.operations.length === 1 ? '!==' : '===', - ) + processValues(context, [propValue]) } return [ @@ -251,11 +247,10 @@ const getSpecialHelper = ( export function processValues( context: CodegenContext, values: CodeFragment[][], - oper: '===' | '!==' = '!==', ): string[] { const conditions: string[] = [] values.forEach(value => { - const condition = processValue(context, value, oper) + const condition = processValue(context, value) if (condition) conditions.push(...condition, ' && ') }) @@ -267,11 +262,11 @@ export function processValues( function processValue( context: CodegenContext, values: CodeFragment[], - oper: '===' | '!==' = '!==', ): string[] | undefined { const { currentRenderEffect, renderEffectSeemNames } = context - const { varNamesToDeclare, varNamesOverwritten, conditions } = + const { varNamesToDeclare, varNamesOverwritten, conditions, operations } = currentRenderEffect! + const oper = operations.length === 1 ? '!==' : '===' for (let frag of values) { if (!isArray(frag)) continue From 72e6b810fca753c3affa37f25f1fb5983d338362 Mon Sep 17 00:00:00 2001 From: daiwei Date: Wed, 4 Dec 2024 11:00:55 +0800 Subject: [PATCH 22/47] wip: add comments --- packages/compiler-vapor/src/generate.ts | 1 + packages/compiler-vapor/src/generators/operation.ts | 3 +++ packages/compiler-vapor/src/generators/prop.ts | 7 +++++-- 3 files changed, 9 insertions(+), 2 deletions(-) diff --git a/packages/compiler-vapor/src/generate.ts b/packages/compiler-vapor/src/generate.ts index f4ccb1846..4027f956d 100644 --- a/packages/compiler-vapor/src/generate.ts +++ b/packages/compiler-vapor/src/generate.ts @@ -38,6 +38,7 @@ export class CodegenContext { currentRenderEffect: IREffect | undefined = undefined renderEffectSeemNames: Record = Object.create(null) shouldGenEffectDeps = (): boolean => { + // only need to generate effect deps when it's not nested in v-once or v-for return !!( this.currentRenderEffect && !this.currentRenderEffect.inVOnce && diff --git a/packages/compiler-vapor/src/generators/operation.ts b/packages/compiler-vapor/src/generators/operation.ts index 2babb4bc8..4e4f0fe3b 100644 --- a/packages/compiler-vapor/src/generators/operation.ts +++ b/packages/compiler-vapor/src/generators/operation.ts @@ -98,12 +98,14 @@ export function genEffect( const { varNamesToDeclare, conditions } = currentRenderEffect! const operationsExps = genOperations(operations, context) + // declare variables: let _foo, _bar if (varNamesToDeclare.size) { frag.splice(1, 0, `let ${[...varNamesToDeclare].join(', ')};`, NEWLINE) } const newlineCount = operationsExps.filter(frag => frag === NEWLINE).length if (newlineCount > 1) { + // multiline early return condition: if (_foo === _ctx.foo && _bar === _ctx.bar) return const condition: CodeFragment[] = conditions.length > 0 ? [NEWLINE, `if(`, ...conditions.join(' && '), `) return`] @@ -118,6 +120,7 @@ export function genEffect( '})', ) } else { + // single line early return condition: _foo !== _ctx.foo && _bar !== _ctx.bar && const condition: CodeFragment[] = conditions.length > 0 ? [...conditions.join(' && '), ' && '] : [] push(...condition, ...operationsExps.filter(frag => frag !== NEWLINE), ')') diff --git a/packages/compiler-vapor/src/generators/prop.ts b/packages/compiler-vapor/src/generators/prop.ts index b1c0cce1e..1b0ebea7d 100644 --- a/packages/compiler-vapor/src/generators/prop.ts +++ b/packages/compiler-vapor/src/generators/prop.ts @@ -266,11 +266,14 @@ function processValue( const { currentRenderEffect, renderEffectSeemNames } = context const { varNamesToDeclare, varNamesOverwritten, conditions, operations } = currentRenderEffect! + + // for multiple values the early return condition should be `if (_foo === _ctx.foo) return` const oper = operations.length === 1 ? '!==' : '===' - for (let frag of values) { + for (const frag of values) { if (!isArray(frag)) continue - let [newName, , , rawName] = frag + // [code, newlineIndex, loc, name] -> [(_name = code), newlineIndex, loc, name] + const [newName, , , rawName] = frag if (rawName) { let name = rawName.replace(/[^\w]/g, '_') if (varNamesOverwritten.has(name)) continue From c1a36881cce6ee2e274ba44190254804c9c3cc6b Mon Sep 17 00:00:00 2001 From: daiwei Date: Wed, 4 Dec 2024 11:01:40 +0800 Subject: [PATCH 23/47] wip: add comments --- packages/compiler-vapor/src/generators/prop.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/compiler-vapor/src/generators/prop.ts b/packages/compiler-vapor/src/generators/prop.ts index 1b0ebea7d..7b11b9e03 100644 --- a/packages/compiler-vapor/src/generators/prop.ts +++ b/packages/compiler-vapor/src/generators/prop.ts @@ -267,7 +267,7 @@ function processValue( const { varNamesToDeclare, varNamesOverwritten, conditions, operations } = currentRenderEffect! - // for multiple values the early return condition should be `if (_foo === _ctx.foo) return` + // for multiline the early return condition should be `if (_foo === _ctx.foo) return` const oper = operations.length === 1 ? '!==' : '===' for (const frag of values) { if (!isArray(frag)) continue From 84adc78465f3bbb7b8a13a5ed1a72af265460180 Mon Sep 17 00:00:00 2001 From: daiwei Date: Wed, 4 Dec 2024 13:32:30 +0800 Subject: [PATCH 24/47] wip: fix incorrect condition --- .../__tests__/__snapshots__/compile.spec.ts.snap | 2 +- packages/compiler-vapor/__tests__/compile.spec.ts | 2 +- .../transforms/__snapshots__/vBind.spec.ts.snap | 6 +++--- .../__tests__/transforms/vBind.spec.ts | 6 +++--- packages/compiler-vapor/src/generators/operation.ts | 12 ++++++++++-- 5 files changed, 18 insertions(+), 10 deletions(-) diff --git a/packages/compiler-vapor/__tests__/__snapshots__/compile.spec.ts.snap b/packages/compiler-vapor/__tests__/__snapshots__/compile.spec.ts.snap index 7092652ac..2a251895a 100644 --- a/packages/compiler-vapor/__tests__/__snapshots__/compile.spec.ts.snap +++ b/packages/compiler-vapor/__tests__/__snapshots__/compile.spec.ts.snap @@ -207,7 +207,7 @@ exports[`compile > expression parsing > v-bind 1`] = ` const n0 = t0() _setInheritAttrs(true) let _key_value, _foo; - _renderEffect(() => _key_value !== key.value && _foo !== _unref(foo) && _setDynamicProps(n0, [{ [(_key_value = key.value)+1]: (_foo = _unref(foo))[key.value+1]() }], true)) + _renderEffect(() => (_key_value !== key.value || _foo !== _unref(foo)) && _setDynamicProps(n0, [{ [(_key_value = key.value)+1]: (_foo = _unref(foo))[key.value+1]() }], true)) return n0 })()" `; diff --git a/packages/compiler-vapor/__tests__/compile.spec.ts b/packages/compiler-vapor/__tests__/compile.spec.ts index e1596b64a..f2abf48f9 100644 --- a/packages/compiler-vapor/__tests__/compile.spec.ts +++ b/packages/compiler-vapor/__tests__/compile.spec.ts @@ -195,7 +195,7 @@ describe('compile', () => { expect(code).matchSnapshot() expect(code).contains('key.value+1') expect(code).contains( - '_key_value !== key.value && _foo !== _unref(foo) && _setDynamicProps(n0, [{ [(_key_value = key.value)+1]: (_foo = _unref(foo))[key.value+1]() }], true)', + '(_key_value !== key.value || _foo !== _unref(foo)) && _setDynamicProps(n0, [{ [(_key_value = key.value)+1]: (_foo = _unref(foo))[key.value+1]() }], true)', ) }) 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 944fe34d5..a56a511bb 100644 --- a/packages/compiler-vapor/__tests__/transforms/__snapshots__/vBind.spec.ts.snap +++ b/packages/compiler-vapor/__tests__/transforms/__snapshots__/vBind.spec.ts.snap @@ -100,7 +100,7 @@ export function render(_ctx) { const n0 = t0() _setInheritAttrs(true) let _foo, _id; - _renderEffect(() => _foo !== _ctx.foo && _id !== _ctx.id && _setDynamicProps(n0, [{ [_camelize((_foo = _ctx.foo))]: (_id = _ctx.id) }], true)) + _renderEffect(() => (_foo !== _ctx.foo || _id !== _ctx.id) && _setDynamicProps(n0, [{ [_camelize((_foo = _ctx.foo))]: (_id = _ctx.id) }], true)) return n0 }" `; @@ -217,7 +217,7 @@ export function render(_ctx) { const n0 = t0() _setInheritAttrs(true) let _fooBar, _id; - _renderEffect(() => _fooBar !== _ctx.fooBar && _id !== _ctx.id && _setDynamicProps(n0, [{ ["." + (_fooBar = _ctx.fooBar)]: (_id = _ctx.id) }], true)) + _renderEffect(() => (_fooBar !== _ctx.fooBar || _id !== _ctx.id) && _setDynamicProps(n0, [{ ["." + (_fooBar = _ctx.fooBar)]: (_id = _ctx.id) }], true)) return n0 }" `; @@ -469,7 +469,7 @@ export function render(_ctx) { const n0 = t0() _setInheritAttrs(true) let _id, _title; - _renderEffect(() => _id !== _ctx.id && _title !== _ctx.title && _setDynamicProps(n0, [{ [(_id = _ctx.id)]: _ctx.id, [(_title = _ctx.title)]: _ctx.title }], true)) + _renderEffect(() => (_id !== _ctx.id || _title !== _ctx.title) && _setDynamicProps(n0, [{ [(_id = _ctx.id)]: _ctx.id, [(_title = _ctx.title)]: _ctx.title }], true)) return n0 }" `; diff --git a/packages/compiler-vapor/__tests__/transforms/vBind.spec.ts b/packages/compiler-vapor/__tests__/transforms/vBind.spec.ts index c5b33cded..f69fc34f8 100644 --- a/packages/compiler-vapor/__tests__/transforms/vBind.spec.ts +++ b/packages/compiler-vapor/__tests__/transforms/vBind.spec.ts @@ -177,7 +177,7 @@ describe('compiler v-bind', () => { ], }) expect(code).contains( - '_id !== _ctx.id && _title !== _ctx.title && _setDynamicProps(n0, [{ [(_id = _ctx.id)]: _ctx.id, [(_title = _ctx.title)]: _ctx.title }], true)', + '(_id !== _ctx.id || _title !== _ctx.title) && _setDynamicProps(n0, [{ [(_id = _ctx.id)]: _ctx.id, [(_title = _ctx.title)]: _ctx.title }], true)', ) }) @@ -351,7 +351,7 @@ describe('compiler v-bind', () => { expect(code).matchSnapshot() expect(code).contains('renderEffect') expect(code).contains( - `_foo !== _ctx.foo && _id !== _ctx.id && _setDynamicProps(n0, [{ [_camelize((_foo = _ctx.foo))]: (_id = _ctx.id) }], true)`, + `(_foo !== _ctx.foo || _id !== _ctx.id) && _setDynamicProps(n0, [{ [_camelize((_foo = _ctx.foo))]: (_id = _ctx.id) }], true)`, ) }) @@ -436,7 +436,7 @@ describe('compiler v-bind', () => { }) expect(code).contains('renderEffect') expect(code).contains( - `_fooBar !== _ctx.fooBar && _id !== _ctx.id && _setDynamicProps(n0, [{ ["." + (_fooBar = _ctx.fooBar)]: (_id = _ctx.id) }], true)`, + `(_fooBar !== _ctx.fooBar || _id !== _ctx.id) && _setDynamicProps(n0, [{ ["." + (_fooBar = _ctx.fooBar)]: (_id = _ctx.id) }], true)`, ) }) diff --git a/packages/compiler-vapor/src/generators/operation.ts b/packages/compiler-vapor/src/generators/operation.ts index 4e4f0fe3b..fdef9b26d 100644 --- a/packages/compiler-vapor/src/generators/operation.ts +++ b/packages/compiler-vapor/src/generators/operation.ts @@ -120,9 +120,17 @@ export function genEffect( '})', ) } else { - // single line early return condition: _foo !== _ctx.foo && _bar !== _ctx.bar && + // single line early return condition: _foo !== _ctx.foo || _bar !== _ctx.bar && + const multiple = conditions.length > 1 const condition: CodeFragment[] = - conditions.length > 0 ? [...conditions.join(' && '), ' && '] : [] + conditions.length > 0 + ? [ + multiple ? `(` : undefined, + ...conditions.join(' || '), + multiple ? `)` : undefined, + ' && ', + ] + : [] push(...condition, ...operationsExps.filter(frag => frag !== NEWLINE), ')') } From 64368bb3689cd723f8b6d018d0f9b10c8a458413 Mon Sep 17 00:00:00 2001 From: daiwei Date: Wed, 4 Dec 2024 15:26:35 +0800 Subject: [PATCH 25/47] wip: save --- .../__snapshots__/vBind.spec.ts.snap | 16 +++--- .../__tests__/transforms/vBind.spec.ts | 8 +-- .../src/generators/operation.ts | 2 +- .../compiler-vapor/src/generators/prop.ts | 21 ++++++- packages/runtime-vapor/src/dom/prop.ts | 57 ++++++------------- packages/runtime-vapor/src/dom/style.ts | 14 ++--- 6 files changed, 56 insertions(+), 62 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 a56a511bb..86d7a6ccd 100644 --- a/packages/compiler-vapor/__tests__/transforms/__snapshots__/vBind.spec.ts.snap +++ b/packages/compiler-vapor/__tests__/transforms/__snapshots__/vBind.spec.ts.snap @@ -85,8 +85,8 @@ const t0 = _template("
") export function render(_ctx) { const n0 = t0() _setInheritAttrs(["fooBar"]) - let _id; - _renderEffect(() => _id !== _ctx.id && _setDynamicProp(n0, "fooBar", (_id = _ctx.id))) + let _id, _prev_id; + _renderEffect(() => _id !== _ctx.id && _setDynamicProp(n0, "fooBar", _prev_id, (_prev_id = (_id = _ctx.id)))) return n0 }" `; @@ -112,8 +112,8 @@ const t0 = _template("
") export function render(_ctx) { const n0 = t0() _setInheritAttrs(["fooBar"]) - let _fooBar; - _renderEffect(() => _fooBar !== _ctx.fooBar && _setDynamicProp(n0, "fooBar", (_fooBar = _ctx.fooBar))) + let _fooBar, _prev_fooBar; + _renderEffect(() => _fooBar !== _ctx.fooBar && _setDynamicProp(n0, "fooBar", _prev_fooBar, (_prev_fooBar = (_fooBar = _ctx.fooBar)))) return n0 }" `; @@ -333,8 +333,8 @@ const t0 = _template("") export function render(_ctx) { const n0 = t0() _setInheritAttrs(["value"]) - let _foo; - _renderEffect(() => _foo !== _ctx.foo && _setDynamicProp(n0, "value", (_foo = _ctx.foo))) + let _foo, _prev_foo; + _renderEffect(() => _foo !== _ctx.foo && _setDynamicProp(n0, "value", _prev_foo, (_prev_foo = (_foo = _ctx.foo)))) return n0 }" `; @@ -494,8 +494,8 @@ const t0 = _template("
") export function render(_ctx) { const n0 = t0() _setInheritAttrs(["camel-case"]) - let _camelCase; - _renderEffect(() => _camelCase !== _ctx.camelCase && _setDynamicProp(n0, "camel-case", (_camelCase = _ctx.camelCase))) + let _camelCase, _prev_camelCase; + _renderEffect(() => _camelCase !== _ctx.camelCase && _setDynamicProp(n0, "camel-case", _prev_camelCase, (_prev_camelCase = (_camelCase = _ctx.camelCase)))) return n0 }" `; diff --git a/packages/compiler-vapor/__tests__/transforms/vBind.spec.ts b/packages/compiler-vapor/__tests__/transforms/vBind.spec.ts index f69fc34f8..5a529dd69 100644 --- a/packages/compiler-vapor/__tests__/transforms/vBind.spec.ts +++ b/packages/compiler-vapor/__tests__/transforms/vBind.spec.ts @@ -131,7 +131,7 @@ describe('compiler v-bind', () => { }, }) expect(code).contains( - '_camelCase !== _ctx.camelCase && _setDynamicProp(n0, "camel-case", (_camelCase = _ctx.camelCase))', + '_camelCase !== _ctx.camelCase && _setDynamicProp(n0, "camel-case", _prev_camelCase, (_prev_camelCase = (_camelCase = _ctx.camelCase)))', ) }) @@ -293,7 +293,7 @@ describe('compiler v-bind', () => { expect(code).matchSnapshot() expect(code).contains( - '_id !== _ctx.id && _setDynamicProp(n0, "fooBar", (_id = _ctx.id))', + '_id !== _ctx.id && _setDynamicProp(n0, "fooBar", _prev_id, (_prev_id = (_id = _ctx.id)))', ) }) @@ -319,7 +319,7 @@ describe('compiler v-bind', () => { }) expect(code).contains('renderEffect') expect(code).contains( - '_fooBar !== _ctx.fooBar && _setDynamicProp(n0, "fooBar", (_fooBar = _ctx.fooBar))', + '_fooBar !== _ctx.fooBar && _setDynamicProp(n0, "fooBar", _prev_fooBar, (_prev_fooBar = (_fooBar = _ctx.fooBar)))', ) }) @@ -794,7 +794,7 @@ describe('compiler v-bind', () => { `) expect(code).matchSnapshot() expect(code).contains( - ' _foo !== _ctx.foo && _setDynamicProp(n0, "value", (_foo = _ctx.foo))', + '_foo !== _ctx.foo && _setDynamicProp(n0, "value", _prev_foo, (_prev_foo = (_foo = _ctx.foo)))', ) }) diff --git a/packages/compiler-vapor/src/generators/operation.ts b/packages/compiler-vapor/src/generators/operation.ts index fdef9b26d..d997df1bc 100644 --- a/packages/compiler-vapor/src/generators/operation.ts +++ b/packages/compiler-vapor/src/generators/operation.ts @@ -120,7 +120,7 @@ export function genEffect( '})', ) } else { - // single line early return condition: _foo !== _ctx.foo || _bar !== _ctx.bar && + // single line early return condition: (_foo !== _ctx.foo || _bar !== _ctx.bar) && const multiple = conditions.length > 1 const condition: CodeFragment[] = conditions.length > 0 diff --git a/packages/compiler-vapor/src/generators/prop.ts b/packages/compiler-vapor/src/generators/prop.ts index 7b11b9e03..9bfd930c6 100644 --- a/packages/compiler-vapor/src/generators/prop.ts +++ b/packages/compiler-vapor/src/generators/prop.ts @@ -35,6 +35,8 @@ import { toHandlerKey, } from '@vue/shared' +const helperNeedPrevValue = ['setStyle', 'setDynamicProp'] + // only the static key prop will reach here export function genSetProp( oper: SetPropIRNode, @@ -49,7 +51,11 @@ export function genSetProp( let propValue = genPropValue(values, context) if (shouldGenEffectDeps()) { - processValues(context, [propValue]) + processValues( + context, + [propValue], + helperNeedPrevValue.includes(helperName), + ) } return [ @@ -247,10 +253,11 @@ const getSpecialHelper = ( export function processValues( context: CodegenContext, values: CodeFragment[][], + needPrevValue = false, ): string[] { const conditions: string[] = [] values.forEach(value => { - const condition = processValue(context, value) + const condition = processValue(context, value, needPrevValue) if (condition) conditions.push(...condition, ' && ') }) @@ -262,6 +269,7 @@ export function processValues( function processValue( context: CodegenContext, values: CodeFragment[], + needPrevValue = false, ): string[] | undefined { const { currentRenderEffect, renderEffectSeemNames } = context const { varNamesToDeclare, varNamesOverwritten, conditions, operations } = @@ -269,6 +277,7 @@ function processValue( // for multiline the early return condition should be `if (_foo === _ctx.foo) return` const oper = operations.length === 1 ? '!==' : '===' + let oldValueName = '' for (const frag of values) { if (!isArray(frag)) continue @@ -290,9 +299,17 @@ function processValue( conditions.push(`${name} ${oper} ${newName}`) // replace the original code fragment with the assignment expression frag[0] = `(${name} = ${newName})` + oldValueName += `${name}` } } + if (oldValueName && needPrevValue) { + oldValueName = `_prev${oldValueName}` + varNamesToDeclare.add(oldValueName) + values.unshift(`${oldValueName}, (${oldValueName} = `) + values.push(')') + } + if (conditions.length > 0) { return [[...new Set(conditions)].join(' && ')] } diff --git a/packages/runtime-vapor/src/dom/prop.ts b/packages/runtime-vapor/src/dom/prop.ts index bd6ce1f12..1529ba78e 100644 --- a/packages/runtime-vapor/src/dom/prop.ts +++ b/packages/runtime-vapor/src/dom/prop.ts @@ -14,11 +14,7 @@ import { } from '@vue/shared' import { warn } from '../warning' import { setStyle } from './style' -import { - MetadataKind, - getMetadata, - recordPropMetadata, -} from '../componentMetadata' +import { MetadataKind, getMetadata } from '../componentMetadata' import { on } from './event' import type { Data } from '@vue/runtime-shared' import { currentInstance } from '../component' @@ -29,32 +25,18 @@ export function mergeInheritAttr(key: string, value: any): unknown { } export function setClass(el: Element, value: any, root?: boolean): void { - const prev = recordPropMetadata( - el, - 'class', - (value = normalizeClass(root ? mergeInheritAttr('class', value) : value)), - ) - - if (value !== prev && (value || prev)) { - el.className = value - } + el.className = normalizeClass(root ? mergeInheritAttr('class', value) : value) } export function setAttr(el: Element, key: string, value: any): void { - const oldVal = recordPropMetadata(el, key, value) - if (value !== oldVal) { - if (value != null) { - el.setAttribute(key, value) - } else { - el.removeAttribute(key) - } + if (value != null) { + el.setAttribute(key, value) + } else { + el.removeAttribute(key) } } export function setValue(el: any, value: any): void { - const oldVal = recordPropMetadata(el, 'value', value) - if (value === oldVal) return - // store value as _value as well since // non-string values will be stringified. el._value = value @@ -71,9 +53,6 @@ export function setValue(el: any, value: any): void { } export function setDOMProp(el: any, key: string, value: any): void { - const oldVal = recordPropMetadata(el, key, value) - if (value === oldVal) return - let needRemove = false if (value === '' || value == null) { const type = typeof el[key] @@ -109,13 +88,18 @@ export function setDOMProp(el: any, key: string, value: any): void { needRemove && el.removeAttribute(key) } -export function setDynamicProp(el: Element, key: string, value: any): void { +export function setDynamicProp( + el: Element, + key: string, + prev: any, + value: any, +): void { // TODO const isSVG = false if (key === 'class') { setClass(el, value) } else if (key === 'style') { - setStyle(el as HTMLElement, value) + setStyle(el as HTMLElement, prev, value) } else if (isOn(key)) { on(el, key[2].toLowerCase() + key.slice(3), () => value, { effect: true }) } else if ( @@ -167,12 +151,12 @@ export function setDynamicProps( const hasNewValue = props[key] || props['.' + key] || props['^' + key] if (oldProps[key] && !hasNewValue) { - setDynamicProp(el, key, null) + setDynamicProp(el, key, undefined, null) } } for (const key in props) { - setDynamicProp(el, key, props[key]) + setDynamicProp(el, key, undefined, props[key]) } } @@ -213,18 +197,11 @@ export function mergeProps(...args: Data[]): Data { } export function setText(el: Node, ...values: any[]): void { - const text = values.map(v => toDisplayString(v)).join('') - const oldVal = recordPropMetadata(el, 'textContent', text) - if (text !== oldVal) { - el.textContent = text - } + el.textContent = values.map(v => toDisplayString(v)).join('') } export function setHtml(el: Element, value: any): void { - const oldVal = recordPropMetadata(el, 'innerHTML', value) - if (value !== oldVal) { - el.innerHTML = value == null ? '' : value - } + el.innerHTML = value == null ? '' : value } // TODO copied from runtime-dom diff --git a/packages/runtime-vapor/src/dom/style.ts b/packages/runtime-vapor/src/dom/style.ts index 5ee233a0c..fbea1dc50 100644 --- a/packages/runtime-vapor/src/dom/style.ts +++ b/packages/runtime-vapor/src/dom/style.ts @@ -7,15 +7,15 @@ import { normalizeStyle, } from '@vue/shared' import { warn } from '../warning' -import { recordPropMetadata } from '../componentMetadata' import { mergeInheritAttr } from './prop' -export function setStyle(el: HTMLElement, value: any, root?: boolean): void { - const prev = recordPropMetadata( - el, - 'style', - (value = normalizeStyle(root ? mergeInheritAttr('style', value) : value)), - ) +export function setStyle( + el: HTMLElement, + prev: any, + value: any, + root?: boolean, +): void { + value = normalizeStyle(root ? mergeInheritAttr('style', value) : value) patchStyle(el, prev, value) } From 6c4f689dcc3ff2e6176eb8b2c117303c0c4081e2 Mon Sep 17 00:00:00 2001 From: daiwei Date: Wed, 4 Dec 2024 16:47:45 +0800 Subject: [PATCH 26/47] wip: fix mutiline code gen --- .../__snapshots__/vBind.spec.ts.snap | 22 ++++++------ .../__tests__/transforms/vBind.spec.ts | 14 ++++---- .../src/generators/operation.ts | 5 +++ .../compiler-vapor/src/generators/prop.ts | 36 ++++++++++++------- 4 files changed, 48 insertions(+), 29 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 86d7a6ccd..51be8df3c 100644 --- a/packages/compiler-vapor/__tests__/transforms/__snapshots__/vBind.spec.ts.snap +++ b/packages/compiler-vapor/__tests__/transforms/__snapshots__/vBind.spec.ts.snap @@ -85,8 +85,8 @@ const t0 = _template("
") export function render(_ctx) { const n0 = t0() _setInheritAttrs(["fooBar"]) - let _id, _prev_id; - _renderEffect(() => _id !== _ctx.id && _setDynamicProp(n0, "fooBar", _prev_id, (_prev_id = (_id = _ctx.id)))) + let _id; + _renderEffect(() => _id !== _ctx.id && _setDynamicProp(n0, "fooBar", _id, (_id = _ctx.id))) return n0 }" `; @@ -112,8 +112,8 @@ const t0 = _template("
") export function render(_ctx) { const n0 = t0() _setInheritAttrs(["fooBar"]) - let _fooBar, _prev_fooBar; - _renderEffect(() => _fooBar !== _ctx.fooBar && _setDynamicProp(n0, "fooBar", _prev_fooBar, (_prev_fooBar = (_fooBar = _ctx.fooBar)))) + let _fooBar; + _renderEffect(() => _fooBar !== _ctx.fooBar && _setDynamicProp(n0, "fooBar", _fooBar, (_fooBar = _ctx.fooBar))) return n0 }" `; @@ -333,8 +333,8 @@ const t0 = _template("") export function render(_ctx) { const n0 = t0() _setInheritAttrs(["value"]) - let _foo, _prev_foo; - _renderEffect(() => _foo !== _ctx.foo && _setDynamicProp(n0, "value", _prev_foo, (_prev_foo = (_foo = _ctx.foo)))) + let _foo; + _renderEffect(() => _foo !== _ctx.foo && _setDynamicProp(n0, "value", _foo, (_foo = _ctx.foo))) return n0 }" `; @@ -431,18 +431,20 @@ export function render(_ctx) { let _width; _renderEffect(() => { if(_width === _ctx.width) return - _setAttr(n3, "width", (_width = _ctx.width)) + _setAttr(n3, "width", _ctx.width) _setAttr(n4, "width", _ctx.width) _setAttr(n5, "width", _ctx.width) _setAttr(n6, "width", _ctx.width) + _width = _ctx.width }) let _height; _renderEffect(() => { if(_height === _ctx.height) return - _setAttr(n3, "height", (_height = _ctx.height)) + _setAttr(n3, "height", _ctx.height) _setAttr(n4, "height", _ctx.height) _setAttr(n5, "height", _ctx.height) _setAttr(n6, "height", _ctx.height) + _height = _ctx.height }) return [n0, n1, n2, n3, n4, n5, n6] }" @@ -494,8 +496,8 @@ const t0 = _template("
") export function render(_ctx) { const n0 = t0() _setInheritAttrs(["camel-case"]) - let _camelCase, _prev_camelCase; - _renderEffect(() => _camelCase !== _ctx.camelCase && _setDynamicProp(n0, "camel-case", _prev_camelCase, (_prev_camelCase = (_camelCase = _ctx.camelCase)))) + let _camelCase; + _renderEffect(() => _camelCase !== _ctx.camelCase && _setDynamicProp(n0, "camel-case", _camelCase, (_camelCase = _ctx.camelCase))) return n0 }" `; diff --git a/packages/compiler-vapor/__tests__/transforms/vBind.spec.ts b/packages/compiler-vapor/__tests__/transforms/vBind.spec.ts index 5a529dd69..55312f7f7 100644 --- a/packages/compiler-vapor/__tests__/transforms/vBind.spec.ts +++ b/packages/compiler-vapor/__tests__/transforms/vBind.spec.ts @@ -131,7 +131,7 @@ describe('compiler v-bind', () => { }, }) expect(code).contains( - '_camelCase !== _ctx.camelCase && _setDynamicProp(n0, "camel-case", _prev_camelCase, (_prev_camelCase = (_camelCase = _ctx.camelCase)))', + '_camelCase !== _ctx.camelCase && _setDynamicProp(n0, "camel-case", _camelCase, (_camelCase = _ctx.camelCase))', ) }) @@ -293,7 +293,7 @@ describe('compiler v-bind', () => { expect(code).matchSnapshot() expect(code).contains( - '_id !== _ctx.id && _setDynamicProp(n0, "fooBar", _prev_id, (_prev_id = (_id = _ctx.id)))', + '_id !== _ctx.id && _setDynamicProp(n0, "fooBar", _id, (_id = _ctx.id))', ) }) @@ -319,7 +319,7 @@ describe('compiler v-bind', () => { }) expect(code).contains('renderEffect') expect(code).contains( - '_fooBar !== _ctx.fooBar && _setDynamicProp(n0, "fooBar", _prev_fooBar, (_prev_fooBar = (_fooBar = _ctx.fooBar)))', + '_fooBar !== _ctx.fooBar && _setDynamicProp(n0, "fooBar", _fooBar, (_fooBar = _ctx.fooBar))', ) }) @@ -675,8 +675,10 @@ describe('compiler v-bind', () => { ) expect(code).contains('if(_width === _ctx.width) return') expect(code).contains('if(_height === _ctx.height) return') - expect(code).contains('_setAttr(n3, "width", (_width = _ctx.width))') - expect(code).contains('_setAttr(n3, "height", (_height = _ctx.height))') + expect(code).contains('_height = _ctx.height') + expect(code).contains('_height = _ctx.height') + expect(code).contains('_setAttr(n3, "width", _ctx.width)') + expect(code).contains('_setAttr(n3, "height", _ctx.height)') expect(code).contains('_setAttr(n4, "width", _ctx.width)') expect(code).contains('_setAttr(n4, "height", _ctx.height)') expect(code).contains('_setAttr(n5, "width", _ctx.width)') @@ -794,7 +796,7 @@ describe('compiler v-bind', () => { `) expect(code).matchSnapshot() expect(code).contains( - '_foo !== _ctx.foo && _setDynamicProp(n0, "value", _prev_foo, (_prev_foo = (_foo = _ctx.foo)))', + '_foo !== _ctx.foo && _setDynamicProp(n0, "value", _foo, (_foo = _ctx.foo))', ) }) diff --git a/packages/compiler-vapor/src/generators/operation.ts b/packages/compiler-vapor/src/generators/operation.ts index d997df1bc..923c59633 100644 --- a/packages/compiler-vapor/src/generators/operation.ts +++ b/packages/compiler-vapor/src/generators/operation.ts @@ -110,11 +110,16 @@ export function genEffect( conditions.length > 0 ? [NEWLINE, `if(`, ...conditions.join(' && '), `) return`] : [] + const assignment: CodeFragment[] = + conditions.length > 0 + ? [NEWLINE, ...conditions.map(c => c.replace('===', '=')).join(';')] + : [] push( '{', INDENT_START, ...condition, ...operationsExps, + ...assignment, INDENT_END, NEWLINE, '})', diff --git a/packages/compiler-vapor/src/generators/prop.ts b/packages/compiler-vapor/src/generators/prop.ts index 9bfd930c6..d88548e5c 100644 --- a/packages/compiler-vapor/src/generators/prop.ts +++ b/packages/compiler-vapor/src/generators/prop.ts @@ -275,12 +275,10 @@ function processValue( const { varNamesToDeclare, varNamesOverwritten, conditions, operations } = currentRenderEffect! - // for multiline the early return condition should be `if (_foo === _ctx.foo) return` - const oper = operations.length === 1 ? '!==' : '===' - let oldValueName = '' + const isMultiLine = operations.length > 1 + let prevValueName = '' for (const frag of values) { if (!isArray(frag)) continue - // [code, newlineIndex, loc, name] -> [(_name = code), newlineIndex, loc, name] const [newName, , , rawName] = frag if (rawName) { @@ -296,18 +294,30 @@ function processValue( else name += ++renderEffectSeemNames[name] varNamesToDeclare.add(name) - conditions.push(`${name} ${oper} ${newName}`) - // replace the original code fragment with the assignment expression - frag[0] = `(${name} = ${newName})` - oldValueName += `${name}` + // for multiline renderEffect the early return condition should be `if (_foo === _ctx.foo) return` + conditions.push(`${name} ${isMultiLine ? '===' : '!=='} ${newName}`) + + if (!isMultiLine) { + // replace the original code fragment with the assignment expression + frag[0] = `(${name} = ${newName})` + } + prevValueName += `${name}` } } - if (oldValueName && needPrevValue) { - oldValueName = `_prev${oldValueName}` - varNamesToDeclare.add(oldValueName) - values.unshift(`${oldValueName}, (${oldValueName} = `) - values.push(')') + if (needPrevValue && prevValueName) { + const needNewPrevName = varNamesToDeclare.size > 1 + prevValueName = needNewPrevName + ? `_prev${prevValueName}` + : [...varNamesToDeclare][0] + varNamesToDeclare.add(prevValueName) + values.unshift( + ...[ + `${prevValueName}, `, + needNewPrevName ? `(${prevValueName} = ` : undefined, + ], + ) + needNewPrevName && values.push(')') } if (conditions.length > 0) { From 43743b839a880d2ecce8a25510c16917beb62b08 Mon Sep 17 00:00:00 2001 From: daiwei Date: Wed, 4 Dec 2024 17:06:51 +0800 Subject: [PATCH 27/47] refactor: prevValue parameter --- .../compiler-vapor/src/generators/prop.ts | 47 +++++++++---------- 1 file changed, 21 insertions(+), 26 deletions(-) diff --git a/packages/compiler-vapor/src/generators/prop.ts b/packages/compiler-vapor/src/generators/prop.ts index d88548e5c..4d4b81442 100644 --- a/packages/compiler-vapor/src/generators/prop.ts +++ b/packages/compiler-vapor/src/generators/prop.ts @@ -42,7 +42,7 @@ export function genSetProp( oper: SetPropIRNode, context: CodegenContext, ): CodeFragment[] { - const { vaporHelper, shouldGenEffectDeps } = context + const { vaporHelper, shouldGenEffectDeps, currentRenderEffect } = context const { prop: { key, values, modifier }, tag, @@ -51,11 +51,25 @@ export function genSetProp( let propValue = genPropValue(values, context) if (shouldGenEffectDeps()) { - processValues( - context, - [propValue], - helperNeedPrevValue.includes(helperName), - ) + processValues(context, [propValue]) + + const { varNamesToDeclare } = currentRenderEffect! + // need prevValue parameter + if ( + varNamesToDeclare.size > 0 && + helperNeedPrevValue.includes(helperName) + ) { + const prevValueName = [...varNamesToDeclare].join('') + varNamesToDeclare.add(prevValueName) + const needReCacheValue = varNamesToDeclare.size > 1 + propValue.unshift( + ...[ + `${prevValueName}, `, // prevValue parameter + needReCacheValue ? `(${prevValueName} = ` : undefined, // cache value to prevValue + ], + ) + needReCacheValue && propValue.push(')') + } } return [ @@ -253,11 +267,10 @@ const getSpecialHelper = ( export function processValues( context: CodegenContext, values: CodeFragment[][], - needPrevValue = false, ): string[] { const conditions: string[] = [] values.forEach(value => { - const condition = processValue(context, value, needPrevValue) + const condition = processValue(context, value) if (condition) conditions.push(...condition, ' && ') }) @@ -269,14 +282,12 @@ export function processValues( function processValue( context: CodegenContext, values: CodeFragment[], - needPrevValue = false, ): string[] | undefined { const { currentRenderEffect, renderEffectSeemNames } = context const { varNamesToDeclare, varNamesOverwritten, conditions, operations } = currentRenderEffect! const isMultiLine = operations.length > 1 - let prevValueName = '' for (const frag of values) { if (!isArray(frag)) continue // [code, newlineIndex, loc, name] -> [(_name = code), newlineIndex, loc, name] @@ -301,25 +312,9 @@ function processValue( // replace the original code fragment with the assignment expression frag[0] = `(${name} = ${newName})` } - prevValueName += `${name}` } } - if (needPrevValue && prevValueName) { - const needNewPrevName = varNamesToDeclare.size > 1 - prevValueName = needNewPrevName - ? `_prev${prevValueName}` - : [...varNamesToDeclare][0] - varNamesToDeclare.add(prevValueName) - values.unshift( - ...[ - `${prevValueName}, `, - needNewPrevName ? `(${prevValueName} = ` : undefined, - ], - ) - needNewPrevName && values.push(')') - } - if (conditions.length > 0) { return [[...new Set(conditions)].join(' && ')] } From 02209bdafd3434761a6b59425e3291538135b0a5 Mon Sep 17 00:00:00 2001 From: daiwei Date: Wed, 4 Dec 2024 21:29:12 +0800 Subject: [PATCH 28/47] chore: update --- packages/compiler-vapor/src/generate.ts | 8 ++------ packages/compiler-vapor/src/ir/index.ts | 1 - packages/compiler-vapor/src/transform.ts | 1 - 3 files changed, 2 insertions(+), 8 deletions(-) diff --git a/packages/compiler-vapor/src/generate.ts b/packages/compiler-vapor/src/generate.ts index 4027f956d..318fb302f 100644 --- a/packages/compiler-vapor/src/generate.ts +++ b/packages/compiler-vapor/src/generate.ts @@ -38,12 +38,8 @@ export class CodegenContext { currentRenderEffect: IREffect | undefined = undefined renderEffectSeemNames: Record = Object.create(null) shouldGenEffectDeps = (): boolean => { - // only need to generate effect deps when it's not nested in v-once or v-for - return !!( - this.currentRenderEffect && - !this.currentRenderEffect.inVOnce && - !this.currentRenderEffect.inVFor - ) + // only need to generate effect deps when it's not nested in v-for + return !!(this.currentRenderEffect && !this.currentRenderEffect.inVFor) } identifiers: Record = Object.create(null) diff --git a/packages/compiler-vapor/src/ir/index.ts b/packages/compiler-vapor/src/ir/index.ts index 85a3634bf..5860ee532 100644 --- a/packages/compiler-vapor/src/ir/index.ts +++ b/packages/compiler-vapor/src/ir/index.ts @@ -271,7 +271,6 @@ export interface IREffect { varNamesOverwritten: Set conditions: string[] inVFor: boolean - inVOnce: boolean } type Overwrite = Pick> & diff --git a/packages/compiler-vapor/src/transform.ts b/packages/compiler-vapor/src/transform.ts index 7a3f4ccdd..d19c0899b 100644 --- a/packages/compiler-vapor/src/transform.ts +++ b/packages/compiler-vapor/src/transform.ts @@ -155,7 +155,6 @@ export class TransformContext { varNamesToDeclare: new Set(), varNamesOverwritten: new Set(), inVFor: this.inVFor > 0, - inVOnce: this.inVOnce, }) } From b8521fa7b3e9d5f96cedb11a26d7493f8d79ec24 Mon Sep 17 00:00:00 2001 From: daiwei Date: Wed, 4 Dec 2024 21:35:29 +0800 Subject: [PATCH 29/47] chore: update snap --- .../__snapshots__/compile.spec.ts.snap | 10 +- .../transformChildren.spec.ts.snap | 4 +- .../transformElement.spec.ts.snap | 10 +- .../__snapshots__/vBind.spec.ts.snap | 104 +++++++++--------- .../__snapshots__/vHtml.spec.ts.snap | 4 +- .../transforms/__snapshots__/vIf.spec.ts.snap | 6 +- .../__snapshots__/vModel.spec.ts.snap | 2 +- .../__snapshots__/vText.spec.ts.snap | 4 +- .../__tests__/transforms/vBind.spec.ts | 22 ++-- .../src/generators/operation.ts | 3 +- 10 files changed, 85 insertions(+), 84 deletions(-) diff --git a/packages/compiler-vapor/__tests__/__snapshots__/compile.spec.ts.snap b/packages/compiler-vapor/__tests__/__snapshots__/compile.spec.ts.snap index 2a251895a..1818f13ea 100644 --- a/packages/compiler-vapor/__tests__/__snapshots__/compile.spec.ts.snap +++ b/packages/compiler-vapor/__tests__/__snapshots__/compile.spec.ts.snap @@ -6,7 +6,7 @@ const t0 = _template("
") export function render(_ctx, $props, $emit, $attrs, $slots) { const n0 = t0() - let _count; + let _count _renderEffect(() => _count !== _ctx.count && _setText(n0, "count is ", (_count = _ctx.count), ".")) return n0 }" @@ -163,7 +163,7 @@ export function render(_ctx, $props, $emit, $attrs, $slots) { const n1 = _createComponent(_component_Comp) const n2 = _createTextNode(() => [_ctx.bar]) _insert([n1, n2], n3) - let _foo; + let _foo _renderEffect(() => _foo !== _ctx.foo && _setDOMProp(n3, "id", (_foo = _ctx.foo))) return [n0, n3] }" @@ -187,9 +187,9 @@ export function render(_ctx) { const n0 = t0() _delegate(n0, "click", () => _ctx.handleClick) _setInheritAttrs(["id"]) - let _count; + let _count _renderEffect(() => _count !== _ctx.count && _setText(n0, (_count = _ctx.count), "foo", _ctx.count, "foo", _ctx.count)) - let _count1; + let _count1 _renderEffect(() => _count1 !== _ctx.count && _setDOMProp(n0, "id", (_count1 = _ctx.count))) return n0 }" @@ -206,7 +206,7 @@ exports[`compile > expression parsing > v-bind 1`] = ` "((_ctx) => { const n0 = t0() _setInheritAttrs(true) - let _key_value, _foo; + let _key_value, _foo _renderEffect(() => (_key_value !== key.value || _foo !== _unref(foo)) && _setDynamicProps(n0, [{ [(_key_value = key.value)+1]: (_foo = _unref(foo))[key.value+1]() }], true)) return n0 })()" diff --git a/packages/compiler-vapor/__tests__/transforms/__snapshots__/transformChildren.spec.ts.snap b/packages/compiler-vapor/__tests__/transforms/__snapshots__/transformChildren.spec.ts.snap index 7dbf0156a..c868e413b 100644 --- a/packages/compiler-vapor/__tests__/transforms/__snapshots__/transformChildren.spec.ts.snap +++ b/packages/compiler-vapor/__tests__/transforms/__snapshots__/transformChildren.spec.ts.snap @@ -11,9 +11,9 @@ export function render(_ctx) { const n2 = n3.nextSibling const n1 = _createTextNode(() => [_ctx.second, " ", _ctx.third, " "]) _insert(n1, n4, n3) - let _first; + let _first _renderEffect(() => _first !== _ctx.first && _setText(n0, (_first = _ctx.first))) - let _forth; + let _forth _renderEffect(() => _forth !== _ctx.forth && _setText(n2, (_forth = _ctx.forth))) return n4 }" diff --git a/packages/compiler-vapor/__tests__/transforms/__snapshots__/transformElement.spec.ts.snap b/packages/compiler-vapor/__tests__/transforms/__snapshots__/transformElement.spec.ts.snap index f7d078181..829a34ec3 100644 --- a/packages/compiler-vapor/__tests__/transforms/__snapshots__/transformElement.spec.ts.snap +++ b/packages/compiler-vapor/__tests__/transforms/__snapshots__/transformElement.spec.ts.snap @@ -303,7 +303,7 @@ const t0 = _template("
") export function render(_ctx) { const n0 = t0() _setInheritAttrs(["class"]) - let _isBar; + let _isBar _renderEffect(() => _isBar !== _ctx.isBar && _setClass(n0, ["foo", { bar: (_isBar = _ctx.isBar) }], true)) return n0 }" @@ -356,7 +356,7 @@ const t0 = _template("
") export function render(_ctx) { const n0 = t0() _setInheritAttrs(true) - let _obj; + let _obj _renderEffect(() => _obj !== _ctx.obj && _setDynamicProps(n0, [(_obj = _ctx.obj)], true)) return n0 }" @@ -369,7 +369,7 @@ const t0 = _template("
") export function render(_ctx) { const n0 = t0() _setInheritAttrs(true) - let _obj; + let _obj _renderEffect(() => _obj !== _ctx.obj && _setDynamicProps(n0, [{ id: "foo" }, (_obj = _ctx.obj)], true)) return n0 }" @@ -382,7 +382,7 @@ const t0 = _template("
") export function render(_ctx) { const n0 = t0() _setInheritAttrs(true) - let _obj; + let _obj _renderEffect(() => _obj !== _ctx.obj && _setDynamicProps(n0, [(_obj = _ctx.obj), { id: "foo" }], true)) return n0 }" @@ -395,7 +395,7 @@ const t0 = _template("
") export function render(_ctx) { const n0 = t0() _setInheritAttrs(true) - let _obj; + let _obj _renderEffect(() => _obj !== _ctx.obj && _setDynamicProps(n0, [{ id: "foo" }, (_obj = _ctx.obj), { class: "bar" }], true)) return n0 }" 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 51be8df3c..896a1a356 100644 --- a/packages/compiler-vapor/__tests__/transforms/__snapshots__/vBind.spec.ts.snap +++ b/packages/compiler-vapor/__tests__/transforms/__snapshots__/vBind.spec.ts.snap @@ -7,7 +7,7 @@ const t0 = _template("
") export function render(_ctx) { const n0 = t0() _setInheritAttrs(["foo-bar"]) - let _id; + let _id _renderEffect(() => _id !== _ctx.id && _setAttr(n0, "foo-bar", (_id = _ctx.id))) return n0 }" @@ -20,7 +20,7 @@ const t0 = _template("
") export function render(_ctx) { const n0 = t0() _setInheritAttrs(["innerHTML"]) - let _foo; + let _foo _renderEffect(() => _foo !== _ctx.foo && _setAttr(n0, "innerHTML", (_foo = _ctx.foo))) return n0 }" @@ -33,7 +33,7 @@ const t0 = _template("
") export function render(_ctx) { const n0 = t0() _setInheritAttrs(["foo-bar"]) - let _fooBar; + let _fooBar _renderEffect(() => _fooBar !== _ctx.fooBar && _setAttr(n0, "foo-bar", (_fooBar = _ctx.fooBar))) return n0 }" @@ -46,7 +46,7 @@ const t0 = _template("") export function render(_ctx) { const n0 = t0() _setInheritAttrs(["value"]) - let _foo; + let _foo _renderEffect(() => _foo !== _ctx.foo && _setAttr(n0, "value", (_foo = _ctx.foo))) return n0 }" @@ -59,7 +59,7 @@ const t0 = _template("
") export function render(_ctx) { const n0 = t0() _setInheritAttrs(["textContent"]) - let _foo; + let _foo _renderEffect(() => _foo !== _ctx.foo && _setAttr(n0, "textContent", (_foo = _ctx.foo))) return n0 }" @@ -72,7 +72,7 @@ const t0 = _template("
") export function render(_ctx) { const n0 = t0() _setInheritAttrs(["value"]) - let _foo; + let _foo _renderEffect(() => _foo !== _ctx.foo && _setAttr(n0, "value", (_foo = _ctx.foo))) return n0 }" @@ -85,7 +85,7 @@ const t0 = _template("
") export function render(_ctx) { const n0 = t0() _setInheritAttrs(["fooBar"]) - let _id; + let _id _renderEffect(() => _id !== _ctx.id && _setDynamicProp(n0, "fooBar", _id, (_id = _ctx.id))) return n0 }" @@ -99,7 +99,7 @@ const t0 = _template("
") export function render(_ctx) { const n0 = t0() _setInheritAttrs(true) - let _foo, _id; + let _foo, _id _renderEffect(() => (_foo !== _ctx.foo || _id !== _ctx.id) && _setDynamicProps(n0, [{ [_camelize((_foo = _ctx.foo))]: (_id = _ctx.id) }], true)) return n0 }" @@ -112,7 +112,7 @@ const t0 = _template("
") export function render(_ctx) { const n0 = t0() _setInheritAttrs(["fooBar"]) - let _fooBar; + let _fooBar _renderEffect(() => _fooBar !== _ctx.fooBar && _setDynamicProp(n0, "fooBar", _fooBar, (_fooBar = _ctx.fooBar))) return n0 }" @@ -125,7 +125,7 @@ const t0 = _template("
") export function render(_ctx) { const n0 = t0() _setInheritAttrs(["fooBar"]) - let _id; + let _id _renderEffect(() => _id !== _ctx.id && _setDOMProp(n0, "fooBar", (_id = _ctx.id))) return n0 }" @@ -138,7 +138,7 @@ const t0 = _template("
") export function render(_ctx) { const n0 = t0() _setInheritAttrs(["innerHTML"]) - let _foo; + let _foo _renderEffect(() => _foo !== _ctx.foo && _setHtml(n0, (_foo = _ctx.foo))) return n0 }" @@ -151,7 +151,7 @@ const t0 = _template("
") export function render(_ctx) { const n0 = t0() _setInheritAttrs(["fooBar"]) - let _fooBar; + let _fooBar _renderEffect(() => _fooBar !== _ctx.fooBar && _setDOMProp(n0, "fooBar", (_fooBar = _ctx.fooBar))) return n0 }" @@ -164,7 +164,7 @@ const t0 = _template("") export function render(_ctx) { const n0 = t0() _setInheritAttrs(["value"]) - let _foo; + let _foo _renderEffect(() => _foo !== _ctx.foo && _setDOMProp(n0, "value", (_foo = _ctx.foo))) return n0 }" @@ -177,7 +177,7 @@ const t0 = _template("
") export function render(_ctx) { const n0 = t0() _setInheritAttrs(["textContent"]) - let _foo; + let _foo _renderEffect(() => _foo !== _ctx.foo && _setText(n0, (_foo = _ctx.foo))) return n0 }" @@ -190,7 +190,7 @@ const t0 = _template("
") export function render(_ctx) { const n0 = t0() _setInheritAttrs(["value"]) - let _foo; + let _foo _renderEffect(() => _foo !== _ctx.foo && _setValue(n0, (_foo = _ctx.foo))) return n0 }" @@ -203,7 +203,7 @@ const t0 = _template("
") export function render(_ctx) { const n0 = t0() _setInheritAttrs(["fooBar"]) - let _id; + let _id _renderEffect(() => _id !== _ctx.id && _setDOMProp(n0, "fooBar", (_id = _ctx.id))) return n0 }" @@ -216,7 +216,7 @@ const t0 = _template("
") export function render(_ctx) { const n0 = t0() _setInheritAttrs(true) - let _fooBar, _id; + let _fooBar, _id _renderEffect(() => (_fooBar !== _ctx.fooBar || _id !== _ctx.id) && _setDynamicProps(n0, [{ ["." + (_fooBar = _ctx.fooBar)]: (_id = _ctx.id) }], true)) return n0 }" @@ -229,7 +229,7 @@ const t0 = _template("
") export function render(_ctx) { const n0 = t0() _setInheritAttrs(["innerHTML"]) - let _foo; + let _foo _renderEffect(() => _foo !== _ctx.foo && _setHtml(n0, (_foo = _ctx.foo))) return n0 }" @@ -242,7 +242,7 @@ const t0 = _template("
") export function render(_ctx) { const n0 = t0() _setInheritAttrs(["fooBar"]) - let _fooBar; + let _fooBar _renderEffect(() => _fooBar !== _ctx.fooBar && _setDOMProp(n0, "fooBar", (_fooBar = _ctx.fooBar))) return n0 }" @@ -255,7 +255,7 @@ const t0 = _template("") export function render(_ctx) { const n0 = t0() _setInheritAttrs(["value"]) - let _foo; + let _foo _renderEffect(() => _foo !== _ctx.foo && _setDOMProp(n0, "value", (_foo = _ctx.foo))) return n0 }" @@ -268,7 +268,7 @@ const t0 = _template("
") export function render(_ctx) { const n0 = t0() _setInheritAttrs(["textContent"]) - let _foo; + let _foo _renderEffect(() => _foo !== _ctx.foo && _setText(n0, (_foo = _ctx.foo))) return n0 }" @@ -281,7 +281,7 @@ const t0 = _template("
") export function render(_ctx) { const n0 = t0() _setInheritAttrs(["value"]) - let _foo; + let _foo _renderEffect(() => _foo !== _ctx.foo && _setValue(n0, (_foo = _ctx.foo))) return n0 }" @@ -294,7 +294,7 @@ const t0 = _template("
") export function render(_ctx) { const n0 = t0() _setInheritAttrs(["innerHTML"]) - let _foo; + let _foo _renderEffect(() => _foo !== _ctx.foo && _setHtml(n0, (_foo = _ctx.foo))) return n0 }" @@ -307,7 +307,7 @@ const t0 = _template("
") export function render(_ctx) { const n0 = t0() _setInheritAttrs(["textContent"]) - let _foo; + let _foo _renderEffect(() => _foo !== _ctx.foo && _setText(n0, (_foo = _ctx.foo))) return n0 }" @@ -320,7 +320,7 @@ const t0 = _template("") export function render(_ctx) { const n0 = t0() _setInheritAttrs(["value"]) - let _foo; + let _foo _renderEffect(() => _foo !== _ctx.foo && _setValue(n0, (_foo = _ctx.foo))) return n0 }" @@ -333,7 +333,7 @@ const t0 = _template("") export function render(_ctx) { const n0 = t0() _setInheritAttrs(["value"]) - let _foo; + let _foo _renderEffect(() => _foo !== _ctx.foo && _setDynamicProp(n0, "value", _foo, (_foo = _ctx.foo))) return n0 }" @@ -346,15 +346,15 @@ const t0 = _template("
") export function render(_ctx) { const n0 = t0() _setInheritAttrs(["id", "title", "lang", "dir", "tabindex"]) - let _id; + let _id _renderEffect(() => _id !== _ctx.id && _setDOMProp(n0, "id", (_id = _ctx.id))) - let _title; + let _title _renderEffect(() => _title !== _ctx.title && _setDOMProp(n0, "title", (_title = _ctx.title))) - let _lang; + let _lang _renderEffect(() => _lang !== _ctx.lang && _setDOMProp(n0, "lang", (_lang = _ctx.lang))) - let _dir; + let _dir _renderEffect(() => _dir !== _ctx.dir && _setDOMProp(n0, "dir", (_dir = _ctx.dir))) - let _tabindex; + let _tabindex _renderEffect(() => _tabindex !== _ctx.tabindex && _setDOMProp(n0, "tabindex", (_tabindex = _ctx.tabindex))) return n0 }" @@ -367,15 +367,15 @@ const t0 = _template("") export function render(_ctx) { const n0 = t0() _setInheritAttrs(["autofucus", "dir", "displaystyle", "mathcolor", "tabindex"]) - let _autofucus; + let _autofucus _renderEffect(() => _autofucus !== _ctx.autofucus && _setDOMProp(n0, "autofucus", (_autofucus = _ctx.autofucus))) - let _dir; + let _dir _renderEffect(() => _dir !== _ctx.dir && _setDOMProp(n0, "dir", (_dir = _ctx.dir))) - let _displaystyle; + let _displaystyle _renderEffect(() => _displaystyle !== _ctx.displaystyle && _setDOMProp(n0, "displaystyle", (_displaystyle = _ctx.displaystyle))) - let _mathcolor; + let _mathcolor _renderEffect(() => _mathcolor !== _ctx.mathcolor && _setDOMProp(n0, "mathcolor", (_mathcolor = _ctx.mathcolor))) - let _tabindex; + let _tabindex _renderEffect(() => _tabindex !== _ctx.tabindex && _setDOMProp(n0, "tabindex", (_tabindex = _ctx.tabindex))) return n0 }" @@ -388,11 +388,11 @@ const t0 = _template("") export function render(_ctx) { const n0 = t0() _setInheritAttrs(["id", "lang", "tabindex"]) - let _id; + let _id _renderEffect(() => _id !== _ctx.id && _setDOMProp(n0, "id", (_id = _ctx.id))) - let _lang; + let _lang _renderEffect(() => _lang !== _ctx.lang && _setDOMProp(n0, "lang", (_lang = _ctx.lang))) - let _tabindex; + let _tabindex _renderEffect(() => _tabindex !== _ctx.tabindex && _setDOMProp(n0, "tabindex", (_tabindex = _ctx.tabindex))) return n0 }" @@ -416,19 +416,19 @@ export function render(_ctx) { const n4 = t4() const n5 = t5() const n6 = t6() - let _spellcheck; + let _spellcheck _renderEffect(() => _spellcheck !== _ctx.spellcheck && _setAttr(n0, "spellcheck", (_spellcheck = _ctx.spellcheck))) - let _draggable; + let _draggable _renderEffect(() => _draggable !== _ctx.draggable && _setAttr(n0, "draggable", (_draggable = _ctx.draggable))) - let _translate; + let _translate _renderEffect(() => _translate !== _ctx.translate && _setAttr(n0, "translate", (_translate = _ctx.translate))) - let _form; + let _form _renderEffect(() => _form !== _ctx.form && _setAttr(n0, "form", (_form = _ctx.form))) - let _list; + let _list _renderEffect(() => _list !== _ctx.list && _setAttr(n1, "list", (_list = _ctx.list))) - let _type; + let _type _renderEffect(() => _type !== _ctx.type && _setAttr(n2, "type", (_type = _ctx.type))) - let _width; + let _width _renderEffect(() => { if(_width === _ctx.width) return _setAttr(n3, "width", _ctx.width) @@ -437,7 +437,7 @@ export function render(_ctx) { _setAttr(n6, "width", _ctx.width) _width = _ctx.width }) - let _height; + let _height _renderEffect(() => { if(_height === _ctx.height) return _setAttr(n3, "height", _ctx.height) @@ -457,7 +457,7 @@ const t0 = _template("
") export function render(_ctx) { const n0 = t0() _setInheritAttrs(["id"]) - let _id; + let _id _renderEffect(() => _id !== _ctx.id && _setDOMProp(n0, "id", (_id = _ctx.id))) return n0 }" @@ -470,7 +470,7 @@ const t0 = _template("
") export function render(_ctx) { const n0 = t0() _setInheritAttrs(true) - let _id, _title; + let _id, _title _renderEffect(() => (_id !== _ctx.id || _title !== _ctx.title) && _setDynamicProps(n0, [{ [(_id = _ctx.id)]: _ctx.id, [(_title = _ctx.title)]: _ctx.title }], true)) return n0 }" @@ -483,7 +483,7 @@ const t0 = _template("
") export function render(_ctx) { const n0 = t0() _setInheritAttrs(true) - let _id; + let _id _renderEffect(() => _id !== _ctx.id && _setDynamicProps(n0, [{ [(_id = _ctx.id)]: _ctx.id, foo: "bar", checked: "" }], true)) return n0 }" @@ -496,7 +496,7 @@ const t0 = _template("
") export function render(_ctx) { const n0 = t0() _setInheritAttrs(["camel-case"]) - let _camelCase; + let _camelCase _renderEffect(() => _camelCase !== _ctx.camelCase && _setDynamicProp(n0, "camel-case", _camelCase, (_camelCase = _ctx.camelCase))) return n0 }" @@ -509,7 +509,7 @@ const t0 = _template("
") export function render(_ctx) { const n0 = t0() _setInheritAttrs(["id"]) - let _id; + let _id _renderEffect(() => _id !== _ctx.id && _setDOMProp(n0, "id", (_id = _ctx.id))) return n0 }" diff --git a/packages/compiler-vapor/__tests__/transforms/__snapshots__/vHtml.spec.ts.snap b/packages/compiler-vapor/__tests__/transforms/__snapshots__/vHtml.spec.ts.snap index 034ff1d27..0deb4bf33 100644 --- a/packages/compiler-vapor/__tests__/transforms/__snapshots__/vHtml.spec.ts.snap +++ b/packages/compiler-vapor/__tests__/transforms/__snapshots__/vHtml.spec.ts.snap @@ -6,7 +6,7 @@ const t0 = _template("
") export function render(_ctx, $props, $emit, $attrs, $slots) { const n0 = t0() - let _code; + let _code _renderEffect(() => _code !== _ctx.code && _setHtml(n0, (_code = _ctx.code))) return n0 }" @@ -18,7 +18,7 @@ const t0 = _template("
") export function render(_ctx) { const n0 = t0() - let _test; + let _test _renderEffect(() => _test !== _ctx.test && _setHtml(n0, (_test = _ctx.test))) return n0 }" diff --git a/packages/compiler-vapor/__tests__/transforms/__snapshots__/vIf.spec.ts.snap b/packages/compiler-vapor/__tests__/transforms/__snapshots__/vIf.spec.ts.snap index b77fc3332..e40c0bdbc 100644 --- a/packages/compiler-vapor/__tests__/transforms/__snapshots__/vIf.spec.ts.snap +++ b/packages/compiler-vapor/__tests__/transforms/__snapshots__/vIf.spec.ts.snap @@ -7,7 +7,7 @@ const t0 = _template("
") export function render(_ctx) { const n0 = _createIf(() => (_ctx.ok), () => { const n2 = t0() - let _msg; + let _msg _renderEffect(() => _msg !== _ctx.msg && _setText(n2, (_msg = _ctx.msg))) return n2 }) @@ -38,7 +38,7 @@ export function render(_ctx) { const n11 = t4() return [n10, n11] })) - let _text; + let _text _renderEffect(() => _text !== _ctx.text && _setText(n13, (_text = _ctx.text))) return [n0, n13] }" @@ -72,7 +72,7 @@ export function render(_ctx) { const n2 = t0() const n3 = t1() const n4 = t2() - let _msg; + let _msg _renderEffect(() => _msg !== _ctx.msg && _setText(n4, (_msg = _ctx.msg))) return [n2, n3, n4] }) diff --git a/packages/compiler-vapor/__tests__/transforms/__snapshots__/vModel.spec.ts.snap b/packages/compiler-vapor/__tests__/transforms/__snapshots__/vModel.spec.ts.snap index bdb4acdd4..0ed562a25 100644 --- a/packages/compiler-vapor/__tests__/transforms/__snapshots__/vModel.spec.ts.snap +++ b/packages/compiler-vapor/__tests__/transforms/__snapshots__/vModel.spec.ts.snap @@ -254,7 +254,7 @@ export function render(_ctx) { _withDirectives(n0, [[_vModelDynamic, () => _ctx.model]]) _delegate(n0, "update:modelValue", () => $event => (_ctx.model = $event)) _setInheritAttrs(true) - let _obj; + let _obj _renderEffect(() => _obj !== _ctx.obj && _setDynamicProps(n0, [(_obj = _ctx.obj)], true)) return n0 }" diff --git a/packages/compiler-vapor/__tests__/transforms/__snapshots__/vText.spec.ts.snap b/packages/compiler-vapor/__tests__/transforms/__snapshots__/vText.spec.ts.snap index 2d689022a..e966c3b84 100644 --- a/packages/compiler-vapor/__tests__/transforms/__snapshots__/vText.spec.ts.snap +++ b/packages/compiler-vapor/__tests__/transforms/__snapshots__/vText.spec.ts.snap @@ -6,7 +6,7 @@ const t0 = _template("
") export function render(_ctx, $props, $emit, $attrs, $slots) { const n0 = t0() - let _str; + let _str _renderEffect(() => _str !== _ctx.str && _setText(n0, (_str = _ctx.str))) return n0 }" @@ -18,7 +18,7 @@ const t0 = _template("
") export function render(_ctx) { const n0 = t0() - let _test; + let _test _renderEffect(() => _test !== _ctx.test && _setText(n0, (_test = _ctx.test))) return n0 }" diff --git a/packages/compiler-vapor/__tests__/transforms/vBind.spec.ts b/packages/compiler-vapor/__tests__/transforms/vBind.spec.ts index 55312f7f7..469ce8c64 100644 --- a/packages/compiler-vapor/__tests__/transforms/vBind.spec.ts +++ b/packages/compiler-vapor/__tests__/transforms/vBind.spec.ts @@ -715,15 +715,15 @@ describe('compiler v-bind', () => { `) expect(code).matchSnapshot() - expect(code).contains('let _id;') + expect(code).contains('let _id') expect(code).contains( '_id !== _ctx.id && _setDOMProp(n0, "id", (_id = _ctx.id))', ) - expect(code).contains('let _lang;') + expect(code).contains('let _lang') expect(code).contains( '_lang !== _ctx.lang && _setDOMProp(n0, "lang", (_lang = _ctx.lang))', ) - expect(code).contains('let _tabindex;') + expect(code).contains('let _tabindex') expect(code).contains( '_tabindex !== _ctx.tabindex && _setDOMProp(n0, "tabindex", (_tabindex = _ctx.tabindex))', ) @@ -735,23 +735,23 @@ describe('compiler v-bind', () => { `) expect(code).matchSnapshot() - expect(code).contains('let _autofucus;') + expect(code).contains('let _autofucus') expect(code).contains( '_autofucus !== _ctx.autofucus && _setDOMProp(n0, "autofucus", (_autofucus = _ctx.autofucus))', ) - expect(code).contains('let _dir;') + expect(code).contains('let _dir') expect(code).contains( '_dir !== _ctx.dir && _setDOMProp(n0, "dir", (_dir = _ctx.dir))', ) - expect(code).contains('let _displaystyle;') + expect(code).contains('let _displaystyle') expect(code).contains( '_displaystyle !== _ctx.displaystyle && _setDOMProp(n0, "displaystyle", (_displaystyle = _ctx.displaystyle))', ) - expect(code).contains('let _mathcolor;') + expect(code).contains('let _mathcolor') expect(code).contains( '_mathcolor !== _ctx.mathcolor && _setDOMProp(n0, "mathcolor", (_mathcolor = _ctx.mathcolor))', ) - expect(code).contains('let _tabindex;') + expect(code).contains('let _tabindex') expect(code).contains( '_tabindex !== _ctx.tabindex && _setDOMProp(n0, "tabindex", (_tabindex = _ctx.tabindex))', ) @@ -762,7 +762,7 @@ describe('compiler v-bind', () => {
`) expect(code).matchSnapshot() - expect(code).contains('let _foo;') + expect(code).contains('let _foo') expect(code).contains( '_foo !== _ctx.foo && _setHtml(n0, (_foo = _ctx.foo))', ) @@ -773,7 +773,7 @@ describe('compiler v-bind', () => {
`) expect(code).matchSnapshot() - expect(code).contains('let _foo;') + expect(code).contains('let _foo') expect(code).contains( '_foo !== _ctx.foo && _setText(n0, (_foo = _ctx.foo))', ) @@ -784,7 +784,7 @@ describe('compiler v-bind', () => { `) expect(code).matchSnapshot() - expect(code).contains('let _foo;') + expect(code).contains('let _foo') expect(code).contains( '_foo !== _ctx.foo && _setValue(n0, (_foo = _ctx.foo))', ) diff --git a/packages/compiler-vapor/src/generators/operation.ts b/packages/compiler-vapor/src/generators/operation.ts index 923c59633..81f0e20e6 100644 --- a/packages/compiler-vapor/src/generators/operation.ts +++ b/packages/compiler-vapor/src/generators/operation.ts @@ -100,7 +100,7 @@ export function genEffect( // declare variables: let _foo, _bar if (varNamesToDeclare.size) { - frag.splice(1, 0, `let ${[...varNamesToDeclare].join(', ')};`, NEWLINE) + frag.splice(1, 0, `let ${[...varNamesToDeclare].join(', ')}`, NEWLINE) } const newlineCount = operationsExps.filter(frag => frag === NEWLINE).length @@ -110,6 +110,7 @@ export function genEffect( conditions.length > 0 ? [NEWLINE, `if(`, ...conditions.join(' && '), `) return`] : [] + // assignment: _foo = _ctx.foo; _bar = _ctx.bar const assignment: CodeFragment[] = conditions.length > 0 ? [NEWLINE, ...conditions.map(c => c.replace('===', '=')).join(';')] From ffb0f60dcf3324dda1712902e01c0dd62078b6ca Mon Sep 17 00:00:00 2001 From: daiwei Date: Wed, 4 Dec 2024 23:07:15 +0800 Subject: [PATCH 30/47] wip: save --- packages/compiler-vapor/src/generate.ts | 10 ++-- .../compiler-vapor/src/generators/html.ts | 4 +- .../src/generators/operation.ts | 36 +++++------ .../compiler-vapor/src/generators/prop.ts | 60 +++++++++---------- .../compiler-vapor/src/generators/text.ts | 4 +- packages/compiler-vapor/src/ir/index.ts | 6 +- packages/compiler-vapor/src/transform.ts | 6 +- 7 files changed, 64 insertions(+), 62 deletions(-) diff --git a/packages/compiler-vapor/src/generate.ts b/packages/compiler-vapor/src/generate.ts index 318fb302f..14bc78fd0 100644 --- a/packages/compiler-vapor/src/generate.ts +++ b/packages/compiler-vapor/src/generate.ts @@ -35,11 +35,13 @@ export class CodegenContext { delegates: Set = new Set() - currentRenderEffect: IREffect | undefined = undefined - renderEffectSeemNames: Record = Object.create(null) - shouldGenEffectDeps = (): boolean => { + processingRenderEffect: IREffect | undefined = undefined + allRenderEffectSeenNames: Record = Object.create(null) + shouldCacheRenderEffectDeps = (): boolean => { // only need to generate effect deps when it's not nested in v-for - return !!(this.currentRenderEffect && !this.currentRenderEffect.inVFor) + return !!( + this.processingRenderEffect && !this.processingRenderEffect.inVFor + ) } identifiers: Record = Object.create(null) diff --git a/packages/compiler-vapor/src/generators/html.ts b/packages/compiler-vapor/src/generators/html.ts index 548b47840..9175ae372 100644 --- a/packages/compiler-vapor/src/generators/html.ts +++ b/packages/compiler-vapor/src/generators/html.ts @@ -8,10 +8,10 @@ export function genSetHtml( oper: SetHtmlIRNode, context: CodegenContext, ): CodeFragment[] { - const { vaporHelper, shouldGenEffectDeps } = context + const { vaporHelper, shouldCacheRenderEffectDeps } = context const { value, element } = oper let html = genExpression(value, context) - if (shouldGenEffectDeps()) { + if (shouldCacheRenderEffectDeps()) { processValues(context, [html]) } return [NEWLINE, ...genCall(vaporHelper('setHtml'), `n${element}`, html)] diff --git a/packages/compiler-vapor/src/generators/operation.ts b/packages/compiler-vapor/src/generators/operation.ts index 81f0e20e6..db4e998c8 100644 --- a/packages/compiler-vapor/src/generators/operation.ts +++ b/packages/compiler-vapor/src/generators/operation.ts @@ -80,7 +80,7 @@ export function genEffects( ): CodeFragment[] { const [frag, push] = buildCodeFragment() for (let i = 0; i < effects.length; i++) { - const effect = (context.currentRenderEffect = effects[i]) + const effect = (context.processingRenderEffect = effects[i]) push(...genEffect(effect, context)) } return frag @@ -90,54 +90,54 @@ export function genEffect( { operations }: IREffect, context: CodegenContext, ): CodeFragment[] { - const { vaporHelper, currentRenderEffect } = context + const { vaporHelper, processingRenderEffect } = context const [frag, push] = buildCodeFragment( NEWLINE, `${vaporHelper('renderEffect')}(() => `, ) - const { varNamesToDeclare, conditions } = currentRenderEffect! + const { declareNames, earlyCheckExps } = processingRenderEffect! const operationsExps = genOperations(operations, context) // declare variables: let _foo, _bar - if (varNamesToDeclare.size) { - frag.splice(1, 0, `let ${[...varNamesToDeclare].join(', ')}`, NEWLINE) + if (declareNames.size) { + frag.splice(1, 0, `let ${[...declareNames].join(', ')}`, NEWLINE) } const newlineCount = operationsExps.filter(frag => frag === NEWLINE).length if (newlineCount > 1) { // multiline early return condition: if (_foo === _ctx.foo && _bar === _ctx.bar) return - const condition: CodeFragment[] = - conditions.length > 0 - ? [NEWLINE, `if(`, ...conditions.join(' && '), `) return`] + const checkExps: CodeFragment[] = + earlyCheckExps.length > 0 + ? [NEWLINE, `if(`, ...earlyCheckExps.join(' && '), `) return`] : [] // assignment: _foo = _ctx.foo; _bar = _ctx.bar - const assignment: CodeFragment[] = - conditions.length > 0 - ? [NEWLINE, ...conditions.map(c => c.replace('===', '=')).join(';')] + const assignmentExps: CodeFragment[] = + earlyCheckExps.length > 0 + ? [NEWLINE, ...earlyCheckExps.map(c => c.replace('===', '=')).join(';')] : [] push( '{', INDENT_START, - ...condition, + ...checkExps, ...operationsExps, - ...assignment, + ...assignmentExps, INDENT_END, NEWLINE, '})', ) } else { // single line early return condition: (_foo !== _ctx.foo || _bar !== _ctx.bar) && - const multiple = conditions.length > 1 - const condition: CodeFragment[] = - conditions.length > 0 + const multiple = earlyCheckExps.length > 1 + const checkExps: CodeFragment[] = + earlyCheckExps.length > 0 ? [ multiple ? `(` : undefined, - ...conditions.join(' || '), + ...earlyCheckExps.join(' || '), multiple ? `)` : undefined, ' && ', ] : [] - push(...condition, ...operationsExps.filter(frag => frag !== NEWLINE), ')') + push(...checkExps, ...operationsExps.filter(frag => frag !== NEWLINE), ')') } return frag diff --git a/packages/compiler-vapor/src/generators/prop.ts b/packages/compiler-vapor/src/generators/prop.ts index 4d4b81442..da6534e5d 100644 --- a/packages/compiler-vapor/src/generators/prop.ts +++ b/packages/compiler-vapor/src/generators/prop.ts @@ -42,7 +42,8 @@ export function genSetProp( oper: SetPropIRNode, context: CodegenContext, ): CodeFragment[] { - const { vaporHelper, shouldGenEffectDeps, currentRenderEffect } = context + const { vaporHelper, shouldCacheRenderEffectDeps, processingRenderEffect } = + context const { prop: { key, values, modifier }, tag, @@ -50,18 +51,15 @@ export function genSetProp( const { helperName, omitKey } = getRuntimeHelper(tag, key.content, modifier) let propValue = genPropValue(values, context) - if (shouldGenEffectDeps()) { + if (shouldCacheRenderEffectDeps()) { processValues(context, [propValue]) - const { varNamesToDeclare } = currentRenderEffect! + const { declareNames } = processingRenderEffect! // need prevValue parameter - if ( - varNamesToDeclare.size > 0 && - helperNeedPrevValue.includes(helperName) - ) { - const prevValueName = [...varNamesToDeclare].join('') - varNamesToDeclare.add(prevValueName) - const needReCacheValue = varNamesToDeclare.size > 1 + if (declareNames.size > 0 && helperNeedPrevValue.includes(helperName)) { + const prevValueName = [...declareNames].join('') + declareNames.add(prevValueName) + const needReCacheValue = declareNames.size > 1 propValue.unshift( ...[ `${prevValueName}, `, // prevValue parameter @@ -92,7 +90,7 @@ export function genDynamicProps( oper: SetDynamicPropsIRNode, context: CodegenContext, ): CodeFragment[] { - const { vaporHelper, shouldGenEffectDeps } = context + const { vaporHelper, shouldCacheRenderEffectDeps } = context const values = oper.props.map(props => Array.isArray(props) ? genLiteralObjectProps(props, context) // static and dynamic arg props @@ -101,7 +99,7 @@ export function genDynamicProps( : genExpression(props.value, context), ) // v-bind="" - if (shouldGenEffectDeps()) { + if (shouldCacheRenderEffectDeps()) { processValues(context, values) } @@ -268,14 +266,16 @@ export function processValues( context: CodegenContext, values: CodeFragment[][], ): string[] { - const conditions: string[] = [] + const allCheckExps: string[] = [] values.forEach(value => { - const condition = processValue(context, value) - if (condition) conditions.push(...condition, ' && ') + const checkExps = processValue(context, value) + if (checkExps) allCheckExps.push(...checkExps, ' && ') }) - return conditions.length > 0 - ? (context.currentRenderEffect!.conditions = [...new Set(conditions)]) + return allCheckExps.length > 0 + ? (context.processingRenderEffect!.earlyCheckExps = [ + ...new Set(allCheckExps), + ]) : [] } @@ -283,9 +283,9 @@ function processValue( context: CodegenContext, values: CodeFragment[], ): string[] | undefined { - const { currentRenderEffect, renderEffectSeemNames } = context - const { varNamesToDeclare, varNamesOverwritten, conditions, operations } = - currentRenderEffect! + const { processingRenderEffect, allRenderEffectSeenNames } = context + const { declareNames, rewrittenNames, earlyCheckExps, operations } = + processingRenderEffect! const isMultiLine = operations.length > 1 for (const frag of values) { @@ -294,19 +294,19 @@ function processValue( const [newName, , , rawName] = frag if (rawName) { let name = rawName.replace(/[^\w]/g, '_') - if (varNamesOverwritten.has(name)) continue - varNamesOverwritten.add(name) + if (rewrittenNames.has(name)) continue + rewrittenNames.add(name) name = `_${name}` - if (varNamesToDeclare.has(name)) continue + if (declareNames.has(name)) continue - if (renderEffectSeemNames[name] === undefined) - renderEffectSeemNames[name] = 0 - else name += ++renderEffectSeemNames[name] + if (allRenderEffectSeenNames[name] === undefined) + allRenderEffectSeenNames[name] = 0 + else name += ++allRenderEffectSeenNames[name] - varNamesToDeclare.add(name) + declareNames.add(name) // for multiline renderEffect the early return condition should be `if (_foo === _ctx.foo) return` - conditions.push(`${name} ${isMultiLine ? '===' : '!=='} ${newName}`) + earlyCheckExps.push(`${name} ${isMultiLine ? '===' : '!=='} ${newName}`) if (!isMultiLine) { // replace the original code fragment with the assignment expression @@ -315,7 +315,7 @@ function processValue( } } - if (conditions.length > 0) { - return [[...new Set(conditions)].join(' && ')] + if (earlyCheckExps.length > 0) { + return [[...new Set(earlyCheckExps)].join(' && ')] } } diff --git a/packages/compiler-vapor/src/generators/text.ts b/packages/compiler-vapor/src/generators/text.ts index 4c9c86334..7eaaaa7fc 100644 --- a/packages/compiler-vapor/src/generators/text.ts +++ b/packages/compiler-vapor/src/generators/text.ts @@ -14,10 +14,10 @@ export function genSetText( oper: SetTextIRNode, context: CodegenContext, ): CodeFragment[] { - const { vaporHelper, shouldGenEffectDeps } = context + const { vaporHelper, shouldCacheRenderEffectDeps } = context const { element, values } = oper const texts = values.map(value => genExpression(value, context)) - if (shouldGenEffectDeps()) { + if (shouldCacheRenderEffectDeps()) { processValues(context, texts) } return [NEWLINE, ...genCall(vaporHelper('setText'), `n${element}`, ...texts)] diff --git a/packages/compiler-vapor/src/ir/index.ts b/packages/compiler-vapor/src/ir/index.ts index 5860ee532..9c735c487 100644 --- a/packages/compiler-vapor/src/ir/index.ts +++ b/packages/compiler-vapor/src/ir/index.ts @@ -267,9 +267,9 @@ export interface IRDynamicInfo { export interface IREffect { expressions: SimpleExpressionNode[] operations: OperationNode[] - varNamesToDeclare: Set - varNamesOverwritten: Set - conditions: string[] + declareNames: Set + rewrittenNames: Set + earlyCheckExps: string[] inVFor: boolean } diff --git a/packages/compiler-vapor/src/transform.ts b/packages/compiler-vapor/src/transform.ts index d19c0899b..619ec7232 100644 --- a/packages/compiler-vapor/src/transform.ts +++ b/packages/compiler-vapor/src/transform.ts @@ -151,9 +151,9 @@ export class TransformContext { this.block.effect.push({ expressions, operations, - conditions: [], - varNamesToDeclare: new Set(), - varNamesOverwritten: new Set(), + earlyCheckExps: [], + declareNames: new Set(), + rewrittenNames: new Set(), inVFor: this.inVFor > 0, }) } From 5eabc92725acc58b7b6a1d35314a41f430296afc Mon Sep 17 00:00:00 2001 From: daiwei Date: Thu, 5 Dec 2024 10:22:32 +0800 Subject: [PATCH 31/47] wip: save --- packages/compiler-vapor/src/generators/operation.ts | 13 ++++++++----- packages/compiler-vapor/src/generators/prop.ts | 3 +-- 2 files changed, 9 insertions(+), 7 deletions(-) diff --git a/packages/compiler-vapor/src/generators/operation.ts b/packages/compiler-vapor/src/generators/operation.ts index db4e998c8..b3600ea2d 100644 --- a/packages/compiler-vapor/src/generators/operation.ts +++ b/packages/compiler-vapor/src/generators/operation.ts @@ -105,22 +105,25 @@ export function genEffect( const newlineCount = operationsExps.filter(frag => frag === NEWLINE).length if (newlineCount > 1) { - // multiline early return condition: if (_foo === _ctx.foo && _bar === _ctx.bar) return - const checkExps: CodeFragment[] = + // multiline early return condition: if (_foo !== _ctx.foo || _bar !== _ctx.bar) { + const checkExpsStart: CodeFragment[] = earlyCheckExps.length > 0 - ? [NEWLINE, `if(`, ...earlyCheckExps.join(' && '), `) return`] + ? [NEWLINE, `if(`, ...earlyCheckExps.join(' || '), `) {`, INDENT_START] : [] + const checkExpsEnd: CodeFragment[] = + earlyCheckExps.length > 0 ? [INDENT_END, NEWLINE, '}'] : [] // assignment: _foo = _ctx.foo; _bar = _ctx.bar const assignmentExps: CodeFragment[] = earlyCheckExps.length > 0 - ? [NEWLINE, ...earlyCheckExps.map(c => c.replace('===', '=')).join(';')] + ? [NEWLINE, ...earlyCheckExps.map(c => c.replace('!==', '=')).join(';')] : [] push( '{', INDENT_START, - ...checkExps, + ...checkExpsStart, ...operationsExps, ...assignmentExps, + ...checkExpsEnd, INDENT_END, NEWLINE, '})', diff --git a/packages/compiler-vapor/src/generators/prop.ts b/packages/compiler-vapor/src/generators/prop.ts index da6534e5d..155ba86a0 100644 --- a/packages/compiler-vapor/src/generators/prop.ts +++ b/packages/compiler-vapor/src/generators/prop.ts @@ -305,8 +305,7 @@ function processValue( else name += ++allRenderEffectSeenNames[name] declareNames.add(name) - // for multiline renderEffect the early return condition should be `if (_foo === _ctx.foo) return` - earlyCheckExps.push(`${name} ${isMultiLine ? '===' : '!=='} ${newName}`) + earlyCheckExps.push(`${name} !== ${newName}`) if (!isMultiLine) { // replace the original code fragment with the assignment expression From 275c626229c24590f5fe7826c0046e6e024adde1 Mon Sep 17 00:00:00 2001 From: daiwei Date: Thu, 5 Dec 2024 10:25:35 +0800 Subject: [PATCH 32/47] wip: save --- packages/compiler-vapor/src/generators/operation.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/packages/compiler-vapor/src/generators/operation.ts b/packages/compiler-vapor/src/generators/operation.ts index b3600ea2d..a52f28ae8 100644 --- a/packages/compiler-vapor/src/generators/operation.ts +++ b/packages/compiler-vapor/src/generators/operation.ts @@ -105,7 +105,7 @@ export function genEffect( const newlineCount = operationsExps.filter(frag => frag === NEWLINE).length if (newlineCount > 1) { - // multiline early return condition: if (_foo !== _ctx.foo || _bar !== _ctx.bar) { + // multiline check expression: if (_foo !== _ctx.foo || _bar !== _ctx.bar) { const checkExpsStart: CodeFragment[] = earlyCheckExps.length > 0 ? [NEWLINE, `if(`, ...earlyCheckExps.join(' || '), `) {`, INDENT_START] @@ -129,7 +129,7 @@ export function genEffect( '})', ) } else { - // single line early return condition: (_foo !== _ctx.foo || _bar !== _ctx.bar) && + // single line check expression: (_foo !== _ctx.foo || _bar !== _ctx.bar) && const multiple = earlyCheckExps.length > 1 const checkExps: CodeFragment[] = earlyCheckExps.length > 0 From bb2a8a823f315f580d63a983191ac8e03d497aa6 Mon Sep 17 00:00:00 2001 From: daiwei Date: Thu, 5 Dec 2024 10:39:01 +0800 Subject: [PATCH 33/47] refactor: merge renderEffect --- .../src/generators/operation.ts | 19 +++++++------------ 1 file changed, 7 insertions(+), 12 deletions(-) diff --git a/packages/compiler-vapor/src/generators/operation.ts b/packages/compiler-vapor/src/generators/operation.ts index a52f28ae8..864a32e04 100644 --- a/packages/compiler-vapor/src/generators/operation.ts +++ b/packages/compiler-vapor/src/generators/operation.ts @@ -78,11 +78,14 @@ export function genEffects( effects: IREffect[], context: CodegenContext, ): CodeFragment[] { + const { vaporHelper } = context const [frag, push] = buildCodeFragment() + push(NEWLINE, `${vaporHelper('renderEffect')}(() => {`, INDENT_START) for (let i = 0; i < effects.length; i++) { const effect = (context.processingRenderEffect = effects[i]) push(...genEffect(effect, context)) } + push(INDENT_END, NEWLINE, '})') return frag } @@ -90,11 +93,8 @@ export function genEffect( { operations }: IREffect, context: CodegenContext, ): CodeFragment[] { - const { vaporHelper, processingRenderEffect } = context - const [frag, push] = buildCodeFragment( - NEWLINE, - `${vaporHelper('renderEffect')}(() => `, - ) + const { processingRenderEffect } = context + const [frag, push] = buildCodeFragment(NEWLINE) const { declareNames, earlyCheckExps } = processingRenderEffect! const operationsExps = genOperations(operations, context) @@ -108,7 +108,7 @@ export function genEffect( // multiline check expression: if (_foo !== _ctx.foo || _bar !== _ctx.bar) { const checkExpsStart: CodeFragment[] = earlyCheckExps.length > 0 - ? [NEWLINE, `if(`, ...earlyCheckExps.join(' || '), `) {`, INDENT_START] + ? [`if(`, ...earlyCheckExps.join(' || '), `) {`, INDENT_START] : [] const checkExpsEnd: CodeFragment[] = earlyCheckExps.length > 0 ? [INDENT_END, NEWLINE, '}'] : [] @@ -118,15 +118,10 @@ export function genEffect( ? [NEWLINE, ...earlyCheckExps.map(c => c.replace('!==', '=')).join(';')] : [] push( - '{', - INDENT_START, ...checkExpsStart, ...operationsExps, ...assignmentExps, ...checkExpsEnd, - INDENT_END, - NEWLINE, - '})', ) } else { // single line check expression: (_foo !== _ctx.foo || _bar !== _ctx.bar) && @@ -140,7 +135,7 @@ export function genEffect( ' && ', ] : [] - push(...checkExps, ...operationsExps.filter(frag => frag !== NEWLINE), ')') + push(...checkExps, ...operationsExps.filter(frag => frag !== NEWLINE)) } return frag From a3984a783c0f29caf78ae7c177bf680ef2f824d9 Mon Sep 17 00:00:00 2001 From: daiwei Date: Thu, 5 Dec 2024 11:34:01 +0800 Subject: [PATCH 34/47] wip: save --- .../__snapshots__/compile.spec.ts.snap | 13 +- .../transformChildren.spec.ts.snap | 9 +- .../transformElement.spec.ts.snap | 14 +- .../transformTemplateRef.spec.ts.snap | 2 +- .../__snapshots__/vBind.spec.ts.snap | 167 ++++++++---------- .../__snapshots__/vFor.spec.ts.snap | 18 +- .../__snapshots__/vHtml.spec.ts.snap | 4 +- .../transforms/__snapshots__/vIf.spec.ts.snap | 6 +- .../__snapshots__/vModel.spec.ts.snap | 2 +- .../transforms/__snapshots__/vOn.spec.ts.snap | 18 +- .../__snapshots__/vText.spec.ts.snap | 4 +- .../__tests__/transforms/vBind.spec.ts | 12 +- .../src/generators/operation.ts | 30 +++- .../compiler-vapor/src/generators/utils.ts | 9 +- 14 files changed, 157 insertions(+), 151 deletions(-) diff --git a/packages/compiler-vapor/__tests__/__snapshots__/compile.spec.ts.snap b/packages/compiler-vapor/__tests__/__snapshots__/compile.spec.ts.snap index 1818f13ea..651e79472 100644 --- a/packages/compiler-vapor/__tests__/__snapshots__/compile.spec.ts.snap +++ b/packages/compiler-vapor/__tests__/__snapshots__/compile.spec.ts.snap @@ -1,7 +1,7 @@ // Vitest Snapshot v1, https://vitest.dev/guide/snapshot.html exports[`compile > bindings 1`] = ` -"import { renderEffect as _renderEffect, setText as _setText, template as _template } from 'vue/vapor'; +"import { setText as _setText, renderEffect as _renderEffect, template as _template } from 'vue/vapor'; const t0 = _template("
") export function render(_ctx, $props, $emit, $attrs, $slots) { @@ -152,7 +152,7 @@ export function render(_ctx, $props, $emit, $attrs, $slots) { `; exports[`compile > directives > v-pre > should not affect siblings after it 1`] = ` -"import { resolveComponent as _resolveComponent, createComponent as _createComponent, createTextNode as _createTextNode, insert as _insert, renderEffect as _renderEffect, setDOMProp as _setDOMProp, template as _template } from 'vue/vapor'; +"import { resolveComponent as _resolveComponent, createComponent as _createComponent, createTextNode as _createTextNode, insert as _insert, setDOMProp as _setDOMProp, renderEffect as _renderEffect, template as _template } from 'vue/vapor'; const t0 = _template("
{{ bar }}
") const t1 = _template("
") @@ -179,7 +179,7 @@ export function render(_ctx) { `; exports[`compile > dynamic root nodes and interpolation 1`] = ` -"import { delegate as _delegate, setInheritAttrs as _setInheritAttrs, renderEffect as _renderEffect, setText as _setText, setDOMProp as _setDOMProp, delegateEvents as _delegateEvents, template as _template } from 'vue/vapor'; +"import { delegate as _delegate, setInheritAttrs as _setInheritAttrs, setText as _setText, setDOMProp as _setDOMProp, renderEffect as _renderEffect, delegateEvents as _delegateEvents, template as _template } from 'vue/vapor'; const t0 = _template("") _delegateEvents("click") @@ -187,10 +187,9 @@ export function render(_ctx) { const n0 = t0() _delegate(n0, "click", () => _ctx.handleClick) _setInheritAttrs(["id"]) - let _count - _renderEffect(() => _count !== _ctx.count && _setText(n0, (_count = _ctx.count), "foo", _ctx.count, "foo", _ctx.count)) - let _count1 - _renderEffect(() => _count1 !== _ctx.count && _setDOMProp(n0, "id", (_count1 = _ctx.count))) + let _count, _count1 + _renderEffect(() => _count !== _ctx.count && _setText(n0, (_count = _ctx.count), "foo", _ctx.count, "foo", _ctx.count) + _count1 !== _ctx.count && _setDOMProp(n0, "id", (_count1 = _ctx.count))) return n0 }" `; diff --git a/packages/compiler-vapor/__tests__/transforms/__snapshots__/transformChildren.spec.ts.snap b/packages/compiler-vapor/__tests__/transforms/__snapshots__/transformChildren.spec.ts.snap index c868e413b..4d9b23978 100644 --- a/packages/compiler-vapor/__tests__/transforms/__snapshots__/transformChildren.spec.ts.snap +++ b/packages/compiler-vapor/__tests__/transforms/__snapshots__/transformChildren.spec.ts.snap @@ -1,7 +1,7 @@ // Vitest Snapshot v1, https://vitest.dev/guide/snapshot.html exports[`compiler: children transform > children & sibling references 1`] = ` -"import { next as _next, createTextNode as _createTextNode, insert as _insert, renderEffect as _renderEffect, setText as _setText, template as _template } from 'vue/vapor'; +"import { next as _next, createTextNode as _createTextNode, insert as _insert, setText as _setText, renderEffect as _renderEffect, template as _template } from 'vue/vapor'; const t0 = _template("

") export function render(_ctx) { @@ -11,10 +11,9 @@ export function render(_ctx) { const n2 = n3.nextSibling const n1 = _createTextNode(() => [_ctx.second, " ", _ctx.third, " "]) _insert(n1, n4, n3) - let _first - _renderEffect(() => _first !== _ctx.first && _setText(n0, (_first = _ctx.first))) - let _forth - _renderEffect(() => _forth !== _ctx.forth && _setText(n2, (_forth = _ctx.forth))) + let _first, _forth + _renderEffect(() => _first !== _ctx.first && _setText(n0, (_first = _ctx.first)) + _forth !== _ctx.forth && _setText(n2, (_forth = _ctx.forth))) return n4 }" `; diff --git a/packages/compiler-vapor/__tests__/transforms/__snapshots__/transformElement.spec.ts.snap b/packages/compiler-vapor/__tests__/transforms/__snapshots__/transformElement.spec.ts.snap index 829a34ec3..fac547334 100644 --- a/packages/compiler-vapor/__tests__/transforms/__snapshots__/transformElement.spec.ts.snap +++ b/packages/compiler-vapor/__tests__/transforms/__snapshots__/transformElement.spec.ts.snap @@ -297,7 +297,7 @@ export function render(_ctx) { `; exports[`compiler: element transform > props merging: class 1`] = ` -"import { setInheritAttrs as _setInheritAttrs, renderEffect as _renderEffect, setClass as _setClass, template as _template } from 'vue/vapor'; +"import { setInheritAttrs as _setInheritAttrs, setClass as _setClass, renderEffect as _renderEffect, template as _template } from 'vue/vapor'; const t0 = _template("
") export function render(_ctx) { @@ -327,7 +327,7 @@ export function render(_ctx) { `; exports[`compiler: element transform > props merging: style 1`] = ` -"import { setInheritAttrs as _setInheritAttrs, renderEffect as _renderEffect, setStyle as _setStyle, template as _template } from 'vue/vapor'; +"import { setInheritAttrs as _setInheritAttrs, setStyle as _setStyle, renderEffect as _renderEffect, template as _template } from 'vue/vapor'; const t0 = _template("
") export function render(_ctx) { @@ -350,7 +350,7 @@ export function render(_ctx) { `; exports[`compiler: element transform > v-bind="obj" 1`] = ` -"import { setInheritAttrs as _setInheritAttrs, renderEffect as _renderEffect, setDynamicProps as _setDynamicProps, template as _template } from 'vue/vapor'; +"import { setInheritAttrs as _setInheritAttrs, setDynamicProps as _setDynamicProps, renderEffect as _renderEffect, template as _template } from 'vue/vapor'; const t0 = _template("
") export function render(_ctx) { @@ -363,7 +363,7 @@ export function render(_ctx) { `; exports[`compiler: element transform > v-bind="obj" after static prop 1`] = ` -"import { setInheritAttrs as _setInheritAttrs, renderEffect as _renderEffect, setDynamicProps as _setDynamicProps, template as _template } from 'vue/vapor'; +"import { setInheritAttrs as _setInheritAttrs, setDynamicProps as _setDynamicProps, renderEffect as _renderEffect, template as _template } from 'vue/vapor'; const t0 = _template("
") export function render(_ctx) { @@ -376,7 +376,7 @@ export function render(_ctx) { `; exports[`compiler: element transform > v-bind="obj" before static prop 1`] = ` -"import { setInheritAttrs as _setInheritAttrs, renderEffect as _renderEffect, setDynamicProps as _setDynamicProps, template as _template } from 'vue/vapor'; +"import { setInheritAttrs as _setInheritAttrs, setDynamicProps as _setDynamicProps, renderEffect as _renderEffect, template as _template } from 'vue/vapor'; const t0 = _template("
") export function render(_ctx) { @@ -389,7 +389,7 @@ export function render(_ctx) { `; exports[`compiler: element transform > v-bind="obj" between static props 1`] = ` -"import { setInheritAttrs as _setInheritAttrs, renderEffect as _renderEffect, setDynamicProps as _setDynamicProps, template as _template } from 'vue/vapor'; +"import { setInheritAttrs as _setInheritAttrs, setDynamicProps as _setDynamicProps, renderEffect as _renderEffect, template as _template } from 'vue/vapor'; const t0 = _template("
") export function render(_ctx) { @@ -402,7 +402,7 @@ export function render(_ctx) { `; exports[`compiler: element transform > v-on="obj" 1`] = ` -"import { renderEffect as _renderEffect, setDynamicEvents as _setDynamicEvents, template as _template } from 'vue/vapor'; +"import { setDynamicEvents as _setDynamicEvents, renderEffect as _renderEffect, template as _template } from 'vue/vapor'; const t0 = _template("
") export function render(_ctx) { diff --git a/packages/compiler-vapor/__tests__/transforms/__snapshots__/transformTemplateRef.spec.ts.snap b/packages/compiler-vapor/__tests__/transforms/__snapshots__/transformTemplateRef.spec.ts.snap index a60019925..efada2de9 100644 --- a/packages/compiler-vapor/__tests__/transforms/__snapshots__/transformTemplateRef.spec.ts.snap +++ b/packages/compiler-vapor/__tests__/transforms/__snapshots__/transformTemplateRef.spec.ts.snap @@ -1,7 +1,7 @@ // Vitest Snapshot v1, https://vitest.dev/guide/snapshot.html exports[`compiler: template ref transform > dynamic ref 1`] = ` -"import { renderEffect as _renderEffect, setRef as _setRef, template as _template } from 'vue/vapor'; +"import { setRef as _setRef, renderEffect as _renderEffect, template as _template } from 'vue/vapor'; const t0 = _template("
") export function render(_ctx) { 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 896a1a356..ef7717859 100644 --- a/packages/compiler-vapor/__tests__/transforms/__snapshots__/vBind.spec.ts.snap +++ b/packages/compiler-vapor/__tests__/transforms/__snapshots__/vBind.spec.ts.snap @@ -1,7 +1,7 @@ // Vitest Snapshot v1, https://vitest.dev/guide/snapshot.html exports[`compiler v-bind > .attr modifier 1`] = ` -"import { setInheritAttrs as _setInheritAttrs, renderEffect as _renderEffect, setAttr as _setAttr, template as _template } from 'vue/vapor'; +"import { setInheritAttrs as _setInheritAttrs, setAttr as _setAttr, renderEffect as _renderEffect, template as _template } from 'vue/vapor'; const t0 = _template("
") export function render(_ctx) { @@ -14,7 +14,7 @@ export function render(_ctx) { `; exports[`compiler v-bind > .attr modifier w/ innerHTML 1`] = ` -"import { setInheritAttrs as _setInheritAttrs, renderEffect as _renderEffect, setAttr as _setAttr, template as _template } from 'vue/vapor'; +"import { setInheritAttrs as _setInheritAttrs, setAttr as _setAttr, renderEffect as _renderEffect, template as _template } from 'vue/vapor'; const t0 = _template("
") export function render(_ctx) { @@ -27,7 +27,7 @@ export function render(_ctx) { `; exports[`compiler v-bind > .attr modifier w/ no expression 1`] = ` -"import { setInheritAttrs as _setInheritAttrs, renderEffect as _renderEffect, setAttr as _setAttr, template as _template } from 'vue/vapor'; +"import { setInheritAttrs as _setInheritAttrs, setAttr as _setAttr, renderEffect as _renderEffect, template as _template } from 'vue/vapor'; const t0 = _template("
") export function render(_ctx) { @@ -40,7 +40,7 @@ export function render(_ctx) { `; exports[`compiler v-bind > .attr modifier w/ progress value 1`] = ` -"import { setInheritAttrs as _setInheritAttrs, renderEffect as _renderEffect, setAttr as _setAttr, template as _template } from 'vue/vapor'; +"import { setInheritAttrs as _setInheritAttrs, setAttr as _setAttr, renderEffect as _renderEffect, template as _template } from 'vue/vapor'; const t0 = _template("") export function render(_ctx) { @@ -53,7 +53,7 @@ export function render(_ctx) { `; exports[`compiler v-bind > .attr modifier w/ textContent 1`] = ` -"import { setInheritAttrs as _setInheritAttrs, renderEffect as _renderEffect, setAttr as _setAttr, template as _template } from 'vue/vapor'; +"import { setInheritAttrs as _setInheritAttrs, setAttr as _setAttr, renderEffect as _renderEffect, template as _template } from 'vue/vapor'; const t0 = _template("
") export function render(_ctx) { @@ -66,7 +66,7 @@ export function render(_ctx) { `; exports[`compiler v-bind > .attr modifier w/ value 1`] = ` -"import { setInheritAttrs as _setInheritAttrs, renderEffect as _renderEffect, setAttr as _setAttr, template as _template } from 'vue/vapor'; +"import { setInheritAttrs as _setInheritAttrs, setAttr as _setAttr, renderEffect as _renderEffect, template as _template } from 'vue/vapor'; const t0 = _template("
") export function render(_ctx) { @@ -79,7 +79,7 @@ export function render(_ctx) { `; exports[`compiler v-bind > .camel modifier 1`] = ` -"import { setInheritAttrs as _setInheritAttrs, renderEffect as _renderEffect, setDynamicProp as _setDynamicProp, template as _template } from 'vue/vapor'; +"import { setInheritAttrs as _setInheritAttrs, setDynamicProp as _setDynamicProp, renderEffect as _renderEffect, template as _template } from 'vue/vapor'; const t0 = _template("
") export function render(_ctx) { @@ -93,7 +93,7 @@ export function render(_ctx) { exports[`compiler v-bind > .camel modifier w/ dynamic arg 1`] = ` "import { camelize as _camelize } from 'vue'; -import { setInheritAttrs as _setInheritAttrs, renderEffect as _renderEffect, setDynamicProps as _setDynamicProps, template as _template } from 'vue/vapor'; +import { setInheritAttrs as _setInheritAttrs, setDynamicProps as _setDynamicProps, renderEffect as _renderEffect, template as _template } from 'vue/vapor'; const t0 = _template("
") export function render(_ctx) { @@ -106,7 +106,7 @@ export function render(_ctx) { `; exports[`compiler v-bind > .camel modifier w/ no expression 1`] = ` -"import { setInheritAttrs as _setInheritAttrs, renderEffect as _renderEffect, setDynamicProp as _setDynamicProp, template as _template } from 'vue/vapor'; +"import { setInheritAttrs as _setInheritAttrs, setDynamicProp as _setDynamicProp, renderEffect as _renderEffect, template as _template } from 'vue/vapor'; const t0 = _template("
") export function render(_ctx) { @@ -119,7 +119,7 @@ export function render(_ctx) { `; exports[`compiler v-bind > .prop modifier (shorthand) 1`] = ` -"import { setInheritAttrs as _setInheritAttrs, renderEffect as _renderEffect, setDOMProp as _setDOMProp, template as _template } from 'vue/vapor'; +"import { setInheritAttrs as _setInheritAttrs, setDOMProp as _setDOMProp, renderEffect as _renderEffect, template as _template } from 'vue/vapor'; const t0 = _template("
") export function render(_ctx) { @@ -132,7 +132,7 @@ export function render(_ctx) { `; exports[`compiler v-bind > .prop modifier (shorthand) w/ innerHTML 1`] = ` -"import { setInheritAttrs as _setInheritAttrs, renderEffect as _renderEffect, setHtml as _setHtml, template as _template } from 'vue/vapor'; +"import { setInheritAttrs as _setInheritAttrs, setHtml as _setHtml, renderEffect as _renderEffect, template as _template } from 'vue/vapor'; const t0 = _template("
") export function render(_ctx) { @@ -145,7 +145,7 @@ export function render(_ctx) { `; exports[`compiler v-bind > .prop modifier (shorthand) w/ no expression 1`] = ` -"import { setInheritAttrs as _setInheritAttrs, renderEffect as _renderEffect, setDOMProp as _setDOMProp, template as _template } from 'vue/vapor'; +"import { setInheritAttrs as _setInheritAttrs, setDOMProp as _setDOMProp, renderEffect as _renderEffect, template as _template } from 'vue/vapor'; const t0 = _template("
") export function render(_ctx) { @@ -158,7 +158,7 @@ export function render(_ctx) { `; exports[`compiler v-bind > .prop modifier (shorthand) w/ progress value 1`] = ` -"import { setInheritAttrs as _setInheritAttrs, renderEffect as _renderEffect, setDOMProp as _setDOMProp, template as _template } from 'vue/vapor'; +"import { setInheritAttrs as _setInheritAttrs, setDOMProp as _setDOMProp, renderEffect as _renderEffect, template as _template } from 'vue/vapor'; const t0 = _template("") export function render(_ctx) { @@ -171,7 +171,7 @@ export function render(_ctx) { `; exports[`compiler v-bind > .prop modifier (shorthand) w/ textContent 1`] = ` -"import { setInheritAttrs as _setInheritAttrs, renderEffect as _renderEffect, setText as _setText, template as _template } from 'vue/vapor'; +"import { setInheritAttrs as _setInheritAttrs, setText as _setText, renderEffect as _renderEffect, template as _template } from 'vue/vapor'; const t0 = _template("
") export function render(_ctx) { @@ -184,7 +184,7 @@ export function render(_ctx) { `; exports[`compiler v-bind > .prop modifier (shorthand) w/ value 1`] = ` -"import { setInheritAttrs as _setInheritAttrs, renderEffect as _renderEffect, setValue as _setValue, template as _template } from 'vue/vapor'; +"import { setInheritAttrs as _setInheritAttrs, setValue as _setValue, renderEffect as _renderEffect, template as _template } from 'vue/vapor'; const t0 = _template("
") export function render(_ctx) { @@ -197,7 +197,7 @@ export function render(_ctx) { `; exports[`compiler v-bind > .prop modifier 1`] = ` -"import { setInheritAttrs as _setInheritAttrs, renderEffect as _renderEffect, setDOMProp as _setDOMProp, template as _template } from 'vue/vapor'; +"import { setInheritAttrs as _setInheritAttrs, setDOMProp as _setDOMProp, renderEffect as _renderEffect, template as _template } from 'vue/vapor'; const t0 = _template("
") export function render(_ctx) { @@ -210,7 +210,7 @@ export function render(_ctx) { `; exports[`compiler v-bind > .prop modifier w/ dynamic arg 1`] = ` -"import { setInheritAttrs as _setInheritAttrs, renderEffect as _renderEffect, setDynamicProps as _setDynamicProps, template as _template } from 'vue/vapor'; +"import { setInheritAttrs as _setInheritAttrs, setDynamicProps as _setDynamicProps, renderEffect as _renderEffect, template as _template } from 'vue/vapor'; const t0 = _template("
") export function render(_ctx) { @@ -223,7 +223,7 @@ export function render(_ctx) { `; exports[`compiler v-bind > .prop modifier w/ innerHTML 1`] = ` -"import { setInheritAttrs as _setInheritAttrs, renderEffect as _renderEffect, setHtml as _setHtml, template as _template } from 'vue/vapor'; +"import { setInheritAttrs as _setInheritAttrs, setHtml as _setHtml, renderEffect as _renderEffect, template as _template } from 'vue/vapor'; const t0 = _template("
") export function render(_ctx) { @@ -236,7 +236,7 @@ export function render(_ctx) { `; exports[`compiler v-bind > .prop modifier w/ no expression 1`] = ` -"import { setInheritAttrs as _setInheritAttrs, renderEffect as _renderEffect, setDOMProp as _setDOMProp, template as _template } from 'vue/vapor'; +"import { setInheritAttrs as _setInheritAttrs, setDOMProp as _setDOMProp, renderEffect as _renderEffect, template as _template } from 'vue/vapor'; const t0 = _template("
") export function render(_ctx) { @@ -249,7 +249,7 @@ export function render(_ctx) { `; exports[`compiler v-bind > .prop modifier w/ progress value 1`] = ` -"import { setInheritAttrs as _setInheritAttrs, renderEffect as _renderEffect, setDOMProp as _setDOMProp, template as _template } from 'vue/vapor'; +"import { setInheritAttrs as _setInheritAttrs, setDOMProp as _setDOMProp, renderEffect as _renderEffect, template as _template } from 'vue/vapor'; const t0 = _template("") export function render(_ctx) { @@ -262,7 +262,7 @@ export function render(_ctx) { `; exports[`compiler v-bind > .prop modifier w/ textContent 1`] = ` -"import { setInheritAttrs as _setInheritAttrs, renderEffect as _renderEffect, setText as _setText, template as _template } from 'vue/vapor'; +"import { setInheritAttrs as _setInheritAttrs, setText as _setText, renderEffect as _renderEffect, template as _template } from 'vue/vapor'; const t0 = _template("
") export function render(_ctx) { @@ -275,7 +275,7 @@ export function render(_ctx) { `; exports[`compiler v-bind > .prop modifier w/ value 1`] = ` -"import { setInheritAttrs as _setInheritAttrs, renderEffect as _renderEffect, setValue as _setValue, template as _template } from 'vue/vapor'; +"import { setInheritAttrs as _setInheritAttrs, setValue as _setValue, renderEffect as _renderEffect, template as _template } from 'vue/vapor'; const t0 = _template("
") export function render(_ctx) { @@ -288,7 +288,7 @@ export function render(_ctx) { `; exports[`compiler v-bind > :innerHTML 1`] = ` -"import { setInheritAttrs as _setInheritAttrs, renderEffect as _renderEffect, setHtml as _setHtml, template as _template } from 'vue/vapor'; +"import { setInheritAttrs as _setInheritAttrs, setHtml as _setHtml, renderEffect as _renderEffect, template as _template } from 'vue/vapor'; const t0 = _template("
") export function render(_ctx) { @@ -301,7 +301,7 @@ export function render(_ctx) { `; exports[`compiler v-bind > :textContext 1`] = ` -"import { setInheritAttrs as _setInheritAttrs, renderEffect as _renderEffect, setText as _setText, template as _template } from 'vue/vapor'; +"import { setInheritAttrs as _setInheritAttrs, setText as _setText, renderEffect as _renderEffect, template as _template } from 'vue/vapor'; const t0 = _template("
") export function render(_ctx) { @@ -314,7 +314,7 @@ export function render(_ctx) { `; exports[`compiler v-bind > :value 1`] = ` -"import { setInheritAttrs as _setInheritAttrs, renderEffect as _renderEffect, setValue as _setValue, template as _template } from 'vue/vapor'; +"import { setInheritAttrs as _setInheritAttrs, setValue as _setValue, renderEffect as _renderEffect, template as _template } from 'vue/vapor'; const t0 = _template("") export function render(_ctx) { @@ -327,7 +327,7 @@ export function render(_ctx) { `; exports[`compiler v-bind > :value w/ progress 1`] = ` -"import { setInheritAttrs as _setInheritAttrs, renderEffect as _renderEffect, setDynamicProp as _setDynamicProp, template as _template } from 'vue/vapor'; +"import { setInheritAttrs as _setInheritAttrs, setDynamicProp as _setDynamicProp, renderEffect as _renderEffect, template as _template } from 'vue/vapor'; const t0 = _template("") export function render(_ctx) { @@ -340,66 +340,62 @@ export function render(_ctx) { `; exports[`compiler v-bind > HTML global attributes should set as dom prop 1`] = ` -"import { setInheritAttrs as _setInheritAttrs, renderEffect as _renderEffect, setDOMProp as _setDOMProp, template as _template } from 'vue/vapor'; +"import { setInheritAttrs as _setInheritAttrs, setDOMProp as _setDOMProp, renderEffect as _renderEffect, template as _template } from 'vue/vapor'; const t0 = _template("
") export function render(_ctx) { const n0 = t0() _setInheritAttrs(["id", "title", "lang", "dir", "tabindex"]) - let _id - _renderEffect(() => _id !== _ctx.id && _setDOMProp(n0, "id", (_id = _ctx.id))) - let _title - _renderEffect(() => _title !== _ctx.title && _setDOMProp(n0, "title", (_title = _ctx.title))) - let _lang - _renderEffect(() => _lang !== _ctx.lang && _setDOMProp(n0, "lang", (_lang = _ctx.lang))) - let _dir - _renderEffect(() => _dir !== _ctx.dir && _setDOMProp(n0, "dir", (_dir = _ctx.dir))) - let _tabindex - _renderEffect(() => _tabindex !== _ctx.tabindex && _setDOMProp(n0, "tabindex", (_tabindex = _ctx.tabindex))) + let _id, _title, _lang, _dir, _tabindex + _renderEffect(() => { + _id !== _ctx.id && _setDOMProp(n0, "id", (_id = _ctx.id)) + _title !== _ctx.title && _setDOMProp(n0, "title", (_title = _ctx.title)) + _lang !== _ctx.lang && _setDOMProp(n0, "lang", (_lang = _ctx.lang)) + _dir !== _ctx.dir && _setDOMProp(n0, "dir", (_dir = _ctx.dir)) + _tabindex !== _ctx.tabindex && _setDOMProp(n0, "tabindex", (_tabindex = _ctx.tabindex)) + }) return n0 }" `; exports[`compiler v-bind > MathML global attributes should set as dom prop 1`] = ` -"import { setInheritAttrs as _setInheritAttrs, renderEffect as _renderEffect, setDOMProp as _setDOMProp, template as _template } from 'vue/vapor'; +"import { setInheritAttrs as _setInheritAttrs, setDOMProp as _setDOMProp, renderEffect as _renderEffect, template as _template } from 'vue/vapor'; const t0 = _template("") export function render(_ctx) { const n0 = t0() _setInheritAttrs(["autofucus", "dir", "displaystyle", "mathcolor", "tabindex"]) - let _autofucus - _renderEffect(() => _autofucus !== _ctx.autofucus && _setDOMProp(n0, "autofucus", (_autofucus = _ctx.autofucus))) - let _dir - _renderEffect(() => _dir !== _ctx.dir && _setDOMProp(n0, "dir", (_dir = _ctx.dir))) - let _displaystyle - _renderEffect(() => _displaystyle !== _ctx.displaystyle && _setDOMProp(n0, "displaystyle", (_displaystyle = _ctx.displaystyle))) - let _mathcolor - _renderEffect(() => _mathcolor !== _ctx.mathcolor && _setDOMProp(n0, "mathcolor", (_mathcolor = _ctx.mathcolor))) - let _tabindex - _renderEffect(() => _tabindex !== _ctx.tabindex && _setDOMProp(n0, "tabindex", (_tabindex = _ctx.tabindex))) + let _autofucus, _dir, _displaystyle, _mathcolor, _tabindex + _renderEffect(() => { + _autofucus !== _ctx.autofucus && _setDOMProp(n0, "autofucus", (_autofucus = _ctx.autofucus)) + _dir !== _ctx.dir && _setDOMProp(n0, "dir", (_dir = _ctx.dir)) + _displaystyle !== _ctx.displaystyle && _setDOMProp(n0, "displaystyle", (_displaystyle = _ctx.displaystyle)) + _mathcolor !== _ctx.mathcolor && _setDOMProp(n0, "mathcolor", (_mathcolor = _ctx.mathcolor)) + _tabindex !== _ctx.tabindex && _setDOMProp(n0, "tabindex", (_tabindex = _ctx.tabindex)) + }) return n0 }" `; exports[`compiler v-bind > SVG global attributes should set as dom prop 1`] = ` -"import { setInheritAttrs as _setInheritAttrs, renderEffect as _renderEffect, setDOMProp as _setDOMProp, template as _template } from 'vue/vapor'; +"import { setInheritAttrs as _setInheritAttrs, setDOMProp as _setDOMProp, renderEffect as _renderEffect, template as _template } from 'vue/vapor'; const t0 = _template("") export function render(_ctx) { const n0 = t0() _setInheritAttrs(["id", "lang", "tabindex"]) - let _id - _renderEffect(() => _id !== _ctx.id && _setDOMProp(n0, "id", (_id = _ctx.id))) - let _lang - _renderEffect(() => _lang !== _ctx.lang && _setDOMProp(n0, "lang", (_lang = _ctx.lang))) - let _tabindex - _renderEffect(() => _tabindex !== _ctx.tabindex && _setDOMProp(n0, "tabindex", (_tabindex = _ctx.tabindex))) + let _id, _lang, _tabindex + _renderEffect(() => { + _id !== _ctx.id && _setDOMProp(n0, "id", (_id = _ctx.id)) + _lang !== _ctx.lang && _setDOMProp(n0, "lang", (_lang = _ctx.lang)) + _tabindex !== _ctx.tabindex && _setDOMProp(n0, "tabindex", (_tabindex = _ctx.tabindex)) + }) return n0 }" `; exports[`compiler v-bind > attributes must be set as attribute 1`] = ` -"import { renderEffect as _renderEffect, setAttr as _setAttr, template as _template } from 'vue/vapor'; +"import { setAttr as _setAttr, renderEffect as _renderEffect, template as _template } from 'vue/vapor'; const t0 = _template("
") const t1 = _template("") const t2 = _template("") @@ -416,42 +412,35 @@ export function render(_ctx) { const n4 = t4() const n5 = t5() const n6 = t6() - let _spellcheck - _renderEffect(() => _spellcheck !== _ctx.spellcheck && _setAttr(n0, "spellcheck", (_spellcheck = _ctx.spellcheck))) - let _draggable - _renderEffect(() => _draggable !== _ctx.draggable && _setAttr(n0, "draggable", (_draggable = _ctx.draggable))) - let _translate - _renderEffect(() => _translate !== _ctx.translate && _setAttr(n0, "translate", (_translate = _ctx.translate))) - let _form - _renderEffect(() => _form !== _ctx.form && _setAttr(n0, "form", (_form = _ctx.form))) - let _list - _renderEffect(() => _list !== _ctx.list && _setAttr(n1, "list", (_list = _ctx.list))) - let _type - _renderEffect(() => _type !== _ctx.type && _setAttr(n2, "type", (_type = _ctx.type))) - let _width - _renderEffect(() => { - if(_width === _ctx.width) return - _setAttr(n3, "width", _ctx.width) - _setAttr(n4, "width", _ctx.width) - _setAttr(n5, "width", _ctx.width) - _setAttr(n6, "width", _ctx.width) - _width = _ctx.width - }) - let _height + let _spellcheck, _draggable, _translate, _form, _list, _type, _width, _height _renderEffect(() => { - if(_height === _ctx.height) return - _setAttr(n3, "height", _ctx.height) - _setAttr(n4, "height", _ctx.height) - _setAttr(n5, "height", _ctx.height) - _setAttr(n6, "height", _ctx.height) - _height = _ctx.height + _spellcheck !== _ctx.spellcheck && _setAttr(n0, "spellcheck", (_spellcheck = _ctx.spellcheck)) + _draggable !== _ctx.draggable && _setAttr(n0, "draggable", (_draggable = _ctx.draggable)) + _translate !== _ctx.translate && _setAttr(n0, "translate", (_translate = _ctx.translate)) + _form !== _ctx.form && _setAttr(n0, "form", (_form = _ctx.form)) + _list !== _ctx.list && _setAttr(n1, "list", (_list = _ctx.list)) + _type !== _ctx.type && _setAttr(n2, "type", (_type = _ctx.type)) + if(_width !== _ctx.width) { + _setAttr(n3, "width", _ctx.width) + _setAttr(n4, "width", _ctx.width) + _setAttr(n5, "width", _ctx.width) + _setAttr(n6, "width", _ctx.width) + _width = _ctx.width + } + if(_height !== _ctx.height) { + _setAttr(n3, "height", _ctx.height) + _setAttr(n4, "height", _ctx.height) + _setAttr(n5, "height", _ctx.height) + _setAttr(n6, "height", _ctx.height) + _height = _ctx.height + } }) return [n0, n1, n2, n3, n4, n5, n6] }" `; exports[`compiler v-bind > basic 1`] = ` -"import { setInheritAttrs as _setInheritAttrs, renderEffect as _renderEffect, setDOMProp as _setDOMProp, template as _template } from 'vue/vapor'; +"import { setInheritAttrs as _setInheritAttrs, setDOMProp as _setDOMProp, renderEffect as _renderEffect, template as _template } from 'vue/vapor'; const t0 = _template("
") export function render(_ctx) { @@ -464,7 +453,7 @@ export function render(_ctx) { `; exports[`compiler v-bind > dynamic arg 1`] = ` -"import { setInheritAttrs as _setInheritAttrs, renderEffect as _renderEffect, setDynamicProps as _setDynamicProps, template as _template } from 'vue/vapor'; +"import { setInheritAttrs as _setInheritAttrs, setDynamicProps as _setDynamicProps, renderEffect as _renderEffect, template as _template } from 'vue/vapor'; const t0 = _template("
") export function render(_ctx) { @@ -477,7 +466,7 @@ export function render(_ctx) { `; exports[`compiler v-bind > dynamic arg w/ static attribute 1`] = ` -"import { setInheritAttrs as _setInheritAttrs, renderEffect as _renderEffect, setDynamicProps as _setDynamicProps, template as _template } from 'vue/vapor'; +"import { setInheritAttrs as _setInheritAttrs, setDynamicProps as _setDynamicProps, renderEffect as _renderEffect, template as _template } from 'vue/vapor'; const t0 = _template("
") export function render(_ctx) { @@ -490,7 +479,7 @@ export function render(_ctx) { `; exports[`compiler v-bind > no expression (shorthand) 1`] = ` -"import { setInheritAttrs as _setInheritAttrs, renderEffect as _renderEffect, setDynamicProp as _setDynamicProp, template as _template } from 'vue/vapor'; +"import { setInheritAttrs as _setInheritAttrs, setDynamicProp as _setDynamicProp, renderEffect as _renderEffect, template as _template } from 'vue/vapor'; const t0 = _template("
") export function render(_ctx) { @@ -503,7 +492,7 @@ export function render(_ctx) { `; exports[`compiler v-bind > no expression 1`] = ` -"import { setInheritAttrs as _setInheritAttrs, renderEffect as _renderEffect, setDOMProp as _setDOMProp, template as _template } from 'vue/vapor'; +"import { setInheritAttrs as _setInheritAttrs, setDOMProp as _setDOMProp, renderEffect as _renderEffect, template as _template } from 'vue/vapor'; const t0 = _template("
") export function render(_ctx) { 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 a82221728..10283b118 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 > array de-structured value 1`] = ` -"import { renderEffect as _renderEffect, setText as _setText, withDestructure as _withDestructure, createFor as _createFor, template as _template } from 'vue/vapor'; +"import { setText as _setText, renderEffect as _renderEffect, withDestructure as _withDestructure, createFor as _createFor, template as _template } from 'vue/vapor'; const t0 = _template("
") export function render(_ctx) { @@ -15,7 +15,7 @@ export function render(_ctx) { `; exports[`compiler: v-for > basic v-for 1`] = ` -"import { delegate as _delegate, renderEffect as _renderEffect, setText as _setText, createFor as _createFor, delegateEvents as _delegateEvents, template as _template } from 'vue/vapor'; +"import { delegate as _delegate, setText as _setText, renderEffect as _renderEffect, createFor as _createFor, delegateEvents as _delegateEvents, template as _template } from 'vue/vapor'; const t0 = _template("
") _delegateEvents("click") @@ -31,7 +31,7 @@ export function render(_ctx) { `; exports[`compiler: v-for > function params w/ prefixIdentifiers: false 1`] = ` -"import { renderEffect as _renderEffect, setText as _setText, createFor as _createFor, template as _template } from 'vue/vapor'; +"import { setText as _setText, renderEffect as _renderEffect, createFor as _createFor, template as _template } from 'vue/vapor'; const t0 = _template("
") export function render(_ctx) { @@ -45,15 +45,15 @@ export function render(_ctx) { `; exports[`compiler: v-for > multi effect 1`] = ` -"import { setInheritAttrs as _setInheritAttrs, renderEffect as _renderEffect, setDynamicProp as _setDynamicProp, createFor as _createFor, template as _template } from 'vue/vapor'; +"import { setInheritAttrs as _setInheritAttrs, setDynamicProp as _setDynamicProp, renderEffect as _renderEffect, createFor as _createFor, template as _template } from 'vue/vapor'; const t0 = _template("
") export function render(_ctx) { const n0 = _createFor(() => (_ctx.items), (_ctx0) => { const n2 = t0() _setInheritAttrs(["item", "index"]) - _renderEffect(() => _setDynamicProp(n2, "item", _ctx0[0].value)) - _renderEffect(() => _setDynamicProp(n2, "index", _ctx0[1].value)) + _renderEffect(() => _setDynamicProp(n2, "item", _ctx0[0].value) + _setDynamicProp(n2, "index", _ctx0[1].value)) return n2 }) return n0 @@ -61,7 +61,7 @@ export function render(_ctx) { `; exports[`compiler: v-for > nested v-for 1`] = ` -"import { renderEffect as _renderEffect, setText as _setText, createFor as _createFor, insert as _insert, template as _template } from 'vue/vapor'; +"import { setText as _setText, renderEffect as _renderEffect, createFor as _createFor, insert as _insert, template as _template } from 'vue/vapor'; const t0 = _template("") const t1 = _template("
") @@ -81,7 +81,7 @@ export function render(_ctx) { `; exports[`compiler: v-for > object de-structured value 1`] = ` -"import { renderEffect as _renderEffect, setText as _setText, withDestructure as _withDestructure, createFor as _createFor, template as _template } from 'vue/vapor'; +"import { setText as _setText, renderEffect as _renderEffect, withDestructure as _withDestructure, createFor as _createFor, template as _template } from 'vue/vapor'; const t0 = _template("
") export function render(_ctx) { @@ -95,7 +95,7 @@ export function render(_ctx) { `; exports[`compiler: v-for > v-for aliases w/ complex expressions 1`] = ` -"import { renderEffect as _renderEffect, setText as _setText, withDestructure as _withDestructure, createFor as _createFor, template as _template } from 'vue/vapor'; +"import { setText as _setText, renderEffect as _renderEffect, withDestructure as _withDestructure, createFor as _createFor, template as _template } from 'vue/vapor'; const t0 = _template("
") export function render(_ctx) { diff --git a/packages/compiler-vapor/__tests__/transforms/__snapshots__/vHtml.spec.ts.snap b/packages/compiler-vapor/__tests__/transforms/__snapshots__/vHtml.spec.ts.snap index 0deb4bf33..34b621bc6 100644 --- a/packages/compiler-vapor/__tests__/transforms/__snapshots__/vHtml.spec.ts.snap +++ b/packages/compiler-vapor/__tests__/transforms/__snapshots__/vHtml.spec.ts.snap @@ -1,7 +1,7 @@ // Vitest Snapshot v1, https://vitest.dev/guide/snapshot.html exports[`v-html > should convert v-html to innerHTML 1`] = ` -"import { renderEffect as _renderEffect, setHtml as _setHtml, template as _template } from 'vue/vapor'; +"import { setHtml as _setHtml, renderEffect as _renderEffect, template as _template } from 'vue/vapor'; const t0 = _template("
") export function render(_ctx, $props, $emit, $attrs, $slots) { @@ -13,7 +13,7 @@ export function render(_ctx, $props, $emit, $attrs, $slots) { `; exports[`v-html > should raise error and ignore children when v-html is present 1`] = ` -"import { renderEffect as _renderEffect, setHtml as _setHtml, template as _template } from 'vue/vapor'; +"import { setHtml as _setHtml, renderEffect as _renderEffect, template as _template } from 'vue/vapor'; const t0 = _template("
") export function render(_ctx) { diff --git a/packages/compiler-vapor/__tests__/transforms/__snapshots__/vIf.spec.ts.snap b/packages/compiler-vapor/__tests__/transforms/__snapshots__/vIf.spec.ts.snap index e40c0bdbc..42cb0a4d2 100644 --- a/packages/compiler-vapor/__tests__/transforms/__snapshots__/vIf.spec.ts.snap +++ b/packages/compiler-vapor/__tests__/transforms/__snapshots__/vIf.spec.ts.snap @@ -1,7 +1,7 @@ // Vitest Snapshot v1, https://vitest.dev/guide/snapshot.html exports[`compiler: v-if > basic v-if 1`] = ` -"import { renderEffect as _renderEffect, setText as _setText, createIf as _createIf, template as _template } from 'vue/vapor'; +"import { setText as _setText, renderEffect as _renderEffect, createIf as _createIf, template as _template } from 'vue/vapor'; const t0 = _template("
") export function render(_ctx) { @@ -16,7 +16,7 @@ export function render(_ctx) { `; exports[`compiler: v-if > comment between branches 1`] = ` -"import { createIf as _createIf, renderEffect as _renderEffect, setText as _setText, template as _template } from 'vue/vapor'; +"import { createIf as _createIf, setText as _setText, renderEffect as _renderEffect, template as _template } from 'vue/vapor'; const t0 = _template("
") const t1 = _template("") const t2 = _template("

") @@ -62,7 +62,7 @@ export function render(_ctx) { `; exports[`compiler: v-if > template v-if 1`] = ` -"import { renderEffect as _renderEffect, setText as _setText, createIf as _createIf, template as _template } from 'vue/vapor'; +"import { setText as _setText, renderEffect as _renderEffect, createIf as _createIf, template as _template } from 'vue/vapor'; const t0 = _template("
") const t1 = _template("hello") const t2 = _template("

") diff --git a/packages/compiler-vapor/__tests__/transforms/__snapshots__/vModel.spec.ts.snap b/packages/compiler-vapor/__tests__/transforms/__snapshots__/vModel.spec.ts.snap index 0ed562a25..6b5535e21 100644 --- a/packages/compiler-vapor/__tests__/transforms/__snapshots__/vModel.spec.ts.snap +++ b/packages/compiler-vapor/__tests__/transforms/__snapshots__/vModel.spec.ts.snap @@ -246,7 +246,7 @@ export function render(_ctx) { `; exports[`compiler: vModel transform > should support w/ dynamic v-bind 1`] = ` -"import { vModelDynamic as _vModelDynamic, withDirectives as _withDirectives, delegate as _delegate, setInheritAttrs as _setInheritAttrs, renderEffect as _renderEffect, setDynamicProps as _setDynamicProps, template as _template } from 'vue/vapor'; +"import { vModelDynamic as _vModelDynamic, withDirectives as _withDirectives, delegate as _delegate, setInheritAttrs as _setInheritAttrs, setDynamicProps as _setDynamicProps, renderEffect as _renderEffect, template as _template } from 'vue/vapor'; const t0 = _template("") export function render(_ctx) { diff --git a/packages/compiler-vapor/__tests__/transforms/__snapshots__/vOn.spec.ts.snap b/packages/compiler-vapor/__tests__/transforms/__snapshots__/vOn.spec.ts.snap index cbd195b83..8657e0611 100644 --- a/packages/compiler-vapor/__tests__/transforms/__snapshots__/vOn.spec.ts.snap +++ b/packages/compiler-vapor/__tests__/transforms/__snapshots__/vOn.spec.ts.snap @@ -13,12 +13,13 @@ export function render(_ctx) { `; exports[`v-on > dynamic arg 1`] = ` -"import { renderEffect as _renderEffect, on as _on, template as _template } from 'vue/vapor'; +"import { on as _on, renderEffect as _renderEffect, template as _template } from 'vue/vapor'; const t0 = _template("
") export function render(_ctx) { const n0 = t0() _renderEffect(() => { + _on(n0, _ctx.event, () => _ctx.handler, { effect: true }) @@ -28,12 +29,13 @@ export function render(_ctx) { `; exports[`v-on > dynamic arg with complex exp prefixing 1`] = ` -"import { renderEffect as _renderEffect, on as _on, template as _template } from 'vue/vapor'; +"import { on as _on, renderEffect as _renderEffect, template as _template } from 'vue/vapor'; const t0 = _template("
") export function render(_ctx) { const n0 = t0() _renderEffect(() => { + _on(n0, _ctx.event(_ctx.foo), () => _ctx.handler, { effect: true }) @@ -43,12 +45,13 @@ export function render(_ctx) { `; exports[`v-on > dynamic arg with prefixing 1`] = ` -"import { renderEffect as _renderEffect, on as _on, template as _template } from 'vue/vapor'; +"import { on as _on, renderEffect as _renderEffect, template as _template } from 'vue/vapor'; const t0 = _template("
") export function render(_ctx) { const n0 = t0() _renderEffect(() => { + _on(n0, _ctx.event, () => _ctx.handler, { effect: true }) @@ -372,12 +375,13 @@ export function render(_ctx) { `; exports[`v-on > should transform click.middle 2`] = ` -"import { renderEffect as _renderEffect, on as _on, template as _template } from 'vue/vapor'; +"import { on as _on, renderEffect as _renderEffect, template as _template } from 'vue/vapor'; const t0 = _template("
") export function render(_ctx) { const n0 = t0() _renderEffect(() => { + _on(n0, (_ctx.event) === "click" ? "mouseup" : (_ctx.event), () => _ctx.test, { modifiers: ["middle"], effect: true @@ -402,12 +406,13 @@ export function render(_ctx) { `; exports[`v-on > should transform click.right 2`] = ` -"import { renderEffect as _renderEffect, on as _on, template as _template } from 'vue/vapor'; +"import { on as _on, renderEffect as _renderEffect, template as _template } from 'vue/vapor'; const t0 = _template("
") export function render(_ctx) { const n0 = t0() _renderEffect(() => { + _on(n0, (_ctx.event) === "click" ? "contextmenu" : (_ctx.event), () => _ctx.test, { modifiers: ["right"], keys: ["right"], @@ -431,12 +436,13 @@ export function render(_ctx) { `; exports[`v-on > should wrap both for dynamic key event w/ left/right modifiers 1`] = ` -"import { renderEffect as _renderEffect, on as _on, template as _template } from 'vue/vapor'; +"import { on as _on, renderEffect as _renderEffect, template as _template } from 'vue/vapor'; const t0 = _template("
") export function render(_ctx) { const n0 = t0() _renderEffect(() => { + _on(n0, _ctx.e, () => _ctx.test, { modifiers: ["left"], keys: ["left"], diff --git a/packages/compiler-vapor/__tests__/transforms/__snapshots__/vText.spec.ts.snap b/packages/compiler-vapor/__tests__/transforms/__snapshots__/vText.spec.ts.snap index e966c3b84..1b98a024c 100644 --- a/packages/compiler-vapor/__tests__/transforms/__snapshots__/vText.spec.ts.snap +++ b/packages/compiler-vapor/__tests__/transforms/__snapshots__/vText.spec.ts.snap @@ -1,7 +1,7 @@ // Vitest Snapshot v1, https://vitest.dev/guide/snapshot.html exports[`v-text > should convert v-text to textContent 1`] = ` -"import { renderEffect as _renderEffect, setText as _setText, template as _template } from 'vue/vapor'; +"import { setText as _setText, renderEffect as _renderEffect, template as _template } from 'vue/vapor'; const t0 = _template("
") export function render(_ctx, $props, $emit, $attrs, $slots) { @@ -13,7 +13,7 @@ export function render(_ctx, $props, $emit, $attrs, $slots) { `; exports[`v-text > should raise error and ignore children when v-text is present 1`] = ` -"import { renderEffect as _renderEffect, setText as _setText, template as _template } from 'vue/vapor'; +"import { setText as _setText, renderEffect as _renderEffect, template as _template } from 'vue/vapor'; const t0 = _template("
") export function render(_ctx) { diff --git a/packages/compiler-vapor/__tests__/transforms/vBind.spec.ts b/packages/compiler-vapor/__tests__/transforms/vBind.spec.ts index 469ce8c64..2fefa6d38 100644 --- a/packages/compiler-vapor/__tests__/transforms/vBind.spec.ts +++ b/packages/compiler-vapor/__tests__/transforms/vBind.spec.ts @@ -673,8 +673,8 @@ describe('compiler v-bind', () => { expect(code).contains( '_type !== _ctx.type && _setAttr(n2, "type", (_type = _ctx.type))', ) - expect(code).contains('if(_width === _ctx.width) return') - expect(code).contains('if(_height === _ctx.height) return') + expect(code).contains('if(_width !== _ctx.width) {') + expect(code).contains('if(_height !== _ctx.height) {') expect(code).contains('_height = _ctx.height') expect(code).contains('_height = _ctx.height') expect(code).contains('_setAttr(n3, "width", _ctx.width)') @@ -715,15 +715,12 @@ describe('compiler v-bind', () => { `) expect(code).matchSnapshot() - expect(code).contains('let _id') expect(code).contains( '_id !== _ctx.id && _setDOMProp(n0, "id", (_id = _ctx.id))', ) - expect(code).contains('let _lang') expect(code).contains( '_lang !== _ctx.lang && _setDOMProp(n0, "lang", (_lang = _ctx.lang))', ) - expect(code).contains('let _tabindex') expect(code).contains( '_tabindex !== _ctx.tabindex && _setDOMProp(n0, "tabindex", (_tabindex = _ctx.tabindex))', ) @@ -735,23 +732,18 @@ describe('compiler v-bind', () => { `) expect(code).matchSnapshot() - expect(code).contains('let _autofucus') expect(code).contains( '_autofucus !== _ctx.autofucus && _setDOMProp(n0, "autofucus", (_autofucus = _ctx.autofucus))', ) - expect(code).contains('let _dir') expect(code).contains( '_dir !== _ctx.dir && _setDOMProp(n0, "dir", (_dir = _ctx.dir))', ) - expect(code).contains('let _displaystyle') expect(code).contains( '_displaystyle !== _ctx.displaystyle && _setDOMProp(n0, "displaystyle", (_displaystyle = _ctx.displaystyle))', ) - expect(code).contains('let _mathcolor') expect(code).contains( '_mathcolor !== _ctx.mathcolor && _setDOMProp(n0, "mathcolor", (_mathcolor = _ctx.mathcolor))', ) - expect(code).contains('let _tabindex') expect(code).contains( '_tabindex !== _ctx.tabindex && _setDOMProp(n0, "tabindex", (_tabindex = _ctx.tabindex))', ) diff --git a/packages/compiler-vapor/src/generators/operation.ts b/packages/compiler-vapor/src/generators/operation.ts index 864a32e04..3be0db881 100644 --- a/packages/compiler-vapor/src/generators/operation.ts +++ b/packages/compiler-vapor/src/generators/operation.ts @@ -79,28 +79,44 @@ export function genEffects( context: CodegenContext, ): CodeFragment[] { const { vaporHelper } = context - const [frag, push] = buildCodeFragment() - push(NEWLINE, `${vaporHelper('renderEffect')}(() => {`, INDENT_START) + const [frag, push, unshift] = buildCodeFragment() + const declareNames = new Set() for (let i = 0; i < effects.length; i++) { const effect = (context.processingRenderEffect = effects[i]) - push(...genEffect(effect, context)) + i > 0 && push(NEWLINE) + push(...genEffect(effect, context, declareNames)) + } + + const newLineCount = frag.filter(frag => frag === NEWLINE).length + if (newLineCount > 1) { + unshift(`{`, INDENT_START, NEWLINE) + push(INDENT_END, NEWLINE, '}') + } + + if (effects.length) { + unshift(NEWLINE, `${vaporHelper('renderEffect')}(() => `) + push(`)`) + } + + // declare variables: let _foo, _bar + if (declareNames.size) { + frag.splice(1, 0, `let ${[...declareNames].join(', ')}`, NEWLINE) } - push(INDENT_END, NEWLINE, '})') return frag } export function genEffect( { operations }: IREffect, context: CodegenContext, + allDeclareNames: Set, ): CodeFragment[] { const { processingRenderEffect } = context - const [frag, push] = buildCodeFragment(NEWLINE) + const [frag, push] = buildCodeFragment() const { declareNames, earlyCheckExps } = processingRenderEffect! const operationsExps = genOperations(operations, context) - // declare variables: let _foo, _bar if (declareNames.size) { - frag.splice(1, 0, `let ${[...declareNames].join(', ')}`, NEWLINE) + allDeclareNames.add([...declareNames].join(', ')) } const newlineCount = operationsExps.filter(frag => frag === NEWLINE).length diff --git a/packages/compiler-vapor/src/generators/utils.ts b/packages/compiler-vapor/src/generators/utils.ts index f001d8e92..904b3dc87 100644 --- a/packages/compiler-vapor/src/generators/utils.ts +++ b/packages/compiler-vapor/src/generators/utils.ts @@ -29,9 +29,14 @@ export type CodeFragments = Exclude | CodeFragment[] export function buildCodeFragment( ...frag: CodeFragment[] -): [CodeFragment[], (...items: CodeFragment[]) => number] { +): [ + CodeFragment[], + (...items: CodeFragment[]) => number, + (...items: CodeFragment[]) => number, +] { const push = frag.push.bind(frag) - return [frag, push] + const unshift = frag.unshift.bind(frag) + return [frag, push, unshift] } export type CodeFragmentDelimiters = [ From f1baf942c65305b20ba282af6a74c9392aa792dc Mon Sep 17 00:00:00 2001 From: daiwei Date: Thu, 5 Dec 2024 14:03:01 +0800 Subject: [PATCH 35/47] wip: save --- .../__tests__/__snapshots__/compile.spec.ts.snap | 6 ++++-- .../transforms/__snapshots__/transformChildren.spec.ts.snap | 6 ++++-- .../__tests__/transforms/__snapshots__/vFor.spec.ts.snap | 6 ++++-- packages/compiler-vapor/src/generators/operation.ts | 4 +++- 4 files changed, 15 insertions(+), 7 deletions(-) diff --git a/packages/compiler-vapor/__tests__/__snapshots__/compile.spec.ts.snap b/packages/compiler-vapor/__tests__/__snapshots__/compile.spec.ts.snap index 651e79472..9e911d04f 100644 --- a/packages/compiler-vapor/__tests__/__snapshots__/compile.spec.ts.snap +++ b/packages/compiler-vapor/__tests__/__snapshots__/compile.spec.ts.snap @@ -188,8 +188,10 @@ export function render(_ctx) { _delegate(n0, "click", () => _ctx.handleClick) _setInheritAttrs(["id"]) let _count, _count1 - _renderEffect(() => _count !== _ctx.count && _setText(n0, (_count = _ctx.count), "foo", _ctx.count, "foo", _ctx.count) - _count1 !== _ctx.count && _setDOMProp(n0, "id", (_count1 = _ctx.count))) + _renderEffect(() => { + _count !== _ctx.count && _setText(n0, (_count = _ctx.count), "foo", _ctx.count, "foo", _ctx.count) + _count1 !== _ctx.count && _setDOMProp(n0, "id", (_count1 = _ctx.count)) + }) return n0 }" `; diff --git a/packages/compiler-vapor/__tests__/transforms/__snapshots__/transformChildren.spec.ts.snap b/packages/compiler-vapor/__tests__/transforms/__snapshots__/transformChildren.spec.ts.snap index 4d9b23978..db2dbaa57 100644 --- a/packages/compiler-vapor/__tests__/transforms/__snapshots__/transformChildren.spec.ts.snap +++ b/packages/compiler-vapor/__tests__/transforms/__snapshots__/transformChildren.spec.ts.snap @@ -12,8 +12,10 @@ export function render(_ctx) { const n1 = _createTextNode(() => [_ctx.second, " ", _ctx.third, " "]) _insert(n1, n4, n3) let _first, _forth - _renderEffect(() => _first !== _ctx.first && _setText(n0, (_first = _ctx.first)) - _forth !== _ctx.forth && _setText(n2, (_forth = _ctx.forth))) + _renderEffect(() => { + _first !== _ctx.first && _setText(n0, (_first = _ctx.first)) + _forth !== _ctx.forth && _setText(n2, (_forth = _ctx.forth)) + }) return n4 }" `; 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 10283b118..580b41046 100644 --- a/packages/compiler-vapor/__tests__/transforms/__snapshots__/vFor.spec.ts.snap +++ b/packages/compiler-vapor/__tests__/transforms/__snapshots__/vFor.spec.ts.snap @@ -52,8 +52,10 @@ export function render(_ctx) { const n0 = _createFor(() => (_ctx.items), (_ctx0) => { const n2 = t0() _setInheritAttrs(["item", "index"]) - _renderEffect(() => _setDynamicProp(n2, "item", _ctx0[0].value) - _setDynamicProp(n2, "index", _ctx0[1].value)) + _renderEffect(() => { + _setDynamicProp(n2, "item", _ctx0[0].value) + _setDynamicProp(n2, "index", _ctx0[1].value) + }) return n2 }) return n0 diff --git a/packages/compiler-vapor/src/generators/operation.ts b/packages/compiler-vapor/src/generators/operation.ts index 3be0db881..f03005039 100644 --- a/packages/compiler-vapor/src/generators/operation.ts +++ b/packages/compiler-vapor/src/generators/operation.ts @@ -81,14 +81,16 @@ export function genEffects( const { vaporHelper } = context const [frag, push, unshift] = buildCodeFragment() const declareNames = new Set() + let operationsCount = 0 for (let i = 0; i < effects.length; i++) { const effect = (context.processingRenderEffect = effects[i]) + operationsCount += effect.operations.length i > 0 && push(NEWLINE) push(...genEffect(effect, context, declareNames)) } const newLineCount = frag.filter(frag => frag === NEWLINE).length - if (newLineCount > 1) { + if (newLineCount > 1 || operationsCount > 1) { unshift(`{`, INDENT_START, NEWLINE) push(INDENT_END, NEWLINE, '}') } From e9793089f387bef0c78e0da57a378734617f153f Mon Sep 17 00:00:00 2001 From: daiwei Date: Thu, 5 Dec 2024 14:39:45 +0800 Subject: [PATCH 36/47] refactor: merge effect by identifiers in expressions --- .../__snapshots__/compile.spec.ts.snap | 9 ++++-- packages/compiler-vapor/src/ir/index.ts | 1 + packages/compiler-vapor/src/transform.ts | 32 +++++++++++++------ 3 files changed, 29 insertions(+), 13 deletions(-) diff --git a/packages/compiler-vapor/__tests__/__snapshots__/compile.spec.ts.snap b/packages/compiler-vapor/__tests__/__snapshots__/compile.spec.ts.snap index 9e911d04f..816a8e2ff 100644 --- a/packages/compiler-vapor/__tests__/__snapshots__/compile.spec.ts.snap +++ b/packages/compiler-vapor/__tests__/__snapshots__/compile.spec.ts.snap @@ -187,10 +187,13 @@ export function render(_ctx) { const n0 = t0() _delegate(n0, "click", () => _ctx.handleClick) _setInheritAttrs(["id"]) - let _count, _count1 + let _count _renderEffect(() => { - _count !== _ctx.count && _setText(n0, (_count = _ctx.count), "foo", _ctx.count, "foo", _ctx.count) - _count1 !== _ctx.count && _setDOMProp(n0, "id", (_count1 = _ctx.count)) + if(_count !== _ctx.count) { + _setText(n0, _ctx.count, "foo", _ctx.count, "foo", _ctx.count) + _setDOMProp(n0, "id", _ctx.count) + _count = _ctx.count + } }) return n0 }" diff --git a/packages/compiler-vapor/src/ir/index.ts b/packages/compiler-vapor/src/ir/index.ts index 9c735c487..d71d5b556 100644 --- a/packages/compiler-vapor/src/ir/index.ts +++ b/packages/compiler-vapor/src/ir/index.ts @@ -266,6 +266,7 @@ export interface IRDynamicInfo { export interface IREffect { expressions: SimpleExpressionNode[] + identifiers: string[] operations: OperationNode[] declareNames: Set rewrittenNames: Set diff --git a/packages/compiler-vapor/src/transform.ts b/packages/compiler-vapor/src/transform.ts index 619ec7232..23c97266f 100644 --- a/packages/compiler-vapor/src/transform.ts +++ b/packages/compiler-vapor/src/transform.ts @@ -5,6 +5,7 @@ import { type CompilerCompatOptions, type ElementNode, ElementTypes, + type ExpressionNode, NodeTypes, type RootNode, type SimpleExpressionNode, @@ -12,8 +13,16 @@ import { defaultOnError, defaultOnWarn, isVSlot, + walkIdentifiers, } from '@vue/compiler-dom' -import { EMPTY_OBJ, NOOP, extend, isArray, isString } from '@vue/shared' +import { + EMPTY_OBJ, + NOOP, + extend, + isArray, + isString, + looseEqual, +} from '@vue/shared' import { type BlockIRNode, DynamicFlag, @@ -142,8 +151,10 @@ export class TransformContext { if (this.inVOnce || expressions.length === 0) { return this.registerOperation(...operations) } + const ids = new Set() + expressions.forEach(exp => extractIdentifiers(ids, exp)) const existing = this.block.effect.find(e => - isSameExpression(e.expressions, expressions), + looseEqual(e.identifiers, Array.from(ids)), ) if (existing) { existing.operations.push(...operations) @@ -155,16 +166,9 @@ export class TransformContext { declareNames: new Set(), rewrittenNames: new Set(), inVFor: this.inVFor > 0, + identifiers: Array.from(ids), }) } - - function isSameExpression( - a: SimpleExpressionNode[], - b: SimpleExpressionNode[], - ) { - if (a.length !== b.length) return false - return a.every((exp, i) => exp.content === b[i].content) - } } registerOperation(...node: OperationNode[]): void { this.block.operation.push(...node) @@ -300,3 +304,11 @@ export function createStructuralDirectiveTransform( } } } + +function extractIdentifiers(ids: Set, node: ExpressionNode) { + if (node.ast) { + walkIdentifiers(node.ast, n => ids.add(n.name)) + } else if (node.ast === null) { + ids.add((node as SimpleExpressionNode).content) + } +} From 24fa426cc9ea88cd7dcf38dffe5097dbcd4d7bad Mon Sep 17 00:00:00 2001 From: daiwei Date: Fri, 6 Dec 2024 21:31:45 +0800 Subject: [PATCH 37/47] refactor: setDynamicProp(s) need return prev value --- .../__snapshots__/compile.spec.ts.snap | 4 +- .../compiler-vapor/__tests__/compile.spec.ts | 2 +- .../transformElement.spec.ts.snap | 8 ++-- .../__snapshots__/vBind.spec.ts.snap | 22 ++++----- .../__snapshots__/vModel.spec.ts.snap | 2 +- .../transforms/transformElement.spec.ts | 8 ++-- .../__tests__/transforms/vBind.spec.ts | 16 +++---- .../compiler-vapor/src/generators/prop.ts | 46 +++++++++++-------- packages/runtime-vapor/src/dom/prop.ts | 28 ++++++----- 9 files changed, 75 insertions(+), 61 deletions(-) diff --git a/packages/compiler-vapor/__tests__/__snapshots__/compile.spec.ts.snap b/packages/compiler-vapor/__tests__/__snapshots__/compile.spec.ts.snap index 816a8e2ff..843b58e00 100644 --- a/packages/compiler-vapor/__tests__/__snapshots__/compile.spec.ts.snap +++ b/packages/compiler-vapor/__tests__/__snapshots__/compile.spec.ts.snap @@ -210,8 +210,8 @@ exports[`compile > expression parsing > v-bind 1`] = ` "((_ctx) => { const n0 = t0() _setInheritAttrs(true) - let _key_value, _foo - _renderEffect(() => (_key_value !== key.value || _foo !== _unref(foo)) && _setDynamicProps(n0, [{ [(_key_value = key.value)+1]: (_foo = _unref(foo))[key.value+1]() }], true)) + let _key_value, _foo, _key_value_foo + _renderEffect(() => (_key_value !== key.value || _foo !== _unref(foo)) && (_key_value_foo = _setDynamicProps(n0, _key_value_foo, [{ [key.value+1]: _unref(foo)[key.value+1]() }], true))) return n0 })()" `; diff --git a/packages/compiler-vapor/__tests__/compile.spec.ts b/packages/compiler-vapor/__tests__/compile.spec.ts index f2abf48f9..9b8770d59 100644 --- a/packages/compiler-vapor/__tests__/compile.spec.ts +++ b/packages/compiler-vapor/__tests__/compile.spec.ts @@ -195,7 +195,7 @@ describe('compile', () => { expect(code).matchSnapshot() expect(code).contains('key.value+1') expect(code).contains( - '(_key_value !== key.value || _foo !== _unref(foo)) && _setDynamicProps(n0, [{ [(_key_value = key.value)+1]: (_foo = _unref(foo))[key.value+1]() }], true)', + '(_key_value !== key.value || _foo !== _unref(foo)) && (_key_value_foo = _setDynamicProps(n0, _key_value_foo, [{ [key.value+1]: _unref(foo)[key.value+1]() }], true))', ) }) diff --git a/packages/compiler-vapor/__tests__/transforms/__snapshots__/transformElement.spec.ts.snap b/packages/compiler-vapor/__tests__/transforms/__snapshots__/transformElement.spec.ts.snap index fac547334..2b5ab3680 100644 --- a/packages/compiler-vapor/__tests__/transforms/__snapshots__/transformElement.spec.ts.snap +++ b/packages/compiler-vapor/__tests__/transforms/__snapshots__/transformElement.spec.ts.snap @@ -357,7 +357,7 @@ export function render(_ctx) { const n0 = t0() _setInheritAttrs(true) let _obj - _renderEffect(() => _obj !== _ctx.obj && _setDynamicProps(n0, [(_obj = _ctx.obj)], true)) + _renderEffect(() => _obj !== _ctx.obj && (_obj = _setDynamicProps(n0, _obj, [_ctx.obj], true))) return n0 }" `; @@ -370,7 +370,7 @@ export function render(_ctx) { const n0 = t0() _setInheritAttrs(true) let _obj - _renderEffect(() => _obj !== _ctx.obj && _setDynamicProps(n0, [{ id: "foo" }, (_obj = _ctx.obj)], true)) + _renderEffect(() => _obj !== _ctx.obj && (_obj = _setDynamicProps(n0, _obj, [{ id: "foo" }, _ctx.obj], true))) return n0 }" `; @@ -383,7 +383,7 @@ export function render(_ctx) { const n0 = t0() _setInheritAttrs(true) let _obj - _renderEffect(() => _obj !== _ctx.obj && _setDynamicProps(n0, [(_obj = _ctx.obj), { id: "foo" }], true)) + _renderEffect(() => _obj !== _ctx.obj && (_obj = _setDynamicProps(n0, _obj, [_ctx.obj, { id: "foo" }], true))) return n0 }" `; @@ -396,7 +396,7 @@ export function render(_ctx) { const n0 = t0() _setInheritAttrs(true) let _obj - _renderEffect(() => _obj !== _ctx.obj && _setDynamicProps(n0, [{ id: "foo" }, (_obj = _ctx.obj), { class: "bar" }], true)) + _renderEffect(() => _obj !== _ctx.obj && (_obj = _setDynamicProps(n0, _obj, [{ id: "foo" }, _ctx.obj, { class: "bar" }], true))) return n0 }" `; 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 ef7717859..9b38fe90a 100644 --- a/packages/compiler-vapor/__tests__/transforms/__snapshots__/vBind.spec.ts.snap +++ b/packages/compiler-vapor/__tests__/transforms/__snapshots__/vBind.spec.ts.snap @@ -86,7 +86,7 @@ export function render(_ctx) { const n0 = t0() _setInheritAttrs(["fooBar"]) let _id - _renderEffect(() => _id !== _ctx.id && _setDynamicProp(n0, "fooBar", _id, (_id = _ctx.id))) + _renderEffect(() => _id !== _ctx.id && (_id = _setDynamicProp(n0, "fooBar", _id, _ctx.id))) return n0 }" `; @@ -99,8 +99,8 @@ const t0 = _template("
") export function render(_ctx) { const n0 = t0() _setInheritAttrs(true) - let _foo, _id - _renderEffect(() => (_foo !== _ctx.foo || _id !== _ctx.id) && _setDynamicProps(n0, [{ [_camelize((_foo = _ctx.foo))]: (_id = _ctx.id) }], true)) + let _foo, _id, _foo_id + _renderEffect(() => (_foo !== _ctx.foo || _id !== _ctx.id) && (_foo_id = _setDynamicProps(n0, _foo_id, [{ [_camelize(_ctx.foo)]: _ctx.id }], true))) return n0 }" `; @@ -113,7 +113,7 @@ export function render(_ctx) { const n0 = t0() _setInheritAttrs(["fooBar"]) let _fooBar - _renderEffect(() => _fooBar !== _ctx.fooBar && _setDynamicProp(n0, "fooBar", _fooBar, (_fooBar = _ctx.fooBar))) + _renderEffect(() => _fooBar !== _ctx.fooBar && (_fooBar = _setDynamicProp(n0, "fooBar", _fooBar, _ctx.fooBar))) return n0 }" `; @@ -216,8 +216,8 @@ const t0 = _template("
") export function render(_ctx) { const n0 = t0() _setInheritAttrs(true) - let _fooBar, _id - _renderEffect(() => (_fooBar !== _ctx.fooBar || _id !== _ctx.id) && _setDynamicProps(n0, [{ ["." + (_fooBar = _ctx.fooBar)]: (_id = _ctx.id) }], true)) + let _fooBar, _id, _fooBar_id + _renderEffect(() => (_fooBar !== _ctx.fooBar || _id !== _ctx.id) && (_fooBar_id = _setDynamicProps(n0, _fooBar_id, [{ ["." + _ctx.fooBar]: _ctx.id }], true))) return n0 }" `; @@ -334,7 +334,7 @@ export function render(_ctx) { const n0 = t0() _setInheritAttrs(["value"]) let _foo - _renderEffect(() => _foo !== _ctx.foo && _setDynamicProp(n0, "value", _foo, (_foo = _ctx.foo))) + _renderEffect(() => _foo !== _ctx.foo && (_foo = _setDynamicProp(n0, "value", _foo, _ctx.foo))) return n0 }" `; @@ -459,8 +459,8 @@ const t0 = _template("
") export function render(_ctx) { const n0 = t0() _setInheritAttrs(true) - let _id, _title - _renderEffect(() => (_id !== _ctx.id || _title !== _ctx.title) && _setDynamicProps(n0, [{ [(_id = _ctx.id)]: _ctx.id, [(_title = _ctx.title)]: _ctx.title }], true)) + let _id, _title, _id_title + _renderEffect(() => (_id !== _ctx.id || _title !== _ctx.title) && (_id_title = _setDynamicProps(n0, _id_title, [{ [_ctx.id]: _ctx.id, [_ctx.title]: _ctx.title }], true))) return n0 }" `; @@ -473,7 +473,7 @@ export function render(_ctx) { const n0 = t0() _setInheritAttrs(true) let _id - _renderEffect(() => _id !== _ctx.id && _setDynamicProps(n0, [{ [(_id = _ctx.id)]: _ctx.id, foo: "bar", checked: "" }], true)) + _renderEffect(() => _id !== _ctx.id && (_id = _setDynamicProps(n0, _id, [{ [_ctx.id]: _ctx.id, foo: "bar", checked: "" }], true))) return n0 }" `; @@ -486,7 +486,7 @@ export function render(_ctx) { const n0 = t0() _setInheritAttrs(["camel-case"]) let _camelCase - _renderEffect(() => _camelCase !== _ctx.camelCase && _setDynamicProp(n0, "camel-case", _camelCase, (_camelCase = _ctx.camelCase))) + _renderEffect(() => _camelCase !== _ctx.camelCase && (_camelCase = _setDynamicProp(n0, "camel-case", _camelCase, _ctx.camelCase))) return n0 }" `; diff --git a/packages/compiler-vapor/__tests__/transforms/__snapshots__/vModel.spec.ts.snap b/packages/compiler-vapor/__tests__/transforms/__snapshots__/vModel.spec.ts.snap index 6b5535e21..0b3851662 100644 --- a/packages/compiler-vapor/__tests__/transforms/__snapshots__/vModel.spec.ts.snap +++ b/packages/compiler-vapor/__tests__/transforms/__snapshots__/vModel.spec.ts.snap @@ -255,7 +255,7 @@ export function render(_ctx) { _delegate(n0, "update:modelValue", () => $event => (_ctx.model = $event)) _setInheritAttrs(true) let _obj - _renderEffect(() => _obj !== _ctx.obj && _setDynamicProps(n0, [(_obj = _ctx.obj)], true)) + _renderEffect(() => _obj !== _ctx.obj && (_obj = _setDynamicProps(n0, _obj, [_ctx.obj], true))) return n0 }" `; diff --git a/packages/compiler-vapor/__tests__/transforms/transformElement.spec.ts b/packages/compiler-vapor/__tests__/transforms/transformElement.spec.ts index 9871f27c3..631beac52 100644 --- a/packages/compiler-vapor/__tests__/transforms/transformElement.spec.ts +++ b/packages/compiler-vapor/__tests__/transforms/transformElement.spec.ts @@ -589,7 +589,7 @@ describe('compiler: element transform', () => { }, ]) expect(code).contains( - '_obj !== _ctx.obj && _setDynamicProps(n0, [(_obj = _ctx.obj)], true)', + '_obj !== _ctx.obj && (_obj = _setDynamicProps(n0, _obj, [_ctx.obj], true))', ) }) @@ -627,7 +627,7 @@ describe('compiler: element transform', () => { }, ]) expect(code).contains( - '_obj !== _ctx.obj && _setDynamicProps(n0, [{ id: "foo" }, (_obj = _ctx.obj)], true)', + '_obj !== _ctx.obj && (_obj = _setDynamicProps(n0, _obj, [{ id: "foo" }, _ctx.obj], true))', ) }) @@ -655,7 +655,7 @@ describe('compiler: element transform', () => { }, ]) expect(code).contains( - '_obj !== _ctx.obj && _setDynamicProps(n0, [(_obj = _ctx.obj), { id: "foo" }], true)', + '_obj !== _ctx.obj && (_obj = _setDynamicProps(n0, _obj, [_ctx.obj, { id: "foo" }], true))', ) }) @@ -684,7 +684,7 @@ describe('compiler: element transform', () => { }, ]) expect(code).contains( - '_obj !== _ctx.obj && _setDynamicProps(n0, [{ id: "foo" }, (_obj = _ctx.obj), { class: "bar" }], true)', + '_obj !== _ctx.obj && (_obj = _setDynamicProps(n0, _obj, [{ id: "foo" }, _ctx.obj, { class: "bar" }], true))', ) }) diff --git a/packages/compiler-vapor/__tests__/transforms/vBind.spec.ts b/packages/compiler-vapor/__tests__/transforms/vBind.spec.ts index 2fefa6d38..0c1e697ce 100644 --- a/packages/compiler-vapor/__tests__/transforms/vBind.spec.ts +++ b/packages/compiler-vapor/__tests__/transforms/vBind.spec.ts @@ -131,7 +131,7 @@ describe('compiler v-bind', () => { }, }) expect(code).contains( - '_camelCase !== _ctx.camelCase && _setDynamicProp(n0, "camel-case", _camelCase, (_camelCase = _ctx.camelCase))', + '_camelCase !== _ctx.camelCase && (_camelCase = _setDynamicProp(n0, "camel-case", _camelCase, _ctx.camelCase))', ) }) @@ -177,7 +177,7 @@ describe('compiler v-bind', () => { ], }) expect(code).contains( - '(_id !== _ctx.id || _title !== _ctx.title) && _setDynamicProps(n0, [{ [(_id = _ctx.id)]: _ctx.id, [(_title = _ctx.title)]: _ctx.title }], true)', + '(_id !== _ctx.id || _title !== _ctx.title) && (_id_title = _setDynamicProps(n0, _id_title, [{ [_ctx.id]: _ctx.id, [_ctx.title]: _ctx.title }], true))', ) }) @@ -230,7 +230,7 @@ describe('compiler v-bind', () => { ], }) expect(code).contains( - '_id !== _ctx.id && _setDynamicProps(n0, [{ [(_id = _ctx.id)]: _ctx.id, foo: "bar", checked: "" }], true)', + '_id !== _ctx.id && (_id = _setDynamicProps(n0, _id, [{ [_ctx.id]: _ctx.id, foo: "bar", checked: "" }], true))', ) }) @@ -293,7 +293,7 @@ describe('compiler v-bind', () => { expect(code).matchSnapshot() expect(code).contains( - '_id !== _ctx.id && _setDynamicProp(n0, "fooBar", _id, (_id = _ctx.id))', + '_id !== _ctx.id && (_id = _setDynamicProp(n0, "fooBar", _id, _ctx.id))', ) }) @@ -319,7 +319,7 @@ describe('compiler v-bind', () => { }) expect(code).contains('renderEffect') expect(code).contains( - '_fooBar !== _ctx.fooBar && _setDynamicProp(n0, "fooBar", _fooBar, (_fooBar = _ctx.fooBar))', + '_fooBar !== _ctx.fooBar && (_fooBar = _setDynamicProp(n0, "fooBar", _fooBar, _ctx.fooBar))', ) }) @@ -351,7 +351,7 @@ describe('compiler v-bind', () => { expect(code).matchSnapshot() expect(code).contains('renderEffect') expect(code).contains( - `(_foo !== _ctx.foo || _id !== _ctx.id) && _setDynamicProps(n0, [{ [_camelize((_foo = _ctx.foo))]: (_id = _ctx.id) }], true)`, + `(_foo !== _ctx.foo || _id !== _ctx.id) && (_foo_id = _setDynamicProps(n0, _foo_id, [{ [_camelize(_ctx.foo)]: _ctx.id }], true))`, ) }) @@ -436,7 +436,7 @@ describe('compiler v-bind', () => { }) expect(code).contains('renderEffect') expect(code).contains( - `(_fooBar !== _ctx.fooBar || _id !== _ctx.id) && _setDynamicProps(n0, [{ ["." + (_fooBar = _ctx.fooBar)]: (_id = _ctx.id) }], true)`, + `(_fooBar !== _ctx.fooBar || _id !== _ctx.id) && (_fooBar_id = _setDynamicProps(n0, _fooBar_id, [{ ["." + _ctx.fooBar]: _ctx.id }], true))`, ) }) @@ -788,7 +788,7 @@ describe('compiler v-bind', () => { `) expect(code).matchSnapshot() expect(code).contains( - '_foo !== _ctx.foo && _setDynamicProp(n0, "value", _foo, (_foo = _ctx.foo))', + '_foo !== _ctx.foo && (_foo = _setDynamicProp(n0, "value", _foo, _ctx.foo))', ) }) diff --git a/packages/compiler-vapor/src/generators/prop.ts b/packages/compiler-vapor/src/generators/prop.ts index 155ba86a0..f7321ad62 100644 --- a/packages/compiler-vapor/src/generators/prop.ts +++ b/packages/compiler-vapor/src/generators/prop.ts @@ -35,7 +35,8 @@ import { toHandlerKey, } from '@vue/shared' -const helperNeedPrevValue = ['setStyle', 'setDynamicProp'] +// those runtime helpers will return the prevValue +const helperNeedPrevValue = ['setStyle', 'setDynamicProp', 'setDynamicProps'] // only the static key prop will reach here export function genSetProp( @@ -51,37 +52,32 @@ export function genSetProp( const { helperName, omitKey } = getRuntimeHelper(tag, key.content, modifier) let propValue = genPropValue(values, context) + let prevValueName if (shouldCacheRenderEffectDeps()) { - processValues(context, [propValue]) - + const needReturnValue = helperNeedPrevValue.includes(helperName) + processValues(context, [propValue], !needReturnValue) const { declareNames } = processingRenderEffect! - // need prevValue parameter - if (declareNames.size > 0 && helperNeedPrevValue.includes(helperName)) { - const prevValueName = [...declareNames].join('') + if (declareNames.size > 0 && needReturnValue) { + prevValueName = [...declareNames].join('') declareNames.add(prevValueName) - const needReCacheValue = declareNames.size > 1 - propValue.unshift( - ...[ - `${prevValueName}, `, // prevValue parameter - needReCacheValue ? `(${prevValueName} = ` : undefined, // cache value to prevValue - ], - ) - needReCacheValue && propValue.push(')') } } return [ NEWLINE, + ...(prevValueName ? [`(`, `${prevValueName} = `] : []), ...genCall( [vaporHelper(helperName), null], `n${oper.element}`, omitKey ? false : genExpression(key, context), + ...(prevValueName ? [`${prevValueName}`] : []), propValue, // only `setClass` and `setStyle` need merge inherit attr oper.root && (helperName === 'setClass' || helperName === 'setStyle') ? 'true' : undefined, ), + ...(prevValueName ? [`)`] : []), ] } @@ -90,7 +86,8 @@ export function genDynamicProps( oper: SetDynamicPropsIRNode, context: CodegenContext, ): CodeFragment[] { - const { vaporHelper, shouldCacheRenderEffectDeps } = context + const { vaporHelper, shouldCacheRenderEffectDeps, processingRenderEffect } = + context const values = oper.props.map(props => Array.isArray(props) ? genLiteralObjectProps(props, context) // static and dynamic arg props @@ -99,18 +96,27 @@ export function genDynamicProps( : genExpression(props.value, context), ) // v-bind="" + let prevValueName if (shouldCacheRenderEffectDeps()) { - processValues(context, values) + processValues(context, values, false) + const { declareNames } = processingRenderEffect! + if (declareNames.size > 0) { + prevValueName = [...declareNames].join('') + declareNames.add(prevValueName) + } } return [ NEWLINE, + ...(prevValueName ? [`(`, `${prevValueName} = `] : []), ...genCall( vaporHelper('setDynamicProps'), `n${oper.element}`, + ...(prevValueName ? [`${prevValueName}`] : []), genMulti(DELIMITERS_ARRAY, ...values), oper.root && 'true', ), + ...(prevValueName ? [`)`] : []), ] } @@ -265,10 +271,11 @@ const getSpecialHelper = ( export function processValues( context: CodegenContext, values: CodeFragment[][], + needRewrite: boolean = true, ): string[] { const allCheckExps: string[] = [] values.forEach(value => { - const checkExps = processValue(context, value) + const checkExps = processValue(context, value, needRewrite) if (checkExps) allCheckExps.push(...checkExps, ' && ') }) @@ -282,12 +289,13 @@ export function processValues( function processValue( context: CodegenContext, values: CodeFragment[], + needRewrite: boolean = true, ): string[] | undefined { const { processingRenderEffect, allRenderEffectSeenNames } = context const { declareNames, rewrittenNames, earlyCheckExps, operations } = processingRenderEffect! - const isMultiLine = operations.length > 1 + const isSingleLine = operations.length === 1 for (const frag of values) { if (!isArray(frag)) continue // [code, newlineIndex, loc, name] -> [(_name = code), newlineIndex, loc, name] @@ -307,7 +315,7 @@ function processValue( declareNames.add(name) earlyCheckExps.push(`${name} !== ${newName}`) - if (!isMultiLine) { + if (needRewrite && isSingleLine) { // replace the original code fragment with the assignment expression frag[0] = `(${name} = ${newName})` } diff --git a/packages/runtime-vapor/src/dom/prop.ts b/packages/runtime-vapor/src/dom/prop.ts index 1529ba78e..4142eb342 100644 --- a/packages/runtime-vapor/src/dom/prop.ts +++ b/packages/runtime-vapor/src/dom/prop.ts @@ -14,7 +14,6 @@ import { } from '@vue/shared' import { warn } from '../warning' import { setStyle } from './style' -import { MetadataKind, getMetadata } from '../componentMetadata' import { on } from './event' import type { Data } from '@vue/runtime-shared' import { currentInstance } from '../component' @@ -134,30 +133,37 @@ export function setDynamicProp( export function setDynamicProps( el: Element, + oldProps: any, args: any[], root?: boolean, ): void { - const oldProps = getMetadata(el)[MetadataKind.prop] + // const oldProps = getMetadata(el)[MetadataKind.prop] if (root) { args.unshift(currentInstance!.attrs) } const props = args.length > 1 ? mergeProps(...args) : args[0] - for (const key in oldProps) { - // TODO should these keys be allowed as dynamic keys? The current logic of the runtime-core will throw an error - if (key === 'textContent' || key === 'innerHTML') { - continue - } + if (oldProps) { + for (const key in oldProps) { + // TODO should these keys be allowed as dynamic keys? The current logic of the runtime-core will throw an error + if (key === 'textContent' || key === 'innerHTML') { + continue + } - const hasNewValue = props[key] || props['.' + key] || props['^' + key] - if (oldProps[key] && !hasNewValue) { - setDynamicProp(el, key, undefined, null) + const oldValue = oldProps[key] + const hasNewValue = props[key] || props['.' + key] || props['^' + key] + if (oldValue && !hasNewValue) { + setDynamicProp(el, key, oldValue, null) + } } } + const prev = Object.create(null) for (const key in props) { - setDynamicProp(el, key, undefined, props[key]) + setDynamicProp(el, key, undefined, (prev[key] = props[key])) } + + return prev } export function mergeProp( From d9bb2fd5429a5afccc94c84d37b90f2a5d4e3ea7 Mon Sep 17 00:00:00 2001 From: daiwei Date: Fri, 6 Dec 2024 21:53:19 +0800 Subject: [PATCH 38/47] test: update tests --- .../__tests__/apiSetupContext.spec.ts | 8 +- .../runtime-vapor/__tests__/dom/prop.spec.ts | 77 +++++++++++-------- packages/runtime-vapor/src/componentAttrs.ts | 3 +- .../runtime-vapor/src/componentFallback.ts | 9 ++- packages/runtime-vapor/src/dom/prop.ts | 4 +- packages/runtime-vapor/src/dom/style.ts | 3 +- 6 files changed, 63 insertions(+), 41 deletions(-) diff --git a/packages/runtime-vapor/__tests__/apiSetupContext.spec.ts b/packages/runtime-vapor/__tests__/apiSetupContext.spec.ts index 3444c3407..e94cd2196 100644 --- a/packages/runtime-vapor/__tests__/apiSetupContext.spec.ts +++ b/packages/runtime-vapor/__tests__/apiSetupContext.spec.ts @@ -78,7 +78,8 @@ describe('api: setup context', () => { inheritAttrs: false, setup(props, { attrs }) { const el = document.createElement('div') - renderEffect(() => setDynamicProps(el, [attrs])) + let prev: any + renderEffect(() => (prev = setDynamicProps(el, prev, [attrs]))) return el }, }) @@ -115,7 +116,10 @@ describe('api: setup context', () => { const n0 = createComponent(Wrapper, null, { default: () => { const n0 = template('
')() as HTMLDivElement - renderEffect(() => setDynamicProps(n0, [attrs], true)) + let prev: any + renderEffect( + () => (prev = setDynamicProps(n0, prev, [attrs], true)), + ) return n0 }, }) diff --git a/packages/runtime-vapor/__tests__/dom/prop.spec.ts b/packages/runtime-vapor/__tests__/dom/prop.spec.ts index 50a39cea9..f75d40b3d 100644 --- a/packages/runtime-vapor/__tests__/dom/prop.spec.ts +++ b/packages/runtime-vapor/__tests__/dom/prop.spec.ts @@ -78,83 +78,87 @@ describe('patchProp', () => { describe('setStyle', () => { test('should set style', () => { const el = document.createElement('div') - setStyle(el, 'color: red') + setStyle(el, '', 'color: red') expect(el.style.cssText).toBe('color: red;') }) test('should work with camelCase', () => { const el = document.createElement('div') - setStyle(el, { fontSize: '12px' }) + setStyle(el, null, { fontSize: '12px' }) expect(el.style.cssText).toBe('font-size: 12px;') }) test('shoud set style with object and array property', () => { const el = document.createElement('div') - setStyle(el, { color: 'red' }) + let prev: any + prev = setStyle(el, prev, { color: 'red' }) expect(el.style.cssText).toBe('color: red;') - setStyle(el, [{ color: 'blue' }, { fontSize: '12px' }]) + setStyle(el, prev, [{ color: 'blue' }, { fontSize: '12px' }]) expect(el.style.cssText).toBe('color: blue; font-size: 12px;') }) test('should remove if falsy value', () => { const el = document.createElement('div') - setStyle(el, { color: undefined, borderRadius: null }) + let prev + prev = setStyle(el, prev, { color: undefined, borderRadius: null }) expect(el.style.cssText).toBe('') - setStyle(el, { color: 'red' }) + prev = setStyle(el, prev, { color: 'red' }) expect(el.style.cssText).toBe('color: red;') - setStyle(el, { color: undefined, borderRadius: null }) + setStyle(el, prev, { color: undefined, borderRadius: null }) expect(el.style.cssText).toBe('') }) test('should work with !important', () => { const el = document.createElement('div') - setStyle(el, { color: 'red !important' }) + setStyle(el, null, { color: 'red !important' }) expect(el.style.cssText).toBe('color: red !important;') }) test('should work with camelCase and !important', () => { const el = document.createElement('div') - setStyle(el, { fontSize: '12px !important' }) + setStyle(el, null, { fontSize: '12px !important' }) expect(el.style.cssText).toBe('font-size: 12px !important;') }) test('should work with multiple entries', () => { const el = document.createElement('div') - setStyle(el, { color: 'red', marginRight: '10px' }) + setStyle(el, null, { color: 'red', marginRight: '10px' }) expect(el.style.getPropertyValue('color')).toBe('red') expect(el.style.getPropertyValue('margin-right')).toBe('10px') }) test('should patch with falsy style value', () => { const el = document.createElement('div') - setStyle(el, { width: '100px' }) + let prev: any + prev = setStyle(el, prev, { width: '100px' }) expect(el.style.cssText).toBe('width: 100px;') - setStyle(el, { width: 0 }) + prev = setStyle(el, prev, { width: 0 }) expect(el.style.cssText).toBe('width: 0px;') }) test('should remove style attribute on falsy value', () => { const el = document.createElement('div') - setStyle(el, { width: '100px' }) + let prev: any + prev = setStyle(el, prev, { width: '100px' }) expect(el.style.cssText).toBe('width: 100px;') - setStyle(el, { width: undefined }) + prev = setStyle(el, prev, { width: undefined }) expect(el.style.cssText).toBe('') - setStyle(el, { width: '100px' }) + prev = setStyle(el, prev, { width: '100px' }) expect(el.style.cssText).toBe('width: 100px;') - setStyle(el, null) + setStyle(el, prev, null) expect(el.hasAttribute('style')).toBe(false) expect(el.style.cssText).toBe('') }) test('should warn for trailing semicolons', () => { const el = document.createElement('div') - setStyle(el, { color: 'red;' }) + setStyle(el, null, { color: 'red;' }) expect( `Unexpected semicolon at the end of 'color' style value: 'red;'`, ).toHaveBeenWarned() - setStyle(el, { '--custom': '100; ' }) + setStyle(el, null, { '--custom': '100; ' }) expect( `Unexpected semicolon at the end of '--custom' style value: '100; '`, ).toHaveBeenWarned() @@ -162,13 +166,16 @@ describe('patchProp', () => { test('should not warn for trailing semicolons', () => { const el = document.createElement('div') - setStyle(el, { '--custom': '100\\;' }) + setStyle(el, null, { '--custom': '100\\;' }) expect(el.style.getPropertyValue('--custom')).toBe('100\\;') }) test('should work with shorthand properties', () => { const el = document.createElement('div') - setStyle(el, { borderBottom: '1px solid red', border: '1px solid green' }) + setStyle(el, null, { + borderBottom: '1px solid red', + border: '1px solid green', + }) expect(el.style.border).toBe('1px solid green') expect(el.style.borderBottom).toBe('1px solid green') }) @@ -193,19 +200,21 @@ describe('patchProp', () => { test('should work with css custom properties', () => { const el = mockElementWithStyle() - setStyle(el as any, { '--theme': 'red' }) + setStyle(el as any, null, { '--theme': 'red' }) expect(el.style.getPropertyValue('--theme')).toBe('red') }) test('should auto vendor prefixing', () => { const el = mockElementWithStyle() - setStyle(el as any, { transition: 'all 1s' }) + setStyle(el as any, null, { transition: 'all 1s' }) expect(el.style.WebkitTransition).toBe('all 1s') }) test('should work with multiple values', () => { const el = mockElementWithStyle() - setStyle(el as any, { display: ['-webkit-box', '-ms-flexbox', 'flex'] }) + setStyle(el as any, null, { + display: ['-webkit-box', '-ms-flexbox', 'flex'], + }) expect(el.style.display).toBe('flex') }) }) @@ -335,12 +344,13 @@ describe('patchProp', () => { describe('setDynamicProp', () => { const element = document.createElement('div') + let prev: any function setDynamicProp( key: string, value: any, el = element.cloneNode(true) as HTMLElement, ) { - _setDynamicProp(el, key, value) + prev = _setDynamicProp(el, key, prev, value) return el } @@ -397,25 +407,25 @@ describe('patchProp', () => { describe('setDynamicProps', () => { test('basic set dynamic props', () => { const el = document.createElement('div') - setDynamicProps(el, [{ foo: 'val' }, { bar: 'val' }]) + setDynamicProps(el, null, [{ foo: 'val' }, { bar: 'val' }]) expect(el.getAttribute('foo')).toBe('val') expect(el.getAttribute('bar')).toBe('val') }) test('should merge props', () => { const el = document.createElement('div') - setDynamicProps(el, [{ foo: 'val' }, { foo: 'newVal' }]) + setDynamicProps(el, null, [{ foo: 'val' }, { foo: 'newVal' }]) expect(el.getAttribute('foo')).toBe('newVal') }) test('should reset old props', () => { const el = document.createElement('div') - - setDynamicProps(el, [{ foo: 'val' }]) + let prev: any + prev = setDynamicProps(el, prev, [{ foo: 'val' }]) expect(el.attributes.length).toBe(1) expect(el.getAttribute('foo')).toBe('val') - setDynamicProps(el, [{ bar: 'val' }]) + prev = setDynamicProps(el, prev, [{ bar: 'val' }]) expect(el.attributes.length).toBe(1) expect(el.getAttribute('bar')).toBe('val') expect(el.getAttribute('foo')).toBeNull() @@ -424,18 +434,19 @@ describe('patchProp', () => { test('should reset old modifier props', () => { const el = document.createElement('div') - setDynamicProps(el, [{ ['.foo']: 'val' }]) + let prev: any + prev = setDynamicProps(el, prev, [{ ['.foo']: 'val' }]) expect((el as any).foo).toBe('val') - setDynamicProps(el, [{ ['.bar']: 'val' }]) + prev = setDynamicProps(el, prev, [{ ['.bar']: 'val' }]) expect((el as any).bar).toBe('val') expect((el as any).foo).toBe('') - setDynamicProps(el, [{ ['^foo']: 'val' }]) + prev = setDynamicProps(el, prev, [{ ['^foo']: 'val' }]) expect(el.attributes.length).toBe(1) expect(el.getAttribute('foo')).toBe('val') - setDynamicProps(el, [{ ['^bar']: 'val' }]) + prev = setDynamicProps(el, prev, [{ ['^bar']: 'val' }]) expect(el.attributes.length).toBe(1) expect(el.getAttribute('bar')).toBe('val') expect(el.getAttribute('foo')).toBeNull() diff --git a/packages/runtime-vapor/src/componentAttrs.ts b/packages/runtime-vapor/src/componentAttrs.ts index 635b45a7a..683597783 100644 --- a/packages/runtime-vapor/src/componentAttrs.ts +++ b/packages/runtime-vapor/src/componentAttrs.ts @@ -119,6 +119,7 @@ export function fallThroughAttrs( } } + let prevAttrs = instance.attrs renderEffect(() => { for (const key in instance.attrs) { if (dynamicAttrs && dynamicAttrs.includes(key)) continue @@ -130,7 +131,7 @@ export function fallThroughAttrs( value = instance.attrs[key] } - setDynamicProp(element, key, value) + setDynamicProp(element, key, prevAttrs[key], value) } }) } diff --git a/packages/runtime-vapor/src/componentFallback.ts b/packages/runtime-vapor/src/componentFallback.ts index adceb5446..ce0e82e5d 100644 --- a/packages/runtime-vapor/src/componentFallback.ts +++ b/packages/runtime-vapor/src/componentFallback.ts @@ -24,6 +24,7 @@ export function fallbackComponent( if (rawProps || Object.keys(instance.attrs).length) { rawProps = [() => instance.attrs, ...normalizeRawProps(rawProps)] + let prevValue: any, prevStyle: any renderEffect(() => { let classes: unknown[] | undefined let styles: unknown[] | undefined @@ -34,12 +35,16 @@ export function fallbackComponent( const value = getter ? valueOrGetter() : valueOrGetter if (key === 'class') (classes ||= []).push(value) else if (key === 'style') (styles ||= []).push(value) - else setDynamicProp(el, key, value) + else { + prevValue = setDynamicProp(el, key, prevValue, value) + } }, ) if (classes) setClass(el, classes) - if (styles) setStyle(el, styles) + if (styles) { + prevStyle = setStyle(el, prevStyle, styles) + } }) } diff --git a/packages/runtime-vapor/src/dom/prop.ts b/packages/runtime-vapor/src/dom/prop.ts index 4142eb342..652a74482 100644 --- a/packages/runtime-vapor/src/dom/prop.ts +++ b/packages/runtime-vapor/src/dom/prop.ts @@ -92,13 +92,13 @@ export function setDynamicProp( key: string, prev: any, value: any, -): void { +): any { // TODO const isSVG = false if (key === 'class') { setClass(el, value) } else if (key === 'style') { - setStyle(el as HTMLElement, prev, value) + return setStyle(el as HTMLElement, prev, value) } else if (isOn(key)) { on(el, key[2].toLowerCase() + key.slice(3), () => value, { effect: true }) } else if ( diff --git a/packages/runtime-vapor/src/dom/style.ts b/packages/runtime-vapor/src/dom/style.ts index fbea1dc50..213dfec4b 100644 --- a/packages/runtime-vapor/src/dom/style.ts +++ b/packages/runtime-vapor/src/dom/style.ts @@ -14,9 +14,10 @@ export function setStyle( prev: any, value: any, root?: boolean, -): void { +): any { value = normalizeStyle(root ? mergeInheritAttr('style', value) : value) patchStyle(el, prev, value) + return value } // TODO copied from packages/runtime-dom/src/modules/style.ts From 29dff1fc95b8d107c3b2b120e9de407c2677c265 Mon Sep 17 00:00:00 2001 From: daiwei Date: Sat, 7 Dec 2024 19:55:34 +0800 Subject: [PATCH 39/47] chore: improve codegen for single line render effect with return value --- packages/compiler-vapor/src/generators/prop.ts | 17 +++++++++++++---- 1 file changed, 13 insertions(+), 4 deletions(-) diff --git a/packages/compiler-vapor/src/generators/prop.ts b/packages/compiler-vapor/src/generators/prop.ts index f7321ad62..1107d4489 100644 --- a/packages/compiler-vapor/src/generators/prop.ts +++ b/packages/compiler-vapor/src/generators/prop.ts @@ -43,8 +43,12 @@ export function genSetProp( oper: SetPropIRNode, context: CodegenContext, ): CodeFragment[] { - const { vaporHelper, shouldCacheRenderEffectDeps, processingRenderEffect } = - context + const { + vaporHelper, + shouldCacheRenderEffectDeps, + processingRenderEffect, + block, + } = context const { prop: { key, values, modifier }, tag, @@ -63,9 +67,14 @@ export function genSetProp( } } + // single-line render effect that needs to return a value, the expression needs to be wrapped + // in parentheses. e.g. _foo === _ctx.foo && (_foo = _setStyle(...)) + const needWrap = block.operation.length === 1 return [ NEWLINE, - ...(prevValueName ? [`(`, `${prevValueName} = `] : []), + ...(prevValueName + ? [needWrap ? `(` : undefined, `${prevValueName} = `] + : []), ...genCall( [vaporHelper(helperName), null], `n${oper.element}`, @@ -77,7 +86,7 @@ export function genSetProp( ? 'true' : undefined, ), - ...(prevValueName ? [`)`] : []), + ...(prevValueName && needWrap ? [`)`] : []), ] } From b2bb28741de170f9820bde078d11f80123c7b1f7 Mon Sep 17 00:00:00 2001 From: daiwei Date: Sat, 7 Dec 2024 20:29:55 +0800 Subject: [PATCH 40/47] wip: save --- .../compiler-vapor/src/generators/prop.ts | 94 ++++++++++--------- 1 file changed, 52 insertions(+), 42 deletions(-) diff --git a/packages/compiler-vapor/src/generators/prop.ts b/packages/compiler-vapor/src/generators/prop.ts index 1107d4489..3a0964dd1 100644 --- a/packages/compiler-vapor/src/generators/prop.ts +++ b/packages/compiler-vapor/src/generators/prop.ts @@ -35,45 +35,27 @@ import { toHandlerKey, } from '@vue/shared' -// those runtime helpers will return the prevValue -const helperNeedPrevValue = ['setStyle', 'setDynamicProp', 'setDynamicProps'] - // only the static key prop will reach here export function genSetProp( oper: SetPropIRNode, context: CodegenContext, ): CodeFragment[] { - const { - vaporHelper, - shouldCacheRenderEffectDeps, - processingRenderEffect, - block, - } = context + const { vaporHelper } = context const { prop: { key, values, modifier }, tag, } = oper const { helperName, omitKey } = getRuntimeHelper(tag, key.content, modifier) - let propValue = genPropValue(values, context) - - let prevValueName - if (shouldCacheRenderEffectDeps()) { - const needReturnValue = helperNeedPrevValue.includes(helperName) - processValues(context, [propValue], !needReturnValue) - const { declareNames } = processingRenderEffect! - if (declareNames.size > 0 && needReturnValue) { - prevValueName = [...declareNames].join('') - declareNames.add(prevValueName) - } - } - - // single-line render effect that needs to return a value, the expression needs to be wrapped - // in parentheses. e.g. _foo === _ctx.foo && (_foo = _setStyle(...)) - const needWrap = block.operation.length === 1 + const propValue = genPropValue(values, context) + const { prevValueName, shouldWrapInParentheses } = processPropValues( + context, + helperName, + [propValue], + ) return [ NEWLINE, ...(prevValueName - ? [needWrap ? `(` : undefined, `${prevValueName} = `] + ? [shouldWrapInParentheses ? `(` : undefined, `${prevValueName} = `] : []), ...genCall( [vaporHelper(helperName), null], @@ -86,7 +68,7 @@ export function genSetProp( ? 'true' : undefined, ), - ...(prevValueName && needWrap ? [`)`] : []), + ...(prevValueName && shouldWrapInParentheses ? [`)`] : []), ] } @@ -95,8 +77,7 @@ export function genDynamicProps( oper: SetDynamicPropsIRNode, context: CodegenContext, ): CodeFragment[] { - const { vaporHelper, shouldCacheRenderEffectDeps, processingRenderEffect } = - context + const { vaporHelper } = context const values = oper.props.map(props => Array.isArray(props) ? genLiteralObjectProps(props, context) // static and dynamic arg props @@ -104,20 +85,16 @@ export function genDynamicProps( ? genLiteralObjectProps([props], context) // dynamic arg props : genExpression(props.value, context), ) // v-bind="" - - let prevValueName - if (shouldCacheRenderEffectDeps()) { - processValues(context, values, false) - const { declareNames } = processingRenderEffect! - if (declareNames.size > 0) { - prevValueName = [...declareNames].join('') - declareNames.add(prevValueName) - } - } - + const { prevValueName, shouldWrapInParentheses } = processPropValues( + context, + 'setDynamicProps', + values, + ) return [ NEWLINE, - ...(prevValueName ? [`(`, `${prevValueName} = `] : []), + ...(prevValueName + ? [shouldWrapInParentheses ? `(` : undefined, `${prevValueName} = `] + : []), ...genCall( vaporHelper('setDynamicProps'), `n${oper.element}`, @@ -125,7 +102,7 @@ export function genDynamicProps( genMulti(DELIMITERS_ARRAY, ...values), oper.root && 'true', ), - ...(prevValueName ? [`)`] : []), + ...(prevValueName && shouldWrapInParentheses ? [`)`] : []), ] } @@ -277,6 +254,39 @@ const getSpecialHelper = ( return specialHelpers[keyName] || null } +// those runtime helpers will return the prevValue +const helpersNeedCachedReturnValue = [ + 'setStyle', + 'setDynamicProp', + 'setDynamicProps', +] + +function processPropValues( + context: CodegenContext, + helperName: string, + values: CodeFragment[][], +): { prevValueName: string | undefined; shouldWrapInParentheses: boolean } { + const { shouldCacheRenderEffectDeps, processingRenderEffect } = context + // single-line render effect and the operation needs cache return a value, + // the expression needs to be wrapped in parentheses. + // e.g. _foo === _ctx.foo && (_foo = _setStyle(...)) + let shouldWrapInParentheses: boolean = false + let prevValueName + if (shouldCacheRenderEffectDeps()) { + const needReturnValue = helpersNeedCachedReturnValue.includes(helperName) + processValues(context, values, !needReturnValue) + const { declareNames } = processingRenderEffect! + // if the operation needs to cache the return value and has multiple declareNames, + // combine them into a single name as the return value name. + if (declareNames.size > 0 && needReturnValue) { + prevValueName = [...declareNames].join('') + declareNames.add(prevValueName) + } + shouldWrapInParentheses = processingRenderEffect!.operations.length === 1 + } + return { prevValueName, shouldWrapInParentheses } +} + export function processValues( context: CodegenContext, values: CodeFragment[][], From 4d86db7a631d157b1b3fb0ed6d65f18ac021c649 Mon Sep 17 00:00:00 2001 From: daiwei Date: Sun, 8 Dec 2024 11:12:41 +0800 Subject: [PATCH 41/47] wip: save --- packages/compiler-vapor/src/transform.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/compiler-vapor/src/transform.ts b/packages/compiler-vapor/src/transform.ts index 23c97266f..0b4f71f8d 100644 --- a/packages/compiler-vapor/src/transform.ts +++ b/packages/compiler-vapor/src/transform.ts @@ -307,7 +307,7 @@ export function createStructuralDirectiveTransform( function extractIdentifiers(ids: Set, node: ExpressionNode) { if (node.ast) { - walkIdentifiers(node.ast, n => ids.add(n.name)) + walkIdentifiers(node.ast, n => ids.add(n.name), true) } else if (node.ast === null) { ids.add((node as SimpleExpressionNode).content) } From 90f754364e17e8fece503b2d15ee8ae0db138038 Mon Sep 17 00:00:00 2001 From: daiwei Date: Sun, 8 Dec 2024 13:24:52 +0800 Subject: [PATCH 42/47] chore: codegen for member expression --- packages/compiler-vapor/src/generators/expression.ts | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/packages/compiler-vapor/src/generators/expression.ts b/packages/compiler-vapor/src/generators/expression.ts index d13a66412..9bf7c5ce6 100644 --- a/packages/compiler-vapor/src/generators/expression.ts +++ b/packages/compiler-vapor/src/generators/expression.ts @@ -1,4 +1,4 @@ -import { isGloballyAllowed } from '@vue/shared' +import { isArray, isGloballyAllowed } from '@vue/shared' import { BindingTypes, NewlineType, @@ -95,7 +95,14 @@ export function genExpression( ) if (i === ids.length - 1 && end < content.length) { - push([content.slice(end), NewlineType.Unknown]) + const rest = content.slice(end) + // merge member expression into the last identifier's fragment + const last = frag[frag.length - 1] + if (hasMemberExpression && isArray(last) && last[3]) { + last[0] += rest + } else { + push([rest, NewlineType.Unknown]) + } } }) From 3acad8dec8a31aa5b4356bbb249f6c253864af08 Mon Sep 17 00:00:00 2001 From: daiwei Date: Sun, 8 Dec 2024 15:24:44 +0800 Subject: [PATCH 43/47] wip: save --- packages/compiler-vapor/src/generators/expression.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/packages/compiler-vapor/src/generators/expression.ts b/packages/compiler-vapor/src/generators/expression.ts index 9bf7c5ce6..ef0176263 100644 --- a/packages/compiler-vapor/src/generators/expression.ts +++ b/packages/compiler-vapor/src/generators/expression.ts @@ -96,9 +96,9 @@ export function genExpression( if (i === ids.length - 1 && end < content.length) { const rest = content.slice(end) - // merge member expression into the last identifier's fragment const last = frag[frag.length - 1] - if (hasMemberExpression && isArray(last) && last[3]) { + if (hasMemberExpression && isArray(last)) { + // merge rest content into the last identifier's generated name last[0] += rest } else { push([rest, NewlineType.Unknown]) From 484e8edc695505042b0586509dd0637476cdcda5 Mon Sep 17 00:00:00 2001 From: daiwei Date: Sun, 8 Dec 2024 15:35:33 +0800 Subject: [PATCH 44/47] chore: add semi when necessary --- packages/compiler-vapor/src/generators/operation.ts | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/packages/compiler-vapor/src/generators/operation.ts b/packages/compiler-vapor/src/generators/operation.ts index f03005039..8dc196e59 100644 --- a/packages/compiler-vapor/src/generators/operation.ts +++ b/packages/compiler-vapor/src/generators/operation.ts @@ -85,8 +85,10 @@ export function genEffects( for (let i = 0; i < effects.length; i++) { const effect = (context.processingRenderEffect = effects[i]) operationsCount += effect.operations.length + const frags = genEffect(effect, context, declareNames) + const needSemi = frag[frag.length - 1] === ')' && frags[0] === '(' i > 0 && push(NEWLINE) - push(...genEffect(effect, context, declareNames)) + push(needSemi ? ';' : undefined, ...frags) } const newLineCount = frag.filter(frag => frag === NEWLINE).length From 950ba68ad8a648091b5df2cff9196764098def00 Mon Sep 17 00:00:00 2001 From: daiwei Date: Sun, 8 Dec 2024 15:39:36 +0800 Subject: [PATCH 45/47] test: add test --- .../transforms/__snapshots__/vBind.spec.ts.snap | 12 ++++++++++++ .../__tests__/transforms/vBind.spec.ts | 10 ++++++++++ 2 files changed, 22 insertions(+) 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 9b38fe90a..f40057f38 100644 --- a/packages/compiler-vapor/__tests__/transforms/__snapshots__/vBind.spec.ts.snap +++ b/packages/compiler-vapor/__tests__/transforms/__snapshots__/vBind.spec.ts.snap @@ -452,6 +452,18 @@ export function render(_ctx) { }" `; +exports[`compiler v-bind > bind member expression 1`] = ` +"import { setDOMProp as _setDOMProp, renderEffect as _renderEffect, template as _template } from 'vue/vapor'; +const t0 = _template("
") + +export function render(_ctx) { + const n0 = t0() + let _obj + _renderEffect(() => _obj !== _ctx.obj.count.bar && _setDOMProp(n0, "id", (_obj = _ctx.obj.count.bar))) + return [n0, n1] +}" +`; + exports[`compiler v-bind > dynamic arg 1`] = ` "import { setInheritAttrs as _setInheritAttrs, setDynamicProps as _setDynamicProps, renderEffect as _renderEffect, template as _template } from 'vue/vapor'; const t0 = _template("
") diff --git a/packages/compiler-vapor/__tests__/transforms/vBind.spec.ts b/packages/compiler-vapor/__tests__/transforms/vBind.spec.ts index 0c1e697ce..87c7752aa 100644 --- a/packages/compiler-vapor/__tests__/transforms/vBind.spec.ts +++ b/packages/compiler-vapor/__tests__/transforms/vBind.spec.ts @@ -792,6 +792,16 @@ describe('compiler v-bind', () => { ) }) + test('bind member expression', () => { + const { code } = compileWithVBind(` +
/> + `) + expect(code).matchSnapshot() + expect(code).contains( + '_obj !== _ctx.obj.count.bar && _setDOMProp(n0, "id", (_obj = _ctx.obj.count.bar))', + ) + }) + test('number value', () => { const { code } = compileWithVBind(``) expect(code).matchSnapshot() From 3a7a3977e3ef0782e0f12f54030ee0c7ac3c5196 Mon Sep 17 00:00:00 2001 From: daiwei Date: Sun, 8 Dec 2024 15:43:12 +0800 Subject: [PATCH 46/47] chore: remove recordPropMetadata and tests --- .../runtime-vapor/__tests__/dom/prop.spec.ts | 29 ------------------- .../runtime-vapor/src/componentMetadata.ts | 7 ----- 2 files changed, 36 deletions(-) diff --git a/packages/runtime-vapor/__tests__/dom/prop.spec.ts b/packages/runtime-vapor/__tests__/dom/prop.spec.ts index f75d40b3d..6f6666e4c 100644 --- a/packages/runtime-vapor/__tests__/dom/prop.spec.ts +++ b/packages/runtime-vapor/__tests__/dom/prop.spec.ts @@ -14,7 +14,6 @@ import { ComponentInternalInstance, setCurrentInstance, } from '../../src/component' -import { getMetadata, recordPropMetadata } from '../../src/componentMetadata' import { getCurrentScope } from '@vue/reactivity' let removeComponentInstance = NOOP @@ -35,34 +34,6 @@ afterEach(() => { }) describe('patchProp', () => { - describe('recordPropMetadata', () => { - test('should record prop metadata', () => { - const node = {} as Node // the node is just a key - let prev = recordPropMetadata(node, 'class', 'foo') - expect(prev).toBeUndefined() - prev = recordPropMetadata(node, 'class', 'bar') - expect(prev).toBe('foo') - prev = recordPropMetadata(node, 'style', 'color: red') - expect(prev).toBeUndefined() - prev = recordPropMetadata(node, 'style', 'color: blue') - expect(prev).toBe('color: red') - - expect(getMetadata(node)).toEqual([ - { class: 'bar', style: 'color: blue' }, - {}, - ]) - }) - - test('should have different metadata for different nodes', () => { - const node1 = {} as Node - const node2 = {} as Node - recordPropMetadata(node1, 'class', 'foo') - recordPropMetadata(node2, 'class', 'bar') - expect(getMetadata(node1)).toEqual([{ class: 'foo' }, {}]) - expect(getMetadata(node2)).toEqual([{ class: 'bar' }, {}]) - }) - }) - describe('setClass', () => { test('should set class', () => { const el = document.createElement('div') diff --git a/packages/runtime-vapor/src/componentMetadata.ts b/packages/runtime-vapor/src/componentMetadata.ts index ab2ad0bc6..4160d083c 100644 --- a/packages/runtime-vapor/src/componentMetadata.ts +++ b/packages/runtime-vapor/src/componentMetadata.ts @@ -18,13 +18,6 @@ export function getMetadata( return el.$$metadata || (el.$$metadata = [{}, {}]) } -export function recordPropMetadata(el: Node, key: string, value: any): any { - const metadata = getMetadata(el)[MetadataKind.prop] - const prev = metadata[key] - if (prev !== value) metadata[key] = value - return prev -} - export function recordEventMetadata(el: Node, key: string, value: any) { const metadata = getMetadata(el)[MetadataKind.event] const handlers = (metadata[key] ||= []) From 9f73dbf6c075ce11c28eac012e30d018ac8f2647 Mon Sep 17 00:00:00 2001 From: daiwei Date: Sun, 8 Dec 2024 15:45:14 +0800 Subject: [PATCH 47/47] chore: update --- packages/runtime-vapor/src/dom/prop.ts | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/packages/runtime-vapor/src/dom/prop.ts b/packages/runtime-vapor/src/dom/prop.ts index 652a74482..e43cff1d9 100644 --- a/packages/runtime-vapor/src/dom/prop.ts +++ b/packages/runtime-vapor/src/dom/prop.ts @@ -160,7 +160,12 @@ export function setDynamicProps( const prev = Object.create(null) for (const key in props) { - setDynamicProp(el, key, undefined, (prev[key] = props[key])) + setDynamicProp( + el, + key, + oldProps ? oldProps[key] : undefined, + (prev[key] = props[key]), + ) } return prev