diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index abedf405cde..39abb68de70 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -7345,12 +7345,8 @@ namespace ts { return type.id; } - function binarySearchTypes(types: Type[], type: Type): number { - return binarySearch(types, type, getTypeId, compareValues); - } - function containsType(types: Type[], type: Type): boolean { - return binarySearchTypes(types, type) >= 0; + return binarySearch(types, type, getTypeId, compareValues) >= 0; } // Return true if the given intersection type contains (a) more than one unit type or (b) an object @@ -7391,7 +7387,7 @@ namespace ts { if (flags & TypeFlags.Number) typeSet.containsNumber = true; if (flags & TypeFlags.StringOrNumberLiteral) typeSet.containsStringOrNumberLiteral = true; const len = typeSet.length; - const index = len && type.id > typeSet[len - 1].id ? ~len : binarySearchTypes(typeSet, type); + const index = len && type.id > typeSet[len - 1].id ? ~len : binarySearch(typeSet, type, getTypeId, compareValues); if (index < 0) { if (!(flags & TypeFlags.Object && (type).objectFlags & ObjectFlags.Anonymous && type.symbol && type.symbol.flags & (SymbolFlags.Function | SymbolFlags.Method) && containsIdenticalType(typeSet, type))) { diff --git a/src/compiler/core.ts b/src/compiler/core.ts index 0ccb7253331..dd30b36470f 100644 --- a/src/compiler/core.ts +++ b/src/compiler/core.ts @@ -1017,15 +1017,15 @@ namespace ts { while (low <= high) { const middle = low + ((high - low) >> 1); const midKey = keySelector(array[middle]); - - if (keyComparer(midKey, key) === 0) { - return middle; - } - else if (keyComparer(midKey, key) > 0) { - high = middle - 1; - } - else { - low = middle + 1; + switch (keyComparer(midKey, key)) { + case Comparison.LessThan: + low = middle + 1; + break; + case Comparison.EqualTo: + return middle; + case Comparison.GreaterThan: + high = middle - 1; + break; } } @@ -1852,27 +1852,8 @@ namespace ts { return text1 ? Comparison.GreaterThan : Comparison.LessThan; } - export function sortAndDeduplicateDiagnostics(diagnostics: Diagnostic[]): Diagnostic[] { - return deduplicateSortedDiagnostics(diagnostics.sort(compareDiagnostics)); - } - - export function deduplicateSortedDiagnostics(diagnostics: Diagnostic[]): Diagnostic[] { - if (diagnostics.length < 2) { - return diagnostics; - } - - const newDiagnostics = [diagnostics[0]]; - let previousDiagnostic = diagnostics[0]; - for (let i = 1; i < diagnostics.length; i++) { - const currentDiagnostic = diagnostics[i]; - const isDupe = compareDiagnostics(currentDiagnostic, previousDiagnostic) === Comparison.EqualTo; - if (!isDupe) { - newDiagnostics.push(currentDiagnostic); - previousDiagnostic = currentDiagnostic; - } - } - - return newDiagnostics; + export function sortAndDeduplicateDiagnostics(diagnostics: ReadonlyArray): Diagnostic[] { + return sortAndDeduplicate(diagnostics, compareDiagnostics); } export function normalizeSlashes(path: string): string { diff --git a/src/compiler/utilities.ts b/src/compiler/utilities.ts index 1ade3cc6374..4e55ae04d03 100644 --- a/src/compiler/utilities.ts +++ b/src/compiler/utilities.ts @@ -2291,6 +2291,7 @@ namespace ts { let nonFileDiagnostics: Diagnostic[] = []; const fileDiagnostics = createMap(); + let hasReadNonFileDiagnostics = false; let diagnosticsModified = false; let modificationCount = 0; @@ -2320,6 +2321,12 @@ namespace ts { } } else { + // If we've already read the non-file diagnostics, do not modify the existing array. + if (hasReadNonFileDiagnostics) { + hasReadNonFileDiagnostics = false; + nonFileDiagnostics = nonFileDiagnostics.slice(); + } + diagnostics = nonFileDiagnostics; } @@ -2330,6 +2337,7 @@ namespace ts { function getGlobalDiagnostics(): Diagnostic[] { sortAndDeduplicate(); + hasReadNonFileDiagnostics = true; return nonFileDiagnostics; } diff --git a/src/harness/fourslash.ts b/src/harness/fourslash.ts index d88f0e0854e..7ecf783aee6 100644 --- a/src/harness/fourslash.ts +++ b/src/harness/fourslash.ts @@ -531,15 +531,31 @@ namespace FourSlash { } for (const { start, length, messageText, file } of errors) { - Harness.IO.log(" from: " + showPosition(file, start) + - ", to: " + showPosition(file, start + length) + + Harness.IO.log(" " + this.formatRange(file, start, length) + ", message: " + ts.flattenDiagnosticMessageText(messageText, Harness.IO.newLine()) + "\n"); } + } - function showPosition(file: ts.SourceFile, pos: number) { + private formatRange(file: ts.SourceFile, start: number, length: number) { + if (file) { + return `from: ${this.formatLineAndCharacterOfPosition(file, start)}, to: ${this.formatLineAndCharacterOfPosition(file, start + length)}`; + } + return "global"; + } + + private formatLineAndCharacterOfPosition(file: ts.SourceFile, pos: number) { + if (file) { const { line, character } = ts.getLineAndCharacterOfPosition(file, pos); return `${line}:${character}`; } + return "global"; + } + + private formatPosition(file: ts.SourceFile, pos: number) { + if (file) { + return file.fileName + "@" + pos; + } + return "global"; } public verifyNoErrors() { @@ -549,7 +565,7 @@ namespace FourSlash { if (errors.length) { this.printErrorLog(/*expectErrors*/ false, errors); const error = errors[0]; - this.raiseError(`Found an error: ${error.file.fileName}@${error.start}: ${error.messageText}`); + this.raiseError(`Found an error: ${this.formatPosition(error.file, error.start)}: ${error.messageText}`); } }); } diff --git a/tests/cases/fourslash/incrementalParsingDynamicImport1.ts b/tests/cases/fourslash/incrementalParsingDynamicImport1.ts index 0f15dcb3b1b..511f3835f5b 100644 --- a/tests/cases/fourslash/incrementalParsingDynamicImport1.ts +++ b/tests/cases/fourslash/incrementalParsingDynamicImport1.ts @@ -7,11 +7,11 @@ //// var x1 = import("./foo"); //// x1.then(foo => { -//// var s: string = foo.bar(); +//// var s: string = foo.bar(); //// }) //// /*1*/ -verify.numberOfErrorsInCurrentFile(1); +verify.numberOfErrorsInCurrentFile(2); goTo.marker("1"); edit.insert(" "); -verify.numberOfErrorsInCurrentFile(1); \ No newline at end of file +verify.numberOfErrorsInCurrentFile(2); \ No newline at end of file diff --git a/tests/cases/fourslash/incrementalParsingDynamicImport3.ts b/tests/cases/fourslash/incrementalParsingDynamicImport3.ts index b3da4c5b538..64aca403ad9 100644 --- a/tests/cases/fourslash/incrementalParsingDynamicImport3.ts +++ b/tests/cases/fourslash/incrementalParsingDynamicImport3.ts @@ -11,4 +11,4 @@ verify.numberOfErrorsInCurrentFile(0); goTo.marker("1"); edit.insert("("); -verify.numberOfErrorsInCurrentFile(2); \ No newline at end of file +verify.numberOfErrorsInCurrentFile(3); \ No newline at end of file