Пример #1
0
 private static boolean acceptExtendsBound(PsiClassType extendsBound, int depth) {
   PsiType[] parameters = extendsBound.getParameters();
   if (parameters.length == 1) {
     PsiType argType = parameters[0];
     if (argType instanceof PsiCapturedWildcardType && depth == 0) {
       argType = ((PsiCapturedWildcardType) argType).getWildcard();
     }
     if (argType instanceof PsiWildcardType) {
       if (!((PsiWildcardType) argType).isBounded()) return true;
       final PsiType bound = ((PsiWildcardType) argType).getExtendsBound();
       if (bound instanceof PsiClassType
           && TypeConversionUtil.erasure(bound).equals(TypeConversionUtil.erasure(extendsBound))) {
         return acceptExtendsBound((PsiClassType) bound, depth + 1);
       }
       if (bound instanceof PsiIntersectionType) {
         for (PsiType extendsType : ((PsiIntersectionType) bound).getConjuncts()) {
           if (acceptExtendsBound(extendsBound, extendsType)) {
             return true;
           }
         }
       }
     }
   }
   return false;
 }
 @Nullable
 private static PsiType getGenericElementType(PsiType collectionType) {
   if (collectionType instanceof PsiClassType) {
     PsiClassType classType = (PsiClassType) collectionType;
     PsiType[] parameters = classType.getParameters();
     if (parameters.length == 1) {
       return parameters[0];
     }
   }
   return null;
 }
    public Boolean visitClassType(final PsiClassType classType) {
      final PsiClass aClass = classType.resolve();
      if (aClass instanceof PsiTypeParameter && myTypeParams.contains((PsiTypeParameter) aClass))
        return true;

      final PsiType[] types = classType.getParameters();
      for (final PsiType psiType : types) {
        if (psiType.accept(this).booleanValue()) return true;
      }
      return false;
    }
Пример #4
0
 @Override
 public Boolean visitClassType(PsiClassType classType) {
   boolean used = false;
   for (PsiType paramType : classType.getParameters()) {
     final Boolean paramAccepted = paramType.accept(this);
     used |= paramAccepted != null && paramAccepted.booleanValue();
   }
   final PsiClass resolve = classType.resolve();
   if (resolve instanceof PsiTypeParameter) {
     final PsiTypeParameter typeParameter = (PsiTypeParameter) resolve;
     if (check(typeParameter)) {
       myUsedTypeParams.add(typeParameter);
       return true;
     }
   }
   return used;
 }
  public boolean incorporate() {
    final Collection<InferenceVariable> inferenceVariables = mySession.getInferenceVariables();
    final PsiSubstitutor substitutor =
        mySession.retrieveNonPrimitiveEqualsBounds(inferenceVariables);
    for (InferenceVariable inferenceVariable : inferenceVariables) {
      if (inferenceVariable.getInstantiation() != PsiType.NULL) continue;
      final List<PsiType> eqBounds = inferenceVariable.getBounds(InferenceBound.EQ);
      final List<PsiType> upperBounds = inferenceVariable.getBounds(InferenceBound.UPPER);
      final List<PsiType> lowerBounds = inferenceVariable.getBounds(InferenceBound.LOWER);

      eqEq(eqBounds);

      upDown(lowerBounds, upperBounds, substitutor);
      upDown(eqBounds, upperBounds, substitutor);
      upDown(lowerBounds, eqBounds, substitutor);

      upUp(upperBounds);
    }

    for (Pair<PsiTypeParameter[], PsiClassType> capture : myCaptures) {
      final PsiClassType right = capture.second;
      final PsiClass gClass = right.resolve();
      LOG.assertTrue(gClass != null);
      final PsiTypeParameter[] parameters = capture.first;
      PsiType[] typeArgs = right.getParameters();
      if (parameters.length != typeArgs.length) continue;
      for (int i = 0; i < typeArgs.length; i++) {
        PsiType aType = typeArgs[i];
        if (aType instanceof PsiCapturedWildcardType) {
          aType = ((PsiCapturedWildcardType) aType).getWildcard();
        }
        final InferenceVariable inferenceVariable = mySession.getInferenceVariable(parameters[i]);
        LOG.assertTrue(inferenceVariable != null);

        final List<PsiType> eqBounds = inferenceVariable.getBounds(InferenceBound.EQ);
        final List<PsiType> upperBounds = inferenceVariable.getBounds(InferenceBound.UPPER);
        final List<PsiType> lowerBounds = inferenceVariable.getBounds(InferenceBound.LOWER);

        if (aType instanceof PsiWildcardType) {

          for (PsiType eqBound : eqBounds) {
            if (!isInferenceVariableOrFreshTypeParameter(eqBound)) return false;
          }

          final PsiClassType[] paramBounds = inferenceVariable.getParameter().getExtendsListTypes();

          PsiType glb = null;
          for (PsiClassType paramBound : paramBounds) {
            if (glb == null) {
              glb = paramBound;
            } else {
              glb = GenericsUtil.getGreatestLowerBound(glb, paramBound);
            }
          }

          if (!((PsiWildcardType) aType).isBounded()) {

            for (PsiType upperBound : upperBounds) {
              if (glb != null && mySession.getInferenceVariable(upperBound) == null) {
                addConstraint(
                    new StrictSubtypingConstraint(
                        upperBound, mySession.substituteWithInferenceVariables(glb)));
              }
            }

            for (PsiType lowerBound : lowerBounds) {
              if (isInferenceVariableOrFreshTypeParameter(lowerBound)) return false;
            }

          } else if (((PsiWildcardType) aType).isExtends()) {

            final PsiType extendsBound = ((PsiWildcardType) aType).getExtendsBound();

            for (PsiType upperBound : upperBounds) {
              if (mySession.getInferenceVariable(upperBound) == null) {
                if (paramBounds.length == 1
                        && paramBounds[0].equalsToText(CommonClassNames.JAVA_LANG_OBJECT)
                    || paramBounds.length == 0) {
                  addConstraint(new StrictSubtypingConstraint(upperBound, extendsBound));
                } else if (extendsBound.equalsToText(CommonClassNames.JAVA_LANG_OBJECT)
                    && glb != null) {
                  addConstraint(
                      new StrictSubtypingConstraint(
                          upperBound, mySession.substituteWithInferenceVariables(glb)));
                }
              }
            }

            for (PsiType lowerBound : lowerBounds) {
              if (isInferenceVariableOrFreshTypeParameter(lowerBound)) return false;
            }

          } else {
            LOG.assertTrue(((PsiWildcardType) aType).isSuper());
            final PsiType superBound = ((PsiWildcardType) aType).getSuperBound();

            for (PsiType upperBound : upperBounds) {
              if (glb != null && mySession.getInferenceVariable(upperBound) == null) {
                addConstraint(
                    new StrictSubtypingConstraint(
                        mySession.substituteWithInferenceVariables(glb), upperBound));
              }
            }

            for (PsiType lowerBound : lowerBounds) {
              if (mySession.getInferenceVariable(lowerBound) == null) {
                addConstraint(new StrictSubtypingConstraint(lowerBound, superBound));
              }
            }
          }
        } else {
          inferenceVariable.addBound(aType, InferenceBound.EQ);
        }
      }
    }
    return true;
  }