Skip to content

Commit 9b4191f

Browse files
committed
Cache packagejson scopes per directory
1 parent 4ba5cb8 commit 9b4191f

File tree

46 files changed

+5604
-12413
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

46 files changed

+5604
-12413
lines changed

src/compiler/builder.ts

Lines changed: 51 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -55,6 +55,7 @@ import {
5555
getNormalizedAbsolutePath,
5656
getOptionsNameMap,
5757
getOwnKeys,
58+
getPackageJsonLocationFromScope,
5859
getRelativePathFromDirectory,
5960
GetResolutionWithResolvedFileName,
6061
getResolvedModuleOfResolution,
@@ -69,7 +70,6 @@ import {
6970
isJsonSourceFile,
7071
isNumber,
7172
isString,
72-
last,
7373
map,
7474
mapDefined,
7575
maybeBind,
@@ -86,6 +86,7 @@ import {
8686
outFile,
8787
PackageJsonInfo,
8888
PackageJsonInfoCache,
89+
PackageJsonScope,
8990
Path,
9091
Program,
9192
ProjectReference,
@@ -194,7 +195,7 @@ export interface ReusableBuilderProgramState extends BuilderState {
194195
modules: CacheWithRedirects<Path, ModeAwareCache<ResolvedModuleWithFailedLookupLocations>> | undefined;
195196
typeRefs: CacheWithRedirects<Path, ModeAwareCache<ResolvedTypeReferenceDirectiveWithFailedLookupLocations>> | undefined;
196197
moduleNameToDirectoryMap: CacheWithRedirects<ModeAwareCacheKey, Map<Path, ResolvedModuleWithFailedLookupLocations>>;
197-
dirToPackageJsonMap: Map<Path, string>;
198+
dirToPackageJsonScope: Map<Path, PackageJsonScope>;
198199
perDirPackageJsonMap: Map<Path, string> | undefined;
199200
packageJsonCache: PackageJsonInfoCache | undefined;
200201
};
@@ -1474,21 +1475,20 @@ function getCacheResolutions(state: BuilderProgramState, getCanonicalFileName: G
14741475
let typeRefs: CacheWithRedirects<Path, ModeAwareCache<ResolvedTypeReferenceDirectiveWithFailedLookupLocations>> | undefined;
14751476
getCanonicalFileName ??= createGetCanonicalFileName(state.program!.useCaseSensitiveFileNames());
14761477
const moduleNameToDirectoryMap = createCacheWithRedirects<ModeAwareCacheKey, Map<Path, ResolvedModuleWithFailedLookupLocations>>(state.compilerOptions);
1477-
const dirToPackageJsonMap = new Map<Path, string>();
1478+
const dirToPackageJsonScope = new Map<Path, PackageJsonScope>();
14781479
let perDirPackageJsonMap: Map<Path, string> | undefined;
14791480
state.program!.getSourceFiles().forEach(f => {
14801481
modules = toPerDirectoryCache(state, getCanonicalFileName!, modules, getResolvedModuleOfResolution, f, f.resolvedModules, moduleNameToDirectoryMap);
14811482
typeRefs = toPerDirectoryCache(state, getCanonicalFileName!, typeRefs, getResolvedTypeReferenceDirectiveOfResolution, f, f.resolvedTypeReferenceDirectiveNames);
1482-
if (f.packageJsonScope) {
1483+
if (f.packageJsonScope?.info) {
14831484
const dirPath = getDirectoryPath(f.resolvedPath);
1484-
if (!dirToPackageJsonMap?.has(dirPath)) {
1485-
const result = last(f.packageJsonLocations!);
1486-
(perDirPackageJsonMap ??= new Map()).set(dirPath, result);
1485+
if (!dirToPackageJsonScope?.has(dirPath)) {
1486+
(perDirPackageJsonMap ??= new Map()).set(dirPath, getPackageJsonLocationFromScope(f.packageJsonScope)!);
14871487
moduleNameToDirectorySet(
1488-
dirToPackageJsonMap,
1488+
dirToPackageJsonScope,
14891489
dirPath,
1490-
result,
1491-
identity,
1490+
f.packageJsonScope,
1491+
getPackageJsonLocationFromScope,
14921492
dir => toPath(dir, state.program!.getCurrentDirectory(), getCanonicalFileName!),
14931493
ancestorPath => perDirPackageJsonMap?.delete(ancestorPath),
14941494
);
@@ -1505,7 +1505,7 @@ function getCacheResolutions(state: BuilderProgramState, getCanonicalFileName: G
15051505
modules,
15061506
typeRefs,
15071507
moduleNameToDirectoryMap,
1508-
dirToPackageJsonMap,
1508+
dirToPackageJsonScope,
15091509
perDirPackageJsonMap,
15101510
packageJsonCache: state.program!.getModuleResolutionCache()?.getPackageJsonInfoCache().clone(),
15111511
};
@@ -2170,6 +2170,7 @@ export function createOldBuildInfoProgram(
21702170
if (!cacheResolutions && !resuableCacheResolutions) return undefined;
21712171
const fileExistsMap = new Map<string, boolean>();
21722172
const affectingLoationsSameMap = new Map<string, boolean>();
2173+
const packageJsonInfoMap = new Map<string, PackageJsonInfo | false>();
21732174

21742175
type Resolution = ResolvedModuleWithFailedLookupLocations & ResolvedTypeReferenceDirectiveWithFailedLookupLocations;
21752176
type ResolutionEntry = [name: string, resolutionId: ProgramBuildInfoResolutionId, mode: ResolutionMode];
@@ -2179,6 +2180,7 @@ export function createOldBuildInfoProgram(
21792180
const decodedResolvedTypeRefs: DecodedResolvedMap = createCacheWithRedirects(compilerOptions);
21802181
const decodedModuleNameToDirectoryMap: DecodedModuleNameToDirectoryMap = createCacheWithRedirects(compilerOptions);
21812182
let decodedPackageJsonMap: Map<Path, string> | undefined;
2183+
let packageJsonScopes: Map<string, PackageJsonScope | false> | undefined;
21822184
let decodedHashes: Map<ProgramBuildInfoAbsoluteFileId, string | undefined> | undefined;
21832185

21842186
let resolutions: (Resolution | false)[] | undefined;
@@ -2208,7 +2210,7 @@ export function createOldBuildInfoProgram(
22082210
/*moduleNameToDirectoryMap*/ undefined,
22092211
/*decodedModuleNameToDirectoryMap*/ undefined,
22102212
),
2211-
getPackageJsonPath,
2213+
getPackageJsonScope,
22122214
};
22132215
function fileExists(fileName: string) {
22142216
let result = fileExistsMap.get(fileName);
@@ -2235,10 +2237,28 @@ export function createOldBuildInfoProgram(
22352237
return result;
22362238
}
22372239

2238-
function getPackageJsonPath(dirPath: Path) {
2239-
const fromCache = cacheResolutions?.dirToPackageJsonMap?.get(dirPath);
2240+
function getPackageJsonInfo(fileName: string) {
2241+
let result = packageJsonInfoMap.get(fileName);
2242+
if (result === undefined) packageJsonInfoMap.set(fileName, result = host.getPackageJsonInfo(fileName) || false);
2243+
return result || undefined;
2244+
}
2245+
2246+
function getPackageJsonScope(dirPath: Path): PackageJsonScope | undefined{
2247+
const fromCache = cacheResolutions?.dirToPackageJsonScope?.get(dirPath);
22402248
if (fromCache) {
2241-
return fileExists(fromCache) ? fromCache : undefined;
2249+
const packageJson = getPackageJsonLocationFromScope(fromCache)!;
2250+
let result = packageJsonScopes?.get(packageJson);
2251+
if (result === undefined) {
2252+
(packageJsonScopes ??= new Map()).set(
2253+
packageJson,
2254+
result = affectingLocationsSame(packageJson, fromCache.info) ?
2255+
fromCache :
2256+
fileExists(packageJson) ?
2257+
{ info: getPackageJsonInfo(packageJson), affectingLocations: [packageJson] } :
2258+
false
2259+
);
2260+
}
2261+
return result || undefined;
22422262
}
22432263
if (!resuableCacheResolutions?.cache.packageJsons) return;
22442264
if (!decodedPackageJsonMap) {
@@ -2264,8 +2284,22 @@ export function createOldBuildInfoProgram(
22642284
);
22652285
}
22662286
}
2267-
const fromDecoded = decodedPackageJsonMap.get(dirPath);
2268-
return fromDecoded && fileExists(fromDecoded) ? fromDecoded : undefined;
2287+
return toPackageJsonScope(decodedPackageJsonMap.get(dirPath));
2288+
}
2289+
2290+
function toPackageJsonScope(file: string | undefined): PackageJsonScope | undefined {
2291+
if (!file) return undefined;
2292+
let result = packageJsonScopes?.get(file);
2293+
if (result !== undefined) return result || undefined;
2294+
(packageJsonScopes ??= new Map());
2295+
if (fileExists(file)) {
2296+
result = {
2297+
info: getPackageJsonInfo(file),
2298+
affectingLocations: [file]
2299+
};
2300+
}
2301+
packageJsonScopes.set(file, result || false);
2302+
return result;
22692303
}
22702304

22712305
function getResolvedFromCache<T extends ResolvedModuleWithFailedLookupLocations | ResolvedTypeReferenceDirectiveWithFailedLookupLocations>(

src/compiler/checker.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4716,7 +4716,7 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker {
47164716
let diagnosticDetails;
47174717
const ext = tryGetExtensionFromPath(currentSourceFile.fileName);
47184718
if (ext === Extension.Ts || ext === Extension.Js || ext === Extension.Tsx || ext === Extension.Jsx) {
4719-
const scope = currentSourceFile.packageJsonScope;
4719+
const scope = currentSourceFile.packageJsonScope?.info;
47204720
const targetExt = ext === Extension.Ts ? Extension.Mts : ext === Extension.Js ? Extension.Mjs : undefined;
47214721
if (scope && !scope.contents.packageJsonContent.type) {
47224722
if (targetExt) {

src/compiler/diagnosticMessages.json

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5154,6 +5154,14 @@
51545154
"category": "Message",
51555155
"code": 6261
51565156
},
5157+
"Directory '{0}' resolves to '{1}' scope according to cache.": {
5158+
"category": "Message",
5159+
"code": 6263
5160+
},
5161+
"Directory '{0}' has no containing package.json scope according to cache.": {
5162+
"category": "Message",
5163+
"code": 6264
5164+
},
51575165

51585166
"Directory '{0}' has no containing package.json scope. Imports will not resolve.": {
51595167
"category": "Message",

0 commit comments

Comments
 (0)