MCPcopy Create free account
hub / github.com/Effect-TS/effect / getIndex

Function getIndex

packages/effect/src/SchemaAST.ts:2639–2777  ·  view source on GitHub ↗
(types: ReadonlyArray<AST>)

Source from the content-addressed store, hash-verified

2637const emptyCandidates: ReadonlyArray<never> = Object.freeze([])
2638
2639function getIndex(types: ReadonlyArray<AST>): CandidateIndex {
2640 let index = candidateIndexCache.get(types)
2641 if (index) return index
2642
2643 let bySentinel: SentinelIndex | undefined
2644 let sentinelCandidateCount = 0
2645 let otherwise: { [K in Type]?: Array<number> } | undefined
2646 let literalCandidates: Map<LiteralValue | symbol, Array<AST>> | undefined
2647 let onlyLiterals = true
2648 for (let i = 0; i < types.length; i++) {
2649 const a = types[i]
2650 const encoded = toCandidate(a)
2651 if (isNever(encoded)) continue
2652
2653 if (onlyLiterals) {
2654 if (isLiteral(encoded) || isUniqueSymbol(encoded)) {
2655 literalCandidates ??= new Map()
2656 const literal = isLiteral(encoded) ? encoded.literal : encoded.symbol
2657 let arr = literalCandidates.get(literal)
2658 if (!arr) literalCandidates.set(literal, arr = [])
2659 arr.push(a)
2660 } else {
2661 onlyLiterals = false
2662 }
2663 }
2664
2665 const sentinels = collectSentinels(encoded)
2666
2667 if (sentinels.length) { // discriminated variants
2668 bySentinel ??= new Map()
2669 sentinelCandidateCount++
2670 for (const { key, literal } of sentinels) {
2671 let entry = bySentinel.get(key)
2672 if (!entry) bySentinel.set(key, entry = [new Map(), new Set()])
2673 entry[1].add(i)
2674 let indexes = entry[0].get(literal)
2675 if (!indexes) entry[0].set(literal, indexes = new Set())
2676 indexes.add(i)
2677 }
2678 } else { // non-discriminated
2679 otherwise ??= {}
2680 const candidateTypes = getCandidateTypes(encoded)
2681 for (const t of candidateTypes) (otherwise[t] ??= []).push(i)
2682 }
2683 }
2684
2685 if (onlyLiterals && literalCandidates) {
2686 literalCandidates.forEach(Object.freeze)
2687 index = (input) => literalCandidates.get(input) ?? emptyCandidates
2688 } else if (bySentinel?.size === 1 && !otherwise) {
2689 const [key, [byValue]] = bySentinel.entries().next().value!
2690 const candidates = byValue as unknown as Map<LiteralValue | symbol, ReadonlyArray<AST>>
2691 for (const [literal, indexes] of byValue) {
2692 candidates.set(literal, Object.freeze(Array.from(indexes, (index) => types[index])))
2693 }
2694 index = (input, isConstructor) => {
2695 if (Predicate.isObjectKeyword(input)) {
2696 const value = Object.hasOwn(input, key) ? (input as any)[key] : undefined

Callers 1

getCandidatesFunction · 0.85

Calls 13

isNeverFunction · 0.85
collectSentinelsFunction · 0.85
getCandidateTypesFunction · 0.85
filterLiteralsFunction · 0.85
pushMethod · 0.80
filterMethod · 0.80
getMethod · 0.65
setMethod · 0.65
addMethod · 0.65
forEachMethod · 0.65
nextMethod · 0.65
mapMethod · 0.45

Tested by

no test coverage detected