aboutsummaryrefslogtreecommitdiff
path: root/crates/assists/src/utils.rs
diff options
context:
space:
mode:
Diffstat (limited to 'crates/assists/src/utils.rs')
-rw-r--r--crates/assists/src/utils.rs52
1 files changed, 44 insertions, 8 deletions
diff --git a/crates/assists/src/utils.rs b/crates/assists/src/utils.rs
index 5dd32aef1..8418e6e12 100644
--- a/crates/assists/src/utils.rs
+++ b/crates/assists/src/utils.rs
@@ -2,6 +2,7 @@
2 2
3use std::ops; 3use std::ops;
4 4
5use ast::TypeBoundsOwner;
5use hir::{Adt, HasSource}; 6use hir::{Adt, HasSource};
6use ide_db::{helpers::SnippetCap, RootDatabase}; 7use ide_db::{helpers::SnippetCap, RootDatabase};
7use itertools::Itertools; 8use itertools::Itertools;
@@ -367,21 +368,56 @@ pub(crate) fn find_impl_block_end(impl_def: ast::Impl, buf: &mut String) -> Opti
367// Generates the surrounding `impl Type { <code> }` including type and lifetime 368// Generates the surrounding `impl Type { <code> }` including type and lifetime
368// parameters 369// parameters
369pub(crate) fn generate_impl_text(adt: &ast::Adt, code: &str) -> String { 370pub(crate) fn generate_impl_text(adt: &ast::Adt, code: &str) -> String {
370 let type_params = adt.generic_param_list(); 371 generate_impl_text_inner(adt, None, code)
372}
373
374// Generates the surrounding `impl <trait> for Type { <code> }` including type
375// and lifetime parameters
376pub(crate) fn generate_trait_impl_text(adt: &ast::Adt, trait_text: &str, code: &str) -> String {
377 generate_impl_text_inner(adt, Some(trait_text), code)
378}
379
380fn generate_impl_text_inner(adt: &ast::Adt, trait_text: Option<&str>, code: &str) -> String {
381 let generic_params = adt.generic_param_list();
371 let mut buf = String::with_capacity(code.len()); 382 let mut buf = String::with_capacity(code.len());
372 buf.push_str("\n\nimpl"); 383 buf.push_str("\n\n");
373 if let Some(type_params) = &type_params { 384 adt.attrs()
374 format_to!(buf, "{}", type_params.syntax()); 385 .filter(|attr| attr.as_simple_call().map(|(name, _arg)| name == "cfg").unwrap_or(false))
386 .for_each(|attr| buf.push_str(format!("{}\n", attr.to_string()).as_str()));
387 buf.push_str("impl");
388 if let Some(generic_params) = &generic_params {
389 let lifetimes = generic_params.lifetime_params().map(|lt| format!("{}", lt.syntax()));
390 let type_params = generic_params.type_params().map(|type_param| {
391 let mut buf = String::new();
392 if let Some(it) = type_param.name() {
393 format_to!(buf, "{}", it.syntax());
394 }
395 if let Some(it) = type_param.colon_token() {
396 format_to!(buf, "{} ", it);
397 }
398 if let Some(it) = type_param.type_bound_list() {
399 format_to!(buf, "{}", it.syntax());
400 }
401 buf
402 });
403 let generics = lifetimes.chain(type_params).format(", ");
404 format_to!(buf, "<{}>", generics);
375 } 405 }
376 buf.push(' '); 406 buf.push(' ');
407 if let Some(trait_text) = trait_text {
408 buf.push_str(trait_text);
409 buf.push_str(" for ");
410 }
377 buf.push_str(adt.name().unwrap().text()); 411 buf.push_str(adt.name().unwrap().text());
378 if let Some(type_params) = type_params { 412 if let Some(generic_params) = generic_params {
379 let lifetime_params = type_params 413 let lifetime_params = generic_params
380 .lifetime_params() 414 .lifetime_params()
381 .filter_map(|it| it.lifetime()) 415 .filter_map(|it| it.lifetime())
382 .map(|it| SmolStr::from(it.text())); 416 .map(|it| SmolStr::from(it.text()));
383 let type_params = 417 let type_params = generic_params
384 type_params.type_params().filter_map(|it| it.name()).map(|it| SmolStr::from(it.text())); 418 .type_params()
419 .filter_map(|it| it.name())
420 .map(|it| SmolStr::from(it.text()));
385 format_to!(buf, "<{}>", lifetime_params.chain(type_params).format(", ")) 421 format_to!(buf, "<{}>", lifetime_params.chain(type_params).format(", "))
386 } 422 }
387 423