diff options
-rw-r--r-- | Cargo.lock | 16 | ||||
-rw-r--r-- | crates/ra_lsp_server/Cargo.toml | 2 | ||||
-rw-r--r-- | crates/ra_lsp_server/src/project_model.rs | 42 | ||||
-rw-r--r-- | crates/ra_project_model/Cargo.toml | 30 | ||||
-rw-r--r-- | crates/ra_project_model/src/cargo_workspace.rs (renamed from crates/ra_lsp_server/src/project_model/cargo_workspace.rs) | 8 | ||||
-rw-r--r-- | crates/ra_project_model/src/lib.rs | 45 | ||||
-rw-r--r-- | crates/ra_project_model/src/sysroot.rs (renamed from crates/ra_lsp_server/src/project_model/sysroot.rs) | 17 | ||||
-rw-r--r-- | crates/ra_syntax/Cargo.toml | 2 |
8 files changed, 109 insertions, 53 deletions
diff --git a/Cargo.lock b/Cargo.lock index 9c65b39f7..2f6a132a5 100644 --- a/Cargo.lock +++ b/Cargo.lock | |||
@@ -1008,7 +1008,6 @@ dependencies = [ | |||
1008 | name = "ra_lsp_server" | 1008 | name = "ra_lsp_server" |
1009 | version = "0.1.0" | 1009 | version = "0.1.0" |
1010 | dependencies = [ | 1010 | dependencies = [ |
1011 | "cargo_metadata 0.7.1 (registry+https://github.com/rust-lang/crates.io-index)", | ||
1012 | "crossbeam-channel 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)", | 1011 | "crossbeam-channel 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)", |
1013 | "drop_bomb 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)", | 1012 | "drop_bomb 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)", |
1014 | "failure 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)", | 1013 | "failure 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)", |
@@ -1021,6 +1020,7 @@ dependencies = [ | |||
1021 | "parking_lot 0.7.1 (registry+https://github.com/rust-lang/crates.io-index)", | 1020 | "parking_lot 0.7.1 (registry+https://github.com/rust-lang/crates.io-index)", |
1022 | "ra_arena 0.1.0", | 1021 | "ra_arena 0.1.0", |
1023 | "ra_ide_api 0.1.0", | 1022 | "ra_ide_api 0.1.0", |
1023 | "ra_project_model 0.1.0", | ||
1024 | "ra_syntax 0.1.0", | 1024 | "ra_syntax 0.1.0", |
1025 | "ra_text_edit 0.1.0", | 1025 | "ra_text_edit 0.1.0", |
1026 | "ra_vfs 0.1.0", | 1026 | "ra_vfs 0.1.0", |
@@ -1046,6 +1046,20 @@ dependencies = [ | |||
1046 | ] | 1046 | ] |
1047 | 1047 | ||
1048 | [[package]] | 1048 | [[package]] |
1049 | name = "ra_project_model" | ||
1050 | version = "0.1.0" | ||
1051 | dependencies = [ | ||
1052 | "cargo_metadata 0.7.1 (registry+https://github.com/rust-lang/crates.io-index)", | ||
1053 | "failure 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)", | ||
1054 | "failure_derive 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)", | ||
1055 | "ra_arena 0.1.0", | ||
1056 | "rustc-hash 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)", | ||
1057 | "smol_str 0.1.9 (registry+https://github.com/rust-lang/crates.io-index)", | ||
1058 | "test_utils 0.1.0", | ||
1059 | "walkdir 2.2.7 (registry+https://github.com/rust-lang/crates.io-index)", | ||
1060 | ] | ||
1061 | |||
1062 | [[package]] | ||
1049 | name = "ra_syntax" | 1063 | name = "ra_syntax" |
1050 | version = "0.1.0" | 1064 | version = "0.1.0" |
1051 | dependencies = [ | 1065 | dependencies = [ |
diff --git a/crates/ra_lsp_server/Cargo.toml b/crates/ra_lsp_server/Cargo.toml index bb92747f2..f46d77893 100644 --- a/crates/ra_lsp_server/Cargo.toml +++ b/crates/ra_lsp_server/Cargo.toml | |||
@@ -19,7 +19,6 @@ url_serde = "0.2.0" | |||
19 | lsp-types = "0.55.0" | 19 | lsp-types = "0.55.0" |
20 | walkdir = "2.2.7" | 20 | walkdir = "2.2.7" |
21 | im = "12.0.0" | 21 | im = "12.0.0" |
22 | cargo_metadata = "0.7.0" | ||
23 | rustc-hash = "1.0" | 22 | rustc-hash = "1.0" |
24 | parking_lot = "0.7.0" | 23 | parking_lot = "0.7.0" |
25 | 24 | ||
@@ -30,6 +29,7 @@ ra_ide_api = { path = "../ra_ide_api" } | |||
30 | ra_arena = { path = "../ra_arena" } | 29 | ra_arena = { path = "../ra_arena" } |
31 | gen_lsp_server = { path = "../gen_lsp_server" } | 30 | gen_lsp_server = { path = "../gen_lsp_server" } |
32 | ra_vfs = { path = "../ra_vfs" } | 31 | ra_vfs = { path = "../ra_vfs" } |
32 | ra_project_model = { path = "../ra_project_model" } | ||
33 | 33 | ||
34 | [dev-dependencies] | 34 | [dev-dependencies] |
35 | tempfile = "3" | 35 | tempfile = "3" |
diff --git a/crates/ra_lsp_server/src/project_model.rs b/crates/ra_lsp_server/src/project_model.rs index fd5875a0a..6800eb138 100644 --- a/crates/ra_lsp_server/src/project_model.rs +++ b/crates/ra_lsp_server/src/project_model.rs | |||
@@ -1,34 +1,13 @@ | |||
1 | mod cargo_workspace; | 1 | use std::path::PathBuf; |
2 | mod sysroot; | ||
3 | 2 | ||
4 | use std::path::{Path, PathBuf}; | ||
5 | |||
6 | use failure::bail; | ||
7 | use thread_worker::{WorkerHandle, Worker}; | 3 | use thread_worker::{WorkerHandle, Worker}; |
8 | 4 | ||
9 | use crate::Result; | 5 | use crate::Result; |
10 | 6 | ||
11 | pub use crate::project_model::{ | 7 | pub use ra_project_model::{ |
12 | cargo_workspace::{CargoWorkspace, Package, Target, TargetKind}, | 8 | ProjectWorkspace, CargoWorkspace, Package, Target, TargetKind, Sysroot, |
13 | sysroot::Sysroot, | ||
14 | }; | 9 | }; |
15 | 10 | ||
16 | #[derive(Debug, Clone)] | ||
17 | pub struct ProjectWorkspace { | ||
18 | pub(crate) cargo: CargoWorkspace, | ||
19 | pub(crate) sysroot: Sysroot, | ||
20 | } | ||
21 | |||
22 | impl ProjectWorkspace { | ||
23 | pub fn discover(path: &Path) -> Result<ProjectWorkspace> { | ||
24 | let cargo_toml = find_cargo_toml(path)?; | ||
25 | let cargo = CargoWorkspace::from_cargo_metadata(&cargo_toml)?; | ||
26 | let sysroot = Sysroot::discover(&cargo_toml)?; | ||
27 | let res = ProjectWorkspace { cargo, sysroot }; | ||
28 | Ok(res) | ||
29 | } | ||
30 | } | ||
31 | |||
32 | pub fn workspace_loader() -> (Worker<PathBuf, Result<ProjectWorkspace>>, WorkerHandle) { | 11 | pub fn workspace_loader() -> (Worker<PathBuf, Result<ProjectWorkspace>>, WorkerHandle) { |
33 | thread_worker::spawn::<PathBuf, Result<ProjectWorkspace>, _>( | 12 | thread_worker::spawn::<PathBuf, Result<ProjectWorkspace>, _>( |
34 | "workspace loader", | 13 | "workspace loader", |
@@ -42,18 +21,3 @@ pub fn workspace_loader() -> (Worker<PathBuf, Result<ProjectWorkspace>>, WorkerH | |||
42 | }, | 21 | }, |
43 | ) | 22 | ) |
44 | } | 23 | } |
45 | |||
46 | fn find_cargo_toml(path: &Path) -> Result<PathBuf> { | ||
47 | if path.ends_with("Cargo.toml") { | ||
48 | return Ok(path.to_path_buf()); | ||
49 | } | ||
50 | let mut curr = Some(path); | ||
51 | while let Some(path) = curr { | ||
52 | let candidate = path.join("Cargo.toml"); | ||
53 | if candidate.exists() { | ||
54 | return Ok(candidate); | ||
55 | } | ||
56 | curr = path.parent(); | ||
57 | } | ||
58 | bail!("can't find Cargo.toml at {}", path.display()) | ||
59 | } | ||
diff --git a/crates/ra_project_model/Cargo.toml b/crates/ra_project_model/Cargo.toml new file mode 100644 index 000000000..5215e5232 --- /dev/null +++ b/crates/ra_project_model/Cargo.toml | |||
@@ -0,0 +1,30 @@ | |||
1 | [package] | ||
2 | edition = "2018" | ||
3 | name = "ra_project_model" | ||
4 | version = "0.1.0" | ||
5 | authors = ["Aleksey Kladov <[email protected]>"] | ||
6 | |||
7 | [dependencies] | ||
8 | # itertools = "0.8.0" | ||
9 | # join_to_string = "0.1.3" | ||
10 | # log = "0.4.5" | ||
11 | # relative-path = "0.4.0" | ||
12 | # rayon = "1.0.2" | ||
13 | # fst = "0.3.1" | ||
14 | rustc-hash = "1.0" | ||
15 | # parking_lot = "0.7.0" | ||
16 | # unicase = "2.2.0" | ||
17 | |||
18 | # TODO get rid of these? | ||
19 | failure = "0.1.4" | ||
20 | failure_derive = "0.1.4" | ||
21 | |||
22 | smol_str = { version = "0.1.9", features = ["serde"] } | ||
23 | walkdir = "2.2.7" | ||
24 | |||
25 | cargo_metadata = "0.7.0" | ||
26 | |||
27 | ra_arena = { path = "../ra_arena" } | ||
28 | |||
29 | [dev-dependencies] | ||
30 | test_utils = { path = "../test_utils" } | ||
diff --git a/crates/ra_lsp_server/src/project_model/cargo_workspace.rs b/crates/ra_project_model/src/cargo_workspace.rs index 3b76389d2..f3e67d0e5 100644 --- a/crates/ra_lsp_server/src/project_model/cargo_workspace.rs +++ b/crates/ra_project_model/src/cargo_workspace.rs | |||
@@ -1,17 +1,17 @@ | |||
1 | use std::path::{Path, PathBuf}; | 1 | use std::path::{Path, PathBuf}; |
2 | 2 | ||
3 | use cargo_metadata::{MetadataCommand, CargoOpt}; | 3 | use cargo_metadata::{MetadataCommand, CargoOpt}; |
4 | use ra_syntax::SmolStr; | 4 | use smol_str::SmolStr; |
5 | use ra_arena::{Arena, RawId, impl_arena_id}; | 5 | use ra_arena::{Arena, RawId, impl_arena_id}; |
6 | use rustc_hash::FxHashMap; | 6 | use rustc_hash::FxHashMap; |
7 | use failure::format_err; | 7 | use failure::format_err; |
8 | 8 | ||
9 | use crate::Result; | 9 | use crate::Result; |
10 | 10 | ||
11 | /// `CargoWorksapce` represents the logical structure of, well, a Cargo | 11 | /// `CargoWorkspace` represents the logical structure of, well, a Cargo |
12 | /// workspace. It pretty closely mirrors `cargo metadata` output. | 12 | /// workspace. It pretty closely mirrors `cargo metadata` output. |
13 | /// | 13 | /// |
14 | /// Note that internally, rust analyzer uses a differnet structure: | 14 | /// Note that internally, rust analyzer uses a different structure: |
15 | /// `CrateGraph`. `CrateGraph` is lower-level: it knows only about the crates, | 15 | /// `CrateGraph`. `CrateGraph` is lower-level: it knows only about the crates, |
16 | /// while this knows about `Pacakges` & `Targets`: purely cargo-related | 16 | /// while this knows about `Pacakges` & `Targets`: purely cargo-related |
17 | /// concepts. | 17 | /// concepts. |
@@ -162,9 +162,11 @@ impl CargoWorkspace { | |||
162 | 162 | ||
163 | Ok(CargoWorkspace { packages, targets }) | 163 | Ok(CargoWorkspace { packages, targets }) |
164 | } | 164 | } |
165 | |||
165 | pub fn packages<'a>(&'a self) -> impl Iterator<Item = Package> + 'a { | 166 | pub fn packages<'a>(&'a self) -> impl Iterator<Item = Package> + 'a { |
166 | self.packages.iter().map(|(id, _pkg)| id) | 167 | self.packages.iter().map(|(id, _pkg)| id) |
167 | } | 168 | } |
169 | |||
168 | pub fn target_by_root(&self, root: &Path) -> Option<Target> { | 170 | pub fn target_by_root(&self, root: &Path) -> Option<Target> { |
169 | self.packages().filter_map(|pkg| pkg.targets(self).find(|it| it.root(self) == root)).next() | 171 | self.packages().filter_map(|pkg| pkg.targets(self).find(|it| it.root(self) == root)).next() |
170 | } | 172 | } |
diff --git a/crates/ra_project_model/src/lib.rs b/crates/ra_project_model/src/lib.rs new file mode 100644 index 000000000..3a7bbace7 --- /dev/null +++ b/crates/ra_project_model/src/lib.rs | |||
@@ -0,0 +1,45 @@ | |||
1 | mod cargo_workspace; | ||
2 | mod sysroot; | ||
3 | |||
4 | use std::path::{Path, PathBuf}; | ||
5 | |||
6 | use failure::bail; | ||
7 | |||
8 | pub use crate::{ | ||
9 | cargo_workspace::{CargoWorkspace, Package, Target, TargetKind}, | ||
10 | sysroot::Sysroot, | ||
11 | }; | ||
12 | |||
13 | // TODO use own error enum? | ||
14 | pub type Result<T> = ::std::result::Result<T, ::failure::Error>; | ||
15 | |||
16 | #[derive(Debug, Clone)] | ||
17 | pub struct ProjectWorkspace { | ||
18 | pub cargo: CargoWorkspace, | ||
19 | pub sysroot: Sysroot, | ||
20 | } | ||
21 | |||
22 | impl ProjectWorkspace { | ||
23 | pub fn discover(path: &Path) -> Result<ProjectWorkspace> { | ||
24 | let cargo_toml = find_cargo_toml(path)?; | ||
25 | let cargo = CargoWorkspace::from_cargo_metadata(&cargo_toml)?; | ||
26 | let sysroot = Sysroot::discover(&cargo_toml)?; | ||
27 | let res = ProjectWorkspace { cargo, sysroot }; | ||
28 | Ok(res) | ||
29 | } | ||
30 | } | ||
31 | |||
32 | fn find_cargo_toml(path: &Path) -> Result<PathBuf> { | ||
33 | if path.ends_with("Cargo.toml") { | ||
34 | return Ok(path.to_path_buf()); | ||
35 | } | ||
36 | let mut curr = Some(path); | ||
37 | while let Some(path) = curr { | ||
38 | let candidate = path.join("Cargo.toml"); | ||
39 | if candidate.exists() { | ||
40 | return Ok(candidate); | ||
41 | } | ||
42 | curr = path.parent(); | ||
43 | } | ||
44 | bail!("can't find Cargo.toml at {}", path.display()) | ||
45 | } | ||
diff --git a/crates/ra_lsp_server/src/project_model/sysroot.rs b/crates/ra_project_model/src/sysroot.rs index 49210ac7a..18824dbe5 100644 --- a/crates/ra_lsp_server/src/project_model/sysroot.rs +++ b/crates/ra_project_model/src/sysroot.rs | |||
@@ -3,7 +3,8 @@ use std::{ | |||
3 | process::Command, | 3 | process::Command, |
4 | }; | 4 | }; |
5 | 5 | ||
6 | use ra_syntax::SmolStr; | 6 | use smol_str::SmolStr; |
7 | |||
7 | use ra_arena::{Arena, RawId, impl_arena_id}; | 8 | use ra_arena::{Arena, RawId, impl_arena_id}; |
8 | 9 | ||
9 | use crate::Result; | 10 | use crate::Result; |
@@ -25,15 +26,15 @@ struct SysrootCrateData { | |||
25 | } | 26 | } |
26 | 27 | ||
27 | impl Sysroot { | 28 | impl Sysroot { |
28 | pub(crate) fn std(&self) -> Option<SysrootCrate> { | 29 | pub fn std(&self) -> Option<SysrootCrate> { |
29 | self.by_name("std") | 30 | self.by_name("std") |
30 | } | 31 | } |
31 | 32 | ||
32 | pub(crate) fn crates<'a>(&'a self) -> impl Iterator<Item = SysrootCrate> + 'a { | 33 | pub fn crates<'a>(&'a self) -> impl Iterator<Item = SysrootCrate> + 'a { |
33 | self.crates.iter().map(|(id, _data)| id) | 34 | self.crates.iter().map(|(id, _data)| id) |
34 | } | 35 | } |
35 | 36 | ||
36 | pub(super) fn discover(cargo_toml: &Path) -> Result<Sysroot> { | 37 | pub fn discover(cargo_toml: &Path) -> Result<Sysroot> { |
37 | let rustc_output = Command::new("rustc") | 38 | let rustc_output = Command::new("rustc") |
38 | .current_dir(cargo_toml.parent().unwrap()) | 39 | .current_dir(cargo_toml.parent().unwrap()) |
39 | .args(&["--print", "sysroot"]) | 40 | .args(&["--print", "sysroot"]) |
@@ -80,16 +81,16 @@ impl Sysroot { | |||
80 | } | 81 | } |
81 | 82 | ||
82 | impl SysrootCrate { | 83 | impl SysrootCrate { |
83 | pub(crate) fn name(self, sysroot: &Sysroot) -> &SmolStr { | 84 | pub fn name(self, sysroot: &Sysroot) -> &SmolStr { |
84 | &sysroot.crates[self].name | 85 | &sysroot.crates[self].name |
85 | } | 86 | } |
86 | pub(crate) fn root(self, sysroot: &Sysroot) -> &Path { | 87 | pub fn root(self, sysroot: &Sysroot) -> &Path { |
87 | sysroot.crates[self].root.as_path() | 88 | sysroot.crates[self].root.as_path() |
88 | } | 89 | } |
89 | pub(crate) fn root_dir(self, sysroot: &Sysroot) -> &Path { | 90 | pub fn root_dir(self, sysroot: &Sysroot) -> &Path { |
90 | self.root(sysroot).parent().unwrap() | 91 | self.root(sysroot).parent().unwrap() |
91 | } | 92 | } |
92 | pub(crate) fn deps<'a>(self, sysroot: &'a Sysroot) -> impl Iterator<Item = SysrootCrate> + 'a { | 93 | pub fn deps<'a>(self, sysroot: &'a Sysroot) -> impl Iterator<Item = SysrootCrate> + 'a { |
93 | sysroot.crates[self].deps.iter().map(|&it| it) | 94 | sysroot.crates[self].deps.iter().map(|&it| it) |
94 | } | 95 | } |
95 | } | 96 | } |
diff --git a/crates/ra_syntax/Cargo.toml b/crates/ra_syntax/Cargo.toml index 0ec8492aa..7c7a85a75 100644 --- a/crates/ra_syntax/Cargo.toml +++ b/crates/ra_syntax/Cargo.toml | |||
@@ -15,7 +15,7 @@ drop_bomb = "0.1.4" | |||
15 | parking_lot = "0.7.0" | 15 | parking_lot = "0.7.0" |
16 | rowan = "0.3.3" | 16 | rowan = "0.3.3" |
17 | 17 | ||
18 | # ideally, `serde` should be enabled by `ra_lsp_serder`, but we enable it here | 18 | # ideally, `serde` should be enabled by `ra_lsp_server`, but we enable it here |
19 | # to reduce number of compilations | 19 | # to reduce number of compilations |
20 | text_unit = { version = "0.1.6", features = ["serde"] } | 20 | text_unit = { version = "0.1.6", features = ["serde"] } |
21 | smol_str = { version = "0.1.9", features = ["serde"] } | 21 | smol_str = { version = "0.1.9", features = ["serde"] } |