@@ -7,8 +7,8 @@ use itertools::Itertools;
77use log:: { info, warn} ;
88use ra_ap_base_db:: { CrateId , SourceDatabase } ;
99use ra_ap_cfg:: CfgAtom ;
10- use ra_ap_hir:: db:: DefDatabase ;
11- use ra_ap_hir:: { DefMap , Semantics } ;
10+ use ra_ap_hir:: db:: { DefDatabase , HirDatabase } ;
11+ use ra_ap_hir:: { DefMap , ModPath , ModuleDefId , Semantics , TypeRef , Variant } ;
1212use ra_ap_hir_def:: LocalModuleId ;
1313use ra_ap_ide_db:: line_index:: { LineCol , LineIndex } ;
1414use ra_ap_ide_db:: RootDatabase ;
@@ -39,6 +39,203 @@ struct Extractor<'a> {
3939 steps : Vec < ExtractionStep > ,
4040}
4141
42+ fn emit_hir_path (
43+ trap : & mut TrapFile ,
44+ path : & ra_ap_hir_def:: path:: Path ,
45+ ) -> trap:: Label < generated:: Path > {
46+ let part = path. segments ( ) . last ( ) . map ( |segment| {
47+ let name_ref = trap. emit ( generated:: NameRef {
48+ id : trap:: TrapId :: Star ,
49+ text : Some ( segment. name . as_str ( ) . to_owned ( ) ) ,
50+ } ) ;
51+ trap. emit ( generated:: PathSegment {
52+ id : trap:: TrapId :: Star ,
53+ generic_arg_list : None ,
54+ name_ref : Some ( name_ref) ,
55+ param_list : None ,
56+ path_type : None ,
57+ ret_type : None ,
58+ return_type_syntax : None ,
59+ type_repr : None ,
60+ } )
61+ } ) ;
62+ let qualifier = path
63+ . mod_path ( )
64+ . filter ( |p| !p. segments ( ) . is_empty ( ) )
65+ . and_then ( |_| path. qualifier ( ) . as_ref ( ) . map ( |p| emit_hir_path ( trap, p) ) ) ;
66+ trap. emit ( generated:: Path {
67+ id : trap:: TrapId :: Star ,
68+ qualifier,
69+ part,
70+ } )
71+ }
72+ fn emit_hir_fn (
73+ trap : & mut TrapFile ,
74+ self_type : Option < & TypeRef > ,
75+ params : & [ & TypeRef ] ,
76+ ret_type : & TypeRef ,
77+ is_async : bool ,
78+ is_const : bool ,
79+ is_unsafe : bool ,
80+ ) -> trap:: Label < generated:: FnPtrTypeRepr > {
81+ let ret = emit_hir_typeref ( trap, ret_type) ;
82+
83+ let ret = trap. emit ( generated:: RetTypeRepr {
84+ id : trap:: TrapId :: Star ,
85+ type_repr : ret,
86+ } ) ;
87+ let self_param = self_type. map ( |ty| {
88+ let type_repr = emit_hir_typeref ( trap, ty) ;
89+ trap. emit ( generated:: SelfParam {
90+ id : trap:: TrapId :: Star ,
91+ attrs : vec ! [ ] ,
92+ type_repr,
93+ is_mut : false ,
94+ lifetime : None ,
95+ name : None ,
96+ } )
97+ } ) ;
98+ let params = params
99+ . iter ( )
100+ . map ( |t| {
101+ let type_repr = emit_hir_typeref ( trap, t) ;
102+ trap. emit ( generated:: Param {
103+ id : trap:: TrapId :: Star ,
104+ attrs : vec ! [ ] ,
105+ type_repr,
106+ pat : None ,
107+ } )
108+ } )
109+ . collect ( ) ;
110+ let params = trap. emit ( generated:: ParamList {
111+ id : trap:: TrapId :: Star ,
112+ params,
113+ self_param,
114+ } ) ;
115+ trap. emit ( generated:: FnPtrTypeRepr {
116+ id : trap:: TrapId :: Star ,
117+ abi : None ,
118+ is_async,
119+ is_const,
120+ is_unsafe,
121+ param_list : Some ( params) ,
122+ ret_type : Some ( ret) ,
123+ } )
124+ }
125+ fn emit_hir_typeref ( trap : & mut TrapFile , ty : & TypeRef ) -> Option < trap:: Label < generated:: TypeRepr > > {
126+ match ty {
127+ TypeRef :: Never => Some (
128+ trap. emit ( generated:: NeverTypeRepr {
129+ id : trap:: TrapId :: Star ,
130+ } )
131+ . into ( ) ,
132+ ) ,
133+ TypeRef :: Placeholder => Some (
134+ trap. emit ( generated:: InferTypeRepr {
135+ id : trap:: TrapId :: Star ,
136+ } )
137+ . into ( ) ,
138+ ) ,
139+ TypeRef :: Tuple ( fields) => {
140+ let fields = fields
141+ . iter ( )
142+ . flat_map ( |field| emit_hir_typeref ( trap, field) )
143+ . collect ( ) ;
144+ Some (
145+ trap. emit ( generated:: TupleTypeRepr {
146+ id : trap:: TrapId :: Star ,
147+ fields,
148+ } )
149+ . into ( ) ,
150+ )
151+ }
152+ TypeRef :: RawPtr ( type_ref, mutability) => {
153+ let type_repr = emit_hir_typeref ( trap, type_ref) ;
154+ Some (
155+ trap. emit ( generated:: PtrTypeRepr {
156+ id : trap:: TrapId :: Star ,
157+ is_const : mutability. is_shared ( ) ,
158+ is_mut : mutability. is_mut ( ) ,
159+ type_repr,
160+ } )
161+ . into ( ) ,
162+ )
163+ }
164+ TypeRef :: Reference ( type_ref, lifetime_ref, mutability) => {
165+ let type_repr = emit_hir_typeref ( trap, type_ref) ;
166+ let lifetime = lifetime_ref. as_ref ( ) . map ( |x| {
167+ trap. emit ( generated:: Lifetime {
168+ id : trap:: TrapId :: Star ,
169+ text : Some ( x. name . as_str ( ) . to_owned ( ) ) ,
170+ } )
171+ } ) ;
172+ Some (
173+ trap. emit ( generated:: RefTypeRepr {
174+ id : trap:: TrapId :: Star ,
175+ is_mut : mutability. is_mut ( ) ,
176+ type_repr,
177+ lifetime,
178+ } )
179+ . into ( ) ,
180+ )
181+ }
182+ TypeRef :: Array ( type_ref, _const_ref) => {
183+ let element_type_repr = emit_hir_typeref ( trap, type_ref) ;
184+ // TODO: handle array size constant
185+ let const_arg = None ;
186+ Some (
187+ trap. emit ( generated:: ArrayTypeRepr {
188+ id : trap:: TrapId :: Star ,
189+ element_type_repr,
190+ const_arg,
191+ } )
192+ . into ( ) ,
193+ )
194+ }
195+ TypeRef :: Slice ( type_ref) => {
196+ let type_repr = emit_hir_typeref ( trap, type_ref) ;
197+ Some (
198+ trap. emit ( generated:: SliceTypeRepr {
199+ id : trap:: TrapId :: Star ,
200+ type_repr,
201+ } )
202+ . into ( ) ,
203+ )
204+ }
205+ TypeRef :: Fn ( params, _, is_unsafe, _symbol) => {
206+ let ( ret_type, params) = params. split_last ( ) . unwrap ( ) ;
207+ let params: Vec < _ > = params. as_ref ( ) . iter ( ) . map ( |x| & x. 1 ) . collect ( ) ;
208+ Some (
209+ emit_hir_fn (
210+ trap,
211+ None ,
212+ & params[ ..] ,
213+ & ret_type. 1 ,
214+ false ,
215+ false ,
216+ * is_unsafe,
217+ )
218+ . into ( ) ,
219+ )
220+ }
221+ TypeRef :: Path ( path) => {
222+ let path = Some ( emit_hir_path ( trap, path) ) ;
223+
224+ Some (
225+ trap. emit ( generated:: PathTypeRepr {
226+ id : trap:: TrapId :: Star ,
227+ path,
228+ } )
229+ . into ( ) ,
230+ )
231+ }
232+ TypeRef :: ImplTrait ( _) => None , // TODO handle impl
233+ TypeRef :: DynTrait ( _) => None , // TODO handle dyn
234+ TypeRef :: Macro ( _) => None ,
235+ TypeRef :: Error => None ,
236+ }
237+ }
238+
42239impl < ' a > Extractor < ' a > {
43240 pub fn new ( archiver : & ' a Archiver , traps : & ' a trap:: TrapFileProvider ) -> Self {
44241 Self {
@@ -237,18 +434,130 @@ impl<'a> Extractor<'a> {
237434 trap. commit ( ) ;
238435
239436 fn go (
240- db : & dyn DefDatabase ,
437+ db : & dyn HirDatabase ,
241438 map : & DefMap ,
242439 parent : trap:: Label < generated:: ModuleContainer > ,
243440 name : & str ,
244441 module : LocalModuleId ,
245442 trap : & mut TrapFile ,
246443 ) {
247444 let module = & map. modules [ module] ;
445+ let items = & module. scope ;
446+ let mut values = Vec :: new ( ) ;
447+
448+ for ( name, item) in items. entries ( ) {
449+ let def = item. with_visibility ( ra_ap_hir:: Visibility :: Public ) ;
450+ if let Some ( ( value, _, _import) ) = def. values {
451+ match value {
452+ ModuleDefId :: FunctionId ( function) => {
453+ let function = db. function_data ( function) ;
454+ let params: Vec < _ > =
455+ function. params . iter ( ) . map ( |x| x. as_ref ( ) ) . collect ( ) ;
456+ let ( self_type, params) = if function. has_self_param ( ) {
457+ ( Some ( params[ 0 ] ) , & params[ 1 ..] )
458+ } else {
459+ ( None , & params[ ..] )
460+ } ;
461+ let ret_type = function. ret_type . as_ref ( ) ;
462+ let type_ = emit_hir_fn (
463+ trap,
464+ self_type,
465+ params,
466+ ret_type,
467+ function. is_async ( ) ,
468+ function. is_const ( ) ,
469+ function. is_unsafe ( ) ,
470+ )
471+ . into ( ) ;
472+
473+ values. push ( trap. emit ( generated:: ValueItem {
474+ id : trap:: TrapId :: Star ,
475+ name : name. as_str ( ) . to_owned ( ) ,
476+ type_,
477+ } ) ) ;
478+ }
479+ ModuleDefId :: ConstId ( konst) => {
480+ let konst = db. const_data ( konst) ;
481+ if let Some ( type_) = emit_hir_typeref ( trap, & konst. type_ref ) {
482+ values. push ( trap. emit ( generated:: ValueItem {
483+ id : trap:: TrapId :: Star ,
484+ name : name. as_str ( ) . to_owned ( ) ,
485+ type_,
486+ } ) ) ;
487+ }
488+ }
489+ ModuleDefId :: StaticId ( statik) => {
490+ let statik = db. static_data ( statik) ;
491+ if let Some ( type_) = emit_hir_typeref ( trap, & statik. type_ref ) {
492+ values. push ( trap. emit ( generated:: ValueItem {
493+ id : trap:: TrapId :: Star ,
494+ name : name. as_str ( ) . to_owned ( ) ,
495+ type_,
496+ } ) ) ;
497+ }
498+ }
499+ ModuleDefId :: EnumVariantId ( variant_id) => {
500+ let variant: Variant = variant_id. into ( ) ;
501+ let tp = variant. parent_enum ( db) ;
502+ let mut mod_path = ModPath :: from_kind ( ra_ap_hir:: PathKind :: Abs ) ;
503+
504+ mod_path. extend (
505+ tp. module ( db)
506+ . path_to_root ( db)
507+ . iter ( )
508+ . flat_map ( |x| x. name ( db) ) ,
509+ ) ;
510+ mod_path. push_segment ( tp. name ( db) ) ;
511+ let ret_type = TypeRef :: Path (
512+ ra_ap_hir_def:: path:: Path :: from_known_path_with_no_generic (
513+ mod_path,
514+ ) ,
515+ ) ;
516+ //
517+ let variant_data = db. enum_variant_data ( variant_id) ;
518+ let type_ = match variant_data. variant_data . as_ref ( ) {
519+ ra_ap_hir_def:: data:: adt:: VariantData :: Unit => {
520+ emit_hir_typeref ( trap, & ret_type)
521+ }
522+ ra_ap_hir_def:: data:: adt:: VariantData :: Tuple ( arena) => {
523+ let params: Vec < _ > =
524+ arena. values ( ) . map ( |f| f. type_ref . as_ref ( ) ) . collect ( ) ;
525+ Some (
526+ emit_hir_fn (
527+ trap,
528+ None ,
529+ & params[ ..] ,
530+ & ret_type,
531+ false ,
532+ false ,
533+ false ,
534+ )
535+ . into ( ) ,
536+ )
537+ }
538+ ra_ap_hir_def:: data:: adt:: VariantData :: Record ( _) => {
539+ // record enums are not "values"
540+ None
541+ }
542+ } ;
543+ if let Some ( type_) = type_ {
544+ values. push ( trap. emit ( generated:: ValueItem {
545+ id : trap:: TrapId :: Star ,
546+ name : name. as_str ( ) . to_owned ( ) ,
547+ type_,
548+ } ) ) ;
549+ }
550+ }
551+ _ => ( ) ,
552+ }
553+ }
554+ if let Some ( ( _type_id, _, _import) ) = def. types { }
555+ }
248556 let label = trap. emit ( generated:: CrateModule {
249557 id : trap:: TrapId :: Star ,
250558 name : name. to_owned ( ) ,
251559 parent,
560+ values,
252561 } ) ;
253562 for ( name, child) in module
254563 . children
0 commit comments