Can someone explain me why those 2 ways to write t...
# code-coverage
g
Can someone explain me why those 2 ways to write the code doesn't have the same coverage ? Even with parenthesis before the elvis I still get a lower coverage 🤔
j
I would open an issue in Kover/Jacoco
k
These two pieces of code don't produce the same bytecode. If I decompile the bytecode back to Java, I get this (including Java syntax errors due to the decompiler): Original Kotlin code:
Copy code
fun f(nullableField: Int?): String {
    return nullableField?.let { "hello$it" } ?: "nobody"
}

fun g(nullableField: Int?): String {
    val foobar = nullableField?.let { "hello$it" }
    return foobar ?: "nobody"
}
Kotlin -> Bytecode -> Decompiled Java:
Copy code
@NotNull
   public static final String f(@Nullable Integer nullableField) {
      String var10000;
      if (nullableField != null) {
         int it = ((Number)nullableField).intValue();
         int var3 = false;
         var10000 = "hello" + it;
         if (var10000 != null) {
            return var10000;
         }
      }

      var10000 = "nobody";
      return var10000;
   }

   @NotNull
   public static final String g(@Nullable Integer nullableField) {
      String var10000;
      if (nullableField != null) {
         int it = ((Number)nullableField).intValue();
         int var4 = false;
         var10000 = "hello" + it;
      } else {
         var10000 = null;
      }

      String foobar = var10000;
      var10000 = foobar;
      if (foobar == null) {
         var10000 = "nobody";
      }

      return var10000;
   }
g
Interesting! Well, in the f() method, the
if (var10000 != null)
makes no sense to me, as it's a local variable previously set with a non-null value. And in the g() method, I'm not sure why we need
var10000 = foobar;
Should I understand that Kotlin compiler is not properly inferring nullability in those cases and build "suboptimal" bytecode? (and so Kover/Jacoco can't do anything I presume)
k
One of the problems with
Copy code
nullableField?.let { "hello$it" } ?: "nobody"
is that it produces code for the case when
nullableField != null
but
"hello$it" == null
. We know that can never happen, but JaCoCo doesn't.
g
Should IntelliJ-Kover be able to detect that? (I've in mind that JaCoCo is Java oriented so can't infer based on kotlin code/contracts)
k
I think it would be good if both Kover and JaCoCo could be changed to account for this issue. JaCoCo developers are aware that it's often used with Kotlin. However, it works on bytecode, not source code, so it may require a change in the Kotlin compiler.