Skip to content

Commit 485e709

Browse files
committed
fix(compiler): correct execution order of operations
1 parent 9c10b3b commit 485e709

File tree

17 files changed

+262
-356
lines changed

17 files changed

+262
-356
lines changed

docs/introduction/getting-started.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,7 @@ We assume you are already familiar with the basic usages of Vue before you conti
2525
pnpm add vue-jsx-vapor
2626

2727
# runtime
28-
pnpm add https://pkg.pr.new/vue@72d63f1
28+
pnpm add https://pkg.pr.new/vue@9e2eea9
2929
```
3030

3131
The Vue Vapor runtime is not release, so we use [pkg.pr.new](https://github.com/stackblitz-labs/pkg.pr.new) to install.

packages/compiler/src/compile.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -122,8 +122,8 @@ export function getBaseTransformPreset(): TransformPreset {
122122
transformVIf,
123123
transformVFor,
124124
transformTemplateRef,
125-
transformText,
126125
transformElement,
126+
transformText,
127127
transformVSlot,
128128
transformChildren,
129129
],

packages/compiler/src/ir/index.ts

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -57,7 +57,6 @@ export interface BlockIRNode extends BaseIRNode {
5757
tempId: number
5858
effect: IREffect[]
5959
operation: OperationNode[]
60-
expressions: SimpleExpressionNode[]
6160
returns: number[]
6261
}
6362

packages/compiler/src/transform.ts

Lines changed: 14 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -161,41 +161,31 @@ export class TransformContext<
161161

162162
registerEffect(
163163
expressions: SimpleExpressionNode[],
164-
...operations: OperationNode[]
164+
operation: OperationNode | OperationNode[],
165+
getEffectIndex = (): number => this.block.effect.length,
166+
getOperationIndex = (): number => this.block.operation.length,
165167
) {
168+
const operations = [operation].flat()
166169
expressions = expressions.filter((exp) => !isConstantExpression(exp))
167170
if (
168171
this.inVOnce ||
169172
expressions.length === 0 ||
170173
expressions.every((e) => e.ast && isConstantNode(e.ast, {}))
171174
) {
172-
return this.registerOperation(...operations)
175+
return this.registerOperation(operations, getOperationIndex)
173176
}
174177

175-
this.block.expressions.push(...expressions)
176-
const existing = this.block.effect.find((e) =>
177-
isSameExpression(e.expressions, expressions),
178-
)
179-
if (existing) {
180-
existing.operations.push(...operations)
181-
} else {
182-
this.block.effect.push({
183-
expressions,
184-
operations,
185-
})
186-
}
187-
188-
function isSameExpression(
189-
a: SimpleExpressionNode[],
190-
b: SimpleExpressionNode[],
191-
) {
192-
if (a.length !== b.length) return false
193-
return a.every((exp, i) => exp.content === b[i].content)
194-
}
178+
this.block.effect.splice(getEffectIndex(), 0, {
179+
expressions,
180+
operations,
181+
})
195182
}
196183

197-
registerOperation(...node: OperationNode[]) {
198-
this.block.operation.push(...node)
184+
registerOperation(
185+
operation: OperationNode | OperationNode[],
186+
getOperationIndex = (): number => this.block.operation.length,
187+
) {
188+
this.block.operation.splice(getOperationIndex(), 0, ...[operation].flat())
199189
}
200190

201191
create<E extends T>(node: E, index: number): TransformContext<E> {

packages/compiler/src/transforms/transformElement.ts

Lines changed: 31 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,10 @@ const isEventRegex = /^on[A-Z]/
3535
const isDirectiveRegex = /^v-[a-z]/
3636

3737
export const transformElement: NodeTransform = (node, context) => {
38+
let effectIndex = context.block.effect.length
39+
const getEffectIndex = () => effectIndex++
40+
let operationIndex = context.block.operation.length
41+
const getOperationIndex = () => operationIndex++
3842
return function postTransformElement() {
3943
;({ node } = context)
4044
if (node.type !== 'JSXElement' || isTemplate(node)) return
@@ -71,6 +75,8 @@ export const transformElement: NodeTransform = (node, context) => {
7175
propsResult,
7276
singleRoot,
7377
context as TransformContext<JSXElement>,
78+
getEffectIndex,
79+
getOperationIndex,
7480
)
7581
}
7682
}
@@ -120,6 +126,8 @@ function transformNativeElement(
120126
propsResult: PropsResult,
121127
singleRoot: boolean,
122128
context: TransformContext<JSXElement>,
129+
getEffectIndex: () => number,
130+
getOperationIndex: () => number,
123131
) {
124132
const { scopeId } = context.options
125133

@@ -131,12 +139,17 @@ function transformNativeElement(
131139
const dynamicProps: string[] = []
132140
if (propsResult[0] /* dynamic props */) {
133141
const [, dynamicArgs, expressions] = propsResult
134-
context.registerEffect(expressions, {
135-
type: IRNodeTypes.SET_DYNAMIC_PROPS,
136-
element: context.reference(),
137-
props: dynamicArgs,
138-
root: singleRoot,
139-
})
142+
context.registerEffect(
143+
expressions,
144+
{
145+
type: IRNodeTypes.SET_DYNAMIC_PROPS,
146+
element: context.reference(),
147+
props: dynamicArgs,
148+
root: singleRoot,
149+
},
150+
getEffectIndex,
151+
getOperationIndex,
152+
)
140153
} else {
141154
for (const prop of propsResult[1]) {
142155
const { key, values } = prop
@@ -145,13 +158,18 @@ function transformNativeElement(
145158
if (values[0].content) template += `="${values[0].content}"`
146159
} else {
147160
dynamicProps.push(key.content)
148-
context.registerEffect(values, {
149-
type: IRNodeTypes.SET_PROP,
150-
element: context.reference(),
151-
prop,
152-
tag,
153-
root: singleRoot,
154-
})
161+
context.registerEffect(
162+
values,
163+
{
164+
type: IRNodeTypes.SET_PROP,
165+
element: context.reference(),
166+
prop,
167+
tag,
168+
root: singleRoot,
169+
},
170+
getEffectIndex,
171+
getOperationIndex,
172+
)
155173
}
156174
}
157175
}

packages/compiler/src/transforms/utils.ts

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,6 @@ export function newBlock(node: BlockIRNode['node']): BlockIRNode {
3434
effect: [],
3535
operation: [],
3636
returns: [],
37-
expressions: [],
3837
tempId: 0,
3938
}
4039
}

packages/compiler/test/__snapshots__/compile.spec.ts.snap

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,30 @@ exports[`compile > dynamic root 2`] = `
1616
"
1717
`;
1818

19+
exports[`compile > execution order > basic 1`] = `
20+
"
21+
const n0 = t0()
22+
_setProp(n0, "foo", true)
23+
const x0 = _child(n0)
24+
_setNodes(x0, () => (foo))
25+
return n0
26+
"
27+
`;
28+
29+
exports[`compile > execution order > with v-once 1`] = `
30+
"
31+
const n3 = t0()
32+
const n0 = _child(n3)
33+
const n1 = _next(n0)
34+
const n2 = _nthChild(n3, 3)
35+
const x0 = _child(n0)
36+
_setNodes(x0, foo)
37+
_setNodes(n1, () => (bar))
38+
_setNodes(n2, () => (baz))
39+
return n3
40+
"
41+
`;
42+
1943
exports[`compile > expression parsing > interpolation 1`] = `
2044
"
2145
const n0 = _createNodes(() => (a + b))

