diff --git a/vue-language-tools/vue-component-meta/tests/index.spec.ts b/vue-language-tools/vue-component-meta/tests/index.spec.ts index e331b328d..2fd1ea43c 100644 --- a/vue-language-tools/vue-component-meta/tests/index.spec.ts +++ b/vue-language-tools/vue-component-meta/tests/index.spec.ts @@ -550,6 +550,32 @@ const worker = (checker: ComponentMetaChecker, withTsconfig: boolean) => describ expect(d).toBeDefined(); }); + test('template-slots without a script block', () => { + const componentPath = path.resolve(__dirname, '../../vue-test-workspace/vue-component-meta/template-slots/component-no-script.vue'); + const meta = checker.getComponentMeta(componentPath); + + const a = meta.slots.find(slot => + slot.name === 'default' + && slot.type === '{ num: number; }' + ); + const b = meta.slots.find(slot => + slot.name === 'named-slot' + && slot.type === '{ str: string; }' + ); + const c = meta.slots.find(slot => + slot.name === 'vbind' + && slot.type === '{ num: number; str: string; }' + ); + const d = meta.slots.find(slot => + slot.name === 'no-bind' + ); + + expect(a).toBeDefined(); + expect(b).toBeDefined(); + expect(c).toBeDefined(); + expect(d).toBeDefined(); + }); + test('class-slots', () => { const componentPath = path.resolve(__dirname, '../../vue-test-workspace/vue-component-meta/class-slots/component.vue'); const meta = checker.getComponentMeta(componentPath); diff --git a/vue-language-tools/vue-language-core/src/generators/script.ts b/vue-language-tools/vue-language-core/src/generators/script.ts index a0f4f32f3..690c8f571 100644 --- a/vue-language-tools/vue-language-core/src/generators/script.ts +++ b/vue-language-tools/vue-language-core/src/generators/script.ts @@ -17,7 +17,7 @@ import { walkInterpolationFragment } from '../utils/transform'; export function generate( ts: typeof import('typescript/lib/tsserverlibrary'), fileName: string, - sfc: Sfc, + _sfc: Sfc, lang: string, scriptRanges: ScriptRanges | undefined, scriptSetupRanges: ScriptSetupRanges | undefined, @@ -31,6 +31,41 @@ export function generate( mirrorBehaviorMappings: SourceMaps.Mapping<[MirrorBehaviorCapabilities, MirrorBehaviorCapabilities]>[] = [], ) { + // monkey fix for https://github.com/johnsoncodehk/volar/pull/2113 + const sfc = { + script: _sfc.script, + scriptSetup: _sfc.scriptSetup, + }; + if (!sfc.script && !sfc.scriptSetup) { + sfc.scriptSetup = { + content: '', + lang: 'ts', + name: '', + start: 0, + end: 0, + startTagEnd: 0, + endTagStart: 0, + generic: undefined, + genericOffset: 0, + }; + scriptSetupRanges = { + bindings: [], + emitsAssignName: undefined, + emitsRuntimeArg: undefined, + emitsTypeArg: undefined, + emitsTypeNums: 0, + exposeRuntimeArg: undefined, + exposeTypeArg: undefined, + importSectionEndOffset: 0, + notOnTopTypeExports: [], + propsAssignName: undefined, + propsRuntimeArg: undefined, + propsTypeArg: undefined, + typeBindings: [], + withDefaultsArg: undefined, + }; + } + const bypassDefineComponent = lang === 'js' || lang === 'jsx'; const vueVersion = vueCompilerOptions.target ?? 3; const vueLibName = getVueLibraryName(vueVersion); diff --git a/vue-language-tools/vue-test-workspace/vue-component-meta/template-slots/component-no-script.vue b/vue-language-tools/vue-test-workspace/vue-component-meta/template-slots/component-no-script.vue new file mode 100644 index 000000000..e117a809e --- /dev/null +++ b/vue-language-tools/vue-test-workspace/vue-component-meta/template-slots/component-no-script.vue @@ -0,0 +1,6 @@ +