Unnamed repository; edit this file 'description' to name the repository.
Diffstat (limited to 'crates/test-fixture/src/lib.rs')
| -rw-r--r-- | crates/test-fixture/src/lib.rs | 173 |
1 files changed, 109 insertions, 64 deletions
diff --git a/crates/test-fixture/src/lib.rs b/crates/test-fixture/src/lib.rs index 37dfb87721..2f379d419e 100644 --- a/crates/test-fixture/src/lib.rs +++ b/crates/test-fixture/src/lib.rs @@ -1,12 +1,14 @@ //! A set of high-level utility fixture methods to use in tests. -use std::{iter, mem, str::FromStr, sync}; +use std::{mem, str::FromStr, sync}; use base_db::{ - CrateDisplayName, CrateGraph, CrateId, CrateName, CrateOrigin, CrateWorkspaceData, Dependency, - Env, FileChange, FileSet, LangCrateOrigin, SourceRoot, SourceRootDatabase, Version, VfsPath, + Crate, CrateDisplayName, CrateGraphBuilder, CrateName, CrateOrigin, CrateWorkspaceData, + DependencyBuilder, Env, FileChange, FileSet, LangCrateOrigin, SourceDatabase, SourceRoot, + Version, VfsPath, salsa, }; use cfg::CfgOptions; use hir_expand::{ + EditionedFileId, FileRange, change::ChangeWithProcMacros, db::ExpandDatabase, files::FilePosition, @@ -15,26 +17,27 @@ use hir_expand::{ }, quote, tt::{Leaf, TokenTree, TopSubtree, TopSubtreeBuilder, TtElement, TtIter}, - FileRange, }; -use intern::{sym, Symbol}; +use intern::{Symbol, sym}; +use paths::AbsPathBuf; use rustc_hash::FxHashMap; -use span::{Edition, EditionedFileId, FileId, Span}; +use span::{Edition, FileId, Span}; use stdx::itertools::Itertools; use test_utils::{ - extract_range_or_offset, Fixture, FixtureWithProjectMeta, RangeOrOffset, CURSOR_MARKER, - ESCAPED_CURSOR_MARKER, + CURSOR_MARKER, ESCAPED_CURSOR_MARKER, Fixture, FixtureWithProjectMeta, RangeOrOffset, + extract_range_or_offset, }; +use triomphe::Arc; pub const WORKSPACE: base_db::SourceRootId = base_db::SourceRootId(0); -pub trait WithFixture: Default + ExpandDatabase + SourceRootDatabase + 'static { +pub trait WithFixture: Default + ExpandDatabase + SourceDatabase + 'static { #[track_caller] fn with_single_file( #[rust_analyzer::rust_fixture] ra_fixture: &str, ) -> (Self, EditionedFileId) { - let fixture = ChangeFixture::parse(ra_fixture); let mut db = Self::default(); + let fixture = ChangeFixture::parse(&db, ra_fixture); fixture.change.apply(&mut db); assert_eq!(fixture.files.len(), 1, "Multiple file found in the fixture"); (db, fixture.files[0]) @@ -44,8 +47,8 @@ pub trait WithFixture: Default + ExpandDatabase + SourceRootDatabase + 'static { fn with_many_files( #[rust_analyzer::rust_fixture] ra_fixture: &str, ) -> (Self, Vec<EditionedFileId>) { - let fixture = ChangeFixture::parse(ra_fixture); let mut db = Self::default(); + let fixture = ChangeFixture::parse(&db, ra_fixture); fixture.change.apply(&mut db); assert!(fixture.file_position.is_none()); (db, fixture.files) @@ -53,8 +56,8 @@ pub trait WithFixture: Default + ExpandDatabase + SourceRootDatabase + 'static { #[track_caller] fn with_files(#[rust_analyzer::rust_fixture] ra_fixture: &str) -> Self { - let fixture = ChangeFixture::parse(ra_fixture); let mut db = Self::default(); + let fixture = ChangeFixture::parse(&db, ra_fixture); fixture.change.apply(&mut db); assert!(fixture.file_position.is_none()); db @@ -65,8 +68,8 @@ pub trait WithFixture: Default + ExpandDatabase + SourceRootDatabase + 'static { #[rust_analyzer::rust_fixture] ra_fixture: &str, proc_macros: Vec<(String, ProcMacro)>, ) -> Self { - let fixture = ChangeFixture::parse_with_proc_macros(ra_fixture, proc_macros); let mut db = Self::default(); + let fixture = ChangeFixture::parse_with_proc_macros(&db, ra_fixture, proc_macros); fixture.change.apply(&mut db); assert!(fixture.file_position.is_none()); db @@ -90,8 +93,8 @@ pub trait WithFixture: Default + ExpandDatabase + SourceRootDatabase + 'static { fn with_range_or_offset( #[rust_analyzer::rust_fixture] ra_fixture: &str, ) -> (Self, EditionedFileId, RangeOrOffset) { - let fixture = ChangeFixture::parse(ra_fixture); let mut db = Self::default(); + let fixture = ChangeFixture::parse(&db, ra_fixture); fixture.change.apply(&mut db); let (file_id, range_or_offset) = fixture @@ -100,18 +103,12 @@ pub trait WithFixture: Default + ExpandDatabase + SourceRootDatabase + 'static { (db, file_id, range_or_offset) } - fn test_crate(&self) -> CrateId { - let crate_graph = self.crate_graph(); - let mut it = crate_graph.iter(); - let mut res = it.next().unwrap(); - while crate_graph[res].origin.is_lang() { - res = it.next().unwrap(); - } - res + fn test_crate(&self) -> Crate { + self.all_crates().iter().copied().find(|&krate| !krate.data(self).origin.is_lang()).unwrap() } } -impl<DB: ExpandDatabase + SourceRootDatabase + Default + 'static> WithFixture for DB {} +impl<DB: ExpandDatabase + SourceDatabase + Default + 'static> WithFixture for DB {} pub struct ChangeFixture { pub file_position: Option<(EditionedFileId, RangeOrOffset)>, @@ -122,11 +119,15 @@ pub struct ChangeFixture { const SOURCE_ROOT_PREFIX: &str = "/"; impl ChangeFixture { - pub fn parse(#[rust_analyzer::rust_fixture] ra_fixture: &str) -> ChangeFixture { - Self::parse_with_proc_macros(ra_fixture, Vec::new()) + pub fn parse( + db: &dyn salsa::Database, + #[rust_analyzer::rust_fixture] ra_fixture: &str, + ) -> ChangeFixture { + Self::parse_with_proc_macros(db, ra_fixture, Vec::new()) } pub fn parse_with_proc_macros( + db: &dyn salsa::Database, #[rust_analyzer::rust_fixture] ra_fixture: &str, mut proc_macro_defs: Vec<(String, ProcMacro)>, ) -> ChangeFixture { @@ -142,13 +143,14 @@ impl ChangeFixture { let channel = toolchain.as_deref().unwrap_or("stable"); Version::parse(&format!("1.76.0-{channel}")).unwrap() }); - let mut source_change = FileChange::new(); + let mut source_change = FileChange::default(); let mut files = Vec::new(); - let mut crate_graph = CrateGraph::default(); + let mut crate_graph = CrateGraphBuilder::default(); let mut crates = FxHashMap::default(); let mut crate_deps = Vec::new(); let mut default_crate_root: Option<FileId> = None; + let mut default_edition = Edition::CURRENT; let mut default_cfg = CfgOptions::default(); let mut default_env = Env::from_iter([( String::from("__ra_is_test_fixture"), @@ -162,6 +164,12 @@ impl ChangeFixture { let mut file_position = None; + let crate_ws_data = + Arc::new(CrateWorkspaceData { data_layout: target_data_layout, toolchain }); + + // FIXME: This is less than ideal + let proc_macro_cwd = Arc::new(AbsPathBuf::assert_utf8(std::env::current_dir().unwrap())); + for entry in fixture { let mut range_or_offset = None; let text = if entry.text.contains(CURSOR_MARKER) { @@ -180,7 +188,7 @@ impl ChangeFixture { let meta = FileMeta::from_fixture(entry, current_source_root_kind); if let Some(range_or_offset) = range_or_offset { file_position = - Some((EditionedFileId::new(file_id, meta.edition), range_or_offset)); + Some((EditionedFileId::new(db, file_id, meta.edition), range_or_offset)); } assert!(meta.path.starts_with(SOURCE_ROOT_PREFIX)); @@ -208,12 +216,13 @@ impl ChangeFixture { meta.edition, Some(crate_name.clone().into()), version, - From::from(meta.cfg.clone()), - Some(From::from(meta.cfg)), + meta.cfg.clone(), + Some(meta.cfg), meta.env, origin, false, - None, + proc_macro_cwd.clone(), + crate_ws_data.clone(), ); let prev = crates.insert(crate_name.clone(), crate_id); assert!(prev.is_none(), "multiple crates with same name: {crate_name}"); @@ -228,6 +237,7 @@ impl ChangeFixture { } else if meta.path == "/main.rs" || meta.path == "/lib.rs" { assert!(default_crate_root.is_none()); default_crate_root = Some(file_id); + default_edition = meta.edition; default_cfg.extend(meta.cfg.into_iter()); default_env.extend_from_other(&meta.env); } @@ -235,7 +245,7 @@ impl ChangeFixture { source_change.change_file(file_id, Some(text)); let path = VfsPath::new_virtual_path(meta.path); file_set.insert(file_id, path); - files.push(EditionedFileId::new(file_id, meta.edition)); + files.push(EditionedFileId::new(db, file_id, meta.edition)); file_id = FileId::from_raw(file_id.index() + 1); } @@ -244,23 +254,27 @@ impl ChangeFixture { .expect("missing default crate root, specify a main.rs or lib.rs"); crate_graph.add_crate_root( crate_root, - Edition::CURRENT, + default_edition, Some(CrateName::new("ra_test_fixture").unwrap().into()), None, - From::from(default_cfg.clone()), - Some(From::from(default_cfg)), + default_cfg.clone(), + Some(default_cfg), default_env, CrateOrigin::Local { repo: None, name: None }, false, - None, + proc_macro_cwd.clone(), + crate_ws_data.clone(), ); } else { for (from, to, prelude) in crate_deps { let from_id = crates[&from]; let to_id = crates[&to]; - let sysroot = crate_graph[to_id].origin.is_lang(); + let sysroot = crate_graph[to_id].basic.origin.is_lang(); crate_graph - .add_dep(from_id, Dependency::with_prelude(to.clone(), to_id, prelude, sysroot)) + .add_dep( + from_id, + DependencyBuilder::with_prelude(to.clone(), to_id, prelude, sysroot), + ) .unwrap(); } } @@ -275,7 +289,7 @@ impl ChangeFixture { source_change.change_file(core_file, Some(mini_core.source_code())); - let all_crates = crate_graph.crates_in_topological_order(); + let all_crates = crate_graph.iter().collect::<Vec<_>>(); let core_crate = crate_graph.add_crate_root( core_file, @@ -290,14 +304,15 @@ impl ChangeFixture { )]), CrateOrigin::Lang(LangCrateOrigin::Core), false, - None, + proc_macro_cwd.clone(), + crate_ws_data.clone(), ); for krate in all_crates { crate_graph .add_dep( krate, - Dependency::with_prelude( + DependencyBuilder::with_prelude( CrateName::new("core").unwrap(), core_crate, true, @@ -323,7 +338,7 @@ impl ChangeFixture { source_change.change_file(proc_lib_file, Some(source)); - let all_crates = crate_graph.crates_in_topological_order(); + let all_crates = crate_graph.iter().collect::<Vec<_>>(); let proc_macros_crate = crate_graph.add_crate_root( proc_lib_file, @@ -338,7 +353,8 @@ impl ChangeFixture { )]), CrateOrigin::Local { repo: None, name: None }, true, - None, + proc_macro_cwd.clone(), + crate_ws_data, ); proc_macros.insert(proc_macros_crate, Ok(proc_macro)); @@ -346,7 +362,10 @@ impl ChangeFixture { crate_graph .add_dep( krate, - Dependency::new(CrateName::new("proc_macros").unwrap(), proc_macros_crate), + DependencyBuilder::new( + CrateName::new("proc_macros").unwrap(), + proc_macros_crate, + ), ) .unwrap(); } @@ -358,19 +377,9 @@ impl ChangeFixture { }; roots.push(root); - let mut change = - ChangeWithProcMacros { source_change, proc_macros: Some(proc_macros.build()) }; + let mut change = ChangeWithProcMacros { source_change, proc_macros: Some(proc_macros) }; change.source_change.set_roots(roots); - change.source_change.set_ws_data( - crate_graph - .iter() - .zip(iter::repeat(From::from(CrateWorkspaceData { - data_layout: target_data_layout, - toolchain, - }))) - .collect(), - ); change.source_change.set_crate_graph(crate_graph); ChangeFixture { file_position, files, change } @@ -649,10 +658,14 @@ impl ProcMacroExpander for IdentityProcMacroExpander { _: Span, _: Span, _: Span, - _: Option<String>, + _: String, ) -> Result<TopSubtree, ProcMacroExpansionError> { Ok(subtree.clone()) } + + fn eq_dyn(&self, other: &dyn ProcMacroExpander) -> bool { + other.as_any().type_id() == std::any::TypeId::of::<Self>() + } } // Expands to a macro_rules! macro, for issue #18089. @@ -667,7 +680,7 @@ impl ProcMacroExpander for Issue18089ProcMacroExpander { _: Span, call_site: Span, _: Span, - _: Option<String>, + _: String, ) -> Result<TopSubtree, ProcMacroExpansionError> { let tt::TokenTree::Leaf(macro_name) = &subtree.0[2] else { return Err(ProcMacroExpansionError::Panic("incorrect input".to_owned())); @@ -684,6 +697,10 @@ impl ProcMacroExpander for Issue18089ProcMacroExpander { #subtree }) } + + fn eq_dyn(&self, other: &dyn ProcMacroExpander) -> bool { + other.as_any().type_id() == std::any::TypeId::of::<Self>() + } } // Pastes the attribute input as its output @@ -698,12 +715,16 @@ impl ProcMacroExpander for AttributeInputReplaceProcMacroExpander { _: Span, _: Span, _: Span, - _: Option<String>, + _: String, ) -> Result<TopSubtree, ProcMacroExpansionError> { attrs .cloned() .ok_or_else(|| ProcMacroExpansionError::Panic("Expected attribute input".into())) } + + fn eq_dyn(&self, other: &dyn ProcMacroExpander) -> bool { + other.as_any().type_id() == std::any::TypeId::of::<Self>() + } } #[derive(Debug)] @@ -717,7 +738,7 @@ impl ProcMacroExpander for Issue18840ProcMacroExpander { def_site: Span, _: Span, _: Span, - _: Option<String>, + _: String, ) -> Result<TopSubtree, ProcMacroExpansionError> { // Input: // ``` @@ -735,6 +756,10 @@ impl ProcMacroExpander for Issue18840ProcMacroExpander { top_subtree_delimiter_mut.close = def_site; Ok(result) } + + fn eq_dyn(&self, other: &dyn ProcMacroExpander) -> bool { + other.as_any().type_id() == std::any::TypeId::of::<Self>() + } } #[derive(Debug)] @@ -748,7 +773,7 @@ impl ProcMacroExpander for MirrorProcMacroExpander { _: Span, _: Span, _: Span, - _: Option<String>, + _: String, ) -> Result<TopSubtree, ProcMacroExpansionError> { fn traverse(builder: &mut TopSubtreeBuilder, iter: TtIter<'_>) { for tt in iter.collect_vec().into_iter().rev() { @@ -766,6 +791,10 @@ impl ProcMacroExpander for MirrorProcMacroExpander { traverse(&mut builder, input.iter()); Ok(builder.build()) } + + fn eq_dyn(&self, other: &dyn ProcMacroExpander) -> bool { + other.as_any().type_id() == std::any::TypeId::of::<Self>() + } } // Replaces every literal with an empty string literal and every identifier with its first letter, @@ -782,7 +811,7 @@ impl ProcMacroExpander for ShortenProcMacroExpander { _: Span, _: Span, _: Span, - _: Option<String>, + _: String, ) -> Result<TopSubtree, ProcMacroExpansionError> { let mut result = input.0.clone(); for it in &mut result { @@ -806,6 +835,10 @@ impl ProcMacroExpander for ShortenProcMacroExpander { } } } + + fn eq_dyn(&self, other: &dyn ProcMacroExpander) -> bool { + other.as_any().type_id() == std::any::TypeId::of::<Self>() + } } // Reads ident type within string quotes, for issue #17479. @@ -820,7 +853,7 @@ impl ProcMacroExpander for Issue17479ProcMacroExpander { _: Span, _: Span, _: Span, - _: Option<String>, + _: String, ) -> Result<TopSubtree, ProcMacroExpansionError> { let TokenTree::Leaf(Leaf::Literal(lit)) = &subtree.0[1] else { return Err(ProcMacroExpansionError::Panic("incorrect Input".into())); @@ -831,6 +864,10 @@ impl ProcMacroExpander for Issue17479ProcMacroExpander { #symbol() }) } + + fn eq_dyn(&self, other: &dyn ProcMacroExpander) -> bool { + other.as_any().type_id() == std::any::TypeId::of::<Self>() + } } // Reads ident type within string quotes, for issue #17479. @@ -845,7 +882,7 @@ impl ProcMacroExpander for Issue18898ProcMacroExpander { def_site: Span, _: Span, _: Span, - _: Option<String>, + _: String, ) -> Result<TopSubtree, ProcMacroExpansionError> { let span = subtree .token_trees() @@ -882,6 +919,10 @@ impl ProcMacroExpander for Issue18898ProcMacroExpander { } }) } + + fn eq_dyn(&self, other: &dyn ProcMacroExpander) -> bool { + other.as_any().type_id() == std::any::TypeId::of::<Self>() + } } // Reads ident type within string quotes, for issue #17479. @@ -896,7 +937,7 @@ impl ProcMacroExpander for DisallowCfgProcMacroExpander { _: Span, _: Span, _: Span, - _: Option<String>, + _: String, ) -> Result<TopSubtree, ProcMacroExpansionError> { for tt in subtree.token_trees().flat_tokens() { if let tt::TokenTree::Leaf(tt::Leaf::Ident(ident)) = tt { @@ -909,4 +950,8 @@ impl ProcMacroExpander for DisallowCfgProcMacroExpander { } Ok(subtree.clone()) } + + fn eq_dyn(&self, other: &dyn ProcMacroExpander) -> bool { + other.as_any().type_id() == std::any::TypeId::of::<Self>() + } } |