mirror of
https://github.com/microsoft/TypeScript.git
synced 2025-11-18 17:21:48 +00:00
More work on PR feedback update
This commit is contained in:
@@ -1482,6 +1482,7 @@ namespace ts {
|
||||
return error.code === Diagnostics.No_inputs_were_found_in_config_file_0_Specified_include_paths_were_1_and_exclude_paths_were_2.code;
|
||||
}
|
||||
|
||||
/*@internal*/
|
||||
export function getErrorForNoInputFiles({ includeSpecs, excludeSpecs }: ConfigFileSpecs, configFileName: string | undefined) {
|
||||
return createCompilerDiagnostic(
|
||||
Diagnostics.No_inputs_were_found_in_config_file_0_Specified_include_paths_were_1_and_exclude_paths_were_2,
|
||||
@@ -1928,9 +1929,9 @@ namespace ts {
|
||||
/**
|
||||
* Expands an array of file specifications.
|
||||
*
|
||||
* @param fileNames The literal file names to include.
|
||||
* @param include The wildcard file specifications to include.
|
||||
* @param exclude The wildcard file specifications to exclude.
|
||||
* @param filesSpecs The literal file names to include.
|
||||
* @param includeSpecs The wildcard file specifications to include.
|
||||
* @param excludeSpecs The wildcard file specifications to exclude.
|
||||
* @param basePath The base path for any relative file specifications.
|
||||
* @param options Compiler options.
|
||||
* @param host The host used to resolve files and directories.
|
||||
|
||||
@@ -3607,10 +3607,6 @@ namespace ts {
|
||||
export function getCombinedLocalAndExportSymbolFlags(symbol: Symbol): SymbolFlags {
|
||||
return symbol.exportSymbol ? symbol.exportSymbol.flags | symbol.flags : symbol.flags;
|
||||
}
|
||||
|
||||
export function isRecursiveDirectoryWatch(flags: WatchDirectoryFlags) {
|
||||
return (flags & WatchDirectoryFlags.Recursive) !== 0;
|
||||
}
|
||||
}
|
||||
|
||||
namespace ts {
|
||||
|
||||
@@ -534,7 +534,7 @@ namespace ts.projectSystem {
|
||||
}
|
||||
|
||||
/**
|
||||
* This will call the directory watcher for the foldeFullPath and recursive directory watchers for this and base folders
|
||||
* This will call the directory watcher for the folderFullPath and recursive directory watchers for this and base folders
|
||||
*/
|
||||
private invokeDirectoryWatcher(folderFullPath: string, fileName: string) {
|
||||
const relativePath = this.getRelativePathToDirectory(folderFullPath, fileName);
|
||||
|
||||
@@ -246,7 +246,7 @@ namespace ts.server {
|
||||
export const enum WatchType {
|
||||
ConfigFilePath = "Config file for the program",
|
||||
MissingFilePath = "Missing file from program",
|
||||
WildCardDirectories = "Wild card directory",
|
||||
WildcardDirectories = "Wild card directory",
|
||||
TypeRoot = "Type root of the project",
|
||||
ClosedScriptInfo = "Closed Script info",
|
||||
ConfigFileForInferredRoot = "Config file for the inferred project root"
|
||||
@@ -363,7 +363,7 @@ namespace ts.server {
|
||||
* - Or it is present if we have configured project open with config file at that location
|
||||
* In this case the exists property is always true
|
||||
*/
|
||||
private readonly mapOfConfigFileExistenceInfo = createMap<ConfigFileExistenceInfo>();
|
||||
private readonly configFileExistenceInfoCache = createMap<ConfigFileExistenceInfo>();
|
||||
private readonly throttledOperations: ThrottledOperations;
|
||||
|
||||
private readonly hostConfiguration: HostConfiguration;
|
||||
@@ -693,7 +693,7 @@ namespace ts.server {
|
||||
}
|
||||
|
||||
private onConfigChangedForConfiguredProject(project: ConfiguredProject, eventKind: FileWatcherEventKind) {
|
||||
const configFileExistenceInfo = this.mapOfConfigFileExistenceInfo.get(project.canonicalConfigFilePath);
|
||||
const configFileExistenceInfo = this.configFileExistenceInfoCache.get(project.canonicalConfigFilePath);
|
||||
if (eventKind === FileWatcherEventKind.Deleted) {
|
||||
// Update the cached status
|
||||
// We arent updating or removing the cached config file presence info as that will be taken care of by
|
||||
@@ -725,7 +725,7 @@ namespace ts.server {
|
||||
private onConfigFileChangeForOpenScriptInfo(configFileName: NormalizedPath, eventKind: FileWatcherEventKind) {
|
||||
// This callback is called only if we dont have config file project for this config file
|
||||
const canonicalConfigPath = normalizedPathToPath(configFileName, this.currentDirectory, this.toCanonicalFileName);
|
||||
const configFileExistenceInfo = this.mapOfConfigFileExistenceInfo.get(canonicalConfigPath);
|
||||
const configFileExistenceInfo = this.configFileExistenceInfoCache.get(canonicalConfigPath);
|
||||
configFileExistenceInfo.exists = (eventKind !== FileWatcherEventKind.Deleted);
|
||||
this.logConfigFileWatchUpdate(configFileName, canonicalConfigPath, configFileExistenceInfo, ConfigFileWatcherStatus.ReloadingFiles);
|
||||
|
||||
@@ -852,7 +852,7 @@ namespace ts.server {
|
||||
}
|
||||
|
||||
private configFileExists(configFileName: NormalizedPath, canonicalConfigFilePath: string, info: ScriptInfo) {
|
||||
let configFileExistenceInfo = this.mapOfConfigFileExistenceInfo.get(canonicalConfigFilePath);
|
||||
let configFileExistenceInfo = this.configFileExistenceInfoCache.get(canonicalConfigFilePath);
|
||||
if (configFileExistenceInfo) {
|
||||
// By default the info would get impacted by presence of config file since its in the detection path
|
||||
// Only adding the info as a root to inferred project will need the existence to be watched by file watcher
|
||||
@@ -877,13 +877,13 @@ namespace ts.server {
|
||||
openFilesImpactedByConfigFile.set(info.path, false);
|
||||
const exists = this.host.fileExists(configFileName);
|
||||
configFileExistenceInfo = { exists, openFilesImpactedByConfigFile };
|
||||
this.mapOfConfigFileExistenceInfo.set(canonicalConfigFilePath, configFileExistenceInfo);
|
||||
this.configFileExistenceInfoCache.set(canonicalConfigFilePath, configFileExistenceInfo);
|
||||
this.logConfigFileWatchUpdate(configFileName, canonicalConfigFilePath, configFileExistenceInfo, ConfigFileWatcherStatus.OpenFilesImpactedByConfigFileAdd);
|
||||
return exists;
|
||||
}
|
||||
|
||||
private setConfigFileExistenceByNewConfiguredProject(project: ConfiguredProject) {
|
||||
const configFileExistenceInfo = this.mapOfConfigFileExistenceInfo.get(project.canonicalConfigFilePath);
|
||||
const configFileExistenceInfo = this.configFileExistenceInfoCache.get(project.canonicalConfigFilePath);
|
||||
if (configFileExistenceInfo) {
|
||||
Debug.assert(configFileExistenceInfo.exists);
|
||||
// close existing watcher
|
||||
@@ -900,7 +900,7 @@ namespace ts.server {
|
||||
else {
|
||||
// We could be in this scenario if project is the configured project tracked by external project
|
||||
// Since that route doesnt check if the config file is present or not
|
||||
this.mapOfConfigFileExistenceInfo.set(project.canonicalConfigFilePath, {
|
||||
this.configFileExistenceInfoCache.set(project.canonicalConfigFilePath, {
|
||||
exists: true,
|
||||
openFilesImpactedByConfigFile: createMap<boolean>()
|
||||
});
|
||||
@@ -915,7 +915,7 @@ namespace ts.server {
|
||||
}
|
||||
|
||||
private setConfigFileExistenceInfoByClosedConfiguredProject(closedProject: ConfiguredProject) {
|
||||
const configFileExistenceInfo = this.mapOfConfigFileExistenceInfo.get(closedProject.canonicalConfigFilePath);
|
||||
const configFileExistenceInfo = this.configFileExistenceInfoCache.get(closedProject.canonicalConfigFilePath);
|
||||
Debug.assert(!!configFileExistenceInfo);
|
||||
if (configFileExistenceInfo.openFilesImpactedByConfigFile.size) {
|
||||
const configFileName = closedProject.getConfigFilePath();
|
||||
@@ -933,7 +933,7 @@ namespace ts.server {
|
||||
}
|
||||
else {
|
||||
// There is not a single file open thats tracking the status of this config file. Remove from cache
|
||||
this.mapOfConfigFileExistenceInfo.delete(closedProject.canonicalConfigFilePath);
|
||||
this.configFileExistenceInfoCache.delete(closedProject.canonicalConfigFilePath);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -983,7 +983,7 @@ namespace ts.server {
|
||||
private stopWatchingConfigFilesForClosedScriptInfo(info: ScriptInfo) {
|
||||
Debug.assert(!info.isScriptOpen());
|
||||
this.forEachConfigFileLocation(info, (configFileName, canonicalConfigFilePath) => {
|
||||
const configFileExistenceInfo = this.mapOfConfigFileExistenceInfo.get(canonicalConfigFilePath);
|
||||
const configFileExistenceInfo = this.configFileExistenceInfoCache.get(canonicalConfigFilePath);
|
||||
if (configFileExistenceInfo) {
|
||||
const infoIsRootOfInferredProject = configFileExistenceInfo.openFilesImpactedByConfigFile.get(info.path);
|
||||
|
||||
@@ -1006,7 +1006,7 @@ namespace ts.server {
|
||||
if (!configFileExistenceInfo.openFilesImpactedByConfigFile.size &&
|
||||
!this.getConfiguredProjectByCanonicalConfigFilePath(canonicalConfigFilePath)) {
|
||||
Debug.assert(!configFileExistenceInfo.configFileWatcherForRootOfInferredProject);
|
||||
this.mapOfConfigFileExistenceInfo.delete(canonicalConfigFilePath);
|
||||
this.configFileExistenceInfoCache.delete(canonicalConfigFilePath);
|
||||
}
|
||||
}
|
||||
});
|
||||
@@ -1019,14 +1019,14 @@ namespace ts.server {
|
||||
startWatchingConfigFilesForInferredProjectRoot(info: ScriptInfo) {
|
||||
Debug.assert(info.isScriptOpen());
|
||||
this.forEachConfigFileLocation(info, (configFileName, canonicalConfigFilePath) => {
|
||||
let configFilePresenceInfo = this.mapOfConfigFileExistenceInfo.get(canonicalConfigFilePath);
|
||||
let configFilePresenceInfo = this.configFileExistenceInfoCache.get(canonicalConfigFilePath);
|
||||
if (!configFilePresenceInfo) {
|
||||
// Create the cache
|
||||
configFilePresenceInfo = {
|
||||
exists: this.host.fileExists(configFileName),
|
||||
openFilesImpactedByConfigFile: createMap<boolean>()
|
||||
};
|
||||
this.mapOfConfigFileExistenceInfo.set(canonicalConfigFilePath, configFilePresenceInfo);
|
||||
this.configFileExistenceInfoCache.set(canonicalConfigFilePath, configFilePresenceInfo);
|
||||
}
|
||||
|
||||
// Set this file as the root of inferred project
|
||||
@@ -1050,7 +1050,7 @@ namespace ts.server {
|
||||
/* @internal */
|
||||
stopWatchingConfigFilesForInferredProjectRoot(info: ScriptInfo, reason: WatcherCloseReason) {
|
||||
this.forEachConfigFileLocation(info, (configFileName, canonicalConfigFilePath) => {
|
||||
const configFileExistenceInfo = this.mapOfConfigFileExistenceInfo.get(canonicalConfigFilePath);
|
||||
const configFileExistenceInfo = this.configFileExistenceInfoCache.get(canonicalConfigFilePath);
|
||||
if (configFileExistenceInfo && configFileExistenceInfo.openFilesImpactedByConfigFile.has(info.path)) {
|
||||
Debug.assert(info.isScriptOpen());
|
||||
|
||||
@@ -1607,14 +1607,14 @@ namespace ts.server {
|
||||
|
||||
/* @internal */
|
||||
closeDirectoryWatcher(watchType: WatchType, project: Project, directory: string, watcher: FileWatcher, flags: WatchDirectoryFlags, reason: WatcherCloseReason) {
|
||||
const recursive = isRecursiveDirectoryWatch(flags);
|
||||
const recursive = (flags & WatchDirectoryFlags.Recursive) !== 0;
|
||||
this.logger.info(`DirectoryWatcher ${recursive ? "recursive" : ""}:: Close: ${directory} Project: ${project.getProjectName()} WatchType: ${watchType} Reason: ${reason}`);
|
||||
watcher.close();
|
||||
}
|
||||
|
||||
/* @internal */
|
||||
addDirectoryWatcher(watchType: WatchType, project: Project, directory: string, cb: ServerDirectoryWatcherCallback, flags: WatchDirectoryFlags) {
|
||||
const recursive = isRecursiveDirectoryWatch(flags);
|
||||
const recursive = (flags & WatchDirectoryFlags.Recursive) !== 0;
|
||||
this.logger.info(`DirectoryWatcher ${recursive ? "recursive" : ""}:: Added: ${directory} Project: ${project.getProjectName()} WatchType: ${watchType}`);
|
||||
return this.host.watchDirectory(directory, fileName => {
|
||||
const path = toNormalizedPath(getNormalizedAbsolutePath(fileName, directory));
|
||||
|
||||
@@ -1153,22 +1153,25 @@ namespace ts.server {
|
||||
createNewValue: (directory, flags) => {
|
||||
return {
|
||||
watcher: this.projectService.addDirectoryWatcher(
|
||||
WatchType.WildCardDirectories, this, directory,
|
||||
WatchType.WildcardDirectories, this, directory,
|
||||
path => this.projectService.onFileAddOrRemoveInWatchedDirectoryOfProject(this, path),
|
||||
flags
|
||||
),
|
||||
flags
|
||||
};
|
||||
},
|
||||
// Close existing watch thats not needed any more or doesnt match recursive flags
|
||||
onDeleteExistingValue: (directory, wildcardDirectoryWatcher, isNotSame) =>
|
||||
this.closeWildcardDirectoryWatcher(directory, wildcardDirectoryWatcher, isNotSame ? WatcherCloseReason.RecursiveChanged : WatcherCloseReason.NotNeeded),
|
||||
// Close existing watch thats not needed any more
|
||||
onDeleteExistingValue: (directory, wildcardDirectoryWatcher) =>
|
||||
this.closeWildcardDirectoryWatcher(directory, wildcardDirectoryWatcher, WatcherCloseReason.NotNeeded),
|
||||
// Close existing watch that doesnt match in the recursive flags
|
||||
onDeleteExistingMismatchValue: (directory, wildcardDirectoryWatcher) =>
|
||||
this.closeWildcardDirectoryWatcher(directory, wildcardDirectoryWatcher, WatcherCloseReason.RecursiveChanged),
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
private closeWildcardDirectoryWatcher(directory: string, { watcher, flags }: WildcardDirectoryWatcher, closeReason: WatcherCloseReason) {
|
||||
this.projectService.closeDirectoryWatcher(WatchType.WildCardDirectories, this, directory, watcher, flags, closeReason);
|
||||
this.projectService.closeDirectoryWatcher(WatchType.WildcardDirectories, this, directory, watcher, flags, closeReason);
|
||||
}
|
||||
|
||||
stopWatchingWildCards(reason: WatcherCloseReason) {
|
||||
|
||||
+13
-8
@@ -299,14 +299,14 @@ namespace ts.server {
|
||||
}
|
||||
|
||||
/**
|
||||
* clears already present map (!== undefined) by calling onDeleteExistingValue callback before deleting that key/value
|
||||
* clears already present map by calling onDeleteExistingValue callback before deleting that key/value
|
||||
*/
|
||||
export function clearMap<T>(map: Map<T>, onDeleteExistingValue: (key: string, existingValue: T) => void) {
|
||||
// Remove all
|
||||
map.forEach((existingValue, key) => {
|
||||
map.delete(key);
|
||||
onDeleteExistingValue(key, existingValue);
|
||||
});
|
||||
map.clear();
|
||||
}
|
||||
|
||||
export interface MutateMapOptions<T, U> {
|
||||
@@ -314,6 +314,7 @@ namespace ts.server {
|
||||
onDeleteExistingValue(key: string, existingValue: T, isNotSame?: boolean): void;
|
||||
|
||||
isSameValue?(existingValue: T, valueInNewMap: U): boolean;
|
||||
onDeleteExistingMismatchValue?(key: string, existingValue: T): void;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -322,16 +323,20 @@ namespace ts.server {
|
||||
export function mutateMap<T, U>(map: Map<T>, newMap: ReadonlyMap<U>, options: MutateMapOptions<T, U>) {
|
||||
// If there are new values update them
|
||||
if (newMap) {
|
||||
const { isSameValue, createNewValue, onDeleteExistingValue } = options;
|
||||
const { isSameValue, createNewValue, onDeleteExistingValue, onDeleteExistingMismatchValue } = options;
|
||||
// Needs update
|
||||
map.forEach((existingValue, key) => {
|
||||
const valueInNewMap = newMap.get(key);
|
||||
if (valueInNewMap === undefined ||
|
||||
// different value - remove it
|
||||
(isSameValue && !isSameValue(existingValue, valueInNewMap))) {
|
||||
const isNotSame = valueInNewMap !== undefined;
|
||||
// Not present any more in new map, remove it
|
||||
if (valueInNewMap === undefined) {
|
||||
map.delete(key);
|
||||
onDeleteExistingValue(key, existingValue, isNotSame);
|
||||
onDeleteExistingValue(key, existingValue);
|
||||
}
|
||||
// different value - remove it
|
||||
else if (isSameValue && !isSameValue(existingValue, valueInNewMap)) {
|
||||
Debug.assert(!!onDeleteExistingMismatchValue);
|
||||
map.delete(key);
|
||||
onDeleteExistingMismatchValue(key, existingValue);
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
Reference in New Issue
Block a user