Skip to content

Commit ece125b

Browse files
refactor(language-core): wrap template virtual code into a function (#4784)
* refactor(language-core): wrap template virtual code into a function * fix: drop `declare` --------- Co-authored-by: KazariEX <1364035137@qq.com>
1 parent fd30217 commit ece125b

File tree

6 files changed

+118
-93
lines changed

6 files changed

+118
-93
lines changed

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

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -41,7 +41,7 @@ export function* generateComponent(
4141
yield generateSfcBlockSection(options.sfc.script, args.start + 1, args.end - 1, codeFeatures.all);
4242
}
4343
if (options.vueCompilerOptions.target >= 3.5 && scriptSetupRanges.templateRefs.length) {
44-
yield `__typeRefs: {} as __VLS_Refs,${newLine}`;
44+
yield `__typeRefs: {} as __VLS_TemplateResult['refs'],${newLine}`;
4545
}
4646
yield `})`;
4747
}
@@ -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 = `typeof __VLS_templateAttrs`;
145+
let attrsType = `__VLS_TemplateResult['attrs']`;
146146
if (hasEmitsOption) {
147147
attrsType = `Omit<${attrsType}, \`on\${string}\`>`;
148148
}

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

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ import { generateScriptSetup, generateScriptSetupImports } from './scriptSetup';
1010
import { generateSrc } from './src';
1111
import { generateTemplate } from './template';
1212
import { generateGlobalTypes } from '../globalTypes';
13+
import { generateInternalComponent } from './internalComponent';
1314

