aboutsummaryrefslogtreecommitdiff
path: root/crates
diff options
context:
space:
mode:
Diffstat (limited to 'crates')
-rw-r--r--crates/hir_def/src/nameres/tests/incremental.rs74
-rw-r--r--crates/hir_ty/src/tests.rs45
-rw-r--r--crates/hir_ty/src/tests/incremental.rs51
3 files changed, 125 insertions, 45 deletions
diff --git a/crates/hir_def/src/nameres/tests/incremental.rs b/crates/hir_def/src/nameres/tests/incremental.rs
index d884a6eb4..7bf152e26 100644
--- a/crates/hir_def/src/nameres/tests/incremental.rs
+++ b/crates/hir_def/src/nameres/tests/incremental.rs
@@ -1,6 +1,8 @@
1use std::sync::Arc; 1use std::sync::Arc;
2 2
3use base_db::SourceDatabaseExt; 3use base_db::{salsa::SweepStrategy, SourceDatabaseExt};
4
5use crate::{AdtId, ModuleDefId};
4 6
5use super::*; 7use super::*;
6 8
@@ -163,3 +165,73 @@ m!(Z);
163 assert_eq!(n_reparsed_macros, 0); 165 assert_eq!(n_reparsed_macros, 0);
164 } 166 }
165} 167}
168
169#[test]
170fn item_tree_prevents_reparsing() {
171 // The `ItemTree` is used by both name resolution and the various queries in `adt.rs` and
172 // `data.rs`. After computing the `ItemTree` and deleting the parse tree, we should be able to
173 // run those other queries without triggering a reparse.
174
175 let (db, pos) = TestDB::with_position(
176 r#"
177pub struct S;
178pub union U {}
179pub enum E {
180 Variant,
181}
182pub fn f(_: S) { $0 }
183pub trait Tr {}
184impl Tr for () {}
185pub const C: u8 = 0;
186pub static ST: u8 = 0;
187pub type Ty = ();
188"#,
189 );
190 let krate = db.test_crate();
191 {
192 let events = db.log_executed(|| {
193 db.file_item_tree(pos.file_id.into());
194 });
195 let n_calculated_item_trees = events.iter().filter(|it| it.contains("item_tree")).count();
196 assert_eq!(n_calculated_item_trees, 1);
197 let n_parsed_files = events.iter().filter(|it| it.contains("parse(")).count();
198 assert_eq!(n_parsed_files, 1);
199 }
200
201 // Delete the parse tree.
202 let sweep = SweepStrategy::default().discard_values().sweep_all_revisions();
203 base_db::ParseQuery.in_db(&db).sweep(sweep);
204
205 {
206 let events = db.log_executed(|| {
207 let crate_def_map = db.crate_def_map(krate);
208 let (_, module_data) = crate_def_map.modules.iter().last().unwrap();
209 assert_eq!(module_data.scope.resolutions().count(), 8);
210 assert_eq!(module_data.scope.impls().count(), 1);
211
212 for imp in module_data.scope.impls() {
213 db.impl_data(imp);
214 }
215
216 for (_, res) in module_data.scope.resolutions() {
217 match res.values.or(res.types).unwrap().0 {
218 ModuleDefId::FunctionId(f) => drop(db.function_data(f)),
219 ModuleDefId::AdtId(adt) => match adt {
220 AdtId::StructId(it) => drop(db.struct_data(it)),
221 AdtId::UnionId(it) => drop(db.union_data(it)),
222 AdtId::EnumId(it) => drop(db.enum_data(it)),
223 },
224 ModuleDefId::ConstId(it) => drop(db.const_data(it)),
225 ModuleDefId::StaticId(it) => drop(db.static_data(it)),
226 ModuleDefId::TraitId(it) => drop(db.trait_data(it)),
227 ModuleDefId::TypeAliasId(it) => drop(db.type_alias_data(it)),
228 ModuleDefId::EnumVariantId(_)
229 | ModuleDefId::ModuleId(_)
230 | ModuleDefId::BuiltinType(_) => unreachable!(),
231 }
232 }
233 });
234 let n_reparsed_files = events.iter().filter(|it| it.contains("parse(")).count();
235 assert_eq!(n_reparsed_files, 0);
236 }
237}
diff --git a/crates/hir_ty/src/tests.rs b/crates/hir_ty/src/tests.rs
index cc819373c..9d726b024 100644
--- a/crates/hir_ty/src/tests.rs
+++ b/crates/hir_ty/src/tests.rs
@@ -7,6 +7,7 @@ mod traits;
7mod method_resolution; 7mod method_resolution;
8mod macros; 8mod macros;
9mod display_source_code; 9mod display_source_code;
10mod incremental;
10 11
11use std::{env, sync::Arc}; 12use std::{env, sync::Arc};
12 13
@@ -317,50 +318,6 @@ fn ellipsize(mut text: String, max_len: usize) -> String {
317 text 318 text
318} 319}
319 320
320#[test]
321fn typing_whitespace_inside_a_function_should_not_invalidate_types() {
322 let (mut db, pos) = TestDB::with_position(
323 "
324 //- /lib.rs
325 fn foo() -> i32 {
326 $01 + 1
327 }
328 ",
329 );
330 {
331 let events = db.log_executed(|| {
332 let module = db.module_for_file(pos.file_id);
333 let crate_def_map = module.def_map(&db);
334 visit_module(&db, &crate_def_map, module.local_id, &mut |def| {
335 db.infer(def);
336 });
337 });
338 assert!(format!("{:?}", events).contains("infer"))
339 }
340
341 let new_text = "
342 fn foo() -> i32 {
343 1
344 +
345 1
346 }
347 "
348 .to_string();
349
350 db.set_file_text(pos.file_id, Arc::new(new_text));
351
352 {
353 let events = db.log_executed(|| {
354 let module = db.module_for_file(pos.file_id);
355 let crate_def_map = module.def_map(&db);
356 visit_module(&db, &crate_def_map, module.local_id, &mut |def| {
357 db.infer(def);
358 });
359 });
360 assert!(!format!("{:?}", events).contains("infer"), "{:#?}", events)
361 }
362}
363
364fn check_infer(ra_fixture: &str, expect: Expect) { 321fn check_infer(ra_fixture: &str, expect: Expect) {
365 let mut actual = infer(ra_fixture); 322 let mut actual = infer(ra_fixture);
366 actual.push('\n'); 323 actual.push('\n');
diff --git a/crates/hir_ty/src/tests/incremental.rs b/crates/hir_ty/src/tests/incremental.rs
new file mode 100644
index 000000000..3e08e83e8
--- /dev/null
+++ b/crates/hir_ty/src/tests/incremental.rs
@@ -0,0 +1,51 @@
1use std::sync::Arc;
2
3use base_db::{fixture::WithFixture, SourceDatabaseExt};
4
5use crate::{db::HirDatabase, test_db::TestDB};
6
7use super::visit_module;
8
9#[test]
10fn typing_whitespace_inside_a_function_should_not_invalidate_types() {
11 let (mut db, pos) = TestDB::with_position(
12 "
13 //- /lib.rs
14 fn foo() -> i32 {
15 $01 + 1
16 }
17 ",
18 );
19 {
20 let events = db.log_executed(|| {
21 let module = db.module_for_file(pos.file_id);
22 let crate_def_map = module.def_map(&db);
23 visit_module(&db, &crate_def_map, module.local_id, &mut |def| {
24 db.infer(def);
25 });
26 });
27 assert!(format!("{:?}", events).contains("infer"))
28 }
29
30 let new_text = "
31 fn foo() -> i32 {
32 1
33 +
34 1
35 }
36 "
37 .to_string();
38
39 db.set_file_text(pos.file_id, Arc::new(new_text));
40
41 {
42 let events = db.log_executed(|| {
43 let module = db.module_for_file(pos.file_id);
44 let crate_def_map = module.def_map(&db);
45 visit_module(&db, &crate_def_map, module.local_id, &mut |def| {
46 db.infer(def);
47 });
48 });
49 assert!(!format!("{:?}", events).contains("infer"), "{:#?}", events)
50 }
51}