From 00d927a1885ec2938d3365a8e136993445b437f5 Mon Sep 17 00:00:00 2001 From: David Wood Date: Tue, 5 Mar 2019 22:29:23 +0100 Subject: Initial implementation of project-lock.json. This commit adds a initial implementation of project-lock.json, a build system agnostic method of specifying the crate graph and roots. --- crates/ra_lsp_server/src/cargo_target_spec.rs | 20 +++---- crates/ra_lsp_server/src/server_world.rs | 9 +--- crates/ra_lsp_server/tests/heavy_tests/main.rs | 65 ++++++++++++++++++++++- crates/ra_lsp_server/tests/heavy_tests/support.rs | 6 ++- 4 files changed, 82 insertions(+), 18 deletions(-) (limited to 'crates/ra_lsp_server') diff --git a/crates/ra_lsp_server/src/cargo_target_spec.rs b/crates/ra_lsp_server/src/cargo_target_spec.rs index e011eab7c..cdf2ec10b 100644 --- a/crates/ra_lsp_server/src/cargo_target_spec.rs +++ b/crates/ra_lsp_server/src/cargo_target_spec.rs @@ -1,5 +1,5 @@ use crate::{ - project_model::TargetKind, + project_model::{self, TargetKind}, server_world::ServerWorld, Result }; @@ -65,14 +65,16 @@ impl CargoTargetSpec { }; let file_id = world.analysis().crate_root(crate_id)?; let path = world.vfs.read().file2path(ra_vfs::VfsFile(file_id.0.into())); - let res = world.workspaces.iter().find_map(|ws| { - let tgt = ws.cargo.target_by_root(&path)?; - let res = CargoTargetSpec { - package: tgt.package(&ws.cargo).name(&ws.cargo).to_string(), - target: tgt.name(&ws.cargo).to_string(), - target_kind: tgt.kind(&ws.cargo), - }; - Some(res) + let res = world.workspaces.iter().find_map(|ws| match ws { + project_model::ProjectWorkspace::Cargo { cargo, .. } => { + let tgt = cargo.target_by_root(&path)?; + Some(CargoTargetSpec { + package: tgt.package(&cargo).name(&cargo).to_string(), + target: tgt.name(&cargo).to_string(), + target_kind: tgt.kind(&cargo), + }) + } + project_model::ProjectWorkspace::Json { .. } => None, }); Ok(res) } diff --git a/crates/ra_lsp_server/src/server_world.rs b/crates/ra_lsp_server/src/server_world.rs index 4a68c019f..4625a26a7 100644 --- a/crates/ra_lsp_server/src/server_world.rs +++ b/crates/ra_lsp_server/src/server_world.rs @@ -40,12 +40,7 @@ impl ServerWorldState { let mut roots = Vec::new(); roots.push(root.clone()); for ws in workspaces.iter() { - for pkg in ws.cargo.packages() { - roots.push(pkg.root(&ws.cargo).to_path_buf()); - } - for krate in ws.sysroot.crates() { - roots.push(krate.root_dir(&ws.sysroot).to_path_buf()) - } + ws.add_roots(&mut roots); } let (mut vfs, roots) = Vfs::new(roots); let roots_to_scan = roots.len(); @@ -185,7 +180,7 @@ impl ServerWorld { } else { res.push_str("workspaces:\n"); for w in self.workspaces.iter() { - res += &format!("{} packages loaded\n", w.cargo.packages().count()); + res += &format!("{} packages loaded\n", w.count()); } } res.push_str("\nanalysis:\n"); diff --git a/crates/ra_lsp_server/tests/heavy_tests/main.rs b/crates/ra_lsp_server/tests/heavy_tests/main.rs index 1c099a78f..641f84cfc 100644 --- a/crates/ra_lsp_server/tests/heavy_tests/main.rs +++ b/crates/ra_lsp_server/tests/heavy_tests/main.rs @@ -12,8 +12,9 @@ use ra_lsp_server::req::{ CodeActionParams, CodeActionRequest, Formatting, Runnables, RunnablesParams, CompletionParams, Completion, }; use serde_json::json; +use tempfile::TempDir; -use crate::support::project; +use crate::support::{project, project_with_tmpdir}; const LOG: &'static str = ""; @@ -258,3 +259,65 @@ fn main() {} json!([]), ); } + +#[test] +fn test_missing_module_code_action_in_json_project() { + let tmp_dir = TempDir::new().unwrap(); + let code = format!( + r#" +//- rust-project.json +{{ + "roots": [ "{PATH}" ], + "crates": [ {{ "root_module": "{PATH}/src/lib.rs", "deps": [], "edition": "2015" }} ] +}} + +//- src/lib.rs +mod bar; + +fn main() {} +"#, + PATH = tmp_dir.path().display() + ); + let server = project_with_tmpdir(tmp_dir, &code); + server.wait_for_feedback("workspace loaded"); + let empty_context = || CodeActionContext { diagnostics: Vec::new(), only: None }; + server.request::( + CodeActionParams { + text_document: server.doc_id("src/lib.rs"), + range: Range::new(Position::new(0, 4), Position::new(0, 7)), + context: empty_context(), + }, + json!([ + { + "command": { + "arguments": [ + { + "cursorPosition": null, + "label": "create module", + "workspaceEdit": { + "documentChanges": [ + { + "kind": "create", + "uri": "file:///[..]/src/bar.rs" + } + ] + } + } + ], + "command": "rust-analyzer.applySourceChange", + "title": "create module" + }, + "title": "create module" + } + ]), + ); + + server.request::( + CodeActionParams { + text_document: server.doc_id("src/lib.rs"), + range: Range::new(Position::new(2, 4), Position::new(2, 7)), + context: empty_context(), + }, + json!([]), + ); +} diff --git a/crates/ra_lsp_server/tests/heavy_tests/support.rs b/crates/ra_lsp_server/tests/heavy_tests/support.rs index 8bfc8d622..e02d7858e 100644 --- a/crates/ra_lsp_server/tests/heavy_tests/support.rs +++ b/crates/ra_lsp_server/tests/heavy_tests/support.rs @@ -27,12 +27,16 @@ use ra_lsp_server::{ }; pub fn project(fixture: &str) -> Server { + let tmp_dir = TempDir::new().unwrap(); + project_with_tmpdir(tmp_dir, fixture) +} + +pub fn project_with_tmpdir(tmp_dir: TempDir, fixture: &str) -> Server { static INIT: Once = Once::new(); INIT.call_once(|| { let _ = Logger::with_env_or_str(crate::LOG).start().unwrap(); }); - let tmp_dir = TempDir::new().unwrap(); let mut paths = vec![]; for entry in parse_fixture(fixture) { -- cgit v1.2.3 From 614dd3c34721a4f97e8c4f1eb89aed4362338ebb Mon Sep 17 00:00:00 2001 From: David Wood Date: Thu, 7 Mar 2019 00:39:50 +0100 Subject: Rename and change `add_roots` to return a `Vec`. --- crates/ra_lsp_server/src/server_world.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'crates/ra_lsp_server') diff --git a/crates/ra_lsp_server/src/server_world.rs b/crates/ra_lsp_server/src/server_world.rs index 4625a26a7..7163568b9 100644 --- a/crates/ra_lsp_server/src/server_world.rs +++ b/crates/ra_lsp_server/src/server_world.rs @@ -40,7 +40,7 @@ impl ServerWorldState { let mut roots = Vec::new(); roots.push(root.clone()); for ws in workspaces.iter() { - ws.add_roots(&mut roots); + roots.extend(ws.to_roots()); } let (mut vfs, roots) = Vfs::new(roots); let roots_to_scan = roots.len(); -- cgit v1.2.3 From 3bc33ae712d24f19f348828b0b18cda3d09a2360 Mon Sep 17 00:00:00 2001 From: David Wood Date: Thu, 7 Mar 2019 00:53:26 +0100 Subject: Add test demonstrating logic for handling deps. --- crates/ra_lsp_server/tests/heavy_tests/main.rs | 45 +++++++++++++++++++++++++- 1 file changed, 44 insertions(+), 1 deletion(-) (limited to 'crates/ra_lsp_server') diff --git a/crates/ra_lsp_server/tests/heavy_tests/main.rs b/crates/ra_lsp_server/tests/heavy_tests/main.rs index 641f84cfc..8e4e1fb88 100644 --- a/crates/ra_lsp_server/tests/heavy_tests/main.rs +++ b/crates/ra_lsp_server/tests/heavy_tests/main.rs @@ -279,7 +279,7 @@ fn main() {} PATH = tmp_dir.path().display() ); let server = project_with_tmpdir(tmp_dir, &code); - server.wait_for_feedback("workspace loaded"); + server.wait_for_message("workspace loaded"); let empty_context = || CodeActionContext { diagnostics: Vec::new(), only: None }; server.request::( CodeActionParams { @@ -321,3 +321,46 @@ fn main() {} json!([]), ); } + +#[test] +fn completes_items_from_second_crate_in_json_project() { + let tmp_dir = TempDir::new().unwrap(); + let code = format!( + r#" +//- rust-project.json +{{ + "roots": [ "{PATH}" ], + "crates": [ + {{ + "root_module": "{PATH}/foo/lib.rs", + "deps": [ + {{ + "name": "bar", + "crate": 1 + }} + ], + "edition": "2015" + }}, + {{ "root_module": "{PATH}/bar/lib.rs", "deps": [], "edition": "2015" }} + ] +}} + +//- bar/lib.rs +pub struct Spam; +pub struct CannedMeat; + +//- foo/lib.rs +extern crate bar; +use bar::Spam; +"#, + PATH = tmp_dir.path().display() + ); + let server = project_with_tmpdir(tmp_dir, &code); + server.wait_for_message("workspace loaded"); + let res = server.send_request::(CompletionParams { + text_document: server.doc_id("foo/lib.rs"), + context: None, + position: Position::new(1, 10), + }); + assert!(format!("{}", res).contains("CannedMeat")); +} -- cgit v1.2.3 From 4cd757c1e32f0cf1f281b82cd55615d0e47edb24 Mon Sep 17 00:00:00 2001 From: David Wood Date: Thu, 7 Mar 2019 12:28:19 +0100 Subject: Remove rust-project.json test w/ dependencies. --- crates/ra_lsp_server/tests/heavy_tests/main.rs | 43 -------------------------- 1 file changed, 43 deletions(-) (limited to 'crates/ra_lsp_server') diff --git a/crates/ra_lsp_server/tests/heavy_tests/main.rs b/crates/ra_lsp_server/tests/heavy_tests/main.rs index 8e4e1fb88..41c240139 100644 --- a/crates/ra_lsp_server/tests/heavy_tests/main.rs +++ b/crates/ra_lsp_server/tests/heavy_tests/main.rs @@ -321,46 +321,3 @@ fn main() {} json!([]), ); } - -#[test] -fn completes_items_from_second_crate_in_json_project() { - let tmp_dir = TempDir::new().unwrap(); - let code = format!( - r#" -//- rust-project.json -{{ - "roots": [ "{PATH}" ], - "crates": [ - {{ - "root_module": "{PATH}/foo/lib.rs", - "deps": [ - {{ - "name": "bar", - "crate": 1 - }} - ], - "edition": "2015" - }}, - {{ "root_module": "{PATH}/bar/lib.rs", "deps": [], "edition": "2015" }} - ] -}} - -//- bar/lib.rs -pub struct Spam; -pub struct CannedMeat; - -//- foo/lib.rs -extern crate bar; -use bar::Spam; -"#, - PATH = tmp_dir.path().display() - ); - let server = project_with_tmpdir(tmp_dir, &code); - server.wait_for_message("workspace loaded"); - let res = server.send_request::(CompletionParams { - text_document: server.doc_id("foo/lib.rs"), - context: None, - position: Position::new(1, 10), - }); - assert!(format!("{}", res).contains("CannedMeat")); -} -- cgit v1.2.3