langtools/src/share/classes/com/sun/tools/javac/comp/Infer.java
changeset 24063 3e3c18700277
parent 23395 e7e0973e6d2e
child 24226 08b586e22328
equal deleted inserted replaced
24062:09047fd2a43e 24063:3e3c18700277
   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).