@@ -519,6 +519,192 @@ fn can_create_partial_path_from_node() {
519519 ) ;
520520}
521521
522+ #[ test]
523+ fn can_append_edges ( ) -> Result < ( ) , PathResolutionError > {
524+ let mut graph = StackGraph :: new ( ) ;
525+ let file = graph. add_file ( "test" ) . expect ( "" ) ;
526+ let jump_to_scope_node = StackGraph :: jump_to_node ( ) ;
527+ let scope0 = create_scope_node ( & mut graph, file, false ) ;
528+ let scope1 = create_scope_node ( & mut graph, file, false ) ;
529+ let foo_ref = create_push_symbol_node ( & mut graph, file, "foo" , false ) ;
530+ let foo_def = create_pop_symbol_node ( & mut graph, file, "foo" , false ) ;
531+ let bar_ref = create_push_symbol_node ( & mut graph, file, "bar" , false ) ;
532+ let bar_def = create_pop_symbol_node ( & mut graph, file, "bar" , false ) ;
533+ let exported_scope = create_scope_node ( & mut graph, file, true ) ;
534+ let exported_scope_id = graph[ exported_scope] . id ( ) ;
535+ let baz_ref = create_push_scoped_symbol_node ( & mut graph, file, "baz" , exported_scope_id, false ) ;
536+ let baz_def = create_pop_scoped_symbol_node ( & mut graph, file, "baz" , false ) ;
537+ let drop_scopes = create_drop_scopes_node ( & mut graph, file) ;
538+
539+ fn run (
540+ graph : & StackGraph ,
541+ left : NicePartialPath ,
542+ right : NiceEdge ,
543+ expected : & str ,
544+ ) -> Result < ( ) , PathResolutionError > {
545+ let mut g = StackGraph :: new ( ) ;
546+ g. add_from_graph ( graph) . expect ( "" ) ;
547+
548+ let mut ps = PartialPaths :: new ( ) ;
549+
550+ let mut l = create_partial_path_and_edges ( & mut g, & mut ps, left) . expect ( "" ) ;
551+ let r = create_edge ( & mut g, right) ;
552+
553+ l. append ( graph, & mut ps, r) ?;
554+ let actual = l. display ( & g, & mut ps) . to_string ( ) ;
555+ assert_eq ! ( expected, actual) ;
556+
557+ Ok ( ( ) )
558+ }
559+
560+ fn verify ( graph : & StackGraph , left : NicePartialPath , right : NiceEdge , expected : & str ) {
561+ run ( graph, left, right, expected) . expect ( "" ) ;
562+ }
563+
564+ fn verify_not ( graph : & StackGraph , left : NicePartialPath , right : NiceEdge ) {
565+ run ( graph, left, right, "" ) . expect_err ( "" ) ;
566+ }
567+
568+ verify (
569+ & graph,
570+ & [ foo_ref, scope0] ,
571+ ( scope0, foo_def) ,
572+ "<%1> ($1) [test(2) push foo] -> [test(3) pop foo] <%1> ($1)" ,
573+ ) ;
574+
575+ verify (
576+ & graph,
577+ & [ foo_ref, scope0] ,
578+ ( scope0, scope1) ,
579+ "<%1> ($1) [test(2) push foo] -> [test(1) scope] <foo,%1> ($1)" ,
580+ ) ;
581+
582+ verify (
583+ & graph,
584+ & [ scope0, scope1] ,
585+ ( scope1, foo_ref) ,
586+ "<%1> ($1) [test(0) scope] -> [test(2) push foo] <foo,%1> ($1)" ,
587+ ) ;
588+
589+ verify (
590+ & graph,
591+ & [ foo_def, scope0] ,
592+ ( scope0, bar_ref) ,
593+ "<foo,%1> ($1) [test(3) pop foo] -> [test(4) push bar] <bar,%1> ($1)" ,
594+ ) ;
595+
596+ verify (
597+ & graph,
598+ & [ foo_ref, scope0, foo_def] ,
599+ ( foo_def, bar_ref) ,
600+ "<%1> ($1) [test(2) push foo] -> [test(4) push bar] <bar,%1> ($1)" ,
601+ ) ;
602+
603+ verify (
604+ & graph,
605+ & [ foo_def, scope0, bar_ref] ,
606+ ( bar_ref, bar_def) ,
607+ "<foo,%1> ($1) [test(3) pop foo] -> [test(5) pop bar] <%1> ($1)" ,
608+ ) ;
609+
610+ verify (
611+ & graph,
612+ & [ baz_ref, scope0, baz_def] ,
613+ ( baz_def, bar_ref) ,
614+ "<%1> ($1) [test(7) push scoped baz test(6)] -> [test(4) push bar] <bar,%1> ([test(6)],$1)" ,
615+ ) ;
616+
617+ verify (
618+ & graph,
619+ & [ foo_def, scope0, baz_ref] ,
620+ ( baz_ref, baz_def) ,
621+ "<foo,%1> ($1) [test(3) pop foo] -> [test(8) pop scoped baz] <%1> ([test(6)],$1)" ,
622+ ) ;
623+
624+ verify (
625+ & graph,
626+ & [ scope0, drop_scopes] ,
627+ ( drop_scopes, scope1) ,
628+ "<%1> ($1) [test(0) scope] -> [test(1) scope] <%1> ()" ,
629+ ) ;
630+
631+ verify_not (
632+ & graph,
633+ & [ scope0, drop_scopes, scope1] ,
634+ ( scope1, jump_to_scope_node) ,
635+ ) ;
636+
637+ verify (
638+ & graph,
639+ & [ baz_def, scope0] ,
640+ ( scope0, jump_to_scope_node) ,
641+ "<baz/($2),%1> ($1) [test(8) pop scoped baz] -> [jump to scope] <%1> ($2)" ,
642+ ) ;
643+
644+ verify (
645+ & graph,
646+ & [ baz_ref, scope0] ,
647+ ( scope0, jump_to_scope_node) ,
648+ "<%1> ($1) [test(7) push scoped baz test(6)] -> [jump to scope] <baz/([test(6)],$1),%1> ($1)" ,
649+ ) ;
650+
651+ Ok ( ( ) )
652+ }
653+
654+ #[ test]
655+ fn can_append_edges_without_precondition_variables ( ) -> Result < ( ) , PathResolutionError > {
656+ let mut graph = StackGraph :: new ( ) ;
657+ let file = graph. add_file ( "test" ) . expect ( "" ) ;
658+ let scope0 = create_scope_node ( & mut graph, file, false ) ;
659+ let foo_ref = create_push_symbol_node ( & mut graph, file, "foo" , false ) ;
660+ let foo_def = create_pop_symbol_node ( & mut graph, file, "foo" , false ) ;
661+ let bar_ref = create_push_symbol_node ( & mut graph, file, "bar" , false ) ;
662+ let bar_def = create_pop_symbol_node ( & mut graph, file, "bar" , false ) ;
663+
664+ fn run (
665+ graph : & StackGraph ,
666+ left : NicePartialPath ,
667+ right : NiceEdge ,
668+ expected : & str ,
669+ ) -> Result < ( ) , PathResolutionError > {
670+ let mut g = StackGraph :: new ( ) ;
671+ g. add_from_graph ( graph) . expect ( "" ) ;
672+
673+ let mut ps = PartialPaths :: new ( ) ;
674+
675+ let mut l = create_partial_path_and_edges ( & mut g, & mut ps, left) . expect ( "" ) ;
676+ l. eliminate_precondition_stack_variables ( & mut ps) ;
677+ let r = create_edge ( & mut g, right) ;
678+
679+ l. append ( graph, & mut ps, r) ?;
680+ let actual = l. display ( & g, & mut ps) . to_string ( ) ;
681+ assert_eq ! ( expected, actual) ;
682+
683+ Ok ( ( ) )
684+ }
685+
686+ fn verify ( graph : & StackGraph , left : NicePartialPath , right : NiceEdge , expected : & str ) {
687+ run ( graph, left, right, expected) . expect ( "" ) ;
688+ }
689+
690+ fn verify_not ( graph : & StackGraph , left : NicePartialPath , right : NiceEdge ) {
691+ run ( graph, left, right, "" ) . expect_err ( "" ) ;
692+ }
693+
694+ verify (
695+ & graph,
696+ & [ foo_ref, scope0, foo_def] ,
697+ ( foo_def, bar_ref) ,
698+ "<> () [test(1) push foo] -> [test(3) push bar] <bar> ()" ,
699+ ) ;
700+
701+ verify_not ( & graph, & [ scope0] , ( scope0, bar_def) ) ;
702+
703+ verify_not ( & graph, & [ foo_ref, scope0, foo_def] , ( foo_def, bar_def) ) ;
704+
705+ Ok ( ( ) )
706+ }
707+
522708#[ test]
523709fn can_append_partial_paths ( ) -> Result < ( ) , PathResolutionError > {
524710 let mut graph = StackGraph :: new ( ) ;
@@ -658,24 +844,61 @@ fn can_append_partial_paths() -> Result<(), PathResolutionError> {
658844 "<%1> ($1) [test(7) push scoped baz test(6)] -> [jump to scope] <baz/([test(6)],$1),%1> ($1)" ,
659845 ) ;
660846
661- // verify that without stack variables in the precondition, the precondition cannot grow because of concatenation
662- {
663- let left = & [ scope0] ;
664- let right = & [ scope0, bar_def] ;
847+ Ok ( ( ) )
848+ }
665849
850+ #[ test]
851+ fn can_append_partial_paths_without_precondition_variables ( ) -> Result < ( ) , PathResolutionError > {
852+ let mut graph = StackGraph :: new ( ) ;
853+ let file = graph. add_file ( "test" ) . expect ( "" ) ;
854+ let scope0 = create_scope_node ( & mut graph, file, false ) ;
855+ let foo_ref = create_push_symbol_node ( & mut graph, file, "foo" , false ) ;
856+ let foo_def = create_pop_symbol_node ( & mut graph, file, "foo" , false ) ;
857+ let bar_ref = create_push_symbol_node ( & mut graph, file, "bar" , false ) ;
858+ let bar_def = create_pop_symbol_node ( & mut graph, file, "bar" , false ) ;
859+
860+ fn run (
861+ graph : & StackGraph ,
862+ left : NicePartialPath ,
863+ right : NicePartialPath ,
864+ expected : & str ,
865+ ) -> Result < ( ) , PathResolutionError > {
666866 let mut g = StackGraph :: new ( ) ;
667- g. add_from_graph ( & graph) . expect ( "" ) ;
867+ g. add_from_graph ( graph) . expect ( "" ) ;
668868
669869 let mut ps = PartialPaths :: new ( ) ;
870+
670871 let mut l = create_partial_path_and_edges ( & mut g, & mut ps, left) . expect ( "" ) ;
671872 l. eliminate_precondition_stack_variables ( & mut ps) ;
672873 let mut r = create_partial_path_and_edges ( & mut g, & mut ps, right) . expect ( "" ) ;
673874
674875 r. ensure_no_overlapping_variables ( & mut ps, & l) ;
675- let result = l. concatenate ( & g, & mut ps, & r) ;
676- result. expect_err ( "" ) ;
876+ l. concatenate ( & g, & mut ps, & r) ?;
877+ let actual = l. display ( & g, & mut ps) . to_string ( ) ;
878+ assert_eq ! ( expected, actual) ;
879+
880+ Ok ( ( ) )
881+ }
882+
883+ fn verify ( graph : & StackGraph , left : NicePartialPath , right : NicePartialPath , expected : & str ) {
884+ run ( graph, left, right, expected) . expect ( "" ) ;
885+ }
886+
887+ fn verify_not ( graph : & StackGraph , left : NicePartialPath , right : NicePartialPath ) {
888+ run ( graph, left, right, "" ) . expect_err ( "" ) ;
677889 }
678890
891+ verify (
892+ & graph,
893+ & [ foo_ref, scope0] ,
894+ & [ scope0, foo_def, bar_ref] ,
895+ "<> () [test(1) push foo] -> [test(3) push bar] <bar> ()" ,
896+ ) ;
897+
898+ verify_not ( & graph, & [ scope0] , & [ scope0, bar_def] ) ;
899+
900+ verify_not ( & graph, & [ foo_ref, scope0, foo_def] , & [ foo_def, bar_def] ) ;
901+
679902 Ok ( ( ) )
680903}
681904
0 commit comments