diff --git a/core/src/main/java/com/google/errorprone/bugpatterns/nullness/NullArgumentForNonNullParameter.java b/core/src/main/java/com/google/errorprone/bugpatterns/nullness/NullArgumentForNonNullParameter.java index 502579442cc..3f37148fd48 100644 --- a/core/src/main/java/com/google/errorprone/bugpatterns/nullness/NullArgumentForNonNullParameter.java +++ b/core/src/main/java/com/google/errorprone/bugpatterns/nullness/NullArgumentForNonNullParameter.java @@ -51,6 +51,7 @@ import com.sun.source.tree.Tree; import com.sun.source.tree.TryTree; import com.sun.tools.javac.code.Symbol; +import com.sun.tools.javac.code.Symbol.ClassSymbol; import com.sun.tools.javac.code.Symbol.MethodSymbol; import com.sun.tools.javac.code.Symbol.VarSymbol; import com.sun.tools.javac.code.Type; @@ -145,7 +146,23 @@ private Description match( return; } - state.reportMatch(describeMatch(argTree)); + String ownerName = methodSymbol.owner.getSimpleName().toString(); + if (ownerName.isEmpty() && methodSymbol.owner instanceof ClassSymbol) { + /* + * TODO(cpovirk): Add a test for this once we fix the + * hasExtraParameterForEnclosingInstance case. + */ + ownerName = + ((ClassSymbol) methodSymbol.owner).getSuperclass().tsym.getSimpleName().toString(); + } + + String message = + String.format( + "Null is not permitted for parameter '%s' of %s '%s'.", + paramSymbol.getSimpleName(), + methodSymbol.isConstructor() ? "constructor" : "method", + methodSymbol.isConstructor() ? ownerName : methodSymbol.getSimpleName()); + state.reportMatch(buildDescription(argTree).setMessage(message).build()); }); return NO_MATCH; // Any matches were reported through state.reportMatch. diff --git a/core/src/test/java/com/google/errorprone/bugpatterns/nullness/NullArgumentForNonNullParameterTest.java b/core/src/test/java/com/google/errorprone/bugpatterns/nullness/NullArgumentForNonNullParameterTest.java index d0eb9040436..36373e59e3e 100644 --- a/core/src/test/java/com/google/errorprone/bugpatterns/nullness/NullArgumentForNonNullParameterTest.java +++ b/core/src/test/java/com/google/errorprone/bugpatterns/nullness/NullArgumentForNonNullParameterTest.java @@ -30,6 +30,27 @@ public class NullArgumentForNonNullParameterTest { CompilationTestHelper.newInstance(NullArgumentForNonNullParameter.class, getClass()) .setArgs("-XepOpt:Nullness:Conservative=false"); + @Test + public void positiveConstructor() { + aggressiveHelper + .addSourceLines( + "Foo.java", + """ + import org.jspecify.annotations.NullMarked; + + @NullMarked + class Foo { + Foo(String s) {} + + void foo() { + // BUG: Diagnostic contains: parameter 's' of constructor 'Foo' + new Foo(null); + } + } + """) + .doTest(); + } + @Test public void positivePrimitive() { conservativeHelper @@ -42,7 +63,7 @@ class Foo { void consume(int i) {} void foo(Optional o) { - // BUG: Diagnostic contains: + // BUG: Diagnostic contains: parameter 'i' of method 'consume' consume(o.orElse(null)); } } @@ -99,7 +120,7 @@ public void positiveJavaOptionalOf() { class Foo { void foo() { - // BUG: Diagnostic contains: + // BUG: Diagnostic contains: parameter 'value' of method 'of' Optional.of(null); } }