Skip to content

Commit fb50920

Browse files
authored
Merge pull request #32092 from microsoft/report-multiple-overload-errors
Report multiple overload errors
2 parents e8bf958 + 05a4e8f commit fb50920

File tree

56 files changed

+2307
-799
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

56 files changed

+2307
-799
lines changed

src/compiler/checker.ts

Lines changed: 224 additions & 75 deletions
Large diffs are not rendered by default.

src/compiler/core.ts

Lines changed: 9 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -600,24 +600,18 @@ namespace ts {
600600
*
601601
* @param array The array to flatten.
602602
*/
603-
export function flatten<T>(array: ReadonlyArray<T | ReadonlyArray<T> | undefined>): T[];
604-
export function flatten<T>(array: ReadonlyArray<T | ReadonlyArray<T> | undefined> | undefined): T[] | undefined;
605-
export function flatten<T>(array: ReadonlyArray<T | ReadonlyArray<T> | undefined> | undefined): T[] | undefined {
606-
let result: T[] | undefined;
607-
if (array) {
608-
result = [];
609-
for (const v of array) {
610-
if (v) {
611-
if (isArray(v)) {
612-
addRange(result, v);
613-
}
614-
else {
615-
result.push(v);
616-
}
603+
export function flatten<T>(array: T[][] | ReadonlyArray<T | ReadonlyArray<T> | undefined>): T[] {
604+
const result = [];
605+
for (const v of array) {
606+
if (v) {
607+
if (isArray(v)) {
608+
addRange(result, v);
609+
}
610+
else {
611+
result.push(v);
617612
}
618613
}
619614
}
620-
621615
return result;
622616
}
623617

src/compiler/diagnosticMessages.json

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2677,6 +2677,22 @@
26772677
"category": "Error",
26782678
"code": 2768
26792679
},
2680+
"No overload matches this call.": {
2681+
"category": "Error",
2682+
"code": 2769
2683+
},
2684+
"The last overload gave the following error.": {
2685+
"category": "Error",
2686+
"code": 2770
2687+
},
2688+
"The last overload is declared here.": {
2689+
"category": "Error",
2690+
"code": 2771
2691+
},
2692+
"Overload {0} of {1}, '{2}', gave the following error.": {
2693+
"category": "Error",
2694+
"code": 2772
2695+
},
26802696

26812697
"Import declaration '{0}' is using private name '{1}'.": {
26822698
"category": "Error",

src/compiler/program.ts

Lines changed: 19 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -502,30 +502,29 @@ namespace ts {
502502
return output;
503503
}
504504

505-
export function flattenDiagnosticMessageText(messageText: string | DiagnosticMessageChain | undefined, newLine: string): string {
506-
if (isString(messageText)) {
507-
return messageText;
505+
export function flattenDiagnosticMessageText(diag: string | DiagnosticMessageChain | undefined, newLine: string, indent = 0): string {
506+
if (isString(diag)) {
507+
return diag;
508508
}
509-
else {
510-
let diagnosticChain = messageText;
511-
let result = "";
512-
513-
let indent = 0;
514-
while (diagnosticChain) {
515-
if (indent) {
516-
result += newLine;
509+
else if (diag === undefined) {
510+
return "";
511+
}
512+
let result = "";
513+
if (indent) {
514+
result += newLine;
517515

518-
for (let i = 0; i < indent; i++) {
519-
result += " ";
520-
}
521-
}
522-
result += diagnosticChain.messageText;
523-
indent++;
524-
diagnosticChain = diagnosticChain.next;
516+
for (let i = 0; i < indent; i++) {
517+
result += " ";
518+
}
519+
}
520+
result += diag.messageText;
521+
indent++;
522+
if (diag.next) {
523+
for (const kid of diag.next) {
524+
result += flattenDiagnosticMessageText(kid, newLine, indent);
525525
}
526-
527-
return result;
528526
}
527+
return result;
529528
}
530529

531530
/* @internal */

src/compiler/types.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4577,7 +4577,7 @@ namespace ts {
45774577
messageText: string;
45784578
category: DiagnosticCategory;
45794579
code: number;
4580-
next?: DiagnosticMessageChain;
4580+
next?: DiagnosticMessageChain[];
45814581
}
45824582

45834583
export interface Diagnostic extends DiagnosticRelatedInformation {

src/compiler/utilities.ts

Lines changed: 38 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -7125,8 +7125,8 @@ namespace ts {
71257125
};
71267126
}
71277127

7128-
export function chainDiagnosticMessages(details: DiagnosticMessageChain | undefined, message: DiagnosticMessage, ...args: (string | number | undefined)[]): DiagnosticMessageChain;
7129-
export function chainDiagnosticMessages(details: DiagnosticMessageChain | undefined, message: DiagnosticMessage): DiagnosticMessageChain {
7128+
export function chainDiagnosticMessages(details: DiagnosticMessageChain | DiagnosticMessageChain[] | undefined, message: DiagnosticMessage, ...args: (string | number | undefined)[]): DiagnosticMessageChain;
7129+
export function chainDiagnosticMessages(details: DiagnosticMessageChain | DiagnosticMessageChain[] | undefined, message: DiagnosticMessage): DiagnosticMessageChain {
71307130
let text = getLocaleSpecificMessage(message);
71317131

71327132
if (arguments.length > 2) {
@@ -7138,18 +7138,17 @@ namespace ts {
71387138
category: message.category,
71397139
code: message.code,
71407140

7141-
next: details
7141+
next: details === undefined || Array.isArray(details) ? details : [details]
71427142
};
71437143
}
71447144

7145-
export function concatenateDiagnosticMessageChains(headChain: DiagnosticMessageChain, tailChain: DiagnosticMessageChain): DiagnosticMessageChain {
7145+
export function concatenateDiagnosticMessageChains(headChain: DiagnosticMessageChain, tailChain: DiagnosticMessageChain): void {
71467146
let lastChain = headChain;
71477147
while (lastChain.next) {
7148-
lastChain = lastChain.next;
7148+
lastChain = lastChain.next[0];
71497149
}
71507150

7151-
lastChain.next = tailChain;
7152-
return headChain;
7151+
lastChain.next = [tailChain];
71537152
}
71547153

71557154
function getDiagnosticFilePath(diagnostic: Diagnostic): string | undefined {
@@ -7185,29 +7184,42 @@ namespace ts {
71857184
}
71867185

71877186
function compareMessageText(t1: string | DiagnosticMessageChain, t2: string | DiagnosticMessageChain): Comparison {
7188-
let text1: string | DiagnosticMessageChain | undefined = t1;
7189-
let text2: string | DiagnosticMessageChain | undefined = t2;
7190-
while (text1 && text2) {
7191-
// We still have both chains.
7192-
const string1 = isString(text1) ? text1 : text1.messageText;
7193-
const string2 = isString(text2) ? text2 : text2.messageText;
7194-
7195-
const res = compareStringsCaseSensitive(string1, string2);
7187+
if (typeof t1 === "string" && typeof t2 === "string") {
7188+
return compareStringsCaseSensitive(t1, t2);
7189+
}
7190+
else if (typeof t1 === "string") {
7191+
return Comparison.LessThan;
7192+
}
7193+
else if (typeof t2 === "string") {
7194+
return Comparison.GreaterThan;
7195+
}
7196+
let res = compareStringsCaseSensitive(t1.messageText, t2.messageText);
7197+
if (res) {
7198+
return res;
7199+
}
7200+
if (!t1.next && !t2.next) {
7201+
return Comparison.EqualTo;
7202+
}
7203+
if (!t1.next) {
7204+
return Comparison.LessThan;
7205+
}
7206+
if (!t2.next) {
7207+
return Comparison.GreaterThan;
7208+
}
7209+
const len = Math.min(t1.next.length, t2.next.length);
7210+
for (let i = 0; i < len; i++) {
7211+
res = compareMessageText(t1.next[i], t2.next[i]);
71967212
if (res) {
71977213
return res;
71987214
}
7199-
7200-
text1 = isString(text1) ? undefined : text1.next;
7201-
text2 = isString(text2) ? undefined : text2.next;
72027215
}
7203-
7204-
if (!text1 && !text2) {
7205-
// if the chains are done, then these messages are the same.
7206-
return Comparison.EqualTo;
7216+
if (t1.next.length < t2.next.length) {
7217+
return Comparison.LessThan;
72077218
}
7208-
7209-
// We still have one chain remaining. The shorter chain should come first.
7210-
return text1 ? Comparison.GreaterThan : Comparison.LessThan;
7219+
else if (t1.next.length > t2.next.length) {
7220+
return Comparison.GreaterThan;
7221+
}
7222+
return Comparison.EqualTo;
72117223
}
72127224

72137225
export function getEmitScriptTarget(compilerOptions: CompilerOptions) {
@@ -8105,7 +8117,7 @@ namespace ts {
81058117
visitDirectory(basePath, combinePaths(currentDirectory, basePath), depth);
81068118
}
81078119

8108-
return flatten<string>(results);
8120+
return flatten(results);
81098121

81108122
function visitDirectory(path: string, absolutePath: string, depth: number | undefined) {
81118123
const canonicalPath = toCanonical(realpath(absolutePath));

src/harness/fourslash.ts

Lines changed: 12 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1497,13 +1497,7 @@ Actual: ${stringify(fullActual)}`);
14971497
const diagnostics = ts.getPreEmitDiagnostics(this.languageService.getProgram()!); // TODO: GH#18217
14981498
for (const diagnostic of diagnostics) {
14991499
if (!ts.isString(diagnostic.messageText)) {
1500-
let chainedMessage: ts.DiagnosticMessageChain | undefined = diagnostic.messageText;
1501-
let indentation = " ";
1502-
while (chainedMessage) {
1503-
resultString += indentation + chainedMessage.messageText + Harness.IO.newLine();
1504-
chainedMessage = chainedMessage.next;
1505-
indentation = indentation + " ";
1506-
}
1500+
resultString += this.flattenChainedMessage(diagnostic.messageText);
15071501
}
15081502
else {
15091503
resultString += " " + diagnostic.messageText + Harness.IO.newLine();
@@ -1521,6 +1515,17 @@ Actual: ${stringify(fullActual)}`);
15211515
Harness.Baseline.runBaseline(ts.Debug.assertDefined(this.testData.globalOptions[MetadataOptionNames.baselineFile]), resultString);
15221516
}
15231517

1518+
private flattenChainedMessage(diag: ts.DiagnosticMessageChain, indent = " ") {
1519+
let result = "";
1520+
result += indent + diag.messageText + Harness.IO.newLine();
1521+
if (diag.next) {
1522+
for (const kid of diag.next) {
1523+
result += this.flattenChainedMessage(kid, indent + " ");
1524+
}
1525+
}
1526+
return result;
1527+
}
1528+
15241529
public baselineQuickInfo() {
15251530
const baselineFile = this.getBaselineFileName();
15261531
Harness.Baseline.runBaseline(

tests/baselines/reference/api/tsserverlibrary.d.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2457,7 +2457,7 @@ declare namespace ts {
24572457
messageText: string;
24582458
category: DiagnosticCategory;
24592459
code: number;
2460-
next?: DiagnosticMessageChain;
2460+
next?: DiagnosticMessageChain[];
24612461
}
24622462
interface Diagnostic extends DiagnosticRelatedInformation {
24632463
/** May store more in future. For now, this will simply be `true` to indicate when a diagnostic is an unused-identifier diagnostic. */
@@ -4277,7 +4277,7 @@ declare namespace ts {
42774277
function formatDiagnostics(diagnostics: ReadonlyArray<Diagnostic>, host: FormatDiagnosticsHost): string;
42784278
function formatDiagnostic(diagnostic: Diagnostic, host: FormatDiagnosticsHost): string;
42794279
function formatDiagnosticsWithColorAndContext(diagnostics: ReadonlyArray<Diagnostic>, host: FormatDiagnosticsHost): string;
4280-
function flattenDiagnosticMessageText(messageText: string | DiagnosticMessageChain | undefined, newLine: string): string;
4280+
function flattenDiagnosticMessageText(diag: string | DiagnosticMessageChain | undefined, newLine: string, indent?: number): string;
42814281
function getConfigFileParsingDiagnostics(configFileParseResult: ParsedCommandLine): ReadonlyArray<Diagnostic>;
42824282
/**
42834283
* Create a new 'Program' instance. A Program is an immutable collection of 'SourceFile's and a 'CompilerOptions'

tests/baselines/reference/api/typescript.d.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2457,7 +2457,7 @@ declare namespace ts {
24572457
messageText: string;
24582458
category: DiagnosticCategory;
24592459
code: number;
2460-
next?: DiagnosticMessageChain;
2460+
next?: DiagnosticMessageChain[];
24612461
}
24622462
interface Diagnostic extends DiagnosticRelatedInformation {
24632463
/** May store more in future. For now, this will simply be `true` to indicate when a diagnostic is an unused-identifier diagnostic. */
@@ -4277,7 +4277,7 @@ declare namespace ts {
42774277
function formatDiagnostics(diagnostics: ReadonlyArray<Diagnostic>, host: FormatDiagnosticsHost): string;
42784278
function formatDiagnostic(diagnostic: Diagnostic, host: FormatDiagnosticsHost): string;
42794279
function formatDiagnosticsWithColorAndContext(diagnostics: ReadonlyArray<Diagnostic>, host: FormatDiagnosticsHost): string;
4280-
function flattenDiagnosticMessageText(messageText: string | DiagnosticMessageChain | undefined, newLine: string): string;
4280+
function flattenDiagnosticMessageText(diag: string | DiagnosticMessageChain | undefined, newLine: string, indent?: number): string;
42814281
function getConfigFileParsingDiagnostics(configFileParseResult: ParsedCommandLine): ReadonlyArray<Diagnostic>;
42824282
/**
42834283
* Create a new 'Program' instance. A Program is an immutable collection of 'SourceFile's and a 'CompilerOptions'

0 commit comments

Comments
 (0)