mirror of
https://gitflic.ru/project/openide/openide.git
synced 2026-09-27 10:03:11 +07:00
[java-inspections] Quick-fix for missing not-null annotation on type element
GitOrigin-RevId: 6c7d91b8f30015eb1b5f51be422951ba8ef6b36b
This commit is contained in:
committed by
intellij-monorepo-bot
parent
a395ba4819
commit
afc371e029
@@ -155,6 +155,7 @@ service.uses=Uses service <a href="#javaClass/{0}">{0}</a><br><div style='margin
|
||||
suppress.for.parameter=Suppress for parameter
|
||||
suppress.for.statement.with.comment=Suppress for statement with comment
|
||||
intention.add.annotation.family=Add annotation
|
||||
intention.add.type.annotation.family=Add type annotation
|
||||
intention.text.remove.annotation=Remove
|
||||
|
||||
scope.package=Package {0}
|
||||
|
||||
+48
@@ -0,0 +1,48 @@
|
||||
// Copyright 2000-2021 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file.
|
||||
package com.intellij.codeInsight.intention;
|
||||
|
||||
import com.intellij.codeInspection.LocalQuickFix;
|
||||
import com.intellij.codeInspection.ProblemDescriptor;
|
||||
import com.intellij.java.analysis.JavaAnalysisBundle;
|
||||
import com.intellij.openapi.project.Project;
|
||||
import com.intellij.openapi.util.text.StringUtil;
|
||||
import com.intellij.psi.PsiAnnotation;
|
||||
import com.intellij.psi.PsiTypeElement;
|
||||
import com.intellij.util.ObjectUtils;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
import java.util.Collection;
|
||||
|
||||
public class AddTypeAnnotationFix implements LocalQuickFix {
|
||||
private final @NotNull String myAnnotationToAdd;
|
||||
@SafeFieldForPreview
|
||||
private final @NotNull Collection<String> myAnnotationsToRemove;
|
||||
|
||||
public AddTypeAnnotationFix(@NotNull String annotationToAdd, @NotNull Collection<String> annotationsToRemove) {
|
||||
myAnnotationToAdd = annotationToAdd;
|
||||
myAnnotationsToRemove = annotationsToRemove;
|
||||
}
|
||||
|
||||
@Override
|
||||
public @NotNull String getName() {
|
||||
return JavaAnalysisBundle.message("inspection.i18n.quickfix.annotate.as", StringUtil.getShortName(myAnnotationToAdd));
|
||||
}
|
||||
|
||||
@Override
|
||||
public @NotNull String getFamilyName() {
|
||||
return JavaAnalysisBundle.message("intention.add.type.annotation.family");
|
||||
}
|
||||
|
||||
@Override
|
||||
public void applyFix(@NotNull Project project,
|
||||
@NotNull ProblemDescriptor descriptor) {
|
||||
PsiTypeElement typeElement = ObjectUtils.tryCast(descriptor.getStartElement(), PsiTypeElement.class);
|
||||
if (typeElement == null || !typeElement.acceptsAnnotations()) return;
|
||||
for (PsiAnnotation annotation : typeElement.getAnnotations()) {
|
||||
if (myAnnotationsToRemove.contains(annotation.getQualifiedName())) {
|
||||
annotation.delete();
|
||||
}
|
||||
}
|
||||
typeElement.addAnnotation(myAnnotationToAdd);
|
||||
}
|
||||
}
|
||||
+5
-2
@@ -7,6 +7,7 @@ import com.intellij.codeInsight.NullabilityAnnotationInfo;
|
||||
import com.intellij.codeInsight.NullableNotNullManager;
|
||||
import com.intellij.codeInsight.daemon.impl.analysis.JavaGenericsUtil;
|
||||
import com.intellij.codeInsight.intention.AddAnnotationPsiFix;
|
||||
import com.intellij.codeInsight.intention.AddTypeAnnotationFix;
|
||||
import com.intellij.codeInspection.*;
|
||||
import com.intellij.codeInspection.dataFlow.DfaPsiUtil;
|
||||
import com.intellij.codeInspection.dataFlow.instructions.MethodCallInstruction;
|
||||
@@ -257,9 +258,11 @@ public class NullableStuffInspectionBase extends AbstractBaseJavaLocalInspection
|
||||
PsiTypeElement[] typeArguments = getReferenceTypeArguments(reference);
|
||||
if (typeParameters.length > 0 && typeParameters.length == typeArguments.length && !(typeArguments[0].getType() instanceof PsiDiamondType)) {
|
||||
for (int i = 0; i < typeParameters.length; i++) {
|
||||
PsiTypeElement typeArgument = typeArguments[i];
|
||||
if (DfaPsiUtil.getTypeNullability(JavaPsiFacade.getElementFactory(element.getProject()).createType(typeParameters[i])) ==
|
||||
Nullability.NOT_NULL && DfaPsiUtil.getTypeNullability(typeArguments[i].getType()) != Nullability.NOT_NULL) {
|
||||
reportProblem(holder, typeArguments[i], "non.null.type.argument.is.expected");
|
||||
Nullability.NOT_NULL && DfaPsiUtil.getTypeNullability(typeArgument.getType()) != Nullability.NOT_NULL) {
|
||||
AddTypeAnnotationFix fix = new AddTypeAnnotationFix(manager.getDefaultNotNull(), manager.getNullables());
|
||||
reportProblem(holder, typeArgument, fix, "non.null.type.argument.is.expected");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,7 @@
|
||||
import typeUse.*;
|
||||
|
||||
class Bar<T extends @NotNull Object> {
|
||||
public static void main(String[] args) {
|
||||
Bar<<warning descr="Non-null type argument is expected">S<caret>tring</warning>> bar;
|
||||
}
|
||||
}
|
||||
+7
@@ -0,0 +1,7 @@
|
||||
import typeUse.*;
|
||||
|
||||
class Bar<T extends @NotNull Object> {
|
||||
public static void main(String[] args) {
|
||||
Bar<<warning descr="Non-null type argument is expected">@Nullable S<caret>tring</warning>> bar;
|
||||
}
|
||||
}
|
||||
+7
@@ -0,0 +1,7 @@
|
||||
import typeUse.*;
|
||||
|
||||
class Bar<T extends @NotNull Object> {
|
||||
public static void main(String[] args) {
|
||||
Bar<@NotNull S<caret>tring> bar;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,7 @@
|
||||
import typeUse.*;
|
||||
|
||||
class Bar<T extends @NotNull Object> {
|
||||
public static void main(String[] args) {
|
||||
Bar<@NotNull S<caret>tring> bar;
|
||||
}
|
||||
}
|
||||
+37
-15
@@ -45,6 +45,12 @@ public class NullableStuffInspectionTest extends LightJavaCodeInsightFixtureTest
|
||||
myFixture.testHighlighting(true, false, true, getTestName(false) + ".java");
|
||||
}
|
||||
|
||||
private void doTestWithFix(String intentionAction) {
|
||||
doTest();
|
||||
myFixture.launchAction(myFixture.findSingleIntention(intentionAction));
|
||||
myFixture.checkResultByFile(getTestName(false) + "_after.java");
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setUp() throws Exception {
|
||||
super.setUp();
|
||||
@@ -289,30 +295,22 @@ public class NullableStuffInspectionTest extends LightJavaCodeInsightFixtureTest
|
||||
}
|
||||
|
||||
public void testAnnotateQuickFixOnMethodReference() {
|
||||
doTest();
|
||||
myFixture.launchAction(myFixture.findSingleIntention("Annotate"));
|
||||
myFixture.checkResultByFile(getTestName(false) + "_after.java");
|
||||
doTestWithFix("Annotate");
|
||||
}
|
||||
|
||||
public void testAnnotateOverridingParametersOnNotNullMethod() {
|
||||
myInspection.REPORT_ANNOTATION_NOT_PROPAGATED_TO_OVERRIDERS = true;
|
||||
doTest();
|
||||
myFixture.launchAction(myFixture.findSingleIntention("Annotate overridden method parameters"));
|
||||
myFixture.checkResultByFile(getTestName(false) + "_after.java");
|
||||
doTestWithFix("Annotate overridden method parameters");
|
||||
}
|
||||
|
||||
public void testRemoveMethodAnnotationRemovesOverriders() {
|
||||
myInspection.REPORT_ANNOTATION_NOT_PROPAGATED_TO_OVERRIDERS = true;
|
||||
doTest();
|
||||
myFixture.launchAction(myFixture.findSingleIntention("Remove annotation"));
|
||||
myFixture.checkResultByFile(getTestName(false) + "_after.java");
|
||||
doTestWithFix("Remove annotation");
|
||||
}
|
||||
|
||||
public void testRemoveParameterAnnotationRemovesOverriders() {
|
||||
myInspection.REPORT_ANNOTATION_NOT_PROPAGATED_TO_OVERRIDERS = true;
|
||||
doTest();
|
||||
myFixture.launchAction(myFixture.findSingleIntention("Remove annotation"));
|
||||
myFixture.checkResultByFile(getTestName(false) + "_after.java");
|
||||
doTestWithFix("Remove annotation");
|
||||
}
|
||||
|
||||
public void testNullPassedToNullableParameter() {
|
||||
@@ -343,8 +341,32 @@ public class NullableStuffInspectionTest extends LightJavaCodeInsightFixtureTest
|
||||
public void testOverridersHaveNonDefaultAnnotation() {
|
||||
myFixture.addClass("package org.eclipse.jdt.annotation;\n\nimport java.lang.annotation.*;\n\n@Target(ElementType.PARAMETER) public @interface NonNull { }");
|
||||
myInspection.REPORT_ANNOTATION_NOT_PROPAGATED_TO_OVERRIDERS = true;
|
||||
doTest();
|
||||
myFixture.launchAction(myFixture.findSingleIntention("Annotate overridden method parameters"));
|
||||
myFixture.checkResultByFile(getTestName(false) + "_after.java");
|
||||
doTestWithFix("Annotate overridden method parameters");
|
||||
}
|
||||
|
||||
public void testQuickFixOnTypeArgument() {
|
||||
DataFlowInspection8Test.setupTypeUseAnnotations("typeUse", myFixture);
|
||||
NullableNotNullManager manager = NullableNotNullManager.getInstance(getProject());
|
||||
String oldDefault = manager.getDefaultNotNull();
|
||||
try {
|
||||
manager.setDefaultNotNull("typeUse.NotNull");
|
||||
doTestWithFix("Annotate as @NotNull");
|
||||
}
|
||||
finally {
|
||||
manager.setDefaultNotNull(oldDefault);
|
||||
}
|
||||
}
|
||||
|
||||
public void testQuickFixOnTypeArgumentNullable() {
|
||||
DataFlowInspection8Test.setupTypeUseAnnotations("typeUse", myFixture);
|
||||
NullableNotNullManager manager = NullableNotNullManager.getInstance(getProject());
|
||||
String oldDefault = manager.getDefaultNotNull();
|
||||
try {
|
||||
manager.setDefaultNotNull("typeUse.NotNull");
|
||||
doTestWithFix("Annotate as @NotNull");
|
||||
}
|
||||
finally {
|
||||
manager.setDefaultNotNull(oldDefault);
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user