sway_lsp/capabilities/code_actions/common/
generate_impl.rsuse sway_core::{
transform::{AttributeKind, AttributesMap},
TypeParameter,
};
use sway_types::Spanned;
use crate::capabilities::code_actions::CodeAction;
pub(crate) const CONTRACT: &str = "Contract";
pub(crate) const TAB: &str = " ";
pub(crate) trait GenerateImplCodeAction<'a, T: Spanned>: CodeAction<'a, T> {
fn decl_name(&self) -> String;
fn type_param_string(&self, type_params: &[TypeParameter]) -> Option<String> {
if type_params.is_empty() {
None
} else {
Some(
type_params
.iter()
.map(|param| param.name.to_string())
.collect::<Vec<_>>()
.join(", "),
)
}
}
fn impl_string(
&self,
type_params: Option<String>,
body: String,
for_name: Option<String>,
) -> String {
let for_string = match for_name {
Some(name) => format!(" for {name}"),
None => String::new(),
};
let type_param_string = match type_params {
Some(params) => format!("<{params}>"),
None => String::new(),
};
format!(
"\nimpl{} {}{}{} {{{}}}\n",
type_param_string,
self.decl_name(),
type_param_string,
for_string,
body
)
}
fn attribute_string(&self, attr_map: &AttributesMap, include_comments: bool) -> String {
let attr_string = attr_map
.iter()
.map(|(kind, attrs)| {
attrs
.iter()
.filter_map(|attr| match kind {
AttributeKind::DocComment { .. } => {
if include_comments {
return Some(format!("{}{}", TAB, attr.span.as_str()));
}
None
}
_ => Some(format!("{}{}", TAB, attr.span.as_str())),
})
.collect::<Vec<String>>()
.join("\n")
})
.collect::<Vec<String>>()
.join("\n");
let attribute_padding = if attr_string.len() > 1 { "\n" } else { "" };
format!("{attr_string}{attribute_padding}")
}
fn fn_signature_string(
&self,
fn_name: String,
params_string: String,
attr_map: &AttributesMap,
return_type_string: String,
body: Option<String>,
) -> String {
let attribute_string = self.attribute_string(attr_map, false);
let body_string = match body {
Some(body) => format!(" {body} "),
None => String::new(),
};
format!(
"{attribute_string}{TAB}fn {fn_name}({params_string}){return_type_string} {{{body_string}}}",
)
}
}