1- use ide_db:: syntax_helpers:: node_ext:: for_each_break_and_continue_expr;
1+ use ide_db:: {
2+ source_change:: SourceChangeBuilder , syntax_helpers:: node_ext:: for_each_break_and_continue_expr,
3+ } ;
24use syntax:: {
3- T ,
4- ast:: { self , AstNode , HasLoopBody } ,
5+ SyntaxToken , T ,
6+ ast:: {
7+ self , AstNode , HasLoopBody ,
8+ make:: { self , tokens} ,
9+ syntax_factory:: SyntaxFactory ,
10+ } ,
11+ syntax_editor:: { Position , SyntaxEditor } ,
512} ;
613
714use crate :: { AssistContext , AssistId , Assists } ;
@@ -21,9 +28,9 @@ use crate::{AssistContext, AssistId, Assists};
2128// ->
2229// ```
2330// fn main() {
24- // 'l : loop {
25- // break 'l ;
26- // continue 'l ;
31+ // ${1:'l} : loop {
32+ // break ${2:'l} ;
33+ // continue ${0:'l} ;
2734// }
2835// }
2936// ```
@@ -39,30 +46,56 @@ pub(crate) fn add_label_to_loop(acc: &mut Assists, ctx: &AssistContext<'_>) -> O
3946 "Add Label" ,
4047 loop_expr. syntax ( ) . text_range ( ) ,
4148 |builder| {
42- builder. insert ( loop_kw. text_range ( ) . start ( ) , "'l: " ) ;
49+ let make = SyntaxFactory :: with_mappings ( ) ;
50+ let mut editor = builder. make_editor ( loop_expr. syntax ( ) ) ;
51+
52+ let label = make. lifetime ( "'l" ) ;
53+ let elements = vec ! [
54+ label. syntax( ) . clone( ) . into( ) ,
55+ make:: token( T ![ : ] ) . into( ) ,
56+ tokens:: single_space( ) . into( ) ,
57+ ] ;
58+ editor. insert_all ( Position :: before ( & loop_kw) , elements) ;
59+
60+ if let Some ( cap) = ctx. config . snippet_cap {
61+ editor. add_annotation ( label. syntax ( ) , builder. make_placeholder_snippet ( cap) ) ;
62+ }
4363
4464 let loop_body = loop_expr. loop_body ( ) . and_then ( |it| it. stmt_list ( ) ) ;
45- for_each_break_and_continue_expr (
46- loop_expr. label ( ) ,
47- loop_body,
48- & mut |expr| match expr {
49- ast:: Expr :: BreakExpr ( break_expr) => {
50- if let Some ( break_token) = break_expr. break_token ( ) {
51- builder. insert ( break_token. text_range ( ) . end ( ) , " 'l" )
52- }
53- }
54- ast:: Expr :: ContinueExpr ( continue_expr) => {
55- if let Some ( continue_token) = continue_expr. continue_token ( ) {
56- builder. insert ( continue_token. text_range ( ) . end ( ) , " 'l" )
57- }
58- }
59- _ => { }
60- } ,
61- ) ;
65+ for_each_break_and_continue_expr ( loop_expr. label ( ) , loop_body, & mut |expr| {
66+ let token = match expr {
67+ ast:: Expr :: BreakExpr ( break_expr) => break_expr. break_token ( ) ,
68+ ast:: Expr :: ContinueExpr ( continue_expr) => continue_expr. continue_token ( ) ,
69+ _ => return ,
70+ } ;
71+ if let Some ( token) = token {
72+ insert_label_after_token ( & mut editor, & make, & token, ctx, builder) ;
73+ }
74+ } ) ;
75+
76+ editor. add_mappings ( make. finish_with_mappings ( ) ) ;
77+ builder. add_file_edits ( ctx. vfs_file_id ( ) , editor) ;
78+ builder. rename ( ) ;
6279 } ,
6380 )
6481}
6582
83+ fn insert_label_after_token (
84+ editor : & mut SyntaxEditor ,
85+ make : & SyntaxFactory ,
86+ token : & SyntaxToken ,
87+ ctx : & AssistContext < ' _ > ,
88+ builder : & mut SourceChangeBuilder ,
89+ ) {
90+ let label = make. lifetime ( "'l" ) ;
91+ let elements = vec ! [ tokens:: single_space( ) . into( ) , label. syntax( ) . clone( ) . into( ) ] ;
92+ editor. insert_all ( Position :: after ( token) , elements) ;
93+
94+ if let Some ( cap) = ctx. config . snippet_cap {
95+ editor. add_annotation ( label. syntax ( ) , builder. make_placeholder_snippet ( cap) ) ;
96+ }
97+ }
98+
6699#[ cfg( test) ]
67100mod tests {
68101 use crate :: tests:: { check_assist, check_assist_not_applicable} ;
@@ -82,9 +115,9 @@ fn main() {
82115}"# ,
83116 r#"
84117fn main() {
85- 'l : loop {
86- break 'l ;
87- continue 'l ;
118+ ${1:'l} : loop {
119+ break ${2:'l} ;
120+ continue ${0:'l} ;
88121 }
89122}"# ,
90123 ) ;
@@ -107,9 +140,9 @@ fn main() {
107140}"# ,
108141 r#"
109142fn main() {
110- 'l : loop {
111- break 'l ;
112- continue 'l ;
143+ ${1:'l} : loop {
144+ break ${2:'l} ;
145+ continue ${0:'l} ;
113146 loop {
114147 break;
115148 continue;
@@ -139,9 +172,9 @@ fn main() {
139172 loop {
140173 break;
141174 continue;
142- 'l : loop {
143- break 'l ;
144- continue 'l ;
175+ ${1:'l} : loop {
176+ break ${2:'l} ;
177+ continue ${0:'l} ;
145178 }
146179 }
147180}"# ,
0 commit comments