1415
export const codeFeatures = {
1516
all: {
@@ -112,7 +113,10 @@ export function* generateScript(options: ScriptCodegenOptions): Generator<Code,
112113
else {
113114
yield generateSfcBlockSection(options.sfc.script, 0, classBlockEnd, codeFeatures.all);
114115
yield `__VLS_template = () => {`;
115-
yield* generateTemplate(options, ctx, true);
116+
const templateCodegenCtx = yield* generateTemplate(options, ctx, true);
117+
if (templateCodegenCtx) {
118+
yield* generateInternalComponent(options, ctx, templateCodegenCtx);
119+
}
116120
yield `},${newLine}`;
117121
yield generateSfcBlockSection(options.sfc.script, classBlockEnd, options.sfc.script.content.length, codeFeatures.all);
118122
}
@@ -135,7 +139,12 @@ export function* generateScript(options: ScriptCodegenOptions): Generator<Code,
135139
yield newLine;
136140

137141
if (!ctx.generatedTemplate) {
138-
yield* generateTemplate(options, ctx, false);
142+
yield `function __VLS_template() {${newLine}`;
143+
const templateCodegenCtx = yield* generateTemplate(options, ctx, false);
144+
yield `}${endOfLine}`;
145+
if (templateCodegenCtx) {
146+
yield* generateInternalComponent(options, ctx, templateCodegenCtx);
147+
}
139148
}
140149

141150
if (options.edited) {

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

Lines changed: 12 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ import { endOfLine, generateSfcBlockSection, newLine } from '../common';
44
import { generateComponent, generateEmitsOption } from './component';
55
import type { ScriptCodegenContext } from './context';
66
import { ScriptCodegenOptions, codeFeatures } from './index';
7+
import { generateInternalComponent } from './internalComponent';
78
import { generateCssClassProperty, generateTemplate } from './template';
89

910
export function* generateScriptSetupImports(
@@ -70,7 +71,7 @@ export function* generateScriptSetup(
7071
+ ` props: ${ctx.localTypes.PrettifyLocal}<typeof __VLS_functionalComponentProps & __VLS_PublicProps> & __VLS_BuiltInPublicProps,${newLine}`
7172
+ ` expose(exposed: import('${options.vueCompilerOptions.lib}').ShallowUnwrapRef<${scriptSetupRanges.expose.define ? 'typeof __VLS_exposed' : '{}'}>): void,${newLine}`
7273
+ ` attrs: any,${newLine}`
73-
+ ` slots: __VLS_Slots,${newLine}`
74+
+ ` slots: __VLS_TemplateResult['slots'],${newLine}`
7475
+ ` emit: ${emitTypes.length ? emitTypes.join(' & ') : `{}`},${newLine}`
7576
+ ` }${endOfLine}`;
7677
yield ` })(),${newLine}`; // __VLS_setup = (async () => {
@@ -246,9 +247,9 @@ function* generateSetupFunction(
246247
if (define?.arg) {
247248
setupCodeModifies.push([
248249
[
249-
`<__VLS_Refs[`,
250+
`<__VLS_TemplateResult['refs'][`,
250251
generateSfcBlockSection(scriptSetup, define.arg.start, define.arg.end, codeFeatures.navigation),
251-
`], keyof __VLS_Refs>`
252+
`], keyof __VLS_TemplateResult['refs']>`
252253
],
253254
define.arg.start - 1,
254255
define.arg.start - 1
@@ -287,17 +288,21 @@ function* generateSetupFunction(
287288
yield* generateComponentProps(options, ctx, scriptSetup, scriptSetupRanges, definePropMirrors);
288289
yield* generateModelEmits(options, scriptSetup, scriptSetupRanges);
289290
yield* generateStyleModules(options, ctx);
290-
yield* generateTemplate(options, ctx, false);
291-
yield `type __VLS_Refs = typeof __VLS_templateRefs${endOfLine}`;
292-
yield `type __VLS_Slots = typeof __VLS_templateSlots${endOfLine}`;
291+
yield `function __VLS_template() {${newLine}`;
292+
const templateCodegenCtx = yield* generateTemplate(options, ctx, false);
293+
yield `}${endOfLine}`;
294+
if (templateCodegenCtx) {
295+
yield* generateInternalComponent(options, ctx, templateCodegenCtx);
296+
}
297+
yield `type __VLS_TemplateResult = ReturnType<typeof __VLS_template>${endOfLine}`;
293298

294299
if (syntax) {
295300
if (!options.vueCompilerOptions.skipTemplateCodegen && (options.templateCodegen?.hasSlot || scriptSetupRanges?.slots.define)) {
296301
yield `const __VLS_component = `;
297302
yield* generateComponent(options, ctx, scriptSetup, scriptSetupRanges);
298303
yield endOfLine;
299304
yield `${syntax} `;
300-
yield `{} as ${ctx.localTypes.WithTemplateSlots}<typeof __VLS_component, __VLS_Slots>${endOfLine}`;
305+
yield `{} as ${ctx.localTypes.WithTemplateSlots}<typeof __VLS_component, __VLS_TemplateResult['slots']>${endOfLine}`;
301306
}
302307
else {
303308
yield `${syntax} `;

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

Lines changed: 12 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,6 @@ import { forEachInterpolationSegment } from '../template/interpolation';
77
import { generateStyleScopedClasses } from '../template/styleScopedClasses';
88
import type { ScriptCodegenContext } from './context';
99
import { codeFeatures, type ScriptCodegenOptions } from './index';
10-
import { generateInternalComponent } from './internalComponent';
1110

1211
export function* generateTemplateCtx(
1312
options: ScriptCodegenOptions,
@@ -93,7 +92,7 @@ export function* generateTemplate(
9392
options: ScriptCodegenOptions,
9493
ctx: ScriptCodegenContext,
9594
isClassComponent: boolean
96-
): Generator<Code> {
95+
): Generator<Code, TemplateCodegenContext | undefined> {
9796
ctx.generatedTemplate = true;
9897

9998
if (!options.vueCompilerOptions.skipTemplateCodegen) {
@@ -104,15 +103,17 @@ export function* generateTemplate(
104103
yield* generateTemplateCtx(options, isClassComponent);
105104
yield* generateTemplateComponents(options);
106105
yield* generateTemplateBody(options, templateCodegenCtx);
107-
yield* generateInternalComponent(options, ctx, templateCodegenCtx);
106+
return templateCodegenCtx;
108107
}
109108
else {
110109
const templateUsageVars = [...getTemplateUsageVars(options, ctx)];
111110
yield `// @ts-ignore${newLine}`;
112111
yield `[${templateUsageVars.join(', ')}]${newLine}`;
113-
yield `const __VLS_templateSlots = {}${endOfLine}`;
114-
yield `const __VLS_templateRefs = {}${endOfLine}`;
115-
yield `const __VLS_templateAttrs = {}${endOfLine}`;
112+
yield `return {${newLine}`;
113+
yield ` slots: {},${newLine}`;
114+
yield ` refs: {},${newLine}`;
115+
yield ` attrs: {},${newLine}`;
116+
yield `}${endOfLine}`;
116117
}
117118
}
118119

@@ -164,9 +165,11 @@ function* generateTemplateBody(
164165
}
165166
}
166167

167-
yield `const __VLS_templateSlots = ${options.scriptSetupRanges?.slots.name ?? '__VLS_slots'}${endOfLine}`;
168-
yield `const __VLS_templateRefs = $refs${endOfLine}`;
169-
yield `const __VLS_templateAttrs = {} as Partial<typeof __VLS_inheritedAttrs>${endOfLine}`;
168+
yield `return {${newLine}`;
169+
yield ` slots: ${options.scriptSetupRanges?.slots.name ?? '__VLS_slots'},${newLine}`;
170+
yield ` refs: $refs,${newLine}`;
171+
yield ` attrs: {} as Partial<typeof __VLS_inheritedAttrs>,${newLine}`;
172+
yield `}${endOfLine}`;
170173
}
171174

172175
export function* generateCssClassProperty(

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

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -68,7 +68,7 @@ export function* generateTemplate(options: TemplateCodegenOptions): Generator<Co
6868
yield `: ${varName},${newLine}`;
6969
}
7070
yield `}${endOfLine}`;
71-
yield `declare var $refs: typeof __VLS_refs${endOfLine}`;
71+
yield `var $refs!: typeof __VLS_refs${endOfLine}`;
7272
}
7373

7474
function* generateSlotsType(): Generator<Code> {

packages/tsc/tests/__snapshots__/dts.spec.ts.snap

Lines changed: 80 additions & 72 deletions
Original file line numberDiff line numberDiff line change
@@ -633,26 +633,26 @@ export {};
633633
`;
634634
635635
exports[`vue-tsc-dts > Input: template-slots/component.vue, Output: template-slots/component.vue.d.ts 1`] = `
636-
"declare var __VLS_0: {};
637-
declare var __VLS_1: {
638-
num: number;
639-
};
640-
declare var __VLS_2: {
641-
str: string;
642-
};
643-
declare var __VLS_3: {
644-
num: number;
645-
str: string;
646-
};
647-
declare const __VLS_templateSlots: {
648-
"no-bind"?(_: typeof __VLS_0): any;
649-
default?(_: typeof __VLS_1): any;
650-
"named-slot"?(_: typeof __VLS_2): any;
651-
vbind?(_: typeof __VLS_3): any;
636+
"declare function __VLS_template(): {
637+
slots: {
638+
"no-bind"?(_: {}): any;
639+
default?(_: {
640+
num: number;
641+
}): any;
642+
"named-slot"?(_: {
643+
str: string;
644+
}): any;
645+
vbind?(_: {
646+
num: number;
647+
str: string;
648+
}): any;
649+
};
650+
refs: {};
651+
attrs: Partial<{}>;
652652
};
653-
type __VLS_Slots = typeof __VLS_templateSlots;
653+
type __VLS_TemplateResult = ReturnType<typeof __VLS_template>;
654654
declare const __VLS_component: import("vue").DefineComponent<{}, {}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {}, string, import("vue").PublicProps, Readonly<import("vue").ExtractPropTypes<{}>>, {}, {}>;
655-
declare const _default: __VLS_WithTemplateSlots<typeof __VLS_component, __VLS_Slots>;
655+
declare const _default: __VLS_WithTemplateSlots<typeof __VLS_component, __VLS_TemplateResult["slots"]>;
656656
export default _default;
657657
type __VLS_WithTemplateSlots<T, S> = T & {
658658
new (): {
@@ -664,34 +664,38 @@ type __VLS_WithTemplateSlots<T, S> = T & {
664664
665665
exports[`vue-tsc-dts > Input: template-slots/component-define-slots.vue, Output: template-slots/component-define-slots.vue.d.ts 1`] = `
666666
"import { VNode } from 'vue';
667-
declare const __VLS_templateSlots: Readonly<{
668-
default: (props: {
669-
num: number;
670-
}) => VNode[];
671-
'named-slot': (props: {
672-
str: string;
673-
}) => VNode[];
674-
vbind: (props: {
675-
num: number;
676-
str: string;
677-
}) => VNode[];
678-
'no-bind': () => VNode[];
679-
}> & {
680-
default: (props: {
681-
num: number;
682-
}) => VNode[];
683-
'named-slot': (props: {
684-
str: string;
685-
}) => VNode[];
686-
vbind: (props: {
687-
num: number;
688-
str: string;
689-
}) => VNode[];
690-
'no-bind': () => VNode[];
667+
declare function __VLS_template(): {
668+
slots: Readonly<{
669+
default: (props: {
670+
num: number;
671+
}) => VNode[];
672+
'named-slot': (props: {
673+
str: string;
674+
}) => VNode[];
675+
vbind: (props: {
676+
num: number;
677+
str: string;
678+
}) => VNode[];
679+
'no-bind': () => VNode[];
680+
}> & {
681+
default: (props: {
682+
num: number;
683+
}) => VNode[];
684+
'named-slot': (props: {
685+
str: string;
686+
}) => VNode[];
687+
vbind: (props: {
688+
num: number;
689+
str: string;
690+
}) => VNode[];
691+
'no-bind': () => VNode[];
692+
};
693+
refs: {};
694+
attrs: Partial<{}>;
691695
};
692-
type __VLS_Slots = typeof __VLS_templateSlots;
696+
type __VLS_TemplateResult = ReturnType<typeof __VLS_template>;
693697
declare const __VLS_component: import("vue").DefineComponent<{}, {}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {}, string, import("vue").PublicProps, Readonly<import("vue").ExtractPropTypes<{}>>, {}, {}>;
694-
declare const _default: __VLS_WithTemplateSlots<typeof __VLS_component, __VLS_Slots>;
698+
declare const _default: __VLS_WithTemplateSlots<typeof __VLS_component, __VLS_TemplateResult["slots"]>;
695699
export default _default;
696700
type __VLS_WithTemplateSlots<T, S> = T & {
697701
new (): {
@@ -702,18 +706,22 @@ type __VLS_WithTemplateSlots<T, S> = T & {
702706
`;
703707
704708
exports[`vue-tsc-dts > Input: template-slots/component-destructuring.vue, Output: template-slots/component-destructuring.vue.d.ts 1`] = `
705-
"declare const __VLS_templateSlots: Readonly<{
706-
bottom: (props: {
707-
num: number;
708-
}) => any[];
709-
}> & {
710-
bottom: (props: {
711-
num: number;
712-
}) => any[];
709+
"declare function __VLS_template(): {
710+
slots: Readonly<{
711+
bottom: (props: {
712+
num: number;
713+
}) => any[];
714+
}> & {
715+
bottom: (props: {
716+
num: number;
717+
}) => any[];
718+
};
719+
refs: {};
720+
attrs: Partial<{}>;
713721
};
714-
type __VLS_Slots = typeof __VLS_templateSlots;
722+
type __VLS_TemplateResult = ReturnType<typeof __VLS_template>;
715723
declare const __VLS_component: import("vue").DefineComponent<{}, {}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {}, string, import("vue").PublicProps, Readonly<import("vue").ExtractPropTypes<{}>>, {}, {}>;
716-
declare const _default: __VLS_WithTemplateSlots<typeof __VLS_component, __VLS_Slots>;
724+
declare const _default: __VLS_WithTemplateSlots<typeof __VLS_component, __VLS_TemplateResult["slots"]>;
717725
export default _default;
718726
type __VLS_WithTemplateSlots<T, S> = T & {
719727
new (): {
@@ -724,26 +732,26 @@ type __VLS_WithTemplateSlots<T, S> = T & {
724732
`;
725733
726734
exports[`vue-tsc-dts > Input: template-slots/component-no-script.vue, Output: template-slots/component-no-script.vue.d.ts 1`] = `
727-
"declare var __VLS_0: {};
728-
declare var __VLS_1: {
729-
num: number;
730-
};
731-
declare var __VLS_2: {
732-
str: string;
733-
};
734-
declare var __VLS_3: {
735-
num: number;
736-
str: string;
737-
};
738-
declare const __VLS_templateSlots: {
739-
"no-bind"?(_: typeof __VLS_0): any;
740-
default?(_: typeof __VLS_1): any;
741-
"named-slot"?(_: typeof __VLS_2): any;
742-
vbind?(_: typeof __VLS_3): any;
735+
"declare function __VLS_template(): {
736+
slots: {
737+
"no-bind"?(_: {}): any;
738+
default?(_: {
739+
num: number;
740+
}): any;
741+
"named-slot"?(_: {
742+
str: string;
743+
}): any;
744+
vbind?(_: {
745+
num: number;
746+
str: string;
747+
}): any;
748+
};
749+
refs: {};
750+
attrs: Partial<{}>;
743751
};
744-
type __VLS_Slots = typeof __VLS_templateSlots;
752+
type __VLS_TemplateResult = ReturnType<typeof __VLS_template>;
745753
declare const __VLS_component: import("vue").DefineComponent<{}, {}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {}, string, import("vue").PublicProps, Readonly<import("vue").ExtractPropTypes<{}>>, {}, {}>;
746-
declare const _default: __VLS_WithTemplateSlots<typeof __VLS_component, __VLS_Slots>;
754+
declare const _default: __VLS_WithTemplateSlots<typeof __VLS_component, __VLS_TemplateResult["slots"]>;
747755
export default _default;
748756
type __VLS_WithTemplateSlots<T, S> = T & {
749757
new (): {

0 commit comments

Comments
 (0)