Skip to content

Commit

Permalink
fix(language-core): inline dynamic event handlers should not expect c…
Browse files Browse the repository at this point in the history
…ommas

Refs #4387 (comment)
  • Loading branch information
johnsoncodehk committed May 16, 2024
1 parent edb85ed commit 75fd6d2
Show file tree
Hide file tree
Showing 3 changed files with 55 additions and 27 deletions.
32 changes: 20 additions & 12 deletions packages/language-core/lib/codegen/template/element.ts
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,11 @@ export function* generateComponent(
const tagOffsets = endTagOffset !== undefined
? [startTagOffset, endTagOffset]
: [startTagOffset];
const propsFailedExps: CompilerDOM.SimpleExpressionNode[] = [];
const propsFailedExps: {
node: CompilerDOM.SimpleExpressionNode;
prefix: string;
suffix: string;
}[] = [];
const possibleOriginalNames = getPossibleOriginalComponentNames(node.tag, true);
const matchImportName = possibleOriginalNames.find(name => options.scriptSetupImportComponentNames.has(name));
const var_originalComponent = matchImportName ?? ctx.getInternalVariable();
Expand Down Expand Up @@ -225,12 +229,12 @@ export function* generateComponent(
yield* generateInterpolation(
options,
ctx,
failedExp.loc.source,
failedExp.loc,
failedExp.loc.start.offset,
failedExp.node.loc.source,
failedExp.node.loc,
failedExp.node.loc.start.offset,
ctx.codeFeatures.all,
'(',
')',
failedExp.prefix,
failedExp.suffix,
);
yield endOfLine;
}
Expand Down Expand Up @@ -268,7 +272,11 @@ export function* generateElement(
const endTagOffset = !node.isSelfClosing && options.template.lang === 'html'
? node.loc.start.offset + node.loc.source.lastIndexOf(node.tag)
: undefined;
const propsFailedExps: CompilerDOM.SimpleExpressionNode[] = [];
const propsFailedExps: {
node: CompilerDOM.SimpleExpressionNode;
prefix: string;
suffix: string;
}[] = [];

yield `__VLS_elementAsFunction(__VLS_intrinsicElements`;
yield* generatePropertyAccess(
Expand Down Expand Up @@ -303,12 +311,12 @@ export function* generateElement(
yield* generateInterpolation(
options,
ctx,
failedExp.loc.source,
failedExp.loc,
failedExp.loc.start.offset,
failedExp.node.loc.source,
failedExp.node.loc,
failedExp.node.loc.start.offset,
ctx.codeFeatures.all,
'(',
')',
failedExp.prefix,
failedExp.suffix,
);
yield endOfLine;
}
Expand Down
39 changes: 24 additions & 15 deletions packages/language-core/lib/codegen/template/elementProps.ts
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,11 @@ export function* generateElementProps(
node: CompilerDOM.ElementNode,
props: CompilerDOM.ElementNode['props'],
enableCodeFeatures: boolean,
propsFailedExps?: CompilerDOM.SimpleExpressionNode[],
propsFailedExps?: {
node: CompilerDOM.SimpleExpressionNode;
prefix: string;
suffix: string;
}[],
): Generator<Code> {
const isIntrinsicElement = node.tagType === CompilerDOM.ElementTypes.ELEMENT || node.tagType === CompilerDOM.ElementTypes.TEMPLATE;
const canCamelize = node.tagType === CompilerDOM.ElementTypes.COMPONENT;
Expand All @@ -44,26 +48,31 @@ export function* generateElementProps(
yield `...{ '${camelize('on-' + prop.arg.loc.source)}': {} as any }, `;
}
}
else {
if (
prop.arg?.type === CompilerDOM.NodeTypes.SIMPLE_EXPRESSION
&& prop.arg.loc.source.startsWith('[')
&& prop.arg.loc.source.endsWith(']')
) {
propsFailedExps?.push(prop.arg);
}
if (prop.exp?.type === CompilerDOM.NodeTypes.SIMPLE_EXPRESSION) {
propsFailedExps?.push(prop.exp);
}
else if (
prop.arg?.type === CompilerDOM.NodeTypes.SIMPLE_EXPRESSION
&& prop.exp?.type === CompilerDOM.NodeTypes.SIMPLE_EXPRESSION
&& prop.arg.loc.source.startsWith('[')
&& prop.arg.loc.source.endsWith(']')
) {
propsFailedExps?.push({ node: prop.arg, prefix: '(', suffix: ')' });
propsFailedExps?.push({ node: prop.exp, prefix: '() => {', suffix: '}' });
}
else if (
!prop.arg
&& prop.exp?.type === CompilerDOM.NodeTypes.SIMPLE_EXPRESSION
) {
propsFailedExps?.push({ node: prop.exp, prefix: '(', suffix: ')' });
}
}
}

for (const prop of props) {
if (
prop.type === CompilerDOM.NodeTypes.DIRECTIVE
&& (prop.name === 'bind' || prop.name === 'model')
&& (prop.name === 'model' || prop.arg?.type === CompilerDOM.NodeTypes.SIMPLE_EXPRESSION)
&& (
(prop.name === 'bind' && prop.arg?.type === CompilerDOM.NodeTypes.SIMPLE_EXPRESSION)
|| prop.name === 'model'
)
&& (!prop.exp || prop.exp.type === CompilerDOM.NodeTypes.SIMPLE_EXPRESSION)
) {
let propName: string | undefined;
Expand All @@ -82,7 +91,7 @@ export function* generateElementProps(
|| options.vueCompilerOptions.dataAttributes.some(pattern => minimatch(propName!, pattern))
) {
if (prop.exp && prop.exp.constType !== CompilerDOM.ConstantTypes.CAN_STRINGIFY) {
propsFailedExps?.push(prop.exp);
propsFailedExps?.push({ node: prop.exp, prefix: '(', suffix: ')' });
}
continue;
}
Expand Down
11 changes: 11 additions & 0 deletions test-workspace/tsc/vue3/#4387/comment-2113645943.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
<template>
<div @['click']="{
isActive = false;
frame = 0;
}" />
</template>

<script lang="ts" setup>
let isActive = false;
let frame = 0;
</script>

0 comments on commit 75fd6d2

Please sign in to comment.