langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/code/Types.java
changeset 29555 71f15ff4b409
parent 29554 6d7957bd6866
child 29842 826ac2519523
equal deleted inserted replaced
29554:6d7957bd6866 29555:71f15ff4b409
    30 import java.util.HashMap;
    30 import java.util.HashMap;
    31 import java.util.Locale;
    31 import java.util.Locale;
    32 import java.util.Map;
    32 import java.util.Map;
    33 import java.util.Set;
    33 import java.util.Set;
    34 import java.util.WeakHashMap;
    34 import java.util.WeakHashMap;
       
    35 import java.util.function.BiPredicate;
       
    36 import java.util.stream.Collector;
    35 
    37 
    36 import javax.tools.JavaFileObject;
    38 import javax.tools.JavaFileObject;
    37 
    39 
    38 import com.sun.tools.javac.code.Attribute.RetentionPolicy;
    40 import com.sun.tools.javac.code.Attribute.RetentionPolicy;
    39 import com.sun.tools.javac.code.Lint.LintCategory;
    41 import com.sun.tools.javac.code.Lint.LintCategory;
  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      */