From 8716c4cec3a05ba891b20b5f28df69d925b913ad Mon Sep 17 00:00:00 2001 From: Aleksey Kladov Date: Fri, 2 Oct 2020 15:45:09 +0200 Subject: Move ide::AnalysisChange -> base_db::Change This seems like a better factoring logically; ideally, clients shouldn't touch `set_` methods of the database directly. Additionally, I think this should remove the unfortunate duplication in fixture code. --- crates/base_db/src/change.rs | 97 ++++++++ crates/base_db/src/lib.rs | 2 + crates/ide/src/lib.rs | 7 +- crates/ide/src/mock_analysis.rs | 6 +- crates/ide/src/parent_module.rs | 4 +- crates/ide_db/src/apply_change.rs | 239 +++++++++++++++++++ crates/ide_db/src/change.rs | 305 ------------------------- crates/ide_db/src/lib.rs | 2 +- crates/rust-analyzer/src/cli/analysis_bench.rs | 7 +- crates/rust-analyzer/src/cli/load_cargo.rs | 4 +- crates/rust-analyzer/src/global_state.rs | 4 +- crates/rust-analyzer/src/reload.rs | 4 +- 12 files changed, 355 insertions(+), 326 deletions(-) create mode 100644 crates/base_db/src/change.rs create mode 100644 crates/ide_db/src/apply_change.rs delete mode 100644 crates/ide_db/src/change.rs diff --git a/crates/base_db/src/change.rs b/crates/base_db/src/change.rs new file mode 100644 index 000000000..043e03bba --- /dev/null +++ b/crates/base_db/src/change.rs @@ -0,0 +1,97 @@ +//! Defines a unit of change that can applied to the database to get the next +//! state. Changes are transactional. + +use std::{fmt, sync::Arc}; + +use rustc_hash::FxHashSet; +use salsa::Durability; +use vfs::FileId; + +use crate::{CrateGraph, SourceDatabaseExt, SourceRoot, SourceRootId}; + +/// Encapsulate a bunch of raw `.set` calls on the database. +#[derive(Default)] +pub struct Change { + pub roots: Option>, + pub files_changed: Vec<(FileId, Option>)>, + pub crate_graph: Option, +} + +impl fmt::Debug for Change { + fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result { + let mut d = fmt.debug_struct("AnalysisChange"); + if let Some(roots) = &self.roots { + d.field("roots", roots); + } + if !self.files_changed.is_empty() { + d.field("files_changed", &self.files_changed.len()); + } + if self.crate_graph.is_some() { + d.field("crate_graph", &self.crate_graph); + } + d.finish() + } +} + +impl Change { + pub fn new() -> Change { + Change::default() + } + + pub fn set_roots(&mut self, roots: Vec) { + self.roots = Some(roots); + } + + pub fn change_file(&mut self, file_id: FileId, new_text: Option>) { + self.files_changed.push((file_id, new_text)) + } + + pub fn set_crate_graph(&mut self, graph: CrateGraph) { + self.crate_graph = Some(graph); + } + + pub fn apply(self, db: &mut dyn SourceDatabaseExt) { + let _p = profile::span("RootDatabase::apply_change"); + // db.request_cancellation(); + // log::info!("apply_change {:?}", change); + if let Some(roots) = self.roots { + let mut local_roots = FxHashSet::default(); + let mut library_roots = FxHashSet::default(); + for (idx, root) in roots.into_iter().enumerate() { + let root_id = SourceRootId(idx as u32); + let durability = durability(&root); + if root.is_library { + library_roots.insert(root_id); + } else { + local_roots.insert(root_id); + } + for file_id in root.iter() { + db.set_file_source_root_with_durability(file_id, root_id, durability); + } + db.set_source_root_with_durability(root_id, Arc::new(root), durability); + } + // db.set_local_roots_with_durability(Arc::new(local_roots), Durability::HIGH); + // db.set_library_roots_with_durability(Arc::new(library_roots), Durability::HIGH); + } + + for (file_id, text) in self.files_changed { + let source_root_id = db.file_source_root(file_id); + let source_root = db.source_root(source_root_id); + let durability = durability(&source_root); + // XXX: can't actually remove the file, just reset the text + let text = text.unwrap_or_default(); + db.set_file_text_with_durability(file_id, text, durability) + } + if let Some(crate_graph) = self.crate_graph { + db.set_crate_graph_with_durability(Arc::new(crate_graph), Durability::HIGH) + } + } +} + +fn durability(source_root: &SourceRoot) -> Durability { + if source_root.is_library { + Durability::HIGH + } else { + Durability::LOW + } +} diff --git a/crates/base_db/src/lib.rs b/crates/base_db/src/lib.rs index ee3415850..e38aa7257 100644 --- a/crates/base_db/src/lib.rs +++ b/crates/base_db/src/lib.rs @@ -1,6 +1,7 @@ //! base_db defines basic database traits. The concrete DB is defined by ide. mod cancellation; mod input; +mod change; pub mod fixture; use std::{panic, sync::Arc}; @@ -10,6 +11,7 @@ use syntax::{ast, Parse, SourceFile, TextRange, TextSize}; pub use crate::{ cancellation::Canceled, + change::Change, input::{ CrateData, CrateGraph, CrateId, CrateName, Dependency, Edition, Env, FileId, ProcMacroId, SourceRoot, SourceRootId, diff --git a/crates/ide/src/lib.rs b/crates/ide/src/lib.rs index bab3ec1ff..073b766a5 100644 --- a/crates/ide/src/lib.rs +++ b/crates/ide/src/lib.rs @@ -87,12 +87,11 @@ pub use assists::{ utils::MergeBehaviour, Assist, AssistConfig, AssistId, AssistKind, ResolvedAssist, }; pub use base_db::{ - Canceled, CrateGraph, CrateId, Edition, FileId, FilePosition, FileRange, SourceRoot, + Canceled, Change, CrateGraph, CrateId, Edition, FileId, FilePosition, FileRange, SourceRoot, SourceRootId, }; pub use hir::{Documentation, Semantics}; pub use ide_db::{ - change::AnalysisChange, label::Label, line_index::{LineCol, LineIndex}, search::SearchScope, @@ -141,7 +140,7 @@ impl AnalysisHost { /// Applies changes to the current state of the world. If there are /// outstanding snapshots, they will be canceled. - pub fn apply_change(&mut self, change: AnalysisChange) { + pub fn apply_change(&mut self, change: Change) { self.db.apply_change(change) } @@ -195,7 +194,7 @@ impl Analysis { file_set.insert(file_id, VfsPath::new_virtual_path("/main.rs".to_string())); let source_root = SourceRoot::new_local(file_set); - let mut change = AnalysisChange::new(); + let mut change = Change::new(); change.set_roots(vec![source_root]); let mut crate_graph = CrateGraph::default(); // FIXME: cfg options diff --git a/crates/ide/src/mock_analysis.rs b/crates/ide/src/mock_analysis.rs index 327cdf91e..6812db9b9 100644 --- a/crates/ide/src/mock_analysis.rs +++ b/crates/ide/src/mock_analysis.rs @@ -7,9 +7,7 @@ use test_utils::{ extract_annotations, extract_range_or_offset, Fixture, RangeOrOffset, CURSOR_MARKER, }; -use crate::{ - Analysis, AnalysisChange, AnalysisHost, CrateGraph, Edition, FileId, FilePosition, FileRange, -}; +use crate::{Analysis, AnalysisHost, Change, CrateGraph, Edition, FileId, FilePosition, FileRange}; /// Mock analysis is used in test to bootstrap an AnalysisHost/Analysis /// from a set of in-memory files. @@ -95,7 +93,7 @@ impl MockAnalysis { } pub(crate) fn analysis_host(self) -> AnalysisHost { let mut host = AnalysisHost::default(); - let mut change = AnalysisChange::new(); + let mut change = Change::new(); let mut file_set = FileSet::default(); let mut crate_graph = CrateGraph::default(); let mut root_crate = None; diff --git a/crates/ide/src/parent_module.rs b/crates/ide/src/parent_module.rs index 59ed2967c..68b107901 100644 --- a/crates/ide/src/parent_module.rs +++ b/crates/ide/src/parent_module.rs @@ -69,7 +69,7 @@ mod tests { use crate::{ mock_analysis::{analysis_and_position, MockAnalysis}, - AnalysisChange, CrateGraph, + Change, CrateGraph, Edition::Edition2018, }; @@ -146,7 +146,7 @@ mod foo; Env::default(), Default::default(), ); - let mut change = AnalysisChange::new(); + let mut change = Change::new(); change.set_crate_graph(crate_graph); host.apply_change(change); diff --git a/crates/ide_db/src/apply_change.rs b/crates/ide_db/src/apply_change.rs new file mode 100644 index 000000000..da16fa21d --- /dev/null +++ b/crates/ide_db/src/apply_change.rs @@ -0,0 +1,239 @@ +//! Applies changes to the IDE state transactionally. + +use std::{fmt, sync::Arc}; + +use base_db::{ + salsa::{Database, Durability, SweepStrategy}, + Change, FileId, SourceRootId, +}; +use profile::{memory_usage, Bytes}; +use rustc_hash::FxHashSet; + +use crate::{symbol_index::SymbolsDatabase, RootDatabase}; + +#[derive(Debug)] +struct AddFile { + file_id: FileId, + path: String, + text: Arc, +} + +#[derive(Debug)] +struct RemoveFile { + file_id: FileId, + path: String, +} + +#[derive(Default)] +struct RootChange { + added: Vec, + removed: Vec, +} + +impl fmt::Debug for RootChange { + fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result { + fmt.debug_struct("AnalysisChange") + .field("added", &self.added.len()) + .field("removed", &self.removed.len()) + .finish() + } +} + +impl RootDatabase { + pub fn request_cancellation(&mut self) { + let _p = profile::span("RootDatabase::request_cancellation"); + self.salsa_runtime_mut().synthetic_write(Durability::LOW); + } + + pub fn apply_change(&mut self, change: Change) { + let _p = profile::span("RootDatabase::apply_change"); + self.request_cancellation(); + log::info!("apply_change {:?}", change); + if let Some(roots) = &change.roots { + let mut local_roots = FxHashSet::default(); + let mut library_roots = FxHashSet::default(); + for (idx, root) in roots.iter().enumerate() { + let root_id = SourceRootId(idx as u32); + if root.is_library { + library_roots.insert(root_id); + } else { + local_roots.insert(root_id); + } + } + self.set_local_roots_with_durability(Arc::new(local_roots), Durability::HIGH); + self.set_library_roots_with_durability(Arc::new(library_roots), Durability::HIGH); + } + change.apply(self); + } + + pub fn collect_garbage(&mut self) { + if cfg!(feature = "wasm") { + return; + } + + let _p = profile::span("RootDatabase::collect_garbage"); + + let sweep = SweepStrategy::default().discard_values().sweep_all_revisions(); + + base_db::ParseQuery.in_db(self).sweep(sweep); + hir::db::ParseMacroQuery.in_db(self).sweep(sweep); + + // Macros do take significant space, but less then the syntax trees + // self.query(hir::db::MacroDefQuery).sweep(sweep); + // self.query(hir::db::MacroArgTextQuery).sweep(sweep); + // self.query(hir::db::MacroExpandQuery).sweep(sweep); + + hir::db::AstIdMapQuery.in_db(self).sweep(sweep); + + hir::db::BodyWithSourceMapQuery.in_db(self).sweep(sweep); + + hir::db::ExprScopesQuery.in_db(self).sweep(sweep); + hir::db::InferQueryQuery.in_db(self).sweep(sweep); + hir::db::BodyQuery.in_db(self).sweep(sweep); + } + + // Feature: Memory Usage + // + // Clears rust-analyzer's internal database and prints memory usage statistics. + // + // |=== + // | Editor | Action Name + // + // | VS Code | **Rust Analyzer: Memory Usage (Clears Database)** + // |=== + pub fn per_query_memory_usage(&mut self) -> Vec<(String, Bytes)> { + let mut acc: Vec<(String, Bytes)> = vec![]; + let sweep = SweepStrategy::default().discard_values().sweep_all_revisions(); + macro_rules! sweep_each_query { + ($($q:path)*) => {$( + let before = memory_usage().allocated; + $q.in_db(self).sweep(sweep); + let after = memory_usage().allocated; + let q: $q = Default::default(); + let name = format!("{:?}", q); + acc.push((name, before - after)); + + let before = memory_usage().allocated; + $q.in_db(self).sweep(sweep.discard_everything()); + let after = memory_usage().allocated; + let q: $q = Default::default(); + let name = format!("{:?} (deps)", q); + acc.push((name, before - after)); + + let before = memory_usage().allocated; + $q.in_db(self).purge(); + let after = memory_usage().allocated; + let q: $q = Default::default(); + let name = format!("{:?} (purge)", q); + acc.push((name, before - after)); + )*} + } + sweep_each_query![ + // SourceDatabase + base_db::ParseQuery + base_db::CrateGraphQuery + + // SourceDatabaseExt + base_db::FileTextQuery + base_db::FileSourceRootQuery + base_db::SourceRootQuery + base_db::SourceRootCratesQuery + + // AstDatabase + hir::db::AstIdMapQuery + hir::db::MacroArgTextQuery + hir::db::MacroDefQuery + hir::db::ParseMacroQuery + hir::db::MacroExpandQuery + + // DefDatabase + hir::db::ItemTreeQuery + hir::db::CrateDefMapQueryQuery + hir::db::StructDataQuery + hir::db::UnionDataQuery + hir::db::EnumDataQuery + hir::db::ImplDataQuery + hir::db::TraitDataQuery + hir::db::TypeAliasDataQuery + hir::db::FunctionDataQuery + hir::db::ConstDataQuery + hir::db::StaticDataQuery + hir::db::BodyWithSourceMapQuery + hir::db::BodyQuery + hir::db::ExprScopesQuery + hir::db::GenericParamsQuery + hir::db::AttrsQuery + hir::db::ModuleLangItemsQuery + hir::db::CrateLangItemsQuery + hir::db::LangItemQuery + hir::db::DocumentationQuery + hir::db::ImportMapQuery + + // HirDatabase + hir::db::InferQueryQuery + hir::db::TyQuery + hir::db::ValueTyQuery + hir::db::ImplSelfTyQuery + hir::db::ImplTraitQuery + hir::db::FieldTypesQuery + hir::db::CallableItemSignatureQuery + hir::db::GenericPredicatesForParamQuery + hir::db::GenericPredicatesQuery + hir::db::GenericDefaultsQuery + hir::db::InherentImplsInCrateQuery + hir::db::TraitImplsInCrateQuery + hir::db::TraitImplsInDepsQuery + hir::db::AssociatedTyDataQuery + hir::db::AssociatedTyDataQuery + hir::db::TraitDatumQuery + hir::db::StructDatumQuery + hir::db::ImplDatumQuery + hir::db::FnDefDatumQuery + hir::db::ReturnTypeImplTraitsQuery + hir::db::InternCallableDefQuery + hir::db::InternTypeParamIdQuery + hir::db::InternImplTraitIdQuery + hir::db::InternClosureQuery + hir::db::AssociatedTyValueQuery + hir::db::TraitSolveQuery + + // SymbolsDatabase + crate::symbol_index::FileSymbolsQuery + crate::symbol_index::LibrarySymbolsQuery + crate::symbol_index::LocalRootsQuery + crate::symbol_index::LibraryRootsQuery + + // LineIndexDatabase + crate::LineIndexQuery + ]; + + // To collect interned data, we need to bump the revision counter by performing a synthetic + // write. + // We do this after collecting the non-interned queries to correctly attribute memory used + // by interned data. + self.salsa_runtime_mut().synthetic_write(Durability::HIGH); + + sweep_each_query![ + // AstDatabase + hir::db::InternMacroQuery + hir::db::InternEagerExpansionQuery + + // InternDatabase + hir::db::InternFunctionQuery + hir::db::InternStructQuery + hir::db::InternUnionQuery + hir::db::InternEnumQuery + hir::db::InternConstQuery + hir::db::InternStaticQuery + hir::db::InternTraitQuery + hir::db::InternTypeAliasQuery + hir::db::InternImplQuery + + // HirDatabase + hir::db::InternTypeParamIdQuery + ]; + + acc.sort_by_key(|it| std::cmp::Reverse(it.1)); + acc + } +} diff --git a/crates/ide_db/src/change.rs b/crates/ide_db/src/change.rs deleted file mode 100644 index 7f98111c4..000000000 --- a/crates/ide_db/src/change.rs +++ /dev/null @@ -1,305 +0,0 @@ -//! Defines a unit of change that can applied to a state of IDE to get the next -//! state. Changes are transactional. - -use std::{fmt, sync::Arc}; - -use base_db::{ - salsa::{Database, Durability, SweepStrategy}, - CrateGraph, FileId, SourceDatabase, SourceDatabaseExt, SourceRoot, SourceRootId, -}; -use profile::{memory_usage, Bytes}; -use rustc_hash::FxHashSet; - -use crate::{symbol_index::SymbolsDatabase, RootDatabase}; - -#[derive(Default)] -pub struct AnalysisChange { - roots: Option>, - files_changed: Vec<(FileId, Option>)>, - crate_graph: Option, -} - -impl fmt::Debug for AnalysisChange { - fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result { - let mut d = fmt.debug_struct("AnalysisChange"); - if let Some(roots) = &self.roots { - d.field("roots", roots); - } - if !self.files_changed.is_empty() { - d.field("files_changed", &self.files_changed.len()); - } - if self.crate_graph.is_some() { - d.field("crate_graph", &self.crate_graph); - } - d.finish() - } -} - -impl AnalysisChange { - pub fn new() -> AnalysisChange { - AnalysisChange::default() - } - - pub fn set_roots(&mut self, roots: Vec) { - self.roots = Some(roots); - } - - pub fn change_file(&mut self, file_id: FileId, new_text: Option>) { - self.files_changed.push((file_id, new_text)) - } - - pub fn set_crate_graph(&mut self, graph: CrateGraph) { - self.crate_graph = Some(graph); - } -} - -#[derive(Debug)] -struct AddFile { - file_id: FileId, - path: String, - text: Arc, -} - -#[derive(Debug)] -struct RemoveFile { - file_id: FileId, - path: String, -} - -#[derive(Default)] -struct RootChange { - added: Vec, - removed: Vec, -} - -impl fmt::Debug for RootChange { - fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result { - fmt.debug_struct("AnalysisChange") - .field("added", &self.added.len()) - .field("removed", &self.removed.len()) - .finish() - } -} - -impl RootDatabase { - pub fn request_cancellation(&mut self) { - let _p = profile::span("RootDatabase::request_cancellation"); - self.salsa_runtime_mut().synthetic_write(Durability::LOW); - } - - pub fn apply_change(&mut self, change: AnalysisChange) { - let _p = profile::span("RootDatabase::apply_change"); - self.request_cancellation(); - log::info!("apply_change {:?}", change); - if let Some(roots) = change.roots { - let mut local_roots = FxHashSet::default(); - let mut library_roots = FxHashSet::default(); - for (idx, root) in roots.into_iter().enumerate() { - let root_id = SourceRootId(idx as u32); - let durability = durability(&root); - if root.is_library { - library_roots.insert(root_id); - } else { - local_roots.insert(root_id); - } - for file_id in root.iter() { - self.set_file_source_root_with_durability(file_id, root_id, durability); - } - self.set_source_root_with_durability(root_id, Arc::new(root), durability); - } - self.set_local_roots_with_durability(Arc::new(local_roots), Durability::HIGH); - self.set_library_roots_with_durability(Arc::new(library_roots), Durability::HIGH); - } - - for (file_id, text) in change.files_changed { - let source_root_id = self.file_source_root(file_id); - let source_root = self.source_root(source_root_id); - let durability = durability(&source_root); - // XXX: can't actually remove the file, just reset the text - let text = text.unwrap_or_default(); - self.set_file_text_with_durability(file_id, text, durability) - } - if let Some(crate_graph) = change.crate_graph { - self.set_crate_graph_with_durability(Arc::new(crate_graph), Durability::HIGH) - } - } - - pub fn collect_garbage(&mut self) { - if cfg!(feature = "wasm") { - return; - } - - let _p = profile::span("RootDatabase::collect_garbage"); - - let sweep = SweepStrategy::default().discard_values().sweep_all_revisions(); - - base_db::ParseQuery.in_db(self).sweep(sweep); - hir::db::ParseMacroQuery.in_db(self).sweep(sweep); - - // Macros do take significant space, but less then the syntax trees - // self.query(hir::db::MacroDefQuery).sweep(sweep); - // self.query(hir::db::MacroArgTextQuery).sweep(sweep); - // self.query(hir::db::MacroExpandQuery).sweep(sweep); - - hir::db::AstIdMapQuery.in_db(self).sweep(sweep); - - hir::db::BodyWithSourceMapQuery.in_db(self).sweep(sweep); - - hir::db::ExprScopesQuery.in_db(self).sweep(sweep); - hir::db::InferQueryQuery.in_db(self).sweep(sweep); - hir::db::BodyQuery.in_db(self).sweep(sweep); - } - - // Feature: Memory Usage - // - // Clears rust-analyzer's internal database and prints memory usage statistics. - // - // |=== - // | Editor | Action Name - // - // | VS Code | **Rust Analyzer: Memory Usage (Clears Database)** - // |=== - pub fn per_query_memory_usage(&mut self) -> Vec<(String, Bytes)> { - let mut acc: Vec<(String, Bytes)> = vec![]; - let sweep = SweepStrategy::default().discard_values().sweep_all_revisions(); - macro_rules! sweep_each_query { - ($($q:path)*) => {$( - let before = memory_usage().allocated; - $q.in_db(self).sweep(sweep); - let after = memory_usage().allocated; - let q: $q = Default::default(); - let name = format!("{:?}", q); - acc.push((name, before - after)); - - let before = memory_usage().allocated; - $q.in_db(self).sweep(sweep.discard_everything()); - let after = memory_usage().allocated; - let q: $q = Default::default(); - let name = format!("{:?} (deps)", q); - acc.push((name, before - after)); - - let before = memory_usage().allocated; - $q.in_db(self).purge(); - let after = memory_usage().allocated; - let q: $q = Default::default(); - let name = format!("{:?} (purge)", q); - acc.push((name, before - after)); - )*} - } - sweep_each_query![ - // SourceDatabase - base_db::ParseQuery - base_db::CrateGraphQuery - - // SourceDatabaseExt - base_db::FileTextQuery - base_db::FileSourceRootQuery - base_db::SourceRootQuery - base_db::SourceRootCratesQuery - - // AstDatabase - hir::db::AstIdMapQuery - hir::db::MacroArgTextQuery - hir::db::MacroDefQuery - hir::db::ParseMacroQuery - hir::db::MacroExpandQuery - - // DefDatabase - hir::db::ItemTreeQuery - hir::db::CrateDefMapQueryQuery - hir::db::StructDataQuery - hir::db::UnionDataQuery - hir::db::EnumDataQuery - hir::db::ImplDataQuery - hir::db::TraitDataQuery - hir::db::TypeAliasDataQuery - hir::db::FunctionDataQuery - hir::db::ConstDataQuery - hir::db::StaticDataQuery - hir::db::BodyWithSourceMapQuery - hir::db::BodyQuery - hir::db::ExprScopesQuery - hir::db::GenericParamsQuery - hir::db::AttrsQuery - hir::db::ModuleLangItemsQuery - hir::db::CrateLangItemsQuery - hir::db::LangItemQuery - hir::db::DocumentationQuery - hir::db::ImportMapQuery - - // HirDatabase - hir::db::InferQueryQuery - hir::db::TyQuery - hir::db::ValueTyQuery - hir::db::ImplSelfTyQuery - hir::db::ImplTraitQuery - hir::db::FieldTypesQuery - hir::db::CallableItemSignatureQuery - hir::db::GenericPredicatesForParamQuery - hir::db::GenericPredicatesQuery - hir::db::GenericDefaultsQuery - hir::db::InherentImplsInCrateQuery - hir::db::TraitImplsInCrateQuery - hir::db::TraitImplsInDepsQuery - hir::db::AssociatedTyDataQuery - hir::db::AssociatedTyDataQuery - hir::db::TraitDatumQuery - hir::db::StructDatumQuery - hir::db::ImplDatumQuery - hir::db::FnDefDatumQuery - hir::db::ReturnTypeImplTraitsQuery - hir::db::InternCallableDefQuery - hir::db::InternTypeParamIdQuery - hir::db::InternImplTraitIdQuery - hir::db::InternClosureQuery - hir::db::AssociatedTyValueQuery - hir::db::TraitSolveQuery - - // SymbolsDatabase - crate::symbol_index::FileSymbolsQuery - crate::symbol_index::LibrarySymbolsQuery - crate::symbol_index::LocalRootsQuery - crate::symbol_index::LibraryRootsQuery - - // LineIndexDatabase - crate::LineIndexQuery - ]; - - // To collect interned data, we need to bump the revision counter by performing a synthetic - // write. - // We do this after collecting the non-interned queries to correctly attribute memory used - // by interned data. - self.salsa_runtime_mut().synthetic_write(Durability::HIGH); - - sweep_each_query![ - // AstDatabase - hir::db::InternMacroQuery - hir::db::InternEagerExpansionQuery - - // InternDatabase - hir::db::InternFunctionQuery - hir::db::InternStructQuery - hir::db::InternUnionQuery - hir::db::InternEnumQuery - hir::db::InternConstQuery - hir::db::InternStaticQuery - hir::db::InternTraitQuery - hir::db::InternTypeAliasQuery - hir::db::InternImplQuery - - // HirDatabase - hir::db::InternTypeParamIdQuery - ]; - - acc.sort_by_key(|it| std::cmp::Reverse(it.1)); - acc - } -} - -fn durability(source_root: &SourceRoot) -> Durability { - if source_root.is_library { - Durability::HIGH - } else { - Durability::LOW - } -} diff --git a/crates/ide_db/src/lib.rs b/crates/ide_db/src/lib.rs index 0d209c6ec..7eff247c7 100644 --- a/crates/ide_db/src/lib.rs +++ b/crates/ide_db/src/lib.rs @@ -2,10 +2,10 @@ //! //! It is mainly a `HirDatabase` for semantic analysis, plus a `SymbolsDatabase`, for fuzzy search. +mod apply_change; pub mod label; pub mod line_index; pub mod symbol_index; -pub mod change; pub mod defs; pub mod search; pub mod imports_locator; diff --git a/crates/rust-analyzer/src/cli/analysis_bench.rs b/crates/rust-analyzer/src/cli/analysis_bench.rs index c312e0a2e..d1c095ba5 100644 --- a/crates/rust-analyzer/src/cli/analysis_bench.rs +++ b/crates/rust-analyzer/src/cli/analysis_bench.rs @@ -8,8 +8,7 @@ use base_db::{ FileId, }; use ide::{ - Analysis, AnalysisChange, AnalysisHost, CompletionConfig, DiagnosticsConfig, FilePosition, - LineCol, + Analysis, AnalysisHost, Change, CompletionConfig, DiagnosticsConfig, FilePosition, LineCol, }; use vfs::AbsPathBuf; @@ -143,7 +142,7 @@ fn do_work T, T>(host: &mut AnalysisHost, file_id: FileId, w { let mut text = host.analysis().file_text(file_id).unwrap().to_string(); text.push_str("\n/* Hello world */\n"); - let mut change = AnalysisChange::new(); + let mut change = Change::new(); change.change_file(file_id, Some(Arc::new(text))); host.apply_change(change); } @@ -156,7 +155,7 @@ fn do_work T, T>(host: &mut AnalysisHost, file_id: FileId, w { let mut text = host.analysis().file_text(file_id).unwrap().to_string(); text.push_str("\npub fn _dummy() {}\n"); - let mut change = AnalysisChange::new(); + let mut change = Change::new(); change.change_file(file_id, Some(Arc::new(text))); host.apply_change(change); } diff --git a/crates/rust-analyzer/src/cli/load_cargo.rs b/crates/rust-analyzer/src/cli/load_cargo.rs index c47cf6ef3..7ae1c9055 100644 --- a/crates/rust-analyzer/src/cli/load_cargo.rs +++ b/crates/rust-analyzer/src/cli/load_cargo.rs @@ -5,7 +5,7 @@ use std::{path::Path, sync::Arc}; use anyhow::Result; use base_db::CrateGraph; use crossbeam_channel::{unbounded, Receiver}; -use ide::{AnalysisChange, AnalysisHost}; +use ide::{AnalysisHost, Change}; use project_model::{CargoConfig, ProcMacroClient, ProjectManifest, ProjectWorkspace}; use vfs::{loader::Handle, AbsPath, AbsPathBuf}; @@ -62,7 +62,7 @@ fn load( ) -> AnalysisHost { let lru_cap = std::env::var("RA_LRU_CAP").ok().and_then(|it| it.parse::().ok()); let mut host = AnalysisHost::new(lru_cap); - let mut analysis_change = AnalysisChange::new(); + let mut analysis_change = Change::new(); // wait until Vfs has loaded all roots for task in receiver { diff --git a/crates/rust-analyzer/src/global_state.rs b/crates/rust-analyzer/src/global_state.rs index 96313aaec..dafab6a6a 100644 --- a/crates/rust-analyzer/src/global_state.rs +++ b/crates/rust-analyzer/src/global_state.rs @@ -8,7 +8,7 @@ use std::{sync::Arc, time::Instant}; use base_db::{CrateId, VfsPath}; use crossbeam_channel::{unbounded, Receiver, Sender}; use flycheck::FlycheckHandle; -use ide::{Analysis, AnalysisChange, AnalysisHost, FileId}; +use ide::{Analysis, AnalysisHost, Change, FileId}; use lsp_types::{SemanticTokens, Url}; use parking_lot::{Mutex, RwLock}; use project_model::{CargoWorkspace, ProcMacroClient, ProjectWorkspace, Target}; @@ -139,7 +139,7 @@ impl GlobalState { let mut has_fs_changes = false; let change = { - let mut change = AnalysisChange::new(); + let mut change = Change::new(); let (vfs, line_endings_map) = &mut *self.vfs.write(); let changed_files = vfs.take_changes(); if changed_files.is_empty() { diff --git a/crates/rust-analyzer/src/reload.rs b/crates/rust-analyzer/src/reload.rs index de0dbcad4..f7215f129 100644 --- a/crates/rust-analyzer/src/reload.rs +++ b/crates/rust-analyzer/src/reload.rs @@ -3,7 +3,7 @@ use std::{mem, sync::Arc}; use base_db::{CrateGraph, SourceRoot, VfsPath}; use flycheck::{FlycheckConfig, FlycheckHandle}; -use ide::AnalysisChange; +use ide::Change; use project_model::{ProcMacroClient, ProjectWorkspace}; use vfs::{file_set::FileSetConfig, AbsPath, AbsPathBuf, ChangeKind}; @@ -171,7 +171,7 @@ impl GlobalState { ); } - let mut change = AnalysisChange::new(); + let mut change = Change::new(); let project_folders = ProjectFolders::new(&workspaces); -- cgit v1.2.3 From eeb27f95f1025128f8a1d24a515eb009498a1d44 Mon Sep 17 00:00:00 2001 From: Aleksey Kladov Date: Fri, 2 Oct 2020 16:07:33 +0200 Subject: Rewrite fixtures on top of Change --- crates/base_db/src/fixture.rs | 173 ++++++++++++++++++++++-------------------- 1 file changed, 90 insertions(+), 83 deletions(-) diff --git a/crates/base_db/src/fixture.rs b/crates/base_db/src/fixture.rs index 5ff8ead0e..48fa73bf0 100644 --- a/crates/base_db/src/fixture.rs +++ b/crates/base_db/src/fixture.rs @@ -65,24 +65,26 @@ use test_utils::{extract_range_or_offset, Fixture, RangeOrOffset, CURSOR_MARKER} use vfs::{file_set::FileSet, VfsPath}; use crate::{ - input::CrateName, CrateGraph, CrateId, Edition, Env, FileId, FilePosition, SourceDatabaseExt, - SourceRoot, SourceRootId, + input::CrateName, Change, CrateGraph, CrateId, Edition, Env, FileId, FilePosition, + SourceDatabaseExt, SourceRoot, SourceRootId, }; pub const WORKSPACE: SourceRootId = SourceRootId(0); pub trait WithFixture: Default + SourceDatabaseExt + 'static { fn with_single_file(text: &str) -> (Self, FileId) { + let fixture = ChangeFixture::parse(text); let mut db = Self::default(); - let (_, files) = with_files(&mut db, text); - assert_eq!(files.len(), 1); - (db, files[0]) + fixture.change.apply(&mut db); + assert_eq!(fixture.files.len(), 1); + (db, fixture.files[0]) } fn with_files(ra_fixture: &str) -> Self { + let fixture = ChangeFixture::parse(ra_fixture); let mut db = Self::default(); - let (pos, _) = with_files(&mut db, ra_fixture); - assert!(pos.is_none()); + fixture.change.apply(&mut db); + assert!(fixture.file_position.is_none()); db } @@ -96,9 +98,10 @@ pub trait WithFixture: Default + SourceDatabaseExt + 'static { } fn with_range_or_offset(ra_fixture: &str) -> (Self, FileId, RangeOrOffset) { + let fixture = ChangeFixture::parse(ra_fixture); let mut db = Self::default(); - let (pos, _) = with_files(&mut db, ra_fixture); - let (file_id, range_or_offset) = pos.unwrap(); + fixture.change.apply(&mut db); + let (file_id, range_or_offset) = fixture.file_position.unwrap(); (db, file_id, range_or_offset) } @@ -113,89 +116,93 @@ pub trait WithFixture: Default + SourceDatabaseExt + 'static { impl WithFixture for DB {} -fn with_files( - db: &mut dyn SourceDatabaseExt, - fixture: &str, -) -> (Option<(FileId, RangeOrOffset)>, Vec) { - let fixture = Fixture::parse(fixture); - - let mut files = Vec::new(); - let mut crate_graph = CrateGraph::default(); - let mut crates = FxHashMap::default(); - let mut crate_deps = Vec::new(); - let mut default_crate_root: Option = None; - - let mut file_set = FileSet::default(); - let source_root_id = WORKSPACE; - let source_root_prefix = "/".to_string(); - let mut file_id = FileId(0); - - let mut file_position = None; - - for entry in fixture { - let text = if entry.text.contains(CURSOR_MARKER) { - let (range_or_offset, text) = extract_range_or_offset(&entry.text); - assert!(file_position.is_none()); - file_position = Some((file_id, range_or_offset)); - text.to_string() - } else { - entry.text.clone() - }; +pub struct ChangeFixture { + file_position: Option<(FileId, RangeOrOffset)>, + files: Vec, + change: Change, +} - let meta = FileMeta::from(entry); - assert!(meta.path.starts_with(&source_root_prefix)); +impl ChangeFixture { + fn parse(ra_fixture: &str) -> ChangeFixture { + let fixture = Fixture::parse(ra_fixture); + let mut change = Change::new(); + + let mut files = Vec::new(); + let mut crate_graph = CrateGraph::default(); + let mut crates = FxHashMap::default(); + let mut crate_deps = Vec::new(); + let mut default_crate_root: Option = None; + + let mut file_set = FileSet::default(); + let source_root_prefix = "/".to_string(); + let mut file_id = FileId(0); + + let mut file_position = None; + + for entry in fixture { + let text = if entry.text.contains(CURSOR_MARKER) { + let (range_or_offset, text) = extract_range_or_offset(&entry.text); + assert!(file_position.is_none()); + file_position = Some((file_id, range_or_offset)); + text.to_string() + } else { + entry.text.clone() + }; + + let meta = FileMeta::from(entry); + assert!(meta.path.starts_with(&source_root_prefix)); + + if let Some(krate) = meta.krate { + let crate_id = crate_graph.add_crate_root( + file_id, + meta.edition, + Some(krate.clone()), + meta.cfg, + meta.env, + Default::default(), + ); + let crate_name = CrateName::new(&krate).unwrap(); + let prev = crates.insert(crate_name.clone(), crate_id); + assert!(prev.is_none()); + for dep in meta.deps { + let dep = CrateName::new(&dep).unwrap(); + crate_deps.push((crate_name.clone(), dep)) + } + } else if meta.path == "/main.rs" || meta.path == "/lib.rs" { + assert!(default_crate_root.is_none()); + default_crate_root = Some(file_id); + } + + change.change_file(file_id, Some(Arc::new(text))); + let path = VfsPath::new_virtual_path(meta.path); + file_set.insert(file_id, path.into()); + files.push(file_id); + file_id.0 += 1; + } - if let Some(krate) = meta.krate { - let crate_id = crate_graph.add_crate_root( - file_id, - meta.edition, - Some(krate.clone()), - meta.cfg, - meta.env, + if crates.is_empty() { + let crate_root = default_crate_root.unwrap(); + crate_graph.add_crate_root( + crate_root, + Edition::Edition2018, + None, + CfgOptions::default(), + Env::default(), Default::default(), ); - let crate_name = CrateName::new(&krate).unwrap(); - let prev = crates.insert(crate_name.clone(), crate_id); - assert!(prev.is_none()); - for dep in meta.deps { - let dep = CrateName::new(&dep).unwrap(); - crate_deps.push((crate_name.clone(), dep)) + } else { + for (from, to) in crate_deps { + let from_id = crates[&from]; + let to_id = crates[&to]; + crate_graph.add_dep(from_id, CrateName::new(&to).unwrap(), to_id).unwrap(); } - } else if meta.path == "/main.rs" || meta.path == "/lib.rs" { - assert!(default_crate_root.is_none()); - default_crate_root = Some(file_id); } - db.set_file_text(file_id, Arc::new(text)); - db.set_file_source_root(file_id, source_root_id); - let path = VfsPath::new_virtual_path(meta.path); - file_set.insert(file_id, path.into()); - files.push(file_id); - file_id.0 += 1; - } + change.set_roots(vec![SourceRoot::new_local(file_set)]); + change.set_crate_graph(crate_graph); - if crates.is_empty() { - let crate_root = default_crate_root.unwrap(); - crate_graph.add_crate_root( - crate_root, - Edition::Edition2018, - None, - CfgOptions::default(), - Env::default(), - Default::default(), - ); - } else { - for (from, to) in crate_deps { - let from_id = crates[&from]; - let to_id = crates[&to]; - crate_graph.add_dep(from_id, CrateName::new(&to).unwrap(), to_id).unwrap(); - } + ChangeFixture { file_position, files, change } } - - db.set_source_root(source_root_id, Arc::new(SourceRoot::new_local(file_set))); - db.set_crate_graph(Arc::new(crate_graph)); - - (file_position, files) } struct FileMeta { -- cgit v1.2.3 From 09348b247465864c6462a39055803bcbb0156cfe Mon Sep 17 00:00:00 2001 From: Aleksey Kladov Date: Fri, 2 Oct 2020 16:13:48 +0200 Subject: Get rid of MockAnalysis --- crates/base_db/src/fixture.rs | 14 +- crates/ide/src/call_hierarchy.rs | 52 ++--- crates/ide/src/completion/complete_keyword.rs | 8 +- crates/ide/src/completion/complete_mod.rs | 4 +- .../ide/src/completion/complete_qualified_path.rs | 4 +- .../src/completion/complete_unqualified_path.rs | 14 +- crates/ide/src/completion/presentation.rs | 4 +- crates/ide/src/diagnostics.rs | 28 ++- crates/ide/src/display/navigation_target.rs | 4 +- crates/ide/src/goto_definition.rs | 24 ++- crates/ide/src/goto_implementation.rs | 6 +- crates/ide/src/goto_type_definition.rs | 7 +- crates/ide/src/hover.rs | 92 ++++----- crates/ide/src/mock_analysis.rs | 209 ++++++--------------- crates/ide/src/parent_module.rs | 40 +--- crates/ide/src/references.rs | 118 ++++++------ crates/ide/src/references/rename.rs | 34 ++-- crates/ide/src/runnables.rs | 40 ++-- crates/ide/src/syntax_highlighting/tests.rs | 6 +- 19 files changed, 288 insertions(+), 420 deletions(-) diff --git a/crates/base_db/src/fixture.rs b/crates/base_db/src/fixture.rs index 48fa73bf0..b7286fc7d 100644 --- a/crates/base_db/src/fixture.rs +++ b/crates/base_db/src/fixture.rs @@ -117,13 +117,13 @@ pub trait WithFixture: Default + SourceDatabaseExt + 'static { impl WithFixture for DB {} pub struct ChangeFixture { - file_position: Option<(FileId, RangeOrOffset)>, - files: Vec, - change: Change, + pub file_position: Option<(FileId, RangeOrOffset)>, + pub files: Vec, + pub change: Change, } impl ChangeFixture { - fn parse(ra_fixture: &str) -> ChangeFixture { + pub fn parse(ra_fixture: &str) -> ChangeFixture { let fixture = Fixture::parse(ra_fixture); let mut change = Change::new(); @@ -132,6 +132,7 @@ impl ChangeFixture { let mut crates = FxHashMap::default(); let mut crate_deps = Vec::new(); let mut default_crate_root: Option = None; + let mut default_cfg = CfgOptions::default(); let mut file_set = FileSet::default(); let source_root_prefix = "/".to_string(); @@ -171,6 +172,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_cfg = meta.cfg; } change.change_file(file_id, Some(Arc::new(text))); @@ -185,8 +187,8 @@ impl ChangeFixture { crate_graph.add_crate_root( crate_root, Edition::Edition2018, - None, - CfgOptions::default(), + Some("test".to_string()), + default_cfg, Env::default(), Default::default(), ); diff --git a/crates/ide/src/call_hierarchy.rs b/crates/ide/src/call_hierarchy.rs index 58e26b94c..0fb49de71 100644 --- a/crates/ide/src/call_hierarchy.rs +++ b/crates/ide/src/call_hierarchy.rs @@ -181,8 +181,8 @@ fn caller() { call<|>ee(); } "#, - "callee FN FileId(1) 0..14 3..9", - &["caller FN FileId(1) 15..44 18..24 : [33..39]"], + "callee FN FileId(0) 0..14 3..9", + &["caller FN FileId(0) 15..44 18..24 : [33..39]"], &[], ); } @@ -197,8 +197,8 @@ fn caller() { callee(); } "#, - "callee FN FileId(1) 0..14 3..9", - &["caller FN FileId(1) 15..44 18..24 : [33..39]"], + "callee FN FileId(0) 0..14 3..9", + &["caller FN FileId(0) 15..44 18..24 : [33..39]"], &[], ); } @@ -214,8 +214,8 @@ fn caller() { callee(); } "#, - "callee FN FileId(1) 0..14 3..9", - &["caller FN FileId(1) 15..58 18..24 : [33..39, 47..53]"], + "callee FN FileId(0) 0..14 3..9", + &["caller FN FileId(0) 15..58 18..24 : [33..39, 47..53]"], &[], ); } @@ -234,10 +234,10 @@ fn caller2() { callee(); } "#, - "callee FN FileId(1) 0..14 3..9", + "callee FN FileId(0) 0..14 3..9", &[ - "caller1 FN FileId(1) 15..45 18..25 : [34..40]", - "caller2 FN FileId(1) 47..77 50..57 : [66..72]", + "caller1 FN FileId(0) 15..45 18..25 : [34..40]", + "caller2 FN FileId(0) 47..77 50..57 : [66..72]", ], &[], ); @@ -263,10 +263,10 @@ mod tests { } } "#, - "callee FN FileId(1) 0..14 3..9", + "callee FN FileId(0) 0..14 3..9", &[ - "caller1 FN FileId(1) 15..45 18..25 : [34..40]", - "test_caller FN FileId(1) 95..149 110..121 : [134..140]", + "caller1 FN FileId(0) 15..45 18..25 : [34..40]", + "test_caller FN FileId(0) 95..149 110..121 : [134..140]", ], &[], ); @@ -287,8 +287,8 @@ fn caller() { //- /foo/mod.rs pub fn callee() {} "#, - "callee FN FileId(2) 0..18 7..13", - &["caller FN FileId(1) 27..56 30..36 : [45..51]"], + "callee FN FileId(1) 0..18 7..13", + &["caller FN FileId(0) 27..56 30..36 : [45..51]"], &[], ); } @@ -304,9 +304,9 @@ fn call<|>er() { callee(); } "#, - "caller FN FileId(1) 15..58 18..24", + "caller FN FileId(0) 15..58 18..24", &[], - &["callee FN FileId(1) 0..14 3..9 : [33..39, 47..53]"], + &["callee FN FileId(0) 0..14 3..9 : [33..39, 47..53]"], ); } @@ -325,9 +325,9 @@ fn call<|>er() { //- /foo/mod.rs pub fn callee() {} "#, - "caller FN FileId(1) 27..56 30..36", + "caller FN FileId(0) 27..56 30..36", &[], - &["callee FN FileId(2) 0..18 7..13 : [45..51]"], + &["callee FN FileId(1) 0..18 7..13 : [45..51]"], ); } @@ -348,9 +348,9 @@ fn caller3() { } "#, - "caller2 FN FileId(1) 33..64 36..43", - &["caller1 FN FileId(1) 0..31 3..10 : [19..26]"], - &["caller3 FN FileId(1) 66..83 69..76 : [52..59]"], + "caller2 FN FileId(0) 33..64 36..43", + &["caller1 FN FileId(0) 0..31 3..10 : [19..26]"], + &["caller3 FN FileId(0) 66..83 69..76 : [52..59]"], ); } @@ -368,9 +368,9 @@ fn main() { a<|>() } "#, - "a FN FileId(1) 0..18 3..4", - &["main FN FileId(1) 31..52 34..38 : [47..48]"], - &["b FN FileId(1) 20..29 23..24 : [13..14]"], + "a FN FileId(0) 0..18 3..4", + &["main FN FileId(0) 31..52 34..38 : [47..48]"], + &["b FN FileId(0) 20..29 23..24 : [13..14]"], ); check_hierarchy( @@ -385,8 +385,8 @@ fn main() { a() } "#, - "b FN FileId(1) 20..29 23..24", - &["a FN FileId(1) 0..18 3..4 : [13..14]"], + "b FN FileId(0) 20..29 23..24", + &["a FN FileId(0) 0..18 3..4 : [13..14]"], &[], ); } diff --git a/crates/ide/src/completion/complete_keyword.rs b/crates/ide/src/completion/complete_keyword.rs index 5645b41fa..e59747095 100644 --- a/crates/ide/src/completion/complete_keyword.rs +++ b/crates/ide/src/completion/complete_keyword.rs @@ -495,13 +495,13 @@ Some multi-line comment<|> fn test_completion_await_impls_future() { check( r#" -//- /main.rs +//- /main.rs crate:main deps:std use std::future::*; struct A {} impl Future for A {} fn foo(a: A) { a.<|> } -//- /std/lib.rs +//- /std/lib.rs crate:std pub mod future { #[lang = "future_trait"] pub trait Future {} @@ -514,14 +514,14 @@ pub mod future { check( r#" -//- /main.rs +//- /main.rs crate:main deps:std use std::future::*; fn foo() { let a = async {}; a.<|> } -//- /std/lib.rs +//- /std/lib.rs crate:std pub mod future { #[lang = "future_trait"] pub trait Future { diff --git a/crates/ide/src/completion/complete_mod.rs b/crates/ide/src/completion/complete_mod.rs index 3cfc2e131..c7a99bdc3 100644 --- a/crates/ide/src/completion/complete_mod.rs +++ b/crates/ide/src/completion/complete_mod.rs @@ -300,7 +300,7 @@ mod tests { // "#, // expect![[r#" // md bar; - // "#]], + // "#]],foo // ); // } @@ -308,7 +308,7 @@ mod tests { fn already_declared_bin_module_completion_omitted() { check( r#" - //- /src/bin.rs + //- /src/bin.rs crate:main fn main() {} //- /src/bin/foo.rs mod <|> diff --git a/crates/ide/src/completion/complete_qualified_path.rs b/crates/ide/src/completion/complete_qualified_path.rs index 00e89f0fd..2fafedd47 100644 --- a/crates/ide/src/completion/complete_qualified_path.rs +++ b/crates/ide/src/completion/complete_qualified_path.rs @@ -422,10 +422,10 @@ fn foo() { let _ = U::<|> } fn completes_use_paths_across_crates() { check( r#" -//- /main.rs +//- /main.rs crate:main deps:foo use foo::<|>; -//- /foo/lib.rs +//- /foo/lib.rs crate:foo pub mod bar { pub struct S; } "#, expect![[r#" diff --git a/crates/ide/src/completion/complete_unqualified_path.rs b/crates/ide/src/completion/complete_unqualified_path.rs index 8eda4b64d..2010d9a2f 100644 --- a/crates/ide/src/completion/complete_unqualified_path.rs +++ b/crates/ide/src/completion/complete_unqualified_path.rs @@ -271,10 +271,10 @@ fn quux() { <|> } fn completes_extern_prelude() { check( r#" -//- /lib.rs +//- /lib.rs crate:main deps:other_crate use <|>; -//- /other_crate/lib.rs +//- /other_crate/lib.rs crate:other_crate // nothing here "#, expect![[r#" @@ -350,10 +350,10 @@ fn foo() { fn completes_prelude() { check( r#" -//- /main.rs +//- /main.rs crate:main deps:std fn foo() { let x: <|> } -//- /std/lib.rs +//- /std/lib.rs crate:std #[prelude_import] use prelude::*; @@ -371,16 +371,16 @@ mod prelude { struct Option; } fn completes_std_prelude_if_core_is_defined() { check( r#" -//- /main.rs +//- /main.rs crate:main deps:core,std fn foo() { let x: <|> } -//- /core/lib.rs +//- /core/lib.rs crate:core #[prelude_import] use prelude::*; mod prelude { struct Option; } -//- /std/lib.rs +//- /std/lib.rs crate:std deps:core #[prelude_import] use prelude::*; diff --git a/crates/ide/src/completion/presentation.rs b/crates/ide/src/completion/presentation.rs index 987cbfa7a..a5172b87e 100644 --- a/crates/ide/src/completion/presentation.rs +++ b/crates/ide/src/completion/presentation.rs @@ -1172,9 +1172,9 @@ fn foo(xs: Vec) check_edit( "frobnicate!", r#" -//- /main.rs +//- /main.rs crate:main deps:foo use foo::<|>; -//- /foo/lib.rs +//- /foo/lib.rs crate:foo #[macro_export] macro_rules frobnicate { () => () } "#, diff --git a/crates/ide/src/diagnostics.rs b/crates/ide/src/diagnostics.rs index dc815a483..906f72a42 100644 --- a/crates/ide/src/diagnostics.rs +++ b/crates/ide/src/diagnostics.rs @@ -219,7 +219,7 @@ mod tests { use test_utils::assert_eq_text; use crate::{ - mock_analysis::{analysis_and_position, single_file, MockAnalysis}, + mock_analysis::{analysis_and_position, many_files, single_file}, DiagnosticsConfig, }; @@ -282,9 +282,7 @@ mod tests { /// Takes a multi-file input fixture with annotated cursor position and checks that no diagnostics /// apply to the file containing the cursor. fn check_no_diagnostics(ra_fixture: &str) { - let mock = MockAnalysis::with_files(ra_fixture); - let files = mock.files().map(|(it, _)| it).collect::>(); - let analysis = mock.analysis(); + let (analysis, files) = many_files(ra_fixture); let diagnostics = files .into_iter() .flat_map(|file_id| { @@ -304,7 +302,7 @@ mod tests { fn test_wrap_return_type() { check_fix( r#" -//- /main.rs +//- /main.rs crate:main deps:core use core::result::Result::{self, Ok, Err}; fn div(x: i32, y: i32) -> Result { @@ -313,7 +311,7 @@ fn div(x: i32, y: i32) -> Result { } x / y<|> } -//- /core/lib.rs +//- /core/lib.rs crate:core pub mod result { pub enum Result { Ok(T), Err(E) } } @@ -335,7 +333,7 @@ fn div(x: i32, y: i32) -> Result { fn test_wrap_return_type_handles_generic_functions() { check_fix( r#" -//- /main.rs +//- /main.rs crate:main deps:core use core::result::Result::{self, Ok, Err}; fn div(x: T) -> Result { @@ -344,7 +342,7 @@ fn div(x: T) -> Result { } <|>x } -//- /core/lib.rs +//- /core/lib.rs crate:core pub mod result { pub enum Result { Ok(T), Err(E) } } @@ -366,7 +364,7 @@ fn div(x: T) -> Result { fn test_wrap_return_type_handles_type_aliases() { check_fix( r#" -//- /main.rs +//- /main.rs crate:main deps:core use core::result::Result::{self, Ok, Err}; type MyResult = Result; @@ -377,7 +375,7 @@ fn div(x: i32, y: i32) -> MyResult { } x <|>/ y } -//- /core/lib.rs +//- /core/lib.rs crate:core pub mod result { pub enum Result { Ok(T), Err(E) } } @@ -401,12 +399,12 @@ fn div(x: i32, y: i32) -> MyResult { fn test_wrap_return_type_not_applicable_when_expr_type_does_not_match_ok_type() { check_no_diagnostics( r#" -//- /main.rs +//- /main.rs crate:main deps:core use core::result::Result::{self, Ok, Err}; fn foo() -> Result<(), i32> { 0 } -//- /core/lib.rs +//- /core/lib.rs crate:core pub mod result { pub enum Result { Ok(T), Err(E) } } @@ -418,14 +416,14 @@ pub mod result { fn test_wrap_return_type_not_applicable_when_return_type_is_not_result() { check_no_diagnostics( r#" -//- /main.rs +//- /main.rs crate:main deps:core use core::result::Result::{self, Ok, Err}; enum SomeOtherEnum { Ok(i32), Err(String) } fn foo() -> SomeOtherEnum { 0 } -//- /core/lib.rs +//- /core/lib.rs crate:core pub mod result { pub enum Result { Ok(T), Err(E) } } @@ -567,7 +565,7 @@ fn test_fn() { file_system_edits: [ CreateFile { anchor: FileId( - 1, + 0, ), dst: "foo.rs", }, diff --git a/crates/ide/src/display/navigation_target.rs b/crates/ide/src/display/navigation_target.rs index 1ee80c2dd..bace2f3a3 100644 --- a/crates/ide/src/display/navigation_target.rs +++ b/crates/ide/src/display/navigation_target.rs @@ -439,7 +439,7 @@ fn foo() { enum FooInner { } } [ NavigationTarget { file_id: FileId( - 1, + 0, ), full_range: 0..17, focus_range: Some( @@ -455,7 +455,7 @@ fn foo() { enum FooInner { } } }, NavigationTarget { file_id: FileId( - 1, + 0, ), full_range: 29..46, focus_range: Some( diff --git a/crates/ide/src/goto_definition.rs b/crates/ide/src/goto_definition.rs index 15e9b7fad..5fd2d1e9a 100644 --- a/crates/ide/src/goto_definition.rs +++ b/crates/ide/src/goto_definition.rs @@ -103,12 +103,11 @@ mod tests { use base_db::FileRange; use syntax::{TextRange, TextSize}; - use crate::mock_analysis::MockAnalysis; + use crate::mock_analysis::analysis_and_annotations; fn check(ra_fixture: &str) { - let (mock, position) = MockAnalysis::with_files_and_position(ra_fixture); - let (mut expected, data) = mock.annotation(); - let analysis = mock.analysis(); + let (analysis, position, mut annotations) = analysis_and_annotations(ra_fixture); + let (mut expected, data) = annotations.pop().unwrap(); match data.as_str() { "" => (), "file" => { @@ -133,9 +132,9 @@ mod tests { fn goto_def_for_extern_crate() { check( r#" - //- /main.rs + //- /main.rs crate:main deps:std extern crate std<|>; - //- /std/lib.rs + //- /std/lib.rs crate:std // empty //^ file "#, @@ -146,9 +145,9 @@ mod tests { fn goto_def_for_renamed_extern_crate() { check( r#" - //- /main.rs + //- /main.rs crate:main deps:std extern crate std as abc<|>; - //- /std/lib.rs + //- /std/lib.rs crate:std // empty //^ file "#, @@ -342,10 +341,10 @@ fn bar() { fn goto_def_for_use_alias() { check( r#" -//- /lib.rs +//- /lib.rs crate:main deps:foo use foo as bar<|>; -//- /foo/lib.rs +//- /foo/lib.rs crate:foo // empty //^ file "#, @@ -356,10 +355,10 @@ use foo as bar<|>; fn goto_def_for_use_alias_foo_macro() { check( r#" -//- /lib.rs +//- /lib.rs crate:main deps:foo use foo::foo as bar<|>; -//- /foo/lib.rs +//- /foo/lib.rs crate:foo #[macro_export] macro_rules! foo { () => { () } } //^^^ @@ -371,7 +370,6 @@ macro_rules! foo { () => { () } } fn goto_def_for_methods() { check( r#" -//- /lib.rs struct Foo; impl Foo { fn frobnicate(&self) { } diff --git a/crates/ide/src/goto_implementation.rs b/crates/ide/src/goto_implementation.rs index f503f4ec5..a88854d05 100644 --- a/crates/ide/src/goto_implementation.rs +++ b/crates/ide/src/goto_implementation.rs @@ -76,12 +76,10 @@ fn impls_for_trait( mod tests { use base_db::FileRange; - use crate::mock_analysis::MockAnalysis; + use crate::mock_analysis::analysis_and_annotations; fn check(ra_fixture: &str) { - let (mock, position) = MockAnalysis::with_files_and_position(ra_fixture); - let annotations = mock.annotations(); - let analysis = mock.analysis(); + let (analysis, position, annotations) = analysis_and_annotations(ra_fixture); let navs = analysis.goto_implementation(position).unwrap().unwrap().info; diff --git a/crates/ide/src/goto_type_definition.rs b/crates/ide/src/goto_type_definition.rs index 4a151b150..b55a2dbb1 100644 --- a/crates/ide/src/goto_type_definition.rs +++ b/crates/ide/src/goto_type_definition.rs @@ -56,13 +56,12 @@ fn pick_best(tokens: TokenAtOffset) -> Option { mod tests { use base_db::FileRange; - use crate::mock_analysis::MockAnalysis; + use crate::mock_analysis::analysis_and_annotations; fn check(ra_fixture: &str) { - let (mock, position) = MockAnalysis::with_files_and_position(ra_fixture); - let (expected, data) = mock.annotation(); + let (analysis, position, mut annotations) = analysis_and_annotations(ra_fixture); + let (expected, data) = annotations.pop().unwrap(); assert!(data.is_empty()); - let analysis = mock.analysis(); let mut navs = analysis.goto_type_definition(position).unwrap().unwrap().info; assert_eq!(navs.len(), 1); diff --git a/crates/ide/src/hover.rs b/crates/ide/src/hover.rs index bb9f12cd3..008061a39 100644 --- a/crates/ide/src/hover.rs +++ b/crates/ide/src/hover.rs @@ -1275,7 +1275,7 @@ fn bar() { fo<|>o(); } Implementaion( FilePosition { file_id: FileId( - 1, + 0, ), offset: 13, }, @@ -1289,9 +1289,9 @@ fn bar() { fo<|>o(); } fn test_hover_extern_crate() { check( r#" -//- /main.rs +//- /main.rs crate:main deps:std extern crate st<|>d; -//- /std/lib.rs +//- /std/lib.rs crate:std //! Standard library for this test //! //! Printed? @@ -1307,9 +1307,9 @@ extern crate st<|>d; ); check( r#" -//- /main.rs +//- /main.rs crate:main deps:std extern crate std as ab<|>c; -//- /std/lib.rs +//- /std/lib.rs crate:std //! Standard library for this test //! //! Printed? @@ -1989,7 +1989,7 @@ fn foo() { let bar = Bar; bar.fo<|>o(); } Implementaion( FilePosition { file_id: FileId( - 1, + 0, ), offset: 6, }, @@ -2008,7 +2008,7 @@ fn foo() { let bar = Bar; bar.fo<|>o(); } Implementaion( FilePosition { file_id: FileId( - 1, + 0, ), offset: 7, }, @@ -2027,7 +2027,7 @@ fn foo() { let bar = Bar; bar.fo<|>o(); } Implementaion( FilePosition { file_id: FileId( - 1, + 0, ), offset: 6, }, @@ -2046,7 +2046,7 @@ fn foo() { let bar = Bar; bar.fo<|>o(); } Implementaion( FilePosition { file_id: FileId( - 1, + 0, ), offset: 5, }, @@ -2069,7 +2069,7 @@ fn foo_<|>test() {} Runnable { nav: NavigationTarget { file_id: FileId( - 1, + 0, ), full_range: 0..24, focus_range: Some( @@ -2112,7 +2112,7 @@ mod tests<|> { Runnable { nav: NavigationTarget { file_id: FileId( - 1, + 0, ), full_range: 0..46, focus_range: Some( @@ -2151,7 +2151,7 @@ fn main() { let s<|>t = S{ f1:0 }; } mod_path: "test::S", nav: NavigationTarget { file_id: FileId( - 1, + 0, ), full_range: 0..19, focus_range: Some( @@ -2190,7 +2190,7 @@ fn main() { let s<|>t = S{ f1:Arg(0) }; } mod_path: "test::S", nav: NavigationTarget { file_id: FileId( - 1, + 0, ), full_range: 17..37, focus_range: Some( @@ -2209,7 +2209,7 @@ fn main() { let s<|>t = S{ f1:Arg(0) }; } mod_path: "test::Arg", nav: NavigationTarget { file_id: FileId( - 1, + 0, ), full_range: 0..16, focus_range: Some( @@ -2248,7 +2248,7 @@ fn main() { let s<|>t = S{ f1: S{ f1: Arg(0) } }; } mod_path: "test::S", nav: NavigationTarget { file_id: FileId( - 1, + 0, ), full_range: 17..37, focus_range: Some( @@ -2267,7 +2267,7 @@ fn main() { let s<|>t = S{ f1: S{ f1: Arg(0) } }; } mod_path: "test::Arg", nav: NavigationTarget { file_id: FileId( - 1, + 0, ), full_range: 0..16, focus_range: Some( @@ -2309,7 +2309,7 @@ fn main() { let s<|>t = (A(1), B(2), M::C(3) ); } mod_path: "test::A", nav: NavigationTarget { file_id: FileId( - 1, + 0, ), full_range: 0..14, focus_range: Some( @@ -2328,7 +2328,7 @@ fn main() { let s<|>t = (A(1), B(2), M::C(3) ); } mod_path: "test::B", nav: NavigationTarget { file_id: FileId( - 1, + 0, ), full_range: 15..29, focus_range: Some( @@ -2347,7 +2347,7 @@ fn main() { let s<|>t = (A(1), B(2), M::C(3) ); } mod_path: "test::M::C", nav: NavigationTarget { file_id: FileId( - 1, + 0, ), full_range: 42..60, focus_range: Some( @@ -2386,7 +2386,7 @@ fn main() { let s<|>t = foo(); } mod_path: "test::Foo", nav: NavigationTarget { file_id: FileId( - 1, + 0, ), full_range: 0..12, focus_range: Some( @@ -2426,7 +2426,7 @@ fn main() { let s<|>t = foo(); } mod_path: "test::Foo", nav: NavigationTarget { file_id: FileId( - 1, + 0, ), full_range: 0..15, focus_range: Some( @@ -2445,7 +2445,7 @@ fn main() { let s<|>t = foo(); } mod_path: "test::S", nav: NavigationTarget { file_id: FileId( - 1, + 0, ), full_range: 16..25, focus_range: Some( @@ -2485,7 +2485,7 @@ fn main() { let s<|>t = foo(); } mod_path: "test::Foo", nav: NavigationTarget { file_id: FileId( - 1, + 0, ), full_range: 0..12, focus_range: Some( @@ -2504,7 +2504,7 @@ fn main() { let s<|>t = foo(); } mod_path: "test::Bar", nav: NavigationTarget { file_id: FileId( - 1, + 0, ), full_range: 13..25, focus_range: Some( @@ -2547,7 +2547,7 @@ fn main() { let s<|>t = foo(); } mod_path: "test::Foo", nav: NavigationTarget { file_id: FileId( - 1, + 0, ), full_range: 0..15, focus_range: Some( @@ -2566,7 +2566,7 @@ fn main() { let s<|>t = foo(); } mod_path: "test::Bar", nav: NavigationTarget { file_id: FileId( - 1, + 0, ), full_range: 16..31, focus_range: Some( @@ -2585,7 +2585,7 @@ fn main() { let s<|>t = foo(); } mod_path: "test::S1", nav: NavigationTarget { file_id: FileId( - 1, + 0, ), full_range: 32..44, focus_range: Some( @@ -2604,7 +2604,7 @@ fn main() { let s<|>t = foo(); } mod_path: "test::S2", nav: NavigationTarget { file_id: FileId( - 1, + 0, ), full_range: 45..57, focus_range: Some( @@ -2641,7 +2641,7 @@ fn foo(ar<|>g: &impl Foo) {} mod_path: "test::Foo", nav: NavigationTarget { file_id: FileId( - 1, + 0, ), full_range: 0..12, focus_range: Some( @@ -2681,7 +2681,7 @@ fn foo(ar<|>g: &impl Foo + Bar) {} mod_path: "test::Foo", nav: NavigationTarget { file_id: FileId( - 1, + 0, ), full_range: 0..12, focus_range: Some( @@ -2700,7 +2700,7 @@ fn foo(ar<|>g: &impl Foo + Bar) {} mod_path: "test::Bar", nav: NavigationTarget { file_id: FileId( - 1, + 0, ), full_range: 13..28, focus_range: Some( @@ -2719,7 +2719,7 @@ fn foo(ar<|>g: &impl Foo + Bar) {} mod_path: "test::S", nav: NavigationTarget { file_id: FileId( - 1, + 0, ), full_range: 29..39, focus_range: Some( @@ -2764,7 +2764,7 @@ mod future { mod_path: "test::future::Future", nav: NavigationTarget { file_id: FileId( - 1, + 0, ), full_range: 101..163, focus_range: Some( @@ -2783,7 +2783,7 @@ mod future { mod_path: "test::S", nav: NavigationTarget { file_id: FileId( - 1, + 0, ), full_range: 0..9, focus_range: Some( @@ -2821,7 +2821,7 @@ fn foo(ar<|>g: &impl Foo) {} mod_path: "test::Foo", nav: NavigationTarget { file_id: FileId( - 1, + 0, ), full_range: 0..15, focus_range: Some( @@ -2840,7 +2840,7 @@ fn foo(ar<|>g: &impl Foo) {} mod_path: "test::S", nav: NavigationTarget { file_id: FileId( - 1, + 0, ), full_range: 16..27, focus_range: Some( @@ -2883,7 +2883,7 @@ fn main() { let s<|>t = foo(); } mod_path: "test::B", nav: NavigationTarget { file_id: FileId( - 1, + 0, ), full_range: 42..55, focus_range: Some( @@ -2902,7 +2902,7 @@ fn main() { let s<|>t = foo(); } mod_path: "test::Foo", nav: NavigationTarget { file_id: FileId( - 1, + 0, ), full_range: 0..12, focus_range: Some( @@ -2939,7 +2939,7 @@ fn foo(ar<|>g: &dyn Foo) {} mod_path: "test::Foo", nav: NavigationTarget { file_id: FileId( - 1, + 0, ), full_range: 0..12, focus_range: Some( @@ -2977,7 +2977,7 @@ fn foo(ar<|>g: &dyn Foo) {} mod_path: "test::Foo", nav: NavigationTarget { file_id: FileId( - 1, + 0, ), full_range: 0..15, focus_range: Some( @@ -2996,7 +2996,7 @@ fn foo(ar<|>g: &dyn Foo) {} mod_path: "test::S", nav: NavigationTarget { file_id: FileId( - 1, + 0, ), full_range: 16..27, focus_range: Some( @@ -3037,7 +3037,7 @@ fn foo(a<|>rg: &impl ImplTrait>>>) {} mod_path: "test::ImplTrait", nav: NavigationTarget { file_id: FileId( - 1, + 0, ), full_range: 0..21, focus_range: Some( @@ -3056,7 +3056,7 @@ fn foo(a<|>rg: &impl ImplTrait>>>) {} mod_path: "test::B", nav: NavigationTarget { file_id: FileId( - 1, + 0, ), full_range: 43..57, focus_range: Some( @@ -3075,7 +3075,7 @@ fn foo(a<|>rg: &impl ImplTrait>>>) {} mod_path: "test::DynTrait", nav: NavigationTarget { file_id: FileId( - 1, + 0, ), full_range: 22..42, focus_range: Some( @@ -3094,7 +3094,7 @@ fn foo(a<|>rg: &impl ImplTrait>>>) {} mod_path: "test::S", nav: NavigationTarget { file_id: FileId( - 1, + 0, ), full_range: 58..69, focus_range: Some( @@ -3142,7 +3142,7 @@ fn main() { let s<|>t = test().get(); } mod_path: "test::Foo", nav: NavigationTarget { file_id: FileId( - 1, + 0, ), full_range: 0..62, focus_range: Some( diff --git a/crates/ide/src/mock_analysis.rs b/crates/ide/src/mock_analysis.rs index 6812db9b9..838547599 100644 --- a/crates/ide/src/mock_analysis.rs +++ b/crates/ide/src/mock_analysis.rs @@ -1,174 +1,73 @@ //! FIXME: write short doc here -use std::sync::Arc; -use base_db::{CrateName, FileSet, SourceRoot, VfsPath}; -use cfg::CfgOptions; -use test_utils::{ - extract_annotations, extract_range_or_offset, Fixture, RangeOrOffset, CURSOR_MARKER, -}; +use base_db::fixture::ChangeFixture; +use test_utils::{extract_annotations, RangeOrOffset}; -use crate::{Analysis, AnalysisHost, Change, CrateGraph, Edition, FileId, FilePosition, FileRange}; - -/// Mock analysis is used in test to bootstrap an AnalysisHost/Analysis -/// from a set of in-memory files. -#[derive(Debug, Default)] -pub(crate) struct MockAnalysis { - files: Vec, -} - -impl MockAnalysis { - /// Creates `MockAnalysis` using a fixture data in the following format: - /// - /// ```not_rust - /// //- /main.rs - /// mod foo; - /// fn main() {} - /// - /// //- /foo.rs - /// struct Baz; - /// ``` - pub(crate) fn with_files(ra_fixture: &str) -> MockAnalysis { - let (res, pos) = MockAnalysis::with_fixture(ra_fixture); - assert!(pos.is_none()); - res - } - - /// Same as `with_files`, but requires that a single file contains a `<|>` marker, - /// whose position is also returned. - pub(crate) fn with_files_and_position(fixture: &str) -> (MockAnalysis, FilePosition) { - let (res, position) = MockAnalysis::with_fixture(fixture); - let (file_id, range_or_offset) = position.expect("expected a marker (<|>)"); - let offset = match range_or_offset { - RangeOrOffset::Range(_) => panic!(), - RangeOrOffset::Offset(it) => it, - }; - (res, FilePosition { file_id, offset }) - } - - fn with_fixture(fixture: &str) -> (MockAnalysis, Option<(FileId, RangeOrOffset)>) { - let mut position = None; - let mut res = MockAnalysis::default(); - for mut entry in Fixture::parse(fixture) { - if entry.text.contains(CURSOR_MARKER) { - assert!(position.is_none(), "only one marker (<|>) per fixture is allowed"); - let (range_or_offset, text) = extract_range_or_offset(&entry.text); - entry.text = text; - let file_id = res.add_file_fixture(entry); - position = Some((file_id, range_or_offset)); - } else { - res.add_file_fixture(entry); - } - } - (res, position) - } - - fn add_file_fixture(&mut self, fixture: Fixture) -> FileId { - let file_id = FileId((self.files.len() + 1) as u32); - self.files.push(fixture); - file_id - } - - pub(crate) fn id_of(&self, path: &str) -> FileId { - let (file_id, _) = - self.files().find(|(_, data)| path == data.path).expect("no file in this mock"); - file_id - } - pub(crate) fn annotations(&self) -> Vec<(FileRange, String)> { - self.files() - .flat_map(|(file_id, fixture)| { - let annotations = extract_annotations(&fixture.text); - annotations - .into_iter() - .map(move |(range, data)| (FileRange { file_id, range }, data)) - }) - .collect() - } - pub(crate) fn files(&self) -> impl Iterator + '_ { - self.files.iter().enumerate().map(|(idx, fixture)| (FileId(idx as u32 + 1), fixture)) - } - pub(crate) fn annotation(&self) -> (FileRange, String) { - let mut all = self.annotations(); - assert_eq!(all.len(), 1); - all.pop().unwrap() - } - pub(crate) fn analysis_host(self) -> AnalysisHost { - let mut host = AnalysisHost::default(); - let mut change = Change::new(); - let mut file_set = FileSet::default(); - let mut crate_graph = CrateGraph::default(); - let mut root_crate = None; - for (i, data) in self.files.into_iter().enumerate() { - let path = data.path; - assert!(path.starts_with('/')); - - let mut cfg = CfgOptions::default(); - data.cfg_atoms.iter().for_each(|it| cfg.insert_atom(it.into())); - data.cfg_key_values.iter().for_each(|(k, v)| cfg.insert_key_value(k.into(), v.into())); - let edition: Edition = - data.edition.and_then(|it| it.parse().ok()).unwrap_or(Edition::Edition2018); - - let file_id = FileId(i as u32 + 1); - let env = data.env.into_iter().collect(); - if path == "/lib.rs" || path == "/main.rs" { - root_crate = Some(crate_graph.add_crate_root( - file_id, - edition, - Some("test".to_string()), - cfg, - env, - Default::default(), - )); - } else if path.ends_with("/lib.rs") { - let base = &path[..path.len() - "/lib.rs".len()]; - let crate_name = &base[base.rfind('/').unwrap() + '/'.len_utf8()..]; - let other_crate = crate_graph.add_crate_root( - file_id, - edition, - Some(crate_name.to_string()), - cfg, - env, - Default::default(), - ); - if let Some(root_crate) = root_crate { - crate_graph - .add_dep(root_crate, CrateName::new(crate_name).unwrap(), other_crate) - .unwrap(); - } - } - let path = VfsPath::new_virtual_path(path.to_string()); - file_set.insert(file_id, path); - change.change_file(file_id, Some(Arc::new(data.text).to_owned())); - } - change.set_crate_graph(crate_graph); - change.set_roots(vec![SourceRoot::new_local(file_set)]); - host.apply_change(change); - host - } - pub(crate) fn analysis(self) -> Analysis { - self.analysis_host().analysis() - } -} +use crate::{Analysis, AnalysisHost, FileId, FilePosition, FileRange}; /// Creates analysis from a multi-file fixture, returns positions marked with <|>. pub(crate) fn analysis_and_position(ra_fixture: &str) -> (Analysis, FilePosition) { - let (mock, position) = MockAnalysis::with_files_and_position(ra_fixture); - (mock.analysis(), position) + let mut host = AnalysisHost::default(); + let change_fixture = ChangeFixture::parse(ra_fixture); + host.db.apply_change(change_fixture.change); + let (file_id, range_or_offset) = change_fixture.file_position.expect("expected a marker (<|>)"); + let offset = match range_or_offset { + RangeOrOffset::Range(_) => panic!(), + RangeOrOffset::Offset(it) => it, + }; + (host.analysis(), FilePosition { file_id, offset }) } /// Creates analysis for a single file. pub(crate) fn single_file(ra_fixture: &str) -> (Analysis, FileId) { - let mock = MockAnalysis::with_files(ra_fixture); - let file_id = mock.id_of("/main.rs"); - (mock.analysis(), file_id) + let mut host = AnalysisHost::default(); + let change_fixture = ChangeFixture::parse(ra_fixture); + host.db.apply_change(change_fixture.change); + (host.analysis(), change_fixture.files[0]) +} + +/// Creates analysis for a single file. +pub(crate) fn many_files(ra_fixture: &str) -> (Analysis, Vec) { + let mut host = AnalysisHost::default(); + let change_fixture = ChangeFixture::parse(ra_fixture); + host.db.apply_change(change_fixture.change); + (host.analysis(), change_fixture.files) } /// Creates analysis for a single file, returns range marked with a pair of <|>. pub(crate) fn analysis_and_range(ra_fixture: &str) -> (Analysis, FileRange) { - let (res, position) = MockAnalysis::with_fixture(ra_fixture); - let (file_id, range_or_offset) = position.expect("expected a marker (<|>)"); + let mut host = AnalysisHost::default(); + let change_fixture = ChangeFixture::parse(ra_fixture); + host.db.apply_change(change_fixture.change); + let (file_id, range_or_offset) = change_fixture.file_position.expect("expected a marker (<|>)"); let range = match range_or_offset { RangeOrOffset::Range(it) => it, RangeOrOffset::Offset(_) => panic!(), }; - (res.analysis(), FileRange { file_id, range }) + (host.analysis(), FileRange { file_id, range }) +} + +/// Creates analysis from a multi-file fixture, returns positions marked with <|>. +pub(crate) fn analysis_and_annotations( + ra_fixture: &str, +) -> (Analysis, FilePosition, Vec<(FileRange, String)>) { + let mut host = AnalysisHost::default(); + let change_fixture = ChangeFixture::parse(ra_fixture); + host.db.apply_change(change_fixture.change); + let (file_id, range_or_offset) = change_fixture.file_position.expect("expected a marker (<|>)"); + let offset = match range_or_offset { + RangeOrOffset::Range(_) => panic!(), + RangeOrOffset::Offset(it) => it, + }; + + let annotations = change_fixture + .files + .iter() + .flat_map(|&file_id| { + let file_text = host.analysis().file_text(file_id).unwrap(); + let annotations = extract_annotations(&file_text); + annotations.into_iter().map(move |(range, data)| (FileRange { file_id, range }, data)) + }) + .collect(); + (host.analysis(), FilePosition { file_id, offset }, annotations) } diff --git a/crates/ide/src/parent_module.rs b/crates/ide/src/parent_module.rs index 68b107901..253454476 100644 --- a/crates/ide/src/parent_module.rs +++ b/crates/ide/src/parent_module.rs @@ -63,15 +63,9 @@ pub(crate) fn crate_for(db: &RootDatabase, file_id: FileId) -> Vec { #[cfg(test)] mod tests { - use base_db::Env; - use cfg::CfgOptions; use test_utils::mark; - use crate::{ - mock_analysis::{analysis_and_position, MockAnalysis}, - Change, CrateGraph, - Edition::Edition2018, - }; + use crate::mock_analysis::{analysis_and_position, single_file}; #[test] fn test_resolve_parent_module() { @@ -84,7 +78,7 @@ mod tests { ", ); let nav = analysis.parent_module(pos).unwrap().pop().unwrap(); - nav.assert_match("foo MODULE FileId(1) 0..8"); + nav.assert_match("foo MODULE FileId(0) 0..8"); } #[test] @@ -103,7 +97,7 @@ mod tests { ", ); let nav = analysis.parent_module(pos).unwrap().pop().unwrap(); - nav.assert_match("foo MODULE FileId(1) 0..8"); + nav.assert_match("foo MODULE FileId(0) 0..8"); } #[test] @@ -119,37 +113,19 @@ mod tests { ", ); let nav = analysis.parent_module(pos).unwrap().pop().unwrap(); - nav.assert_match("baz MODULE FileId(1) 32..44"); + nav.assert_match("baz MODULE FileId(0) 32..44"); } #[test] fn test_resolve_crate_root() { - let mock = MockAnalysis::with_files( + let (analysis, file_id) = single_file( r#" -//- /bar.rs +//- /main.rs mod foo; //- /foo.rs -// empty +<|> "#, ); - let root_file = mock.id_of("/bar.rs"); - let mod_file = mock.id_of("/foo.rs"); - let mut host = mock.analysis_host(); - assert!(host.analysis().crate_for(mod_file).unwrap().is_empty()); - - let mut crate_graph = CrateGraph::default(); - let crate_id = crate_graph.add_crate_root( - root_file, - Edition2018, - None, - CfgOptions::default(), - Env::default(), - Default::default(), - ); - let mut change = Change::new(); - change.set_crate_graph(crate_graph); - host.apply_change(change); - - assert_eq!(host.analysis().crate_for(mod_file).unwrap(), vec![crate_id]); + assert_eq!(analysis.crate_for(file_id).unwrap().len(), 1); } } diff --git a/crates/ide/src/references.rs b/crates/ide/src/references.rs index 1e3e944e9..157e0dc94 100644 --- a/crates/ide/src/references.rs +++ b/crates/ide/src/references.rs @@ -190,10 +190,11 @@ fn get_struct_def_name_for_struct_literal_search( #[cfg(test)] mod tests { + use base_db::FileId; use expect_test::{expect, Expect}; use stdx::format_to; - use crate::{mock_analysis::MockAnalysis, SearchScope}; + use crate::{mock_analysis::analysis_and_position, SearchScope}; #[test] fn test_struct_literal_after_space() { @@ -211,9 +212,9 @@ fn main() { } "#, expect![[r#" - Foo STRUCT FileId(1) 0..26 7..10 Other + Foo STRUCT FileId(0) 0..26 7..10 Other - FileId(1) 101..104 StructLiteral + FileId(0) 101..104 StructLiteral "#]], ); } @@ -229,10 +230,10 @@ struct Foo<|> {} } "#, expect![[r#" - Foo STRUCT FileId(1) 0..13 7..10 Other + Foo STRUCT FileId(0) 0..13 7..10 Other - FileId(1) 41..44 Other - FileId(1) 54..57 StructLiteral + FileId(0) 41..44 Other + FileId(0) 54..57 StructLiteral "#]], ); } @@ -248,9 +249,9 @@ struct Foo <|>{} } "#, expect![[r#" - Foo STRUCT FileId(1) 0..16 7..10 Other + Foo STRUCT FileId(0) 0..16 7..10 Other - FileId(1) 64..67 StructLiteral + FileId(0) 64..67 StructLiteral "#]], ); } @@ -267,9 +268,9 @@ fn main() { } "#, expect![[r#" - Foo STRUCT FileId(1) 0..16 7..10 Other + Foo STRUCT FileId(0) 0..16 7..10 Other - FileId(1) 54..57 StructLiteral + FileId(0) 54..57 StructLiteral "#]], ); } @@ -290,12 +291,12 @@ fn main() { i = 5; }"#, expect![[r#" - i IDENT_PAT FileId(1) 24..25 Other Write + i IDENT_PAT FileId(0) 24..25 Other Write - FileId(1) 50..51 Other Write - FileId(1) 54..55 Other Read - FileId(1) 76..77 Other Write - FileId(1) 94..95 Other Write + FileId(0) 50..51 Other Write + FileId(0) 54..55 Other Read + FileId(0) 76..77 Other Write + FileId(0) 94..95 Other Write "#]], ); } @@ -314,10 +315,10 @@ fn bar() { } "#, expect![[r#" - spam IDENT_PAT FileId(1) 19..23 Other + spam IDENT_PAT FileId(0) 19..23 Other - FileId(1) 34..38 Other Read - FileId(1) 41..45 Other Read + FileId(0) 34..38 Other Read + FileId(0) 41..45 Other Read "#]], ); } @@ -329,9 +330,9 @@ fn bar() { fn foo(i : u32) -> u32 { i<|> } "#, expect![[r#" - i IDENT_PAT FileId(1) 7..8 Other + i IDENT_PAT FileId(0) 7..8 Other - FileId(1) 25..26 Other Read + FileId(0) 25..26 Other Read "#]], ); } @@ -343,9 +344,9 @@ fn foo(i : u32) -> u32 { i<|> } fn foo(i<|> : u32) -> u32 { i } "#, expect![[r#" - i IDENT_PAT FileId(1) 7..8 Other + i IDENT_PAT FileId(0) 7..8 Other - FileId(1) 25..26 Other Read + FileId(0) 25..26 Other Read "#]], ); } @@ -364,9 +365,9 @@ fn main(s: Foo) { } "#, expect![[r#" - spam RECORD_FIELD FileId(1) 17..30 21..25 Other + spam RECORD_FIELD FileId(0) 17..30 21..25 Other - FileId(1) 67..71 Other Read + FileId(0) 67..71 Other Read "#]], ); } @@ -381,7 +382,7 @@ impl Foo { } "#, expect![[r#" - f FN FileId(1) 27..43 30..31 Other + f FN FileId(0) 27..43 30..31 Other "#]], ); @@ -398,7 +399,7 @@ enum Foo { } "#, expect![[r#" - B VARIANT FileId(1) 22..23 22..23 Other + B VARIANT FileId(0) 22..23 22..23 Other "#]], ); @@ -439,10 +440,10 @@ fn f() { } "#, expect![[r#" - Foo STRUCT FileId(2) 17..51 28..31 Other + Foo STRUCT FileId(1) 17..51 28..31 Other - FileId(1) 53..56 StructLiteral - FileId(3) 79..82 StructLiteral + FileId(0) 53..56 StructLiteral + FileId(2) 79..82 StructLiteral "#]], ); } @@ -469,9 +470,9 @@ pub struct Foo { } "#, expect![[r#" - foo SOURCE_FILE FileId(2) 0..35 Other + foo SOURCE_FILE FileId(1) 0..35 Other - FileId(1) 14..17 Other + FileId(0) 14..17 Other "#]], ); } @@ -497,10 +498,10 @@ pub(super) struct Foo<|> { } "#, expect![[r#" - Foo STRUCT FileId(3) 0..41 18..21 Other + Foo STRUCT FileId(2) 0..41 18..21 Other - FileId(2) 20..23 Other - FileId(2) 47..50 StructLiteral + FileId(1) 20..23 Other + FileId(1) 47..50 StructLiteral "#]], ); } @@ -525,20 +526,20 @@ pub(super) struct Foo<|> { code, None, expect![[r#" - quux FN FileId(1) 19..35 26..30 Other + quux FN FileId(0) 19..35 26..30 Other + FileId(1) 16..20 StructLiteral FileId(2) 16..20 StructLiteral - FileId(3) 16..20 StructLiteral "#]], ); check_with_scope( code, - Some("/bar.rs"), + Some(SearchScope::single_file(FileId(2))), expect![[r#" - quux FN FileId(1) 19..35 26..30 Other + quux FN FileId(0) 19..35 26..30 Other - FileId(3) 16..20 StructLiteral + FileId(2) 16..20 StructLiteral "#]], ); } @@ -556,10 +557,10 @@ fn foo() { } "#, expect![[r#" - m1 MACRO_CALL FileId(1) 0..46 29..31 Other + m1 MACRO_CALL FileId(0) 0..46 29..31 Other - FileId(1) 63..65 StructLiteral - FileId(1) 73..75 StructLiteral + FileId(0) 63..65 StructLiteral + FileId(0) 73..75 StructLiteral "#]], ); } @@ -574,10 +575,10 @@ fn foo() { } "#, expect![[r#" - i IDENT_PAT FileId(1) 23..24 Other Write + i IDENT_PAT FileId(0) 23..24 Other Write - FileId(1) 34..35 Other Write - FileId(1) 38..39 Other Read + FileId(0) 34..35 Other Write + FileId(0) 38..39 Other Read "#]], ); } @@ -596,10 +597,10 @@ fn foo() { } "#, expect![[r#" - f RECORD_FIELD FileId(1) 15..21 15..16 Other + f RECORD_FIELD FileId(0) 15..21 15..16 Other - FileId(1) 55..56 Other Read - FileId(1) 68..69 Other Write + FileId(0) 55..56 Other Read + FileId(0) 68..69 Other Write "#]], ); } @@ -614,9 +615,9 @@ fn foo() { } "#, expect![[r#" - i IDENT_PAT FileId(1) 19..20 Other + i IDENT_PAT FileId(0) 19..20 Other - FileId(1) 26..27 Other Write + FileId(0) 26..27 Other Write "#]], ); } @@ -638,9 +639,9 @@ fn main() { } "#, expect![[r#" - new FN FileId(1) 54..81 61..64 Other + new FN FileId(0) 54..81 61..64 Other - FileId(1) 126..129 StructLiteral + FileId(0) 126..129 StructLiteral "#]], ); } @@ -660,10 +661,10 @@ use crate::f; fn g() { f(); } "#, expect![[r#" - f FN FileId(1) 22..31 25..26 Other + f FN FileId(0) 22..31 25..26 Other - FileId(2) 11..12 Other - FileId(2) 24..25 StructLiteral + FileId(1) 11..12 Other + FileId(1) 24..25 StructLiteral "#]], ); } @@ -672,11 +673,8 @@ fn g() { f(); } check_with_scope(ra_fixture, None, expect) } - fn check_with_scope(ra_fixture: &str, search_scope: Option<&str>, expect: Expect) { - let (mock_analysis, pos) = MockAnalysis::with_files_and_position(ra_fixture); - let search_scope = - search_scope.map(|path| SearchScope::single_file(mock_analysis.id_of(path))); - let analysis = mock_analysis.analysis(); + fn check_with_scope(ra_fixture: &str, search_scope: Option, expect: Expect) { + let (analysis, pos) = analysis_and_position(ra_fixture); let refs = analysis.find_all_refs(pos, search_scope).unwrap().unwrap(); let mut actual = String::new(); diff --git a/crates/ide/src/references/rename.rs b/crates/ide/src/references/rename.rs index 301629763..366527070 100644 --- a/crates/ide/src/references/rename.rs +++ b/crates/ide/src/references/rename.rs @@ -602,7 +602,7 @@ mod foo<|>; source_file_edits: [ SourceFileEdit { file_id: FileId( - 2, + 1, ), edit: TextEdit { indels: [ @@ -617,10 +617,10 @@ mod foo<|>; file_system_edits: [ MoveFile { src: FileId( - 3, + 2, ), anchor: FileId( - 3, + 2, ), dst: "foo2.rs", }, @@ -655,7 +655,7 @@ use crate::foo<|>::FooContent; source_file_edits: [ SourceFileEdit { file_id: FileId( - 1, + 0, ), edit: TextEdit { indels: [ @@ -668,7 +668,7 @@ use crate::foo<|>::FooContent; }, SourceFileEdit { file_id: FileId( - 3, + 2, ), edit: TextEdit { indels: [ @@ -683,10 +683,10 @@ use crate::foo<|>::FooContent; file_system_edits: [ MoveFile { src: FileId( - 2, + 1, ), anchor: FileId( - 2, + 1, ), dst: "quux.rs", }, @@ -715,7 +715,7 @@ mod fo<|>o; source_file_edits: [ SourceFileEdit { file_id: FileId( - 1, + 0, ), edit: TextEdit { indels: [ @@ -730,10 +730,10 @@ mod fo<|>o; file_system_edits: [ MoveFile { src: FileId( - 2, + 1, ), anchor: FileId( - 2, + 1, ), dst: "../foo2/mod.rs", }, @@ -763,7 +763,7 @@ mod outer { mod fo<|>o; } source_file_edits: [ SourceFileEdit { file_id: FileId( - 1, + 0, ), edit: TextEdit { indels: [ @@ -778,10 +778,10 @@ mod outer { mod fo<|>o; } file_system_edits: [ MoveFile { src: FileId( - 2, + 1, ), anchor: FileId( - 2, + 1, ), dst: "bar.rs", }, @@ -834,7 +834,7 @@ pub mod foo<|>; source_file_edits: [ SourceFileEdit { file_id: FileId( - 2, + 1, ), edit: TextEdit { indels: [ @@ -847,7 +847,7 @@ pub mod foo<|>; }, SourceFileEdit { file_id: FileId( - 1, + 0, ), edit: TextEdit { indels: [ @@ -862,10 +862,10 @@ pub mod foo<|>; file_system_edits: [ MoveFile { src: FileId( - 3, + 2, ), anchor: FileId( - 3, + 2, ), dst: "foo2.rs", }, diff --git a/crates/ide/src/runnables.rs b/crates/ide/src/runnables.rs index cfeff40c1..961066277 100644 --- a/crates/ide/src/runnables.rs +++ b/crates/ide/src/runnables.rs @@ -335,7 +335,7 @@ fn bench() {} Runnable { nav: NavigationTarget { file_id: FileId( - 1, + 0, ), full_range: 1..13, focus_range: Some( @@ -353,7 +353,7 @@ fn bench() {} Runnable { nav: NavigationTarget { file_id: FileId( - 1, + 0, ), full_range: 15..39, focus_range: Some( @@ -378,7 +378,7 @@ fn bench() {} Runnable { nav: NavigationTarget { file_id: FileId( - 1, + 0, ), full_range: 41..75, focus_range: Some( @@ -403,7 +403,7 @@ fn bench() {} Runnable { nav: NavigationTarget { file_id: FileId( - 1, + 0, ), full_range: 77..99, focus_range: Some( @@ -494,7 +494,7 @@ fn should_have_no_runnable_6() {} Runnable { nav: NavigationTarget { file_id: FileId( - 1, + 0, ), full_range: 1..13, focus_range: Some( @@ -512,7 +512,7 @@ fn should_have_no_runnable_6() {} Runnable { nav: NavigationTarget { file_id: FileId( - 1, + 0, ), full_range: 15..74, focus_range: None, @@ -532,7 +532,7 @@ fn should_have_no_runnable_6() {} Runnable { nav: NavigationTarget { file_id: FileId( - 1, + 0, ), full_range: 76..148, focus_range: None, @@ -552,7 +552,7 @@ fn should_have_no_runnable_6() {} Runnable { nav: NavigationTarget { file_id: FileId( - 1, + 0, ), full_range: 150..254, focus_range: None, @@ -596,7 +596,7 @@ impl Data { Runnable { nav: NavigationTarget { file_id: FileId( - 1, + 0, ), full_range: 1..13, focus_range: Some( @@ -614,7 +614,7 @@ impl Data { Runnable { nav: NavigationTarget { file_id: FileId( - 1, + 0, ), full_range: 44..98, focus_range: None, @@ -653,7 +653,7 @@ mod test_mod { Runnable { nav: NavigationTarget { file_id: FileId( - 1, + 0, ), full_range: 1..51, focus_range: Some( @@ -673,7 +673,7 @@ mod test_mod { Runnable { nav: NavigationTarget { file_id: FileId( - 1, + 0, ), full_range: 20..49, focus_range: Some( @@ -733,7 +733,7 @@ mod root_tests { Runnable { nav: NavigationTarget { file_id: FileId( - 1, + 0, ), full_range: 22..323, focus_range: Some( @@ -753,7 +753,7 @@ mod root_tests { Runnable { nav: NavigationTarget { file_id: FileId( - 1, + 0, ), full_range: 51..192, focus_range: Some( @@ -773,7 +773,7 @@ mod root_tests { Runnable { nav: NavigationTarget { file_id: FileId( - 1, + 0, ), full_range: 84..126, focus_range: Some( @@ -798,7 +798,7 @@ mod root_tests { Runnable { nav: NavigationTarget { file_id: FileId( - 1, + 0, ), full_range: 140..182, focus_range: Some( @@ -823,7 +823,7 @@ mod root_tests { Runnable { nav: NavigationTarget { file_id: FileId( - 1, + 0, ), full_range: 202..286, focus_range: Some( @@ -843,7 +843,7 @@ mod root_tests { Runnable { nav: NavigationTarget { file_id: FileId( - 1, + 0, ), full_range: 235..276, focus_range: Some( @@ -886,7 +886,7 @@ fn test_foo1() {} Runnable { nav: NavigationTarget { file_id: FileId( - 1, + 0, ), full_range: 1..50, focus_range: Some( @@ -934,7 +934,7 @@ fn test_foo1() {} Runnable { nav: NavigationTarget { file_id: FileId( - 1, + 0, ), full_range: 1..72, focus_range: Some( diff --git a/crates/ide/src/syntax_highlighting/tests.rs b/crates/ide/src/syntax_highlighting/tests.rs index 211e62ea1..eaa4e163e 100644 --- a/crates/ide/src/syntax_highlighting/tests.rs +++ b/crates/ide/src/syntax_highlighting/tests.rs @@ -462,12 +462,12 @@ macro_rules! noop { fn test_extern_crate() { check_highlighting( r#" - //- /main.rs + //- /main.rs crate:main deps:std,alloc extern crate std; extern crate alloc as abc; - //- /std/lib.rs + //- /std/lib.rs crate:std pub struct S; - //- /alloc/lib.rs + //- /alloc/lib.rs crate:alloc pub struct A "#, expect_file!["./test_data/highlight_extern_crate.html"], -- cgit v1.2.3 From b06259673f9b535a63c0cabf4eeb935ff73d86d0 Mon Sep 17 00:00:00 2001 From: Aleksey Kladov Date: Fri, 2 Oct 2020 17:34:31 +0200 Subject: rename mock_analysis -> fixture --- crates/ide/src/call_hierarchy.rs | 4 +- crates/ide/src/call_info.rs | 4 +- crates/ide/src/completion.rs | 4 +- crates/ide/src/completion/test_utils.rs | 9 ++-- crates/ide/src/diagnostics.rs | 15 +++--- crates/ide/src/display/navigation_target.rs | 6 +-- crates/ide/src/expand_macro.rs | 4 +- crates/ide/src/extend_selection.rs | 4 +- crates/ide/src/fixture.rs | 70 +++++++++++++++++++++++++++ crates/ide/src/fn_references.rs | 10 ++-- crates/ide/src/goto_definition.rs | 4 +- crates/ide/src/goto_implementation.rs | 4 +- crates/ide/src/goto_type_definition.rs | 4 +- crates/ide/src/hover.rs | 16 +++---- crates/ide/src/inlay_hints.rs | 6 +-- crates/ide/src/lib.rs | 2 +- crates/ide/src/mock_analysis.rs | 73 ----------------------------- crates/ide/src/parent_module.rs | 10 ++-- crates/ide/src/references.rs | 4 +- crates/ide/src/references/rename.rs | 8 ++-- crates/ide/src/runnables.rs | 4 +- crates/ide/src/syntax_highlighting/tests.rs | 10 ++-- crates/ide/src/syntax_tree.rs | 16 +++---- crates/ide/src/typing/on_enter.rs | 4 +- 24 files changed, 143 insertions(+), 152 deletions(-) create mode 100644 crates/ide/src/fixture.rs delete mode 100644 crates/ide/src/mock_analysis.rs diff --git a/crates/ide/src/call_hierarchy.rs b/crates/ide/src/call_hierarchy.rs index 0fb49de71..d2cf2cc7d 100644 --- a/crates/ide/src/call_hierarchy.rs +++ b/crates/ide/src/call_hierarchy.rs @@ -139,7 +139,7 @@ impl CallLocations { mod tests { use base_db::FilePosition; - use crate::mock_analysis::analysis_and_position; + use crate::fixture; fn check_hierarchy( ra_fixture: &str, @@ -147,7 +147,7 @@ mod tests { expected_incoming: &[&str], expected_outgoing: &[&str], ) { - let (analysis, pos) = analysis_and_position(ra_fixture); + let (analysis, pos) = fixture::position(ra_fixture); let mut navs = analysis.call_hierarchy(pos).unwrap().unwrap().info; assert_eq!(navs.len(), 1); diff --git a/crates/ide/src/call_info.rs b/crates/ide/src/call_info.rs index 7e99c6b72..d7b2b926e 100644 --- a/crates/ide/src/call_info.rs +++ b/crates/ide/src/call_info.rs @@ -232,10 +232,10 @@ mod tests { use expect_test::{expect, Expect}; use test_utils::mark; - use crate::mock_analysis::analysis_and_position; + use crate::fixture; fn check(ra_fixture: &str, expect: Expect) { - let (analysis, position) = analysis_and_position(ra_fixture); + let (analysis, position) = fixture::position(ra_fixture); let call_info = analysis.call_info(position).unwrap(); let actual = match call_info { Some(call_info) => { diff --git a/crates/ide/src/completion.rs b/crates/ide/src/completion.rs index daea2aa95..697f691b0 100644 --- a/crates/ide/src/completion.rs +++ b/crates/ide/src/completion.rs @@ -133,7 +133,7 @@ pub(crate) fn completions( #[cfg(test)] mod tests { use crate::completion::completion_config::CompletionConfig; - use crate::mock_analysis::analysis_and_position; + use crate::fixture; struct DetailAndDocumentation<'a> { detail: &'a str, @@ -141,7 +141,7 @@ mod tests { } fn check_detail_and_documentation(ra_fixture: &str, expected: DetailAndDocumentation) { - let (analysis, position) = analysis_and_position(ra_fixture); + let (analysis, position) = fixture::position(ra_fixture); let config = CompletionConfig::default(); let completions = analysis.completions(&config, position).unwrap().unwrap(); for item in completions { diff --git a/crates/ide/src/completion/test_utils.rs b/crates/ide/src/completion/test_utils.rs index 1452d7e9e..feb8cd2a6 100644 --- a/crates/ide/src/completion/test_utils.rs +++ b/crates/ide/src/completion/test_utils.rs @@ -8,8 +8,7 @@ use test_utils::assert_eq_text; use crate::{ completion::{completion_item::CompletionKind, CompletionConfig}, - mock_analysis::analysis_and_position, - CompletionItem, + fixture, CompletionItem, }; pub(crate) fn do_completion(code: &str, kind: CompletionKind) -> Vec { @@ -80,7 +79,7 @@ pub(crate) fn check_edit_with_config( ra_fixture_after: &str, ) { let ra_fixture_after = trim_indent(ra_fixture_after); - let (analysis, position) = analysis_and_position(ra_fixture_before); + let (analysis, position) = fixture::position(ra_fixture_before); let completions: Vec = analysis.completions(&config, position).unwrap().unwrap().into(); let (completion,) = completions @@ -94,7 +93,7 @@ pub(crate) fn check_edit_with_config( } pub(crate) fn check_pattern_is_applicable(code: &str, check: fn(SyntaxElement) -> bool) { - let (analysis, pos) = analysis_and_position(code); + let (analysis, pos) = fixture::position(code); analysis .with_db(|db| { let sema = Semantics::new(db); @@ -109,6 +108,6 @@ pub(crate) fn get_all_completion_items( config: CompletionConfig, code: &str, ) -> Vec { - let (analysis, position) = analysis_and_position(code); + let (analysis, position) = fixture::position(code); analysis.completions(&config, position).unwrap().unwrap().into() } diff --git a/crates/ide/src/diagnostics.rs b/crates/ide/src/diagnostics.rs index 906f72a42..f5d627b6e 100644 --- a/crates/ide/src/diagnostics.rs +++ b/crates/ide/src/diagnostics.rs @@ -218,10 +218,7 @@ mod tests { use stdx::trim_indent; use test_utils::assert_eq_text; - use crate::{ - mock_analysis::{analysis_and_position, many_files, single_file}, - DiagnosticsConfig, - }; + use crate::{fixture, DiagnosticsConfig}; /// Takes a multi-file input fixture with annotated cursor positions, /// and checks that: @@ -231,7 +228,7 @@ mod tests { fn check_fix(ra_fixture_before: &str, ra_fixture_after: &str) { let after = trim_indent(ra_fixture_after); - let (analysis, file_position) = analysis_and_position(ra_fixture_before); + let (analysis, file_position) = fixture::position(ra_fixture_before); let diagnostic = analysis .diagnostics(&DiagnosticsConfig::default(), file_position.file_id) .unwrap() @@ -260,7 +257,7 @@ mod tests { /// which has a fix that can apply to other files. fn check_apply_diagnostic_fix_in_other_file(ra_fixture_before: &str, ra_fixture_after: &str) { let ra_fixture_after = &trim_indent(ra_fixture_after); - let (analysis, file_pos) = analysis_and_position(ra_fixture_before); + let (analysis, file_pos) = fixture::position(ra_fixture_before); let current_file_id = file_pos.file_id; let diagnostic = analysis .diagnostics(&DiagnosticsConfig::default(), current_file_id) @@ -282,7 +279,7 @@ mod tests { /// Takes a multi-file input fixture with annotated cursor position and checks that no diagnostics /// apply to the file containing the cursor. fn check_no_diagnostics(ra_fixture: &str) { - let (analysis, files) = many_files(ra_fixture); + let (analysis, files) = fixture::files(ra_fixture); let diagnostics = files .into_iter() .flat_map(|file_id| { @@ -293,7 +290,7 @@ mod tests { } fn check_expect(ra_fixture: &str, expect: Expect) { - let (analysis, file_id) = single_file(ra_fixture); + let (analysis, file_id) = fixture::file(ra_fixture); let diagnostics = analysis.diagnostics(&DiagnosticsConfig::default(), file_id).unwrap(); expect.assert_debug_eq(&diagnostics) } @@ -785,7 +782,7 @@ struct Foo { let mut config = DiagnosticsConfig::default(); config.disabled.insert("unresolved-module".into()); - let (analysis, file_id) = single_file(r#"mod foo;"#); + let (analysis, file_id) = fixture::file(r#"mod foo;"#); let diagnostics = analysis.diagnostics(&config, file_id).unwrap(); assert!(diagnostics.is_empty()); diff --git a/crates/ide/src/display/navigation_target.rs b/crates/ide/src/display/navigation_target.rs index bace2f3a3..cf9d617dc 100644 --- a/crates/ide/src/display/navigation_target.rs +++ b/crates/ide/src/display/navigation_target.rs @@ -423,11 +423,11 @@ pub(crate) fn description_from_symbol(db: &RootDatabase, symbol: &FileSymbol) -> mod tests { use expect_test::expect; - use crate::{mock_analysis::single_file, Query}; + use crate::{fixture, Query}; #[test] fn test_nav_for_symbol() { - let (analysis, _) = single_file( + let (analysis, _) = fixture::file( r#" enum FooInner { } fn foo() { enum FooInner { } } @@ -478,7 +478,7 @@ fn foo() { enum FooInner { } } #[test] fn test_world_symbols_are_case_sensitive() { - let (analysis, _) = single_file( + let (analysis, _) = fixture::file( r#" fn foo() {} struct Foo; diff --git a/crates/ide/src/expand_macro.rs b/crates/ide/src/expand_macro.rs index 8a285bcf7..8d75e0f05 100644 --- a/crates/ide/src/expand_macro.rs +++ b/crates/ide/src/expand_macro.rs @@ -122,10 +122,10 @@ fn insert_whitespaces(syn: SyntaxNode) -> String { mod tests { use expect_test::{expect, Expect}; - use crate::mock_analysis::analysis_and_position; + use crate::fixture; fn check(ra_fixture: &str, expect: Expect) { - let (analysis, pos) = analysis_and_position(ra_fixture); + let (analysis, pos) = fixture::position(ra_fixture); let expansion = analysis.expand_macro(pos).unwrap().unwrap(); let actual = format!("{}\n{}", expansion.name, expansion.expansion); expect.assert_eq(&actual); diff --git a/crates/ide/src/extend_selection.rs b/crates/ide/src/extend_selection.rs index 34563a026..3ee0af8ad 100644 --- a/crates/ide/src/extend_selection.rs +++ b/crates/ide/src/extend_selection.rs @@ -315,12 +315,12 @@ fn adj_comments(comment: &ast::Comment, dir: Direction) -> ast::Comment { #[cfg(test)] mod tests { - use crate::mock_analysis::analysis_and_position; + use crate::fixture; use super::*; fn do_check(before: &str, afters: &[&str]) { - let (analysis, position) = analysis_and_position(&before); + let (analysis, position) = fixture::position(&before); let before = analysis.file_text(position.file_id).unwrap(); let range = TextRange::empty(position.offset); let mut frange = FileRange { file_id: position.file_id, range }; diff --git a/crates/ide/src/fixture.rs b/crates/ide/src/fixture.rs new file mode 100644 index 000000000..ed06689f0 --- /dev/null +++ b/crates/ide/src/fixture.rs @@ -0,0 +1,70 @@ +//! Utilities for creating `Analysis` instances for tests. +use base_db::fixture::ChangeFixture; +use test_utils::{extract_annotations, RangeOrOffset}; + +use crate::{Analysis, AnalysisHost, FileId, FilePosition, FileRange}; + +/// Creates analysis for a single file. +pub(crate) fn file(ra_fixture: &str) -> (Analysis, FileId) { + let mut host = AnalysisHost::default(); + let change_fixture = ChangeFixture::parse(ra_fixture); + host.db.apply_change(change_fixture.change); + (host.analysis(), change_fixture.files[0]) +} + +/// Creates analysis for many files. +pub(crate) fn files(ra_fixture: &str) -> (Analysis, Vec) { + let mut host = AnalysisHost::default(); + let change_fixture = ChangeFixture::parse(ra_fixture); + host.db.apply_change(change_fixture.change); + (host.analysis(), change_fixture.files) +} + +/// Creates analysis from a multi-file fixture, returns positions marked with <|>. +pub(crate) fn position(ra_fixture: &str) -> (Analysis, FilePosition) { + let mut host = AnalysisHost::default(); + let change_fixture = ChangeFixture::parse(ra_fixture); + host.db.apply_change(change_fixture.change); + let (file_id, range_or_offset) = change_fixture.file_position.expect("expected a marker (<|>)"); + let offset = match range_or_offset { + RangeOrOffset::Range(_) => panic!(), + RangeOrOffset::Offset(it) => it, + }; + (host.analysis(), FilePosition { file_id, offset }) +} + +/// Creates analysis for a single file, returns range marked with a pair of <|>. +pub(crate) fn range(ra_fixture: &str) -> (Analysis, FileRange) { + let mut host = AnalysisHost::default(); + let change_fixture = ChangeFixture::parse(ra_fixture); + host.db.apply_change(change_fixture.change); + let (file_id, range_or_offset) = change_fixture.file_position.expect("expected a marker (<|>)"); + let range = match range_or_offset { + RangeOrOffset::Range(it) => it, + RangeOrOffset::Offset(_) => panic!(), + }; + (host.analysis(), FileRange { file_id, range }) +} + +/// Creates analysis from a multi-file fixture, returns positions marked with <|>. +pub(crate) fn annotations(ra_fixture: &str) -> (Analysis, FilePosition, Vec<(FileRange, String)>) { + let mut host = AnalysisHost::default(); + let change_fixture = ChangeFixture::parse(ra_fixture); + host.db.apply_change(change_fixture.change); + let (file_id, range_or_offset) = change_fixture.file_position.expect("expected a marker (<|>)"); + let offset = match range_or_offset { + RangeOrOffset::Range(_) => panic!(), + RangeOrOffset::Offset(it) => it, + }; + + let annotations = change_fixture + .files + .iter() + .flat_map(|&file_id| { + let file_text = host.analysis().file_text(file_id).unwrap(); + let annotations = extract_annotations(&file_text); + annotations.into_iter().map(move |(range, data)| (FileRange { file_id, range }, data)) + }) + .collect(); + (host.analysis(), FilePosition { file_id, offset }, annotations) +} diff --git a/crates/ide/src/fn_references.rs b/crates/ide/src/fn_references.rs index 1989a562b..459f201ed 100644 --- a/crates/ide/src/fn_references.rs +++ b/crates/ide/src/fn_references.rs @@ -25,15 +25,14 @@ fn method_range(item: SyntaxNode, file_id: FileId) -> Option { #[cfg(test)] mod tests { - use crate::mock_analysis::analysis_and_position; + use crate::fixture; use crate::{FileRange, TextSize}; use std::ops::RangeInclusive; #[test] fn test_find_all_methods() { - let (analysis, pos) = analysis_and_position( + let (analysis, pos) = fixture::position( r#" - //- /lib.rs fn private_fn() {<|>} pub fn pub_fn() {} @@ -48,9 +47,8 @@ mod tests { #[test] fn test_find_trait_methods() { - let (analysis, pos) = analysis_and_position( + let (analysis, pos) = fixture::position( r#" - //- /lib.rs trait Foo { fn bar() {<|>} fn baz() {} @@ -64,7 +62,7 @@ mod tests { #[test] fn test_skip_tests() { - let (analysis, pos) = analysis_and_position( + let (analysis, pos) = fixture::position( r#" //- /lib.rs #[test] diff --git a/crates/ide/src/goto_definition.rs b/crates/ide/src/goto_definition.rs index 5fd2d1e9a..582bf4837 100644 --- a/crates/ide/src/goto_definition.rs +++ b/crates/ide/src/goto_definition.rs @@ -103,10 +103,10 @@ mod tests { use base_db::FileRange; use syntax::{TextRange, TextSize}; - use crate::mock_analysis::analysis_and_annotations; + use crate::fixture; fn check(ra_fixture: &str) { - let (analysis, position, mut annotations) = analysis_and_annotations(ra_fixture); + let (analysis, position, mut annotations) = fixture::annotations(ra_fixture); let (mut expected, data) = annotations.pop().unwrap(); match data.as_str() { "" => (), diff --git a/crates/ide/src/goto_implementation.rs b/crates/ide/src/goto_implementation.rs index a88854d05..6c586bbd1 100644 --- a/crates/ide/src/goto_implementation.rs +++ b/crates/ide/src/goto_implementation.rs @@ -76,10 +76,10 @@ fn impls_for_trait( mod tests { use base_db::FileRange; - use crate::mock_analysis::analysis_and_annotations; + use crate::fixture; fn check(ra_fixture: &str) { - let (analysis, position, annotations) = analysis_and_annotations(ra_fixture); + let (analysis, position, annotations) = fixture::annotations(ra_fixture); let navs = analysis.goto_implementation(position).unwrap().unwrap().info; diff --git a/crates/ide/src/goto_type_definition.rs b/crates/ide/src/goto_type_definition.rs index b55a2dbb1..6d0df04dd 100644 --- a/crates/ide/src/goto_type_definition.rs +++ b/crates/ide/src/goto_type_definition.rs @@ -56,10 +56,10 @@ fn pick_best(tokens: TokenAtOffset) -> Option { mod tests { use base_db::FileRange; - use crate::mock_analysis::analysis_and_annotations; + use crate::fixture; fn check(ra_fixture: &str) { - let (analysis, position, mut annotations) = analysis_and_annotations(ra_fixture); + let (analysis, position, mut annotations) = fixture::annotations(ra_fixture); let (expected, data) = annotations.pop().unwrap(); assert!(data.is_empty()); diff --git a/crates/ide/src/hover.rs b/crates/ide/src/hover.rs index 008061a39..9cf02f0a3 100644 --- a/crates/ide/src/hover.rs +++ b/crates/ide/src/hover.rs @@ -377,17 +377,17 @@ mod tests { use base_db::FileLoader; use expect_test::{expect, Expect}; - use crate::mock_analysis::analysis_and_position; + use crate::fixture; use super::*; fn check_hover_no_result(ra_fixture: &str) { - let (analysis, position) = analysis_and_position(ra_fixture); + let (analysis, position) = fixture::position(ra_fixture); assert!(analysis.hover(position, true).unwrap().is_none()); } fn check(ra_fixture: &str, expect: Expect) { - let (analysis, position) = analysis_and_position(ra_fixture); + let (analysis, position) = fixture::position(ra_fixture); let hover = analysis.hover(position, true).unwrap().unwrap(); let content = analysis.db.file_text(position.file_id); @@ -398,7 +398,7 @@ mod tests { } fn check_hover_no_links(ra_fixture: &str, expect: Expect) { - let (analysis, position) = analysis_and_position(ra_fixture); + let (analysis, position) = fixture::position(ra_fixture); let hover = analysis.hover(position, false).unwrap().unwrap(); let content = analysis.db.file_text(position.file_id); @@ -409,7 +409,7 @@ mod tests { } fn check_actions(ra_fixture: &str, expect: Expect) { - let (analysis, position) = analysis_and_position(ra_fixture); + let (analysis, position) = fixture::position(ra_fixture); let hover = analysis.hover(position, true).unwrap().unwrap(); expect.assert_debug_eq(&hover.info.actions) } @@ -963,7 +963,7 @@ impl Thing { "#]], ) } /* FIXME: revive these tests - let (analysis, position) = analysis_and_position( + let (analysis, position) = fixture::position( " struct Thing { x: u32 } impl Thing { @@ -977,7 +977,7 @@ impl Thing { let hover = analysis.hover(position).unwrap().unwrap(); assert_eq!(trim_markup(&hover.info.markup.as_str()), ("Thing")); - let (analysis, position) = analysis_and_position( + let (analysis, position) = fixture::position( " enum Thing { A } impl Thing { @@ -990,7 +990,7 @@ impl Thing { let hover = analysis.hover(position).unwrap().unwrap(); assert_eq!(trim_markup(&hover.info.markup.as_str()), ("enum Thing")); - let (analysis, position) = analysis_and_position( + let (analysis, position) = fixture::position( " enum Thing { A } impl Thing { diff --git a/crates/ide/src/inlay_hints.rs b/crates/ide/src/inlay_hints.rs index 583f39d85..0afe5f8fd 100644 --- a/crates/ide/src/inlay_hints.rs +++ b/crates/ide/src/inlay_hints.rs @@ -339,14 +339,14 @@ mod tests { use expect_test::{expect, Expect}; use test_utils::extract_annotations; - use crate::{inlay_hints::InlayHintsConfig, mock_analysis::single_file}; + use crate::{fixture, inlay_hints::InlayHintsConfig}; fn check(ra_fixture: &str) { check_with_config(InlayHintsConfig::default(), ra_fixture); } fn check_with_config(config: InlayHintsConfig, ra_fixture: &str) { - let (analysis, file_id) = single_file(ra_fixture); + let (analysis, file_id) = fixture::file(ra_fixture); let expected = extract_annotations(&*analysis.file_text(file_id).unwrap()); let inlay_hints = analysis.inlay_hints(file_id, &config).unwrap(); let actual = @@ -355,7 +355,7 @@ mod tests { } fn check_expect(config: InlayHintsConfig, ra_fixture: &str, expect: Expect) { - let (analysis, file_id) = single_file(ra_fixture); + let (analysis, file_id) = fixture::file(ra_fixture); let inlay_hints = analysis.inlay_hints(file_id, &config).unwrap(); expect.assert_debug_eq(&inlay_hints) } diff --git a/crates/ide/src/lib.rs b/crates/ide/src/lib.rs index 073b766a5..1aa673cf8 100644 --- a/crates/ide/src/lib.rs +++ b/crates/ide/src/lib.rs @@ -16,7 +16,7 @@ macro_rules! eprintln { } #[cfg(test)] -mod mock_analysis; +mod fixture; mod markup; mod prime_caches; diff --git a/crates/ide/src/mock_analysis.rs b/crates/ide/src/mock_analysis.rs deleted file mode 100644 index 838547599..000000000 --- a/crates/ide/src/mock_analysis.rs +++ /dev/null @@ -1,73 +0,0 @@ -//! FIXME: write short doc here - -use base_db::fixture::ChangeFixture; -use test_utils::{extract_annotations, RangeOrOffset}; - -use crate::{Analysis, AnalysisHost, FileId, FilePosition, FileRange}; - -/// Creates analysis from a multi-file fixture, returns positions marked with <|>. -pub(crate) fn analysis_and_position(ra_fixture: &str) -> (Analysis, FilePosition) { - let mut host = AnalysisHost::default(); - let change_fixture = ChangeFixture::parse(ra_fixture); - host.db.apply_change(change_fixture.change); - let (file_id, range_or_offset) = change_fixture.file_position.expect("expected a marker (<|>)"); - let offset = match range_or_offset { - RangeOrOffset::Range(_) => panic!(), - RangeOrOffset::Offset(it) => it, - }; - (host.analysis(), FilePosition { file_id, offset }) -} - -/// Creates analysis for a single file. -pub(crate) fn single_file(ra_fixture: &str) -> (Analysis, FileId) { - let mut host = AnalysisHost::default(); - let change_fixture = ChangeFixture::parse(ra_fixture); - host.db.apply_change(change_fixture.change); - (host.analysis(), change_fixture.files[0]) -} - -/// Creates analysis for a single file. -pub(crate) fn many_files(ra_fixture: &str) -> (Analysis, Vec) { - let mut host = AnalysisHost::default(); - let change_fixture = ChangeFixture::parse(ra_fixture); - host.db.apply_change(change_fixture.change); - (host.analysis(), change_fixture.files) -} - -/// Creates analysis for a single file, returns range marked with a pair of <|>. -pub(crate) fn analysis_and_range(ra_fixture: &str) -> (Analysis, FileRange) { - let mut host = AnalysisHost::default(); - let change_fixture = ChangeFixture::parse(ra_fixture); - host.db.apply_change(change_fixture.change); - let (file_id, range_or_offset) = change_fixture.file_position.expect("expected a marker (<|>)"); - let range = match range_or_offset { - RangeOrOffset::Range(it) => it, - RangeOrOffset::Offset(_) => panic!(), - }; - (host.analysis(), FileRange { file_id, range }) -} - -/// Creates analysis from a multi-file fixture, returns positions marked with <|>. -pub(crate) fn analysis_and_annotations( - ra_fixture: &str, -) -> (Analysis, FilePosition, Vec<(FileRange, String)>) { - let mut host = AnalysisHost::default(); - let change_fixture = ChangeFixture::parse(ra_fixture); - host.db.apply_change(change_fixture.change); - let (file_id, range_or_offset) = change_fixture.file_position.expect("expected a marker (<|>)"); - let offset = match range_or_offset { - RangeOrOffset::Range(_) => panic!(), - RangeOrOffset::Offset(it) => it, - }; - - let annotations = change_fixture - .files - .iter() - .flat_map(|&file_id| { - let file_text = host.analysis().file_text(file_id).unwrap(); - let annotations = extract_annotations(&file_text); - annotations.into_iter().map(move |(range, data)| (FileRange { file_id, range }, data)) - }) - .collect(); - (host.analysis(), FilePosition { file_id, offset }, annotations) -} diff --git a/crates/ide/src/parent_module.rs b/crates/ide/src/parent_module.rs index 253454476..ef94acfec 100644 --- a/crates/ide/src/parent_module.rs +++ b/crates/ide/src/parent_module.rs @@ -65,11 +65,11 @@ pub(crate) fn crate_for(db: &RootDatabase, file_id: FileId) -> Vec { mod tests { use test_utils::mark; - use crate::mock_analysis::{analysis_and_position, single_file}; + use crate::fixture::{self}; #[test] fn test_resolve_parent_module() { - let (analysis, pos) = analysis_and_position( + let (analysis, pos) = fixture::position( " //- /lib.rs mod foo; @@ -84,7 +84,7 @@ mod tests { #[test] fn test_resolve_parent_module_on_module_decl() { mark::check!(test_resolve_parent_module_on_module_decl); - let (analysis, pos) = analysis_and_position( + let (analysis, pos) = fixture::position( " //- /lib.rs mod foo; @@ -102,7 +102,7 @@ mod tests { #[test] fn test_resolve_parent_module_for_inline() { - let (analysis, pos) = analysis_and_position( + let (analysis, pos) = fixture::position( " //- /lib.rs mod foo { @@ -118,7 +118,7 @@ mod tests { #[test] fn test_resolve_crate_root() { - let (analysis, file_id) = single_file( + let (analysis, file_id) = fixture::file( r#" //- /main.rs mod foo; diff --git a/crates/ide/src/references.rs b/crates/ide/src/references.rs index 157e0dc94..e0830eb4f 100644 --- a/crates/ide/src/references.rs +++ b/crates/ide/src/references.rs @@ -194,7 +194,7 @@ mod tests { use expect_test::{expect, Expect}; use stdx::format_to; - use crate::{mock_analysis::analysis_and_position, SearchScope}; + use crate::{fixture, SearchScope}; #[test] fn test_struct_literal_after_space() { @@ -674,7 +674,7 @@ fn g() { f(); } } fn check_with_scope(ra_fixture: &str, search_scope: Option, expect: Expect) { - let (analysis, pos) = analysis_and_position(ra_fixture); + let (analysis, pos) = fixture::position(ra_fixture); let refs = analysis.find_all_refs(pos, search_scope).unwrap().unwrap(); let mut actual = String::new(); diff --git a/crates/ide/src/references/rename.rs b/crates/ide/src/references/rename.rs index 366527070..8cbe1ae5a 100644 --- a/crates/ide/src/references/rename.rs +++ b/crates/ide/src/references/rename.rs @@ -275,11 +275,11 @@ mod tests { use test_utils::{assert_eq_text, mark}; use text_edit::TextEdit; - use crate::{mock_analysis::analysis_and_position, FileId}; + use crate::{fixture, FileId}; fn check(new_name: &str, ra_fixture_before: &str, ra_fixture_after: &str) { let ra_fixture_after = &trim_indent(ra_fixture_after); - let (analysis, position) = analysis_and_position(ra_fixture_before); + let (analysis, position) = fixture::position(ra_fixture_before); let source_change = analysis.rename(position, new_name).unwrap(); let mut text_edit_builder = TextEdit::builder(); let mut file_id: Option = None; @@ -297,7 +297,7 @@ mod tests { } fn check_expect(new_name: &str, ra_fixture: &str, expect: Expect) { - let (analysis, position) = analysis_and_position(ra_fixture); + let (analysis, position) = fixture::position(ra_fixture); let source_change = analysis.rename(position, new_name).unwrap().unwrap(); expect.assert_debug_eq(&source_change) } @@ -314,7 +314,7 @@ mod tests { #[test] fn test_rename_to_invalid_identifier() { - let (analysis, position) = analysis_and_position(r#"fn main() { let i<|> = 1; }"#); + let (analysis, position) = fixture::position(r#"fn main() { let i<|> = 1; }"#); let new_name = "invalid!"; let source_change = analysis.rename(position, new_name).unwrap(); assert!(source_change.is_none()); diff --git a/crates/ide/src/runnables.rs b/crates/ide/src/runnables.rs index 961066277..752ef2f21 100644 --- a/crates/ide/src/runnables.rs +++ b/crates/ide/src/runnables.rs @@ -292,7 +292,7 @@ fn has_test_function_or_multiple_test_submodules(module: &ast::Module) -> bool { mod tests { use expect_test::{expect, Expect}; - use crate::mock_analysis::analysis_and_position; + use crate::fixture; use super::{RunnableAction, BENCH, BIN, DOCTEST, TEST}; @@ -302,7 +302,7 @@ mod tests { actions: &[&RunnableAction], expect: Expect, ) { - let (analysis, position) = analysis_and_position(ra_fixture); + let (analysis, position) = fixture::position(ra_fixture); let runnables = analysis.runnables(position.file_id).unwrap(); expect.assert_debug_eq(&runnables); assert_eq!( diff --git a/crates/ide/src/syntax_highlighting/tests.rs b/crates/ide/src/syntax_highlighting/tests.rs index eaa4e163e..694c4b7fa 100644 --- a/crates/ide/src/syntax_highlighting/tests.rs +++ b/crates/ide/src/syntax_highlighting/tests.rs @@ -3,7 +3,7 @@ use std::fs; use expect_test::{expect_file, ExpectFile}; use test_utils::project_dir; -use crate::{mock_analysis::single_file, FileRange, TextRange}; +use crate::{fixture, FileRange, TextRange}; #[test] fn test_highlighting() { @@ -178,7 +178,7 @@ fn accidentally_quadratic() { let file = project_dir().join("crates/syntax/test_data/accidentally_quadratic"); let src = fs::read_to_string(file).unwrap(); - let (analysis, file_id) = single_file(&src); + let (analysis, file_id) = fixture::file(&src); // let t = std::time::Instant::now(); let _ = analysis.highlight(file_id).unwrap(); @@ -187,7 +187,7 @@ fn accidentally_quadratic() { #[test] fn test_ranges() { - let (analysis, file_id) = single_file( + let (analysis, file_id) = fixture::file( r#" #[derive(Clone, Debug)] struct Foo { @@ -228,7 +228,7 @@ fn main() { #[test] fn ranges_sorted() { - let (analysis, file_id) = single_file( + let (analysis, file_id) = fixture::file( r#" #[foo(bar = "bar")] macro_rules! test {} @@ -479,7 +479,7 @@ fn test_extern_crate() { /// result as HTML, and compares it with the HTML file given as `snapshot`. /// Note that the `snapshot` file is overwritten by the rendered HTML. fn check_highlighting(ra_fixture: &str, expect: ExpectFile, rainbow: bool) { - let (analysis, file_id) = single_file(ra_fixture); + let (analysis, file_id) = fixture::file(ra_fixture); let actual_html = &analysis.highlight_as_html(file_id, rainbow).unwrap(); expect.assert_eq(actual_html) } diff --git a/crates/ide/src/syntax_tree.rs b/crates/ide/src/syntax_tree.rs index f80044959..0eed2dbd7 100644 --- a/crates/ide/src/syntax_tree.rs +++ b/crates/ide/src/syntax_tree.rs @@ -104,12 +104,12 @@ fn syntax_tree_for_token(node: &SyntaxToken, text_range: TextRange) -> Optionfn foo() {}<|>"#.trim()); + let (analysis, range) = fixture::range(r#"<|>fn foo() {}<|>"#.trim()); let syn = analysis.syntax_tree(range.file_id, Some(range.range)).unwrap(); assert_eq_text!( @@ -206,7 +206,7 @@ FN@0..11 .trim() ); - let (analysis, range) = analysis_and_range( + let (analysis, range) = fixture::range( r#"fn test() { <|>assert!(" fn foo() { @@ -242,7 +242,7 @@ EXPR_STMT@16..58 #[test] fn test_syntax_tree_inside_string() { - let (analysis, range) = analysis_and_range( + let (analysis, range) = fixture::range( r#"fn test() { assert!(" <|>fn foo() { @@ -276,7 +276,7 @@ SOURCE_FILE@0..12 ); // With a raw string - let (analysis, range) = analysis_and_range( + let (analysis, range) = fixture::range( r###"fn test() { assert!(r#" <|>fn foo() { @@ -310,7 +310,7 @@ SOURCE_FILE@0..12 ); // With a raw string - let (analysis, range) = analysis_and_range( + let (analysis, range) = fixture::range( r###"fn test() { assert!(r<|>#" fn foo() { diff --git a/crates/ide/src/typing/on_enter.rs b/crates/ide/src/typing/on_enter.rs index f7d46146c..a0dc4b9df 100644 --- a/crates/ide/src/typing/on_enter.rs +++ b/crates/ide/src/typing/on_enter.rs @@ -109,10 +109,10 @@ mod tests { use stdx::trim_indent; use test_utils::{assert_eq_text, mark}; - use crate::mock_analysis::analysis_and_position; + use crate::fixture; fn apply_on_enter(before: &str) -> Option { - let (analysis, position) = analysis_and_position(&before); + let (analysis, position) = fixture::position(&before); let result = analysis.on_enter(position).unwrap()?; let mut actual = analysis.file_text(position.file_id).unwrap().to_string(); -- cgit v1.2.3