513 } |
513 } |
514 |
514 |
515 /** max number of incorporation rounds */ |
515 /** max number of incorporation rounds */ |
516 static final int MAX_INCORPORATION_STEPS = 100; |
516 static final int MAX_INCORPORATION_STEPS = 100; |
517 |
517 |
|
518 /* If for two types t and s there is a least upper bound that is a |
|
519 * parameterized type G, then there exists a supertype of 't' of the form |
|
520 * G<T1, ..., Tn> and a supertype of 's' of the form G<S1, ..., Sn> |
|
521 * which will be returned by this method. If no such supertypes exists then |
|
522 * null is returned. |
|
523 * |
|
524 * As an example for the following input: |
|
525 * |
|
526 * t = java.util.ArrayList<java.lang.String> |
|
527 * s = java.util.List<T> |
|
528 * |
|
529 * we get this ouput: |
|
530 * |
|
531 * Pair[java.util.List<java.lang.String>,java.util.List<T>] |
|
532 */ |
|
533 private Pair<Type, Type> getParameterizedSupers(Type t, Type s) { |
|
534 Type lubResult = types.lub(t, s); |
|
535 if (lubResult == syms.errType || lubResult == syms.botType || |
|
536 !lubResult.isParameterized()) { |
|
537 return null; |
|
538 } |
|
539 Type asSuperOfT = types.asSuper(t, lubResult.tsym); |
|
540 Type asSuperOfS = types.asSuper(s, lubResult.tsym); |
|
541 return new Pair<>(asSuperOfT, asSuperOfS); |
|
542 } |
|
543 |
518 /** |
544 /** |
519 * This enumeration defines an entry point for doing inference variable |
545 * This enumeration defines an entry point for doing inference variable |
520 * bound incorporation - it can be used to inject custom incorporation |
546 * bound incorporation - it can be used to inject custom incorporation |
521 * logic into the basic bound checking routine |
547 * logic into the basic bound checking routine |
522 */ |
548 */ |
677 @Override |
703 @Override |
678 boolean accepts(UndetVar uv, InferenceContext inferenceContext) { |
704 boolean accepts(UndetVar uv, InferenceContext inferenceContext) { |
679 return !uv.isCaptured() && |
705 return !uv.isCaptured() && |
680 uv.getBounds(InferenceBound.EQ).nonEmpty() && |
706 uv.getBounds(InferenceBound.EQ).nonEmpty() && |
681 uv.getBounds(InferenceBound.LOWER).nonEmpty(); |
707 uv.getBounds(InferenceBound.LOWER).nonEmpty(); |
|
708 } |
|
709 }, |
|
710 /** |
|
711 * Given a bound set containing {@code alpha <: P<T>} and |
|
712 * {@code alpha <: P<S>} where P is a parameterized type, |
|
713 * perform {@code T = S} (which could lead to new bounds). |
|
714 */ |
|
715 CROSS_UPPER_UPPER() { |
|
716 @Override |
|
717 public void apply(UndetVar uv, InferenceContext inferenceContext, Warner warn) { |
|
718 Infer infer = inferenceContext.infer(); |
|
719 List<Type> boundList = uv.getBounds(InferenceBound.UPPER); |
|
720 List<Type> boundListTail = boundList.tail; |
|
721 while (boundList.nonEmpty()) { |
|
722 List<Type> tmpTail = boundListTail; |
|
723 while (tmpTail.nonEmpty()) { |
|
724 Type b1 = boundList.head; |
|
725 Type b2 = tmpTail.head; |
|
726 if (b1 != b2) { |
|
727 Pair<Type, Type> commonSupers = infer.getParameterizedSupers(b1, b2); |
|
728 if (commonSupers != null) { |
|
729 List<Type> allParamsSuperBound1 = commonSupers.fst.allparams(); |
|
730 List<Type> allParamsSuperBound2 = commonSupers.snd.allparams(); |
|
731 while (allParamsSuperBound1.nonEmpty() && allParamsSuperBound2.nonEmpty()) { |
|
732 //traverse the list of all params comparing them |
|
733 if (!allParamsSuperBound1.head.hasTag(WILDCARD) && |
|
734 !allParamsSuperBound2.head.hasTag(WILDCARD)) { |
|
735 isSameType(inferenceContext.asUndetVar(allParamsSuperBound1.head), |
|
736 inferenceContext.asUndetVar(allParamsSuperBound2.head), infer); |
|
737 } |
|
738 allParamsSuperBound1 = allParamsSuperBound1.tail; |
|
739 allParamsSuperBound2 = allParamsSuperBound2.tail; |
|
740 } |
|
741 Assert.check(allParamsSuperBound1.isEmpty() && allParamsSuperBound2.isEmpty()); |
|
742 } |
|
743 } |
|
744 tmpTail = tmpTail.tail; |
|
745 } |
|
746 boundList = boundList.tail; |
|
747 boundListTail = boundList.tail; |
|
748 } |
|
749 } |
|
750 |
|
751 @Override |
|
752 boolean accepts(UndetVar uv, InferenceContext inferenceContext) { |
|
753 return !uv.isCaptured() && |
|
754 uv.getBounds(InferenceBound.UPPER).nonEmpty(); |
682 } |
755 } |
683 }, |
756 }, |
684 /** |
757 /** |
685 * Given a bound set containing {@code alpha == S} and {@code alpha == T} |
758 * Given a bound set containing {@code alpha == S} and {@code alpha == T} |
686 * perform {@code S == T} (which could lead to new bounds). |
759 * perform {@code S == T} (which could lead to new bounds). |