From 0e49abb7fbe9239b97f0b7168ec359014c63f8c0 Mon Sep 17 00:00:00 2001 From: Ville Penttinen Date: Tue, 12 Mar 2019 09:24:46 +0200 Subject: [PATCH 01/15] Refactor CallInfo function signatures to new FunctionSignature type This is used by CallInfo to create a pretty printed function signature that can be used with completions and other places as well. --- crates/ra_hir/src/docs.rs | 6 ++ crates/ra_ide_api/src/call_info.rs | 87 +++++++++++-------- crates/ra_ide_api/src/completion.rs | 61 +++++++++---- .../src/completion/complete_scope.rs | 2 +- crates/ra_ide_api/src/display.rs | 51 +++++++++++ crates/ra_ide_api/src/lib.rs | 31 ++++++- crates/ra_lsp_server/src/conv.rs | 22 +++++ .../ra_lsp_server/src/main_loop/handlers.rs | 23 ++--- 8 files changed, 212 insertions(+), 71 deletions(-) create mode 100644 crates/ra_ide_api/src/display.rs diff --git a/crates/ra_hir/src/docs.rs b/crates/ra_hir/src/docs.rs index 5db72c08a3e7..e3a755b468bd 100644 --- a/crates/ra_hir/src/docs.rs +++ b/crates/ra_hir/src/docs.rs @@ -22,6 +22,12 @@ impl Into for Documentation { } } +impl<'a> Into for &'a Documentation { + fn into(self) -> String { + self.contents().into() + } +} + pub trait Docs { fn docs(&self, db: &impl HirDatabase) -> Option; } diff --git a/crates/ra_ide_api/src/call_info.rs b/crates/ra_ide_api/src/call_info.rs index 29fa7d30b438..a65119315175 100644 --- a/crates/ra_ide_api/src/call_info.rs +++ b/crates/ra_ide_api/src/call_info.rs @@ -30,7 +30,7 @@ pub(crate) fn call_info(db: &RootDatabase, position: FilePosition) -> Option FnCallNode<'a> { impl CallInfo { fn new(db: &RootDatabase, function: hir::Function, node: &ast::FnDef) -> Option { - let label = crate::completion::function_label(node)?; + let sig = crate::completion::function_signature(node)?; let doc = function.docs(db); + let sig = sig.with_doc_opt(doc); - Some(CallInfo { parameters: param_list(node), label, doc, active_parameter: None }) + Some(CallInfo { signature: sig, active_parameter: None }) } -} -fn param_list(node: &ast::FnDef) -> Vec { - let mut res = vec![]; - if let Some(param_list) = node.param_list() { - if let Some(self_param) = param_list.self_param() { - res.push(self_param.syntax().text().to_string()) - } - - // Maybe use param.pat here? See if we can just extract the name? - //res.extend(param_list.params().map(|p| p.syntax().text().to_string())); - res.extend( - param_list.params().filter_map(|p| p.pat()).map(|pat| pat.syntax().text().to_string()), - ); + fn parameters(&self) -> &[String] { + &self.signature.parameters + } + + #[cfg(test)] + fn doc(&self) -> Option<&hir::Documentation> { + self.signature.doc.as_ref() + } + + #[cfg(test)] + fn label(&self) -> String { + self.signature.to_string() } - res } #[cfg(test)] @@ -151,7 +150,7 @@ mod tests { fn bar() { foo(<|>3, ); }"#, ); - assert_eq!(info.parameters, vec!("x".to_string(), "y".to_string())); + assert_eq!(info.parameters(), ["x: u32", "y: u32"]); assert_eq!(info.active_parameter, Some(0)); } @@ -162,7 +161,7 @@ fn bar() { foo(<|>3, ); }"#, fn bar() { foo(3, <|>); }"#, ); - assert_eq!(info.parameters, vec!("x".to_string(), "y".to_string())); + assert_eq!(info.parameters(), ["x: u32", "y: u32"]); assert_eq!(info.active_parameter, Some(1)); } @@ -173,7 +172,27 @@ fn bar() { foo(3, <|>); }"#, fn bar() { foo(<|>); }"#, ); - assert_eq!(info.parameters, vec!("x".to_string(), "y".to_string())); + assert_eq!(info.parameters(), ["x: u32", "y: u32"]); + assert_eq!(info.active_parameter, Some(0)); + } + + #[test] + fn test_fn_signature_two_args_first_generics() { + let info = call_info( + r#"fn foo(x: T, y: U) -> u32 where T: Copy + Display, U: Debug {x + y} +fn bar() { foo(<|>3, ); }"#, + ); + + assert_eq!(info.parameters(), ["x: T", "y: U"]); + assert_eq!( + info.label(), + r#" +fn foo(x: T, y: U) -> u32 +where T: Copy + Display, + U: Debug + "# + .trim() + ); assert_eq!(info.active_parameter, Some(0)); } @@ -184,7 +203,7 @@ fn bar() { foo(<|>); }"#, fn bar() {let _ : F = F::new(<|>);}"#, ); - assert_eq!(info.parameters, Vec::::new()); + assert!(info.parameters().is_empty()); assert_eq!(info.active_parameter, None); } @@ -206,7 +225,7 @@ fn bar() { }"#, ); - assert_eq!(info.parameters, vec!["&self".to_string()]); + assert_eq!(info.parameters(), ["&self"]); assert_eq!(info.active_parameter, None); } @@ -228,7 +247,7 @@ fn bar() { }"#, ); - assert_eq!(info.parameters, vec!["&self".to_string(), "x".to_string()]); + assert_eq!(info.parameters(), ["&self", "x: i32"]); assert_eq!(info.active_parameter, Some(1)); } @@ -248,10 +267,10 @@ fn bar() { "#, ); - assert_eq!(info.parameters, vec!["j".to_string()]); + assert_eq!(info.parameters(), ["j: u32"]); assert_eq!(info.active_parameter, Some(0)); - assert_eq!(info.label, "fn foo(j: u32) -> u32".to_string()); - assert_eq!(info.doc.map(|it| it.into()), Some("test".to_string())); + assert_eq!(info.label(), "fn foo(j: u32) -> u32"); + assert_eq!(info.doc().map(|it| it.into()), Some("test".to_string())); } #[test] @@ -276,11 +295,11 @@ pub fn do() { }"#, ); - assert_eq!(info.parameters, vec!["x".to_string()]); + assert_eq!(info.parameters(), ["x: i32"]); assert_eq!(info.active_parameter, Some(0)); - assert_eq!(info.label, "pub fn add_one(x: i32) -> i32".to_string()); + assert_eq!(info.label(), "pub fn add_one(x: i32) -> i32"); assert_eq!( - info.doc.map(|it| it.into()), + info.doc().map(|it| it.into()), Some( r#"Adds one to the number given. @@ -322,11 +341,11 @@ pub fn do_it() { }"#, ); - assert_eq!(info.parameters, vec!["x".to_string()]); + assert_eq!(info.parameters(), ["x: i32"]); assert_eq!(info.active_parameter, Some(0)); - assert_eq!(info.label, "pub fn add_one(x: i32) -> i32".to_string()); + assert_eq!(info.label(), "pub fn add_one(x: i32) -> i32"); assert_eq!( - info.doc.map(|it| it.into()), + info.doc().map(|it| it.into()), Some( r#"Adds one to the number given. @@ -375,10 +394,10 @@ pub fn foo() { "#, ); - assert_eq!(info.parameters, vec!["&mut self".to_string(), "ctx".to_string()]); + assert_eq!(info.parameters(), ["&mut self", "ctx: &mut Self::Context"]); assert_eq!(info.active_parameter, Some(1)); assert_eq!( - info.doc.map(|it| it.into()), + info.doc().map(|it| it.into()), Some( r#"Method is called when writer finishes. diff --git a/crates/ra_ide_api/src/completion.rs b/crates/ra_ide_api/src/completion.rs index a846a7a3cb2d..d8e4410b2cf7 100644 --- a/crates/ra_ide_api/src/completion.rs +++ b/crates/ra_ide_api/src/completion.rs @@ -13,11 +13,12 @@ mod complete_scope; mod complete_postfix; use ra_db::SourceDatabase; -use ra_syntax::{ast::{self, AstNode}, SyntaxKind::{ATTR, COMMENT}}; +use ra_syntax::{ast::{self, AstNode, NameOwner, VisibilityOwner, TypeParamsOwner}, SyntaxKind::{ATTR, COMMENT}}; use crate::{ db, FilePosition, + FunctionSignature, completion::{ completion_item::{Completions, CompletionKind}, completion_context::CompletionContext, @@ -71,22 +72,52 @@ pub(crate) fn completions(db: &db::RootDatabase, position: FilePosition) -> Opti 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_with_tokens() - .filter(|child| !child.range().is_subrange(&body_range)) // Filter out body - .filter(|child| !(child.kind() == COMMENT || child.kind() == ATTR)) // Filter out comments and attrs - .map(|node| node.to_string()) - .collect(); - label - } else { - node.syntax().text().to_string() +pub fn generic_parameters(node: &N) -> Vec { + let mut res = vec![]; + if let Some(type_params) = node.type_param_list() { + res.extend(type_params.lifetime_params().map(|p| p.syntax().text().to_string())); + res.extend(type_params.type_params().map(|p| p.syntax().text().to_string())); + } + res +} + +pub fn where_predicates(node: &N) -> Vec { + let mut res = vec![]; + if let Some(clause) = node.where_clause() { + res.extend(clause.predicates().map(|p| p.syntax().text().to_string())); + } + res +} + +pub fn function_signature(node: &ast::FnDef) -> Option { + fn param_list(node: &ast::FnDef) -> Vec { + let mut res = vec![]; + if let Some(param_list) = node.param_list() { + if let Some(self_param) = param_list.self_param() { + res.push(self_param.syntax().text().to_string()) + } + + res.extend(param_list.params().map(|param| param.syntax().text().to_string())); + } + res + } + + let sig = FunctionSignature { + visibility: node.visibility().map(|n| n.syntax().text().to_string()), + name: node.name().map(|n| n.text().to_string()), + ret_type: node.ret_type().and_then(|r| r.type_ref()).map(|n| n.syntax().text().to_string()), + parameters: param_list(node), + generic_parameters: generic_parameters(node), + where_predicates: where_predicates(node), + // docs are processed separately + doc: None, }; - Some(label.trim().to_owned()) + Some(sig) +} + +pub fn function_label(node: &ast::FnDef) -> Option { + function_signature(node).map(|n| n.to_string()) } pub fn const_label(node: &ast::ConstDef) -> String { diff --git a/crates/ra_ide_api/src/completion/complete_scope.rs b/crates/ra_ide_api/src/completion/complete_scope.rs index 6146b7bb6905..9d82f22708f0 100644 --- a/crates/ra_ide_api/src/completion/complete_scope.rs +++ b/crates/ra_ide_api/src/completion/complete_scope.rs @@ -145,7 +145,7 @@ mod tests { check_reference_completion( "dont_show_both_completions_for_shadowing", r" - fn foo() -> { + fn foo() { let bar = 92; { let bar = 62; diff --git a/crates/ra_ide_api/src/display.rs b/crates/ra_ide_api/src/display.rs new file mode 100644 index 000000000000..60fa72f1bb1f --- /dev/null +++ b/crates/ra_ide_api/src/display.rs @@ -0,0 +1,51 @@ +use super::*; +use std::fmt::{self, Display}; + +impl Display for FunctionSignature { + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + if let Some(t) = &self.visibility { + write!(f, "{} ", t)?; + } + + if let Some(name) = &self.name { + write!(f, "fn {}", name)?; + } + + if !self.generic_parameters.is_empty() { + write!(f, "<")?; + write_joined(f, &self.generic_parameters, ", ")?; + write!(f, ">")?; + } + + write!(f, "(")?; + write_joined(f, &self.parameters, ", ")?; + write!(f, ")")?; + + if let Some(t) = &self.ret_type { + write!(f, " -> {}", t)?; + } + + if !self.where_predicates.is_empty() { + write!(f, "\nwhere ")?; + write_joined(f, &self.where_predicates, ",\n ")?; + } + + Ok(()) + } +} + +fn write_joined( + f: &mut fmt::Formatter, + items: impl IntoIterator, + sep: &str, +) -> fmt::Result { + let mut first = true; + for e in items { + if !first { + write!(f, "{}", sep)?; + } + first = false; + write!(f, "{}", e)?; + } + Ok(()) +} diff --git a/crates/ra_ide_api/src/lib.rs b/crates/ra_ide_api/src/lib.rs index 9063f78a9fb3..7f8f454bc706 100644 --- a/crates/ra_ide_api/src/lib.rs +++ b/crates/ra_ide_api/src/lib.rs @@ -37,6 +37,7 @@ mod join_lines; mod structure; mod typing; mod matching_brace; +mod display; #[cfg(test)] mod marks; @@ -243,12 +244,36 @@ impl RangeInfo { #[derive(Debug)] pub struct CallInfo { - pub label: String, - pub doc: Option, - pub parameters: Vec, + pub signature: FunctionSignature, pub active_parameter: Option, } +/// Contains information about a function signature +#[derive(Debug)] +pub struct FunctionSignature { + /// Optional visibility + pub visibility: Option, + /// Name of the function + pub name: Option, + /// Documentation for the function + pub doc: Option, + /// Generic parameters + pub generic_parameters: Vec, + /// Parameters of the function + pub parameters: Vec, + /// Optional return type + pub ret_type: Option, + /// Where predicates + pub where_predicates: Vec, +} + +impl FunctionSignature { + pub(crate) fn with_doc_opt(mut self, doc: Option) -> Self { + self.doc = doc; + self + } +} + /// `AnalysisHost` stores the current state of the world. #[derive(Debug, Default)] pub struct AnalysisHost { diff --git a/crates/ra_lsp_server/src/conv.rs b/crates/ra_lsp_server/src/conv.rs index 74e91c236334..4d6ede316c83 100644 --- a/crates/ra_lsp_server/src/conv.rs +++ b/crates/ra_lsp_server/src/conv.rs @@ -174,6 +174,28 @@ impl Conv for ra_ide_api::Documentation { } } +impl Conv for ra_ide_api::FunctionSignature { + type Output = lsp_types::SignatureInformation; + fn conv(self) -> Self::Output { + use lsp_types::{ParameterInformation, ParameterLabel, SignatureInformation}; + + let label = self.to_string(); + + let documentation = self.doc.map(|it| it.conv()); + + let parameters: Vec = self + .parameters + .into_iter() + .map(|param| ParameterInformation { + label: ParameterLabel::Simple(param), + documentation: None, + }) + .collect(); + + SignatureInformation { label, documentation, parameters: Some(parameters) } + } +} + impl ConvWith for TextEdit { type Ctx = LineIndex; type Output = Vec; diff --git a/crates/ra_lsp_server/src/main_loop/handlers.rs b/crates/ra_lsp_server/src/main_loop/handlers.rs index 89e96a33af59..b96deb061e86 100644 --- a/crates/ra_lsp_server/src/main_loop/handlers.rs +++ b/crates/ra_lsp_server/src/main_loop/handlers.rs @@ -3,8 +3,8 @@ use lsp_types::{ CodeActionResponse, CodeLens, Command, Diagnostic, DiagnosticSeverity, CodeAction, DocumentFormattingParams, DocumentHighlight, DocumentSymbol, FoldingRange, FoldingRangeKind, FoldingRangeParams, Hover, HoverContents, Location, MarkupContent, - MarkupKind, ParameterInformation, ParameterLabel, Position, PrepareRenameResponse, Range, - RenameParams, SignatureInformation, SymbolInformation, TextDocumentIdentifier, TextEdit, + MarkupKind, Position, PrepareRenameResponse, Range, + RenameParams,SymbolInformation, TextDocumentIdentifier, TextEdit, WorkspaceEdit, }; use ra_ide_api::{ @@ -403,26 +403,13 @@ pub fn handle_signature_help( ) -> Result> { let position = params.try_conv_with(&world)?; if let Some(call_info) = world.analysis().call_info(position)? { - let parameters: Vec = call_info - .parameters - .into_iter() - .map(|param| ParameterInformation { - label: ParameterLabel::Simple(param.clone()), - documentation: None, - }) - .collect(); + let active_parameter = call_info.active_parameter.map(|it| it as i64); + let sig_info = call_info.signature.conv(); - let documentation = call_info.doc.map(|it| it.conv()); - - let sig_info = SignatureInformation { - label: call_info.label, - documentation, - parameters: Some(parameters), - }; Ok(Some(req::SignatureHelp { signatures: vec![sig_info], active_signature: Some(0), - active_parameter: call_info.active_parameter.map(|it| it as i64), + active_parameter, })) } else { Ok(None) From 751b4544426509b6b9a072c54604fa0ca4438e64 Mon Sep 17 00:00:00 2001 From: Ville Penttinen Date: Thu, 4 Apr 2019 17:54:26 +0300 Subject: [PATCH 02/15] Update test snapshots --- ...__dont_show_both_completions_for_shadowing.snap | 14 +++++++------- .../snapshots/completion_item__return_type.snap | 6 +++--- 2 files changed, 10 insertions(+), 10 deletions(-) diff --git a/crates/ra_ide_api/src/completion/snapshots/completion_item__dont_show_both_completions_for_shadowing.snap b/crates/ra_ide_api/src/completion/snapshots/completion_item__dont_show_both_completions_for_shadowing.snap index 87691b304024..34adcda6cb85 100644 --- a/crates/ra_ide_api/src/completion/snapshots/completion_item__dont_show_both_completions_for_shadowing.snap +++ b/crates/ra_ide_api/src/completion/snapshots/completion_item__dont_show_both_completions_for_shadowing.snap @@ -1,23 +1,23 @@ --- -created: "2019-02-18T09:22:24.188564584Z" -creator: insta@0.6.2 +created: "2019-04-04T14:52:24.531844100Z" +creator: insta@0.7.4 source: crates/ra_ide_api/src/completion/completion_item.rs expression: kind_completions --- [ CompletionItem { label: "bar", - source_range: [129; 129), - delete: [129; 129), + source_range: [126; 126), + delete: [126; 126), insert: "bar", kind: Binding }, CompletionItem { label: "foo", - source_range: [129; 129), - delete: [129; 129), + source_range: [126; 126), + delete: [126; 126), insert: "foo()$0", kind: Function, - detail: "fn foo() ->" + detail: "fn foo()" } ] diff --git a/crates/ra_ide_api/src/completion/snapshots/completion_item__return_type.snap b/crates/ra_ide_api/src/completion/snapshots/completion_item__return_type.snap index 0738cf466ca0..ff36df707b01 100644 --- a/crates/ra_ide_api/src/completion/snapshots/completion_item__return_type.snap +++ b/crates/ra_ide_api/src/completion/snapshots/completion_item__return_type.snap @@ -1,6 +1,6 @@ --- -created: "2019-02-18T09:22:24.182964414Z" -creator: insta@0.6.2 +created: "2019-04-04T14:52:24.525395600Z" +creator: insta@0.7.4 source: crates/ra_ide_api/src/completion/completion_item.rs expression: kind_completions --- @@ -18,6 +18,6 @@ expression: kind_completions delete: [47; 47), insert: "x()$0", kind: Function, - detail: "fn x() ->" + detail: "fn x()" } ] From 84fde47d00bb3ccba3876ad2b2e46c5c59cd07c4 Mon Sep 17 00:00:00 2001 From: Ville Penttinen Date: Thu, 4 Apr 2019 18:06:22 +0300 Subject: [PATCH 03/15] Move test specific things --- crates/ra_hir/src/docs.rs | 6 ------ crates/ra_ide_api/src/call_info.rs | 21 +++++++++++---------- 2 files changed, 11 insertions(+), 16 deletions(-) diff --git a/crates/ra_hir/src/docs.rs b/crates/ra_hir/src/docs.rs index e3a755b468bd..5db72c08a3e7 100644 --- a/crates/ra_hir/src/docs.rs +++ b/crates/ra_hir/src/docs.rs @@ -22,12 +22,6 @@ impl Into for Documentation { } } -impl<'a> Into for &'a Documentation { - fn into(self) -> String { - self.contents().into() - } -} - pub trait Docs { fn docs(&self, db: &impl HirDatabase) -> Option; } diff --git a/crates/ra_ide_api/src/call_info.rs b/crates/ra_ide_api/src/call_info.rs index a65119315175..3c53bd11a793 100644 --- a/crates/ra_ide_api/src/call_info.rs +++ b/crates/ra_ide_api/src/call_info.rs @@ -118,16 +118,6 @@ impl CallInfo { fn parameters(&self) -> &[String] { &self.signature.parameters } - - #[cfg(test)] - fn doc(&self) -> Option<&hir::Documentation> { - self.signature.doc.as_ref() - } - - #[cfg(test)] - fn label(&self) -> String { - self.signature.to_string() - } } #[cfg(test)] @@ -138,6 +128,17 @@ mod tests { use super::*; + // These are only used when testing + impl CallInfo { + fn doc(&self) -> Option { + self.signature.doc.clone() + } + + fn label(&self) -> String { + self.signature.to_string() + } + } + fn call_info(text: &str) -> CallInfo { let (analysis, position) = single_file_with_position(text); analysis.call_info(position).unwrap().unwrap() From 7ba22f1c19c8fbfe45630c35ebd963d4c5475bc9 Mon Sep 17 00:00:00 2001 From: Ville Penttinen Date: Thu, 4 Apr 2019 19:30:20 +0300 Subject: [PATCH 04/15] Move FunctionSignature to display, remove write_joined write_joined is replaced with `join_to_string::join` which provides the necessary functionality. --- crates/ra_ide_api/src/display.rs | 58 +++++++++++++++++++------------- crates/ra_ide_api/src/lib.rs | 27 +-------------- 2 files changed, 36 insertions(+), 49 deletions(-) diff --git a/crates/ra_ide_api/src/display.rs b/crates/ra_ide_api/src/display.rs index 60fa72f1bb1f..9d9d2097f387 100644 --- a/crates/ra_ide_api/src/display.rs +++ b/crates/ra_ide_api/src/display.rs @@ -1,5 +1,34 @@ +//! This module contains utilities for rendering turning things into something +//! that may be used to render in UI. use super::*; use std::fmt::{self, Display}; +use join_to_string::join; + +/// Contains information about a function signature +#[derive(Debug)] +pub struct FunctionSignature { + /// Optional visibility + pub visibility: Option, + /// Name of the function + pub name: Option, + /// Documentation for the function + pub doc: Option, + /// Generic parameters + pub generic_parameters: Vec, + /// Parameters of the function + pub parameters: Vec, + /// Optional return type + pub ret_type: Option, + /// Where predicates + pub where_predicates: Vec, +} + +impl FunctionSignature { + pub(crate) fn with_doc_opt(mut self, doc: Option) -> Self { + self.doc = doc; + self + } +} impl Display for FunctionSignature { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { @@ -12,14 +41,13 @@ impl Display for FunctionSignature { } if !self.generic_parameters.is_empty() { - write!(f, "<")?; - write_joined(f, &self.generic_parameters, ", ")?; - write!(f, ">")?; + join(self.generic_parameters.iter()) + .separator(", ") + .surround_with("<", ">") + .to_fmt(f)?; } - write!(f, "(")?; - write_joined(f, &self.parameters, ", ")?; - write!(f, ")")?; + join(self.parameters.iter()).separator(", ").surround_with("(", ")").to_fmt(f)?; if let Some(t) = &self.ret_type { write!(f, " -> {}", t)?; @@ -27,25 +55,9 @@ impl Display for FunctionSignature { if !self.where_predicates.is_empty() { write!(f, "\nwhere ")?; - write_joined(f, &self.where_predicates, ",\n ")?; + join(self.where_predicates.iter()).separator(",\n ").to_fmt(f)?; } Ok(()) } } - -fn write_joined( - f: &mut fmt::Formatter, - items: impl IntoIterator, - sep: &str, -) -> fmt::Result { - let mut first = true; - for e in items { - if !first { - write!(f, "{}", sep)?; - } - first = false; - write!(f, "{}", e)?; - } - Ok(()) -} diff --git a/crates/ra_ide_api/src/lib.rs b/crates/ra_ide_api/src/lib.rs index 7f8f454bc706..816bab94f07f 100644 --- a/crates/ra_ide_api/src/lib.rs +++ b/crates/ra_ide_api/src/lib.rs @@ -73,6 +73,7 @@ pub use crate::{ syntax_highlighting::HighlightedRange, structure::{StructureNode, file_structure}, diagnostics::Severity, + display::FunctionSignature, }; pub use ra_db::{ @@ -248,32 +249,6 @@ pub struct CallInfo { pub active_parameter: Option, } -/// Contains information about a function signature -#[derive(Debug)] -pub struct FunctionSignature { - /// Optional visibility - pub visibility: Option, - /// Name of the function - pub name: Option, - /// Documentation for the function - pub doc: Option, - /// Generic parameters - pub generic_parameters: Vec, - /// Parameters of the function - pub parameters: Vec, - /// Optional return type - pub ret_type: Option, - /// Where predicates - pub where_predicates: Vec, -} - -impl FunctionSignature { - pub(crate) fn with_doc_opt(mut self, doc: Option) -> Self { - self.doc = doc; - self - } -} - /// `AnalysisHost` stores the current state of the world. #[derive(Debug, Default)] pub struct AnalysisHost { From ed65e2619a42aea7c375d0cbf81d337fffb11a46 Mon Sep 17 00:00:00 2001 From: Ville Penttinen Date: Thu, 4 Apr 2019 19:43:32 +0300 Subject: [PATCH 05/15] Add no parameter test to call_info --- crates/ra_ide_api/src/call_info.rs | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) diff --git a/crates/ra_ide_api/src/call_info.rs b/crates/ra_ide_api/src/call_info.rs index 3c53bd11a793..1885d3da81f7 100644 --- a/crates/ra_ide_api/src/call_info.rs +++ b/crates/ra_ide_api/src/call_info.rs @@ -197,6 +197,25 @@ where T: Copy + Display, assert_eq!(info.active_parameter, Some(0)); } + #[test] + fn test_fn_signature_no_params() { + let info = call_info( + r#"fn foo() -> T where T: Copy + Display {} +fn bar() { foo(<|>); }"#, + ); + + assert!(info.parameters().is_empty()); + assert_eq!( + info.label(), + r#" +fn foo() -> T +where T: Copy + Display + "# + .trim() + ); + assert!(info.active_parameter.is_none()); + } + #[test] fn test_fn_signature_for_impl() { let info = call_info( From f4aa15c16b352d4ac9a90c1668311e4762c5e494 Mon Sep 17 00:00:00 2001 From: Ville Penttinen Date: Thu, 4 Apr 2019 20:05:01 +0300 Subject: [PATCH 06/15] Move FunctionSignature creation to display --- crates/ra_ide_api/src/call_info.rs | 7 ++--- crates/ra_ide_api/src/completion.rs | 48 ++-------------------------- crates/ra_ide_api/src/display.rs | 49 +++++++++++++++++++++++++++++ 3 files changed, 54 insertions(+), 50 deletions(-) diff --git a/crates/ra_ide_api/src/call_info.rs b/crates/ra_ide_api/src/call_info.rs index 1885d3da81f7..66a769c7300e 100644 --- a/crates/ra_ide_api/src/call_info.rs +++ b/crates/ra_ide_api/src/call_info.rs @@ -8,7 +8,7 @@ use ra_syntax::{ }; use hir::Docs; -use crate::{FilePosition, CallInfo, db::RootDatabase}; +use crate::{FilePosition, CallInfo, FunctionSignature, db::RootDatabase}; /// Computes parameter information for the given call expression. pub(crate) fn call_info(db: &RootDatabase, position: FilePosition) -> Option { @@ -108,11 +108,10 @@ impl<'a> FnCallNode<'a> { impl CallInfo { fn new(db: &RootDatabase, function: hir::Function, node: &ast::FnDef) -> Option { - let sig = crate::completion::function_signature(node)?; let doc = function.docs(db); - let sig = sig.with_doc_opt(doc); + let signature = FunctionSignature::from(node).with_doc_opt(doc); - Some(CallInfo { signature: sig, active_parameter: None }) + Some(CallInfo { signature, active_parameter: None }) } fn parameters(&self) -> &[String] { diff --git a/crates/ra_ide_api/src/completion.rs b/crates/ra_ide_api/src/completion.rs index d8e4410b2cf7..71a35c689776 100644 --- a/crates/ra_ide_api/src/completion.rs +++ b/crates/ra_ide_api/src/completion.rs @@ -13,7 +13,7 @@ mod complete_scope; mod complete_postfix; use ra_db::SourceDatabase; -use ra_syntax::{ast::{self, AstNode, NameOwner, VisibilityOwner, TypeParamsOwner}, SyntaxKind::{ATTR, COMMENT}}; +use ra_syntax::{ast::{self, AstNode}, SyntaxKind::{ATTR, COMMENT}}; use crate::{ db, @@ -72,52 +72,8 @@ pub(crate) fn completions(db: &db::RootDatabase, position: FilePosition) -> Opti Some(acc) } -pub fn generic_parameters(node: &N) -> Vec { - let mut res = vec![]; - if let Some(type_params) = node.type_param_list() { - res.extend(type_params.lifetime_params().map(|p| p.syntax().text().to_string())); - res.extend(type_params.type_params().map(|p| p.syntax().text().to_string())); - } - res -} - -pub fn where_predicates(node: &N) -> Vec { - let mut res = vec![]; - if let Some(clause) = node.where_clause() { - res.extend(clause.predicates().map(|p| p.syntax().text().to_string())); - } - res -} - -pub fn function_signature(node: &ast::FnDef) -> Option { - fn param_list(node: &ast::FnDef) -> Vec { - let mut res = vec![]; - if let Some(param_list) = node.param_list() { - if let Some(self_param) = param_list.self_param() { - res.push(self_param.syntax().text().to_string()) - } - - res.extend(param_list.params().map(|param| param.syntax().text().to_string())); - } - res - } - - let sig = FunctionSignature { - visibility: node.visibility().map(|n| n.syntax().text().to_string()), - name: node.name().map(|n| n.text().to_string()), - ret_type: node.ret_type().and_then(|r| r.type_ref()).map(|n| n.syntax().text().to_string()), - parameters: param_list(node), - generic_parameters: generic_parameters(node), - where_predicates: where_predicates(node), - // docs are processed separately - doc: None, - }; - - Some(sig) -} - pub fn function_label(node: &ast::FnDef) -> Option { - function_signature(node).map(|n| n.to_string()) + Some(FunctionSignature::from(node).to_string()) } pub fn const_label(node: &ast::ConstDef) -> String { diff --git a/crates/ra_ide_api/src/display.rs b/crates/ra_ide_api/src/display.rs index 9d9d2097f387..e01635460da9 100644 --- a/crates/ra_ide_api/src/display.rs +++ b/crates/ra_ide_api/src/display.rs @@ -3,6 +3,8 @@ use super::*; use std::fmt::{self, Display}; use join_to_string::join; +use ra_syntax::ast::{self, AstNode, NameOwner, VisibilityOwner, TypeParamsOwner}; +use std::convert::From; /// Contains information about a function signature #[derive(Debug)] @@ -30,6 +32,36 @@ impl FunctionSignature { } } +impl From<&'_ ast::FnDef> for FunctionSignature { + fn from(node: &ast::FnDef) -> FunctionSignature { + fn param_list(node: &ast::FnDef) -> Vec { + let mut res = vec![]; + if let Some(param_list) = node.param_list() { + if let Some(self_param) = param_list.self_param() { + res.push(self_param.syntax().text().to_string()) + } + + res.extend(param_list.params().map(|param| param.syntax().text().to_string())); + } + res + } + + FunctionSignature { + visibility: node.visibility().map(|n| n.syntax().text().to_string()), + name: node.name().map(|n| n.text().to_string()), + ret_type: node + .ret_type() + .and_then(|r| r.type_ref()) + .map(|n| n.syntax().text().to_string()), + parameters: param_list(node), + generic_parameters: generic_parameters(node), + where_predicates: where_predicates(node), + // docs are processed separately + doc: None, + } + } +} + impl Display for FunctionSignature { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { if let Some(t) = &self.visibility { @@ -61,3 +93,20 @@ impl Display for FunctionSignature { Ok(()) } } + +pub(crate) fn generic_parameters(node: &N) -> Vec { + let mut res = vec![]; + if let Some(type_params) = node.type_param_list() { + res.extend(type_params.lifetime_params().map(|p| p.syntax().text().to_string())); + res.extend(type_params.type_params().map(|p| p.syntax().text().to_string())); + } + res +} + +pub(crate) fn where_predicates(node: &N) -> Vec { + let mut res = vec![]; + if let Some(clause) = node.where_clause() { + res.extend(clause.predicates().map(|p| p.syntax().text().to_string())); + } + res +} From 2fe075f56eff65ee6d326f7ea8bc0efccc4df152 Mon Sep 17 00:00:00 2001 From: Ville Penttinen Date: Mon, 8 Apr 2019 10:25:35 +0300 Subject: [PATCH 07/15] Normalize line-endings in display.rs This changes from CRLF to LF --- crates/ra_ide_api/src/display.rs | 224 +++++++++++++++---------------- 1 file changed, 112 insertions(+), 112 deletions(-) diff --git a/crates/ra_ide_api/src/display.rs b/crates/ra_ide_api/src/display.rs index e01635460da9..4ce362ebb19b 100644 --- a/crates/ra_ide_api/src/display.rs +++ b/crates/ra_ide_api/src/display.rs @@ -1,112 +1,112 @@ -//! This module contains utilities for rendering turning things into something -//! that may be used to render in UI. -use super::*; -use std::fmt::{self, Display}; -use join_to_string::join; -use ra_syntax::ast::{self, AstNode, NameOwner, VisibilityOwner, TypeParamsOwner}; -use std::convert::From; - -/// Contains information about a function signature -#[derive(Debug)] -pub struct FunctionSignature { - /// Optional visibility - pub visibility: Option, - /// Name of the function - pub name: Option, - /// Documentation for the function - pub doc: Option, - /// Generic parameters - pub generic_parameters: Vec, - /// Parameters of the function - pub parameters: Vec, - /// Optional return type - pub ret_type: Option, - /// Where predicates - pub where_predicates: Vec, -} - -impl FunctionSignature { - pub(crate) fn with_doc_opt(mut self, doc: Option) -> Self { - self.doc = doc; - self - } -} - -impl From<&'_ ast::FnDef> for FunctionSignature { - fn from(node: &ast::FnDef) -> FunctionSignature { - fn param_list(node: &ast::FnDef) -> Vec { - let mut res = vec![]; - if let Some(param_list) = node.param_list() { - if let Some(self_param) = param_list.self_param() { - res.push(self_param.syntax().text().to_string()) - } - - res.extend(param_list.params().map(|param| param.syntax().text().to_string())); - } - res - } - - FunctionSignature { - visibility: node.visibility().map(|n| n.syntax().text().to_string()), - name: node.name().map(|n| n.text().to_string()), - ret_type: node - .ret_type() - .and_then(|r| r.type_ref()) - .map(|n| n.syntax().text().to_string()), - parameters: param_list(node), - generic_parameters: generic_parameters(node), - where_predicates: where_predicates(node), - // docs are processed separately - doc: None, - } - } -} - -impl Display for FunctionSignature { - fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { - if let Some(t) = &self.visibility { - write!(f, "{} ", t)?; - } - - if let Some(name) = &self.name { - write!(f, "fn {}", name)?; - } - - if !self.generic_parameters.is_empty() { - join(self.generic_parameters.iter()) - .separator(", ") - .surround_with("<", ">") - .to_fmt(f)?; - } - - join(self.parameters.iter()).separator(", ").surround_with("(", ")").to_fmt(f)?; - - if let Some(t) = &self.ret_type { - write!(f, " -> {}", t)?; - } - - if !self.where_predicates.is_empty() { - write!(f, "\nwhere ")?; - join(self.where_predicates.iter()).separator(",\n ").to_fmt(f)?; - } - - Ok(()) - } -} - -pub(crate) fn generic_parameters(node: &N) -> Vec { - let mut res = vec![]; - if let Some(type_params) = node.type_param_list() { - res.extend(type_params.lifetime_params().map(|p| p.syntax().text().to_string())); - res.extend(type_params.type_params().map(|p| p.syntax().text().to_string())); - } - res -} - -pub(crate) fn where_predicates(node: &N) -> Vec { - let mut res = vec![]; - if let Some(clause) = node.where_clause() { - res.extend(clause.predicates().map(|p| p.syntax().text().to_string())); - } - res -} +//! This module contains utilities for rendering turning things into something +//! that may be used to render in UI. +use super::*; +use std::fmt::{self, Display}; +use join_to_string::join; +use ra_syntax::ast::{self, AstNode, NameOwner, VisibilityOwner, TypeParamsOwner}; +use std::convert::From; + +/// Contains information about a function signature +#[derive(Debug)] +pub struct FunctionSignature { + /// Optional visibility + pub visibility: Option, + /// Name of the function + pub name: Option, + /// Documentation for the function + pub doc: Option, + /// Generic parameters + pub generic_parameters: Vec, + /// Parameters of the function + pub parameters: Vec, + /// Optional return type + pub ret_type: Option, + /// Where predicates + pub where_predicates: Vec, +} + +impl FunctionSignature { + pub(crate) fn with_doc_opt(mut self, doc: Option) -> Self { + self.doc = doc; + self + } +} + +impl From<&'_ ast::FnDef> for FunctionSignature { + fn from(node: &ast::FnDef) -> FunctionSignature { + fn param_list(node: &ast::FnDef) -> Vec { + let mut res = vec![]; + if let Some(param_list) = node.param_list() { + if let Some(self_param) = param_list.self_param() { + res.push(self_param.syntax().text().to_string()) + } + + res.extend(param_list.params().map(|param| param.syntax().text().to_string())); + } + res + } + + FunctionSignature { + visibility: node.visibility().map(|n| n.syntax().text().to_string()), + name: node.name().map(|n| n.text().to_string()), + ret_type: node + .ret_type() + .and_then(|r| r.type_ref()) + .map(|n| n.syntax().text().to_string()), + parameters: param_list(node), + generic_parameters: generic_parameters(node), + where_predicates: where_predicates(node), + // docs are processed separately + doc: None, + } + } +} + +impl Display for FunctionSignature { + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + if let Some(t) = &self.visibility { + write!(f, "{} ", t)?; + } + + if let Some(name) = &self.name { + write!(f, "fn {}", name)?; + } + + if !self.generic_parameters.is_empty() { + join(self.generic_parameters.iter()) + .separator(", ") + .surround_with("<", ">") + .to_fmt(f)?; + } + + join(self.parameters.iter()).separator(", ").surround_with("(", ")").to_fmt(f)?; + + if let Some(t) = &self.ret_type { + write!(f, " -> {}", t)?; + } + + if !self.where_predicates.is_empty() { + write!(f, "\nwhere ")?; + join(self.where_predicates.iter()).separator(",\n ").to_fmt(f)?; + } + + Ok(()) + } +} + +pub(crate) fn generic_parameters(node: &N) -> Vec { + let mut res = vec![]; + if let Some(type_params) = node.type_param_list() { + res.extend(type_params.lifetime_params().map(|p| p.syntax().text().to_string())); + res.extend(type_params.type_params().map(|p| p.syntax().text().to_string())); + } + res +} + +pub(crate) fn where_predicates(node: &N) -> Vec { + let mut res = vec![]; + if let Some(clause) = node.where_clause() { + res.extend(clause.predicates().map(|p| p.syntax().text().to_string())); + } + res +} From dfaebd76aba1cfd7ac13b940d7847eb44b953cac Mon Sep 17 00:00:00 2001 From: Ville Penttinen Date: Mon, 8 Apr 2019 10:46:26 +0300 Subject: [PATCH 08/15] Add FunctionSignature::from_hir --- crates/ra_ide_api/src/call_info.rs | 10 ++++------ crates/ra_ide_api/src/display.rs | 7 +++++++ 2 files changed, 11 insertions(+), 6 deletions(-) diff --git a/crates/ra_ide_api/src/call_info.rs b/crates/ra_ide_api/src/call_info.rs index 66a769c7300e..dbb3853d0fcb 100644 --- a/crates/ra_ide_api/src/call_info.rs +++ b/crates/ra_ide_api/src/call_info.rs @@ -6,7 +6,6 @@ use ra_syntax::{ ast::{self, ArgListOwner}, algo::find_node_at_offset, }; -use hir::Docs; use crate::{FilePosition, CallInfo, FunctionSignature, db::RootDatabase}; @@ -27,7 +26,7 @@ pub(crate) fn call_info(db: &RootDatabase, position: FilePosition) -> Option FnCallNode<'a> { } impl CallInfo { - fn new(db: &RootDatabase, function: hir::Function, node: &ast::FnDef) -> Option { - let doc = function.docs(db); - let signature = FunctionSignature::from(node).with_doc_opt(doc); + fn new(db: &RootDatabase, function: hir::Function) -> Self { + let signature = FunctionSignature::from_hir(db, function); - Some(CallInfo { signature, active_parameter: None }) + CallInfo { signature, active_parameter: None } } fn parameters(&self) -> &[String] { diff --git a/crates/ra_ide_api/src/display.rs b/crates/ra_ide_api/src/display.rs index 4ce362ebb19b..c05d59689e17 100644 --- a/crates/ra_ide_api/src/display.rs +++ b/crates/ra_ide_api/src/display.rs @@ -5,6 +5,7 @@ use std::fmt::{self, Display}; use join_to_string::join; use ra_syntax::ast::{self, AstNode, NameOwner, VisibilityOwner, TypeParamsOwner}; use std::convert::From; +use hir::Docs; /// Contains information about a function signature #[derive(Debug)] @@ -30,6 +31,12 @@ impl FunctionSignature { self.doc = doc; self } + + pub(crate) fn from_hir(db: &db::RootDatabase, function: hir::Function) -> Self { + let doc = function.docs(db); + let (_, ast_node) = function.source(db); + FunctionSignature::from(&*ast_node).with_doc_opt(doc) + } } impl From<&'_ ast::FnDef> for FunctionSignature { From 946b5789d1ea6385a345fcb4aa0658392ec44a51 Mon Sep 17 00:00:00 2001 From: Ville Penttinen Date: Mon, 8 Apr 2019 11:44:23 +0300 Subject: [PATCH 09/15] Move completion label functions to display --- crates/ra_ide_api/src/completion.rs | 28 ------------------- .../ra_ide_api/src/completion/presentation.rs | 5 +++- crates/ra_ide_api/src/display.rs | 28 ++++++++++++++++++- crates/ra_ide_api/src/hover.rs | 2 +- 4 files changed, 32 insertions(+), 31 deletions(-) diff --git a/crates/ra_ide_api/src/completion.rs b/crates/ra_ide_api/src/completion.rs index 71a35c689776..deff59cd3ea5 100644 --- a/crates/ra_ide_api/src/completion.rs +++ b/crates/ra_ide_api/src/completion.rs @@ -13,12 +13,10 @@ mod complete_scope; mod complete_postfix; use ra_db::SourceDatabase; -use ra_syntax::{ast::{self, AstNode}, SyntaxKind::{ATTR, COMMENT}}; use crate::{ db, FilePosition, - FunctionSignature, completion::{ completion_item::{Completions, CompletionKind}, completion_context::CompletionContext, @@ -71,29 +69,3 @@ 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 { - Some(FunctionSignature::from(node).to_string()) -} - -pub fn const_label(node: &ast::ConstDef) -> String { - let label: String = node - .syntax() - .children_with_tokens() - .filter(|child| !(child.kind() == COMMENT || child.kind() == ATTR)) - .map(|node| node.to_string()) - .collect(); - - label.trim().to_owned() -} - -pub fn type_label(node: &ast::TypeAliasDef) -> String { - let label: String = node - .syntax() - .children_with_tokens() - .filter(|child| !(child.kind() == COMMENT || child.kind() == ATTR)) - .map(|node| node.to_string()) - .collect(); - - label.trim().to_owned() -} diff --git a/crates/ra_ide_api/src/completion/presentation.rs b/crates/ra_ide_api/src/completion/presentation.rs index 28c8f83ab9f3..9aa346688758 100644 --- a/crates/ra_ide_api/src/completion/presentation.rs +++ b/crates/ra_ide_api/src/completion/presentation.rs @@ -6,6 +6,9 @@ use ra_syntax::ast::NameOwner; use crate::completion::{ Completions, CompletionKind, CompletionItemKind, CompletionContext, CompletionItem, +}; + +use crate::display::{ function_label, const_label, type_label, }; @@ -101,7 +104,7 @@ impl Completions { CompletionItemKind::Function }) .set_documentation(func.docs(ctx.db)) - .set_detail(detail); + .detail(detail); // If not an import, add parenthesis automatically. if ctx.use_item_syntax.is_none() && !ctx.is_call { tested_by!(inserts_parens_for_function_calls); diff --git a/crates/ra_ide_api/src/display.rs b/crates/ra_ide_api/src/display.rs index c05d59689e17..efadb9b10045 100644 --- a/crates/ra_ide_api/src/display.rs +++ b/crates/ra_ide_api/src/display.rs @@ -3,10 +3,36 @@ use super::*; use std::fmt::{self, Display}; use join_to_string::join; -use ra_syntax::ast::{self, AstNode, NameOwner, VisibilityOwner, TypeParamsOwner}; +use ra_syntax::{ast::{self, AstNode, NameOwner, VisibilityOwner, TypeParamsOwner}, SyntaxKind::{ATTR, COMMENT}}; use std::convert::From; use hir::Docs; +pub(crate) fn function_label(node: &ast::FnDef) -> String { + FunctionSignature::from(node).to_string() +} + +pub(crate) fn const_label(node: &ast::ConstDef) -> String { + let label: String = node + .syntax() + .children_with_tokens() + .filter(|child| !(child.kind() == COMMENT || child.kind() == ATTR)) + .map(|node| node.to_string()) + .collect(); + + label.trim().to_owned() +} + +pub(crate) fn type_label(node: &ast::TypeAliasDef) -> String { + let label: String = node + .syntax() + .children_with_tokens() + .filter(|child| !(child.kind() == COMMENT || child.kind() == ATTR)) + .map(|node| node.to_string()) + .collect(); + + label.trim().to_owned() +} + /// Contains information about a function signature #[derive(Debug)] pub struct FunctionSignature { diff --git a/crates/ra_ide_api/src/hover.rs b/crates/ra_ide_api/src/hover.rs index bfa7cd67abc1..7d2c57f82cfd 100644 --- a/crates/ra_ide_api/src/hover.rs +++ b/crates/ra_ide_api/src/hover.rs @@ -235,7 +235,7 @@ impl NavigationTarget { } visitor() - .visit(crate::completion::function_label) + .visit(|node: &ast::FnDef| Some(crate::display::function_label(node))) .visit(|node: &ast::StructDef| visit_node(node, "struct ")) .visit(|node: &ast::EnumDef| visit_node(node, "enum ")) .visit(|node: &ast::TraitDef| visit_node(node, "trait ")) From 027d4d229d7be91630de95d0d3ef004327828bd6 Mon Sep 17 00:00:00 2001 From: Ville Penttinen Date: Mon, 8 Apr 2019 12:20:28 +0300 Subject: [PATCH 10/15] Move navigation_target to display/navigation_target --- crates/ra_ide_api/src/display.rs | 4 ++++ crates/ra_ide_api/src/{ => display}/navigation_target.rs | 0 crates/ra_ide_api/src/lib.rs | 4 +--- crates/ra_ide_api/src/symbol_index.rs | 2 +- 4 files changed, 6 insertions(+), 4 deletions(-) rename crates/ra_ide_api/src/{ => display}/navigation_target.rs (100%) diff --git a/crates/ra_ide_api/src/display.rs b/crates/ra_ide_api/src/display.rs index efadb9b10045..f0c818933064 100644 --- a/crates/ra_ide_api/src/display.rs +++ b/crates/ra_ide_api/src/display.rs @@ -7,6 +7,10 @@ use ra_syntax::{ast::{self, AstNode, NameOwner, VisibilityOwner, TypeParamsOwner use std::convert::From; use hir::Docs; +pub mod navigation_target; + +pub use navigation_target::NavigationTarget; + pub(crate) fn function_label(node: &ast::FnDef) -> String { FunctionSignature::from(node).to_string() } diff --git a/crates/ra_ide_api/src/navigation_target.rs b/crates/ra_ide_api/src/display/navigation_target.rs similarity index 100% rename from crates/ra_ide_api/src/navigation_target.rs rename to crates/ra_ide_api/src/display/navigation_target.rs diff --git a/crates/ra_ide_api/src/lib.rs b/crates/ra_ide_api/src/lib.rs index 816bab94f07f..d76012a8c836 100644 --- a/crates/ra_ide_api/src/lib.rs +++ b/crates/ra_ide_api/src/lib.rs @@ -13,7 +13,6 @@ mod db; pub mod mock_analysis; mod symbol_index; -mod navigation_target; mod change; mod status; @@ -63,7 +62,6 @@ pub use crate::{ change::{AnalysisChange, LibraryData}, completion::{CompletionItem, CompletionItemKind, InsertTextFormat}, runnables::{Runnable, RunnableKind}, - navigation_target::NavigationTarget, references::ReferenceSearchResult, assists::{Assist, AssistId}, hover::{HoverResult}, @@ -73,7 +71,7 @@ pub use crate::{ syntax_highlighting::HighlightedRange, structure::{StructureNode, file_structure}, diagnostics::Severity, - display::FunctionSignature, + display::{FunctionSignature, NavigationTarget}, }; pub use ra_db::{ diff --git a/crates/ra_ide_api/src/symbol_index.rs b/crates/ra_ide_api/src/symbol_index.rs index 0eadc4e71980..914d3fc71a3a 100644 --- a/crates/ra_ide_api/src/symbol_index.rs +++ b/crates/ra_ide_api/src/symbol_index.rs @@ -275,7 +275,7 @@ fn to_file_symbol(node: &SyntaxNode, file_id: FileId) -> Option { mod tests { use ra_syntax::SmolStr; use crate::{ - navigation_target::NavigationTarget, + display::NavigationTarget, mock_analysis::single_file, Query, }; From 7821c56be7fc1699f6fb748e45f4765162b75ba9 Mon Sep 17 00:00:00 2001 From: Ville Penttinen Date: Mon, 8 Apr 2019 16:04:58 +0300 Subject: [PATCH 11/15] Move structure to display/structure --- crates/ra_ide_api/src/display.rs | 6 ++++-- .../src/{ => display}/snapshots/tests__file_structure.snap | 6 +++--- crates/ra_ide_api/src/{ => display}/structure.rs | 0 crates/ra_ide_api/src/lib.rs | 6 ++---- 4 files changed, 9 insertions(+), 9 deletions(-) rename crates/ra_ide_api/src/{ => display}/snapshots/tests__file_structure.snap (97%) rename crates/ra_ide_api/src/{ => display}/structure.rs (100%) diff --git a/crates/ra_ide_api/src/display.rs b/crates/ra_ide_api/src/display.rs index f0c818933064..7a1f40fcfb18 100644 --- a/crates/ra_ide_api/src/display.rs +++ b/crates/ra_ide_api/src/display.rs @@ -1,5 +1,5 @@ -//! This module contains utilities for rendering turning things into something -//! that may be used to render in UI. +//! This module contains utilities for turning SyntaxNodes and HIR types +//! into things that may be used to render in a UI. use super::*; use std::fmt::{self, Display}; use join_to_string::join; @@ -8,8 +8,10 @@ use std::convert::From; use hir::Docs; pub mod navigation_target; +pub mod structure; pub use navigation_target::NavigationTarget; +pub use structure::StructureNode; pub(crate) fn function_label(node: &ast::FnDef) -> String { FunctionSignature::from(node).to_string() diff --git a/crates/ra_ide_api/src/snapshots/tests__file_structure.snap b/crates/ra_ide_api/src/display/snapshots/tests__file_structure.snap similarity index 97% rename from crates/ra_ide_api/src/snapshots/tests__file_structure.snap rename to crates/ra_ide_api/src/display/snapshots/tests__file_structure.snap index 2efa8e22cb39..32dd994849e3 100644 --- a/crates/ra_ide_api/src/snapshots/tests__file_structure.snap +++ b/crates/ra_ide_api/src/display/snapshots/tests__file_structure.snap @@ -1,7 +1,7 @@ --- -created: "2019-02-05T22:03:50.763530100Z" -creator: insta@0.6.1 -source: crates/ra_ide_api/src/structure.rs +created: "2019-04-08T09:44:50.196004400Z" +creator: insta@0.7.4 +source: crates/ra_ide_api/src/display/structure.rs expression: structure --- [ diff --git a/crates/ra_ide_api/src/structure.rs b/crates/ra_ide_api/src/display/structure.rs similarity index 100% rename from crates/ra_ide_api/src/structure.rs rename to crates/ra_ide_api/src/display/structure.rs diff --git a/crates/ra_ide_api/src/lib.rs b/crates/ra_ide_api/src/lib.rs index d76012a8c836..974820a69470 100644 --- a/crates/ra_ide_api/src/lib.rs +++ b/crates/ra_ide_api/src/lib.rs @@ -33,7 +33,6 @@ mod folding_ranges; mod line_index; mod line_index_utils; mod join_lines; -mod structure; mod typing; mod matching_brace; mod display; @@ -69,9 +68,8 @@ pub use crate::{ line_index_utils::translate_offset_with_edit, folding_ranges::{Fold, FoldKind}, syntax_highlighting::HighlightedRange, - structure::{StructureNode, file_structure}, diagnostics::Severity, - display::{FunctionSignature, NavigationTarget}, + display::{FunctionSignature, NavigationTarget, structure::{StructureNode, file_structure}}, }; pub use ra_db::{ @@ -385,7 +383,7 @@ impl Analysis { /// file outline. pub fn file_structure(&self, file_id: FileId) -> Vec { let file = self.db.parse(file_id); - structure::file_structure(&file) + file_structure(&file) } /// Returns the set of folding ranges. From bd6ddfcddebf532e5fa0fe89c00a53e59a5d0704 Mon Sep 17 00:00:00 2001 From: Ville Penttinen Date: Mon, 8 Apr 2019 16:07:50 +0300 Subject: [PATCH 12/15] Make display modules private --- crates/ra_ide_api/src/display.rs | 9 +++++---- crates/ra_ide_api/src/lib.rs | 2 +- 2 files changed, 6 insertions(+), 5 deletions(-) diff --git a/crates/ra_ide_api/src/display.rs b/crates/ra_ide_api/src/display.rs index 7a1f40fcfb18..e29ae3371334 100644 --- a/crates/ra_ide_api/src/display.rs +++ b/crates/ra_ide_api/src/display.rs @@ -1,5 +1,9 @@ //! This module contains utilities for turning SyntaxNodes and HIR types //! into things that may be used to render in a UI. + +mod navigation_target; +mod structure; + use super::*; use std::fmt::{self, Display}; use join_to_string::join; @@ -7,11 +11,8 @@ use ra_syntax::{ast::{self, AstNode, NameOwner, VisibilityOwner, TypeParamsOwner use std::convert::From; use hir::Docs; -pub mod navigation_target; -pub mod structure; - pub use navigation_target::NavigationTarget; -pub use structure::StructureNode; +pub use structure::{StructureNode, file_structure}; pub(crate) fn function_label(node: &ast::FnDef) -> String { FunctionSignature::from(node).to_string() diff --git a/crates/ra_ide_api/src/lib.rs b/crates/ra_ide_api/src/lib.rs index 974820a69470..d25795adcea7 100644 --- a/crates/ra_ide_api/src/lib.rs +++ b/crates/ra_ide_api/src/lib.rs @@ -69,7 +69,7 @@ pub use crate::{ folding_ranges::{Fold, FoldKind}, syntax_highlighting::HighlightedRange, diagnostics::Severity, - display::{FunctionSignature, NavigationTarget, structure::{StructureNode, file_structure}}, + display::{FunctionSignature, NavigationTarget, StructureNode, file_structure}, }; pub use ra_db::{ From fead60aa27e54d3ce48819c30d1db59c52d856c9 Mon Sep 17 00:00:00 2001 From: Ville Penttinen Date: Mon, 8 Apr 2019 16:34:59 +0300 Subject: [PATCH 13/15] Move FunctionSignature to display/function_signature --- crates/ra_ide_api/src/display.rs | 103 +----------------- .../src/display/function_signature.rs | 101 +++++++++++++++++ 2 files changed, 104 insertions(+), 100 deletions(-) create mode 100644 crates/ra_ide_api/src/display/function_signature.rs diff --git a/crates/ra_ide_api/src/display.rs b/crates/ra_ide_api/src/display.rs index e29ae3371334..f1717b008976 100644 --- a/crates/ra_ide_api/src/display.rs +++ b/crates/ra_ide_api/src/display.rs @@ -1,18 +1,15 @@ //! This module contains utilities for turning SyntaxNodes and HIR types //! into things that may be used to render in a UI. +mod function_signature; mod navigation_target; mod structure; -use super::*; -use std::fmt::{self, Display}; -use join_to_string::join; -use ra_syntax::{ast::{self, AstNode, NameOwner, VisibilityOwner, TypeParamsOwner}, SyntaxKind::{ATTR, COMMENT}}; -use std::convert::From; -use hir::Docs; +use ra_syntax::{ast::{self, AstNode, TypeParamsOwner}, SyntaxKind::{ATTR, COMMENT}}; pub use navigation_target::NavigationTarget; pub use structure::{StructureNode, file_structure}; +pub use function_signature::FunctionSignature; pub(crate) fn function_label(node: &ast::FnDef) -> String { FunctionSignature::from(node).to_string() @@ -40,100 +37,6 @@ pub(crate) fn type_label(node: &ast::TypeAliasDef) -> String { label.trim().to_owned() } -/// Contains information about a function signature -#[derive(Debug)] -pub struct FunctionSignature { - /// Optional visibility - pub visibility: Option, - /// Name of the function - pub name: Option, - /// Documentation for the function - pub doc: Option, - /// Generic parameters - pub generic_parameters: Vec, - /// Parameters of the function - pub parameters: Vec, - /// Optional return type - pub ret_type: Option, - /// Where predicates - pub where_predicates: Vec, -} - -impl FunctionSignature { - pub(crate) fn with_doc_opt(mut self, doc: Option) -> Self { - self.doc = doc; - self - } - - pub(crate) fn from_hir(db: &db::RootDatabase, function: hir::Function) -> Self { - let doc = function.docs(db); - let (_, ast_node) = function.source(db); - FunctionSignature::from(&*ast_node).with_doc_opt(doc) - } -} - -impl From<&'_ ast::FnDef> for FunctionSignature { - fn from(node: &ast::FnDef) -> FunctionSignature { - fn param_list(node: &ast::FnDef) -> Vec { - let mut res = vec![]; - if let Some(param_list) = node.param_list() { - if let Some(self_param) = param_list.self_param() { - res.push(self_param.syntax().text().to_string()) - } - - res.extend(param_list.params().map(|param| param.syntax().text().to_string())); - } - res - } - - FunctionSignature { - visibility: node.visibility().map(|n| n.syntax().text().to_string()), - name: node.name().map(|n| n.text().to_string()), - ret_type: node - .ret_type() - .and_then(|r| r.type_ref()) - .map(|n| n.syntax().text().to_string()), - parameters: param_list(node), - generic_parameters: generic_parameters(node), - where_predicates: where_predicates(node), - // docs are processed separately - doc: None, - } - } -} - -impl Display for FunctionSignature { - fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { - if let Some(t) = &self.visibility { - write!(f, "{} ", t)?; - } - - if let Some(name) = &self.name { - write!(f, "fn {}", name)?; - } - - if !self.generic_parameters.is_empty() { - join(self.generic_parameters.iter()) - .separator(", ") - .surround_with("<", ">") - .to_fmt(f)?; - } - - join(self.parameters.iter()).separator(", ").surround_with("(", ")").to_fmt(f)?; - - if let Some(t) = &self.ret_type { - write!(f, " -> {}", t)?; - } - - if !self.where_predicates.is_empty() { - write!(f, "\nwhere ")?; - join(self.where_predicates.iter()).separator(",\n ").to_fmt(f)?; - } - - Ok(()) - } -} - pub(crate) fn generic_parameters(node: &N) -> Vec { let mut res = vec![]; if let Some(type_params) = node.type_param_list() { diff --git a/crates/ra_ide_api/src/display/function_signature.rs b/crates/ra_ide_api/src/display/function_signature.rs new file mode 100644 index 000000000000..d09950bce02f --- /dev/null +++ b/crates/ra_ide_api/src/display/function_signature.rs @@ -0,0 +1,101 @@ +use super::{where_predicates, generic_parameters}; +use crate::db; +use std::fmt::{self, Display}; +use join_to_string::join; +use ra_syntax::ast::{self, AstNode, NameOwner, VisibilityOwner}; +use std::convert::From; +use hir::{Docs, Documentation}; + +/// Contains information about a function signature +#[derive(Debug)] +pub struct FunctionSignature { + /// Optional visibility + pub visibility: Option, + /// Name of the function + pub name: Option, + /// Documentation for the function + pub doc: Option, + /// Generic parameters + pub generic_parameters: Vec, + /// Parameters of the function + pub parameters: Vec, + /// Optional return type + pub ret_type: Option, + /// Where predicates + pub where_predicates: Vec, +} + +impl FunctionSignature { + pub(crate) fn with_doc_opt(mut self, doc: Option) -> Self { + self.doc = doc; + self + } + + pub(crate) fn from_hir(db: &db::RootDatabase, function: hir::Function) -> Self { + let doc = function.docs(db); + let (_, ast_node) = function.source(db); + FunctionSignature::from(&*ast_node).with_doc_opt(doc) + } +} + +impl From<&'_ ast::FnDef> for FunctionSignature { + fn from(node: &ast::FnDef) -> FunctionSignature { + fn param_list(node: &ast::FnDef) -> Vec { + let mut res = vec![]; + if let Some(param_list) = node.param_list() { + if let Some(self_param) = param_list.self_param() { + res.push(self_param.syntax().text().to_string()) + } + + res.extend(param_list.params().map(|param| param.syntax().text().to_string())); + } + res + } + + FunctionSignature { + visibility: node.visibility().map(|n| n.syntax().text().to_string()), + name: node.name().map(|n| n.text().to_string()), + ret_type: node + .ret_type() + .and_then(|r| r.type_ref()) + .map(|n| n.syntax().text().to_string()), + parameters: param_list(node), + generic_parameters: generic_parameters(node), + where_predicates: where_predicates(node), + // docs are processed separately + doc: None, + } + } +} + +impl Display for FunctionSignature { + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + if let Some(t) = &self.visibility { + write!(f, "{} ", t)?; + } + + if let Some(name) = &self.name { + write!(f, "fn {}", name)?; + } + + if !self.generic_parameters.is_empty() { + join(self.generic_parameters.iter()) + .separator(", ") + .surround_with("<", ">") + .to_fmt(f)?; + } + + join(self.parameters.iter()).separator(", ").surround_with("(", ")").to_fmt(f)?; + + if let Some(t) = &self.ret_type { + write!(f, " -> {}", t)?; + } + + if !self.where_predicates.is_empty() { + write!(f, "\nwhere ")?; + join(self.where_predicates.iter()).separator(",\n ").to_fmt(f)?; + } + + Ok(()) + } +} From 07f0069f342afa17536aa4b9db4250f4d6c83954 Mon Sep 17 00:00:00 2001 From: Ville Penttinen Date: Tue, 9 Apr 2019 14:43:11 +0300 Subject: [PATCH 14/15] Move display related things from hover to display --- crates/ra_ide_api/src/display.rs | 27 +++++ .../src/display/navigation_target.rs | 82 ++++++++++++- crates/ra_ide_api/src/hover.rs | 110 +----------------- 3 files changed, 110 insertions(+), 109 deletions(-) diff --git a/crates/ra_ide_api/src/display.rs b/crates/ra_ide_api/src/display.rs index f1717b008976..b68b3a719428 100644 --- a/crates/ra_ide_api/src/display.rs +++ b/crates/ra_ide_api/src/display.rs @@ -5,6 +5,7 @@ mod function_signature; mod navigation_target; mod structure; +use crate::db::RootDatabase; use ra_syntax::{ast::{self, AstNode, TypeParamsOwner}, SyntaxKind::{ATTR, COMMENT}}; pub use navigation_target::NavigationTarget; @@ -53,3 +54,29 @@ pub(crate) fn where_predicates(node: &N) -> Vec { } res } + +pub(crate) fn rust_code_markup>(val: CODE) -> String { + rust_code_markup_with_doc::<_, &str>(val, None) +} + +pub(crate) fn rust_code_markup_with_doc(val: CODE, doc: Option) -> String +where + CODE: AsRef, + DOC: AsRef, +{ + if let Some(doc) = doc { + format!("```rust\n{}\n```\n\n{}", val.as_ref(), doc.as_ref()) + } else { + format!("```rust\n{}\n```", val.as_ref()) + } +} + +// FIXME: this should not really use navigation target. Rather, approximately +// resolved symbol should return a `DefId`. +pub(crate) fn doc_text_for(db: &RootDatabase, nav: NavigationTarget) -> Option { + match (nav.description(db), nav.docs(db)) { + (Some(desc), docs) => Some(rust_code_markup_with_doc(desc, docs)), + (None, Some(docs)) => Some(docs), + _ => None, + } +} diff --git a/crates/ra_ide_api/src/display/navigation_target.rs b/crates/ra_ide_api/src/display/navigation_target.rs index f6d7f31929f4..3c518faf50f0 100644 --- a/crates/ra_ide_api/src/display/navigation_target.rs +++ b/crates/ra_ide_api/src/display/navigation_target.rs @@ -1,7 +1,9 @@ -use ra_db::FileId; +use ra_db::{FileId, SourceDatabase}; use ra_syntax::{ - SyntaxNode, SyntaxNodePtr, AstNode, SmolStr, TextRange, ast, + SyntaxNode, SyntaxNodePtr, AstNode, SmolStr, TextRange, TreeArc, SyntaxKind::{self, NAME}, + ast::{self, NameOwner, VisibilityOwner, TypeAscriptionOwner}, + algo::visit::{visitor, Visitor}, }; use hir::{ModuleSource, FieldSource, Name, ImplItem}; @@ -248,4 +250,80 @@ impl NavigationTarget { container_name: None, } } + + pub(crate) fn node(&self, db: &RootDatabase) -> Option> { + let source_file = db.parse(self.file_id()); + let source_file = source_file.syntax(); + let node = source_file + .descendants() + .find(|node| node.kind() == self.kind() && node.range() == self.full_range())? + .to_owned(); + Some(node) + } + + pub(crate) fn docs(&self, db: &RootDatabase) -> Option { + let node = self.node(db)?; + fn doc_comments(node: &N) -> Option { + node.doc_comment_text() + } + + visitor() + .visit(doc_comments::) + .visit(doc_comments::) + .visit(doc_comments::) + .visit(doc_comments::) + .visit(doc_comments::) + .visit(doc_comments::) + .visit(doc_comments::) + .visit(doc_comments::) + .visit(doc_comments::) + .visit(doc_comments::) + .accept(&node)? + } + + /// Get a description of this node. + /// + /// e.g. `struct Name`, `enum Name`, `fn Name` + pub(crate) fn description(&self, db: &RootDatabase) -> Option { + // FIXME: After type inference is done, add type information to improve the output + let node = self.node(db)?; + + fn visit_ascribed_node(node: &T, prefix: &str) -> Option + where + T: NameOwner + VisibilityOwner + TypeAscriptionOwner, + { + let mut string = visit_node(node, prefix)?; + + if let Some(type_ref) = node.ascribed_type() { + string.push_str(": "); + type_ref.syntax().text().push_to(&mut string); + } + + Some(string) + } + + fn visit_node(node: &T, label: &str) -> Option + where + T: NameOwner + VisibilityOwner, + { + let mut string = + node.visibility().map(|v| format!("{} ", v.syntax().text())).unwrap_or_default(); + string.push_str(label); + string.push_str(node.name()?.text().as_str()); + Some(string) + } + + visitor() + .visit(|node: &ast::FnDef| Some(crate::display::function_label(node))) + .visit(|node: &ast::StructDef| visit_node(node, "struct ")) + .visit(|node: &ast::EnumDef| visit_node(node, "enum ")) + .visit(|node: &ast::TraitDef| visit_node(node, "trait ")) + .visit(|node: &ast::Module| visit_node(node, "mod ")) + .visit(|node: &ast::TypeAliasDef| visit_node(node, "type ")) + .visit(|node: &ast::ConstDef| visit_ascribed_node(node, "const ")) + .visit(|node: &ast::StaticDef| visit_ascribed_node(node, "static ")) + .visit(|node: &ast::NamedFieldDef| visit_ascribed_node(node, "")) + .visit(|node: &ast::EnumVariant| Some(node.name()?.text().to_string())) + .accept(&node)? + } } diff --git a/crates/ra_ide_api/src/hover.rs b/crates/ra_ide_api/src/hover.rs index 7d2c57f82cfd..3a8c93b99fc4 100644 --- a/crates/ra_ide_api/src/hover.rs +++ b/crates/ra_ide_api/src/hover.rs @@ -1,11 +1,11 @@ use ra_db::SourceDatabase; use ra_syntax::{ - AstNode, SyntaxNode, TreeArc, ast::{self, NameOwner, VisibilityOwner, TypeAscriptionOwner}, - algo::{find_covering_element, find_node_at_offset, find_token_at_offset, visit::{visitor, Visitor}}, + AstNode, ast, + algo::{find_covering_element, find_node_at_offset, find_token_at_offset}, }; use hir::HirDisplay; -use crate::{db::RootDatabase, RangeInfo, FilePosition, FileRange, NavigationTarget}; +use crate::{db::RootDatabase, RangeInfo, FilePosition, FileRange, display::{rust_code_markup, doc_text_for}}; /// Contains the results when hovering over an item #[derive(Debug, Clone)] @@ -145,110 +145,6 @@ pub(crate) fn type_of(db: &RootDatabase, frange: FileRange) -> Option { } } -fn rust_code_markup>(val: CODE) -> String { - rust_code_markup_with_doc::<_, &str>(val, None) -} - -fn rust_code_markup_with_doc(val: CODE, doc: Option) -> String -where - CODE: AsRef, - DOC: AsRef, -{ - if let Some(doc) = doc { - format!("```rust\n{}\n```\n\n{}", val.as_ref(), doc.as_ref()) - } else { - format!("```rust\n{}\n```", val.as_ref()) - } -} - -// FIXME: this should not really use navigation target. Rather, approximately -// resolved symbol should return a `DefId`. -fn doc_text_for(db: &RootDatabase, nav: NavigationTarget) -> Option { - match (nav.description(db), nav.docs(db)) { - (Some(desc), docs) => Some(rust_code_markup_with_doc(desc, docs)), - (None, Some(docs)) => Some(docs), - _ => None, - } -} - -impl NavigationTarget { - fn node(&self, db: &RootDatabase) -> Option> { - let source_file = db.parse(self.file_id()); - let source_file = source_file.syntax(); - let node = source_file - .descendants() - .find(|node| node.kind() == self.kind() && node.range() == self.full_range())? - .to_owned(); - Some(node) - } - - fn docs(&self, db: &RootDatabase) -> Option { - let node = self.node(db)?; - fn doc_comments(node: &N) -> Option { - node.doc_comment_text() - } - - visitor() - .visit(doc_comments::) - .visit(doc_comments::) - .visit(doc_comments::) - .visit(doc_comments::) - .visit(doc_comments::) - .visit(doc_comments::) - .visit(doc_comments::) - .visit(doc_comments::) - .visit(doc_comments::) - .visit(doc_comments::) - .accept(&node)? - } - - /// Get a description of this node. - /// - /// e.g. `struct Name`, `enum Name`, `fn Name` - fn description(&self, db: &RootDatabase) -> Option { - // FIXME: After type inference is done, add type information to improve the output - let node = self.node(db)?; - - fn visit_ascribed_node(node: &T, prefix: &str) -> Option - where - T: NameOwner + VisibilityOwner + TypeAscriptionOwner, - { - let mut string = visit_node(node, prefix)?; - - if let Some(type_ref) = node.ascribed_type() { - string.push_str(": "); - type_ref.syntax().text().push_to(&mut string); - } - - Some(string) - } - - fn visit_node(node: &T, label: &str) -> Option - where - T: NameOwner + VisibilityOwner, - { - let mut string = - node.visibility().map(|v| format!("{} ", v.syntax().text())).unwrap_or_default(); - string.push_str(label); - string.push_str(node.name()?.text().as_str()); - Some(string) - } - - visitor() - .visit(|node: &ast::FnDef| Some(crate::display::function_label(node))) - .visit(|node: &ast::StructDef| visit_node(node, "struct ")) - .visit(|node: &ast::EnumDef| visit_node(node, "enum ")) - .visit(|node: &ast::TraitDef| visit_node(node, "trait ")) - .visit(|node: &ast::Module| visit_node(node, "mod ")) - .visit(|node: &ast::TypeAliasDef| visit_node(node, "type ")) - .visit(|node: &ast::ConstDef| visit_ascribed_node(node, "const ")) - .visit(|node: &ast::StaticDef| visit_ascribed_node(node, "static ")) - .visit(|node: &ast::NamedFieldDef| visit_ascribed_node(node, "")) - .visit(|node: &ast::EnumVariant| Some(node.name()?.text().to_string())) - .accept(&node)? - } -} - #[cfg(test)] mod tests { use ra_syntax::TextRange; From 45a2b9252401cc580dfa2e0e761313cc8334d47c Mon Sep 17 00:00:00 2001 From: Ville Penttinen Date: Tue, 9 Apr 2019 16:08:24 +0300 Subject: [PATCH 15/15] Fix doc comment --- crates/ra_ide_api/src/display.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/crates/ra_ide_api/src/display.rs b/crates/ra_ide_api/src/display.rs index b68b3a719428..1b06abf94f5d 100644 --- a/crates/ra_ide_api/src/display.rs +++ b/crates/ra_ide_api/src/display.rs @@ -1,5 +1,5 @@ //! This module contains utilities for turning SyntaxNodes and HIR types -//! into things that may be used to render in a UI. +//! into types that may be used to render in a UI. mod function_signature; mod navigation_target;