11//! Attributes & documentation for hir types.
22use hir_def:: {
3- attr:: Attrs ,
4- docs:: Documentation ,
5- resolver:: { HasResolver , Resolver } ,
6- AdtId , AttrDefId , FunctionId , GenericDefId , ModuleId , StaticId , TraitId , VariantId ,
3+ attr:: Attrs , docs:: Documentation , path:: ModPath , resolver:: HasResolver , AttrDefId , ModuleDefId ,
74} ;
5+ use hir_expand:: hygiene:: Hygiene ;
86use hir_ty:: db:: HirDatabase ;
7+ use syntax:: ast;
98
109use crate :: {
11- doc_links :: Resolvable , Adt , Const , Enum , EnumVariant , Field , Function , GenericDef , ImplDef ,
12- Local , MacroDef , Module , ModuleDef , Static , Struct , Trait , TypeAlias , TypeParam , Union ,
10+ Adt , Const , Enum , EnumVariant , Field , Function , MacroDef , Module , ModuleDef , Static , Struct ,
11+ Trait , TypeAlias , Union ,
1312} ;
1413
1514pub trait HasAttrs {
1615 fn attrs ( self , db : & dyn HirDatabase ) -> Attrs ;
1716 fn docs ( self , db : & dyn HirDatabase ) -> Option < Documentation > ;
17+ fn resolve_doc_path (
18+ self ,
19+ db : & dyn HirDatabase ,
20+ link : & str ,
21+ ns : Option < Namespace > ,
22+ ) -> Option < ModuleDef > ;
23+ }
24+
25+ #[ derive( PartialEq , Eq , Hash , Copy , Clone , Debug ) ]
26+ pub enum Namespace {
27+ Types ,
28+ Values ,
29+ Macros ,
1830}
1931
2032macro_rules! impl_has_attrs {
@@ -28,6 +40,10 @@ macro_rules! impl_has_attrs {
2840 let def = AttrDefId :: $def_id( self . into( ) ) ;
2941 db. documentation( def)
3042 }
43+ fn resolve_doc_path( self , db: & dyn HirDatabase , link: & str , ns: Option <Namespace >) -> Option <ModuleDef > {
44+ let def = AttrDefId :: $def_id( self . into( ) ) ;
45+ resolve_doc_path( db, def, link, ns) . map( ModuleDef :: from)
46+ }
3147 }
3248 ) * } ;
3349}
@@ -54,83 +70,42 @@ macro_rules! impl_has_attrs_adt {
5470 fn docs( self , db: & dyn HirDatabase ) -> Option <Documentation > {
5571 Adt :: $adt( self ) . docs( db)
5672 }
73+ fn resolve_doc_path( self , db: & dyn HirDatabase , link: & str , ns: Option <Namespace >) -> Option <ModuleDef > {
74+ Adt :: $adt( self ) . resolve_doc_path( db, link, ns)
75+ }
5776 }
5877 ) * } ;
5978}
6079
6180impl_has_attrs_adt ! [ Struct , Union , Enum ] ;
6281
63- impl Resolvable for ModuleDef {
64- fn resolver ( & self , db : & dyn HirDatabase ) -> Option < Resolver > {
65- Some ( match self {
66- ModuleDef :: Module ( m) => ModuleId :: from ( m. clone ( ) ) . resolver ( db. upcast ( ) ) ,
67- ModuleDef :: Function ( f) => FunctionId :: from ( f. clone ( ) ) . resolver ( db. upcast ( ) ) ,
68- ModuleDef :: Adt ( adt) => AdtId :: from ( adt. clone ( ) ) . resolver ( db. upcast ( ) ) ,
69- ModuleDef :: EnumVariant ( ev) => {
70- GenericDefId :: from ( GenericDef :: from ( ev. clone ( ) ) ) . resolver ( db. upcast ( ) )
71- }
72- ModuleDef :: Const ( c) => {
73- GenericDefId :: from ( GenericDef :: from ( c. clone ( ) ) ) . resolver ( db. upcast ( ) )
74- }
75- ModuleDef :: Static ( s) => StaticId :: from ( s. clone ( ) ) . resolver ( db. upcast ( ) ) ,
76- ModuleDef :: Trait ( t) => TraitId :: from ( t. clone ( ) ) . resolver ( db. upcast ( ) ) ,
77- ModuleDef :: TypeAlias ( t) => ModuleId :: from ( t. module ( db) ) . resolver ( db. upcast ( ) ) ,
78- // FIXME: This should be a resolver relative to `std/core`
79- ModuleDef :: BuiltinType ( _t) => None ?,
80- } )
81- }
82-
83- fn try_into_module_def ( self ) -> Option < ModuleDef > {
84- Some ( self )
85- }
86- }
87-
88- impl Resolvable for TypeParam {
89- fn resolver ( & self , db : & dyn HirDatabase ) -> Option < Resolver > {
90- Some ( ModuleId :: from ( self . module ( db) ) . resolver ( db. upcast ( ) ) )
91- }
92-
93- fn try_into_module_def ( self ) -> Option < ModuleDef > {
94- None
95- }
96- }
97-
98- impl Resolvable for MacroDef {
99- fn resolver ( & self , db : & dyn HirDatabase ) -> Option < Resolver > {
100- Some ( ModuleId :: from ( self . module ( db) ?) . resolver ( db. upcast ( ) ) )
101- }
102-
103- fn try_into_module_def ( self ) -> Option < ModuleDef > {
104- None
105- }
106- }
107-
108- impl Resolvable for Field {
109- fn resolver ( & self , db : & dyn HirDatabase ) -> Option < Resolver > {
110- Some ( VariantId :: from ( self . parent_def ( db) ) . resolver ( db. upcast ( ) ) )
111- }
112-
113- fn try_into_module_def ( self ) -> Option < ModuleDef > {
114- None
115- }
116- }
117-
118- impl Resolvable for ImplDef {
119- fn resolver ( & self , db : & dyn HirDatabase ) -> Option < Resolver > {
120- Some ( ModuleId :: from ( self . module ( db) ) . resolver ( db. upcast ( ) ) )
121- }
122-
123- fn try_into_module_def ( self ) -> Option < ModuleDef > {
124- None
125- }
126- }
127-
128- impl Resolvable for Local {
129- fn resolver ( & self , db : & dyn HirDatabase ) -> Option < Resolver > {
130- Some ( ModuleId :: from ( self . module ( db) ) . resolver ( db. upcast ( ) ) )
131- }
132-
133- fn try_into_module_def ( self ) -> Option < ModuleDef > {
134- None
135- }
82+ fn resolve_doc_path (
83+ db : & dyn HirDatabase ,
84+ def : AttrDefId ,
85+ link : & str ,
86+ ns : Option < Namespace > ,
87+ ) -> Option < ModuleDefId > {
88+ let resolver = match def {
89+ AttrDefId :: ModuleId ( it) => it. resolver ( db. upcast ( ) ) ,
90+ AttrDefId :: FieldId ( it) => it. parent . resolver ( db. upcast ( ) ) ,
91+ AttrDefId :: AdtId ( it) => it. resolver ( db. upcast ( ) ) ,
92+ AttrDefId :: FunctionId ( it) => it. resolver ( db. upcast ( ) ) ,
93+ AttrDefId :: EnumVariantId ( it) => it. parent . resolver ( db. upcast ( ) ) ,
94+ AttrDefId :: StaticId ( it) => it. resolver ( db. upcast ( ) ) ,
95+ AttrDefId :: ConstId ( it) => it. resolver ( db. upcast ( ) ) ,
96+ AttrDefId :: TraitId ( it) => it. resolver ( db. upcast ( ) ) ,
97+ AttrDefId :: TypeAliasId ( it) => it. resolver ( db. upcast ( ) ) ,
98+ AttrDefId :: ImplId ( it) => it. resolver ( db. upcast ( ) ) ,
99+ AttrDefId :: MacroDefId ( _) => return None ,
100+ } ;
101+ let path = ast:: Path :: parse ( link) . ok ( ) ?;
102+ let modpath = ModPath :: from_src ( path, & Hygiene :: new_unhygienic ( ) ) . unwrap ( ) ;
103+ let resolved = resolver. resolve_module_path_in_items ( db. upcast ( ) , & modpath) ;
104+ let def = match ns {
105+ Some ( Namespace :: Types ) => resolved. take_types ( ) ?,
106+ Some ( Namespace :: Values ) => resolved. take_values ( ) ?,
107+ Some ( Namespace :: Macros ) => return None ,
108+ None => resolved. iter_items ( ) . find_map ( |it| it. as_module_def_id ( ) ) ?,
109+ } ;
110+ Some ( def. into ( ) )
136111}
0 commit comments