diff options
author | Aleksey Kladov <[email protected]> | 2020-06-03 13:48:38 +0100 |
---|---|---|
committer | Aleksey Kladov <[email protected]> | 2020-06-03 14:17:26 +0100 |
commit | fa019c8f562326a720d2ef9165626c4c5703f67b (patch) | |
tree | dac38194fb66e0d563ffb52bbbc0e740f824cfd8 | |
parent | 2e7d12d2f3ccfd1ef9946d1212e2455e5937c521 (diff) |
Document rust-project.json
-rw-r--r-- | crates/ra_project_model/src/lib.rs | 10 | ||||
-rw-r--r-- | crates/rust-analyzer/src/config.rs | 23 | ||||
-rw-r--r-- | crates/rust-analyzer/src/main_loop.rs | 35 | ||||
-rw-r--r-- | docs/user/manual.adoc | 51 | ||||
-rw-r--r-- | editors/code/package.json | 19 |
5 files changed, 118 insertions, 20 deletions
diff --git a/crates/ra_project_model/src/lib.rs b/crates/ra_project_model/src/lib.rs index a99612690..7ad941279 100644 --- a/crates/ra_project_model/src/lib.rs +++ b/crates/ra_project_model/src/lib.rs | |||
@@ -32,6 +32,12 @@ pub enum ProjectWorkspace { | |||
32 | Json { project: JsonProject }, | 32 | Json { project: JsonProject }, |
33 | } | 33 | } |
34 | 34 | ||
35 | impl From<JsonProject> for ProjectWorkspace { | ||
36 | fn from(project: JsonProject) -> ProjectWorkspace { | ||
37 | ProjectWorkspace::Json { project } | ||
38 | } | ||
39 | } | ||
40 | |||
35 | /// `PackageRoot` describes a package root folder. | 41 | /// `PackageRoot` describes a package root folder. |
36 | /// Which may be an external dependency, or a member of | 42 | /// Which may be an external dependency, or a member of |
37 | /// the current workspace. | 43 | /// the current workspace. |
@@ -144,11 +150,11 @@ impl ProjectManifest { | |||
144 | 150 | ||
145 | impl ProjectWorkspace { | 151 | impl ProjectWorkspace { |
146 | pub fn load( | 152 | pub fn load( |
147 | root: ProjectManifest, | 153 | manifest: ProjectManifest, |
148 | cargo_features: &CargoConfig, | 154 | cargo_features: &CargoConfig, |
149 | with_sysroot: bool, | 155 | with_sysroot: bool, |
150 | ) -> Result<ProjectWorkspace> { | 156 | ) -> Result<ProjectWorkspace> { |
151 | let res = match root { | 157 | let res = match manifest { |
152 | ProjectManifest::ProjectJson(project_json) => { | 158 | ProjectManifest::ProjectJson(project_json) => { |
153 | let file = File::open(&project_json).with_context(|| { | 159 | let file = File::open(&project_json).with_context(|| { |
154 | format!("Failed to open json file {}", project_json.display()) | 160 | format!("Failed to open json file {}", project_json.display()) |
diff --git a/crates/rust-analyzer/src/config.rs b/crates/rust-analyzer/src/config.rs index 761bc9c2d..0e5dc56fd 100644 --- a/crates/rust-analyzer/src/config.rs +++ b/crates/rust-analyzer/src/config.rs | |||
@@ -261,6 +261,22 @@ impl Config { | |||
261 | self.lens = LensConfig::NO_LENS; | 261 | self.lens = LensConfig::NO_LENS; |
262 | } | 262 | } |
263 | 263 | ||
264 | if let Some(linked_projects) = get::<Vec<ManifestOrJsonProject>>(value, "/linkedProjects") { | ||
265 | if !linked_projects.is_empty() { | ||
266 | self.linked_projects.clear(); | ||
267 | for linked_project in linked_projects { | ||
268 | let linked_project = match linked_project { | ||
269 | ManifestOrJsonProject::Manifest(it) => match ProjectManifest::from_manifest_file(it) { | ||
270 | Ok(it) => it.into(), | ||
271 | Err(_) => continue, | ||
272 | } | ||
273 | ManifestOrJsonProject::JsonProject(it) => it.into(), | ||
274 | }; | ||
275 | self.linked_projects.push(linked_project); | ||
276 | } | ||
277 | } | ||
278 | } | ||
279 | |||
264 | log::info!("Config::update() = {:#?}", self); | 280 | log::info!("Config::update() = {:#?}", self); |
265 | 281 | ||
266 | fn get<'a, T: Deserialize<'a>>(value: &'a serde_json::Value, pointer: &str) -> Option<T> { | 282 | fn get<'a, T: Deserialize<'a>>(value: &'a serde_json::Value, pointer: &str) -> Option<T> { |
@@ -324,3 +340,10 @@ impl Config { | |||
324 | } | 340 | } |
325 | } | 341 | } |
326 | } | 342 | } |
343 | |||
344 | #[derive(Deserialize)] | ||
345 | #[serde(untagged)] | ||
346 | enum ManifestOrJsonProject { | ||
347 | Manifest(PathBuf), | ||
348 | JsonProject(JsonProject), | ||
349 | } | ||
diff --git a/crates/rust-analyzer/src/main_loop.rs b/crates/rust-analyzer/src/main_loop.rs index d901f21d7..1f8f6b978 100644 --- a/crates/rust-analyzer/src/main_loop.rs +++ b/crates/rust-analyzer/src/main_loop.rs | |||
@@ -105,24 +105,23 @@ pub fn main_loop(config: Config, connection: Connection) -> Result<()> { | |||
105 | .linked_projects | 105 | .linked_projects |
106 | .iter() | 106 | .iter() |
107 | .filter_map(|project| match project { | 107 | .filter_map(|project| match project { |
108 | LinkedProject::ProjectManifest(it) => Some(it), | 108 | LinkedProject::ProjectManifest(manifest) => { |
109 | LinkedProject::JsonProject(_) => None, | 109 | ra_project_model::ProjectWorkspace::load( |
110 | }) | 110 | manifest.clone(), |
111 | .filter_map(|root| { | 111 | &config.cargo, |
112 | ra_project_model::ProjectWorkspace::load( | 112 | config.with_sysroot, |
113 | root.clone(), | 113 | ) |
114 | &config.cargo, | 114 | .map_err(|err| { |
115 | config.with_sysroot, | 115 | log::error!("failed to load workspace: {:#}", err); |
116 | ) | 116 | show_message( |
117 | .map_err(|err| { | 117 | lsp_types::MessageType::Error, |
118 | log::error!("failed to load workspace: {:#}", err); | 118 | format!("rust-analyzer failed to load workspace: {:#}", err), |
119 | show_message( | 119 | &connection.sender, |
120 | lsp_types::MessageType::Error, | 120 | ); |
121 | format!("rust-analyzer failed to load workspace: {:#}", err), | 121 | }) |
122 | &connection.sender, | 122 | .ok() |
123 | ); | 123 | } |
124 | }) | 124 | LinkedProject::JsonProject(it) => Some(it.clone().into()), |
125 | .ok() | ||
126 | }) | 125 | }) |
127 | .collect::<Vec<_>>() | 126 | .collect::<Vec<_>>() |
128 | }; | 127 | }; |
diff --git a/docs/user/manual.adoc b/docs/user/manual.adoc index 202783fd9..ea714f49a 100644 --- a/docs/user/manual.adoc +++ b/docs/user/manual.adoc | |||
@@ -269,6 +269,57 @@ Gnome Builder currently has support for RLS, and there's no way to configure the | |||
269 | 1. Rename, symlink or copy the `rust-analyzer` binary to `rls` and place it somewhere Builder can find (in `PATH`, or under `~/.cargo/bin`). | 269 | 1. Rename, symlink or copy the `rust-analyzer` binary to `rls` and place it somewhere Builder can find (in `PATH`, or under `~/.cargo/bin`). |
270 | 2. Enable the Rust Builder plugin. | 270 | 2. Enable the Rust Builder plugin. |
271 | 271 | ||
272 | == Non-Cargo Based Projects | ||
273 | |||
274 | rust-analyzer does not require Cargo. | ||
275 | However, if you use some other build system, you'll have to describe the structure of your project for rust-analyzer in the `rust-project.json` format: | ||
276 | |||
277 | [source,TypeScript] | ||
278 | ---- | ||
279 | interface JsonProject { | ||
280 | /// The set of paths containing the crates for this project. | ||
281 | /// Any `Crate` must be nested inside some `root`. | ||
282 | roots: string[]; | ||
283 | /// The set of crates comprising the current project. | ||
284 | /// Must include all transitive dependencies as well as sysroot crate (libstd, libcore and such). | ||
285 | crates: Crate[]; | ||
286 | } | ||
287 | |||
288 | interface Crate { | ||
289 | /// Path to the root module of the crate. | ||
290 | root_module: string; | ||
291 | /// Edition of the crate. | ||
292 | edition: "2015" | "2018"; | ||
293 | /// Dependencies | ||
294 | deps: Dep[]; | ||
295 | /// The set of cfgs activated for a given crate, like `["unix", "feature=foo", "feature=bar"]`. | ||
296 | cfg: string[]; | ||
297 | |||
298 | /// value of the OUT_DIR env variable. | ||
299 | out_dir?: string; | ||
300 | /// For proc-macro crates, path to compiles proc-macro (.so file). | ||
301 | proc_macro_dylib_path?: string; | ||
302 | } | ||
303 | |||
304 | interface Dep { | ||
305 | /// Index of a crate in the `crates` array. | ||
306 | crate: number, | ||
307 | /// Name as should appear in the (implicit) `extern crate name` declaration. | ||
308 | name: string, | ||
309 | } | ||
310 | ---- | ||
311 | |||
312 | This format is provisional and subject to change. | ||
313 | Specifically, the `roots` setup will be different eventually. | ||
314 | |||
315 | There are tree ways to feed `rust-project.json` to rust-analyzer: | ||
316 | |||
317 | * Place `rust-project.json` file at the root of the project, and rust-anlayzer will discover it. | ||
318 | * Specify `"rust-analyzer.linkedProjects": [ "path/to/rust-project.json" ]` in the settings (and make sure that your LSP client sends settings as a part of initialize request). | ||
319 | * Specify `"rust-analyzer.linkedProjects": [ { "roots": [...], "crates": [...] }]` inline. | ||
320 | |||
321 | See https://github.com/rust-analyzer/rust-project.json-example for a small example. | ||
322 | |||
272 | == Features | 323 | == Features |
273 | 324 | ||
274 | include::./generated_features.adoc[] | 325 | include::./generated_features.adoc[] |
diff --git a/editors/code/package.json b/editors/code/package.json index d8f4287fd..30ab7ba4a 100644 --- a/editors/code/package.json +++ b/editors/code/package.json | |||
@@ -475,6 +475,25 @@ | |||
475 | "markdownDescription": "Whether to show Implementations lens. Only applies when `#rust-analyzer.lens.enable#` is set.", | 475 | "markdownDescription": "Whether to show Implementations lens. Only applies when `#rust-analyzer.lens.enable#` is set.", |
476 | "type": "boolean", | 476 | "type": "boolean", |
477 | "default": true | 477 | "default": true |
478 | }, | ||
479 | "rust-analyzer.linkedProjects": { | ||
480 | "markdownDescription": [ | ||
481 | "Disable project auto-discovery in favor of explicitly specified set of projects.", | ||
482 | "Elements must be paths pointing to Cargo.toml, rust-project.json, or JSON objects in rust-project.json format" | ||
483 | ], | ||
484 | "type": "array", | ||
485 | "items": { | ||
486 | "type": [ | ||
487 | "string", | ||
488 | "object" | ||
489 | ] | ||
490 | }, | ||
491 | "default": null | ||
492 | }, | ||
493 | "rust-analyzer.withSysroot": { | ||
494 | "markdownDescription": "Internal config for debugging, disables loading of sysroot crates", | ||
495 | "type": "boolean", | ||
496 | "default": true | ||
478 | } | 497 | } |
479 | } | 498 | } |
480 | }, | 499 | }, |