diff --git a/src/compiler/core.ts b/src/compiler/core.ts index 422e31b8d06..5ab8251d5f5 100644 --- a/src/compiler/core.ts +++ b/src/compiler/core.ts @@ -794,6 +794,18 @@ namespace ts { return deduplicated; } + export function insertSorted(array: SortedArray, insert: T, compare: Comparer): void { + if (array.length === 0) { + array.push(insert); + return; + } + + const insertIndex = binarySearch(array, insert, identity, compare); + if (insertIndex < 0) { + array.splice(~insertIndex, 0, insert); + } + } + export function sortAndDeduplicate(array: ReadonlyArray, comparer: Comparer, equalityComparer?: EqualityComparer) { return deduplicateSorted(sort(array, comparer), equalityComparer || comparer); } diff --git a/src/compiler/types.ts b/src/compiler/types.ts index 3a3f41ef138..d95fe5ec09c 100644 --- a/src/compiler/types.ts +++ b/src/compiler/types.ts @@ -5009,6 +5009,10 @@ namespace ts { newLength: number; } + export interface SortedArray extends Array { + " __sortedArrayBrand": any; + } + /* @internal */ export interface DiagnosticCollection { // Adds a diagnostic to this diagnostic collection. diff --git a/src/compiler/utilities.ts b/src/compiler/utilities.ts index 3c76bcf3119..6dfe85e9d97 100644 --- a/src/compiler/utilities.ts +++ b/src/compiler/utilities.ts @@ -2443,11 +2443,10 @@ namespace ts { } export function createDiagnosticCollection(): DiagnosticCollection { - let nonFileDiagnostics: Diagnostic[] = []; - const fileDiagnostics = createMap(); - + let nonFileDiagnostics = [] as SortedArray; + const filesWithDiagnostics = [] as SortedArray; + const fileDiagnostics = createMap>(); let hasReadNonFileDiagnostics = false; - let diagnosticsModified = false; let modificationCount = 0; return { @@ -2467,66 +2466,45 @@ namespace ts { } function add(diagnostic: Diagnostic): void { - let diagnostics: Diagnostic[]; + let diagnostics: SortedArray; if (diagnostic.file) { diagnostics = fileDiagnostics.get(diagnostic.file.fileName); if (!diagnostics) { - diagnostics = []; + diagnostics = [] as SortedArray; fileDiagnostics.set(diagnostic.file.fileName, diagnostics); + insertSorted(filesWithDiagnostics, diagnostic.file.fileName, compareStringsCaseSensitive); } } else { // If we've already read the non-file diagnostics, do not modify the existing array. if (hasReadNonFileDiagnostics) { hasReadNonFileDiagnostics = false; - nonFileDiagnostics = nonFileDiagnostics.slice(); + nonFileDiagnostics = nonFileDiagnostics.slice() as SortedArray; } diagnostics = nonFileDiagnostics; } - diagnostics.push(diagnostic); - diagnosticsModified = true; + insertSorted(diagnostics, diagnostic, compareDiagnostics); modificationCount++; } function getGlobalDiagnostics(): Diagnostic[] { - sortAndDeduplicate(); hasReadNonFileDiagnostics = true; return nonFileDiagnostics; } function getDiagnostics(fileName?: string): Diagnostic[] { - sortAndDeduplicate(); if (fileName) { return fileDiagnostics.get(fileName) || []; } - const allDiagnostics: Diagnostic[] = []; - function pushDiagnostic(d: Diagnostic) { - allDiagnostics.push(d); + const fileDiags = flatMap(filesWithDiagnostics, f => fileDiagnostics.get(f)); + if (!nonFileDiagnostics.length) { + return fileDiags; } - - forEach(nonFileDiagnostics, pushDiagnostic); - - fileDiagnostics.forEach(diagnostics => { - forEach(diagnostics, pushDiagnostic); - }); - - return sortAndDeduplicateDiagnostics(allDiagnostics); - } - - function sortAndDeduplicate() { - if (!diagnosticsModified) { - return; - } - - diagnosticsModified = false; - nonFileDiagnostics = sortAndDeduplicateDiagnostics(nonFileDiagnostics); - - fileDiagnostics.forEach((diagnostics, key) => { - fileDiagnostics.set(key, sortAndDeduplicateDiagnostics(diagnostics)); - }); + fileDiags.unshift(...nonFileDiagnostics); + return fileDiags; } } diff --git a/src/harness/rwcRunner.ts b/src/harness/rwcRunner.ts index ef7a371b0c4..3631186bb48 100644 --- a/src/harness/rwcRunner.ts +++ b/src/harness/rwcRunner.ts @@ -170,7 +170,8 @@ namespace RWC { }); - it("has the expected emitted code", () => { + it("has the expected emitted code", function(this: Mocha.ITestCallbackContext) { + this.timeout(10000); // Allow long timeouts for RWC js verification Harness.Baseline.runMultifileBaseline(baseName, "", () => { return Harness.Compiler.iterateOutputs(compilerResult.files); }, baselineOpts, [".js", ".jsx"]); diff --git a/src/server/types.ts b/src/server/types.ts index 93ffeeccff1..021bf4c28d7 100644 --- a/src/server/types.ts +++ b/src/server/types.ts @@ -22,10 +22,6 @@ declare namespace ts.server { require?(initialPath: string, moduleName: string): RequireResult; } - export interface SortedArray extends Array { - " __sortedArrayBrand": any; - } - export interface SortedReadonlyArray extends ReadonlyArray { " __sortedArrayBrand": any; } diff --git a/src/server/utilities.ts b/src/server/utilities.ts index c44419f8cf3..a086d95f910 100644 --- a/src/server/utilities.ts +++ b/src/server/utilities.ts @@ -232,18 +232,6 @@ namespace ts.server { return base === "tsconfig.json" || base === "jsconfig.json" ? base : undefined; } - export function insertSorted(array: SortedArray, insert: T, compare: Comparer): void { - if (array.length === 0) { - array.push(insert); - return; - } - - const insertIndex = binarySearch(array, insert, identity, compare); - if (insertIndex < 0) { - array.splice(~insertIndex, 0, insert); - } - } - export function removeSorted(array: SortedArray, remove: T, compare: Comparer): void { if (!array || array.length === 0) { return; diff --git a/tests/baselines/reference/api/tsserverlibrary.d.ts b/tests/baselines/reference/api/tsserverlibrary.d.ts index 9d338a9fd10..9a311428cc1 100644 --- a/tests/baselines/reference/api/tsserverlibrary.d.ts +++ b/tests/baselines/reference/api/tsserverlibrary.d.ts @@ -2775,6 +2775,9 @@ declare namespace ts { span: TextSpan; newLength: number; } + interface SortedArray extends Array { + " __sortedArrayBrand": any; + } interface SyntaxList extends Node { _children: Node[]; } @@ -4854,9 +4857,6 @@ declare namespace ts.server { trace?(s: string): void; require?(initialPath: string, moduleName: string): RequireResult; } - interface SortedArray extends Array { - " __sortedArrayBrand": any; - } interface SortedReadonlyArray extends ReadonlyArray { " __sortedArrayBrand": any; } diff --git a/tests/baselines/reference/api/typescript.d.ts b/tests/baselines/reference/api/typescript.d.ts index 3a1fa35146c..f68a53e706e 100644 --- a/tests/baselines/reference/api/typescript.d.ts +++ b/tests/baselines/reference/api/typescript.d.ts @@ -2775,6 +2775,9 @@ declare namespace ts { span: TextSpan; newLength: number; } + interface SortedArray extends Array { + " __sortedArrayBrand": any; + } interface SyntaxList extends Node { _children: Node[]; }