Skip to content

Commit 5df0b3e

Browse files
committed
Refactor without looking continuing to look for tsconfig
This handles the config file change to be similar to what happens when file opens
1 parent b8b0df8 commit 5df0b3e

File tree

70 files changed

+1592
-1923
lines changed

Some content is hidden

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

70 files changed

+1592
-1923
lines changed

src/harness/projectServiceStateLogger.ts

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -104,7 +104,11 @@ export function patchServiceForStateBaseline(service: ProjectService) {
104104
function baselineProjects(currentMappers: Set<DocumentPositionMapper>) {
105105
const autoImportProviderProjects = [] as AutoImportProviderProject[];
106106
const auxiliaryProjects = [] as AuxiliaryProject[];
107-
const orphanConfiguredProjects = service.getOrphanConfiguredProjects(/*toRetainConfiguredProjects*/ undefined);
107+
const orphanConfiguredProjects = service.getOrphanConfiguredProjects(
108+
/*toRetainConfiguredProjects*/ undefined,
109+
/*openFilesWithRetainedConfiguredProject*/ undefined,
110+
/*externalProjectsRetainingConfiguredProjects*/ undefined,
111+
);
108112
const noOpenRef = (project: Project) => isConfiguredProject(project) && (project.isClosed() || orphanConfiguredProjects.has(project));
109113
return baselineState(
110114
[service.externalProjects, service.configuredProjects, service.inferredProjects, autoImportProviderProjects, auxiliaryProjects],

src/server/editorServices.ts

Lines changed: 787 additions & 482 deletions
Large diffs are not rendered by default.

src/server/project.ts

Lines changed: 4 additions & 85 deletions
Original file line numberDiff line numberDiff line change
@@ -141,15 +141,12 @@ import {
141141
emptyArray,
142142
Errors,
143143
FileStats,
144-
forEachResolvedProjectReferenceProject,
145144
LogLevel,
146145
ModuleImportResult,
147146
Msg,
148147
NormalizedPath,
149148
PackageJsonWatcher,
150-
projectContainsInfoDirectly,
151149
ProjectOptions,
152-
ProjectReferenceProjectLoadKind,
153150
ProjectService,
154151
ScriptInfo,
155152
ServerHost,
@@ -2211,7 +2208,7 @@ export abstract class Project implements LanguageServiceHost, ModuleResolutionHo
22112208
private isDefaultProjectForOpenFiles(): boolean {
22122209
return !!forEachEntry(
22132210
this.projectService.openFiles,
2214-
(_, fileName) => this.projectService.tryGetDefaultProjectForFile(toNormalizedPath(fileName)) === this,
2211+
(_projectRootPath, path) => this.projectService.tryGetDefaultProjectForFile(this.projectService.getScriptInfoForPath(path)!) === this,
22152212
);
22162213
}
22172214

@@ -2388,7 +2385,7 @@ export class InferredProject extends Project {
23882385
}
23892386

23902387
override removeRoot(info: ScriptInfo) {
2391-
this.projectService.stopWatchingConfigFilesForInferredProjectRoot(info);
2388+
this.projectService.stopWatchingConfigFilesForScriptInfo(info);
23922389
super.removeRoot(info);
23932390
// Delay toggling to isJsInferredProject = false till we actually need it again
23942391
if (!this.isOrphan() && this._isJsInferredProject && info.isJavaScript()) {
@@ -2412,7 +2409,7 @@ export class InferredProject extends Project {
24122409
}
24132410

24142411
override close() {
2415-
forEach(this.getRootScriptInfos(), info => this.projectService.stopWatchingConfigFilesForInferredProjectRoot(info));
2412+
forEach(this.getRootScriptInfos(), info => this.projectService.stopWatchingConfigFilesForScriptInfo(info));
24162413
super.close();
24172414
}
24182415

@@ -2763,9 +2760,6 @@ export class ConfiguredProject extends Project {
27632760
/** @internal */
27642761
canConfigFileJsonReportNoInputFiles = false;
27652762

2766-
/** Ref count to the project when opened from external project */
2767-
private externalProjectRefCount = 0;
2768-
27692763
private projectReferences: readonly ProjectReference[] | undefined;
27702764

27712765
/**
@@ -2873,8 +2867,7 @@ export class ConfiguredProject extends Project {
28732867
case ProgramUpdateLevel.Full:
28742868
this.openFileWatchTriggered.clear();
28752869
const reason = Debug.checkDefined(this.pendingUpdateReason);
2876-
this.pendingUpdateReason = undefined;
2877-
this.projectService.reloadConfiguredProject(this, reason, /*clearSemanticCache*/ false);
2870+
this.projectService.reloadConfiguredProject(this, reason);
28782871
result = true;
28792872
break;
28802873
default:
@@ -2998,91 +2991,17 @@ export class ConfiguredProject extends Project {
29982991
super.markAsDirty();
29992992
}
30002993

3001-
/** @internal */
3002-
addExternalProjectReference() {
3003-
this.externalProjectRefCount++;
3004-
}
3005-
3006-
/** @internal */
3007-
deleteExternalProjectReference() {
3008-
this.externalProjectRefCount--;
3009-
}
3010-
30112994
/** @internal */
30122995
isSolution() {
30132996
return this.getRootFilesMap().size === 0 &&
30142997
!this.canConfigFileJsonReportNoInputFiles;
30152998
}
30162999

3017-
/**
3018-
* Find the configured project from the project references in project which contains the info directly
3019-
*
3020-
* @internal
3021-
*/
3022-
getDefaultChildProjectFromProjectWithReferences(info: ScriptInfo) {
3023-
return forEachResolvedProjectReferenceProject(
3024-
this,
3025-
info.path,
3026-
child =>
3027-
projectContainsInfoDirectly(child, info) ?
3028-
child :
3029-
undefined,
3030-
ProjectReferenceProjectLoadKind.Find,
3031-
);
3032-
}
3033-
3034-
/**
3035-
* Returns true if the project is needed by any of the open script info/external project
3036-
*
3037-
* @internal
3038-
*/
3039-
hasOpenRef() {
3040-
if (!!this.externalProjectRefCount) {
3041-
return true;
3042-
}
3043-
3044-
// Closed project doesnt have any reference
3045-
if (this.isClosed()) {
3046-
return false;
3047-
}
3048-
3049-
const configFileExistenceInfo = this.projectService.configFileExistenceInfoCache.get(this.canonicalConfigFilePath)!;
3050-
if (this.deferredClose) return !!configFileExistenceInfo.openFilesImpactedByConfigFile?.size;
3051-
if (this.projectService.hasPendingProjectUpdate(this)) {
3052-
// If there is pending update for this project,
3053-
// we dont know if this project would be needed by any of the open files impacted by this config file
3054-
// In that case keep the project alive if there are open files impacted by this project
3055-
return !!configFileExistenceInfo.openFilesImpactedByConfigFile?.size;
3056-
}
3057-
3058-
// If there is no pending update for this project,
3059-
// We know exact set of open files that get impacted by this configured project as the files in the project
3060-
// The project is referenced only if open files impacted by this project are present in this project
3061-
return !!configFileExistenceInfo.openFilesImpactedByConfigFile && forEachEntry(
3062-
configFileExistenceInfo.openFilesImpactedByConfigFile,
3063-
(_value, infoPath) => {
3064-
const info = this.projectService.getScriptInfoForPath(infoPath)!;
3065-
return this.containsScriptInfo(info) ||
3066-
!!forEachResolvedProjectReferenceProject(
3067-
this,
3068-
info.path,
3069-
child => child.containsScriptInfo(info),
3070-
ProjectReferenceProjectLoadKind.Find,
3071-
);
3072-
},
3073-
) || false;
3074-
}
3075-
30763000
/** @internal */
30773001
override isOrphan(): boolean {
30783002
return !!this.deferredClose;
30793003
}
30803004

3081-
/** @internal */
3082-
hasExternalProjectRef() {
3083-
return !!this.externalProjectRefCount;
3084-
}
3085-
30863005
getEffectiveTypeRoots() {
30873006
return getEffectiveTypeRoots(this.getCompilationSettings(), this) || [];
30883007
}

src/server/scriptInfo.ts

Lines changed: 10 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -39,7 +39,6 @@ import {
3939
AbsolutePositionAndLineText,
4040
ConfiguredProject,
4141
Errors,
42-
ExternalProject,
4342
InferredProject,
4443
isBackgroundProject,
4544
isConfiguredProject,
@@ -580,18 +579,16 @@ export class ScriptInfo {
580579
case 0:
581580
return Errors.ThrowNoProject();
582581
case 1:
583-
return ensurePrimaryProjectKind(
584-
!isProjectDeferredClose(this.containingProjects[0]) ?
585-
this.containingProjects[0] : undefined,
586-
);
582+
return isProjectDeferredClose(this.containingProjects[0]) || isBackgroundProject(this.containingProjects[0]) ?
583+
Errors.ThrowNoProject() :
584+
this.containingProjects[0];
587585
default:
588586
// If this file belongs to multiple projects, below is the order in which default project is used
587+
// - first external project
589588
// - for open script info, its default configured project during opening is default if info is part of it
590589
// - first configured project of which script info is not a source of project reference redirect
591590
// - first configured project
592-
// - first external project
593591
// - first inferred project
594-
let firstExternalProject: ExternalProject | undefined;
595592
let firstConfiguredProject: ConfiguredProject | undefined;
596593
let firstInferredProject: InferredProject | undefined;
597594
let firstNonSourceOfProjectReferenceRedirect: ConfiguredProject | undefined;
@@ -614,20 +611,17 @@ export class ScriptInfo {
614611
}
615612
if (!firstConfiguredProject) firstConfiguredProject = project;
616613
}
617-
else if (!firstExternalProject && isExternalProject(project)) {
618-
firstExternalProject = project;
614+
else if (isExternalProject(project)) {
615+
return project;
619616
}
620617
else if (!firstInferredProject && isInferredProject(project)) {
621618
firstInferredProject = project;
622619
}
623620
}
624-
return ensurePrimaryProjectKind(
625-
defaultConfiguredProject ||
626-
firstNonSourceOfProjectReferenceRedirect ||
627-
firstConfiguredProject ||
628-
firstExternalProject ||
629-
firstInferredProject,
630-
);
621+
return (defaultConfiguredProject ||
622+
firstNonSourceOfProjectReferenceRedirect ||
623+
firstConfiguredProject ||
624+
firstInferredProject) ?? Errors.ThrowNoProject();
631625
}
632626
}
633627

@@ -742,18 +736,6 @@ export class ScriptInfo {
742736
}
743737
}
744738

745-
/**
746-
* Throws an error if `project` is an AutoImportProvider or AuxiliaryProject,
747-
* which are used in the background by other Projects and should never be
748-
* reported as the default project for a ScriptInfo.
749-
*/
750-
function ensurePrimaryProjectKind(project: Project | undefined) {
751-
if (!project || isBackgroundProject(project)) {
752-
return Errors.ThrowNoProject();
753-
}
754-
return project;
755-
}
756-
757739
function failIfInvalidPosition(position: number) {
758740
Debug.assert(typeof position === "number", `Expected position ${position} to be a number.`);
759741
Debug.assert(position >= 0, `Expected position to be non-negative.`);

src/server/session.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3214,7 +3214,7 @@ export class Session<TMessage = string> implements EventSender {
32143214
return this.requiredResponse(response);
32153215
},
32163216
[protocol.CommandTypes.OpenExternalProject]: (request: protocol.OpenExternalProjectRequest) => {
3217-
this.projectService.openExternalProject(request.arguments, /*print*/ true);
3217+
this.projectService.openExternalProject(request.arguments, /*cleanupAfter*/ true);
32183218
// TODO: GH#20447 report errors
32193219
return this.requiredResponse(/*response*/ true);
32203220
},
@@ -3224,7 +3224,7 @@ export class Session<TMessage = string> implements EventSender {
32243224
return this.requiredResponse(/*response*/ true);
32253225
},
32263226
[protocol.CommandTypes.CloseExternalProject]: (request: protocol.CloseExternalProjectRequest) => {
3227-
this.projectService.closeExternalProject(request.arguments.projectFileName, /*print*/ true);
3227+
this.projectService.closeExternalProject(request.arguments.projectFileName, /*cleanupAfter*/ true);
32283228
// TODO: GH#20447 report errors
32293229
return this.requiredResponse(/*response*/ true);
32303230
},

src/testRunner/unittests/tsserver/projects.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -177,7 +177,7 @@ describe("unittests:: tsserver:: projects::", () => {
177177
};
178178
session.host.baselineHost("Before request");
179179
session.logger.info(`request:${ts.server.stringifyIndented(request)}`);
180-
session.getProjectService().openExternalProject(request.arguments, /*print*/ true);
180+
session.getProjectService().openExternalProject(request.arguments, /*cleanupAfter*/ true);
181181
session.host.baselineHost("After request");
182182
baselineTsserverLogs("projects", "external project including config file", session);
183183
});

0 commit comments

Comments
 (0)