Add pub(crate) to functions generated in other module

This commit is contained in:
Timo Freiberg 2020-04-20 18:36:12 +02:00
parent 74780a15f6
commit f2f882bc44
2 changed files with 27 additions and 46 deletions

View file

@ -81,6 +81,7 @@ struct FunctionBuilder {
type_params: Option<ast::TypeParamList>, type_params: Option<ast::TypeParamList>,
params: ast::ParamList, params: ast::ParamList,
file: AssistFile, file: AssistFile,
needs_pub: bool,
} }
impl FunctionBuilder { impl FunctionBuilder {
@ -90,11 +91,12 @@ impl FunctionBuilder {
ctx: &AssistCtx, ctx: &AssistCtx,
call: &ast::CallExpr, call: &ast::CallExpr,
path: &ast::Path, path: &ast::Path,
generate_in: Option<hir::InFile<hir::ModuleSource>>, target_module: Option<hir::InFile<hir::ModuleSource>>,
) -> Option<Self> { ) -> Option<Self> {
let needs_pub = target_module.is_some();
let mut file = AssistFile::default(); let mut file = AssistFile::default();
let target = if let Some(generate_in_module) = generate_in { let target = if let Some(target_module) = target_module {
let (in_file, target) = next_space_for_fn_in_module(ctx.sema.db, generate_in_module)?; let (in_file, target) = next_space_for_fn_in_module(ctx.sema.db, target_module)?;
file = in_file; file = in_file;
target target
} else { } else {
@ -102,12 +104,16 @@ impl FunctionBuilder {
}; };
let fn_name = fn_name(&path)?; let fn_name = fn_name(&path)?;
let (type_params, params) = fn_args(ctx, &call)?; let (type_params, params) = fn_args(ctx, &call)?;
Some(Self { target, fn_name, type_params, params, file }) Some(Self { target, fn_name, type_params, params, file, needs_pub })
} }
fn render(self) -> Option<FunctionTemplate> { fn render(self) -> Option<FunctionTemplate> {
let placeholder_expr = ast::make::expr_todo(); let placeholder_expr = ast::make::expr_todo();
let fn_body = ast::make::block_expr(vec![], Some(placeholder_expr)); let fn_body = ast::make::block_expr(vec![], Some(placeholder_expr));
let fn_def = ast::make::fn_def(self.fn_name, self.type_params, self.params, fn_body); let mut fn_def = ast::make::fn_def(self.fn_name, self.type_params, self.params, fn_body);
if self.needs_pub {
fn_def = ast::make::add_pub_crate_modifier(fn_def);
}
let (fn_def, insert_offset) = match self.target { let (fn_def, insert_offset) = match self.target {
GeneratedFunctionTarget::BehindItem(it) => { GeneratedFunctionTarget::BehindItem(it) => {
@ -116,15 +122,14 @@ impl FunctionBuilder {
(indented, it.text_range().end()) (indented, it.text_range().end())
} }
GeneratedFunctionTarget::InEmptyItemList(it) => { GeneratedFunctionTarget::InEmptyItemList(it) => {
let with_leading_newline = ast::make::add_leading_newlines(1, fn_def); let indent_once = IndentLevel(1);
let indent = IndentLevel::from_node(it.syntax()).indented(); let indent = IndentLevel::from_node(it.syntax());
let mut indented = indent.increase_indent(with_leading_newline);
if !item_list_has_whitespace(&it) { let fn_def = ast::make::add_leading_newlines(1, fn_def);
// In this case we want to make sure there's a newline between the closing let fn_def = indent_once.increase_indent(fn_def);
// function brace and the closing module brace (so it doesn't end in `}}`). let fn_def = ast::make::add_trailing_newlines(1, fn_def);
indented = ast::make::add_trailing_newlines(1, indented); let fn_def = indent.increase_indent(fn_def);
} (fn_def, it.syntax().text_range().start() + TextUnit::from_usize(1))
(indented, it.syntax().text_range().start() + TextUnit::from_usize(1))
} }
}; };
@ -140,11 +145,6 @@ impl FunctionBuilder {
} }
} }
/// Returns true if the given ItemList contains whitespace.
fn item_list_has_whitespace(it: &ast::ItemList) -> bool {
it.syntax().descendants_with_tokens().find(|it| it.kind() == SyntaxKind::WHITESPACE).is_some()
}
enum GeneratedFunctionTarget { enum GeneratedFunctionTarget {
BehindItem(SyntaxNode), BehindItem(SyntaxNode),
InEmptyItemList(ast::ItemList), InEmptyItemList(ast::ItemList),
@ -803,29 +803,7 @@ fn foo() {
", ",
r" r"
mod bar { mod bar {
fn my_fn() { pub(crate) fn my_fn() {
<|>todo!()
}
}
fn foo() {
bar::my_fn()
}
",
);
check_assist(
add_function,
r"
mod bar {
}
fn foo() {
bar::my_fn<|>()
}
",
r"
mod bar {
fn my_fn() {
<|>todo!() <|>todo!()
} }
} }
@ -854,7 +832,7 @@ fn foo() {
mod bar { mod bar {
fn something_else() {} fn something_else() {}
fn my_fn() { pub(crate) fn my_fn() {
<|>todo!() <|>todo!()
} }
} }
@ -872,8 +850,7 @@ fn foo() {
add_function, add_function,
r" r"
mod bar { mod bar {
mod baz { mod baz {}
}
} }
fn foo() { fn foo() {
@ -883,7 +860,7 @@ fn foo() {
r" r"
mod bar { mod bar {
mod baz { mod baz {
fn my_fn() { pub(crate) fn my_fn() {
<|>todo!() <|>todo!()
} }
} }

View file

@ -303,6 +303,10 @@ pub fn add_trailing_newlines(amount_of_newlines: usize, t: impl AstNode) -> ast:
ast_from_text(&format!("{}{}", t.syntax(), newlines)) ast_from_text(&format!("{}{}", t.syntax(), newlines))
} }
pub fn add_pub_crate_modifier(fn_def: ast::FnDef) -> ast::FnDef {
ast_from_text(&format!("pub(crate) {}", fn_def))
}
fn ast_from_text<N: AstNode>(text: &str) -> N { fn ast_from_text<N: AstNode>(text: &str) -> N {
let parse = SourceFile::parse(text); let parse = SourceFile::parse(text);
let node = parse.tree().syntax().descendants().find_map(N::cast).unwrap(); let node = parse.tree().syntax().descendants().find_map(N::cast).unwrap();