From b88ba007cc2631799c2334753a7de807c548685e Mon Sep 17 00:00:00 2001 From: Jeremy Kolb Date: Tue, 29 Jan 2019 21:39:09 -0500 Subject: Pass Documentation up to LSP and add "rust" to our codeblocks there --- crates/ra_ide_api/src/call_info.rs | 66 ++++++---------------- crates/ra_ide_api/src/completion.rs | 19 +++++++ .../ra_ide_api/src/completion/completion_item.rs | 35 ++++-------- crates/ra_ide_api/src/lib.rs | 3 +- 4 files changed, 49 insertions(+), 74 deletions(-) (limited to 'crates/ra_ide_api/src') diff --git a/crates/ra_ide_api/src/call_info.rs b/crates/ra_ide_api/src/call_info.rs index ee1e13799..2eb388e0e 100644 --- a/crates/ra_ide_api/src/call_info.rs +++ b/crates/ra_ide_api/src/call_info.rs @@ -3,9 +3,10 @@ use ra_db::SourceDatabase; use ra_syntax::{ AstNode, SyntaxNode, TextUnit, TextRange, SyntaxKind::FN_DEF, - ast::{self, ArgListOwner, DocCommentsOwner}, + ast::{self, ArgListOwner}, algo::find_node_at_offset, }; +use hir::Docs; use crate::{FilePosition, CallInfo, db::RootDatabase}; @@ -26,7 +27,9 @@ pub(crate) fn call_info(db: &RootDatabase, position: FilePosition) -> Option FnCallNode<'a> { } impl CallInfo { - fn new(node: &ast::FnDef) -> Option { - let label: String = if let Some(body) = node.body() { - let body_range = body.syntax().range(); - let label: String = node - .syntax() - .children() - .filter(|child| !child.range().is_subrange(&body_range)) // Filter out body - .filter(|child| ast::Comment::cast(child).is_none()) // Filter out doc comments - .map(|node| node.text().to_string()) - .collect(); - label - } else { - node.syntax().text().to_string() - }; - - let mut doc = None; - if let Some(docs) = node.doc_comment_text() { - // Massage markdown - let mut processed_lines = Vec::new(); - let mut in_code_block = false; - for line in docs.lines() { - if line.starts_with("```") { - in_code_block = !in_code_block; - } - - let line = if in_code_block && line.starts_with("```") && !line.contains("rust") { - "```rust".into() - } else { - line.to_string() - }; - - processed_lines.push(line); - } - - doc = Some(processed_lines.join("\n")); - } + fn new(db: &RootDatabase, function: hir::Function, node: &ast::FnDef) -> Option { + let label = crate::completion::function_label(node)?; + let doc = function.docs(db); Some(CallInfo { parameters: param_list(node), - label: label.trim().to_owned(), + label, doc, active_parameter: None, }) @@ -284,7 +254,7 @@ fn bar() { assert_eq!(info.parameters, vec!["j".to_string()]); assert_eq!(info.active_parameter, Some(0)); assert_eq!(info.label, "fn foo(j: u32) -> u32".to_string()); - assert_eq!(info.doc, Some("test".into())); + assert_eq!(info.doc.map(|it| it.into()), Some("test".to_string())); } #[test] @@ -313,18 +283,18 @@ pub fn do() { assert_eq!(info.active_parameter, Some(0)); assert_eq!(info.label, "pub fn add_one(x: i32) -> i32".to_string()); assert_eq!( - info.doc, + info.doc.map(|it| it.into()), Some( r#"Adds one to the number given. # Examples -```rust +``` let five = 5; assert_eq!(6, my_crate::add_one(5)); ```"# - .into() + .to_string() ) ); } @@ -359,18 +329,18 @@ pub fn do_it() { assert_eq!(info.active_parameter, Some(0)); assert_eq!(info.label, "pub fn add_one(x: i32) -> i32".to_string()); assert_eq!( - info.doc, + info.doc.map(|it| it.into()), Some( r#"Adds one to the number given. # Examples -```rust +``` let five = 5; assert_eq!(6, my_crate::add_one(5)); ```"# - .into() + .to_string() ) ); } @@ -414,12 +384,12 @@ pub fn foo() { ); assert_eq!(info.active_parameter, Some(1)); assert_eq!( - info.doc, + info.doc.map(|it| it.into()), Some( r#"Method is called when writer finishes. By default this method stops actor's `Context`."# - .into() + .to_string() ) ); } diff --git a/crates/ra_ide_api/src/completion.rs b/crates/ra_ide_api/src/completion.rs index b1867de42..722d94f3a 100644 --- a/crates/ra_ide_api/src/completion.rs +++ b/crates/ra_ide_api/src/completion.rs @@ -10,6 +10,7 @@ mod complete_scope; mod complete_postfix; use ra_db::SourceDatabase; +use ra_syntax::ast::{self, AstNode}; use crate::{ db, @@ -61,3 +62,21 @@ pub(crate) fn completions(db: &db::RootDatabase, position: FilePosition) -> Opti complete_postfix::complete_postfix(&mut acc, &ctx); Some(acc) } + +pub fn function_label(node: &ast::FnDef) -> Option { + let label: String = if let Some(body) = node.body() { + let body_range = body.syntax().range(); + let label: String = node + .syntax() + .children() + .filter(|child| !child.range().is_subrange(&body_range)) // Filter out body + .filter(|child| ast::Comment::cast(child).is_none()) // Filter out comments + .map(|node| node.text().to_string()) + .collect(); + label + } else { + node.syntax().text().to_string() + }; + + Some(label.trim().to_owned()) +} diff --git a/crates/ra_ide_api/src/completion/completion_item.rs b/crates/ra_ide_api/src/completion/completion_item.rs index 49bd636a5..d3bc14894 100644 --- a/crates/ra_ide_api/src/completion/completion_item.rs +++ b/crates/ra_ide_api/src/completion/completion_item.rs @@ -1,12 +1,12 @@ use hir::{Docs, Documentation}; -use ra_syntax::{ - ast::{self, AstNode}, - TextRange, -}; +use ra_syntax::TextRange; use ra_text_edit::TextEdit; use test_utils::tested_by; -use crate::completion::completion_context::CompletionContext; +use crate::completion::{ + completion_context::CompletionContext, + function_label, +}; /// `CompletionItem` describes a single completion variant in the editor pop-up. /// It is basically a POD with various properties. To construct a @@ -97,8 +97,8 @@ impl CompletionItem { self.detail.as_ref().map(|it| it.as_str()) } /// A doc-comment - pub fn documentation(&self) -> Option<&str> { - self.documentation.as_ref().map(|it| it.contents()) + pub fn documentation(&self) -> Option { + self.documentation.clone() } /// What string is used for filtering. pub fn lookup(&self) -> &str { @@ -252,7 +252,7 @@ impl Builder { self.documentation = Some(docs); } - if let Some(label) = function_label(ctx, function) { + if let Some(label) = function_item_label(ctx, function) { self.detail = Some(label); } @@ -292,24 +292,9 @@ impl Into> for Completions { } } -fn function_label(ctx: &CompletionContext, function: hir::Function) -> Option { +fn function_item_label(ctx: &CompletionContext, function: hir::Function) -> Option { let node = function.source(ctx.db).1; - - let label: String = if let Some(body) = node.body() { - let body_range = body.syntax().range(); - let label: String = node - .syntax() - .children() - .filter(|child| !child.range().is_subrange(&body_range)) // Filter out body - .filter(|child| ast::Comment::cast(child).is_none()) // Filter out comments - .map(|node| node.text().to_string()) - .collect(); - label - } else { - node.syntax().text().to_string() - }; - - Some(label.trim().to_owned()) + function_label(&node) } #[cfg(test)] diff --git a/crates/ra_ide_api/src/lib.rs b/crates/ra_ide_api/src/lib.rs index 51947e4cc..09cf0216d 100644 --- a/crates/ra_ide_api/src/lib.rs +++ b/crates/ra_ide_api/src/lib.rs @@ -58,6 +58,7 @@ pub use ra_ide_api_light::{ pub use ra_db::{ Canceled, CrateGraph, CrateId, FileId, FilePosition, FileRange, SourceRootId }; +pub use hir::Documentation; // We use jemalloc mainly to get heap usage statistics, actual performance // differnece is not measures. @@ -266,7 +267,7 @@ impl RangeInfo { #[derive(Debug)] pub struct CallInfo { pub label: String, - pub doc: Option, + pub doc: Option, pub parameters: Vec, pub active_parameter: Option, } -- cgit v1.2.3