packages/compiler/test/compile.spec.ts

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -49,4 +49,30 @@ describe('compile', () => {
4949
expect(code).toMatchSnapshot()
5050
})
5151
})
52+
53+
describe('execution order', () => {
54+
test('basic', () => {
55+
const { code } = compile(`<div foo={true}>{foo}</div>`)
56+
expect(code).matchSnapshot()
57+
expect(code).contains(
58+
`_setProp(n0, "foo", true)
59+
const x0 = _child(n0)
60+
_setNodes(x0, () => (foo))`,
61+
)
62+
})
63+
test('with v-once', () => {
64+
const { code } = compile(
65+
`<div>
66+
<span v-once>{ foo }</span>
67+
{ bar }<br/>
68+
{ baz }
69+
</div>`,
70+
)
71+
expect(code).matchSnapshot()
72+
expect(code).contains(
73+
`_setNodes(n1, () => (bar))
74+
_setNodes(n2, () => (baz))`,
75+
)
76+
})
77+
})
5278
})

packages/compiler/test/transforms/expression.spec.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,8 +13,8 @@ import { makeCompile } from './_utils'
1313
const compileWithVIf = makeCompile({
1414
nodeTransforms: [
1515
transformVOnce,
16-
transformText,
1716
transformElement,
17+
transformText,
1818
transformChildren,
1919
],
2020
})

packages/compiler/test/transforms/transformElement.spec.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,8 +13,8 @@ const compileWithElementTransform = makeCompile({
1313
nodeTransforms: [
1414
transformVFor,
1515
transformElement,
16-
transformChildren,
1716
transformText,
17+
transformChildren,
1818
],
1919
directiveTransforms: {
2020
bind: transformVBind,

packages/compiler/test/transforms/vFor.spec.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,8 +15,8 @@ import { makeCompile } from './_utils'
1515
const compileWithVFor = makeCompile({
1616
nodeTransforms: [
1717
transformVFor,
18-
transformText,
1918
transformElement,
19+
transformText,
2020
transformChildren,
2121
],
2222
directiveTransforms: {

packages/compiler/test/transforms/vIf.spec.ts

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,6 @@ import { describe, expect, test } from 'vitest'
33
import {
44
IRNodeTypes,
55
transformChildren,
6-
// transformComment,
76
transformElement,
87
transformText,
98
transformVIf,
@@ -15,9 +14,8 @@ import { makeCompile } from './_utils'
1514
const compileWithVIf = makeCompile({
1615
nodeTransforms: [
1716
transformVIf,
18-
transformText,
1917
transformElement,
20-
// transformComment,
18+
transformText,
2119
transformChildren,
2220
],
2321
directiveTransforms: {

packages/compiler/test/transforms/vOn.spec.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ import {
1111
import { makeCompile } from './_utils'
1212

1313
const compileWithVOn = makeCompile({
14-
nodeTransforms: [transformText, transformElement, transformChildren],
14+
nodeTransforms: [transformElement, transformText, transformChildren],
1515
directiveTransforms: {
1616
on: transformVOn,
1717
bind: transformVBind,

packages/compiler/test/transforms/vSlot.spec.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,10 +16,10 @@ import { makeCompile } from './_utils'
1616

1717
const compileWithSlots = makeCompile({
1818
nodeTransforms: [
19-
transformText,
2019
transformVIf,
2120
transformVFor,
2221
transformElement,
22+
transformText,
2323
transformVSlot,
2424
transformChildren,
2525
],

packages/compiler/test/transforms/vSlots.spec.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,8 +13,8 @@ import { makeCompile } from './_utils'
1313

1414
const compileWithSlots = makeCompile({
1515
nodeTransforms: [
16-
transformText,
1716
transformElement,
17+
transformText,
1818
transformVSlot,
1919
transformChildren,
2020
],

0 commit comments

Comments
 (0)