()
| 655 | } |
| 656 | |
| 657 | private isStartOfRegex(): boolean { |
| 658 | if (this.tokens.length === 0) { |
| 659 | return true; |
| 660 | } |
| 661 | |
| 662 | const prevToken = this.tokens[this.tokens.length - 1]; |
| 663 | |
| 664 | // If a slash is preceded by a `!` operator, we need to distinguish whether it's a |
| 665 | // negation or a non-null assertion. Regexes can only be precded by negations. |
| 666 | if (prevToken.isOperator('!')) { |
| 667 | const beforePrevToken = this.tokens.length > 1 ? this.tokens[this.tokens.length - 2] : null; |
| 668 | const isNegation = |
| 669 | beforePrevToken === null || |
| 670 | (beforePrevToken.type !== TokenType.Identifier && |
| 671 | !beforePrevToken.isCharacter(chars.$RPAREN) && |
| 672 | !beforePrevToken.isCharacter(chars.$RBRACKET)); |
| 673 | |
| 674 | return isNegation; |
| 675 | } |
| 676 | |
| 677 | // Only consider the slash a regex if it's preceded either by: |
| 678 | // - Any operator, aside from `!` which is special-cased above. |
| 679 | // - Opening paren (e.g. `(/a/)`). |
| 680 | // - Opening bracket (e.g. `[/a/]`). |
| 681 | // - A comma (e.g. `[1, /a/]`). |
| 682 | // - A colon (e.g. `{foo: /a/}`). |
| 683 | return ( |
| 684 | prevToken.type === TokenType.Operator || |
| 685 | prevToken.isCharacter(chars.$LPAREN) || |
| 686 | prevToken.isCharacter(chars.$LBRACKET) || |
| 687 | prevToken.isCharacter(chars.$COMMA) || |
| 688 | prevToken.isCharacter(chars.$COLON) |
| 689 | ); |
| 690 | } |
| 691 | |
| 692 | private scanRegex(tokenStart: number): Token { |
| 693 | this.advance(); |
no test coverage detected