mirror of
https://github.com/rust-lang/rust-analyzer
synced 2024-11-15 09:27:27 +00:00
Merge #6123
6123: Reduce duplication in fixtures r=matklad a=matklad
bors r+
🤖
Co-authored-by: Aleksey Kladov <aleksey.kladov@gmail.com>
This commit is contained in:
commit
673e1ddb9a
38 changed files with 564 additions and 669 deletions
97
crates/base_db/src/change.rs
Normal file
97
crates/base_db/src/change.rs
Normal file
|
@ -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<Vec<SourceRoot>>,
|
||||
pub files_changed: Vec<(FileId, Option<Arc<String>>)>,
|
||||
pub crate_graph: Option<CrateGraph>,
|
||||
}
|
||||
|
||||
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<SourceRoot>) {
|
||||
self.roots = Some(roots);
|
||||
}
|
||||
|
||||
pub fn change_file(&mut self, file_id: FileId, new_text: Option<Arc<String>>) {
|
||||
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
|
||||
}
|
||||
}
|
|
@ -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,95 @@ pub trait WithFixture: Default + SourceDatabaseExt + 'static {
|
|||
|
||||
impl<DB: SourceDatabaseExt + Default + 'static> WithFixture for DB {}
|
||||
|
||||
fn with_files(
|
||||
db: &mut dyn SourceDatabaseExt,
|
||||
fixture: &str,
|
||||
) -> (Option<(FileId, RangeOrOffset)>, Vec<FileId>) {
|
||||
let fixture = Fixture::parse(fixture);
|
||||
pub struct ChangeFixture {
|
||||
pub file_position: Option<(FileId, RangeOrOffset)>,
|
||||
pub files: Vec<FileId>,
|
||||
pub change: Change,
|
||||
}
|
||||
|
||||
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<FileId> = None;
|
||||
impl ChangeFixture {
|
||||
pub fn parse(ra_fixture: &str) -> ChangeFixture {
|
||||
let fixture = Fixture::parse(ra_fixture);
|
||||
let mut change = Change::new();
|
||||
|
||||
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 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<FileId> = None;
|
||||
let mut default_cfg = CfgOptions::default();
|
||||
|
||||
let mut file_position = None;
|
||||
let mut file_set = FileSet::default();
|
||||
let source_root_prefix = "/".to_string();
|
||||
let mut file_id = FileId(0);
|
||||
|
||||
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 mut file_position = None;
|
||||
|
||||
let meta = FileMeta::from(entry);
|
||||
assert!(meta.path.starts_with(&source_root_prefix));
|
||||
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()
|
||||
};
|
||||
|
||||
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,
|
||||
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);
|
||||
default_cfg = meta.cfg;
|
||||
}
|
||||
|
||||
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 crates.is_empty() {
|
||||
let crate_root = default_crate_root.unwrap();
|
||||
crate_graph.add_crate_root(
|
||||
crate_root,
|
||||
Edition::Edition2018,
|
||||
Some("test".to_string()),
|
||||
default_cfg,
|
||||
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);
|
||||
|
||||
ChangeFixture { file_position, files, change }
|
||||
}
|
||||
|
||||
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();
|
||||
}
|
||||
}
|
||||
|
||||
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 {
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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);
|
||||
|
@ -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]"],
|
||||
&[],
|
||||
);
|
||||
}
|
||||
|
|
|
@ -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) => {
|
||||
|
|
|
@ -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 {
|
||||
|
|
|
@ -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 {
|
||||
|
|
|
@ -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 <|>
|
||||
|
|
|
@ -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#"
|
||||
|
|
|
@ -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::*;
|
||||
|
||||
|
|
|
@ -1172,9 +1172,9 @@ fn foo(xs: Vec<i128>)
|
|||
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 { () => () }
|
||||
"#,
|
||||
|
|
|
@ -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<CompletionItem> {
|
||||
|
@ -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<CompletionItem> =
|
||||
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<CompletionItem> {
|
||||
let (analysis, position) = analysis_and_position(code);
|
||||
let (analysis, position) = fixture::position(code);
|
||||
analysis.completions(&config, position).unwrap().unwrap().into()
|
||||
}
|
||||
|
|
|
@ -218,10 +218,7 @@ mod tests {
|
|||
use stdx::trim_indent;
|
||||
use test_utils::assert_eq_text;
|
||||
|
||||
use crate::{
|
||||
mock_analysis::{analysis_and_position, single_file, MockAnalysis},
|
||||
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,9 +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 mock = MockAnalysis::with_files(ra_fixture);
|
||||
let files = mock.files().map(|(it, _)| it).collect::<Vec<_>>();
|
||||
let analysis = mock.analysis();
|
||||
let (analysis, files) = fixture::files(ra_fixture);
|
||||
let diagnostics = files
|
||||
.into_iter()
|
||||
.flat_map(|file_id| {
|
||||
|
@ -295,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)
|
||||
}
|
||||
|
@ -304,7 +299,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<i32, ()> {
|
||||
|
@ -313,7 +308,7 @@ fn div(x: i32, y: i32) -> Result<i32, ()> {
|
|||
}
|
||||
x / y<|>
|
||||
}
|
||||
//- /core/lib.rs
|
||||
//- /core/lib.rs crate:core
|
||||
pub mod result {
|
||||
pub enum Result<T, E> { Ok(T), Err(E) }
|
||||
}
|
||||
|
@ -335,7 +330,7 @@ fn div(x: i32, y: i32) -> Result<i32, ()> {
|
|||
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<T>(x: T) -> Result<T, i32> {
|
||||
|
@ -344,7 +339,7 @@ fn div<T>(x: T) -> Result<T, i32> {
|
|||
}
|
||||
<|>x
|
||||
}
|
||||
//- /core/lib.rs
|
||||
//- /core/lib.rs crate:core
|
||||
pub mod result {
|
||||
pub enum Result<T, E> { Ok(T), Err(E) }
|
||||
}
|
||||
|
@ -366,7 +361,7 @@ fn div<T>(x: T) -> Result<T, i32> {
|
|||
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<T> = Result<T, ()>;
|
||||
|
@ -377,7 +372,7 @@ fn div(x: i32, y: i32) -> MyResult<i32> {
|
|||
}
|
||||
x <|>/ y
|
||||
}
|
||||
//- /core/lib.rs
|
||||
//- /core/lib.rs crate:core
|
||||
pub mod result {
|
||||
pub enum Result<T, E> { Ok(T), Err(E) }
|
||||
}
|
||||
|
@ -401,12 +396,12 @@ fn div(x: i32, y: i32) -> MyResult<i32> {
|
|||
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<T, E> { Ok(T), Err(E) }
|
||||
}
|
||||
|
@ -418,14 +413,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<T, E> { Ok(T), Err(E) }
|
||||
}
|
||||
|
@ -567,7 +562,7 @@ fn test_fn() {
|
|||
file_system_edits: [
|
||||
CreateFile {
|
||||
anchor: FileId(
|
||||
1,
|
||||
0,
|
||||
),
|
||||
dst: "foo.rs",
|
||||
},
|
||||
|
@ -787,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());
|
||||
|
|
|
@ -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 { } }
|
||||
|
@ -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(
|
||||
|
@ -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;
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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 };
|
||||
|
|
70
crates/ide/src/fixture.rs
Normal file
70
crates/ide/src/fixture.rs
Normal file
|
@ -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<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)
|
||||
}
|
||||
|
||||
/// 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)
|
||||
}
|
|
@ -25,15 +25,14 @@ fn method_range(item: SyntaxNode, file_id: FileId) -> Option<FileRange> {
|
|||
|
||||
#[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]
|
||||
|
|
|
@ -103,12 +103,11 @@ mod tests {
|
|||
use base_db::FileRange;
|
||||
use syntax::{TextRange, TextSize};
|
||||
|
||||
use crate::mock_analysis::MockAnalysis;
|
||||
use crate::fixture;
|
||||
|
||||
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) = fixture::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) { }
|
||||
|
|
|
@ -76,12 +76,10 @@ fn impls_for_trait(
|
|||
mod tests {
|
||||
use base_db::FileRange;
|
||||
|
||||
use crate::mock_analysis::MockAnalysis;
|
||||
use crate::fixture;
|
||||
|
||||
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) = fixture::annotations(ra_fixture);
|
||||
|
||||
let navs = analysis.goto_implementation(position).unwrap().unwrap().info;
|
||||
|
||||
|
|
|
@ -56,13 +56,12 @@ fn pick_best(tokens: TokenAtOffset<SyntaxToken>) -> Option<SyntaxToken> {
|
|||
mod tests {
|
||||
use base_db::FileRange;
|
||||
|
||||
use crate::mock_analysis::MockAnalysis;
|
||||
use crate::fixture;
|
||||
|
||||
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) = fixture::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);
|
||||
|
|
|
@ -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 {
|
||||
|
@ -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<S>) {}
|
|||
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<S>) {}
|
|||
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<S>) {}
|
|||
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<S>) {}
|
|||
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<S>) {}
|
|||
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<S>) {}
|
|||
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<S>) {}
|
|||
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<B<dyn DynTrait<B<S>>>>) {}
|
|||
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<B<dyn DynTrait<B<S>>>>) {}
|
|||
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<B<dyn DynTrait<B<S>>>>) {}
|
|||
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<B<dyn DynTrait<B<S>>>>) {}
|
|||
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(
|
||||
|
|
|
@ -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)
|
||||
}
|
||||
|
|
|
@ -16,7 +16,7 @@ macro_rules! eprintln {
|
|||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod mock_analysis;
|
||||
mod fixture;
|
||||
|
||||
mod markup;
|
||||
mod prime_caches;
|
||||
|
@ -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
|
||||
|
|
|
@ -1,176 +0,0 @@
|
|||
//! 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 crate::{
|
||||
Analysis, AnalysisChange, AnalysisHost, 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<Fixture>,
|
||||
}
|
||||
|
||||
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<Item = (FileId, &Fixture)> + '_ {
|
||||
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 = AnalysisChange::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()
|
||||
}
|
||||
}
|
||||
|
||||
/// 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)
|
||||
}
|
||||
|
||||
/// 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)
|
||||
}
|
||||
|
||||
/// 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 range = match range_or_offset {
|
||||
RangeOrOffset::Range(it) => it,
|
||||
RangeOrOffset::Offset(_) => panic!(),
|
||||
};
|
||||
(res.analysis(), FileRange { file_id, range })
|
||||
}
|
|
@ -63,19 +63,13 @@ pub(crate) fn crate_for(db: &RootDatabase, file_id: FileId) -> Vec<CrateId> {
|
|||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use base_db::Env;
|
||||
use cfg::CfgOptions;
|
||||
use test_utils::mark;
|
||||
|
||||
use crate::{
|
||||
mock_analysis::{analysis_and_position, MockAnalysis},
|
||||
AnalysisChange, CrateGraph,
|
||||
Edition::Edition2018,
|
||||
};
|
||||
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,13 +78,13 @@ 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]
|
||||
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;
|
||||
|
@ -103,12 +97,12 @@ 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]
|
||||
fn test_resolve_parent_module_for_inline() {
|
||||
let (analysis, pos) = analysis_and_position(
|
||||
let (analysis, pos) = fixture::position(
|
||||
"
|
||||
//- /lib.rs
|
||||
mod foo {
|
||||
|
@ -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) = fixture::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 = AnalysisChange::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);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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::{fixture, 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<T> <|>{}
|
|||
}
|
||||
"#,
|
||||
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<SearchScope>, expect: Expect) {
|
||||
let (analysis, pos) = fixture::position(ra_fixture);
|
||||
let refs = analysis.find_all_refs(pos, search_scope).unwrap().unwrap();
|
||||
|
||||
let mut actual = String::new();
|
||||
|
|
|
@ -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<FileId> = 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());
|
||||
|
@ -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",
|
||||
},
|
||||
|
|
|
@ -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!(
|
||||
|
@ -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(
|
||||
|
|
|
@ -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 {}
|
||||
|
@ -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"],
|
||||
|
@ -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)
|
||||
}
|
||||
|
|
|
@ -104,12 +104,12 @@ fn syntax_tree_for_token(node: &SyntaxToken, text_range: TextRange) -> Option<St
|
|||
mod tests {
|
||||
use test_utils::assert_eq_text;
|
||||
|
||||
use crate::mock_analysis::{analysis_and_range, single_file};
|
||||
use crate::fixture;
|
||||
|
||||
#[test]
|
||||
fn test_syntax_tree_without_range() {
|
||||
// Basic syntax
|
||||
let (analysis, file_id) = single_file(r#"fn foo() {}"#);
|
||||
let (analysis, file_id) = fixture::file(r#"fn foo() {}"#);
|
||||
let syn = analysis.syntax_tree(file_id, None).unwrap();
|
||||
|
||||
assert_eq_text!(
|
||||
|
@ -132,7 +132,7 @@ SOURCE_FILE@0..11
|
|||
.trim()
|
||||
);
|
||||
|
||||
let (analysis, file_id) = single_file(
|
||||
let (analysis, file_id) = fixture::file(
|
||||
r#"
|
||||
fn test() {
|
||||
assert!("
|
||||
|
@ -184,7 +184,7 @@ SOURCE_FILE@0..60
|
|||
|
||||
#[test]
|
||||
fn test_syntax_tree_with_range() {
|
||||
let (analysis, range) = analysis_and_range(r#"<|>fn 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() {
|
||||
|
|
|
@ -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<String> {
|
||||
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();
|
||||
|
|
|
@ -1,58 +1,16 @@
|
|||
//! Defines a unit of change that can applied to a state of IDE to get the next
|
||||
//! state. Changes are transactional.
|
||||
//! Applies changes to the IDE state transactionally.
|
||||
|
||||
use std::{fmt, sync::Arc};
|
||||
|
||||
use base_db::{
|
||||
salsa::{Database, Durability, SweepStrategy},
|
||||
CrateGraph, FileId, SourceDatabase, SourceDatabaseExt, SourceRoot, SourceRootId,
|
||||
Change, FileId, SourceRootId,
|
||||
};
|
||||
use profile::{memory_usage, Bytes};
|
||||
use rustc_hash::FxHashSet;
|
||||
|
||||
use crate::{symbol_index::SymbolsDatabase, RootDatabase};
|
||||
|
||||
#[derive(Default)]
|
||||
pub struct AnalysisChange {
|
||||
roots: Option<Vec<SourceRoot>>,
|
||||
files_changed: Vec<(FileId, Option<Arc<String>>)>,
|
||||
crate_graph: Option<CrateGraph>,
|
||||
}
|
||||
|
||||
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<SourceRoot>) {
|
||||
self.roots = Some(roots);
|
||||
}
|
||||
|
||||
pub fn change_file(&mut self, file_id: FileId, new_text: Option<Arc<String>>) {
|
||||
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,
|
||||
|
@ -87,41 +45,25 @@ impl RootDatabase {
|
|||
self.salsa_runtime_mut().synthetic_write(Durability::LOW);
|
||||
}
|
||||
|
||||
pub fn apply_change(&mut self, change: AnalysisChange) {
|
||||
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 {
|
||||
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() {
|
||||
for (idx, root) in roots.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)
|
||||
}
|
||||
change.apply(self);
|
||||
}
|
||||
|
||||
pub fn collect_garbage(&mut self) {
|
||||
|
@ -295,11 +237,3 @@ impl RootDatabase {
|
|||
acc
|
||||
}
|
||||
}
|
||||
|
||||
fn durability(source_root: &SourceRoot) -> Durability {
|
||||
if source_root.is_library {
|
||||
Durability::HIGH
|
||||
} else {
|
||||
Durability::LOW
|
||||
}
|
||||
}
|
|
@ -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;
|
||||
|
|
|
@ -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<F: Fn(&Analysis) -> 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<F: Fn(&Analysis) -> 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);
|
||||
}
|
||||
|
|
|
@ -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::<usize>().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 {
|
||||
|
|
|
@ -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() {
|
||||
|
|
|
@ -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);
|
||||
|
||||
|
|
Loading…
Reference in a new issue