1
- use std:: iter;
2
-
3
1
use either:: Either ;
4
2
use hir:: { Adt , FileRange , HasSource , HirDisplay , InFile , Struct , Union , db:: ExpandDatabase } ;
5
3
use ide_db:: text_edit:: TextEdit ;
@@ -194,17 +192,20 @@ fn add_field_to_struct_fix(
194
192
Some ( make:: visibility_pub_crate ( ) )
195
193
} ;
196
194
// FIXME: Allow for choosing a visibility modifier see https://github.com/rust-lang/rust-analyzer/issues/11563
197
- let indent = IndentLevel :: from_node ( struct_syntax. value ) + 1 ;
195
+ let indent = IndentLevel :: from_node ( struct_syntax. value ) ;
198
196
199
- let field = make :: record_field ( visibility , field_name , suggested_type ) . indent ( indent ) ;
200
- let record_field_list = make:: record_field_list ( iter :: once ( field ) ) ;
197
+ let field =
198
+ make:: record_field ( visibility , field_name , suggested_type ) . indent ( indent + 1 ) ;
201
199
// A Unit Struct with no `;` is invalid syntax. We should not suggest this fix.
202
200
let semi_colon =
203
201
algo:: skip_trivia_token ( struct_syntax. value . last_token ( ) ?, Direction :: Prev ) ?;
204
202
if semi_colon. kind ( ) != SyntaxKind :: SEMICOLON {
205
203
return None ;
206
204
}
207
- src_change_builder. replace ( semi_colon. text_range ( ) , record_field_list. to_string ( ) ) ;
205
+ src_change_builder. replace (
206
+ semi_colon. text_range ( ) ,
207
+ format ! ( " {{\n {}{field},\n {indent}}}" , indent + 1 ) ,
208
+ ) ;
208
209
209
210
Some ( Assist {
210
211
id : AssistId :: quick_fix ( "convert-unit-struct-to-record-struct" ) ,
@@ -230,7 +231,7 @@ fn record_field_layout(
230
231
field_list : ast:: RecordFieldList ,
231
232
struct_syntax : & SyntaxNode ,
232
233
) -> Option < ( TextSize , String ) > {
233
- let ( offset, needs_comma, trailing_new_line , indent) = match field_list. fields ( ) . last ( ) {
234
+ let ( offset, needs_comma, indent) = match field_list. fields ( ) . last ( ) {
234
235
Some ( record_field) => {
235
236
let syntax = algo:: skip_trivia_token ( field_list. r_curly_token ( ) ?, Direction :: Prev ) ?;
236
237
@@ -239,19 +240,22 @@ fn record_field_layout(
239
240
(
240
241
last_field_syntax. text_range ( ) . end ( ) ,
241
242
syntax. kind ( ) != SyntaxKind :: COMMA ,
242
- false ,
243
243
last_field_indent,
244
244
)
245
245
}
246
246
// Empty Struct. Add a field right before the closing brace
247
247
None => {
248
248
let indent = IndentLevel :: from_node ( struct_syntax) + 1 ;
249
- let offset = field_list. r_curly_token ( ) ?. text_range ( ) . start ( ) ;
250
- ( offset, false , true , indent)
249
+ let offset = field_list. l_curly_token ( ) ?. text_range ( ) . end ( ) ;
250
+ ( offset, false , indent)
251
251
}
252
252
} ;
253
- let comma = if needs_comma { ",\n " } else { "" } ;
254
- let trailing_new_line = if trailing_new_line { "\n " } else { "" } ;
253
+ let trailing_new_line = if !field_list. syntax ( ) . text ( ) . contains_char ( '\n' ) {
254
+ format ! ( "\n {}" , field_list. indent_level( ) )
255
+ } else {
256
+ String :: new ( )
257
+ } ;
258
+ let comma = if needs_comma { ",\n " } else { "\n " } ;
255
259
let record_field = make:: record_field ( visibility, name, suggested_type) ;
256
260
257
261
Some ( ( offset, format ! ( "{comma}{indent}{record_field}{trailing_new_line}" ) ) )
@@ -377,34 +381,43 @@ fn foo() {
377
381
fn unresolved_field_fix_on_unit ( ) {
378
382
check_fix (
379
383
r#"
384
+ mod indent {
380
385
struct Foo;
381
386
382
387
fn foo() {
383
388
Foo.bar$0;
384
389
}
390
+ }
385
391
"# ,
386
392
r#"
387
- struct Foo{ bar: () }
393
+ mod indent {
394
+ struct Foo {
395
+ bar: (),
396
+ }
388
397
389
398
fn foo() {
390
399
Foo.bar;
391
400
}
401
+ }
392
402
"# ,
393
403
) ;
394
404
}
395
405
#[ test]
396
406
fn unresolved_field_fix_on_empty ( ) {
397
407
check_fix (
398
408
r#"
409
+ mod indent {
399
410
struct Foo{
400
411
}
401
412
402
413
fn foo() {
403
414
let foo = Foo{};
404
415
foo.bar$0;
405
416
}
417
+ }
406
418
"# ,
407
419
r#"
420
+ mod indent {
408
421
struct Foo{
409
422
bar: ()
410
423
}
@@ -413,6 +426,32 @@ fn foo() {
413
426
let foo = Foo{};
414
427
foo.bar;
415
428
}
429
+ }
430
+ "# ,
431
+ ) ;
432
+
433
+ check_fix (
434
+ r#"
435
+ mod indent {
436
+ struct Foo {}
437
+
438
+ fn foo() {
439
+ let foo = Foo{};
440
+ foo.bar$0;
441
+ }
442
+ }
443
+ "# ,
444
+ r#"
445
+ mod indent {
446
+ struct Foo {
447
+ bar: ()
448
+ }
449
+
450
+ fn foo() {
451
+ let foo = Foo{};
452
+ foo.bar;
453
+ }
454
+ }
416
455
"# ,
417
456
) ;
418
457
}
0 commit comments