From b6b87fa4c7711df940a0ed84e8efa0ac228d211b Mon Sep 17 00:00:00 2001 From: KazariEX Date: Thu, 4 Dec 2025 04:03:59 +0800 Subject: [PATCH] fix(language-core): generate component options outside of setup scope --- .../lib/codegen/script/component.ts | 60 ++++++++++---- .../language-core/lib/codegen/script/index.ts | 39 ++++++--- .../lib/codegen/script/scriptSetup.ts | 79 +++++++++++++------ .../lib/codegen/script/template.ts | 2 +- .../tsc/tests/__snapshots__/dts.spec.ts.snap | 30 ++----- .../tsc/passedFixtures/vue3/#5604/main.vue | 16 ++++ .../passedFixtures/vue3/directives/option.vue | 6 +- 7 files changed, 150 insertions(+), 82 deletions(-) create mode 100644 test-workspace/tsc/passedFixtures/vue3/#5604/main.vue diff --git a/packages/language-core/lib/codegen/script/component.ts b/packages/language-core/lib/codegen/script/component.ts index 980553e381..4e376e358f 100644 --- a/packages/language-core/lib/codegen/script/component.ts +++ b/packages/language-core/lib/codegen/script/component.ts @@ -2,7 +2,7 @@ import type { ScriptSetupRanges } from '../../parsers/scriptSetupRanges'; import type { Code, Sfc } from '../../types'; import { codeFeatures } from '../codeFeatures'; import * as names from '../names'; -import { generateSfcBlockSection, newLine } from '../utils'; +import { endOfLine, generateSfcBlockSection, newLine } from '../utils'; import { generateIntersectMerge, generateSpreadMerge } from '../utils/merge'; import type { ScriptCodegenContext } from './context'; import type { ScriptCodegenOptions } from './index'; @@ -12,19 +12,9 @@ export function* generateComponent( ctx: ScriptCodegenContext, scriptSetup: NonNullable, scriptSetupRanges: ScriptSetupRanges, + outputRaw?: boolean, ): Generator { - if ( - options.script - && options.scriptRanges?.componentOptions - && options.scriptRanges.componentOptions.expression.start !== options.scriptRanges.componentOptions.args.start - ) { - // use defineComponent() from user space code if it exist - yield* generateSfcBlockSection( - options.script, - options.scriptRanges.componentOptions.expression.start, - options.scriptRanges.componentOptions.args.start, - codeFeatures.all, - ); + if (outputRaw) { yield `{${newLine}`; } else { @@ -60,11 +50,47 @@ export function* generateComponent( ) { yield `__typeEl: {} as ${names.RootEl},${newLine}`; } - if (options.script && options.scriptRanges?.componentOptions?.args) { - const { args } = options.scriptRanges.componentOptions; - yield* generateSfcBlockSection(options.script, args.start + 1, args.end - 1, codeFeatures.all); + if (hasSlotsType(options)) { + yield `slots: {} as ${ + options.vueCompilerOptions.target >= 3.3 + ? `import('${options.vueCompilerOptions.lib}').SlotsType<${names.Slots}>` + : names.Slots + },${newLine}`; + } + + if (outputRaw) { + yield `}`; + } + else { + yield `})`; + } +} + +export function* generateWithSlots( + options: ScriptCodegenOptions, + ctx: ScriptCodegenContext, + body: Iterable, + output: Iterable, +): Generator { + if (options.vueCompilerOptions.target < 3.3 && hasSlotsType(options)) { + yield `const __VLS_base = `; + yield* body; + yield endOfLine; + yield* output; + yield `{} as ${ctx.localTypes.WithSlots}${endOfLine}`; + } + else { + yield* output; + yield* body; + yield endOfLine; } - yield `})`; +} + +export function hasSlotsType(options: ScriptCodegenOptions) { + return !!( + options.scriptSetupRanges?.defineSlots + || options.templateCodegen?.generatedTypes.has(names.Slots) + ); } function* generateEmitsOption( diff --git a/packages/language-core/lib/codegen/script/index.ts b/packages/language-core/lib/codegen/script/index.ts index eb2aa4a9e7..50b7d87039 100644 --- a/packages/language-core/lib/codegen/script/index.ts +++ b/packages/language-core/lib/codegen/script/index.ts @@ -8,8 +8,14 @@ import * as names from '../names'; import type { TemplateCodegenContext } from '../template/context'; import { endOfLine, generateSfcBlockSection, newLine } from '../utils'; import { endBoundary, startBoundary } from '../utils/boundary'; +import { generateComponent, generateWithSlots } from './component'; import { createScriptCodegenContext, type ScriptCodegenContext } from './context'; -import { generateGeneric, generateScriptSetupImports, generateSetupFunction } from './scriptSetup'; +import { + generateGeneric, + generateScriptAndScriptSetup, + generateScriptSetup, + generateScriptSetupImports, +} from './scriptSetup'; import { generateSrc } from './src'; import { generateTemplate } from './template'; @@ -69,15 +75,15 @@ function* generateWorker( } // + + + + diff --git a/test-workspace/tsc/passedFixtures/vue3/directives/option.vue b/test-workspace/tsc/passedFixtures/vue3/directives/option.vue index fdf1a542b2..4dfac6362b 100644 --- a/test-workspace/tsc/passedFixtures/vue3/directives/option.vue +++ b/test-workspace/tsc/passedFixtures/vue3/directives/option.vue @@ -1,6 +1,5 @@