TypeConversionDescriptorBase (final PsiType from, final PsiType to, final PsiMember member, final PsiExpression context, final TypeMigrationLabeler labeler) { if (member != null && to instanceof PsiClassType && from instanceof PsiClassType) { final PsiClass targetClass = ((PsiClassType)to).resolve(); if (targetClass != null && member.isPhysical()) { if (member instanceof PsiMethod method) { PsiMethod replacer = targetClass.findMethodBySignature(method, true); if (replacer == null) { for (PsiMethod superMethod : method.findDeepestSuperMethods()) { replacer = targetClass.findMethodBySignature(superMethod, true); if (replacer != null) { method = superMethod; break; } } } if (replacer != null) { final boolean isStaticMethodConversion = replacer.hasModifierProperty(PsiModifier.STATIC); boolean isValid = isStaticMethodConversion ? TypeConversionUtil.areTypesConvertible(method.getReturnType(), from) && TypeConversionUtil.areTypesConvertible(replacer.getReturnType(), to) : TypeConversionUtil.areTypesConvertible(method.getReturnType(), replacer.getReturnType()); if (isValid) { final PsiElement parent = context.getParent(); if (context instanceof PsiMethodReferenceExpression) { final PsiType functionalInterfaceType = ((PsiMethodReferenceExpression)context).getFunctionalInterfaceType(); if (Comparing.equal(functionalInterfaceType, to) && method.isEquivalentTo(LambdaUtil.getFunctionalInterfaceMethod(from))) { return new TypeConversionDescriptorBase() { @Override public PsiExpression replace(PsiExpression expression, @NotNull TypeEvaluator evaluator) throws IncorrectOperationException { final PsiMethodReferenceExpression methodReferenceExpression = (PsiMethodReferenceExpression)expression; final PsiExpression qualifierExpression = methodReferenceExpression.getQualifierExpression(); if (qualifierExpression != null) { return (PsiExpression)expression.replace(qualifierExpression); } else { return expression; } } }; } } if (context instanceof PsiReferenceExpression && parent instanceof PsiMethodCallExpression) { final JavaResolveResult resolveResult = ((PsiReferenceExpression)context).advancedResolve(false); final PsiSubstitutor aSubst; final PsiReferenceExpression methodExpression = ((PsiMethodCallExpression)parent).getMethodExpression(); final PsiExpression qualifier = methodExpression.getQualifierExpression(); final PsiClass substitutionClass = method.getContainingClass(); if (qualifier != null) { final PsiType evaluatedQualifierType = labeler.getTypeEvaluator().evaluateType(qualifier); if (evaluatedQualifierType instanceof PsiClassType) { aSubst = ((PsiClassType)evaluatedQualifierType).resolveGenerics().getSubstitutor(); } else { aSubst = PsiSubstitutor.EMPTY; } } else { aSubst = TypeConversionUtil.getClassSubstitutor(member.getContainingClass(), substitutionClass, PsiSubstitutor.EMPTY); } final PsiParameter[] originalParams = ((PsiMethod)member).getParameterList().getParameters(); final PsiParameter[] migrationParams = replacer.getParameterList().getParameters(); final PsiExpression[] actualParams = ((PsiMethodCallExpression)parent).getArgumentList().getExpressions(); assert originalParams.length == migrationParams.length; final PsiSubstitutor methodTypeParamsSubstitutor = labeler.getTypeEvaluator() .createMethodSubstitution(originalParams, actualParams, method, context, aSubst != null ? aSubst : PsiSubstitutor.EMPTY, true); for (int i = 0; i < originalParams.length; i++) { final PsiType originalType = resolveResult.getSubstitutor().substitute(originalParams[i].getType()); PsiType type = migrationParams[i].getType(); if (InheritanceUtil.isInheritorOrSelf(targetClass, substitutionClass, true)) { final PsiSubstitutor superClassSubstitutor = TypeConversionUtil.getClassSubstitutor(substitutionClass, targetClass, PsiSubstitutor.EMPTY); assert (superClassSubstitutor != null); type = superClassSubstitutor.substitute(type); } final PsiType migrationType = methodTypeParamsSubstitutor.substitute(type); if (!originalType.equals(migrationType) && !areParametersAssignable(migrationType, i, actualParams)) { if (migrationType instanceof PsiEllipsisType && actualParams.length != migrationParams.length) { return null; } labeler.migrateExpressionType(actualParams[i], migrationType, context, false, true); } } } return isStaticMethodConversion ? new MyStaticMethodConversionDescriptor(targetClass) : new TypeConversionDescriptorBase(); } } } else if (member instanceof PsiField) { final PsiClass fieldContainingClass = member.getContainingClass(); if (InheritanceUtil.isInheritorOrSelf(targetClass, fieldContainingClass, true)) { return new TypeConversionDescriptorBase(); } } } } return null; }