aboutsummaryrefslogtreecommitdiff
path: root/crates/ra_hir/src
diff options
context:
space:
mode:
authorbors[bot] <bors[bot]@users.noreply.github.com>2019-02-10 11:42:42 +0000
committerbors[bot] <bors[bot]@users.noreply.github.com>2019-02-10 11:42:42 +0000
commit8e4be2708635818aa3e210f0e39fb871cc433004 (patch)
tree569110cbb504c0516b136c414610b0f2edbe5044 /crates/ra_hir/src
parent01b15c9fc2ce128149872ffe02de022bdb157286 (diff)
parent2e9194a621ccb33872d6189ecc30a83c17e6e33a (diff)
Merge #774
774: Batch crate & command r=matklad a=flodiebold This adds a new crate, `ra_batch`, which is intended for scenarios where you're loading a workspace once and then running some analyses using the HIR API. Also, it adds a command to `ra_cli` which uses that to type-check all crates in a workspace and print some statistics: E.g. in rust-analyzer: ``` > $ time target/release/ra_cli analysis-stats Database loaded, 21 roots Crates in this dir: 28 Total modules found: 231 Total declarations: 3694 Total functions: 2408 Total expressions: 47017 Expressions of unknown type: 19826 (42%) Expressions of partially unknown type: 4482 (9%) target/release/ra_cli analysis-stats 3,23s user 0,60s system 100% cpu 3,821 total ``` Or in rust-lang/rust: ``` > $ time ../opensource/rust-analyzer/target/release/ra_cli analysis-stats Database loaded, 77 roots Crates in this dir: 130 Total modules found: 1820 Total declarations: 35038 Total functions: 25914 Total expressions: 753678 Expressions of unknown type: 337975 (44%) Expressions of partially unknown type: 92314 (12%) ../opensource/rust-analyzer/target/release/ra_cli analysis-stats 13,45s user 2,08s system 100% cpu 15,477 total ``` ~This still needs a test. Type-checking all of rust-analyzer sadly takes almost a minute when compiled in debug mode :sweat_smile: So I'll need to add something simpler (maybe just looking at a few modules).~ Co-authored-by: Florian Diebold <[email protected]>
Diffstat (limited to 'crates/ra_hir/src')
-rw-r--r--crates/ra_hir/src/code_model_api.rs34
-rw-r--r--crates/ra_hir/src/expr.rs8
-rw-r--r--crates/ra_hir/src/ty.rs53
3 files changed, 92 insertions, 3 deletions
diff --git a/crates/ra_hir/src/code_model_api.rs b/crates/ra_hir/src/code_model_api.rs
index cafc5279d..19f103855 100644
--- a/crates/ra_hir/src/code_model_api.rs
+++ b/crates/ra_hir/src/code_model_api.rs
@@ -1,7 +1,7 @@
1use std::sync::Arc; 1use std::sync::Arc;
2 2
3use relative_path::RelativePathBuf; 3use relative_path::RelativePathBuf;
4use ra_db::{CrateId, FileId}; 4use ra_db::{CrateId, FileId, SourceRootId};
5use ra_syntax::{ast::self, TreeArc, SyntaxNode}; 5use ra_syntax::{ast::self, TreeArc, SyntaxNode};
6 6
7use crate::{ 7use crate::{
@@ -16,7 +16,7 @@ use crate::{
16 docs::{Documentation, Docs, docs_from_ast}, 16 docs::{Documentation, Docs, docs_from_ast},
17 module_tree::ModuleId, 17 module_tree::ModuleId,
18 ids::{FunctionId, StructId, EnumId, AstItemDef, ConstId, StaticId, TraitId, TypeId}, 18 ids::{FunctionId, StructId, EnumId, AstItemDef, ConstId, StaticId, TraitId, TypeId},
19 impl_block::ImplId, 19 impl_block::{ImplId, ImplBlock},
20 resolve::Resolver, 20 resolve::Resolver,
21}; 21};
22 22
@@ -44,6 +44,15 @@ impl Crate {
44 pub fn root_module(&self, db: &impl PersistentHirDatabase) -> Option<Module> { 44 pub fn root_module(&self, db: &impl PersistentHirDatabase) -> Option<Module> {
45 self.root_module_impl(db) 45 self.root_module_impl(db)
46 } 46 }
47
48 // TODO: should this be in source_binder?
49 pub fn source_root_crates(
50 db: &impl PersistentHirDatabase,
51 source_root: SourceRootId,
52 ) -> Vec<Crate> {
53 let crate_ids = db.source_root_crates(source_root);
54 crate_ids.iter().map(|&crate_id| Crate { crate_id }).collect()
55 }
47} 56}
48 57
49#[derive(Debug)] 58#[derive(Debug)]
@@ -168,6 +177,27 @@ impl Module {
168 let item_map = db.item_map(self.krate); 177 let item_map = db.item_map(self.krate);
169 Resolver::default().push_module_scope(item_map, *self) 178 Resolver::default().push_module_scope(item_map, *self)
170 } 179 }
180
181 pub fn declarations(self, db: &impl HirDatabase) -> Vec<ModuleDef> {
182 let (lowered_module, _) = db.lower_module(self);
183 lowered_module
184 .declarations
185 .values()
186 .cloned()
187 .flat_map(|per_ns| {
188 per_ns.take_types().into_iter().chain(per_ns.take_values().into_iter())
189 })
190 .collect()
191 }
192
193 pub fn impl_blocks(self, db: &impl HirDatabase) -> Vec<ImplBlock> {
194 let module_impl_blocks = db.impls_in_module(self);
195 module_impl_blocks
196 .impls
197 .iter()
198 .map(|(impl_id, _)| ImplBlock::from_id(module_impl_blocks.clone(), impl_id))
199 .collect()
200 }
171} 201}
172 202
173impl Docs for Module { 203impl Docs for Module {
diff --git a/crates/ra_hir/src/expr.rs b/crates/ra_hir/src/expr.rs
index b30e11abb..4e73590d0 100644
--- a/crates/ra_hir/src/expr.rs
+++ b/crates/ra_hir/src/expr.rs
@@ -70,6 +70,14 @@ impl Body {
70 self.owner 70 self.owner
71 } 71 }
72 72
73 pub fn exprs(&self) -> impl Iterator<Item = (ExprId, &Expr)> {
74 self.exprs.iter()
75 }
76
77 pub fn pats(&self) -> impl Iterator<Item = (PatId, &Pat)> {
78 self.pats.iter()
79 }
80
73 pub fn syntax_mapping(&self, db: &impl HirDatabase) -> Arc<BodySyntaxMapping> { 81 pub fn syntax_mapping(&self, db: &impl HirDatabase) -> Arc<BodySyntaxMapping> {
74 db.body_syntax_mapping(self.owner) 82 db.body_syntax_mapping(self.owner)
75 } 83 }
diff --git a/crates/ra_hir/src/ty.rs b/crates/ra_hir/src/ty.rs
index 7203a8a10..2dc1de41a 100644
--- a/crates/ra_hir/src/ty.rs
+++ b/crates/ra_hir/src/ty.rs
@@ -449,6 +449,49 @@ impl Ty {
449 Ty::Tuple(Arc::new([])) 449 Ty::Tuple(Arc::new([]))
450 } 450 }
451 451
452 pub fn walk(&self, f: &mut impl FnMut(&Ty)) {
453 f(self);
454 match self {
455 Ty::Slice(t) | Ty::Array(t) => t.walk(f),
456 Ty::RawPtr(t, _) => t.walk(f),
457 Ty::Ref(t, _) => t.walk(f),
458 Ty::Tuple(ts) => {
459 for t in ts.iter() {
460 t.walk(f);
461 }
462 }
463 Ty::FnPtr(sig) => {
464 for input in &sig.input {
465 input.walk(f);
466 }
467 sig.output.walk(f);
468 }
469 Ty::FnDef { substs, sig, .. } => {
470 for input in &sig.input {
471 input.walk(f);
472 }
473 sig.output.walk(f);
474 for t in substs.0.iter() {
475 t.walk(f);
476 }
477 }
478 Ty::Adt { substs, .. } => {
479 for t in substs.0.iter() {
480 t.walk(f);
481 }
482 }
483 Ty::Bool
484 | Ty::Char
485 | Ty::Int(_)
486 | Ty::Float(_)
487 | Ty::Str
488 | Ty::Never
489 | Ty::Param { .. }
490 | Ty::Infer(_)
491 | Ty::Unknown => {}
492 }
493 }
494
452 fn walk_mut(&mut self, f: &mut impl FnMut(&mut Ty)) { 495 fn walk_mut(&mut self, f: &mut impl FnMut(&mut Ty)) {
453 f(self); 496 f(self);
454 match self { 497 match self {
@@ -491,7 +534,15 @@ impl Ty {
491 } 534 }
492 substs.0 = v.into(); 535 substs.0 = v.into();
493 } 536 }
494 _ => {} 537 Ty::Bool
538 | Ty::Char
539 | Ty::Int(_)
540 | Ty::Float(_)
541 | Ty::Str
542 | Ty::Never
543 | Ty::Param { .. }
544 | Ty::Infer(_)
545 | Ty::Unknown => {}
495 } 546 }
496 } 547 }
497 548