Search in sources :

Example 11 with TypeConversionDescriptor

use of com.intellij.refactoring.typeMigration.TypeConversionDescriptor 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)

Example 12 with TypeConversionDescriptor

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

the class GuavaOptionalConversionRule method fillSimpleDescriptors.

@Override
protected void fillSimpleDescriptors(Map<String, TypeConversionDescriptorBase> descriptorsMap) {
    descriptorsMap.put("absent", new TypeConversionDescriptor("'Optional*.absent()", "java.util.Optional.empty()") {

        @Override
        public PsiExpression replace(PsiExpression expression, @NotNull TypeEvaluator evaluator) {
            LOG.assertTrue(expression instanceof PsiMethodCallExpression);
            final PsiReferenceParameterList typeArguments = ((PsiMethodCallExpression) expression).getTypeArgumentList();
            PsiReferenceParameterList typeArgumentsCopy = typeArguments.getTypeArguments().length == 0 ? null : (PsiReferenceParameterList) typeArguments.copy();
            final PsiMethodCallExpression replacedExpression = (PsiMethodCallExpression) super.replace(expression, evaluator);
            if (typeArgumentsCopy != null) {
                replacedExpression.getTypeArgumentList().replace(typeArgumentsCopy);
            }
            return replacedExpression;
        }
    });
    descriptorsMap.put("of", new TypeConversionDescriptor("'Optional*.of($ref$)", "java.util.Optional.of($ref$)"));
    descriptorsMap.put("fromNullable", new TypeConversionDescriptor("'Optional*.fromNullable($ref$)", "java.util.Optional.ofNullable($ref$)"));
    descriptorsMap.put("presentInstances", new TypeConversionDescriptor("'Optional*.presentInstances($it$)", "java.util.stream.StreamSupport.stream($it$.spliterator(), false).map(java.util.Optional::get).collect(java.util.Collectors.toList())"));
    final TypeConversionDescriptorBase identity = new TypeConversionDescriptorBase();
    descriptorsMap.put("get", identity);
    descriptorsMap.put("isPresent", identity);
    descriptorsMap.put("orNull", new TypeConversionDescriptor("$val$.orNull()", "$val$.orElse(null)"));
    descriptorsMap.put("asSet", new TypeConversionDescriptor("$val$.asSet()", "$val$.map(java.util.Collections::singleton).orElse(java.util.Collections.emptySet())"));
}
Also used : TypeEvaluator(com.intellij.refactoring.typeMigration.TypeEvaluator) TypeConversionDescriptorBase(com.intellij.refactoring.typeMigration.TypeConversionDescriptorBase) TypeConversionDescriptor(com.intellij.refactoring.typeMigration.TypeConversionDescriptor)

Example 13 with TypeConversionDescriptor

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

the class GuavaOptionalConversionRule method findConversionForMethod.

@Nullable
@Override
protected TypeConversionDescriptorBase findConversionForMethod(@Nullable PsiType from, @Nullable PsiType to, @NotNull PsiMethod method, @NotNull String methodName, PsiExpression context, TypeMigrationLabeler labeler) {
    if (!(context instanceof PsiMethodCallExpression)) {
        if ("or".equals(methodName)) {
            PsiMethodCallExpression methodCallExpression = null;
            if (context.getParent() instanceof PsiMethodCallExpression) {
                methodCallExpression = (PsiMethodCallExpression) context.getParent();
            }
            if (methodCallExpression == null) {
                return null;
            }
            final PsiClass aClass = getParameterClass(method);
            if (aClass != null) {
                final String qName = aClass.getQualifiedName();
                if (GUAVA_OPTIONAL.equals(qName)) {
                    TypeConversionDescriptor descriptor = new TypeConversionDescriptor(null, "java.util.Optional.ofNullable($val$.orElseGet($o$::get))") {

                        @Override
                        public PsiExpression replace(PsiExpression expression, @NotNull TypeEvaluator evaluator) {
                            setStringToReplace("$val$.or(" + GuavaOptionalConversionUtil.simplifyParameterPattern((PsiMethodCallExpression) expression) + ")");
                            return super.replace(expression, evaluator);
                        }
                    };
                    if (to != null) {
                        descriptor.withConversionType(to);
                    }
                    return descriptor;
                }
                return GuavaLambda.SUPPLIER.getClassQName().equals(qName) ? new GuavaTypeConversionDescriptor("$val$.or($other$)", "$val$.orElseGet($other$)") : new TypeConversionDescriptor("$val$.or($other$)", "$val$.orElse($other$)");
            }
            return null;
        } else if ("transform".equals(methodName)) {
            final PsiMethodCallExpression methodCall = (PsiMethodCallExpression) (context.getParent());
            final PsiExpression[] arguments = methodCall.getArgumentList().getExpressions();
            if (arguments.length != 1) {
                return null;
            }
            final PsiExpression functionArgument = arguments[0];
            final TypeConversionDescriptor descriptor = new GuavaTypeConversionDescriptor("$val$.transform($fun$)", "$val$.map($fun$)");
            final PsiType typeParameter = GuavaConversionUtil.getFunctionReturnType(functionArgument);
            if (typeParameter == null) {
                return descriptor;
            }
            final String rawOptionalType = JAVA_OPTIONAL + "<" + typeParameter.getCanonicalText(false) + ">";
            return descriptor.withConversionType(JavaPsiFacade.getElementFactory(method.getProject()).createTypeFromText(rawOptionalType, context));
        }
        return null;
    }
    final PsiClass aClass = method.getContainingClass();
    if (aClass == null || !(GuavaFluentIterableConversionRule.FLUENT_ITERABLE.equals(aClass.getQualifiedName()) || GUAVA_OPTIONAL.equals(aClass.getQualifiedName()))) {
        return null;
    }
    return GuavaFluentIterableConversionRule.buildCompoundDescriptor((PsiMethodCallExpression) context, to, labeler);
}
Also used : TypeEvaluator(com.intellij.refactoring.typeMigration.TypeEvaluator) TypeConversionDescriptor(com.intellij.refactoring.typeMigration.TypeConversionDescriptor) NotNull(org.jetbrains.annotations.NotNull) Nullable(org.jetbrains.annotations.Nullable)

Aggregations

TypeConversionDescriptor (com.intellij.refactoring.typeMigration.TypeConversionDescriptor)13 Nullable (org.jetbrains.annotations.Nullable)8 IElementType (com.intellij.psi.tree.IElementType)5 TypeEvaluator (com.intellij.refactoring.typeMigration.TypeEvaluator)5 NotNull (org.jetbrains.annotations.NotNull)3 JavaCodeStyleManager (com.intellij.psi.codeStyle.JavaCodeStyleManager)1 SuggestedNameInfo (com.intellij.psi.codeStyle.SuggestedNameInfo)1 TypeConversionDescriptorBase (com.intellij.refactoring.typeMigration.TypeConversionDescriptorBase)1 IncorrectOperationException (com.intellij.util.IncorrectOperationException)1 HashSet (java.util.HashSet)1 Map (java.util.Map)1 NonNls (org.jetbrains.annotations.NonNls)1