You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
101 lines
3.3 KiB
101 lines
3.3 KiB
/**
|
|
* Copyright (c) Meta Platforms, Inc. and affiliates.
|
|
*
|
|
* This source code is licensed under the MIT license found in the
|
|
* LICENSE file in the root directory of this source tree.
|
|
*
|
|
*
|
|
* @format
|
|
* @oncall react_native
|
|
*/
|
|
|
|
"use strict";
|
|
|
|
const Module = require("./Module");
|
|
const Package = require("./Package");
|
|
class ModuleCache {
|
|
// Cache for "closest package.json" queries by module path.
|
|
|
|
// The inverse of _packagePathByModulePath.
|
|
|
|
constructor(options) {
|
|
this._getClosestPackage = options.getClosestPackage;
|
|
this._moduleCache = Object.create(null);
|
|
this._packageCache = Object.create(null);
|
|
this._packagePathByModulePath = Object.create(null);
|
|
this._modulePathsByPackagePath = Object.create(null);
|
|
}
|
|
getModule(filePath) {
|
|
if (!this._moduleCache[filePath]) {
|
|
this._moduleCache[filePath] = new Module(filePath, this);
|
|
}
|
|
return this._moduleCache[filePath];
|
|
}
|
|
getPackage(filePath) {
|
|
if (!this._packageCache[filePath]) {
|
|
this._packageCache[filePath] = new Package({
|
|
file: filePath,
|
|
});
|
|
}
|
|
return this._packageCache[filePath];
|
|
}
|
|
getPackageForModule(module) {
|
|
return this.getPackageOf(module.path);
|
|
}
|
|
getPackageOf(modulePath) {
|
|
var _this$_modulePathsByP;
|
|
let packagePath = this._packagePathByModulePath[modulePath];
|
|
if (packagePath && this._packageCache[packagePath]) {
|
|
return this._packageCache[packagePath];
|
|
}
|
|
packagePath = this._getClosestPackage(modulePath);
|
|
if (!packagePath) {
|
|
return null;
|
|
}
|
|
this._packagePathByModulePath[modulePath] = packagePath;
|
|
const modulePaths =
|
|
(_this$_modulePathsByP = this._modulePathsByPackagePath[packagePath]) !==
|
|
null && _this$_modulePathsByP !== void 0
|
|
? _this$_modulePathsByP
|
|
: new Set();
|
|
modulePaths.add(modulePath);
|
|
this._modulePathsByPackagePath[packagePath] = modulePaths;
|
|
return this.getPackage(packagePath);
|
|
}
|
|
invalidate(filePath) {
|
|
if (this._moduleCache[filePath]) {
|
|
this._moduleCache[filePath].invalidate();
|
|
delete this._moduleCache[filePath];
|
|
}
|
|
if (this._packageCache[filePath]) {
|
|
this._packageCache[filePath].invalidate();
|
|
delete this._packageCache[filePath];
|
|
}
|
|
if (this._packagePathByModulePath[filePath]) {
|
|
// filePath is a module inside a package.
|
|
const packagePath = this._packagePathByModulePath[filePath];
|
|
delete this._packagePathByModulePath[filePath];
|
|
// This change doesn't invalidate any cached "closest package.json"
|
|
// queries for the package's other modules. Clean up only this module.
|
|
const modulePaths = this._modulePathsByPackagePath[packagePath];
|
|
if (modulePaths) {
|
|
modulePaths.delete(filePath);
|
|
if (modulePaths.size === 0) {
|
|
delete this._modulePathsByPackagePath[packagePath];
|
|
}
|
|
}
|
|
}
|
|
if (this._modulePathsByPackagePath[filePath]) {
|
|
// filePath is a package. This change invalidates all cached "closest
|
|
// package.json" queries for modules inside this package.
|
|
const modulePaths = this._modulePathsByPackagePath[filePath];
|
|
for (const modulePath of modulePaths) {
|
|
delete this._packagePathByModulePath[modulePath];
|
|
}
|
|
modulePaths.clear();
|
|
delete this._modulePathsByPackagePath[filePath];
|
|
}
|
|
}
|
|
}
|
|
module.exports = ModuleCache;
|