Search in sources :

Example 1 with TypeConversionDescriptor

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

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

the class AtomicConversionRule method findDirectConversionForAtomicReference.

@Nullable
private static TypeConversionDescriptor findDirectConversionForAtomicReference(PsiElement context, PsiType to, PsiType from) {
    final PsiElement parent = context.getParent();
    if (parent instanceof PsiAssignmentExpression) {
        final IElementType operationSign = ((PsiAssignmentExpression) parent).getOperationTokenType();
        if (operationSign == JavaTokenType.EQ) {
            return new TypeConversionDescriptor("$qualifier$ = $val$", "$qualifier$.set($val$)", (PsiAssignmentExpression) parent);
        }
    }
    if (context instanceof PsiReferenceExpression) {
        final PsiExpression qualifierExpression = ((PsiReferenceExpression) context).getQualifierExpression();
        final PsiExpression expression = context.getParent() instanceof PsiMethodCallExpression && qualifierExpression != null ? qualifierExpression : (PsiExpression) context;
        return new TypeConversionDescriptor("$qualifier$", "$qualifier$.get()", expression);
    } else if (context instanceof PsiAssignmentExpression) {
        final PsiJavaToken signToken = ((PsiAssignmentExpression) context).getOperationSign();
        final IElementType operationSign = signToken.getTokenType();
        final String sign = signToken.getText();
        if (parent instanceof PsiExpressionStatement) {
            if (operationSign == JavaTokenType.EQ) {
                final PsiExpression lExpression = ((PsiAssignmentExpression) context).getLExpression();
                if (lExpression instanceof PsiReferenceExpression) {
                    final PsiElement element = ((PsiReferenceExpression) lExpression).resolve();
                    if (element instanceof PsiVariable && ((PsiVariable) element).hasModifierProperty(PsiModifier.FINAL)) {
                        return wrapWithNewExpression(to, from, ((PsiAssignmentExpression) context).getRExpression(), element);
                    }
                }
                return new TypeConversionDescriptor("$qualifier$ = $val$", "$qualifier$.set($val$)");
            } else {
                if (PsiUtil.isLanguageLevel8OrHigher(context)) {
                    final String name = JavaCodeStyleManager.getInstance(context.getProject()).suggestUniqueVariableName("v", context, false);
                    return new TypeConversionDescriptor("$qualifier$" + sign + "$val$", "$qualifier$.updateAndGet(" + name + " -> " + getBoxedWrapper(from, to, name + " " + sign.charAt(0) + " $val$)"));
                } else {
                    if (context.getParent() instanceof PsiStatement) {
                        return new TypeConversionDescriptor("$qualifier$" + sign + "$val$", "$qualifier$.set(" + getBoxedWrapper(from, to, "$qualifier$.get() " + sign.charAt(0) + " $val$") + ")");
                    } else {
                        return null;
                    }
                }
            }
        }
    //else should be a conflict
    } else if (context instanceof PsiPostfixExpression) {
        final String sign = ((PsiPostfixExpression) context).getOperationSign().getText();
        return new TypeConversionDescriptor("$qualifier$" + sign, "$qualifier$.getAndSet(" + getBoxedWrapper(from, to, "$qualifier$.get() " + sign.charAt(0) + " 1") + ")");
    } else if (context instanceof PsiPrefixExpression) {
        final PsiJavaToken operationSign = ((PsiPrefixExpression) context).getOperationSign();
        if (operationSign.getTokenType() == JavaTokenType.EXCL) {
            return new TypeConversionDescriptor("!$qualifier$", "!$qualifier$.get()");
        }
        final String sign = operationSign.getText();
        return new TypeConversionDescriptor(sign + "$qualifier$", //todo reject?
        "$qualifier$.set(" + getBoxedWrapper(from, to, "$qualifier$.get() " + sign.charAt(0) + " 1") + ")");
    }
    if (parent instanceof PsiVariable) {
        return wrapWithNewExpression(to, from, null, parent);
    }
    return null;
}
Also used : IElementType(com.intellij.psi.tree.IElementType) TypeConversionDescriptor(com.intellij.refactoring.typeMigration.TypeConversionDescriptor) Nullable(org.jetbrains.annotations.Nullable)

Example 3 with TypeConversionDescriptor

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

the class AtomicConversionRule method findReverseConversionForMethodCall.

