Search in sources :

Example 1 with TypeEvaluator

use of com.intellij.refactoring.typeMigration.TypeEvaluator in project intellij-community by JetBrains.

the class RootTypeConversionRule method findConversion.

public TypeConversionDescriptorBase findConversion(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) {
                PsiMethod method = (PsiMethod) member;
                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;
}
Also used : NotNull(org.jetbrains.annotations.NotNull) TypeConversionDescriptorBase(com.intellij.refactoring.typeMigration.TypeConversionDescriptorBase) TypeEvaluator(com.intellij.refactoring.typeMigration.TypeEvaluator)

Example 2 with TypeEvaluator

use of com.intellij.refactoring.typeMigration.TypeEvaluator in project intellij-community by JetBrains.

the class AtomicConversionRule method findDirectConversion.

@Nullable
public static TypeConversionDescriptor findDirectConversion(PsiElement context, PsiType to, PsiType from) {
    final PsiClass toTypeClass = PsiUtil.resolveClassInType(to);
    LOG.assertTrue(toTypeClass != null);
    final String qualifiedName = toTypeClass.getQualifiedName();
    if (qualifiedName != null) {
        if (qualifiedName.equals(AtomicInteger.class.getName()) || qualifiedName.equals(AtomicLong.class.getName())) {
            if (context instanceof PsiPostfixExpression) {
                final IElementType operationSign = ((PsiPostfixExpression) context).getOperationTokenType();
                if (operationSign == JavaTokenType.MINUSMINUS) {
                    return new TypeConversionDescriptor("$qualifier$--", "$qualifier$.getAndDecrement()");
                }
                if (operationSign == JavaTokenType.PLUSPLUS) {
                    return new TypeConversionDescriptor("$qualifier$++", "$qualifier$.getAndIncrement()");
                }
            } else if (context instanceof PsiPrefixExpression) {
                final IElementType operationSign = ((PsiPrefixExpression) context).getOperationTokenType();
                if (operationSign == JavaTokenType.MINUSMINUS) {
                    return new TypeConversionDescriptor("--$qualifier$", "$qualifier$.decrementAndGet()");
                }
                if (operationSign == JavaTokenType.PLUSPLUS) {
                    return new TypeConversionDescriptor("++$qualifier$", "$qualifier$.incrementAndGet()");
                }
            } else if (context instanceof PsiAssignmentExpression) {
                final PsiJavaToken signToken = ((PsiAssignmentExpression) context).getOperationSign();
                final IElementType operationSign = signToken.getTokenType();
                final String sign = signToken.getText();
                if (operationSign == JavaTokenType.PLUSEQ || operationSign == JavaTokenType.MINUSEQ) {
                    return new TypeConversionDescriptor("$qualifier$ " + sign + " $val$", "$qualifier$.addAndGet(" + (operationSign == JavaTokenType.MINUSEQ ? "-($val$))" : "$val$)")) {

                        @Override
                        public PsiExpression replace(PsiExpression expression, @NotNull TypeEvaluator evaluator) {
                            final PsiMethodCallExpression result = (PsiMethodCallExpression) super.replace(expression, evaluator);
                            final PsiExpression argument = result.getArgumentList().getExpressions()[0];
                            if (argument instanceof PsiPrefixExpression) {
                                final PsiExpression operand = ((PsiPrefixExpression) argument).getOperand();
                                final PsiExpression striped = ParenthesesUtils.stripParentheses(operand);
                                if (striped != null && operand != striped) {
                                    operand.replace(striped);
                                }
                            }
                            return result;
                        }
                    };
                }
            } else if (context instanceof PsiLiteralExpression && !(context.getParent() instanceof PsiAssignmentExpression)) {
                return wrapWithNewExpression(to, from, (PsiExpression) context, context);
            }
        } else if (qualifiedName.equals(AtomicIntegerArray.class.getName()) || qualifiedName.equals(AtomicLongArray.class.getName())) {
            PsiElement parentExpression = context.getParent();
            if (parentExpression instanceof PsiPostfixExpression) {
                final IElementType operationSign = ((PsiPostfixExpression) parentExpression).getOperationTokenType();
                if (operationSign == JavaTokenType.MINUSMINUS) {
                    return new TypeConversionDescriptor("$qualifier$[$idx$]--", "$qualifier$.getAndDecrement($idx$)", (PsiExpression) parentExpression);
                }
                if (operationSign == JavaTokenType.PLUSPLUS) {
                    return new TypeConversionDescriptor("$qualifier$[$idx$]++", "$qualifier$.getAndIncrement($idx$)", (PsiExpression) parentExpression);
                }
            } else if (parentExpression instanceof PsiPrefixExpression) {
                final IElementType operationSign = ((PsiPrefixExpression) parentExpression).getOperationTokenType();
                if (operationSign == JavaTokenType.MINUSMINUS) {
                    return new TypeConversionDescriptor("--$qualifier$[$idx$]", "$qualifier$.decrementAndGet($idx$)", (PsiExpression) parentExpression);
                }
                if (operationSign == JavaTokenType.PLUSPLUS) {
                    return new TypeConversionDescriptor("++$qualifier$[$idx$]", "$qualifier$.incrementAndGet($idx$)", (PsiExpression) parentExpression);
                }
            } else if (parentExpression instanceof PsiAssignmentExpression) {
                final PsiJavaToken signToken = ((PsiAssignmentExpression) parentExpression).getOperationSign();
                final IElementType operationSign = signToken.getTokenType();
                final String sign = signToken.getText();
                if (operationSign == JavaTokenType.PLUSEQ || operationSign == JavaTokenType.MINUSEQ) {
                    return new TypeConversionDescriptor("$qualifier$[$idx$] " + sign + " $val$", "$qualifier$.getAndAdd($idx$, " + (operationSign == JavaTokenType.MINUSEQ ? "-" : "") + "($val$))", (PsiExpression) parentExpression);
                }
            }
        }
    }
    return from instanceof PsiArrayType ? findDirectConversionForAtomicReferenceArray(context, to, from) : findDirectConversionForAtomicReference(context, to, from);
}
Also used : NotNull(org.jetbrains.annotations.NotNull) IElementType(com.intellij.psi.tree.IElementType) TypeEvaluator(com.intellij.refactoring.typeMigration.TypeEvaluator) TypeConversionDescriptor(com.intellij.refactoring.typeMigration.TypeConversionDescriptor) Nullable(org.jetbrains.annotations.Nullable)

