Skip to content

Commit

Permalink
refactor(language-core): optimize codegen size of scoped classes
Browse files Browse the repository at this point in the history
  • Loading branch information
KazariEX committed Dec 18, 2024
1 parent 6c5f9bb commit 9daef54
Show file tree
Hide file tree
Showing 4 changed files with 63 additions and 52 deletions.
91 changes: 49 additions & 42 deletions packages/language-core/lib/codegen/script/template.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,11 +3,28 @@ import type { Code } from '../../types';
import { getSlotsPropertyName, hyphenateTag } from '../../utils/shared';
import { TemplateCodegenContext, createTemplateCodegenContext } from '../template/context';
import { generateInterpolation } from '../template/interpolation';
import { generateStyleScopedClasses } from '../template/styleScopedClasses';
import { generateStyleScopedClassReferences } from '../template/styleScopedClasses';
import { endOfLine, newLine } from '../utils';
import type { ScriptCodegenContext } from './context';
import { codeFeatures, type ScriptCodegenOptions } from './index';

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

const templateCodegenCtx = createTemplateCodegenContext({
scriptSetupBindingNames: new Set(),
edited: options.edited,
});
yield* generateTemplateCtx(options);
yield* generateTemplateComponents(options);
yield* generateTemplateDirectives(options);
yield* generateTemplateBody(options, templateCodegenCtx);
return templateCodegenCtx;
}

function* generateTemplateCtx(options: ScriptCodegenOptions): Generator<Code> {
const exps = [];

Expand Down Expand Up @@ -107,36 +124,50 @@ export function* generateTemplateDirectives(options: ScriptCodegenOptions): Gene
yield `let __VLS_directives!: typeof __VLS_localDirectives & __VLS_GlobalDirectives${endOfLine}`;
}

