import { setFilter , iterableSome } from "collection-utils" ; import { TypeGraph , TypeRef , derefTypeRef } from "../TypeGraph" ; import { Type , UnionType , IntersectionType } from "../Type" ; import { makeGroupsToFlatten } from "../TypeUtils" ; import { assert } from "../support/Support" ; import { StringTypeMapping } from "../TypeBuilder" ; import { GraphRewriteBuilder } from "../GraphRewriting" ; import { unifyTypes , UnifyUnionBuilder } from "../UnifyClasses" ; import { messageAssert } from "../Messages" ; import { emptyTypeAttributes } from "../attributes/TypeAttributes" ; export function flattenUnions ( graph , stringTypeMapping , conflateNumbers , makeObjectTypes , debugPrintReconstitution ) { let needsRepeat = false ; function replace ( types , builder , forwardingRef ) { const unionBuilder = new UnifyUnionBuilder ( builder , makeObjectTypes , true , trefs => { assert ( trefs . length > 0 , "Must have at least one type to build union" ) ; trefs = trefs . map ( tref => builder . reconstituteType ( derefTypeRef ( tref , graph ) ) ) ; if ( trefs . length === 1 ) { return trefs [ 0 ] ; } needsRepeat = true ; return builder . getUnionType ( emptyTypeAttributes , new Set ( trefs ) ) ; } ) ; return unifyTypes ( types , emptyTypeAttributes , builder , unionBuilder , conflateNumbers , forwardingRef ) ; } const allUnions = setFilter ( graph . allTypesUnordered ( ) , t => t instanceof UnionType ) as Set < UnionType > ; const nonCanonicalUnions = setFilter ( allUnions , u => ! u . isCanonical ) ; let foundIntersection = false ; const groups = makeGroupsToFlatten ( nonCanonicalUnions , members => { messageAssert ( members . size > 0 , "IRNoEmptyUnions" , { } ) ; if ( ! iterableSome ( members , m => m instanceof IntersectionType ) ) return true ; foundIntersection = true ; return false ; } ) ; graph = graph . rewrite ( "flatten unions" , stringTypeMapping , false , groups , debugPrintReconstitution , replace ) ; return [ graph , ! needsRepeat && ! foundIntersection ] ; }