1- use hir:: db:: AstDatabase ;
2- use ide_db:: source_change:: SourceChange ;
3- use syntax:: { ast, AstNode } ;
1+ use ide_db:: {
2+ base_db:: { FileLoader , FileRange } ,
3+ source_change:: SourceChange ,
4+ } ;
5+ use syntax:: { TextRange , TextSize } ;
46use text_edit:: TextEdit ;
57
68use crate :: { fix, Assist , Diagnostic , DiagnosticsContext } ;
@@ -15,29 +17,42 @@ pub(crate) fn remove_this_semicolon(
1517 Diagnostic :: new (
1618 "remove-this-semicolon" ,
1719 "remove this semicolon" ,
18- ctx . sema . diagnostics_display_range ( d . expr . clone ( ) . map ( |it| it. into ( ) ) ) . range ,
20+ semicolon_range ( ctx , d ) . unwrap_or_else ( |it| it) . range ,
1921 )
2022 . with_fixes ( fixes ( ctx, d) )
2123}
2224
25+ fn semicolon_range (
26+ ctx : & DiagnosticsContext < ' _ > ,
27+ d : & hir:: RemoveThisSemicolon ,
28+ ) -> Result < FileRange , FileRange > {
29+ let expr_range = ctx. sema . diagnostics_display_range ( d. expr . clone ( ) . map ( |it| it. into ( ) ) ) ;
30+ let file_text = ctx. sema . db . file_text ( expr_range. file_id ) ;
31+ let range_end: usize = expr_range. range . end ( ) . into ( ) ;
32+ // FIXME: This doesn't handle whitespace and comments, but handling those in
33+ // the presence of macros might prove tricky...
34+ if file_text[ range_end..] . starts_with ( ';' ) {
35+ Ok ( FileRange {
36+ file_id : expr_range. file_id ,
37+ range : TextRange :: at ( expr_range. range . end ( ) , TextSize :: of ( ';' ) ) ,
38+ } )
39+ } else {
40+ Err ( expr_range)
41+ }
42+ }
43+
2344fn fixes ( ctx : & DiagnosticsContext < ' _ > , d : & hir:: RemoveThisSemicolon ) -> Option < Vec < Assist > > {
24- let root = ctx. sema . db . parse_or_expand ( d. expr . file_id ) ?;
25-
26- let semicolon = d
27- . expr
28- . value
29- . to_node ( & root)
30- . syntax ( )
31- . parent ( )
32- . and_then ( ast:: ExprStmt :: cast)
33- . and_then ( |expr| expr. semicolon_token ( ) ) ?
34- . text_range ( ) ;
35-
36- let edit = TextEdit :: delete ( semicolon) ;
37- let source_change =
38- SourceChange :: from_text_edit ( d. expr . file_id . original_file ( ctx. sema . db ) , edit) ;
39-
40- Some ( vec ! [ fix( "remove_semicolon" , "Remove this semicolon" , source_change, semicolon) ] )
45+ let semicolon_range = semicolon_range ( ctx, d) . ok ( ) ?;
46+
47+ let edit = TextEdit :: delete ( semicolon_range. range ) ;
48+ let source_change = SourceChange :: from_text_edit ( semicolon_range. file_id , edit) ;
49+
50+ Some ( vec ! [ fix(
51+ "remove_semicolon" ,
52+ "Remove this semicolon" ,
53+ source_change,
54+ semicolon_range. range,
55+ ) ] )
4156}
4257
4358#[ cfg( test) ]
@@ -49,7 +64,7 @@ mod tests {
4964 check_diagnostics (
5065 r#"
5166fn test() -> i32 { 123; }
52- //^^ ^ 💡 error: remove this semicolon
67+ // ^ 💡 error: remove this semicolon
5368"# ,
5469 ) ;
5570 }
0 commit comments