mirror of
https://gitflic.ru/project/openide/openide.git
synced 2026-09-27 10:03:11 +07:00
ignore inferred annotation in @NotNull propagation to overridden methods
This commit is contained in:
+10
-25
@@ -17,9 +17,7 @@ package com.intellij.codeInspection.bytecodeAnalysis;
|
||||
|
||||
import com.intellij.ProjectTopics;
|
||||
import com.intellij.codeInsight.AnnotationUtil;
|
||||
import com.intellij.lang.PsiBuilder;
|
||||
import com.intellij.lang.java.parser.JavaParser;
|
||||
import com.intellij.lang.java.parser.JavaParserUtil;
|
||||
import com.intellij.codeInspection.dataFlow.ControlFlowAnalyzer;
|
||||
import com.intellij.openapi.components.AbstractProjectComponent;
|
||||
import com.intellij.openapi.components.ServiceManager;
|
||||
import com.intellij.openapi.diagnostic.Logger;
|
||||
@@ -28,12 +26,11 @@ import com.intellij.openapi.project.Project;
|
||||
import com.intellij.openapi.roots.ContentIterator;
|
||||
import com.intellij.openapi.roots.ModuleRootAdapter;
|
||||
import com.intellij.openapi.roots.ModuleRootEvent;
|
||||
import com.intellij.openapi.util.Key;
|
||||
import com.intellij.openapi.util.ModificationTracker;
|
||||
import com.intellij.openapi.util.NotNullLazyKey;
|
||||
import com.intellij.openapi.vfs.VirtualFile;
|
||||
import com.intellij.pom.java.LanguageLevel;
|
||||
import com.intellij.psi.*;
|
||||
import com.intellij.psi.impl.source.*;
|
||||
import com.intellij.psi.search.GlobalSearchScope;
|
||||
import com.intellij.psi.search.ProjectScope;
|
||||
import com.intellij.psi.util.CachedValueProvider;
|
||||
@@ -54,15 +51,8 @@ import java.util.Collection;
|
||||
*/
|
||||
public class ProjectBytecodeAnalysis extends AbstractProjectComponent {
|
||||
public static final Logger LOG = Logger.getInstance("#com.intellij.codeInspection.bytecodeAnalysis");
|
||||
public static final Key<Boolean> INFERRED_ANNOTATION = Key.create("INFERRED_ANNOTATION");
|
||||
private static final PsiAnnotation[] NO_DATA = new PsiAnnotation[0];
|
||||
private static final CharTableImpl charTable = new CharTableImpl();
|
||||
private static final JavaParserUtil.ParserWrapper ANNOTATION = new JavaParserUtil.ParserWrapper() {
|
||||
@Override
|
||||
public void parse(final PsiBuilder builder) {
|
||||
JavaParser.INSTANCE.getDeclarationParser().parseAnnotation(builder);
|
||||
}
|
||||
};
|
||||
private final PsiManager myPsiManager;
|
||||
|
||||
private volatile Annotations myAnnotations = null;
|
||||
|
||||
@@ -73,9 +63,8 @@ public class ProjectBytecodeAnalysis extends AbstractProjectComponent {
|
||||
return INSTANCE_KEY.getValue(project);
|
||||
}
|
||||
|
||||
public ProjectBytecodeAnalysis(Project project, PsiManager psiManager) {
|
||||
public ProjectBytecodeAnalysis(Project project) {
|
||||
super(project);
|
||||
myPsiManager = psiManager;
|
||||
|
||||
final MessageBusConnection connection = myProject.getMessageBus().connect();
|
||||
connection.subscribe(ProjectTopics.PROJECT_ROOTS, new ModuleRootAdapter() {
|
||||
@@ -191,7 +180,7 @@ public class ProjectBytecodeAnalysis extends AbstractProjectComponent {
|
||||
if (notNull && contractValue != null) {
|
||||
return new PsiAnnotation[]{
|
||||
getNotNullAnnotation(),
|
||||
createAnnotationFromText("@org.jetbrains.annotations.Contract(" + contractValue + ")")
|
||||
createAnnotationFromText("@" + ControlFlowAnalyzer.ORG_JETBRAINS_ANNOTATIONS_CONTRACT + "(" + contractValue + ")")
|
||||
};
|
||||
}
|
||||
else if (notNull) {
|
||||
@@ -201,7 +190,7 @@ public class ProjectBytecodeAnalysis extends AbstractProjectComponent {
|
||||
}
|
||||
else if (contractValue != null) {
|
||||
return new PsiAnnotation[]{
|
||||
createAnnotationFromText("@org.jetbrains.annotations.Contract(" + contractValue + ")")
|
||||
createAnnotationFromText("@" + ControlFlowAnalyzer.ORG_JETBRAINS_ANNOTATIONS_CONTRACT + "(" + contractValue + ")")
|
||||
};
|
||||
}
|
||||
else {
|
||||
@@ -281,14 +270,10 @@ public class ProjectBytecodeAnalysis extends AbstractProjectComponent {
|
||||
}
|
||||
|
||||
@NotNull
|
||||
PsiAnnotation createAnnotationFromText(@NotNull final String text) throws IncorrectOperationException {
|
||||
synchronized (charTable) {
|
||||
final DummyHolder holder = DummyHolderFactory.createHolder(myPsiManager,
|
||||
new JavaDummyElement(text, ANNOTATION, LanguageLevel.HIGHEST), null,
|
||||
charTable);
|
||||
final PsiElement element = SourceTreeToPsiMap.treeElementToPsi(holder.getTreeElement().getFirstChildNode());
|
||||
return (PsiAnnotation) element;
|
||||
}
|
||||
private PsiAnnotation createAnnotationFromText(@NotNull final String text) throws IncorrectOperationException {
|
||||
PsiAnnotation annotation = JavaPsiFacade.getElementFactory(myProject).createAnnotationFromText(text, null);
|
||||
annotation.putUserData(INFERRED_ANNOTATION, Boolean.TRUE);
|
||||
return annotation;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
+9
-2
@@ -16,6 +16,7 @@
|
||||
package com.intellij.codeInspection.nullable;
|
||||
|
||||
import com.intellij.codeInsight.AnnotationUtil;
|
||||
import com.intellij.codeInsight.InferredAnnotationsManager;
|
||||
import com.intellij.codeInsight.NullableNotNullManager;
|
||||
import com.intellij.codeInsight.daemon.GroupNames;
|
||||
import com.intellij.codeInsight.intention.AddAnnotationPsiFix;
|
||||
@@ -282,7 +283,7 @@ public class NullableStuffInspectionBase extends BaseJavaBatchLocalInspectionToo
|
||||
if (!reported_nullable_method_overrides_notnull
|
||||
&& REPORT_NOTNULL_PARAMETER_OVERRIDES_NULLABLE
|
||||
&& annotated.isDeclaredNullable
|
||||
&& NullableNotNullManager.isNotNull(superMethod)) {
|
||||
&& isNotNullNotInferred(superMethod)) {
|
||||
reported_nullable_method_overrides_notnull = true;
|
||||
final PsiAnnotation annotation = AnnotationUtil.findAnnotation(method, nullableManager.getNullables(), true);
|
||||
holder.registerProblem(annotation != null ? annotation : method.getNameIdentifier(),
|
||||
@@ -293,7 +294,7 @@ public class NullableStuffInspectionBase extends BaseJavaBatchLocalInspectionToo
|
||||
&& REPORT_NOT_ANNOTATED_METHOD_OVERRIDES_NOTNULL
|
||||
&& !annotated.isDeclaredNullable
|
||||
&& !annotated.isDeclaredNotNull
|
||||
&& NullableNotNullManager.isNotNull(superMethod)) {
|
||||
&& isNotNullNotInferred(superMethod)) {
|
||||
reported_not_annotated_method_overrides_notnull = true;
|
||||
final String defaultNotNull = nullableManager.getDefaultNotNull();
|
||||
final String[] annotationsToRemove = ArrayUtil.toStringArray(nullableManager.getNullables());
|
||||
@@ -415,6 +416,12 @@ public class NullableStuffInspectionBase extends BaseJavaBatchLocalInspectionToo
|
||||
}
|
||||
}
|
||||
|
||||
private static boolean isNotNullNotInferred(@NotNull PsiMethod superMethod) {
|
||||
Project project = superMethod.getProject();
|
||||
PsiAnnotation notNull = NullableNotNullManager.getInstance(project).getNotNullAnnotation(superMethod);
|
||||
return notNull != null && !InferredAnnotationsManager.getInstance(project).isInferredAnnotation(notNull);
|
||||
}
|
||||
|
||||
@NotNull
|
||||
private static LocalQuickFix[] wrapFix(LocalQuickFix fix) {
|
||||
if (fix == null) return LocalQuickFix.EMPTY_ARRAY;
|
||||
|
||||
@@ -28,9 +28,14 @@ public class InferredAnnotationsManagerImpl extends InferredAnnotationsManager {
|
||||
return listOwner.getProject().getComponent(ProjectBytecodeAnalysis.class).findInferredAnnotation(listOwner, annotationFQN);
|
||||
}
|
||||
|
||||
@Nullable
|
||||
@NotNull
|
||||
@Override
|
||||
public PsiAnnotation[] findInferredAnnotations(@NotNull PsiModifierListOwner listOwner) {
|
||||
return listOwner.getProject().getComponent(ProjectBytecodeAnalysis.class).findInferredAnnotations(listOwner);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isInferredAnnotation(@NotNull PsiAnnotation annotation) {
|
||||
return annotation.getUserData(ProjectBytecodeAnalysis.INFERRED_ANNOTATION) != null;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -15,10 +15,7 @@
|
||||
*/
|
||||
package com.intellij.codeInsight.generation;
|
||||
|
||||
import com.intellij.codeInsight.AnnotationUtil;
|
||||
import com.intellij.codeInsight.CodeInsightActionHandler;
|
||||
import com.intellij.codeInsight.CodeInsightBundle;
|
||||
import com.intellij.codeInsight.MethodImplementor;
|
||||
import com.intellij.codeInsight.*;
|
||||
import com.intellij.codeInsight.intention.AddAnnotationFix;
|
||||
import com.intellij.codeInsight.intention.AddAnnotationPsiFix;
|
||||
import com.intellij.featureStatistics.FeatureUsageTracker;
|
||||
@@ -259,6 +256,11 @@ public class OverrideImplementUtil extends OverrideImplementExploreUtil {
|
||||
for (String annotation : each.getAnnotations(project)) {
|
||||
if (moduleScope != null && facade.findClass(annotation, moduleScope) == null) continue;
|
||||
if (AnnotationUtil.isAnnotated(overridden, annotation, false, false) && !AnnotationUtil.isAnnotated(method, annotation, false, false)) {
|
||||
PsiAnnotation psiAnnotation = AnnotationUtil.findAnnotation(overridden, annotation);
|
||||
if (psiAnnotation != null && InferredAnnotationsManager.getInstance(project).isInferredAnnotation(psiAnnotation)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
AddAnnotationPsiFix.removePhysicalAnnotations(method, each.annotationsToRemove(project, annotation));
|
||||
AddAnnotationPsiFix.addPhysicalAnnotation(annotation, PsiNameValuePair.EMPTY_ARRAY, method.getModifierList());
|
||||
}
|
||||
|
||||
@@ -35,4 +35,6 @@ public abstract class InferredAnnotationsManager {
|
||||
|
||||
@NotNull
|
||||
public abstract PsiAnnotation[] findInferredAnnotations(@NotNull PsiModifierListOwner listOwner);
|
||||
|
||||
public abstract boolean isInferredAnnotation(@NotNull PsiAnnotation annotation);
|
||||
}
|
||||
|
||||
@@ -94,10 +94,15 @@ public class NullableNotNullManager implements PersistentStateComponent<Element>
|
||||
|
||||
@Nullable
|
||||
public String getNullable(PsiModifierListOwner owner) {
|
||||
PsiAnnotation annotation = findNullabilityAnnotation(owner, false, true);
|
||||
PsiAnnotation annotation = getNullableAnnotation(owner);
|
||||
return annotation == null ? null : annotation.getQualifiedName();
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public PsiAnnotation getNullableAnnotation(PsiModifierListOwner owner) {
|
||||
return findNullabilityAnnotation(owner, false, true);
|
||||
}
|
||||
|
||||
public void setDefaultNullable(@NotNull String defaultNullable) {
|
||||
LOG.assertTrue(getNullables().contains(defaultNullable));
|
||||
myDefaultNullable = defaultNullable;
|
||||
@@ -107,9 +112,14 @@ public class NullableNotNullManager implements PersistentStateComponent<Element>
|
||||
return myDefaultNotNull;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public PsiAnnotation getNotNullAnnotation(PsiModifierListOwner owner) {
|
||||
return findNullabilityAnnotation(owner, false, false);
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public String getNotNull(PsiModifierListOwner owner) {
|
||||
PsiAnnotation annotation = findNullabilityAnnotation(owner, false, false);
|
||||
PsiAnnotation annotation = getNotNullAnnotation(owner);
|
||||
return annotation == null ? null : annotation.getQualifiedName();
|
||||
}
|
||||
|
||||
|
||||
-1
@@ -16,7 +16,6 @@ class MyClass {
|
||||
return super.clone();
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
public String toString() {
|
||||
return super.toString();
|
||||
|
||||
-1
@@ -16,7 +16,6 @@ class A {
|
||||
return super.clone();
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
public String toString() {
|
||||
return super.toString();
|
||||
|
||||
-1
@@ -27,7 +27,6 @@ class MyClass<T> implements A<T> {
|
||||
return super.clone();
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
public String toString() {
|
||||
return super.toString();
|
||||
|
||||
Reference in New Issue
Block a user