Skip to content

Commit dbd6717

Browse files
committed
Load the ancestor projects to find default project for the file
1 parent 8d2b5f4 commit dbd6717

File tree

75 files changed

+1103
-1325
lines changed

Some content is hidden

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

75 files changed

+1103
-1325
lines changed

src/server/editorServices.ts

Lines changed: 521 additions & 328 deletions
Large diffs are not rendered by default.

src/server/project.ts

Lines changed: 2 additions & 82 deletions
Original file line numberDiff line numberDiff line change
@@ -139,15 +139,12 @@ import {
139139
emptyArray,
140140
Errors,
141141
FileStats,
142-
forEachResolvedProjectReferenceProject,
143142
LogLevel,
144143
ModuleImportResult,
145144
Msg,
146145
NormalizedPath,
147146
PackageJsonWatcher,
148-
projectContainsInfoDirectly,
149147
ProjectOptions,
150-
ProjectReferenceProjectLoadKind,
151148
ProjectService,
152149
ScriptInfo,
153150
ServerHost,
@@ -2185,7 +2182,7 @@ export abstract class Project implements LanguageServiceHost, ModuleResolutionHo
21852182
private isDefaultProjectForOpenFiles(): boolean {
21862183
return !!forEachEntry(
21872184
this.projectService.openFiles,
2188-
(_, fileName) => this.projectService.tryGetDefaultProjectForFile(toNormalizedPath(fileName)) === this,
2185+
(_projectRootPath, path) => this.projectService.tryGetDefaultProjectForFile(this.projectService.getScriptInfoForPath(path)!) === this,
21892186
);
21902187
}
21912188

@@ -2681,9 +2678,6 @@ export class ConfiguredProject extends Project {
26812678
/** @internal */
26822679
canConfigFileJsonReportNoInputFiles = false;
26832680

2684-
/** Ref count to the project when opened from external project */
2685-
private externalProjectRefCount = 0;
2686-
26872681
private projectReferences: readonly ProjectReference[] | undefined;
26882682

26892683
/**
@@ -2778,8 +2772,7 @@ export class ConfiguredProject extends Project {
27782772
case ProgramUpdateLevel.Full:
27792773
this.openFileWatchTriggered.clear();
27802774
const reason = Debug.checkDefined(this.pendingUpdateReason);
2781-
this.pendingUpdateReason = undefined;
2782-
this.projectService.reloadConfiguredProject(this, reason, isInitialLoad, /*clearSemanticCache*/ false);
2775+
this.projectService.reloadConfiguredProject(this, reason, isInitialLoad);
27832776
result = true;
27842777
break;
27852778
default:
@@ -2881,85 +2874,12 @@ export class ConfiguredProject extends Project {
28812874
super.close();
28822875
}
28832876

2884-
/** @internal */
2885-
addExternalProjectReference() {
2886-
this.externalProjectRefCount++;
2887-
}
2888-
2889-
/** @internal */
2890-
deleteExternalProjectReference() {
2891-
this.externalProjectRefCount--;
2892-
}
2893-
28942877
/** @internal */
28952878
isSolution() {
28962879
return this.getRootFilesMap().size === 0 &&
28972880
!this.canConfigFileJsonReportNoInputFiles;
28982881
}
28992882

2900-
/**
2901-
* Find the configured project from the project references in project which contains the info directly
2902-
*
2903-
* @internal
2904-
*/
2905-
getDefaultChildProjectFromProjectWithReferences(info: ScriptInfo) {
2906-
return forEachResolvedProjectReferenceProject(
2907-
this,
2908-
info.path,
2909-
child =>
2910-
projectContainsInfoDirectly(child, info) ?
2911-
child :
2912-
undefined,
2913-
ProjectReferenceProjectLoadKind.Find,
2914-
);
2915-
}
2916-
2917-
/**
2918-
* Returns true if the project is needed by any of the open script info/external project
2919-
*
2920-
* @internal
2921-
*/
2922-
hasOpenRef() {
2923-
if (!!this.externalProjectRefCount) {
2924-
return true;
2925-
}
2926-
2927-
// Closed project doesnt have any reference
2928-
if (this.isClosed()) {
2929-
return false;
2930-
}
2931-
2932-
const configFileExistenceInfo = this.projectService.configFileExistenceInfoCache.get(this.canonicalConfigFilePath)!;
2933-
if (this.projectService.hasPendingProjectUpdate(this)) {
2934-
// If there is pending update for this project,
2935-
// we dont know if this project would be needed by any of the open files impacted by this config file
2936-
// In that case keep the project alive if there are open files impacted by this project
2937-
return !!configFileExistenceInfo.openFilesImpactedByConfigFile?.size;
2938-
}
2939-
2940-
// If there is no pending update for this project,
2941-
// We know exact set of open files that get impacted by this configured project as the files in the project
2942-
// The project is referenced only if open files impacted by this project are present in this project
2943-
return !!configFileExistenceInfo.openFilesImpactedByConfigFile && forEachEntry(
2944-
configFileExistenceInfo.openFilesImpactedByConfigFile,
2945-
(_value, infoPath) => {
2946-
const info = this.projectService.getScriptInfoForPath(infoPath)!;
2947-
return this.containsScriptInfo(info) ||
2948-
!!forEachResolvedProjectReferenceProject(
2949-
this,
2950-
info.path,
2951-
child => child.containsScriptInfo(info),
2952-
ProjectReferenceProjectLoadKind.Find,
2953-
);
2954-
},
2955-
) || false;
2956-
}
2957-
2958-
/** @internal */
2959-
hasExternalProjectRef() {
2960-
return !!this.externalProjectRefCount;
2961-
}
2962-
29632883
getEffectiveTypeRoots() {
29642884
return getEffectiveTypeRoots(this.getCompilationSettings(), this) || [];
29652885
}

src/server/scriptInfo.ts

Lines changed: 8 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -38,7 +38,6 @@ import {
3838
AbsolutePositionAndLineText,
3939
ConfiguredProject,
4040
Errors,
41-
ExternalProject,
4241
InferredProject,
4342
isBackgroundProject,
4443
isConfiguredProject,
@@ -566,15 +565,14 @@ export class ScriptInfo {
566565
case 0:
567566
return Errors.ThrowNoProject();
568567
case 1:
569-
return ensurePrimaryProjectKind(this.containingProjects[0]);
568+
return isBackgroundProject(this.containingProjects[0]) ? Errors.ThrowNoProject() : this.containingProjects[0];
570569
default:
571570
// If this file belongs to multiple projects, below is the order in which default project is used
571+
// - first external project
572572
// - for open script info, its default configured project during opening is default if info is part of it
573573
// - first configured project of which script info is not a source of project reference redirect
574574
// - first configured project
575-
// - first external project
576575
// - first inferred project
577-
let firstExternalProject: ExternalProject | undefined;
578576
let firstConfiguredProject: ConfiguredProject | undefined;
579577
let firstInferredProject: InferredProject | undefined;
580578
let firstNonSourceOfProjectReferenceRedirect: ConfiguredProject | undefined;
@@ -596,20 +594,17 @@ export class ScriptInfo {
596594
}
597595
if (!firstConfiguredProject) firstConfiguredProject = project;
598596
}
599-
else if (!firstExternalProject && isExternalProject(project)) {
600-
firstExternalProject = project;
597+
else if (isExternalProject(project)) {
598+
return project;
601599
}
602600
else if (!firstInferredProject && isInferredProject(project)) {
603601
firstInferredProject = project;
604602
}
605603
}
606-
return ensurePrimaryProjectKind(
607-
defaultConfiguredProject ||
608-
firstNonSourceOfProjectReferenceRedirect ||
609-
firstConfiguredProject ||
610-
firstExternalProject ||
611-
firstInferredProject,
612-
);
604+
return (defaultConfiguredProject ||
605+
firstNonSourceOfProjectReferenceRedirect ||
606+
firstConfiguredProject ||
607+
firstInferredProject) ?? Errors.ThrowNoProject();
613608
}
614609
}
615610

