private static PsiType doNormalizeWildcardByPosition( PsiType type, @NotNull PsiExpression expression, PsiExpression topLevel) { if (type instanceof PsiWildcardType) { final PsiWildcardType wildcardType = (PsiWildcardType) type; if (PsiUtil.isAccessedForWriting(topLevel)) { return wildcardType.isSuper() ? wildcardType.getBound() : PsiCapturedWildcardType.create(wildcardType, expression); } else { if (wildcardType.isExtends()) { return wildcardType.getBound(); } else { return PsiType.getJavaLangObject(expression.getManager(), expression.getResolveScope()); } } } else if (type instanceof PsiArrayType) { final PsiType componentType = ((PsiArrayType) type).getComponentType(); final PsiType normalizedComponentType = doNormalizeWildcardByPosition(componentType, expression, topLevel); if (normalizedComponentType != componentType) { return normalizedComponentType.createArrayType(); } } return type; }
@NotNull public static PsiType[] typesByTypeElements(@NotNull PsiTypeElement[] typeElements) { PsiType[] types = PsiType.createArray(typeElements.length); for (int i = 0; i < types.length; i++) { types[i] = typeElements[i].getType(); } if (types.length == 1 && types[0] instanceof PsiDiamondType) { return ((PsiDiamondType) types[0]).resolveInferredTypes().getTypes(); } return types; }
/** Types should be proceed by the callers themselves */ @Deprecated public static PsiType normalizeWildcardTypeByPosition( @NotNull PsiType type, @NotNull PsiExpression expression) { PsiUtilCore.ensureValid(expression); PsiUtil.ensureValidType(type); PsiExpression topLevel = expression; while (topLevel.getParent() instanceof PsiArrayAccessExpression && ((PsiArrayAccessExpression) topLevel.getParent()).getArrayExpression() == topLevel) { topLevel = (PsiExpression) topLevel.getParent(); } if (topLevel instanceof PsiArrayAccessExpression && !PsiUtil.isAccessedForWriting(topLevel)) { return PsiUtil.captureToplevelWildcards(type, expression); } final PsiType normalized = doNormalizeWildcardByPosition(type, expression, topLevel); LOG.assertTrue(normalized.isValid(), type); if (normalized instanceof PsiClassType && !PsiUtil.isAccessedForWriting(topLevel)) { return PsiUtil.captureToplevelWildcards(normalized, expression); } return normalized; }