mirror of
https://github.com/rust-lang/rust-analyzer
synced 2025-01-26 11:55:04 +00:00
Merge #4730
4730: Document rust-project.json r=matklad a=matklad
bors r+
🤖
Co-authored-by: Aleksey Kladov <aleksey.kladov@gmail.com>
This commit is contained in:
commit
1edf6d2d4f
5 changed files with 118 additions and 20 deletions
|
@ -32,6 +32,12 @@ pub enum ProjectWorkspace {
|
||||||
Json { project: JsonProject },
|
Json { project: JsonProject },
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl From<JsonProject> for ProjectWorkspace {
|
||||||
|
fn from(project: JsonProject) -> ProjectWorkspace {
|
||||||
|
ProjectWorkspace::Json { project }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/// `PackageRoot` describes a package root folder.
|
/// `PackageRoot` describes a package root folder.
|
||||||
/// Which may be an external dependency, or a member of
|
/// Which may be an external dependency, or a member of
|
||||||
/// the current workspace.
|
/// the current workspace.
|
||||||
|
@ -144,11 +150,11 @@ impl ProjectManifest {
|
||||||
|
|
||||||
impl ProjectWorkspace {
|
impl ProjectWorkspace {
|
||||||
pub fn load(
|
pub fn load(
|
||||||
root: ProjectManifest,
|
manifest: ProjectManifest,
|
||||||
cargo_features: &CargoConfig,
|
cargo_features: &CargoConfig,
|
||||||
with_sysroot: bool,
|
with_sysroot: bool,
|
||||||
) -> Result<ProjectWorkspace> {
|
) -> Result<ProjectWorkspace> {
|
||||||
let res = match root {
|
let res = match manifest {
|
||||||
ProjectManifest::ProjectJson(project_json) => {
|
ProjectManifest::ProjectJson(project_json) => {
|
||||||
let file = File::open(&project_json).with_context(|| {
|
let file = File::open(&project_json).with_context(|| {
|
||||||
format!("Failed to open json file {}", project_json.display())
|
format!("Failed to open json file {}", project_json.display())
|
||||||
|
|
|
@ -261,6 +261,22 @@ impl Config {
|
||||||
self.lens = LensConfig::NO_LENS;
|
self.lens = LensConfig::NO_LENS;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if let Some(linked_projects) = get::<Vec<ManifestOrJsonProject>>(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);
|
log::info!("Config::update() = {:#?}", self);
|
||||||
|
|
||||||
fn get<'a, T: Deserialize<'a>>(value: &'a serde_json::Value, pointer: &str) -> Option<T> {
|
fn get<'a, T: Deserialize<'a>>(value: &'a serde_json::Value, pointer: &str) -> Option<T> {
|
||||||
|
@ -324,3 +340,10 @@ impl Config {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[derive(Deserialize)]
|
||||||
|
#[serde(untagged)]
|
||||||
|
enum ManifestOrJsonProject {
|
||||||
|
Manifest(PathBuf),
|
||||||
|
JsonProject(JsonProject),
|
||||||
|
}
|
||||||
|
|
|
@ -105,24 +105,23 @@ pub fn main_loop(config: Config, connection: Connection) -> Result<()> {
|
||||||
.linked_projects
|
.linked_projects
|
||||||
.iter()
|
.iter()
|
||||||
.filter_map(|project| match project {
|
.filter_map(|project| match project {
|
||||||
LinkedProject::ProjectManifest(it) => Some(it),
|
LinkedProject::ProjectManifest(manifest) => {
|
||||||
LinkedProject::JsonProject(_) => None,
|
ra_project_model::ProjectWorkspace::load(
|
||||||
})
|
manifest.clone(),
|
||||||
.filter_map(|root| {
|
&config.cargo,
|
||||||
ra_project_model::ProjectWorkspace::load(
|
config.with_sysroot,
|
||||||
root.clone(),
|
)
|
||||||
&config.cargo,
|
.map_err(|err| {
|
||||||
config.with_sysroot,
|
log::error!("failed to load workspace: {:#}", err);
|
||||||
)
|
show_message(
|
||||||
.map_err(|err| {
|
lsp_types::MessageType::Error,
|
||||||
log::error!("failed to load workspace: {:#}", err);
|
format!("rust-analyzer failed to load workspace: {:#}", err),
|
||||||
show_message(
|
&connection.sender,
|
||||||
lsp_types::MessageType::Error,
|
);
|
||||||
format!("rust-analyzer failed to load workspace: {:#}", err),
|
})
|
||||||
&connection.sender,
|
.ok()
|
||||||
);
|
}
|
||||||
})
|
LinkedProject::JsonProject(it) => Some(it.clone().into()),
|
||||||
.ok()
|
|
||||||
})
|
})
|
||||||
.collect::<Vec<_>>()
|
.collect::<Vec<_>>()
|
||||||
};
|
};
|
||||||
|
|
|
@ -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`).
|
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.
|
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
|
== Features
|
||||||
|
|
||||||
include::./generated_features.adoc[]
|
include::./generated_features.adoc[]
|
||||||
|
|
|
@ -475,6 +475,25 @@
|
||||||
"markdownDescription": "Whether to show Implementations lens. Only applies when `#rust-analyzer.lens.enable#` is set.",
|
"markdownDescription": "Whether to show Implementations lens. Only applies when `#rust-analyzer.lens.enable#` is set.",
|
||||||
"type": "boolean",
|
"type": "boolean",
|
||||||
"default": true
|
"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
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
Loading…
Reference in a new issue