@@ -724,18 +719,6 @@ export class ScriptInfo {
724719
}
725720
}
726721

727-
/**
728-
* Throws an error if `project` is an AutoImportProvider or AuxiliaryProject,
729-
* which are used in the background by other Projects and should never be
730-
* reported as the default project for a ScriptInfo.
731-
*/
732-
function ensurePrimaryProjectKind(project: Project | undefined) {
733-
if (!project || isBackgroundProject(project)) {
734-
return Errors.ThrowNoProject();
735-
}
736-
return project;
737-
}
738-
739722
function failIfInvalidPosition(position: number) {
740723
Debug.assert(typeof position === "number", `Expected position ${position} to be a number.`);
741724
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/helpers/tsserver.ts

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -495,5 +495,10 @@ export function logInferredProjectsOrphanStatus(session: TestSession) {
495495
}
496496

497497
export function logConfiguredProjectsHasOpenRefStatus(session: TestSession) {
498-
session.getProjectService().configuredProjects.forEach(configuredProject => session.logger.log(`Configured project: ${configuredProject.projectName} hasOpenRef:: ${configuredProject.hasOpenRef()} isClosed: ${configuredProject.isClosed()}`));
498+
const toRemoveConfiguredProjects = session.getProjectService().getOrphanConfiguredProjects(
499+
/*toRetainConfiguredProjects*/ undefined,
500+
/*openFilesWithRetainedConfiguredProject*/ undefined,
501+
/*externalProjectsRetainingConfiguredProjects*/ undefined,
502+
);
503+
session.getProjectService().configuredProjects.forEach(configuredProject => session.logger.log(`Configured project: ${configuredProject.projectName} hasOpenRef:: ${!toRemoveConfiguredProjects.has(configuredProject)} isClosed: ${configuredProject.isClosed()}`));
499504
}

src/testRunner/unittests/tsserver/projects.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -185,7 +185,7 @@ describe("unittests:: tsserver:: projects::", () => {
185185
};
186186
session.host.baselineHost("Before request");
187187
session.logger.info(`request:${ts.server.stringifyIndented(request)}`);
188-
session.getProjectService().openExternalProject(request.arguments, /*print*/ true);
188+
session.getProjectService().openExternalProject(request.arguments, /*cleanupAfter*/ true);
189189
session.host.baselineHost("After request");
190190
baselineTsserverLogs("projects", "external project including config file", session);
191191
});

