@@ -161,6 +161,16 @@ pub struct HirReturn {
161161 pub proof : HirReturnProof ,
162162}
163163
164+ #[ derive( Debug , Clone , PartialEq , Eq , Default ) ]
165+ pub struct HirFunctionBody {
166+ pub function_name : String ,
167+ pub bindings : Vec < HirBinding > ,
168+ pub call_sites : Vec < HirCallSite > ,
169+ pub field_accesses : Vec < HirFieldAccess > ,
170+ pub effect_events : Vec < HirEffectEvent > ,
171+ pub returns : Vec < HirReturn > ,
172+ }
173+
164174#[ derive( Debug , Default ) ]
165175pub struct Hir {
166176 signatures : HashMap < String , FunctionSig > ,
@@ -171,13 +181,13 @@ pub struct Hir {
171181 call_resolutions_by_span : HashMap < Span , CallResolution > ,
172182 bindings : Vec < HirBinding > ,
173183 bindings_by_span : HashMap < Span , HirBinding > ,
174- bindings_by_function : HashMap < String , Vec < HirBinding > > ,
175184 field_accesses : Vec < HirFieldAccess > ,
176185 field_accesses_by_span : HashMap < Span , HirFieldAccess > ,
177186 effect_events : Vec < HirEffectEvent > ,
178187 effect_events_by_span : HashMap < Span , Vec < HirEffectEvent > > ,
179188 returns : Vec < HirReturn > ,
180189 returns_by_span : HashMap < Span , HirReturn > ,
190+ function_bodies : HashMap < String , HirFunctionBody > ,
181191}
182192
183193impl Hir {
@@ -262,10 +272,8 @@ impl Hir {
262272 self . bindings_by_span . get ( span)
263273 }
264274
265- pub fn function_bindings ( & self , function_name : & str ) -> & [ HirBinding ] {
266- self . bindings_by_function
267- . get ( function_name)
268- . map_or ( & [ ] , Vec :: as_slice)
275+ pub fn function_body ( & self , function_name : & str ) -> Option < & HirFunctionBody > {
276+ self . function_bodies . get ( function_name)
269277 }
270278
271279 pub fn field_access ( & self , span : & Span ) -> Option < & HirFieldAccess > {
@@ -354,16 +362,6 @@ impl Hir {
354362 . iter ( )
355363 . map ( |binding| ( binding. span . clone ( ) , binding. clone ( ) ) )
356364 . collect ( ) ;
357- self . bindings_by_function = facts. bindings . iter ( ) . fold (
358- HashMap :: < String , Vec < HirBinding > > :: new ( ) ,
359- |mut by_function, binding| {
360- by_function
361- . entry ( binding. function_name . clone ( ) )
362- . or_default ( )
363- . push ( binding. clone ( ) ) ;
364- by_function
365- } ,
366- ) ;
367365 self . field_accesses_by_span = facts
368366 . field_accesses
369367 . iter ( )
@@ -384,6 +382,7 @@ impl Hir {
384382 . iter ( )
385383 . map ( |return_fact| ( return_fact. span . clone ( ) , return_fact. clone ( ) ) )
386384 . collect ( ) ;
385+ self . function_bodies = build_function_bodies ( & facts) ;
387386 self . call_sites = facts. call_sites ;
388387 self . bindings = facts. bindings ;
389388 self . field_accesses = facts. field_accesses ;
@@ -392,6 +391,48 @@ impl Hir {
392391 }
393392}
394393
394+ fn build_function_bodies ( facts : & BodyFacts ) -> HashMap < String , HirFunctionBody > {
395+ let mut bodies = HashMap :: < String , HirFunctionBody > :: new ( ) ;
396+ for binding in & facts. bindings {
397+ body_entry ( & mut bodies, & binding. function_name )
398+ . bindings
399+ . push ( binding. clone ( ) ) ;
400+ }
401+ for site in & facts. call_sites {
402+ body_entry ( & mut bodies, & site. function_name )
403+ . call_sites
404+ . push ( site. clone ( ) ) ;
405+ }
406+ for field in & facts. field_accesses {
407+ body_entry ( & mut bodies, & field. function_name )
408+ . field_accesses
409+ . push ( field. clone ( ) ) ;
410+ }
411+ for event in & facts. effect_events {
412+ body_entry ( & mut bodies, & event. function_name )
413+ . effect_events
414+ . push ( event. clone ( ) ) ;
415+ }
416+ for return_fact in & facts. returns {
417+ body_entry ( & mut bodies, & return_fact. function_name )
418+ . returns
419+ . push ( return_fact. clone ( ) ) ;
420+ }
421+ bodies
422+ }
423+
424+ fn body_entry < ' a > (
425+ bodies : & ' a mut HashMap < String , HirFunctionBody > ,
426+ function_name : & str ,
427+ ) -> & ' a mut HirFunctionBody {
428+ bodies
429+ . entry ( function_name. to_string ( ) )
430+ . or_insert_with ( || HirFunctionBody {
431+ function_name : function_name. to_string ( ) ,
432+ ..HirFunctionBody :: default ( )
433+ } )
434+ }
435+
395436#[ derive( Default ) ]
396437struct BodyFacts {
397438 call_sites : Vec < HirCallSite > ,
@@ -1398,7 +1439,10 @@ fn render(body: read String) -> Result<fresh Response, HttpError> {
13981439 ) ) ;
13991440 assert ! ( matches!( sites[ 2 ] . resolution, CallResolution :: Unknown ) ) ;
14001441
1401- let bindings = hir. function_bindings ( "render" ) ;
1442+ let bindings = & hir
1443+ . function_body ( "render" )
1444+ . expect ( "render body exists" )
1445+ . bindings ;
14021446 assert_eq ! ( bindings. len( ) , 2 ) ;
14031447 assert_eq ! ( bindings[ 0 ] . kind, HirBindingKind :: Param ) ;
14041448 assert_eq ! ( bindings[ 0 ] . name, "body" ) ;
@@ -1426,6 +1470,13 @@ fn render(body: read String) -> Result<fresh Response, HttpError> {
14261470 . proof,
14271471 HirReturnProof :: Ident { .. }
14281472 ) ) ;
1473+
1474+ let body = hir. function_body ( "render" ) . expect ( "function body exists" ) ;
1475+ assert_eq ! ( body. function_name, "render" ) ;
1476+ assert_eq ! ( body. bindings. len( ) , 2 ) ;
1477+ assert_eq ! ( body. call_sites. len( ) , 3 ) ;
1478+ assert_eq ! ( body. effect_events. len( ) , 0 ) ;
1479+ assert_eq ! ( body. returns. len( ) , 1 ) ;
14291480 }
14301481
14311482 #[ test]
@@ -1440,7 +1491,10 @@ fn load(path: read Path) -> Unit {
14401491
14411492 let program = parse_source ( "test.rss" , source) ;
14421493 let hir = Hir :: from_syntax ( & program) ;
1443- let bindings = hir. function_bindings ( "load" ) ;
1494+ let bindings = & hir
1495+ . function_body ( "load" )
1496+ . expect ( "load body exists" )
1497+ . bindings ;
14441498
14451499 assert_eq ! ( bindings. len( ) , 2 ) ;
14461500 assert_eq ! ( bindings[ 1 ] . kind, HirBindingKind :: LocalLet ) ;
0 commit comments