Example 3 with TypeEvaluator

use of com.intellij.refactoring.typeMigration.TypeEvaluator in project intellij-community by JetBrains.

the class VoidConversionRule method findConversion.

@Nullable
@Override
public TypeConversionDescriptorBase findConversion(PsiType from, PsiType to, PsiMember member, PsiExpression context, TypeMigrationLabeler labeler) {
    if (PsiType.VOID.equals(to) && context.getParent() instanceof PsiReturnStatement && !SideEffectChecker.mayHaveSideEffects(context)) {
        return new TypeConversionDescriptorBase() {

            @Override
            public PsiExpression replace(PsiExpression expression, @NotNull TypeEvaluator evaluator) throws IncorrectOperationException {
                final PsiElement parent = expression.getParent();
                final Project project = expression.getProject();
                if (parent instanceof PsiReturnStatement) {
                    final PsiReturnStatement replaced = (PsiReturnStatement) parent.replace(JavaPsiFacade.getElementFactory(project).createStatementFromText("return;", null));
                    if (UnnecessaryReturnInspection.isReturnRedundant(replaced, false, null)) {
                        DeleteUnnecessaryStatementFix.deleteUnnecessaryStatement(replaced);
                    }
                }
                return null;
            }
        };
    }
    return null;
}
Also used : Project(com.intellij.openapi.project.Project) TypeConversionDescriptorBase(com.intellij.refactoring.typeMigration.TypeConversionDescriptorBase) TypeEvaluator(com.intellij.refactoring.typeMigration.TypeEvaluator) NotNull(org.jetbrains.annotations.NotNull) Nullable(org.jetbrains.annotations.Nullable)

Example 4 with TypeEvaluator

use of com.intellij.refactoring.typeMigration.TypeEvaluator in project intellij-community by JetBrains.

the class ConvertFieldToAtomicIntention method invoke.

@Override
public void invoke(@NotNull Project project, Editor editor, @NotNull PsiElement element) throws IncorrectOperationException {
    final PsiVariable psiVariable = getVariable(element);
    LOG.assertTrue(psiVariable != null);
    final Query<PsiReference> refs = ReferencesSearch.search(psiVariable);
    final Set<PsiElement> elements = new HashSet<>();
    elements.add(element);
    for (PsiReference reference : refs) {
        elements.add(reference.getElement());
    }
    if (!FileModificationService.getInstance().preparePsiElementsForWrite(elements))
        return;
    psiVariable.normalizeDeclaration();
    final JavaPsiFacade psiFacade = JavaPsiFacade.getInstance(project);
    final PsiElementFactory factory = JavaPsiFacade.getElementFactory(project);
    final PsiType fromType = psiVariable.getType();
    PsiClassType toType;
    final String atomicQualifiedName = myFromToMap.get(fromType);
    if (atomicQualifiedName != null) {
        final PsiClass atomicClass = psiFacade.findClass(atomicQualifiedName, GlobalSearchScope.allScope(project));
        if (atomicClass == null) {
            //show warning
            return;
        }
        toType = factory.createType(atomicClass);
    } else if (fromType instanceof PsiArrayType) {
        final PsiClass atomicReferenceArrayClass = psiFacade.findClass(AtomicReferenceArray.class.getName(), GlobalSearchScope.allScope(project));
        if (atomicReferenceArrayClass == null) {
            //show warning
            return;
        }
        final Map<PsiTypeParameter, PsiType> substitutor = ContainerUtil.newHashMap();
        final PsiTypeParameter[] typeParameters = atomicReferenceArrayClass.getTypeParameters();
        if (typeParameters.length == 1) {
            PsiType componentType = ((PsiArrayType) fromType).getComponentType();
            if (componentType instanceof PsiPrimitiveType)
                componentType = ((PsiPrimitiveType) componentType).getBoxedType(element);
            substitutor.put(typeParameters[0], componentType);
        }
        toType = factory.createType(atomicReferenceArrayClass, factory.createSubstitutor(substitutor));
    } else {
        final PsiClass atomicReferenceClass = psiFacade.findClass(AtomicReference.class.getName(), GlobalSearchScope.allScope(project));
        if (atomicReferenceClass == null) {
            //show warning
            return;
        }
        final Map<PsiTypeParameter, PsiType> substitutor = ContainerUtil.newHashMap();
        final PsiTypeParameter[] typeParameters = atomicReferenceClass.getTypeParameters();
        if (typeParameters.length == 1) {
            PsiType type = fromType;
            if (type instanceof PsiPrimitiveType)
                type = ((PsiPrimitiveType) fromType).getBoxedType(element);
            substitutor.put(typeParameters[0], type);
        }
        toType = factory.createType(atomicReferenceClass, factory.createSubstitutor(substitutor));
    }
    try {
        for (PsiReference reference : refs) {
            PsiElement refElement = reference.getElement();
            PsiElement psiElement = refElement;
            if (psiElement instanceof PsiExpression) {
                final PsiElement parent = psiElement.getParent();
                if (parent instanceof PsiExpression && !(parent instanceof PsiReferenceExpression || parent instanceof PsiPolyadicExpression)) {
                    psiElement = parent;
                }
                if (psiElement instanceof PsiBinaryExpression) {
                    PsiBinaryExpression binary = (PsiBinaryExpression) psiElement;
                    if (isBinaryOpApplicable(binary.getOperationTokenType(), binary.getLOperand(), binary.getROperand(), refElement, toType)) {
                        continue;
                    }
                } else if (psiElement instanceof PsiAssignmentExpression) {
                    final PsiAssignmentExpression assignment = (PsiAssignmentExpression) psiElement;
                    final IElementType opSign = TypeConversionUtil.convertEQtoOperation(assignment.getOperationTokenType());
                    if (isBinaryOpApplicable(opSign, assignment.getLExpression(), assignment.getRExpression(), refElement, toType)) {
                        continue;
                    }
                }
                final TypeConversionDescriptor directConversion = AtomicConversionRule.findDirectConversion(psiElement, toType, fromType);
                if (directConversion != null) {
                    TypeMigrationReplacementUtil.replaceExpression((PsiExpression) psiElement, project, directConversion, new TypeEvaluator(null, null));
                }
            }
        }
        PsiExpression initializer = psiVariable.getInitializer();
        if (initializer != null) {
            if (initializer instanceof PsiArrayInitializerExpression) {
                PsiExpression normalizedExpr = RefactoringUtil.createNewExpressionFromArrayInitializer((PsiArrayInitializerExpression) initializer, psiVariable.getType());
                initializer = (PsiExpression) initializer.replace(normalizedExpr);
            }
            final TypeConversionDescriptor directConversion = AtomicConversionRule.wrapWithNewExpression(toType, fromType, initializer, element);
            if (directConversion != null) {
                TypeMigrationReplacementUtil.replaceExpression(initializer, project, directConversion, new TypeEvaluator(null, null));
            }
        } else if (!assertNotNull(psiVariable.getModifierList()).hasModifierProperty(PsiModifier.FINAL)) {
            final PsiExpression newInitializer = factory.createExpressionFromText("new " + toType.getCanonicalText() + "()", psiVariable);
            if (psiVariable instanceof PsiLocalVariable) {
                ((PsiLocalVariable) psiVariable).setInitializer(newInitializer);
            } else if (psiVariable instanceof PsiField) {
                ((PsiField) psiVariable).setInitializer(newInitializer);
            }
            JavaCodeStyleManager.getInstance(project).shortenClassReferences(psiVariable.getInitializer());
        }
        PsiElement replaced = assertNotNull(psiVariable.getTypeElement()).replace(factory.createTypeElement(toType));
        JavaCodeStyleManager.getInstance(project).shortenClassReferences(replaced);
        if (psiVariable instanceof PsiField || CodeStyleSettingsManager.getSettings(project).GENERATE_FINAL_LOCALS) {
            final PsiModifierList modifierList = assertNotNull(psiVariable.getModifierList());
            modifierList.setModifierProperty(PsiModifier.FINAL, true);
            modifierList.setModifierProperty(PsiModifier.VOLATILE, false);
        }
    } catch (IncorrectOperationException e) {
        LOG.error(e);
    }
}
Also used : TypeEvaluator(com.intellij.refactoring.typeMigration.TypeEvaluator) HashSet(java.util.HashSet) IElementType(com.intellij.psi.tree.IElementType) TypeConversionDescriptor(com.intellij.refactoring.typeMigration.TypeConversionDescriptor) IncorrectOperationException(com.intellij.util.IncorrectOperationException) Map(java.util.Map)

