@@ -712,6 +712,11 @@ namespace ts.server {
712
712
typesMapLocation ?: string ;
713
713
}
714
714
715
+ type IncludePositionDiagnostics < IncludePos extends boolean > =
716
+ IncludePos extends true ? readonly protocol . DiagnosticWithLinePosition [ ]
717
+ : IncludePos extends false ? readonly protocol . Diagnostic [ ]
718
+ : readonly ( protocol . DiagnosticWithLinePosition | protocol . Diagnostic ) [ ] ;
719
+
715
720
export class Session < TMessage = string > implements EventSender {
716
721
private readonly gcTimer : GcTimer ;
717
722
protected projectService : ProjectService ;
@@ -1194,18 +1199,19 @@ namespace ts.server {
1194
1199
} ) ;
1195
1200
}
1196
1201
1197
- private getDiagnosticsWorker (
1198
- args : protocol . FileRequestArgs , isSemantic : boolean , selector : ( project : Project , file : string ) => readonly Diagnostic [ ] , includeLinePosition : boolean
1199
- ) : readonly protocol . DiagnosticWithLinePosition [ ] | readonly protocol . Diagnostic [ ] {
1202
+ private getDiagnosticsWorker < IncludePos extends boolean > (
1203
+ args : protocol . FileRequestArgs , isSemantic : boolean , selector : ( project : Project , file : string ) => readonly Diagnostic [ ] , includeLinePosition : IncludePos
1204
+ ) : IncludePositionDiagnostics < IncludePos > {
1200
1205
const { project, file } = this . getFileAndProject ( args ) ;
1201
1206
if ( isSemantic && isDeclarationFileInJSOnlyNonConfiguredProject ( project , file ) ) {
1202
- return emptyArray ;
1207
+ return emptyArray as unknown as IncludePositionDiagnostics < IncludePos > ;
1203
1208
}
1204
1209
const scriptInfo = project . getScriptInfoForNormalizedPath ( file ) ;
1205
1210
const diagnostics = selector ( project , file ) ;
1206
- return includeLinePosition
1211
+ return ( includeLinePosition
1207
1212
? this . convertToDiagnosticsWithLinePosition ( diagnostics , scriptInfo )
1208
- : diagnostics . map ( d => formatDiag ( file , project , d ) ) ;
1213
+ : diagnostics . map ( d => formatDiag ( file , project , d ) )
1214
+ ) as unknown as IncludePositionDiagnostics < IncludePos > ;
1209
1215
}
1210
1216
1211
1217
private getDefinition ( args : protocol . FileLocationRequestArgs , simplifiedResult : boolean ) : readonly protocol . FileSpanWithContext [ ] | readonly DefinitionInfo [ ] {
@@ -1367,7 +1373,7 @@ namespace ts.server {
1367
1373
emptyArray ;
1368
1374
}
1369
1375
1370
- private getSyntacticDiagnosticsSync ( args : protocol . SyntacticDiagnosticsSyncRequestArgs ) : readonly protocol . Diagnostic [ ] | readonly protocol . DiagnosticWithLinePosition [ ] {
1376
+ private getSyntacticDiagnosticsSync ( args : protocol . SyntacticDiagnosticsSyncRequestArgs ) {
1371
1377
const { configFile } = this . getConfigFileAndProject ( args ) ;
1372
1378
if ( configFile ) {
1373
1379
// all the config file errors are reported as part of semantic check so nothing to report here
@@ -1377,15 +1383,15 @@ namespace ts.server {
1377
1383
return this . getDiagnosticsWorker ( args , /*isSemantic*/ false , ( project , file ) => project . getLanguageService ( ) . getSyntacticDiagnostics ( file ) , ! ! args . includeLinePosition ) ;
1378
1384
}
1379
1385
1380
- private getSemanticDiagnosticsSync ( args : protocol . SemanticDiagnosticsSyncRequestArgs ) : readonly protocol . Diagnostic [ ] | readonly protocol . DiagnosticWithLinePosition [ ] {
1386
+ private getSemanticDiagnosticsSync ( args : protocol . SemanticDiagnosticsSyncRequestArgs ) {
1381
1387
const { configFile, project } = this . getConfigFileAndProject ( args ) ;
1382
1388
if ( configFile ) {
1383
1389
return this . getConfigFileDiagnostics ( configFile , project ! , ! ! args . includeLinePosition ) ; // TODO: GH#18217
1384
1390
}
1385
1391
return this . getDiagnosticsWorker ( args , /*isSemantic*/ true , ( project , file ) => project . getLanguageService ( ) . getSemanticDiagnostics ( file ) . filter ( d => ! ! d . file ) , ! ! args . includeLinePosition ) ;
1386
1392
}
1387
1393
1388
- private getSuggestionDiagnosticsSync ( args : protocol . SuggestionDiagnosticsSyncRequestArgs ) : readonly protocol . Diagnostic [ ] | readonly protocol . DiagnosticWithLinePosition [ ] {
1394
+ private getSuggestionDiagnosticsSync ( args : protocol . SuggestionDiagnosticsSyncRequestArgs ) {
1389
1395
const { configFile } = this . getConfigFileAndProject ( args ) ;
1390
1396
if ( configFile ) {
1391
1397
// Currently there are no info diagnostics for config files.
@@ -2198,7 +2204,23 @@ namespace ts.server {
2198
2204
const scriptInfo = project . getScriptInfoForNormalizedPath ( file ) ! ;
2199
2205
const { startPosition, endPosition } = this . getStartAndEndPosition ( args , scriptInfo ) ;
2200
2206
2201
- const codeActions = project . getLanguageService ( ) . getCodeFixesAtPosition ( file , startPosition , endPosition , args . errorCodes , this . getFormatOptions ( file ) , this . getPreferences ( file ) ) ;
2207
+ let codeActions : readonly CodeFixAction [ ] ;
2208
+ try {
2209
+ codeActions = project . getLanguageService ( ) . getCodeFixesAtPosition ( file , startPosition , endPosition , args . errorCodes , this . getFormatOptions ( file ) , this . getPreferences ( file ) ) ;
2210
+ }
2211
+ catch ( e ) {
2212
+ const existingDiagCodes = flatten ( ( [ "getSyntacticDiagnostics" , "getSemanticDiagnostics" , "getSuggestionDiagnostics" ] as const ) . map ( getter =>
2213
+ this . getDiagnosticsWorker ( args , /*isSemantic*/ getter !== "getSyntacticDiagnostics" ,
2214
+ ( project , file ) => project . getLanguageService ( ) [ getter ] ( file ) ,
2215
+ /*includeLinePosition*/ true )
2216
+ . filter ( d => decodedTextSpanIntersectsWith ( startPosition , endPosition - startPosition , d . start , d . length ) )
2217
+ . map ( d => d . code ) ) ) ;
2218
+ const badCode = args . errorCodes . find ( c => ! existingDiagCodes . includes ( c ) ) ;
2219
+ if ( badCode !== undefined ) {
2220
+ e . message = `Bad error code: ${ badCode } not found in range ${ startPosition } ..${ endPosition } (found: ${ existingDiagCodes . join ( ", " ) } ); could have caused this error:\n${ e . message } ` ;
2221
+ }
2222
+ throw e ;
2223
+ }
2202
2224
return simplifiedResult ? codeActions . map ( codeAction => this . mapCodeFixAction ( codeAction ) ) : codeActions ;
2203
2225
}
2204
2226
0 commit comments