コード例 #1
0
 private static boolean resolveSubstituteConstraints(
     Scope scope,
     TypeVariableBinding[] typeVariables,
     InferenceContext inferenceContext,
     boolean considerEXTENDSConstraints) {
   TypeBinding[] substitutes = inferenceContext.substitutes;
   int varLength = typeVariables.length;
   // check Tj=U constraints
   nextTypeParameter:
   for (int i = 0; i < varLength; i++) {
     TypeVariableBinding current = typeVariables[i];
     TypeBinding substitute = substitutes[i];
     if (substitute != null) continue nextTypeParameter; // already inferred previously
     TypeBinding[] equalSubstitutes =
         inferenceContext.getSubstitutes(current, TypeConstants.CONSTRAINT_EQUAL);
     if (equalSubstitutes != null) {
       nextConstraint:
       for (int j = 0, equalLength = equalSubstitutes.length; j < equalLength; j++) {
         TypeBinding equalSubstitute = equalSubstitutes[j];
         if (equalSubstitute == null) continue nextConstraint;
         if (equalSubstitute == current) {
           // try to find a better different match if any in subsequent equal candidates
           for (int k = j + 1; k < equalLength; k++) {
             equalSubstitute = equalSubstitutes[k];
             if (equalSubstitute != current && equalSubstitute != null) {
               substitutes[i] = equalSubstitute;
               continue nextTypeParameter;
             }
           }
           substitutes[i] = current;
           continue nextTypeParameter;
         }
         //							if (equalSubstitute.isTypeVariable()) {
         //								TypeVariableBinding variable = (TypeVariableBinding) equalSubstitute;
         //								// substituted by a variable of the same method, ignore
         //								if (variable.rank < varLength && typeVariables[variable.rank] == variable) {
         //									// TODO (philippe) rewrite all other constraints to use current instead.
         //									continue nextConstraint;
         //								}
         //							}
         substitutes[i] = equalSubstitute;
         continue nextTypeParameter; // pick first match, applicability check will rule out invalid
         // scenario where others were present
       }
     }
   }
   if (inferenceContext.hasUnresolvedTypeArgument()) {
     // check Tj>:U constraints
     nextTypeParameter:
     for (int i = 0; i < varLength; i++) {
       TypeVariableBinding current = typeVariables[i];
       TypeBinding substitute = substitutes[i];
       if (substitute != null) continue nextTypeParameter; // already inferred previously
       TypeBinding[] bounds =
           inferenceContext.getSubstitutes(current, TypeConstants.CONSTRAINT_SUPER);
       if (bounds == null) continue nextTypeParameter;
       TypeBinding mostSpecificSubstitute = scope.lowerUpperBound(bounds);
       if (mostSpecificSubstitute == null) {
         return false; // incompatible
       }
       if (mostSpecificSubstitute != TypeBinding.VOID) {
         substitutes[i] = mostSpecificSubstitute;
       }
     }
   }
   if (considerEXTENDSConstraints && inferenceContext.hasUnresolvedTypeArgument()) {
     // check Tj<:U constraints
     nextTypeParameter:
     for (int i = 0; i < varLength; i++) {
       TypeVariableBinding current = typeVariables[i];
       TypeBinding substitute = substitutes[i];
       if (substitute != null) continue nextTypeParameter; // already inferred previously
       TypeBinding[] bounds =
           inferenceContext.getSubstitutes(current, TypeConstants.CONSTRAINT_EXTENDS);
       if (bounds == null) continue nextTypeParameter;
       TypeBinding[] glb = Scope.greaterLowerBound(bounds);
       TypeBinding mostSpecificSubstitute = null;
       if (glb != null) mostSpecificSubstitute = glb[0]; // TODO (philippe) need to improve
       // TypeBinding mostSpecificSubstitute = scope.greaterLowerBound(bounds);
       if (mostSpecificSubstitute != null) {
         substitutes[i] = mostSpecificSubstitute;
       }
     }
   }
   return true;
 }
 private static boolean resolveSubstituteConstraints(
     Scope scope,
     TypeVariableBinding[] typeVariables,
     InferenceContext inferenceContext,
     boolean considerEXTENDSConstraints) {
   TypeBinding[] substitutes = inferenceContext.substitutes;
   int varLength = typeVariables.length;
   // check Tj=U constraints
   nextTypeParameter:
   for (int i = 0; i < varLength; i++) {
     TypeVariableBinding current = typeVariables[i];
     TypeBinding substitute = substitutes[i];
     if (substitute != null) continue nextTypeParameter; // already inferred previously
     TypeBinding[] equalSubstitutes =
         inferenceContext.getSubstitutes(current, TypeConstants.CONSTRAINT_EQUAL);
     if (equalSubstitutes != null) {
       nextConstraint:
       for (int j = 0, equalLength = equalSubstitutes.length; j < equalLength; j++) {
         TypeBinding equalSubstitute = equalSubstitutes[j];
         if (equalSubstitute == null) continue nextConstraint;
         if (equalSubstitute == current) {
           // try to find a better different match if any in subsequent equal candidates
           for (int k = j + 1; k < equalLength; k++) {
             equalSubstitute = equalSubstitutes[k];
             if (equalSubstitute != current && equalSubstitute != null) {
               substitutes[i] = equalSubstitute;
               continue nextTypeParameter;
             }
           }
           substitutes[i] = current;
           continue nextTypeParameter;
         }
         //							if (equalSubstitute.isTypeVariable()) {
         //								TypeVariableBinding variable = (TypeVariableBinding) equalSubstitute;
         //								// substituted by a variable of the same method, ignore
         //								if (variable.rank < varLength && typeVariables[variable.rank] == variable) {
         //									// TODO (philippe) rewrite all other constraints to use current instead.
         //									continue nextConstraint;
         //								}
         //							}
         substitutes[i] = equalSubstitute;
         continue
             nextTypeParameter; // pick first match, applicability check will rule out invalid
                                // scenario where others were present
       }
     }
   }
   if (inferenceContext.hasUnresolvedTypeArgument()) {
     // check Tj>:U constraints
     nextTypeParameter:
     for (int i = 0; i < varLength; i++) {
       TypeVariableBinding current = typeVariables[i];
       TypeBinding substitute = substitutes[i];
       if (substitute != null) continue nextTypeParameter; // already inferred previously
       TypeBinding[] bounds =
           inferenceContext.getSubstitutes(current, TypeConstants.CONSTRAINT_SUPER);
       if (bounds == null) continue nextTypeParameter;
       TypeBinding mostSpecificSubstitute = scope.lowerUpperBound(bounds);
       if (mostSpecificSubstitute == null) {
         return false; // incompatible
       }
       if (mostSpecificSubstitute != TypeBinding.VOID) {
         substitutes[i] = mostSpecificSubstitute;
       }
     }
   }
   if (considerEXTENDSConstraints && inferenceContext.hasUnresolvedTypeArgument()) {
     // check Tj<:U constraints
     nextTypeParameter:
     for (int i = 0; i < varLength; i++) {
       TypeVariableBinding current = typeVariables[i];
       TypeBinding substitute = substitutes[i];
       if (substitute != null) continue nextTypeParameter; // already inferred previously
       TypeBinding[] bounds =
           inferenceContext.getSubstitutes(current, TypeConstants.CONSTRAINT_EXTENDS);
       if (bounds == null) continue nextTypeParameter;
       TypeBinding[] glb = Scope.greaterLowerBound(bounds, scope, scope.environment());
       TypeBinding mostSpecificSubstitute = null;
       // https://bugs.eclipse.org/bugs/show_bug.cgi?id=341795 - Per 15.12.2.8, we should fully
       // apply glb
       if (glb != null) {
         if (glb.length == 1) {
           mostSpecificSubstitute = glb[0];
         } else {
           TypeBinding[] otherBounds = new TypeBinding[glb.length - 1];
           System.arraycopy(glb, 1, otherBounds, 0, glb.length - 1);
           mostSpecificSubstitute =
               scope.environment().createWildcard(null, 0, glb[0], otherBounds, Wildcard.EXTENDS);
         }
       }
       if (mostSpecificSubstitute != null) {
         substitutes[i] = mostSpecificSubstitute;
       }
     }
   }
   return true;
 }