@Nullable
private static TypeConversionDescriptor findReverseConversionForMethodCall(PsiElement context) {
    final PsiElement resolved = ((PsiReferenceExpression) context).resolve();
    if (resolved instanceof PsiMethod) {
        final PsiMethod method = (PsiMethod) resolved;
        final int parametersCount = method.getParameterList().getParametersCount();
        final String resolvedName = method.getName();
        if (Comparing.strEqual(resolvedName, "get")) {
            return parametersCount == 0 ? new TypeConversionDescriptor("$qualifier$.get()", "$qualifier$") : new TypeConversionDescriptor("$qualifier$.get($idx$)", "$qualifier$[$idx$]");
        } else if (Comparing.strEqual(resolvedName, "set")) {
            return parametersCount == 1 ? new TypeConversionDescriptor("$qualifier$.set($val$)", "$qualifier$ = $val$") : new TypeConversionDescriptor("$qualifier$.set($idx$, $val$)", "$qualifier$[$idx$] = $val$");
        } else if (Comparing.strEqual(resolvedName, "addAndGet")) {
            return parametersCount == 1 ? new TypeConversionDescriptor("$qualifier$.addAndGet($delta$)", "$qualifier$ + $delta$") : new TypeConversionDescriptor("$qualifier$.addAndGet($idx$, $delta$)", "$qualifier$[$idx$] + $delta$");
        } else if (Comparing.strEqual(resolvedName, "incrementAndGet")) {
            return parametersCount == 0 ? new TypeConversionDescriptor("$qualifier$.incrementAndGet()", "++$qualifier$") : new TypeConversionDescriptor("$qualifier$.incrementAndGet($idx$)", "++$qualifier$[$idx$]");
        } else if (Comparing.strEqual(resolvedName, "decrementAndGet")) {
            return parametersCount == 0 ? new TypeConversionDescriptor("$qualifier$.decrementAndGet()", "--$qualifier$") : new TypeConversionDescriptor("$qualifier$.decrementAndGet($idx$)", "--$qualifier$[$idx$]");
        } else if (Comparing.strEqual(resolvedName, "getAndIncrement")) {
            return parametersCount == 0 ? new TypeConversionDescriptor("$qualifier$.getAndIncrement()", "$qualifier$++") : new TypeConversionDescriptor("$qualifier$.getAndIncrement($idx$)", "$qualifier$[$idx$]++");
        } else if (Comparing.strEqual(resolvedName, "getAndDecrement")) {
            return parametersCount == 0 ? new TypeConversionDescriptor("$qualifier$.getAndDecrement()", "$qualifier$--") : new TypeConversionDescriptor("$qualifier$.getAndDecrement($idx$)", "$qualifier$[$idx$]--");
        } else if (Comparing.strEqual(resolvedName, "getAndAdd")) {
            return parametersCount == 1 ? new TypeConversionDescriptor("$qualifier$.getAndAdd($val$)", "$qualifier$ += $val$") : new TypeConversionDescriptor("$qualifier$.getAndAdd($idx$, $val$)", "$qualifier$[$idx$] += $val$");
        } else if (Comparing.strEqual(resolvedName, "getAndSet")) {
            return parametersCount == 1 ? new TypeConversionDescriptor("$qualifier$.getAndSet($val$)", "$qualifier$ = $val$") : new TypeConversionDescriptor("$qualifier$.getAndSet($idx$, $val$)", "$qualifier$[$idx$] = $val$");
        }
    }
    return null;
}
Also used : TypeConversionDescriptor(com.intellij.refactoring.typeMigration.TypeConversionDescriptor) Nullable(org.jetbrains.annotations.Nullable)

Example 4 with TypeConversionDescriptor

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

the class ListArrayConversionRule method findConversion.

