Skip to content

Commit

Permalink
perf: cache canonical root file names with string Set
Browse files Browse the repository at this point in the history
  • Loading branch information
johnsoncodehk committed Apr 4, 2024
1 parent 9b13a26 commit 98b24e8
Show file tree
Hide file tree
Showing 8 changed files with 56 additions and 99 deletions.
17 changes: 3 additions & 14 deletions packages/component-meta/lib/base.ts
Original file line number Diff line number Diff line change
Expand Up @@ -160,20 +160,9 @@ export function baseCreate(
const vueLanguagePlugin = vue.createVueLanguagePlugin(
ts,
id => id,
fileName => {
if (ts.sys.useCaseSensitiveFileNames) {
return host.getScriptFileNames().includes(fileName) ?? false;
}
else {
const lowerFileName = fileName.toLowerCase();
for (const rootFile of host.getScriptFileNames()) {
if (rootFile.toLowerCase() === lowerFileName) {
return true;
}
}
return false;
}
},
ts.sys.useCaseSensitiveFileNames,
() => host.getProjectVersion?.() ?? '',
() => host.getScriptFileNames(),
host.getCompilationSettings(),
vueCompilerOptions,
);
Expand Down
26 changes: 23 additions & 3 deletions packages/language-core/lib/languageModule.ts
Original file line number Diff line number Diff line change
Expand Up @@ -48,14 +48,21 @@ function getFileRegistryKey(
return JSON.stringify(values);
}

interface _Plugin extends LanguagePlugin<VueGeneratedCode> {
getCanonicalFileName: (fileName: string) => string;
pluginContext: Parameters<VueLanguagePlugin>[0];
}

export function createVueLanguagePlugin(
ts: typeof import('typescript'),
getFileName: (fileId: string) => string,
isValidGlobalTypesHolder: (fileName: string) => boolean,
useCaseSensitiveFileNames: boolean,
getProjectVersion: () => string,
getScriptFileNames: () => string[] | Set<string>,
compilerOptions: ts.CompilerOptions,
vueCompilerOptions: VueCompilerOptions,
codegenStack: boolean = false,
): LanguagePlugin<VueGeneratedCode> {
): _Plugin {
const allowLanguageIds = new Set(['vue']);
const pluginContext: Parameters<VueLanguagePlugin>[0] = {
modules: {
Expand All @@ -81,11 +88,24 @@ export function createVueLanguagePlugin(
allowLanguageIds.add('html');
}

const getCanonicalFileName = useCaseSensitiveFileNames
? (fileName: string) => fileName
: (fileName: string) => fileName.toLowerCase();
let canonicalRootFileNames = new Set<string>();
let canonicalRootFileNamesVersion: string | undefined;

return {
getCanonicalFileName,
pluginContext,
createVirtualCode(fileId, languageId, snapshot) {
if (allowLanguageIds.has(languageId)) {
const fileName = getFileName(fileId);
if (!pluginContext.globalTypesHolder && isValidGlobalTypesHolder(fileName)) {
const projectVersion = getProjectVersion();
if (projectVersion !== canonicalRootFileNamesVersion) {
canonicalRootFileNames = new Set([...getScriptFileNames()].map(getCanonicalFileName));
canonicalRootFileNamesVersion = projectVersion;
}
if (!pluginContext.globalTypesHolder && canonicalRootFileNames.has(getCanonicalFileName(fileName))) {
pluginContext.globalTypesHolder = fileName;
}
const fileRegistry = getFileRegistry(pluginContext.globalTypesHolder === fileName);
Expand Down
17 changes: 3 additions & 14 deletions packages/language-server/node.ts
Original file line number Diff line number Diff line change
Expand Up @@ -80,20 +80,9 @@ connection.onInitialize(async params => {
const vueLanguagePlugin = createVueLanguagePlugin(
tsdk.typescript,
serviceEnv.typescript!.uriToFileName,
fileName => {
if (projectContext.typescript?.sys.useCaseSensitiveFileNames ?? false) {
return projectContext.typescript?.host.getScriptFileNames().includes(fileName) ?? false;
}
else {
const lowerFileName = fileName.toLowerCase();
for (const rootFile of projectContext.typescript?.host.getScriptFileNames() ?? []) {
if (rootFile.toLowerCase() === lowerFileName) {
return true;
}
}
return false;
}
},
projectContext.typescript?.sys.useCaseSensitiveFileNames ?? false,
() => projectContext.typescript?.host.getProjectVersion?.() ?? '',
() => projectContext.typescript?.host.getScriptFileNames() ?? [],
commandLine?.options ?? {},
vueOptions,
options.codegenStack,
Expand Down
17 changes: 3 additions & 14 deletions packages/language-service/tests/utils/createTester.ts
Original file line number Diff line number Diff line change
Expand Up @@ -32,20 +32,9 @@ function createTester(rootUri: string) {
const vueLanguagePlugin = createVueLanguagePlugin(
ts,
serviceEnv.typescript!.uriToFileName,
fileName => {
if (ts.sys.useCaseSensitiveFileNames) {
return projectHost.getScriptFileNames().includes(fileName);
}
else {
const lowerFileName = fileName.toLowerCase();
for (const rootFile of projectHost.getScriptFileNames()) {
if (rootFile.toLowerCase() === lowerFileName) {
return true;
}
}
return false;
}
},
ts.sys.useCaseSensitiveFileNames,
() => projectHost.getProjectVersion?.() ?? '',
() => projectHost.getScriptFileNames(),
parsedCommandLine.options,
parsedCommandLine.vueOptions,
);
Expand Down
4 changes: 3 additions & 1 deletion packages/language-service/tests/utils/format.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,9 @@ const resolvedVueOptions = resolveVueCompilerOptions({});
const vueLanguagePlugin = createVueLanguagePlugin(
ts,
fileId => formatter.env.typescript!.uriToFileName(fileId),
() => false,
false,
() => '',
() => [],
{},
resolvedVueOptions,
);
Expand Down
39 changes: 15 additions & 24 deletions packages/tsc/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,37 +16,28 @@ export function run() {
const vueOptions = typeof configFilePath === 'string'
? vue.createParsedCommandLine(ts, ts.sys, configFilePath.replace(windowsPathReg, '/')).vueOptions
: vue.resolveVueCompilerOptions({});
const writeFile = options.host!.writeFile.bind(options.host);
const getCanonicalFileName = options.host?.useCaseSensitiveFileNames?.()
? (fileName: string) => fileName
: (fileName: string) => fileName.toLowerCase();
const canonicalRootFileNames = new Set(
options.rootNames
.map(rootName => rootName.replace(windowsPathReg, '/'))
.map(getCanonicalFileName)
);
const canonicalGlobalTypesHolderFileNames = new Set<string>();
options.host!.writeFile = (fileName, contents, ...args) => {
if (
fileName.endsWith('.d.ts')
&& canonicalGlobalTypesHolderFileNames.has(getCanonicalFileName(fileName.replace(windowsPathReg, '/')).slice(0, -5))
) {
contents = removeEmitGlobalTypes(contents);
}
return writeFile(fileName, contents, ...args);
};
if (
runExtensions.length === vueOptions.extensions.length
&& runExtensions.every(ext => vueOptions.extensions.includes(ext))
) {
const writeFile = options.host!.writeFile.bind(options.host);
options.host!.writeFile = (fileName, contents, ...args) => {
if (
fileName.endsWith('.d.ts')
&& vueLanguagePlugin
.getCanonicalFileName(fileName.replace(windowsPathReg, '/'))
.slice(0, -5) === vueLanguagePlugin.pluginContext.globalTypesHolder
) {
contents = removeEmitGlobalTypes(contents);
}
return writeFile(fileName, contents, ...args);
};
const vueLanguagePlugin = vue.createVueLanguagePlugin(
ts,
id => id,
fileName => {
const canonicalFileName = getCanonicalFileName(fileName);
canonicalGlobalTypesHolderFileNames.add(canonicalFileName);
return canonicalRootFileNames.has(canonicalFileName);
},
options.host?.useCaseSensitiveFileNames?.() ?? false,
() => '',
() => options.rootNames.map(rootName => rootName.replace(windowsPathReg, '/')),
options.options,
vueOptions,
false,
Expand Down
18 changes: 3 additions & 15 deletions packages/tsc/tests/dts.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -35,21 +35,9 @@ describe('vue-tsc-dts', () => {
const vueLanguagePlugin = vue.createVueLanguagePlugin(
ts,
id => id,
fileName => {
const rootFileNames = options.rootNames.map(rootName => rootName.replace(windowsPathReg, '/'));
if (options.host?.useCaseSensitiveFileNames?.()) {
return rootFileNames.includes(fileName);
}
else {
const lowerFileName = fileName.toLowerCase();
for (const rootFileName of rootFileNames) {
if (rootFileName.toLowerCase() === lowerFileName) {
return true;
}
}
return false;
}
},
options.host?.useCaseSensitiveFileNames?.() ?? false,
() => '',
() => options.rootNames.map(rootName => rootName.replace(windowsPathReg, '/')),
options.options,
vueOptions,
false,
Expand Down
17 changes: 3 additions & 14 deletions packages/typescript-plugin/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -30,20 +30,9 @@ function createLanguageServicePlugin(): ts.server.PluginModuleFactory {
const languagePlugin = vue.createVueLanguagePlugin(
ts,
id => id,
fileName => {
if (info.languageServiceHost.useCaseSensitiveFileNames?.() ?? false) {
return externalFiles.get(info.project)?.has(fileName) ?? false;
}
else {
const lowerFileName = fileName.toLowerCase();
for (const externalFile of externalFiles.get(info.project) ?? []) {
if (externalFile.toLowerCase() === lowerFileName) {
return true;
}
}
return false;
}
},
info.languageServiceHost.useCaseSensitiveFileNames?.() ?? false,
() => info.languageServiceHost.getProjectVersion?.() ?? '',
() => externalFiles.get(info.project) ?? [],
info.languageServiceHost.getCompilationSettings(),
vueOptions,
);
Expand Down

0 comments on commit 98b24e8

Please sign in to comment.