diff options
Diffstat (limited to 'crates')
-rw-r--r-- | crates/ra_assists/src/assists/add_new.rs | 35 | ||||
-rw-r--r-- | crates/ra_batch/src/lib.rs | 2 | ||||
-rw-r--r-- | crates/ra_lsp_server/src/config.rs | 5 | ||||
-rw-r--r-- | crates/ra_lsp_server/src/main_loop.rs | 1 | ||||
-rw-r--r-- | crates/ra_project_model/src/cargo_workspace.rs | 31 | ||||
-rw-r--r-- | crates/ra_project_model/src/lib.rs | 14 |
6 files changed, 61 insertions, 27 deletions
diff --git a/crates/ra_assists/src/assists/add_new.rs b/crates/ra_assists/src/assists/add_new.rs index d340cac8f..b2f946fac 100644 --- a/crates/ra_assists/src/assists/add_new.rs +++ b/crates/ra_assists/src/assists/add_new.rs | |||
@@ -139,43 +139,40 @@ fn find_struct_impl( | |||
139 | 139 | ||
140 | let struct_ty = { | 140 | let struct_ty = { |
141 | let src = InFile { file_id: ctx.frange.file_id.into(), value: strukt.clone() }; | 141 | let src = InFile { file_id: ctx.frange.file_id.into(), value: strukt.clone() }; |
142 | hir::Struct::from_source(db, src).unwrap().ty(db) | 142 | hir::Struct::from_source(db, src)?.ty(db) |
143 | }; | 143 | }; |
144 | 144 | ||
145 | let mut found_new_fn = false; | 145 | let block = module.descendants().filter_map(ast::ImplBlock::cast).find_map(|impl_blk| { |
146 | |||
147 | let block = module.descendants().filter_map(ast::ImplBlock::cast).find(|impl_blk| { | ||
148 | if found_new_fn { | ||
149 | return false; | ||
150 | } | ||
151 | |||
152 | let src = InFile { file_id: ctx.frange.file_id.into(), value: impl_blk.clone() }; | 146 | let src = InFile { file_id: ctx.frange.file_id.into(), value: impl_blk.clone() }; |
153 | let blk = hir::ImplBlock::from_source(db, src).unwrap(); | 147 | let blk = hir::ImplBlock::from_source(db, src)?; |
154 | 148 | ||
155 | let same_ty = blk.target_ty(db) == struct_ty; | 149 | let same_ty = blk.target_ty(db) == struct_ty; |
156 | let not_trait_impl = blk.target_trait(db).is_none(); | 150 | let not_trait_impl = blk.target_trait(db).is_none(); |
157 | 151 | ||
158 | if !(same_ty && not_trait_impl) { | 152 | if !(same_ty && not_trait_impl) { |
159 | return false; | 153 | None |
154 | } else { | ||
155 | Some(impl_blk) | ||
160 | } | 156 | } |
161 | |||
162 | found_new_fn = has_new_fn(impl_blk); | ||
163 | true | ||
164 | }); | 157 | }); |
165 | 158 | ||
166 | if found_new_fn { | 159 | if let Some(ref impl_blk) = block { |
167 | None | 160 | if has_new_fn(impl_blk) { |
168 | } else { | 161 | return None; |
169 | Some(block) | 162 | } |
170 | } | 163 | } |
164 | |||
165 | Some(block) | ||
171 | } | 166 | } |
172 | 167 | ||
173 | fn has_new_fn(imp: &ast::ImplBlock) -> bool { | 168 | fn has_new_fn(imp: &ast::ImplBlock) -> bool { |
174 | if let Some(il) = imp.item_list() { | 169 | if let Some(il) = imp.item_list() { |
175 | for item in il.impl_items() { | 170 | for item in il.impl_items() { |
176 | if let ast::ImplItem::FnDef(f) = item { | 171 | if let ast::ImplItem::FnDef(f) = item { |
177 | if f.name().unwrap().text().eq_ignore_ascii_case("new") { | 172 | if let Some(name) = f.name() { |
178 | return true; | 173 | if name.text().eq_ignore_ascii_case("new") { |
174 | return true; | ||
175 | } | ||
179 | } | 176 | } |
180 | } | 177 | } |
181 | } | 178 | } |
diff --git a/crates/ra_batch/src/lib.rs b/crates/ra_batch/src/lib.rs index 2c9645c00..7744ba85a 100644 --- a/crates/ra_batch/src/lib.rs +++ b/crates/ra_batch/src/lib.rs | |||
@@ -22,7 +22,7 @@ fn vfs_root_to_id(r: ra_vfs::VfsRoot) -> SourceRootId { | |||
22 | 22 | ||
23 | pub fn load_cargo(root: &Path) -> Result<(AnalysisHost, FxHashMap<SourceRootId, PackageRoot>)> { | 23 | pub fn load_cargo(root: &Path) -> Result<(AnalysisHost, FxHashMap<SourceRootId, PackageRoot>)> { |
24 | let root = std::env::current_dir()?.join(root); | 24 | let root = std::env::current_dir()?.join(root); |
25 | let ws = ProjectWorkspace::discover(root.as_ref())?; | 25 | let ws = ProjectWorkspace::discover(root.as_ref(), &Default::default())?; |
26 | let project_roots = ws.to_roots(); | 26 | let project_roots = ws.to_roots(); |
27 | let (sender, receiver) = unbounded(); | 27 | let (sender, receiver) = unbounded(); |
28 | let sender = Box::new(move |t| sender.send(t).unwrap()); | 28 | let sender = Box::new(move |t| sender.send(t).unwrap()); |
diff --git a/crates/ra_lsp_server/src/config.rs b/crates/ra_lsp_server/src/config.rs index 8045f3d60..67942aa41 100644 --- a/crates/ra_lsp_server/src/config.rs +++ b/crates/ra_lsp_server/src/config.rs | |||
@@ -9,6 +9,7 @@ | |||
9 | 9 | ||
10 | use rustc_hash::FxHashMap; | 10 | use rustc_hash::FxHashMap; |
11 | 11 | ||
12 | use ra_project_model::CargoFeatures; | ||
12 | use serde::{Deserialize, Deserializer}; | 13 | use serde::{Deserialize, Deserializer}; |
13 | 14 | ||
14 | /// Client provided initialization options | 15 | /// Client provided initialization options |
@@ -37,6 +38,9 @@ pub struct ServerConfig { | |||
37 | 38 | ||
38 | /// Fine grained feature flags to disable specific features. | 39 | /// Fine grained feature flags to disable specific features. |
39 | pub feature_flags: FxHashMap<String, bool>, | 40 | pub feature_flags: FxHashMap<String, bool>, |
41 | |||
42 | /// Cargo feature configurations. | ||
43 | pub cargo_features: CargoFeatures, | ||
40 | } | 44 | } |
41 | 45 | ||
42 | impl Default for ServerConfig { | 46 | impl Default for ServerConfig { |
@@ -49,6 +53,7 @@ impl Default for ServerConfig { | |||
49 | max_inlay_hint_length: None, | 53 | max_inlay_hint_length: None, |
50 | with_sysroot: true, | 54 | with_sysroot: true, |
51 | feature_flags: FxHashMap::default(), | 55 | feature_flags: FxHashMap::default(), |
56 | cargo_features: Default::default(), | ||
52 | } | 57 | } |
53 | } | 58 | } |
54 | } | 59 | } |
diff --git a/crates/ra_lsp_server/src/main_loop.rs b/crates/ra_lsp_server/src/main_loop.rs index 158cac0be..965e7c53c 100644 --- a/crates/ra_lsp_server/src/main_loop.rs +++ b/crates/ra_lsp_server/src/main_loop.rs | |||
@@ -67,6 +67,7 @@ pub fn main_loop( | |||
67 | let workspace = ra_project_model::ProjectWorkspace::discover_with_sysroot( | 67 | let workspace = ra_project_model::ProjectWorkspace::discover_with_sysroot( |
68 | ws_root.as_path(), | 68 | ws_root.as_path(), |
69 | config.with_sysroot, | 69 | config.with_sysroot, |
70 | &config.cargo_features, | ||
70 | ); | 71 | ); |
71 | match workspace { | 72 | match workspace { |
72 | Ok(workspace) => loaded_workspaces.push(workspace), | 73 | Ok(workspace) => loaded_workspaces.push(workspace), |
diff --git a/crates/ra_project_model/src/cargo_workspace.rs b/crates/ra_project_model/src/cargo_workspace.rs index 351997dcd..4a0437da3 100644 --- a/crates/ra_project_model/src/cargo_workspace.rs +++ b/crates/ra_project_model/src/cargo_workspace.rs | |||
@@ -6,6 +6,7 @@ use cargo_metadata::{CargoOpt, MetadataCommand}; | |||
6 | use ra_arena::{impl_arena_id, Arena, RawId}; | 6 | use ra_arena::{impl_arena_id, Arena, RawId}; |
7 | use ra_db::Edition; | 7 | use ra_db::Edition; |
8 | use rustc_hash::FxHashMap; | 8 | use rustc_hash::FxHashMap; |
9 | use serde::Deserialize; | ||
9 | 10 | ||
10 | use crate::Result; | 11 | use crate::Result; |
11 | 12 | ||
@@ -23,6 +24,20 @@ pub struct CargoWorkspace { | |||
23 | pub(crate) workspace_root: PathBuf, | 24 | pub(crate) workspace_root: PathBuf, |
24 | } | 25 | } |
25 | 26 | ||
27 | #[derive(Deserialize, Clone, Debug, PartialEq, Eq, Default)] | ||
28 | #[serde(rename_all = "camelCase", default)] | ||
29 | pub struct CargoFeatures { | ||
30 | /// Do not activate the `default` feature. | ||
31 | pub no_default_features: bool, | ||
32 | |||
33 | /// Activate all available features | ||
34 | pub all_features: bool, | ||
35 | |||
36 | /// List of features to activate. | ||
37 | /// This will be ignored if `cargo_all_features` is true. | ||
38 | pub features: Vec<String>, | ||
39 | } | ||
40 | |||
26 | #[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)] | 41 | #[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)] |
27 | pub struct Package(RawId); | 42 | pub struct Package(RawId); |
28 | impl_arena_id!(Package); | 43 | impl_arena_id!(Package); |
@@ -132,9 +147,21 @@ impl Target { | |||
132 | } | 147 | } |
133 | 148 | ||
134 | impl CargoWorkspace { | 149 | impl CargoWorkspace { |
135 | pub fn from_cargo_metadata(cargo_toml: &Path) -> Result<CargoWorkspace> { | 150 | pub fn from_cargo_metadata( |
151 | cargo_toml: &Path, | ||
152 | cargo_features: &CargoFeatures, | ||
153 | ) -> Result<CargoWorkspace> { | ||
136 | let mut meta = MetadataCommand::new(); | 154 | let mut meta = MetadataCommand::new(); |
137 | meta.manifest_path(cargo_toml).features(CargoOpt::AllFeatures); | 155 | meta.manifest_path(cargo_toml); |
156 | if cargo_features.all_features { | ||
157 | meta.features(CargoOpt::AllFeatures); | ||
158 | } else if cargo_features.no_default_features { | ||
159 | // FIXME: `NoDefaultFeatures` is mutual exclusive with `SomeFeatures` | ||
160 | // https://github.com/oli-obk/cargo_metadata/issues/79 | ||
161 | meta.features(CargoOpt::NoDefaultFeatures); | ||
162 | } else { | ||
163 | meta.features(CargoOpt::SomeFeatures(cargo_features.features.clone())); | ||
164 | } | ||
138 | if let Some(parent) = cargo_toml.parent() { | 165 | if let Some(parent) = cargo_toml.parent() { |
139 | meta.current_dir(parent); | 166 | meta.current_dir(parent); |
140 | } | 167 | } |
diff --git a/crates/ra_project_model/src/lib.rs b/crates/ra_project_model/src/lib.rs index 55ff4d6ef..d71b7031a 100644 --- a/crates/ra_project_model/src/lib.rs +++ b/crates/ra_project_model/src/lib.rs | |||
@@ -18,7 +18,7 @@ use rustc_hash::FxHashMap; | |||
18 | use serde_json::from_reader; | 18 | use serde_json::from_reader; |
19 | 19 | ||
20 | pub use crate::{ | 20 | pub use crate::{ |
21 | cargo_workspace::{CargoWorkspace, Package, Target, TargetKind}, | 21 | cargo_workspace::{CargoFeatures, CargoWorkspace, Package, Target, TargetKind}, |
22 | json_project::JsonProject, | 22 | json_project::JsonProject, |
23 | sysroot::Sysroot, | 23 | sysroot::Sysroot, |
24 | }; | 24 | }; |
@@ -60,11 +60,15 @@ impl PackageRoot { | |||
60 | } | 60 | } |
61 | 61 | ||
62 | impl ProjectWorkspace { | 62 | impl ProjectWorkspace { |
63 | pub fn discover(path: &Path) -> Result<ProjectWorkspace> { | 63 | pub fn discover(path: &Path, cargo_features: &CargoFeatures) -> Result<ProjectWorkspace> { |
64 | ProjectWorkspace::discover_with_sysroot(path, true) | 64 | ProjectWorkspace::discover_with_sysroot(path, true, cargo_features) |
65 | } | 65 | } |
66 | 66 | ||
67 | pub fn discover_with_sysroot(path: &Path, with_sysroot: bool) -> Result<ProjectWorkspace> { | 67 | pub fn discover_with_sysroot( |
68 | path: &Path, | ||
69 | with_sysroot: bool, | ||
70 | cargo_features: &CargoFeatures, | ||
71 | ) -> Result<ProjectWorkspace> { | ||
68 | match find_rust_project_json(path) { | 72 | match find_rust_project_json(path) { |
69 | Some(json_path) => { | 73 | Some(json_path) => { |
70 | let file = File::open(json_path)?; | 74 | let file = File::open(json_path)?; |
@@ -73,7 +77,7 @@ impl ProjectWorkspace { | |||
73 | } | 77 | } |
74 | None => { | 78 | None => { |
75 | let cargo_toml = find_cargo_toml(path)?; | 79 | let cargo_toml = find_cargo_toml(path)?; |
76 | let cargo = CargoWorkspace::from_cargo_metadata(&cargo_toml)?; | 80 | let cargo = CargoWorkspace::from_cargo_metadata(&cargo_toml, cargo_features)?; |
77 | let sysroot = | 81 | let sysroot = |
78 | if with_sysroot { Sysroot::discover(&cargo_toml)? } else { Sysroot::default() }; | 82 | if with_sysroot { Sysroot::discover(&cargo_toml)? } else { Sysroot::default() }; |
79 | Ok(ProjectWorkspace::Cargo { cargo, sysroot }) | 83 | Ok(ProjectWorkspace::Cargo { cargo, sysroot }) |