@@ -172,7 +172,7 @@ window.initSearch = function(rawSearchIndex) {
172
172
throw new Error ( "`\"` cannot be used in generics" ) ;
173
173
} else if ( query . literalSearch ) {
174
174
throw new Error ( "Cannot have more than one literal search element" ) ;
175
- } else if ( parserState . totalElems !== 0 ) {
175
+ } else if ( parserState . totalElems - parserState . genericsElems > 0 ) {
176
176
throw new Error ( "Cannot use literal search when there is more than one element" ) ;
177
177
}
178
178
parserState . pos += 1 ;
@@ -234,11 +234,11 @@ window.initSearch = function(rawSearchIndex) {
234
234
*
235
235
* @return {QueryElement } - The newly created `QueryElement`.
236
236
*/
237
- function createQueryElement ( query , parserState , name , generics ) {
237
+ function createQueryElement ( query , parserState , name , generics , isInGenerics ) {
238
238
if ( name === '*' || ( name . length === 0 && generics . length === 0 ) ) {
239
239
return ;
240
240
}
241
- if ( query . literalSearch && parserState . totalElems > 0 ) {
241
+ if ( query . literalSearch && parserState . totalElems - parserState . genericsElems > 0 ) {
242
242
throw new Error ( "You cannot have more than one element if you use quotes" ) ;
243
243
}
244
244
var pathSegments = name . split ( "::" ) ;
@@ -261,6 +261,9 @@ window.initSearch = function(rawSearchIndex) {
261
261
throw new Error ( "Found generics without a path" ) ;
262
262
}
263
263
parserState . totalElems += 1 ;
264
+ if ( isInGenerics ) {
265
+ parserState . genericsElems += 1 ;
266
+ }
264
267
return {
265
268
name : name ,
266
269
fullPath : pathSegments ,
@@ -315,6 +318,8 @@ window.initSearch = function(rawSearchIndex) {
315
318
{
316
319
if ( isInGenerics ) {
317
320
throw new Error ( "Unexpected `<` after `<`" ) ;
321
+ } else if ( start >= end ) {
322
+ throw new Error ( "Found generics without a path" ) ;
318
323
}
319
324
parserState . pos += 1 ;
320
325
getItemsBefore ( query , parserState , generics , ">" ) ;
@@ -327,7 +332,8 @@ window.initSearch = function(rawSearchIndex) {
327
332
query ,
328
333
parserState ,
329
334
parserState . userQuery . slice ( start , end ) ,
330
- generics
335
+ generics ,
336
+ isInGenerics
331
337
)
332
338
) ;
333
339
}
@@ -346,13 +352,15 @@ window.initSearch = function(rawSearchIndex) {
346
352
* character.
347
353
*/
348
354
function getItemsBefore ( query , parserState , elems , endChar ) {
349
- var turns = 0 ;
355
+ var foundStopChar = true ;
356
+
350
357
while ( parserState . pos < parserState . length ) {
351
358
var c = parserState . userQuery [ parserState . pos ] ;
352
359
if ( c === endChar ) {
353
360
break ;
354
- } else if ( c === "," && endChar !== "" && turns > 0 ) {
361
+ } else if ( c === "," || c === " " ) {
355
362
parserState . pos += 1 ;
363
+ foundStopChar = true ;
356
364
continue ;
357
365
} else if ( c === ":" && isPathStart ( parserState ) ) {
358
366
throw new Error ( "Unexpected `::`: paths cannot start with `::`" ) ;
@@ -365,15 +373,21 @@ window.initSearch = function(rawSearchIndex) {
365
373
}
366
374
throw new Error ( "Unexpected `" + c + "` after " + extra ) ;
367
375
}
376
+ if ( ! foundStopChar ) {
377
+ if ( endChar !== "" ) {
378
+ throw new Error ( `Expected \`,\`, \` \` or \`${ endChar } \`, found \`${ c } \`` ) ;
379
+ }
380
+ throw new Error ( `Expected \`,\` or \` \`, found \`${ c } \`` ) ;
381
+ }
368
382
var posBefore = parserState . pos ;
369
383
getNextElem ( query , parserState , elems , endChar === ">" ) ;
370
- turns += 1 ;
371
384
// This case can be encountered if `getNextElem` encounted a "stop character" right from
372
- // the start. For example if you have `,,`. In this case, we simply move up the current
373
- // position to continue the parsing.
385
+ // the start. For example if you have `,,` or `<>` . In this case, we simply move up the
386
+ // current position to continue the parsing.
374
387
if ( posBefore === parserState . pos ) {
375
388
parserState . pos += 1 ;
376
389
}
390
+ foundStopChar = false ;
377
391
}
378
392
// We are either at the end of the string or on the `endChar`` character, let's move forward
379
393
// in any case.
@@ -389,10 +403,12 @@ window.initSearch = function(rawSearchIndex) {
389
403
*/
390
404
function parseInput ( query , parserState ) {
391
405
var c , before ;
406
+ var foundStopChar = true ;
392
407
393
408
while ( parserState . pos < parserState . length ) {
394
409
c = parserState . userQuery [ parserState . pos ] ;
395
410
if ( isStopCharacter ( c ) ) {
411
+ foundStopChar = true ;
396
412
if ( c === "," || c === " " ) {
397
413
parserState . pos += 1 ;
398
414
continue ;
@@ -402,6 +418,7 @@ window.initSearch = function(rawSearchIndex) {
402
418
}
403
419
throw new Error ( `Unexpected \`${ c } \` (did you mean \`->\`?)` ) ;
404
420
}
421
+ throw new Error ( `Unexpected \`${ c } \`` ) ;
405
422
} else if ( c === ":" &&
406
423
parserState . typeFilter === null &&
407
424
! isPathStart ( parserState ) )
@@ -419,8 +436,15 @@ window.initSearch = function(rawSearchIndex) {
419
436
parserState . pos += 1 ;
420
437
parserState . totalElems = 0 ;
421
438
query . literalSearch = false ;
439
+ foundStopChar = true ;
422
440
continue ;
423
441
}
442
+ if ( ! foundStopChar ) {
443
+ if ( parserState . typeFilter !== null ) {
444
+ throw new Error ( `Expected \`,\`, \` \` or \`->\`, found \`${ c } \`` ) ;
445
+ }
446
+ throw new Error ( `Expected \`,\`, \` \`, \`:\` or \`->\`, found \`${ c } \`` ) ;
447
+ }
424
448
before = query . elems . length ;
425
449
getNextElem ( query , parserState , query . elems , false ) ;
426
450
if ( query . elems . length === before ) {
@@ -432,6 +456,7 @@ window.initSearch = function(rawSearchIndex) {
432
456
}
433
457
parserState . pos += 1 ;
434
458
}
459
+ foundStopChar = false ;
435
460
}
436
461
while ( parserState . pos < parserState . length ) {
437
462
c = parserState . userQuery [ parserState . pos ] ;
@@ -515,17 +540,17 @@ window.initSearch = function(rawSearchIndex) {
515
540
* arg = path [generics]
516
541
* arg-without-generic = path
517
542
* type-sep = COMMA/WS *(COMMA/WS)
518
- * nonempty-arg-list = arg *(type-sep arg) *(COMMA/WS )
519
- * nonempty-arg-list-without-generics = arg-without-generic *(type-sep arg-without-generic)
520
- * *(COMMA/WS )
521
- * generics = OPEN-ANGLE-BRACKET *WS [ nonempty-arg-list-without-generics ] *WS
543
+ * nonempty-arg-list = *(type-sep) arg *(type-sep arg) *(type-sep )
544
+ * nonempty-arg-list-without-generics = *(type-sep) arg-without-generic
545
+ * *(type-sep arg-without-generic) *(type-sep )
546
+ * generics = OPEN-ANGLE-BRACKET [ nonempty-arg-list-without-generics ] *(type-sep)
522
547
* CLOSE-ANGLE-BRACKET
523
- * return-args = RETURN-ARROW *WS nonempty-arg-list
548
+ * return-args = RETURN-ARROW *(type-sep) nonempty-arg-list
524
549
*
525
- * exact-search = [type-filter *WS COLON] *WS QUOTE ident QUOTE *WS [ generics]
526
- * type-search = [type-filter *WS COLON] *WS path *WS nonempty-arg-list
550
+ * exact-search = [type-filter *WS COLON] [ RETURN-ARROW ] *WS QUOTE ident QUOTE [ generics ]
551
+ * type-search = [type-filter *WS COLON] [ nonempty-arg-list ] [ return-args ]
527
552
*
528
- * query = *WS (exact-search / type-search / return-args ) *WS
553
+ * query = *WS (exact-search / type-search) *WS
529
554
*
530
555
* type-filter = (
531
556
* "mod" /
@@ -578,6 +603,7 @@ window.initSearch = function(rawSearchIndex) {
578
603
pos : 0 ,
579
604
// Total number of elements (includes generics).
580
605
totalElems : 0 ,
606
+ genericsElems : 0 ,
581
607
typeFilter : null ,
582
608
userQuery : userQuery . toLowerCase ( ) ,
583
609
} ;
@@ -606,7 +632,7 @@ window.initSearch = function(rawSearchIndex) {
606
632
query . foundElems = query . elems . length + query . returned . length ;
607
633
if ( query . foundElems === 0 && parserState . length !== 0 ) {
608
634
// In this case, we'll simply keep whatever was entered by the user...
609
- query . elems . push ( createQueryElement ( query , parserState , userQuery , [ ] ) ) ;
635
+ query . elems . push ( createQueryElement ( query , parserState , userQuery , [ ] , false ) ) ;
610
636
query . foundElems += 1 ;
611
637
}
612
638
return query ;
0 commit comments