Merge pull request #25521 from Microsoft/dontWatchAmbientModules
Do not watch modules that get resolved by ambient modules
This commit is contained in:
commit
357f0d6fbd
2 changed files with 65 additions and 27 deletions
|
@ -81,6 +81,7 @@ namespace ts {
|
||||||
let filesWithInvalidatedResolutions: Map<true> | undefined;
|
let filesWithInvalidatedResolutions: Map<true> | undefined;
|
||||||
let filesWithInvalidatedNonRelativeUnresolvedImports: Map<ReadonlyArray<string>> | undefined;
|
let filesWithInvalidatedNonRelativeUnresolvedImports: Map<ReadonlyArray<string>> | undefined;
|
||||||
let allFilesHaveInvalidatedResolution = false;
|
let allFilesHaveInvalidatedResolution = false;
|
||||||
|
const nonRelativeExternalModuleResolutions = createMultiMap<ResolutionWithFailedLookupLocations>();
|
||||||
|
|
||||||
const getCurrentDirectory = memoize(() => resolutionHost.getCurrentDirectory!()); // TODO: GH#18217
|
const getCurrentDirectory = memoize(() => resolutionHost.getCurrentDirectory!()); // TODO: GH#18217
|
||||||
const cachedDirectoryStructureHost = resolutionHost.getCachedDirectoryStructureHost();
|
const cachedDirectoryStructureHost = resolutionHost.getCachedDirectoryStructureHost();
|
||||||
|
@ -154,6 +155,7 @@ namespace ts {
|
||||||
function clear() {
|
function clear() {
|
||||||
clearMap(directoryWatchesOfFailedLookups, closeFileWatcherOf);
|
clearMap(directoryWatchesOfFailedLookups, closeFileWatcherOf);
|
||||||
customFailedLookupPaths.clear();
|
customFailedLookupPaths.clear();
|
||||||
|
nonRelativeExternalModuleResolutions.clear();
|
||||||
closeTypeRootsWatch();
|
closeTypeRootsWatch();
|
||||||
resolvedModuleNames.clear();
|
resolvedModuleNames.clear();
|
||||||
resolvedTypeReferenceDirectives.clear();
|
resolvedTypeReferenceDirectives.clear();
|
||||||
|
@ -199,19 +201,20 @@ namespace ts {
|
||||||
perDirectoryResolvedModuleNames.clear();
|
perDirectoryResolvedModuleNames.clear();
|
||||||
nonRelaticeModuleNameCache.clear();
|
nonRelaticeModuleNameCache.clear();
|
||||||
perDirectoryResolvedTypeReferenceDirectives.clear();
|
perDirectoryResolvedTypeReferenceDirectives.clear();
|
||||||
|
nonRelativeExternalModuleResolutions.forEach(watchFailedLookupLocationOfNonRelativeModuleResolutions);
|
||||||
|
nonRelativeExternalModuleResolutions.clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
function finishCachingPerDirectoryResolution() {
|
function finishCachingPerDirectoryResolution() {
|
||||||
allFilesHaveInvalidatedResolution = false;
|
allFilesHaveInvalidatedResolution = false;
|
||||||
filesWithInvalidatedNonRelativeUnresolvedImports = undefined;
|
filesWithInvalidatedNonRelativeUnresolvedImports = undefined;
|
||||||
|
clearPerDirectoryResolutions();
|
||||||
directoryWatchesOfFailedLookups.forEach((watcher, path) => {
|
directoryWatchesOfFailedLookups.forEach((watcher, path) => {
|
||||||
if (watcher.refCount === 0) {
|
if (watcher.refCount === 0) {
|
||||||
directoryWatchesOfFailedLookups.delete(path);
|
directoryWatchesOfFailedLookups.delete(path);
|
||||||
watcher.watcher.close();
|
watcher.watcher.close();
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
clearPerDirectoryResolutions();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
function resolveModuleName(moduleName: string, containingFile: string, compilerOptions: CompilerOptions, host: ModuleResolutionHost): CachedResolvedModuleWithFailedLookupLocations {
|
function resolveModuleName(moduleName: string, containingFile: string, compilerOptions: CompilerOptions, host: ModuleResolutionHost): CachedResolvedModuleWithFailedLookupLocations {
|
||||||
|
@ -275,7 +278,7 @@ namespace ts {
|
||||||
perDirectoryResolution.set(name, resolution);
|
perDirectoryResolution.set(name, resolution);
|
||||||
}
|
}
|
||||||
resolutionsInFile.set(name, resolution);
|
resolutionsInFile.set(name, resolution);
|
||||||
watchFailedLookupLocationOfResolution(resolution);
|
watchFailedLookupLocationsOfExternalModuleResolutions(name, resolution);
|
||||||
if (existingResolution) {
|
if (existingResolution) {
|
||||||
stopWatchFailedLookupLocationOfResolution(existingResolution);
|
stopWatchFailedLookupLocationOfResolution(existingResolution);
|
||||||
}
|
}
|
||||||
|
@ -441,18 +444,27 @@ namespace ts {
|
||||||
return fileExtensionIsOneOf(path, failedLookupDefaultExtensions);
|
return fileExtensionIsOneOf(path, failedLookupDefaultExtensions);
|
||||||
}
|
}
|
||||||
|
|
||||||
function watchFailedLookupLocationOfResolution(resolution: ResolutionWithFailedLookupLocations) {
|
function watchFailedLookupLocationsOfExternalModuleResolutions(name: string, resolution: ResolutionWithFailedLookupLocations) {
|
||||||
// No need to set the resolution refCount
|
// No need to set the resolution refCount
|
||||||
if (!resolution.failedLookupLocations || !resolution.failedLookupLocations.length) {
|
if (resolution.failedLookupLocations && resolution.failedLookupLocations.length) {
|
||||||
return;
|
if (resolution.refCount) {
|
||||||
}
|
|
||||||
|
|
||||||
if (resolution.refCount !== undefined) {
|
|
||||||
resolution.refCount++;
|
resolution.refCount++;
|
||||||
return;
|
}
|
||||||
|
else {
|
||||||
|
resolution.refCount = 1;
|
||||||
|
if (isExternalModuleNameRelative(name)) {
|
||||||
|
watchFailedLookupLocationOfResolution(resolution);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
nonRelativeExternalModuleResolutions.add(name, resolution);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
resolution.refCount = 1;
|
function watchFailedLookupLocationOfResolution(resolution: ResolutionWithFailedLookupLocations) {
|
||||||
|
Debug.assert(!!resolution.refCount);
|
||||||
|
|
||||||
const { failedLookupLocations } = resolution;
|
const { failedLookupLocations } = resolution;
|
||||||
let setAtRoot = false;
|
let setAtRoot = false;
|
||||||
for (const failedLookupLocation of failedLookupLocations) {
|
for (const failedLookupLocation of failedLookupLocations) {
|
||||||
|
@ -480,6 +492,16 @@ namespace ts {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function setRefCountToUndefined(resolution: ResolutionWithFailedLookupLocations) {
|
||||||
|
resolution.refCount = undefined;
|
||||||
|
}
|
||||||
|
|
||||||
|
function watchFailedLookupLocationOfNonRelativeModuleResolutions(resolutions: ResolutionWithFailedLookupLocations[], name: string) {
|
||||||
|
const updateResolution = resolutionHost.getCurrentProgram().getTypeChecker().tryFindAmbientModuleWithoutAugmentations(name) ?
|
||||||
|
setRefCountToUndefined : watchFailedLookupLocationOfResolution;
|
||||||
|
resolutions.forEach(updateResolution);
|
||||||
|
}
|
||||||
|
|
||||||
function setDirectoryWatcher(dir: string, dirPath: Path, nonRecursive?: boolean) {
|
function setDirectoryWatcher(dir: string, dirPath: Path, nonRecursive?: boolean) {
|
||||||
const dirWatcher = directoryWatchesOfFailedLookups.get(dirPath);
|
const dirWatcher = directoryWatchesOfFailedLookups.get(dirPath);
|
||||||
if (dirWatcher) {
|
if (dirWatcher) {
|
||||||
|
@ -492,11 +514,11 @@ namespace ts {
|
||||||
}
|
}
|
||||||
|
|
||||||
function stopWatchFailedLookupLocationOfResolution(resolution: ResolutionWithFailedLookupLocations) {
|
function stopWatchFailedLookupLocationOfResolution(resolution: ResolutionWithFailedLookupLocations) {
|
||||||
if (!resolution.failedLookupLocations || !resolution.failedLookupLocations.length) {
|
if (!resolution.refCount) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
resolution.refCount!--;
|
resolution.refCount--;
|
||||||
if (resolution.refCount) {
|
if (resolution.refCount) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
|
@ -8486,7 +8486,7 @@ new C();`
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
it("when watching directories for failed lookup locations in amd resolution", () => {
|
describe("when watching directories for failed lookup locations in amd resolution", () => {
|
||||||
const projectRoot = "/user/username/projects/project";
|
const projectRoot = "/user/username/projects/project";
|
||||||
const nodeFile: File = {
|
const nodeFile: File = {
|
||||||
path: `${projectRoot}/src/typings/node.d.ts`,
|
path: `${projectRoot}/src/typings/node.d.ts`,
|
||||||
|
@ -8530,19 +8530,35 @@ export const x = 10;`
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
};
|
};
|
||||||
const files = [nodeFile, electronFile, srcFile, moduleFile, configFile, libFile];
|
|
||||||
|
function verifyModuleResolution(useNodeFile: boolean) {
|
||||||
|
const files = [...(useNodeFile ? [nodeFile] : []), electronFile, srcFile, moduleFile, configFile, libFile];
|
||||||
const host = createServerHost(files);
|
const host = createServerHost(files);
|
||||||
const service = createProjectService(host);
|
const service = createProjectService(host);
|
||||||
service.openClientFile(srcFile.path, srcFile.content, ScriptKind.TS, projectRoot);
|
service.openClientFile(srcFile.path, srcFile.content, ScriptKind.TS, projectRoot);
|
||||||
checkProjectActualFiles(service.configuredProjects.get(configFile.path)!, files.map(f => f.path));
|
checkProjectActualFiles(service.configuredProjects.get(configFile.path)!, files.map(f => f.path));
|
||||||
checkWatchedFilesDetailed(host, mapDefined(files, f => f === srcFile ? undefined : f.path), 1);
|
checkWatchedFilesDetailed(host, mapDefined(files, f => f === srcFile ? undefined : f.path), 1);
|
||||||
|
if (useNodeFile) {
|
||||||
|
checkWatchedDirectories(host, emptyArray, /*recursive*/ false); // since fs resolves to ambient module, shouldnt watch failed lookup
|
||||||
|
}
|
||||||
|
else {
|
||||||
checkWatchedDirectoriesDetailed(host, [`${projectRoot}`], 1, /*recursive*/ false); // failed lookup for fs
|
checkWatchedDirectoriesDetailed(host, [`${projectRoot}`], 1, /*recursive*/ false); // failed lookup for fs
|
||||||
|
}
|
||||||
const expectedWatchedDirectories = createMap<number>();
|
const expectedWatchedDirectories = createMap<number>();
|
||||||
expectedWatchedDirectories.set(`${projectRoot}/src`, 2); // Wild card and failed lookup
|
expectedWatchedDirectories.set(`${projectRoot}/src`, 2); // Wild card and failed lookup
|
||||||
expectedWatchedDirectories.set(`${projectRoot}/somefolder`, 1); // failed lookup for somefolder/module2
|
expectedWatchedDirectories.set(`${projectRoot}/somefolder`, 1); // failed lookup for somefolder/module2
|
||||||
expectedWatchedDirectories.set(`${projectRoot}/node_modules`, 1); // failed lookup for with node_modules/@types/fs
|
expectedWatchedDirectories.set(`${projectRoot}/node_modules`, 1); // failed lookup for with node_modules/@types/fs
|
||||||
expectedWatchedDirectories.set(`${projectRoot}/src/typings`, 1); // typeroot directory
|
expectedWatchedDirectories.set(`${projectRoot}/src/typings`, 1); // typeroot directory
|
||||||
checkWatchedDirectoriesDetailed(host, expectedWatchedDirectories, /*recursive*/ true);
|
checkWatchedDirectoriesDetailed(host, expectedWatchedDirectories, /*recursive*/ true);
|
||||||
|
}
|
||||||
|
|
||||||
|
it("when resolves to ambient module", () => {
|
||||||
|
verifyModuleResolution(/*useNodeFile*/ true);
|
||||||
|
});
|
||||||
|
|
||||||
|
it("when resolution fails", () => {
|
||||||
|
verifyModuleResolution(/*useNodeFile*/ false);
|
||||||
|
});
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue