From fa019c8f562326a720d2ef9165626c4c5703f67b Mon Sep 17 00:00:00 2001 From: Aleksey Kladov Date: Wed, 3 Jun 2020 14:48:38 +0200 Subject: Document rust-project.json --- crates/ra_project_model/src/lib.rs | 10 +++++-- crates/rust-analyzer/src/config.rs | 23 ++++++++++++++++ crates/rust-analyzer/src/main_loop.rs | 35 ++++++++++++------------ docs/user/manual.adoc | 51 +++++++++++++++++++++++++++++++++++ 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 { Json { project: JsonProject }, } +impl From for ProjectWorkspace { + fn from(project: JsonProject) -> ProjectWorkspace { + ProjectWorkspace::Json { project } + } +} + /// `PackageRoot` describes a package root folder. /// Which may be an external dependency, or a member of /// the current workspace. @@ -144,11 +150,11 @@ impl ProjectManifest { impl ProjectWorkspace { pub fn load( - root: ProjectManifest, + manifest: ProjectManifest, cargo_features: &CargoConfig, with_sysroot: bool, ) -> Result { - let res = match root { + let res = match manifest { ProjectManifest::ProjectJson(project_json) => { let file = File::open(&project_json).with_context(|| { 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 { self.lens = LensConfig::NO_LENS; } + if let Some(linked_projects) = get::>(value, "/linkedProjects") { + if !linked_projects.is_empty() { + self.linked_projects.clear(); + for linked_project in linked_projects { + let linked_project = match linked_project { + ManifestOrJsonProject::Manifest(it) => match ProjectManifest::from_manifest_file(it) { + Ok(it) => it.into(), + Err(_) => continue, + } + ManifestOrJsonProject::JsonProject(it) => it.into(), + }; + self.linked_projects.push(linked_project); + } + } + } + log::info!("Config::update() = {:#?}", self); fn get<'a, T: Deserialize<'a>>(value: &'a serde_json::Value, pointer: &str) -> Option { @@ -324,3 +340,10 @@ impl Config { } } } + +#[derive(Deserialize)] +#[serde(untagged)] +enum ManifestOrJsonProject { + Manifest(PathBuf), + JsonProject(JsonProject), +} 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<()> { .linked_projects .iter() .filter_map(|project| match project { - LinkedProject::ProjectManifest(it) => Some(it), - LinkedProject::JsonProject(_) => None, - }) - .filter_map(|root| { - ra_project_model::ProjectWorkspace::load( - root.clone(), - &config.cargo, - config.with_sysroot, - ) - .map_err(|err| { - log::error!("failed to load workspace: {:#}", err); - show_message( - lsp_types::MessageType::Error, - format!("rust-analyzer failed to load workspace: {:#}", err), - &connection.sender, - ); - }) - .ok() + LinkedProject::ProjectManifest(manifest) => { + ra_project_model::ProjectWorkspace::load( + manifest.clone(), + &config.cargo, + config.with_sysroot, + ) + .map_err(|err| { + log::error!("failed to load workspace: {:#}", err); + show_message( + lsp_types::MessageType::Error, + format!("rust-analyzer failed to load workspace: {:#}", err), + &connection.sender, + ); + }) + .ok() + } + LinkedProject::JsonProject(it) => Some(it.clone().into()), }) .collect::>() }; 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 1. Rename, symlink or copy the `rust-analyzer` binary to `rls` and place it somewhere Builder can find (in `PATH`, or under `~/.cargo/bin`). 2. Enable the Rust Builder plugin. +== Non-Cargo Based Projects + +rust-analyzer does not require Cargo. +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: + +[source,TypeScript] +---- +interface JsonProject { + /// The set of paths containing the crates for this project. + /// Any `Crate` must be nested inside some `root`. + roots: string[]; + /// The set of crates comprising the current project. + /// Must include all transitive dependencies as well as sysroot crate (libstd, libcore and such). + crates: Crate[]; +} + +interface Crate { + /// Path to the root module of the crate. + root_module: string; + /// Edition of the crate. + edition: "2015" | "2018"; + /// Dependencies + deps: Dep[]; + /// The set of cfgs activated for a given crate, like `["unix", "feature=foo", "feature=bar"]`. + cfg: string[]; + + /// value of the OUT_DIR env variable. + out_dir?: string; + /// For proc-macro crates, path to compiles proc-macro (.so file). + proc_macro_dylib_path?: string; +} + +interface Dep { + /// Index of a crate in the `crates` array. + crate: number, + /// Name as should appear in the (implicit) `extern crate name` declaration. + name: string, +} +---- + +This format is provisional and subject to change. +Specifically, the `roots` setup will be different eventually. + +There are tree ways to feed `rust-project.json` to rust-analyzer: + +* Place `rust-project.json` file at the root of the project, and rust-anlayzer will discover it. +* 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). +* Specify `"rust-analyzer.linkedProjects": [ { "roots": [...], "crates": [...] }]` inline. + +See https://github.com/rust-analyzer/rust-project.json-example for a small example. + == Features 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 @@ "markdownDescription": "Whether to show Implementations lens. Only applies when `#rust-analyzer.lens.enable#` is set.", "type": "boolean", "default": true + }, + "rust-analyzer.linkedProjects": { + "markdownDescription": [ + "Disable project auto-discovery in favor of explicitly specified set of projects.", + "Elements must be paths pointing to Cargo.toml, rust-project.json, or JSON objects in rust-project.json format" + ], + "type": "array", + "items": { + "type": [ + "string", + "object" + ] + }, + "default": null + }, + "rust-analyzer.withSysroot": { + "markdownDescription": "Internal config for debugging, disables loading of sysroot crates", + "type": "boolean", + "default": true } } }, -- cgit v1.2.3