Skip to content

Commit fdf2989

Browse files
Merge pull request #36383 from uniqueiniquity/redirectInfo
Redirect info
2 parents cf33f7b + 2dd89ca commit fdf2989

File tree

6 files changed

+301
-31
lines changed

6 files changed

+301
-31
lines changed

src/server/editorServices.ts

Lines changed: 11 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -3124,19 +3124,24 @@ namespace ts.server {
31243124
return result;
31253125
}
31263126

3127-
private collectChanges(lastKnownProjectVersions: protocol.ProjectVersionInfo[], currentProjects: Project[], result: ProjectFilesWithTSDiagnostics[]): void {
3127+
private collectChanges(
3128+
lastKnownProjectVersions: protocol.ProjectVersionInfo[],
3129+
currentProjects: Project[],
3130+
includeProjectReferenceRedirectInfo: boolean | undefined,
3131+
result: ProjectFilesWithTSDiagnostics[]
3132+
): void {
31283133
for (const proj of currentProjects) {
31293134
const knownProject = find(lastKnownProjectVersions, p => p.projectName === proj.getProjectName());
3130-
result.push(proj.getChangesSinceVersion(knownProject && knownProject.version));
3135+
result.push(proj.getChangesSinceVersion(knownProject && knownProject.version, includeProjectReferenceRedirectInfo));
31313136
}
31323137
}
31333138

31343139
/* @internal */
3135-
synchronizeProjectList(knownProjects: protocol.ProjectVersionInfo[]): ProjectFilesWithTSDiagnostics[] {
3140+
synchronizeProjectList(knownProjects: protocol.ProjectVersionInfo[], includeProjectReferenceRedirectInfo?: boolean): ProjectFilesWithTSDiagnostics[] {
31363141
const files: ProjectFilesWithTSDiagnostics[] = [];
3137-
this.collectChanges(knownProjects, this.externalProjects, files);
3138-
this.collectChanges(knownProjects, arrayFrom(this.configuredProjects.values()), files);
3139-
this.collectChanges(knownProjects, this.inferredProjects, files);
3142+
this.collectChanges(knownProjects, this.externalProjects, includeProjectReferenceRedirectInfo, files);
3143+
this.collectChanges(knownProjects, arrayFrom(this.configuredProjects.values()), includeProjectReferenceRedirectInfo, files);
3144+
this.collectChanges(knownProjects, this.inferredProjects, includeProjectReferenceRedirectInfo, files);
31403145
return files;
31413146
}
31423147

src/server/project.ts

Lines changed: 73 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -167,7 +167,7 @@ namespace ts.server {
167167
/**
168168
* Set of files that was returned from the last call to getChangesSinceVersion.
169169
*/
170-
private lastReportedFileNames: Map<true> | undefined;
170+
private lastReportedFileNames: Map<boolean> | undefined;
171171
/**
172172
* Last version that was reported.
173173
*/
@@ -803,6 +803,14 @@ namespace ts.server {
803803
return result;
804804
}
805805

806+
/* @internal */
807+
getFileNamesWithRedirectInfo(includeProjectReferenceRedirectInfo: boolean) {
808+
return this.getFileNames().map((fileName): protocol.FileWithProjectReferenceRedirectInfo => ({
809+
fileName,
810+
isSourceOfProjectReferenceRedirect: includeProjectReferenceRedirectInfo && this.isSourceOfProjectReferenceRedirect(fileName)
811+
}));
812+
}
813+
806814
hasConfigFile(configFilePath: NormalizedPath) {
807815
if (this.program && this.languageServiceEnabled) {
808816
const configFile = this.program.getCompilerOptions().configFile;
@@ -1300,7 +1308,15 @@ namespace ts.server {
13001308
}
13011309

13021310
/* @internal */
1303-
getChangesSinceVersion(lastKnownVersion?: number): ProjectFilesWithTSDiagnostics {
1311+
getChangesSinceVersion(lastKnownVersion?: number, includeProjectReferenceRedirectInfo?: boolean): ProjectFilesWithTSDiagnostics {
1312+
const includeProjectReferenceRedirectInfoIfRequested =
1313+
includeProjectReferenceRedirectInfo
1314+
? (files: Map<boolean>) => arrayFrom(files.entries(), ([fileName, isSourceOfProjectReferenceRedirect]): protocol.FileWithProjectReferenceRedirectInfo => ({
1315+
fileName,
1316+
isSourceOfProjectReferenceRedirect
1317+
}))
1318+
: (files: Map<boolean>) => arrayFrom(files.keys());
1319+
13041320
// Update the graph only if initial configured project load is not pending
13051321
if (!this.isInitialLoadPending()) {
13061322
updateProjectIfDirty(this);
@@ -1324,35 +1340,75 @@ namespace ts.server {
13241340
}
13251341
// compute and return the difference
13261342
const lastReportedFileNames = this.lastReportedFileNames;
1327-
const externalFiles = this.getExternalFiles().map(f => toNormalizedPath(f));
1328-
const currentFiles = arrayToSet(this.getFileNames().concat(externalFiles));
1343+
const externalFiles = this.getExternalFiles().map((f): protocol.FileWithProjectReferenceRedirectInfo => ({
1344+
fileName: toNormalizedPath(f),
1345+
isSourceOfProjectReferenceRedirect: false
1346+
}));
1347+
const currentFiles = arrayToMap(
1348+
this.getFileNamesWithRedirectInfo(!!includeProjectReferenceRedirectInfo).concat(externalFiles),
1349+
info => info.fileName,
1350+
info => info.isSourceOfProjectReferenceRedirect
1351+
);
1352+
1353+
const added: Map<boolean> = new Map<boolean>();
1354+
const removed: Map<boolean> = new Map<boolean>();
13291355

1330-
const added: string[] = [];
1331-
const removed: string[] = [];
13321356
const updated: string[] = updatedFileNames ? arrayFrom(updatedFileNames.keys()) : [];
1357+
const updatedRedirects: protocol.FileWithProjectReferenceRedirectInfo[] = [];
13331358

1334-
forEachKey(currentFiles, id => {
1335-
if (!lastReportedFileNames.has(id)) {
1336-
added.push(id);
1359+
forEachEntry(currentFiles, (isSourceOfProjectReferenceRedirect, fileName) => {
1360+
if (!lastReportedFileNames.has(fileName)) {
1361+
added.set(fileName, isSourceOfProjectReferenceRedirect);
1362+
}
1363+
else if (includeProjectReferenceRedirectInfo && isSourceOfProjectReferenceRedirect !== lastReportedFileNames.get(fileName)){
1364+
updatedRedirects.push({
1365+
fileName,
1366+
isSourceOfProjectReferenceRedirect
1367+
});
13371368
}
13381369
});
1339-
forEachKey(lastReportedFileNames, id => {
1340-
if (!currentFiles.has(id)) {
1341-
removed.push(id);
1370+
forEachEntry(lastReportedFileNames, (isSourceOfProjectReferenceRedirect, fileName) => {
1371+
if (!currentFiles.has(fileName)) {
1372+
removed.set(fileName, isSourceOfProjectReferenceRedirect);
13421373
}
13431374
});
13441375
this.lastReportedFileNames = currentFiles;
13451376
this.lastReportedVersion = this.projectProgramVersion;
1346-
return { info, changes: { added, removed, updated }, projectErrors: this.getGlobalProjectErrors() };
1377+
return {
1378+
info,
1379+
changes: {
1380+
added: includeProjectReferenceRedirectInfoIfRequested(added),
1381+
removed: includeProjectReferenceRedirectInfoIfRequested(removed),
1382+
updated: includeProjectReferenceRedirectInfoIfRequested
1383+
? updated.map((fileName): protocol.FileWithProjectReferenceRedirectInfo => ({
1384+
fileName,
1385+
isSourceOfProjectReferenceRedirect: this.isSourceOfProjectReferenceRedirect(fileName)
1386+
}))
1387+
: updated,
1388+
updatedRedirects: includeProjectReferenceRedirectInfo ? updatedRedirects : undefined
1389+
},
1390+
projectErrors: this.getGlobalProjectErrors()
1391+
};
13471392
}
13481393
else {
13491394
// unknown version - return everything
1350-
const projectFileNames = this.getFileNames();
1351-
const externalFiles = this.getExternalFiles().map(f => toNormalizedPath(f));
1395+
const projectFileNames = this.getFileNamesWithRedirectInfo(!!includeProjectReferenceRedirectInfo);
1396+
const externalFiles = this.getExternalFiles().map((f): protocol.FileWithProjectReferenceRedirectInfo => ({
1397+
fileName: toNormalizedPath(f),
1398+
isSourceOfProjectReferenceRedirect: false
1399+
}));
13521400
const allFiles = projectFileNames.concat(externalFiles);
1353-
this.lastReportedFileNames = arrayToSet(allFiles);
1401+
this.lastReportedFileNames = arrayToMap(
1402+
allFiles,
1403+
info => info.fileName,
1404+
info => info.isSourceOfProjectReferenceRedirect
1405+
);
13541406
this.lastReportedVersion = this.projectProgramVersion;
1355-
return { info, files: allFiles, projectErrors: this.getGlobalProjectErrors() };
1407+
return {
1408+
info,
1409+
files: includeProjectReferenceRedirectInfo ? allFiles : allFiles.map(f => f.fileName),
1410+
projectErrors: this.getGlobalProjectErrors()
1411+
};
13561412
}
13571413
}
13581414

src/server/protocol.ts

Lines changed: 28 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1324,22 +1324,39 @@ namespace ts.server.protocol {
13241324
lastFileExceededProgramSize?: string;
13251325
}
13261326

1327+
export interface FileWithProjectReferenceRedirectInfo {
1328+
/**
1329+
* Name of file
1330+
*/
1331+
fileName: string;
1332+
1333+
/**
1334+
* True if the file is primarily included in a referenced project
1335+
*/
1336+
isSourceOfProjectReferenceRedirect: boolean;
1337+
}
1338+
13271339
/**
13281340
* Represents a set of changes that happen in project
13291341
*/
13301342
export interface ProjectChanges {
13311343
/**
13321344
* List of added files
13331345
*/
1334-
added: string[];
1346+
added: string[] | FileWithProjectReferenceRedirectInfo[];
13351347
/**
13361348
* List of removed files
13371349
*/
1338-
removed: string[];
1350+
removed: string[] | FileWithProjectReferenceRedirectInfo[];
13391351
/**
13401352
* List of updated files
13411353
*/
1342-
updated: string[];
1354+
updated: string[] | FileWithProjectReferenceRedirectInfo[];
1355+
/**
1356+
* List of files that have had their project reference redirect status updated
1357+
* Only provided when the synchronizeProjectList request has includeProjectReferenceRedirectInfo set to true
1358+
*/
1359+
updatedRedirects?: FileWithProjectReferenceRedirectInfo[];
13431360
}
13441361

13451362
/**
@@ -1357,8 +1374,10 @@ namespace ts.server.protocol {
13571374
info?: ProjectVersionInfo;
13581375
/**
13591376
* List of files in project (might be omitted if current state of project can be computed using only information from 'changes')
1377+
* This property will have type FileWithProjectReferenceRedirectInfo[] if includeProjectReferenceRedirectInfo is set to true in
1378+
* the corresponding SynchronizeProjectList request; otherwise, it will have type string[].
13601379
*/
1361-
files?: string[];
1380+
files?: string[] | FileWithProjectReferenceRedirectInfo[];
13621381
/**
13631382
* Set of changes in project (omitted if the entire set of files in project should be replaced)
13641383
*/
@@ -1621,6 +1640,11 @@ namespace ts.server.protocol {
16211640
* List of last known projects
16221641
*/
16231642
knownProjects: ProjectVersionInfo[];
1643+
/**
1644+
* If true, response specifies whether or not each file in each project
1645+
* is a source from a project reference redirect
1646+
*/
1647+
includeProjectReferenceRedirectInfo?: boolean;
16241648
}
16251649

16261650
/**

src/server/session.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2265,7 +2265,7 @@ namespace ts.server {
22652265
return this.requiredResponse(/*response*/ true);
22662266
},
22672267
[CommandNames.SynchronizeProjectList]: (request: protocol.SynchronizeProjectListRequest) => {
2268-
const result = this.projectService.synchronizeProjectList(request.arguments.knownProjects);
2268+
const result = this.projectService.synchronizeProjectList(request.arguments.knownProjects, request.arguments.includeProjectReferenceRedirectInfo);
22692269
if (!result.some(p => p.projectErrors && p.projectErrors.length !== 0)) {
22702270
return this.requiredResponse(result);
22712271
}

0 commit comments

Comments
 (0)