Skip to content

Commit

Permalink
refactor(language-core): do not wrap template virtual code with funct…
Browse files Browse the repository at this point in the history
…ion (#4731)
  • Loading branch information
johnsoncodehk authored Aug 27, 2024
1 parent 5936c82 commit 13924d1
Show file tree
Hide file tree
Showing 8 changed files with 130 additions and 137 deletions.
2 changes: 1 addition & 1 deletion packages/language-core/lib/codegen/script/component.ts
Original file line number Diff line number Diff line change
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 = `ReturnType<typeof __VLS_template>['attrs']`;
let attrsType = `typeof __VLS_templateResult['attrs']`;
if (hasEmitsOption) {
attrsType = `Omit<${attrsType}, \`on\${string}\`>`;
}
Expand Down
6 changes: 1 addition & 5 deletions packages/language-core/lib/codegen/script/globalTypes.ts
Original file line number Diff line number Diff line change
Expand Up @@ -66,11 +66,7 @@ declare global {
function __VLS_makeOptional<T>(t: T): { [K in keyof T]?: T[K] };
function __VLS_nonNullable<T>(t: T): T extends null | undefined ? never : T;
type __VLS_SelfComponent<N, C> = string extends N ? {} : N extends string ? { [P in N]: C } : {};
type __VLS_WithComponent<N0 extends string, Ctx, LocalComponents, N1 extends string, N2 extends string, N3 extends string> =
N1 extends keyof Ctx ? N1 extends N0 ? Pick<Ctx, N0 extends keyof Ctx ? N0 : never> : { [K in N0]: Ctx[N1] } :
N2 extends keyof Ctx ? N2 extends N0 ? Pick<Ctx, N0 extends keyof Ctx ? N0 : never> : { [K in N0]: Ctx[N2] } :
N3 extends keyof Ctx ? N3 extends N0 ? Pick<Ctx, N0 extends keyof Ctx ? N0 : never> : { [K in N0]: Ctx[N3] } :
type __VLS_WithComponent<N0 extends string, LocalComponents, N1 extends string, N2 extends string, N3 extends string> =
N1 extends keyof LocalComponents ? N1 extends N0 ? Pick<LocalComponents, N0 extends keyof LocalComponents ? N0 : never> : { [K in N0]: LocalComponents[N1] } :
N2 extends keyof LocalComponents ? N2 extends N0 ? Pick<LocalComponents, N0 extends keyof LocalComponents ? N0 : never> : { [K in N0]: LocalComponents[N2] } :
N3 extends keyof LocalComponents ? N3 extends N0 ? Pick<LocalComponents, N0 extends keyof LocalComponents ? N0 : never> : { [K in N0]: LocalComponents[N3] } :
Expand Down
27 changes: 12 additions & 15 deletions packages/language-core/lib/codegen/script/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -101,9 +101,16 @@ export function* generateScript(options: ScriptCodegenOptions): Generator<Code,
yield generateSfcBlockSection(options.sfc.script, exportDefault.expression.end, options.sfc.script.content.length, codeFeatures.all);
}
else if (classBlockEnd !== undefined) {
yield generateSfcBlockSection(options.sfc.script, 0, classBlockEnd, codeFeatures.all);
yield* generateTemplate(options, ctx, true);
yield generateSfcBlockSection(options.sfc.script, classBlockEnd, options.sfc.script.content.length, codeFeatures.all);
if (options.vueCompilerOptions.skipTemplateCodegen) {
yield generateSfcBlockSection(options.sfc.script, 0, options.sfc.script.content.length, codeFeatures.all);
}
else {
yield generateSfcBlockSection(options.sfc.script, 0, classBlockEnd, codeFeatures.all);
yield `__VLS_template = () => {`;
yield* generateTemplate(options, ctx, true);
yield `},${newLine}`;
yield generateSfcBlockSection(options.sfc.script, classBlockEnd, options.sfc.script.content.length, codeFeatures.all);
}
}
else {
yield generateSfcBlockSection(options.sfc.script, 0, options.sfc.script.content.length, codeFeatures.all);
Expand All @@ -118,12 +125,7 @@ export function* generateScript(options: ScriptCodegenOptions): Generator<Code,
yield `;`;
if (options.sfc.scriptSetup) {
// #4569
yield [
'',
'scriptSetup',
options.sfc.scriptSetup.content.length,
codeFeatures.verification,
];
yield ['', 'scriptSetup', options.sfc.scriptSetup.content.length, codeFeatures.verification];
}
yield newLine;

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

if (options.sfc.scriptSetup) {
yield [
'',
'scriptSetup',
options.sfc.scriptSetup.content.length,
codeFeatures.verification,
];
yield ['', 'scriptSetup', options.sfc.scriptSetup.content.length, codeFeatures.verification];
}

return ctx;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,8 +12,7 @@ export function* generateInternalComponent(
templateCodegenCtx: TemplateCodegenContext
): Generator<Code> {
if (options.sfc.scriptSetup && options.scriptSetupRanges) {
yield `let __VLS_defineComponent!: typeof import('${options.vueCompilerOptions.lib}').defineComponent${endOfLine}`;
yield `const __VLS_internalComponent = __VLS_defineComponent({${newLine}`;
yield `const __VLS_internalComponent = (await import('${options.vueCompilerOptions.lib}')).defineComponent({${newLine}`;
yield `setup() {${newLine}`;
yield `return {${newLine}`;
if (ctx.bypassDefineComponent) {
Expand Down
4 changes: 2 additions & 2 deletions packages/language-core/lib/codegen/script/scriptSetup.ts
Original file line number Diff line number Diff line change
Expand Up @@ -280,8 +280,8 @@ function* generateSetupFunction(
yield* generateModelEmits(options, scriptSetup, scriptSetupRanges);
yield* generateStyleModules(options, ctx);
yield* generateTemplate(options, ctx, false);
yield `type __VLS_Refs = ReturnType<typeof __VLS_template>['refs']${endOfLine}`;
yield `type __VLS_Slots = ReturnType<typeof __VLS_template>['slots']${endOfLine}`;
yield `type __VLS_Refs = typeof __VLS_templateResult['refs']${endOfLine}`;
yield `type __VLS_Slots = typeof __VLS_templateResult['slots']${endOfLine}`;

if (syntax) {
if (!options.vueCompilerOptions.skipTemplateCodegen && (options.templateCodegen?.hasSlot || scriptSetupRanges?.slots.define)) {
Expand Down
131 changes: 58 additions & 73 deletions packages/language-core/lib/codegen/script/template.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,114 +4,99 @@ import { getSlotsPropertyName, hyphenateTag } from '../../utils/shared';
import { endOfLine, newLine } from '../common';
import { TemplateCodegenContext, createTemplateCodegenContext } from '../template/context';
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';
import { generateStyleScopedClasses } from '../template/styleScopedClasses';

export function* generateTemplate(
options: ScriptCodegenOptions,
ctx: ScriptCodegenContext,
isClassComponent: boolean
): Generator<Code> {
ctx.generatedTemplate = true;

if (!options.vueCompilerOptions.skipTemplateCodegen) {
if (isClassComponent) {
yield `__VLS_template = (() => {${newLine}`;
}
else {
yield `const __VLS_template = (() => {${newLine}`;
}
const templateCodegenCtx = createTemplateCodegenContext({ scriptSetupBindingNames: new Set(), edited: options.edited });
yield `const __VLS_template_return = () => {${newLine}`;
yield* generateCtx(options, isClassComponent);
yield* generateTemplateContext(options, templateCodegenCtx);
yield* generateExportOptions(options);
yield* generateConstNameOption(options);
yield `}${endOfLine}`;
yield* generateInternalComponent(options, ctx, templateCodegenCtx);
yield `return __VLS_template_return${endOfLine}`;
yield `})()${endOfLine}`;
export function* generateTemplateCtx(options: ScriptCodegenOptions, isClassComponent: boolean): Generator<Code> {
const types = [];
if (isClassComponent) {
types.push(`typeof this`);
}
else {
yield `function __VLS_template() {${newLine}`;
const templateUsageVars = [...getTemplateUsageVars(options, ctx)];
yield `// @ts-ignore${newLine}`;
yield `[${templateUsageVars.join(', ')}]${newLine}`;
yield `return { slots: {}, refs: {}, attrs: {} }${endOfLine}`;
yield `}${newLine}`;
types.push(`InstanceType<__VLS_PickNotAny<typeof __VLS_internalComponent, new () => {}>>`);
}
if (options.vueCompilerOptions.petiteVueExtensions.some(ext => options.fileBaseName.endsWith(ext))) {
types.push(`typeof globalThis`);
}
if (options.sfc.styles.some(style => style.module)) {
types.push(`__VLS_StyleModules`);
}
yield `let __VLS_ctx!: ${types.join(' & ')}${endOfLine}`;
}

function* generateExportOptions(options: ScriptCodegenOptions): Generator<Code> {
yield newLine;
yield `const __VLS_componentsOption = `;
export function* generateTemplateComponents(options: ScriptCodegenOptions): Generator<Code> {
const exps: Code[] = [];

if (options.sfc.script && options.scriptRanges?.exportDefault?.componentsOption) {
const componentsOption = options.scriptRanges.exportDefault.componentsOption;
yield [
const { componentsOption } = options.scriptRanges.exportDefault;
exps.push([
options.sfc.script.content.substring(componentsOption.start, componentsOption.end),
'script',
componentsOption.start,
codeFeatures.navigation,
];
}
else {
yield `{}`;
]);
}
yield endOfLine;
}

function* generateConstNameOption(options: ScriptCodegenOptions): Generator<Code> {
let nameType: Code | undefined;
if (options.sfc.script && options.scriptRanges?.exportDefault?.nameOption) {
const nameOption = options.scriptRanges.exportDefault.nameOption;
yield `const __VLS_name = `;
yield `${options.sfc.script.content.substring(nameOption.start, nameOption.end)} as const`;
yield endOfLine;
const { nameOption } = options.scriptRanges.exportDefault;
nameType = options.sfc.script.content.substring(nameOption.start, nameOption.end);
}
else if (options.sfc.scriptSetup) {
yield `let __VLS_name!: '${options.scriptSetupRanges?.options.name ?? options.fileBaseName.substring(0, options.fileBaseName.lastIndexOf('.'))}'${endOfLine}`;
nameType = 'typeof __VLS_name';
}
else {
yield `const __VLS_name = undefined${endOfLine}`;
if (nameType) {
exps.push(`{} as {
[K in ${nameType}]: typeof __VLS_internalComponent
& (new () => {
${getSlotsPropertyName(options.vueCompilerOptions.target)}: typeof ${options.scriptSetupRanges?.slots?.name ?? '__VLS_slots'}
})
}`);
}

exps.push(`{} as NonNullable<typeof __VLS_internalComponent extends { components: infer C } ? C : {}>`);
exps.push(`{} as __VLS_GlobalComponents`);
exps.push(`{} as typeof __VLS_ctx`);

yield `const __VLS_components = {${newLine}`;
for (const type of exps) {
yield `...`;
yield type;
yield `,${newLine}`;
}
yield `}${endOfLine}`;
}

function* generateCtx(
export function* generateTemplate(
options: ScriptCodegenOptions,
ctx: ScriptCodegenContext,
isClassComponent: boolean
): Generator<Code> {
yield `let __VLS_ctx!: `;
if (options.vueCompilerOptions.petiteVueExtensions.some(ext => options.fileBaseName.endsWith(ext))) {
yield `typeof globalThis & `;
}
if (!isClassComponent) {
yield `InstanceType<__VLS_PickNotAny<typeof __VLS_internalComponent, new () => {}>>`;
ctx.generatedTemplate = true;

if (!options.vueCompilerOptions.skipTemplateCodegen) {
const templateCodegenCtx = createTemplateCodegenContext({ scriptSetupBindingNames: new Set(), edited: options.edited });
yield* generateTemplateCtx(options, isClassComponent);
yield* generateTemplateComponents(options);
yield* generateTemplateBody(options, templateCodegenCtx);
yield* generateInternalComponent(options, ctx, templateCodegenCtx);
}
else {
yield `typeof this`;
}
/* CSS Module */
if (options.sfc.styles.some(style => style.module)) {
yield ` & __VLS_StyleModules`;
const templateUsageVars = [...getTemplateUsageVars(options, ctx)];
yield `// @ts-ignore${newLine}`;
yield `[${templateUsageVars.join(', ')}]${newLine}`;
yield `const __VLS_templateResult { slots: {}, refs: {}, attrs: {} }${endOfLine}`;
}
yield endOfLine;
}

function* generateTemplateContext(
function* generateTemplateBody(
options: ScriptCodegenOptions,
templateCodegenCtx: TemplateCodegenContext
): Generator<Code> {
/* Components */
yield `/* Components */${newLine}`;
yield `let __VLS_otherComponents!: NonNullable<typeof __VLS_internalComponent extends { components: infer C } ? C : {}> & typeof __VLS_componentsOption${endOfLine}`;
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}`;
yield `let __VLS_localComponents!: typeof __VLS_otherComponents & Omit<typeof __VLS_own, keyof typeof __VLS_otherComponents>${endOfLine}`;
yield `let __VLS_components!: typeof __VLS_localComponents & __VLS_GlobalComponents & typeof __VLS_ctx${endOfLine}`; // for html completion, TS references...

/* Style Scoped */
const firstClasses = new Set<string>();
yield `/* Style Scoped */${newLine}`;
yield `let __VLS_styleScopedClasses!: {}`;
for (let i = 0; i < options.sfc.styles.length; i++) {
const style = options.sfc.styles[i];
Expand Down Expand Up @@ -155,7 +140,7 @@ function* generateTemplateContext(
}
}

yield `return {${newLine}`;
yield `const __VLS_templateResult = {`;
yield `slots: ${options.scriptSetupRanges?.slots.name ?? '__VLS_slots'},${newLine}`;
yield `refs: __VLS_refs as __VLS_PickRefsExpose<typeof __VLS_refs>,${newLine}`;
yield `attrs: {} as Partial<typeof __VLS_inheritedAttrs>,${newLine}`;
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 @@ -120,7 +120,7 @@ export function* generateTemplate(options: TemplateCodegenOptions): Generator<Co
}
components.add(node.tag);
yield newLine;
yield ` & __VLS_WithComponent<'${getCanonicalComponentName(node.tag)}', typeof __VLS_ctx, typeof __VLS_localComponents, `;
yield ` & __VLS_WithComponent<'${getCanonicalComponentName(node.tag)}', typeof __VLS_components, `;
yield getPossibleOriginalComponentNames(node.tag, false)
.map(name => `"${name}"`)
.join(', ');
Expand Down
Loading

0 comments on commit 13924d1

Please sign in to comment.