Skip to content

Commit

Permalink
refactor(language-core): wrap template virtual code into a function (#…
Browse files Browse the repository at this point in the history
…4784)

* refactor(language-core): wrap template virtual code into a function

* fix: drop `declare`

---------

Co-authored-by: KazariEX <[email protected]>
  • Loading branch information
johnsoncodehk and KazariEX authored Sep 1, 2024
1 parent fd30217 commit ece125b
Show file tree
Hide file tree
Showing 6 changed files with 118 additions and 93 deletions.
4 changes: 2 additions & 2 deletions packages/language-core/lib/codegen/script/component.ts
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@ export function* generateComponent(
yield generateSfcBlockSection(options.sfc.script, args.start + 1, args.end - 1, codeFeatures.all);
}
if (options.vueCompilerOptions.target >= 3.5 && scriptSetupRanges.templateRefs.length) {
yield `__typeRefs: {} as __VLS_Refs,${newLine}`;
yield `__typeRefs: {} as __VLS_TemplateResult['refs'],${newLine}`;
}
yield `})`;
}
Expand Down Expand Up @@ -142,7 +142,7 @@ export function* generatePropsOption(
optionExpCodes.push(generateSfcBlockSection(scriptSetup, arg.start, arg.end, codeFeatures.navigation));
}
if (inheritAttrs && options.templateCodegen?.inheritedAttrVars.size) {
let attrsType = `typeof __VLS_templateAttrs`;
let attrsType = `__VLS_TemplateResult['attrs']`;
if (hasEmitsOption) {
attrsType = `Omit<${attrsType}, \`on\${string}\`>`;
}
Expand Down
13 changes: 11 additions & 2 deletions packages/language-core/lib/codegen/script/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ import { generateScriptSetup, generateScriptSetupImports } from './scriptSetup';
import { generateSrc } from './src';
import { generateTemplate } from './template';
import { generateGlobalTypes } from '../globalTypes';
import { generateInternalComponent } from './internalComponent';

export const codeFeatures = {
all: {
Expand Down Expand Up @@ -112,7 +113,10 @@ export function* generateScript(options: ScriptCodegenOptions): Generator<Code,
else {
yield generateSfcBlockSection(options.sfc.script, 0, classBlockEnd, codeFeatures.all);
yield `__VLS_template = () => {`;
yield* generateTemplate(options, ctx, true);
const templateCodegenCtx = yield* generateTemplate(options, ctx, true);
if (templateCodegenCtx) {
yield* generateInternalComponent(options, ctx, templateCodegenCtx);
}
yield `},${newLine}`;
yield generateSfcBlockSection(options.sfc.script, classBlockEnd, options.sfc.script.content.length, codeFeatures.all);
}
Expand All @@ -135,7 +139,12 @@ export function* generateScript(options: ScriptCodegenOptions): Generator<Code,
yield newLine;

if (!ctx.generatedTemplate) {
yield* generateTemplate(options, ctx, false);
yield `function __VLS_template() {${newLine}`;
const templateCodegenCtx = yield* generateTemplate(options, ctx, false);
yield `}${endOfLine}`;
if (templateCodegenCtx) {
yield* generateInternalComponent(options, ctx, templateCodegenCtx);
}
}

if (options.edited) {
Expand Down
19 changes: 12 additions & 7 deletions packages/language-core/lib/codegen/script/scriptSetup.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import { endOfLine, generateSfcBlockSection, newLine } from '../common';
import { generateComponent, generateEmitsOption } from './component';
import type { ScriptCodegenContext } from './context';
import { ScriptCodegenOptions, codeFeatures } from './index';
import { generateInternalComponent } from './internalComponent';
import { generateCssClassProperty, generateTemplate } from './template';

export function* generateScriptSetupImports(
Expand Down Expand Up @@ -70,7 +71,7 @@ export function* generateScriptSetup(
+ ` props: ${ctx.localTypes.PrettifyLocal}<typeof __VLS_functionalComponentProps & __VLS_PublicProps> & __VLS_BuiltInPublicProps,${newLine}`
+ ` expose(exposed: import('${options.vueCompilerOptions.lib}').ShallowUnwrapRef<${scriptSetupRanges.expose.define ? 'typeof __VLS_exposed' : '{}'}>): void,${newLine}`
+ ` attrs: any,${newLine}`
+ ` slots: __VLS_Slots,${newLine}`
+ ` slots: __VLS_TemplateResult['slots'],${newLine}`
+ ` emit: ${emitTypes.length ? emitTypes.join(' & ') : `{}`},${newLine}`
+ ` }${endOfLine}`;
yield ` })(),${newLine}`; // __VLS_setup = (async () => {
Expand Down Expand Up @@ -246,9 +247,9 @@ function* generateSetupFunction(
if (define?.arg) {
setupCodeModifies.push([
[
`<__VLS_Refs[`,
`<__VLS_TemplateResult['refs'][`,
generateSfcBlockSection(scriptSetup, define.arg.start, define.arg.end, codeFeatures.navigation),
`], keyof __VLS_Refs>`
`], keyof __VLS_TemplateResult['refs']>`
],
define.arg.start - 1,
define.arg.start - 1
Expand Down Expand Up @@ -287,17 +288,21 @@ function* generateSetupFunction(
yield* generateComponentProps(options, ctx, scriptSetup, scriptSetupRanges, definePropMirrors);
yield* generateModelEmits(options, scriptSetup, scriptSetupRanges);
yield* generateStyleModules(options, ctx);
yield* generateTemplate(options, ctx, false);
yield `type __VLS_Refs = typeof __VLS_templateRefs${endOfLine}`;
yield `type __VLS_Slots = typeof __VLS_templateSlots${endOfLine}`;
yield `function __VLS_template() {${newLine}`;
const templateCodegenCtx = yield* generateTemplate(options, ctx, false);
yield `}${endOfLine}`;
if (templateCodegenCtx) {
yield* generateInternalComponent(options, ctx, templateCodegenCtx);
}
yield `type __VLS_TemplateResult = ReturnType<typeof __VLS_template>${endOfLine}`;

if (syntax) {
if (!options.vueCompilerOptions.skipTemplateCodegen && (options.templateCodegen?.hasSlot || scriptSetupRanges?.slots.define)) {
yield `const __VLS_component = `;
yield* generateComponent(options, ctx, scriptSetup, scriptSetupRanges);
yield endOfLine;
yield `${syntax} `;
yield `{} as ${ctx.localTypes.WithTemplateSlots}<typeof __VLS_component, __VLS_Slots>${endOfLine}`;
yield `{} as ${ctx.localTypes.WithTemplateSlots}<typeof __VLS_component, __VLS_TemplateResult['slots']>${endOfLine}`;
}
else {
yield `${syntax} `;
Expand Down
21 changes: 12 additions & 9 deletions packages/language-core/lib/codegen/script/template.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,6 @@ import { forEachInterpolationSegment } from '../template/interpolation';
import { generateStyleScopedClasses } from '../template/styleScopedClasses';
import type { ScriptCodegenContext } from './context';
import { codeFeatures, type ScriptCodegenOptions } from './index';
import { generateInternalComponent } from './internalComponent';

export function* generateTemplateCtx(
options: ScriptCodegenOptions,
Expand Down Expand Up @@ -93,7 +92,7 @@ export function* generateTemplate(
options: ScriptCodegenOptions,
ctx: ScriptCodegenContext,
isClassComponent: boolean
): Generator<Code> {
): Generator<Code, TemplateCodegenContext | undefined> {
ctx.generatedTemplate = true;

if (!options.vueCompilerOptions.skipTemplateCodegen) {
Expand All @@ -104,15 +103,17 @@ export function* generateTemplate(
yield* generateTemplateCtx(options, isClassComponent);
yield* generateTemplateComponents(options);
yield* generateTemplateBody(options, templateCodegenCtx);
yield* generateInternalComponent(options, ctx, templateCodegenCtx);
return templateCodegenCtx;
}
else {
const templateUsageVars = [...getTemplateUsageVars(options, ctx)];
yield `// @ts-ignore${newLine}`;
yield `[${templateUsageVars.join(', ')}]${newLine}`;
yield `const __VLS_templateSlots = {}${endOfLine}`;
yield `const __VLS_templateRefs = {}${endOfLine}`;
yield `const __VLS_templateAttrs = {}${endOfLine}`;
yield `return {${newLine}`;
yield ` slots: {},${newLine}`;
yield ` refs: {},${newLine}`;
yield ` attrs: {},${newLine}`;
yield `}${endOfLine}`;
}
}

Expand Down Expand Up @@ -164,9 +165,11 @@ function* generateTemplateBody(
}
}

yield `const __VLS_templateSlots = ${options.scriptSetupRanges?.slots.name ?? '__VLS_slots'}${endOfLine}`;
yield `const __VLS_templateRefs = $refs${endOfLine}`;
yield `const __VLS_templateAttrs = {} as Partial<typeof __VLS_inheritedAttrs>${endOfLine}`;
yield `return {${newLine}`;
yield ` slots: ${options.scriptSetupRanges?.slots.name ?? '__VLS_slots'},${newLine}`;
yield ` refs: $refs,${newLine}`;
yield ` attrs: {} as Partial<typeof __VLS_inheritedAttrs>,${newLine}`;
yield `}${endOfLine}`;
}

export function* generateCssClassProperty(
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 @@ -68,7 +68,7 @@ export function* generateTemplate(options: TemplateCodegenOptions): Generator<Co
yield `: ${varName},${newLine}`;
}
yield `}${endOfLine}`;
yield `declare var $refs: typeof __VLS_refs${endOfLine}`;
yield `var $refs!: typeof __VLS_refs${endOfLine}`;
}

function* generateSlotsType(): Generator<Code> {
Expand Down
152 changes: 80 additions & 72 deletions packages/tsc/tests/__snapshots__/dts.spec.ts.snap
Original file line number Diff line number Diff line change
Expand Up @@ -633,26 +633,26 @@ export {};
`;
exports[`vue-tsc-dts > Input: template-slots/component.vue, Output: template-slots/component.vue.d.ts 1`] = `
"declare var __VLS_0: {};
declare var __VLS_1: {
num: number;
};
declare var __VLS_2: {
str: string;
};
declare var __VLS_3: {
num: number;
str: string;
};
declare const __VLS_templateSlots: {
"no-bind"?(_: typeof __VLS_0): any;
default?(_: typeof __VLS_1): any;
"named-slot"?(_: typeof __VLS_2): any;
vbind?(_: typeof __VLS_3): any;
"declare function __VLS_template(): {
slots: {
"no-bind"?(_: {}): any;
default?(_: {
num: number;
}): any;
"named-slot"?(_: {
str: string;
}): any;
vbind?(_: {
num: number;
str: string;
}): any;
};
refs: {};
attrs: Partial<{}>;
};
type __VLS_Slots = typeof __VLS_templateSlots;
type __VLS_TemplateResult = ReturnType<typeof __VLS_template>;
declare const __VLS_component: import("vue").DefineComponent<{}, {}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {}, string, import("vue").PublicProps, Readonly<import("vue").ExtractPropTypes<{}>>, {}, {}>;
declare const _default: __VLS_WithTemplateSlots<typeof __VLS_component, __VLS_Slots>;
declare const _default: __VLS_WithTemplateSlots<typeof __VLS_component, __VLS_TemplateResult["slots"]>;
export default _default;
type __VLS_WithTemplateSlots<T, S> = T & {
new (): {
Expand All @@ -664,34 +664,38 @@ type __VLS_WithTemplateSlots<T, S> = T & {
exports[`vue-tsc-dts > Input: template-slots/component-define-slots.vue, Output: template-slots/component-define-slots.vue.d.ts 1`] = `
"import { VNode } from 'vue';
declare const __VLS_templateSlots: Readonly<{
default: (props: {
num: number;
}) => VNode[];
'named-slot': (props: {
str: string;
}) => VNode[];
vbind: (props: {
num: number;
str: string;
}) => VNode[];
'no-bind': () => VNode[];
}> & {
default: (props: {
num: number;
}) => VNode[];
'named-slot': (props: {
str: string;
}) => VNode[];
vbind: (props: {
num: number;
str: string;
}) => VNode[];
'no-bind': () => VNode[];
declare function __VLS_template(): {
slots: Readonly<{
default: (props: {
num: number;
}) => VNode[];
'named-slot': (props: {
str: string;
}) => VNode[];
vbind: (props: {
num: number;
str: string;
}) => VNode[];
'no-bind': () => VNode[];
}> & {
default: (props: {
num: number;
}) => VNode[];
'named-slot': (props: {
str: string;
}) => VNode[];
vbind: (props: {
num: number;
str: string;
}) => VNode[];
'no-bind': () => VNode[];
};
refs: {};
attrs: Partial<{}>;
};
type __VLS_Slots = typeof __VLS_templateSlots;
type __VLS_TemplateResult = ReturnType<typeof __VLS_template>;
declare const __VLS_component: import("vue").DefineComponent<{}, {}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {}, string, import("vue").PublicProps, Readonly<import("vue").ExtractPropTypes<{}>>, {}, {}>;
declare const _default: __VLS_WithTemplateSlots<typeof __VLS_component, __VLS_Slots>;
declare const _default: __VLS_WithTemplateSlots<typeof __VLS_component, __VLS_TemplateResult["slots"]>;
export default _default;
type __VLS_WithTemplateSlots<T, S> = T & {
new (): {
Expand All @@ -702,18 +706,22 @@ type __VLS_WithTemplateSlots<T, S> = T & {
`;
exports[`vue-tsc-dts > Input: template-slots/component-destructuring.vue, Output: template-slots/component-destructuring.vue.d.ts 1`] = `
"declare const __VLS_templateSlots: Readonly<{
bottom: (props: {
num: number;
}) => any[];
}> & {
bottom: (props: {
num: number;
}) => any[];
"declare function __VLS_template(): {
slots: Readonly<{
bottom: (props: {
num: number;
}) => any[];
}> & {
bottom: (props: {
num: number;
}) => any[];
};
refs: {};
attrs: Partial<{}>;
};
type __VLS_Slots = typeof __VLS_templateSlots;
type __VLS_TemplateResult = ReturnType<typeof __VLS_template>;
declare const __VLS_component: import("vue").DefineComponent<{}, {}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {}, string, import("vue").PublicProps, Readonly<import("vue").ExtractPropTypes<{}>>, {}, {}>;
declare const _default: __VLS_WithTemplateSlots<typeof __VLS_component, __VLS_Slots>;
declare const _default: __VLS_WithTemplateSlots<typeof __VLS_component, __VLS_TemplateResult["slots"]>;
export default _default;
type __VLS_WithTemplateSlots<T, S> = T & {
new (): {
Expand All @@ -724,26 +732,26 @@ type __VLS_WithTemplateSlots<T, S> = T & {
`;
exports[`vue-tsc-dts > Input: template-slots/component-no-script.vue, Output: template-slots/component-no-script.vue.d.ts 1`] = `
"declare var __VLS_0: {};
declare var __VLS_1: {
num: number;
};
declare var __VLS_2: {
str: string;
};
declare var __VLS_3: {
num: number;
str: string;
};
declare const __VLS_templateSlots: {
"no-bind"?(_: typeof __VLS_0): any;
default?(_: typeof __VLS_1): any;
"named-slot"?(_: typeof __VLS_2): any;
vbind?(_: typeof __VLS_3): any;
"declare function __VLS_template(): {
slots: {
"no-bind"?(_: {}): any;
default?(_: {
num: number;
}): any;
"named-slot"?(_: {
str: string;
}): any;
vbind?(_: {
num: number;
str: string;
}): any;
};
refs: {};
attrs: Partial<{}>;
};
type __VLS_Slots = typeof __VLS_templateSlots;
type __VLS_TemplateResult = ReturnType<typeof __VLS_template>;
declare const __VLS_component: import("vue").DefineComponent<{}, {}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {}, string, import("vue").PublicProps, Readonly<import("vue").ExtractPropTypes<{}>>, {}, {}>;
declare const _default: __VLS_WithTemplateSlots<typeof __VLS_component, __VLS_Slots>;
declare const _default: __VLS_WithTemplateSlots<typeof __VLS_component, __VLS_TemplateResult["slots"]>;
export default _default;
type __VLS_WithTemplateSlots<T, S> = T & {
new (): {
Expand Down

0 comments on commit ece125b

Please sign in to comment.