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 | }, |
