From f8a2b533045757c42c206b2596448baf4737f1f0 Mon Sep 17 00:00:00 2001 From: "Jeremy A. Kolb" Date: Tue, 9 Oct 2018 10:08:17 -0400 Subject: Language Server: textDocument/signatureHelp Implements a pretty barebones function signature help mechanism in the language server. Users can use `Analysis::resolve_callback()` to get basic information about a call site. Fixes #102 --- crates/ra_analysis/tests/tests.rs | 102 ++++++++++++++++++++++++++++++++++++-- 1 file changed, 98 insertions(+), 4 deletions(-) (limited to 'crates/ra_analysis/tests/tests.rs') diff --git a/crates/ra_analysis/tests/tests.rs b/crates/ra_analysis/tests/tests.rs index a886cd0ff..9417ddc1d 100644 --- a/crates/ra_analysis/tests/tests.rs +++ b/crates/ra_analysis/tests/tests.rs @@ -1,6 +1,8 @@ extern crate relative_path; extern crate ra_analysis; extern crate rustc_hash; +extern crate ra_editor; +extern crate ra_syntax; extern crate test_utils; use std::{ @@ -9,8 +11,8 @@ use std::{ use rustc_hash::FxHashMap; use relative_path::{RelativePath, RelativePathBuf}; -use ra_analysis::{Analysis, AnalysisHost, FileId, FileResolver, JobHandle, CrateGraph, CrateId}; -use test_utils::assert_eq_dbg; +use ra_analysis::{Analysis, AnalysisHost, FileId, FileResolver, JobHandle, CrateGraph, CrateId, FnDescriptor}; +use test_utils::{assert_eq_dbg, extract_offset}; #[derive(Debug)] struct FileMap(Vec<(FileId, RelativePathBuf)>); @@ -39,7 +41,7 @@ impl FileResolver for FileMap { } } -fn analysis_host(files: &'static [(&'static str, &'static str)]) -> AnalysisHost { +fn analysis_host(files: &[(&str, &str)]) -> AnalysisHost { let mut host = AnalysisHost::new(); let mut file_map = Vec::new(); for (id, &(path, contents)) in files.iter().enumerate() { @@ -53,10 +55,20 @@ fn analysis_host(files: &'static [(&'static str, &'static str)]) -> AnalysisHost host } -fn analysis(files: &'static [(&'static str, &'static str)]) -> Analysis { +fn analysis(files: &[(&str, &str)]) -> Analysis { analysis_host(files).analysis() } +fn get_signature(text: &str) -> (FnDescriptor, Option) { + let (offset, code) = extract_offset(text); + let code = code.as_str(); + + let (_handle, token) = JobHandle::new(); + let snap = analysis(&[("/lib.rs", code)]); + + snap.resolve_callable(FileId(1), offset, &token).unwrap() +} + #[test] fn test_resolve_module() { let snap = analysis(&[ @@ -145,3 +157,85 @@ fn test_resolve_crate_root() { vec![CrateId(1)], ); } + +#[test] +fn test_fn_signature_two_args_first() { + let (desc, param) = get_signature( +r#"fn foo(x: u32, y: u32) -> u32 {x + y} +fn bar() { foo(<|>3, ); }"#); + + assert_eq!(desc.name, Some("foo".into())); + assert_eq!(desc.params, vec!("x".to_string(),"y".to_string())); + assert_eq!(desc.ret_type, Some("-> u32".into())); + assert_eq!(param, Some(0)); +} + +#[test] +fn test_fn_signature_two_args_second() { + let (desc, param) = get_signature( + r#"fn foo(x: u32, y: u32) -> u32 {x + y} +fn bar() { foo(3, <|>); }"#); + + assert_eq!(desc.name, Some("foo".into())); + assert_eq!(desc.params, vec!("x".to_string(),"y".to_string())); + assert_eq!(desc.ret_type, Some("-> u32".into())); + assert_eq!(param, Some(1)); +} + +#[test] +fn test_fn_signature_for_impl() { + let (desc, param) = get_signature( +r#"struct F; impl F { pub fn new() { F{}} } +fn bar() {let _ : F = F::new(<|>);}"#); + + assert_eq!(desc.name, Some("new".into())); + assert_eq!(desc.params, Vec::::new()); + assert_eq!(desc.ret_type, None); + assert_eq!(param, None); +} + +#[test] +fn test_fn_signature_for_method_self() { + let (desc, param) = get_signature( +r#"struct F; +impl F { + pub fn new() -> F{ + F{} + } + + pub fn do_it(&self) {} +} + +fn bar() { + let f : F = F::new(); + f.do_it(<|>); +}"#); + + assert_eq!(desc.name, Some("do_it".into())); + assert_eq!(desc.params, vec!["&self".to_string()]); + assert_eq!(desc.ret_type, None); + assert_eq!(param, None); +} + +#[test] +fn test_fn_signature_for_method_with_arg() { + let (desc, param) = get_signature( +r#"struct F; +impl F { + pub fn new() -> F{ + F{} + } + + pub fn do_it(&self, x: i32) {} +} + +fn bar() { + let f : F = F::new(); + f.do_it(<|>); +}"#); + + assert_eq!(desc.name, Some("do_it".into())); + assert_eq!(desc.params, vec!["&self".to_string(), "x".to_string()]); + assert_eq!(desc.ret_type, None); + assert_eq!(param, Some(1)); +} \ No newline at end of file -- cgit v1.2.3