FIR resolve: fold flexible types whenever possible #KT-31528 Fixed

This commit is contained in:
Mikhail Glukhikh
2019-12-13 14:42:03 +03:00
parent 9f5a02dc7a
commit 737eaebee6
16 changed files with 69 additions and 48 deletions
@@ -101,9 +101,10 @@ private fun JavaType?.enhancePossiblyFlexible(
} else {
baseEnhanced
}
ConeFlexibleType(
baseEnhanced,
upperBound.withNullability(ConeNullability.NULLABLE)
coneFlexibleOrSimpleType(
session, baseEnhanced,
upperBound.withNullability(ConeNullability.NULLABLE),
isNotNullTypeParameter = false
)
}
else -> {
@@ -6,8 +6,7 @@
package org.jetbrains.kotlin.fir.resolve
import org.jetbrains.kotlin.descriptors.ClassKind
import org.jetbrains.kotlin.fir.FirSession
import org.jetbrains.kotlin.fir.componentArrayAccessor
import org.jetbrains.kotlin.fir.*
import org.jetbrains.kotlin.fir.declarations.*
import org.jetbrains.kotlin.fir.diagnostics.DiagnosticKind
import org.jetbrains.kotlin.fir.diagnostics.FirSimpleDiagnostic
@@ -21,13 +20,11 @@ import org.jetbrains.kotlin.fir.references.FirErrorNamedReference
import org.jetbrains.kotlin.fir.references.FirResolvedNamedReference
import org.jetbrains.kotlin.fir.references.FirSuperReference
import org.jetbrains.kotlin.fir.references.FirThisReference
import org.jetbrains.kotlin.fir.render
import org.jetbrains.kotlin.fir.resolve.calls.ConeInferenceContext
import org.jetbrains.kotlin.fir.resolve.calls.FirNamedReferenceWithCandidate
import org.jetbrains.kotlin.fir.resolve.diagnostics.FirUnresolvedNameError
import org.jetbrains.kotlin.fir.resolve.substitution.AbstractConeSubstitutor
import org.jetbrains.kotlin.fir.resolve.transformers.body.resolve.resultType
import org.jetbrains.kotlin.fir.resolvedTypeFromPrototype
import org.jetbrains.kotlin.fir.scopes.impl.FirMemberScopeProvider
import org.jetbrains.kotlin.fir.scopes.impl.withReplacedConeType
import org.jetbrains.kotlin.fir.symbols.*
@@ -38,6 +35,7 @@ import org.jetbrains.kotlin.fir.types.impl.ConeTypeParameterTypeImpl
import org.jetbrains.kotlin.fir.types.impl.FirErrorTypeRefImpl
import org.jetbrains.kotlin.fir.types.impl.FirResolvedTypeRefImpl
import org.jetbrains.kotlin.name.Name
import org.jetbrains.kotlin.types.AbstractStrictEqualityTypeChecker
import org.jetbrains.kotlin.types.Variance
import org.jetbrains.kotlin.utils.addToStdlib.safeAs
@@ -198,8 +196,24 @@ private fun List<FirQualifierPart>.toTypeProjections(): Array<ConeKotlinTypeProj
}
}.toTypedArray()
fun coneFlexibleOrSimpleType(
typeContext: ConeInferenceContext?,
lowerBound: ConeKotlinType,
upperBound: ConeKotlinType
): ConeKotlinType {
if (lowerBound is ConeFlexibleType) {
return coneFlexibleOrSimpleType(typeContext, lowerBound.lowerBound, upperBound)
}
if (upperBound is ConeFlexibleType) {
return coneFlexibleOrSimpleType(typeContext, lowerBound, upperBound.upperBound)
}
if (typeContext != null && AbstractStrictEqualityTypeChecker.strictEqualTypes(typeContext, lowerBound, upperBound)) {
return lowerBound
}
return ConeFlexibleType(lowerBound, upperBound)
}
fun <T : ConeKotlinType> T.withNullability(nullability: ConeNullability): T {
fun <T : ConeKotlinType> T.withNullability(nullability: ConeNullability, typeContext: ConeInferenceContext? = null): T {
if (this.nullability == nullability) {
return this
}
@@ -208,7 +222,14 @@ fun <T : ConeKotlinType> T.withNullability(nullability: ConeNullability): T {
is ConeClassErrorType -> this
is ConeClassLikeTypeImpl -> ConeClassLikeTypeImpl(lookupTag, typeArguments, nullability.isNullable) as T
is ConeTypeParameterTypeImpl -> ConeTypeParameterTypeImpl(lookupTag, nullability.isNullable) as T
is ConeFlexibleType -> ConeFlexibleType(lowerBound.withNullability(nullability), upperBound.withNullability(nullability)) as T
is ConeFlexibleType -> {
if (nullability == ConeNullability.UNKNOWN) {
if (lowerBound.nullability != upperBound.nullability || lowerBound.nullability == ConeNullability.UNKNOWN) {
return this
}
}
coneFlexibleOrSimpleType(typeContext, lowerBound.withNullability(nullability), upperBound.withNullability(nullability)) as T
}
is ConeTypeVariableType -> ConeTypeVariableType(nullability, lookupTag) as T
is ConeCapturedType -> ConeCapturedType(captureStatus, lowerType, nullability, constructor) as T
is ConeIntersectionType -> when (nullability) {
@@ -362,7 +383,7 @@ private fun BodyResolveComponents.typeFromSymbol(symbol: AbstractFirBasedSymbol<
val returnType = returnTypeCalculator.tryCalculateReturnType(symbol.phasedFir)
if (makeNullable) {
returnType.withReplacedConeType(
returnType.coneTypeUnsafe<ConeKotlinType>().withNullability(ConeNullability.NULLABLE)
returnType.coneTypeUnsafe<ConeKotlinType>().withNullability(ConeNullability.NULLABLE, session.inferenceContext)
)
} else {
returnType
@@ -14,6 +14,7 @@ import org.jetbrains.kotlin.fir.declarations.impl.FirDeclarationStatusImpl
import org.jetbrains.kotlin.fir.declarations.impl.FirSimpleFunctionImpl
import org.jetbrains.kotlin.fir.declarations.impl.FirTypeParameterImpl
import org.jetbrains.kotlin.fir.declarations.impl.FirValueParameterImpl
import org.jetbrains.kotlin.fir.inferenceContext
import org.jetbrains.kotlin.fir.resolve.calls.FirSyntheticFunctionSymbol
import org.jetbrains.kotlin.fir.resolve.substitution.substitutorByMap
import org.jetbrains.kotlin.fir.scopes.ProcessorAction
@@ -87,7 +88,7 @@ class FirSamResolverImpl(
val result =
substitutor
.substituteOrSelf(unsubstitutedFunctionType)
.withNullability(ConeNullability.create(type.isMarkedNullable))
.withNullability(ConeNullability.create(type.isMarkedNullable), firSession.inferenceContext)
require(result is ConeLookupTagBasedType) {
"Function type should always be ConeLookupTagBasedType, but ${result::class} was found"
@@ -10,6 +10,7 @@ import org.jetbrains.kotlin.fir.declarations.FirAnonymousFunction
import org.jetbrains.kotlin.fir.declarations.FirSimpleFunction
import org.jetbrains.kotlin.fir.declarations.FirValueParameter
import org.jetbrains.kotlin.fir.expressions.*
import org.jetbrains.kotlin.fir.inferenceContext
import org.jetbrains.kotlin.fir.references.FirResolvedNamedReference
import org.jetbrains.kotlin.fir.resolve.transformers.body.resolve.firUnsafe
import org.jetbrains.kotlin.fir.resolve.transformers.body.resolve.resultType
@@ -129,7 +130,7 @@ private fun Candidate.resolveBlockArgument(
SimpleConstraintSystemConstraintPosition,
isReceiver = false,
isDispatch = false,
nullableExpectedType = expectedType.type.withNullability(ConeNullability.NULLABLE),
nullableExpectedType = expectedType.type.withNullability(ConeNullability.NULLABLE, sink.components.session.inferenceContext),
sink = sink
)
return
@@ -216,9 +217,10 @@ fun Candidate.resolvePlainArgumentType(
) {
val position = SimpleConstraintSystemConstraintPosition //TODO
val capturedType = prepareCapturedType(argumentType, sink.components.session)
val session = sink.components.session
val capturedType = prepareCapturedType(argumentType, session)
val nullableExpectedType = expectedType.withNullability(ConeNullability.NULLABLE)
val nullableExpectedType = expectedType.withNullability(ConeNullability.NULLABLE, session.inferenceContext)
if (isReceiver && isSafeCall) {
if (!isDispatch && !csBuilder.addSubtypeConstraintIfCompatible(capturedType, nullableExpectedType, position)) {
sink.reportApplicability(CandidateApplicability.WRONG_RECEIVER) // TODO
@@ -47,7 +47,7 @@ interface ConeInferenceContext : TypeSystemInferenceExtensionContext, ConeTypeCo
require(lowerBound is ConeKotlinType)
require(upperBound is ConeKotlinType)
return ConeFlexibleType(lowerBound, upperBound)
return coneFlexibleOrSimpleType(this, lowerBound, upperBound)
}
override fun createSimpleType(
@@ -185,7 +185,7 @@ interface ConeInferenceContext : TypeSystemInferenceExtensionContext, ConeTypeCo
override fun KotlinTypeMarker.withNullability(nullable: Boolean): KotlinTypeMarker {
require(this is ConeKotlinType)
return this.withNullability(ConeNullability.create(nullable))
return this.withNullability(ConeNullability.create(nullable), this@ConeInferenceContext)
}
override fun KotlinTypeMarker.makeDefinitelyNotNullOrNotNull(): KotlinTypeMarker {
@@ -5,8 +5,7 @@
package org.jetbrains.kotlin.fir.resolve.dfa
import org.jetbrains.kotlin.fir.FirElement
import org.jetbrains.kotlin.fir.FirSymbolOwner
import org.jetbrains.kotlin.fir.*
import org.jetbrains.kotlin.fir.contracts.description.ConeBooleanConstantReference
import org.jetbrains.kotlin.fir.contracts.description.ConeConditionalEffectDeclaration
import org.jetbrains.kotlin.fir.contracts.description.ConeConstantReference
@@ -33,8 +32,6 @@ import org.jetbrains.kotlin.fir.symbols.CallableId
import org.jetbrains.kotlin.fir.symbols.impl.FirNamedFunctionSymbol
import org.jetbrains.kotlin.fir.symbols.impl.FirVariableSymbol
import org.jetbrains.kotlin.fir.types.*
import org.jetbrains.kotlin.fir.unwrapSmartcast
import org.jetbrains.kotlin.fir.unwrapWhenSubjectExpression
import org.jetbrains.kotlin.fir.visitors.transformSingle
import org.jetbrains.kotlin.name.FqName
import org.jetbrains.kotlin.name.Name
@@ -527,7 +524,7 @@ class FirDataFlowAnalyzer(private val components: FirAbstractBodyResolveTransfor
qualifiedAccess.explicitReceiver?.let {
val type = it.typeRef.coneTypeSafe<ConeKotlinType>()
?.takeIf { it.isMarkedNullable }
?.withNullability(ConeNullability.NOT_NULL)
?.withNullability(ConeNullability.NOT_NULL, session.inferenceContext)
?: return@let
when (val variable = getOrCreateVariable(it)) {
@@ -5,14 +5,12 @@
package org.jetbrains.kotlin.fir.resolve.transformers
import org.jetbrains.kotlin.fir.FirSession
import org.jetbrains.kotlin.fir.copy
import org.jetbrains.kotlin.fir.*
import org.jetbrains.kotlin.fir.declarations.*
import org.jetbrains.kotlin.fir.diagnostics.FirSimpleDiagnostic
import org.jetbrains.kotlin.fir.expressions.*
import org.jetbrains.kotlin.fir.references.impl.FirResolvedCallableReferenceImpl
import org.jetbrains.kotlin.fir.references.impl.FirResolvedNamedReferenceImpl
import org.jetbrains.kotlin.fir.render
import org.jetbrains.kotlin.fir.resolve.calls.Candidate
import org.jetbrains.kotlin.fir.resolve.calls.FirNamedReferenceWithCandidate
import org.jetbrains.kotlin.fir.resolve.calls.isBuiltinFunctionalType
@@ -21,7 +19,6 @@ import org.jetbrains.kotlin.fir.resolve.substitution.ConeSubstitutor
import org.jetbrains.kotlin.fir.resolve.substitution.substituteOrNull
import org.jetbrains.kotlin.fir.resolve.transformers.body.resolve.resultType
import org.jetbrains.kotlin.fir.resolve.withNullability
import org.jetbrains.kotlin.fir.resolvedTypeFromPrototype
import org.jetbrains.kotlin.fir.scopes.impl.FirIntegerOperatorCall
import org.jetbrains.kotlin.fir.scopes.impl.withReplacedConeType
import org.jetbrains.kotlin.fir.types.*
@@ -165,7 +162,7 @@ class FirCallCompletionResultsWriterTransformer(
val typeRef = typeCalculator.tryCalculateReturnType(declaration).let {
if (functionCall.safe) {
val nullableType = it.coneTypeUnsafe<ConeKotlinType>().withNullability(ConeNullability.NULLABLE)
val nullableType = it.coneTypeUnsafe<ConeKotlinType>().withNullability(ConeNullability.NULLABLE, session.inferenceContext)
it.withReplacedConeType(nullableType)
} else {
it
@@ -7,9 +7,7 @@ package org.jetbrains.kotlin.fir.resolve.transformers
import org.jetbrains.kotlin.descriptors.Modality
import org.jetbrains.kotlin.descriptors.Visibilities
import org.jetbrains.kotlin.fir.FirElement
import org.jetbrains.kotlin.fir.FirSession
import org.jetbrains.kotlin.fir.copy
import org.jetbrains.kotlin.fir.*
import org.jetbrains.kotlin.fir.declarations.FirResolvePhase
import org.jetbrains.kotlin.fir.declarations.addDefaultBoundIfNecessary
import org.jetbrains.kotlin.fir.declarations.impl.FirDeclarationStatusImpl
@@ -190,7 +188,11 @@ class FirSyntheticCallGenerator(
val returnType = FirResolvedTypeRefImpl(null, ConeTypeParameterTypeImpl(typeParameterSymbol.toLookupTag(), false))
val argumentType =
FirResolvedTypeRefImpl(null, returnType.coneTypeUnsafe<ConeKotlinType>().withNullability(ConeNullability.NULLABLE))
FirResolvedTypeRefImpl(
null, returnType.coneTypeUnsafe<ConeKotlinType>().withNullability(
ConeNullability.NULLABLE, session.inferenceContext
)
)
val typeArgument = FirTypeProjectionWithVarianceImpl(null, returnType, Variance.INVARIANT)
return generateMemberFunction(
@@ -6,8 +6,7 @@
package org.jetbrains.kotlin.fir.resolve.transformers.body.resolve
import com.intellij.openapi.progress.ProcessCanceledException
import org.jetbrains.kotlin.fir.BuiltinTypes
import org.jetbrains.kotlin.fir.FirCallResolver
import org.jetbrains.kotlin.fir.*
import org.jetbrains.kotlin.fir.declarations.FirTypeParametersOwner
import org.jetbrains.kotlin.fir.diagnostics.DiagnosticKind
import org.jetbrains.kotlin.fir.diagnostics.FirSimpleDiagnostic
@@ -22,7 +21,6 @@ import org.jetbrains.kotlin.fir.references.FirThisReference
import org.jetbrains.kotlin.fir.references.impl.FirErrorNamedReferenceImpl
import org.jetbrains.kotlin.fir.references.impl.FirExplicitThisReference
import org.jetbrains.kotlin.fir.references.impl.FirSimpleNamedReference
import org.jetbrains.kotlin.fir.render
import org.jetbrains.kotlin.fir.resolve.*
import org.jetbrains.kotlin.fir.resolve.calls.candidate
import org.jetbrains.kotlin.fir.resolve.diagnostics.FirOperatorAmbiguityError
@@ -30,7 +28,6 @@ import org.jetbrains.kotlin.fir.resolve.diagnostics.FirTypeMismatchError
import org.jetbrains.kotlin.fir.resolve.diagnostics.FirVariableExpectedError
import org.jetbrains.kotlin.fir.resolve.transformers.InvocationKindTransformer
import org.jetbrains.kotlin.fir.resolve.transformers.StoreReceiver
import org.jetbrains.kotlin.fir.resolvedTypeFromPrototype
import org.jetbrains.kotlin.fir.scopes.impl.withReplacedConeType
import org.jetbrains.kotlin.fir.symbols.StandardClassIds
import org.jetbrains.kotlin.fir.symbols.impl.ConeClassLookupTagWithFixedSymbol
@@ -278,7 +275,9 @@ class FirExpressionsResolveTransformer(transformer: FirBodyResolveTransformer) :
FirOperation.SAFE_AS -> {
resolved.resultType =
resolved.conversionTypeRef.withReplacedConeType(
resolved.conversionTypeRef.coneTypeUnsafe<ConeKotlinType>().withNullability(ConeNullability.NULLABLE)
resolved.conversionTypeRef.coneTypeUnsafe<ConeKotlinType>().withNullability(
ConeNullability.NULLABLE, session.inferenceContext
)
)
}
else -> error("Unknown type operator")
@@ -125,7 +125,7 @@ interface ConeTypeContext : TypeSystemContext, TypeSystemOptimizationContext, Ty
override fun SimpleTypeMarker.withNullability(nullable: Boolean): SimpleTypeMarker {
require(this is ConeKotlinType)
return withNullability(ConeNullability.create(nullable))
return withNullability(ConeNullability.create(nullable), this as? ConeInferenceContext)
}
override fun SimpleTypeMarker.typeConstructor(): TypeConstructorMarker {
@@ -4,11 +4,11 @@ FILE: main.kt
R|<local>/x|.R|kotlin/Int.toInt|().R|kotlin/Any.toString|()
}
)
R|/MyFunction|<R|kotlin/Int|, R|ft<kotlin/String, kotlin/String>|>(<L> = MyFunction@fun <anonymous>(x: R|kotlin/Int|): R|kotlin/String| {
R|/MyFunction|<R|kotlin/Int|, R|kotlin/String|>(<L> = MyFunction@fun <anonymous>(x: R|kotlin/Int|): R|kotlin/String| {
R|<local>/x|.R|kotlin/Any.toString|()
}
)
R|/MyFunction|<R|kotlin/Any?|, R|ft<kotlin/String, kotlin/String>|>(<L> = MyFunction@fun <anonymous>(x: R|kotlin/Any?|): R|kotlin/String| {
R|/MyFunction|<R|kotlin/Any?|, R|kotlin/String|>(<L> = MyFunction@fun <anonymous>(x: R|kotlin/Any?|): R|kotlin/String| {
String()
}
)
@@ -10,19 +10,19 @@ FILE: main.kt
R|<local>/x|.R|kotlin/Int.toInt|().R|kotlin/Any.toString|()
}
))
R|/foo2|(R|/MyFunction|<R|kotlin/Number|, R|ft<kotlin/String, kotlin/String>|>(<L> = MyFunction@fun <anonymous>(x: R|kotlin/Number|): R|kotlin/String| {
R|/foo2|(R|/MyFunction|<R|kotlin/Number|, R|kotlin/String|>(<L> = MyFunction@fun <anonymous>(x: R|kotlin/Number|): R|kotlin/String| {
R|<local>/x|.R|kotlin/Number.toInt|().R|kotlin/Any.toString|()
}
))
<Inapplicable(INAPPLICABLE): [/foo2]>#(R|/MyFunction|<R|kotlin/Int|, R|ft<kotlin/String, kotlin/String>|>(<L> = MyFunction@fun <anonymous>(x: R|kotlin/Int|): R|kotlin/String| {
<Inapplicable(INAPPLICABLE): [/foo2]>#(R|/MyFunction|<R|kotlin/Int|, R|kotlin/String|>(<L> = MyFunction@fun <anonymous>(x: R|kotlin/Int|): R|kotlin/String| {
R|<local>/x|.R|kotlin/Any.toString|()
}
))
R|/foo3|<R|kotlin/Int|, R|ft<kotlin/String, kotlin/String>|>(R|/MyFunction|<R|kotlin/Int|, R|ft<kotlin/String, kotlin/String>|>(<L> = MyFunction@fun <anonymous>(x: R|kotlin/Int|): R|kotlin/String| {
R|/foo3|<R|kotlin/Int|, R|kotlin/String|>(R|/MyFunction|<R|kotlin/Int|, R|kotlin/String|>(<L> = MyFunction@fun <anonymous>(x: R|kotlin/Int|): R|kotlin/String| {
R|<local>/x|.R|kotlin/Int.plus|(Int(1)).R|kotlin/Any.toString|()
}
), Int(1))
R|/foo3|<R|kotlin/Int|, R|ft<kotlin/String, kotlin/String>|>(R|/MyFunction|<R|kotlin/Int|, R|ft<kotlin/String, kotlin/String>|>(<L> = MyFunction@fun <anonymous>(x: R|kotlin/Number|): R|kotlin/String| {
R|/foo3|<R|kotlin/Int|, R|kotlin/String|>(R|/MyFunction|<R|kotlin/Int|, R|kotlin/String|>(<L> = MyFunction@fun <anonymous>(x: R|kotlin/Number|): R|kotlin/String| {
R|<local>/x|.R|kotlin/Number.toInt|().R|kotlin/Any.toString|()
}
), Int(2))
@@ -12,11 +12,11 @@ FILE: main.kt
R|<local>/x|.R|kotlin/Any.toString|()
}
)
Q|JavaUsage|.R|/JavaUsage.foo3|<R|ft<kotlin/Int, kotlin/Int>|, R|ft<kotlin/String, kotlin/String>|>(foo3@fun <anonymous>(x: R|ft<kotlin/Int, kotlin/Int>|): R|kotlin/Unit| {
Q|JavaUsage|.R|/JavaUsage.foo3|<R|kotlin/Int|, R|kotlin/String|>(foo3@fun <anonymous>(x: R|kotlin/Int|): R|kotlin/Unit| {
R|<local>/x|.R|kotlin/Int.plus|(Int(1)).R|kotlin/Any.toString|()
}
, Int(1))
Q|JavaUsage|.R|/JavaUsage.foo3|<R|ft<kotlin/Int, kotlin/Int>|, R|ft<kotlin/String, kotlin/String>|>(foo3@fun <anonymous>(x: R|kotlin/Number|): R|kotlin/Unit| {
Q|JavaUsage|.R|/JavaUsage.foo3|<R|kotlin/Int|, R|kotlin/String|>(foo3@fun <anonymous>(x: R|kotlin/Number|): R|kotlin/Unit| {
R|<local>/x|.R|kotlin/Number.toInt|().R|kotlin/Any.toString|()
}
, Int(2))
@@ -17,7 +17,7 @@ FILE: main.kt
}
Q|JavaClass|.R|/JavaClass.foo2|(R|<local>/y|)
Q|JavaClass|.R|/JavaClass.foo3|<R|ft<kotlin/Int, kotlin/Int>|>(foo3@fun <anonymous>(it: R|ft<kotlin/Int, kotlin/Int>|): R|ft<kotlin/String, kotlin/String?>!| {
Q|JavaClass|.R|/JavaClass.foo3|<R|kotlin/Int|>(foo3@fun <anonymous>(it: R|kotlin/Int|): R|ft<kotlin/String, kotlin/String?>!| {
R|<local>/it|.R|kotlin/Int.plus|(Int(4)).R|kotlin/Any.toString|()
}
, Int(5))
@@ -13,7 +13,7 @@ FILE: User.kt
protected abstract fun createSettings(): R|T|
public final fun foo(): R|kotlin/Unit| {
this@R|/User|.R|FakeOverride</User.settings: R|T|>| = Q|StaticOwner|.R|/StaticOwner.newInstance|<R|ft<T, T>|>(this@R|/User|.R|FakeOverride</User.settings: R|T|>|.R|kotlin/jvm/javaClass|)
this@R|/User|.R|FakeOverride</User.settings: R|T|>| = Q|StaticOwner|.R|/StaticOwner.newInstance|<R|T|>(this@R|/User|.R|FakeOverride</User.settings: R|T|>|.R|kotlin/jvm/javaClass|)
}
}
@@ -82,8 +82,9 @@ FILE fqName:<root> fileName:/samConversionsWithSmartCasts.kt
FUN name:test8 visibility:public modality:FINAL <> (a:kotlin.Function0<kotlin.Unit>) returnType:kotlin.Unit
VALUE_PARAMETER name:a index:0 type:kotlin.Function0<kotlin.Unit>
BLOCK_BODY
ERROR_CALL 'Unresolved reference: <Inapplicable(INAPPLICABLE): [/J.run1]>#' type=IrErrorType
CALL 'public open fun id <T> (x: T of <root>.J.id?): T of <root>.J.id? [operator] declared in <root>.J' type=kotlin.Function0<kotlin.Unit> origin=null
CALL 'public open fun run1 (r: java.lang.Runnable?): kotlin.Unit [operator] declared in <root>.J' type=kotlin.Unit origin=null
$this: CONSTRUCTOR_CALL 'public constructor <init> () [primary] declared in <root>.J' type=<root>.J origin=null
r: CALL 'public open fun id <T> (x: T of <root>.J.id?): T of <root>.J.id? [operator] declared in <root>.J' type=kotlin.Function0<kotlin.Unit> origin=null
<T>: kotlin.Function0<kotlin.Unit>
x: GET_VAR 'a: kotlin.Function0<kotlin.Unit> declared in <root>.test8' type=kotlin.Function0<kotlin.Unit> origin=null
FUN name:test9 visibility:public modality:FINAL <> () returnType:kotlin.Unit