mirror of
https://gitflic.ru/project/openide/openide.git
synced 2026-09-27 10:03:11 +07:00
IDEA-195683 'Invert boolean' should update contract annotations when applicable
This commit is contained in:
+22
@@ -2,6 +2,9 @@
|
||||
package com.intellij.codeInspection.dataFlow;
|
||||
|
||||
import com.intellij.codeInsight.AnnotationUtil;
|
||||
import com.intellij.codeInsight.InferredAnnotationsManagerImpl;
|
||||
import com.intellij.openapi.project.Project;
|
||||
import com.intellij.openapi.util.text.StringUtil;
|
||||
import com.intellij.psi.PsiAnnotation;
|
||||
import com.intellij.psi.PsiExpression;
|
||||
import com.intellij.psi.PsiMethod;
|
||||
@@ -11,6 +14,7 @@ import com.intellij.psi.util.CachedValuesManager;
|
||||
import com.intellij.psi.util.PsiModificationTracker;
|
||||
import com.siyeh.ig.psiutils.ExpressionUtils;
|
||||
import com.siyeh.ig.psiutils.MethodCallUtils;
|
||||
import one.util.streamex.StreamEx;
|
||||
import org.jetbrains.annotations.Contract;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
@@ -66,6 +70,24 @@ public class JavaMethodContractUtil {
|
||||
return getContractInfo(method).isExplicit();
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a new {@link PsiAnnotation} describing the updated contract. Only contract clauses are updated;
|
||||
* purity and mutation signature (if exist) are left as is.
|
||||
*
|
||||
* @param annotation original annotation to update
|
||||
* @param contracts new contracts
|
||||
* @return new {@link PsiAnnotation} object which describes updated contracts or null if no annotation is required to represent
|
||||
* the target contracts (i.e. contracts is empty, method has no mutation signature and is not marked as pure).
|
||||
*/
|
||||
@Nullable
|
||||
public static PsiAnnotation updateContract(PsiAnnotation annotation, List<StandardMethodContract> contracts) {
|
||||
boolean pure = Boolean.TRUE.equals(AnnotationUtil.getBooleanAttributeValue(annotation, "pure"));
|
||||
String mutates = StringUtil.notNullize(AnnotationUtil.getStringAttributeValue(annotation, MutationSignature.ATTR_MUTATES));
|
||||
String resultValue = StreamEx.of(contracts).joining("; ");
|
||||
Project project = annotation.getProject();
|
||||
return InferredAnnotationsManagerImpl.createContractAnnotation(project, pure, resultValue, mutates);
|
||||
}
|
||||
|
||||
static class ContractInfo {
|
||||
static final ContractInfo EMPTY = new ContractInfo(Collections.emptyList(), false, false, MutationSignature.UNKNOWN);
|
||||
|
||||
|
||||
@@ -2,13 +2,10 @@
|
||||
package com.intellij.refactoring.changeSignature;
|
||||
|
||||
import com.intellij.codeInsight.AnnotationUtil;
|
||||
import com.intellij.codeInsight.InferredAnnotationsManagerImpl;
|
||||
import com.intellij.codeInspection.dataFlow.ContractReturnValue;
|
||||
import com.intellij.codeInspection.dataFlow.JavaMethodContractUtil;
|
||||
import com.intellij.codeInspection.dataFlow.MutationSignature;
|
||||
import com.intellij.codeInspection.dataFlow.StandardMethodContract;
|
||||
import com.intellij.openapi.project.Project;
|
||||
import com.intellij.openapi.util.text.StringUtil;
|
||||
import com.intellij.psi.PsiAnnotation;
|
||||
import com.intellij.psi.PsiMethod;
|
||||
import one.util.streamex.IntStreamEx;
|
||||
@@ -62,11 +59,7 @@ public final class ContractConverter {
|
||||
result.add(convertContract(contract, newToOldIndex, oldToNewIndex, oldParameterNames));
|
||||
}
|
||||
if (result.equals(contracts)) return annotation;
|
||||
boolean pure = Boolean.TRUE.equals(AnnotationUtil.getBooleanAttributeValue(annotation, "pure"));
|
||||
String mutates = StringUtil.notNullize(AnnotationUtil.getStringAttributeValue(annotation, MutationSignature.ATTR_MUTATES));
|
||||
String resultValue = StreamEx.of(result).joining("; ");
|
||||
Project project = method.getProject();
|
||||
return InferredAnnotationsManagerImpl.createContractAnnotation(project, pure, resultValue, mutates);
|
||||
return JavaMethodContractUtil.updateContract(annotation, result);
|
||||
}
|
||||
|
||||
@NotNull
|
||||
|
||||
+34
-1
@@ -15,7 +15,11 @@
|
||||
*/
|
||||
package com.intellij.refactoring.invertBoolean;
|
||||
|
||||
import com.intellij.codeInsight.AnnotationUtil;
|
||||
import com.intellij.codeInsight.daemon.impl.RecursiveCallLineMarkerProvider;
|
||||
import com.intellij.codeInspection.dataFlow.ContractReturnValue;
|
||||
import com.intellij.codeInspection.dataFlow.JavaMethodContractUtil;
|
||||
import com.intellij.codeInspection.dataFlow.StandardMethodContract;
|
||||
import com.intellij.ide.util.SuperMethodWarningUtil;
|
||||
import com.intellij.lang.java.JavaLanguage;
|
||||
import com.intellij.openapi.editor.Editor;
|
||||
@@ -30,12 +34,14 @@ import com.intellij.refactoring.util.CommonRefactoringUtil;
|
||||
import com.intellij.refactoring.util.LambdaRefactoringUtil;
|
||||
import com.intellij.usageView.UsageInfo;
|
||||
import com.intellij.util.Query;
|
||||
import java.util.HashSet;
|
||||
import com.intellij.util.containers.ContainerUtil;
|
||||
import com.intellij.util.containers.MultiMap;
|
||||
import com.siyeh.ig.psiutils.BoolUtils;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
import java.util.Collection;
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
|
||||
public class JavaInvertBooleanDelegate extends InvertBooleanDelegate {
|
||||
@Override
|
||||
@@ -199,6 +205,33 @@ public class JavaInvertBooleanDelegate extends InvertBooleanDelegate {
|
||||
if (initializer != null) {
|
||||
replaceWithNegatedExpression(initializer);
|
||||
}
|
||||
} else if (element instanceof PsiMethod) {
|
||||
updateContract((PsiMethod)element);
|
||||
}
|
||||
}
|
||||
|
||||
private static void updateContract(@NotNull PsiMethod method) {
|
||||
PsiAnnotation annotation = JavaMethodContractUtil.findContractAnnotation(method);
|
||||
if (annotation == null || annotation.getOwner() != method.getModifierList()) return;
|
||||
String text = AnnotationUtil.getStringAttributeValue(annotation, null);
|
||||
if (text == null || text.trim().isEmpty()) return;
|
||||
List<StandardMethodContract> contracts;
|
||||
try {
|
||||
contracts = StandardMethodContract.parseContract(text);
|
||||
}
|
||||
catch (StandardMethodContract.ParseException ignore) {
|
||||
return;
|
||||
}
|
||||
List<StandardMethodContract> newContracts = ContainerUtil.map(contracts, contract -> {
|
||||
ContractReturnValue value = contract.getReturnValue();
|
||||
return value instanceof ContractReturnValue.BooleanReturnValue ?
|
||||
contract.withReturnValue(((ContractReturnValue.BooleanReturnValue)value).negate()) :
|
||||
contract;
|
||||
});
|
||||
if (newContracts.equals(contracts)) return;
|
||||
PsiAnnotation newAnnotation = JavaMethodContractUtil.updateContract(annotation, newContracts);
|
||||
if (newAnnotation != null) {
|
||||
annotation.replace(newAnnotation);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -0,0 +1,12 @@
|
||||
import org.jetbrains.annotations.Contract;
|
||||
|
||||
class C {
|
||||
@Contract(value = "!null, _ -> false; null, null -> false; null, !null -> true", pure = true)
|
||||
boolean f<caret>oo(String s, String s2) {
|
||||
return s == null && s2 != null;
|
||||
}
|
||||
|
||||
void bar() {
|
||||
foo();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,12 @@
|
||||
import org.jetbrains.annotations.Contract;
|
||||
|
||||
class C {
|
||||
@Contract(value = "!null, _ -> true; null, null -> true; null, !null -> false", pure = true)
|
||||
boolean fooInverted(String s, String s2) {
|
||||
return s != null || s2 == null;
|
||||
}
|
||||
|
||||
void bar() {
|
||||
fooInverted();
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user