Make Kotlin warn on assignment of flexible/platform type to non-null type?

Viewed 1421

When calling a non-nullability-annotated Java function from Kotlin, we get flexible-typed return values, denoted by exclamation marks, e.g. String!.

Kotlin silently allows assigning these flexible values to a normal non-null type, e.g. String, which can cause NullPointerExceptions at runtime.

I would prefer to get compiler warnings or errors for such assignments. Alternatively, treat platform types as equivalent to nullable types (e.g. String?).

As an example, with this Java code:

import android.os.SystemClock;
import android.support.annotation.NonNull;
import android.support.annotation.Nullable;

public class NullTest {

    private String maybe() {
        if (SystemClock.elapsedRealtimeNanos() % 2 == 0) {
            return null;
        }
        return "ok";
    }

    public String annotatedNothing()            { return maybe(); }
    @Nullable public String annotatedNullable() { return maybe(); }
    @NonNull  public String annotatedNonNull()  { return "ok"; }

}

...and the following Kotlin code, I'd like to get errors on two new lines (see comments):

fun testnulls() {
    val obj = NullTest()

    val nullExact: String  = obj.annotatedNullable() // already gives an error
    val nullMaybe: String? = obj.annotatedNullable()
    val nullInfer          = obj.annotatedNullable()

    val okayExact: String  = obj.annotatedNonNull()
    val okayMaybe: String? = obj.annotatedNonNull()
    val okayInfer          = obj.annotatedNonNull()

    val bareExact: String  = obj.annotatedNothing() // I want a compiler error here
    val bareMaybe: String? = obj.annotatedNothing()
    val bareInfer          = obj.annotatedNothing()

    print("length " + nullExact.length)
    print("length " + nullMaybe.length) // already gives an error
    print("length " + nullInfer.length) // already gives an error

    print("length " + okayExact.length)
    print("length " + okayMaybe.length) // already gives an error
    print("length " + okayInfer.length)

    print("length " + bareExact.length)
    print("length " + bareMaybe.length) // already gives an error
    print("length " + bareInfer.length) // I want a compiler error here
}

The point is that this will force me to add null checks or !!, making sure that I at least have to be explicit about it.

Is this possible?

In the comments of this 2014 JetBrains blog post, when they introduced platform/flexible types, it sounds like they were planning to add an option to warn about exactly these situations, but I haven't been able to find any further information on that.

4 Answers

I did some research and found some interesting links.

First as others have mentioned it seems like the Kotlin developers wants to avoid false positives and here is a discussion on adding a compile time option to mark platform type usage: https://youtrack.jetbrains.com/issue/KTIJ-6891 Which the kotlin team seems reluctant to add.

However I found that the developers of detekt (a static code analysis tool for kotlin) have an open issue on adding detection of platform type usage: https://github.com/detekt/detekt/issues/3603

And it seems like they are relatively close to adding this. https://github.com/detekt/detekt/pull/4470/files

So hopefully that will help developers catch those NPE's before the users does.

Related