diff options
Diffstat (limited to 'crates/ra_assists/src/handlers')
-rw-r--r-- | crates/ra_assists/src/handlers/add_missing_impl_members.rs | 194 |
1 files changed, 116 insertions, 78 deletions
diff --git a/crates/ra_assists/src/handlers/add_missing_impl_members.rs b/crates/ra_assists/src/handlers/add_missing_impl_members.rs index 2d6d44980..e466c9a86 100644 --- a/crates/ra_assists/src/handlers/add_missing_impl_members.rs +++ b/crates/ra_assists/src/handlers/add_missing_impl_members.rs | |||
@@ -1,6 +1,10 @@ | |||
1 | use hir::HasSource; | 1 | use hir::HasSource; |
2 | use ra_syntax::{ | 2 | use ra_syntax::{ |
3 | ast::{self, edit, make, AstNode, NameOwner}, | 3 | ast::{ |
4 | self, | ||
5 | edit::{self, IndentLevel}, | ||
6 | make, AstNode, NameOwner, | ||
7 | }, | ||
4 | SmolStr, | 8 | SmolStr, |
5 | }; | 9 | }; |
6 | 10 | ||
@@ -40,7 +44,9 @@ enum AddMissingImplMembersMode { | |||
40 | // } | 44 | // } |
41 | // | 45 | // |
42 | // impl Trait<u32> for () { | 46 | // impl Trait<u32> for () { |
43 | // fn foo(&self) -> u32 { todo!() } | 47 | // fn foo(&self) -> u32 { |
48 | // todo!() | ||
49 | // } | ||
44 | // | 50 | // |
45 | // } | 51 | // } |
46 | // ``` | 52 | // ``` |
@@ -165,7 +171,9 @@ fn add_missing_impl_members_inner( | |||
165 | 171 | ||
166 | fn add_body(fn_def: ast::FnDef) -> ast::FnDef { | 172 | fn add_body(fn_def: ast::FnDef) -> ast::FnDef { |
167 | if fn_def.body().is_none() { | 173 | if fn_def.body().is_none() { |
168 | fn_def.with_body(make::block_from_expr(make::expr_todo())) | 174 | let body = make::block_expr(None, Some(make::expr_todo())); |
175 | let body = IndentLevel(1).increase_indent(body); | ||
176 | fn_def.with_body(body) | ||
169 | } else { | 177 | } else { |
170 | fn_def | 178 | fn_def |
171 | } | 179 | } |
@@ -181,7 +189,7 @@ mod tests { | |||
181 | fn test_add_missing_impl_members() { | 189 | fn test_add_missing_impl_members() { |
182 | check_assist( | 190 | check_assist( |
183 | add_missing_impl_members, | 191 | add_missing_impl_members, |
184 | " | 192 | r#" |
185 | trait Foo { | 193 | trait Foo { |
186 | type Output; | 194 | type Output; |
187 | 195 | ||
@@ -197,8 +205,8 @@ struct S; | |||
197 | impl Foo for S { | 205 | impl Foo for S { |
198 | fn bar(&self) {} | 206 | fn bar(&self) {} |
199 | <|> | 207 | <|> |
200 | }", | 208 | }"#, |
201 | " | 209 | r#" |
202 | trait Foo { | 210 | trait Foo { |
203 | type Output; | 211 | type Output; |
204 | 212 | ||
@@ -215,10 +223,14 @@ impl Foo for S { | |||
215 | fn bar(&self) {} | 223 | fn bar(&self) {} |
216 | <|>type Output; | 224 | <|>type Output; |
217 | const CONST: usize = 42; | 225 | const CONST: usize = 42; |
218 | fn foo(&self) { todo!() } | 226 | fn foo(&self) { |
219 | fn baz(&self) { todo!() } | 227 | todo!() |
228 | } | ||
229 | fn baz(&self) { | ||
230 | todo!() | ||
231 | } | ||
220 | 232 | ||
221 | }", | 233 | }"#, |
222 | ); | 234 | ); |
223 | } | 235 | } |
224 | 236 | ||
@@ -226,7 +238,7 @@ impl Foo for S { | |||
226 | fn test_copied_overriden_members() { | 238 | fn test_copied_overriden_members() { |
227 | check_assist( | 239 | check_assist( |
228 | add_missing_impl_members, | 240 | add_missing_impl_members, |
229 | " | 241 | r#" |
230 | trait Foo { | 242 | trait Foo { |
231 | fn foo(&self); | 243 | fn foo(&self); |
232 | fn bar(&self) -> bool { true } | 244 | fn bar(&self) -> bool { true } |
@@ -238,8 +250,8 @@ struct S; | |||
238 | impl Foo for S { | 250 | impl Foo for S { |
239 | fn bar(&self) {} | 251 | fn bar(&self) {} |
240 | <|> | 252 | <|> |
241 | }", | 253 | }"#, |
242 | " | 254 | r#" |
243 | trait Foo { | 255 | trait Foo { |
244 | fn foo(&self); | 256 | fn foo(&self); |
245 | fn bar(&self) -> bool { true } | 257 | fn bar(&self) -> bool { true } |
@@ -250,9 +262,11 @@ struct S; | |||
250 | 262 | ||
251 | impl Foo for S { | 263 | impl Foo for S { |
252 | fn bar(&self) {} | 264 | fn bar(&self) {} |
253 | <|>fn foo(&self) { todo!() } | 265 | <|>fn foo(&self) { |
266 | todo!() | ||
267 | } | ||
254 | 268 | ||
255 | }", | 269 | }"#, |
256 | ); | 270 | ); |
257 | } | 271 | } |
258 | 272 | ||
@@ -260,16 +274,18 @@ impl Foo for S { | |||
260 | fn test_empty_impl_def() { | 274 | fn test_empty_impl_def() { |
261 | check_assist( | 275 | check_assist( |
262 | add_missing_impl_members, | 276 | add_missing_impl_members, |
263 | " | 277 | r#" |
264 | trait Foo { fn foo(&self); } | 278 | trait Foo { fn foo(&self); } |
265 | struct S; | 279 | struct S; |
266 | impl Foo for S { <|> }", | 280 | impl Foo for S { <|> }"#, |
267 | " | 281 | r#" |
268 | trait Foo { fn foo(&self); } | 282 | trait Foo { fn foo(&self); } |
269 | struct S; | 283 | struct S; |
270 | impl Foo for S { | 284 | impl Foo for S { |
271 | <|>fn foo(&self) { todo!() } | 285 | <|>fn foo(&self) { |
272 | }", | 286 | todo!() |
287 | } | ||
288 | }"#, | ||
273 | ); | 289 | ); |
274 | } | 290 | } |
275 | 291 | ||
@@ -277,16 +293,18 @@ impl Foo for S { | |||
277 | fn fill_in_type_params_1() { | 293 | fn fill_in_type_params_1() { |
278 | check_assist( | 294 | check_assist( |
279 | add_missing_impl_members, | 295 | add_missing_impl_members, |
280 | " | 296 | r#" |
281 | trait Foo<T> { fn foo(&self, t: T) -> &T; } | 297 | trait Foo<T> { fn foo(&self, t: T) -> &T; } |
282 | struct S; | 298 | struct S; |
283 | impl Foo<u32> for S { <|> }", | 299 | impl Foo<u32> for S { <|> }"#, |
284 | " | 300 | r#" |
285 | trait Foo<T> { fn foo(&self, t: T) -> &T; } | 301 | trait Foo<T> { fn foo(&self, t: T) -> &T; } |
286 | struct S; | 302 | struct S; |
287 | impl Foo<u32> for S { | 303 | impl Foo<u32> for S { |
288 | <|>fn foo(&self, t: u32) -> &u32 { todo!() } | 304 | <|>fn foo(&self, t: u32) -> &u32 { |
289 | }", | 305 | todo!() |
306 | } | ||
307 | }"#, | ||
290 | ); | 308 | ); |
291 | } | 309 | } |
292 | 310 | ||
@@ -294,16 +312,18 @@ impl Foo<u32> for S { | |||
294 | fn fill_in_type_params_2() { | 312 | fn fill_in_type_params_2() { |
295 | check_assist( | 313 | check_assist( |
296 | add_missing_impl_members, | 314 | add_missing_impl_members, |
297 | " | 315 | r#" |
298 | trait Foo<T> { fn foo(&self, t: T) -> &T; } | 316 | trait Foo<T> { fn foo(&self, t: T) -> &T; } |
299 | struct S; | 317 | struct S; |
300 | impl<U> Foo<U> for S { <|> }", | 318 | impl<U> Foo<U> for S { <|> }"#, |
301 | " | 319 | r#" |
302 | trait Foo<T> { fn foo(&self, t: T) -> &T; } | 320 | trait Foo<T> { fn foo(&self, t: T) -> &T; } |
303 | struct S; | 321 | struct S; |
304 | impl<U> Foo<U> for S { | 322 | impl<U> Foo<U> for S { |
305 | <|>fn foo(&self, t: U) -> &U { todo!() } | 323 | <|>fn foo(&self, t: U) -> &U { |
306 | }", | 324 | todo!() |
325 | } | ||
326 | }"#, | ||
307 | ); | 327 | ); |
308 | } | 328 | } |
309 | 329 | ||
@@ -311,16 +331,18 @@ impl<U> Foo<U> for S { | |||
311 | fn test_cursor_after_empty_impl_def() { | 331 | fn test_cursor_after_empty_impl_def() { |
312 | check_assist( | 332 | check_assist( |
313 | add_missing_impl_members, | 333 | add_missing_impl_members, |
314 | " | 334 | r#" |
315 | trait Foo { fn foo(&self); } | 335 | trait Foo { fn foo(&self); } |
316 | struct S; | 336 | struct S; |
317 | impl Foo for S {}<|>", | 337 | impl Foo for S {}<|>"#, |
318 | " | 338 | r#" |
319 | trait Foo { fn foo(&self); } | 339 | trait Foo { fn foo(&self); } |
320 | struct S; | 340 | struct S; |
321 | impl Foo for S { | 341 | impl Foo for S { |
322 | <|>fn foo(&self) { todo!() } | 342 | <|>fn foo(&self) { |
323 | }", | 343 | todo!() |
344 | } | ||
345 | }"#, | ||
324 | ) | 346 | ) |
325 | } | 347 | } |
326 | 348 | ||
@@ -328,22 +350,24 @@ impl Foo for S { | |||
328 | fn test_qualify_path_1() { | 350 | fn test_qualify_path_1() { |
329 | check_assist( | 351 | check_assist( |
330 | add_missing_impl_members, | 352 | add_missing_impl_members, |
331 | " | 353 | r#" |
332 | mod foo { | 354 | mod foo { |
333 | pub struct Bar; | 355 | pub struct Bar; |
334 | trait Foo { fn foo(&self, bar: Bar); } | 356 | trait Foo { fn foo(&self, bar: Bar); } |
335 | } | 357 | } |
336 | struct S; | 358 | struct S; |
337 | impl foo::Foo for S { <|> }", | 359 | impl foo::Foo for S { <|> }"#, |
338 | " | 360 | r#" |
339 | mod foo { | 361 | mod foo { |
340 | pub struct Bar; | 362 | pub struct Bar; |
341 | trait Foo { fn foo(&self, bar: Bar); } | 363 | trait Foo { fn foo(&self, bar: Bar); } |
342 | } | 364 | } |
343 | struct S; | 365 | struct S; |
344 | impl foo::Foo for S { | 366 | impl foo::Foo for S { |
345 | <|>fn foo(&self, bar: foo::Bar) { todo!() } | 367 | <|>fn foo(&self, bar: foo::Bar) { |
346 | }", | 368 | todo!() |
369 | } | ||
370 | }"#, | ||
347 | ); | 371 | ); |
348 | } | 372 | } |
349 | 373 | ||
@@ -351,22 +375,24 @@ impl foo::Foo for S { | |||
351 | fn test_qualify_path_generic() { | 375 | fn test_qualify_path_generic() { |
352 | check_assist( | 376 | check_assist( |
353 | add_missing_impl_members, | 377 | add_missing_impl_members, |
354 | " | 378 | r#" |
355 | mod foo { | 379 | mod foo { |
356 | pub struct Bar<T>; | 380 | pub struct Bar<T>; |
357 | trait Foo { fn foo(&self, bar: Bar<u32>); } | 381 | trait Foo { fn foo(&self, bar: Bar<u32>); } |
358 | } | 382 | } |
359 | struct S; | 383 | struct S; |
360 | impl foo::Foo for S { <|> }", | 384 | impl foo::Foo for S { <|> }"#, |
361 | " | 385 | r#" |
362 | mod foo { | 386 | mod foo { |
363 | pub struct Bar<T>; | 387 | pub struct Bar<T>; |
364 | trait Foo { fn foo(&self, bar: Bar<u32>); } | 388 | trait Foo { fn foo(&self, bar: Bar<u32>); } |
365 | } | 389 | } |
366 | struct S; | 390 | struct S; |
367 | impl foo::Foo for S { | 391 | impl foo::Foo for S { |
368 | <|>fn foo(&self, bar: foo::Bar<u32>) { todo!() } | 392 | <|>fn foo(&self, bar: foo::Bar<u32>) { |
369 | }", | 393 | todo!() |
394 | } | ||
395 | }"#, | ||
370 | ); | 396 | ); |
371 | } | 397 | } |
372 | 398 | ||
@@ -374,22 +400,24 @@ impl foo::Foo for S { | |||
374 | fn test_qualify_path_and_substitute_param() { | 400 | fn test_qualify_path_and_substitute_param() { |
375 | check_assist( | 401 | check_assist( |
376 | add_missing_impl_members, | 402 | add_missing_impl_members, |
377 | " | 403 | r#" |
378 | mod foo { | 404 | mod foo { |
379 | pub struct Bar<T>; | 405 | pub struct Bar<T>; |
380 | trait Foo<T> { fn foo(&self, bar: Bar<T>); } | 406 | trait Foo<T> { fn foo(&self, bar: Bar<T>); } |
381 | } | 407 | } |
382 | struct S; | 408 | struct S; |
383 | impl foo::Foo<u32> for S { <|> }", | 409 | impl foo::Foo<u32> for S { <|> }"#, |
384 | " | 410 | r#" |
385 | mod foo { | 411 | mod foo { |
386 | pub struct Bar<T>; | 412 | pub struct Bar<T>; |
387 | trait Foo<T> { fn foo(&self, bar: Bar<T>); } | 413 | trait Foo<T> { fn foo(&self, bar: Bar<T>); } |
388 | } | 414 | } |
389 | struct S; | 415 | struct S; |
390 | impl foo::Foo<u32> for S { | 416 | impl foo::Foo<u32> for S { |
391 | <|>fn foo(&self, bar: foo::Bar<u32>) { todo!() } | 417 | <|>fn foo(&self, bar: foo::Bar<u32>) { |
392 | }", | 418 | todo!() |
419 | } | ||
420 | }"#, | ||
393 | ); | 421 | ); |
394 | } | 422 | } |
395 | 423 | ||
@@ -398,15 +426,15 @@ impl foo::Foo<u32> for S { | |||
398 | // when substituting params, the substituted param should not be qualified! | 426 | // when substituting params, the substituted param should not be qualified! |
399 | check_assist( | 427 | check_assist( |
400 | add_missing_impl_members, | 428 | add_missing_impl_members, |
401 | " | 429 | r#" |
402 | mod foo { | 430 | mod foo { |
403 | trait Foo<T> { fn foo(&self, bar: T); } | 431 | trait Foo<T> { fn foo(&self, bar: T); } |
404 | pub struct Param; | 432 | pub struct Param; |
405 | } | 433 | } |
406 | struct Param; | 434 | struct Param; |
407 | struct S; | 435 | struct S; |
408 | impl foo::Foo<Param> for S { <|> }", | 436 | impl foo::Foo<Param> for S { <|> }"#, |
409 | " | 437 | r#" |
410 | mod foo { | 438 | mod foo { |
411 | trait Foo<T> { fn foo(&self, bar: T); } | 439 | trait Foo<T> { fn foo(&self, bar: T); } |
412 | pub struct Param; | 440 | pub struct Param; |
@@ -414,8 +442,10 @@ mod foo { | |||
414 | struct Param; | 442 | struct Param; |
415 | struct S; | 443 | struct S; |
416 | impl foo::Foo<Param> for S { | 444 | impl foo::Foo<Param> for S { |
417 | <|>fn foo(&self, bar: Param) { todo!() } | 445 | <|>fn foo(&self, bar: Param) { |
418 | }", | 446 | todo!() |
447 | } | ||
448 | }"#, | ||
419 | ); | 449 | ); |
420 | } | 450 | } |
421 | 451 | ||
@@ -423,15 +453,15 @@ impl foo::Foo<Param> for S { | |||
423 | fn test_qualify_path_associated_item() { | 453 | fn test_qualify_path_associated_item() { |
424 | check_assist( | 454 | check_assist( |
425 | add_missing_impl_members, | 455 | add_missing_impl_members, |
426 | " | 456 | r#" |
427 | mod foo { | 457 | mod foo { |
428 | pub struct Bar<T>; | 458 | pub struct Bar<T>; |
429 | impl Bar<T> { type Assoc = u32; } | 459 | impl Bar<T> { type Assoc = u32; } |
430 | trait Foo { fn foo(&self, bar: Bar<u32>::Assoc); } | 460 | trait Foo { fn foo(&self, bar: Bar<u32>::Assoc); } |
431 | } | 461 | } |
432 | struct S; | 462 | struct S; |
433 | impl foo::Foo for S { <|> }", | 463 | impl foo::Foo for S { <|> }"#, |
434 | " | 464 | r#" |
435 | mod foo { | 465 | mod foo { |
436 | pub struct Bar<T>; | 466 | pub struct Bar<T>; |
437 | impl Bar<T> { type Assoc = u32; } | 467 | impl Bar<T> { type Assoc = u32; } |
@@ -439,8 +469,10 @@ mod foo { | |||
439 | } | 469 | } |
440 | struct S; | 470 | struct S; |
441 | impl foo::Foo for S { | 471 | impl foo::Foo for S { |
442 | <|>fn foo(&self, bar: foo::Bar<u32>::Assoc) { todo!() } | 472 | <|>fn foo(&self, bar: foo::Bar<u32>::Assoc) { |
443 | }", | 473 | todo!() |
474 | } | ||
475 | }"#, | ||
444 | ); | 476 | ); |
445 | } | 477 | } |
446 | 478 | ||
@@ -448,15 +480,15 @@ impl foo::Foo for S { | |||
448 | fn test_qualify_path_nested() { | 480 | fn test_qualify_path_nested() { |
449 | check_assist( | 481 | check_assist( |
450 | add_missing_impl_members, | 482 | add_missing_impl_members, |
451 | " | 483 | r#" |
452 | mod foo { | 484 | mod foo { |
453 | pub struct Bar<T>; | 485 | pub struct Bar<T>; |
454 | pub struct Baz; | 486 | pub struct Baz; |
455 | trait Foo { fn foo(&self, bar: Bar<Baz>); } | 487 | trait Foo { fn foo(&self, bar: Bar<Baz>); } |
456 | } | 488 | } |
457 | struct S; | 489 | struct S; |
458 | impl foo::Foo for S { <|> }", | 490 | impl foo::Foo for S { <|> }"#, |
459 | " | 491 | r#" |
460 | mod foo { | 492 | mod foo { |
461 | pub struct Bar<T>; | 493 | pub struct Bar<T>; |
462 | pub struct Baz; | 494 | pub struct Baz; |
@@ -464,8 +496,10 @@ mod foo { | |||
464 | } | 496 | } |
465 | struct S; | 497 | struct S; |
466 | impl foo::Foo for S { | 498 | impl foo::Foo for S { |
467 | <|>fn foo(&self, bar: foo::Bar<foo::Baz>) { todo!() } | 499 | <|>fn foo(&self, bar: foo::Bar<foo::Baz>) { |
468 | }", | 500 | todo!() |
501 | } | ||
502 | }"#, | ||
469 | ); | 503 | ); |
470 | } | 504 | } |
471 | 505 | ||
@@ -473,22 +507,24 @@ impl foo::Foo for S { | |||
473 | fn test_qualify_path_fn_trait_notation() { | 507 | fn test_qualify_path_fn_trait_notation() { |
474 | check_assist( | 508 | check_assist( |
475 | add_missing_impl_members, | 509 | add_missing_impl_members, |
476 | " | 510 | r#" |
477 | mod foo { | 511 | mod foo { |
478 | pub trait Fn<Args> { type Output; } | 512 | pub trait Fn<Args> { type Output; } |
479 | trait Foo { fn foo(&self, bar: dyn Fn(u32) -> i32); } | 513 | trait Foo { fn foo(&self, bar: dyn Fn(u32) -> i32); } |
480 | } | 514 | } |
481 | struct S; | 515 | struct S; |
482 | impl foo::Foo for S { <|> }", | 516 | impl foo::Foo for S { <|> }"#, |
483 | " | 517 | r#" |
484 | mod foo { | 518 | mod foo { |
485 | pub trait Fn<Args> { type Output; } | 519 | pub trait Fn<Args> { type Output; } |
486 | trait Foo { fn foo(&self, bar: dyn Fn(u32) -> i32); } | 520 | trait Foo { fn foo(&self, bar: dyn Fn(u32) -> i32); } |
487 | } | 521 | } |
488 | struct S; | 522 | struct S; |
489 | impl foo::Foo for S { | 523 | impl foo::Foo for S { |
490 | <|>fn foo(&self, bar: dyn Fn(u32) -> i32) { todo!() } | 524 | <|>fn foo(&self, bar: dyn Fn(u32) -> i32) { |
491 | }", | 525 | todo!() |
526 | } | ||
527 | }"#, | ||
492 | ); | 528 | ); |
493 | } | 529 | } |
494 | 530 | ||
@@ -496,10 +532,10 @@ impl foo::Foo for S { | |||
496 | fn test_empty_trait() { | 532 | fn test_empty_trait() { |
497 | check_assist_not_applicable( | 533 | check_assist_not_applicable( |
498 | add_missing_impl_members, | 534 | add_missing_impl_members, |
499 | " | 535 | r#" |
500 | trait Foo; | 536 | trait Foo; |
501 | struct S; | 537 | struct S; |
502 | impl Foo for S { <|> }", | 538 | impl Foo for S { <|> }"#, |
503 | ) | 539 | ) |
504 | } | 540 | } |
505 | 541 | ||
@@ -507,13 +543,13 @@ impl Foo for S { <|> }", | |||
507 | fn test_ignore_unnamed_trait_members_and_default_methods() { | 543 | fn test_ignore_unnamed_trait_members_and_default_methods() { |
508 | check_assist_not_applicable( | 544 | check_assist_not_applicable( |
509 | add_missing_impl_members, | 545 | add_missing_impl_members, |
510 | " | 546 | r#" |
511 | trait Foo { | 547 | trait Foo { |
512 | fn (arg: u32); | 548 | fn (arg: u32); |
513 | fn valid(some: u32) -> bool { false } | 549 | fn valid(some: u32) -> bool { false } |
514 | } | 550 | } |
515 | struct S; | 551 | struct S; |
516 | impl Foo for S { <|> }", | 552 | impl Foo for S { <|> }"#, |
517 | ) | 553 | ) |
518 | } | 554 | } |
519 | 555 | ||
@@ -544,7 +580,9 @@ trait Foo { | |||
544 | struct S; | 580 | struct S; |
545 | impl Foo for S { | 581 | impl Foo for S { |
546 | <|>type Output; | 582 | <|>type Output; |
547 | fn foo(&self) { todo!() } | 583 | fn foo(&self) { |
584 | todo!() | ||
585 | } | ||
548 | }"#, | 586 | }"#, |
549 | ) | 587 | ) |
550 | } | 588 | } |
@@ -553,7 +591,7 @@ impl Foo for S { | |||
553 | fn test_default_methods() { | 591 | fn test_default_methods() { |
554 | check_assist( | 592 | check_assist( |
555 | add_missing_default_members, | 593 | add_missing_default_members, |
556 | " | 594 | r#" |
557 | trait Foo { | 595 | trait Foo { |
558 | type Output; | 596 | type Output; |
559 | 597 | ||
@@ -563,8 +601,8 @@ trait Foo { | |||
563 | fn foo(some: u32) -> bool; | 601 | fn foo(some: u32) -> bool; |
564 | } | 602 | } |
565 | struct S; | 603 | struct S; |
566 | impl Foo for S { <|> }", | 604 | impl Foo for S { <|> }"#, |
567 | " | 605 | r#" |
568 | trait Foo { | 606 | trait Foo { |
569 | type Output; | 607 | type Output; |
570 | 608 | ||
@@ -576,7 +614,7 @@ trait Foo { | |||
576 | struct S; | 614 | struct S; |
577 | impl Foo for S { | 615 | impl Foo for S { |
578 | <|>fn valid(some: u32) -> bool { false } | 616 | <|>fn valid(some: u32) -> bool { false } |
579 | }", | 617 | }"#, |
580 | ) | 618 | ) |
581 | } | 619 | } |
582 | } | 620 | } |