Skip to content

Commit

Permalink
refactor: use __VLS_special
Browse files Browse the repository at this point in the history
  • Loading branch information
KazariEX committed Dec 31, 2024
1 parent e3e2f46 commit 62bf2af
Show file tree
Hide file tree
Showing 4 changed files with 35 additions and 64 deletions.
2 changes: 2 additions & 0 deletions packages/language-core/lib/codegen/template/context.ts
Original file line number Diff line number Diff line change
Expand Up @@ -103,6 +103,7 @@ export function createTemplateCodegenContext(options: Pick<TemplateCodegenOption
},
});
const localVars = new Map<string, number>();
const specialVars = new Set<string>();
const accessExternalVariables = new Map<string, Set<number>>();
const slots: {
name: string;
Expand Down Expand Up @@ -132,6 +133,7 @@ export function createTemplateCodegenContext(options: Pick<TemplateCodegenOption
slots,
dynamicSlots,
codeFeatures,
specialVars,
accessExternalVariables,
lastGenericComment,
hasSlotElements,
Expand Down
60 changes: 21 additions & 39 deletions packages/language-core/lib/codegen/template/index.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
import type { Mapping } from '@volar/language-core';
import * as CompilerDOM from '@vue/compiler-dom';
import type * as ts from 'typescript';
import type { Code, Sfc, VueCompilerOptions } from '../../types';
Expand All @@ -25,8 +24,6 @@ export interface TemplateCodegenOptions {
propsAssignName?: string;
inheritAttrs: boolean;
selfComponentName?: string;
getGeneratedLength: () => number;
linkedCodeMappings: Mapping[];
}

export function* generateTemplate(options: TemplateCodegenOptions): Generator<Code, TemplateCodegenContext> {
Expand All @@ -38,20 +35,29 @@ export function* generateTemplate(options: TemplateCodegenOptions): Generator<Co
if (options.propsAssignName) {
ctx.addLocalVariable(options.propsAssignName);
}
ctx.addLocalVariable(getSlotsPropertyName(options.vueCompilerOptions.target));
ctx.addLocalVariable('$attrs');
ctx.addLocalVariable('$refs');
ctx.addLocalVariable('$el');
const slotsPropertyName = getSlotsPropertyName(options.vueCompilerOptions.target);
ctx.specialVars.add(slotsPropertyName);
ctx.specialVars.add('$attrs');
ctx.specialVars.add('$refs');
ctx.specialVars.add('$el');

if (options.template.ast) {
yield* generateTemplateChild(options, ctx, options.template.ast, undefined);
}

yield* generateStyleScopedClassReferences(ctx);
yield* generateSlots(options, ctx);
yield* generateInheritedAttrs(options, ctx);
yield* generateRefs(options, ctx);
yield* generateRootEl(options, ctx);
const speicalTypes = [
[slotsPropertyName, yield* generateSlots(options, ctx)],
['$attrs', yield* generateInheritedAttrs(ctx)],
['$refs', yield* generateRefs(ctx)],
['$el', yield* generateRootEl(ctx)]
];

yield `var __VLS_special!: {${newLine}`;
for (const [name, type] of speicalTypes) {
yield `${name}: ${type}${endOfLine}`;
}
yield `} & { [K in keyof typeof __VLS_ctx]: unknown }${endOfLine}`;

yield* ctx.generateAutoImportCompletion();
return ctx;
Expand Down Expand Up @@ -92,20 +98,17 @@ function* generateSlots(
}
yield `}${endOfLine}`;
}
const name = getSlotsPropertyName(options.vueCompilerOptions.target);
yield* generateContextVariable(options, name, `typeof ${options.slotsAssignName ?? `__VLS_slots`}`);
return `typeof ${options.slotsAssignName ?? `__VLS_slots`}`;
}

function* generateInheritedAttrs(
options: TemplateCodegenOptions,
ctx: TemplateCodegenContext
): Generator<Code> {
yield 'let __VLS_inheritedAttrs!: {}';
for (const varName of ctx.inheritedAttrVars) {
yield ` & typeof ${varName}`;
}
yield endOfLine;
yield* generateContextVariable(options, `$attrs`, `Partial<typeof __VLS_inheritedAttrs> & Record<string, unknown>`);

if (ctx.bindingAttrLocs.length) {
yield `[`;
Expand All @@ -120,10 +123,10 @@ function* generateInheritedAttrs(
}
yield `]${endOfLine}`;
}
return `Partial<typeof __VLS_inheritedAttrs> & Record<string, unknown>`;
}

function* generateRefs(
options: TemplateCodegenOptions,
ctx: TemplateCodegenContext
): Generator<Code> {
yield `const __VLS_refs = {${newLine}`;
Expand All @@ -136,37 +139,16 @@ function* generateRefs(
yield `: ${varName},${newLine}`;
}
yield `}${endOfLine}`;
yield* generateContextVariable(options, `$refs`, `typeof __VLS_refs`);
return `typeof __VLS_refs`;
}

function* generateRootEl(
options: TemplateCodegenOptions,
ctx: TemplateCodegenContext
): Generator<Code> {
yield `let __VLS_rootEl!: `;
yield ctx.singleRootElType ?? `any`;
yield endOfLine;
yield* generateContextVariable(options, `$el`, `typeof __VLS_rootEl`);
}

function* generateContextVariable(
options: TemplateCodegenOptions,
varName: string,
typeExp: string
): Generator<Code> {
yield `/** @type { typeof __VLS_ctx.`;
const sourceOffset = options.getGeneratedLength();
yield `${varName} } */${endOfLine}`;
yield `var `;
const generatedOffset = options.getGeneratedLength();
yield `${varName}!: ${typeExp}${endOfLine}`;

options.linkedCodeMappings.push({
sourceOffsets: [sourceOffset],
generatedOffsets: [generatedOffset],
lengths: [varName.length],
data: undefined,
});
return `typeof __VLS_rootEl`;
}

export function* forEachElementNode(node: CompilerDOM.RootNode | CompilerDOM.TemplateChildNode): Generator<CompilerDOM.ElementNode> {
Expand Down
10 changes: 7 additions & 3 deletions packages/language-core/lib/codegen/template/interpolation.ts
Original file line number Diff line number Diff line change
Expand Up @@ -134,7 +134,7 @@ function* forEachInterpolationSegment(
const curVar = ctxVars[i];
const nextVar = ctxVars[i + 1];

yield* generateVar(code, destructuredPropNames, templateRefNames, curVar, nextVar);
yield* generateVar(code, ctx.specialVars, destructuredPropNames, templateRefNames, curVar, nextVar);

if (nextVar.isShorthand) {
yield [code.slice(curVar.offset + curVar.text.length, nextVar.offset + nextVar.text.length), curVar.offset + curVar.text.length];
Expand All @@ -146,7 +146,7 @@ function* forEachInterpolationSegment(
}

const lastVar = ctxVars.at(-1)!;
yield* generateVar(code, destructuredPropNames, templateRefNames, lastVar);
yield* generateVar(code, ctx.specialVars, destructuredPropNames, templateRefNames, lastVar);
if (lastVar.offset + lastVar.text.length < code.length) {
yield [code.slice(lastVar.offset + lastVar.text.length), lastVar.offset + lastVar.text.length, 'endText'];
}
Expand All @@ -158,6 +158,7 @@ function* forEachInterpolationSegment(

function* generateVar(
code: string,
specialVars: Set<string>,
destructuredPropNames: Set<string> | undefined,
templateRefNames: Set<string> | undefined,
curVar: CtxVar,
Expand All @@ -175,7 +176,10 @@ function* generateVar(
yield [`)`, undefined];
}
else {
if (!isDestructuredProp) {
if (specialVars.has(curVar.text)) {
yield [`__VLS_special.`, undefined];
}
else if (!isDestructuredProp) {
yield [`__VLS_ctx.`, undefined];
}
yield [code.slice(curVar.offset, curVar.offset + curVar.text.length), curVar.offset];
Expand Down
27 changes: 5 additions & 22 deletions packages/language-core/lib/plugins/vue-tsx.ts
Original file line number Diff line number Diff line change
Expand Up @@ -41,22 +41,13 @@ const plugin: VueLanguagePlugin = ctx => {

resolveEmbeddedCode(fileName, sfc, embeddedFile) {

const tsx = useTsx(fileName, sfc);
const _tsx = useTsx(fileName, sfc);

if (/script_(js|jsx|ts|tsx)/.test(embeddedFile.id)) {
const script = tsx.generatedScript.get();
const template = tsx.generatedTemplate.get();
if (script) {
const linkedCodeMappings = [
...script.linkedCodeMappings,
...template?.linkedCodeMappings.map(mapping => ({
...mapping,
sourceOffsets: mapping.sourceOffsets.map(offset => offset + script.templateGeneratedOffset!),
generatedOffsets: mapping.generatedOffsets.map(offset => offset + script.templateGeneratedOffset!),
})) ?? []
];
embeddedFile.content = [...script.codes];
embeddedFile.linkedCodeMappings = linkedCodeMappings;
const tsx = _tsx.generatedScript.get();
if (tsx) {
embeddedFile.content = [...tsx.codes];
embeddedFile.linkedCodeMappings = [...tsx.linkedCodeMappings];
}
}
},
Expand Down Expand Up @@ -184,8 +175,6 @@ function createTsx(
}

const codes: Code[] = [];
const linkedCodeMappings: Mapping[] = [];
let generatedLength = 0;
const codegen = generateTemplate({
ts,
compilerOptions: ctx.compilerOptions,
Expand All @@ -201,25 +190,19 @@ function createTsx(
propsAssignName: propsAssignName.get(),
inheritAttrs: inheritAttrs.get(),
selfComponentName: selfComponentName.get(),
getGeneratedLength: () => generatedLength,
linkedCodeMappings,
});

let current = codegen.next();

while (!current.done) {
const code = current.value;
codes.push(code);
generatedLength += typeof code === 'string'
? code.length
: code[0].length;
current = codegen.next();
}

return {
...current.value,
codes,
linkedCodeMappings,
};
});
const generatedScript = computed(() => {
Expand Down

0 comments on commit 62bf2af

Please sign in to comment.