( xs: ReadonlyArray<AST.AST>, ys: ReadonlyArray<AST.AST>, path: ReadonlyArray<PropertyKey> )
| 3309 | const getTypes = (ast: AST.AST): ReadonlyArray<AST.AST> => AST.isUnion(ast) ? ast.types : [ast] |
| 3310 | |
| 3311 | const intersectUnionMembers = ( |
| 3312 | xs: ReadonlyArray<AST.AST>, |
| 3313 | ys: ReadonlyArray<AST.AST>, |
| 3314 | path: ReadonlyArray<PropertyKey> |
| 3315 | ): Array<AST.AST> => |
| 3316 | array_.flatMap(xs, (x) => |
| 3317 | array_.flatMap(ys, (y) => { |
| 3318 | switch (y._tag) { |
| 3319 | case "Literal": { |
| 3320 | if ( |
| 3321 | (Predicate.isString(y.literal) && AST.isStringKeyword(x) || |
| 3322 | (Predicate.isNumber(y.literal) && AST.isNumberKeyword(x)) || |
| 3323 | (Predicate.isBoolean(y.literal) && AST.isBooleanKeyword(x))) |
| 3324 | ) { |
| 3325 | return [y] |
| 3326 | } |
| 3327 | break |
| 3328 | } |
| 3329 | case "StringKeyword": { |
| 3330 | if (y === AST.stringKeyword) { |
| 3331 | if (AST.isStringKeyword(x) || (AST.isLiteral(x) && Predicate.isString(x.literal))) { |
| 3332 | return [x] |
| 3333 | } else if (AST.isRefinement(x)) { |
| 3334 | return addRefinementToMembers(x, intersectUnionMembers(getTypes(x.from), [y], path)) |
| 3335 | } |
| 3336 | } else if (x === AST.stringKeyword) { |
| 3337 | return [y] |
| 3338 | } |
| 3339 | break |
| 3340 | } |
| 3341 | case "NumberKeyword": { |
| 3342 | if (y === AST.numberKeyword) { |
| 3343 | if (AST.isNumberKeyword(x) || (AST.isLiteral(x) && Predicate.isNumber(x.literal))) { |
| 3344 | return [x] |
| 3345 | } else if (AST.isRefinement(x)) { |
| 3346 | return addRefinementToMembers(x, intersectUnionMembers(getTypes(x.from), [y], path)) |
| 3347 | } |
| 3348 | } else if (x === AST.numberKeyword) { |
| 3349 | return [y] |
| 3350 | } |
| 3351 | break |
| 3352 | } |
| 3353 | case "BooleanKeyword": { |
| 3354 | if (y === AST.booleanKeyword) { |
| 3355 | if (AST.isBooleanKeyword(x) || (AST.isLiteral(x) && Predicate.isBoolean(x.literal))) { |
| 3356 | return [x] |
| 3357 | } else if (AST.isRefinement(x)) { |
| 3358 | return addRefinementToMembers(x, intersectUnionMembers(getTypes(x.from), [y], path)) |
| 3359 | } |
| 3360 | } else if (x === AST.booleanKeyword) { |
| 3361 | return [y] |
| 3362 | } |
| 3363 | break |
| 3364 | } |
| 3365 | case "Union": |
| 3366 | return intersectUnionMembers(getTypes(x), y.types, path) |
| 3367 | case "Suspend": |
| 3368 | return [new AST.Suspend(() => extendAST(x, y.f(), path))] |
no test coverage detected