diff options
author | bors[bot] <26634292+bors[bot]@users.noreply.github.com> | 2019-12-14 11:57:49 +0000 |
---|---|---|
committer | GitHub <[email protected]> | 2019-12-14 11:57:49 +0000 |
commit | 7238037de42a2fd88434930c521b926d7b0026da (patch) | |
tree | 5bb6104ed70200be455ee685e7a69f04a9f70729 | |
parent | 35b22312472b938d6549135f1fd932a26373e73e (diff) | |
parent | f56a2a079069edafd74ef92b7e545f18be88b243 (diff) |
Merge #2548
2548: Support setting cargo features and resolve `default` features by default r=matklad a=oxalica
Fixes #2524
Co-authored-by: oxalica <[email protected]>
-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 | ||||
-rw-r--r-- | editors/code/package.json | 15 | ||||
-rw-r--r-- | editors/code/src/config.ts | 77 | ||||
-rw-r--r-- | editors/code/src/server.ts | 1 |
8 files changed, 125 insertions, 21 deletions
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 }) |
diff --git a/editors/code/package.json b/editors/code/package.json index 7bc08ec31..e3bb07be7 100644 --- a/editors/code/package.json +++ b/editors/code/package.json | |||
@@ -278,6 +278,21 @@ | |||
278 | "type": "number", | 278 | "type": "number", |
279 | "default": 20, | 279 | "default": 20, |
280 | "description": "Maximum length for inlay hints" | 280 | "description": "Maximum length for inlay hints" |
281 | }, | ||
282 | "rust-analyzer.cargoFeatures.noDefaultFeatures": { | ||
283 | "type": "boolean", | ||
284 | "default": false, | ||
285 | "description": "Do not activate the `default` feature" | ||
286 | }, | ||
287 | "rust-analyzer.cargoFeatures.allFeatures": { | ||
288 | "type": "boolean", | ||
289 | "default": true, | ||
290 | "description": "Activate all available features" | ||
291 | }, | ||
292 | "rust-analyzer.cargoFeatures.features": { | ||
293 | "type": "array", | ||
294 | "default": [], | ||
295 | "description": "List of features to activate" | ||
281 | } | 296 | } |
282 | } | 297 | } |
283 | }, | 298 | }, |
diff --git a/editors/code/src/config.ts b/editors/code/src/config.ts index 2d3b6a54e..defdfeb9c 100644 --- a/editors/code/src/config.ts +++ b/editors/code/src/config.ts | |||
@@ -15,6 +15,12 @@ export interface CargoWatchOptions { | |||
15 | ignore: string[]; | 15 | ignore: string[]; |
16 | } | 16 | } |
17 | 17 | ||
18 | export interface CargoFeatures { | ||
19 | noDefaultFeatures: boolean; | ||
20 | allFeatures: boolean; | ||
21 | features: string[]; | ||
22 | } | ||
23 | |||
18 | export class Config { | 24 | export class Config { |
19 | public highlightingOn = true; | 25 | public highlightingOn = true; |
20 | public rainbowHighlightingOn = false; | 26 | public rainbowHighlightingOn = false; |
@@ -35,8 +41,14 @@ export class Config { | |||
35 | command: '', | 41 | command: '', |
36 | ignore: [], | 42 | ignore: [], |
37 | }; | 43 | }; |
44 | public cargoFeatures: CargoFeatures = { | ||
45 | noDefaultFeatures: false, | ||
46 | allFeatures: true, | ||
47 | features: [], | ||
48 | }; | ||
38 | 49 | ||
39 | private prevEnhancedTyping: null | boolean = null; | 50 | private prevEnhancedTyping: null | boolean = null; |
51 | private prevCargoFeatures: null | CargoFeatures = null; | ||
40 | 52 | ||
41 | constructor() { | 53 | constructor() { |
42 | vscode.workspace.onDidChangeConfiguration(_ => | 54 | vscode.workspace.onDidChangeConfiguration(_ => |
@@ -47,6 +59,8 @@ export class Config { | |||
47 | 59 | ||
48 | public userConfigChanged() { | 60 | public userConfigChanged() { |
49 | const config = vscode.workspace.getConfiguration('rust-analyzer'); | 61 | const config = vscode.workspace.getConfiguration('rust-analyzer'); |
62 | let requireReloadMessage = null; | ||
63 | |||
50 | if (config.has('highlightingOn')) { | 64 | if (config.has('highlightingOn')) { |
51 | this.highlightingOn = config.get('highlightingOn') as boolean; | 65 | this.highlightingOn = config.get('highlightingOn') as boolean; |
52 | } | 66 | } |
@@ -74,19 +88,8 @@ export class Config { | |||
74 | } | 88 | } |
75 | 89 | ||
76 | if (this.prevEnhancedTyping !== this.enableEnhancedTyping) { | 90 | if (this.prevEnhancedTyping !== this.enableEnhancedTyping) { |
77 | const reloadAction = 'Reload now'; | 91 | requireReloadMessage = |
78 | vscode.window | 92 | 'Changing enhanced typing setting requires a reload'; |
79 | .showInformationMessage( | ||
80 | 'Changing enhanced typing setting requires a reload', | ||
81 | reloadAction, | ||
82 | ) | ||
83 | .then(selectedAction => { | ||
84 | if (selectedAction === reloadAction) { | ||
85 | vscode.commands.executeCommand( | ||
86 | 'workbench.action.reloadWindow', | ||
87 | ); | ||
88 | } | ||
89 | }); | ||
90 | this.prevEnhancedTyping = this.enableEnhancedTyping; | 93 | this.prevEnhancedTyping = this.enableEnhancedTyping; |
91 | } | 94 | } |
92 | 95 | ||
@@ -153,5 +156,53 @@ export class Config { | |||
153 | if (config.has('withSysroot')) { | 156 | if (config.has('withSysroot')) { |
154 | this.withSysroot = config.get('withSysroot') || false; | 157 | this.withSysroot = config.get('withSysroot') || false; |
155 | } | 158 | } |
159 | |||
160 | if (config.has('cargoFeatures.noDefaultFeatures')) { | ||
161 | this.cargoFeatures.noDefaultFeatures = config.get( | ||
162 | 'cargoFeatures.noDefaultFeatures', | ||
163 | false, | ||
164 | ); | ||
165 | } | ||
166 | if (config.has('cargoFeatures.allFeatures')) { | ||
167 | this.cargoFeatures.allFeatures = config.get( | ||
168 | 'cargoFeatures.allFeatures', | ||
169 | true, | ||
170 | ); | ||
171 | } | ||
172 | if (config.has('cargoFeatures.features')) { | ||
173 | this.cargoFeatures.features = config.get( | ||
174 | 'cargoFeatures.features', | ||
175 | [], | ||
176 | ); | ||
177 | } | ||
178 | |||
179 | if ( | ||
180 | this.prevCargoFeatures !== null && | ||
181 | (this.cargoFeatures.allFeatures !== | ||
182 | this.prevCargoFeatures.allFeatures || | ||
183 | this.cargoFeatures.noDefaultFeatures !== | ||
184 | this.prevCargoFeatures.noDefaultFeatures || | ||
185 | this.cargoFeatures.features.length !== | ||
186 | this.prevCargoFeatures.features.length || | ||
187 | this.cargoFeatures.features.some( | ||
188 | (v, i) => v !== this.prevCargoFeatures!.features[i], | ||
189 | )) | ||
190 | ) { | ||
191 | requireReloadMessage = 'Changing cargo features requires a reload'; | ||
192 | } | ||
193 | this.prevCargoFeatures = { ...this.cargoFeatures }; | ||
194 | |||
195 | if (requireReloadMessage !== null) { | ||
196 | const reloadAction = 'Reload now'; | ||
197 | vscode.window | ||
198 | .showInformationMessage(requireReloadMessage, reloadAction) | ||
199 | .then(selectedAction => { | ||
200 | if (selectedAction === reloadAction) { | ||
201 | vscode.commands.executeCommand( | ||
202 | 'workbench.action.reloadWindow', | ||
203 | ); | ||
204 | } | ||
205 | }); | ||
206 | } | ||
156 | } | 207 | } |
157 | } | 208 | } |
diff --git a/editors/code/src/server.ts b/editors/code/src/server.ts index 2fe45f1ed..5ace1d0fa 100644 --- a/editors/code/src/server.ts +++ b/editors/code/src/server.ts | |||
@@ -59,6 +59,7 @@ export class Server { | |||
59 | useClientWatching: Server.config.useClientWatching, | 59 | useClientWatching: Server.config.useClientWatching, |
60 | featureFlags: Server.config.featureFlags, | 60 | featureFlags: Server.config.featureFlags, |
61 | withSysroot: Server.config.withSysroot, | 61 | withSysroot: Server.config.withSysroot, |
62 | cargoFeatures: Server.config.cargoFeatures, | ||
62 | }, | 63 | }, |
63 | traceOutputChannel, | 64 | traceOutputChannel, |
64 | }; | 65 | }; |