Skip to content

Commit 6f42f9a

Browse files
Merge pull request #15308 from chuckjaz/external-files
Allow plugins to provide a list of external files.
2 parents b7484b7 + 785c281 commit 6f42f9a

File tree

2 files changed

+54
-4
lines changed

2 files changed

+54
-4
lines changed

src/server/project.ts

Lines changed: 23 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -106,6 +106,7 @@ namespace ts.server {
106106
private rootFiles: ScriptInfo[] = [];
107107
private rootFilesMap: FileMap<ScriptInfo> = createFileMap<ScriptInfo>();
108108
private program: ts.Program;
109+
private externalFiles: SortedReadonlyArray<string>;
109110

110111
private cachedUnresolvedImportsPerFile = new UnresolvedImportsMap();
111112
private lastCachedUnresolvedImportsList: SortedReadonlyArray<string>;
@@ -261,8 +262,8 @@ namespace ts.server {
261262
abstract getProjectRootPath(): string | undefined;
262263
abstract getTypeAcquisition(): TypeAcquisition;
263264

264-
getExternalFiles(): string[] {
265-
return [];
265+
getExternalFiles(): SortedReadonlyArray<string> {
266+
return emptyArray as SortedReadonlyArray<string>;
266267
}
267268

268269
getSourceFile(path: Path) {
@@ -561,6 +562,24 @@ namespace ts.server {
561562
}
562563
}
563564
}
565+
566+
const oldExternalFiles = this.externalFiles || emptyArray as SortedReadonlyArray<string>;
567+
this.externalFiles = this.getExternalFiles();
568+
enumerateInsertsAndDeletes(this.externalFiles, oldExternalFiles,
569+
// Ensure a ScriptInfo is created for new external files. This is performed indirectly
570+
// by the LSHost for files in the program when the program is retrieved above but
571+
// the program doesn't contain external files so this must be done explicitly.
572+
inserted => {
573+
const scriptInfo = this.projectService.getOrCreateScriptInfo(inserted, /*openedByClient*/ false);
574+
scriptInfo.attachToProject(this);
575+
},
576+
removed => {
577+
const scriptInfoToDetach = this.projectService.getScriptInfo(removed);
578+
if (scriptInfoToDetach) {
579+
scriptInfoToDetach.detachFromProject(this);
580+
}
581+
});
582+
564583
return hasChanges;
565584
}
566585

@@ -956,7 +975,7 @@ namespace ts.server {
956975
return this.typeAcquisition;
957976
}
958977

959-
getExternalFiles(): string[] {
978+
getExternalFiles(): SortedReadonlyArray<string> {
960979
const items: string[] = [];
961980
for (const plugin of this.plugins) {
962981
if (typeof plugin.getExternalFiles === "function") {
@@ -968,7 +987,7 @@ namespace ts.server {
968987
}
969988
}
970989
}
971-
return items;
990+
return toSortedReadonlyArray(items);
972991
}
973992

974993
watchConfigFile(callback: (project: ConfiguredProject) => void) {

src/server/utilities.ts

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -195,6 +195,37 @@ namespace ts.server {
195195
return <any>arr;
196196
}
197197

198+
export function enumerateInsertsAndDeletes<T>(a: SortedReadonlyArray<T>, b: SortedReadonlyArray<T>, inserted: (item: T) => void, deleted: (item: T) => void, compare?: (a: T, b: T) => Comparison) {
199+
compare = compare || ts.compareValues;
200+
let aIndex = 0;
201+
let bIndex = 0;
202+
const aLen = a.length;
203+
const bLen = b.length;
204+
while (aIndex < aLen && bIndex < bLen) {
205+
const aItem = a[aIndex];
206+
const bItem = b[bIndex];
207+
const compareResult = compare(aItem, bItem);
208+
if (compareResult === Comparison.LessThan) {
209+
inserted(aItem);
210+
aIndex++;
211+
}
212+
else if (compareResult === Comparison.GreaterThan) {
213+
deleted(bItem);
214+
bIndex++;
215+
}
216+
else {
217+
aIndex++;
218+
bIndex++;
219+
}
220+
}
221+
while (aIndex < aLen) {
222+
inserted(a[aIndex++]);
223+
}
224+
while (bIndex < bLen) {
225+
deleted(b[bIndex++]);
226+
}
227+
}
228+
198229
export class ThrottledOperations {
199230
private pendingTimeouts: Map<any> = createMap<any>();
200231
constructor(private readonly host: ServerHost) {

0 commit comments

Comments
 (0)