Skip to content

Commit 7c16dca

Browse files
committed
fix: make directive transforms work
1 parent fa5cdcd commit 7c16dca

File tree

5 files changed

+59
-3
lines changed

5 files changed

+59
-3
lines changed

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

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -206,7 +206,7 @@ function* generateBindings(
206206
}
207207

208208
const usageVars = new Set([
209-
...options.templateCodegen?.components.flatMap(c => [camelize(c), capitalize(camelize(c))]) ?? [],
209+
...options.sfc.template?.ast?.components.flatMap(c => [camelize(c), capitalize(camelize(c))]) ?? [],
210210
...options.templateCodegen?.accessExternalVariables.keys() ?? [],
211211
...templateCodegenCtx.accessExternalVariables.keys(),
212212
]);

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

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -211,7 +211,6 @@ export function createTemplateCodegenContext(
211211
bindingAttrLocs,
212212
inheritedAttrVars,
213213
templateRefs,
214-
components: [] as string[],
215214
currentComponent: undefined as {
216215
get ctxVar(): string;
217216
get propsVar(): string;

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

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -39,7 +39,6 @@ export function* generateComponent(
3939

4040
let isCtxVarUsed = false;
4141
let isPropsVarUsed = false;
42-
ctx.components.push(node.tag);
4342
ctx.currentComponent = {
4443
get ctxVar() {
4544
isCtxVarUsed = true;

packages/language-core/lib/template/compile.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
import { type CompilerOptions, getBaseTransformPreset, parse, transform } from '@vue/compiler-dom';
2+
import { transformElement } from './transforms/transformElement';
23
import { transformText } from './transforms/transformText';
34
import { transformFor } from './transforms/vFor';
45
import { transformIf } from './transforms/vIf';
@@ -12,6 +13,7 @@ export function compileTemplate(source: string, options: CompilerOptions) {
1213
nodeTransforms[0]!, // transformVBindShorthand
1314
transformIf,
1415
transformFor,
16+
transformElement,
1517
transformText,
1618
...options.nodeTransforms || [],
1719
],
Lines changed: 56 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,56 @@
1+
import { createCompilerError, ElementTypes, ErrorCodes, type NodeTransform, NodeTypes } from '@vue/compiler-dom';
2+
import { isBuiltInDirective } from '@vue/shared';
3+
4+
export const transformElement: NodeTransform = (node, context) => {
5+
return () => {
6+
if (node.type !== NodeTypes.ELEMENT || node.tagType === ElementTypes.TEMPLATE) {
7+
return;
8+
}
9+
10+
const isComponent = node.tagType === ElementTypes.COMPONENT;
11+
const isSlotOutlet = node.tagType === ElementTypes.SLOT;
12+
13+
if (isComponent) {
14+
context.components.add(node.tag);
15+
}
16+
17+
for (const prop of node.props) {
18+
if (prop.type !== NodeTypes.DIRECTIVE) {
19+
continue;
20+
}
21+
22+
if (prop.name === 'slot') {
23+
if (!isComponent) {
24+
context.onError(
25+
createCompilerError(ErrorCodes.X_V_SLOT_MISPLACED, prop.loc),
26+
);
27+
}
28+
continue;
29+
}
30+
31+
const isVBind = prop.name === 'bind';
32+
const isVOn = prop.name === 'on';
33+
34+
if (!prop.arg && (isVBind || isVOn)) {
35+
if (!prop.exp) {
36+
context.onError(
37+
createCompilerError(
38+
isVBind
39+
? ErrorCodes.X_V_BIND_NO_EXPRESSION
40+
: ErrorCodes.X_V_ON_NO_EXPRESSION,
41+
prop.loc,
42+
),
43+
);
44+
}
45+
continue;
46+
}
47+
48+
const result = context.directiveTransforms[prop.name]?.(prop, node, context);
49+
if (isSlotOutlet && (result?.needRuntime || !isBuiltInDirective(prop.name))) {
50+
context.onError(
51+
createCompilerError(ErrorCodes.X_V_SLOT_UNEXPECTED_DIRECTIVE_ON_SLOT_OUTLET, prop.loc),
52+
);
53+
}
54+
}
55+
};
56+
};

0 commit comments

Comments
 (0)