aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorFlorian Diebold <[email protected]>2019-02-05 22:10:49 +0000
committerFlorian Diebold <[email protected]>2019-02-09 10:15:25 +0000
commitfcd615e4b76264b4fff7b5be454787bb6a4252ea (patch)
tree112d17480bd065551a9d18c21ab51326f3e3a295
parent34398a8756b56c323d3b4b2ef32fbca32d88a105 (diff)
Extract project model to separate crate
-rw-r--r--Cargo.lock16
-rw-r--r--crates/ra_lsp_server/Cargo.toml2
-rw-r--r--crates/ra_lsp_server/src/project_model.rs42
-rw-r--r--crates/ra_project_model/Cargo.toml30
-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.rs45
-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.toml2
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 = [
1008name = "ra_lsp_server" 1008name = "ra_lsp_server"
1009version = "0.1.0" 1009version = "0.1.0"
1010dependencies = [ 1010dependencies = [
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]]
1049name = "ra_project_model"
1050version = "0.1.0"
1051dependencies = [
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]]
1049name = "ra_syntax" 1063name = "ra_syntax"
1050version = "0.1.0" 1064version = "0.1.0"
1051dependencies = [ 1065dependencies = [
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"
19lsp-types = "0.55.0" 19lsp-types = "0.55.0"
20walkdir = "2.2.7" 20walkdir = "2.2.7"
21im = "12.0.0" 21im = "12.0.0"
22cargo_metadata = "0.7.0"
23rustc-hash = "1.0" 22rustc-hash = "1.0"
24parking_lot = "0.7.0" 23parking_lot = "0.7.0"
25 24
@@ -30,6 +29,7 @@ ra_ide_api = { path = "../ra_ide_api" }
30ra_arena = { path = "../ra_arena" } 29ra_arena = { path = "../ra_arena" }
31gen_lsp_server = { path = "../gen_lsp_server" } 30gen_lsp_server = { path = "../gen_lsp_server" }
32ra_vfs = { path = "../ra_vfs" } 31ra_vfs = { path = "../ra_vfs" }
32ra_project_model = { path = "../ra_project_model" }
33 33
34[dev-dependencies] 34[dev-dependencies]
35tempfile = "3" 35tempfile = "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 @@
1mod cargo_workspace; 1use std::path::PathBuf;
2mod sysroot;
3 2
4use std::path::{Path, PathBuf};
5
6use failure::bail;
7use thread_worker::{WorkerHandle, Worker}; 3use thread_worker::{WorkerHandle, Worker};
8 4
9use crate::Result; 5use crate::Result;
10 6
11pub use crate::project_model::{ 7pub 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)]
17pub struct ProjectWorkspace {
18 pub(crate) cargo: CargoWorkspace,
19 pub(crate) sysroot: Sysroot,
20}
21
22impl 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
32pub fn workspace_loader() -> (Worker<PathBuf, Result<ProjectWorkspace>>, WorkerHandle) { 11pub 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
46fn 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]
2edition = "2018"
3name = "ra_project_model"
4version = "0.1.0"
5authors = ["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"
14rustc-hash = "1.0"
15# parking_lot = "0.7.0"
16# unicase = "2.2.0"
17
18# TODO get rid of these?
19failure = "0.1.4"
20failure_derive = "0.1.4"
21
22smol_str = { version = "0.1.9", features = ["serde"] }
23walkdir = "2.2.7"
24
25cargo_metadata = "0.7.0"
26
27ra_arena = { path = "../ra_arena" }
28
29[dev-dependencies]
30test_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 @@
1use std::path::{Path, PathBuf}; 1use std::path::{Path, PathBuf};
2 2
3use cargo_metadata::{MetadataCommand, CargoOpt}; 3use cargo_metadata::{MetadataCommand, CargoOpt};
4use ra_syntax::SmolStr; 4use smol_str::SmolStr;
5use ra_arena::{Arena, RawId, impl_arena_id}; 5use ra_arena::{Arena, RawId, impl_arena_id};
6use rustc_hash::FxHashMap; 6use rustc_hash::FxHashMap;
7use failure::format_err; 7use failure::format_err;
8 8
9use crate::Result; 9use 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 @@
1mod cargo_workspace;
2mod sysroot;
3
4use std::path::{Path, PathBuf};
5
6use failure::bail;
7
8pub use crate::{
9 cargo_workspace::{CargoWorkspace, Package, Target, TargetKind},
10 sysroot::Sysroot,
11};
12
13// TODO use own error enum?
14pub type Result<T> = ::std::result::Result<T, ::failure::Error>;
15
16#[derive(Debug, Clone)]
17pub struct ProjectWorkspace {
18 pub cargo: CargoWorkspace,
19 pub sysroot: Sysroot,
20}
21
22impl 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
32fn 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
6use ra_syntax::SmolStr; 6use smol_str::SmolStr;
7
7use ra_arena::{Arena, RawId, impl_arena_id}; 8use ra_arena::{Arena, RawId, impl_arena_id};
8 9
9use crate::Result; 10use crate::Result;
@@ -25,15 +26,15 @@ struct SysrootCrateData {
25} 26}
26 27
27impl Sysroot { 28impl 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
82impl SysrootCrate { 83impl 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"
15parking_lot = "0.7.0" 15parking_lot = "0.7.0"
16rowan = "0.3.3" 16rowan = "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
20text_unit = { version = "0.1.6", features = ["serde"] } 20text_unit = { version = "0.1.6", features = ["serde"] }
21smol_str = { version = "0.1.9", features = ["serde"] } 21smol_str = { version = "0.1.9", features = ["serde"] }