Skip to content
This repository was archived by the owner on Jul 19, 2025. It is now read-only.

Commit 077a1ae

Browse files
committed
fix(compiler-core): fix expression transform for try...catch block params
close #11465 close #11467
1 parent 2f9023d commit 077a1ae

File tree

3 files changed

+118
-51
lines changed

3 files changed

+118
-51
lines changed

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

Lines changed: 45 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -14,44 +14,74 @@ return function render(_ctx, _cache, $props, $setup, $data, $options) {
1414
}"
1515
`;
1616

17-
exports[`compiler: expression transform > bindingMetadata > should not prefix temp variable of for loop 1`] = `
17+
exports[`compiler: expression transform > should not prefix catch block param 1`] = `
1818
"const { openBlock: _openBlock, createElementBlock: _createElementBlock } = Vue
1919
20-
return function render(_ctx, _cache, $props, $setup, $data, $options) {
20+
return function render(_ctx, _cache) {
21+
return (_openBlock(), _createElementBlock("div", {
22+
onClick: () => {
23+
try {} catch (err) { console.error(err) }
24+
console.log(_ctx.err)
25+
}
26+
}, null, 8 /* PROPS */, ["onClick"]))
27+
}"
28+
`;
29+
30+
exports[`compiler: expression transform > should not prefix destructured catch block param 1`] = `
31+
"const { openBlock: _openBlock, createElementBlock: _createElementBlock } = Vue
32+
33+
return function render(_ctx, _cache) {
2134
return (_openBlock(), _createElementBlock("div", {
2235
onClick: () => {
23-
for (let i = 0; i < _ctx.list.length; i++) {
24-
_ctx.log(i)
25-
}
36+
try {
37+
throw new Error('sup?')
38+
} catch ({ message: { length } }) {
39+
console.error(length)
2640
}
41+
console.log(_ctx.length)
42+
}
2743
}, null, 8 /* PROPS */, ["onClick"]))
2844
}"
2945
`;
3046

