PSI2IR: Post-process return expressions based on expected return type
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.
This commit is contained in:
+5
@@ -1087,6 +1087,11 @@ public class Fir2IrTextTestGenerated extends AbstractFir2IrTextTest {
|
||||
runTest("compiler/testData/ir/irText/expressions/multipleThisReferences.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("nullCheckOnLambdaReturn.kt")
|
||||
public void testNullCheckOnLambdaReturn() throws Exception {
|
||||
runTest("compiler/testData/ir/irText/expressions/nullCheckOnLambdaReturn.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("objectAsCallable.kt")
|
||||
public void testObjectAsCallable() throws Exception {
|
||||
runTest("compiler/testData/ir/irText/expressions/objectAsCallable.kt");
|
||||
|
||||
+44
-14
@@ -17,9 +17,12 @@
|
||||
package org.jetbrains.kotlin.psi2ir.transformations
|
||||
|
||||
import org.jetbrains.kotlin.builtins.KotlinBuiltIns
|
||||
import org.jetbrains.kotlin.builtins.isFunctionType
|
||||
import org.jetbrains.kotlin.builtins.isSuspendFunctionType
|
||||
import org.jetbrains.kotlin.descriptors.CallableDescriptor
|
||||
import org.jetbrains.kotlin.descriptors.CallableMemberDescriptor
|
||||
import org.jetbrains.kotlin.descriptors.ClassDescriptor
|
||||
import org.jetbrains.kotlin.descriptors.FunctionDescriptor
|
||||
import org.jetbrains.kotlin.ir.IrElement
|
||||
import org.jetbrains.kotlin.ir.IrStatement
|
||||
import org.jetbrains.kotlin.ir.declarations.IrClass
|
||||
@@ -35,6 +38,7 @@ import org.jetbrains.kotlin.ir.types.impl.originalKotlinType
|
||||
import org.jetbrains.kotlin.ir.util.TypeTranslator
|
||||
import org.jetbrains.kotlin.ir.util.coerceToUnitIfNeeded
|
||||
import org.jetbrains.kotlin.ir.visitors.IrElementTransformerVoid
|
||||
import org.jetbrains.kotlin.ir.visitors.transformChildrenVoid
|
||||
import org.jetbrains.kotlin.psi2ir.containsNull
|
||||
import org.jetbrains.kotlin.psi2ir.generators.GeneratorContext
|
||||
import org.jetbrains.kotlin.psi2ir.generators.GeneratorExtensions
|
||||
@@ -43,19 +47,16 @@ import org.jetbrains.kotlin.types.checker.KotlinTypeChecker
|
||||
import org.jetbrains.kotlin.types.typeUtil.*
|
||||
|
||||
fun insertImplicitCasts(element: IrElement, context: GeneratorContext) {
|
||||
element.transformChildren(
|
||||
InsertImplicitCasts(
|
||||
context.builtIns,
|
||||
context.irBuiltIns,
|
||||
context.typeTranslator,
|
||||
context.callToSubstitutedDescriptorMap,
|
||||
context.extensions
|
||||
),
|
||||
null
|
||||
)
|
||||
InsertImplicitCasts(
|
||||
context.builtIns,
|
||||
context.irBuiltIns,
|
||||
context.typeTranslator,
|
||||
context.callToSubstitutedDescriptorMap,
|
||||
context.extensions
|
||||
).run(element)
|
||||
}
|
||||
|
||||
open class InsertImplicitCasts(
|
||||
internal class InsertImplicitCasts(
|
||||
private val builtIns: KotlinBuiltIns,
|
||||
private val irBuiltIns: IrBuiltIns,
|
||||
private val typeTranslator: TypeTranslator,
|
||||
@@ -63,6 +64,22 @@ open class InsertImplicitCasts(
|
||||
private val generatorExtensions: GeneratorExtensions
|
||||
) : IrElementTransformerVoid() {
|
||||
|
||||
private val expectedFunctionExpressionReturnType = hashMapOf<FunctionDescriptor, IrType>()
|
||||
private val returnExpressionsToBePostprocessed = arrayListOf<IrReturn>()
|
||||
|
||||
fun run(element: IrElement) {
|
||||
element.transformChildrenVoid(this)
|
||||
for (irReturn in returnExpressionsToBePostprocessed) {
|
||||
postprocessReturnExpression(irReturn)
|
||||
}
|
||||
}
|
||||
|
||||
private fun postprocessReturnExpression(irReturn: IrReturn) {
|
||||
val returnTarget = irReturn.returnTarget
|
||||
val expectedReturnType = expectedFunctionExpressionReturnType[returnTarget] ?: return
|
||||
irReturn.value = irReturn.value.cast(expectedReturnType)
|
||||
}
|
||||
|
||||
private fun KotlinType.toIrType() = typeTranslator.translateType(this)
|
||||
|
||||
private val IrMemberAccessExpression.substitutedDescriptor
|
||||
@@ -139,6 +156,7 @@ open class InsertImplicitCasts(
|
||||
value = if (expression.returnTargetSymbol is IrConstructorSymbol) {
|
||||
value.coerceToUnit()
|
||||
} else {
|
||||
returnExpressionsToBePostprocessed.add(expression)
|
||||
value.cast(expression.returnTarget.returnType)
|
||||
}
|
||||
}
|
||||
@@ -256,10 +274,23 @@ open class InsertImplicitCasts(
|
||||
private fun IrExpression.cast(irType: IrType): IrExpression =
|
||||
cast(irType.originalKotlinType)
|
||||
|
||||
private fun KotlinType.getFunctionReturnTypeOrNull(): KotlinType? =
|
||||
if (isFunctionType || isSuspendFunctionType)
|
||||
arguments.last().type
|
||||
else
|
||||
null
|
||||
|
||||
private fun IrExpression.cast(expectedType: KotlinType?): IrExpression {
|
||||
if (expectedType == null) return this
|
||||
if (expectedType.isError) return this
|
||||
|
||||
if (this is IrFunctionExpression) {
|
||||
val expectedFunctionReturnType = expectedType.getFunctionReturnTypeOrNull()
|
||||
if (expectedFunctionReturnType != null) {
|
||||
expectedFunctionExpressionReturnType[function.descriptor] = expectedFunctionReturnType.toIrType()
|
||||
}
|
||||
}
|
||||
|
||||
// TODO here we can have non-denotable KotlinTypes (both in 'this@cast.type' and 'expectedType').
|
||||
|
||||
val notNullableExpectedType = expectedType.makeNotNullable()
|
||||
@@ -317,12 +348,12 @@ open class InsertImplicitCasts(
|
||||
)
|
||||
}
|
||||
|
||||
protected open fun IrExpression.coerceToUnit(): IrExpression {
|
||||
private fun IrExpression.coerceToUnit(): IrExpression {
|
||||
val valueType = getKotlinType(this)
|
||||
return coerceToUnitIfNeeded(valueType, irBuiltIns)
|
||||
}
|
||||
|
||||
protected fun getKotlinType(irExpression: IrExpression) =
|
||||
private fun getKotlinType(irExpression: IrExpression) =
|
||||
irExpression.type.originalKotlinType!!
|
||||
|
||||
private fun KotlinType.isBuiltInIntegerType(): Boolean =
|
||||
@@ -335,4 +366,3 @@ open class InsertImplicitCasts(
|
||||
KotlinBuiltIns.isUInt(this) ||
|
||||
KotlinBuiltIns.isULong(this)
|
||||
}
|
||||
|
||||
|
||||
+44
-45
@@ -1,49 +1,5 @@
|
||||
// KOTLIN_CONFIGURATION_FLAGS: +JVM.DISABLE_PARAM_ASSERTIONS
|
||||
// IGNORE_BACKEND: JVM_IR
|
||||
// Missing IMPLICIT_NOTNULL casts
|
||||
// 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; }
|
||||
}
|
||||
}
|
||||
|
||||
// FILE: AssertionChecker.kt
|
||||
// FILE: callAssertions.kt
|
||||
|
||||
class AssertionChecker(val illegalStateExpected: Boolean) {
|
||||
operator fun invoke(name: String, f: () -> Any) {
|
||||
@@ -124,3 +80,46 @@ 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; }
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -0,0 +1,60 @@
|
||||
FILE fqName:<root> fileName:/nullCheckOnLambdaReturn.kt
|
||||
FUN name:check visibility:public modality:FINAL <> (fn:kotlin.Function0<kotlin.Any>) returnType:kotlin.Any
|
||||
VALUE_PARAMETER name:fn index:0 type:kotlin.Function0<kotlin.Any>
|
||||
BLOCK_BODY
|
||||
RETURN type=kotlin.Nothing from='public final fun check (fn: kotlin.Function0<kotlin.Any>): kotlin.Any declared in <root>'
|
||||
CALL 'public abstract fun invoke (): kotlin.Any [operator] declared in kotlin.Function0' type=kotlin.Any origin=null
|
||||
$this: GET_VAR 'fn: kotlin.Function0<kotlin.Any> declared in <root>.check' type=kotlin.Function0<kotlin.Any> origin=null
|
||||
FUN name:id visibility:public modality:FINAL <T> (x:T of <root>.id) returnType:T of <root>.id
|
||||
TYPE_PARAMETER name:T index:0 variance: superTypes:[kotlin.Any?]
|
||||
VALUE_PARAMETER name:x index:0 type:T of <root>.id
|
||||
BLOCK_BODY
|
||||
RETURN type=kotlin.Nothing from='public final fun id <T> (x: T of <root>.id): T of <root>.id declared in <root>'
|
||||
GET_VAR 'x: T of <root>.id declared in <root>.id' type=T of <root>.id origin=null
|
||||
FUN name:test1 visibility:public modality:FINAL <> () returnType:kotlin.Any
|
||||
BLOCK_BODY
|
||||
RETURN type=kotlin.Nothing from='public final fun test1 (): kotlin.Any declared in <root>'
|
||||
CALL 'public final fun check (fn: kotlin.Function0<kotlin.Any>): kotlin.Any declared in <root>' type=kotlin.Any origin=null
|
||||
fn: FUN_EXPR type=kotlin.Function0<kotlin.Any> origin=LAMBDA
|
||||
FUN LOCAL_FUNCTION_FOR_LAMBDA name:<anonymous> visibility:local modality:FINAL <> () returnType:kotlin.Any
|
||||
BLOCK_BODY
|
||||
CALL 'public open fun foo (): kotlin.String? [operator] declared in <root>.J' type=kotlin.String? origin=null
|
||||
PROPERTY name:test2 visibility:public modality:FINAL [val]
|
||||
FIELD PROPERTY_BACKING_FIELD name:test2 type:kotlin.Function0<kotlin.Any> visibility:private [final,static]
|
||||
EXPRESSION_BODY
|
||||
FUN_EXPR type=kotlin.Function0<kotlin.String?> origin=LAMBDA
|
||||
FUN LOCAL_FUNCTION_FOR_LAMBDA name:<anonymous> visibility:local modality:FINAL <> () returnType:kotlin.String?
|
||||
BLOCK_BODY
|
||||
CALL 'public open fun foo (): kotlin.String? [operator] declared in <root>.J' type=kotlin.String? origin=null
|
||||
FUN DEFAULT_PROPERTY_ACCESSOR name:<get-test2> visibility:public modality:FINAL <> () returnType:kotlin.Function0<kotlin.Any>
|
||||
correspondingProperty: PROPERTY name:test2 visibility:public modality:FINAL [val]
|
||||
BLOCK_BODY
|
||||
RETURN type=kotlin.Nothing from='public final fun <get-test2> (): kotlin.Function0<kotlin.Any> declared in <root>'
|
||||
GET_FIELD 'FIELD PROPERTY_BACKING_FIELD name:test2 type:kotlin.Function0<kotlin.Any> visibility:private [final,static]' type=kotlin.Function0<kotlin.Any> origin=null
|
||||
PROPERTY name:test3 visibility:public modality:FINAL [val]
|
||||
FIELD PROPERTY_BACKING_FIELD name:test3 type:kotlin.Function0<kotlin.Any> visibility:private [final,static]
|
||||
EXPRESSION_BODY
|
||||
TYPE_OP type=kotlin.Function0<kotlin.Any> origin=CAST typeOperand=kotlin.Function0<kotlin.Any>
|
||||
FUN_EXPR type=kotlin.Function0<kotlin.String?> origin=LAMBDA
|
||||
FUN LOCAL_FUNCTION_FOR_LAMBDA name:<anonymous> visibility:local modality:FINAL <> () returnType:kotlin.String?
|
||||
BLOCK_BODY
|
||||
CALL 'public open fun foo (): kotlin.String? [operator] declared in <root>.J' type=kotlin.String? origin=null
|
||||
FUN DEFAULT_PROPERTY_ACCESSOR name:<get-test3> visibility:public modality:FINAL <> () returnType:kotlin.Function0<kotlin.Any>
|
||||
correspondingProperty: PROPERTY name:test3 visibility:public modality:FINAL [val]
|
||||
BLOCK_BODY
|
||||
RETURN type=kotlin.Nothing from='public final fun <get-test3> (): kotlin.Function0<kotlin.Any> declared in <root>'
|
||||
GET_FIELD 'FIELD PROPERTY_BACKING_FIELD name:test3 type:kotlin.Function0<kotlin.Any> visibility:private [final,static]' type=kotlin.Function0<kotlin.Any> origin=null
|
||||
PROPERTY name:test4 visibility:public modality:FINAL [val]
|
||||
FIELD PROPERTY_BACKING_FIELD name:test4 type:kotlin.Function0<kotlin.Any> visibility:private [final,static]
|
||||
EXPRESSION_BODY
|
||||
CALL 'public final fun id <T> (x: T of <root>.id): T of <root>.id declared in <root>' type=kotlin.Function0<kotlin.String?> origin=null
|
||||
<T>: kotlin.Function0<kotlin.String?>
|
||||
x: FUN_EXPR type=kotlin.Function0<kotlin.String?> origin=LAMBDA
|
||||
FUN LOCAL_FUNCTION_FOR_LAMBDA name:<anonymous> visibility:local modality:FINAL <> () returnType:kotlin.String?
|
||||
BLOCK_BODY
|
||||
CALL 'public open fun foo (): kotlin.String? [operator] declared in <root>.J' type=kotlin.String? origin=null
|
||||
FUN DEFAULT_PROPERTY_ACCESSOR name:<get-test4> visibility:public modality:FINAL <> () returnType:kotlin.Function0<kotlin.Any>
|
||||
correspondingProperty: PROPERTY name:test4 visibility:public modality:FINAL [val]
|
||||
BLOCK_BODY
|
||||
RETURN type=kotlin.Nothing from='public final fun <get-test4> (): kotlin.Function0<kotlin.Any> declared in <root>'
|
||||
GET_FIELD 'FIELD PROPERTY_BACKING_FIELD name:test4 type:kotlin.Function0<kotlin.Any> visibility:private [final,static]' type=kotlin.Function0<kotlin.Any> origin=null
|
||||
@@ -0,0 +1,17 @@
|
||||
// FILE: nullCheckOnLambdaReturn.kt
|
||||
fun check(fn: () -> Any) = fn()
|
||||
|
||||
fun <T> id(x: T) = x
|
||||
|
||||
fun test1() = check { J.foo() }
|
||||
|
||||
val test2: () -> Any = { J.foo() }
|
||||
|
||||
val test3: () -> Any = { J.foo() } as () -> Any
|
||||
|
||||
val test4: () -> Any = id { J.foo() }
|
||||
|
||||
// FILE: J.java
|
||||
public class J {
|
||||
public static String foo() { return null; }
|
||||
}
|
||||
@@ -0,0 +1,66 @@
|
||||
FILE fqName:<root> fileName:/nullCheckOnLambdaReturn.kt
|
||||
FUN name:check visibility:public modality:FINAL <> (fn:kotlin.Function0<kotlin.Any>) returnType:kotlin.Any
|
||||
VALUE_PARAMETER name:fn index:0 type:kotlin.Function0<kotlin.Any>
|
||||
BLOCK_BODY
|
||||
RETURN type=kotlin.Nothing from='public final fun check (fn: kotlin.Function0<kotlin.Any>): kotlin.Any declared in <root>'
|
||||
CALL 'public abstract fun invoke (): R of kotlin.Function0 [operator] declared in kotlin.Function0' type=kotlin.Any origin=INVOKE
|
||||
$this: GET_VAR 'fn: kotlin.Function0<kotlin.Any> declared in <root>.check' type=kotlin.Function0<kotlin.Any> origin=VARIABLE_AS_FUNCTION
|
||||
FUN name:id visibility:public modality:FINAL <T> (x:T of <root>.id) returnType:T of <root>.id
|
||||
TYPE_PARAMETER name:T index:0 variance: superTypes:[kotlin.Any?]
|
||||
VALUE_PARAMETER name:x index:0 type:T of <root>.id
|
||||
BLOCK_BODY
|
||||
RETURN type=kotlin.Nothing from='public final fun id <T> (x: T of <root>.id): T of <root>.id declared in <root>'
|
||||
GET_VAR 'x: T of <root>.id declared in <root>.id' type=T of <root>.id origin=null
|
||||
FUN name:test1 visibility:public modality:FINAL <> () returnType:kotlin.Any
|
||||
BLOCK_BODY
|
||||
RETURN type=kotlin.Nothing from='public final fun test1 (): kotlin.Any declared in <root>'
|
||||
CALL 'public final fun check (fn: kotlin.Function0<kotlin.Any>): kotlin.Any declared in <root>' type=kotlin.Any origin=null
|
||||
fn: FUN_EXPR type=kotlin.Function0<kotlin.String?> origin=LAMBDA
|
||||
FUN LOCAL_FUNCTION_FOR_LAMBDA name:<anonymous> visibility:local modality:FINAL <> () returnType:kotlin.String?
|
||||
BLOCK_BODY
|
||||
RETURN type=kotlin.Nothing from='local final fun <anonymous> (): kotlin.String? declared in <root>.test1'
|
||||
TYPE_OP type=kotlin.String origin=IMPLICIT_NOTNULL typeOperand=kotlin.String
|
||||
CALL 'public open fun foo (): kotlin.String? declared in <root>.J' type=kotlin.String? origin=null
|
||||
PROPERTY name:test2 visibility:public modality:FINAL [val]
|
||||
FIELD PROPERTY_BACKING_FIELD name:test2 type:kotlin.Function0<kotlin.Any> visibility:private [final,static]
|
||||
EXPRESSION_BODY
|
||||
FUN_EXPR type=kotlin.Function0<kotlin.String?> origin=LAMBDA
|
||||
FUN LOCAL_FUNCTION_FOR_LAMBDA name:<anonymous> visibility:local modality:FINAL <> () returnType:kotlin.String?
|
||||
BLOCK_BODY
|
||||
RETURN type=kotlin.Nothing from='local final fun <anonymous> (): kotlin.String? declared in <root>.test2'
|
||||
TYPE_OP type=kotlin.String origin=IMPLICIT_NOTNULL typeOperand=kotlin.String
|
||||
CALL 'public open fun foo (): kotlin.String? declared in <root>.J' type=kotlin.String? origin=null
|
||||
FUN DEFAULT_PROPERTY_ACCESSOR name:<get-test2> visibility:public modality:FINAL <> () returnType:kotlin.Function0<kotlin.Any>
|
||||
correspondingProperty: PROPERTY name:test2 visibility:public modality:FINAL [val]
|
||||
BLOCK_BODY
|
||||
RETURN type=kotlin.Nothing from='public final fun <get-test2> (): kotlin.Function0<kotlin.Any> declared in <root>'
|
||||
GET_FIELD 'FIELD PROPERTY_BACKING_FIELD name:test2 type:kotlin.Function0<kotlin.Any> visibility:private [final,static]' type=kotlin.Function0<kotlin.Any> origin=null
|
||||
PROPERTY name:test3 visibility:public modality:FINAL [val]
|
||||
FIELD PROPERTY_BACKING_FIELD name:test3 type:kotlin.Function0<kotlin.Any> visibility:private [final,static]
|
||||
EXPRESSION_BODY
|
||||
TYPE_OP type=kotlin.Function0<kotlin.Any> origin=CAST typeOperand=kotlin.Function0<kotlin.Any>
|
||||
FUN_EXPR type=kotlin.Function0<kotlin.String?> origin=LAMBDA
|
||||
FUN LOCAL_FUNCTION_FOR_LAMBDA name:<anonymous> visibility:local modality:FINAL <> () returnType:kotlin.String?
|
||||
BLOCK_BODY
|
||||
RETURN type=kotlin.Nothing from='local final fun <anonymous> (): kotlin.String? declared in <root>.test3'
|
||||
CALL 'public open fun foo (): kotlin.String? declared in <root>.J' type=kotlin.String? origin=null
|
||||
FUN DEFAULT_PROPERTY_ACCESSOR name:<get-test3> visibility:public modality:FINAL <> () returnType:kotlin.Function0<kotlin.Any>
|
||||
correspondingProperty: PROPERTY name:test3 visibility:public modality:FINAL [val]
|
||||
BLOCK_BODY
|
||||
RETURN type=kotlin.Nothing from='public final fun <get-test3> (): kotlin.Function0<kotlin.Any> declared in <root>'
|
||||
GET_FIELD 'FIELD PROPERTY_BACKING_FIELD name:test3 type:kotlin.Function0<kotlin.Any> visibility:private [final,static]' type=kotlin.Function0<kotlin.Any> origin=null
|
||||
PROPERTY name:test4 visibility:public modality:FINAL [val]
|
||||
FIELD PROPERTY_BACKING_FIELD name:test4 type:kotlin.Function0<kotlin.Any> visibility:private [final,static]
|
||||
EXPRESSION_BODY
|
||||
CALL 'public final fun id <T> (x: T of <root>.id): T of <root>.id declared in <root>' type=kotlin.Function0<kotlin.String?> origin=null
|
||||
<T>: kotlin.Function0<kotlin.String?>
|
||||
x: FUN_EXPR type=kotlin.Function0<kotlin.String?> origin=LAMBDA
|
||||
FUN LOCAL_FUNCTION_FOR_LAMBDA name:<anonymous> visibility:local modality:FINAL <> () returnType:kotlin.String?
|
||||
BLOCK_BODY
|
||||
RETURN type=kotlin.Nothing from='local final fun <anonymous> (): kotlin.String? declared in <root>.test4'
|
||||
CALL 'public open fun foo (): kotlin.String? declared in <root>.J' type=kotlin.String? origin=null
|
||||
FUN DEFAULT_PROPERTY_ACCESSOR name:<get-test4> visibility:public modality:FINAL <> () returnType:kotlin.Function0<kotlin.Any>
|
||||
correspondingProperty: PROPERTY name:test4 visibility:public modality:FINAL [val]
|
||||
BLOCK_BODY
|
||||
RETURN type=kotlin.Nothing from='public final fun <get-test4> (): kotlin.Function0<kotlin.Any> declared in <root>'
|
||||
GET_FIELD 'FIELD PROPERTY_BACKING_FIELD name:test4 type:kotlin.Function0<kotlin.Any> visibility:private [final,static]' type=kotlin.Function0<kotlin.Any> origin=null
|
||||
@@ -1086,6 +1086,11 @@ public class IrTextTestCaseGenerated extends AbstractIrTextTestCase {
|
||||
runTest("compiler/testData/ir/irText/expressions/multipleThisReferences.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("nullCheckOnLambdaReturn.kt")
|
||||
public void testNullCheckOnLambdaReturn() throws Exception {
|
||||
runTest("compiler/testData/ir/irText/expressions/nullCheckOnLambdaReturn.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("objectAsCallable.kt")
|
||||
public void testObjectAsCallable() throws Exception {
|
||||
runTest("compiler/testData/ir/irText/expressions/objectAsCallable.kt");
|
||||
|
||||
Reference in New Issue
Block a user