mirror of
https://github.com/microsoft/TypeScript.git
synced 2026-05-17 01:49:57 -05:00
PR feedback
This commit is contained in:
@@ -349,7 +349,7 @@ namespace ts.server {
|
||||
private readonly projectToSizeMap: Map<number> = createMap<number>();
|
||||
/**
|
||||
* This is a map of config file paths existance that doesnt need query to disk
|
||||
* - The entry can be present because there is inferred project that needs to watch addition of config file to folder
|
||||
* - The entry can be present because there is inferred project that needs to watch addition of config file to directory
|
||||
* In this case the exists could be true/false based on config file is present or not
|
||||
* - 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
|
||||
@@ -753,15 +753,15 @@ namespace ts.server {
|
||||
return this.watchDirectory(
|
||||
this.host,
|
||||
directory,
|
||||
fileOrFolder => {
|
||||
const fileOrFolderPath = this.toPath(fileOrFolder);
|
||||
project.getCachedDirectoryStructureHost().addOrDeleteFileOrFolder(fileOrFolder, fileOrFolderPath);
|
||||
fileOrDirectory => {
|
||||
const fileOrDirectoryPath = this.toPath(fileOrDirectory);
|
||||
project.getCachedDirectoryStructureHost().addOrDeleteFileOrDirectory(fileOrDirectory, fileOrDirectoryPath);
|
||||
const configFilename = project.getConfigFilePath();
|
||||
|
||||
// If the the added or created file or folder is not supported file name, ignore the file
|
||||
// If the the added or created file or directory is not supported file name, ignore the file
|
||||
// But when watched directory is added/removed, we need to reload the file list
|
||||
if (fileOrFolderPath !== directory && !isSupportedSourceFileName(fileOrFolder, project.getCompilationSettings(), this.hostConfiguration.extraFileExtensions)) {
|
||||
this.logger.info(`Project: ${configFilename} Detected file add/remove of non supported extension: ${fileOrFolder}`);
|
||||
if (fileOrDirectoryPath !== directory && !isSupportedSourceFileName(fileOrDirectory, project.getCompilationSettings(), this.hostConfiguration.extraFileExtensions)) {
|
||||
this.logger.info(`Project: ${configFilename} Detected file add/remove of non supported extension: ${fileOrDirectory}`);
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -833,7 +833,7 @@ namespace ts.server {
|
||||
switch (project.projectKind) {
|
||||
case ProjectKind.External:
|
||||
unorderedRemoveItem(this.externalProjects, <ExternalProject>project);
|
||||
this.projectToSizeMap.delete((project as ExternalProject).externalProjectName);
|
||||
this.projectToSizeMap.delete(project.getProjectName());
|
||||
break;
|
||||
case ProjectKind.Configured:
|
||||
this.configuredProjects.delete((<ConfiguredProject>project).canonicalConfigFilePath);
|
||||
@@ -852,7 +852,7 @@ namespace ts.server {
|
||||
|
||||
const project = this.getOrCreateInferredProjectForProjectRootPathIfEnabled(info, projectRootPath) ||
|
||||
this.getOrCreateSingleInferredProjectIfEnabled() ||
|
||||
this.createInferredProject();
|
||||
this.createInferredProject(getDirectoryPath(info.path));
|
||||
|
||||
project.addRoot(info);
|
||||
project.updateGraph();
|
||||
@@ -1374,7 +1374,7 @@ namespace ts.server {
|
||||
|
||||
this.addFilesToNonInferredProjectAndUpdateGraph(project, files, externalFilePropertyReader, typeAcquisition);
|
||||
this.externalProjects.push(project);
|
||||
this.sendProjectTelemetry(project.externalProjectName, project);
|
||||
this.sendProjectTelemetry(projectFileName, project);
|
||||
return project;
|
||||
}
|
||||
|
||||
@@ -1461,7 +1461,7 @@ namespace ts.server {
|
||||
this.addFilesToNonInferredProjectAndUpdateGraph(project, filesToAdd, fileNamePropertyReader, projectOptions.typeAcquisition);
|
||||
this.configuredProjects.set(project.canonicalConfigFilePath, project);
|
||||
this.setConfigFileExistenceByNewConfiguredProject(project);
|
||||
this.sendProjectTelemetry(project.getConfigFilePath(), project, projectOptions);
|
||||
this.sendProjectTelemetry(configFileName, project, projectOptions);
|
||||
return project;
|
||||
}
|
||||
|
||||
@@ -1584,7 +1584,7 @@ namespace ts.server {
|
||||
return project;
|
||||
}
|
||||
}
|
||||
return this.createInferredProject(/*isSingleInferredProject*/ false, projectRootPath);
|
||||
return this.createInferredProject(projectRootPath, /*isSingleInferredProject*/ false, projectRootPath);
|
||||
}
|
||||
|
||||
// we don't have an explicit root path, so we should try to find an inferred project
|
||||
@@ -1621,12 +1621,12 @@ namespace ts.server {
|
||||
return this.inferredProjects[0];
|
||||
}
|
||||
|
||||
return this.createInferredProject(/*isSingleInferredProject*/ true);
|
||||
return this.createInferredProject(/*rootDirectoryForResolution*/ undefined, /*isSingleInferredProject*/ true);
|
||||
}
|
||||
|
||||
private createInferredProject(isSingleInferredProject?: boolean, projectRootPath?: string): InferredProject {
|
||||
private createInferredProject(rootDirectoryForResolution: string | undefined, isSingleInferredProject?: boolean, projectRootPath?: string): InferredProject {
|
||||
const compilerOptions = projectRootPath && this.compilerOptionsForInferredProjectsPerProjectRoot.get(projectRootPath) || this.compilerOptionsForInferredProjects;
|
||||
const project = new InferredProject(this, this.documentRegistry, compilerOptions, projectRootPath);
|
||||
const project = new InferredProject(this, this.documentRegistry, compilerOptions, projectRootPath, rootDirectoryForResolution);
|
||||
if (isSingleInferredProject) {
|
||||
this.inferredProjects.unshift(project);
|
||||
}
|
||||
@@ -1669,10 +1669,12 @@ namespace ts.server {
|
||||
}
|
||||
}
|
||||
|
||||
/*@internal*/
|
||||
getOrCreateScriptInfoNotOpenedByClientForNormalizedPath(fileName: NormalizedPath, scriptKind?: ScriptKind, hasMixedContent?: boolean, hostToQueryFileExistsOn?: DirectoryStructureHost) {
|
||||
return this.getOrCreateScriptInfoForNormalizedPath(fileName, /*openedByClient*/ false, /*fileContent*/ undefined, scriptKind, hasMixedContent, hostToQueryFileExistsOn);
|
||||
}
|
||||
|
||||
/*@internal*/
|
||||
getOrCreateScriptInfoOpenedByClientForNormalizedPath(fileName: NormalizedPath, fileContent?: string, scriptKind?: ScriptKind, hasMixedContent?: boolean, hostToQueryFileExistsOn?: DirectoryStructureHost) {
|
||||
return this.getOrCreateScriptInfoForNormalizedPath(fileName, /*openedByClient*/ true, fileContent, scriptKind, hasMixedContent, hostToQueryFileExistsOn);
|
||||
}
|
||||
|
||||
@@ -162,7 +162,8 @@ namespace ts.server {
|
||||
*/
|
||||
private projectStateVersion = 0;
|
||||
|
||||
private changedAutomaticTypeDirectiveNames = false;
|
||||
/*@internal*/
|
||||
hasChangedAutomaticTypeDirectiveNames = false;
|
||||
|
||||
private typingFiles: SortedReadonlyArray<string>;
|
||||
|
||||
@@ -201,7 +202,8 @@ namespace ts.server {
|
||||
languageServiceEnabled: boolean,
|
||||
private compilerOptions: CompilerOptions,
|
||||
public compileOnSaveEnabled: boolean,
|
||||
/*@internal*/public directoryStructureHost: DirectoryStructureHost) {
|
||||
/*@internal*/public directoryStructureHost: DirectoryStructureHost,
|
||||
rootDirectoryForResolution: string | undefined) {
|
||||
|
||||
if (!this.compilerOptions) {
|
||||
this.compilerOptions = getDefaultCompilerOptions();
|
||||
@@ -224,7 +226,7 @@ namespace ts.server {
|
||||
}
|
||||
|
||||
this.languageService = createLanguageService(this, this.documentRegistry);
|
||||
this.resolutionCache = createResolutionCache(this);
|
||||
this.resolutionCache = createResolutionCache(this, rootDirectoryForResolution);
|
||||
if (!languageServiceEnabled) {
|
||||
this.disableLanguageService();
|
||||
}
|
||||
@@ -244,29 +246,26 @@ namespace ts.server {
|
||||
}
|
||||
|
||||
getScriptFileNames() {
|
||||
const result: string[] = [];
|
||||
if (this.rootFiles) {
|
||||
this.rootFilesMap.forEach((value, _path) => {
|
||||
const f: ScriptInfo = isScriptInfo(value) && value;
|
||||
if (this.languageServiceEnabled || (f && f.isScriptOpen())) {
|
||||
// if language service is disabled - process only files that are open
|
||||
result.push(f ? f.fileName : value as NormalizedPath);
|
||||
}
|
||||
});
|
||||
if (this.typingFiles) {
|
||||
for (const f of this.typingFiles) {
|
||||
result.push(f);
|
||||
}
|
||||
}
|
||||
if (!this.rootFiles) {
|
||||
return ts.emptyArray;
|
||||
}
|
||||
return result;
|
||||
|
||||
let result: string[] | undefined;
|
||||
this.rootFilesMap.forEach(value => {
|
||||
if (this.languageServiceEnabled || (isScriptInfo(value) && value.isScriptOpen())) {
|
||||
// if language service is disabled - process only files that are open
|
||||
(result || (result = [])).push(isScriptInfo(value) ? value.fileName : value);
|
||||
}
|
||||
});
|
||||
|
||||
return addRange(result, this.typingFiles) || ts.emptyArray;
|
||||
}
|
||||
|
||||
private getScriptInfoLSHost(fileName: string) {
|
||||
private getOrCreateScriptInfoAndAttachToProject(fileName: string) {
|
||||
const scriptInfo = this.projectService.getOrCreateScriptInfoNotOpenedByClient(fileName, this.directoryStructureHost);
|
||||
if (scriptInfo) {
|
||||
const existingValue = this.rootFilesMap.get(scriptInfo.path);
|
||||
if (existingValue !== undefined && existingValue !== scriptInfo) {
|
||||
if (existingValue !== scriptInfo && existingValue !== undefined) {
|
||||
// This was missing path earlier but now the file exists. Update the root
|
||||
this.rootFiles.push(scriptInfo);
|
||||
this.rootFilesMap.set(scriptInfo.path, scriptInfo);
|
||||
@@ -277,17 +276,17 @@ namespace ts.server {
|
||||
}
|
||||
|
||||
getScriptKind(fileName: string) {
|
||||
const info = this.getScriptInfoLSHost(fileName);
|
||||
const info = this.getOrCreateScriptInfoAndAttachToProject(fileName);
|
||||
return info && info.scriptKind;
|
||||
}
|
||||
|
||||
getScriptVersion(filename: string) {
|
||||
const info = this.getScriptInfoLSHost(filename);
|
||||
const info = this.getOrCreateScriptInfoAndAttachToProject(filename);
|
||||
return info && info.getLatestVersion();
|
||||
}
|
||||
|
||||
getScriptSnapshot(filename: string): IScriptSnapshot {
|
||||
const scriptInfo = this.getScriptInfoLSHost(filename);
|
||||
const scriptInfo = this.getOrCreateScriptInfoAndAttachToProject(filename);
|
||||
if (scriptInfo) {
|
||||
return scriptInfo.getSnapshot();
|
||||
}
|
||||
@@ -377,15 +376,10 @@ namespace ts.server {
|
||||
|
||||
/*@internal*/
|
||||
onChangedAutomaticTypeDirectiveNames() {
|
||||
this.changedAutomaticTypeDirectiveNames = true;
|
||||
this.hasChangedAutomaticTypeDirectiveNames = true;
|
||||
this.projectService.delayUpdateProjectGraphAndInferredProjectsRefresh(this);
|
||||
}
|
||||
|
||||
/*@internal*/
|
||||
hasChangedAutomaticTypeDirectiveNames() {
|
||||
return this.changedAutomaticTypeDirectiveNames;
|
||||
}
|
||||
|
||||
/*@internal*/
|
||||
getGlobalCache() {
|
||||
return this.getTypeAcquisition().enable ? this.projectService.typingsInstaller.globalTypingsCacheLocation : undefined;
|
||||
@@ -802,7 +796,7 @@ namespace ts.server {
|
||||
// - oldProgram is not set - this is a first time updateGraph is called
|
||||
// - newProgram is different from the old program and structure of the old program was not reused.
|
||||
const hasChanges = !oldProgram || (this.program !== oldProgram && !(oldProgram.structureIsReused & StructureIsReused.Completely));
|
||||
this.changedAutomaticTypeDirectiveNames = false;
|
||||
this.hasChangedAutomaticTypeDirectiveNames = false;
|
||||
if (hasChanges) {
|
||||
if (oldProgram) {
|
||||
for (const f of oldProgram.getSourceFiles()) {
|
||||
@@ -1035,7 +1029,12 @@ namespace ts.server {
|
||||
super.setCompilerOptions(newOptions);
|
||||
}
|
||||
|
||||
constructor(projectService: ProjectService, documentRegistry: DocumentRegistry, compilerOptions: CompilerOptions, public readonly projectRootPath?: string | undefined) {
|
||||
constructor(
|
||||
projectService: ProjectService,
|
||||
documentRegistry: DocumentRegistry,
|
||||
compilerOptions: CompilerOptions,
|
||||
public readonly projectRootPath: string | undefined,
|
||||
rootDirectoryForResolution: string | undefined) {
|
||||
super(InferredProject.newName(),
|
||||
ProjectKind.Inferred,
|
||||
projectService,
|
||||
@@ -1044,7 +1043,8 @@ namespace ts.server {
|
||||
/*languageServiceEnabled*/ true,
|
||||
compilerOptions,
|
||||
/*compileOnSaveEnabled*/ false,
|
||||
projectService.host);
|
||||
projectService.host,
|
||||
rootDirectoryForResolution);
|
||||
}
|
||||
|
||||
addRoot(info: ScriptInfo) {
|
||||
@@ -1053,13 +1053,6 @@ namespace ts.server {
|
||||
this.toggleJsInferredProject(/*isJsInferredProject*/ true);
|
||||
}
|
||||
super.addRoot(info);
|
||||
// For first root set the resolution cache root dir
|
||||
if (this.getRootFiles.length === 1) {
|
||||
const rootDirPath = this.getProjectRootPath();
|
||||
if (rootDirPath) {
|
||||
this.resolutionCache.setRootDirectory(rootDirPath);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
removeRoot(info: ScriptInfo) {
|
||||
@@ -1081,11 +1074,9 @@ namespace ts.server {
|
||||
}
|
||||
|
||||
getProjectRootPath() {
|
||||
// Single inferred project does not have a project root.
|
||||
if (this.projectService.useSingleInferredProject) {
|
||||
return undefined;
|
||||
}
|
||||
return this.projectRootPath || getDirectoryPath(this.getRootFiles()[0]);
|
||||
return this.projectRootPath ||
|
||||
// Single inferred project does not have a project root.
|
||||
!this.projectService.useSingleInferredProject && getDirectoryPath(this.getRootFiles()[0]);
|
||||
}
|
||||
|
||||
close() {
|
||||
@@ -1135,10 +1126,18 @@ namespace ts.server {
|
||||
languageServiceEnabled: boolean,
|
||||
public compileOnSaveEnabled: boolean,
|
||||
cachedDirectoryStructureHost: CachedDirectoryStructureHost) {
|
||||
super(configFileName, ProjectKind.Configured, projectService, documentRegistry, hasExplicitListOfFiles, languageServiceEnabled, compilerOptions, compileOnSaveEnabled, cachedDirectoryStructureHost);
|
||||
super(configFileName,
|
||||
ProjectKind.Configured,
|
||||
projectService,
|
||||
documentRegistry,
|
||||
hasExplicitListOfFiles,
|
||||
languageServiceEnabled,
|
||||
compilerOptions,
|
||||
compileOnSaveEnabled,
|
||||
cachedDirectoryStructureHost,
|
||||
getDirectoryPath(configFileName));
|
||||
this.canonicalConfigFilePath = asNormalizedPath(projectService.toCanonicalFileName(configFileName));
|
||||
this.enablePlugins();
|
||||
this.resolutionCache.setRootDirectory(getDirectoryPath(configFileName));
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -1370,8 +1369,15 @@ namespace ts.server {
|
||||
languageServiceEnabled: boolean,
|
||||
public compileOnSaveEnabled: boolean,
|
||||
private readonly projectFilePath?: string) {
|
||||
super(externalProjectName, ProjectKind.External, projectService, documentRegistry, /*hasExplicitListOfFiles*/ true, languageServiceEnabled, compilerOptions, compileOnSaveEnabled, projectService.host);
|
||||
this.resolutionCache.setRootDirectory(this.getProjectRootPath());
|
||||
super(externalProjectName,
|
||||
ProjectKind.External,
|
||||
projectService,
|
||||
documentRegistry,
|
||||
/*hasExplicitListOfFiles*/ true,
|
||||
languageServiceEnabled, compilerOptions,
|
||||
compileOnSaveEnabled,
|
||||
projectService.host,
|
||||
getDirectoryPath(projectFilePath || normalizeSlashes(externalProjectName)));
|
||||
}
|
||||
|
||||
getExcludedFiles() {
|
||||
|
||||
@@ -4,17 +4,36 @@ namespace ts.server {
|
||||
|
||||
/* @internal */
|
||||
export class TextStorage {
|
||||
// Generated only on demand and removes the text if any edits
|
||||
/**
|
||||
* Generated only on demand (based on edits, or information requested)
|
||||
* The property text is set to undefined when edits happen on the cache
|
||||
*/
|
||||
private svc: ScriptVersionCache | undefined;
|
||||
private svcVersion = 0;
|
||||
|
||||
// Store text when there is no svc or svc has no change, on edit, remove the text
|
||||
/**
|
||||
* Stores the text when there are no changes to the script version cache
|
||||
* The script version cache is generated on demand and text is still retained.
|
||||
* Only on edits to the script version cache, the text will be set to undefined
|
||||
*/
|
||||
private text: string;
|
||||
/**
|
||||
* Line map for the text when there is no script version cache present
|
||||
*/
|
||||
private lineMap: number[];
|
||||
private textVersion = 0;
|
||||
|
||||
/**
|
||||
* True if the text is for the file thats open in the editor
|
||||
*/
|
||||
public isOpen: boolean;
|
||||
/**
|
||||
* True if the text present is the text from the file on the disk
|
||||
*/
|
||||
private ownFileText: boolean;
|
||||
/**
|
||||
* True when reloading contents of file from the disk is pending
|
||||
*/
|
||||
private pendingReloadFromDisk: boolean;
|
||||
|
||||
constructor(private readonly host: ServerHost, private readonly fileName: NormalizedPath) {
|
||||
|
||||
Reference in New Issue
Block a user