Skip to content

Commit dc4e4c7

Browse files
author
Côme ALLART
committed
fix: add mod files in path in generated examples
1 parent 220137f commit dc4e4c7

File tree

1 file changed

+27
-27
lines changed

1 file changed

+27
-27
lines changed

crates/ide_assists/src/handlers/generate_documentation_template.rs

Lines changed: 27 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
use hir::ModuleDef;
12
use ide_db::assists::{AssistId, AssistKind};
23
use stdx::to_lower_snake_case;
34
use syntax::{
@@ -51,8 +52,6 @@ pub(crate) fn generate_documentation_template(
5152
let parent_syntax = ast_func.syntax();
5253
let text_range = parent_syntax.text_range();
5354
let indent_level = IndentLevel::from_node(&parent_syntax);
54-
let krate_name =
55-
ctx.sema.scope(&parent_syntax).module()?.krate().display_name(ctx.db())?.to_string();
5655

5756
acc.add(
5857
AssistId("generate_documentation_template", AssistKind::Generate),
@@ -63,7 +62,7 @@ pub(crate) fn generate_documentation_template(
6362
// Introduction / short function description before the sections
6463
doc_lines.push(introduction_builder(&ast_func));
6564
// Then come the sections
66-
if let Some(mut lines) = examples_builder(&ast_func, krate_name) {
65+
if let Some(mut lines) = examples_builder(&ast_func, ctx) {
6766
doc_lines.push("".into());
6867
doc_lines.append(&mut lines);
6968
}
@@ -94,16 +93,16 @@ fn introduction_builder(ast_func: &ast::Fn) -> String {
9493
}
9594

9695
/// Builds an `# Examples` section. An option is returned to be able to manage an error in the AST.
97-
fn examples_builder(ast_func: &ast::Fn, krate_name: String) -> Option<Vec<String>> {
96+
fn examples_builder(ast_func: &ast::Fn, ctx: &AssistContext) -> Option<Vec<String>> {
9897
let (no_panic_ex, panic_ex) = if is_in_trait_def(ast_func) {
9998
let message = "// Example template not implemented for trait functions";
10099
(Some(vec![message.into()]), Some(vec![message.into()]))
101100
} else {
102101
let panic_ex = match can_panic(ast_func) {
103-
Some(true) => gen_panic_ex_template(ast_func, krate_name.clone()),
102+
Some(true) => gen_panic_ex_template(ast_func, ctx),
104103
_ => None,
105104
};
106-
let no_panic_ex = gen_ex_template(ast_func, krate_name);
105+
let no_panic_ex = gen_ex_template(ast_func, ctx);
107106
(no_panic_ex, panic_ex)
108107
};
109108

@@ -146,8 +145,8 @@ fn safety_builder(ast_func: &ast::Fn) -> Option<Vec<String>> {
146145

147146
/// Generate an example template which should not panic
148147
/// `None` if the function has a `self` parameter but is not in an `impl`.
149-
fn gen_ex_template(ast_func: &ast::Fn, krate_name: String) -> Option<Vec<String>> {
150-
let (mut lines, ex_helper) = gen_ex_start_helper(ast_func, krate_name)?;
148+
fn gen_ex_template(ast_func: &ast::Fn, ctx: &AssistContext) -> Option<Vec<String>> {
149+
let (mut lines, ex_helper) = gen_ex_start_helper(ast_func, ctx)?;
151150
// Call the function, check result
152151
if returns_a_value(ast_func) {
153152
if count_parameters(&ex_helper.param_list) < 3 {
@@ -171,8 +170,8 @@ fn gen_ex_template(ast_func: &ast::Fn, krate_name: String) -> Option<Vec<String>
171170

172171
/// Generate an example template which should panic
173172
/// `None` if the function has a `self` parameter but is not in an `impl`.
174-
fn gen_panic_ex_template(ast_func: &ast::Fn, krate_name: String) -> Option<Vec<String>> {
175-
let (mut lines, ex_helper) = gen_ex_start_helper(ast_func, krate_name)?;
173+
fn gen_panic_ex_template(ast_func: &ast::Fn, ctx: &AssistContext) -> Option<Vec<String>> {
174+
let (mut lines, ex_helper) = gen_ex_start_helper(ast_func, ctx)?;
176175
match returns_a_value(ast_func) {
177176
true => lines.push(format!("let _ = {}; // panics", ex_helper.function_call)),
178177
false => lines.push(format!("{}; // panics", ex_helper.function_call)),
@@ -190,14 +189,14 @@ struct ExHelper {
190189

191190
/// Build the start of the example and transmit the useful intermediary results.
192191
/// `None` if the function has a `self` parameter but is not in an `impl`.
193-
fn gen_ex_start_helper(ast_func: &ast::Fn, krate_name: String) -> Option<(Vec<String>, ExHelper)> {
192+
fn gen_ex_start_helper(ast_func: &ast::Fn, ctx: &AssistContext) -> Option<(Vec<String>, ExHelper)> {
194193
let mut lines = Vec::new();
195194
let is_unsafe = ast_func.unsafe_token().is_some();
196195
let param_list = ast_func.param_list()?;
197196
let ref_mut_params = ref_mut_params(&param_list);
198197
let self_name: Option<String> = self_name(ast_func);
199198

200-
lines.push(format!("use {};", build_path(ast_func, krate_name)));
199+
lines.push(format!("use {};", build_path(ast_func, ctx)?));
201200
lines.push("".into());
202201
if let Some(self_definition) = self_definition(ast_func, self_name.as_deref()) {
203202
lines.push(self_definition);
@@ -220,6 +219,12 @@ fn is_public(ast_func: &ast::Fn) -> bool {
220219
.all(|module| has_pub(&module))
221220
}
222221

222+
/// Get the name of the current crate
223+
fn crate_name(ast_func: &ast::Fn, ctx: &AssistContext) -> Option<String> {
224+
let krate = ctx.sema.scope(&ast_func.syntax()).module()?.krate();
225+
Some(krate.display_name(ctx.db())?.to_string())
226+
}
227+
223228
/// Check if visibility is exactly `pub` (not `pub(crate)` for instance)
224229
fn has_pub<T: HasVisibility>(item: &T) -> bool {
225230
item.visibility().map(|v| v.path().is_none()).unwrap_or(false)
@@ -377,21 +382,16 @@ fn string_vec_from(string_array: &[&str]) -> Vec<String> {
377382
}
378383

379384
/// Helper function to build the path of the module in the which is the node
380-
fn build_path(ast_func: &ast::Fn, krate_name: String) -> String {
381-
let mut path: Vec<String> = ast_func
382-
.syntax()
383-
.ancestors()
384-
.filter_map(|m| ast::Module::cast(m).and_then(|m| m.name()))
385-
.map(|m| m.to_string())
386-
.collect();
387-
path.push(krate_name);
388-
path.reverse();
389-
path.push(
390-
self_partial_type(ast_func)
391-
.or_else(|| ast_func.name().map(|n| n.to_string()))
392-
.unwrap_or_else(|| "*".into()),
393-
);
394-
intersperse_string(path.into_iter(), "::")
385+
fn build_path(ast_func: &ast::Fn, ctx: &AssistContext) -> Option<String> {
386+
let crate_name = crate_name(ast_func, ctx)?;
387+
let leaf = self_partial_type(ast_func)
388+
.or_else(|| ast_func.name().map(|n| n.to_string()))
389+
.unwrap_or_else(|| "*".into());
390+
let func_module_def: ModuleDef = ctx.sema.to_def(ast_func)?.module(ctx.db()).into();
391+
match func_module_def.canonical_path(ctx.db()) {
392+
Some(path) => Some(format!("{}::{}::{}", crate_name, path, leaf)),
393+
None => Some(format!("{}::{}", crate_name, leaf)),
394+
}
395395
}
396396

397397
/// Helper function to get the return type of a function

0 commit comments

Comments
 (0)