Skip to content

Commit 9f3d8cc

Browse files
fix(language-core): AST fault tolerance for key binding on template (#5807)
1 parent 5bf90db commit 9f3d8cc

File tree

2 files changed

+43
-1
lines changed
  • packages/language-core/lib/virtualCode
  • test-workspace/tsc/passedFixtures/vue3/#4539

2 files changed

+43
-1
lines changed

packages/language-core/lib/virtualCode/normalize.ts

Lines changed: 38 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@ export function normalizeTemplateAST(root: CompilerDOM.RootNode) {
1919
expressionPlugins: ['typescript'],
2020
};
2121

22-
for (const { children } of forEachElementNode(root)) {
22+
for (const { children, codegenNode, props } of forEachElementNode(root)) {
2323
for (let i = 0; i < children.length; i++) {
2424
const child = children[i]!;
2525
if (child.type !== CompilerDOM.NodeTypes.ELEMENT) {
@@ -37,6 +37,43 @@ export function normalizeTemplateAST(root: CompilerDOM.RootNode) {
3737
continue;
3838
}
3939
}
40+
// #4539
41+
if (
42+
codegenNode
43+
&& 'props' in codegenNode
44+
&& codegenNode.props
45+
&& 'properties' in codegenNode.props
46+
) {
47+
for (const p of codegenNode.props.properties) {
48+
if (
49+
p.key.type === CompilerDOM.NodeTypes.SIMPLE_EXPRESSION
50+
&& p.key.content === 'key'
51+
&& !p.key.isHandlerKey
52+
&& !p.key.loc.source
53+
&& p.value.type === CompilerDOM.NodeTypes.SIMPLE_EXPRESSION
54+
&& p.value.constType === CompilerDOM.ConstantTypes.NOT_CONSTANT
55+
) {
56+
const contentBeforeValue = root.loc.source.slice(0, p.value.loc.start.offset);
57+
const argOffset = contentBeforeValue.lastIndexOf('key');
58+
props.push({
59+
type: CompilerDOM.NodeTypes.DIRECTIVE,
60+
name: 'bind',
61+
exp: p.value,
62+
loc: p.loc,
63+
arg: {
64+
...p.key,
65+
loc: {
66+
start: { line: -1, column: -1, offset: argOffset },
67+
end: { line: -1, column: -1, offset: argOffset + 'key'.length },
68+
source: 'key',
69+
},
70+
},
71+
modifiers: [],
72+
});
73+
break;
74+
}
75+
}
76+
}
4077
}
4178
}
4279

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
<template>
2+
<template v-for="x in [1]" :key="x">
3+
<div></div>
4+
</template>
5+
</template>

0 commit comments

Comments
 (0)