mirror of
https://github.com/rust-lang/rust-analyzer
synced 2024-11-16 17:58:16 +00:00
Merge #10225
10225: internal: Add proc-macro fixture directive r=Veykril a=Veykril Co-authored-by: Lukas Wirth <lukastw97@gmail.com>
This commit is contained in:
commit
c3eb646487
3 changed files with 82 additions and 8 deletions
|
@ -6,11 +6,13 @@ use rustc_hash::FxHashMap;
|
||||||
use test_utils::{
|
use test_utils::{
|
||||||
extract_range_or_offset, Fixture, RangeOrOffset, CURSOR_MARKER, ESCAPED_CURSOR_MARKER,
|
extract_range_or_offset, Fixture, RangeOrOffset, CURSOR_MARKER, ESCAPED_CURSOR_MARKER,
|
||||||
};
|
};
|
||||||
|
use tt::Subtree;
|
||||||
use vfs::{file_set::FileSet, VfsPath};
|
use vfs::{file_set::FileSet, VfsPath};
|
||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
input::CrateName, Change, CrateDisplayName, CrateGraph, CrateId, Edition, Env, FileId,
|
input::CrateName, Change, CrateDisplayName, CrateGraph, CrateId, Edition, Env, FileId,
|
||||||
FilePosition, FileRange, SourceDatabaseExt, SourceRoot, SourceRootId,
|
FilePosition, FileRange, ProcMacro, ProcMacroExpander, ProcMacroExpansionError,
|
||||||
|
SourceDatabaseExt, SourceRoot, SourceRootId,
|
||||||
};
|
};
|
||||||
|
|
||||||
pub const WORKSPACE: SourceRootId = SourceRootId(0);
|
pub const WORKSPACE: SourceRootId = SourceRootId(0);
|
||||||
|
@ -81,7 +83,7 @@ pub struct ChangeFixture {
|
||||||
|
|
||||||
impl ChangeFixture {
|
impl ChangeFixture {
|
||||||
pub fn parse(ra_fixture: &str) -> ChangeFixture {
|
pub fn parse(ra_fixture: &str) -> ChangeFixture {
|
||||||
let (mini_core, fixture) = Fixture::parse(ra_fixture);
|
let (mini_core, proc_macros, fixture) = Fixture::parse(ra_fixture);
|
||||||
let mut change = Change::new();
|
let mut change = Change::new();
|
||||||
|
|
||||||
let mut files = Vec::new();
|
let mut files = Vec::new();
|
||||||
|
@ -203,6 +205,39 @@ impl ChangeFixture {
|
||||||
crate_graph.add_dep(krate, CrateName::new("core").unwrap(), core_crate).unwrap();
|
crate_graph.add_dep(krate, CrateName::new("core").unwrap(), core_crate).unwrap();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if !proc_macros.is_empty() {
|
||||||
|
let proc_lib_file = file_id;
|
||||||
|
file_id.0 += 1;
|
||||||
|
|
||||||
|
let mut fs = FileSet::default();
|
||||||
|
fs.insert(
|
||||||
|
proc_lib_file,
|
||||||
|
VfsPath::new_virtual_path("/sysroot/proc_macros/lib.rs".to_string()),
|
||||||
|
);
|
||||||
|
roots.push(SourceRoot::new_library(fs));
|
||||||
|
|
||||||
|
change.change_file(proc_lib_file, Some(Arc::new(String::new())));
|
||||||
|
|
||||||
|
let all_crates = crate_graph.crates_in_topological_order();
|
||||||
|
|
||||||
|
let proc_macros_crate = crate_graph.add_crate_root(
|
||||||
|
proc_lib_file,
|
||||||
|
Edition::Edition2021,
|
||||||
|
Some(CrateDisplayName::from_canonical_name("proc_macros".to_string())),
|
||||||
|
CfgOptions::default(),
|
||||||
|
CfgOptions::default(),
|
||||||
|
Env::default(),
|
||||||
|
test_proc_macros(&proc_macros),
|
||||||
|
);
|
||||||
|
|
||||||
|
for krate in all_crates {
|
||||||
|
crate_graph
|
||||||
|
.add_dep(krate, CrateName::new("proc_macros").unwrap(), proc_macros_crate)
|
||||||
|
.unwrap();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
let root = match current_source_root_kind {
|
let root = match current_source_root_kind {
|
||||||
SourceRootKind::Local => SourceRoot::new_local(mem::take(&mut file_set)),
|
SourceRootKind::Local => SourceRoot::new_local(mem::take(&mut file_set)),
|
||||||
SourceRootKind::Library => SourceRoot::new_library(mem::take(&mut file_set)),
|
SourceRootKind::Library => SourceRoot::new_library(mem::take(&mut file_set)),
|
||||||
|
@ -215,6 +250,16 @@ impl ChangeFixture {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn test_proc_macros(proc_macros: &[String]) -> Vec<ProcMacro> {
|
||||||
|
std::array::IntoIter::new([ProcMacro {
|
||||||
|
name: "identity".into(),
|
||||||
|
kind: crate::ProcMacroKind::Attr,
|
||||||
|
expander: Arc::new(IdentityProcMacroExpander),
|
||||||
|
}])
|
||||||
|
.filter(|pm| proc_macros.iter().any(|name| name == &pm.name))
|
||||||
|
.collect()
|
||||||
|
}
|
||||||
|
|
||||||
#[derive(Debug, Clone, Copy)]
|
#[derive(Debug, Clone, Copy)]
|
||||||
enum SourceRootKind {
|
enum SourceRootKind {
|
||||||
Local,
|
Local,
|
||||||
|
@ -253,3 +298,16 @@ impl From<Fixture> for FileMeta {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[derive(Debug)]
|
||||||
|
pub struct IdentityProcMacroExpander;
|
||||||
|
impl ProcMacroExpander for IdentityProcMacroExpander {
|
||||||
|
fn expand(
|
||||||
|
&self,
|
||||||
|
subtree: &Subtree,
|
||||||
|
_: Option<&Subtree>,
|
||||||
|
_: &Env,
|
||||||
|
) -> Result<Subtree, ProcMacroExpansionError> {
|
||||||
|
Ok(subtree.clone())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -78,7 +78,8 @@ impl<'a> Project<'a> {
|
||||||
profile::init_from(crate::PROFILE);
|
profile::init_from(crate::PROFILE);
|
||||||
});
|
});
|
||||||
|
|
||||||
let (mini_core, fixtures) = Fixture::parse(self.fixture);
|
let (mini_core, proc_macros, fixtures) = Fixture::parse(self.fixture);
|
||||||
|
assert!(proc_macros.is_empty());
|
||||||
assert!(mini_core.is_none());
|
assert!(mini_core.is_none());
|
||||||
for entry in fixtures {
|
for entry in fixtures {
|
||||||
let path = tmp_dir.path().join(&entry.path['/'.len_utf8()..]);
|
let path = tmp_dir.path().join(&entry.path['/'.len_utf8()..]);
|
||||||
|
|
|
@ -92,19 +92,32 @@ impl Fixture {
|
||||||
/// //- other meta
|
/// //- other meta
|
||||||
/// ```
|
/// ```
|
||||||
///
|
///
|
||||||
/// Fixture can also start with a minicore declaration:
|
/// Fixture can also start with a proc_macros and minicore declaration(in that order):
|
||||||
///
|
///
|
||||||
/// ```
|
/// ```
|
||||||
|
/// //- proc_macros: identity
|
||||||
/// //- minicore: sized
|
/// //- minicore: sized
|
||||||
/// ```
|
/// ```
|
||||||
///
|
///
|
||||||
/// That will include a subset of `libcore` into the fixture, see
|
/// That will include predefined proc macros and a subset of `libcore` into the fixture, see
|
||||||
/// `minicore.rs` for what's available.
|
/// `minicore.rs` for what's available.
|
||||||
pub fn parse(ra_fixture: &str) -> (Option<MiniCore>, Vec<Fixture>) {
|
pub fn parse(ra_fixture: &str) -> (Option<MiniCore>, Vec<String>, Vec<Fixture>) {
|
||||||
let fixture = trim_indent(ra_fixture);
|
let fixture = trim_indent(ra_fixture);
|
||||||
let mut fixture = fixture.as_str();
|
let mut fixture = fixture.as_str();
|
||||||
let mut mini_core = None;
|
let mut mini_core = None;
|
||||||
let mut res: Vec<Fixture> = Vec::new();
|
let mut res: Vec<Fixture> = Vec::new();
|
||||||
|
let mut test_proc_macros = vec![];
|
||||||
|
|
||||||
|
if fixture.starts_with("//- proc_macros:") {
|
||||||
|
let first_line = fixture.split_inclusive('\n').next().unwrap();
|
||||||
|
test_proc_macros = first_line
|
||||||
|
.strip_prefix("//- proc_macros:")
|
||||||
|
.unwrap()
|
||||||
|
.split(',')
|
||||||
|
.map(|it| it.trim().to_string())
|
||||||
|
.collect();
|
||||||
|
fixture = &fixture[first_line.len()..];
|
||||||
|
}
|
||||||
|
|
||||||
if fixture.starts_with("//- minicore:") {
|
if fixture.starts_with("//- minicore:") {
|
||||||
let first_line = fixture.split_inclusive('\n').next().unwrap();
|
let first_line = fixture.split_inclusive('\n').next().unwrap();
|
||||||
|
@ -144,7 +157,7 @@ impl Fixture {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
(mini_core, res)
|
(mini_core, test_proc_macros, res)
|
||||||
}
|
}
|
||||||
|
|
||||||
//- /lib.rs crate:foo deps:bar,baz cfg:foo=a,bar=b env:OUTDIR=path/to,OTHER=foo
|
//- /lib.rs crate:foo deps:bar,baz cfg:foo=a,bar=b env:OUTDIR=path/to,OTHER=foo
|
||||||
|
@ -355,13 +368,15 @@ fn parse_fixture_checks_further_indented_metadata() {
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn parse_fixture_gets_full_meta() {
|
fn parse_fixture_gets_full_meta() {
|
||||||
let (mini_core, parsed) = Fixture::parse(
|
let (mini_core, proc_macros, parsed) = Fixture::parse(
|
||||||
r#"
|
r#"
|
||||||
|
//- proc_macros: identity
|
||||||
//- minicore: coerce_unsized
|
//- minicore: coerce_unsized
|
||||||
//- /lib.rs crate:foo deps:bar,baz cfg:foo=a,bar=b,atom env:OUTDIR=path/to,OTHER=foo
|
//- /lib.rs crate:foo deps:bar,baz cfg:foo=a,bar=b,atom env:OUTDIR=path/to,OTHER=foo
|
||||||
mod m;
|
mod m;
|
||||||
"#,
|
"#,
|
||||||
);
|
);
|
||||||
|
assert_eq!(proc_macros, vec!["identity".to_string()]);
|
||||||
assert_eq!(mini_core.unwrap().activated_flags, vec!["coerce_unsized".to_string()]);
|
assert_eq!(mini_core.unwrap().activated_flags, vec!["coerce_unsized".to_string()]);
|
||||||
assert_eq!(1, parsed.len());
|
assert_eq!(1, parsed.len());
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue