Fix NPE in JavaNullabilityChecker when checking equals-calls
This NPE was introduced in ce41b5745a
Prior to the latter change there was a synthetic PSI element for each
equals-related call, thus callOperationNode was not null here.
== are intentionally treated as safe calls, but for nullability checker
it's not relevant, it only should report warnings on real safe-calls
This commit is contained in:
+2
-1
@@ -109,8 +109,9 @@ class JavaNullabilityChecker : AdditionalTypeChecker {
|
||||
}
|
||||
|
||||
if (safeAccess) {
|
||||
val safeAccessElement = c.call.callOperationNode?.psi ?: return
|
||||
doIfNotNull(receiverArgument.type, { dataFlowValue }, c) {
|
||||
c.trace.report(Errors.UNNECESSARY_SAFE_CALL.on(c.call.callOperationNode!!.psi, receiverArgument.type))
|
||||
c.trace.report(Errors.UNNECESSARY_SAFE_CALL.on(safeAccessElement, receiverArgument.type))
|
||||
}
|
||||
|
||||
return
|
||||
|
||||
+49
@@ -0,0 +1,49 @@
|
||||
// !DIAGNOSTICS: -UNUSED_VARIABLE -UNUSED_PARAMETER
|
||||
// JSR305_GLOBAL_REPORT warn
|
||||
|
||||
// FILE: spr/NonNullApi.java
|
||||
|
||||
package spr;
|
||||
|
||||
import java.lang.annotation.Documented;
|
||||
import java.lang.annotation.ElementType;
|
||||
import java.lang.annotation.Retention;
|
||||
import java.lang.annotation.RetentionPolicy;
|
||||
import java.lang.annotation.Target;
|
||||
import javax.annotation.Nonnull;
|
||||
import javax.annotation.meta.TypeQualifierDefault;
|
||||
|
||||
@Target(ElementType.TYPE)
|
||||
@Retention(RetentionPolicy.RUNTIME)
|
||||
@Documented
|
||||
@Nonnull
|
||||
@TypeQualifierDefault({ElementType.METHOD, ElementType.PARAMETER})
|
||||
public @interface NonNullApi {
|
||||
}
|
||||
|
||||
// FILE: A.java
|
||||
|
||||
import spr.*;
|
||||
|
||||
@NonNullApi
|
||||
public class A {
|
||||
public String getBar() {
|
||||
return "";
|
||||
}
|
||||
}
|
||||
|
||||
// FILE: main.kt
|
||||
|
||||
fun main(a: A) {
|
||||
if (a.getBar() == "1" && a.hashCode() != 0) return
|
||||
if (a.getBar() != "2" && a.hashCode() != 0) return
|
||||
|
||||
if (<!SENSELESS_COMPARISON!>a.getBar() == null<!> && a.hashCode() != 0) return
|
||||
if (<!SENSELESS_COMPARISON!>a.getBar() != null<!> && a.hashCode() != 0) return
|
||||
|
||||
if (a.bar == "1" && a.hashCode() != 0) return
|
||||
if (a.bar != "2" && a.hashCode() != 0) return
|
||||
|
||||
if (<!SENSELESS_COMPARISON!>a.bar == null<!> && a.hashCode() != 0) return
|
||||
if (<!SENSELESS_COMPARISON!>a.bar != null<!> && a.hashCode() != 0) return
|
||||
}
|
||||
+21
@@ -0,0 +1,21 @@
|
||||
package
|
||||
|
||||
public fun main(/*0*/ a: A): kotlin.Unit
|
||||
|
||||
@spr.NonNullApi public open class A {
|
||||
public constructor A()
|
||||
public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean
|
||||
public open fun getBar(): kotlin.String!
|
||||
public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int
|
||||
public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String
|
||||
}
|
||||
|
||||
package spr {
|
||||
|
||||
@kotlin.annotation.Target(allowedTargets = {AnnotationTarget.CLASS, AnnotationTarget.FILE}) @kotlin.annotation.Retention(value = AnnotationRetention.RUNTIME) @kotlin.annotation.MustBeDocumented @javax.annotation.Nonnull @javax.annotation.meta.TypeQualifierDefault(value = {ElementType.METHOD, ElementType.PARAMETER}) public final annotation class NonNullApi : kotlin.Annotation {
|
||||
public constructor NonNullApi()
|
||||
public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean
|
||||
public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int
|
||||
public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String
|
||||
}
|
||||
}
|
||||
+6
@@ -294,6 +294,12 @@ public class ForeignAnnotationsNoAnnotationInClasspathTestGenerated extends Abst
|
||||
KotlinTestUtils.assertAllTestsPresentByMetadata(this.getClass(), new File("compiler/testData/foreignAnnotations/tests/jsr305/nullabilityWarnings/typeQualifierDefault"), Pattern.compile("^(.+)\\.kt$"), TargetBackend.ANY, true);
|
||||
}
|
||||
|
||||
@TestMetadata("equalsOnNonNull.kt")
|
||||
public void testEqualsOnNonNull() throws Exception {
|
||||
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/foreignAnnotations/tests/jsr305/nullabilityWarnings/typeQualifierDefault/equalsOnNonNull.kt");
|
||||
doTest(fileName);
|
||||
}
|
||||
|
||||
@TestMetadata("fieldsAreNullable.kt")
|
||||
public void testFieldsAreNullable() throws Exception {
|
||||
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/foreignAnnotations/tests/jsr305/nullabilityWarnings/typeQualifierDefault/fieldsAreNullable.kt");
|
||||
|
||||
+6
@@ -294,6 +294,12 @@ public class ForeignAnnotationsNoAnnotationInClasspathWithFastClassReadingTestGe
|
||||
KotlinTestUtils.assertAllTestsPresentByMetadata(this.getClass(), new File("compiler/testData/foreignAnnotations/tests/jsr305/nullabilityWarnings/typeQualifierDefault"), Pattern.compile("^(.+)\\.kt$"), TargetBackend.ANY, true);
|
||||
}
|
||||
|
||||
@TestMetadata("equalsOnNonNull.kt")
|
||||
public void testEqualsOnNonNull() throws Exception {
|
||||
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/foreignAnnotations/tests/jsr305/nullabilityWarnings/typeQualifierDefault/equalsOnNonNull.kt");
|
||||
doTest(fileName);
|
||||
}
|
||||
|
||||
@TestMetadata("fieldsAreNullable.kt")
|
||||
public void testFieldsAreNullable() throws Exception {
|
||||
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/foreignAnnotations/tests/jsr305/nullabilityWarnings/typeQualifierDefault/fieldsAreNullable.kt");
|
||||
|
||||
@@ -294,6 +294,12 @@ public class ForeignAnnotationsTestGenerated extends AbstractForeignAnnotationsT
|
||||
KotlinTestUtils.assertAllTestsPresentByMetadata(this.getClass(), new File("compiler/testData/foreignAnnotations/tests/jsr305/nullabilityWarnings/typeQualifierDefault"), Pattern.compile("^(.+)\\.kt$"), TargetBackend.ANY, true);
|
||||
}
|
||||
|
||||
@TestMetadata("equalsOnNonNull.kt")
|
||||
public void testEqualsOnNonNull() throws Exception {
|
||||
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/foreignAnnotations/tests/jsr305/nullabilityWarnings/typeQualifierDefault/equalsOnNonNull.kt");
|
||||
doTest(fileName);
|
||||
}
|
||||
|
||||
@TestMetadata("fieldsAreNullable.kt")
|
||||
public void testFieldsAreNullable() throws Exception {
|
||||
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/foreignAnnotations/tests/jsr305/nullabilityWarnings/typeQualifierDefault/fieldsAreNullable.kt");
|
||||
|
||||
+6
@@ -294,6 +294,12 @@ public class JavacForeignAnnotationsTestGenerated extends AbstractJavacForeignAn
|
||||
KotlinTestUtils.assertAllTestsPresentByMetadata(this.getClass(), new File("compiler/testData/foreignAnnotations/tests/jsr305/nullabilityWarnings/typeQualifierDefault"), Pattern.compile("^(.+)\\.kt$"), TargetBackend.ANY, true);
|
||||
}
|
||||
|
||||
@TestMetadata("equalsOnNonNull.kt")
|
||||
public void testEqualsOnNonNull() throws Exception {
|
||||
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/foreignAnnotations/tests/jsr305/nullabilityWarnings/typeQualifierDefault/equalsOnNonNull.kt");
|
||||
doTest(fileName);
|
||||
}
|
||||
|
||||
@TestMetadata("fieldsAreNullable.kt")
|
||||
public void testFieldsAreNullable() throws Exception {
|
||||
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/foreignAnnotations/tests/jsr305/nullabilityWarnings/typeQualifierDefault/fieldsAreNullable.kt");
|
||||
|
||||
Reference in New Issue
Block a user