aboutsummaryrefslogtreecommitdiff
path: root/crates/ra_hir/src/code_model.rs
diff options
context:
space:
mode:
authorvsrs <[email protected]>2020-06-10 19:24:36 +0100
committervsrs <[email protected]>2020-06-18 08:15:43 +0100
commitc50157f33025b6ff01809b975a3d12c0e43a0072 (patch)
tree2b40e6ee3cbb463000432c760311b8a2a1a3292c /crates/ra_hir/src/code_model.rs
parent4d6c6a6b1e00f61af96e16386c7f03f83f96a173 (diff)
Add `Go to Type Definition` hover action.
Diffstat (limited to 'crates/ra_hir/src/code_model.rs')
-rw-r--r--crates/ra_hir/src/code_model.rs108
1 files changed, 106 insertions, 2 deletions
diff --git a/crates/ra_hir/src/code_model.rs b/crates/ra_hir/src/code_model.rs
index 1a9f6cc76..c22eb451b 100644
--- a/crates/ra_hir/src/code_model.rs
+++ b/crates/ra_hir/src/code_model.rs
@@ -26,8 +26,8 @@ use hir_ty::{
26 autoderef, 26 autoderef,
27 display::{HirDisplayError, HirFormatter}, 27 display::{HirDisplayError, HirFormatter},
28 expr::ExprValidator, 28 expr::ExprValidator,
29 method_resolution, ApplicationTy, Canonical, InEnvironment, Substs, TraitEnvironment, Ty, 29 method_resolution, ApplicationTy, Canonical, GenericPredicate, InEnvironment, OpaqueTyId,
30 TyDefId, TypeCtor, 30 Substs, TraitEnvironment, Ty, TyDefId, TypeCtor, TypeWalk,
31}; 31};
32use ra_db::{CrateId, CrateName, Edition, FileId}; 32use ra_db::{CrateId, CrateName, Edition, FileId};
33use ra_prof::profile; 33use ra_prof::profile;
@@ -1380,6 +1380,87 @@ impl Type {
1380 ty: InEnvironment { value: ty, environment: self.ty.environment.clone() }, 1380 ty: InEnvironment { value: ty, environment: self.ty.environment.clone() },
1381 } 1381 }
1382 } 1382 }
1383
1384 /// Returns a flattened list of all the ADTs and Traits mentioned in the type
1385 pub fn flattened_type_items(&self, db: &dyn HirDatabase) -> Vec<AdtOrTrait> {
1386 fn push_new_item(item: AdtOrTrait, acc: &mut Vec<AdtOrTrait>) {
1387 if !acc.contains(&item) {
1388 acc.push(item);
1389 }
1390 }
1391
1392 fn push_bounds(
1393 db: &dyn HirDatabase,
1394 predicates: &[GenericPredicate],
1395 acc: &mut Vec<AdtOrTrait>,
1396 ) {
1397 for p in predicates.iter() {
1398 match p {
1399 GenericPredicate::Implemented(trait_ref) => {
1400 push_new_item(Trait::from(trait_ref.trait_).into(), acc);
1401 walk_types(db, &trait_ref.substs, acc);
1402 }
1403 GenericPredicate::Projection(_) => {}
1404 GenericPredicate::Error => (),
1405 }
1406 }
1407 }
1408
1409 fn walk_types<T: TypeWalk>(db: &dyn HirDatabase, tw: &T, acc: &mut Vec<AdtOrTrait>) {
1410 tw.walk(&mut |ty| walk_type(db, ty, acc));
1411 }
1412
1413 fn walk_type(db: &dyn HirDatabase, ty: &Ty, acc: &mut Vec<AdtOrTrait>) {
1414 match ty.strip_references() {
1415 Ty::Apply(ApplicationTy { ctor, parameters, .. }) => {
1416 match ctor {
1417 TypeCtor::Adt(adt_id) => push_new_item(Adt::from(*adt_id).into(), acc),
1418 _ => (),
1419 }
1420 // adt params, tuples, etc...
1421 walk_types(db, parameters, acc);
1422 }
1423 Ty::Dyn(predicates) => {
1424 push_bounds(db, predicates, acc);
1425 }
1426 Ty::Placeholder(id) => {
1427 let generic_params = db.generic_params(id.parent);
1428 let param_data = &generic_params.types[id.local_id];
1429 match param_data.provenance {
1430 hir_def::generics::TypeParamProvenance::ArgumentImplTrait => {
1431 let predicates: Vec<_> = db
1432 .generic_predicates_for_param(*id)
1433 .into_iter()
1434 .map(|pred| pred.value.clone())
1435 .collect();
1436 push_bounds(db, &predicates, acc);
1437 }
1438 _ => (),
1439 }
1440 }
1441 Ty::Opaque(opaque_ty) => {
1442 let bounds = match opaque_ty.opaque_ty_id {
1443 OpaqueTyId::ReturnTypeImplTrait(func, idx) => {
1444 let datas = db
1445 .return_type_impl_traits(func)
1446 .expect("impl trait id without data");
1447 let data = (*datas)
1448 .as_ref()
1449 .map(|rpit| rpit.impl_traits[idx as usize].bounds.clone());
1450 data.clone().subst(&opaque_ty.parameters)
1451 }
1452 };
1453 push_bounds(db, &bounds.value, acc);
1454 walk_types(db, &opaque_ty.parameters, acc);
1455 }
1456 _ => (),
1457 }
1458 }
1459
1460 let mut res: Vec<AdtOrTrait> = Vec::new(); // not a Set to preserve the order
1461 walk_type(db, &self.ty.value, &mut res);
1462 res
1463 }
1383} 1464}
1384 1465
1385impl HirDisplay for Type { 1466impl HirDisplay for Type {
@@ -1488,3 +1569,26 @@ pub trait HasVisibility {
1488 vis.is_visible_from(db.upcast(), module.id) 1569 vis.is_visible_from(db.upcast(), module.id)
1489 } 1570 }
1490} 1571}
1572
1573#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)]
1574pub enum AdtOrTrait {
1575 Adt(Adt),
1576 Trait(Trait),
1577}
1578impl_froms!(AdtOrTrait: Adt, Trait);
1579
1580impl AdtOrTrait {
1581 pub fn module(self, db: &dyn HirDatabase) -> Module {
1582 match self {
1583 AdtOrTrait::Adt(adt) => adt.module(db),
1584 AdtOrTrait::Trait(trait_) => trait_.module(db),
1585 }
1586 }
1587
1588 pub fn name(self, db: &dyn HirDatabase) -> Name {
1589 match self {
1590 AdtOrTrait::Adt(adt) => adt.name(db),
1591 AdtOrTrait::Trait(trait_) => trait_.name(db),
1592 }
1593 }
1594}