Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat(language-core): unwrap __VLS_template & type support of useAttrs #5106

Open
wants to merge 3 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 3 additions & 3 deletions packages/language-core/lib/codegen/script/component.ts
Original file line number Diff line number Diff line change
Expand Up @@ -41,10 +41,10 @@ export function* generateComponent(
yield generateSfcBlockSection(options.sfc.script, args.start + 1, args.end - 1, codeFeatures.all);
}
if (options.vueCompilerOptions.target >= 3.5 && options.templateCodegen?.templateRefs.size) {
yield `__typeRefs: {} as __VLS_TemplateResult['refs'],${newLine}`;
yield `__typeRefs: {} as __VLS_TemplateRefs,${newLine}`;
}
if (options.vueCompilerOptions.target >= 3.5 && options.templateCodegen?.singleRootElType) {
yield `__typeEl: {} as __VLS_TemplateResult['rootEl'],${newLine}`;
yield `__typeEl: {} as __VLS_TemplateEl,${newLine}`;
}
yield `})`;
}
Expand Down Expand Up @@ -154,7 +154,7 @@ export function* generatePropsOption(
});
}
if (inheritAttrs && options.templateCodegen?.inheritedAttrVars.size) {
let attrsType = `__VLS_TemplateResult['attrs']`;
let attrsType = `__VLS_TemplateAttrs`;
if (hasEmitsOption) {
attrsType = `Omit<${attrsType}, \`on\${string}\`>`;
}
Expand Down
2 changes: 0 additions & 2 deletions packages/language-core/lib/codegen/script/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -151,9 +151,7 @@ export function* generateScript(options: ScriptCodegenOptions): Generator<Code,
}

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

Expand Down
36 changes: 16 additions & 20 deletions packages/language-core/lib/codegen/script/scriptSetup.ts
Original file line number Diff line number Diff line change
Expand Up @@ -65,10 +65,10 @@ export function* generateScriptSetup(
}

