[by Willem Verstraeten] dfa: support @AutoValue and other immutable annotations from ConcurrencyAnnotationsManager (IDEA-208913)

adapted from https://github.com/JetBrains/intellij-community/pull/1090
This commit is contained in:
Willem Verstraeten
2019-03-26 16:39:57 +01:00
committed by peter
parent 792667afdc
commit f15d0a899d
4 changed files with 20 additions and 3 deletions
@@ -16,6 +16,7 @@
package com.intellij.codeInspection.dataFlow.value;
import com.intellij.codeInsight.AnnotationUtil;
import com.intellij.codeInsight.ConcurrencyAnnotationsManager;
import com.intellij.codeInsight.Nullability;
import com.intellij.codeInspection.dataFlow.*;
import com.intellij.codeInspection.dataFlow.rangeSet.LongRangeSet;
@@ -232,8 +233,7 @@ public class DfaExpressionFactory {
}
}
if (method.getParameterList().isEmpty()) {
if ((JavaMethodContractUtil.isPure(method) ||
AnnotationUtil.findAnnotation(method.getContainingClass(), "javax.annotation.concurrent.Immutable") != null) &&
if ((JavaMethodContractUtil.isPure(method) || isClassAnnotatedImmutable(method)) &&
isContractAllowedForGetter(method)) {
return new GetterDescriptor(method);
}
@@ -242,6 +242,11 @@ public class DfaExpressionFactory {
return null;
}
private static boolean isClassAnnotatedImmutable(PsiMethod method) {
List<String> annotations = ConcurrencyAnnotationsManager.getInstance(method.getProject()).getImmutableAnnotations();
return AnnotationUtil.findAnnotation(method.getContainingClass(), annotations) != null;
}
private static boolean isContractAllowedForGetter(PsiMethod method) {
List<? extends MethodContract> contracts = JavaMethodContractUtil.getMethodCallContracts(method, null);
if (contracts.size() == 1) {
@@ -17,7 +17,6 @@ package com.intellij.codeInsight;
import com.intellij.openapi.components.ServiceManager;
import com.intellij.openapi.project.Project;
import com.intellij.util.Function;
import com.intellij.util.containers.ContainerUtil;
import java.util.ArrayList;
@@ -42,6 +41,8 @@ public class ConcurrencyAnnotationsManager {
fillDefaults(myGuardedByList, GUARDED_BY);
fillDefaults(myThreadSafeList, THREAD_SAFE);
fillDefaults(myNotThreadSafeList, NOT_THREAD_SAFE);
myImmutableList.add("com.google.auto.value.AutoValue");
}
private static void fillDefaults(List<? super String> list, final String annoName) {
@@ -3,11 +3,21 @@ interface Intf {
@org.jetbrains.annotations.Nullable String foo();
}
@com.google.auto.value.AutoValue
abstract class Value {
abstract @org.jetbrains.annotations.Nullable String foo();
}
class Usage {
void bar(Intf i) {
if (i.foo() != null) {
System.out.println(i.foo().length());
}
}
void bar(Value i) {
if (i.foo() != null) {
System.out.println(i.foo().length());
}
}
}
@@ -278,6 +278,7 @@ public class DataFlowInspectionTest extends DataFlowInspectionTestCase {
}
public void testImmutableClassNonGetterMethod() {
myFixture.addClass("package com.google.auto.value; public @interface AutoValue {}");
myFixture.addClass("package javax.annotation.concurrent; public @interface Immutable {}");
doTest();
}