From 638dd64c61ba156c92205c7a91630f045e24ffe7 Mon Sep 17 00:00:00 2001 From: Andrew Branch Date: Wed, 25 Jan 2023 16:35:58 -0800 Subject: [PATCH] Add cache to auto-import package.json filter --- src/compiler/moduleSpecifiers.ts | 4 ++- src/services/utilities.ts | 50 +++++++++++++++++++++++++++----- 2 files changed, 45 insertions(+), 9 deletions(-) diff --git a/src/compiler/moduleSpecifiers.ts b/src/compiler/moduleSpecifiers.ts index 6dbbcb3fae03f..e33c5611e602d 100644 --- a/src/compiler/moduleSpecifiers.ts +++ b/src/compiler/moduleSpecifiers.ts @@ -369,7 +369,9 @@ function computeModuleSpecifiers( let redirectPathsSpecifiers: string[] | undefined; let relativeSpecifiers: string[] | undefined; for (const modulePath of modulePaths) { - const specifier = tryGetModuleNameAsNodeModule(modulePath, info, importingSourceFile, host, compilerOptions, userPreferences, /*packageNameOnly*/ undefined, options.overrideImportMode); + const specifier = modulePath.isInNodeModules + ? tryGetModuleNameAsNodeModule(modulePath, info, importingSourceFile, host, compilerOptions, userPreferences, /*packageNameOnly*/ undefined, options.overrideImportMode) + : undefined; nodeModulesSpecifiers = append(nodeModulesSpecifiers, specifier); if (specifier && modulePath.isRedirect) { // If we got a specifier for a redirect, it was a bare package specifier (e.g. "@foo/bar", diff --git a/src/services/utilities.ts b/src/services/utilities.ts index 9935d419b2c4b..aa1d3e44d8053 100644 --- a/src/services/utilities.ts +++ b/src/services/utilities.ts @@ -3663,7 +3663,13 @@ export function createPackageJsonImportFilter(fromFile: SourceFile, preferences: ).filter(p => p.parseable); let usesNodeCoreModules: boolean | undefined; - return { allowsImportingAmbientModule, allowsImportingSourceFile, allowsImportingSpecifier }; + let ambientModuleCache: Map | undefined; + let sourceFileCache: Map | undefined; + return { + allowsImportingAmbientModule, + allowsImportingSourceFile, + allowsImportingSpecifier, + }; function moduleSpecifierIsCoveredByPackageJson(specifier: string) { const packageName = getNodeModuleRootSpecifier(specifier); @@ -3680,19 +3686,34 @@ export function createPackageJsonImportFilter(fromFile: SourceFile, preferences: return true; } - const declaringSourceFile = moduleSymbol.valueDeclaration.getSourceFile(); - const declaringNodeModuleName = getNodeModulesPackageNameFromFileName(declaringSourceFile.fileName, moduleSpecifierResolutionHost); - if (typeof declaringNodeModuleName === "undefined") { - return true; + if (!ambientModuleCache) { + ambientModuleCache = new Map(); + } + else { + const cached = ambientModuleCache.get(moduleSymbol); + if (cached !== undefined) { + return cached; + } } const declaredModuleSpecifier = stripQuotes(moduleSymbol.getName()); if (isAllowedCoreNodeModulesImport(declaredModuleSpecifier)) { + ambientModuleCache.set(moduleSymbol, true); return true; } - return moduleSpecifierIsCoveredByPackageJson(declaringNodeModuleName) - || moduleSpecifierIsCoveredByPackageJson(declaredModuleSpecifier); + const declaringSourceFile = moduleSymbol.valueDeclaration.getSourceFile(); + const declaringNodeModuleName = getNodeModulesPackageNameFromFileName(declaringSourceFile.fileName, moduleSpecifierResolutionHost); + if (typeof declaringNodeModuleName === "undefined") { + ambientModuleCache.set(moduleSymbol, true); + return true; + } + + const result = + moduleSpecifierIsCoveredByPackageJson(declaringNodeModuleName) || + moduleSpecifierIsCoveredByPackageJson(declaredModuleSpecifier); + ambientModuleCache.set(moduleSymbol, result); + return result; } function allowsImportingSourceFile(sourceFile: SourceFile, moduleSpecifierResolutionHost: ModuleSpecifierResolutionHost): boolean { @@ -3700,12 +3721,25 @@ export function createPackageJsonImportFilter(fromFile: SourceFile, preferences: return true; } + if (!sourceFileCache) { + sourceFileCache = new Map(); + } + else { + const cached = sourceFileCache.get(sourceFile); + if (cached !== undefined) { + return cached; + } + } + const moduleSpecifier = getNodeModulesPackageNameFromFileName(sourceFile.fileName, moduleSpecifierResolutionHost); if (!moduleSpecifier) { + sourceFileCache.set(sourceFile, true); return true; } - return moduleSpecifierIsCoveredByPackageJson(moduleSpecifier); + const result = moduleSpecifierIsCoveredByPackageJson(moduleSpecifier); + sourceFileCache.set(sourceFile, result); + return result; } function allowsImportingSpecifier(moduleSpecifier: string) {