yield `return {} as {${newLine}`
+ ` props: ${ctx.localTypes.PrettifyLocal}<__VLS_OwnProps & __VLS_PublicProps & __VLS_TemplateResult['attrs']> & __VLS_BuiltInPublicProps,${newLine}`
+ ` props: ${ctx.localTypes.PrettifyLocal}<__VLS_OwnProps & __VLS_PublicProps & __VLS_TemplateAttrs> & __VLS_BuiltInPublicProps,${newLine}`
+ ` expose(exposed: import('${options.vueCompilerOptions.lib}').ShallowUnwrapRef<${scriptSetupRanges.defineExpose ? 'typeof __VLS_exposed' : '{}'}>): void,${newLine}`
+ ` attrs: any,${newLine}`
+ ` slots: __VLS_TemplateResult['slots'],${newLine}`
+ ` slots: __VLS_TemplateSlots,${newLine}`
+ ` emit: ${emitTypes.length ? emitTypes.join(' & ') : `{}`},${newLine}`
+ `}${endOfLine}`;
yield `})(),${newLine}`; // __VLS_setup = (async () => {
Expand Down Expand Up @@ -170,18 +170,17 @@ function* generateSetupFunction(
]);
}
}
// TODO: circular reference
// for (const { callExp } of scriptSetupRanges.useAttrs) {
// setupCodeModifies.push([
// [`(`],
// callExp.start,
// callExp.start
// ], [
// [` as __VLS_TemplateResult['attrs'] & Record<string, unknown>)`],
// callExp.end,
// callExp.end
// ]);
// }
for (const { callExp } of scriptSetupRanges.useAttrs) {
setupCodeModifies.push([
[`(`],
callExp.start,
callExp.start
], [
[` as typeof __VLS_special.$attrs)`],
callExp.end,
callExp.end
]);
}
for (const { callExp, exp, arg } of scriptSetupRanges.useCssModule) {
setupCodeModifies.push([
[`(`],
Expand Down Expand Up @@ -216,7 +215,7 @@ function* generateSetupFunction(
callExp.start,
callExp.start
], [
[` as __VLS_TemplateResult['slots'])`],
[` as typeof __VLS_special.$slots)`],
callExp.end,
callExp.end
]);
Expand All @@ -225,7 +224,7 @@ function* generateSetupFunction(
for (const { callExp, exp, arg } of scriptSetupRanges.useTemplateRef) {
const templateRefType = arg
? [
`__VLS_TemplateResult['refs'][`,
`__VLS_TemplateRefs[`,
generateSfcBlockSection(scriptSetup, arg.start, arg.end, codeFeatures.all),
`]`
]
Expand Down Expand Up @@ -294,19 +293,16 @@ function* generateSetupFunction(

yield* generateComponentProps(options, ctx, scriptSetup, scriptSetupRanges);
yield* generateModelEmit(scriptSetup, scriptSetupRanges);
yield `function __VLS_template() {${newLine}`;
const templateCodegenCtx = yield* generateTemplate(options, ctx);
yield `}${endOfLine}`;
yield* generateComponentSelf(options, ctx, templateCodegenCtx);
yield `type __VLS_TemplateResult = ReturnType<typeof __VLS_template>${endOfLine}`;

if (syntax) {
if (!options.vueCompilerOptions.skipTemplateCodegen && (options.templateCodegen?.hasSlot || scriptSetupRanges.defineSlots)) {
yield `const __VLS_component = `;
yield* generateComponent(options, ctx, scriptSetup, scriptSetupRanges);
yield endOfLine;
yield `${syntax} `;
yield `{} as ${ctx.localTypes.WithTemplateSlots}<typeof __VLS_component, __VLS_TemplateResult['slots']>${endOfLine}`;
yield `{} as ${ctx.localTypes.WithTemplateSlots}<typeof __VLS_component, __VLS_TemplateSlots>${endOfLine}`;
}
else {
yield `${syntax} `;
Expand Down
10 changes: 4 additions & 6 deletions packages/language-core/lib/codegen/script/template.ts
Original file line number Diff line number Diff line change
Expand Up @@ -131,12 +131,10 @@ function* generateTemplateBody(
yield `const __VLS_rootEl = {} as any${endOfLine}`;
}

yield `return {${newLine}`;
yield ` attrs: {} as Partial<typeof __VLS_inheritedAttrs>,${newLine}`;
yield ` slots: ${options.scriptSetupRanges?.defineSlots?.name ?? '__VLS_slots'},${newLine}`;
yield ` refs: __VLS_refs,${newLine}`;
yield ` rootEl: __VLS_rootEl,${newLine}`;
yield `}${endOfLine}`;
yield `type __VLS_TemplateAttrs = Partial<typeof __VLS_inheritedAttrs>${endOfLine}`;
yield `type __VLS_TemplateSlots = typeof ${options.scriptSetupRanges?.defineSlots?.name ?? '__VLS_slots'}${endOfLine}`;
yield `type __VLS_TemplateRefs = typeof __VLS_refs${endOfLine}`;
yield `type __VLS_TemplateEl = typeof __VLS_rootEl${endOfLine}`;
}

function* generateStyleScopedClasses(
Expand Down
156 changes: 72 additions & 84 deletions packages/tsc/tests/__snapshots__/dts.spec.ts.snap
Original file line number Diff line number Diff line change
Expand Up @@ -617,27 +617,26 @@ export {};
`;

exports[`vue-tsc-dts > Input: template-slots/component.vue, Output: template-slots/component.vue.d.ts 1`] = `
"declare function __VLS_template(): {
attrs: Partial<{}>;
slots: {
'no-bind'?(_: {}): any;
default?(_: {
num: number;
}): any;
'named-slot'?(_: {
str: string;
}): any;
vbind?(_: {
num: number;
str: string;
}): any;
};
refs: {};
rootEl: any;
"declare var __VLS_0: {};
declare var __VLS_1: {
num: number;
};
declare var __VLS_2: {
str: string;
};
type __VLS_TemplateResult = ReturnType<typeof __VLS_template>;
declare var __VLS_3: {
num: number;
str: string;
};
declare var __VLS_slots: {
'no-bind'?(_: typeof __VLS_0): any;
default?(_: typeof __VLS_1): any;
'named-slot'?(_: typeof __VLS_2): any;
vbind?(_: typeof __VLS_3): any;
};
type __VLS_TemplateSlots = typeof __VLS_slots;
declare const __VLS_component: import("vue").DefineComponent<{}, {}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {}, string, import("vue").PublicProps, Readonly<{}> & Readonly<{}>, {}, {}, {}, {}, string, import("vue").ComponentProvideOptions, true, {}, any>;
declare const _default: __VLS_WithTemplateSlots<typeof __VLS_component, __VLS_TemplateResult["slots"]>;
declare const _default: __VLS_WithTemplateSlots<typeof __VLS_component, __VLS_TemplateSlots>;
export default _default;
type __VLS_WithTemplateSlots<T, S> = T & {
new (): {
Expand All @@ -649,39 +648,34 @@ 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 function __VLS_template(): {
attrs: Partial<{}>;
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: {};
rootEl: any;
declare const __VLS_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[];
};
type __VLS_TemplateResult = ReturnType<typeof __VLS_template>;
type __VLS_TemplateSlots = typeof __VLS_slots;
declare const __VLS_component: import("vue").DefineComponent<{}, {}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {}, string, import("vue").PublicProps, Readonly<{}> & Readonly<{}>, {}, {}, {}, {}, string, import("vue").ComponentProvideOptions, true, {}, any>;
declare const _default: __VLS_WithTemplateSlots<typeof __VLS_component, __VLS_TemplateResult["slots"]>;
declare const _default: __VLS_WithTemplateSlots<typeof __VLS_component, __VLS_TemplateSlots>;
export default _default;
type __VLS_WithTemplateSlots<T, S> = T & {
new (): {
Expand All @@ -692,23 +686,18 @@ 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 function __VLS_template(): {
attrs: Partial<{}>;
slots: Readonly<{
bottom: (props: {
num: number;
}) => any[];
}> & {
bottom: (props: {
num: number;
}) => any[];
};
refs: {};
rootEl: any;
"declare const __VLS_slots: Readonly<{
bottom: (props: {
num: number;
}) => any[];
}> & {
bottom: (props: {
num: number;
}) => any[];
};
type __VLS_TemplateResult = ReturnType<typeof __VLS_template>;
type __VLS_TemplateSlots = typeof __VLS_slots;
declare const __VLS_component: import("vue").DefineComponent<{}, {}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {}, string, import("vue").PublicProps, Readonly<{}> & Readonly<{}>, {}, {}, {}, {}, string, import("vue").ComponentProvideOptions, true, {}, any>;
declare const _default: __VLS_WithTemplateSlots<typeof __VLS_component, __VLS_TemplateResult["slots"]>;
declare const _default: __VLS_WithTemplateSlots<typeof __VLS_component, __VLS_TemplateSlots>;
export default _default;
type __VLS_WithTemplateSlots<T, S> = T & {
new (): {
Expand All @@ -719,27 +708,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 function __VLS_template(): {
attrs: Partial<{}>;
slots: {
'no-bind'?(_: {}): any;
default?(_: {
num: number;
}): any;
'named-slot'?(_: {
str: string;
}): any;
vbind?(_: {
num: number;
str: string;
}): any;
};
refs: {};
rootEl: any;
"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 var __VLS_slots: {
'no-bind'?(_: typeof __VLS_0): any;
default?(_: typeof __VLS_1): any;
'named-slot'?(_: typeof __VLS_2): any;
vbind?(_: typeof __VLS_3): any;
};
type __VLS_TemplateResult = ReturnType<typeof __VLS_template>;
type __VLS_TemplateSlots = typeof __VLS_slots;
declare const __VLS_component: import("vue").DefineComponent<{}, {}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {}, string, import("vue").PublicProps, Readonly<{}> & Readonly<{}>, {}, {}, {}, {}, string, import("vue").ComponentProvideOptions, true, {}, any>;
declare const _default: __VLS_WithTemplateSlots<typeof __VLS_component, __VLS_TemplateResult["slots"]>;
declare const _default: __VLS_WithTemplateSlots<typeof __VLS_component, __VLS_TemplateSlots>;
export default _default;
type __VLS_WithTemplateSlots<T, S> = T & {
new (): {
Expand Down
Loading