From 581d2b73aaf24ea330d72e1d5a82e743488c656e Mon Sep 17 00:00:00 2001 From: peter Date: Tue, 11 Feb 2014 15:30:24 +0100 Subject: [PATCH] IDEA-120586 @ParametersAreNonnullByDefault support broken --- .../dataFlow/DataFlowInspectionBase.java | 12 +-- .../nullable/NullableStuffInspectionBase.java | 70 +++++++-------- .../intellij/codeInsight/AnnotationUtil.java | 4 +- .../codeInsight/NullableNotNullManager.java | 86 ++++++++++--------- .../HonorParameterDefaultInSetters.java | 17 ++++ ...t.java => HonorSuperParameterDefault.java} | 2 +- .../HonorThisParameterDefault.java | 13 +++ .../NullableStuffInspectionTest.java | 22 ++++- 8 files changed, 138 insertions(+), 88 deletions(-) create mode 100644 java/java-tests/testData/inspection/nullableProblems/HonorParameterDefaultInSetters.java rename java/java-tests/testData/inspection/nullableProblems/{ParametersAreNonnullByDefault.java => HonorSuperParameterDefault.java} (73%) create mode 100644 java/java-tests/testData/inspection/nullableProblems/HonorThisParameterDefault.java diff --git a/java/java-analysis-impl/src/com/intellij/codeInspection/dataFlow/DataFlowInspectionBase.java b/java/java-analysis-impl/src/com/intellij/codeInspection/dataFlow/DataFlowInspectionBase.java index 564b15281b08..cc1b2ae059cd 100644 --- a/java/java-analysis-impl/src/com/intellij/codeInspection/dataFlow/DataFlowInspectionBase.java +++ b/java/java-analysis-impl/src/com/intellij/codeInspection/dataFlow/DataFlowInspectionBase.java @@ -107,6 +107,7 @@ public class DataFlowInspectionBase extends BaseJavaBatchLocalInspectionTool { public void visitIfStatement(PsiIfStatement statement) { PsiExpression condition = statement.getCondition(); if (BranchingInstruction.isBoolConst(condition)) { + assert condition != null; LocalQuickFix fix = createSimplifyBooleanExpressionFix(condition, condition.textMatches(PsiKeyword.TRUE)); holder.registerProblem(condition, "Condition is always " + condition.getText(), fix); } @@ -499,12 +500,13 @@ public class DataFlowInspectionBase extends BaseJavaBatchLocalInspectionTool { holder.registerProblem(expr, text); } else if (AnnotationUtil.isAnnotatingApplicable(statement)) { - final String defaultNullable = NullableNotNullManager.getInstance(holder.getProject()).getPresentableDefaultNullable(); - final String text = isNullLiteralExpression(expr) - ? InspectionsBundle.message("dataflow.message.return.null.from.notnullable", defaultNullable) - : InspectionsBundle.message("dataflow.message.return.nullable.from.notnullable", defaultNullable); final NullableNotNullManager manager = NullableNotNullManager.getInstance(expr.getProject()); - holder.registerProblem(expr, text, new AnnotateMethodFix(manager.getDefaultNullable(), ArrayUtil.toStringArray(manager.getNotNulls())){ + final String defaultNullable = manager.getDefaultNullable(); + final String presentableNullable = StringUtil.getShortName(defaultNullable); + final String text = isNullLiteralExpression(expr) + ? InspectionsBundle.message("dataflow.message.return.null.from.notnullable", presentableNullable) + : InspectionsBundle.message("dataflow.message.return.nullable.from.notnullable", presentableNullable); + holder.registerProblem(expr, text, new AnnotateMethodFix(defaultNullable, ArrayUtil.toStringArray(manager.getNotNulls())){ @Override public int shouldAnnotateBaseMethod(PsiMethod method, PsiMethod superMethod, Project project) { return 1; diff --git a/java/java-analysis-impl/src/com/intellij/codeInspection/nullable/NullableStuffInspectionBase.java b/java/java-analysis-impl/src/com/intellij/codeInspection/nullable/NullableStuffInspectionBase.java index e01a3f18a6be..0edaee491523 100644 --- a/java/java-analysis-impl/src/com/intellij/codeInspection/nullable/NullableStuffInspectionBase.java +++ b/java/java-analysis-impl/src/com/intellij/codeInspection/nullable/NullableStuffInspectionBase.java @@ -98,8 +98,6 @@ public class NullableStuffInspectionBase extends BaseJavaBatchLocalInspectionToo String propName = JavaCodeStyleManager.getInstance(project).variableNameToPropertyName(field.getName(), VariableKind.FIELD); final boolean isStatic = field.hasModifierProperty(PsiModifier.STATIC); final PsiMethod getter = PropertyUtil.findPropertyGetter(field.getContainingClass(), propName, isStatic, false); - final String nullableSimpleName = StringUtil.getShortName(manager.getDefaultNullable()); - final String notNullSimpleName = StringUtil.getShortName(manager.getDefaultNotNull()); final PsiIdentifier nameIdentifier = getter == null ? null : getter.getNameIdentifier(); if (nameIdentifier != null && nameIdentifier.isPhysical()) { if (PropertyUtil.isSimpleGetter(getter)) { @@ -110,20 +108,16 @@ public class NullableStuffInspectionBase extends BaseJavaBatchLocalInspectionToo } }; if (REPORT_NOT_ANNOTATED_GETTER) { - if (!AnnotationUtil.isAnnotated(getter, manager.getAllAnnotations(), false, false) && - !TypeConversionUtil.isPrimitiveAndNotNull(getter.getReturnType())) { + if (!manager.hasNullability(getter) && !TypeConversionUtil.isPrimitiveAndNotNull(getter.getReturnType())) { holder.registerProblem(nameIdentifier, InspectionsBundle - .message("inspection.nullable.problems.annotated.field.getter.not.annotated", StringUtil.getShortName(anno)), + .message("inspection.nullable.problems.annotated.field.getter.not.annotated", getPresentableAnnoName(field)), ProblemHighlightType.GENERIC_ERROR_OR_WARNING, getterAnnoFix); } } - if (annotated.isDeclaredNotNull && manager.isNullable(getter, false)) { + if (annotated.isDeclaredNotNull && manager.isNullable(getter, false) || + annotated.isDeclaredNullable && manager.isNotNull(getter, false)) { holder.registerProblem(nameIdentifier, InspectionsBundle.message( - "inspection.nullable.problems.annotated.field.getter.conflict", StringUtil.getShortName(anno), nullableSimpleName), - ProblemHighlightType.GENERIC_ERROR_OR_WARNING, getterAnnoFix); - } else if (annotated.isDeclaredNullable && manager.isNotNull(getter, false)) { - holder.registerProblem(nameIdentifier, InspectionsBundle.message( - "inspection.nullable.problems.annotated.field.getter.conflict", StringUtil.getShortName(anno), notNullSimpleName), + "inspection.nullable.problems.annotated.field.getter.conflict", getPresentableAnnoName(field), getPresentableAnnoName(getter)), ProblemHighlightType.GENERIC_ERROR_OR_WARNING, getterAnnoFix); } } @@ -137,30 +131,23 @@ public class NullableStuffInspectionBase extends BaseJavaBatchLocalInspectionToo final PsiParameter parameter = parameters[0]; LOG.assertTrue(parameter != null, setter.getText()); AddAnnotationPsiFix addAnnoFix = new AddAnnotationPsiFix(anno, parameter, PsiNameValuePair.EMPTY_ARRAY, ArrayUtil.toStringArray(annoToRemove)); - if (REPORT_NOT_ANNOTATED_GETTER && !AnnotationUtil.isAnnotated(parameter, manager.getAllAnnotations(), false, false) && !TypeConversionUtil.isPrimitiveAndNotNull(parameter.getType())) { + if (REPORT_NOT_ANNOTATED_GETTER && !manager.hasNullability(parameter) && !TypeConversionUtil.isPrimitiveAndNotNull(parameter.getType())) { final PsiIdentifier nameIdentifier1 = parameter.getNameIdentifier(); assertValidElement(setter, parameter, nameIdentifier1); holder.registerProblem(nameIdentifier1, InspectionsBundle.message("inspection.nullable.problems.annotated.field.setter.parameter.not.annotated", - StringUtil.getShortName(anno)), + getPresentableAnnoName(field)), ProblemHighlightType.GENERIC_ERROR_OR_WARNING, addAnnoFix); } if (PropertyUtil.isSimpleSetter(setter)) { - if (annotated.isDeclaredNotNull && manager.isNullable(parameter, false)) { + if (annotated.isDeclaredNotNull && manager.isNullable(parameter, false) || + annotated.isDeclaredNullable && manager.isNotNull(parameter, false)) { final PsiIdentifier nameIdentifier1 = parameter.getNameIdentifier(); assertValidElement(setter, parameter, nameIdentifier1); holder.registerProblem(nameIdentifier1, InspectionsBundle.message( "inspection.nullable.problems.annotated.field.setter.parameter.conflict", - StringUtil.getShortName(anno), nullableSimpleName), - ProblemHighlightType.GENERIC_ERROR_OR_WARNING, - addAnnoFix); - } - else if (annotated.isDeclaredNullable && manager.isNotNull(parameter, false)) { - final PsiIdentifier nameIdentifier1 = parameter.getNameIdentifier(); - assertValidElement(setter, parameter, nameIdentifier1); - holder.registerProblem(nameIdentifier1, InspectionsBundle.message( - "inspection.nullable.problems.annotated.field.setter.parameter.conflict", StringUtil.getShortName(anno), notNullSimpleName), + getPresentableAnnoName(field), getPresentableAnnoName(parameter)), ProblemHighlightType.GENERIC_ERROR_OR_WARNING, addAnnoFix); } @@ -173,12 +160,12 @@ public class NullableStuffInspectionBase extends BaseJavaBatchLocalInspectionToo if (target instanceof PsiParameter) { PsiParameter parameter = (PsiParameter)target; AddAnnotationPsiFix fix = new AddAnnotationPsiFix(anno, parameter, PsiNameValuePair.EMPTY_ARRAY, ArrayUtil.toStringArray(annoToRemove)); - if (REPORT_NOT_ANNOTATED_GETTER && !AnnotationUtil.isAnnotated(parameter, manager.getAllAnnotations(), false, false) && !TypeConversionUtil.isPrimitiveAndNotNull(parameter.getType())) { + if (REPORT_NOT_ANNOTATED_GETTER && !manager.hasNullability(parameter) && !TypeConversionUtil.isPrimitiveAndNotNull(parameter.getType())) { final PsiIdentifier nameIdentifier2 = parameter.getNameIdentifier(); assert nameIdentifier2 != null : parameter; holder.registerProblem(nameIdentifier2, InspectionsBundle .message("inspection.nullable.problems.annotated.field.constructor.parameter.not.annotated", - StringUtil.getShortName(anno)), + getPresentableAnnoName(field)), ProblemHighlightType.GENERIC_ERROR_OR_WARNING, fix); continue; } @@ -194,8 +181,8 @@ public class NullableStuffInspectionBase extends BaseJavaBatchLocalInspectionToo final PsiIdentifier nameIdentifier2 = parameter.getNameIdentifier(); assert nameIdentifier2 != null : parameter; holder.registerProblem(nameIdentifier2, InspectionsBundle.message( - "inspection.nullable.problems.annotated.field.constructor.parameter.conflict", StringUtil.getShortName(anno), - notNullSimpleName), + "inspection.nullable.problems.annotated.field.constructor.parameter.conflict", getPresentableAnnoName(field), + getPresentableAnnoName(parameter)), ProblemHighlightType.GENERIC_ERROR_OR_WARNING, fix); } @@ -219,6 +206,17 @@ public class NullableStuffInspectionBase extends BaseJavaBatchLocalInspectionToo }; } + @NotNull + private static String getPresentableAnnoName(@NotNull PsiModifierListOwner owner) { + NullableNotNullManager manager = NullableNotNullManager.getInstance(owner.getProject()); + String anno = manager.getNotNull(owner); + return StringUtil.getShortName(anno != null ? anno : StringUtil.notNullize(manager.getNullable(owner), "???")); + } + + private static String getPresentableAnnoName(@NotNull PsiAnnotation annotation) { + return StringUtil.getShortName(StringUtil.notNullize(annotation.getQualifiedName(), "???")); + } + private static class Annotated { private final boolean isDeclaredNotNull; private final boolean isDeclaredNullable; @@ -288,7 +286,7 @@ public class NullableStuffInspectionBase extends BaseJavaBatchLocalInspectionToo reported_nullable_method_overrides_notnull = true; final PsiAnnotation annotation = AnnotationUtil.findAnnotation(method, nullableManager.getNullables(), true); holder.registerProblem(annotation != null ? annotation : method.getNameIdentifier(), - InspectionsBundle.message("inspection.nullable.problems.Nullable.method.overrides.NotNull", nullableManager.getPresentableDefaultNullable(), nullableManager.getPresentableDefaultNotNull()), + InspectionsBundle.message("inspection.nullable.problems.Nullable.method.overrides.NotNull", getPresentableAnnoName(method), getPresentableAnnoName(superMethod)), ProblemHighlightType.GENERIC_ERROR_OR_WARNING); } if (!reported_not_annotated_method_overrides_notnull @@ -303,7 +301,7 @@ public class NullableStuffInspectionBase extends BaseJavaBatchLocalInspectionToo ? createAnnotateMethodFix(defaultNotNull, annotationsToRemove) : createChangeDefaultNotNullFix(nullableManager, superMethod); holder.registerProblem(method.getNameIdentifier(), - InspectionsBundle.message("inspection.nullable.problems.method.overrides.NotNull", nullableManager.getPresentableDefaultNotNull()), + InspectionsBundle.message("inspection.nullable.problems.method.overrides.NotNull", getPresentableAnnoName(superMethod)), ProblemHighlightType.GENERIC_ERROR_OR_WARNING, wrapFix(fix)); } @@ -322,19 +320,18 @@ public class NullableStuffInspectionBase extends BaseJavaBatchLocalInspectionToo final PsiAnnotation annotation = AnnotationUtil.findAnnotation(parameter, nullableManager.getNotNulls(), true); holder.registerProblem(annotation != null ? annotation : parameter.getNameIdentifier(), InspectionsBundle.message("inspection.nullable.problems.NotNull.parameter.overrides.Nullable", - nullableManager.getPresentableDefaultNotNull(), - nullableManager.getPresentableDefaultNullable()), + getPresentableAnnoName(parameter), + getPresentableAnnoName(superParameter)), ProblemHighlightType.GENERIC_ERROR_OR_WARNING); } if (!reported_not_annotated_parameter_overrides_notnull[i] && REPORT_NOT_ANNOTATED_METHOD_OVERRIDES_NOTNULL) { - if (!AnnotationUtil.isAnnotated(parameter, nullableManager.getAllAnnotations(), false, false) && - nullableManager.isNotNull(superParameter, false)) { + if (!nullableManager.hasNullability(parameter) && nullableManager.isNotNull(superParameter, false)) { reported_not_annotated_parameter_overrides_notnull[i] = true; final LocalQuickFix fix = AnnotationUtil.isAnnotatingApplicable(parameter, nullableManager.getDefaultNotNull()) ? new AddNotNullAnnotationFix(parameter) : createChangeDefaultNotNullFix(nullableManager, superParameter); holder.registerProblem(parameter.getNameIdentifier(), - InspectionsBundle.message("inspection.nullable.problems.parameter.overrides.NotNull", nullableManager.getPresentableDefaultNotNull()), + InspectionsBundle.message("inspection.nullable.problems.parameter.overrides.NotNull", getPresentableAnnoName(superParameter)), ProblemHighlightType.GENERIC_ERROR_OR_WARNING, wrapFix(fix)); } @@ -441,10 +438,9 @@ public class NullableStuffInspectionBase extends BaseJavaBatchLocalInspectionToo private static void reportNullableNotNullConflict(final ProblemsHolder holder, final PsiModifierListOwner listOwner, final PsiAnnotation declaredNullable, final PsiAnnotation declaredNotNull) { - final NullableNotNullManager nullableNotNullManager = NullableNotNullManager.getInstance(holder.getProject()); final String bothNullableNotNullMessage = InspectionsBundle.message("inspection.nullable.problems.Nullable.NotNull.conflict", - nullableNotNullManager.getPresentableDefaultNullable(), - nullableNotNullManager.getPresentableDefaultNotNull()); + getPresentableAnnoName(declaredNullable), + getPresentableAnnoName(declaredNotNull)); holder.registerProblem(declaredNotNull.isPhysical() ? declaredNotNull : listOwner.getNavigationElement(), bothNullableNotNullMessage, ProblemHighlightType.GENERIC_ERROR_OR_WARNING, new RemoveAnnotationQuickFix(declaredNotNull, listOwner)); diff --git a/java/java-psi-api/src/com/intellij/codeInsight/AnnotationUtil.java b/java/java-psi-api/src/com/intellij/codeInsight/AnnotationUtil.java index a33350580c39..a5cf55067a8c 100644 --- a/java/java-psi-api/src/com/intellij/codeInsight/AnnotationUtil.java +++ b/java/java-psi-api/src/com/intellij/codeInsight/AnnotationUtil.java @@ -78,12 +78,12 @@ public class AnnotationUtil { } @Nullable - public static PsiAnnotation findAnnotation(PsiModifierListOwner listOwner, @NotNull String... annotationNames) { + public static PsiAnnotation findAnnotation(@Nullable PsiModifierListOwner listOwner, @NotNull String... annotationNames) { return findAnnotation(listOwner, false, annotationNames); } @Nullable - public static PsiAnnotation findAnnotation(PsiModifierListOwner listOwner, final boolean skipExternal, @NotNull String... annotationNames) { + public static PsiAnnotation findAnnotation(@Nullable PsiModifierListOwner listOwner, final boolean skipExternal, @NotNull String... annotationNames) { if (annotationNames.length == 0) return null; Set set = annotationNames.length == 1 ? Collections.singleton(annotationNames[0]) : new HashSet(Arrays.asList(annotationNames)); return findAnnotation(listOwner, set, skipExternal); diff --git a/java/java-psi-api/src/com/intellij/codeInsight/NullableNotNullManager.java b/java/java-psi-api/src/com/intellij/codeInsight/NullableNotNullManager.java index e97bd854841c..668390cda407 100644 --- a/java/java-psi-api/src/com/intellij/codeInsight/NullableNotNullManager.java +++ b/java/java-psi-api/src/com/intellij/codeInsight/NullableNotNullManager.java @@ -23,8 +23,9 @@ import com.intellij.openapi.util.DefaultJDOMExternalizer; import com.intellij.openapi.util.InvalidDataException; import com.intellij.openapi.util.JDOMExternalizableStringList; import com.intellij.openapi.util.WriteExternalException; -import com.intellij.openapi.util.text.StringUtil; import com.intellij.psi.*; +import com.intellij.psi.util.TypeConversionUtil; +import com.intellij.util.containers.ContainerUtil; import org.jdom.Element; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; @@ -55,10 +56,11 @@ public class NullableNotNullManager implements PersistentStateComponent return ServiceManager.getService(project, NullableNotNullManager.class); } - public Collection getAllAnnotations() { - final List all = new ArrayList(getNullables()); - all.addAll(getNotNulls()); - return all; + /** + * @return if owner has a @NotNull or @Nullable annotation, or is in scope of @ParametersAreNullableByDefault or ParametersAreNonnullByDefault + */ + public boolean hasNullability(@NotNull PsiModifierListOwner owner) { + return isNullable(owner, false) || isNotNull(owner, false); } private static void addAllIfNotPresent(Collection collection, String... annotations) { @@ -86,16 +88,10 @@ public class NullableNotNullManager implements PersistentStateComponent return myDefaultNullable; } - public String getPresentableDefaultNullable() { - return StringUtil.getShortName(myDefaultNullable); - } - @Nullable public String getNullable(PsiModifierListOwner owner) { - for (String nullable : getNullables()) { - if (AnnotationUtil.isAnnotated(owner, nullable, false, false)) return nullable; - } - return null; + PsiAnnotation annotation = findNullabilityAnnotation(owner, false, true); + return annotation == null ? null : annotation.getQualifiedName(); } public void setDefaultNullable(@NotNull String defaultNullable) { @@ -106,16 +102,11 @@ public class NullableNotNullManager implements PersistentStateComponent public String getDefaultNotNull() { return myDefaultNotNull; } - public String getPresentableDefaultNotNull() { - return StringUtil.getShortName(myDefaultNotNull); - } @Nullable public String getNotNull(PsiModifierListOwner owner) { - for (String notNull : getNotNulls()) { - if (AnnotationUtil.isAnnotated(owner, notNull, false, false)) return notNull; - } - return null; + PsiAnnotation annotation = findNullabilityAnnotation(owner, false, false); + return annotation == null ? null : annotation.getQualifiedName(); } public void setDefaultNotNull(@NotNull String defaultNotNull) { @@ -123,43 +114,56 @@ public class NullableNotNullManager implements PersistentStateComponent myDefaultNotNull = defaultNotNull; } - public boolean isNullable(PsiModifierListOwner owner, boolean checkBases) { - if (AnnotationUtil.isAnnotated(owner, getNullables(), checkBases, false)) { - return true; + @Nullable + private PsiAnnotation findNullabilityAnnotation(@NotNull PsiModifierListOwner owner, boolean checkBases, boolean nullable) { + Set qNames = ContainerUtil.newHashSet(nullable ? getNullables() : getNotNulls()); + PsiAnnotation annotation = checkBases && (owner instanceof PsiClass || owner instanceof PsiMethod) + ? AnnotationUtil.findAnnotationInHierarchy(owner, qNames) + : AnnotationUtil.findAnnotation(owner, qNames); + if (annotation != null) { + return annotation; } - return owner instanceof PsiParameter && - !AnnotationUtil.isAnnotated(owner, Arrays.asList(DEFAULT_NOT_NULLS), checkBases, false) && //honor annotation even if it's not configured - isContainerAnnotated(owner, "javax.annotation.ParametersAreNullableByDefault"); - } - - public boolean isNotNull(PsiModifierListOwner owner, boolean checkBases) { - if (AnnotationUtil.isAnnotated(owner, getNotNulls(), checkBases, false)) { - return true; + if (owner instanceof PsiParameter && !TypeConversionUtil.isPrimitiveAndNotNull(((PsiParameter)owner).getType())) { + // even if javax.annotation.Nullable is not configured, it should still take precedence over ByDefault annotations + if (AnnotationUtil.isAnnotated(owner, nullable ? Arrays.asList(DEFAULT_NOT_NULLS) : Arrays.asList(DEFAULT_NULLABLES), checkBases, false)) { + return null; + } + return findContainerAnnotation(owner, nullable + ? "javax.annotation.ParametersAreNullableByDefault" + : "javax.annotation.ParametersAreNonnullByDefault"); } - - return owner instanceof PsiParameter && - !AnnotationUtil.isAnnotated(owner, Arrays.asList(DEFAULT_NULLABLES), checkBases, false) && //honor annotation even if it's not configured - isContainerAnnotated(owner, "javax.annotation.ParametersAreNonnullByDefault"); + return null; } - private static boolean isContainerAnnotated(PsiModifierListOwner owner, String annotationFQN) { + public boolean isNullable(@NotNull PsiModifierListOwner owner, boolean checkBases) { + return findNullabilityAnnotation(owner, checkBases, true) != null; + } + + public boolean isNotNull(@NotNull PsiModifierListOwner owner, boolean checkBases) { + return findNullabilityAnnotation(owner, checkBases, false) != null; + } + + @Nullable + private static PsiAnnotation findContainerAnnotation(PsiModifierListOwner owner, String annotationFQN) { PsiElement element = owner.getParent(); while (element != null) { - if (element instanceof PsiModifierListOwner && - AnnotationUtil.isAnnotated((PsiModifierListOwner)element, annotationFQN, false, false)) { - return true; + if (element instanceof PsiModifierListOwner) { + PsiAnnotation annotation = AnnotationUtil.findAnnotation((PsiModifierListOwner)element, annotationFQN); + if (annotation != null) { + return annotation; + } } if (element instanceof PsiClassOwner) { String packageName = ((PsiClassOwner)element).getPackageName(); PsiPackage psiPackage = JavaPsiFacade.getInstance(element.getProject()).findPackage(packageName); - return psiPackage != null && AnnotationUtil.isAnnotated(psiPackage, annotationFQN, false, false); + return AnnotationUtil.findAnnotation(psiPackage, annotationFQN); } element = element.getContext(); } - return false; + return null; } public List getNullables() { diff --git a/java/java-tests/testData/inspection/nullableProblems/HonorParameterDefaultInSetters.java b/java/java-tests/testData/inspection/nullableProblems/HonorParameterDefaultInSetters.java new file mode 100644 index 000000000000..a6b9b17afe42 --- /dev/null +++ b/java/java-tests/testData/inspection/nullableProblems/HonorParameterDefaultInSetters.java @@ -0,0 +1,17 @@ +package foo; + +import javax.annotation.Nullable; + +class C { + @Nullable + private String a; + private String b; + + public void setA(String a) { + this.a = a; + } + + public void setB(@Nullable String b) { // doesn't lead to a warning because b field is not a parameter + this.b = b; + } +} \ No newline at end of file diff --git a/java/java-tests/testData/inspection/nullableProblems/ParametersAreNonnullByDefault.java b/java/java-tests/testData/inspection/nullableProblems/HonorSuperParameterDefault.java similarity index 73% rename from java/java-tests/testData/inspection/nullableProblems/ParametersAreNonnullByDefault.java rename to java/java-tests/testData/inspection/nullableProblems/HonorSuperParameterDefault.java index 8c0bafd2a578..174f7b7f1fd2 100644 --- a/java/java-tests/testData/inspection/nullableProblems/ParametersAreNonnullByDefault.java +++ b/java/java-tests/testData/inspection/nullableProblems/HonorSuperParameterDefault.java @@ -6,7 +6,7 @@ class B { public void fun(Object o) {} }; new AnyFunction() { - public void fun(Object o) {} + public void fun(Object o) {} }; } } \ No newline at end of file diff --git a/java/java-tests/testData/inspection/nullableProblems/HonorThisParameterDefault.java b/java/java-tests/testData/inspection/nullableProblems/HonorThisParameterDefault.java new file mode 100644 index 000000000000..626734ebb9b5 --- /dev/null +++ b/java/java-tests/testData/inspection/nullableProblems/HonorThisParameterDefault.java @@ -0,0 +1,13 @@ +package foo; + +interface A { + void f(double a); + void f2(Object a); +} + +class B implements A { + public void f(double a) { + } + public void f2(Object a) { + } +} \ No newline at end of file diff --git a/java/java-tests/testSrc/com/intellij/codeInspection/NullableStuffInspectionTest.java b/java/java-tests/testSrc/com/intellij/codeInspection/NullableStuffInspectionTest.java index 1d197834a598..843dcbbb8bfe 100644 --- a/java/java-tests/testSrc/com/intellij/codeInspection/NullableStuffInspectionTest.java +++ b/java/java-tests/testSrc/com/intellij/codeInspection/NullableStuffInspectionTest.java @@ -37,7 +37,7 @@ public class NullableStuffInspectionTest extends LightCodeInsightFixtureTestCase doTest(); } - public void testParametersAreNonnullByDefault() { + public void testHonorSuperParameterDefault() { myFixture.addClass("package javax.annotation; public @interface ParametersAreNonnullByDefault {}"); myFixture.addClass("package javax.annotation; public @interface Nullable {}"); myFixture.addFileToProject("foo/package-info.java", "@javax.annotation.ParametersAreNonnullByDefault package foo;"); @@ -45,8 +45,26 @@ public class NullableStuffInspectionTest extends LightCodeInsightFixtureTestCase myFixture.addClass("import javax.annotation.*; package foo; public interface NullableFunction { void fun(@Nullable Object o); }"); myFixture.addClass("package foo; public interface AnyFunction { void fun(Object o); }"); - myInspection.REPORT_ANNOTATION_NOT_PROPAGATED_TO_OVERRIDERS = true; doTest(); } + public void testHonorThisParameterDefault() { + myFixture.addClass("package javax.annotation; public @interface ParametersAreNonnullByDefault {}"); + myFixture.addFileToProject("foo/package-info.java", "@javax.annotation.ParametersAreNonnullByDefault package foo;"); + + myFixture.configureFromExistingVirtualFile(myFixture.copyFileToProject(getTestName(false) + ".java", "foo/Classes.java")); + myFixture.enableInspections(myInspection); + myFixture.checkHighlighting(true, false, true); + } + + public void testHonorParameterDefaultInSetters() { + myFixture.addClass("package javax.annotation; public @interface ParametersAreNonnullByDefault {}"); + myFixture.addClass("package javax.annotation; public @interface Nullable {}"); + myFixture.addFileToProject("foo/package-info.java", "@javax.annotation.ParametersAreNonnullByDefault package foo;"); + + myFixture.configureFromExistingVirtualFile(myFixture.copyFileToProject(getTestName(false) + ".java", "foo/Classes.java")); + myFixture.enableInspections(myInspection); + myFixture.checkHighlighting(true, false, true); + } + } \ No newline at end of file