@@ -578,7 +578,10 @@ function initSearch(rawSearchIndex) {
578
578
// Syntactically, bindings are parsed as generics,
579
579
// but the query engine treats them differently.
580
580
if ( gen . bindingName !== null ) {
581
- bindings . set ( gen . bindingName . name , [ gen , ...gen . bindingName . generics ] ) ;
581
+ if ( gen . name !== null ) {
582
+ gen . bindingName . generics . unshift ( gen ) ;
583
+ }
584
+ bindings . set ( gen . bindingName . name , gen . bindingName . generics ) ;
582
585
return false ;
583
586
}
584
587
return true ;
@@ -678,6 +681,38 @@ function initSearch(rawSearchIndex) {
678
681
return end ;
679
682
}
680
683
684
+ function getFilteredNextElem ( query , parserState , elems , isInGenerics ) {
685
+ const start = parserState . pos ;
686
+ if ( parserState . userQuery [ parserState . pos ] === ":" && ! isPathStart ( parserState ) ) {
687
+ throw [ "Expected type filter before " , ":" ] ;
688
+ }
689
+ getNextElem ( query , parserState , elems , isInGenerics ) ;
690
+ if ( parserState . userQuery [ parserState . pos ] === ":" && ! isPathStart ( parserState ) ) {
691
+ if ( parserState . typeFilter !== null ) {
692
+ throw [
693
+ "Unexpected " ,
694
+ ":" ,
695
+ " (expected path after type filter " ,
696
+ parserState . typeFilter + ":" ,
697
+ ")" ,
698
+ ] ;
699
+ }
700
+ if ( elems . length === 0 ) {
701
+ throw [ "Expected type filter before " , ":" ] ;
702
+ } else if ( query . literalSearch ) {
703
+ throw [ "Cannot use quotes on type filter" ] ;
704
+ }
705
+ // The type filter doesn't count as an element since it's a modifier.
706
+ const typeFilterElem = elems . pop ( ) ;
707
+ checkExtraTypeFilterCharacters ( start , parserState ) ;
708
+ parserState . typeFilter = typeFilterElem . name ;
709
+ parserState . pos += 1 ;
710
+ parserState . totalElems -= 1 ;
711
+ query . literalSearch = false ;
712
+ getNextElem ( query , parserState , elems , isInGenerics ) ;
713
+ }
714
+ }
715
+
681
716
/**
682
717
* @param {ParsedQuery } query
683
718
* @param {ParserState } parserState
@@ -752,6 +787,32 @@ function initSearch(rawSearchIndex) {
752
787
}
753
788
parserState . pos += 1 ;
754
789
getItemsBefore ( query , parserState , generics , ">" ) ;
790
+ } else if ( parserState . pos < parserState . length &&
791
+ parserState . userQuery [ parserState . pos ] === "("
792
+ ) {
793
+ if ( start >= end ) {
794
+ throw [ "Found generics without a path" ] ;
795
+ }
796
+ if ( parserState . isInBinding ) {
797
+ throw [ "Unexpected " , "(" , " after " , "=" ] ;
798
+ }
799
+ parserState . pos += 1 ;
800
+ const typeFilter = parserState . typeFilter ;
801
+ parserState . typeFilter = null ;
802
+ getItemsBefore ( query , parserState , generics , ")" ) ;
803
+ skipWhitespace ( parserState ) ;
804
+ if ( isReturnArrow ( parserState ) ) {
805
+ parserState . pos += 2 ;
806
+ skipWhitespace ( parserState ) ;
807
+ getFilteredNextElem ( query , parserState , generics , isInGenerics ) ;
808
+ generics [ generics . length - 1 ] . bindingName = makePrimitiveElement ( "output" ) ;
809
+ } else {
810
+ generics . push ( makePrimitiveElement ( null , {
811
+ bindingName : makePrimitiveElement ( "output" ) ,
812
+ typeFilter : null ,
813
+ } ) ) ;
814
+ }
815
+ parserState . typeFilter = typeFilter ;
755
816
}
756
817
if ( isStringElem ) {
757
818
skipWhitespace ( parserState ) ;
@@ -811,7 +872,6 @@ function initSearch(rawSearchIndex) {
811
872
function getItemsBefore ( query , parserState , elems , endChar ) {
812
873
let foundStopChar = true ;
813
874
let foundSeparator = false ;
814
- let start = parserState . pos ;
815
875
816
876
// If this is a generic, keep the outer item's type filter around.
817
877
const oldTypeFilter = parserState . typeFilter ;
@@ -874,24 +934,6 @@ function initSearch(rawSearchIndex) {
874
934
continue ;
875
935
} else if ( c === ":" && isPathStart ( parserState ) ) {
876
936
throw [ "Unexpected " , "::" , ": paths cannot start with " , "::" ] ;
877
- } else if ( c === ":" ) {
878
- if ( parserState . typeFilter !== null ) {
879
- throw [ "Unexpected " , ":" ] ;
880
- }
881
- if ( elems . length === 0 ) {
882
- throw [ "Expected type filter before " , ":" ] ;
883
- } else if ( query . literalSearch ) {
884
- throw [ "Cannot use quotes on type filter" ] ;
885
- }
886
- // The type filter doesn't count as an element since it's a modifier.
887
- const typeFilterElem = elems . pop ( ) ;
888
- checkExtraTypeFilterCharacters ( start , parserState ) ;
889
- parserState . typeFilter = typeFilterElem . name ;
890
- parserState . pos += 1 ;
891
- parserState . totalElems -= 1 ;
892
- query . literalSearch = false ;
893
- foundStopChar = true ;
894
- continue ;
895
937
} else if ( isEndCharacter ( c ) ) {
896
938
throw [ "Unexpected " , c , " after " , extra ] ;
897
939
}
@@ -926,8 +968,7 @@ function initSearch(rawSearchIndex) {
926
968
] ;
927
969
}
928
970
const posBefore = parserState . pos ;
929
- start = parserState . pos ;
930
- getNextElem ( query , parserState , elems , endChar !== "" ) ;
971
+ getFilteredNextElem ( query , parserState , elems , endChar !== "" ) ;
931
972
if ( endChar !== "" && parserState . pos >= parserState . length ) {
932
973
throw [ "Unclosed " , extra ] ;
933
974
}
@@ -1004,7 +1045,6 @@ function initSearch(rawSearchIndex) {
1004
1045
*/
1005
1046
function parseInput ( query , parserState ) {
1006
1047
let foundStopChar = true ;
1007
- let start = parserState . pos ;
1008
1048
1009
1049
while ( parserState . pos < parserState . length ) {
1010
1050
const c = parserState . userQuery [ parserState . pos ] ;
@@ -1022,29 +1062,6 @@ function initSearch(rawSearchIndex) {
1022
1062
throw [ "Unexpected " , c , " after " , parserState . userQuery [ parserState . pos - 1 ] ] ;
1023
1063
}
1024
1064
throw [ "Unexpected " , c ] ;
1025
- } else if ( c === ":" && ! isPathStart ( parserState ) ) {
1026
- if ( parserState . typeFilter !== null ) {
1027
- throw [
1028
- "Unexpected " ,
1029
- ":" ,
1030
- " (expected path after type filter " ,
1031
- parserState . typeFilter + ":" ,
1032
- ")" ,
1033
- ] ;
1034
- } else if ( query . elems . length === 0 ) {
1035
- throw [ "Expected type filter before " , ":" ] ;
1036
- } else if ( query . literalSearch ) {
1037
- throw [ "Cannot use quotes on type filter" ] ;
1038
- }
1039
- // The type filter doesn't count as an element since it's a modifier.
1040
- const typeFilterElem = query . elems . pop ( ) ;
1041
- checkExtraTypeFilterCharacters ( start , parserState ) ;
1042
- parserState . typeFilter = typeFilterElem . name ;
1043
- parserState . pos += 1 ;
1044
- parserState . totalElems -= 1 ;
1045
- query . literalSearch = false ;
1046
- foundStopChar = true ;
1047
- continue ;
1048
1065
} else if ( c === " " ) {
1049
1066
skipWhitespace ( parserState ) ;
1050
1067
continue ;
@@ -1080,8 +1097,7 @@ function initSearch(rawSearchIndex) {
1080
1097
] ;
1081
1098
}
1082
1099
const before = query . elems . length ;
1083
- start = parserState . pos ;
1084
- getNextElem ( query , parserState , query . elems , false ) ;
1100
+ getFilteredNextElem ( query , parserState , query . elems , false ) ;
1085
1101
if ( query . elems . length === before ) {
1086
1102
// Nothing was added, weird... Let's increase the position to not remain stuck.
1087
1103
parserState . pos += 1 ;
0 commit comments