FIR2IR: find & use delegate-to members properly
This commit is contained in:
+114
-61
@@ -10,14 +10,17 @@ import org.jetbrains.kotlin.fir.*
|
||||
import org.jetbrains.kotlin.fir.backend.*
|
||||
import org.jetbrains.kotlin.fir.declarations.*
|
||||
import org.jetbrains.kotlin.fir.declarations.utils.modality
|
||||
import org.jetbrains.kotlin.fir.resolve.fullyExpandedType
|
||||
import org.jetbrains.kotlin.fir.scopes.*
|
||||
import org.jetbrains.kotlin.fir.scopes.impl.delegatedWrapperData
|
||||
import org.jetbrains.kotlin.fir.scopes.processAllFunctions
|
||||
import org.jetbrains.kotlin.fir.scopes.processAllProperties
|
||||
import org.jetbrains.kotlin.fir.scopes.unsubstitutedScope
|
||||
import org.jetbrains.kotlin.fir.symbols.ConeClassLikeLookupTag
|
||||
import org.jetbrains.kotlin.fir.symbols.impl.FirCallableSymbol
|
||||
import org.jetbrains.kotlin.fir.symbols.impl.FirNamedFunctionSymbol
|
||||
import org.jetbrains.kotlin.fir.symbols.impl.FirPropertySymbol
|
||||
import org.jetbrains.kotlin.fir.types.ConeClassLikeType
|
||||
import org.jetbrains.kotlin.fir.types.coneType
|
||||
import org.jetbrains.kotlin.fir.types.lowerBoundIfFlexible
|
||||
import org.jetbrains.kotlin.fir.types.toSymbol
|
||||
import org.jetbrains.kotlin.ir.declarations.*
|
||||
import org.jetbrains.kotlin.ir.expressions.IrBlockBody
|
||||
import org.jetbrains.kotlin.ir.expressions.impl.IrCallImpl
|
||||
@@ -31,6 +34,7 @@ import org.jetbrains.kotlin.ir.types.isUnit
|
||||
import org.jetbrains.kotlin.name.ClassId
|
||||
import org.jetbrains.kotlin.name.FqName
|
||||
import org.jetbrains.kotlin.name.JvmNames.JVM_DEFAULT_CLASS_ID
|
||||
import org.jetbrains.kotlin.name.Name
|
||||
|
||||
/**
|
||||
* A generator for delegated members from implementation by delegation.
|
||||
@@ -43,34 +47,31 @@ class DelegatedMemberGenerator(
|
||||
private val components: Fir2IrComponents
|
||||
) : Fir2IrComponents by components {
|
||||
|
||||
companion object {
|
||||
private val PLATFORM_DEPENDENT_CLASS_ID = ClassId.topLevel(FqName("kotlin.internal.PlatformDependent"))
|
||||
}
|
||||
|
||||
private val baseFunctionSymbols = mutableMapOf<IrFunction, List<FirNamedFunctionSymbol>>()
|
||||
private val basePropertySymbols = mutableMapOf<IrProperty, List<FirPropertySymbol>>()
|
||||
|
||||
private data class DeclarationBodyInfo(
|
||||
val declaration: IrDeclaration,
|
||||
val field: IrField,
|
||||
val delegateToSymbol: FirCallableSymbol<*>
|
||||
val delegateToSymbol: FirCallableSymbol<*>,
|
||||
val delegateToLookupTag: ConeClassLikeLookupTag?
|
||||
)
|
||||
|
||||
private val bodiesInfo = mutableListOf<DeclarationBodyInfo>()
|
||||
|
||||
fun generateBodies() {
|
||||
for ((declaration, irField, delegateToSymbol) in bodiesInfo) {
|
||||
for ((declaration, irField, delegateToSymbol, delegateToLookupTag) in bodiesInfo) {
|
||||
when (declaration) {
|
||||
is IrSimpleFunction -> {
|
||||
val member = declarationStorage.getIrFunctionSymbol(
|
||||
delegateToSymbol as FirNamedFunctionSymbol
|
||||
delegateToSymbol as FirNamedFunctionSymbol, delegateToLookupTag
|
||||
).owner as? IrSimpleFunction ?: continue
|
||||
val body = createDelegateBody(irField, declaration, member)
|
||||
declaration.body = body
|
||||
}
|
||||
is IrProperty -> {
|
||||
val member = declarationStorage.getIrPropertySymbol(
|
||||
delegateToSymbol as FirPropertySymbol
|
||||
delegateToSymbol as FirPropertySymbol, delegateToLookupTag
|
||||
).owner as? IrProperty ?: continue
|
||||
val getter = declaration.getter!!
|
||||
getter.body = createDelegateBody(irField, getter, member.getter!!)
|
||||
@@ -84,25 +85,43 @@ class DelegatedMemberGenerator(
|
||||
bodiesInfo.clear()
|
||||
}
|
||||
|
||||
private fun FirTypeParameter.boundClass(): FirClass {
|
||||
val boundType = bounds.first().coneType.fullyExpandedType(session).lowerBoundIfFlexible()
|
||||
val boundClassifier = boundType.toSymbol(session)!!.fir
|
||||
if (boundClassifier is FirClass) return boundClassifier
|
||||
return (boundClassifier as FirTypeParameter).boundClass()
|
||||
}
|
||||
|
||||
// Generate delegated members for [subClass]. The synthetic field [irField] has the super interface type.
|
||||
fun generate(irField: IrField, firField: FirField, firSubClass: FirClass, subClass: IrClass) {
|
||||
val subClassLookupTag = firSubClass.symbol.toLookupTag()
|
||||
|
||||
val subClassScope = firSubClass.unsubstitutedScope(session, scopeSession, withForcedTypeCalculator = true)
|
||||
val subClassScope = firSubClass.unsubstitutedScope(session, scopeSession, withForcedTypeCalculator = false)
|
||||
val delegateToType = firField.initializer!!.typeRef.coneType.fullyExpandedType(session).lowerBoundIfFlexible()
|
||||
val delegateToClass = when (val fir = delegateToType.toSymbol(session)?.fir) {
|
||||
is FirClass -> fir
|
||||
is FirTypeParameter -> fir.boundClass()
|
||||
else -> throw AssertionError("${fir?.render()}")
|
||||
}
|
||||
|
||||
val delegateToScope = delegateToClass.unsubstitutedScope(session, scopeSession, withForcedTypeCalculator = false)
|
||||
val delegateToLookupTag = (delegateToType as? ConeClassLikeType)?.lookupTag
|
||||
|
||||
subClassScope.processAllFunctions { functionSymbol ->
|
||||
val unwrapped =
|
||||
functionSymbol
|
||||
.unwrapDelegateTarget(subClassLookupTag, firField)
|
||||
functionSymbol.unwrapDelegateTarget(subClassLookupTag, firField)
|
||||
?: return@processAllFunctions
|
||||
|
||||
if (shouldSkipDelegationFor(unwrapped)) {
|
||||
return@processAllFunctions
|
||||
}
|
||||
val delegateToSymbol = findDelegateToSymbol(
|
||||
unwrapped.symbol,
|
||||
delegateToScope::processFunctionsByName,
|
||||
delegateToScope::processOverriddenFunctions
|
||||
) ?: return@processAllFunctions
|
||||
|
||||
val irSubFunction = generateDelegatedFunction(
|
||||
subClass, firSubClass, functionSymbol.fir
|
||||
)
|
||||
bodiesInfo += DeclarationBodyInfo(irSubFunction, irField, unwrapped.symbol)
|
||||
bodiesInfo += DeclarationBodyInfo(irSubFunction, irField, delegateToSymbol, delegateToLookupTag)
|
||||
declarationStorage.cacheDelegationFunction(functionSymbol.fir, irSubFunction)
|
||||
subClass.addMember(irSubFunction)
|
||||
}
|
||||
@@ -111,42 +130,54 @@ class DelegatedMemberGenerator(
|
||||
if (propertySymbol !is FirPropertySymbol) return@processAllProperties
|
||||
|
||||
val unwrapped =
|
||||
propertySymbol
|
||||
.unwrapDelegateTarget(subClassLookupTag, firField)
|
||||
propertySymbol.unwrapDelegateTarget(subClassLookupTag, firField)
|
||||
?: return@processAllProperties
|
||||
|
||||
if (shouldSkipDelegationFor(unwrapped)) {
|
||||
return@processAllProperties
|
||||
}
|
||||
val delegateToSymbol = findDelegateToSymbol(
|
||||
unwrapped.symbol,
|
||||
{ name, processor ->
|
||||
delegateToScope.processPropertiesByName(name) {
|
||||
if (it !is FirPropertySymbol) return@processPropertiesByName
|
||||
processor(it)
|
||||
}
|
||||
},
|
||||
delegateToScope::processOverriddenProperties
|
||||
) ?: return@processAllProperties
|
||||
|
||||
val irSubProperty = generateDelegatedProperty(
|
||||
subClass, firSubClass, propertySymbol.fir
|
||||
)
|
||||
bodiesInfo += DeclarationBodyInfo(irSubProperty, irField, unwrapped.symbol)
|
||||
bodiesInfo += DeclarationBodyInfo(irSubProperty, irField, delegateToSymbol, delegateToLookupTag)
|
||||
declarationStorage.cacheDelegatedProperty(propertySymbol.fir, irSubProperty)
|
||||
subClass.addMember(irSubProperty)
|
||||
}
|
||||
}
|
||||
|
||||
private fun shouldSkipDelegationFor(unwrapped: FirCallableDeclaration): Boolean {
|
||||
// See org.jetbrains.kotlin.resolve.jvm.JvmDelegationFilter
|
||||
return (unwrapped is FirSimpleFunction && unwrapped.isDefaultJavaMethod()) ||
|
||||
unwrapped.hasAnnotation(JVM_DEFAULT_CLASS_ID) ||
|
||||
unwrapped.hasAnnotation(PLATFORM_DEPENDENT_CLASS_ID)
|
||||
}
|
||||
|
||||
private fun FirSimpleFunction.isDefaultJavaMethod(): Boolean =
|
||||
when {
|
||||
isIntersectionOverride ->
|
||||
baseForIntersectionOverride!!.isDefaultJavaMethod()
|
||||
isSubstitutionOverride ->
|
||||
originalForSubstitutionOverride!!.isDefaultJavaMethod()
|
||||
else -> {
|
||||
// Check that we have a non-abstract method from Java interface
|
||||
origin == FirDeclarationOrigin.Enhancement && modality == Modality.OPEN
|
||||
private inline fun <reified S : FirCallableSymbol<*>> findDelegateToSymbol(
|
||||
unwrappedSymbol: S,
|
||||
processCallables: (name: Name, processor: (S) -> Unit) -> Unit,
|
||||
crossinline processOverridden: (base: S, processor: (S) -> ProcessorAction) -> ProcessorAction
|
||||
): S? {
|
||||
var result: S? = null
|
||||
// The purpose of this code is to find member in delegate-to scope
|
||||
// which matches or overrides unwrappedSymbol (which is in turn taken from subclass scope).
|
||||
processCallables(unwrappedSymbol.name) { candidateSymbol ->
|
||||
if (result != null) return@processCallables
|
||||
if (candidateSymbol === unwrappedSymbol) {
|
||||
result = candidateSymbol
|
||||
return@processCallables
|
||||
}
|
||||
processOverridden(candidateSymbol) {
|
||||
if (it === unwrappedSymbol) {
|
||||
result = candidateSymbol
|
||||
ProcessorAction.STOP
|
||||
} else {
|
||||
ProcessorAction.NEXT
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return result
|
||||
}
|
||||
|
||||
fun bindDelegatedMembersOverriddenSymbols(irClass: IrClass) {
|
||||
val superClasses by lazy(LazyThreadSafetyMode.NONE) {
|
||||
@@ -275,36 +306,58 @@ class DelegatedMemberGenerator(
|
||||
declarationStorage,
|
||||
fakeOverrideGenerator
|
||||
)
|
||||
annotationGenerator.generate(delegateProperty.getter!!, firDelegateProperty)
|
||||
annotationGenerator.generate(getter, firDelegateProperty)
|
||||
if (delegateProperty.isVar) {
|
||||
val setter = delegateProperty.setter!!
|
||||
setter.overriddenSymbols =
|
||||
firDelegateProperty.generateOverriddenAccessorSymbols(
|
||||
firSubClass, isGetter = false, session, scopeSession, declarationStorage, fakeOverrideGenerator
|
||||
)
|
||||
annotationGenerator.generate(delegateProperty.setter!!, firDelegateProperty)
|
||||
annotationGenerator.generate(setter, firDelegateProperty)
|
||||
}
|
||||
|
||||
return delegateProperty
|
||||
}
|
||||
|
||||
companion object {
|
||||
private val PLATFORM_DEPENDENT_CLASS_ID = ClassId.topLevel(FqName("kotlin.internal.PlatformDependent"))
|
||||
private fun <S : FirCallableSymbol<D>, D : FirCallableDeclaration> S.unwrapDelegateTarget(
|
||||
subClassLookupTag: ConeClassLikeLookupTag,
|
||||
firField: FirField,
|
||||
): D? {
|
||||
val callable = this.fir as? D ?: return null
|
||||
|
||||
val delegatedWrapperData = callable.delegatedWrapperData ?: return null
|
||||
if (delegatedWrapperData.containingClass != subClassLookupTag) return null
|
||||
if (delegatedWrapperData.delegateField != firField) return null
|
||||
|
||||
val wrapped = delegatedWrapperData.wrapped as? D ?: return null
|
||||
|
||||
@Suppress("UNCHECKED_CAST")
|
||||
val wrappedSymbol = wrapped.symbol as? S ?: return null
|
||||
|
||||
@Suppress("UNCHECKED_CAST")
|
||||
return (wrappedSymbol.unwrapCallRepresentative().fir as D).takeIf { !shouldSkipDelegationFor(it) }
|
||||
}
|
||||
|
||||
private fun shouldSkipDelegationFor(unwrapped: FirCallableDeclaration): Boolean {
|
||||
// See org.jetbrains.kotlin.resolve.jvm.JvmDelegationFilter
|
||||
return (unwrapped is FirSimpleFunction && unwrapped.isDefaultJavaMethod()) ||
|
||||
unwrapped.hasAnnotation(JVM_DEFAULT_CLASS_ID) ||
|
||||
unwrapped.hasAnnotation(PLATFORM_DEPENDENT_CLASS_ID)
|
||||
}
|
||||
|
||||
private fun FirSimpleFunction.isDefaultJavaMethod(): Boolean =
|
||||
when {
|
||||
isIntersectionOverride ->
|
||||
baseForIntersectionOverride!!.isDefaultJavaMethod()
|
||||
isSubstitutionOverride ->
|
||||
originalForSubstitutionOverride!!.isDefaultJavaMethod()
|
||||
else -> {
|
||||
// Check that we have a non-abstract method from Java interface
|
||||
origin == FirDeclarationOrigin.Enhancement && modality == Modality.OPEN
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private fun <S : FirCallableSymbol<D>, D : FirCallableDeclaration> S.unwrapDelegateTarget(
|
||||
subClassLookupTag: ConeClassLikeLookupTag,
|
||||
firField: FirField,
|
||||
): D? {
|
||||
val callable = this.fir as? D ?: return null
|
||||
|
||||
val delegatedWrapperData = callable.delegatedWrapperData ?: return null
|
||||
if (delegatedWrapperData.containingClass != subClassLookupTag) return null
|
||||
if (delegatedWrapperData.delegateField != firField) return null
|
||||
|
||||
val wrapped = delegatedWrapperData.wrapped as? D ?: return null
|
||||
|
||||
@Suppress("UNCHECKED_CAST")
|
||||
val wrappedSymbol = wrapped.symbol as? S ?: return null
|
||||
|
||||
@Suppress("UNCHECKED_CAST")
|
||||
return wrappedSymbol.unwrapCallRepresentative().fir as D
|
||||
}
|
||||
|
||||
@@ -215,7 +215,7 @@ FILE fqName:<root> fileName:/delegatedImplementation.kt
|
||||
VALUE_PARAMETER name:x index:0 type:kotlin.Int
|
||||
VALUE_PARAMETER name:s index:1 type:kotlin.String
|
||||
BLOCK_BODY
|
||||
CALL 'public abstract fun foo (x: kotlin.Int, s: kotlin.String): kotlin.Unit declared in <root>.IBase' type=kotlin.Unit origin=null
|
||||
CALL 'public final fun foo (x: kotlin.Int, s: kotlin.String): kotlin.Unit declared in <root>.BaseImpl' type=kotlin.Unit origin=null
|
||||
$this: GET_FIELD 'FIELD DELEGATE name:<$$delegate_0> type:<root>.BaseImpl visibility:local [final]' type=<root>.BaseImpl origin=null
|
||||
receiver: GET_VAR '<this>: <root>.Test1 declared in <root>.Test1.foo' type=<root>.Test1 origin=null
|
||||
x: GET_VAR 'x: kotlin.Int declared in <root>.Test1.foo' type=kotlin.Int origin=null
|
||||
@@ -226,7 +226,7 @@ FILE fqName:<root> fileName:/delegatedImplementation.kt
|
||||
$this: VALUE_PARAMETER name:<this> type:<root>.Test1
|
||||
BLOCK_BODY
|
||||
RETURN type=kotlin.Nothing from='public open fun bar (): kotlin.Int declared in <root>.Test1'
|
||||
CALL 'public abstract fun bar (): kotlin.Int declared in <root>.IBase' type=kotlin.Int origin=null
|
||||
CALL 'public final fun bar (): kotlin.Int declared in <root>.BaseImpl' type=kotlin.Int origin=null
|
||||
$this: GET_FIELD 'FIELD DELEGATE name:<$$delegate_0> type:<root>.BaseImpl visibility:local [final]' type=<root>.BaseImpl origin=null
|
||||
receiver: GET_VAR '<this>: <root>.Test1 declared in <root>.Test1.bar' type=<root>.Test1 origin=null
|
||||
FUN DELEGATED_MEMBER name:qux visibility:public modality:OPEN <> ($this:<root>.Test1, $receiver:kotlin.String) returnType:kotlin.Unit
|
||||
@@ -235,7 +235,7 @@ FILE fqName:<root> fileName:/delegatedImplementation.kt
|
||||
$this: VALUE_PARAMETER name:<this> type:<root>.Test1
|
||||
$receiver: VALUE_PARAMETER name:<this> type:kotlin.String
|
||||
BLOCK_BODY
|
||||
CALL 'public abstract fun qux (): kotlin.Unit declared in <root>.IBase' type=kotlin.Unit origin=null
|
||||
CALL 'public final fun qux (): kotlin.Unit declared in <root>.BaseImpl' type=kotlin.Unit origin=null
|
||||
$this: GET_FIELD 'FIELD DELEGATE name:<$$delegate_0> type:<root>.BaseImpl visibility:local [final]' type=<root>.BaseImpl origin=null
|
||||
receiver: GET_VAR '<this>: <root>.Test1 declared in <root>.Test1.qux' type=<root>.Test1 origin=null
|
||||
$receiver: GET_VAR '<this>: kotlin.String declared in <root>.Test1.qux' type=kotlin.String origin=null
|
||||
@@ -268,7 +268,7 @@ FILE fqName:<root> fileName:/delegatedImplementation.kt
|
||||
VALUE_PARAMETER name:x index:0 type:kotlin.Int
|
||||
VALUE_PARAMETER name:s index:1 type:kotlin.String
|
||||
BLOCK_BODY
|
||||
CALL 'public abstract fun foo (x: kotlin.Int, s: kotlin.String): kotlin.Unit declared in <root>.IBase' type=kotlin.Unit origin=null
|
||||
CALL 'public final fun foo (x: kotlin.Int, s: kotlin.String): kotlin.Unit declared in <root>.BaseImpl' type=kotlin.Unit origin=null
|
||||
$this: GET_FIELD 'FIELD DELEGATE name:<$$delegate_0> type:<root>.BaseImpl visibility:local [final]' type=<root>.BaseImpl origin=null
|
||||
receiver: GET_VAR '<this>: <root>.Test2 declared in <root>.Test2.foo' type=<root>.Test2 origin=null
|
||||
x: GET_VAR 'x: kotlin.Int declared in <root>.Test2.foo' type=kotlin.Int origin=null
|
||||
@@ -279,7 +279,7 @@ FILE fqName:<root> fileName:/delegatedImplementation.kt
|
||||
$this: VALUE_PARAMETER name:<this> type:<root>.Test2
|
||||
BLOCK_BODY
|
||||
RETURN type=kotlin.Nothing from='public open fun bar (): kotlin.Int declared in <root>.Test2'
|
||||
CALL 'public abstract fun bar (): kotlin.Int declared in <root>.IBase' type=kotlin.Int origin=null
|
||||
CALL 'public final fun bar (): kotlin.Int declared in <root>.BaseImpl' type=kotlin.Int origin=null
|
||||
$this: GET_FIELD 'FIELD DELEGATE name:<$$delegate_0> type:<root>.BaseImpl visibility:local [final]' type=<root>.BaseImpl origin=null
|
||||
receiver: GET_VAR '<this>: <root>.Test2 declared in <root>.Test2.bar' type=<root>.Test2 origin=null
|
||||
FUN DELEGATED_MEMBER name:qux visibility:public modality:OPEN <> ($this:<root>.Test2, $receiver:kotlin.String) returnType:kotlin.Unit
|
||||
@@ -288,7 +288,7 @@ FILE fqName:<root> fileName:/delegatedImplementation.kt
|
||||
$this: VALUE_PARAMETER name:<this> type:<root>.Test2
|
||||
$receiver: VALUE_PARAMETER name:<this> type:kotlin.String
|
||||
BLOCK_BODY
|
||||
CALL 'public abstract fun qux (): kotlin.Unit declared in <root>.IBase' type=kotlin.Unit origin=null
|
||||
CALL 'public final fun qux (): kotlin.Unit declared in <root>.BaseImpl' type=kotlin.Unit origin=null
|
||||
$this: GET_FIELD 'FIELD DELEGATE name:<$$delegate_0> type:<root>.BaseImpl visibility:local [final]' type=<root>.BaseImpl origin=null
|
||||
receiver: GET_VAR '<this>: <root>.Test2 declared in <root>.Test2.qux' type=<root>.Test2 origin=null
|
||||
$receiver: GET_VAR '<this>: kotlin.String declared in <root>.Test2.qux' type=kotlin.String origin=null
|
||||
|
||||
+1
-1
@@ -58,7 +58,7 @@ FILE fqName:<root> fileName:/delegatedImplementationWithExplicitOverride.kt
|
||||
public abstract fun foo (): kotlin.Unit declared in <root>.IFooBar
|
||||
$this: VALUE_PARAMETER name:<this> type:<root>.C
|
||||
BLOCK_BODY
|
||||
CALL 'public abstract fun foo (): kotlin.Unit declared in <root>.IFooBar' type=kotlin.Unit origin=null
|
||||
CALL 'public final fun foo (): kotlin.Unit declared in <root>.FooBarImpl' type=kotlin.Unit origin=null
|
||||
$this: GET_FIELD 'FIELD DELEGATE name:<$$delegate_0> type:<root>.FooBarImpl visibility:local [final]' type=<root>.FooBarImpl origin=null
|
||||
receiver: GET_VAR '<this>: <root>.C declared in <root>.C.foo' type=<root>.C origin=null
|
||||
FIELD DELEGATE name:<$$delegate_0> type:<root>.FooBarImpl visibility:local [final]
|
||||
|
||||
+5
-5
@@ -137,7 +137,7 @@ FILE fqName:<root> fileName:/implicitNotNullOnDelegatedImplementation.kt
|
||||
$this: VALUE_PARAMETER name:<this> type:<root>.TestJFoo
|
||||
BLOCK_BODY
|
||||
RETURN type=kotlin.Nothing from='public open fun foo (): kotlin.String declared in <root>.TestJFoo'
|
||||
CALL 'public abstract fun foo (): kotlin.String declared in <root>.IFoo' type=kotlin.String origin=null
|
||||
CALL 'public open fun foo (): @[EnhancedNullability] kotlin.String declared in <root>.JFoo' type=kotlin.String origin=null
|
||||
$this: GET_FIELD 'FIELD DELEGATE name:<$$delegate_0> type:<root>.JFoo visibility:local [final]' type=<root>.JFoo origin=null
|
||||
receiver: GET_VAR '<this>: <root>.TestJFoo declared in <root>.TestJFoo.foo' type=<root>.TestJFoo origin=null
|
||||
FIELD DELEGATE name:<$$delegate_0> type:<root>.JFoo visibility:local [final]
|
||||
@@ -168,7 +168,7 @@ FILE fqName:<root> fileName:/implicitNotNullOnDelegatedImplementation.kt
|
||||
$this: VALUE_PARAMETER name:<this> type:<root>.TestK1
|
||||
BLOCK_BODY
|
||||
RETURN type=kotlin.Nothing from='public open fun foo (): kotlin.String declared in <root>.TestK1'
|
||||
CALL 'public abstract fun foo (): kotlin.String declared in <root>.IFoo' type=kotlin.String origin=null
|
||||
CALL 'public open fun foo (): @[EnhancedNullability] kotlin.String [fake_override] declared in <root>.K1' type=kotlin.String origin=null
|
||||
$this: GET_FIELD 'FIELD DELEGATE name:<$$delegate_0> type:<root>.K1 visibility:local [final]' type=<root>.K1 origin=null
|
||||
receiver: GET_VAR '<this>: <root>.TestK1 declared in <root>.TestK1.foo' type=<root>.TestK1 origin=null
|
||||
FIELD DELEGATE name:<$$delegate_0> type:<root>.K1 visibility:local [final]
|
||||
@@ -199,7 +199,7 @@ FILE fqName:<root> fileName:/implicitNotNullOnDelegatedImplementation.kt
|
||||
$this: VALUE_PARAMETER name:<this> type:<root>.TestK2
|
||||
BLOCK_BODY
|
||||
RETURN type=kotlin.Nothing from='public open fun foo (): kotlin.String declared in <root>.TestK2'
|
||||
CALL 'public abstract fun foo (): kotlin.String declared in <root>.IFoo' type=kotlin.String origin=null
|
||||
CALL 'public final fun foo (): kotlin.String declared in <root>.K2' type=kotlin.String origin=null
|
||||
$this: GET_FIELD 'FIELD DELEGATE name:<$$delegate_0> type:<root>.K2 visibility:local [final]' type=<root>.K2 origin=null
|
||||
receiver: GET_VAR '<this>: <root>.TestK2 declared in <root>.TestK2.foo' type=<root>.TestK2 origin=null
|
||||
FIELD DELEGATE name:<$$delegate_0> type:<root>.K2 visibility:local [final]
|
||||
@@ -230,7 +230,7 @@ FILE fqName:<root> fileName:/implicitNotNullOnDelegatedImplementation.kt
|
||||
$this: VALUE_PARAMETER name:<this> type:<root>.TestK3
|
||||
BLOCK_BODY
|
||||
RETURN type=kotlin.Nothing from='public open fun foo (): kotlin.String declared in <root>.TestK3'
|
||||
CALL 'public abstract fun foo (): kotlin.String declared in <root>.IFoo' type=kotlin.String origin=null
|
||||
CALL 'public open fun foo (): kotlin.String [fake_override] declared in <root>.K3' type=kotlin.String origin=null
|
||||
$this: GET_FIELD 'FIELD DELEGATE name:<$$delegate_0> type:<root>.K3 visibility:local [final]' type=<root>.K3 origin=null
|
||||
receiver: GET_VAR '<this>: <root>.TestK3 declared in <root>.TestK3.foo' type=<root>.TestK3 origin=null
|
||||
FIELD DELEGATE name:<$$delegate_0> type:<root>.K3 visibility:local [final]
|
||||
@@ -261,7 +261,7 @@ FILE fqName:<root> fileName:/implicitNotNullOnDelegatedImplementation.kt
|
||||
$this: VALUE_PARAMETER name:<this> type:<root>.TestK4
|
||||
BLOCK_BODY
|
||||
RETURN type=kotlin.Nothing from='public open fun foo (): kotlin.String declared in <root>.TestK4'
|
||||
CALL 'public abstract fun foo (): kotlin.String declared in <root>.IFoo' type=kotlin.String origin=null
|
||||
CALL 'public final fun foo (): @[FlexibleNullability] kotlin.String? declared in <root>.K4' type=kotlin.String origin=null
|
||||
$this: GET_FIELD 'FIELD DELEGATE name:<$$delegate_0> type:<root>.K4 visibility:local [final]' type=<root>.K4 origin=null
|
||||
receiver: GET_VAR '<this>: <root>.TestK4 declared in <root>.TestK4.foo' type=<root>.TestK4 origin=null
|
||||
FIELD DELEGATE name:<$$delegate_0> type:<root>.K4 visibility:local [final]
|
||||
|
||||
+1
-2
@@ -13,8 +13,7 @@ FILE fqName:<root> fileName:/kt45934.kt
|
||||
$this: VALUE_PARAMETER name:<this> type:<root>.C
|
||||
BLOCK_BODY
|
||||
RETURN type=kotlin.Nothing from='public open fun foo <C> (): @[FlexibleNullability] kotlin.collections.List<@[FlexibleNullability] C of <root>.C.foo?>? declared in <root>.C'
|
||||
CALL 'public abstract fun foo <C> (): @[FlexibleNullability] kotlin.collections.List<@[FlexibleNullability] C of <root>.I.foo?>? declared in <root>.I' type=@[FlexibleNullability] kotlin.collections.List<@[FlexibleNullability] C of <root>.C.foo?>? origin=null
|
||||
<C>: C of <root>.C.foo
|
||||
CALL 'public open fun foo (): @[FlexibleNullability] kotlin.collections.List<@[FlexibleNullability] kotlin.String?>? declared in <root>.J' type=@[FlexibleNullability] kotlin.collections.List<@[FlexibleNullability] C of <root>.C.foo?>? origin=null
|
||||
$this: GET_FIELD 'FIELD DELEGATE name:<$$delegate_0> type:<root>.J visibility:local [final]' type=<root>.J origin=null
|
||||
receiver: GET_VAR '<this>: <root>.C declared in <root>.C.foo' type=<root>.C origin=null
|
||||
FIELD DELEGATE name:<$$delegate_0> type:<root>.J visibility:local [final]
|
||||
|
||||
+1
-1
@@ -61,7 +61,7 @@ FILE fqName:<root> fileName:/nullCheckOnInterfaceDelegation.kt
|
||||
$this: VALUE_PARAMETER name:<this> type:<root>.Delegated
|
||||
BLOCK_BODY
|
||||
RETURN type=kotlin.Nothing from='public open fun foo (): kotlin.String declared in <root>.Delegated'
|
||||
CALL 'public abstract fun foo (): kotlin.String declared in <root>.IFoo' type=kotlin.String origin=null
|
||||
CALL 'public final fun foo (): @[FlexibleNullability] kotlin.String? declared in <root>.Derived' type=kotlin.String origin=null
|
||||
$this: GET_FIELD 'FIELD DELEGATE name:<$$delegate_0> type:<root>.Derived visibility:local [final]' type=<root>.Derived origin=null
|
||||
receiver: GET_VAR '<this>: <root>.Delegated declared in <root>.Delegated.foo' type=<root>.Delegated origin=null
|
||||
FIELD DELEGATE name:<$$delegate_0> type:<root>.Derived visibility:local [final]
|
||||
|
||||
Reference in New Issue
Block a user