mirror of
https://github.com/jlengrand/kotlin.git
synced 2026-05-09 15:53:37 +00:00
Consider the following example:
Java:
public class J {
public static String foo() { return null; }
}
Kotlin:
fun check(fn: () -> Any) = fn()
fun test() = check { J.foo() }
When a lambda expression returns a value of platform type ('String!'),
corresponding lambda has platform type in its return type, which is
approximated to corresponding nullable type ('String?') in IR.
However, the lambda itself could occur in position with a functional
expected type ('() -> Any'). This implies an extra implicit cast on a
return value of lambda expression ('J.foo()'), although it conforms to
the return type of lambda.
126 lines
2.5 KiB
Kotlin
Vendored
126 lines
2.5 KiB
Kotlin
Vendored
// KOTLIN_CONFIGURATION_FLAGS: +JVM.DISABLE_PARAM_ASSERTIONS
|
|
// FILE: callAssertions.kt
|
|
|
|
class AssertionChecker(val illegalStateExpected: Boolean) {
|
|
operator fun invoke(name: String, f: () -> Any) {
|
|
try {
|
|
f()
|
|
} catch (e: IllegalStateException) {
|
|
if (!illegalStateExpected) throw AssertionError("Unexpected IllegalStateException on calling $name")
|
|
return
|
|
}
|
|
if (illegalStateExpected) throw AssertionError("IllegalStateException expected on calling $name")
|
|
}
|
|
}
|
|
|
|
|
|
interface Tr {
|
|
fun foo(): String
|
|
}
|
|
|
|
class Derived : A(), Tr {
|
|
override fun foo() = super<A>.foo()
|
|
}
|
|
|
|
class Delegated : Tr by Derived() {
|
|
}
|
|
|
|
fun checkAssertions(illegalStateExpected: Boolean) {
|
|
val check = AssertionChecker(illegalStateExpected)
|
|
|
|
// simple call
|
|
check("foo") { A().foo() }
|
|
|
|
// simple static call
|
|
check("staticFoo") { A.staticFoo() }
|
|
|
|
// supercall
|
|
check("foo") { Derived().foo() }
|
|
|
|
// delegated call
|
|
check("foo") { Delegated().foo() }
|
|
|
|
// collection element
|
|
check("get") { A()[""] }
|
|
|
|
// binary expression
|
|
check("plus") { A() + A() }
|
|
|
|
// field
|
|
check("NULL") { A().NULL }
|
|
|
|
// static field
|
|
check("STATIC_NULL") { A.STATIC_NULL }
|
|
|
|
// postfix expression
|
|
// TODO:
|
|
// check("inc") { var a = A().a(); a++ }
|
|
|
|
// prefix expression
|
|
check("inc-b") { var a = A.B.b(); a++ }
|
|
|
|
// prefix expression
|
|
check("inc-c") { var a = A.C.c(); a++ }
|
|
|
|
// prefix expression
|
|
check("inc") { var a = A().a(); ++a }
|
|
|
|
// prefix expression
|
|
check("inc-b") { var a = A.B.b(); ++a }
|
|
|
|
// prefix expression
|
|
// TODO:
|
|
// check("inc-c") { var a = A.C.c(); ++a }
|
|
}
|
|
|
|
operator fun A.C.inc(): A.C = A.C()
|
|
operator fun <T> T.inc(): T = null as T
|
|
|
|
fun box(): String {
|
|
checkAssertions(true)
|
|
return "OK"
|
|
}
|
|
|
|
// FILE: A.java
|
|
|
|
import org.jetbrains.annotations.NotNull;
|
|
|
|
public class A {
|
|
@NotNull
|
|
public final String NULL = null;
|
|
|
|
@NotNull
|
|
public static final String STATIC_NULL = null;
|
|
|
|
public String foo() {
|
|
return null;
|
|
}
|
|
|
|
public static String staticFoo() {
|
|
return null;
|
|
}
|
|
|
|
public A plus(A a) {
|
|
return null;
|
|
}
|
|
|
|
public A inc() {
|
|
return null;
|
|
}
|
|
|
|
public Object get(Object o) {
|
|
return null;
|
|
}
|
|
|
|
public A a() { return this; }
|
|
|
|
public static class B {
|
|
public static B b() { return null; }
|
|
}
|
|
|
|
public static class C {
|
|
public static C c() { return null; }
|
|
}
|
|
}
|
|
|