mirror of
https://gitflic.ru/project/openide/openide.git
synced 2026-09-27 10:03:11 +07:00
don't return inferred annotations that will be neglected anyway (e.g. on overrideable methods)
This commit is contained in:
+28
-22
@@ -48,22 +48,22 @@ public class InferredAnnotationsManagerImpl extends InferredAnnotationsManager {
|
||||
}
|
||||
}
|
||||
|
||||
if (!ignoreInference(listOwner, annotationFQN)) {
|
||||
PsiAnnotation fromBytecode = ProjectBytecodeAnalysis.getInstance(myProject).findInferredAnnotation(listOwner, annotationFQN);
|
||||
if (fromBytecode != null) {
|
||||
return fromBytecode;
|
||||
}
|
||||
if (ignoreInference(listOwner, annotationFQN)) {
|
||||
return null;
|
||||
}
|
||||
|
||||
PsiAnnotation fromBytecode = ProjectBytecodeAnalysis.getInstance(myProject).findInferredAnnotation(listOwner, annotationFQN);
|
||||
if (fromBytecode != null) {
|
||||
return fromBytecode;
|
||||
}
|
||||
|
||||
if (canInferFromSource(listOwner)) {
|
||||
//noinspection ConstantConditions
|
||||
PsiMethod method = (PsiMethod)listOwner;
|
||||
if (listOwner instanceof PsiMethod) {
|
||||
if (ORG_JETBRAINS_ANNOTATIONS_CONTRACT.equals(annotationFQN)) {
|
||||
return getInferredContractAnnotation(method);
|
||||
return getInferredContractAnnotation((PsiMethod)listOwner);
|
||||
}
|
||||
|
||||
|
||||
if ((AnnotationUtil.NOT_NULL.equals(annotationFQN) || AnnotationUtil.NULLABLE.equals(annotationFQN))) {
|
||||
PsiAnnotation anno = getInferredNullityAnnotation(method);
|
||||
PsiAnnotation anno = getInferredNullityAnnotation((PsiMethod)listOwner);
|
||||
return anno == null ? null : annotationFQN.equals(anno.getQualifiedName()) ? anno : null;
|
||||
}
|
||||
}
|
||||
@@ -79,6 +79,9 @@ public class InferredAnnotationsManagerImpl extends InferredAnnotationsManager {
|
||||
|
||||
@Override
|
||||
public boolean ignoreInference(@NotNull PsiModifierListOwner owner, @Nullable String annotationFQN) {
|
||||
if (owner instanceof PsiMethod && PsiUtil.canBeOverriden((PsiMethod)owner)) {
|
||||
return true;
|
||||
}
|
||||
if (ORG_JETBRAINS_ANNOTATIONS_CONTRACT.equals(annotationFQN) && hasHardcodedContracts(owner)) {
|
||||
return true;
|
||||
}
|
||||
@@ -138,10 +141,6 @@ public class InferredAnnotationsManagerImpl extends InferredAnnotationsManager {
|
||||
return ProjectBytecodeAnalysis.getInstance(myProject).createContractAnnotation(attrs);
|
||||
}
|
||||
|
||||
private static boolean canInferFromSource(PsiModifierListOwner listOwner) {
|
||||
return listOwner instanceof PsiMethod && !PsiUtil.canBeOverriden((PsiMethod)listOwner);
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
public PsiAnnotation[] findInferredAnnotations(@NotNull PsiModifierListOwner listOwner) {
|
||||
@@ -150,17 +149,24 @@ public class InferredAnnotationsManagerImpl extends InferredAnnotationsManager {
|
||||
PsiAnnotation[] fromBytecode = ProjectBytecodeAnalysis.getInstance(myProject).findInferredAnnotations(listOwner);
|
||||
for (PsiAnnotation annotation : fromBytecode) {
|
||||
if (!ignoreInference(listOwner, annotation.getQualifiedName())) {
|
||||
if (!ORG_JETBRAINS_ANNOTATIONS_CONTRACT.equals(annotation.getQualifiedName()) || canInferFromSource(listOwner)) {
|
||||
result.add(annotation);
|
||||
}
|
||||
result.add(annotation);
|
||||
}
|
||||
}
|
||||
|
||||
if (canInferFromSource(listOwner)) {
|
||||
if (listOwner instanceof PsiMethod) {
|
||||
PsiAnnotation hardcoded = getHardcodedContractAnnotation((PsiMethod)listOwner);
|
||||
ContainerUtil.addIfNotNull(result, hardcoded != null ? hardcoded : getInferredContractAnnotation((PsiMethod)listOwner));
|
||||
|
||||
ContainerUtil.addIfNotNull(result, getInferredNullityAnnotation((PsiMethod)listOwner));
|
||||
if (hardcoded != null) {
|
||||
result.add(hardcoded);
|
||||
} else if (!ignoreInference(listOwner, ORG_JETBRAINS_ANNOTATIONS_CONTRACT)) {
|
||||
ContainerUtil.addIfNotNull(result, getInferredContractAnnotation((PsiMethod)listOwner));
|
||||
}
|
||||
|
||||
if (!ignoreInference(listOwner, AnnotationUtil.NOT_NULL) || !ignoreInference(listOwner, AnnotationUtil.NULLABLE)) {
|
||||
PsiAnnotation annotation = getInferredNullityAnnotation((PsiMethod)listOwner);
|
||||
if (annotation != null && !ignoreInference(listOwner, annotation.getQualifiedName())) {
|
||||
result.add(annotation);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return result.isEmpty() ? PsiAnnotation.EMPTY_ARRAY : result.toArray(new PsiAnnotation[result.size()]);
|
||||
|
||||
-4
@@ -1490,10 +1490,6 @@ public class ControlFlowAnalyzer extends JavaElementVisitor {
|
||||
final PsiAnnotation contractAnno = findContractAnnotation(method);
|
||||
final int paramCount = method.getParameterList().getParametersCount();
|
||||
if (contractAnno != null) {
|
||||
if (AnnotationUtil.isInferredAnnotation(contractAnno) && PsiUtil.canBeOverriden(method)) {
|
||||
return Collections.emptyList();
|
||||
}
|
||||
|
||||
return CachedValuesManager.getCachedValue(contractAnno, new CachedValueProvider<List<MethodContract>>() {
|
||||
@Nullable
|
||||
@Override
|
||||
|
||||
@@ -24,7 +24,6 @@ import com.intellij.openapi.util.InvalidDataException;
|
||||
import com.intellij.openapi.util.JDOMExternalizableStringList;
|
||||
import com.intellij.openapi.util.WriteExternalException;
|
||||
import com.intellij.psi.*;
|
||||
import com.intellij.psi.util.PsiUtil;
|
||||
import com.intellij.psi.util.TypeConversionUtil;
|
||||
import com.intellij.util.containers.ContainerUtil;
|
||||
import org.jdom.Element;
|
||||
@@ -168,30 +167,16 @@ public class NullableNotNullManager implements PersistentStateComponent<Element>
|
||||
myDefaultNotNull = defaultNotNull;
|
||||
}
|
||||
|
||||
private static boolean skipAnnotation(@NotNull PsiAnnotation annotation, @NotNull PsiModifierListOwner owner) {
|
||||
return owner instanceof PsiMethod &&
|
||||
PsiUtil.canBeOverriden((PsiMethod)owner) &&
|
||||
AnnotationUtil.isInferredAnnotation(annotation) &&
|
||||
AnnotationUtil.NOT_NULL.equals(annotation.getQualifiedName());
|
||||
}
|
||||
|
||||
@Nullable
|
||||
private PsiAnnotation findNullabilityAnnotation(@NotNull PsiModifierListOwner owner, boolean checkBases, boolean nullable) {
|
||||
Set<String> qNames = ContainerUtil.newHashSet(nullable ? getNullables() : getNotNulls());
|
||||
PsiAnnotation annotation = AnnotationUtil.findAnnotation(owner, qNames);
|
||||
if (annotation != null && !skipAnnotation(annotation, owner)) {
|
||||
PsiAnnotation annotation = checkBases && (owner instanceof PsiClass || owner instanceof PsiMethod)
|
||||
? AnnotationUtil.findAnnotationInHierarchy(owner, qNames)
|
||||
: AnnotationUtil.findAnnotation(owner, qNames);
|
||||
if (annotation != null) {
|
||||
return annotation;
|
||||
}
|
||||
|
||||
if (checkBases && owner instanceof PsiMethod) {
|
||||
for (PsiModifierListOwner superOwner : AnnotationUtil.getSuperAnnotationOwners(owner)) {
|
||||
annotation = AnnotationUtil.findAnnotation(superOwner, qNames);
|
||||
if (annotation != null && !skipAnnotation(annotation, superOwner)) {
|
||||
return annotation;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
PsiType type = getOwnerType(owner);
|
||||
if (type == null || TypeConversionUtil.isPrimitiveAndNotNull(type)) return null;
|
||||
|
||||
@@ -317,7 +302,6 @@ public class NullableNotNullManager implements PersistentStateComponent<Element>
|
||||
}
|
||||
|
||||
try {
|
||||
//noinspection deprecation
|
||||
DefaultJDOMExternalizer.writeExternal(this, component);
|
||||
}
|
||||
catch (WriteExternalException e) {
|
||||
@@ -329,7 +313,6 @@ public class NullableNotNullManager implements PersistentStateComponent<Element>
|
||||
@Override
|
||||
public void loadState(Element state) {
|
||||
try {
|
||||
//noinspection deprecation
|
||||
DefaultJDOMExternalizer.readExternal(this, state);
|
||||
if (myNullables.isEmpty()) {
|
||||
Collections.addAll(myNullables, DEFAULT_NULLABLES);
|
||||
|
||||
-5
@@ -2346,11 +2346,6 @@
|
||||
<item name="java.lang.System void checkKey(java.lang.String) 0">
|
||||
<annotation name="org.jetbrains.annotations.NotNull"/>
|
||||
</item>
|
||||
<item name="java.lang.System void exit(int)">
|
||||
<annotation name="org.jetbrains.annotations.Contract">
|
||||
<val val=""_ -> fail""/>
|
||||
</annotation>
|
||||
</item>
|
||||
<item name="java.lang.System void setProperties(java.util.Properties) 0">
|
||||
<annotation name="org.jetbrains.annotations.Nullable"/>
|
||||
</item>
|
||||
|
||||
+4
-10
@@ -3834,18 +3834,12 @@
|
||||
<item name="org.apache.commons.lang.Validate void notEmpty(java.util.Map, java.lang.String) 0">
|
||||
<annotation name="org.jetbrains.annotations.NotNull"/>
|
||||
</item>
|
||||
<!-- hardcoded start -->
|
||||
<item name="org.apache.commons.lang.Validate void notNull(java.lang.Object)">
|
||||
<annotation name="org.jetbrains.annotations.Contract">
|
||||
<val val="value = "null -> fail", pure = true"/>
|
||||
</annotation>
|
||||
<item name="org.apache.commons.lang.Validate void notNull(java.lang.Object) 0">
|
||||
<annotation name="org.jetbrains.annotations.NotNull"/>
|
||||
</item>
|
||||
<item name="org.apache.commons.lang.Validate void notNull(java.lang.Object, java.lang.String)">
|
||||
<annotation name="org.jetbrains.annotations.Contract">
|
||||
<val val="value = "null, _ -> fail", pure = true"/>
|
||||
</annotation>
|
||||
<item name="org.apache.commons.lang.Validate void notNull(java.lang.Object, java.lang.String) 0">
|
||||
<annotation name="org.jetbrains.annotations.NotNull"/>
|
||||
</item>
|
||||
<!-- hardcoded end -->
|
||||
<item name="org.apache.commons.lang.WordUtils WordUtils()">
|
||||
<annotation name="org.jetbrains.annotations.Contract">
|
||||
<val val="pure=true"/>
|
||||
|
||||
+1
-2
@@ -17,7 +17,6 @@ package com.intellij.codeInspection.bytecodeAnalysis;
|
||||
|
||||
import com.intellij.codeInsight.AnnotationUtil;
|
||||
import com.intellij.codeInsight.ExternalAnnotationsManager;
|
||||
import com.intellij.codeInsight.InferredAnnotationsManager;
|
||||
import com.intellij.codeInsight.daemon.GutterMark;
|
||||
import com.intellij.openapi.application.ex.PathManagerEx;
|
||||
import com.intellij.openapi.projectRoots.Sdk;
|
||||
@@ -257,7 +256,7 @@ public class BytecodeAnalysisIntegrationTest extends JavaCodeInsightFixtureTestC
|
||||
|
||||
@Nullable
|
||||
private PsiAnnotation findInferredAnnotation(PsiModifierListOwner owner, String fqn) {
|
||||
return InferredAnnotationsManager.getInstance(myModule.getProject()).findInferredAnnotation(owner, fqn);
|
||||
return ProjectBytecodeAnalysis.getInstance(getProject()).findInferredAnnotation(owner, fqn);
|
||||
}
|
||||
|
||||
@Nullable
|
||||
|
||||
+5
-6
@@ -16,7 +16,6 @@
|
||||
package com.intellij.codeInspection.bytecodeAnalysis;
|
||||
|
||||
import com.intellij.codeInsight.AnnotationUtil;
|
||||
import com.intellij.codeInsight.InferredAnnotationsManager;
|
||||
import com.intellij.codeInspection.bytecodeAnalysis.asm.LeakingParameters;
|
||||
import com.intellij.codeInspection.bytecodeAnalysis.data.*;
|
||||
import com.intellij.openapi.util.io.FileUtil;
|
||||
@@ -48,7 +47,7 @@ public class BytecodeAnalysisTest extends JavaCodeInsightFixtureTestCase {
|
||||
public static final String ORG_JETBRAINS_ANNOTATIONS_CONTRACT = Contract.class.getName();
|
||||
private final String myClassesProjectRelativePath = "/classes/" + Test01.class.getPackage().getName().replace('.', '/');
|
||||
private JavaPsiFacade myJavaPsiFacade;
|
||||
private InferredAnnotationsManager myInferredAnnotationsManager;
|
||||
private ProjectBytecodeAnalysis myBytecodeAnalysisService;
|
||||
private MessageDigest myMessageDigest;
|
||||
|
||||
|
||||
@@ -56,7 +55,7 @@ public class BytecodeAnalysisTest extends JavaCodeInsightFixtureTestCase {
|
||||
protected void setUp() throws Exception {
|
||||
super.setUp();
|
||||
myJavaPsiFacade = JavaPsiFacade.getInstance(myModule.getProject());
|
||||
myInferredAnnotationsManager = InferredAnnotationsManager.getInstance(myModule.getProject());
|
||||
myBytecodeAnalysisService = ProjectBytecodeAnalysis.getInstance(myModule.getProject());
|
||||
myMessageDigest = MessageDigest.getInstance("MD5");
|
||||
setUpDataClasses();
|
||||
}
|
||||
@@ -131,7 +130,7 @@ public class BytecodeAnalysisTest extends JavaCodeInsightFixtureTestCase {
|
||||
params: for (int i = 0; i < annotations.length; i++) {
|
||||
Annotation[] parameterAnnotations = annotations[i];
|
||||
PsiParameter psiParameter = psiMethod.getParameterList().getParameters()[i];
|
||||
PsiAnnotation inferredAnnotation = myInferredAnnotationsManager.findInferredAnnotation(psiParameter, AnnotationUtil.NOT_NULL);
|
||||
PsiAnnotation inferredAnnotation = myBytecodeAnalysisService.findInferredAnnotation(psiParameter, AnnotationUtil.NOT_NULL);
|
||||
for (Annotation parameterAnnotation : parameterAnnotations) {
|
||||
if (parameterAnnotation.annotationType() == ExpectNotNull.class) {
|
||||
assertNotNull(javaMethod.toString() + " " + i, inferredAnnotation);
|
||||
@@ -143,13 +142,13 @@ public class BytecodeAnalysisTest extends JavaCodeInsightFixtureTestCase {
|
||||
|
||||
// not-null result
|
||||
ExpectNotNull expectedAnnotation = javaMethod.getAnnotation(ExpectNotNull.class);
|
||||
PsiAnnotation actualAnnotation = myInferredAnnotationsManager.findInferredAnnotation(psiMethod, AnnotationUtil.NOT_NULL);
|
||||
PsiAnnotation actualAnnotation = myBytecodeAnalysisService.findInferredAnnotation(psiMethod, AnnotationUtil.NOT_NULL);
|
||||
assertEquals(javaMethod.toString(), expectedAnnotation == null, actualAnnotation == null);
|
||||
|
||||
|
||||
// contracts
|
||||
ExpectContract expectedContract = javaMethod.getAnnotation(ExpectContract.class);
|
||||
PsiAnnotation actualContract = myInferredAnnotationsManager.findInferredAnnotation(psiMethod, ORG_JETBRAINS_ANNOTATIONS_CONTRACT);
|
||||
PsiAnnotation actualContract = myBytecodeAnalysisService.findInferredAnnotation(psiMethod, ORG_JETBRAINS_ANNOTATIONS_CONTRACT);
|
||||
|
||||
String expectedText = expectedContract == null ? "null" : expectedContract.toString();
|
||||
String inferredText = actualContract == null ? "null" : actualContract.getText();
|
||||
|
||||
Reference in New Issue
Block a user