mirror of
https://github.com/rust-lang/rust-analyzer
synced 2024-12-27 21:43:37 +00:00
Auto merge of #14405 - Veykril:proc-macro-loading, r=Veykril
feat: Load proc-macros asynchronously Closes https://github.com/rust-lang/rust-analyzer/issues/8646
This commit is contained in:
commit
90340b71ad
23 changed files with 289 additions and 228 deletions
|
@ -6,7 +6,7 @@ use std::{fmt, sync::Arc};
|
||||||
use salsa::Durability;
|
use salsa::Durability;
|
||||||
use vfs::FileId;
|
use vfs::FileId;
|
||||||
|
|
||||||
use crate::{CrateGraph, SourceDatabaseExt, SourceRoot, SourceRootId};
|
use crate::{CrateGraph, ProcMacros, SourceDatabaseExt, SourceRoot, SourceRootId};
|
||||||
|
|
||||||
/// Encapsulate a bunch of raw `.set` calls on the database.
|
/// Encapsulate a bunch of raw `.set` calls on the database.
|
||||||
#[derive(Default)]
|
#[derive(Default)]
|
||||||
|
@ -14,6 +14,7 @@ pub struct Change {
|
||||||
pub roots: Option<Vec<SourceRoot>>,
|
pub roots: Option<Vec<SourceRoot>>,
|
||||||
pub files_changed: Vec<(FileId, Option<Arc<String>>)>,
|
pub files_changed: Vec<(FileId, Option<Arc<String>>)>,
|
||||||
pub crate_graph: Option<CrateGraph>,
|
pub crate_graph: Option<CrateGraph>,
|
||||||
|
pub proc_macros: Option<ProcMacros>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl fmt::Debug for Change {
|
impl fmt::Debug for Change {
|
||||||
|
@ -49,6 +50,10 @@ impl Change {
|
||||||
self.crate_graph = Some(graph);
|
self.crate_graph = Some(graph);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn set_proc_macros(&mut self, proc_macros: ProcMacros) {
|
||||||
|
self.proc_macros = Some(proc_macros);
|
||||||
|
}
|
||||||
|
|
||||||
pub fn apply(self, db: &mut dyn SourceDatabaseExt) {
|
pub fn apply(self, db: &mut dyn SourceDatabaseExt) {
|
||||||
let _p = profile::span("RootDatabase::apply_change");
|
let _p = profile::span("RootDatabase::apply_change");
|
||||||
if let Some(roots) = self.roots {
|
if let Some(roots) = self.roots {
|
||||||
|
@ -73,6 +78,9 @@ impl Change {
|
||||||
if let Some(crate_graph) = self.crate_graph {
|
if let Some(crate_graph) = self.crate_graph {
|
||||||
db.set_crate_graph_with_durability(Arc::new(crate_graph), Durability::HIGH)
|
db.set_crate_graph_with_durability(Arc::new(crate_graph), Durability::HIGH)
|
||||||
}
|
}
|
||||||
|
if let Some(proc_macros) = self.proc_macros {
|
||||||
|
db.set_proc_macros_with_durability(Arc::new(proc_macros), Durability::HIGH)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -12,8 +12,8 @@ use vfs::{file_set::FileSet, VfsPath};
|
||||||
use crate::{
|
use crate::{
|
||||||
input::{CrateName, CrateOrigin, LangCrateOrigin},
|
input::{CrateName, CrateOrigin, LangCrateOrigin},
|
||||||
Change, CrateDisplayName, CrateGraph, CrateId, Dependency, Edition, Env, FileId, FilePosition,
|
Change, CrateDisplayName, CrateGraph, CrateId, Dependency, Edition, Env, FileId, FilePosition,
|
||||||
FileRange, ProcMacro, ProcMacroExpander, ProcMacroExpansionError, SourceDatabaseExt,
|
FileRange, ProcMacro, ProcMacroExpander, ProcMacroExpansionError, ProcMacros,
|
||||||
SourceRoot, SourceRootId,
|
SourceDatabaseExt, SourceRoot, SourceRootId,
|
||||||
};
|
};
|
||||||
|
|
||||||
pub const WORKSPACE: SourceRootId = SourceRootId(0);
|
pub const WORKSPACE: SourceRootId = SourceRootId(0);
|
||||||
|
@ -100,7 +100,7 @@ impl ChangeFixture {
|
||||||
|
|
||||||
pub fn parse_with_proc_macros(
|
pub fn parse_with_proc_macros(
|
||||||
ra_fixture: &str,
|
ra_fixture: &str,
|
||||||
mut proc_macros: Vec<(String, ProcMacro)>,
|
mut proc_macro_defs: Vec<(String, ProcMacro)>,
|
||||||
) -> ChangeFixture {
|
) -> ChangeFixture {
|
||||||
let (mini_core, proc_macro_names, fixture) = Fixture::parse(ra_fixture);
|
let (mini_core, proc_macro_names, fixture) = Fixture::parse(ra_fixture);
|
||||||
let mut change = Change::new();
|
let mut change = Change::new();
|
||||||
|
@ -160,7 +160,6 @@ impl ChangeFixture {
|
||||||
meta.cfg.clone(),
|
meta.cfg.clone(),
|
||||||
meta.cfg,
|
meta.cfg,
|
||||||
meta.env,
|
meta.env,
|
||||||
Ok(Vec::new()),
|
|
||||||
false,
|
false,
|
||||||
origin,
|
origin,
|
||||||
meta.target_data_layout
|
meta.target_data_layout
|
||||||
|
@ -200,7 +199,6 @@ impl ChangeFixture {
|
||||||
default_cfg.clone(),
|
default_cfg.clone(),
|
||||||
default_cfg,
|
default_cfg,
|
||||||
Env::default(),
|
Env::default(),
|
||||||
Ok(Vec::new()),
|
|
||||||
false,
|
false,
|
||||||
CrateOrigin::CratesIo { repo: None, name: None },
|
CrateOrigin::CratesIo { repo: None, name: None },
|
||||||
default_target_data_layout
|
default_target_data_layout
|
||||||
|
@ -244,7 +242,6 @@ impl ChangeFixture {
|
||||||
CfgOptions::default(),
|
CfgOptions::default(),
|
||||||
CfgOptions::default(),
|
CfgOptions::default(),
|
||||||
Env::default(),
|
Env::default(),
|
||||||
Ok(Vec::new()),
|
|
||||||
false,
|
false,
|
||||||
CrateOrigin::Lang(LangCrateOrigin::Core),
|
CrateOrigin::Lang(LangCrateOrigin::Core),
|
||||||
target_layout.clone(),
|
target_layout.clone(),
|
||||||
|
@ -257,12 +254,13 @@ impl ChangeFixture {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
let mut proc_macros = ProcMacros::default();
|
||||||
if !proc_macro_names.is_empty() {
|
if !proc_macro_names.is_empty() {
|
||||||
let proc_lib_file = file_id;
|
let proc_lib_file = file_id;
|
||||||
file_id.0 += 1;
|
file_id.0 += 1;
|
||||||
|
|
||||||
proc_macros.extend(default_test_proc_macros());
|
proc_macro_defs.extend(default_test_proc_macros());
|
||||||
let (proc_macro, source) = filter_test_proc_macros(&proc_macro_names, proc_macros);
|
let (proc_macro, source) = filter_test_proc_macros(&proc_macro_names, proc_macro_defs);
|
||||||
let mut fs = FileSet::default();
|
let mut fs = FileSet::default();
|
||||||
fs.insert(
|
fs.insert(
|
||||||
proc_lib_file,
|
proc_lib_file,
|
||||||
|
@ -282,11 +280,11 @@ impl ChangeFixture {
|
||||||
CfgOptions::default(),
|
CfgOptions::default(),
|
||||||
CfgOptions::default(),
|
CfgOptions::default(),
|
||||||
Env::default(),
|
Env::default(),
|
||||||
Ok(proc_macro),
|
|
||||||
true,
|
true,
|
||||||
CrateOrigin::CratesIo { repo: None, name: None },
|
CrateOrigin::CratesIo { repo: None, name: None },
|
||||||
target_layout,
|
target_layout,
|
||||||
);
|
);
|
||||||
|
proc_macros.insert(proc_macros_crate, Ok(proc_macro));
|
||||||
|
|
||||||
for krate in all_crates {
|
for krate in all_crates {
|
||||||
crate_graph
|
crate_graph
|
||||||
|
@ -305,6 +303,7 @@ impl ChangeFixture {
|
||||||
roots.push(root);
|
roots.push(root);
|
||||||
change.set_roots(roots);
|
change.set_roots(roots);
|
||||||
change.set_crate_graph(crate_graph);
|
change.set_crate_graph(crate_graph);
|
||||||
|
change.set_proc_macros(proc_macros);
|
||||||
|
|
||||||
ChangeFixture { file_position, files, change }
|
ChangeFixture { file_position, files, change }
|
||||||
}
|
}
|
||||||
|
|
|
@ -6,14 +6,17 @@
|
||||||
//! actual IO. See `vfs` and `project_model` in the `rust-analyzer` crate for how
|
//! actual IO. See `vfs` and `project_model` in the `rust-analyzer` crate for how
|
||||||
//! actual IO is done and lowered to input.
|
//! actual IO is done and lowered to input.
|
||||||
|
|
||||||
use std::{fmt, ops, panic::RefUnwindSafe, str::FromStr, sync::Arc};
|
use std::{fmt, mem, ops, panic::RefUnwindSafe, str::FromStr, sync::Arc};
|
||||||
|
|
||||||
use cfg::CfgOptions;
|
use cfg::CfgOptions;
|
||||||
use rustc_hash::FxHashMap;
|
use rustc_hash::FxHashMap;
|
||||||
use stdx::hash::{NoHashHashMap, NoHashHashSet};
|
use stdx::hash::{NoHashHashMap, NoHashHashSet};
|
||||||
use syntax::SmolStr;
|
use syntax::SmolStr;
|
||||||
use tt::token_id::Subtree;
|
use tt::token_id::Subtree;
|
||||||
use vfs::{file_set::FileSet, AnchoredPath, FileId, VfsPath};
|
use vfs::{file_set::FileSet, AbsPathBuf, AnchoredPath, FileId, VfsPath};
|
||||||
|
|
||||||
|
pub type ProcMacroPaths = FxHashMap<CrateId, Result<(Option<String>, AbsPathBuf), String>>;
|
||||||
|
pub type ProcMacros = FxHashMap<CrateId, ProcMacroLoadResult>;
|
||||||
|
|
||||||
/// Files are grouped into source roots. A source root is a directory on the
|
/// Files are grouped into source roots. A source root is a directory on the
|
||||||
/// file systems which is watched for changes. Typically it corresponds to a
|
/// file systems which is watched for changes. Typically it corresponds to a
|
||||||
|
@ -269,7 +272,6 @@ pub struct CrateData {
|
||||||
pub target_layout: TargetLayoutLoadResult,
|
pub target_layout: TargetLayoutLoadResult,
|
||||||
pub env: Env,
|
pub env: Env,
|
||||||
pub dependencies: Vec<Dependency>,
|
pub dependencies: Vec<Dependency>,
|
||||||
pub proc_macro: ProcMacroLoadResult,
|
|
||||||
pub origin: CrateOrigin,
|
pub origin: CrateOrigin,
|
||||||
pub is_proc_macro: bool,
|
pub is_proc_macro: bool,
|
||||||
}
|
}
|
||||||
|
@ -322,7 +324,6 @@ impl CrateGraph {
|
||||||
cfg_options: CfgOptions,
|
cfg_options: CfgOptions,
|
||||||
potential_cfg_options: CfgOptions,
|
potential_cfg_options: CfgOptions,
|
||||||
env: Env,
|
env: Env,
|
||||||
proc_macro: ProcMacroLoadResult,
|
|
||||||
is_proc_macro: bool,
|
is_proc_macro: bool,
|
||||||
origin: CrateOrigin,
|
origin: CrateOrigin,
|
||||||
target_layout: Result<Arc<str>, Arc<str>>,
|
target_layout: Result<Arc<str>, Arc<str>>,
|
||||||
|
@ -335,7 +336,6 @@ impl CrateGraph {
|
||||||
cfg_options,
|
cfg_options,
|
||||||
potential_cfg_options,
|
potential_cfg_options,
|
||||||
env,
|
env,
|
||||||
proc_macro,
|
|
||||||
dependencies: Vec::new(),
|
dependencies: Vec::new(),
|
||||||
origin,
|
origin,
|
||||||
target_layout,
|
target_layout,
|
||||||
|
@ -456,11 +456,11 @@ impl CrateGraph {
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Extends this crate graph by adding a complete disjoint second crate
|
/// Extends this crate graph by adding a complete disjoint second crate
|
||||||
/// graph.
|
/// graph and adjust the ids in the [`ProcMacroPaths`] accordingly.
|
||||||
///
|
///
|
||||||
/// The ids of the crates in the `other` graph are shifted by the return
|
/// The ids of the crates in the `other` graph are shifted by the return
|
||||||
/// amount.
|
/// amount.
|
||||||
pub fn extend(&mut self, other: CrateGraph) -> u32 {
|
pub fn extend(&mut self, other: CrateGraph, proc_macros: &mut ProcMacroPaths) -> u32 {
|
||||||
let start = self.arena.len() as u32;
|
let start = self.arena.len() as u32;
|
||||||
self.arena.extend(other.arena.into_iter().map(|(id, mut data)| {
|
self.arena.extend(other.arena.into_iter().map(|(id, mut data)| {
|
||||||
let new_id = id.shift(start);
|
let new_id = id.shift(start);
|
||||||
|
@ -469,6 +469,11 @@ impl CrateGraph {
|
||||||
}
|
}
|
||||||
(new_id, data)
|
(new_id, data)
|
||||||
}));
|
}));
|
||||||
|
|
||||||
|
*proc_macros = mem::take(proc_macros)
|
||||||
|
.into_iter()
|
||||||
|
.map(|(id, macros)| (id.shift(start), macros))
|
||||||
|
.collect();
|
||||||
start
|
start
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -645,7 +650,6 @@ mod tests {
|
||||||
CfgOptions::default(),
|
CfgOptions::default(),
|
||||||
CfgOptions::default(),
|
CfgOptions::default(),
|
||||||
Env::default(),
|
Env::default(),
|
||||||
Ok(Vec::new()),
|
|
||||||
false,
|
false,
|
||||||
CrateOrigin::CratesIo { repo: None, name: None },
|
CrateOrigin::CratesIo { repo: None, name: None },
|
||||||
Err("".into()),
|
Err("".into()),
|
||||||
|
@ -658,7 +662,6 @@ mod tests {
|
||||||
CfgOptions::default(),
|
CfgOptions::default(),
|
||||||
CfgOptions::default(),
|
CfgOptions::default(),
|
||||||
Env::default(),
|
Env::default(),
|
||||||
Ok(Vec::new()),
|
|
||||||
false,
|
false,
|
||||||
CrateOrigin::CratesIo { repo: None, name: None },
|
CrateOrigin::CratesIo { repo: None, name: None },
|
||||||
Err("".into()),
|
Err("".into()),
|
||||||
|
@ -671,7 +674,6 @@ mod tests {
|
||||||
CfgOptions::default(),
|
CfgOptions::default(),
|
||||||
CfgOptions::default(),
|
CfgOptions::default(),
|
||||||
Env::default(),
|
Env::default(),
|
||||||
Ok(Vec::new()),
|
|
||||||
false,
|
false,
|
||||||
CrateOrigin::CratesIo { repo: None, name: None },
|
CrateOrigin::CratesIo { repo: None, name: None },
|
||||||
Err("".into()),
|
Err("".into()),
|
||||||
|
@ -698,7 +700,6 @@ mod tests {
|
||||||
CfgOptions::default(),
|
CfgOptions::default(),
|
||||||
CfgOptions::default(),
|
CfgOptions::default(),
|
||||||
Env::default(),
|
Env::default(),
|
||||||
Ok(Vec::new()),
|
|
||||||
false,
|
false,
|
||||||
CrateOrigin::CratesIo { repo: None, name: None },
|
CrateOrigin::CratesIo { repo: None, name: None },
|
||||||
Err("".into()),
|
Err("".into()),
|
||||||
|
@ -711,7 +712,6 @@ mod tests {
|
||||||
CfgOptions::default(),
|
CfgOptions::default(),
|
||||||
CfgOptions::default(),
|
CfgOptions::default(),
|
||||||
Env::default(),
|
Env::default(),
|
||||||
Ok(Vec::new()),
|
|
||||||
false,
|
false,
|
||||||
CrateOrigin::CratesIo { repo: None, name: None },
|
CrateOrigin::CratesIo { repo: None, name: None },
|
||||||
Err("".into()),
|
Err("".into()),
|
||||||
|
@ -735,7 +735,6 @@ mod tests {
|
||||||
CfgOptions::default(),
|
CfgOptions::default(),
|
||||||
CfgOptions::default(),
|
CfgOptions::default(),
|
||||||
Env::default(),
|
Env::default(),
|
||||||
Ok(Vec::new()),
|
|
||||||
false,
|
false,
|
||||||
CrateOrigin::CratesIo { repo: None, name: None },
|
CrateOrigin::CratesIo { repo: None, name: None },
|
||||||
Err("".into()),
|
Err("".into()),
|
||||||
|
@ -748,7 +747,6 @@ mod tests {
|
||||||
CfgOptions::default(),
|
CfgOptions::default(),
|
||||||
CfgOptions::default(),
|
CfgOptions::default(),
|
||||||
Env::default(),
|
Env::default(),
|
||||||
Ok(Vec::new()),
|
|
||||||
false,
|
false,
|
||||||
CrateOrigin::CratesIo { repo: None, name: None },
|
CrateOrigin::CratesIo { repo: None, name: None },
|
||||||
Err("".into()),
|
Err("".into()),
|
||||||
|
@ -761,7 +759,6 @@ mod tests {
|
||||||
CfgOptions::default(),
|
CfgOptions::default(),
|
||||||
CfgOptions::default(),
|
CfgOptions::default(),
|
||||||
Env::default(),
|
Env::default(),
|
||||||
Ok(Vec::new()),
|
|
||||||
false,
|
false,
|
||||||
CrateOrigin::CratesIo { repo: None, name: None },
|
CrateOrigin::CratesIo { repo: None, name: None },
|
||||||
Err("".into()),
|
Err("".into()),
|
||||||
|
@ -785,7 +782,6 @@ mod tests {
|
||||||
CfgOptions::default(),
|
CfgOptions::default(),
|
||||||
CfgOptions::default(),
|
CfgOptions::default(),
|
||||||
Env::default(),
|
Env::default(),
|
||||||
Ok(Vec::new()),
|
|
||||||
false,
|
false,
|
||||||
CrateOrigin::CratesIo { repo: None, name: None },
|
CrateOrigin::CratesIo { repo: None, name: None },
|
||||||
Err("".into()),
|
Err("".into()),
|
||||||
|
@ -798,7 +794,6 @@ mod tests {
|
||||||
CfgOptions::default(),
|
CfgOptions::default(),
|
||||||
CfgOptions::default(),
|
CfgOptions::default(),
|
||||||
Env::default(),
|
Env::default(),
|
||||||
Ok(Vec::new()),
|
|
||||||
false,
|
false,
|
||||||
CrateOrigin::CratesIo { repo: None, name: None },
|
CrateOrigin::CratesIo { repo: None, name: None },
|
||||||
Err("".into()),
|
Err("".into()),
|
||||||
|
|
|
@ -16,8 +16,8 @@ pub use crate::{
|
||||||
input::{
|
input::{
|
||||||
CrateData, CrateDisplayName, CrateGraph, CrateId, CrateName, CrateOrigin, Dependency,
|
CrateData, CrateDisplayName, CrateGraph, CrateId, CrateName, CrateOrigin, Dependency,
|
||||||
Edition, Env, LangCrateOrigin, ProcMacro, ProcMacroExpander, ProcMacroExpansionError,
|
Edition, Env, LangCrateOrigin, ProcMacro, ProcMacroExpander, ProcMacroExpansionError,
|
||||||
ProcMacroId, ProcMacroKind, ProcMacroLoadResult, SourceRoot, SourceRootId,
|
ProcMacroId, ProcMacroKind, ProcMacroLoadResult, ProcMacroPaths, ProcMacros, SourceRoot,
|
||||||
TargetLayoutLoadResult,
|
SourceRootId, TargetLayoutLoadResult,
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
pub use salsa::{self, Cancelled};
|
pub use salsa::{self, Cancelled};
|
||||||
|
@ -73,6 +73,10 @@ pub trait SourceDatabase: FileLoader + std::fmt::Debug {
|
||||||
/// The crate graph.
|
/// The crate graph.
|
||||||
#[salsa::input]
|
#[salsa::input]
|
||||||
fn crate_graph(&self) -> Arc<CrateGraph>;
|
fn crate_graph(&self) -> Arc<CrateGraph>;
|
||||||
|
|
||||||
|
/// The crate graph.
|
||||||
|
#[salsa::input]
|
||||||
|
fn proc_macros(&self) -> Arc<ProcMacros>;
|
||||||
}
|
}
|
||||||
|
|
||||||
fn parse_query(db: &dyn SourceDatabase, file_id: FileId) -> Parse<ast::SourceFile> {
|
fn parse_query(db: &dyn SourceDatabase, file_id: FileId) -> Parse<ast::SourceFile> {
|
||||||
|
|
|
@ -78,25 +78,35 @@ pub(super) fn collect_defs(db: &dyn DefDatabase, mut def_map: DefMap, tree_id: T
|
||||||
}
|
}
|
||||||
|
|
||||||
let cfg_options = &krate.cfg_options;
|
let cfg_options = &krate.cfg_options;
|
||||||
let proc_macros = match &krate.proc_macro {
|
|
||||||
Ok(proc_macros) => {
|
|
||||||
proc_macros
|
|
||||||
.iter()
|
|
||||||
.enumerate()
|
|
||||||
.map(|(idx, it)| {
|
|
||||||
// FIXME: a hacky way to create a Name from string.
|
|
||||||
let name =
|
|
||||||
tt::Ident { text: it.name.clone(), span: tt::TokenId::unspecified() };
|
|
||||||
(name.as_name(), ProcMacroExpander::new(base_db::ProcMacroId(idx as u32)))
|
|
||||||
})
|
|
||||||
.collect()
|
|
||||||
}
|
|
||||||
Err(e) => {
|
|
||||||
def_map.proc_macro_loading_error = Some(e.clone().into_boxed_str());
|
|
||||||
Vec::new()
|
|
||||||
}
|
|
||||||
};
|
|
||||||
let is_proc_macro = krate.is_proc_macro;
|
let is_proc_macro = krate.is_proc_macro;
|
||||||
|
let proc_macros = if is_proc_macro {
|
||||||
|
match db.proc_macros().get(&def_map.krate) {
|
||||||
|
Some(Ok(proc_macros)) => {
|
||||||
|
proc_macros
|
||||||
|
.iter()
|
||||||
|
.enumerate()
|
||||||
|
.map(|(idx, it)| {
|
||||||
|
// FIXME: a hacky way to create a Name from string.
|
||||||
|
let name =
|
||||||
|
tt::Ident { text: it.name.clone(), span: tt::TokenId::unspecified() };
|
||||||
|
(name.as_name(), ProcMacroExpander::new(base_db::ProcMacroId(idx as u32)))
|
||||||
|
})
|
||||||
|
.collect()
|
||||||
|
}
|
||||||
|
Some(Err(e)) => {
|
||||||
|
def_map.proc_macro_loading_error = Some(e.clone().into_boxed_str());
|
||||||
|
Vec::new()
|
||||||
|
}
|
||||||
|
None => {
|
||||||
|
def_map.proc_macro_loading_error =
|
||||||
|
Some("No proc-macros present for crate".to_owned().into_boxed_str());
|
||||||
|
Vec::new()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
vec![]
|
||||||
|
};
|
||||||
|
|
||||||
let mut collector = DefCollector {
|
let mut collector = DefCollector {
|
||||||
db,
|
db,
|
||||||
|
|
|
@ -33,10 +33,10 @@ impl ProcMacroExpander {
|
||||||
) -> ExpandResult<tt::Subtree> {
|
) -> ExpandResult<tt::Subtree> {
|
||||||
match self.proc_macro_id {
|
match self.proc_macro_id {
|
||||||
Some(id) => {
|
Some(id) => {
|
||||||
let krate_graph = db.crate_graph();
|
let proc_macros = db.proc_macros();
|
||||||
let proc_macros = match &krate_graph[def_crate].proc_macro {
|
let proc_macros = match proc_macros.get(&def_crate) {
|
||||||
Ok(proc_macros) => proc_macros,
|
Some(Ok(proc_macros)) => proc_macros,
|
||||||
Err(_) => {
|
Some(Err(_)) | None => {
|
||||||
never!("Non-dummy expander even though there are no proc macros");
|
never!("Non-dummy expander even though there are no proc macros");
|
||||||
return ExpandResult::with_err(
|
return ExpandResult::with_err(
|
||||||
tt::Subtree::empty(),
|
tt::Subtree::empty(),
|
||||||
|
@ -59,6 +59,7 @@ impl ProcMacroExpander {
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
let krate_graph = db.crate_graph();
|
||||||
// Proc macros have access to the environment variables of the invoking crate.
|
// Proc macros have access to the environment variables of the invoking crate.
|
||||||
let env = &krate_graph[calling_crate].env;
|
let env = &krate_graph[calling_crate].env;
|
||||||
match proc_macro.expander.expand(tt, attr_arg, env) {
|
match proc_macro.expander.expand(tt, attr_arg, env) {
|
||||||
|
|
|
@ -64,6 +64,7 @@ impl RootDatabase {
|
||||||
// SourceDatabase
|
// SourceDatabase
|
||||||
base_db::ParseQuery
|
base_db::ParseQuery
|
||||||
base_db::CrateGraphQuery
|
base_db::CrateGraphQuery
|
||||||
|
base_db::ProcMacrosQuery
|
||||||
|
|
||||||
// SourceDatabaseExt
|
// SourceDatabaseExt
|
||||||
base_db::FileTextQuery
|
base_db::FileTextQuery
|
||||||
|
|
|
@ -137,6 +137,7 @@ impl RootDatabase {
|
||||||
pub fn new(lru_capacity: Option<usize>) -> RootDatabase {
|
pub fn new(lru_capacity: Option<usize>) -> RootDatabase {
|
||||||
let mut db = RootDatabase { storage: ManuallyDrop::new(salsa::Storage::default()) };
|
let mut db = RootDatabase { storage: ManuallyDrop::new(salsa::Storage::default()) };
|
||||||
db.set_crate_graph_with_durability(Default::default(), Durability::HIGH);
|
db.set_crate_graph_with_durability(Default::default(), Durability::HIGH);
|
||||||
|
db.set_proc_macros_with_durability(Default::default(), Durability::HIGH);
|
||||||
db.set_local_roots_with_durability(Default::default(), Durability::HIGH);
|
db.set_local_roots_with_durability(Default::default(), Durability::HIGH);
|
||||||
db.set_library_roots_with_durability(Default::default(), Durability::HIGH);
|
db.set_library_roots_with_durability(Default::default(), Durability::HIGH);
|
||||||
db.set_enable_proc_attr_macros(false);
|
db.set_enable_proc_attr_macros(false);
|
||||||
|
|
|
@ -235,7 +235,6 @@ impl Analysis {
|
||||||
cfg_options.clone(),
|
cfg_options.clone(),
|
||||||
cfg_options,
|
cfg_options,
|
||||||
Env::default(),
|
Env::default(),
|
||||||
Ok(Vec::new()),
|
|
||||||
false,
|
false,
|
||||||
CrateOrigin::CratesIo { repo: None, name: None },
|
CrateOrigin::CratesIo { repo: None, name: None },
|
||||||
Err("Analysis::from_single_file has no target layout".into()),
|
Err("Analysis::from_single_file has no target layout".into()),
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
use std::sync::Arc;
|
use std::sync::Arc;
|
||||||
|
|
||||||
use ide_db::{
|
use ide_db::{
|
||||||
base_db::{salsa::Durability, CrateGraph, SourceDatabase},
|
base_db::{salsa::Durability, CrateGraph, ProcMacros, SourceDatabase},
|
||||||
FxHashMap, RootDatabase,
|
FxHashMap, RootDatabase,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -16,6 +16,7 @@ use ide_db::{
|
||||||
// |===
|
// |===
|
||||||
pub(crate) fn shuffle_crate_graph(db: &mut RootDatabase) {
|
pub(crate) fn shuffle_crate_graph(db: &mut RootDatabase) {
|
||||||
let crate_graph = db.crate_graph();
|
let crate_graph = db.crate_graph();
|
||||||
|
let proc_macros = db.proc_macros();
|
||||||
|
|
||||||
let mut shuffled_ids = crate_graph.iter().collect::<Vec<_>>();
|
let mut shuffled_ids = crate_graph.iter().collect::<Vec<_>>();
|
||||||
|
|
||||||
|
@ -23,6 +24,7 @@ pub(crate) fn shuffle_crate_graph(db: &mut RootDatabase) {
|
||||||
stdx::rand::shuffle(&mut shuffled_ids, |i| rng.rand_range(0..i as u32) as usize);
|
stdx::rand::shuffle(&mut shuffled_ids, |i| rng.rand_range(0..i as u32) as usize);
|
||||||
|
|
||||||
let mut new_graph = CrateGraph::default();
|
let mut new_graph = CrateGraph::default();
|
||||||
|
let mut new_proc_macros = ProcMacros::default();
|
||||||
|
|
||||||
let mut map = FxHashMap::default();
|
let mut map = FxHashMap::default();
|
||||||
for old_id in shuffled_ids.iter().copied() {
|
for old_id in shuffled_ids.iter().copied() {
|
||||||
|
@ -35,11 +37,11 @@ pub(crate) fn shuffle_crate_graph(db: &mut RootDatabase) {
|
||||||
data.cfg_options.clone(),
|
data.cfg_options.clone(),
|
||||||
data.potential_cfg_options.clone(),
|
data.potential_cfg_options.clone(),
|
||||||
data.env.clone(),
|
data.env.clone(),
|
||||||
data.proc_macro.clone(),
|
|
||||||
data.is_proc_macro,
|
data.is_proc_macro,
|
||||||
data.origin.clone(),
|
data.origin.clone(),
|
||||||
data.target_layout.clone(),
|
data.target_layout.clone(),
|
||||||
);
|
);
|
||||||
|
new_proc_macros.insert(new_id, proc_macros[&old_id].clone());
|
||||||
map.insert(old_id, new_id);
|
map.insert(old_id, new_id);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -53,4 +55,5 @@ pub(crate) fn shuffle_crate_graph(db: &mut RootDatabase) {
|
||||||
}
|
}
|
||||||
|
|
||||||
db.set_crate_graph_with_durability(Arc::new(new_graph), Durability::HIGH);
|
db.set_crate_graph_with_durability(Arc::new(new_graph), Durability::HIGH);
|
||||||
|
db.set_proc_macros_with_durability(Arc::new(new_proc_macros), Durability::HIGH);
|
||||||
}
|
}
|
||||||
|
|
|
@ -3,7 +3,7 @@ use std::{
|
||||||
path::{Path, PathBuf},
|
path::{Path, PathBuf},
|
||||||
};
|
};
|
||||||
|
|
||||||
use base_db::{CrateGraph, FileId};
|
use base_db::{CrateGraph, FileId, ProcMacroPaths};
|
||||||
use cfg::{CfgAtom, CfgDiff};
|
use cfg::{CfgAtom, CfgDiff};
|
||||||
use expect_test::{expect, Expect};
|
use expect_test::{expect, Expect};
|
||||||
use paths::{AbsPath, AbsPathBuf};
|
use paths::{AbsPath, AbsPathBuf};
|
||||||
|
@ -14,11 +14,14 @@ use crate::{
|
||||||
WorkspaceBuildScripts,
|
WorkspaceBuildScripts,
|
||||||
};
|
};
|
||||||
|
|
||||||
fn load_cargo(file: &str) -> CrateGraph {
|
fn load_cargo(file: &str) -> (CrateGraph, ProcMacroPaths) {
|
||||||
load_cargo_with_overrides(file, CfgOverrides::default())
|
load_cargo_with_overrides(file, CfgOverrides::default())
|
||||||
}
|
}
|
||||||
|
|
||||||
fn load_cargo_with_overrides(file: &str, cfg_overrides: CfgOverrides) -> CrateGraph {
|
fn load_cargo_with_overrides(
|
||||||
|
file: &str,
|
||||||
|
cfg_overrides: CfgOverrides,
|
||||||
|
) -> (CrateGraph, ProcMacroPaths) {
|
||||||
let meta = get_test_json_file(file);
|
let meta = get_test_json_file(file);
|
||||||
let cargo_workspace = CargoWorkspace::new(meta);
|
let cargo_workspace = CargoWorkspace::new(meta);
|
||||||
let project_workspace = ProjectWorkspace::Cargo {
|
let project_workspace = ProjectWorkspace::Cargo {
|
||||||
|
@ -34,7 +37,7 @@ fn load_cargo_with_overrides(file: &str, cfg_overrides: CfgOverrides) -> CrateGr
|
||||||
to_crate_graph(project_workspace)
|
to_crate_graph(project_workspace)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn load_rust_project(file: &str) -> CrateGraph {
|
fn load_rust_project(file: &str) -> (CrateGraph, ProcMacroPaths) {
|
||||||
let data = get_test_json_file(file);
|
let data = get_test_json_file(file);
|
||||||
let project = rooted_project_json(data);
|
let project = rooted_project_json(data);
|
||||||
let sysroot = Ok(get_fake_sysroot());
|
let sysroot = Ok(get_fake_sysroot());
|
||||||
|
@ -92,9 +95,8 @@ fn rooted_project_json(data: ProjectJsonData) -> ProjectJson {
|
||||||
ProjectJson::new(base, data)
|
ProjectJson::new(base, data)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn to_crate_graph(project_workspace: ProjectWorkspace) -> CrateGraph {
|
fn to_crate_graph(project_workspace: ProjectWorkspace) -> (CrateGraph, ProcMacroPaths) {
|
||||||
project_workspace.to_crate_graph(
|
project_workspace.to_crate_graph(
|
||||||
&mut |_, _| Ok(Vec::new()),
|
|
||||||
&mut {
|
&mut {
|
||||||
let mut counter = 0;
|
let mut counter = 0;
|
||||||
move |_path| {
|
move |_path| {
|
||||||
|
@ -117,7 +119,8 @@ fn cargo_hello_world_project_model_with_wildcard_overrides() {
|
||||||
let cfg_overrides = CfgOverrides::Wildcard(
|
let cfg_overrides = CfgOverrides::Wildcard(
|
||||||
CfgDiff::new(Vec::new(), vec![CfgAtom::Flag("test".into())]).unwrap(),
|
CfgDiff::new(Vec::new(), vec![CfgAtom::Flag("test".into())]).unwrap(),
|
||||||
);
|
);
|
||||||
let crate_graph = load_cargo_with_overrides("hello-world-metadata.json", cfg_overrides);
|
let (crate_graph, _proc_macros) =
|
||||||
|
load_cargo_with_overrides("hello-world-metadata.json", cfg_overrides);
|
||||||
check_crate_graph(
|
check_crate_graph(
|
||||||
crate_graph,
|
crate_graph,
|
||||||
expect![[r#"
|
expect![[r#"
|
||||||
|
@ -184,9 +187,6 @@ fn cargo_hello_world_project_model_with_wildcard_overrides() {
|
||||||
prelude: true,
|
prelude: true,
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
proc_macro: Err(
|
|
||||||
"crate has not (yet) been built",
|
|
||||||
),
|
|
||||||
origin: CratesIo {
|
origin: CratesIo {
|
||||||
repo: None,
|
repo: None,
|
||||||
name: Some(
|
name: Some(
|
||||||
|
@ -265,9 +265,6 @@ fn cargo_hello_world_project_model_with_wildcard_overrides() {
|
||||||
prelude: true,
|
prelude: true,
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
proc_macro: Err(
|
|
||||||
"crate has not (yet) been built",
|
|
||||||
),
|
|
||||||
origin: CratesIo {
|
origin: CratesIo {
|
||||||
repo: None,
|
repo: None,
|
||||||
name: Some(
|
name: Some(
|
||||||
|
@ -346,9 +343,6 @@ fn cargo_hello_world_project_model_with_wildcard_overrides() {
|
||||||
prelude: true,
|
prelude: true,
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
proc_macro: Err(
|
|
||||||
"crate has not (yet) been built",
|
|
||||||
),
|
|
||||||
origin: CratesIo {
|
origin: CratesIo {
|
||||||
repo: None,
|
repo: None,
|
||||||
name: Some(
|
name: Some(
|
||||||
|
@ -427,9 +421,6 @@ fn cargo_hello_world_project_model_with_wildcard_overrides() {
|
||||||
prelude: true,
|
prelude: true,
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
proc_macro: Err(
|
|
||||||
"crate has not (yet) been built",
|
|
||||||
),
|
|
||||||
origin: CratesIo {
|
origin: CratesIo {
|
||||||
repo: None,
|
repo: None,
|
||||||
name: Some(
|
name: Some(
|
||||||
|
@ -498,9 +489,6 @@ fn cargo_hello_world_project_model_with_wildcard_overrides() {
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
dependencies: [],
|
dependencies: [],
|
||||||
proc_macro: Err(
|
|
||||||
"crate has not (yet) been built",
|
|
||||||
),
|
|
||||||
origin: CratesIo {
|
origin: CratesIo {
|
||||||
repo: Some(
|
repo: Some(
|
||||||
"https://github.com/rust-lang/libc",
|
"https://github.com/rust-lang/libc",
|
||||||
|
@ -527,7 +515,8 @@ fn cargo_hello_world_project_model_with_selective_overrides() {
|
||||||
.collect(),
|
.collect(),
|
||||||
)
|
)
|
||||||
};
|
};
|
||||||
let crate_graph = load_cargo_with_overrides("hello-world-metadata.json", cfg_overrides);
|
let (crate_graph, _proc_macros) =
|
||||||
|
load_cargo_with_overrides("hello-world-metadata.json", cfg_overrides);
|
||||||
check_crate_graph(
|
check_crate_graph(
|
||||||
crate_graph,
|
crate_graph,
|
||||||
expect![[r#"
|
expect![[r#"
|
||||||
|
@ -596,9 +585,6 @@ fn cargo_hello_world_project_model_with_selective_overrides() {
|
||||||
prelude: true,
|
prelude: true,
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
proc_macro: Err(
|
|
||||||
"crate has not (yet) been built",
|
|
||||||
),
|
|
||||||
origin: CratesIo {
|
origin: CratesIo {
|
||||||
repo: None,
|
repo: None,
|
||||||
name: Some(
|
name: Some(
|
||||||
|
@ -679,9 +665,6 @@ fn cargo_hello_world_project_model_with_selective_overrides() {
|
||||||
prelude: true,
|
prelude: true,
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
proc_macro: Err(
|
|
||||||
"crate has not (yet) been built",
|
|
||||||
),
|
|
||||||
origin: CratesIo {
|
origin: CratesIo {
|
||||||
repo: None,
|
repo: None,
|
||||||
name: Some(
|
name: Some(
|
||||||
|
@ -762,9 +745,6 @@ fn cargo_hello_world_project_model_with_selective_overrides() {
|
||||||
prelude: true,
|
prelude: true,
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
proc_macro: Err(
|
|
||||||
"crate has not (yet) been built",
|
|
||||||
),
|
|
||||||
origin: CratesIo {
|
origin: CratesIo {
|
||||||
repo: None,
|
repo: None,
|
||||||
name: Some(
|
name: Some(
|
||||||
|
@ -845,9 +825,6 @@ fn cargo_hello_world_project_model_with_selective_overrides() {
|
||||||
prelude: true,
|
prelude: true,
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
proc_macro: Err(
|
|
||||||
"crate has not (yet) been built",
|
|
||||||
),
|
|
||||||
origin: CratesIo {
|
origin: CratesIo {
|
||||||
repo: None,
|
repo: None,
|
||||||
name: Some(
|
name: Some(
|
||||||
|
@ -916,9 +893,6 @@ fn cargo_hello_world_project_model_with_selective_overrides() {
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
dependencies: [],
|
dependencies: [],
|
||||||
proc_macro: Err(
|
|
||||||
"crate has not (yet) been built",
|
|
||||||
),
|
|
||||||
origin: CratesIo {
|
origin: CratesIo {
|
||||||
repo: Some(
|
repo: Some(
|
||||||
"https://github.com/rust-lang/libc",
|
"https://github.com/rust-lang/libc",
|
||||||
|
@ -936,7 +910,7 @@ fn cargo_hello_world_project_model_with_selective_overrides() {
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn cargo_hello_world_project_model() {
|
fn cargo_hello_world_project_model() {
|
||||||
let crate_graph = load_cargo("hello-world-metadata.json");
|
let (crate_graph, _proc_macros) = load_cargo("hello-world-metadata.json");
|
||||||
check_crate_graph(
|
check_crate_graph(
|
||||||
crate_graph,
|
crate_graph,
|
||||||
expect![[r#"
|
expect![[r#"
|
||||||
|
@ -1005,9 +979,6 @@ fn cargo_hello_world_project_model() {
|
||||||
prelude: true,
|
prelude: true,
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
proc_macro: Err(
|
|
||||||
"crate has not (yet) been built",
|
|
||||||
),
|
|
||||||
origin: CratesIo {
|
origin: CratesIo {
|
||||||
repo: None,
|
repo: None,
|
||||||
name: Some(
|
name: Some(
|
||||||
|
@ -1088,9 +1059,6 @@ fn cargo_hello_world_project_model() {
|
||||||
prelude: true,
|
prelude: true,
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
proc_macro: Err(
|
|
||||||
"crate has not (yet) been built",
|
|
||||||
),
|
|
||||||
origin: CratesIo {
|
origin: CratesIo {
|
||||||
repo: None,
|
repo: None,
|
||||||
name: Some(
|
name: Some(
|
||||||
|
@ -1171,9 +1139,6 @@ fn cargo_hello_world_project_model() {
|
||||||
prelude: true,
|
prelude: true,
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
proc_macro: Err(
|
|
||||||
"crate has not (yet) been built",
|
|
||||||
),
|
|
||||||
origin: CratesIo {
|
origin: CratesIo {
|
||||||
repo: None,
|
repo: None,
|
||||||
name: Some(
|
name: Some(
|
||||||
|
@ -1254,9 +1219,6 @@ fn cargo_hello_world_project_model() {
|
||||||
prelude: true,
|
prelude: true,
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
proc_macro: Err(
|
|
||||||
"crate has not (yet) been built",
|
|
||||||
),
|
|
||||||
origin: CratesIo {
|
origin: CratesIo {
|
||||||
repo: None,
|
repo: None,
|
||||||
name: Some(
|
name: Some(
|
||||||
|
@ -1325,9 +1287,6 @@ fn cargo_hello_world_project_model() {
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
dependencies: [],
|
dependencies: [],
|
||||||
proc_macro: Err(
|
|
||||||
"crate has not (yet) been built",
|
|
||||||
),
|
|
||||||
origin: CratesIo {
|
origin: CratesIo {
|
||||||
repo: Some(
|
repo: Some(
|
||||||
"https://github.com/rust-lang/libc",
|
"https://github.com/rust-lang/libc",
|
||||||
|
@ -1345,7 +1304,7 @@ fn cargo_hello_world_project_model() {
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn rust_project_hello_world_project_model() {
|
fn rust_project_hello_world_project_model() {
|
||||||
let crate_graph = load_rust_project("hello-world-project.json");
|
let (crate_graph, _proc_macros) = load_rust_project("hello-world-project.json");
|
||||||
check_crate_graph(
|
check_crate_graph(
|
||||||
crate_graph,
|
crate_graph,
|
||||||
expect![[r#"
|
expect![[r#"
|
||||||
|
@ -1390,9 +1349,6 @@ fn rust_project_hello_world_project_model() {
|
||||||
prelude: true,
|
prelude: true,
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
proc_macro: Err(
|
|
||||||
"no proc macro loaded for sysroot crate",
|
|
||||||
),
|
|
||||||
origin: Lang(
|
origin: Lang(
|
||||||
Alloc,
|
Alloc,
|
||||||
),
|
),
|
||||||
|
@ -1427,9 +1383,6 @@ fn rust_project_hello_world_project_model() {
|
||||||
entries: {},
|
entries: {},
|
||||||
},
|
},
|
||||||
dependencies: [],
|
dependencies: [],
|
||||||
proc_macro: Err(
|
|
||||||
"no proc macro loaded for sysroot crate",
|
|
||||||
),
|
|
||||||
origin: Lang(
|
origin: Lang(
|
||||||
Core,
|
Core,
|
||||||
),
|
),
|
||||||
|
@ -1464,9 +1417,6 @@ fn rust_project_hello_world_project_model() {
|
||||||
entries: {},
|
entries: {},
|
||||||
},
|
},
|
||||||
dependencies: [],
|
dependencies: [],
|
||||||
proc_macro: Err(
|
|
||||||
"no proc macro loaded for sysroot crate",
|
|
||||||
),
|
|
||||||
origin: Lang(
|
origin: Lang(
|
||||||
Other,
|
Other,
|
||||||
),
|
),
|
||||||
|
@ -1501,9 +1451,6 @@ fn rust_project_hello_world_project_model() {
|
||||||
entries: {},
|
entries: {},
|
||||||
},
|
},
|
||||||
dependencies: [],
|
dependencies: [],
|
||||||
proc_macro: Err(
|
|
||||||
"no proc macro loaded for sysroot crate",
|
|
||||||
),
|
|
||||||
origin: Lang(
|
origin: Lang(
|
||||||
Other,
|
Other,
|
||||||
),
|
),
|
||||||
|
@ -1557,9 +1504,6 @@ fn rust_project_hello_world_project_model() {
|
||||||
prelude: true,
|
prelude: true,
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
proc_macro: Err(
|
|
||||||
"no proc macro loaded for sysroot crate",
|
|
||||||
),
|
|
||||||
origin: Lang(
|
origin: Lang(
|
||||||
Other,
|
Other,
|
||||||
),
|
),
|
||||||
|
@ -1594,9 +1538,6 @@ fn rust_project_hello_world_project_model() {
|
||||||
entries: {},
|
entries: {},
|
||||||
},
|
},
|
||||||
dependencies: [],
|
dependencies: [],
|
||||||
proc_macro: Err(
|
|
||||||
"no proc macro loaded for sysroot crate",
|
|
||||||
),
|
|
||||||
origin: Lang(
|
origin: Lang(
|
||||||
Other,
|
Other,
|
||||||
),
|
),
|
||||||
|
@ -1704,9 +1645,6 @@ fn rust_project_hello_world_project_model() {
|
||||||
prelude: true,
|
prelude: true,
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
proc_macro: Err(
|
|
||||||
"no proc macro loaded for sysroot crate",
|
|
||||||
),
|
|
||||||
origin: Lang(
|
origin: Lang(
|
||||||
Std,
|
Std,
|
||||||
),
|
),
|
||||||
|
@ -1741,9 +1679,6 @@ fn rust_project_hello_world_project_model() {
|
||||||
entries: {},
|
entries: {},
|
||||||
},
|
},
|
||||||
dependencies: [],
|
dependencies: [],
|
||||||
proc_macro: Err(
|
|
||||||
"no proc macro loaded for sysroot crate",
|
|
||||||
),
|
|
||||||
origin: Lang(
|
origin: Lang(
|
||||||
Other,
|
Other,
|
||||||
),
|
),
|
||||||
|
@ -1778,9 +1713,6 @@ fn rust_project_hello_world_project_model() {
|
||||||
entries: {},
|
entries: {},
|
||||||
},
|
},
|
||||||
dependencies: [],
|
dependencies: [],
|
||||||
proc_macro: Err(
|
|
||||||
"no proc macro loaded for sysroot crate",
|
|
||||||
),
|
|
||||||
origin: Lang(
|
origin: Lang(
|
||||||
Test,
|
Test,
|
||||||
),
|
),
|
||||||
|
@ -1815,9 +1747,6 @@ fn rust_project_hello_world_project_model() {
|
||||||
entries: {},
|
entries: {},
|
||||||
},
|
},
|
||||||
dependencies: [],
|
dependencies: [],
|
||||||
proc_macro: Err(
|
|
||||||
"no proc macro loaded for sysroot crate",
|
|
||||||
),
|
|
||||||
origin: Lang(
|
origin: Lang(
|
||||||
Other,
|
Other,
|
||||||
),
|
),
|
||||||
|
@ -1889,9 +1818,6 @@ fn rust_project_hello_world_project_model() {
|
||||||
prelude: false,
|
prelude: false,
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
proc_macro: Err(
|
|
||||||
"no proc macro dylib present",
|
|
||||||
),
|
|
||||||
origin: CratesIo {
|
origin: CratesIo {
|
||||||
repo: None,
|
repo: None,
|
||||||
name: Some(
|
name: Some(
|
||||||
|
@ -1907,7 +1833,7 @@ fn rust_project_hello_world_project_model() {
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn rust_project_is_proc_macro_has_proc_macro_dep() {
|
fn rust_project_is_proc_macro_has_proc_macro_dep() {
|
||||||
let crate_graph = load_rust_project("is-proc-macro-project.json");
|
let (crate_graph, _proc_macros) = load_rust_project("is-proc-macro-project.json");
|
||||||
// Since the project only defines one crate (outside the sysroot crates),
|
// Since the project only defines one crate (outside the sysroot crates),
|
||||||
// it should be the one with the biggest Id.
|
// it should be the one with the biggest Id.
|
||||||
let crate_id = crate_graph.iter().max().unwrap();
|
let crate_id = crate_graph.iter().max().unwrap();
|
||||||
|
|
|
@ -7,7 +7,7 @@ use std::{collections::VecDeque, fmt, fs, process::Command, sync::Arc};
|
||||||
use anyhow::{bail, format_err, Context, Result};
|
use anyhow::{bail, format_err, Context, Result};
|
||||||
use base_db::{
|
use base_db::{
|
||||||
CrateDisplayName, CrateGraph, CrateId, CrateName, CrateOrigin, Dependency, Edition, Env,
|
CrateDisplayName, CrateGraph, CrateId, CrateName, CrateOrigin, Dependency, Edition, Env,
|
||||||
FileId, LangCrateOrigin, ProcMacroLoadResult, TargetLayoutLoadResult,
|
FileId, LangCrateOrigin, ProcMacroPaths, TargetLayoutLoadResult,
|
||||||
};
|
};
|
||||||
use cfg::{CfgDiff, CfgOptions};
|
use cfg::{CfgDiff, CfgOptions};
|
||||||
use paths::{AbsPath, AbsPathBuf};
|
use paths::{AbsPath, AbsPathBuf};
|
||||||
|
@ -576,16 +576,14 @@ impl ProjectWorkspace {
|
||||||
|
|
||||||
pub fn to_crate_graph(
|
pub fn to_crate_graph(
|
||||||
&self,
|
&self,
|
||||||
load_proc_macro: &mut dyn FnMut(&str, &AbsPath) -> ProcMacroLoadResult,
|
|
||||||
load: &mut dyn FnMut(&AbsPath) -> Option<FileId>,
|
load: &mut dyn FnMut(&AbsPath) -> Option<FileId>,
|
||||||
extra_env: &FxHashMap<String, String>,
|
extra_env: &FxHashMap<String, String>,
|
||||||
) -> CrateGraph {
|
) -> (CrateGraph, ProcMacroPaths) {
|
||||||
let _p = profile::span("ProjectWorkspace::to_crate_graph");
|
let _p = profile::span("ProjectWorkspace::to_crate_graph");
|
||||||
|
|
||||||
let mut crate_graph = match self {
|
let (mut crate_graph, proc_macros) = match self {
|
||||||
ProjectWorkspace::Json { project, sysroot, rustc_cfg } => project_json_to_crate_graph(
|
ProjectWorkspace::Json { project, sysroot, rustc_cfg } => project_json_to_crate_graph(
|
||||||
rustc_cfg.clone(),
|
rustc_cfg.clone(),
|
||||||
load_proc_macro,
|
|
||||||
load,
|
load,
|
||||||
project,
|
project,
|
||||||
sysroot.as_ref().ok(),
|
sysroot.as_ref().ok(),
|
||||||
|
@ -602,7 +600,6 @@ impl ProjectWorkspace {
|
||||||
toolchain: _,
|
toolchain: _,
|
||||||
target_layout,
|
target_layout,
|
||||||
} => cargo_to_crate_graph(
|
} => cargo_to_crate_graph(
|
||||||
load_proc_macro,
|
|
||||||
load,
|
load,
|
||||||
rustc.as_ref().ok(),
|
rustc.as_ref().ok(),
|
||||||
cargo,
|
cargo,
|
||||||
|
@ -630,7 +627,7 @@ impl ProjectWorkspace {
|
||||||
} else {
|
} else {
|
||||||
tracing::debug!("Did not patch std to depend on cfg-if")
|
tracing::debug!("Did not patch std to depend on cfg-if")
|
||||||
}
|
}
|
||||||
crate_graph
|
(crate_graph, proc_macros)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn eq_ignore_build_data(&self, other: &Self) -> bool {
|
pub fn eq_ignore_build_data(&self, other: &Self) -> bool {
|
||||||
|
@ -679,14 +676,14 @@ impl ProjectWorkspace {
|
||||||
|
|
||||||
fn project_json_to_crate_graph(
|
fn project_json_to_crate_graph(
|
||||||
rustc_cfg: Vec<CfgFlag>,
|
rustc_cfg: Vec<CfgFlag>,
|
||||||
load_proc_macro: &mut dyn FnMut(&str, &AbsPath) -> ProcMacroLoadResult,
|
|
||||||
load: &mut dyn FnMut(&AbsPath) -> Option<FileId>,
|
load: &mut dyn FnMut(&AbsPath) -> Option<FileId>,
|
||||||
project: &ProjectJson,
|
project: &ProjectJson,
|
||||||
sysroot: Option<&Sysroot>,
|
sysroot: Option<&Sysroot>,
|
||||||
extra_env: &FxHashMap<String, String>,
|
extra_env: &FxHashMap<String, String>,
|
||||||
target_layout: TargetLayoutLoadResult,
|
target_layout: TargetLayoutLoadResult,
|
||||||
) -> CrateGraph {
|
) -> (CrateGraph, ProcMacroPaths) {
|
||||||
let mut crate_graph = CrateGraph::default();
|
let mut crate_graph = CrateGraph::default();
|
||||||
|
let mut proc_macros = FxHashMap::default();
|
||||||
let sysroot_deps = sysroot.as_ref().map(|sysroot| {
|
let sysroot_deps = sysroot.as_ref().map(|sysroot| {
|
||||||
sysroot_to_crate_graph(
|
sysroot_to_crate_graph(
|
||||||
&mut crate_graph,
|
&mut crate_graph,
|
||||||
|
@ -707,14 +704,15 @@ fn project_json_to_crate_graph(
|
||||||
})
|
})
|
||||||
.map(|(crate_id, krate, file_id)| {
|
.map(|(crate_id, krate, file_id)| {
|
||||||
let env = krate.env.clone().into_iter().collect();
|
let env = krate.env.clone().into_iter().collect();
|
||||||
let proc_macro = match krate.proc_macro_dylib_path.clone() {
|
if let Some(path) = krate.proc_macro_dylib_path.clone() {
|
||||||
Some(it) => load_proc_macro(
|
proc_macros.insert(
|
||||||
krate.display_name.as_ref().map(|it| it.canonical_name()).unwrap_or(""),
|
crate_id,
|
||||||
&it,
|
Ok((
|
||||||
),
|
krate.display_name.as_ref().map(|it| it.canonical_name().to_owned()),
|
||||||
None => Err("no proc macro dylib present".into()),
|
path,
|
||||||
};
|
)),
|
||||||
|
);
|
||||||
|
}
|
||||||
let target_cfgs = match krate.target.as_deref() {
|
let target_cfgs = match krate.target.as_deref() {
|
||||||
Some(target) => cfg_cache
|
Some(target) => cfg_cache
|
||||||
.entry(target)
|
.entry(target)
|
||||||
|
@ -734,7 +732,6 @@ fn project_json_to_crate_graph(
|
||||||
cfg_options.clone(),
|
cfg_options.clone(),
|
||||||
cfg_options,
|
cfg_options,
|
||||||
env,
|
env,
|
||||||
proc_macro,
|
|
||||||
krate.is_proc_macro,
|
krate.is_proc_macro,
|
||||||
if krate.display_name.is_some() {
|
if krate.display_name.is_some() {
|
||||||
CrateOrigin::CratesIo {
|
CrateOrigin::CratesIo {
|
||||||
|
@ -776,11 +773,10 @@ fn project_json_to_crate_graph(
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
crate_graph
|
(crate_graph, proc_macros)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn cargo_to_crate_graph(
|
fn cargo_to_crate_graph(
|
||||||
load_proc_macro: &mut dyn FnMut(&str, &AbsPath) -> ProcMacroLoadResult,
|
|
||||||
load: &mut dyn FnMut(&AbsPath) -> Option<FileId>,
|
load: &mut dyn FnMut(&AbsPath) -> Option<FileId>,
|
||||||
rustc: Option<&(CargoWorkspace, WorkspaceBuildScripts)>,
|
rustc: Option<&(CargoWorkspace, WorkspaceBuildScripts)>,
|
||||||
cargo: &CargoWorkspace,
|
cargo: &CargoWorkspace,
|
||||||
|
@ -789,9 +785,10 @@ fn cargo_to_crate_graph(
|
||||||
override_cfg: &CfgOverrides,
|
override_cfg: &CfgOverrides,
|
||||||
build_scripts: &WorkspaceBuildScripts,
|
build_scripts: &WorkspaceBuildScripts,
|
||||||
target_layout: TargetLayoutLoadResult,
|
target_layout: TargetLayoutLoadResult,
|
||||||
) -> CrateGraph {
|
) -> (CrateGraph, ProcMacroPaths) {
|
||||||
let _p = profile::span("cargo_to_crate_graph");
|
let _p = profile::span("cargo_to_crate_graph");
|
||||||
let mut crate_graph = CrateGraph::default();
|
let mut crate_graph = CrateGraph::default();
|
||||||
|
let mut proc_macros = FxHashMap::default();
|
||||||
let (public_deps, libproc_macro) = match sysroot {
|
let (public_deps, libproc_macro) = match sysroot {
|
||||||
Some(sysroot) => sysroot_to_crate_graph(
|
Some(sysroot) => sysroot_to_crate_graph(
|
||||||
&mut crate_graph,
|
&mut crate_graph,
|
||||||
|
@ -855,10 +852,10 @@ fn cargo_to_crate_graph(
|
||||||
if let Some(file_id) = load(&cargo[tgt].root) {
|
if let Some(file_id) = load(&cargo[tgt].root) {
|
||||||
let crate_id = add_target_crate_root(
|
let crate_id = add_target_crate_root(
|
||||||
&mut crate_graph,
|
&mut crate_graph,
|
||||||
|
&mut proc_macros,
|
||||||
&cargo[pkg],
|
&cargo[pkg],
|
||||||
build_scripts.get_output(pkg),
|
build_scripts.get_output(pkg),
|
||||||
cfg_options.clone(),
|
cfg_options.clone(),
|
||||||
&mut |path| load_proc_macro(&cargo[tgt].name, path),
|
|
||||||
file_id,
|
file_id,
|
||||||
&cargo[tgt].name,
|
&cargo[tgt].name,
|
||||||
cargo[tgt].is_proc_macro,
|
cargo[tgt].is_proc_macro,
|
||||||
|
@ -931,9 +928,9 @@ fn cargo_to_crate_graph(
|
||||||
if let Some((rustc_workspace, rustc_build_scripts)) = rustc {
|
if let Some((rustc_workspace, rustc_build_scripts)) = rustc {
|
||||||
handle_rustc_crates(
|
handle_rustc_crates(
|
||||||
&mut crate_graph,
|
&mut crate_graph,
|
||||||
|
&mut proc_macros,
|
||||||
&mut pkg_to_lib_crate,
|
&mut pkg_to_lib_crate,
|
||||||
load,
|
load,
|
||||||
load_proc_macro,
|
|
||||||
rustc_workspace,
|
rustc_workspace,
|
||||||
cargo,
|
cargo,
|
||||||
&public_deps,
|
&public_deps,
|
||||||
|
@ -952,7 +949,7 @@ fn cargo_to_crate_graph(
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
crate_graph
|
(crate_graph, proc_macros)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn detached_files_to_crate_graph(
|
fn detached_files_to_crate_graph(
|
||||||
|
@ -961,7 +958,7 @@ fn detached_files_to_crate_graph(
|
||||||
detached_files: &[AbsPathBuf],
|
detached_files: &[AbsPathBuf],
|
||||||
sysroot: Option<&Sysroot>,
|
sysroot: Option<&Sysroot>,
|
||||||
target_layout: TargetLayoutLoadResult,
|
target_layout: TargetLayoutLoadResult,
|
||||||
) -> CrateGraph {
|
) -> (CrateGraph, ProcMacroPaths) {
|
||||||
let _p = profile::span("detached_files_to_crate_graph");
|
let _p = profile::span("detached_files_to_crate_graph");
|
||||||
let mut crate_graph = CrateGraph::default();
|
let mut crate_graph = CrateGraph::default();
|
||||||
let (public_deps, _libproc_macro) = match sysroot {
|
let (public_deps, _libproc_macro) = match sysroot {
|
||||||
|
@ -998,7 +995,6 @@ fn detached_files_to_crate_graph(
|
||||||
cfg_options.clone(),
|
cfg_options.clone(),
|
||||||
cfg_options.clone(),
|
cfg_options.clone(),
|
||||||
Env::default(),
|
Env::default(),
|
||||||
Ok(Vec::new()),
|
|
||||||
false,
|
false,
|
||||||
CrateOrigin::CratesIo {
|
CrateOrigin::CratesIo {
|
||||||
repo: None,
|
repo: None,
|
||||||
|
@ -1009,14 +1005,14 @@ fn detached_files_to_crate_graph(
|
||||||
|
|
||||||
public_deps.add_to_crate_graph(&mut crate_graph, detached_file_crate);
|
public_deps.add_to_crate_graph(&mut crate_graph, detached_file_crate);
|
||||||
}
|
}
|
||||||
crate_graph
|
(crate_graph, FxHashMap::default())
|
||||||
}
|
}
|
||||||
|
|
||||||
fn handle_rustc_crates(
|
fn handle_rustc_crates(
|
||||||
crate_graph: &mut CrateGraph,
|
crate_graph: &mut CrateGraph,
|
||||||
|
proc_macros: &mut ProcMacroPaths,
|
||||||
pkg_to_lib_crate: &mut FxHashMap<Package, CrateId>,
|
pkg_to_lib_crate: &mut FxHashMap<Package, CrateId>,
|
||||||
load: &mut dyn FnMut(&AbsPath) -> Option<FileId>,
|
load: &mut dyn FnMut(&AbsPath) -> Option<FileId>,
|
||||||
load_proc_macro: &mut dyn FnMut(&str, &AbsPath) -> ProcMacroLoadResult,
|
|
||||||
rustc_workspace: &CargoWorkspace,
|
rustc_workspace: &CargoWorkspace,
|
||||||
cargo: &CargoWorkspace,
|
cargo: &CargoWorkspace,
|
||||||
public_deps: &SysrootPublicDeps,
|
public_deps: &SysrootPublicDeps,
|
||||||
|
@ -1075,10 +1071,10 @@ fn handle_rustc_crates(
|
||||||
if let Some(file_id) = load(&rustc_workspace[tgt].root) {
|
if let Some(file_id) = load(&rustc_workspace[tgt].root) {
|
||||||
let crate_id = add_target_crate_root(
|
let crate_id = add_target_crate_root(
|
||||||
crate_graph,
|
crate_graph,
|
||||||
|
proc_macros,
|
||||||
&rustc_workspace[pkg],
|
&rustc_workspace[pkg],
|
||||||
build_scripts.get_output(pkg),
|
build_scripts.get_output(pkg),
|
||||||
cfg_options.clone(),
|
cfg_options.clone(),
|
||||||
&mut |path| load_proc_macro(&rustc_workspace[tgt].name, path),
|
|
||||||
file_id,
|
file_id,
|
||||||
&rustc_workspace[tgt].name,
|
&rustc_workspace[tgt].name,
|
||||||
rustc_workspace[tgt].is_proc_macro,
|
rustc_workspace[tgt].is_proc_macro,
|
||||||
|
@ -1140,10 +1136,10 @@ fn handle_rustc_crates(
|
||||||
|
|
||||||
fn add_target_crate_root(
|
fn add_target_crate_root(
|
||||||
crate_graph: &mut CrateGraph,
|
crate_graph: &mut CrateGraph,
|
||||||
|
proc_macros: &mut ProcMacroPaths,
|
||||||
pkg: &PackageData,
|
pkg: &PackageData,
|
||||||
build_data: Option<&BuildScriptOutput>,
|
build_data: Option<&BuildScriptOutput>,
|
||||||
cfg_options: CfgOptions,
|
cfg_options: CfgOptions,
|
||||||
load_proc_macro: &mut dyn FnMut(&AbsPath) -> ProcMacroLoadResult,
|
|
||||||
file_id: FileId,
|
file_id: FileId,
|
||||||
cargo_name: &str,
|
cargo_name: &str,
|
||||||
is_proc_macro: bool,
|
is_proc_macro: bool,
|
||||||
|
@ -1176,14 +1172,8 @@ fn add_target_crate_root(
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
let proc_macro = match build_data.as_ref().map(|it| it.proc_macro_dylib_path.as_ref()) {
|
|
||||||
Some(Some(it)) => load_proc_macro(it),
|
|
||||||
Some(None) => Err("no proc macro dylib present".into()),
|
|
||||||
None => Err("crate has not (yet) been built".into()),
|
|
||||||
};
|
|
||||||
|
|
||||||
let display_name = CrateDisplayName::from_canonical_name(cargo_name.to_string());
|
let display_name = CrateDisplayName::from_canonical_name(cargo_name.to_string());
|
||||||
crate_graph.add_crate_root(
|
let crate_id = crate_graph.add_crate_root(
|
||||||
file_id,
|
file_id,
|
||||||
edition,
|
edition,
|
||||||
Some(display_name),
|
Some(display_name),
|
||||||
|
@ -1191,11 +1181,19 @@ fn add_target_crate_root(
|
||||||
cfg_options,
|
cfg_options,
|
||||||
potential_cfg_options,
|
potential_cfg_options,
|
||||||
env,
|
env,
|
||||||
proc_macro,
|
|
||||||
is_proc_macro,
|
is_proc_macro,
|
||||||
CrateOrigin::CratesIo { repo: pkg.repository.clone(), name: Some(pkg.name.clone()) },
|
CrateOrigin::CratesIo { repo: pkg.repository.clone(), name: Some(pkg.name.clone()) },
|
||||||
target_layout,
|
target_layout,
|
||||||
)
|
);
|
||||||
|
let proc_macro = match build_data.as_ref().map(|it| &it.proc_macro_dylib_path) {
|
||||||
|
Some(it) => it.clone().map(Ok),
|
||||||
|
None => Some(Err("crate has not (yet) been built".into())),
|
||||||
|
};
|
||||||
|
if let Some(proc_macro) = proc_macro {
|
||||||
|
proc_macros.insert(crate_id, proc_macro.map(|path| (Some(cargo_name.to_owned()), path)));
|
||||||
|
}
|
||||||
|
|
||||||
|
crate_id
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Default)]
|
#[derive(Default)]
|
||||||
|
@ -1237,7 +1235,6 @@ fn sysroot_to_crate_graph(
|
||||||
cfg_options.clone(),
|
cfg_options.clone(),
|
||||||
cfg_options.clone(),
|
cfg_options.clone(),
|
||||||
env,
|
env,
|
||||||
Err("no proc macro loaded for sysroot crate".into()),
|
|
||||||
false,
|
false,
|
||||||
CrateOrigin::Lang(LangCrateOrigin::from(&*sysroot[krate].name)),
|
CrateOrigin::Lang(LangCrateOrigin::from(&*sysroot[krate].name)),
|
||||||
target_layout.clone(),
|
target_layout.clone(),
|
||||||
|
|
|
@ -6,7 +6,10 @@ use anyhow::Result;
|
||||||
use crossbeam_channel::{unbounded, Receiver};
|
use crossbeam_channel::{unbounded, Receiver};
|
||||||
use hir::db::DefDatabase;
|
use hir::db::DefDatabase;
|
||||||
use ide::{AnalysisHost, Change};
|
use ide::{AnalysisHost, Change};
|
||||||
use ide_db::{base_db::CrateGraph, FxHashMap};
|
use ide_db::{
|
||||||
|
base_db::{CrateGraph, ProcMacros},
|
||||||
|
FxHashMap,
|
||||||
|
};
|
||||||
use proc_macro_api::ProcMacroServer;
|
use proc_macro_api::ProcMacroServer;
|
||||||
use project_model::{CargoConfig, ProjectManifest, ProjectWorkspace};
|
use project_model::{CargoConfig, ProjectManifest, ProjectWorkspace};
|
||||||
use vfs::{loader::Handle, AbsPath, AbsPathBuf};
|
use vfs::{loader::Handle, AbsPath, AbsPathBuf};
|
||||||
|
@ -66,7 +69,7 @@ pub fn load_workspace(
|
||||||
Box::new(loader)
|
Box::new(loader)
|
||||||
};
|
};
|
||||||
|
|
||||||
let proc_macro_client = match &load_config.with_proc_macro_server {
|
let proc_macro_server = match &load_config.with_proc_macro_server {
|
||||||
ProcMacroServerChoice::Sysroot => ws
|
ProcMacroServerChoice::Sysroot => ws
|
||||||
.find_sysroot_proc_macro_srv()
|
.find_sysroot_proc_macro_srv()
|
||||||
.ok_or_else(|| "failed to find sysroot proc-macro server".to_owned())
|
.ok_or_else(|| "failed to find sysroot proc-macro server".to_owned())
|
||||||
|
@ -79,10 +82,7 @@ pub fn load_workspace(
|
||||||
ProcMacroServerChoice::None => Err("proc macro server disabled".to_owned()),
|
ProcMacroServerChoice::None => Err("proc macro server disabled".to_owned()),
|
||||||
};
|
};
|
||||||
|
|
||||||
let crate_graph = ws.to_crate_graph(
|
let (crate_graph, proc_macros) = ws.to_crate_graph(
|
||||||
&mut |_, path: &AbsPath| {
|
|
||||||
load_proc_macro(proc_macro_client.as_ref().map_err(|e| &**e), path, &[])
|
|
||||||
},
|
|
||||||
&mut |path: &AbsPath| {
|
&mut |path: &AbsPath| {
|
||||||
let contents = loader.load_sync(path);
|
let contents = loader.load_sync(path);
|
||||||
let path = vfs::VfsPath::from(path.to_path_buf());
|
let path = vfs::VfsPath::from(path.to_path_buf());
|
||||||
|
@ -91,6 +91,21 @@ pub fn load_workspace(
|
||||||
},
|
},
|
||||||
extra_env,
|
extra_env,
|
||||||
);
|
);
|
||||||
|
let proc_macros = {
|
||||||
|
let proc_macro_server = match &proc_macro_server {
|
||||||
|
Ok(it) => Ok(it),
|
||||||
|
Err(e) => Err(e.as_str()),
|
||||||
|
};
|
||||||
|
proc_macros
|
||||||
|
.into_iter()
|
||||||
|
.map(|(crate_id, path)| {
|
||||||
|
(
|
||||||
|
crate_id,
|
||||||
|
path.and_then(|(_, path)| load_proc_macro(proc_macro_server, &path, &[])),
|
||||||
|
)
|
||||||
|
})
|
||||||
|
.collect()
|
||||||
|
};
|
||||||
|
|
||||||
let project_folders = ProjectFolders::new(&[ws], &[]);
|
let project_folders = ProjectFolders::new(&[ws], &[]);
|
||||||
loader.set_config(vfs::loader::Config {
|
loader.set_config(vfs::loader::Config {
|
||||||
|
@ -100,17 +115,23 @@ pub fn load_workspace(
|
||||||
});
|
});
|
||||||
|
|
||||||
tracing::debug!("crate graph: {:?}", crate_graph);
|
tracing::debug!("crate graph: {:?}", crate_graph);
|
||||||
let host =
|
let host = load_crate_graph(
|
||||||
load_crate_graph(crate_graph, project_folders.source_root_config, &mut vfs, &receiver);
|
crate_graph,
|
||||||
|
proc_macros,
|
||||||
|
project_folders.source_root_config,
|
||||||
|
&mut vfs,
|
||||||
|
&receiver,
|
||||||
|
);
|
||||||
|
|
||||||
if load_config.prefill_caches {
|
if load_config.prefill_caches {
|
||||||
host.analysis().parallel_prime_caches(1, |_| {})?;
|
host.analysis().parallel_prime_caches(1, |_| {})?;
|
||||||
}
|
}
|
||||||
Ok((host, vfs, proc_macro_client.ok()))
|
Ok((host, vfs, proc_macro_server.ok()))
|
||||||
}
|
}
|
||||||
|
|
||||||
fn load_crate_graph(
|
fn load_crate_graph(
|
||||||
crate_graph: CrateGraph,
|
crate_graph: CrateGraph,
|
||||||
|
proc_macros: ProcMacros,
|
||||||
source_root_config: SourceRootConfig,
|
source_root_config: SourceRootConfig,
|
||||||
vfs: &mut vfs::Vfs,
|
vfs: &mut vfs::Vfs,
|
||||||
receiver: &Receiver<vfs::loader::Message>,
|
receiver: &Receiver<vfs::loader::Message>,
|
||||||
|
@ -149,6 +170,7 @@ fn load_crate_graph(
|
||||||
analysis_change.set_roots(source_roots);
|
analysis_change.set_roots(source_roots);
|
||||||
|
|
||||||
analysis_change.set_crate_graph(crate_graph);
|
analysis_change.set_crate_graph(crate_graph);
|
||||||
|
analysis_change.set_proc_macros(proc_macros);
|
||||||
|
|
||||||
host.apply_change(analysis_change);
|
host.apply_change(analysis_change);
|
||||||
host
|
host
|
||||||
|
|
|
@ -59,10 +59,11 @@ pub(crate) struct GlobalState {
|
||||||
pub(crate) mem_docs: MemDocs,
|
pub(crate) mem_docs: MemDocs,
|
||||||
pub(crate) semantic_tokens_cache: Arc<Mutex<FxHashMap<Url, SemanticTokens>>>,
|
pub(crate) semantic_tokens_cache: Arc<Mutex<FxHashMap<Url, SemanticTokens>>>,
|
||||||
pub(crate) shutdown_requested: bool,
|
pub(crate) shutdown_requested: bool,
|
||||||
pub(crate) proc_macro_changed: bool,
|
|
||||||
pub(crate) last_reported_status: Option<lsp_ext::ServerStatusParams>,
|
pub(crate) last_reported_status: Option<lsp_ext::ServerStatusParams>,
|
||||||
pub(crate) source_root_config: SourceRootConfig,
|
pub(crate) source_root_config: SourceRootConfig,
|
||||||
pub(crate) proc_macro_clients: Vec<Result<ProcMacroServer, String>>,
|
|
||||||
|
pub(crate) proc_macro_changed: bool,
|
||||||
|
pub(crate) proc_macro_clients: Arc<[Result<ProcMacroServer, String>]>,
|
||||||
|
|
||||||
pub(crate) flycheck: Arc<[FlycheckHandle]>,
|
pub(crate) flycheck: Arc<[FlycheckHandle]>,
|
||||||
pub(crate) flycheck_sender: Sender<flycheck::Message>,
|
pub(crate) flycheck_sender: Sender<flycheck::Message>,
|
||||||
|
@ -151,10 +152,11 @@ impl GlobalState {
|
||||||
mem_docs: MemDocs::default(),
|
mem_docs: MemDocs::default(),
|
||||||
semantic_tokens_cache: Arc::new(Default::default()),
|
semantic_tokens_cache: Arc::new(Default::default()),
|
||||||
shutdown_requested: false,
|
shutdown_requested: false,
|
||||||
proc_macro_changed: false,
|
|
||||||
last_reported_status: None,
|
last_reported_status: None,
|
||||||
source_root_config: SourceRootConfig::default(),
|
source_root_config: SourceRootConfig::default(),
|
||||||
proc_macro_clients: vec![],
|
|
||||||
|
proc_macro_changed: false,
|
||||||
|
proc_macro_clients: Arc::new([]),
|
||||||
|
|
||||||
flycheck: Arc::new([]),
|
flycheck: Arc::new([]),
|
||||||
flycheck_sender,
|
flycheck_sender,
|
||||||
|
|
|
@ -5,6 +5,7 @@
|
||||||
use std::{
|
use std::{
|
||||||
io::Write as _,
|
io::Write as _,
|
||||||
process::{self, Stdio},
|
process::{self, Stdio},
|
||||||
|
sync::Arc,
|
||||||
};
|
};
|
||||||
|
|
||||||
use anyhow::Context;
|
use anyhow::Context;
|
||||||
|
@ -44,7 +45,7 @@ use crate::{
|
||||||
};
|
};
|
||||||
|
|
||||||
pub(crate) fn handle_workspace_reload(state: &mut GlobalState, _: ()) -> Result<()> {
|
pub(crate) fn handle_workspace_reload(state: &mut GlobalState, _: ()) -> Result<()> {
|
||||||
state.proc_macro_clients.clear();
|
state.proc_macro_clients = Arc::new([]);
|
||||||
state.proc_macro_changed = false;
|
state.proc_macro_changed = false;
|
||||||
|
|
||||||
state.fetch_workspaces_queue.request_op("reload workspace request".to_string());
|
state.fetch_workspaces_queue.request_op("reload workspace request".to_string());
|
||||||
|
@ -52,6 +53,14 @@ pub(crate) fn handle_workspace_reload(state: &mut GlobalState, _: ()) -> Result<
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub(crate) fn handle_proc_macros_reload(state: &mut GlobalState, _: ()) -> Result<()> {
|
||||||
|
state.proc_macro_clients = Arc::new([]);
|
||||||
|
state.proc_macro_changed = false;
|
||||||
|
|
||||||
|
state.fetch_build_data_queue.request_op("reload proc macros request".to_string());
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
pub(crate) fn handle_cancel_flycheck(state: &mut GlobalState, _: ()) -> Result<()> {
|
pub(crate) fn handle_cancel_flycheck(state: &mut GlobalState, _: ()) -> Result<()> {
|
||||||
let _p = profile::span("handle_stop_flycheck");
|
let _p = profile::span("handle_stop_flycheck");
|
||||||
state.flycheck.iter().for_each(|flycheck| flycheck.cancel());
|
state.flycheck.iter().for_each(|flycheck| flycheck.cancel());
|
||||||
|
|
|
@ -51,6 +51,14 @@ impl Request for ReloadWorkspace {
|
||||||
const METHOD: &'static str = "rust-analyzer/reloadWorkspace";
|
const METHOD: &'static str = "rust-analyzer/reloadWorkspace";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub enum ReloadProcMacros {}
|
||||||
|
|
||||||
|
impl Request for ReloadProcMacros {
|
||||||
|
type Params = ();
|
||||||
|
type Result = ();
|
||||||
|
const METHOD: &'static str = "rust-analyzer/reloadProcMacros";
|
||||||
|
}
|
||||||
|
|
||||||
pub enum SyntaxTree {}
|
pub enum SyntaxTree {}
|
||||||
|
|
||||||
impl Request for SyntaxTree {
|
impl Request for SyntaxTree {
|
||||||
|
|
|
@ -24,7 +24,7 @@ use crate::{
|
||||||
handlers, lsp_ext,
|
handlers, lsp_ext,
|
||||||
lsp_utils::{apply_document_changes, notification_is, Progress},
|
lsp_utils::{apply_document_changes, notification_is, Progress},
|
||||||
mem_docs::DocumentData,
|
mem_docs::DocumentData,
|
||||||
reload::{self, BuildDataProgress, ProjectWorkspaceProgress},
|
reload::{self, BuildDataProgress, ProcMacroProgress, ProjectWorkspaceProgress},
|
||||||
Result,
|
Result,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -68,6 +68,7 @@ pub(crate) enum Task {
|
||||||
PrimeCaches(PrimeCachesProgress),
|
PrimeCaches(PrimeCachesProgress),
|
||||||
FetchWorkspace(ProjectWorkspaceProgress),
|
FetchWorkspace(ProjectWorkspaceProgress),
|
||||||
FetchBuildData(BuildDataProgress),
|
FetchBuildData(BuildDataProgress),
|
||||||
|
LoadProcMacros(ProcMacroProgress),
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
|
@ -487,6 +488,21 @@ impl GlobalState {
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
if let Some(state) = state {
|
||||||
|
self.report_progress("Building", state, msg, None, None);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Task::LoadProcMacros(progress) => {
|
||||||
|
let (state, msg) = match progress {
|
||||||
|
ProcMacroProgress::Begin => (Some(Progress::Begin), None),
|
||||||
|
ProcMacroProgress::Report(msg) => (Some(Progress::Report), Some(msg)),
|
||||||
|
ProcMacroProgress::End(proc_macro_load_result) => {
|
||||||
|
self.set_proc_macros(proc_macro_load_result);
|
||||||
|
|
||||||
|
(Some(Progress::End), None)
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
if let Some(state) = state {
|
if let Some(state) = state {
|
||||||
self.report_progress("Loading", state, msg, None, None);
|
self.report_progress("Loading", state, msg, None, None);
|
||||||
}
|
}
|
||||||
|
@ -633,6 +649,7 @@ impl GlobalState {
|
||||||
|
|
||||||
dispatcher
|
dispatcher
|
||||||
.on_sync_mut::<lsp_ext::ReloadWorkspace>(handlers::handle_workspace_reload)
|
.on_sync_mut::<lsp_ext::ReloadWorkspace>(handlers::handle_workspace_reload)
|
||||||
|
.on_sync_mut::<lsp_ext::ReloadProcMacros>(handlers::handle_proc_macros_reload)
|
||||||
.on_sync_mut::<lsp_ext::MemoryUsage>(handlers::handle_memory_usage)
|
.on_sync_mut::<lsp_ext::MemoryUsage>(handlers::handle_memory_usage)
|
||||||
.on_sync_mut::<lsp_ext::ShuffleCrateGraph>(handlers::handle_shuffle_crate_graph)
|
.on_sync_mut::<lsp_ext::ShuffleCrateGraph>(handlers::handle_shuffle_crate_graph)
|
||||||
.on_sync::<lsp_ext::JoinLines>(handlers::handle_join_lines)
|
.on_sync::<lsp_ext::JoinLines>(handlers::handle_join_lines)
|
||||||
|
|
|
@ -12,7 +12,7 @@
|
||||||
//! correct. Instead, we try to provide a best-effort service. Even if the
|
//! correct. Instead, we try to provide a best-effort service. Even if the
|
||||||
//! project is currently loading and we don't have a full project model, we
|
//! project is currently loading and we don't have a full project model, we
|
||||||
//! still want to respond to various requests.
|
//! still want to respond to various requests.
|
||||||
use std::{collections::hash_map::Entry, mem, sync::Arc};
|
use std::{collections::hash_map::Entry, iter, mem, sync::Arc};
|
||||||
|
|
||||||
use flycheck::{FlycheckConfig, FlycheckHandle};
|
use flycheck::{FlycheckConfig, FlycheckHandle};
|
||||||
use hir::db::DefDatabase;
|
use hir::db::DefDatabase;
|
||||||
|
@ -20,7 +20,7 @@ use ide::Change;
|
||||||
use ide_db::{
|
use ide_db::{
|
||||||
base_db::{
|
base_db::{
|
||||||
CrateGraph, Env, ProcMacro, ProcMacroExpander, ProcMacroExpansionError, ProcMacroKind,
|
CrateGraph, Env, ProcMacro, ProcMacroExpander, ProcMacroExpansionError, ProcMacroKind,
|
||||||
ProcMacroLoadResult, SourceRoot, VfsPath,
|
ProcMacroLoadResult, ProcMacroPaths, ProcMacros, SourceRoot, VfsPath,
|
||||||
},
|
},
|
||||||
FxHashMap,
|
FxHashMap,
|
||||||
};
|
};
|
||||||
|
@ -54,6 +54,13 @@ pub(crate) enum BuildDataProgress {
|
||||||
End((Arc<Vec<ProjectWorkspace>>, Vec<anyhow::Result<WorkspaceBuildScripts>>)),
|
End((Arc<Vec<ProjectWorkspace>>, Vec<anyhow::Result<WorkspaceBuildScripts>>)),
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[derive(Debug)]
|
||||||
|
pub(crate) enum ProcMacroProgress {
|
||||||
|
Begin,
|
||||||
|
Report(String),
|
||||||
|
End(ProcMacros),
|
||||||
|
}
|
||||||
|
|
||||||
impl GlobalState {
|
impl GlobalState {
|
||||||
pub(crate) fn is_quiescent(&self) -> bool {
|
pub(crate) fn is_quiescent(&self) -> bool {
|
||||||
!(self.last_reported_status.is_none()
|
!(self.last_reported_status.is_none()
|
||||||
|
@ -216,6 +223,59 @@ impl GlobalState {
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub(crate) fn load_proc_macros(&mut self, paths: Vec<ProcMacroPaths>) {
|
||||||
|
tracing::info!("will load proc macros");
|
||||||
|
let dummy_replacements = self.config.dummy_replacements().clone();
|
||||||
|
let proc_macro_clients = self.proc_macro_clients.clone();
|
||||||
|
|
||||||
|
self.task_pool.handle.spawn_with_sender(move |sender| {
|
||||||
|
sender.send(Task::LoadProcMacros(ProcMacroProgress::Begin)).unwrap();
|
||||||
|
|
||||||
|
let dummy_replacements = &dummy_replacements;
|
||||||
|
let progress = {
|
||||||
|
let sender = sender.clone();
|
||||||
|
&move |msg| {
|
||||||
|
sender.send(Task::LoadProcMacros(ProcMacroProgress::Report(msg))).unwrap()
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
let mut res = FxHashMap::default();
|
||||||
|
for (client, paths) in proc_macro_clients
|
||||||
|
.iter()
|
||||||
|
.map(|res| res.as_ref().map_err(|e| &**e))
|
||||||
|
.chain(iter::repeat_with(|| Err("Proc macros are disabled")))
|
||||||
|
.zip(paths)
|
||||||
|
{
|
||||||
|
res.extend(paths.into_iter().map(move |(crate_id, res)| {
|
||||||
|
(
|
||||||
|
crate_id,
|
||||||
|
res.and_then(|(crate_name, path)| {
|
||||||
|
progress(path.display().to_string());
|
||||||
|
load_proc_macro(
|
||||||
|
client,
|
||||||
|
&path,
|
||||||
|
crate_name
|
||||||
|
.as_deref()
|
||||||
|
.and_then(|crate_name| {
|
||||||
|
dummy_replacements.get(crate_name).map(|v| &**v)
|
||||||
|
})
|
||||||
|
.unwrap_or_default(),
|
||||||
|
)
|
||||||
|
}),
|
||||||
|
)
|
||||||
|
}));
|
||||||
|
}
|
||||||
|
|
||||||
|
sender.send(Task::LoadProcMacros(ProcMacroProgress::End(res))).unwrap();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
pub(crate) fn set_proc_macros(&mut self, proc_macros: ProcMacros) {
|
||||||
|
let mut change = Change::new();
|
||||||
|
change.set_proc_macros(proc_macros);
|
||||||
|
self.analysis_host.apply_change(change);
|
||||||
|
}
|
||||||
|
|
||||||
pub(crate) fn switch_workspaces(&mut self, cause: Cause) {
|
pub(crate) fn switch_workspaces(&mut self, cause: Cause) {
|
||||||
let _p = profile::span("GlobalState::switch_workspaces");
|
let _p = profile::span("GlobalState::switch_workspaces");
|
||||||
tracing::info!(%cause, "will switch workspaces");
|
tracing::info!(%cause, "will switch workspaces");
|
||||||
|
@ -303,8 +363,6 @@ impl GlobalState {
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
let mut change = Change::new();
|
|
||||||
|
|
||||||
let files_config = self.config.files();
|
let files_config = self.config.files();
|
||||||
let project_folders = ProjectFolders::new(&self.workspaces, &files_config.exclude);
|
let project_folders = ProjectFolders::new(&self.workspaces, &files_config.exclude);
|
||||||
|
|
||||||
|
@ -353,11 +411,10 @@ impl GlobalState {
|
||||||
watch,
|
watch,
|
||||||
version: self.vfs_config_version,
|
version: self.vfs_config_version,
|
||||||
});
|
});
|
||||||
|
self.source_root_config = project_folders.source_root_config;
|
||||||
|
|
||||||
// Create crate graph from all the workspaces
|
// Create crate graph from all the workspaces
|
||||||
let crate_graph = {
|
let (crate_graph, proc_macro_paths) = {
|
||||||
let dummy_replacements = self.config.dummy_replacements();
|
|
||||||
|
|
||||||
let vfs = &mut self.vfs.write().0;
|
let vfs = &mut self.vfs.write().0;
|
||||||
let loader = &mut self.loader;
|
let loader = &mut self.loader;
|
||||||
let mem_docs = &self.mem_docs;
|
let mem_docs = &self.mem_docs;
|
||||||
|
@ -376,33 +433,26 @@ impl GlobalState {
|
||||||
};
|
};
|
||||||
|
|
||||||
let mut crate_graph = CrateGraph::default();
|
let mut crate_graph = CrateGraph::default();
|
||||||
for (idx, ws) in self.workspaces.iter().enumerate() {
|
let mut proc_macros = Vec::default();
|
||||||
let proc_macro_client = match self.proc_macro_clients.get(idx) {
|
for ws in &**self.workspaces {
|
||||||
Some(res) => res.as_ref().map_err(|e| &**e),
|
let (other, mut crate_proc_macros) =
|
||||||
None => Err("Proc macros are disabled"),
|
ws.to_crate_graph(&mut load, &self.config.cargo().extra_env);
|
||||||
};
|
crate_graph.extend(other, &mut crate_proc_macros);
|
||||||
let mut load_proc_macro = move |crate_name: &str, path: &AbsPath| {
|
proc_macros.push(crate_proc_macros);
|
||||||
load_proc_macro(
|
|
||||||
proc_macro_client,
|
|
||||||
path,
|
|
||||||
dummy_replacements.get(crate_name).map(|v| &**v).unwrap_or_default(),
|
|
||||||
)
|
|
||||||
};
|
|
||||||
crate_graph.extend(ws.to_crate_graph(
|
|
||||||
&mut load_proc_macro,
|
|
||||||
&mut load,
|
|
||||||
&self.config.cargo().extra_env,
|
|
||||||
));
|
|
||||||
}
|
}
|
||||||
crate_graph
|
(crate_graph, proc_macros)
|
||||||
};
|
};
|
||||||
|
let mut change = Change::new();
|
||||||
change.set_crate_graph(crate_graph);
|
change.set_crate_graph(crate_graph);
|
||||||
|
|
||||||
self.source_root_config = project_folders.source_root_config;
|
|
||||||
|
|
||||||
self.analysis_host.apply_change(change);
|
self.analysis_host.apply_change(change);
|
||||||
self.process_changes();
|
self.process_changes();
|
||||||
|
|
||||||
|
if same_workspaces && !self.fetch_workspaces_queue.op_requested() {
|
||||||
|
self.load_proc_macros(proc_macro_paths);
|
||||||
|
}
|
||||||
|
|
||||||
self.reload_flycheck();
|
self.reload_flycheck();
|
||||||
|
|
||||||
tracing::info!("did switch workspaces");
|
tracing::info!("did switch workspaces");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
<!---
|
<!---
|
||||||
lsp_ext.rs hash: 37f31ae648632897
|
lsp_ext.rs hash: 92fe1037312754df
|
||||||
|
|
||||||
If you need to change the above hash to make the test pass, please check if you
|
If you need to change the above hash to make the test pass, please check if you
|
||||||
need to adjust this doc as well and ping this issue:
|
need to adjust this doc as well and ping this issue:
|
||||||
|
|
|
@ -749,6 +749,10 @@ export function reloadWorkspace(ctx: CtxInit): Cmd {
|
||||||
return async () => ctx.client.sendRequest(ra.reloadWorkspace);
|
return async () => ctx.client.sendRequest(ra.reloadWorkspace);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export function reloadProcMacros(ctx: CtxInit): Cmd {
|
||||||
|
return async () => ctx.client.sendRequest(ra.reloadProcMacros);
|
||||||
|
}
|
||||||
|
|
||||||
export function addProject(ctx: CtxInit): Cmd {
|
export function addProject(ctx: CtxInit): Cmd {
|
||||||
return async () => {
|
return async () => {
|
||||||
const discoverProjectCommand = ctx.config.discoverProjectCommand;
|
const discoverProjectCommand = ctx.config.discoverProjectCommand;
|
||||||
|
|
|
@ -378,10 +378,13 @@ export class Ctx {
|
||||||
if (statusBar.tooltip.value) {
|
if (statusBar.tooltip.value) {
|
||||||
statusBar.tooltip.appendText("\n\n");
|
statusBar.tooltip.appendText("\n\n");
|
||||||
}
|
}
|
||||||
|
statusBar.tooltip.appendMarkdown("\n\n[Open logs](command:rust-analyzer.openLogs)");
|
||||||
statusBar.tooltip.appendMarkdown(
|
statusBar.tooltip.appendMarkdown(
|
||||||
"\n\n[Reload Workspace](command:rust-analyzer.reloadWorkspace)"
|
"\n\n[Reload Workspace](command:rust-analyzer.reloadWorkspace)"
|
||||||
);
|
);
|
||||||
statusBar.tooltip.appendMarkdown("\n\n[Open logs](command:rust-analyzer.openLogs)");
|
statusBar.tooltip.appendMarkdown(
|
||||||
|
"\n\n[Rebuild Proc Macros](command:rust-analyzer.reloadProcMacros)"
|
||||||
|
);
|
||||||
statusBar.tooltip.appendMarkdown("\n\n[Restart server](command:rust-analyzer.startServer)");
|
statusBar.tooltip.appendMarkdown("\n\n[Restart server](command:rust-analyzer.startServer)");
|
||||||
statusBar.tooltip.appendMarkdown("\n\n[Stop server](command:rust-analyzer.stopServer)");
|
statusBar.tooltip.appendMarkdown("\n\n[Stop server](command:rust-analyzer.stopServer)");
|
||||||
if (!status.quiescent) icon = "$(sync~spin) ";
|
if (!status.quiescent) icon = "$(sync~spin) ";
|
||||||
|
|
|
@ -43,6 +43,7 @@ export const relatedTests = new lc.RequestType<lc.TextDocumentPositionParams, Te
|
||||||
"rust-analyzer/relatedTests"
|
"rust-analyzer/relatedTests"
|
||||||
);
|
);
|
||||||
export const reloadWorkspace = new lc.RequestType0<null, void>("rust-analyzer/reloadWorkspace");
|
export const reloadWorkspace = new lc.RequestType0<null, void>("rust-analyzer/reloadWorkspace");
|
||||||
|
export const reloadProcMacros = new lc.RequestType0<null, void>("rust-analyzer/reloadProcMacros");
|
||||||
|
|
||||||
export const runFlycheck = new lc.NotificationType<{
|
export const runFlycheck = new lc.NotificationType<{
|
||||||
textDocument: lc.TextDocumentIdentifier | null;
|
textDocument: lc.TextDocumentIdentifier | null;
|
||||||
|
|
|
@ -153,6 +153,7 @@ function createCommands(): Record<string, CommandFactory> {
|
||||||
memoryUsage: { enabled: commands.memoryUsage },
|
memoryUsage: { enabled: commands.memoryUsage },
|
||||||
shuffleCrateGraph: { enabled: commands.shuffleCrateGraph },
|
shuffleCrateGraph: { enabled: commands.shuffleCrateGraph },
|
||||||
reloadWorkspace: { enabled: commands.reloadWorkspace },
|
reloadWorkspace: { enabled: commands.reloadWorkspace },
|
||||||
|
reloadProcMacros: { enabled: commands.reloadProcMacros },
|
||||||
addProject: { enabled: commands.addProject },
|
addProject: { enabled: commands.addProject },
|
||||||
matchingBrace: { enabled: commands.matchingBrace },
|
matchingBrace: { enabled: commands.matchingBrace },
|
||||||
joinLines: { enabled: commands.joinLines },
|
joinLines: { enabled: commands.joinLines },
|
||||||
|
|
Loading…
Reference in a new issue