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