diff options
author | vsrs <[email protected]> | 2020-06-10 19:24:36 +0100 |
---|---|---|
committer | vsrs <[email protected]> | 2020-06-18 08:15:43 +0100 |
commit | c50157f33025b6ff01809b975a3d12c0e43a0072 (patch) | |
tree | 2b40e6ee3cbb463000432c760311b8a2a1a3292c /crates/ra_hir | |
parent | 4d6c6a6b1e00f61af96e16386c7f03f83f96a173 (diff) |
Add `Go to Type Definition` hover action.
Diffstat (limited to 'crates/ra_hir')
-rw-r--r-- | crates/ra_hir/src/code_model.rs | 108 | ||||
-rw-r--r-- | crates/ra_hir/src/lib.rs | 8 |
2 files changed, 110 insertions, 6 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 | }; |
32 | use ra_db::{CrateId, CrateName, Edition, FileId}; | 32 | use ra_db::{CrateId, CrateName, Edition, FileId}; |
33 | use ra_prof::profile; | 33 | use 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 | ||
1385 | impl HirDisplay for Type { | 1466 | impl 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)] | ||
1574 | pub enum AdtOrTrait { | ||
1575 | Adt(Adt), | ||
1576 | Trait(Trait), | ||
1577 | } | ||
1578 | impl_froms!(AdtOrTrait: Adt, Trait); | ||
1579 | |||
1580 | impl 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 | } | ||
diff --git a/crates/ra_hir/src/lib.rs b/crates/ra_hir/src/lib.rs index 3364a822f..eded039e4 100644 --- a/crates/ra_hir/src/lib.rs +++ b/crates/ra_hir/src/lib.rs | |||
@@ -51,10 +51,10 @@ mod has_source; | |||
51 | 51 | ||
52 | pub use crate::{ | 52 | pub use crate::{ |
53 | code_model::{ | 53 | code_model::{ |
54 | Adt, AsAssocItem, AssocItem, AssocItemContainer, AttrDef, Const, Crate, CrateDependency, | 54 | Adt, AdtOrTrait, AsAssocItem, AssocItem, AssocItemContainer, AttrDef, Const, Crate, |
55 | DefWithBody, Docs, Enum, EnumVariant, Field, FieldSource, Function, GenericDef, HasAttrs, | 55 | CrateDependency, DefWithBody, Docs, Enum, EnumVariant, Field, FieldSource, Function, |
56 | HasVisibility, ImplDef, Local, MacroDef, Module, ModuleDef, ScopeDef, Static, Struct, | 56 | GenericDef, HasAttrs, HasVisibility, ImplDef, Local, MacroDef, Module, ModuleDef, ScopeDef, |
57 | Trait, Type, TypeAlias, TypeParam, Union, VariantDef, Visibility, | 57 | Static, Struct, Trait, Type, TypeAlias, TypeParam, Union, VariantDef, Visibility, |
58 | }, | 58 | }, |
59 | has_source::HasSource, | 59 | has_source::HasSource, |
60 | semantics::{original_range, PathResolution, Semantics, SemanticsScope}, | 60 | semantics::{original_range, PathResolution, Semantics, SemanticsScope}, |