@Nullable private PsiType extractContentTypeFromType(PsiType collectionType) { if (!(collectionType instanceof PsiClassType)) { return null; } final PsiClassType classType = (PsiClassType) collectionType; final PsiType[] parameterTypes = classType.getParameters(); if (parameterTypes.length == 0) { return null; } final PsiType parameterType = parameterTypes[0]; if (parameterType == null) { return null; } if (parameterType instanceof PsiWildcardType) { final PsiWildcardType wildcardType = (PsiWildcardType) parameterType; return wildcardType.getExtendsBound(); } else if (parameterType instanceof PsiCapturedWildcardType) { final PsiCapturedWildcardType capturedWildcardType = (PsiCapturedWildcardType) parameterType; final PsiWildcardType wildcardType = capturedWildcardType.getWildcard(); return wildcardType.getExtendsBound(); } return parameterType; }
private static boolean isIndexedListLoopStatement(PsiForStatement forStatement, boolean ignoreUntypedCollections) { final PsiStatement initialization = forStatement.getInitialization(); if (!(initialization instanceof PsiDeclarationStatement)) { return false; } final PsiDeclarationStatement declaration = (PsiDeclarationStatement)initialization; final PsiElement[] declaredElements = declaration.getDeclaredElements(); final PsiElement secondDeclaredElement; if (declaredElements.length == 1) { secondDeclaredElement = null; } else if (declaredElements.length == 2) { secondDeclaredElement = declaredElements[1]; } else { return false; } final PsiElement declaredElement = declaredElements[0]; if (!(declaredElement instanceof PsiVariable)) { return false; } final PsiVariable indexVariable = (PsiVariable)declaredElement; final PsiExpression initialValue = indexVariable.getInitializer(); if (initialValue == null) { return false; } final Object constant = ExpressionUtils.computeConstantExpression(initialValue); if (!(constant instanceof Number)) { return false; } final Number number = (Number)constant; if (number.intValue() != 0) { return false; } final PsiExpression condition = forStatement.getCondition(); final Holder collectionHolder = getCollectionFromSizeComparison(condition, indexVariable, secondDeclaredElement); if (collectionHolder == null) { return false; } final PsiStatement update = forStatement.getUpdate(); if (!VariableAccessUtils.variableIsIncremented(indexVariable, update)) { return false; } final PsiStatement body = forStatement.getBody(); if (!isIndexVariableOnlyUsedAsListIndex(collectionHolder, indexVariable, body)) { return false; } if (collectionHolder != Holder.DUMMY) { final PsiVariable collection = collectionHolder.getVariable(); final PsiClassType collectionType = (PsiClassType)collection.getType(); final PsiType[] parameters = collectionType.getParameters(); if (ignoreUntypedCollections && parameters.length == 0) { return false; } return !VariableAccessUtils.variableIsAssigned(collection, body); } return true; }
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; }
@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; }
@Override public Boolean visitClassType(PsiClassType classType) { if (classType.getParameters().length > 0) { PsiClassType rawType = classType.rawType(); return rawType.equalsToText(CommonClassNames.JAVA_LANG_CLASS); } PsiClass aClass = classType.resolve(); if (aClass != null && (aClass.isAnnotationType() || aClass.isEnum())) { return Boolean.TRUE; } return classType.equalsToText(CommonClassNames.JAVA_LANG_CLASS) || classType.equalsToText(CommonClassNames.JAVA_LANG_STRING); }
private static PsiType removeClassWildcard(PsiType type) { if (type instanceof PsiClassType) { final PsiClass psiClass = ((PsiClassType) type).resolve(); if (psiClass != null && CommonClassNames.JAVA_LANG_CLASS.equals(psiClass.getQualifiedName())) { PsiClassType erased = (PsiClassType) GenericsUtil.eliminateWildcards(type); PsiType[] parameters = erased.getParameters(); if (parameters.length == 1 && !parameters[0].equalsToText(CommonClassNames.JAVA_LANG_OBJECT)) { return erased; } } } return type; }
@NotNull @Override public PsiType[] getParameters() { return ContainerUtil.map2Array( myDelegate.getParameters(), PsiType.class, new Function<PsiType, PsiType>() { @Override public PsiType fun(PsiType type) { if (type == null) { LOG.error( myDelegate + " of " + myDelegate.getClass() + "; substitutor=" + myDelegate.resolveGenerics().getSubstitutor()); return null; } return mapType(type); } }); }
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; }
@Override public int getParameterCount() { return myDelegate.getParameters().length; }