export function* generateTemplate(
function* generateTemplateBody(
options: ScriptCodegenOptions,
ctx: ScriptCodegenContext
): Generator<Code, TemplateCodegenContext> {
ctx.generatedTemplate = true;
templateCodegenCtx: TemplateCodegenContext
): Generator<Code> {
yield* generateStyleScopedClasses(options, templateCodegenCtx);
yield* generateStyleScopedClassReferences(templateCodegenCtx, true);
yield* generateCssVars(options, templateCodegenCtx);

const templateCodegenCtx = createTemplateCodegenContext({
scriptSetupBindingNames: new Set(),
edited: options.edited,
});
yield* generateTemplateCtx(options);
yield* generateTemplateComponents(options);
yield* generateTemplateDirectives(options);
yield* generateTemplateBody(options, templateCodegenCtx);
return templateCodegenCtx;
if (options.templateCodegen) {
for (const code of options.templateCodegen.codes) {
yield code;
}
}
else {
yield `// no template${newLine}`;
if (!options.scriptSetupRanges?.defineSlots) {
yield `const __VLS_slots = {}${endOfLine}`;
}
yield `const __VLS_inheritedAttrs = {}${endOfLine}`;
yield `const $refs = {}${endOfLine}`;
yield `const $el = {} 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: $refs,${newLine}`;
yield ` rootEl: $el,${newLine}`;
yield `}${endOfLine}`;
}

function* generateTemplateBody(
function* generateStyleScopedClasses(
options: ScriptCodegenOptions,
templateCodegenCtx: TemplateCodegenContext
ctx: TemplateCodegenContext
): Generator<Code> {
const firstClasses = new Set<string>();
yield `let __VLS_styleScopedClasses!: {}`;
yield `type __VLS_StyleScopedClasses = {}`;
for (let i = 0; i < options.sfc.styles.length; i++) {
const style = options.sfc.styles[i];
const option = options.vueCompilerOptions.experimentalResolveStyleCssClasses;
if (option === 'always' || (option === 'scoped' && style.scoped)) {
for (const className of style.classNames) {
if (firstClasses.has(className.text)) {
templateCodegenCtx.scopedClasses.push({
ctx.scopedClasses.push({
source: 'style_' + i,
className: className.text.slice(1),
offset: className.offset + 1
Expand All @@ -155,30 +186,6 @@ function* generateTemplateBody(
}
}
yield endOfLine;
yield* generateStyleScopedClasses(templateCodegenCtx, true);
yield* generateCssVars(options, templateCodegenCtx);

if (options.templateCodegen) {
for (const code of options.templateCodegen.codes) {
yield code;
}
}
else {
yield `// no template${newLine}`;
if (!options.scriptSetupRanges?.defineSlots) {
yield `const __VLS_slots = {}${endOfLine}`;
}
yield `const __VLS_inheritedAttrs = {}${endOfLine}`;
yield `const $refs = {}${endOfLine}`;
yield `const $el = {} 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: $refs,${newLine}`;
yield ` rootEl: $el,${newLine}`;
yield `}${endOfLine}`;
}

export function* generateCssClassProperty(
Expand Down
4 changes: 2 additions & 2 deletions packages/language-core/lib/codegen/template/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ import { generateStringLiteralKey } from '../utils/stringLiteralKey';
import { TemplateCodegenContext, createTemplateCodegenContext } from './context';
import { getCanonicalComponentName, getPossibleOriginalComponentNames } from './element';
import { generateObjectProperty } from './objectProperty';
import { generateStyleScopedClasses } from './styleScopedClasses';
import { generateStyleScopedClassReferences } from './styleScopedClasses';
import { generateTemplateChild, getVForNode } from './templateChild';

export interface TemplateCodegenOptions {
Expand Down Expand Up @@ -46,7 +46,7 @@ export function* generateTemplate(options: TemplateCodegenOptions): Generator<Co
yield* generateTemplateChild(options, ctx, options.template.ast, undefined, undefined, undefined);
}

yield* generateStyleScopedClasses(ctx);
yield* generateStyleScopedClassReferences(ctx);
yield* generateSlots(options, ctx);
yield* generateInheritedAttrs(ctx);
yield* generateRefs(ctx);
Expand Down
18 changes: 11 additions & 7 deletions packages/language-core/lib/codegen/template/styleScopedClasses.ts
Original file line number Diff line number Diff line change
@@ -1,23 +1,27 @@
import type { Code } from '../../types';
import { endOfLine, newLine } from '../utils';
import { endOfLine } from '../utils';
import type { TemplateCodegenContext } from './context';

export function* generateStyleScopedClasses(
export function* generateStyleScopedClassReferences(
ctx: TemplateCodegenContext,
withDot = false
): Generator<Code> {
if (!ctx.emptyClassOffsets.length && !ctx.scopedClasses.length) {
return;
}

yield `[`;
for (const offset of ctx.emptyClassOffsets) {
yield `__VLS_styleScopedClasses['`;
yield `'`;
yield [
'',
'template',
offset,
ctx.codeFeatures.additionalCompletion,
];
yield `']${endOfLine}`;
yield `', `;
}
for (const { source, className, offset } of ctx.scopedClasses) {
yield `__VLS_styleScopedClasses[`;
yield [
'',
source,
Expand All @@ -35,9 +39,9 @@ export function* generateStyleScopedClasses(
offset + className.length,
ctx.codeFeatures.navigationWithoutRename,
];
yield `]${endOfLine}`;
yield `, `;
}
yield newLine;
yield `] as (keyof __VLS_StyleScopedClasses)[]${endOfLine}`;

function* escapeString(source: string, className: string, offset: number, escapeTargets: string[]): Generator<Code> {
let count = 0;
Expand Down
2 changes: 1 addition & 1 deletion test-workspace/tsc/passedFixtures/#3688/main.vue
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
<template>
{{ () => {
exactType(__VLS_styleScopedClasses, {} as { 'foo'?: boolean });
exactType({} as __VLS_StyleScopedClasses, {} as { 'foo'?: boolean });
} }}
</template>

Expand Down

0 comments on commit 9daef54

Please sign in to comment.