1
1
//! Attributes & documentation for hir types.
2
2
use 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 ,
7
4
} ;
5
+ use hir_expand:: hygiene:: Hygiene ;
8
6
use hir_ty:: db:: HirDatabase ;
7
+ use syntax:: ast;
9
8
10
9
use 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 ,
13
12
} ;
14
13
15
14
pub trait HasAttrs {
16
15
fn attrs ( self , db : & dyn HirDatabase ) -> Attrs ;
17
16
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 ,
18
30
}
19
31
20
32
macro_rules! impl_has_attrs {
@@ -28,6 +40,10 @@ macro_rules! impl_has_attrs {
28
40
let def = AttrDefId :: $def_id( self . into( ) ) ;
29
41
db. documentation( def)
30
42
}
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
+ }
31
47
}
32
48
) * } ;
33
49
}
@@ -54,83 +70,42 @@ macro_rules! impl_has_attrs_adt {
54
70
fn docs( self , db: & dyn HirDatabase ) -> Option <Documentation > {
55
71
Adt :: $adt( self ) . docs( db)
56
72
}
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
+ }
57
76
}
58
77
) * } ;
59
78
}
60
79
61
80
impl_has_attrs_adt ! [ Struct , Union , Enum ] ;
62
81
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 ( ) )
136
111
}
0 commit comments