Example 5 with TypeEvaluator

use of com.intellij.refactoring.typeMigration.TypeEvaluator in project intellij-community by JetBrains.

the class GuavaFluentIterableConversionRule method getOneMethodDescriptor.

@Nullable
private static TypeConversionDescriptorBase getOneMethodDescriptor(@NotNull String methodName, @NotNull PsiMethod method, @NotNull PsiType from, @Nullable PsiType to, @Nullable PsiExpression context) {
    TypeConversionDescriptor descriptorBase = null;
    PsiType conversionType = null;
    boolean needSpecifyType = true;
    if (methodName.equals("of")) {
        descriptorBase = new TypeConversionDescriptor("'FluentIterable*.of($arr$)", "java.util.Arrays.stream($arr$)");
    } else if (methodName.equals("from")) {
        descriptorBase = new TypeConversionDescriptor("'FluentIterable*.from($it$)", null) {

            @Override
            public PsiExpression replace(PsiExpression expression, @NotNull TypeEvaluator evaluator) {
                final PsiMethodCallExpression methodCall = (PsiMethodCallExpression) expression;
                PsiExpression argument = PseudoLambdaReplaceTemplate.replaceTypeParameters(methodCall.getArgumentList().getExpressions()[0]);
                if (argument == null) {
                    return expression;
                }
                boolean isCollection = InheritanceUtil.isInheritor(PsiTypesUtil.getPsiClass(argument.getType()), CommonClassNames.JAVA_UTIL_COLLECTION);
                setReplaceByString(isCollection ? "($it$).stream()" : "java.util.stream.StreamSupport.stream(($it$).spliterator(), false)");
                final PsiExpression replaced = super.replace(expression, evaluator);
                ParenthesesUtils.removeParentheses(replaced, false);
                return replaced;
            }
        };
    } else if (methodName.equals("filter")) {
        descriptorBase = FluentIterableConversionUtil.getFilterDescriptor(method, context);
    } else if (methodName.equals("isEmpty")) {
        descriptorBase = new TypeConversionDescriptor("$q$.isEmpty()", null) {

            @Override
            public PsiExpression replace(PsiExpression expression, @NotNull TypeEvaluator evaluator) {
                final PsiElement parent = expression.getParent();
                boolean isDoubleNegation = false;
                if (parent instanceof PsiExpression && DoubleNegationInspection.isNegation((PsiExpression) parent)) {
                    isDoubleNegation = true;
                    expression = (PsiExpression) parent.replace(expression);
                }
                setReplaceByString((isDoubleNegation ? "" : "!") + "$q$.findAny().isPresent()");
                return super.replace(expression, evaluator);
            }
        };
        needSpecifyType = false;
    } else if (methodName.equals("transformAndConcat")) {
        descriptorBase = new FluentIterableConversionUtil.TransformAndConcatConversionRule();
    } else if (methodName.equals("toArray")) {
        descriptorBase = FluentIterableConversionUtil.getToArrayDescriptor(from, context);
        needSpecifyType = false;
    } else if (methodName.equals("copyInto")) {
        descriptorBase = new FluentIterableConversionUtil.CopyIntoConversionDescriptor();
        needSpecifyType = false;
    } else if (methodName.equals("append")) {
        descriptorBase = createDescriptorForAppend(method, context);
    } else if (methodName.equals("get")) {
        descriptorBase = new TypeConversionDescriptor("$it$.get($p$)", null) {

            @Override
            public PsiExpression replace(PsiExpression expression, @NotNull TypeEvaluator evaluator) {
                PsiMethodCallExpression methodCall = (PsiMethodCallExpression) expression;
                final PsiExpression[] arguments = methodCall.getArgumentList().getExpressions();
                setReplaceByString("$it$.skip($p$).findFirst().get()");
                if (arguments.length == 1 && arguments[0] instanceof PsiLiteralExpression) {
                    final Object value = ((PsiLiteralExpression) arguments[0]).getValue();
                    if (value != null && value.equals(0)) {
                        setReplaceByString("$it$.findFirst().get()");
                    }
                }
                return super.replace(expression, evaluator);
            }
        };
        needSpecifyType = false;
    } else if (methodName.equals("contains")) {
        descriptorBase = new TypeConversionDescriptor("$it$.contains($o$)", null) {

            @Override
            public PsiExpression replace(PsiExpression expression, @NotNull TypeEvaluator evaluator) {
                final PsiMethodCallExpression methodCallExpression = (PsiMethodCallExpression) expression;
                final PsiExpression qualifier = methodCallExpression.getMethodExpression().getQualifierExpression();
                LOG.assertTrue(qualifier != null);
                final PsiClassType qualifierType = (PsiClassType) qualifier.getType();
                LOG.assertTrue(qualifierType != null);
                final PsiType[] parameters = qualifierType.getParameters();
                final JavaCodeStyleManager codeStyleManager = JavaCodeStyleManager.getInstance(expression.getProject());
                final SuggestedNameInfo suggestedNameInfo = codeStyleManager.suggestVariableName(VariableKind.LOCAL_VARIABLE, null, null, parameters.length == 1 ? parameters[0] : null, false);
                final String suggestedName = codeStyleManager.suggestUniqueVariableName(suggestedNameInfo, expression, false).names[0];
                setReplaceByString("$it$.anyMatch(" + suggestedName + " -> java.util.Objects.equals(" + suggestedName + ", $o$))");
                return super.replace(expression, evaluator);
            }
        };
        needSpecifyType = false;
    } else if (methodName.equals("last")) {
        descriptorBase = new TypeConversionDescriptor("$it$.last()", null) {

            @Override
            public PsiExpression replace(PsiExpression expression, @NotNull TypeEvaluator evaluator) {
                final JavaCodeStyleManager codeStyleManager = JavaCodeStyleManager.getInstance(expression.getProject());
                String varA = suggestName("a", codeStyleManager, expression);
                String varB = suggestName("b", codeStyleManager, expression);
                setReplaceByString("$it$.reduce((" + varA + ", " + varB + ") -> " + varB + ")");
                return super.replace(expression, evaluator);
            }

            private String suggestName(String baseName, JavaCodeStyleManager codeStyleManager, PsiElement place) {
                final SuggestedNameInfo suggestedNameInfo = codeStyleManager.suggestVariableName(VariableKind.LOCAL_VARIABLE, baseName, null, null, false);
                return codeStyleManager.suggestUniqueVariableName(suggestedNameInfo, place, false).names[0];
            }
        };
    } else {
        final TypeConversionDescriptorFactory base = DESCRIPTORS_MAP.get(methodName);
        if (base != null) {
            final TypeConversionDescriptor descriptor = base.create();
            needSpecifyType = base.isChainedMethod();
            if (needSpecifyType && !base.isFluentIterableReturnType()) {
                conversionType = GuavaConversionUtil.addTypeParameters(GuavaOptionalConversionRule.JAVA_OPTIONAL, context.getType(), context);
            }
            descriptorBase = descriptor;
        }
    }
    if (descriptorBase == null) {
        return FluentIterableConversionUtil.createToCollectionDescriptor(methodName, context);
    }
    if (needSpecifyType) {
        if (conversionType == null) {
            PsiMethodCallExpression methodCall = (PsiMethodCallExpression) (context instanceof PsiMethodCallExpression ? context : context.getParent());
            conversionType = GuavaConversionUtil.addTypeParameters(GuavaTypeConversionDescriptor.isIterable(methodCall) ? CommonClassNames.JAVA_LANG_ITERABLE : StreamApiConstants.JAVA_UTIL_STREAM_STREAM, context.getType(), context);
        }
        descriptorBase.withConversionType(conversionType);
    }
    return descriptorBase;
}
Also used : NotNull(org.jetbrains.annotations.NotNull) TypeEvaluator(com.intellij.refactoring.typeMigration.TypeEvaluator) JavaCodeStyleManager(com.intellij.psi.codeStyle.JavaCodeStyleManager) TypeConversionDescriptor(com.intellij.refactoring.typeMigration.TypeConversionDescriptor) SuggestedNameInfo(com.intellij.psi.codeStyle.SuggestedNameInfo) Nullable(org.jetbrains.annotations.Nullable)

Aggregations

TypeEvaluator (com.intellij.refactoring.typeMigration.TypeEvaluator)7 TypeConversionDescriptor (com.intellij.refactoring.typeMigration.TypeConversionDescriptor)5 NotNull (org.jetbrains.annotations.NotNull)5 Nullable (org.jetbrains.annotations.Nullable)4 TypeConversionDescriptorBase (com.intellij.refactoring.typeMigration.TypeConversionDescriptorBase)3 IElementType (com.intellij.psi.tree.IElementType)2 Project (com.intellij.openapi.project.Project)1 JavaCodeStyleManager (com.intellij.psi.codeStyle.JavaCodeStyleManager)1 SuggestedNameInfo (com.intellij.psi.codeStyle.SuggestedNameInfo)1 IncorrectOperationException (com.intellij.util.IncorrectOperationException)1 HashSet (java.util.HashSet)1 Map (java.util.Map)1