Skip to content

Commit

Permalink
Use enumerateInsertsAndDeletes
Browse files Browse the repository at this point in the history
  • Loading branch information
Andy Hanson committed Jul 17, 2017
1 parent 3dc53fc commit a9aea4b
Show file tree
Hide file tree
Showing 5 changed files with 54 additions and 70 deletions.
56 changes: 15 additions & 41 deletions src/server/builder.ts
Original file line number Diff line number Diff line change
Expand Up @@ -203,8 +203,8 @@ namespace ts.server {
}

class ModuleBuilderFileInfo extends BuilderFileInfo {
references: ModuleBuilderFileInfo[] = [];
referencedBy: ModuleBuilderFileInfo[] = [];
references = createSortedArray<ModuleBuilderFileInfo>();
readonly referencedBy = createSortedArray<ModuleBuilderFileInfo>();
scriptVersionForReferences: string;

static compareFileInfos(lf: ModuleBuilderFileInfo, rf: ModuleBuilderFileInfo): Comparison {
Expand All @@ -223,7 +223,7 @@ namespace ts.server {
for (const reference of this.references) {
reference.removeReferencedBy(this);
}
this.references = [];
this.references = createSortedArray<ModuleBuilderFileInfo>();
}
}

Expand All @@ -240,13 +240,13 @@ namespace ts.server {
super.clear();
}

private getReferencedFileInfos(fileInfo: ModuleBuilderFileInfo): ModuleBuilderFileInfo[] {
private getReferencedFileInfos(fileInfo: ModuleBuilderFileInfo): SortedArray<ModuleBuilderFileInfo> {
if (!fileInfo.isExternalModuleOrHasOnlyAmbientExternalModules()) {
return [];
return createSortedArray();
}

const referencedFilePaths = this.project.getReferencedFiles(fileInfo.scriptInfo.path);
return referencedFilePaths.map(f => this.getOrCreateFileInfo(f)).sort(ModuleBuilderFileInfo.compareFileInfos);
return toSortedArray(referencedFilePaths.map(f => this.getOrCreateFileInfo(f)), ModuleBuilderFileInfo.compareFileInfos);
}

protected ensureFileInfoIfInProject(_scriptInfo: ScriptInfo) {
Expand Down Expand Up @@ -286,41 +286,15 @@ namespace ts.server {

const newReferences = this.getReferencedFileInfos(fileInfo);
const oldReferences = fileInfo.references;

let oldIndex = 0;
let newIndex = 0;
while (oldIndex < oldReferences.length && newIndex < newReferences.length) {
const oldReference = oldReferences[oldIndex];
const newReference = newReferences[newIndex];
const compare = ModuleBuilderFileInfo.compareFileInfos(oldReference, newReference);
switch (compare) {
case Comparison.LessThan:
// New reference is greater then current reference. That means
// the current reference doesn't exist anymore after parsing. So delete
// references.
oldReference.removeReferencedBy(fileInfo);
oldIndex++;
break;
case Comparison.GreaterThan:
// A new reference info. Add it.
newReference.addReferencedBy(fileInfo);
newIndex++;
break;
case Comparison.EqualTo:
// Equal. Go to next
oldIndex++;
newIndex++;
break;
}
}
// Clean old references
for (let i = oldIndex; i < oldReferences.length; i++) {
oldReferences[i].removeReferencedBy(fileInfo);
}
// Update new references
for (let i = newIndex; i < newReferences.length; i++) {
newReferences[i].addReferencedBy(fileInfo);
}
enumerateInsertsAndDeletes(oldReferences, newReferences,
/*inserted*/ newReference => newReference.addReferencedBy(fileInfo),
/*deleted*/ oldReference => {
// New reference is greater then current reference. That means
// the current reference doesn't exist anymore after parsing. So delete
// references.
oldReference.removeReferencedBy(fileInfo);
},
/*compare*/ ModuleBuilderFileInfo.compareFileInfos);

fileInfo.references = newReferences;
fileInfo.scriptVersionForReferences = fileInfo.scriptInfo.getLatestVersion();
Expand Down
4 changes: 2 additions & 2 deletions src/server/project.ts
Original file line number Diff line number Diff line change
Expand Up @@ -554,7 +554,7 @@ namespace ts.server {
for (const sourceFile of this.program.getSourceFiles()) {
this.extractUnresolvedImportsFromSourceFile(sourceFile, result);
}
this.lastCachedUnresolvedImportsList = toSortedReadonlyArray(result);
this.lastCachedUnresolvedImportsList = toSortedArray(result);
}
unresolvedImports = this.lastCachedUnresolvedImportsList;

Expand Down Expand Up @@ -1057,7 +1057,7 @@ namespace ts.server {
}

getExternalFiles(): SortedReadonlyArray<string> {
return toSortedReadonlyArray(flatMap(this.plugins, plugin => {
return toSortedArray(flatMap(this.plugins, plugin => {
if (typeof plugin.getExternalFiles !== "function") return;
try {
return plugin.getExternalFiles(this);
Expand Down
6 changes: 5 additions & 1 deletion src/server/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -20,8 +20,12 @@ declare namespace ts.server {
require?(initialPath: string, moduleName: string): RequireResult;
}

export interface SortedArray<T> extends Array<T> {
" __sortedArrayBrand": any;
}

export interface SortedReadonlyArray<T> extends ReadonlyArray<T> {
" __sortedReadonlyArrayBrand": any;
" __sortedArrayBrand": any;
}

export interface TypingInstallerRequest {
Expand Down
2 changes: 1 addition & 1 deletion src/server/typingsCache.ts
Original file line number Diff line number Diff line change
Expand Up @@ -110,7 +110,7 @@ namespace ts.server {
this.perProjectCache.set(projectName, {
compilerOptions,
typeAcquisition,
typings: toSortedReadonlyArray(newTypings),
typings: toSortedArray(newTypings),
unresolvedImports,
poisoned: false
});
Expand Down
56 changes: 31 additions & 25 deletions src/server/utilities.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ namespace ts.server {
verbose
}

export const emptyArray: ReadonlyArray<any> = [];
export const emptyArray: SortedReadonlyArray<never> = createSortedArray<never>();

export interface Logger {
close(): void;
Expand Down Expand Up @@ -190,39 +190,45 @@ namespace ts.server {
return `/dev/null/inferredProject${counter}*`;
}

export function toSortedReadonlyArray(arr: string[]): SortedReadonlyArray<string> {
arr.sort();
return <any>arr;
export function createSortedArray<T>(): SortedArray<T> {
return [] as SortedArray<T>;
}

export function enumerateInsertsAndDeletes<T>(a: SortedReadonlyArray<T>, b: SortedReadonlyArray<T>, inserted: (item: T) => void, deleted: (item: T) => void, compare?: (a: T, b: T) => Comparison) {
export function toSortedArray(arr: string[]): SortedArray<string>;
export function toSortedArray<T>(arr: T[], comparer: Comparer<T>): SortedArray<T>;
export function toSortedArray<T>(arr: T[], comparer?: Comparer<T>): SortedArray<T> {
arr.sort(comparer);
return arr as SortedArray<T>;
}

export function enumerateInsertsAndDeletes<T>(newItems: SortedReadonlyArray<T>, oldItems: SortedReadonlyArray<T>, inserted: (newItem: T) => void, deleted: (oldItem: T) => void, compare?: Comparer<T>) {
compare = compare || 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);
let newIndex = 0;
let oldIndex = 0;
const newLen = newItems.length;
const oldLen = oldItems.length;
while (newIndex < newLen && oldIndex < oldLen) {
const newItem = newItems[newIndex];
const oldItem = oldItems[oldIndex];
const compareResult = compare(newItem, oldItem);
if (compareResult === Comparison.LessThan) {
inserted(aItem);
aIndex++;
inserted(newItem);
newIndex++;
}
else if (compareResult === Comparison.GreaterThan) {
deleted(bItem);
bIndex++;
deleted(oldItem);
oldIndex++;
}
else {
aIndex++;
bIndex++;
newIndex++;
oldIndex++;
}
}
while (aIndex < aLen) {
inserted(a[aIndex++]);
while (newIndex < newLen) {
inserted(newItems[newIndex++]);
}
while (bIndex < bLen) {
deleted(b[bIndex++]);
while (oldIndex < oldLen) {
deleted(oldItems[oldIndex++]);
}
}

Expand Down Expand Up @@ -274,7 +280,7 @@ namespace ts.server {
}
}

export function insertSorted<T>(array: T[], insert: T, compare: Comparer<T>): void {
export function insertSorted<T>(array: SortedArray<T>, insert: T, compare: Comparer<T>): void {
if (array.length === 0) {
array.push(insert);
return;
Expand All @@ -286,7 +292,7 @@ namespace ts.server {
}
}

export function removeSorted<T>(array: T[], remove: T, compare: Comparer<T>): void {
export function removeSorted<T>(array: SortedArray<T>, remove: T, compare: Comparer<T>): void {
if (!array || array.length === 0) {
return;
}
Expand Down

0 comments on commit a9aea4b

Please sign in to comment.