@@ -41,6 +41,7 @@ import {
41
41
canHaveLocals ,
42
42
canHaveModifiers ,
43
43
type CanHaveModuleSpecifier ,
44
+ CanonicalDiagnostic ,
44
45
CaseBlock ,
45
46
CaseClause ,
46
47
CaseOrDefaultClause ,
@@ -2178,6 +2179,7 @@ export function createFileDiagnosticFromMessageChain(file: SourceFile, start: nu
2178
2179
category : messageChain . category ,
2179
2180
messageText : messageChain . next ? messageChain : messageChain . messageText ,
2180
2181
relatedInformation,
2182
+ canonicalHead : messageChain . canonicalHead ,
2181
2183
} ;
2182
2184
}
2183
2185
@@ -2216,6 +2218,14 @@ export function createDiagnosticForRange(sourceFile: SourceFile, range: TextRang
2216
2218
} ;
2217
2219
}
2218
2220
2221
+ /** @internal */
2222
+ export function getCanonicalDiagnostic ( message : DiagnosticMessage , ...args : string [ ] ) : CanonicalDiagnostic {
2223
+ return {
2224
+ code : message . code ,
2225
+ messageText : formatMessage ( message , ...args ) ,
2226
+ } ;
2227
+ }
2228
+
2219
2229
/** @internal */
2220
2230
export function getSpanOfTokenAtPosition ( sourceFile : SourceFile , pos : number ) : TextSpan {
2221
2231
const scanner = createScanner ( sourceFile . languageVersion , /*skipTrivia*/ true , sourceFile . languageVariant , sourceFile . text , /*onError*/ undefined , pos ) ;
@@ -8540,11 +8550,13 @@ export function compareDiagnostics(d1: Diagnostic, d2: Diagnostic): Comparison {
8540
8550
8541
8551
/** @internal */
8542
8552
export function compareDiagnosticsSkipRelatedInformation ( d1 : Diagnostic , d2 : Diagnostic ) : Comparison {
8553
+ const code1 = getDiagnosticCode ( d1 ) ;
8554
+ const code2 = getDiagnosticCode ( d2 ) ;
8543
8555
return compareStringsCaseSensitive ( getDiagnosticFilePath ( d1 ) , getDiagnosticFilePath ( d2 ) ) ||
8544
8556
compareValues ( d1 . start , d2 . start ) ||
8545
8557
compareValues ( d1 . length , d2 . length ) ||
8546
- compareValues ( d1 . code , d2 . code ) ||
8547
- compareMessageText ( d1 . messageText , d2 . messageText ) ||
8558
+ compareValues ( code1 , code2 ) ||
8559
+ compareMessageText ( d1 , d2 ) ||
8548
8560
Comparison . EqualTo ;
8549
8561
}
8550
8562
@@ -8566,25 +8578,38 @@ function compareRelatedInformation(d1: Diagnostic, d2: Diagnostic): Comparison {
8566
8578
// An diagnostic message with more elaboration should be considered *less than* a diagnostic message
8567
8579
// with less elaboration that is otherwise similar.
8568
8580
function compareMessageText (
8569
- t1 : string | Pick < DiagnosticMessageChain , "messageText" | "next" > ,
8570
- t2 : string | Pick < DiagnosticMessageChain , "messageText" | "next" > ,
8581
+ d1 : Diagnostic ,
8582
+ d2 : Diagnostic ,
8571
8583
) : Comparison {
8572
- if ( typeof t1 === "string" && typeof t2 === "string" ) {
8573
- return compareStringsCaseSensitive ( t1 , t2 ) ;
8584
+ let headMsg1 = getDiagnosticMessage ( d1 ) ;
8585
+ let headMsg2 = getDiagnosticMessage ( d2 ) ;
8586
+ if ( typeof headMsg1 !== "string" ) {
8587
+ headMsg1 = headMsg1 . messageText ;
8574
8588
}
8575
-
8576
- if ( typeof t1 === "string" ) {
8577
- t1 = { messageText : t1 } ;
8589
+ if ( typeof headMsg2 !== "string" ) {
8590
+ headMsg2 = headMsg2 . messageText ;
8578
8591
}
8579
- if ( typeof t2 === "string" ) {
8580
- t2 = { messageText : t2 } ;
8592
+ const chain1 = typeof d1 . messageText !== "string" ? d1 . messageText . next : undefined ;
8593
+ const chain2 = typeof d2 . messageText !== "string" ? d2 . messageText . next : undefined ;
8594
+
8595
+ let res = compareStringsCaseSensitive ( headMsg1 , headMsg2 ) ;
8596
+ if ( res ) {
8597
+ return res ;
8581
8598
}
8582
- const res = compareStringsCaseSensitive ( t1 . messageText , t2 . messageText ) ;
8599
+
8600
+ res = compareMessageChain ( chain1 , chain2 ) ;
8583
8601
if ( res ) {
8584
8602
return res ;
8585
8603
}
8586
8604
8587
- return compareMessageChain ( t1 . next , t2 . next ) ;
8605
+ if ( d1 . canonicalHead && ! d2 . canonicalHead ) {
8606
+ return Comparison . LessThan ;
8607
+ }
8608
+ if ( d2 . canonicalHead && ! d1 . canonicalHead ) {
8609
+ return Comparison . GreaterThan ;
8610
+ }
8611
+
8612
+ return Comparison . EqualTo ;
8588
8613
}
8589
8614
8590
8615
// First compare by size of the message chain,
@@ -8659,11 +8684,23 @@ function compareMessageChainContent(
8659
8684
8660
8685
/** @internal */
8661
8686
export function diagnosticsEqualityComparer ( d1 : Diagnostic , d2 : Diagnostic ) : boolean {
8687
+ const code1 = getDiagnosticCode ( d1 ) ;
8688
+ const code2 = getDiagnosticCode ( d2 ) ;
8689
+ const msg1 = getDiagnosticMessage ( d1 ) ;
8690
+ const msg2 = getDiagnosticMessage ( d2 ) ;
8662
8691
return compareStringsCaseSensitive ( getDiagnosticFilePath ( d1 ) , getDiagnosticFilePath ( d2 ) ) === Comparison . EqualTo &&
8663
8692
compareValues ( d1 . start , d2 . start ) === Comparison . EqualTo &&
8664
8693
compareValues ( d1 . length , d2 . length ) === Comparison . EqualTo &&
8665
- compareValues ( d1 . code , d2 . code ) === Comparison . EqualTo &&
8666
- messageTextEqualityComparer ( d1 . messageText , d2 . messageText ) ;
8694
+ compareValues ( code1 , code2 ) === Comparison . EqualTo &&
8695
+ messageTextEqualityComparer ( msg1 , msg2 ) ;
8696
+ }
8697
+
8698
+ function getDiagnosticCode ( d : Diagnostic ) : number {
8699
+ return d . canonicalHead ?. code || d . code ;
8700
+ }
8701
+
8702
+ function getDiagnosticMessage ( d : Diagnostic ) : string | DiagnosticMessageChain {
8703
+ return d . canonicalHead ?. messageText || d . messageText ;
8667
8704
}
8668
8705
8669
8706
function messageTextEqualityComparer ( m1 : string | DiagnosticMessageChain , m2 : string | DiagnosticMessageChain ) : boolean {
0 commit comments