@Nullable private static String getTypeName(PsiType type, boolean withIndices) { type = type.getDeepComponentType(); if (type instanceof PsiClassType) { final PsiClassType classType = (PsiClassType) type; final String className = classType.getClassName(); if (className != null || !withIndices) return className; final PsiClass aClass = classType.resolve(); return aClass instanceof PsiAnonymousClass ? ((PsiAnonymousClass) aClass).getBaseClassType().getClassName() : null; } else if (type instanceof PsiPrimitiveType) { return type.getPresentableText(); } else if (type instanceof PsiWildcardType) { return getTypeName(((PsiWildcardType) type).getExtendsBound(), withIndices); } else if (type instanceof PsiIntersectionType) { return getTypeName(((PsiIntersectionType) type).getRepresentative(), withIndices); } else if (type instanceof PsiCapturedWildcardType) { return getTypeName(((PsiCapturedWildcardType) type).getWildcard(), withIndices); } else if (type instanceof PsiDisjunctionType) { return getTypeName(((PsiDisjunctionType) type).getLeastUpperBound(), withIndices); } else { return null; } }
@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; }
@Nullable private PsiType extractListTypeFromContainingClass( PsiElement element) { PsiClass listClass = PsiTreeUtil.getParentOfType(element, PsiClass.class); if (listClass == null) { return null; } final PsiMethod[] getMethods = listClass.findMethodsByName("get", true); if (getMethods.length == 0) { return null; } final PsiType type = getMethods[0].getReturnType(); if (!(type instanceof PsiClassType)) { return null; } final PsiClassType classType = (PsiClassType)type; final PsiClass parameterClass = classType.resolve(); if (parameterClass == null) { return null; } PsiClass subClass = null; while (listClass != null && !listClass.hasTypeParameters()) { subClass = listClass; listClass = listClass.getSuperClass(); } if (listClass == null || subClass == null) { return TypeUtils.getObjectType(element); } final PsiTypeParameter[] typeParameters = listClass.getTypeParameters(); if (!parameterClass.equals(typeParameters[0])) { return TypeUtils.getObjectType(element); } final PsiReferenceList extendsList = subClass.getExtendsList(); if (extendsList == null) { return null; } final PsiJavaCodeReferenceElement[] referenceElements = extendsList.getReferenceElements(); if (referenceElements.length == 0) { return null; } final PsiType[] types = referenceElements[0].getTypeParameters(); if (types.length == 0) { return TypeUtils.getObjectType(element); } return types[0]; }