31-
exports[`compiler: expression transform > bindingMetadata > should not prefix temp variable of for...in 1`] = `
47+
exports[`compiler: expression transform > should not prefix temp variable of for loop 1`] = `
3248
"const { openBlock: _openBlock, createElementBlock: _createElementBlock } = Vue
3349
34-
return function render(_ctx, _cache, $props, $setup, $data, $options) {
50+
return function render(_ctx, _cache) {
3551
return (_openBlock(), _createElementBlock("div", {
3652
onClick: () => {
37-
for (const x in _ctx.list) {
38-
_ctx.log(x)
39-
}
53+
for (let i = 0; i < _ctx.list.length; i++) {
54+
_ctx.log(i)
4055
}
56+
}
4157
}, null, 8 /* PROPS */, ["onClick"]))
4258
}"
4359
`;
4460

45-
exports[`compiler: expression transform > bindingMetadata > should not prefix temp variable of for...of 1`] = `
61+
exports[`compiler: expression transform > should not prefix temp variable of for...in 1`] = `
4662
"const { openBlock: _openBlock, createElementBlock: _createElementBlock } = Vue
4763
48-
return function render(_ctx, _cache, $props, $setup, $data, $options) {
64+
return function render(_ctx, _cache) {
65+
return (_openBlock(), _createElementBlock("div", {
66+
onClick: () => {
67+
for (const x in _ctx.list) {
68+
_ctx.log(x)
69+
}
70+
}
71+
}, null, 8 /* PROPS */, ["onClick"]))
72+
}"
73+
`;
74+
75+
exports[`compiler: expression transform > should not prefix temp variable of for...of 1`] = `
76+
"const { openBlock: _openBlock, createElementBlock: _createElementBlock } = Vue
77+
78+
return function render(_ctx, _cache) {
4979
return (_openBlock(), _createElementBlock("div", {
5080
onClick: () => {
51-
for (const x of _ctx.list) {
52-
_ctx.log(x)
53-
}
81+
for (const x of _ctx.list) {
82+
_ctx.log(x)
5483
}
84+
}
5585
}, null, 8 /* PROPS */, ["onClick"]))
5686
}"
5787
`;

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

Lines changed: 69 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,10 @@ function parseWithExpressionTransform(
2727
return ast.children[0]
2828
}
2929

30+
function compile(template: string) {
31+
return baseCompile(template, { prefixIdentifiers: true })
32+
}
33+
3034
describe('compiler: expression transform', () => {
3135
test('interpolation (root)', () => {
3236
const node = parseWithExpressionTransform(`{{ foo }}`) as InterpolationNode
@@ -291,6 +295,7 @@ describe('compiler: expression transform', () => {
291295
],
292296
})
293297
})
298+
294299
test('should not prefix an object property key', () => {
295300
const node = parseWithExpressionTransform(
296301
`{{ { foo() { baz() }, value: bar } }}`,
@@ -457,6 +462,70 @@ describe('compiler: expression transform', () => {
457462
})
458463
})
459464

465+
test('should not prefix temp variable of for...in', () => {
466+
const { code } = compile(
467+
`<div @click="() => {
468+
for (const x in list) {
469+
log(x)
470+
}
471+
}"/>`,
472+
)
473+
expect(code).not.toMatch(`_ctx.x`)
474+
expect(code).toMatchSnapshot()
475+
})
476+
477+
test('should not prefix temp variable of for...of', () => {
478+
const { code } = compile(
479+
`<div @click="() => {
480+
for (const x of list) {
481+
log(x)
482+
}
483+
}"/>`,
484+
)
485+
expect(code).not.toMatch(`_ctx.x`)
486+
expect(code).toMatchSnapshot()
487+
})
488+
489+
test('should not prefix temp variable of for loop', () => {
490+
const { code } = compile(
491+
`<div @click="() => {
492+
for (let i = 0; i < list.length; i++) {
493+
log(i)
494+
}
495+
}"/>`,
496+
)
497+
expect(code).not.toMatch(`_ctx.i`)
498+
expect(code).toMatchSnapshot()
499+
})
500+
501+
test('should not prefix catch block param', () => {
502+
const { code } = compile(
503+
`<div @click="() => {
504+
try {} catch (err) { console.error(err) }
505+
console.log(err)
506+
}"/>`,
507+
)
508+
expect(code).not.toMatch(`console.error(_ctx.err)`)
509+
expect(code).toMatch(`console.log(_ctx.err)`)
510+
expect(code).toMatchSnapshot()
511+
})
512+
513+
test('should not prefix destructured catch block param', () => {
514+
const { code } = compile(
515+
`<div @click="() => {
516+
try {
517+
throw new Error('sup?')
518+
} catch ({ message: { length } }) {
519+
console.error(length)
520+
}
521+
console.log(length)
522+
}"/>`,
523+
)
524+
expect(code).not.toMatch(`console.error(_ctx.length)`)
525+
expect(code).toMatch(`console.log(_ctx.length)`)
526+
expect(code).toMatchSnapshot()
527+
})
528+
460529
describe('ES Proposals support', () => {
461530
test('bigInt', () => {
462531
const node = parseWithExpressionTransform(
@@ -555,42 +624,6 @@ describe('compiler: expression transform', () => {
555624
expect(code).toMatchSnapshot()
556625
})
557626

558-
test('should not prefix temp variable of for...in', () => {
559-
const { code } = compileWithBindingMetadata(
560-
`<div @click="() => {
561-
for (const x in list) {
562-
log(x)
563-
}
564-
}"/>`,
565-
)
566-
expect(code).not.toMatch(`_ctx.x`)
567-
expect(code).toMatchSnapshot()
568-
})
569-
570-
test('should not prefix temp variable of for...of', () => {
571-
const { code } = compileWithBindingMetadata(
572-
`<div @click="() => {
573-
for (const x of list) {
574-
log(x)
575-
}
576-
}"/>`,
577-
)
578-
expect(code).not.toMatch(`_ctx.x`)
579-
expect(code).toMatchSnapshot()
580-
})
581-
582-
test('should not prefix temp variable of for loop', () => {
583-
const { code } = compileWithBindingMetadata(
584-
`<div @click="() => {
585-
for (let i = 0; i < list.length; i++) {
586-
log(i)
587-
}
588-
}"/>`,
589-
)
590-
expect(code).not.toMatch(`_ctx.i`)
591-
expect(code).toMatchSnapshot()
592-
})
593-
594627
test('inline mode', () => {
595628
const { code } = compileWithBindingMetadata(
596629
`<div>{{ props }} {{ setup }} {{ setupConst }} {{ data }} {{ options }} {{ isNaN }}</div>`,

packages/compiler-core/src/babelUtils.ts

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -77,6 +77,10 @@ export function walkIdentifiers(
7777
markScopeIdentifier(node, id, knownIds),
7878
)
7979
}
80+
} else if (node.type === 'CatchClause' && node.param) {
81+
for (const id of extractIdentifiers(node.param)) {
82+
markScopeIdentifier(node, id, knownIds)
83+
}
8084
}
8185
},
8286
leave(node: Node & { scopeIds?: Set<string> }, parent: Node | null) {

0 commit comments

Comments
 (0)