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);
}
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;
}
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;
}
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;
}
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;
}
Aggregations