tests/baselines/reference/api/typescript.d.ts

Lines changed: 8 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -3476,8 +3476,6 @@ declare namespace ts {
34763476
*/
34773477
class ConfiguredProject extends Project {
34783478
readonly canonicalConfigFilePath: NormalizedPath;
3479-
/** Ref count to the project when opened from external project */
3480-
private externalProjectRefCount;
34813479
private projectReferences;
34823480
/**
34833481
* If the project has reload from disk pending, it reloads (and then updates graph as part of that) instead of just updating the graph
@@ -3704,7 +3702,7 @@ declare namespace ts {
37043702
/**
37053703
* maps external project file name to list of config files that were the part of this project
37063704
*/
3707-
private readonly externalProjectToConfiguredProjectMap;
3705+
private readonly externalProjectToConfigFilesMap;
37083706
/**
37093707
* external projects (configuration and list of root files is not controlled by tsserver)
37103708
*/
@@ -3720,7 +3718,7 @@ declare namespace ts {
37203718
/**
37213719
* Open files: with value being project root path, and key being Path of the file that is open
37223720
*/
3723-
readonly openFiles: Map<string, NormalizedPath | undefined>;
3721+
readonly openFiles: Map<Path, NormalizedPath | undefined>;
37243722
/**
37253723
* Map of open files that are opened without complete path but have projectRoot as current directory
37263724
*/
@@ -3815,6 +3813,8 @@ declare namespace ts {
38153813
* the newly opened file.
38163814
*/
38173815
private forEachConfigFileLocation;
3816+
private getConfigFileNameForFileFromCache;
3817+
private setConfigFileNameForFileInCache;
38183818
/**
38193819
* This function tries to search for a tsconfig.json for the given file.
38203820
* This is different from the method the compiler uses because
@@ -3868,14 +3868,6 @@ declare namespace ts {
38683868
* This does not reload contents of open files from disk. But we could do that if needed
38693869
*/
38703870
reloadProjects(): void;
3871-
/**
3872-
* This function goes through all the openFiles and tries to file the config file for them.
3873-
* If the config file is found and it refers to existing project, it reloads it either immediately
3874-
* or schedules it for reload depending on delayReload option
3875-
* If there is no existing project it just opens the configured project for the config file
3876-
* reloadForInfo provides a way to filter out files to reload configured project for
3877-
*/
3878-
private reloadConfiguredProjectForFiles;
38793871
/**
38803872
* Remove the root of inferred project if script info is part of another project
38813873
*/
@@ -3896,12 +3888,13 @@ declare namespace ts {
38963888
openClientFile(fileName: string, fileContent?: string, scriptKind?: ScriptKind, projectRootPath?: string): OpenConfiguredProjectResult;
38973889
private findExternalProjectContainingOpenScriptInfo;
38983890
private getOrCreateOpenScriptInfo;
3891+
private tryFindDefaultConfiguredProjectForOpenScriptInfo;
38993892
private assignProjectToOpenedScriptInfo;
3900-
private createAncestorProjects;
3893+
private forEachAncestorProject;
39013894
private ensureProjectChildren;
3902-
private cleanupAfterOpeningFile;
3895+
private cleanupConfiguredProjects;
3896+
private cleanupProjectsAndScriptInfos;
39033897
openClientFileWithNormalizedPath(fileName: NormalizedPath, fileContent?: string, scriptKind?: ScriptKind, hasMixedContent?: boolean, projectRootPath?: NormalizedPath): OpenConfiguredProjectResult;
3904-
private removeOrphanConfiguredProjects;
39053898
private removeOrphanScriptInfos;
39063899
private telemetryOnOpenFile;
39073900
/**
@@ -3910,7 +3903,6 @@ declare namespace ts {
39103903
*/
39113904
closeClientFile(uncheckedFileName: string): void;
39123905
private collectChanges;
3913-
private closeConfiguredProjectReferencedFromExternalProject;
39143906
closeExternalProject(uncheckedFileName: string): void;
39153907
openExternalProjects(projects: protocol.ExternalProject[]): void;
39163908
/** Makes a filename safe to insert in a RegExp */

tests/baselines/reference/tsserver/autoImportProvider/Does-not-create-auto-import-providers-upon-opening-projects-for-find-all-references.js

Lines changed: 0 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -517,19 +517,11 @@ Info seq [hh:mm:ss:mss] event:
517517
}
518518
}
519519
Info seq [hh:mm:ss:mss] Finding references to /packages/b/index.ts position 13 in project /tsconfig.json
520-
Info seq [hh:mm:ss:mss] Search path: /packages/b
521-
Info seq [hh:mm:ss:mss] For info: /packages/b/index.ts :: Config file name: /packages/b/tsconfig.json
522-
Info seq [hh:mm:ss:mss] Search path: /packages/b
523-
Info seq [hh:mm:ss:mss] For info: /packages/b/index.ts :: Config file name: /packages/b/tsconfig.json
524520
Info seq [hh:mm:ss:mss] Search path: /packages/a
525521
Info seq [hh:mm:ss:mss] For info: /packages/a/index.ts :: Config file name: /packages/a/tsconfig.json
526522
Info seq [hh:mm:ss:mss] Search path: /packages/a
527523
Info seq [hh:mm:ss:mss] For info: /packages/a/index.ts :: Config file name: /packages/a/tsconfig.json
528524
Info seq [hh:mm:ss:mss] Finding references to /packages/b/index.ts position 13 in project /packages/a/tsconfig.json
529-
Info seq [hh:mm:ss:mss] Search path: /packages/b
530-
Info seq [hh:mm:ss:mss] For info: /packages/b/index.ts :: Config file name: /packages/b/tsconfig.json
531-
Info seq [hh:mm:ss:mss] Search path: /packages/b
532-
Info seq [hh:mm:ss:mss] For info: /packages/b/index.ts :: Config file name: /packages/b/tsconfig.json
533525
Info seq [hh:mm:ss:mss] response:
534526
{
535527
"response": {

tests/baselines/reference/tsserver/declarationFileMaps/findAllReferences-starting-at-definition.js

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -857,10 +857,6 @@ Info seq [hh:mm:ss:mss] request:
857857
Info seq [hh:mm:ss:mss] Finding references to /a/a.ts position 16 in project /a/tsconfig.json
858858
Info seq [hh:mm:ss:mss] FileWatcher:: Added:: WatchInfo: /a/bin/a.d.ts.map 500 undefined WatchType: Closed Script info
859859
Info seq [hh:mm:ss:mss] Finding references to /a/bin/a.d.ts position 24 in project /dev/null/inferredProject1*
860-
Info seq [hh:mm:ss:mss] Search path: /a
861-
Info seq [hh:mm:ss:mss] For info: /a/a.ts :: Config file name: /a/tsconfig.json
862-
Info seq [hh:mm:ss:mss] Search path: /a
863-
Info seq [hh:mm:ss:mss] For info: /a/a.ts :: Config file name: /a/tsconfig.json
864860
Info seq [hh:mm:ss:mss] response:
865861
{
866862
"response": {

tests/baselines/reference/tsserver/declarationFileMaps/renameLocations-starting-at-definition.js

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -855,8 +855,6 @@ Info seq [hh:mm:ss:mss] request:
855855
"type": "request"
856856
}
857857
Info seq [hh:mm:ss:mss] FileWatcher:: Added:: WatchInfo: /a/bin/a.d.ts.map 500 undefined WatchType: Closed Script info
858-
Info seq [hh:mm:ss:mss] Search path: /a
859-
Info seq [hh:mm:ss:mss] For info: /a/a.ts :: Config file name: /a/tsconfig.json
860858
Info seq [hh:mm:ss:mss] response:
861859
{
862860
"response": {

0 commit comments

Comments
 (0)
pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy