Skip to content

Commit 3037e55

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 8bb01ab commit 3037e55

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

@@ -2376,7 +2373,7 @@ export class InferredProject extends Project {
23762373
}
23772374

23782375
override removeRoot(info: ScriptInfo) {
2379-
this.projectService.stopWatchingConfigFilesForInferredProjectRoot(info);
2376+
this.projectService.stopWatchingConfigFilesForScriptInfo(info);
23802377
super.removeRoot(info);
23812378
// Delay toggling to isJsInferredProject = false till we actually need it again
23822379
if (!this.isOrphan() && this._isJsInferredProject && info.isJavaScript()) {
@@ -2400,7 +2397,7 @@ export class InferredProject extends Project {
24002397
}
24012398

24022399
override close() {
2403-
forEach(this.getRootScriptInfos(), info => this.projectService.stopWatchingConfigFilesForInferredProjectRoot(info));
2400+
forEach(this.getRootScriptInfos(), info => this.projectService.stopWatchingConfigFilesForScriptInfo(info));
24042401
super.close();
24052402
}
24062403

@@ -2751,9 +2748,6 @@ export class ConfiguredProject extends Project {
27512748
/** @internal */
27522749
canConfigFileJsonReportNoInputFiles = false;
27532750

2754-
/** Ref count to the project when opened from external project */
2755-
private externalProjectRefCount = 0;
2756-
27572751
private projectReferences: readonly ProjectReference[] | undefined;
27582752

27592753
/**
@@ -2861,8 +2855,7 @@ export class ConfiguredProject extends Project {
28612855
case ProgramUpdateLevel.Full:
28622856
this.openFileWatchTriggered.clear();
28632857
const reason = Debug.checkDefined(this.pendingUpdateReason);
2864-
this.pendingUpdateReason = undefined;
2865-
this.projectService.reloadConfiguredProject(this, reason, /*clearSemanticCache*/ false);
2858+
this.projectService.reloadConfiguredProject(this, reason);
28662859
result = true;
28672860
break;
28682861
default:
@@ -2986,91 +2979,17 @@ export class ConfiguredProject extends Project {
29862979
super.markAsDirty();
29872980
}
29882981

2989-
/** @internal */
2990-
addExternalProjectReference() {
2991-
this.externalProjectRefCount++;
2992-
}
2993-
2994-
/** @internal */
2995-
deleteExternalProjectReference() {
2996-
this.externalProjectRefCount--;
2997-
}
2998-
29992982
/** @internal */
30002983
isSolution() {
30012984
return this.getRootFilesMap().size === 0 &&
30022985
!this.canConfigFileJsonReportNoInputFiles;
30032986
}
30042987

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

3069-
/** @internal */
3070-
hasExternalProjectRef() {
3071-
return !!this.externalProjectRefCount;
3072-
}
3073-
30742993
getEffectiveTypeRoots() {
30752994
return getEffectiveTypeRoots(this.getCompilationSettings(), this) || [];
30762995
}

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
@@ -3190,7 +3190,7 @@ export class Session<TMessage = string> implements EventSender {
31903190
return this.requiredResponse(response);
31913191
},
31923192
[protocol.CommandTypes.OpenExternalProject]: (request: protocol.OpenExternalProjectRequest) => {
3193-
this.projectService.openExternalProject(request.arguments, /*print*/ true);
3193+
this.projectService.openExternalProject(request.arguments, /*cleanupAfter*/ true);
31943194
// TODO: GH#20447 report errors
31953195
return this.requiredResponse(/*response*/ true);
31963196
},
@@ -3200,7 +3200,7 @@ export class Session<TMessage = string> implements EventSender {
32003200
return this.requiredResponse(/*response*/ true);
32013201
},
32023202
[protocol.CommandTypes.CloseExternalProject]: (request: protocol.CloseExternalProjectRequest) => {
3203-
this.projectService.closeExternalProject(request.arguments.projectFileName, /*print*/ true);
3203+
this.projectService.closeExternalProject(request.arguments.projectFileName, /*cleanupAfter*/ true);
32043204
// TODO: GH#20447 report errors
32053205
return this.requiredResponse(/*response*/ true);
32063206
},

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)