Skip to content

Commit 13924d1

Browse files
refactor(language-core): do not wrap template virtual code with function (#4731)
1 parent 5936c82 commit 13924d1

File tree

8 files changed

+130
-137
lines changed

8 files changed

+130
-137
lines changed

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

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -142,7 +142,7 @@ export function* generatePropsOption(
142142
optionExpCodes.push(generateSfcBlockSection(scriptSetup, arg.start, arg.end, codeFeatures.navigation));
143143
}
144144
if (inheritAttrs && options.templateCodegen?.inheritedAttrVars.size) {
145-
let attrsType = `ReturnType<typeof __VLS_template>['attrs']`;
145+
let attrsType = `typeof __VLS_templateResult['attrs']`;
146146
if (hasEmitsOption) {
147147
attrsType = `Omit<${attrsType}, \`on\${string}\`>`;
148148
}

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

Lines changed: 1 addition & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -66,11 +66,7 @@ declare global {
6666
function __VLS_makeOptional<T>(t: T): { [K in keyof T]?: T[K] };
6767
function __VLS_nonNullable<T>(t: T): T extends null | undefined ? never : T;
6868
69-
type __VLS_SelfComponent<N, C> = string extends N ? {} : N extends string ? { [P in N]: C } : {};
70-
type __VLS_WithComponent<N0 extends string, Ctx, LocalComponents, N1 extends string, N2 extends string, N3 extends string> =
71-
N1 extends keyof Ctx ? N1 extends N0 ? Pick<Ctx, N0 extends keyof Ctx ? N0 : never> : { [K in N0]: Ctx[N1] } :
72-
N2 extends keyof Ctx ? N2 extends N0 ? Pick<Ctx, N0 extends keyof Ctx ? N0 : never> : { [K in N0]: Ctx[N2] } :
73-
N3 extends keyof Ctx ? N3 extends N0 ? Pick<Ctx, N0 extends keyof Ctx ? N0 : never> : { [K in N0]: Ctx[N3] } :
69+
type __VLS_WithComponent<N0 extends string, LocalComponents, N1 extends string, N2 extends string, N3 extends string> =
7470
N1 extends keyof LocalComponents ? N1 extends N0 ? Pick<LocalComponents, N0 extends keyof LocalComponents ? N0 : never> : { [K in N0]: LocalComponents[N1] } :
7571
N2 extends keyof LocalComponents ? N2 extends N0 ? Pick<LocalComponents, N0 extends keyof LocalComponents ? N0 : never> : { [K in N0]: LocalComponents[N2] } :
7672
N3 extends keyof LocalComponents ? N3 extends N0 ? Pick<LocalComponents, N0 extends keyof LocalComponents ? N0 : never> : { [K in N0]: LocalComponents[N3] } :

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

Lines changed: 12 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -101,9 +101,16 @@ export function* generateScript(options: ScriptCodegenOptions): Generator<Code,
101101
yield generateSfcBlockSection(options.sfc.script, exportDefault.expression.end, options.sfc.script.content.length, codeFeatures.all);
102102
}
103103
else if (classBlockEnd !== undefined) {
104-
yield generateSfcBlockSection(options.sfc.script, 0, classBlockEnd, codeFeatures.all);
105-
yield* generateTemplate(options, ctx, true);
106-
yield generateSfcBlockSection(options.sfc.script, classBlockEnd, options.sfc.script.content.length, codeFeatures.all);
104+
if (options.vueCompilerOptions.skipTemplateCodegen) {
105+
yield generateSfcBlockSection(options.sfc.script, 0, options.sfc.script.content.length, codeFeatures.all);
106+
}
107+
else {
108+
yield generateSfcBlockSection(options.sfc.script, 0, classBlockEnd, codeFeatures.all);
109+
yield `__VLS_template = () => {`;
110+
yield* generateTemplate(options, ctx, true);
111+
yield `},${newLine}`;
112+
yield generateSfcBlockSection(options.sfc.script, classBlockEnd, options.sfc.script.content.length, codeFeatures.all);
113+
}
107114
}
108115
else {
109116
yield generateSfcBlockSection(options.sfc.script, 0, options.sfc.script.content.length, codeFeatures.all);
@@ -118,12 +125,7 @@ export function* generateScript(options: ScriptCodegenOptions): Generator<Code,
118125
yield `;`;
119126
if (options.sfc.scriptSetup) {
120127
// #4569
121-
yield [
122-
'',
123-
'scriptSetup',
124-
options.sfc.scriptSetup.content.length,
125-
codeFeatures.verification,
126-
];
128+
yield ['', 'scriptSetup', options.sfc.scriptSetup.content.length, codeFeatures.verification];
127129
}
128130
yield newLine;
129131

@@ -138,12 +140,7 @@ export function* generateScript(options: ScriptCodegenOptions): Generator<Code,
138140
}
139141

140142
if (options.sfc.scriptSetup) {
141-
yield [
142-
'',
143-
'scriptSetup',
144-
options.sfc.scriptSetup.content.length,
145-
codeFeatures.verification,
146-
];
143+
yield ['', 'scriptSetup', options.sfc.scriptSetup.content.length, codeFeatures.verification];
147144
}
148145

149146
return ctx;

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

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -12,8 +12,7 @@ export function* generateInternalComponent(
1212
templateCodegenCtx: TemplateCodegenContext
1313
): Generator<Code> {
1414
if (options.sfc.scriptSetup && options.scriptSetupRanges) {
15-
yield `let __VLS_defineComponent!: typeof import('${options.vueCompilerOptions.lib}').defineComponent${endOfLine}`;
16-
yield `const __VLS_internalComponent = __VLS_defineComponent({${newLine}`;
15+
yield `const __VLS_internalComponent = (await import('${options.vueCompilerOptions.lib}')).defineComponent({${newLine}`;
1716
yield `setup() {${newLine}`;
1817
yield `return {${newLine}`;
1918
if (ctx.bypassDefineComponent) {

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

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -280,8 +280,8 @@ function* generateSetupFunction(
280280
yield* generateModelEmits(options, scriptSetup, scriptSetupRanges);
281281
yield* generateStyleModules(options, ctx);
282282
yield* generateTemplate(options, ctx, false);
283-
yield `type __VLS_Refs = ReturnType<typeof __VLS_template>['refs']${endOfLine}`;
284-
yield `type __VLS_Slots = ReturnType<typeof __VLS_template>['slots']${endOfLine}`;
283+
yield `type __VLS_Refs = typeof __VLS_templateResult['refs']${endOfLine}`;
284+
yield `type __VLS_Slots = typeof __VLS_templateResult['slots']${endOfLine}`;
285285

286286
if (syntax) {
287287
if (!options.vueCompilerOptions.skipTemplateCodegen && (options.templateCodegen?.hasSlot || scriptSetupRanges?.slots.define)) {

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

Lines changed: 58 additions & 73 deletions
Original file line numberDiff line numberDiff line change
@@ -4,114 +4,99 @@ import { getSlotsPropertyName, hyphenateTag } from '../../utils/shared';
44
import { endOfLine, newLine } from '../common';
55
import { TemplateCodegenContext, createTemplateCodegenContext } from '../template/context';
66
import { forEachInterpolationSegment } from '../template/interpolation';
7+
import { generateStyleScopedClasses } from '../template/styleScopedClasses';
78
import type { ScriptCodegenContext } from './context';
89
import { codeFeatures, type ScriptCodegenOptions } from './index';
910
import { generateInternalComponent } from './internalComponent';
10-
import { generateStyleScopedClasses } from '../template/styleScopedClasses';
11-
12-
export function* generateTemplate(
13-
options: ScriptCodegenOptions,
14-
ctx: ScriptCodegenContext,
15-
isClassComponent: boolean
16-
): Generator<Code> {
17-
ctx.generatedTemplate = true;
1811

19-
if (!options.vueCompilerOptions.skipTemplateCodegen) {
20-
if (isClassComponent) {
21-
yield `__VLS_template = (() => {${newLine}`;
22-
}
23-
else {
24-
yield `const __VLS_template = (() => {${newLine}`;
25-
}
26-
const templateCodegenCtx = createTemplateCodegenContext({ scriptSetupBindingNames: new Set(), edited: options.edited });
27-
yield `const __VLS_template_return = () => {${newLine}`;
28-
yield* generateCtx(options, isClassComponent);
29-
yield* generateTemplateContext(options, templateCodegenCtx);
30-
yield* generateExportOptions(options);
31-
yield* generateConstNameOption(options);
32-
yield `}${endOfLine}`;
33-
yield* generateInternalComponent(options, ctx, templateCodegenCtx);
34-
yield `return __VLS_template_return${endOfLine}`;
35-
yield `})()${endOfLine}`;
12+
export function* generateTemplateCtx(options: ScriptCodegenOptions, isClassComponent: boolean): Generator<Code> {
13+
const types = [];
14+
if (isClassComponent) {
15+
types.push(`typeof this`);
3616
}
3717
else {
38-
yield `function __VLS_template() {${newLine}`;
39-
const templateUsageVars = [...getTemplateUsageVars(options, ctx)];
40-
yield `// @ts-ignore${newLine}`;
41-
yield `[${templateUsageVars.join(', ')}]${newLine}`;
42-
yield `return { slots: {}, refs: {}, attrs: {} }${endOfLine}`;
43-
yield `}${newLine}`;
18+
types.push(`InstanceType<__VLS_PickNotAny<typeof __VLS_internalComponent, new () => {}>>`);
4419
}
20+
if (options.vueCompilerOptions.petiteVueExtensions.some(ext => options.fileBaseName.endsWith(ext))) {
21+
types.push(`typeof globalThis`);
22+
}
23+
if (options.sfc.styles.some(style => style.module)) {
24+
types.push(`__VLS_StyleModules`);
25+
}
26+
yield `let __VLS_ctx!: ${types.join(' & ')}${endOfLine}`;
4527
}
4628

47-
function* generateExportOptions(options: ScriptCodegenOptions): Generator<Code> {
48-
yield newLine;
49-
yield `const __VLS_componentsOption = `;
29+
export function* generateTemplateComponents(options: ScriptCodegenOptions): Generator<Code> {
30+
const exps: Code[] = [];
31+
5032
if (options.sfc.script && options.scriptRanges?.exportDefault?.componentsOption) {
51-
const componentsOption = options.scriptRanges.exportDefault.componentsOption;
52-
yield [
33+
const { componentsOption } = options.scriptRanges.exportDefault;
34+
exps.push([
5335
options.sfc.script.content.substring(componentsOption.start, componentsOption.end),
5436
'script',
5537
componentsOption.start,
5638
codeFeatures.navigation,
57-
];
58-
}
59-
else {
60-
yield `{}`;
39+
]);
6140
}
62-
yield endOfLine;
63-
}
6441

65-
function* generateConstNameOption(options: ScriptCodegenOptions): Generator<Code> {
42+
let nameType: Code | undefined;
6643
if (options.sfc.script && options.scriptRanges?.exportDefault?.nameOption) {
67-
const nameOption = options.scriptRanges.exportDefault.nameOption;
68-
yield `const __VLS_name = `;
69-
yield `${options.sfc.script.content.substring(nameOption.start, nameOption.end)} as const`;
70-
yield endOfLine;
44+
const { nameOption } = options.scriptRanges.exportDefault;
45+
nameType = options.sfc.script.content.substring(nameOption.start, nameOption.end);
7146
}
7247
else if (options.sfc.scriptSetup) {
7348
yield `let __VLS_name!: '${options.scriptSetupRanges?.options.name ?? options.fileBaseName.substring(0, options.fileBaseName.lastIndexOf('.'))}'${endOfLine}`;
49+
nameType = 'typeof __VLS_name';
7450
}
75-
else {
76-
yield `const __VLS_name = undefined${endOfLine}`;
51+
if (nameType) {
52+
exps.push(`{} as {
53+
[K in ${nameType}]: typeof __VLS_internalComponent
54+
& (new () => {
55+
${getSlotsPropertyName(options.vueCompilerOptions.target)}: typeof ${options.scriptSetupRanges?.slots?.name ?? '__VLS_slots'}
56+
})
57+
}`);
58+
}
59+
60+
exps.push(`{} as NonNullable<typeof __VLS_internalComponent extends { components: infer C } ? C : {}>`);
61+
exps.push(`{} as __VLS_GlobalComponents`);
62+
exps.push(`{} as typeof __VLS_ctx`);
63+
64+
yield `const __VLS_components = {${newLine}`;
65+
for (const type of exps) {
66+
yield `...`;
67+
yield type;
68+
yield `,${newLine}`;
7769
}
70+
yield `}${endOfLine}`;
7871
}
7972

80-
function* generateCtx(
73+
export function* generateTemplate(
8174
options: ScriptCodegenOptions,
75+
ctx: ScriptCodegenContext,
8276
isClassComponent: boolean
8377
): Generator<Code> {
84-
yield `let __VLS_ctx!: `;
85-
if (options.vueCompilerOptions.petiteVueExtensions.some(ext => options.fileBaseName.endsWith(ext))) {
86-
yield `typeof globalThis & `;
87-
}
88-
if (!isClassComponent) {
89-
yield `InstanceType<__VLS_PickNotAny<typeof __VLS_internalComponent, new () => {}>>`;
78+
ctx.generatedTemplate = true;
79+
80+
if (!options.vueCompilerOptions.skipTemplateCodegen) {
81+
const templateCodegenCtx = createTemplateCodegenContext({ scriptSetupBindingNames: new Set(), edited: options.edited });
82+
yield* generateTemplateCtx(options, isClassComponent);
83+
yield* generateTemplateComponents(options);
84+
yield* generateTemplateBody(options, templateCodegenCtx);
85+
yield* generateInternalComponent(options, ctx, templateCodegenCtx);
9086
}
9187
else {
92-
yield `typeof this`;
93-
}
94-
/* CSS Module */
95-
if (options.sfc.styles.some(style => style.module)) {
96-
yield ` & __VLS_StyleModules`;
88+
const templateUsageVars = [...getTemplateUsageVars(options, ctx)];
89+
yield `// @ts-ignore${newLine}`;
90+
yield `[${templateUsageVars.join(', ')}]${newLine}`;
91+
yield `const __VLS_templateResult { slots: {}, refs: {}, attrs: {} }${endOfLine}`;
9792
}
98-
yield endOfLine;
9993
}
10094

101-
function* generateTemplateContext(
95+
function* generateTemplateBody(
10296
options: ScriptCodegenOptions,
10397
templateCodegenCtx: TemplateCodegenContext
10498
): Generator<Code> {
105-
/* Components */
106-
yield `/* Components */${newLine}`;
107-
yield `let __VLS_otherComponents!: NonNullable<typeof __VLS_internalComponent extends { components: infer C } ? C : {}> & typeof __VLS_componentsOption${endOfLine}`;
108-
yield `let __VLS_own!: __VLS_SelfComponent<typeof __VLS_name, typeof __VLS_internalComponent & (new () => { ${getSlotsPropertyName(options.vueCompilerOptions.target)}: typeof ${options.scriptSetupRanges?.slots?.name ?? '__VLS_slots'} })>${endOfLine}`;
109-
yield `let __VLS_localComponents!: typeof __VLS_otherComponents & Omit<typeof __VLS_own, keyof typeof __VLS_otherComponents>${endOfLine}`;
110-
yield `let __VLS_components!: typeof __VLS_localComponents & __VLS_GlobalComponents & typeof __VLS_ctx${endOfLine}`; // for html completion, TS references...
111-
112-
/* Style Scoped */
11399
const firstClasses = new Set<string>();
114-
yield `/* Style Scoped */${newLine}`;
115100
yield `let __VLS_styleScopedClasses!: {}`;
116101
for (let i = 0; i < options.sfc.styles.length; i++) {
117102
const style = options.sfc.styles[i];
@@ -155,7 +140,7 @@ function* generateTemplateContext(
155140
}
156141
}
157142

158-
yield `return {${newLine}`;
143+
yield `const __VLS_templateResult = {`;
159144
yield `slots: ${options.scriptSetupRanges?.slots.name ?? '__VLS_slots'},${newLine}`;
160145
yield `refs: __VLS_refs as __VLS_PickRefsExpose<typeof __VLS_refs>,${newLine}`;
161146
yield `attrs: {} as Partial<typeof __VLS_inheritedAttrs>,${newLine}`;

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

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -120,7 +120,7 @@ export function* generateTemplate(options: TemplateCodegenOptions): Generator<Co
120120
}
121121
components.add(node.tag);
122122
yield newLine;
123-
yield ` & __VLS_WithComponent<'${getCanonicalComponentName(node.tag)}', typeof __VLS_ctx, typeof __VLS_localComponents, `;
123+
yield ` & __VLS_WithComponent<'${getCanonicalComponentName(node.tag)}', typeof __VLS_components, `;
124124
yield getPossibleOriginalComponentNames(node.tag, false)
125125
.map(name => `"${name}"`)
126126
.join(', ');

0 commit comments

Comments
 (0)