Skip to content

Commit 72f9dcc

Browse files
committed
perf: drop internal component
1 parent 7cbcb3f commit 72f9dcc

File tree

11 files changed

+115
-102
lines changed

11 files changed

+115
-102
lines changed

packages/language-core/lib/codegen/script/componentSelf.ts

Lines changed: 0 additions & 72 deletions
This file was deleted.

packages/language-core/lib/codegen/script/index.ts

Lines changed: 3 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,6 @@ import { codeFeatures } from '../codeFeatures';
77
import type { TemplateCodegenContext } from '../template/context';
88
import { endOfLine, generateSfcBlockSection, newLine } from '../utils';
99
import { wrapWith } from '../utils/wrapWith';
10-
import { generateComponentSelf } from './componentSelf';
1110
import { createScriptCodegenContext, type ScriptCodegenContext } from './context';
1211
import { generateScriptSetup, generateScriptSetupImports } from './scriptSetup';
1312
import { generateSrc } from './src';
@@ -93,6 +92,7 @@ export function* generateScript(options: ScriptCodegenOptions): Generator<Code,
9392
if (wrapRight) {
9493
yield wrapRight;
9594
}
95+
yield endOfLine;
9696
}
9797
else if (classBlockEnd !== undefined) {
9898
if (options.vueCompilerOptions.skipTemplateCodegen) {
@@ -101,8 +101,7 @@ export function* generateScript(options: ScriptCodegenOptions): Generator<Code,
101101
else {
102102
yield generateSfcBlockSection(options.sfc.script, 0, classBlockEnd, codeFeatures.all);
103103
yield `__VLS_template = () => {${newLine}`;
104-
const templateCodegenCtx = yield* generateTemplate(options, ctx);
105-
yield* generateComponentSelf(options, ctx, templateCodegenCtx);
104+
yield* generateTemplate(options, ctx);
106105
yield `}${endOfLine}`;
107106
yield generateSfcBlockSection(
108107
options.sfc.script,
@@ -126,8 +125,7 @@ export function* generateScript(options: ScriptCodegenOptions): Generator<Code,
126125
}
127126

128127
if (!ctx.generatedTemplate) {
129-
const templateCodegenCtx = yield* generateTemplate(options, ctx);
130-
yield* generateComponentSelf(options, ctx, templateCodegenCtx);
128+
yield* generateTemplate(options, ctx);
131129
}
132130

133131
yield* generateExportDefault(options);

packages/language-core/lib/codegen/script/scriptSetup.ts

Lines changed: 14 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -2,11 +2,10 @@ import { camelize } from '@vue/shared';
22
import type { ScriptSetupRanges } from '../../parsers/scriptSetupRanges';
33
import type { Code, Sfc, TextRange } from '../../types';
44
import { codeFeatures } from '../codeFeatures';
5-
import { endOfLine, generateSfcBlockSection, newLine } from '../utils';
5+
import { endOfLine, generateSfcBlockSection, identifierRegex, newLine } from '../utils';
66
import { generateCamelized } from '../utils/camelized';
77
import { wrapWith } from '../utils/wrapWith';
88
import { generateComponent, generateEmitsOption } from './component';
9-
import { generateComponentSelf } from './componentSelf';
109
import type { ScriptCodegenContext } from './context';
1110
import { generateConstExport, generateScriptSectionPartiallyEnding, type ScriptCodegenOptions } from './index';
1211
import { generateTemplate } from './template';
@@ -302,8 +301,7 @@ function* generateSetupFunction(
302301

303302
yield* generateComponentProps(options, ctx, scriptSetup, scriptSetupRanges);
304303
yield* generateModelEmit(scriptSetup, scriptSetupRanges);
305-
const templateCodegenCtx = yield* generateTemplate(options, ctx);
306-
yield* generateComponentSelf(options, ctx, templateCodegenCtx);
304+
yield* generateTemplate(options, ctx);
307305

308306
if (syntax) {
309307
const prefix = syntax === 'return'
@@ -403,6 +401,18 @@ function* generateDefineWithType(
403401
];
404402
}
405403
}
404+
else if (!identifierRegex.test(name)) {
405+
yield [[`const ${defaultName} = `], statement.start, callExp.start];
406+
yield [
407+
[
408+
endOfLine,
409+
generateSfcBlockSection(scriptSetup, statement.start, callExp.start, codeFeatures.all),
410+
defaultName,
411+
],
412+
statement.end,
413+
statement.end,
414+
];
415+
}
406416
}
407417

408418
function* generateComponentProps(

packages/language-core/lib/codegen/script/template.ts

Lines changed: 86 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -6,32 +6,47 @@ import { generateStyleScopedClasses } from '../style/scopedClasses';
66
import { createTemplateCodegenContext, type TemplateCodegenContext } from '../template/context';
77
import { generateInterpolation } from '../template/interpolation';
88
import { generateStyleScopedClassReferences } from '../template/styleScopedClasses';
9-
import { endOfLine, newLine } from '../utils';
9+
import { endOfLine, generateSfcBlockSection, newLine } from '../utils';
1010
import { generateIntersectMerge, generateSpreadMerge } from '../utils/merge';
1111
import type { ScriptCodegenContext } from './context';
1212
import type { ScriptCodegenOptions } from './index';
1313

1414
export function* generateTemplate(
1515
options: ScriptCodegenOptions,
1616
ctx: ScriptCodegenContext,
17-
): Generator<Code, TemplateCodegenContext> {
17+
): Generator<Code> {
1818
ctx.generatedTemplate = true;
1919

2020
const templateCodegenCtx = createTemplateCodegenContext({
2121
scriptSetupBindingNames: new Set(),
2222
});
23-
yield* generateTemplateCtx(options);
23+
yield* generateBindings(options, ctx);
24+
yield* generateTemplateCtx(options, ctx);
2425
yield* generateTemplateElements();
2526
yield* generateTemplateComponents(options);
2627
yield* generateTemplateDirectives(options);
2728
yield* generateTemplateBody(options, templateCodegenCtx);
28-
return templateCodegenCtx;
29+
30+
if (options.sfc.script && options.scriptRanges?.exportDefault) {
31+
yield `const __VLS_self = (await import('${options.vueCompilerOptions.lib}')).defineComponent(`;
32+
const { args } = options.scriptRanges.exportDefault;
33+
yield generateSfcBlockSection(options.sfc.script, args.start, args.end, codeFeatures.all);
34+
yield `)${endOfLine}`;
35+
}
2936
}
3037

31-
function* generateTemplateCtx(options: ScriptCodegenOptions): Generator<Code> {
32-
const exps = [];
38+
function* generateTemplateCtx(
39+
options: ScriptCodegenOptions,
40+
ctx: ScriptCodegenContext,
41+
): Generator<Code> {
42+
const exps: Code[] = [];
3343

34-
exps.push(`{} as InstanceType<__VLS_PickNotAny<typeof __VLS_self, new () => {}>>`);
44+
if (options.sfc.script && options.scriptRanges?.exportDefault) {
45+
exps.push(`{} as InstanceType<__VLS_PickNotAny<typeof __VLS_self, new () => {}>>`);
46+
}
47+
else {
48+
exps.push(`{} as import('${options.vueCompilerOptions.lib}').ComponentPublicInstance`);
49+
}
3550

3651
if (options.vueCompilerOptions.petiteVueExtensions.some(ext => options.fileName.endsWith(ext))) {
3752
exps.push(`globalThis`);
@@ -40,6 +55,34 @@ function* generateTemplateCtx(options: ScriptCodegenOptions): Generator<Code> {
4055
exps.push(`{} as __VLS_StyleModules`);
4156
}
4257

58+
if (ctx.generatedPropsType || options.scriptSetupRanges?.defineProps) {
59+
yield `type __VLS_InternalProps = `;
60+
const { defineProps } = options.scriptSetupRanges ?? {};
61+
if (defineProps) {
62+
yield `__VLS_SpreadMerge<__VLS_PublicProps, typeof ${defineProps.name ?? `__VLS_props`}>`;
63+
}
64+
else {
65+
yield `__VLS_PublicProps`;
66+
}
67+
yield endOfLine;
68+
exps.push(`{} as __VLS_InternalProps`);
69+
exps.push(`{} as { $props: __VLS_InternalProps }`);
70+
}
71+
72+
const emitTypes: Code[] = [];
73+
if (options.scriptSetupRanges?.defineEmits) {
74+
emitTypes.push(`typeof ${options.scriptSetupRanges.defineEmits.name ?? `__VLS_emit`}`);
75+
}
76+
if (options.scriptSetupRanges?.defineModel.length) {
77+
emitTypes.push(`typeof __VLS_modelEmit`);
78+
}
79+
if (emitTypes.length) {
80+
yield `type __VLS_ResolvedEmit = ${emitTypes.join(' & ')}${endOfLine}`;
81+
exps.push(`{} as { $emit: __VLS_ResolvedEmit }`);
82+
}
83+
84+
exps.push(`{} as import('${options.vueCompilerOptions.lib}').ShallowUnwrapRef<typeof __VLS_bindings>`);
85+
4386
yield `const __VLS_ctx = `;
4487
yield* generateSpreadMerge(exps);
4588
yield endOfLine;
@@ -65,14 +108,14 @@ function* generateTemplateComponents(options: ScriptCodegenOptions): Generator<C
65108
types.push(`typeof __VLS_componentsOption`);
66109
}
67110

68-
yield `type __VLS_LocalComponents =`;
111+
yield `type __VLS_LocalComponents = `;
69112
yield* generateIntersectMerge(types);
70113
yield endOfLine;
71114

72115
yield `let __VLS_components!: __VLS_LocalComponents & __VLS_GlobalComponents${endOfLine}`;
73116
}
74117

75-
export function* generateTemplateDirectives(options: ScriptCodegenOptions): Generator<Code> {
118+
function* generateTemplateDirectives(options: ScriptCodegenOptions): Generator<Code> {
76119
const types: Code[] = [`typeof __VLS_ctx`];
77120

78121
if (options.sfc.script && options.scriptRanges?.exportDefault?.directivesOption) {
@@ -88,7 +131,7 @@ export function* generateTemplateDirectives(options: ScriptCodegenOptions): Gene
88131
types.push(`__VLS_ResolveDirectives<typeof __VLS_directivesOption>`);
89132
}
90133

91-
yield `type __VLS_LocalDirectives =`;
134+
yield `type __VLS_LocalDirectives = `;
92135
yield* generateIntersectMerge(types);
93136
yield endOfLine;
94137

@@ -138,7 +181,39 @@ function* generateCssVars(options: ScriptCodegenOptions, ctx: TemplateCodegenCon
138181
yield `// CSS variable injection end ${newLine}`;
139182
}
140183

141-
export function getTemplateUsageVars(options: ScriptCodegenOptions, ctx: ScriptCodegenContext) {
184+
function* generateBindings(
185+
options: ScriptCodegenOptions,
186+
ctx: ScriptCodegenContext,
187+
): Generator<Code> {
188+
yield `const __VLS_bindings = {${newLine}`;
189+
if (options.sfc.scriptSetup && options.scriptSetupRanges) {
190+
const templateUsageVars = getTemplateUsageVars(options, ctx);
191+
for (
192+
const [content, bindings] of [
193+
[options.sfc.scriptSetup.content, options.scriptSetupRanges.bindings] as const,
194+
options.sfc.script && options.scriptRanges
195+
? [options.sfc.script.content, options.scriptRanges.bindings] as const
196+
: ['', []] as const,
197+
]
198+
) {
199+
for (const { range } of bindings) {
200+
const varName = content.slice(range.start, range.end);
201+
if (!templateUsageVars.has(varName)) {
202+
continue;
203+
}
204+
205+
const token = Symbol(varName.length);
206+
yield ['', undefined, 0, { __linkedToken: token }];
207+
yield `${varName}: ${varName} as typeof `;
208+
yield ['', undefined, 0, { __linkedToken: token }];
209+
yield `${varName},${newLine}`;
210+
}
211+
}
212+
}
213+
yield `}${endOfLine}`;
214+
}
215+
216+
function getTemplateUsageVars(options: ScriptCodegenOptions, ctx: ScriptCodegenContext) {
142217
const usageVars = new Set<string>();
143218
const components = new Set(options.sfc.template?.ast?.components);
144219

packages/language-core/lib/codegen/template/index.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,8 +19,8 @@ export interface TemplateCodegenOptions {
1919
destructuredPropNames: Set<string>;
2020
templateRefNames: Set<string>;
2121
hasDefineSlots?: boolean;
22-
slotsAssignName?: string;
2322
propsAssignName?: string;
23+
slotsAssignName?: string;
2424
inheritAttrs: boolean;
2525
selfComponentName?: string;
2626
}

packages/language-core/lib/parsers/scriptSetupRanges.ts

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -349,7 +349,9 @@ export function parseScriptSetupRanges(
349349

350350
function parseCallExpressionAssignment(node: ts.CallExpression, parent: ts.Node) {
351351
return {
352-
name: ts.isVariableDeclaration(parent) ? _getNodeText(parent.name) : undefined,
352+
name: ts.isVariableDeclaration(parent) && ts.isIdentifier(parent.name)
353+
? _getNodeText(parent.name)
354+
: undefined,
353355
...parseCallExpression(node),
354356
};
355357
}

packages/language-core/lib/plugins/vue-tsx.ts

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -150,10 +150,10 @@ function createTsx(
150150

151151
const setupHasDefineSlots = computed(() => !!getScriptSetupRanges()?.defineSlots);
152152

153-
const getSetupSlotsAssignName = computed(() => getScriptSetupRanges()?.defineSlots?.name);
154-
155153
const getSetupPropsAssignName = computed(() => getScriptSetupRanges()?.defineProps?.name);
156154

155+
const getSetupSlotsAssignName = computed(() => getScriptSetupRanges()?.defineSlots?.name);
156+
157157
const getSetupInheritAttrs = computed(() => {
158158
const value = getScriptSetupRanges()?.defineOptions?.inheritAttrs
159159
?? getScriptRanges()?.exportDefault?.inheritAttrsOption;
@@ -198,8 +198,8 @@ function createTsx(
198198
destructuredPropNames: getSetupDestructuredPropNames(),
199199
templateRefNames: getSetupTemplateRefNames(),
200200
hasDefineSlots: setupHasDefineSlots(),
201-
slotsAssignName: getSetupSlotsAssignName(),
202201
propsAssignName: getSetupPropsAssignName(),
202+
slotsAssignName: getSetupSlotsAssignName(),
203203
inheritAttrs: getSetupInheritAttrs(),
204204
selfComponentName: getComponentSelfName(),
205205
});

packages/tsc/tests/typecheck.spec.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -14,8 +14,8 @@ describe(`vue-tsc`, () => {
1414
"test-workspace/tsc/failureFixtures/#3632/scriptSetup.vue(3,1): error TS1109: Expression expected.",
1515
"test-workspace/tsc/failureFixtures/#5071/withoutScript.vue(2,26): error TS1005: ';' expected.",
1616
"test-workspace/tsc/failureFixtures/directives/main.vue(12,2): error TS2578: Unused '@ts-expect-error' directive.",
17-
"test-workspace/tsc/failureFixtures/directives/main.vue(4,6): error TS2339: Property 'notExist' does not exist on type 'CreateComponentPublicInstanceWithMixins<Readonly<{} & {} & {}>, { exist: {}; }, {}, {}, {}, {}, {}, {}, PublicProps, {}, true, {}, {}, GlobalComponents, GlobalDirectives, ... 12 more ..., {}>'.",
18-
"test-workspace/tsc/failureFixtures/directives/main.vue(9,6): error TS2339: Property 'notExist' does not exist on type 'CreateComponentPublicInstanceWithMixins<Readonly<{} & {} & {}>, { exist: {}; }, {}, {}, {}, {}, {}, {}, PublicProps, {}, true, {}, {}, GlobalComponents, GlobalDirectives, ... 12 more ..., {}>'.",
17+
"test-workspace/tsc/failureFixtures/directives/main.vue(4,6): error TS2339: Property 'notExist' does not exist on type '{ exist: {}; $: ComponentInternalInstance; $data: {}; $props: {}; $attrs: Data; $refs: Data; $slots: Readonly<InternalSlots>; ... 8 more ...; $watch<T extends string | ((...args: any) => any)>(source: T, cb: T extends (...args: any) => infer R ? (args_0: R, args_1: R, args_2: OnCleanup) => any : (args_0: any, args_1...'.",
18+
"test-workspace/tsc/failureFixtures/directives/main.vue(9,6): error TS2339: Property 'notExist' does not exist on type '{ exist: {}; $: ComponentInternalInstance; $data: {}; $props: {}; $attrs: Data; $refs: Data; $slots: Readonly<InternalSlots>; ... 8 more ...; $watch<T extends string | ((...args: any) => any)>(source: T, cb: T extends (...args: any) => infer R ? (args_0: R, args_1: R, args_2: OnCleanup) => any : (args_0: any, args_1...'.",
1919
]
2020
`);
2121
});

test-workspace/tsc/passedFixtures/vue3/#3779/main.vue

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,5 +6,5 @@ defineProps<{
66
</script>
77

88
<template>
9-
<h1>{{ exactType(optionalBoolean, {} as boolean | undefined) }}</h1>
9+
<h1>{{ exactType(optionalBoolean, {} as boolean) }}</h1>
1010
</template>

test-workspace/tsc/passedFixtures/vue3/#3779/named.vue

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,5 +6,5 @@ defineProps<{
66
</script>
77

88
<template>
9-
<h1>{{ exactType(optionalBoolean, {} as boolean | undefined) }}</h1>
9+
<h1>{{ exactType(optionalBoolean, {} as boolean) }}</h1>
1010
</template>

0 commit comments

Comments
 (0)