void (PsiExpression expr, PsiType migrationType, PsiElement place, boolean alreadyProcessed, boolean isCovariant) { PsiType originalType = expr.getType(); if (originalType == null || originalType.equals(migrationType)) return; if (originalType.equals(PsiTypes.nullType())) { if (migrationType instanceof PsiPrimitiveType) { markFailedConversion(migrationType, expr); return; } if (place instanceof PsiVariable) { PsiType type = ((PsiVariable)place).getType(); if (((PsiVariable)place).getInitializer() == expr && myRules.shouldConvertNull(type, migrationType, expr)) { convertExpression(expr, migrationType, type, isCovariant); } } return; } if (expr instanceof PsiConditionalExpression condExpr) { for (PsiExpression e : new PsiExpression[]{condExpr.getThenExpression(), condExpr.getElseExpression()}) { if (e != null) { migrateExpressionType(e, migrationType, place, alreadyProcessed, false); } } getTypeEvaluator().setType(new TypeMigrationUsageInfo(expr), migrationType); return; } else if (expr instanceof PsiClassObjectAccessExpression) { if (!TypeConversionUtil.isAssignable(migrationType, expr.getType())) { markFailedConversion(migrationType, expr); return; } } else if (expr instanceof PsiArrayInitializerExpression && migrationType instanceof PsiArrayType) { final PsiExpression[] initializers = ((PsiArrayInitializerExpression)expr).getInitializers(); for (PsiExpression initializer : initializers) { migrateExpressionType(initializer, ((PsiArrayType)migrationType).getComponentType(), expr, alreadyProcessed, true); } getTypeEvaluator().setType(new TypeMigrationUsageInfo(expr), migrationType); return; } else if (expr instanceof PsiArrayAccessExpression) { migrateExpressionType(((PsiArrayAccessExpression)expr).getArrayExpression(), migrationType.createArrayType(), place, alreadyProcessed, isCovariant); return; } else if (expr instanceof PsiReferenceExpression) { final PsiElement resolved = ((PsiReferenceExpression)expr).resolve(); if (resolved != null) { if (!addMigrationRoot(resolved, migrationType, place, alreadyProcessed, !isCovariant)) { convertExpression(expr, migrationType, getTypeEvaluator().evaluateType(expr), isCovariant); } } return; } else if (expr instanceof PsiMethodCallExpression) { final PsiMethod resolved = ((PsiMethodCallExpression)expr).resolveMethod(); if (resolved != null) { if (!addMigrationRoot(resolved, migrationType, place, alreadyProcessed, !isCovariant)) { convertExpression(expr, migrationType, getTypeEvaluator().evaluateType(expr), isCovariant); } } return; } else if (expr instanceof PsiNewExpression) { if (originalType.getArrayDimensions() == migrationType.getArrayDimensions()) { if (migrationType.getArrayDimensions() > 0) { final PsiType elementType = ((PsiArrayType)migrationType).getComponentType(); final PsiArrayInitializerExpression arrayInitializer = ((PsiNewExpression)expr).getArrayInitializer(); if (arrayInitializer != null) { final PsiExpression[] initializers = arrayInitializer.getInitializers(); for (int i = initializers.length - 1; i >= 0; i--) { migrateExpressionType(initializers[i], elementType, place, alreadyProcessed, true); } } if (isGenericsArrayType(elementType)) { markFailedConversion(migrationType, expr); return; } if (!alreadyProcessed) { final TypeMigrationUsageInfo usageInfo = new TypeMigrationUsageInfo(expr); usageInfo.setOwnerRoot(myCurrentRoot); myNewExpressionTypeChange.put(usageInfo, migrationType); getTypeEvaluator().setType(new TypeMigrationUsageInfo(expr), migrationType); } return; } else if (migrationType instanceof PsiClassType && originalType instanceof PsiClassType && ((PsiClassType)migrationType).rawType().isAssignableFrom(((PsiClassType)originalType).rawType())) { final PsiClass originalClass = PsiUtil.resolveClassInType(originalType); if (originalClass instanceof PsiAnonymousClass) { originalType = ((PsiAnonymousClass)originalClass).getBaseClassType(); } final PsiType type = TypeEvaluator.substituteType(migrationType, originalType, true, ((PsiClassType)originalType).resolveGenerics().getElement(), JavaPsiFacade.getElementFactory(expr.getProject()) .createType(((PsiClassType)originalType).resolve(), PsiSubstitutor.EMPTY)); if (type != null) { final TypeMigrationUsageInfo usageInfo = new TypeMigrationUsageInfo(expr); usageInfo.setOwnerRoot(myCurrentRoot); myNewExpressionTypeChange.put(usageInfo, type); getTypeEvaluator().setType(new TypeMigrationUsageInfo(expr), type); return; } } } } else if (expr instanceof PsiLambdaExpression) { //TODO conversion of lambda expression now works incorrectly [Dmitry Batkovich] return; } convertExpression(expr, migrationType, originalType, isCovariant); }