@@ -643,21 +643,112 @@ module TestPostProcessing {
643643
644644 module Make< InlineExpectationsTestSig Input, InputSig< Input > Input2> {
645645 private import InlineExpectationsTest as InlineExpectationsTest
646- private import InlineExpectationsTest:: Make< Input >
646+
647+ bindingset [ loc]
648+ private predicate parseLocationString (
649+ string loc , string relativePath , int sl , int sc , int el , int ec
650+ ) {
651+ relativePath = loc .splitAt ( ":" , 0 ) and
652+ sl = loc .splitAt ( ":" , 1 ) .toInt ( ) and
653+ sc = loc .splitAt ( ":" , 2 ) .toInt ( ) and
654+ el = loc .splitAt ( ":" , 3 ) .toInt ( ) and
655+ ec = loc .splitAt ( ":" , 4 ) .toInt ( )
656+ }
657+
658+ pragma [ nomagic]
659+ private string getRelativePathTo ( string absolutePath ) {
660+ exists ( Input:: Location loc |
661+ loc .hasLocationInfo ( absolutePath , _, _, _, _) and
662+ parseLocationString ( Input2:: getRelativeUrl ( loc ) , result , _, _, _, _)
663+ )
664+ }
665+
666+ private newtype TTestLocation =
667+ MkInputLocation ( Input:: Location loc ) or
668+ MkResultLocation ( string relativePath , int sl , int sc , int el , int ec ) {
669+ exists ( string data |
670+ queryResults ( _, _, _, data ) and
671+ parseLocationString ( data , relativePath , sl , sc , el , ec ) and
672+ not Input2:: getRelativeUrl ( _) = data // avoid duplicate locations
673+ )
674+ }
675+
676+ /**
677+ * A location that is either an `Input::Location` or a location from an alert.
678+ *
679+ * We use this location type to support queries that select a location that does not correspond
680+ * to an instance of `Input::Location`.
681+ */
682+ abstract private class TestLocationImpl extends TTestLocation {
683+ string getAbsoluteFile ( ) { this .hasLocationInfo ( result , _, _, _, _) }
684+
685+ int getStartLine ( ) { this .hasLocationInfo ( _, result , _, _, _) }
686+
687+ int getStartColumn ( ) { this .hasLocationInfo ( _, _, result , _, _) }
688+
689+ int getEndLine ( ) { this .hasLocationInfo ( _, _, _, result , _) }
690+
691+ int getEndColumn ( ) { this .hasLocationInfo ( _, _, _, _, result ) }
692+
693+ abstract string getRelativeUrl ( ) ;
694+
695+ final string toString ( ) { result = this .getRelativeUrl ( ) }
696+
697+ abstract predicate hasLocationInfo ( string file , int sl , int sc , int el , int ec ) ;
698+ }
699+
700+ private class LocationFromResult extends TestLocationImpl , MkResultLocation {
701+ override string getRelativeUrl ( ) {
702+ exists ( string file , int sl , int sc , int el , int ec |
703+ this = MkResultLocation ( file , sl , sc , el , ec ) and
704+ result = file + ":" + sl + ":" + sc + ":" + el + ":" + ec
705+ )
706+ }
707+
708+ override predicate hasLocationInfo ( string file , int sl , int sc , int el , int ec ) {
709+ this = MkResultLocation ( getRelativePathTo ( file ) , sl , sc , el , ec )
710+ }
711+ }
712+
713+ private class LocationFromInput extends TestLocationImpl , MkInputLocation {
714+ private Input:: Location loc ;
715+
716+ LocationFromInput ( ) { this = MkInputLocation ( loc ) }
717+
718+ override string getRelativeUrl ( ) { result = Input2:: getRelativeUrl ( loc ) }
719+
720+ override predicate hasLocationInfo ( string file , int sl , int sc , int el , int ec ) {
721+ loc .hasLocationInfo ( file , sl , sc , el , ec )
722+ }
723+ }
724+
725+ final class TestLocation = TestLocationImpl ;
726+
727+ module TestImpl2 implements InlineExpectationsTestSig {
728+ final class Location = TestLocation ;
729+
730+ final private class ExpectationCommentFinal = Input:: ExpectationComment ;
731+
732+ class ExpectationComment extends ExpectationCommentFinal {
733+ Location getLocation ( ) { result = MkInputLocation ( super .getLocation ( ) ) }
734+ }
735+ }
736+
737+ private import InlineExpectationsTest:: Make< TestImpl2 >
647738
648739 /** Holds if the given locations refer to the same lines, but possibly with different column numbers. */
649740 bindingset [ loc1, loc2]
650741 pragma [ inline_late]
651- private predicate sameLineInfo ( Input :: Location loc1 , Input :: Location loc2 ) {
742+ private predicate sameLineInfo ( TestLocation loc1 , TestLocation loc2 ) {
652743 exists ( string file , int line1 , int line2 |
653744 loc1 .hasLocationInfo ( file , line1 , _, line2 , _) and
654745 loc2 .hasLocationInfo ( file , line1 , _, line2 , _)
655746 )
656747 }
657748
658749 pragma [ nomagic]
659- private predicate mainQueryResult ( int row , int column , Input :: Location loc ) {
660- queryResults ( mainResultSet ( ) , row , column , Input2 :: getRelativeUrl ( loc ) )
750+ private predicate mainQueryResult ( int row , int column , TestLocation loc ) {
751+ queryResults ( mainResultSet ( ) , row , column , loc . getRelativeUrl ( ) )
661752 }
662753
663754 /**
@@ -668,7 +759,7 @@ module TestPostProcessing {
668759 */
669760 private string getSourceTag ( int row ) {
670761 getQueryKind ( ) = "path-problem" and
671- exists ( Input :: Location sourceLoc , Input :: Location selectLoc |
762+ exists ( TestLocation sourceLoc , TestLocation selectLoc |
672763 mainQueryResult ( row , 0 , selectLoc ) and
673764 mainQueryResult ( row , 2 , sourceLoc ) and
674765 if sameLineInfo ( selectLoc , sourceLoc ) then result = "Alert" else result = "Source"
@@ -733,7 +824,7 @@ module TestPostProcessing {
733824 }
734825
735826 additional predicate hasPathProblemSource (
736- int row , Input :: Location location , string element , string tag , string value
827+ int row , TestLocation location , string element , string tag , string value
737828 ) {
738829 getQueryKind ( ) = "path-problem" and
739830 mainQueryResult ( row , 2 , location ) and
@@ -742,7 +833,7 @@ module TestPostProcessing {
742833 value = ""
743834 }
744835
745- predicate hasActualResult ( Input :: Location location , string element , string tag , string value ) {
836+ predicate hasActualResult ( TestLocation location , string element , string tag , string value ) {
746837 hasPathProblemSource ( _, location , element , tag , value )
747838 }
748839 }
@@ -770,15 +861,15 @@ module TestPostProcessing {
770861 private predicate hasPathProblemSource = PathProblemSourceTestInput:: hasPathProblemSource / 5 ;
771862
772863 private predicate hasPathProblemSink (
773- int row , Input :: Location location , string element , string tag
864+ int row , TestLocation location , string element , string tag
774865 ) {
775866 getQueryKind ( ) = "path-problem" and
776867 mainQueryResult ( row , 4 , location ) and
777868 queryResults ( mainResultSet ( ) , row , 5 , element ) and
778869 tag = getSinkTag ( row )
779870 }
780871
781- private predicate hasAlert ( int row , Input :: Location location , string element , string tag ) {
872+ private predicate hasAlert ( int row , TestLocation location , string element , string tag ) {
782873 getQueryKind ( ) = [ "problem" , "path-problem" ] and
783874 mainQueryResult ( row , 0 , location ) and
784875 queryResults ( mainResultSet ( ) , row , 2 , element ) and
@@ -793,15 +884,15 @@ module TestPostProcessing {
793884 * present).
794885 */
795886 private string getValue ( int row ) {
796- exists ( Input :: Location location , string element , string tag , string val |
887+ exists ( TestLocation location , string element , string tag , string val |
797888 hasPathProblemSource ( row , location , element , tag , val ) and
798889 result =
799890 PathProblemSourceTest:: getAMatchingExpectation ( location , element , tag , val , false )
800891 .getValue ( )
801892 )
802893 }
803894
804- predicate hasActualResult ( Input :: Location location , string element , string tag , string value ) {
895+ predicate hasActualResult ( TestLocation location , string element , string tag , string value ) {
805896 exists ( int row |
806897 hasPathProblemSource ( row , location , element , tag , _)
807898 or
@@ -840,7 +931,7 @@ module TestPostProcessing {
840931 rankedTestFailures ( row , f ) and
841932 f = MkTestFailure ( fl , message )
842933 |
843- column = 0 and data = Input2 :: getRelativeUrl ( fl .getLocation ( ) )
934+ column = 0 and data = fl .getLocation ( ) . getRelativeUrl ( )
844935 or
845936 column = 1 and data = fl .toString ( )
846937 or
0 commit comments