mirror of
				https://github.com/rust-lang/rust-analyzer.git
				synced 2025-11-03 13:13:18 +00:00 
			
		
		
		
	Merge #9029
9029: minor: test that `ItemTree` makes `hir_def` queries syntax-independent r=jonas-schievink a=jonas-schievink bors r+ Co-authored-by: Jonas Schievink <jonasschievink@gmail.com>
This commit is contained in:
		
						commit
						5b4589f474
					
				@ -1,6 +1,8 @@
 | 
			
		||||
use std::sync::Arc;
 | 
			
		||||
 | 
			
		||||
use base_db::SourceDatabaseExt;
 | 
			
		||||
use base_db::{salsa::SweepStrategy, SourceDatabaseExt};
 | 
			
		||||
 | 
			
		||||
use crate::{AdtId, ModuleDefId};
 | 
			
		||||
 | 
			
		||||
use super::*;
 | 
			
		||||
 | 
			
		||||
@ -163,3 +165,73 @@ m!(Z);
 | 
			
		||||
        assert_eq!(n_reparsed_macros, 0);
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#[test]
 | 
			
		||||
fn item_tree_prevents_reparsing() {
 | 
			
		||||
    // The `ItemTree` is used by both name resolution and the various queries in `adt.rs` and
 | 
			
		||||
    // `data.rs`. After computing the `ItemTree` and deleting the parse tree, we should be able to
 | 
			
		||||
    // run those other queries without triggering a reparse.
 | 
			
		||||
 | 
			
		||||
    let (db, pos) = TestDB::with_position(
 | 
			
		||||
        r#"
 | 
			
		||||
pub struct S;
 | 
			
		||||
pub union U {}
 | 
			
		||||
pub enum E {
 | 
			
		||||
    Variant,
 | 
			
		||||
}
 | 
			
		||||
pub fn f(_: S) { $0 }
 | 
			
		||||
pub trait Tr {}
 | 
			
		||||
impl Tr for () {}
 | 
			
		||||
pub const C: u8 = 0;
 | 
			
		||||
pub static ST: u8 = 0;
 | 
			
		||||
pub type Ty = ();
 | 
			
		||||
"#,
 | 
			
		||||
    );
 | 
			
		||||
    let krate = db.test_crate();
 | 
			
		||||
    {
 | 
			
		||||
        let events = db.log_executed(|| {
 | 
			
		||||
            db.file_item_tree(pos.file_id.into());
 | 
			
		||||
        });
 | 
			
		||||
        let n_calculated_item_trees = events.iter().filter(|it| it.contains("item_tree")).count();
 | 
			
		||||
        assert_eq!(n_calculated_item_trees, 1);
 | 
			
		||||
        let n_parsed_files = events.iter().filter(|it| it.contains("parse(")).count();
 | 
			
		||||
        assert_eq!(n_parsed_files, 1);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    // Delete the parse tree.
 | 
			
		||||
    let sweep = SweepStrategy::default().discard_values().sweep_all_revisions();
 | 
			
		||||
    base_db::ParseQuery.in_db(&db).sweep(sweep);
 | 
			
		||||
 | 
			
		||||
    {
 | 
			
		||||
        let events = db.log_executed(|| {
 | 
			
		||||
            let crate_def_map = db.crate_def_map(krate);
 | 
			
		||||
            let (_, module_data) = crate_def_map.modules.iter().last().unwrap();
 | 
			
		||||
            assert_eq!(module_data.scope.resolutions().count(), 8);
 | 
			
		||||
            assert_eq!(module_data.scope.impls().count(), 1);
 | 
			
		||||
 | 
			
		||||
            for imp in module_data.scope.impls() {
 | 
			
		||||
                db.impl_data(imp);
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            for (_, res) in module_data.scope.resolutions() {
 | 
			
		||||
                match res.values.or(res.types).unwrap().0 {
 | 
			
		||||
                    ModuleDefId::FunctionId(f) => drop(db.function_data(f)),
 | 
			
		||||
                    ModuleDefId::AdtId(adt) => match adt {
 | 
			
		||||
                        AdtId::StructId(it) => drop(db.struct_data(it)),
 | 
			
		||||
                        AdtId::UnionId(it) => drop(db.union_data(it)),
 | 
			
		||||
                        AdtId::EnumId(it) => drop(db.enum_data(it)),
 | 
			
		||||
                    },
 | 
			
		||||
                    ModuleDefId::ConstId(it) => drop(db.const_data(it)),
 | 
			
		||||
                    ModuleDefId::StaticId(it) => drop(db.static_data(it)),
 | 
			
		||||
                    ModuleDefId::TraitId(it) => drop(db.trait_data(it)),
 | 
			
		||||
                    ModuleDefId::TypeAliasId(it) => drop(db.type_alias_data(it)),
 | 
			
		||||
                    ModuleDefId::EnumVariantId(_)
 | 
			
		||||
                    | ModuleDefId::ModuleId(_)
 | 
			
		||||
                    | ModuleDefId::BuiltinType(_) => unreachable!(),
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
        });
 | 
			
		||||
        let n_reparsed_files = events.iter().filter(|it| it.contains("parse(")).count();
 | 
			
		||||
        assert_eq!(n_reparsed_files, 0);
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@ -7,6 +7,7 @@ mod traits;
 | 
			
		||||
mod method_resolution;
 | 
			
		||||
mod macros;
 | 
			
		||||
mod display_source_code;
 | 
			
		||||
mod incremental;
 | 
			
		||||
 | 
			
		||||
use std::{env, sync::Arc};
 | 
			
		||||
 | 
			
		||||
@ -317,50 +318,6 @@ fn ellipsize(mut text: String, max_len: usize) -> String {
 | 
			
		||||
    text
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#[test]
 | 
			
		||||
fn typing_whitespace_inside_a_function_should_not_invalidate_types() {
 | 
			
		||||
    let (mut db, pos) = TestDB::with_position(
 | 
			
		||||
        "
 | 
			
		||||
        //- /lib.rs
 | 
			
		||||
        fn foo() -> i32 {
 | 
			
		||||
            $01 + 1
 | 
			
		||||
        }
 | 
			
		||||
    ",
 | 
			
		||||
    );
 | 
			
		||||
    {
 | 
			
		||||
        let events = db.log_executed(|| {
 | 
			
		||||
            let module = db.module_for_file(pos.file_id);
 | 
			
		||||
            let crate_def_map = module.def_map(&db);
 | 
			
		||||
            visit_module(&db, &crate_def_map, module.local_id, &mut |def| {
 | 
			
		||||
                db.infer(def);
 | 
			
		||||
            });
 | 
			
		||||
        });
 | 
			
		||||
        assert!(format!("{:?}", events).contains("infer"))
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    let new_text = "
 | 
			
		||||
        fn foo() -> i32 {
 | 
			
		||||
            1
 | 
			
		||||
            +
 | 
			
		||||
            1
 | 
			
		||||
        }
 | 
			
		||||
    "
 | 
			
		||||
    .to_string();
 | 
			
		||||
 | 
			
		||||
    db.set_file_text(pos.file_id, Arc::new(new_text));
 | 
			
		||||
 | 
			
		||||
    {
 | 
			
		||||
        let events = db.log_executed(|| {
 | 
			
		||||
            let module = db.module_for_file(pos.file_id);
 | 
			
		||||
            let crate_def_map = module.def_map(&db);
 | 
			
		||||
            visit_module(&db, &crate_def_map, module.local_id, &mut |def| {
 | 
			
		||||
                db.infer(def);
 | 
			
		||||
            });
 | 
			
		||||
        });
 | 
			
		||||
        assert!(!format!("{:?}", events).contains("infer"), "{:#?}", events)
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
fn check_infer(ra_fixture: &str, expect: Expect) {
 | 
			
		||||
    let mut actual = infer(ra_fixture);
 | 
			
		||||
    actual.push('\n');
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										51
									
								
								crates/hir_ty/src/tests/incremental.rs
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										51
									
								
								crates/hir_ty/src/tests/incremental.rs
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,51 @@
 | 
			
		||||
use std::sync::Arc;
 | 
			
		||||
 | 
			
		||||
use base_db::{fixture::WithFixture, SourceDatabaseExt};
 | 
			
		||||
 | 
			
		||||
use crate::{db::HirDatabase, test_db::TestDB};
 | 
			
		||||
 | 
			
		||||
use super::visit_module;
 | 
			
		||||
 | 
			
		||||
#[test]
 | 
			
		||||
fn typing_whitespace_inside_a_function_should_not_invalidate_types() {
 | 
			
		||||
    let (mut db, pos) = TestDB::with_position(
 | 
			
		||||
        "
 | 
			
		||||
        //- /lib.rs
 | 
			
		||||
        fn foo() -> i32 {
 | 
			
		||||
            $01 + 1
 | 
			
		||||
        }
 | 
			
		||||
    ",
 | 
			
		||||
    );
 | 
			
		||||
    {
 | 
			
		||||
        let events = db.log_executed(|| {
 | 
			
		||||
            let module = db.module_for_file(pos.file_id);
 | 
			
		||||
            let crate_def_map = module.def_map(&db);
 | 
			
		||||
            visit_module(&db, &crate_def_map, module.local_id, &mut |def| {
 | 
			
		||||
                db.infer(def);
 | 
			
		||||
            });
 | 
			
		||||
        });
 | 
			
		||||
        assert!(format!("{:?}", events).contains("infer"))
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    let new_text = "
 | 
			
		||||
        fn foo() -> i32 {
 | 
			
		||||
            1
 | 
			
		||||
            +
 | 
			
		||||
            1
 | 
			
		||||
        }
 | 
			
		||||
    "
 | 
			
		||||
    .to_string();
 | 
			
		||||
 | 
			
		||||
    db.set_file_text(pos.file_id, Arc::new(new_text));
 | 
			
		||||
 | 
			
		||||
    {
 | 
			
		||||
        let events = db.log_executed(|| {
 | 
			
		||||
            let module = db.module_for_file(pos.file_id);
 | 
			
		||||
            let crate_def_map = module.def_map(&db);
 | 
			
		||||
            visit_module(&db, &crate_def_map, module.local_id, &mut |def| {
 | 
			
		||||
                db.infer(def);
 | 
			
		||||
            });
 | 
			
		||||
        });
 | 
			
		||||
        assert!(!format!("{:?}", events).contains("infer"), "{:#?}", events)
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user