Skip to content

Commit

Permalink
fix(compiler-core): fix expression transform for try...catch block pa…
Browse files Browse the repository at this point in the history
…rams

close #11465
close #11467
  • Loading branch information
yyx990803 committed Aug 5, 2024
1 parent 2f9023d commit 077a1ae
Show file tree
Hide file tree
Showing 3 changed files with 118 additions and 51 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -14,44 +14,74 @@ return function render(_ctx, _cache, $props, $setup, $data, $options) {
}"
`;

exports[`compiler: expression transform > bindingMetadata > should not prefix temp variable of for loop 1`] = `
exports[`compiler: expression transform > should not prefix catch block param 1`] = `
"const { openBlock: _openBlock, createElementBlock: _createElementBlock } = Vue
return function render(_ctx, _cache, $props, $setup, $data, $options) {
return function render(_ctx, _cache) {
return (_openBlock(), _createElementBlock("div", {
onClick: () => {
try {} catch (err) { console.error(err) }
console.log(_ctx.err)
}
}, null, 8 /* PROPS */, ["onClick"]))
}"
`;

exports[`compiler: expression transform > should not prefix destructured catch block param 1`] = `
"const { openBlock: _openBlock, createElementBlock: _createElementBlock } = Vue
return function render(_ctx, _cache) {
return (_openBlock(), _createElementBlock("div", {
onClick: () => {
for (let i = 0; i < _ctx.list.length; i++) {
_ctx.log(i)
}
try {
throw new Error('sup?')
} catch ({ message: { length } }) {
console.error(length)
}
console.log(_ctx.length)
}
}, null, 8 /* PROPS */, ["onClick"]))
}"
`;

exports[`compiler: expression transform > bindingMetadata > should not prefix temp variable of for...in 1`] = `
exports[`compiler: expression transform > should not prefix temp variable of for loop 1`] = `
"const { openBlock: _openBlock, createElementBlock: _createElementBlock } = Vue
return function render(_ctx, _cache, $props, $setup, $data, $options) {
return function render(_ctx, _cache) {
return (_openBlock(), _createElementBlock("div", {
onClick: () => {
for (const x in _ctx.list) {
_ctx.log(x)
}
for (let i = 0; i < _ctx.list.length; i++) {
_ctx.log(i)
}
}
}, null, 8 /* PROPS */, ["onClick"]))
}"
`;

exports[`compiler: expression transform > bindingMetadata > should not prefix temp variable of for...of 1`] = `
exports[`compiler: expression transform > should not prefix temp variable of for...in 1`] = `
"const { openBlock: _openBlock, createElementBlock: _createElementBlock } = Vue
return function render(_ctx, _cache, $props, $setup, $data, $options) {
return function render(_ctx, _cache) {
return (_openBlock(), _createElementBlock("div", {
onClick: () => {
for (const x in _ctx.list) {
_ctx.log(x)
}
}
}, null, 8 /* PROPS */, ["onClick"]))
}"
`;

exports[`compiler: expression transform > should not prefix temp variable of for...of 1`] = `
"const { openBlock: _openBlock, createElementBlock: _createElementBlock } = Vue
return function render(_ctx, _cache) {
return (_openBlock(), _createElementBlock("div", {
onClick: () => {
for (const x of _ctx.list) {
_ctx.log(x)
}
for (const x of _ctx.list) {
_ctx.log(x)
}
}
}, null, 8 /* PROPS */, ["onClick"]))
}"
`;
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,10 @@ function parseWithExpressionTransform(
return ast.children[0]
}

function compile(template: string) {
return baseCompile(template, { prefixIdentifiers: true })
}

describe('compiler: expression transform', () => {
test('interpolation (root)', () => {
const node = parseWithExpressionTransform(`{{ foo }}`) as InterpolationNode
Expand Down Expand Up @@ -291,6 +295,7 @@ describe('compiler: expression transform', () => {
],
})
})

test('should not prefix an object property key', () => {
const node = parseWithExpressionTransform(
`{{ { foo() { baz() }, value: bar } }}`,
Expand Down Expand Up @@ -457,6 +462,70 @@ describe('compiler: expression transform', () => {
})
})

test('should not prefix temp variable of for...in', () => {
const { code } = compile(
`<div @click="() => {
for (const x in list) {
log(x)
}
}"/>`,
)
expect(code).not.toMatch(`_ctx.x`)
expect(code).toMatchSnapshot()
})

test('should not prefix temp variable of for...of', () => {
const { code } = compile(
`<div @click="() => {
for (const x of list) {
log(x)
}
}"/>`,
)
expect(code).not.toMatch(`_ctx.x`)
expect(code).toMatchSnapshot()
})

test('should not prefix temp variable of for loop', () => {
const { code } = compile(
`<div @click="() => {
for (let i = 0; i < list.length; i++) {
log(i)
}
}"/>`,
)
expect(code).not.toMatch(`_ctx.i`)
expect(code).toMatchSnapshot()
})

test('should not prefix catch block param', () => {
const { code } = compile(
`<div @click="() => {
try {} catch (err) { console.error(err) }
console.log(err)
}"/>`,
)
expect(code).not.toMatch(`console.error(_ctx.err)`)
expect(code).toMatch(`console.log(_ctx.err)`)
expect(code).toMatchSnapshot()
})

test('should not prefix destructured catch block param', () => {
const { code } = compile(
`<div @click="() => {
try {
throw new Error('sup?')
} catch ({ message: { length } }) {
console.error(length)
}
console.log(length)
}"/>`,
)
expect(code).not.toMatch(`console.error(_ctx.length)`)
expect(code).toMatch(`console.log(_ctx.length)`)
expect(code).toMatchSnapshot()
})

describe('ES Proposals support', () => {
test('bigInt', () => {
const node = parseWithExpressionTransform(
Expand Down Expand Up @@ -555,42 +624,6 @@ describe('compiler: expression transform', () => {
expect(code).toMatchSnapshot()
})

test('should not prefix temp variable of for...in', () => {
const { code } = compileWithBindingMetadata(
`<div @click="() => {
for (const x in list) {
log(x)
}
}"/>`,
)
expect(code).not.toMatch(`_ctx.x`)
expect(code).toMatchSnapshot()
})

test('should not prefix temp variable of for...of', () => {
const { code } = compileWithBindingMetadata(
`<div @click="() => {
for (const x of list) {
log(x)
}
}"/>`,
)
expect(code).not.toMatch(`_ctx.x`)
expect(code).toMatchSnapshot()
})

test('should not prefix temp variable of for loop', () => {
const { code } = compileWithBindingMetadata(
`<div @click="() => {
for (let i = 0; i < list.length; i++) {
log(i)
}
}"/>`,
)
expect(code).not.toMatch(`_ctx.i`)
expect(code).toMatchSnapshot()
})

test('inline mode', () => {
const { code } = compileWithBindingMetadata(
`<div>{{ props }} {{ setup }} {{ setupConst }} {{ data }} {{ options }} {{ isNaN }}</div>`,
Expand Down
4 changes: 4 additions & 0 deletions packages/compiler-core/src/babelUtils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -77,6 +77,10 @@ export function walkIdentifiers(
markScopeIdentifier(node, id, knownIds),
)
}
} else if (node.type === 'CatchClause' && node.param) {
for (const id of extractIdentifiers(node.param)) {
markScopeIdentifier(node, id, knownIds)
}
}
},
leave(node: Node & { scopeIds?: Set<string> }, parent: Node | null) {
Expand Down

0 comments on commit 077a1ae

Please sign in to comment.