Skip to content

Commit

Permalink
fix: ts < 5.0 not recognized import('./__VLS_types.d.ts')
Browse files Browse the repository at this point in the history
close #2742
  • Loading branch information
johnsoncodehk committed Apr 27, 2023
1 parent 9344e23 commit bc4a6b1
Show file tree
Hide file tree
Showing 8 changed files with 54 additions and 36 deletions.
4 changes: 3 additions & 1 deletion CHANGELOG.md
Expand Up @@ -2,9 +2,11 @@

## Unreleased

- fix: avoid `<component>` type checking with string literal assignment ([#2725](https://github.com/johnsoncodehk/volar/issues/2725))
- fix: avoid `<component :is>` type checking with string literal assignment ([#2725](https://github.com/johnsoncodehk/volar/issues/2725))
- fix: `<slot>` reporting false positive error when `strictTemplates` enabled ([#2726](https://github.com/johnsoncodehk/volar/issues/2726)) ([#2723](https://github.com/johnsoncodehk/volar/issues/2723))
- fix: error using custom directive: `Expected 2 arguments, but got 1.` ([#2730](https://github.com/johnsoncodehk/volar/issues/2730))
- fix: namespaced tag not working without script setup
- fix: component intellisense not working in template if TS version < 5.0 ([#2742](https://github.com/johnsoncodehk/volar/issues/2742))

## 1.6.0 (2023/4/27)

Expand Down
26 changes: 14 additions & 12 deletions packages/vue-language-core/src/generators/script.ts
Expand Up @@ -13,7 +13,7 @@ import { Sfc } from '../types';
import type { VueCompilerOptions } from '../types';
import { getSlotsPropertyName, getVueLibraryName } from '../utils/shared';
import { walkInterpolationFragment } from '../utils/transform';
import { genConstructorOverloads } from '../utils/localTypes';
import * as sharedTypes from '../utils/directorySharedTypes';
import * as muggle from 'muggle-string';

export function generate(
Expand All @@ -29,10 +29,12 @@ export function generate(
htmlGen: ReturnType<typeof templateGen['generate']> | undefined,
compilerOptions: ts.CompilerOptions,
vueCompilerOptions: VueCompilerOptions,
codes: Segment<FileRangeCapabilities>[] = [],
mirrorBehaviorMappings: SourceMaps.Mapping<[MirrorBehaviorCapabilities, MirrorBehaviorCapabilities]>[] = [],
sharedTypesImport: string,
) {

const codes: Segment<FileRangeCapabilities>[] = [];
const mirrorBehaviorMappings: SourceMaps.Mapping<[MirrorBehaviorCapabilities, MirrorBehaviorCapabilities]>[] = [];

//#region monkey fix: https://github.com/johnsoncodehk/volar/pull/2113
const sfc = {
script: _sfc.script,
Expand Down Expand Up @@ -135,10 +137,10 @@ export function generate(
codes.push('type __VLS_UnionToIntersection<U> = __VLS_Prettify<(U extends unknown ? (arg: U) => unknown : never) extends ((arg: infer P) => unknown) ? P : never>;\n');
usedPrettify = true;
if (scriptSetupRanges && scriptSetupRanges.emitsTypeNums !== -1) {
codes.push(genConstructorOverloads('__VLS_ConstructorOverloads', scriptSetupRanges.emitsTypeNums));
codes.push(sharedTypes.genConstructorOverloads('__VLS_ConstructorOverloads', scriptSetupRanges.emitsTypeNums));
}
else {
codes.push(genConstructorOverloads('__VLS_ConstructorOverloads'));
codes.push(sharedTypes.genConstructorOverloads('__VLS_ConstructorOverloads'));
}
}
if (usedHelperTypes.WithTemplateSlots) {
Expand Down Expand Up @@ -606,13 +608,13 @@ declare function defineProp<T>(value?: T | (() => T), required?: boolean, rest?:
// fill $props
if (scriptSetupRanges.propsTypeArg) {
// NOTE: defineProps is inaccurate for $props
codes.push(`$props: (await import('./__VLS_types.d.ts')).makeOptional(defineProps<`);
codes.push(`$props: (await import('${sharedTypesImport}')).makeOptional(defineProps<`);
addExtraReferenceVirtualCode('scriptSetup', scriptSetupRanges.propsTypeArg.start, scriptSetupRanges.propsTypeArg.end);
codes.push(`>()),\n`);
}
else if (scriptSetupRanges.propsRuntimeArg) {
// NOTE: defineProps is inaccurate for $props
codes.push(`$props: (await import('./__VLS_types.d.ts')).makeOptional(defineProps(`);
codes.push(`$props: (await import('${sharedTypesImport}')).makeOptional(defineProps(`);
addExtraReferenceVirtualCode('scriptSetup', scriptSetupRanges.propsRuntimeArg.start, scriptSetupRanges.propsRuntimeArg.end);
codes.push(`)),\n`);
}
Expand Down Expand Up @@ -813,13 +815,13 @@ declare function defineProp<T>(value?: T | (() => T), required?: boolean, rest?:

codes.push(`let __VLS_ctx!: ${useGlobalThisTypeInCtx ? 'typeof globalThis &' : ''}`);
if (sfc.scriptSetup) {
codes.push(`InstanceType<import('./__VLS_types.d.ts').PickNotAny<typeof __VLS_publicComponent, new () => {}>> & `);
codes.push(`InstanceType<import('${sharedTypesImport}').PickNotAny<typeof __VLS_publicComponent, new () => {}>> & `);
}
codes.push(`InstanceType<import('./__VLS_types.d.ts').PickNotAny<typeof __VLS_internalComponent, new () => {}>> & {\n`);
codes.push(`InstanceType<import('${sharedTypesImport}').PickNotAny<typeof __VLS_internalComponent, new () => {}>> & {\n`);

/* CSS Module */
for (const cssModule of cssModuleClasses) {
codes.push(`${cssModule.style.module}: Record<string, string> & import('./__VLS_types.d.ts').Prettify<{}`);
codes.push(`${cssModule.style.module}: Record<string, string> & import('${sharedTypesImport}').Prettify<{}`);
for (const classNameRange of cssModule.classNameRanges) {
generateCssClassProperty(
cssModule.index,
Expand All @@ -836,8 +838,8 @@ declare function defineProp<T>(value?: T | (() => T), required?: boolean, rest?:
/* Components */
codes.push('/* Components */\n');
codes.push(`let __VLS_localComponents!: NonNullable<typeof __VLS_internalComponent extends { components: infer C } ? C : {}> & typeof __VLS_componentsOption & typeof __VLS_ctx;\n`);
codes.push(`let __VLS_otherComponents!: typeof __VLS_localComponents & import('./__VLS_types.d.ts').GlobalComponents;\n`);
codes.push(`let __VLS_own!: import('./__VLS_types.d.ts').SelfComponent<typeof __VLS_name, typeof __VLS_internalComponent & typeof __VLS_publicComponent & (new () => { ${getSlotsPropertyName(vueCompilerOptions.target)}: typeof __VLS_slots })>;\n`);
codes.push(`let __VLS_otherComponents!: typeof __VLS_localComponents & import('${sharedTypesImport}').GlobalComponents;\n`);
codes.push(`let __VLS_own!: import('${sharedTypesImport}').SelfComponent<typeof __VLS_name, typeof __VLS_internalComponent & typeof __VLS_publicComponent & (new () => { ${getSlotsPropertyName(vueCompilerOptions.target)}: typeof __VLS_slots })>;\n`);
codes.push(`let __VLS_components!: typeof __VLS_otherComponents & Omit<typeof __VLS_own, keyof typeof __VLS_otherComponents>;\n`);

/* Style Scoped */
Expand Down
21 changes: 11 additions & 10 deletions packages/vue-language-core/src/generators/template.ts
Expand Up @@ -67,6 +67,7 @@ export function generate(
sourceLang: string,
templateAst: CompilerDOM.RootNode,
hasScriptSetupSlots: boolean,
sharedTypesImport: string,
cssScopedClasses: string[] = [],
) {

Expand Down Expand Up @@ -177,7 +178,7 @@ export function generate(
const varName = validTsVar.test(tagName) ? tagName : capitalize(camelize(tagName.replace(/:/g, '-')));

codes.push(
`& import('./__VLS_types.d.ts').WithComponent<'${varName}', typeof __VLS_components, `,
`& import('${sharedTypesImport}').WithComponent<'${varName}', typeof __VLS_components, `,
// order is important: https://github.com/johnsoncodehk/volar/issues/2010
`"${capitalize(camelize(tagName))}", `,
`"${camelize(tagName)}", `,
Expand Down Expand Up @@ -460,7 +461,7 @@ export function generate(
codes.push([leftExpressionText, 'template', leftExpressionRange.start, capabilitiesPresets.all]);
formatCodes.push(...createFormatCode(leftExpressionText, leftExpressionRange.start, formatBrackets.normal));
}
codes.push(`] of (await import('./__VLS_types.d.ts')).getVForSourceType`);
codes.push(`] of (await import('${sharedTypesImport}')).getVForSourceType`);
if (source.type === CompilerDOM.NodeTypes.SIMPLE_EXPRESSION) {
codes.push(
...createInterpolationCode(
Expand Down Expand Up @@ -559,7 +560,7 @@ export function generate(
}

codes.push(
`const ${var_functionalComponent} = (await import('./__VLS_types.d.ts')).asFunctionalComponent(`,
`const ${var_functionalComponent} = (await import('${sharedTypesImport}')).asFunctionalComponent(`,
`${var_originalComponent}, `,
`new ${var_originalComponent}({`,
...createPropsCode(node, props, 'slots'),
Expand Down Expand Up @@ -605,12 +606,12 @@ export function generate(
tagOffsets.length ? ['', 'template', tagOffsets[0] + tag.length, capabilitiesPresets.diagnosticOnly]
: dynamicTagExp ? ['', 'template', startTagOffset + tag.length, capabilitiesPresets.diagnosticOnly]
: '',
`, ...(await import('./__VLS_types.d.ts')).functionalComponentArgsRest(${var_functionalComponent}));\n`,
`, ...(await import('${sharedTypesImport}')).functionalComponentArgsRest(${var_functionalComponent}));\n`,
);

if (tag !== 'template' && tag !== 'slot') {
componentCtxVar = `__VLS_${elementIndex++}`;
codes.push(`const ${componentCtxVar} = (await import('./__VLS_types.d.ts')).pickFunctionalComponentCtx(${var_originalComponent}, ${var_componentInstance})!;\n`);
codes.push(`const ${componentCtxVar} = (await import('${sharedTypesImport}')).pickFunctionalComponentCtx(${var_originalComponent}, ${var_componentInstance})!;\n`);
parentEl = node;
}

Expand Down Expand Up @@ -649,7 +650,7 @@ export function generate(
if (vScope?.type === CompilerDOM.NodeTypes.DIRECTIVE && vScope.exp) {

const scopeVar = `__VLS_${elementIndex++}`;
const condition = `(await import('./__VLS_types.d.ts')).withScope(__VLS_ctx, ${scopeVar})`;
const condition = `(await import('${sharedTypesImport}')).withScope(__VLS_ctx, ${scopeVar})`;

codes.push(`const ${scopeVar} = `);
codes.push([
Expand Down Expand Up @@ -709,7 +710,7 @@ export function generate(
slotDir.exp.loc.start.offset,
capabilitiesPresets.all,
],
`] = (await import('./__VLS_types.d.ts')).getSlotParams(`,
`] = (await import('${sharedTypesImport}')).getSlotParams(`,
);
}
else {
Expand All @@ -721,7 +722,7 @@ export function generate(
slotDir.exp.loc.start.offset,
capabilitiesPresets.all,
],
` = (await import('./__VLS_types.d.ts')).getSlotParam(`,
` = (await import('${sharedTypesImport}')).getSlotParam(`,
);
}
}
Expand Down Expand Up @@ -794,7 +795,7 @@ export function generate(
const eventVar = `__VLS_${elementIndex++}`;
codes.push(
`let ${eventVar} = { '${prop.arg.loc.source}': `,
`(await import('./__VLS_types.d.ts')).pickEvent(${componentCtxVar}.emit!, '${prop.arg.loc.source}' as const, (await import('./__VLS_types.d.ts')).componentProps(${componentVar}, ${componentInstanceVar})`,
`(await import('${sharedTypesImport}')).pickEvent(${componentCtxVar}.emit!, '${prop.arg.loc.source}' as const, (await import('${sharedTypesImport}')).componentProps(${componentVar}, ${componentInstanceVar})`,
...createPropertyAccessCode([
camelize('on-' + prop.arg.loc.source), // onClickOutside
'template',
Expand Down Expand Up @@ -1357,7 +1358,7 @@ export function generate(
prop.loc.start.offset,
capabilitiesPresets.diagnosticOnly,
],
`(await import('./__VLS_types.d.ts')).directiveFunction(__VLS_ctx.`,
`(await import('${sharedTypesImport}')).directiveFunction(__VLS_ctx.`,
[
camelize('v-' + prop.name),
'template',
Expand Down
7 changes: 4 additions & 3 deletions packages/vue-language-core/src/index.ts
@@ -1,13 +1,14 @@
export * from './generators/template';
export * from './languageModule';
export * as scriptRanges from './parsers/scriptRanges';
export * from './parsers/scriptSetupRanges';
export * from './plugins';
export * from './sourceFile';
export * from './types';
export * as localTypes from './utils/localTypes';
export * from './utils/ts';
export * from './utils/parseSfc';

export * as scriptRanges from './parsers/scriptRanges';
export * as sharedTypes from './utils/directorySharedTypes';

export * from '@volar/language-core';
export * from '@volar/source-map';
export * from '@volar/source-map';
12 changes: 6 additions & 6 deletions packages/vue-language-core/src/languageModule.ts
Expand Up @@ -3,7 +3,7 @@ import { posix as path } from 'path';
import { getDefaultVueLanguagePlugins } from './plugins';
import { VueFile } from './sourceFile';
import { VueCompilerOptions } from './types';
import * as localTypes from './utils/localTypes';
import * as sharedTypes from './utils/directorySharedTypes';
import type * as ts from 'typescript/lib/tsserverlibrary';

export function createLanguageModules(
Expand All @@ -19,7 +19,7 @@ export function createLanguageModules(
compilerOptions,
vueCompilerOptions,
);
const sharedTypesSnapshot = ts.ScriptSnapshot.fromString(localTypes.getTypesCode(vueCompilerOptions.target, vueCompilerOptions));
const sharedTypesSnapshot = ts.ScriptSnapshot.fromString(sharedTypes.getTypesCode(vueCompilerOptions.target, vueCompilerOptions));
const languageModule: embedded.LanguageModule = {
createFile(fileName, snapshot, languageId) {
if (
Expand All @@ -39,7 +39,7 @@ export function createLanguageModules(
return {
fileExists(fileName) {
const basename = path.basename(fileName);
if (basename === localTypes.typesFileName) {
if (basename === sharedTypes.baseName) {
return true;
}
return host.fileExists(fileName);
Expand All @@ -53,14 +53,14 @@ export function createLanguageModules(
},
getScriptVersion(fileName) {
const basename = path.basename(fileName);
if (basename === localTypes.typesFileName) {
if (basename === sharedTypes.baseName) {
return '';
}
return host.getScriptVersion(fileName);
},
getScriptSnapshot(fileName) {
const basename = path.basename(fileName);
if (basename === localTypes.typesFileName) {
if (basename === sharedTypes.baseName) {
return sharedTypesSnapshot;
}
return host.getScriptSnapshot(fileName);
Expand All @@ -77,7 +77,7 @@ export function createLanguageModules(
function getSharedTypesFiles(fileNames: string[]) {
const moduleFiles = fileNames.filter(fileName => vueCompilerOptions.extensions.some(ext => fileName.endsWith(ext)));
const moduleFileDirs = [...new Set(moduleFiles.map(path.dirname))];
return moduleFileDirs.map(dir => path.join(dir, localTypes.typesFileName));
return moduleFileDirs.map(dir => path.join(dir, sharedTypes.baseName));
}
}

Expand Down
4 changes: 4 additions & 0 deletions packages/vue-language-core/src/plugins/vue-tsx.ts
Expand Up @@ -8,11 +8,13 @@ import { FileCapabilities, FileKind } from '@volar/language-core';
import { TextRange } from '../types';
import { parseCssClassNames } from '../utils/parseCssClassNames';
import { parseCssVars } from '../utils/parseCssVars';
import * as sharedTypes from '../utils/directorySharedTypes';

const plugin: VueLanguagePlugin = ({ modules, vueCompilerOptions, compilerOptions }) => {

const ts = modules.typescript;
const instances = new WeakMap<Sfc, ReturnType<typeof createTsx>>();
const sharedTypesImport = sharedTypes.getImportName(compilerOptions);

return {

Expand Down Expand Up @@ -138,6 +140,7 @@ const plugin: VueLanguagePlugin = ({ modules, vueCompilerOptions, compilerOption
_sfc.template?.lang ?? 'html',
_sfc.templateAst,
hasScriptSetupSlots.value,
sharedTypesImport,
Object.values(cssScopedClasses.value).map(style => style.classNames).flat(),
);
});
Expand All @@ -157,6 +160,7 @@ const plugin: VueLanguagePlugin = ({ modules, vueCompilerOptions, compilerOption
htmlGen.value,
compilerOptions,
vueCompilerOptions,
sharedTypesImport,
);
});

Expand Down
@@ -1,8 +1,16 @@
import { VueCompilerOptions } from '../types';
import { getSlotsPropertyName } from './shared';
import { getVueLibraryName } from './shared';
import type * as ts from 'typescript/lib/tsserverlibrary';

export const typesFileName = '__VLS_types.d.ts';
export const baseName = '__VLS_types.d.ts';

export function getImportName(compilerOptions: ts.CompilerOptions) {
if (!compilerOptions.module || compilerOptions.module === 1) {
return './__VLS_types';
}
return './__VLS_types.js';
};

export function getTypesCode(
vueVersion: number,
Expand Down
6 changes: 3 additions & 3 deletions packages/vue-language-service/src/helpers.ts
Expand Up @@ -2,7 +2,7 @@ import * as vue from '@volar/vue-language-core';
import * as embedded from '@volar/language-core';
import * as CompilerDOM from '@vue/compiler-dom';
import { computed, ComputedRef } from '@vue/reactivity';
import { typesFileName } from '@volar/vue-language-core/out/utils/localTypes';
import { sharedTypes } from '@volar/vue-language-core';
import { camelize, capitalize } from '@vue/shared';

import type * as ts from 'typescript/lib/tsserverlibrary';
Expand Down Expand Up @@ -167,7 +167,7 @@ export function checkNativeTags(
fileName: string,
) {

const sharedTypesFileName = fileName.substring(0, fileName.lastIndexOf('/')) + '/' + typesFileName;
const sharedTypesFileName = fileName.substring(0, fileName.lastIndexOf('/')) + '/' + sharedTypes.baseName;
const result = new Set<string>();

let tsSourceFile: ts.SourceFile | undefined;
Expand Down Expand Up @@ -198,7 +198,7 @@ export function getElementAttrs(
tagName: string,
) {

const sharedTypesFileName = fileName.substring(0, fileName.lastIndexOf('/')) + '/' + typesFileName;
const sharedTypesFileName = fileName.substring(0, fileName.lastIndexOf('/')) + '/' + sharedTypes.baseName;

let tsSourceFile: ts.SourceFile | undefined;

Expand Down

0 comments on commit bc4a6b1

Please sign in to comment.