Skip to content

Commit a2d810e

Browse files
authored
fix(compiler-core): avoid rewriting scope variables in inline for loops (#7245)
close #7238
1 parent d11e978 commit a2d810e

File tree

3 files changed

+91
-0
lines changed

3 files changed

+91
-0
lines changed

packages/compiler-core/__tests__/transforms/__snapshots__/transformExpressions.spec.ts.snap

+42
Original file line numberDiff line numberDiff line change
@@ -13,3 +13,45 @@ return function render(_ctx, _cache, $props, $setup, $data, $options) {
1313
return (_openBlock(), _createElementBlock(\\"div\\", null, _toDisplayString($props.props) + \\" \\" + _toDisplayString($setup.setup) + \\" \\" + _toDisplayString($data.data) + \\" \\" + _toDisplayString($options.options) + \\" \\" + _toDisplayString($setup.isNaN), 1 /* TEXT */))
1414
}"
1515
`;
16+
17+
exports[`compiler: expression transform > bindingMetadata > should not prefix temp variable of for loop 1`] = `
18+
"const { openBlock: _openBlock, createElementBlock: _createElementBlock } = Vue
19+
20+
return function render(_ctx, _cache, $props, $setup, $data, $options) {
21+
return (_openBlock(), _createElementBlock(\\"div\\", {
22+
onClick: () => {
23+
for (let i = 0; i < _ctx.list.length; i++) {
24+
_ctx.log(i)
25+
}
26+
}
27+
}, null, 8 /* PROPS */, [\\"onClick\\"]))
28+
}"
29+
`;
30+
31+
exports[`compiler: expression transform > bindingMetadata > should not prefix temp variable of for...in 1`] = `
32+
"const { openBlock: _openBlock, createElementBlock: _createElementBlock } = Vue
33+
34+
return function render(_ctx, _cache, $props, $setup, $data, $options) {
35+
return (_openBlock(), _createElementBlock(\\"div\\", {
36+
onClick: () => {
37+
for (const x in _ctx.list) {
38+
_ctx.log(x)
39+
}
40+
}
41+
}, null, 8 /* PROPS */, [\\"onClick\\"]))
42+
}"
43+
`;
44+
45+
exports[`compiler: expression transform > bindingMetadata > should not prefix temp variable of for...of 1`] = `
46+
"const { openBlock: _openBlock, createElementBlock: _createElementBlock } = Vue
47+
48+
return function render(_ctx, _cache, $props, $setup, $data, $options) {
49+
return (_openBlock(), _createElementBlock(\\"div\\", {
50+
onClick: () => {
51+
for (const x of _ctx.list) {
52+
_ctx.log(x)
53+
}
54+
}
55+
}, null, 8 /* PROPS */, [\\"onClick\\"]))
56+
}"
57+
`;

packages/compiler-core/__tests__/transforms/transformExpressions.spec.ts

+36
Original file line numberDiff line numberDiff line change
@@ -534,6 +534,42 @@ describe('compiler: expression transform', () => {
534534
expect(code).toMatchSnapshot()
535535
})
536536

537+
test('should not prefix temp variable of for...in', () => {
538+
const { code } = compileWithBindingMetadata(
539+
`<div @click="() => {
540+
for (const x in list) {
541+
log(x)
542+
}
543+
}"/>`
544+
)
545+
expect(code).not.toMatch(`_ctx.x`)
546+
expect(code).toMatchSnapshot()
547+
})
548+
549+
test('should not prefix temp variable of for...of', () => {
550+
const { code } = compileWithBindingMetadata(
551+
`<div @click="() => {
552+
for (const x of list) {
553+
log(x)
554+
}
555+
}"/>`
556+
)
557+
expect(code).not.toMatch(`_ctx.x`)
558+
expect(code).toMatchSnapshot()
559+
})
560+
561+
test('should not prefix temp variable of for loop', () => {
562+
const { code } = compileWithBindingMetadata(
563+
`<div @click="() => {
564+
for (let i = 0; i < list.length; i++) {
565+
log(i)
566+
}
567+
}"/>`
568+
)
569+
expect(code).not.toMatch(`_ctx.i`)
570+
expect(code).toMatchSnapshot()
571+
})
572+
537573
test('inline mode', () => {
538574
const { code } = compileWithBindingMetadata(
539575
`<div>{{ props }} {{ setup }} {{ setupConst }} {{ data }} {{ options }} {{ isNaN }}</div>`,

packages/compiler-core/src/babelUtils.ts

+13
Original file line numberDiff line numberDiff line change
@@ -165,6 +165,19 @@ export function walkBlockDeclarations(
165165
) {
166166
if (stmt.declare || !stmt.id) continue
167167
onIdent(stmt.id)
168+
} else if (
169+
stmt.type === 'ForOfStatement' ||
170+
stmt.type === 'ForInStatement' ||
171+
stmt.type === 'ForStatement'
172+
) {
173+
const variable = stmt.type === 'ForStatement' ? stmt.init : stmt.left
174+
if (variable && variable.type === 'VariableDeclaration') {
175+
for (const decl of variable.declarations) {
176+
for (const id of extractIdentifiers(decl.id)) {
177+
onIdent(id)
178+
}
179+
}
180+
}
168181
}
169182
}
170183
}

0 commit comments

Comments
 (0)