mirror of
https://github.com/microsoft/TypeScript.git
synced 2026-05-17 01:49:57 -05:00
Move insertSorted from server to core, use for diagnostic collections (#21401)
* Move insertSorted from server to core, use for diagnostic collections * All keep the overall list sorted, too * Increase timeout for js verification * Use knowledge of how diagnostics are sorted to make all diagnostic list creation lazy and more efficient * Staunchly avoid array allocation in favor of resizing an existing array
This commit is contained in:
@@ -794,6 +794,18 @@ namespace ts {
|
||||
return deduplicated;
|
||||
}
|
||||
|
||||
export function insertSorted<T>(array: SortedArray<T>, insert: T, compare: Comparer<T>): 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<T>(array: ReadonlyArray<T>, comparer: Comparer<T>, equalityComparer?: EqualityComparer<T>) {
|
||||
return deduplicateSorted(sort(array, comparer), equalityComparer || comparer);
|
||||
}
|
||||
|
||||
@@ -5009,6 +5009,10 @@ namespace ts {
|
||||
newLength: number;
|
||||
}
|
||||
|
||||
export interface SortedArray<T> extends Array<T> {
|
||||
" __sortedArrayBrand": any;
|
||||
}
|
||||
|
||||
/* @internal */
|
||||
export interface DiagnosticCollection {
|
||||
// Adds a diagnostic to this diagnostic collection.
|
||||
|
||||
@@ -2443,11 +2443,10 @@ namespace ts {
|
||||
}
|
||||
|
||||
export function createDiagnosticCollection(): DiagnosticCollection {
|
||||
let nonFileDiagnostics: Diagnostic[] = [];
|
||||
const fileDiagnostics = createMap<Diagnostic[]>();
|
||||
|
||||
let nonFileDiagnostics = [] as SortedArray<Diagnostic>;
|
||||
const filesWithDiagnostics = [] as SortedArray<string>;
|
||||
const fileDiagnostics = createMap<SortedArray<Diagnostic>>();
|
||||
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<Diagnostic>;
|
||||
if (diagnostic.file) {
|
||||
diagnostics = fileDiagnostics.get(diagnostic.file.fileName);
|
||||
if (!diagnostics) {
|
||||
diagnostics = [];
|
||||
diagnostics = [] as SortedArray<Diagnostic>;
|
||||
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<Diagnostic>;
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -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"]);
|
||||
|
||||
@@ -22,10 +22,6 @@ 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> {
|
||||
" __sortedArrayBrand": any;
|
||||
}
|
||||
|
||||
@@ -232,18 +232,6 @@ namespace ts.server {
|
||||
return base === "tsconfig.json" || base === "jsconfig.json" ? base : undefined;
|
||||
}
|
||||
|
||||
export function insertSorted<T>(array: SortedArray<T>, insert: T, compare: Comparer<T>): 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<T>(array: SortedArray<T>, remove: T, compare: Comparer<T>): void {
|
||||
if (!array || array.length === 0) {
|
||||
return;
|
||||
|
||||
Reference in New Issue
Block a user