mirror of
https://github.com/rust-lang/rust.git
synced 2025-01-19 11:12:43 +00:00
add sysroot boilerplate
This commit is contained in:
parent
b6bc55f542
commit
e8923713c5
@ -347,11 +347,11 @@ pub fn handle_runnables(
|
|||||||
.read()
|
.read()
|
||||||
.file2path(ra_vfs::VfsFile(file_id.0.into()));
|
.file2path(ra_vfs::VfsFile(file_id.0.into()));
|
||||||
let res = world.workspaces.iter().find_map(|ws| {
|
let res = world.workspaces.iter().find_map(|ws| {
|
||||||
let tgt = ws.target_by_root(&path)?;
|
let tgt = ws.cargo.target_by_root(&path)?;
|
||||||
let res = CargoTargetSpec {
|
let res = CargoTargetSpec {
|
||||||
package: tgt.package(ws).name(ws).to_string(),
|
package: tgt.package(&ws.cargo).name(&ws.cargo).to_string(),
|
||||||
target: tgt.name(ws).to_string(),
|
target: tgt.name(&ws.cargo).to_string(),
|
||||||
target_kind: tgt.kind(ws),
|
target_kind: tgt.kind(&ws.cargo),
|
||||||
};
|
};
|
||||||
Some(res)
|
Some(res)
|
||||||
});
|
});
|
||||||
|
@ -1,4 +1,7 @@
|
|||||||
use std::path::{Path, PathBuf};
|
use std::{
|
||||||
|
path::{Path, PathBuf},
|
||||||
|
process::Command,
|
||||||
|
};
|
||||||
|
|
||||||
use cargo_metadata::{metadata_run, CargoOpt};
|
use cargo_metadata::{metadata_run, CargoOpt};
|
||||||
use ra_syntax::SmolStr;
|
use ra_syntax::SmolStr;
|
||||||
@ -9,6 +12,36 @@ use thread_worker::{WorkerHandle, Worker};
|
|||||||
|
|
||||||
use crate::Result;
|
use crate::Result;
|
||||||
|
|
||||||
|
#[derive(Debug, Clone)]
|
||||||
|
pub struct ProjectWorkspace {
|
||||||
|
pub(crate) cargo: CargoWorkspace,
|
||||||
|
pub(crate) sysroot: Sysroot,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl ProjectWorkspace {
|
||||||
|
pub fn discover(path: &Path) -> Result<ProjectWorkspace> {
|
||||||
|
let cargo_toml = find_cargo_toml(path)?;
|
||||||
|
let cargo = CargoWorkspace::from_cargo_metadata(&cargo_toml)?;
|
||||||
|
let sysroot = sysroot_info(&cargo_toml)?;
|
||||||
|
let res = ProjectWorkspace { cargo, sysroot };
|
||||||
|
Ok(res)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn workspace_loader() -> (Worker<PathBuf, Result<ProjectWorkspace>>, WorkerHandle) {
|
||||||
|
thread_worker::spawn::<PathBuf, Result<ProjectWorkspace>, _>(
|
||||||
|
"workspace loader",
|
||||||
|
1,
|
||||||
|
|input_receiver, output_sender| {
|
||||||
|
input_receiver
|
||||||
|
.into_iter()
|
||||||
|
.map(|path| ProjectWorkspace::discover(path.as_path()))
|
||||||
|
.try_for_each(|it| output_sender.send(it))
|
||||||
|
.unwrap()
|
||||||
|
},
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
/// `CargoWorksapce` represents the logical structure of, well, a Cargo
|
/// `CargoWorksapce` represents the logical structure of, well, a Cargo
|
||||||
/// workspace. It pretty closely mirrors `cargo metadata` output.
|
/// workspace. It pretty closely mirrors `cargo metadata` output.
|
||||||
///
|
///
|
||||||
@ -63,6 +96,11 @@ pub enum TargetKind {
|
|||||||
Other,
|
Other,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[derive(Debug, Clone)]
|
||||||
|
pub(crate) struct Sysroot {
|
||||||
|
crates: FxHashMap<SmolStr, PathBuf>,
|
||||||
|
}
|
||||||
|
|
||||||
impl Package {
|
impl Package {
|
||||||
pub fn name(self, ws: &CargoWorkspace) -> &str {
|
pub fn name(self, ws: &CargoWorkspace) -> &str {
|
||||||
ws.packages[self].name.as_str()
|
ws.packages[self].name.as_str()
|
||||||
@ -160,6 +198,68 @@ impl CargoWorkspace {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn sysroot_info(cargo_toml: &Path) -> Result<Sysroot> {
|
||||||
|
let rustc_output = Command::new("rustc")
|
||||||
|
.current_dir(cargo_toml.parent().unwrap())
|
||||||
|
.args(&["--print", "sysroot"])
|
||||||
|
.output()?;
|
||||||
|
if !rustc_output.status.success() {
|
||||||
|
failure::bail!("failed to locate sysroot")
|
||||||
|
}
|
||||||
|
let stdout = String::from_utf8(rustc_output.stdout)?;
|
||||||
|
let sysroot_path = Path::new(stdout.trim());
|
||||||
|
let src = sysroot_path.join("lib/rustlib/src/rust/src");
|
||||||
|
|
||||||
|
let crates: &[(&str, &[&str])] = &[
|
||||||
|
(
|
||||||
|
"std",
|
||||||
|
&[
|
||||||
|
"alloc_jemalloc",
|
||||||
|
"alloc_system",
|
||||||
|
"panic_abort",
|
||||||
|
"rand",
|
||||||
|
"compiler_builtins",
|
||||||
|
"unwind",
|
||||||
|
"rustc_asan",
|
||||||
|
"rustc_lsan",
|
||||||
|
"rustc_msan",
|
||||||
|
"rustc_tsan",
|
||||||
|
"build_helper",
|
||||||
|
],
|
||||||
|
),
|
||||||
|
("core", &[]),
|
||||||
|
("alloc", &[]),
|
||||||
|
("collections", &[]),
|
||||||
|
("libc", &[]),
|
||||||
|
("panic_unwind", &[]),
|
||||||
|
("proc_macro", &[]),
|
||||||
|
("rustc_unicode", &[]),
|
||||||
|
("std_unicode", &[]),
|
||||||
|
("test", &[]),
|
||||||
|
// Feature gated
|
||||||
|
("alloc_jemalloc", &[]),
|
||||||
|
("alloc_system", &[]),
|
||||||
|
("compiler_builtins", &[]),
|
||||||
|
("getopts", &[]),
|
||||||
|
("panic_unwind", &[]),
|
||||||
|
("panic_abort", &[]),
|
||||||
|
("rand", &[]),
|
||||||
|
("term", &[]),
|
||||||
|
("unwind", &[]),
|
||||||
|
// Dependencies
|
||||||
|
("build_helper", &[]),
|
||||||
|
("rustc_asan", &[]),
|
||||||
|
("rustc_lsan", &[]),
|
||||||
|
("rustc_msan", &[]),
|
||||||
|
("rustc_tsan", &[]),
|
||||||
|
("syntax", &[]),
|
||||||
|
];
|
||||||
|
|
||||||
|
Ok(Sysroot {
|
||||||
|
crates: FxHashMap::default(),
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
fn find_cargo_toml(path: &Path) -> Result<PathBuf> {
|
fn find_cargo_toml(path: &Path) -> Result<PathBuf> {
|
||||||
if path.ends_with("Cargo.toml") {
|
if path.ends_with("Cargo.toml") {
|
||||||
return Ok(path.to_path_buf());
|
return Ok(path.to_path_buf());
|
||||||
@ -190,17 +290,3 @@ impl TargetKind {
|
|||||||
TargetKind::Other
|
TargetKind::Other
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn workspace_loader() -> (Worker<PathBuf, Result<CargoWorkspace>>, WorkerHandle) {
|
|
||||||
thread_worker::spawn::<PathBuf, Result<CargoWorkspace>, _>(
|
|
||||||
"workspace loader",
|
|
||||||
1,
|
|
||||||
|input_receiver, output_sender| {
|
|
||||||
input_receiver
|
|
||||||
.into_iter()
|
|
||||||
.map(|path| CargoWorkspace::from_cargo_metadata(path.as_path()))
|
|
||||||
.try_for_each(|it| output_sender.send(it))
|
|
||||||
.unwrap()
|
|
||||||
},
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
0
crates/ra_lsp_server/src/project_model/sysroot.rs
Normal file
0
crates/ra_lsp_server/src/project_model/sysroot.rs
Normal file
@ -15,7 +15,7 @@ use parking_lot::RwLock;
|
|||||||
use failure::format_err;
|
use failure::format_err;
|
||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
project_model::{CargoWorkspace, TargetKind},
|
project_model::{ProjectWorkspace, TargetKind},
|
||||||
Result,
|
Result,
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -23,26 +23,26 @@ use crate::{
|
|||||||
pub struct ServerWorldState {
|
pub struct ServerWorldState {
|
||||||
pub roots_to_scan: usize,
|
pub roots_to_scan: usize,
|
||||||
pub root: PathBuf,
|
pub root: PathBuf,
|
||||||
pub workspaces: Arc<Vec<CargoWorkspace>>,
|
pub workspaces: Arc<Vec<ProjectWorkspace>>,
|
||||||
pub analysis_host: AnalysisHost,
|
pub analysis_host: AnalysisHost,
|
||||||
pub vfs: Arc<RwLock<Vfs>>,
|
pub vfs: Arc<RwLock<Vfs>>,
|
||||||
}
|
}
|
||||||
|
|
||||||
pub struct ServerWorld {
|
pub struct ServerWorld {
|
||||||
pub workspaces: Arc<Vec<CargoWorkspace>>,
|
pub workspaces: Arc<Vec<ProjectWorkspace>>,
|
||||||
pub analysis: Analysis,
|
pub analysis: Analysis,
|
||||||
pub vfs: Arc<RwLock<Vfs>>,
|
pub vfs: Arc<RwLock<Vfs>>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl ServerWorldState {
|
impl ServerWorldState {
|
||||||
pub fn new(root: PathBuf, workspaces: Vec<CargoWorkspace>) -> ServerWorldState {
|
pub fn new(root: PathBuf, workspaces: Vec<ProjectWorkspace>) -> ServerWorldState {
|
||||||
let mut change = AnalysisChange::new();
|
let mut change = AnalysisChange::new();
|
||||||
|
|
||||||
let mut roots = Vec::new();
|
let mut roots = Vec::new();
|
||||||
roots.push(root.clone());
|
roots.push(root.clone());
|
||||||
for ws in workspaces.iter() {
|
for ws in workspaces.iter() {
|
||||||
for pkg in ws.packages() {
|
for pkg in ws.cargo.packages() {
|
||||||
roots.push(pkg.root(&ws).to_path_buf());
|
roots.push(pkg.root(&ws.cargo).to_path_buf());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
let roots_to_scan = roots.len();
|
let roots_to_scan = roots.len();
|
||||||
@ -56,13 +56,13 @@ impl ServerWorldState {
|
|||||||
let mut pkg_to_lib_crate = FxHashMap::default();
|
let mut pkg_to_lib_crate = FxHashMap::default();
|
||||||
let mut pkg_crates = FxHashMap::default();
|
let mut pkg_crates = FxHashMap::default();
|
||||||
for ws in workspaces.iter() {
|
for ws in workspaces.iter() {
|
||||||
for pkg in ws.packages() {
|
for pkg in ws.cargo.packages() {
|
||||||
for tgt in pkg.targets(ws) {
|
for tgt in pkg.targets(&ws.cargo) {
|
||||||
let root = tgt.root(ws);
|
let root = tgt.root(&ws.cargo);
|
||||||
if let Some(file_id) = vfs.load(root) {
|
if let Some(file_id) = vfs.load(root) {
|
||||||
let file_id = FileId(file_id.0.into());
|
let file_id = FileId(file_id.0.into());
|
||||||
let crate_id = crate_graph.add_crate_root(file_id);
|
let crate_id = crate_graph.add_crate_root(file_id);
|
||||||
if tgt.kind(ws) == TargetKind::Lib {
|
if tgt.kind(&ws.cargo) == TargetKind::Lib {
|
||||||
pkg_to_lib_crate.insert(pkg, crate_id);
|
pkg_to_lib_crate.insert(pkg, crate_id);
|
||||||
}
|
}
|
||||||
pkg_crates
|
pkg_crates
|
||||||
@ -72,8 +72,8 @@ impl ServerWorldState {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
for pkg in ws.packages() {
|
for pkg in ws.cargo.packages() {
|
||||||
for dep in pkg.dependencies(ws) {
|
for dep in pkg.dependencies(&ws.cargo) {
|
||||||
if let Some(&to) = pkg_to_lib_crate.get(&dep.pkg) {
|
if let Some(&to) = pkg_to_lib_crate.get(&dep.pkg) {
|
||||||
for &from in pkg_crates.get(&pkg).into_iter().flatten() {
|
for &from in pkg_crates.get(&pkg).into_iter().flatten() {
|
||||||
crate_graph.add_dep(from, dep.name.clone(), to);
|
crate_graph.add_dep(from, dep.name.clone(), to);
|
||||||
|
@ -4,7 +4,7 @@ use languageserver_types::{
|
|||||||
CodeActionContext, DocumentFormattingParams, FormattingOptions, Position, Range,
|
CodeActionContext, DocumentFormattingParams, FormattingOptions, Position, Range,
|
||||||
};
|
};
|
||||||
use ra_lsp_server::req::{
|
use ra_lsp_server::req::{
|
||||||
CodeActionParams, CodeActionRequest, Formatting, Runnables, RunnablesParams,
|
CodeActionParams, CodeActionRequest, Formatting, Runnables, RunnablesParams, CompletionParams, Completion,
|
||||||
};
|
};
|
||||||
use serde_json::json;
|
use serde_json::json;
|
||||||
|
|
||||||
@ -12,6 +12,45 @@ use crate::support::project;
|
|||||||
|
|
||||||
const LOG: &'static str = "";
|
const LOG: &'static str = "";
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn completes_items_from_standard_library() {
|
||||||
|
let server = project(
|
||||||
|
r#"
|
||||||
|
//- Cargo.toml
|
||||||
|
[package]
|
||||||
|
name = "foo"
|
||||||
|
version = "0.0.0"
|
||||||
|
|
||||||
|
//- src/lib.rs
|
||||||
|
use std::collections::;
|
||||||
|
"#,
|
||||||
|
);
|
||||||
|
server.wait_for_feedback("workspace loaded");
|
||||||
|
server.request::<Completion>(
|
||||||
|
CompletionParams {
|
||||||
|
text_document: server.doc_id("src/lib.rs"),
|
||||||
|
context: None,
|
||||||
|
position: Position::new(0, 22),
|
||||||
|
},
|
||||||
|
json!([
|
||||||
|
{
|
||||||
|
"filterText": "self",
|
||||||
|
"insertText": "self",
|
||||||
|
"insertTextFormat": 1,
|
||||||
|
"kind": 14,
|
||||||
|
"label": "self"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"filterText": "super",
|
||||||
|
"insertText": "super",
|
||||||
|
"insertTextFormat": 1,
|
||||||
|
"kind": 14,
|
||||||
|
"label": "super"
|
||||||
|
}
|
||||||
|
]),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_runnables_no_project() {
|
fn test_runnables_no_project() {
|
||||||
let server = project(
|
let server = project(
|
||||||
|
Loading…
Reference in New Issue
Block a user