Skip to content

Commit 75fd6d2

Browse files
committed
fix(language-core): inline dynamic event handlers should not expect commas
Refs #4387 (comment)
1 parent edb85ed commit 75fd6d2

File tree

3 files changed

+55
-27
lines changed

3 files changed

+55
-27
lines changed

packages/language-core/lib/codegen/template/element.ts

Lines changed: 20 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,11 @@ export function* generateComponent(
2828
const tagOffsets = endTagOffset !== undefined
2929
? [startTagOffset, endTagOffset]
3030
: [startTagOffset];
31-
const propsFailedExps: CompilerDOM.SimpleExpressionNode[] = [];
31+
const propsFailedExps: {
32+
node: CompilerDOM.SimpleExpressionNode;
33+
prefix: string;
34+
suffix: string;
35+
}[] = [];
3236
const possibleOriginalNames = getPossibleOriginalComponentNames(node.tag, true);
3337
const matchImportName = possibleOriginalNames.find(name => options.scriptSetupImportComponentNames.has(name));
3438
const var_originalComponent = matchImportName ?? ctx.getInternalVariable();
@@ -225,12 +229,12 @@ export function* generateComponent(
225229
yield* generateInterpolation(
226230
options,
227231
ctx,
228-
failedExp.loc.source,
229-
failedExp.loc,
230-
failedExp.loc.start.offset,
232+
failedExp.node.loc.source,
233+
failedExp.node.loc,
234+
failedExp.node.loc.start.offset,
231235
ctx.codeFeatures.all,
232-
'(',
233-
')',
236+
failedExp.prefix,
237+
failedExp.suffix,
234238
);
235239
yield endOfLine;
236240
}
@@ -268,7 +272,11 @@ export function* generateElement(
268272
const endTagOffset = !node.isSelfClosing && options.template.lang === 'html'
269273
? node.loc.start.offset + node.loc.source.lastIndexOf(node.tag)
270274
: undefined;
271-
const propsFailedExps: CompilerDOM.SimpleExpressionNode[] = [];
275+
const propsFailedExps: {
276+
node: CompilerDOM.SimpleExpressionNode;
277+
prefix: string;
278+
suffix: string;
279+
}[] = [];
272280

273281
yield `__VLS_elementAsFunction(__VLS_intrinsicElements`;
274282
yield* generatePropertyAccess(
@@ -303,12 +311,12 @@ export function* generateElement(
303311
yield* generateInterpolation(
304312
options,
305313
ctx,
306-
failedExp.loc.source,
307-
failedExp.loc,
308-
failedExp.loc.start.offset,
314+
failedExp.node.loc.source,
315+
failedExp.node.loc,
316+
failedExp.node.loc.start.offset,
309317
ctx.codeFeatures.all,
310-
'(',
311-
')',
318+
failedExp.prefix,
319+
failedExp.suffix,
312320
);
313321
yield endOfLine;
314322
}

packages/language-core/lib/codegen/template/elementProps.ts

Lines changed: 24 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,11 @@ export function* generateElementProps(
1818
node: CompilerDOM.ElementNode,
1919
props: CompilerDOM.ElementNode['props'],
2020
enableCodeFeatures: boolean,
21-
propsFailedExps?: CompilerDOM.SimpleExpressionNode[],
21+
propsFailedExps?: {
22+
node: CompilerDOM.SimpleExpressionNode;
23+
prefix: string;
24+
suffix: string;
25+
}[],
2226
): Generator<Code> {
2327
const isIntrinsicElement = node.tagType === CompilerDOM.ElementTypes.ELEMENT || node.tagType === CompilerDOM.ElementTypes.TEMPLATE;
2428
const canCamelize = node.tagType === CompilerDOM.ElementTypes.COMPONENT;
@@ -44,26 +48,31 @@ export function* generateElementProps(
4448
yield `...{ '${camelize('on-' + prop.arg.loc.source)}': {} as any }, `;
4549
}
4650
}
47-
else {
48-
if (
49-
prop.arg?.type === CompilerDOM.NodeTypes.SIMPLE_EXPRESSION
50-
&& prop.arg.loc.source.startsWith('[')
51-
&& prop.arg.loc.source.endsWith(']')
52-
) {
53-
propsFailedExps?.push(prop.arg);
54-
}
55-
if (prop.exp?.type === CompilerDOM.NodeTypes.SIMPLE_EXPRESSION) {
56-
propsFailedExps?.push(prop.exp);
57-
}
51+
else if (
52+
prop.arg?.type === CompilerDOM.NodeTypes.SIMPLE_EXPRESSION
53+
&& prop.exp?.type === CompilerDOM.NodeTypes.SIMPLE_EXPRESSION
54+
&& prop.arg.loc.source.startsWith('[')
55+
&& prop.arg.loc.source.endsWith(']')
56+
) {
57+
propsFailedExps?.push({ node: prop.arg, prefix: '(', suffix: ')' });
58+
propsFailedExps?.push({ node: prop.exp, prefix: '() => {', suffix: '}' });
59+
}
60+
else if (
61+
!prop.arg
62+
&& prop.exp?.type === CompilerDOM.NodeTypes.SIMPLE_EXPRESSION
63+
) {
64+
propsFailedExps?.push({ node: prop.exp, prefix: '(', suffix: ')' });
5865
}
5966
}
6067
}
6168

6269
for (const prop of props) {
6370
if (
6471
prop.type === CompilerDOM.NodeTypes.DIRECTIVE
65-
&& (prop.name === 'bind' || prop.name === 'model')
66-
&& (prop.name === 'model' || prop.arg?.type === CompilerDOM.NodeTypes.SIMPLE_EXPRESSION)
72+
&& (
73+
(prop.name === 'bind' && prop.arg?.type === CompilerDOM.NodeTypes.SIMPLE_EXPRESSION)
74+
|| prop.name === 'model'
75+
)
6776
&& (!prop.exp || prop.exp.type === CompilerDOM.NodeTypes.SIMPLE_EXPRESSION)
6877
) {
6978
let propName: string | undefined;
@@ -82,7 +91,7 @@ export function* generateElementProps(
8291
|| options.vueCompilerOptions.dataAttributes.some(pattern => minimatch(propName!, pattern))
8392
) {
8493
if (prop.exp && prop.exp.constType !== CompilerDOM.ConstantTypes.CAN_STRINGIFY) {
85-
propsFailedExps?.push(prop.exp);
94+
propsFailedExps?.push({ node: prop.exp, prefix: '(', suffix: ')' });
8695
}
8796
continue;
8897
}
Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
<template>
2+
<div @['click']="{
3+
isActive = false;
4+
frame = 0;
5+
}" />
6+
</template>
7+
8+
<script lang="ts" setup>
9+
let isActive = false;
10+
let frame = 0;
11+
</script>

0 commit comments

Comments
 (0)