@@ -190,7 +190,10 @@ impl LanguageServer for Backend {
190190 let uri = & params. text_document . uri ;
191191
192192 // .wit files don't have semantic tokens
193- if uri. path ( ) . as_str ( ) . ends_with ( ".wit" ) {
193+ if std:: path:: Path :: new ( uri. path ( ) . as_str ( ) )
194+ . extension ( )
195+ . is_some_and ( |ext| ext. eq_ignore_ascii_case ( "wit" ) )
196+ {
194197 return Ok ( None ) ;
195198 }
196199
@@ -207,7 +210,7 @@ impl LanguageServer for Backend {
207210 for func in & functions {
208211 // Add function name token (declaration)
209212 if let Ok ( name_range) = find_function_name_range ( func, & doc. text ) {
210- let len = func. name ( ) . as_inner ( ) . len ( ) as u32 ;
213+ let len = u32 :: try_from ( func. name ( ) . as_inner ( ) . len ( ) ) . map_err ( LspError :: from ) ? ;
211214 raw_tokens. push ( (
212215 name_range. start . line ,
213216 name_range. start . character ,
@@ -222,7 +225,7 @@ impl LanguageServer for Backend {
222225 . pre_order_iter ( )
223226 . filter_map ( |expr| {
224227 if let parse:: ExprTree :: Call ( call) = expr {
225- get_call_span ( call ) . ok ( ) . map ( |span| ( call, span ) )
228+ Some ( ( call, get_call_span ( call ) ) )
226229 } else {
227230 None
228231 }
@@ -249,8 +252,7 @@ impl LanguageServer for Backend {
249252 // The function name starts after "jet::"
250253 ( semantic_token_types:: FUNCTION , 5 )
251254 }
252- parse:: CallName :: Custom ( _) => ( semantic_token_types:: FUNCTION , 0 ) ,
253- _ => ( semantic_token_types:: FUNCTION , 0 ) , // Built-in functions
255+ _ => ( semantic_token_types:: FUNCTION , 0 ) ,
254256 } ;
255257
256258 // Add the function name token
@@ -263,8 +265,8 @@ impl LanguageServer for Backend {
263265 if func_name_len > 0 {
264266 raw_tokens. push ( (
265267 start. line ,
266- start. character + prefix_len as u32 ,
267- func_name_len as u32 ,
268+ start. character + u32:: try_from ( prefix_len ) . map_err ( LspError :: from ) ? ,
269+ u32:: try_from ( func_name_len ) . map_err ( LspError :: from ) ? ,
268270 token_type,
269271 0 ,
270272 ) ) ;
@@ -314,7 +316,10 @@ impl LanguageServer for Backend {
314316 let uri = & params. text_document . uri ;
315317
316318 // .wit files don't have symbols
317- if uri. path ( ) . as_str ( ) . ends_with ( ".wit" ) {
319+ if std:: path:: Path :: new ( uri. path ( ) . as_str ( ) )
320+ . extension ( )
321+ . is_some_and ( |ext| ext. eq_ignore_ascii_case ( "wit" ) )
322+ {
318323 return Ok ( None ) ;
319324 }
320325
@@ -391,9 +396,8 @@ impl LanguageServer for Backend {
391396 . unwrap_or_default ( ) ;
392397
393398 // Find function call context: look for unclosed '(' and count commas
394- let ( func_name, active_param) = match find_function_call_context ( & line_str) {
395- Some ( ctx) => ctx,
396- None => return Ok ( None ) ,
399+ let Some ( ( func_name, active_param) ) = find_function_call_context ( & line_str) else {
400+ return Ok ( None ) ;
397401 } ;
398402
399403 // Try to find the function signature
@@ -465,7 +469,10 @@ impl LanguageServer for Backend {
465469 let uri = & params. text_document_position_params . text_document . uri ;
466470
467471 // .wit files don't have hover info
468- if uri. path ( ) . as_str ( ) . ends_with ( ".wit" ) {
472+ if std:: path:: Path :: new ( uri. path ( ) . as_str ( ) )
473+ . extension ( )
474+ . is_some_and ( |ext| ext. eq_ignore_ascii_case ( "wit" ) )
475+ {
469476 return Ok ( None ) ;
470477 }
471478
@@ -484,7 +491,7 @@ impl LanguageServer for Backend {
484491 return Ok ( None ) ;
485492 } ;
486493
487- let call_span = get_call_span ( call) ? ;
494+ let call_span = get_call_span ( call) ;
488495 let ( start, end) = span_to_positions ( & call_span, & doc. text ) ?;
489496
490497 let description = match call. name ( ) {
@@ -668,7 +675,10 @@ impl Backend {
668675 /// Function which executed on change of file (`did_save`, `did_open` or `did_change` methods)
669676 async fn on_change ( & self , params : TextDocumentItem < ' _ > ) {
670677 // Check if this is a witness file
671- if params. uri . path ( ) . as_str ( ) . ends_with ( ".wit" ) {
678+ if std:: path:: Path :: new ( params. uri . path ( ) . as_str ( ) )
679+ . extension ( )
680+ . is_some_and ( |ext| ext. eq_ignore_ascii_case ( "wit" ) )
681+ {
672682 self . on_change_witness ( params) . await ;
673683 return ;
674684 }
@@ -764,74 +774,59 @@ fn parse_program(text: &str) -> (Vec<RichError>, Option<Document>) {
764774fn validate_witness_file ( text : & str ) -> Vec < Diagnostic > {
765775 let mut diagnostics = Vec :: new ( ) ;
766776
767- // Try to parse as JSON
768777 let json: serde_json:: Value = match serde_json:: from_str ( text) {
769778 Ok ( v) => v,
770779 Err ( e) => {
771- // JSON parse error - find the position
772- let line = e. line ( ) . saturating_sub ( 1 ) as u32 ;
773- let col = e. column ( ) . saturating_sub ( 1 ) as u32 ;
780+ let line = u32:: try_from ( e. line ( ) . saturating_sub ( 1 ) ) . unwrap_or ( 0 ) ;
781+ let col = u32:: try_from ( e. column ( ) . saturating_sub ( 1 ) ) . unwrap_or ( 0 ) ;
774782 diagnostics. push ( Diagnostic :: new_simple (
775783 Range :: new (
776784 tower_lsp_server:: lsp_types:: Position :: new ( line, col) ,
777785 tower_lsp_server:: lsp_types:: Position :: new ( line, col + 1 ) ,
778786 ) ,
779- format ! ( "JSON syntax error: {}" , e ) ,
787+ format ! ( "JSON syntax error: {e}" ) ,
780788 ) ) ;
781789 return diagnostics;
782790 }
783791 } ;
784792
785- // Must be an object
786- let obj = match json. as_object ( ) {
787- Some ( o) => o,
788- None => {
789- diagnostics. push ( Diagnostic :: new_simple (
790- Range :: new (
791- tower_lsp_server:: lsp_types:: Position :: new ( 0 , 0 ) ,
792- tower_lsp_server:: lsp_types:: Position :: new ( 0 , 1 ) ,
793- ) ,
794- "Witness file must be a JSON object" . to_string ( ) ,
795- ) ) ;
796- return diagnostics;
797- }
793+ let Some ( obj) = json. as_object ( ) else {
794+ diagnostics. push ( Diagnostic :: new_simple (
795+ Range :: new (
796+ tower_lsp_server:: lsp_types:: Position :: new ( 0 , 0 ) ,
797+ tower_lsp_server:: lsp_types:: Position :: new ( 0 , 1 ) ,
798+ ) ,
799+ "Witness file must be a JSON object" . to_string ( ) ,
800+ ) ) ;
801+ return diagnostics;
798802 } ;
799803
800- // Validate each witness entry
801804 for ( name, value) in obj {
802- let witness_obj = match value. as_object ( ) {
803- Some ( o) => o,
804- None => {
805- // Find approximate position for this key
806- if let Some ( pos) = find_key_position ( text, name) {
807- diagnostics. push ( Diagnostic :: new_simple (
808- Range :: new ( pos, pos) ,
809- format ! (
810- "Witness '{}' must be an object with 'value' and 'type' fields" ,
811- name
812- ) ,
813- ) ) ;
814- }
815- continue ;
805+ let Some ( witness_obj) = value. as_object ( ) else {
806+ // Find approximate position for this key
807+ if let Some ( pos) = find_key_position ( text, name) {
808+ diagnostics. push ( Diagnostic :: new_simple (
809+ Range :: new ( pos, pos) ,
810+ format ! ( "Witness '{name}' must be an object with 'value' and 'type' fields" ) ,
811+ ) ) ;
816812 }
813+ continue ;
817814 } ;
818815
819- // Check for required 'value' field
820816 if !witness_obj. contains_key ( "value" ) {
821817 if let Some ( pos) = find_key_position ( text, name) {
822818 diagnostics. push ( Diagnostic :: new_simple (
823819 Range :: new ( pos, pos) ,
824- format ! ( "Witness '{}' is missing required 'value' field" , name ) ,
820+ format ! ( "Witness '{name }' is missing required 'value' field" ) ,
825821 ) ) ;
826822 }
827823 }
828824
829- // Check for required 'type' field
830825 if !witness_obj. contains_key ( "type" ) {
831826 if let Some ( pos) = find_key_position ( text, name) {
832827 diagnostics. push ( Diagnostic :: new_simple (
833828 Range :: new ( pos, pos) ,
834- format ! ( "Witness '{}' is missing required 'type' field" , name ) ,
829+ format ! ( "Witness '{name }' is missing required 'type' field" ) ,
835830 ) ) ;
836831 }
837832 }
0 commit comments