mirror of
https://gitflic.ru/project/openide/openide.git
synced 2026-09-27 10:03:11 +07:00
java convert to atomic intention: assignment conversion fix IDEA-161639
This commit is contained in:
+16
-6
@@ -7,7 +7,6 @@ import com.intellij.lang.java.JavaLanguage;
|
||||
import com.intellij.openapi.diagnostic.Logger;
|
||||
import com.intellij.openapi.editor.Editor;
|
||||
import com.intellij.openapi.project.Project;
|
||||
import com.intellij.openapi.util.Pair;
|
||||
import com.intellij.psi.*;
|
||||
import com.intellij.psi.codeStyle.CodeStyleSettingsManager;
|
||||
import com.intellij.psi.codeStyle.JavaCodeStyleManager;
|
||||
@@ -21,15 +20,14 @@ import com.intellij.refactoring.typeMigration.TypeConversionDescriptor;
|
||||
import com.intellij.refactoring.typeMigration.TypeEvaluator;
|
||||
import com.intellij.refactoring.typeMigration.TypeMigrationReplacementUtil;
|
||||
import com.intellij.refactoring.typeMigration.rules.AtomicConversionRule;
|
||||
import com.intellij.refactoring.typeMigration.usageInfo.TypeMigrationUsageInfo;
|
||||
import com.intellij.refactoring.util.RefactoringUtil;
|
||||
import com.intellij.util.IncorrectOperationException;
|
||||
import com.intellij.util.Query;
|
||||
import com.intellij.util.containers.ContainerUtil;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import java.util.HashSet;
|
||||
import java.util.LinkedList;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
import java.util.concurrent.atomic.*;
|
||||
@@ -160,7 +158,8 @@ public class ConvertFieldToAtomicIntention extends PsiElementBaseIntentionAction
|
||||
|
||||
try {
|
||||
for (PsiReference reference : refs) {
|
||||
PsiElement psiElement = reference.getElement();
|
||||
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)) {
|
||||
@@ -168,14 +167,14 @@ public class ConvertFieldToAtomicIntention extends PsiElementBaseIntentionAction
|
||||
}
|
||||
if (psiElement instanceof PsiBinaryExpression) {
|
||||
PsiBinaryExpression binary = (PsiBinaryExpression)psiElement;
|
||||
if (isBinaryOperatorApplicable(binary.getOperationTokenType(), binary.getLOperand(), binary.getROperand(), true)) {
|
||||
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 (opSign != null && isBinaryOperatorApplicable(opSign, assignment.getLExpression(), assignment.getRExpression(), true)) {
|
||||
if (isBinaryOpApplicable(opSign, assignment.getLExpression(), assignment.getRExpression(), refElement, toType)) {
|
||||
continue;
|
||||
}
|
||||
}
|
||||
@@ -227,4 +226,15 @@ public class ConvertFieldToAtomicIntention extends PsiElementBaseIntentionAction
|
||||
public boolean startInWriteAction() {
|
||||
return true;
|
||||
}
|
||||
|
||||
private static boolean isBinaryOpApplicable(@Nullable IElementType opSign,
|
||||
@NotNull PsiExpression lExpr,
|
||||
@Nullable PsiExpression rExpr,
|
||||
@NotNull PsiElement varElement,
|
||||
@NotNull PsiType migrationType) {
|
||||
if (opSign == null || rExpr == null) return false;
|
||||
PsiType lType = lExpr == varElement ? migrationType : lExpr.getType();
|
||||
PsiType rType = rExpr == varElement ? migrationType : rExpr.getType();
|
||||
return isBinaryOperatorApplicable(opSign, lType, rType, true);
|
||||
}
|
||||
}
|
||||
|
||||
+35
-8
@@ -7,13 +7,16 @@ package com.intellij.refactoring.typeMigration.rules;
|
||||
import com.intellij.openapi.diagnostic.Logger;
|
||||
import com.intellij.openapi.util.Comparing;
|
||||
import com.intellij.psi.*;
|
||||
import com.intellij.psi.codeStyle.JavaCodeStyleManager;
|
||||
import com.intellij.psi.impl.PsiDiamondTypeUtil;
|
||||
import com.intellij.psi.tree.IElementType;
|
||||
import com.intellij.psi.util.PsiUtil;
|
||||
import com.intellij.psi.util.TypeConversionUtil;
|
||||
import com.intellij.refactoring.typeMigration.TypeConversionDescriptor;
|
||||
import com.intellij.refactoring.typeMigration.TypeConversionDescriptorBase;
|
||||
import com.intellij.refactoring.typeMigration.TypeEvaluator;
|
||||
import com.intellij.refactoring.typeMigration.TypeMigrationLabeler;
|
||||
import com.siyeh.ig.psiutils.ParenthesesUtils;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
@@ -114,9 +117,22 @@ public class AtomicConversionRule extends TypeConversionRule {
|
||||
final IElementType operationSign = signToken.getTokenType();
|
||||
final String sign = signToken.getText();
|
||||
if (operationSign == JavaTokenType.PLUSEQ || operationSign == JavaTokenType.MINUSEQ) {
|
||||
return new TypeConversionDescriptor("$qualifier$ " + sign + " $val$", "$qualifier$.getAndAdd(" +
|
||||
(operationSign == JavaTokenType.MINUSEQ ? "-" : "") +
|
||||
"($val$))");
|
||||
return new TypeConversionDescriptor("$qualifier$ " + sign + " $val$",
|
||||
"$qualifier$.addAndGet(" + (operationSign == JavaTokenType.MINUSEQ ? "-($val$))" : "$val$)")) {
|
||||
@Override
|
||||
public PsiExpression replace(PsiExpression expression, 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;
|
||||
}
|
||||
};
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -198,11 +214,22 @@ public class AtomicConversionRule extends TypeConversionRule {
|
||||
return new TypeConversionDescriptor("$qualifier$ = $val$", "$qualifier$.set($val$)");
|
||||
}
|
||||
else {
|
||||
return new TypeConversionDescriptor("$qualifier$" + sign + "$val$", "$qualifier$.set(" +
|
||||
getBoxedWrapper(from, to, "$qualifier$.get() " +
|
||||
sign.charAt(0) +
|
||||
" $val$") +
|
||||
")");
|
||||
if (PsiUtil.isLanguageLevel8OrHigher(context)) {
|
||||
final String name =
|
||||
JavaCodeStyleManager.getInstance(context.getProject()).suggestUniqueVariableName("v", context, false);
|
||||
return new TypeConversionDescriptor("$qualifier$" + sign + "$val$", "$qualifier$.updateAndGet("
|
||||
+ name + " -> " + 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
|
||||
}
|
||||
|
||||
@@ -0,0 +1,18 @@
|
||||
import java.util.concurrent.atomic.AtomicLong;
|
||||
|
||||
// "Convert to atomic" "true"
|
||||
class A {
|
||||
final AtomicLong x = new AtomicLong(0);
|
||||
|
||||
public void testAtomicLong() {
|
||||
x.getAndIncrement();
|
||||
x.getAndDecrement();
|
||||
x.addAndGet(2);
|
||||
x.addAndGet(-2);
|
||||
x.updateAndGet(v -> v * 3);
|
||||
x.updateAndGet(v -> v / 3);
|
||||
x.updateAndGet(v -> v % 3);
|
||||
x.updateAndGet(v -> v & 3);
|
||||
x.updateAndGet(v -> v | 3);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,16 @@
|
||||
// "Convert to atomic" "true"
|
||||
class A {
|
||||
long <caret>x = 0;
|
||||
|
||||
public void testAtomicLong() {
|
||||
x++;
|
||||
x--;
|
||||
x+=2;
|
||||
x-=2;
|
||||
x*=3;
|
||||
x/=3;
|
||||
x%=3;
|
||||
x&=3;
|
||||
x|=3;
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user