@@ -7,6 +7,7 @@ use dashmap::DashMap;
77use tower_lsp_server:: ls_types:: DocumentRangeFormattingParams ;
88use url:: Url ;
99
10+ use crate :: error:: LspError ;
1011use crate :: {
1112 capabilities, completions, document_symbol, execute_command, goto_definition, hover, references, semantic_tokens,
1213} ;
@@ -25,7 +26,7 @@ struct Backend {
2526 client : Client ,
2627 hir : Arc < RwLock < mq_hir:: Hir > > ,
2728 source_map : RwLock < BiMap < String , mq_hir:: SourceId > > ,
28- error_map : DashMap < String , Vec < ( std :: string :: String , mq_lang :: Range ) > > ,
29+ error_map : DashMap < String , Vec < LspError > > ,
2930 text_map : DashMap < String , Arc < String > > ,
3031 config : LspConfig ,
3132}
@@ -230,7 +231,7 @@ impl LanguageServer for Backend {
230231 params : DocumentRangeFormattingParams ,
231232 ) -> jsonrpc:: Result < Option < Vec < ls_types:: TextEdit > > > {
232233 if let Some ( errors) = self . error_map . get ( & params. text_document . uri . to_string ( ) )
233- && !errors. is_empty ( )
234+ && !( * errors) . is_empty ( )
234235 {
235236 return Ok ( None ) ;
236237 }
@@ -326,9 +327,21 @@ impl Backend {
326327 let ( source_id, _) = self . hir . write ( ) . unwrap ( ) . add_nodes ( uri. clone ( ) , & nodes) ;
327328
328329 let uri_string = uri. to_string ( ) ;
330+ let mut errors = errors
331+ . error_ranges ( & text)
332+ . into_iter ( )
333+ . map ( |( message, range) | LspError :: SyntaxError ( ( message, range) ) )
334+ . collect :: < Vec < _ > > ( ) ;
335+
336+ if errors. is_empty ( ) && self . config . enable_type_checking {
337+ let mut checker = mq_check:: TypeChecker :: with_options ( self . config . type_checker_options ) ;
338+ let type_errors = checker. check ( & self . hir . read ( ) . unwrap ( ) ) ;
339+ errors. extend ( type_errors. into_iter ( ) . map ( LspError :: TypeError ) ) ;
340+ }
341+
329342 self . source_map . write ( ) . unwrap ( ) . insert ( uri_string. clone ( ) , source_id) ;
330343 self . text_map . insert ( uri_string. clone ( ) , text. to_string ( ) . into ( ) ) ;
331- self . error_map . insert ( uri_string, errors. error_ranges ( & text ) ) ;
344+ self . error_map . insert ( uri_string, errors) ;
332345 }
333346
334347 async fn diagnostics ( & self , uri : Url , version : Option < i32 > ) {
@@ -340,46 +353,8 @@ impl Backend {
340353
341354 // Add parsing errors if they exist
342355 if let Some ( errors) = file_errors {
343- diagnostics. extend ( errors. iter ( ) . map ( |( message, item) | {
344- ls_types:: Diagnostic :: new_simple (
345- ls_types:: Range :: new (
346- ls_types:: Position {
347- line : item. start . line - 1 ,
348- character : ( item. start . column - 1 ) as u32 ,
349- } ,
350- ls_types:: Position {
351- line : item. end . line - 1 ,
352- character : ( item. end . column - 1 ) as u32 ,
353- } ,
354- ) ,
355- message. to_string ( ) ,
356- )
357- } ) ) ;
358-
359- if errors. is_empty ( ) && self . config . enable_type_checking {
360- let mut checker = mq_check:: TypeChecker :: with_options ( self . config . type_checker_options ) ;
361- let type_errors = checker. check ( & self . hir . read ( ) . unwrap ( ) ) ;
362-
363- diagnostics. extend ( type_errors. iter ( ) . filter_map ( |type_error| {
364- type_error. location ( ) . map ( |location| {
365- let mut diagnostic = ls_types:: Diagnostic :: new_simple (
366- ls_types:: Range :: new (
367- ls_types:: Position {
368- line : location. 0 ,
369- character : location. 1 as u32 ,
370- } ,
371- ls_types:: Position {
372- line : location. 0 ,
373- character : location. 1 as u32 ,
374- } ,
375- ) ,
376- type_error. to_string ( ) ,
377- ) ;
378- diagnostic. severity = Some ( ls_types:: DiagnosticSeverity :: ERROR ) ;
379- diagnostic
380- } )
381- } ) ) ;
382- }
356+ let errors: Vec < ls_types:: Diagnostic > = ( * errors) . iter ( ) . map ( Into :: into) . collect :: < Vec < _ > > ( ) ;
357+ diagnostics. extend ( errors) ;
383358 }
384359
385360 {
@@ -580,7 +555,14 @@ mod tests {
580555
581556 let ( _, errors) = mq_lang:: parse_recovery ( text) ;
582557 backend. text_map . insert ( uri. to_string ( ) , text. to_string ( ) . into ( ) ) ;
583- backend. error_map . insert ( uri. to_string ( ) , errors. error_ranges ( text) ) ;
558+ backend. error_map . insert (
559+ uri. to_string ( ) ,
560+ errors
561+ . error_ranges ( text)
562+ . into_iter ( )
563+ . map ( |( message, range) | LspError :: SyntaxError ( ( message, range) ) )
564+ . collect ( ) ,
565+ ) ;
584566
585567 let result = backend
586568 . formatting ( ls_types:: DocumentFormattingParams {
@@ -931,7 +913,14 @@ mod tests {
931913 let text = "def main(): invalid_syntax" ;
932914 let ( _, errors) = mq_lang:: parse_recovery ( text) ;
933915 backend. text_map . insert ( uri. to_string ( ) , text. to_string ( ) . into ( ) ) ;
934- backend. error_map . insert ( uri. to_string ( ) , errors. error_ranges ( text) ) ;
916+ backend. error_map . insert (
917+ uri. to_string ( ) ,
918+ errors
919+ . error_ranges ( text)
920+ . into_iter ( )
921+ . map ( |( message, range) | LspError :: SyntaxError ( ( message, range) ) )
922+ . collect ( ) ,
923+ ) ;
935924
936925 backend
937926 . source_map
@@ -1032,7 +1021,14 @@ mod tests {
10321021 let text = "def main() 1;" ; // Missing colon
10331022 let ( _, errors) = mq_lang:: parse_recovery ( text) ;
10341023 backend. text_map . insert ( uri. to_string ( ) , text. to_string ( ) . into ( ) ) ;
1035- backend. error_map . insert ( uri. to_string ( ) , errors. error_ranges ( text) ) ;
1024+ backend. error_map . insert (
1025+ uri. to_string ( ) ,
1026+ errors
1027+ . error_ranges ( text)
1028+ . into_iter ( )
1029+ . map ( |( message, range) | LspError :: SyntaxError ( ( message, range) ) )
1030+ . collect ( ) ,
1031+ ) ;
10361032
10371033 // We can't directly test client.publish_diagnostics was called with correct diagnostics,
10381034 // but we can verify the code doesn't panic
@@ -1060,7 +1056,14 @@ mod tests {
10601056
10611057 backend. source_map . write ( ) . unwrap ( ) . insert ( uri. to_string ( ) , source_id) ;
10621058 backend. text_map . insert ( uri. to_string ( ) , code. to_string ( ) . into ( ) ) ;
1063- backend. error_map . insert ( uri. to_string ( ) , errors. error_ranges ( code) ) ;
1059+ backend. error_map . insert (
1060+ uri. to_string ( ) ,
1061+ errors
1062+ . error_ranges ( code)
1063+ . into_iter ( )
1064+ . map ( |( message, range) | LspError :: SyntaxError ( ( message, range) ) )
1065+ . collect ( ) ,
1066+ ) ;
10641067
10651068 // Check unused functions are detected
10661069 {
@@ -1094,13 +1097,13 @@ mod tests {
10941097 backend. text_map . insert ( uri. to_string ( ) , text. to_string ( ) . into ( ) ) ;
10951098 backend. error_map . insert (
10961099 uri. to_string ( ) ,
1097- vec ! [ (
1100+ vec ! [ LspError :: SyntaxError ( (
10981101 "Syntax error" . to_string( ) ,
10991102 mq_lang:: Range {
11001103 start: mq_lang:: Position { line: 1 , column: 10 } ,
11011104 end: mq_lang:: Position { line: 1 , column: 11 } ,
11021105 } ,
1103- ) ] ,
1106+ ) ) ] ,
11041107 ) ;
11051108
11061109 let result = backend
@@ -1139,7 +1142,14 @@ mod tests {
11391142
11401143 backend. source_map . write ( ) . unwrap ( ) . insert ( uri. to_string ( ) , source_id) ;
11411144 backend. text_map . insert ( uri. to_string ( ) , code. to_string ( ) . into ( ) ) ;
1142- backend. error_map . insert ( uri. to_string ( ) , errors. error_ranges ( code) ) ;
1145+ backend. error_map . insert (
1146+ uri. to_string ( ) ,
1147+ errors
1148+ . error_ranges ( code)
1149+ . into_iter ( )
1150+ . map ( |( message, range) | LspError :: SyntaxError ( ( message, range) ) )
1151+ . collect ( ) ,
1152+ ) ;
11431153
11441154 // Check unreachable code warnings are detected
11451155 {
@@ -1254,13 +1264,13 @@ mod tests {
12541264 backend. text_map . insert ( uri. to_string ( ) , text. to_string ( ) . into ( ) ) ;
12551265 backend. error_map . insert (
12561266 uri. to_string ( ) ,
1257- vec ! [ (
1267+ vec ! [ LspError :: SyntaxError ( (
12581268 "Syntax error" . to_string( ) ,
12591269 mq_lang:: Range {
12601270 start: mq_lang:: Position { line: 0 , column: 0 } ,
12611271 end: mq_lang:: Position { line: 0 , column: 10 } ,
12621272 } ,
1263- ) ] ,
1273+ ) ) ] ,
12641274 ) ;
12651275
12661276 let params = DocumentRangeFormattingParams {
@@ -1327,7 +1337,14 @@ mod tests {
13271337
13281338 backend. source_map . write ( ) . unwrap ( ) . insert ( uri. to_string ( ) , source_id) ;
13291339 backend. text_map . insert ( uri. to_string ( ) , code. to_string ( ) . into ( ) ) ;
1330- backend. error_map . insert ( uri. to_string ( ) , errors. error_ranges ( code) ) ;
1340+ backend. error_map . insert (
1341+ uri. to_string ( ) ,
1342+ errors
1343+ . error_ranges ( code)
1344+ . into_iter ( )
1345+ . map ( |( message, range) | LspError :: SyntaxError ( ( message, range) ) )
1346+ . collect ( ) ,
1347+ ) ;
13311348
13321349 // No type errors should be emitted since type checking is disabled
13331350 // (diagnostics() calls publish_diagnostics internally, we just verify it doesn't panic)
@@ -1355,7 +1372,14 @@ mod tests {
13551372
13561373 backend. source_map . write ( ) . unwrap ( ) . insert ( uri. to_string ( ) , source_id) ;
13571374 backend. text_map . insert ( uri. to_string ( ) , code. to_string ( ) . into ( ) ) ;
1358- backend. error_map . insert ( uri. to_string ( ) , errors. error_ranges ( code) ) ;
1375+ backend. error_map . insert (
1376+ uri. to_string ( ) ,
1377+ errors
1378+ . error_ranges ( code)
1379+ . into_iter ( )
1380+ . map ( |( message, range) | LspError :: SyntaxError ( ( message, range) ) )
1381+ . collect ( ) ,
1382+ ) ;
13591383
13601384 assert ! ( backend. error_map. get( & uri. to_string( ) ) . unwrap( ) . is_empty( ) ) ;
13611385
@@ -1384,7 +1408,14 @@ mod tests {
13841408
13851409 backend. source_map . write ( ) . unwrap ( ) . insert ( uri. to_string ( ) , source_id) ;
13861410 backend. text_map . insert ( uri. to_string ( ) , code. to_string ( ) . into ( ) ) ;
1387- backend. error_map . insert ( uri. to_string ( ) , errors. error_ranges ( code) ) ;
1411+ backend. error_map . insert (
1412+ uri. to_string ( ) ,
1413+ errors
1414+ . error_ranges ( code)
1415+ . into_iter ( )
1416+ . map ( |( message, range) | LspError :: SyntaxError ( ( message, range) ) )
1417+ . collect ( ) ,
1418+ ) ;
13881419
13891420 // Parse errors should be empty so type checking runs
13901421 assert ! ( backend. error_map. get( & uri. to_string( ) ) . unwrap( ) . is_empty( ) ) ;
@@ -1417,13 +1448,13 @@ mod tests {
14171448 backend. text_map . insert ( uri. to_string ( ) , text. to_string ( ) . into ( ) ) ;
14181449 backend. error_map . insert (
14191450 uri. to_string ( ) ,
1420- vec ! [ (
1451+ vec ! [ LspError :: SyntaxError ( (
14211452 "Syntax error" . to_string( ) ,
14221453 mq_lang:: Range {
14231454 start: mq_lang:: Position { line: 1 , column: 1 } ,
14241455 end: mq_lang:: Position { line: 1 , column: 5 } ,
14251456 } ,
1426- ) ] ,
1457+ ) ) ] ,
14271458 ) ;
14281459
14291460 // Parse errors are present, so type checking should be skipped
@@ -1461,7 +1492,14 @@ mod tests {
14611492
14621493 backend. source_map . write ( ) . unwrap ( ) . insert ( uri. to_string ( ) , source_id) ;
14631494 backend. text_map . insert ( uri. to_string ( ) , code. to_string ( ) . into ( ) ) ;
1464- backend. error_map . insert ( uri. to_string ( ) , errors. error_ranges ( code) ) ;
1495+ backend. error_map . insert (
1496+ uri. to_string ( ) ,
1497+ errors
1498+ . error_ranges ( code)
1499+ . into_iter ( )
1500+ . map ( |( message, range) | LspError :: SyntaxError ( ( message, range) ) )
1501+ . collect ( ) ,
1502+ ) ;
14651503
14661504 assert ! ( backend. error_map. get( & uri. to_string( ) ) . unwrap( ) . is_empty( ) ) ;
14671505
@@ -1496,7 +1534,14 @@ mod tests {
14961534
14971535 backend. source_map . write ( ) . unwrap ( ) . insert ( uri. to_string ( ) , source_id) ;
14981536 backend. text_map . insert ( uri. to_string ( ) , code. to_string ( ) . into ( ) ) ;
1499- backend. error_map . insert ( uri. to_string ( ) , errors. error_ranges ( code) ) ;
1537+ backend. error_map . insert (
1538+ uri. to_string ( ) ,
1539+ errors
1540+ . error_ranges ( code)
1541+ . into_iter ( )
1542+ . map ( |( message, range) | LspError :: SyntaxError ( ( message, range) ) )
1543+ . collect ( ) ,
1544+ ) ;
15001545
15011546 assert ! ( backend. error_map. get( & uri. to_string( ) ) . unwrap( ) . is_empty( ) ) ;
15021547
0 commit comments