Skip to content

Commit e2febf0

Browse files
authored
refactor(language-core): simplify current component info passing (#5078)
1 parent b026d64 commit e2febf0

File tree

8 files changed

+51
-57
lines changed

8 files changed

+51
-57
lines changed

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

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -117,7 +117,6 @@ export function createTemplateCodegenContext(options: Pick<TemplateCodegenOption
117117
}[] = [];
118118
const hasSlotElements = new Set<CompilerDOM.ElementNode>();;
119119
const blockConditions: string[] = [];
120-
const usedComponentCtxVars = new Set<string>();
121120
const scopedClasses: {
122121
source: string;
123122
className: string;
@@ -137,14 +136,18 @@ export function createTemplateCodegenContext(options: Pick<TemplateCodegenOption
137136
lastGenericComment,
138137
hasSlotElements,
139138
blockConditions,
140-
usedComponentCtxVars,
141139
scopedClasses,
142140
emptyClassOffsets,
143141
inlayHints,
144142
hasSlot: false,
145143
bindingAttrLocs,
146144
inheritedAttrVars,
147145
templateRefs,
146+
currentComponent: undefined as {
147+
node: CompilerDOM.ElementNode;
148+
ctxVar: string;
149+
used: boolean;
150+
} | undefined,
148151
singleRootElType: undefined as string | undefined,
149152
singleRootNode: undefined as CompilerDOM.ElementNode | undefined,
150153
accessExternalVariable(name: string, offset?: number) {

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

Lines changed: 22 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -23,8 +23,7 @@ const colonReg = /:/g;
2323
export function* generateComponent(
2424
options: TemplateCodegenOptions,
2525
ctx: TemplateCodegenContext,
26-
node: CompilerDOM.ElementNode,
27-
currentComponent: CompilerDOM.ElementNode | undefined
26+
node: CompilerDOM.ElementNode
2827
): Generator<Code> {
2928
const startTagOffset = node.loc.start.offset + options.template.content.slice(node.loc.start.offset).indexOf(node.tag);
3029
const endTagOffset = !node.isSelfClosing && options.template.lang === 'html' ? node.loc.start.offset + node.loc.source.lastIndexOf(node.tag) : undefined;
@@ -43,6 +42,12 @@ export function* generateComponent(
4342
const var_defineComponentCtx = ctx.getInternalVariable();
4443
const isComponentTag = node.tag.toLowerCase() === 'component';
4544

45+
ctx.currentComponent = {
46+
node,
47+
ctxVar: var_defineComponentCtx,
48+
used: false
49+
};
50+
4651
let props = node.props;
4752
let dynamicTagInfo: {
4853
tag: string;
@@ -231,16 +236,14 @@ export function* generateComponent(
231236
);
232237
yield `, ...__VLS_functionalComponentArgsRest(${var_functionalComponent}))${endOfLine}`;
233238

234-
currentComponent = node;
235-
236239
yield* generateFailedPropExps(options, ctx, failedPropExps);
237240

238241
const [refName, offset] = yield* generateVScope(options, ctx, node, props);
239242
const isRootNode = node === ctx.singleRootNode;
240243

241244
if (refName || isRootNode) {
242245
const varName = ctx.getInternalVariable();
243-
ctx.usedComponentCtxVars.add(var_defineComponentCtx);
246+
ctx.currentComponent.used = true;
244247

245248
yield `var ${varName} = {} as (Parameters<NonNullable<typeof ${var_defineComponentCtx}['expose']>>[0] | null)`;
246249
if (node.codegenNode?.type === CompilerDOM.NodeTypes.VNODE_CALL
@@ -261,7 +264,7 @@ export function* generateComponent(
261264

262265
const usedComponentEventsVar = yield* generateElementEvents(options, ctx, node, var_functionalComponent, var_componentInstance, var_componentEvents);
263266
if (usedComponentEventsVar) {
264-
ctx.usedComponentCtxVars.add(var_defineComponentCtx);
267+
ctx.currentComponent.used = true;
265268
yield `let ${var_componentEmit}!: typeof ${var_defineComponentCtx}.emit${endOfLine}`;
266269
yield `let ${var_componentEvents}!: __VLS_NormalizeEmits<typeof ${var_componentEmit}>${endOfLine}`;
267270
}
@@ -280,13 +283,13 @@ export function* generateComponent(
280283

281284
const slotDir = node.props.find(p => p.type === CompilerDOM.NodeTypes.DIRECTIVE && p.name === 'slot') as CompilerDOM.DirectiveNode;
282285
if (slotDir) {
283-
yield* generateComponentSlot(options, ctx, node, slotDir, currentComponent, var_defineComponentCtx);
286+
yield* generateComponentSlot(options, ctx, node, slotDir);
284287
}
285288
else {
286-
yield* generateElementChildren(options, ctx, node, currentComponent, var_defineComponentCtx);
289+
yield* generateElementChildren(options, ctx, node);
287290
}
288291

289-
if (ctx.usedComponentCtxVars.has(var_defineComponentCtx)) {
292+
if (ctx.currentComponent.used) {
290293
yield `var ${var_defineComponentCtx}!: __VLS_PickFunctionalComponentCtx<typeof ${var_originalComponent}, typeof ${var_componentInstance}>${endOfLine}`;
291294
}
292295
}
@@ -295,8 +298,6 @@ export function* generateElement(
295298
options: TemplateCodegenOptions,
296299
ctx: TemplateCodegenContext,
297300
node: CompilerDOM.ElementNode,
298-
currentComponent: CompilerDOM.ElementNode | undefined,
299-
componentCtxVar: string | undefined,
300301
isVForChild: boolean
301302
): Generator<Code> {
302303
const startTagOffset = node.loc.start.offset + options.template.content.slice(node.loc.start.offset).indexOf(node.tag);
@@ -349,11 +350,11 @@ export function* generateElement(
349350
}
350351

351352
const slotDir = node.props.find(p => p.type === CompilerDOM.NodeTypes.DIRECTIVE && p.name === 'slot') as CompilerDOM.DirectiveNode;
352-
if (slotDir && componentCtxVar) {
353-
yield* generateComponentSlot(options, ctx, node, slotDir, currentComponent, componentCtxVar);
353+
if (slotDir && ctx.currentComponent) {
354+
yield* generateComponentSlot(options, ctx, node, slotDir);
354355
}
355356
else {
356-
yield* generateElementChildren(options, ctx, node, currentComponent, componentCtxVar);
357+
yield* generateElementChildren(options, ctx, node);
357358
}
358359

359360
if (
@@ -486,14 +487,12 @@ function* generateComponentSlot(
486487
options: TemplateCodegenOptions,
487488
ctx: TemplateCodegenContext,
488489
node: CompilerDOM.ElementNode,
489-
slotDir: CompilerDOM.DirectiveNode,
490-
currentComponent: CompilerDOM.ElementNode | undefined,
491-
componentCtxVar: string
490+
slotDir: CompilerDOM.DirectiveNode
492491
): Generator<Code> {
493492
yield `{${newLine}`;
494-
ctx.usedComponentCtxVars.add(componentCtxVar);
495-
if (currentComponent) {
496-
ctx.hasSlotElements.add(currentComponent);
493+
if (ctx.currentComponent) {
494+
ctx.currentComponent.used = true;
495+
ctx.hasSlotElements.add(ctx.currentComponent.node);
497496
}
498497
const slotBlockVars: string[] = [];
499498
yield `const {`;
@@ -517,7 +516,7 @@ function* generateComponentSlot(
517516
`default`
518517
);
519518
}
520-
yield `: __VLS_thisSlot } = ${componentCtxVar}.slots!${endOfLine}`;
519+
yield `: __VLS_thisSlot } = ${ctx.currentComponent!.ctxVar}.slots!${endOfLine}`;
521520

522521
if (slotDir?.exp?.type === CompilerDOM.NodeTypes.SIMPLE_EXPRESSION) {
523522
const slotAst = createTsAst(options.ts, slotDir, `(${slotDir.exp.content}) => {}`);
@@ -552,7 +551,7 @@ function* generateComponentSlot(
552551

553552
let prev: CompilerDOM.TemplateChildNode | undefined;
554553
for (const childNode of node.children) {
555-
yield* generateTemplateChild(options, ctx, childNode, currentComponent, prev, componentCtxVar);
554+
yield* generateTemplateChild(options, ctx, childNode, prev);
556555
prev = childNode;
557556
}
558557

@@ -564,7 +563,7 @@ function* generateComponentSlot(
564563
isStatic = slotDir.arg.isStatic;
565564
}
566565
if (isStatic && slotDir && !slotDir.arg) {
567-
yield `${componentCtxVar}.slots!['`;
566+
yield `${ctx.currentComponent!.ctxVar}.slots!['`;
568567
yield [
569568
'',
570569
'template',

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

Lines changed: 5 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -8,28 +8,26 @@ import { generateTemplateChild } from './templateChild';
88
export function* generateElementChildren(
99
options: TemplateCodegenOptions,
1010
ctx: TemplateCodegenContext,
11-
node: CompilerDOM.ElementNode,
12-
currentComponent: CompilerDOM.ElementNode | undefined,
13-
componentCtxVar: string | undefined
11+
node: CompilerDOM.ElementNode
1412
): Generator<Code> {
1513
yield* ctx.resetDirectiveComments('end of element children start');
1614
let prev: CompilerDOM.TemplateChildNode | undefined;
1715
for (const childNode of node.children) {
18-
yield* generateTemplateChild(options, ctx, childNode, currentComponent, prev, componentCtxVar);
16+
yield* generateTemplateChild(options, ctx, childNode, prev);
1917
prev = childNode;
2018
}
2119
yield* ctx.generateAutoImportCompletion();
2220

2321
// fix https://github.com/vuejs/language-tools/issues/932
2422
if (
25-
componentCtxVar
23+
ctx.currentComponent
2624
&& !ctx.hasSlotElements.has(node)
2725
&& node.children.length
2826
&& node.tagType !== CompilerDOM.ElementTypes.ELEMENT
2927
&& node.tagType !== CompilerDOM.ElementTypes.TEMPLATE
3028
) {
31-
ctx.usedComponentCtxVars.add(componentCtxVar);
32-
yield `${componentCtxVar}.slots!.`;
29+
ctx.currentComponent.used = true;
30+
yield `${ctx.currentComponent.ctxVar}.slots!.`;
3331
yield* wrapWith(
3432
node.children[0].loc.start.offset,
3533
node.children[node.children.length - 1].loc.end.offset,

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

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -40,7 +40,7 @@ export function* generateTemplate(options: TemplateCodegenOptions): Generator<Co
4040
ctx.addLocalVariable('$el');
4141

4242
if (options.template.ast) {
43-
yield* generateTemplateChild(options, ctx, options.template.ast, undefined, undefined, undefined);
43+
yield* generateTemplateChild(options, ctx, options.template.ast, undefined);
4444
}
4545

4646
yield* generateStyleScopedClassReferences(ctx);

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

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -11,9 +11,7 @@ import { generateInterpolation } from './interpolation';
1111
export function* generateSlotOutlet(
1212
options: TemplateCodegenOptions,
1313
ctx: TemplateCodegenContext,
14-
node: CompilerDOM.SlotOutletNode,
15-
currentComponent: CompilerDOM.ElementNode | undefined,
16-
componentCtxVar: string | undefined
14+
node: CompilerDOM.SlotOutletNode
1715
): Generator<Code> {
1816
const startTagOffset = node.loc.start.offset + options.template.content.slice(node.loc.start.offset).indexOf(node.tag);
1917
const varSlot = ctx.getInternalVariable();
@@ -114,5 +112,5 @@ export function* generateSlotOutlet(
114112
}
115113
}
116114
yield* ctx.generateAutoImportCompletion();
117-
yield* generateElementChildren(options, ctx, node, currentComponent, componentCtxVar);
115+
yield* generateElementChildren(options, ctx, node);
118116
}

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

Lines changed: 12 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -29,9 +29,7 @@ export function* generateTemplateChild(
2929
options: TemplateCodegenOptions,
3030
ctx: TemplateCodegenContext,
3131
node: CompilerDOM.RootNode | CompilerDOM.TemplateChildNode | CompilerDOM.SimpleExpressionNode,
32-
currentComponent: CompilerDOM.ElementNode | undefined,
3332
prevNode: CompilerDOM.TemplateChildNode | undefined,
34-
componentCtxVar: string | undefined,
3533
isVForChild: boolean = false
3634
): Generator<Code> {
3735
if (prevNode?.type === CompilerDOM.NodeTypes.COMMENT) {
@@ -71,7 +69,7 @@ export function* generateTemplateChild(
7169
ctx.singleRootNode = node.children[0];
7270
}
7371
for (const childNode of node.children) {
74-
yield* generateTemplateChild(options, ctx, childNode, currentComponent, prev, componentCtxVar);
72+
yield* generateTemplateChild(options, ctx, childNode, prev);
7573
prev = childNode;
7674
}
7775
yield* ctx.resetDirectiveComments('end of root');
@@ -80,35 +78,37 @@ export function* generateTemplateChild(
8078
const vForNode = getVForNode(node);
8179
const vIfNode = getVIfNode(node);
8280
if (vForNode) {
83-
yield* generateVFor(options, ctx, vForNode, currentComponent, componentCtxVar);
81+
yield* generateVFor(options, ctx, vForNode);
8482
}
8583
else if (vIfNode) {
86-
yield* generateVIf(options, ctx, vIfNode, currentComponent, componentCtxVar);
84+
yield* generateVIf(options, ctx, vIfNode);
8785
}
8886
else {
8987
if (node.tagType === CompilerDOM.ElementTypes.SLOT) {
90-
yield* generateSlotOutlet(options, ctx, node, currentComponent, componentCtxVar);
88+
yield* generateSlotOutlet(options, ctx, node);
9189
}
9290
else if (
9391
node.tagType === CompilerDOM.ElementTypes.ELEMENT
9492
|| node.tagType === CompilerDOM.ElementTypes.TEMPLATE
9593
) {
96-
yield* generateElement(options, ctx, node, currentComponent, componentCtxVar, isVForChild);
94+
yield* generateElement(options, ctx, node, isVForChild);
9795
}
9896
else {
99-
yield* generateComponent(options, ctx, node, currentComponent);
97+
const { currentComponent } = ctx;
98+
yield* generateComponent(options, ctx, node);
99+
ctx.currentComponent = currentComponent;
100100
}
101101
}
102102
}
103103
else if (node.type === CompilerDOM.NodeTypes.TEXT_CALL) {
104104
// {{ var }}
105-
yield* generateTemplateChild(options, ctx, node.content, currentComponent, undefined, componentCtxVar);
105+
yield* generateTemplateChild(options, ctx, node.content, undefined);
106106
}
107107
else if (node.type === CompilerDOM.NodeTypes.COMPOUND_EXPRESSION) {
108108
// {{ ... }} {{ ... }}
109109
for (const childNode of node.children) {
110110
if (typeof childNode === 'object') {
111-
yield* generateTemplateChild(options, ctx, childNode, currentComponent, undefined, componentCtxVar);
111+
yield* generateTemplateChild(options, ctx, childNode, undefined);
112112
}
113113
}
114114
}
@@ -130,11 +130,11 @@ export function* generateTemplateChild(
130130
}
131131
else if (node.type === CompilerDOM.NodeTypes.IF) {
132132
// v-if / v-else-if / v-else
133-
yield* generateVIf(options, ctx, node, currentComponent, componentCtxVar);
133+
yield* generateVIf(options, ctx, node);
134134
}
135135
else if (node.type === CompilerDOM.NodeTypes.FOR) {
136136
// v-for
137-
yield* generateVFor(options, ctx, node, currentComponent, componentCtxVar);
137+
yield* generateVFor(options, ctx, node);
138138
}
139139
else if (node.type === CompilerDOM.NodeTypes.TEXT) {
140140
// not needed progress

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

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -9,9 +9,7 @@ import { generateTemplateChild } from './templateChild';
99
export function* generateVFor(
1010
options: TemplateCodegenOptions,
1111
ctx: TemplateCodegenContext,
12-
node: CompilerDOM.ForNode,
13-
currentComponent: CompilerDOM.ElementNode | undefined,
14-
componentCtxVar: string | undefined
12+
node: CompilerDOM.ForNode
1513
): Generator<Code> {
1614
const { source } = node.parseResult;
1715
const { leftExpressionRange, leftExpressionText } = parseVForNode(node);
@@ -88,7 +86,7 @@ export function* generateVFor(
8886
}
8987
let prev: CompilerDOM.TemplateChildNode | undefined;
9088
for (const childNode of node.children) {
91-
yield* generateTemplateChild(options, ctx, childNode, currentComponent, prev, componentCtxVar, true);
89+
yield* generateTemplateChild(options, ctx, childNode, prev, true);
9290
prev = childNode;
9391
}
9492
for (const varName of forBlockVars) {

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

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -10,9 +10,7 @@ import { generateTemplateChild } from './templateChild';
1010
export function* generateVIf(
1111
options: TemplateCodegenOptions,
1212
ctx: TemplateCodegenContext,
13-
node: CompilerDOM.IfNode,
14-
currentComponent: CompilerDOM.ElementNode | undefined,
15-
componentCtxVar: string | undefined
13+
node: CompilerDOM.IfNode
1614
): Generator<Code> {
1715

1816
let originalBlockConditionsLength = ctx.blockConditions.length;
@@ -61,7 +59,7 @@ export function* generateVIf(
6159
}
6260
let prev: CompilerDOM.TemplateChildNode | undefined;
6361
for (const childNode of branch.children) {
64-
yield* generateTemplateChild(options, ctx, childNode, currentComponent, prev, componentCtxVar);
62+
yield* generateTemplateChild(options, ctx, childNode, prev);
6563
prev = childNode;
6664
}
6765
yield* ctx.generateAutoImportCompletion();

0 commit comments

Comments
 (0)