Skip to content

Commit f0fa83f

Browse files
authored
Localizing refactoring conflicts gathering (part 1) (#253)
* Localizing refactoring conflicts gathering (part 1). * Removing RUI+RWA.
1 parent e6d476e commit f0fa83f

28 files changed

Lines changed: 855 additions & 760 deletions

‎java-analysis-impl/src/main/java/com/intellij/java/analysis/impl/codeInspection/dataFlow/ContractChecker.java‎

Lines changed: 14 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -12,8 +12,10 @@
1212
import com.intellij.java.language.psi.*;
1313
import com.intellij.java.language.psi.util.PsiUtil;
1414
import com.intellij.java.analysis.impl.codeInspection.ControlFlowUtils;
15+
import consulo.annotation.access.RequiredReadAction;
1516
import consulo.java.analysis.localize.JavaAnalysisLocalize;
1617
import consulo.language.psi.PsiElement;
18+
import consulo.localize.LocalizeValue;
1719
import consulo.util.collection.ContainerUtil;
1820
import jakarta.annotation.Nonnull;
1921

@@ -87,20 +89,20 @@ public DfaInstructionState[] visitControlTransfer(
8789
@Nonnull DataFlowRunner runner,
8890
@Nonnull DfaMemoryState state
8991
) {
90-
if (instruction instanceof ReturnInstruction && ((ReturnInstruction)instruction).isViaException()) {
91-
ContainerUtil.addIfNotNull(myFailures, ((ReturnInstruction)instruction).getAnchor());
92+
if (instruction instanceof ReturnInstruction returnInsn && returnInsn.isViaException()) {
93+
ContainerUtil.addIfNotNull(myFailures, returnInsn.getAnchor());
9294
}
9395
else {
9496
myMayReturnNormally = true;
9597
}
9698
return super.visitControlTransfer(instruction, runner, state);
9799
}
98100

99-
private Map<PsiElement, String> getErrors() {
100-
HashMap<PsiElement, String> errors = new HashMap<>();
101+
private Map<PsiElement, LocalizeValue> getErrors() {
102+
Map<PsiElement, LocalizeValue> errors = new HashMap<>();
101103
for (PsiElement element : myViolations) {
102104
if (!myNonViolations.contains(element)) {
103-
errors.put(element, JavaAnalysisLocalize.inspectionContractCheckerContractViolated(myContract).get());
105+
errors.put(element, JavaAnalysisLocalize.inspectionContractCheckerContractViolated(myContract));
104106
}
105107
}
106108

@@ -111,13 +113,13 @@ private Map<PsiElement, String> getErrors() {
111113
if (myContract.isTrivial()) {
112114
errors.put(
113115
element,
114-
JavaAnalysisLocalize.inspectionContractCheckerMethodAlwaysFailsTrivial(myContract).get()
116+
JavaAnalysisLocalize.inspectionContractCheckerMethodAlwaysFailsTrivial(myContract)
115117
);
116118
}
117119
else {
118120
errors.put(
119121
element,
120-
JavaAnalysisLocalize.inspectionContractCheckerMethodAlwaysFailsNontrivial(myContract).get()
122+
JavaAnalysisLocalize.inspectionContractCheckerMethodAlwaysFailsNontrivial(myContract)
121123
);
122124
}
123125
}
@@ -127,7 +129,7 @@ else if (myFailures.isEmpty() && errors.isEmpty() && myMayReturnNormally) {
127129
PsiIdentifier nameIdentifier = myMethod.getNameIdentifier();
128130
errors.put(
129131
nameIdentifier != null ? nameIdentifier : myMethod,
130-
JavaAnalysisLocalize.inspectionContractCheckerNoExceptionThrown(myContract).get()
132+
JavaAnalysisLocalize.inspectionContractCheckerNoExceptionThrown(myContract)
131133
);
132134
}
133135

@@ -143,7 +145,8 @@ private static boolean weCannotInferAnythingAboutMethodReturnValue(MethodCallIns
143145
}
144146
}
145147

146-
public static Map<PsiElement, String> checkContractClause(PsiMethod method, StandardMethodContract contract, boolean ownContract) {
148+
@RequiredReadAction
149+
public static Map<PsiElement, LocalizeValue> checkContractClause(PsiMethod method, StandardMethodContract contract, boolean ownContract) {
147150
PsiCodeBlock body = method.getBody();
148151
if (body == null) {
149152
return Collections.emptyMap();
@@ -152,8 +155,8 @@ public static Map<PsiElement, String> checkContractClause(PsiMethod method, Stan
152155
DataFlowRunner runner = new DataFlowRunner(method.getProject(), null);
153156

154157
PsiParameter[] parameters = method.getParameterList().getParameters();
155-
final DfaMemoryState initialState = runner.createMemoryState();
156-
final DfaValueFactory factory = runner.getFactory();
158+
DfaMemoryState initialState = runner.createMemoryState();
159+
DfaValueFactory factory = runner.getFactory();
157160
for (int i = 0; i < contract.getParameterCount(); i++) {
158161
ValueConstraint constraint = contract.getParameterConstraint(i);
159162
DfaValue comparisonValue = constraint.getComparisonValue(factory);

‎java-analysis-impl/src/main/java/com/intellij/java/analysis/impl/codeInspection/dataFlow/ContractReturnValue.java‎

Lines changed: 10 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@
99
import com.intellij.java.analysis.impl.codeInspection.dataFlow.value.DfaVariableValue;
1010
import com.intellij.java.language.psi.*;
1111
import consulo.java.analysis.localize.JavaAnalysisLocalize;
12+
import consulo.localize.LocalizeValue;
1213
import jakarta.annotation.Nonnull;
1314
import jakarta.annotation.Nullable;
1415
import org.jetbrains.annotations.Contract;
@@ -83,11 +84,14 @@ public String toString() {
8384
* @return null if this contract return value makes sense for the supplied return type.
8485
* Otherwise the human-readable error message is returned.
8586
*/
86-
public final String getMethodCompatibilityProblem(PsiMethod method) {
87-
//noinspection HardCodedStringLiteral
88-
return validators().map(fn -> fn.apply(method)).filter(Objects::nonNull).findFirst()
89-
.map((JavaAnalysisLocalize.contractReturnValueValidationPrefix(this).get() + ' ')::concat)
90-
.orElse(null);
87+
@Nonnull
88+
public final LocalizeValue getMethodCompatibilityProblem(PsiMethod method) {
89+
return validators()
90+
.map(fn -> fn.apply(method))
91+
.filter(Objects::nonNull)
92+
.findFirst()
93+
.map(value -> JavaAnalysisLocalize.contractReturnValueValidationProblem(myName, value))
94+
.orElse(LocalizeValue.empty());
9195
}
9296

9397
/**
@@ -575,7 +579,7 @@ Stream<Validator> validators() {
575579

576580
@Override
577581
public boolean equals(Object obj) {
578-
return this == obj || (obj instanceof ParameterReturnValue && ((ParameterReturnValue)obj).myParamNumber == myParamNumber);
582+
return this == obj || (obj instanceof ParameterReturnValue paramReturnValue && paramReturnValue.myParamNumber == myParamNumber);
579583
}
580584

581585
@Override

‎java-analysis-impl/src/main/java/com/intellij/java/analysis/impl/codeInspection/dataFlow/MutationSignature.java‎

Lines changed: 18 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77
import com.siyeh.ig.psiutils.MethodCallUtils;
88
import consulo.annotation.access.RequiredReadAction;
99
import consulo.java.analysis.localize.JavaAnalysisLocalize;
10+
import consulo.localize.LocalizeValue;
1011
import consulo.util.lang.ObjectUtil;
1112
import jakarta.annotation.Nonnull;
1213
import jakarta.annotation.Nullable;
@@ -118,8 +119,12 @@ public String toString() {
118119
if (this == UNKNOWN) {
119120
return "(unknown)";
120121
}
121-
return IntStreamEx.range(myParameters.length).mapToEntry(idx -> "param" + (idx + 1), idx -> myParameters[idx])
122-
.prepend("this", myThis).filterValues(b -> b).keys().joining(",");
122+
return IntStreamEx.range(myParameters.length)
123+
.mapToEntry(idx -> "param" + (idx + 1), idx -> myParameters[idx])
124+
.prepend("this", myThis)
125+
.filterValues(b -> b)
126+
.keys()
127+
.joining(",");
123128
}
124129

125130
/**
@@ -208,31 +213,30 @@ else if (!part.isEmpty()) {
208213
* @param method a method to apply the signature
209214
* @return error message or null if signature is valid
210215
*/
211-
@Nullable
212-
public static String checkSignature(@Nonnull String signature, @Nonnull PsiMethod method) {
216+
@Nonnull
217+
public static LocalizeValue checkSignature(@Nonnull String signature, @Nonnull PsiMethod method) {
213218
try {
214219
MutationSignature ms = parse(signature);
215-
if (ms.myThis && method.hasModifierProperty(PsiModifier.STATIC)) {
216-
return JavaAnalysisLocalize.mutationSignatureProblemStaticMethodCannotMutateThis().get();
220+
if (ms.myThis && method.isStatic()) {
221+
return JavaAnalysisLocalize.mutationSignatureProblemStaticMethodCannotMutateThis();
217222
}
218223
PsiParameter[] parameters = method.getParameterList().getParameters();
219224
if (ms.myParameters.length > parameters.length) {
220-
return JavaAnalysisLocalize.mutationSignatureProblemReferenceToParameterInvalid(ms.myParameters.length).get();
225+
return JavaAnalysisLocalize.mutationSignatureProblemReferenceToParameterInvalid(ms.myParameters.length);
221226
}
222227
for (int i = 0; i < ms.myParameters.length; i++) {
223228
if (ms.myParameters[i]) {
224229
PsiType type = parameters[i].getType();
225230
if (ClassUtils.isImmutable(type)) {
226-
return JavaAnalysisLocalize.mutationSignatureProblemParameterHasImmutableType(i + 1, type.getPresentableText())
227-
.get();
231+
return JavaAnalysisLocalize.mutationSignatureProblemParameterHasImmutableType(i + 1, type.getPresentableText());
228232
}
229233
}
230234
}
231235
}
232236
catch (IllegalArgumentException ex) {
233-
return ex.getMessage();
237+
return LocalizeValue.ofNullable(ex.getMessage());
234238
}
235-
return null;
239+
return LocalizeValue.empty();
236240
}
237241

238242
@Nonnull
@@ -256,8 +260,7 @@ public static MutationSignature fromCall(@Nullable PsiCall call) {
256260
}
257261
return fromMethod(method);
258262
}
259-
if (call instanceof PsiNewExpression) {
260-
PsiNewExpression newExpression = (PsiNewExpression)call;
263+
if (call instanceof PsiNewExpression newExpression) {
261264
if (newExpression.isArrayCreation()) {
262265
return PURE;
263266
}
@@ -275,12 +278,12 @@ public static MutationSignature fromCall(@Nullable PsiCall call) {
275278
Set<PsiClass> visited = new HashSet<>();
276279
while (true) {
277280
for (PsiField field : clazz.getFields()) {
278-
if (!field.hasModifierProperty(PsiModifier.STATIC) && field.hasInitializer()) {
281+
if (!field.isStatic() && field.hasInitializer()) {
279282
return UNKNOWN;
280283
}
281284
}
282285
for (PsiClassInitializer initializer : clazz.getInitializers()) {
283-
if (!initializer.hasModifierProperty(PsiModifier.STATIC)) {
286+
if (!initializer.isStatic()) {
284287
return UNKNOWN;
285288
}
286289
}

‎plugin/src/main/java/com/intellij/java/impl/ig/fixes/MakeClassFinalFix.java‎

Lines changed: 69 additions & 68 deletions
Original file line numberDiff line numberDiff line change
@@ -21,9 +21,10 @@
2121
import com.intellij.java.language.psi.PsiModifierList;
2222
import com.siyeh.ig.InspectionGadgetsFix;
2323
import com.siyeh.localize.InspectionGadgetsLocalize;
24+
import consulo.annotation.access.RequiredReadAction;
25+
import consulo.annotation.access.RequiredWriteAction;
2426
import consulo.application.AccessToken;
2527
import consulo.application.WriteAction;
26-
import consulo.application.util.function.Processor;
2728
import consulo.application.util.query.Query;
2829
import consulo.language.editor.inspection.ProblemDescriptor;
2930
import consulo.language.editor.refactoring.ui.ConflictsDialog;
@@ -37,79 +38,79 @@
3738
import jakarta.annotation.Nonnull;
3839

3940
/**
40-
* @author Bas Leijdekkers
41-
*/
41+
* @author Bas Leijdekkers
42+
*/
4243
public class MakeClassFinalFix extends InspectionGadgetsFix {
44+
private final String className;
4345

44-
private final String className;
45-
46-
public MakeClassFinalFix(PsiClass aClass) {
47-
className = aClass.getName();
48-
}
49-
50-
@Override
51-
@Nonnull
52-
public LocalizeValue getName() {
53-
return InspectionGadgetsLocalize.makeClassFinalFixName(className);
54-
}
55-
56-
@Override
57-
protected void doFix(Project project, ProblemDescriptor descriptor) throws IncorrectOperationException {
58-
final PsiElement element = descriptor.getPsiElement();
59-
final PsiClass containingClass = PsiTreeUtil.getParentOfType(element, PsiClass.class);
60-
if (containingClass == null) {
61-
return;
46+
@RequiredReadAction
47+
public MakeClassFinalFix(PsiClass aClass) {
48+
className = aClass.getName();
6249
}
63-
final PsiModifierList modifierList = containingClass.getModifierList();
64-
if (modifierList == null) {
65-
return;
66-
}
67-
if (!isOnTheFly()) {
68-
if (ClassInheritorsSearch.search(containingClass).findFirst() != null) {
69-
return;
70-
}
71-
modifierList.setModifierProperty(PsiModifier.FINAL, true);
72-
modifierList.setModifierProperty(PsiModifier.ABSTRACT, false);
73-
return;
50+
51+
@Nonnull
52+
@Override
53+
public LocalizeValue getName() {
54+
return InspectionGadgetsLocalize.makeClassFinalFixName(className);
7455
}
75-
final MultiMap<PsiElement, String> conflicts = new MultiMap();
76-
final Query<PsiClass> search = ClassInheritorsSearch.search(containingClass);
77-
search.forEach(new Processor<PsiClass>() {
78-
@Override
79-
public boolean process(PsiClass aClass) {
80-
conflicts.putValue(
81-
containingClass,
82-
InspectionGadgetsLocalize.zeroWillNoLongerBeOverridableBy1(
83-
RefactoringUIUtil.getDescription(containingClass, false),
84-
RefactoringUIUtil.getDescription(aClass, false)
85-
).get()
86-
);
87-
return true;
88-
}
89-
});
90-
final boolean conflictsDialogOK;
91-
if (!conflicts.isEmpty()) {
92-
final ConflictsDialog conflictsDialog = new ConflictsDialog(element.getProject(), conflicts, new Runnable() {
93-
@Override
94-
public void run() {
95-
final AccessToken token = WriteAction.start();
96-
try {
56+
57+
@Override
58+
@RequiredWriteAction
59+
protected void doFix(Project project, ProblemDescriptor descriptor) throws IncorrectOperationException {
60+
PsiElement element = descriptor.getPsiElement();
61+
PsiClass containingClass = PsiTreeUtil.getParentOfType(element, PsiClass.class);
62+
if (containingClass == null) {
63+
return;
64+
}
65+
PsiModifierList modifierList = containingClass.getModifierList();
66+
if (modifierList == null) {
67+
return;
68+
}
69+
if (!isOnTheFly()) {
70+
if (ClassInheritorsSearch.search(containingClass).findFirst() != null) {
71+
return;
72+
}
73+
modifierList.setModifierProperty(PsiModifier.FINAL, true);
74+
modifierList.setModifierProperty(PsiModifier.ABSTRACT, false);
75+
return;
76+
}
77+
MultiMap<PsiElement, LocalizeValue> conflicts = new MultiMap<>();
78+
Query<PsiClass> search = ClassInheritorsSearch.search(containingClass);
79+
search.forEach(aClass -> {
80+
conflicts.putValue(
81+
containingClass,
82+
InspectionGadgetsLocalize.zeroWillNoLongerBeOverridableBy1(
83+
RefactoringUIUtil.getDescription(containingClass, false),
84+
RefactoringUIUtil.getDescription(aClass, false)
85+
)
86+
);
87+
return true;
88+
});
89+
boolean conflictsDialogOK;
90+
if (!conflicts.isEmpty()) {
91+
ConflictsDialog conflictsDialog = new ConflictsDialog(
92+
element.getProject(),
93+
conflicts,
94+
() -> {
95+
AccessToken token = WriteAction.start();
96+
try {
97+
modifierList.setModifierProperty(PsiModifier.FINAL, true);
98+
modifierList.setModifierProperty(PsiModifier.ABSTRACT, false);
99+
}
100+
finally {
101+
token.finish();
102+
}
103+
}
104+
);
105+
conflictsDialog.show();
106+
conflictsDialogOK = conflictsDialog.isOK();
107+
}
108+
else {
109+
conflictsDialogOK = true;
110+
}
111+
if (conflictsDialogOK) {
97112
modifierList.setModifierProperty(PsiModifier.FINAL, true);
98113
modifierList.setModifierProperty(PsiModifier.ABSTRACT, false);
99-
}
100-
finally {
101-
token.finish();
102-
}
103114
}
104-
});
105-
conflictsDialog.show();
106-
conflictsDialogOK = conflictsDialog.isOK();
107-
} else {
108-
conflictsDialogOK = true;
109-
}
110-
if (conflictsDialogOK) {
111-
modifierList.setModifierProperty(PsiModifier.FINAL, true);
112-
modifierList.setModifierProperty(PsiModifier.ABSTRACT, false);
113115
}
114-
}
115116
}

0 commit comments

Comments
 (0)