Skip to content

Commit

Permalink
refactor(language-core): simplify current component info passing (#5078)
Browse files Browse the repository at this point in the history
  • Loading branch information
KazariEX authored Dec 23, 2024
1 parent b026d64 commit e2febf0
Show file tree
Hide file tree
Showing 8 changed files with 51 additions and 57 deletions.
7 changes: 5 additions & 2 deletions packages/language-core/lib/codegen/template/context.ts
Original file line number Diff line number Diff line change
Expand Up @@ -117,7 +117,6 @@ export function createTemplateCodegenContext(options: Pick<TemplateCodegenOption
}[] = [];
const hasSlotElements = new Set<CompilerDOM.ElementNode>();;
const blockConditions: string[] = [];
const usedComponentCtxVars = new Set<string>();
const scopedClasses: {
source: string;
className: string;
Expand All @@ -137,14 +136,18 @@ export function createTemplateCodegenContext(options: Pick<TemplateCodegenOption
lastGenericComment,
hasSlotElements,
blockConditions,
usedComponentCtxVars,
scopedClasses,
emptyClassOffsets,
inlayHints,
hasSlot: false,
bindingAttrLocs,
inheritedAttrVars,
templateRefs,
currentComponent: undefined as {
node: CompilerDOM.ElementNode;
ctxVar: string;
used: boolean;
} | undefined,
singleRootElType: undefined as string | undefined,
singleRootNode: undefined as CompilerDOM.ElementNode | undefined,
accessExternalVariable(name: string, offset?: number) {
Expand Down
45 changes: 22 additions & 23 deletions packages/language-core/lib/codegen/template/element.ts
Original file line number Diff line number Diff line change
Expand Up @@ -23,8 +23,7 @@ const colonReg = /:/g;
export function* generateComponent(
options: TemplateCodegenOptions,
ctx: TemplateCodegenContext,
node: CompilerDOM.ElementNode,
currentComponent: CompilerDOM.ElementNode | undefined
node: CompilerDOM.ElementNode
): Generator<Code> {
const startTagOffset = node.loc.start.offset + options.template.content.slice(node.loc.start.offset).indexOf(node.tag);
const endTagOffset = !node.isSelfClosing && options.template.lang === 'html' ? node.loc.start.offset + node.loc.source.lastIndexOf(node.tag) : undefined;
Expand All @@ -43,6 +42,12 @@ export function* generateComponent(
const var_defineComponentCtx = ctx.getInternalVariable();
const isComponentTag = node.tag.toLowerCase() === 'component';

ctx.currentComponent = {
node,
ctxVar: var_defineComponentCtx,
used: false
};

let props = node.props;
let dynamicTagInfo: {
tag: string;
Expand Down Expand Up @@ -231,16 +236,14 @@ export function* generateComponent(
);
yield `, ...__VLS_functionalComponentArgsRest(${var_functionalComponent}))${endOfLine}`;

currentComponent = node;

yield* generateFailedPropExps(options, ctx, failedPropExps);

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

if (refName || isRootNode) {
const varName = ctx.getInternalVariable();
ctx.usedComponentCtxVars.add(var_defineComponentCtx);
ctx.currentComponent.used = true;

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

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

const slotDir = node.props.find(p => p.type === CompilerDOM.NodeTypes.DIRECTIVE && p.name === 'slot') as CompilerDOM.DirectiveNode;
if (slotDir) {
yield* generateComponentSlot(options, ctx, node, slotDir, currentComponent, var_defineComponentCtx);
yield* generateComponentSlot(options, ctx, node, slotDir);
}
else {
yield* generateElementChildren(options, ctx, node, currentComponent, var_defineComponentCtx);
yield* generateElementChildren(options, ctx, node);
}

if (ctx.usedComponentCtxVars.has(var_defineComponentCtx)) {
if (ctx.currentComponent.used) {
yield `var ${var_defineComponentCtx}!: __VLS_PickFunctionalComponentCtx<typeof ${var_originalComponent}, typeof ${var_componentInstance}>${endOfLine}`;
}
}
Expand All @@ -295,8 +298,6 @@ export function* generateElement(
options: TemplateCodegenOptions,
ctx: TemplateCodegenContext,
node: CompilerDOM.ElementNode,
currentComponent: CompilerDOM.ElementNode | undefined,
componentCtxVar: string | undefined,
isVForChild: boolean
): Generator<Code> {
const startTagOffset = node.loc.start.offset + options.template.content.slice(node.loc.start.offset).indexOf(node.tag);
Expand Down Expand Up @@ -349,11 +350,11 @@ export function* generateElement(
}

const slotDir = node.props.find(p => p.type === CompilerDOM.NodeTypes.DIRECTIVE && p.name === 'slot') as CompilerDOM.DirectiveNode;
if (slotDir && componentCtxVar) {
yield* generateComponentSlot(options, ctx, node, slotDir, currentComponent, componentCtxVar);
if (slotDir && ctx.currentComponent) {
yield* generateComponentSlot(options, ctx, node, slotDir);
}
else {
yield* generateElementChildren(options, ctx, node, currentComponent, componentCtxVar);
yield* generateElementChildren(options, ctx, node);
}

if (
Expand Down Expand Up @@ -486,14 +487,12 @@ function* generateComponentSlot(
options: TemplateCodegenOptions,
ctx: TemplateCodegenContext,
node: CompilerDOM.ElementNode,
slotDir: CompilerDOM.DirectiveNode,
currentComponent: CompilerDOM.ElementNode | undefined,
componentCtxVar: string
slotDir: CompilerDOM.DirectiveNode
): Generator<Code> {
yield `{${newLine}`;
ctx.usedComponentCtxVars.add(componentCtxVar);
if (currentComponent) {
ctx.hasSlotElements.add(currentComponent);
if (ctx.currentComponent) {
ctx.currentComponent.used = true;
ctx.hasSlotElements.add(ctx.currentComponent.node);
}
const slotBlockVars: string[] = [];
yield `const {`;
Expand All @@ -517,7 +516,7 @@ function* generateComponentSlot(
`default`
);
}
yield `: __VLS_thisSlot } = ${componentCtxVar}.slots!${endOfLine}`;
yield `: __VLS_thisSlot } = ${ctx.currentComponent!.ctxVar}.slots!${endOfLine}`;

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

let prev: CompilerDOM.TemplateChildNode | undefined;
for (const childNode of node.children) {
yield* generateTemplateChild(options, ctx, childNode, currentComponent, prev, componentCtxVar);
yield* generateTemplateChild(options, ctx, childNode, prev);
prev = childNode;
}

Expand All @@ -564,7 +563,7 @@ function* generateComponentSlot(
isStatic = slotDir.arg.isStatic;
}
if (isStatic && slotDir && !slotDir.arg) {
yield `${componentCtxVar}.slots!['`;
yield `${ctx.currentComponent!.ctxVar}.slots!['`;
yield [
'',
'template',
Expand Down
12 changes: 5 additions & 7 deletions packages/language-core/lib/codegen/template/elementChildren.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,28 +8,26 @@ import { generateTemplateChild } from './templateChild';
export function* generateElementChildren(
options: TemplateCodegenOptions,
ctx: TemplateCodegenContext,
node: CompilerDOM.ElementNode,
currentComponent: CompilerDOM.ElementNode | undefined,
componentCtxVar: string | undefined
node: CompilerDOM.ElementNode
): Generator<Code> {
yield* ctx.resetDirectiveComments('end of element children start');
let prev: CompilerDOM.TemplateChildNode | undefined;
for (const childNode of node.children) {
yield* generateTemplateChild(options, ctx, childNode, currentComponent, prev, componentCtxVar);
yield* generateTemplateChild(options, ctx, childNode, prev);
prev = childNode;
}
yield* ctx.generateAutoImportCompletion();

// fix https://github.com/vuejs/language-tools/issues/932
if (
componentCtxVar
ctx.currentComponent
&& !ctx.hasSlotElements.has(node)
&& node.children.length
&& node.tagType !== CompilerDOM.ElementTypes.ELEMENT
&& node.tagType !== CompilerDOM.ElementTypes.TEMPLATE
) {
ctx.usedComponentCtxVars.add(componentCtxVar);
yield `${componentCtxVar}.slots!.`;
ctx.currentComponent.used = true;
yield `${ctx.currentComponent.ctxVar}.slots!.`;
yield* wrapWith(
node.children[0].loc.start.offset,
node.children[node.children.length - 1].loc.end.offset,
Expand Down
2 changes: 1 addition & 1 deletion packages/language-core/lib/codegen/template/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@ export function* generateTemplate(options: TemplateCodegenOptions): Generator<Co
ctx.addLocalVariable('$el');

if (options.template.ast) {
yield* generateTemplateChild(options, ctx, options.template.ast, undefined, undefined, undefined);
yield* generateTemplateChild(options, ctx, options.template.ast, undefined);
}

yield* generateStyleScopedClassReferences(ctx);
Expand Down
6 changes: 2 additions & 4 deletions packages/language-core/lib/codegen/template/slotOutlet.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,9 +11,7 @@ import { generateInterpolation } from './interpolation';
export function* generateSlotOutlet(
options: TemplateCodegenOptions,
ctx: TemplateCodegenContext,
node: CompilerDOM.SlotOutletNode,
currentComponent: CompilerDOM.ElementNode | undefined,
componentCtxVar: string | undefined
node: CompilerDOM.SlotOutletNode
): Generator<Code> {
const startTagOffset = node.loc.start.offset + options.template.content.slice(node.loc.start.offset).indexOf(node.tag);
const varSlot = ctx.getInternalVariable();
Expand Down Expand Up @@ -114,5 +112,5 @@ export function* generateSlotOutlet(
}
}
yield* ctx.generateAutoImportCompletion();
yield* generateElementChildren(options, ctx, node, currentComponent, componentCtxVar);
yield* generateElementChildren(options, ctx, node);
}
24 changes: 12 additions & 12 deletions packages/language-core/lib/codegen/template/templateChild.ts
Original file line number Diff line number Diff line change
Expand Up @@ -29,9 +29,7 @@ export function* generateTemplateChild(
options: TemplateCodegenOptions,
ctx: TemplateCodegenContext,
node: CompilerDOM.RootNode | CompilerDOM.TemplateChildNode | CompilerDOM.SimpleExpressionNode,
currentComponent: CompilerDOM.ElementNode | undefined,
prevNode: CompilerDOM.TemplateChildNode | undefined,
componentCtxVar: string | undefined,
isVForChild: boolean = false
): Generator<Code> {
if (prevNode?.type === CompilerDOM.NodeTypes.COMMENT) {
Expand Down Expand Up @@ -71,7 +69,7 @@ export function* generateTemplateChild(
ctx.singleRootNode = node.children[0];
}
for (const childNode of node.children) {
yield* generateTemplateChild(options, ctx, childNode, currentComponent, prev, componentCtxVar);
yield* generateTemplateChild(options, ctx, childNode, prev);
prev = childNode;
}
yield* ctx.resetDirectiveComments('end of root');
Expand All @@ -80,35 +78,37 @@ export function* generateTemplateChild(
const vForNode = getVForNode(node);
const vIfNode = getVIfNode(node);
if (vForNode) {
yield* generateVFor(options, ctx, vForNode, currentComponent, componentCtxVar);
yield* generateVFor(options, ctx, vForNode);
}
else if (vIfNode) {
yield* generateVIf(options, ctx, vIfNode, currentComponent, componentCtxVar);
yield* generateVIf(options, ctx, vIfNode);
}
else {
if (node.tagType === CompilerDOM.ElementTypes.SLOT) {
yield* generateSlotOutlet(options, ctx, node, currentComponent, componentCtxVar);
yield* generateSlotOutlet(options, ctx, node);
}
else if (
node.tagType === CompilerDOM.ElementTypes.ELEMENT
|| node.tagType === CompilerDOM.ElementTypes.TEMPLATE
) {
yield* generateElement(options, ctx, node, currentComponent, componentCtxVar, isVForChild);
yield* generateElement(options, ctx, node, isVForChild);
}
else {
yield* generateComponent(options, ctx, node, currentComponent);
const { currentComponent } = ctx;
yield* generateComponent(options, ctx, node);
ctx.currentComponent = currentComponent;
}
}
}
else if (node.type === CompilerDOM.NodeTypes.TEXT_CALL) {
// {{ var }}
yield* generateTemplateChild(options, ctx, node.content, currentComponent, undefined, componentCtxVar);
yield* generateTemplateChild(options, ctx, node.content, undefined);
}
else if (node.type === CompilerDOM.NodeTypes.COMPOUND_EXPRESSION) {
// {{ ... }} {{ ... }}
for (const childNode of node.children) {
if (typeof childNode === 'object') {
yield* generateTemplateChild(options, ctx, childNode, currentComponent, undefined, componentCtxVar);
yield* generateTemplateChild(options, ctx, childNode, undefined);
}
}
}
Expand All @@ -130,11 +130,11 @@ export function* generateTemplateChild(
}
else if (node.type === CompilerDOM.NodeTypes.IF) {
// v-if / v-else-if / v-else
yield* generateVIf(options, ctx, node, currentComponent, componentCtxVar);
yield* generateVIf(options, ctx, node);
}
else if (node.type === CompilerDOM.NodeTypes.FOR) {
// v-for
yield* generateVFor(options, ctx, node, currentComponent, componentCtxVar);
yield* generateVFor(options, ctx, node);
}
else if (node.type === CompilerDOM.NodeTypes.TEXT) {
// not needed progress
Expand Down
6 changes: 2 additions & 4 deletions packages/language-core/lib/codegen/template/vFor.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,9 +9,7 @@ import { generateTemplateChild } from './templateChild';
export function* generateVFor(
options: TemplateCodegenOptions,
ctx: TemplateCodegenContext,
node: CompilerDOM.ForNode,
currentComponent: CompilerDOM.ElementNode | undefined,
componentCtxVar: string | undefined
node: CompilerDOM.ForNode
): Generator<Code> {
const { source } = node.parseResult;
const { leftExpressionRange, leftExpressionText } = parseVForNode(node);
Expand Down Expand Up @@ -88,7 +86,7 @@ export function* generateVFor(
}
let prev: CompilerDOM.TemplateChildNode | undefined;
for (const childNode of node.children) {
yield* generateTemplateChild(options, ctx, childNode, currentComponent, prev, componentCtxVar, true);
yield* generateTemplateChild(options, ctx, childNode, prev, true);
prev = childNode;
}
for (const varName of forBlockVars) {
Expand Down
6 changes: 2 additions & 4 deletions packages/language-core/lib/codegen/template/vIf.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,9 +10,7 @@ import { generateTemplateChild } from './templateChild';
export function* generateVIf(
options: TemplateCodegenOptions,
ctx: TemplateCodegenContext,
node: CompilerDOM.IfNode,
currentComponent: CompilerDOM.ElementNode | undefined,
componentCtxVar: string | undefined
node: CompilerDOM.IfNode
): Generator<Code> {

let originalBlockConditionsLength = ctx.blockConditions.length;
Expand Down Expand Up @@ -61,7 +59,7 @@ export function* generateVIf(
}
let prev: CompilerDOM.TemplateChildNode | undefined;
for (const childNode of branch.children) {
yield* generateTemplateChild(options, ctx, childNode, currentComponent, prev, componentCtxVar);
yield* generateTemplateChild(options, ctx, childNode, prev);
prev = childNode;
}
yield* ctx.generateAutoImportCompletion();
Expand Down

0 comments on commit e2febf0

Please sign in to comment.