mirror of
https://github.com/rust-lang/rust.git
synced 2025-01-19 03:03:21 +00:00
add sysroot boilerplate
This commit is contained in:
parent
b6bc55f542
commit
e8923713c5
@ -347,11 +347,11 @@ pub fn handle_runnables(
|
||||
.read()
|
||||
.file2path(ra_vfs::VfsFile(file_id.0.into()));
|
||||
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 {
|
||||
package: tgt.package(ws).name(ws).to_string(),
|
||||
target: tgt.name(ws).to_string(),
|
||||
target_kind: tgt.kind(ws),
|
||||
package: tgt.package(&ws.cargo).name(&ws.cargo).to_string(),
|
||||
target: tgt.name(&ws.cargo).to_string(),
|
||||
target_kind: tgt.kind(&ws.cargo),
|
||||
};
|
||||
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 ra_syntax::SmolStr;
|
||||
@ -9,6 +12,36 @@ use thread_worker::{WorkerHandle, Worker};
|
||||
|
||||
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
|
||||
/// workspace. It pretty closely mirrors `cargo metadata` output.
|
||||
///
|
||||
@ -63,6 +96,11 @@ pub enum TargetKind {
|
||||
Other,
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone)]
|
||||
pub(crate) struct Sysroot {
|
||||
crates: FxHashMap<SmolStr, PathBuf>,
|
||||
}
|
||||
|
||||
impl Package {
|
||||
pub fn name(self, ws: &CargoWorkspace) -> &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> {
|
||||
if path.ends_with("Cargo.toml") {
|
||||
return Ok(path.to_path_buf());
|
||||
@ -190,17 +290,3 @@ impl TargetKind {
|
||||
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 crate::{
|
||||
project_model::{CargoWorkspace, TargetKind},
|
||||
project_model::{ProjectWorkspace, TargetKind},
|
||||
Result,
|
||||
};
|
||||
|
||||
@ -23,26 +23,26 @@ use crate::{
|
||||
pub struct ServerWorldState {
|
||||
pub roots_to_scan: usize,
|
||||
pub root: PathBuf,
|
||||
pub workspaces: Arc<Vec<CargoWorkspace>>,
|
||||
pub workspaces: Arc<Vec<ProjectWorkspace>>,
|
||||
pub analysis_host: AnalysisHost,
|
||||
pub vfs: Arc<RwLock<Vfs>>,
|
||||
}
|
||||
|
||||
pub struct ServerWorld {
|
||||
pub workspaces: Arc<Vec<CargoWorkspace>>,
|
||||
pub workspaces: Arc<Vec<ProjectWorkspace>>,
|
||||
pub analysis: Analysis,
|
||||
pub vfs: Arc<RwLock<Vfs>>,
|
||||
}
|
||||
|
||||
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 roots = Vec::new();
|
||||
roots.push(root.clone());
|
||||
for ws in workspaces.iter() {
|
||||
for pkg in ws.packages() {
|
||||
roots.push(pkg.root(&ws).to_path_buf());
|
||||
for pkg in ws.cargo.packages() {
|
||||
roots.push(pkg.root(&ws.cargo).to_path_buf());
|
||||
}
|
||||
}
|
||||
let roots_to_scan = roots.len();
|
||||
@ -56,13 +56,13 @@ impl ServerWorldState {
|
||||
let mut pkg_to_lib_crate = FxHashMap::default();
|
||||
let mut pkg_crates = FxHashMap::default();
|
||||
for ws in workspaces.iter() {
|
||||
for pkg in ws.packages() {
|
||||
for tgt in pkg.targets(ws) {
|
||||
let root = tgt.root(ws);
|
||||
for pkg in ws.cargo.packages() {
|
||||
for tgt in pkg.targets(&ws.cargo) {
|
||||
let root = tgt.root(&ws.cargo);
|
||||
if let Some(file_id) = vfs.load(root) {
|
||||
let file_id = FileId(file_id.0.into());
|
||||
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_crates
|
||||
@ -72,8 +72,8 @@ impl ServerWorldState {
|
||||
}
|
||||
}
|
||||
}
|
||||
for pkg in ws.packages() {
|
||||
for dep in pkg.dependencies(ws) {
|
||||
for pkg in ws.cargo.packages() {
|
||||
for dep in pkg.dependencies(&ws.cargo) {
|
||||
if let Some(&to) = pkg_to_lib_crate.get(&dep.pkg) {
|
||||
for &from in pkg_crates.get(&pkg).into_iter().flatten() {
|
||||
crate_graph.add_dep(from, dep.name.clone(), to);
|
||||
|
@ -4,7 +4,7 @@ use languageserver_types::{
|
||||
CodeActionContext, DocumentFormattingParams, FormattingOptions, Position, Range,
|
||||
};
|
||||
use ra_lsp_server::req::{
|
||||
CodeActionParams, CodeActionRequest, Formatting, Runnables, RunnablesParams,
|
||||
CodeActionParams, CodeActionRequest, Formatting, Runnables, RunnablesParams, CompletionParams, Completion,
|
||||
};
|
||||
use serde_json::json;
|
||||
|
||||
@ -12,6 +12,45 @@ use crate::support::project;
|
||||
|
||||
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]
|
||||
fn test_runnables_no_project() {
|
||||
let server = project(
|
||||
|
Loading…
Reference in New Issue
Block a user