diff options
author | bors[bot] <bors[bot]@users.noreply.github.com> | 2019-02-10 11:42:42 +0000 |
---|---|---|
committer | bors[bot] <bors[bot]@users.noreply.github.com> | 2019-02-10 11:42:42 +0000 |
commit | 8e4be2708635818aa3e210f0e39fb871cc433004 (patch) | |
tree | 569110cbb504c0516b136c414610b0f2edbe5044 /crates/ra_hir | |
parent | 01b15c9fc2ce128149872ffe02de022bdb157286 (diff) | |
parent | 2e9194a621ccb33872d6189ecc30a83c17e6e33a (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')
-rw-r--r-- | crates/ra_hir/src/code_model_api.rs | 34 | ||||
-rw-r--r-- | crates/ra_hir/src/expr.rs | 8 | ||||
-rw-r--r-- | crates/ra_hir/src/ty.rs | 53 |
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 @@ | |||
1 | use std::sync::Arc; | 1 | use std::sync::Arc; |
2 | 2 | ||
3 | use relative_path::RelativePathBuf; | 3 | use relative_path::RelativePathBuf; |
4 | use ra_db::{CrateId, FileId}; | 4 | use ra_db::{CrateId, FileId, SourceRootId}; |
5 | use ra_syntax::{ast::self, TreeArc, SyntaxNode}; | 5 | use ra_syntax::{ast::self, TreeArc, SyntaxNode}; |
6 | 6 | ||
7 | use crate::{ | 7 | use 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 | ||
173 | impl Docs for Module { | 203 | impl 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 | ||