public TypeConversionDescriptorBase findConversion(final PsiType from, final PsiType to, PsiMember member, final PsiExpression context, final TypeMigrationLabeler labeler) {
    PsiExpression expression = context;
    PsiClassType classType = from instanceof PsiClassType ? (PsiClassType) from : to instanceof PsiClassType ? (PsiClassType) to : null;
    PsiArrayType arrayType = from instanceof PsiArrayType ? (PsiArrayType) from : to instanceof PsiArrayType ? (PsiArrayType) to : null;
    if (classType == null || arrayType == null)
        return null;
    final PsiType collectionType = evaluateCollectionsType(classType, expression);
    if (collectionType == null)
        return null;
    if (member == null) {
        final PsiMethodCallExpression callExpression = PsiTreeUtil.getParentOfType(context, PsiMethodCallExpression.class);
        if (callExpression != null) {
            member = callExpression.resolveMethod();
            expression = callExpression;
        }
    }
    if (member instanceof PsiMethod) {
        TypeConversionDescriptor descriptor = changeCollectionCallsToArray((PsiMethod) member, context, collectionType, arrayType);
        if (descriptor != null)
            return descriptor;
        @NonNls final String memberName = member.getName();
        assert memberName != null;
        if (memberName.equals("sort")) {
            if (((PsiMethod) member).getParameterList().getParametersCount() == 1) {
                descriptor = new TypeConversionDescriptor("Arrays.sort($qualifier$)", "Collections.sort($qualifier$)", expression);
            } else {
                descriptor = new TypeConversionDescriptor("Arrays.sort($qualifier$, $expr$)", "Collections.sort($qualifier$, $expr$)", expression);
            }
        } else if (memberName.equals("binarySearch")) {
            if (((PsiMethod) member).getParameterList().getParametersCount() == 2) {
                descriptor = new TypeConversionDescriptor("Arrays.binarySearch($qualifier$, $key$)", "Collections.binarySearch($qualifier$, $key$)", expression);
            } else {
                descriptor = new TypeConversionDescriptor("Arrays.binarySearch($qualifier$, $key$, $comparator$)", "Collections.binarySearch($qualifier$, $key$, $comparator$)", expression);
            }
        } else if (memberName.equals("asList")) {
            if (((PsiMethod) member).getParameterList().getParametersCount() == 1) {
                descriptor = new TypeConversionDescriptor("Arrays.asList($qualifier$)", "$qualifier$", expression);
            }
        } else if (memberName.equals("fill")) {
            descriptor = new TypeConversionDescriptor("Arrays.fill($qualifier$, $filler$)", "Collections.fill($qualifier$, $filler$)", expression);
        }
        if (descriptor != null) {
            return from instanceof PsiClassType ? new TypeConversionDescriptor(descriptor.getReplaceByString(), descriptor.getStringToReplace(), descriptor.getExpression()) : descriptor;
        }
    }
    if (member instanceof PsiField && "length".equals(member.getName())) {
        return new TypeConversionDescriptor("$qualifier$.length", "$qualifier$.size()");
    }
    final PsiElement parent = context.getParent();
    if (parent instanceof PsiAssignmentExpression && ((PsiAssignmentExpression) parent).getLExpression() == context) {
        if (TypeConversionUtil.isAssignable(collectionType, arrayType.getComponentType())) {
            return new TypeConversionDescriptor("$qualifier$[$idx$] = $expr$", "$qualifier$.set($idx$, $expr$)", (PsiExpression) parent);
        }
    } else if (context instanceof PsiArrayAccessExpression && TypeConversionUtil.isAssignable(arrayType.getComponentType(), collectionType)) {
        return new TypeConversionDescriptor("$qualifier$[$idx$]", "$qualifier$.get($idx$)");
    }
    return null;
}
Also used : NonNls(org.jetbrains.annotations.NonNls) TypeConversionDescriptor(com.intellij.refactoring.typeMigration.TypeConversionDescriptor)

Example 5 with TypeConversionDescriptor

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

the class GuavaFluentIterableConversionRule method createDescriptorForAppend.

@Nullable
private static TypeConversionDescriptor createDescriptorForAppend(PsiMethod method, PsiExpression context) {
    LOG.assertTrue("append".equals(method.getName()));
    final PsiParameterList list = method.getParameterList();
    if (list.getParametersCount() != 1)
        return null;
    final PsiType parameterType = list.getParameters()[0].getType();
    if (parameterType instanceof PsiEllipsisType) {
        return new TypeConversionDescriptor("$q$.append('params*)", "java.util.stream.Stream.concat($q$, java.util.Arrays.asList($params$).stream())");
    } else if (parameterType instanceof PsiClassType) {
        final PsiClass psiClass = PsiTypesUtil.getPsiClass(parameterType);
        if (psiClass != null && CommonClassNames.JAVA_LANG_ITERABLE.equals(psiClass.getQualifiedName())) {
            PsiMethodCallExpression methodCall = (PsiMethodCallExpression) (context instanceof PsiMethodCallExpression ? context : context.getParent());
            final PsiExpression expression = methodCall.getArgumentList().getExpressions()[0];
            boolean isCollection = InheritanceUtil.isInheritor(PsiTypesUtil.getPsiClass(expression.getType()), CommonClassNames.JAVA_UTIL_COLLECTION);
            final String argTemplate = isCollection ? "$arg$.stream()" : "java.util.stream.StreamSupport.stream($arg$.spliterator(), false)";
            return new TypeConversionDescriptor("$q$.append($arg$)", "java.util.stream.Stream.concat($q$," + argTemplate + ")");
        }
    }
    return null;
}
Also used : TypeConversionDescriptor(com.intellij.refactoring.typeMigration.TypeConversionDescriptor) 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