( ast: TemplateLiteral, input: string, options: ParseOptions )
| 3819 | } |
| 3820 | |
| 3821 | function segmentTemplateLiteralParts( |
| 3822 | ast: TemplateLiteral, |
| 3823 | input: string, |
| 3824 | options: ParseOptions |
| 3825 | ): Array<string> | undefined { |
| 3826 | const parts = ast.encodedParts |
| 3827 | const literals = ast.literals |
| 3828 | const inputLength = input.length |
| 3829 | for (let i = 0; i < literals.length; i++) { |
| 3830 | const literal = literals[i] |
| 3831 | if (literal && !input.includes(literal)) return undefined |
| 3832 | } |
| 3833 | if (ast.suffixLengths[0] > inputLength) return undefined |
| 3834 | |
| 3835 | const out = new Array<string>(parts.length) |
| 3836 | let failures: Set<number> | undefined |
| 3837 | function go(i: number, pos: number): boolean { |
| 3838 | if (i === parts.length) return pos === inputLength |
| 3839 | if (failures?.has(i * (inputLength + 1) + pos)) return false |
| 3840 | const part = parts[i] |
| 3841 | if (i === parts.length - 1) { |
| 3842 | const s = input.slice(pos) |
| 3843 | if (part.matchPart(s, options) !== undefined) { |
| 3844 | out[i] = s |
| 3845 | return true |
| 3846 | } |
| 3847 | } else if (part._tag === "Literal") { |
| 3848 | const s = literals[i]! |
| 3849 | if (input.startsWith(s, pos) && go(i + 1, pos + s.length)) { |
| 3850 | out[i] = s |
| 3851 | return true |
| 3852 | } |
| 3853 | } else { |
| 3854 | const maximumEnd = inputLength - ast.suffixLengths[i + 1] |
| 3855 | // Splits preceding a literal only need to consider occurrences of that literal. |
| 3856 | const anchor = literals[i + 1] |
| 3857 | let end = anchor === undefined ? maximumEnd : input.lastIndexOf(anchor, maximumEnd) |
| 3858 | while (end >= pos) { |
| 3859 | const s = input.slice(pos, end) |
| 3860 | if (part.matchPart(s, options) !== undefined && go(i + 1, end)) { |
| 3861 | out[i] = s |
| 3862 | return true |
| 3863 | } |
| 3864 | if (end === 0) break |
| 3865 | end = anchor === undefined ? end - 1 : input.lastIndexOf(anchor, end - 1) |
| 3866 | } |
| 3867 | } |
| 3868 | failures ??= new Set() |
| 3869 | failures.add(i * (inputLength + 1) + pos) |
| 3870 | return false |
| 3871 | } |
| 3872 | return go(0, 0) ? out : undefined |
| 3873 | } |
| 3874 | |
| 3875 | /** @internal */ |
| 3876 | export const enumsToLiterals = memoize((ast: Enum): Union<Literal> => { |
no test coverage detected