3404 } |
3406 } |
3405 return cl; |
3407 return cl; |
3406 } |
3408 } |
3407 |
3409 |
3408 /** |
3410 /** |
|
3411 * Collect types into a new closure (using a @code{ClosureHolder}) |
|
3412 */ |
|
3413 public Collector<Type, ClosureHolder, List<Type>> closureCollector(boolean minClosure, BiPredicate<Type, Type> shouldSkip) { |
|
3414 return Collector.of(() -> new ClosureHolder(minClosure, shouldSkip), |
|
3415 ClosureHolder::add, |
|
3416 ClosureHolder::merge, |
|
3417 ClosureHolder::closure); |
|
3418 } |
|
3419 //where |
|
3420 class ClosureHolder { |
|
3421 List<Type> closure; |
|
3422 final boolean minClosure; |
|
3423 final BiPredicate<Type, Type> shouldSkip; |
|
3424 |
|
3425 ClosureHolder(boolean minClosure, BiPredicate<Type, Type> shouldSkip) { |
|
3426 this.closure = List.nil(); |
|
3427 this.minClosure = minClosure; |
|
3428 this.shouldSkip = shouldSkip; |
|
3429 } |
|
3430 |
|
3431 void add(Type type) { |
|
3432 closure = insert(closure, type, shouldSkip); |
|
3433 } |
|
3434 |
|
3435 ClosureHolder merge(ClosureHolder other) { |
|
3436 closure = union(closure, other.closure, shouldSkip); |
|
3437 return this; |
|
3438 } |
|
3439 |
|
3440 List<Type> closure() { |
|
3441 return minClosure ? closureMin(closure) : closure; |
|
3442 } |
|
3443 } |
|
3444 |
|
3445 BiPredicate<Type, Type> basicClosureSkip = (t1, t2) -> t1.tsym == t2.tsym; |
|
3446 |
|
3447 /** |
3409 * Insert a type in a closure |
3448 * Insert a type in a closure |
3410 */ |
3449 */ |
3411 public List<Type> insert(List<Type> cl, Type t) { |
3450 public List<Type> insert(List<Type> cl, Type t, BiPredicate<Type, Type> shouldSkip) { |
3412 if (cl.isEmpty()) { |
3451 if (cl.isEmpty()) { |
3413 return cl.prepend(t); |
3452 return cl.prepend(t); |
3414 } else if (t.tsym == cl.head.tsym) { |
3453 } else if (shouldSkip.test(t, cl.head)) { |
3415 return cl; |
3454 return cl; |
3416 } else if (t.tsym.precedes(cl.head.tsym, this)) { |
3455 } else if (t.tsym.precedes(cl.head.tsym, this)) { |
3417 return cl.prepend(t); |
3456 return cl.prepend(t); |
3418 } else { |
3457 } else { |
3419 // t comes after head, or the two are unrelated |
3458 // t comes after head, or the two are unrelated |
3420 return insert(cl.tail, t).prepend(cl.head); |
3459 return insert(cl.tail, t, shouldSkip).prepend(cl.head); |
3421 } |
3460 } |
|
3461 } |
|
3462 |
|
3463 public List<Type> insert(List<Type> cl, Type t) { |
|
3464 return insert(cl, t, basicClosureSkip); |
3422 } |
3465 } |
3423 |
3466 |
3424 /** |
3467 /** |
3425 * Form the union of two closures |
3468 * Form the union of two closures |
3426 */ |
3469 */ |
3427 public List<Type> union(List<Type> cl1, List<Type> cl2) { |
3470 public List<Type> union(List<Type> cl1, List<Type> cl2, BiPredicate<Type, Type> shouldSkip) { |
3428 if (cl1.isEmpty()) { |
3471 if (cl1.isEmpty()) { |
3429 return cl2; |
3472 return cl2; |
3430 } else if (cl2.isEmpty()) { |
3473 } else if (cl2.isEmpty()) { |
3431 return cl1; |
3474 return cl1; |
3432 } else if (cl1.head.tsym == cl2.head.tsym) { |
3475 } else if (shouldSkip.test(cl1.head, cl2.head)) { |
3433 return union(cl1.tail, cl2.tail).prepend(cl1.head); |
3476 return union(cl1.tail, cl2.tail, shouldSkip).prepend(cl1.head); |
3434 } else if (cl1.head.tsym.precedes(cl2.head.tsym, this)) { |
3477 } else if (cl1.head.tsym.precedes(cl2.head.tsym, this)) { |
3435 return union(cl1.tail, cl2).prepend(cl1.head); |
3478 return union(cl1.tail, cl2, shouldSkip).prepend(cl1.head); |
3436 } else if (cl2.head.tsym.precedes(cl1.head.tsym, this)) { |
3479 } else if (cl2.head.tsym.precedes(cl1.head.tsym, this)) { |
3437 return union(cl1, cl2.tail).prepend(cl2.head); |
3480 return union(cl1, cl2.tail, shouldSkip).prepend(cl2.head); |
3438 } else { |
3481 } else { |
3439 // unrelated types |
3482 // unrelated types |
3440 return union(cl1.tail, cl2).prepend(cl1.head); |
3483 return union(cl1.tail, cl2, shouldSkip).prepend(cl1.head); |
3441 } |
3484 } |
|
3485 } |
|
3486 |
|
3487 public List<Type> union(List<Type> cl1, List<Type> cl2) { |
|
3488 return union(cl1, cl2, basicClosureSkip); |
3442 } |
3489 } |
3443 |
3490 |
3444 /** |
3491 /** |
3445 * Intersect two closures |
3492 * Intersect two closures |
3446 */ |
3493 */ |