Merge pull request #15308 from chuckjaz/external-files

Allow plugins to provide a list of external files.
This commit is contained in:
Ryan Cavanaugh
2017-06-05 13:14:25 -07:00
committed by GitHub
2 changed files with 54 additions and 4 deletions

View File

@@ -106,6 +106,7 @@ namespace ts.server {
private rootFiles: ScriptInfo[] = [];
private rootFilesMap: FileMap<ScriptInfo> = createFileMap<ScriptInfo>();
private program: ts.Program;
private externalFiles: SortedReadonlyArray<string>;
private cachedUnresolvedImportsPerFile = new UnresolvedImportsMap();
private lastCachedUnresolvedImportsList: SortedReadonlyArray<string>;
@@ -261,8 +262,8 @@ namespace ts.server {
abstract getProjectRootPath(): string | undefined;
abstract getTypeAcquisition(): TypeAcquisition;
getExternalFiles(): string[] {
return [];
getExternalFiles(): SortedReadonlyArray<string> {
return emptyArray as SortedReadonlyArray<string>;
}
getSourceFile(path: Path) {
@@ -561,6 +562,24 @@ namespace ts.server {
}
}
}
const oldExternalFiles = this.externalFiles || emptyArray as SortedReadonlyArray<string>;
this.externalFiles = this.getExternalFiles();
enumerateInsertsAndDeletes(this.externalFiles, oldExternalFiles,
// Ensure a ScriptInfo is created for new external files. This is performed indirectly
// by the LSHost for files in the program when the program is retrieved above but
// the program doesn't contain external files so this must be done explicitly.
inserted => {
const scriptInfo = this.projectService.getOrCreateScriptInfo(inserted, /*openedByClient*/ false);
scriptInfo.attachToProject(this);
},
removed => {
const scriptInfoToDetach = this.projectService.getScriptInfo(removed);
if (scriptInfoToDetach) {
scriptInfoToDetach.detachFromProject(this);
}
});
return hasChanges;
}
@@ -956,7 +975,7 @@ namespace ts.server {
return this.typeAcquisition;
}
getExternalFiles(): string[] {
getExternalFiles(): SortedReadonlyArray<string> {
const items: string[] = [];
for (const plugin of this.plugins) {
if (typeof plugin.getExternalFiles === "function") {
@@ -968,7 +987,7 @@ namespace ts.server {
}
}
}
return items;
return toSortedReadonlyArray(items);
}
watchConfigFile(callback: (project: ConfiguredProject) => void) {

View File

@@ -195,6 +195,37 @@ namespace ts.server {
return <any>arr;
}
export function enumerateInsertsAndDeletes<T>(a: SortedReadonlyArray<T>, b: SortedReadonlyArray<T>, inserted: (item: T) => void, deleted: (item: T) => void, compare?: (a: T, b: T) => Comparison) {
compare = compare || ts.compareValues;
let aIndex = 0;
let bIndex = 0;
const aLen = a.length;
const bLen = b.length;
while (aIndex < aLen && bIndex < bLen) {
const aItem = a[aIndex];
const bItem = b[bIndex];
const compareResult = compare(aItem, bItem);
if (compareResult === Comparison.LessThan) {
inserted(aItem);
aIndex++;
}
else if (compareResult === Comparison.GreaterThan) {
deleted(bItem);
bIndex++;
}
else {
aIndex++;
bIndex++;
}
}
while (aIndex < aLen) {
inserted(a[aIndex++]);
}
while (bIndex < bLen) {
deleted(b[bIndex++]);
}
}
export class ThrottledOperations {
private pendingTimeouts: Map<any> = createMap<any>();
constructor(private readonly host: ServerHost) {