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.backend.*
|
||||||
import org.jetbrains.kotlin.fir.declarations.*
|
import org.jetbrains.kotlin.fir.declarations.*
|
||||||
import org.jetbrains.kotlin.fir.declarations.utils.modality
|
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.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.ConeClassLikeLookupTag
|
||||||
import org.jetbrains.kotlin.fir.symbols.impl.FirCallableSymbol
|
import org.jetbrains.kotlin.fir.symbols.impl.FirCallableSymbol
|
||||||
import org.jetbrains.kotlin.fir.symbols.impl.FirNamedFunctionSymbol
|
import org.jetbrains.kotlin.fir.symbols.impl.FirNamedFunctionSymbol
|
||||||
import org.jetbrains.kotlin.fir.symbols.impl.FirPropertySymbol
|
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.declarations.*
|
||||||
import org.jetbrains.kotlin.ir.expressions.IrBlockBody
|
import org.jetbrains.kotlin.ir.expressions.IrBlockBody
|
||||||
import org.jetbrains.kotlin.ir.expressions.impl.IrCallImpl
|
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.ClassId
|
||||||
import org.jetbrains.kotlin.name.FqName
|
import org.jetbrains.kotlin.name.FqName
|
||||||
import org.jetbrains.kotlin.name.JvmNames.JVM_DEFAULT_CLASS_ID
|
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.
|
* A generator for delegated members from implementation by delegation.
|
||||||
@@ -43,34 +47,31 @@ class DelegatedMemberGenerator(
|
|||||||
private val components: Fir2IrComponents
|
private val components: Fir2IrComponents
|
||||||
) : Fir2IrComponents by components {
|
) : 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 baseFunctionSymbols = mutableMapOf<IrFunction, List<FirNamedFunctionSymbol>>()
|
||||||
private val basePropertySymbols = mutableMapOf<IrProperty, List<FirPropertySymbol>>()
|
private val basePropertySymbols = mutableMapOf<IrProperty, List<FirPropertySymbol>>()
|
||||||
|
|
||||||
private data class DeclarationBodyInfo(
|
private data class DeclarationBodyInfo(
|
||||||
val declaration: IrDeclaration,
|
val declaration: IrDeclaration,
|
||||||
val field: IrField,
|
val field: IrField,
|
||||||
val delegateToSymbol: FirCallableSymbol<*>
|
val delegateToSymbol: FirCallableSymbol<*>,
|
||||||
|
val delegateToLookupTag: ConeClassLikeLookupTag?
|
||||||
)
|
)
|
||||||
|
|
||||||
private val bodiesInfo = mutableListOf<DeclarationBodyInfo>()
|
private val bodiesInfo = mutableListOf<DeclarationBodyInfo>()
|
||||||
|
|
||||||
fun generateBodies() {
|
fun generateBodies() {
|
||||||
for ((declaration, irField, delegateToSymbol) in bodiesInfo) {
|
for ((declaration, irField, delegateToSymbol, delegateToLookupTag) in bodiesInfo) {
|
||||||
when (declaration) {
|
when (declaration) {
|
||||||
is IrSimpleFunction -> {
|
is IrSimpleFunction -> {
|
||||||
val member = declarationStorage.getIrFunctionSymbol(
|
val member = declarationStorage.getIrFunctionSymbol(
|
||||||
delegateToSymbol as FirNamedFunctionSymbol
|
delegateToSymbol as FirNamedFunctionSymbol, delegateToLookupTag
|
||||||
).owner as? IrSimpleFunction ?: continue
|
).owner as? IrSimpleFunction ?: continue
|
||||||
val body = createDelegateBody(irField, declaration, member)
|
val body = createDelegateBody(irField, declaration, member)
|
||||||
declaration.body = body
|
declaration.body = body
|
||||||
}
|
}
|
||||||
is IrProperty -> {
|
is IrProperty -> {
|
||||||
val member = declarationStorage.getIrPropertySymbol(
|
val member = declarationStorage.getIrPropertySymbol(
|
||||||
delegateToSymbol as FirPropertySymbol
|
delegateToSymbol as FirPropertySymbol, delegateToLookupTag
|
||||||
).owner as? IrProperty ?: continue
|
).owner as? IrProperty ?: continue
|
||||||
val getter = declaration.getter!!
|
val getter = declaration.getter!!
|
||||||
getter.body = createDelegateBody(irField, getter, member.getter!!)
|
getter.body = createDelegateBody(irField, getter, member.getter!!)
|
||||||
@@ -84,25 +85,43 @@ class DelegatedMemberGenerator(
|
|||||||
bodiesInfo.clear()
|
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.
|
// Generate delegated members for [subClass]. The synthetic field [irField] has the super interface type.
|
||||||
fun generate(irField: IrField, firField: FirField, firSubClass: FirClass, subClass: IrClass) {
|
fun generate(irField: IrField, firField: FirField, firSubClass: FirClass, subClass: IrClass) {
|
||||||
val subClassLookupTag = firSubClass.symbol.toLookupTag()
|
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 ->
|
subClassScope.processAllFunctions { functionSymbol ->
|
||||||
val unwrapped =
|
val unwrapped =
|
||||||
functionSymbol
|
functionSymbol.unwrapDelegateTarget(subClassLookupTag, firField)
|
||||||
.unwrapDelegateTarget(subClassLookupTag, firField)
|
|
||||||
?: return@processAllFunctions
|
?: return@processAllFunctions
|
||||||
|
|
||||||
if (shouldSkipDelegationFor(unwrapped)) {
|
val delegateToSymbol = findDelegateToSymbol(
|
||||||
return@processAllFunctions
|
unwrapped.symbol,
|
||||||
}
|
delegateToScope::processFunctionsByName,
|
||||||
|
delegateToScope::processOverriddenFunctions
|
||||||
|
) ?: return@processAllFunctions
|
||||||
|
|
||||||
val irSubFunction = generateDelegatedFunction(
|
val irSubFunction = generateDelegatedFunction(
|
||||||
subClass, firSubClass, functionSymbol.fir
|
subClass, firSubClass, functionSymbol.fir
|
||||||
)
|
)
|
||||||
bodiesInfo += DeclarationBodyInfo(irSubFunction, irField, unwrapped.symbol)
|
bodiesInfo += DeclarationBodyInfo(irSubFunction, irField, delegateToSymbol, delegateToLookupTag)
|
||||||
declarationStorage.cacheDelegationFunction(functionSymbol.fir, irSubFunction)
|
declarationStorage.cacheDelegationFunction(functionSymbol.fir, irSubFunction)
|
||||||
subClass.addMember(irSubFunction)
|
subClass.addMember(irSubFunction)
|
||||||
}
|
}
|
||||||
@@ -111,42 +130,54 @@ class DelegatedMemberGenerator(
|
|||||||
if (propertySymbol !is FirPropertySymbol) return@processAllProperties
|
if (propertySymbol !is FirPropertySymbol) return@processAllProperties
|
||||||
|
|
||||||
val unwrapped =
|
val unwrapped =
|
||||||
propertySymbol
|
propertySymbol.unwrapDelegateTarget(subClassLookupTag, firField)
|
||||||
.unwrapDelegateTarget(subClassLookupTag, firField)
|
|
||||||
?: return@processAllProperties
|
?: return@processAllProperties
|
||||||
|
|
||||||
if (shouldSkipDelegationFor(unwrapped)) {
|
val delegateToSymbol = findDelegateToSymbol(
|
||||||
return@processAllProperties
|
unwrapped.symbol,
|
||||||
}
|
{ name, processor ->
|
||||||
|
delegateToScope.processPropertiesByName(name) {
|
||||||
|
if (it !is FirPropertySymbol) return@processPropertiesByName
|
||||||
|
processor(it)
|
||||||
|
}
|
||||||
|
},
|
||||||
|
delegateToScope::processOverriddenProperties
|
||||||
|
) ?: return@processAllProperties
|
||||||
|
|
||||||
val irSubProperty = generateDelegatedProperty(
|
val irSubProperty = generateDelegatedProperty(
|
||||||
subClass, firSubClass, propertySymbol.fir
|
subClass, firSubClass, propertySymbol.fir
|
||||||
)
|
)
|
||||||
bodiesInfo += DeclarationBodyInfo(irSubProperty, irField, unwrapped.symbol)
|
bodiesInfo += DeclarationBodyInfo(irSubProperty, irField, delegateToSymbol, delegateToLookupTag)
|
||||||
declarationStorage.cacheDelegatedProperty(propertySymbol.fir, irSubProperty)
|
declarationStorage.cacheDelegatedProperty(propertySymbol.fir, irSubProperty)
|
||||||
subClass.addMember(irSubProperty)
|
subClass.addMember(irSubProperty)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun shouldSkipDelegationFor(unwrapped: FirCallableDeclaration): Boolean {
|
private inline fun <reified S : FirCallableSymbol<*>> findDelegateToSymbol(
|
||||||
// See org.jetbrains.kotlin.resolve.jvm.JvmDelegationFilter
|
unwrappedSymbol: S,
|
||||||
return (unwrapped is FirSimpleFunction && unwrapped.isDefaultJavaMethod()) ||
|
processCallables: (name: Name, processor: (S) -> Unit) -> Unit,
|
||||||
unwrapped.hasAnnotation(JVM_DEFAULT_CLASS_ID) ||
|
crossinline processOverridden: (base: S, processor: (S) -> ProcessorAction) -> ProcessorAction
|
||||||
unwrapped.hasAnnotation(PLATFORM_DEPENDENT_CLASS_ID)
|
): S? {
|
||||||
}
|
var result: S? = null
|
||||||
|
// The purpose of this code is to find member in delegate-to scope
|
||||||
private fun FirSimpleFunction.isDefaultJavaMethod(): Boolean =
|
// which matches or overrides unwrappedSymbol (which is in turn taken from subclass scope).
|
||||||
when {
|
processCallables(unwrappedSymbol.name) { candidateSymbol ->
|
||||||
isIntersectionOverride ->
|
if (result != null) return@processCallables
|
||||||
baseForIntersectionOverride!!.isDefaultJavaMethod()
|
if (candidateSymbol === unwrappedSymbol) {
|
||||||
isSubstitutionOverride ->
|
result = candidateSymbol
|
||||||
originalForSubstitutionOverride!!.isDefaultJavaMethod()
|
return@processCallables
|
||||||
else -> {
|
}
|
||||||
// Check that we have a non-abstract method from Java interface
|
processOverridden(candidateSymbol) {
|
||||||
origin == FirDeclarationOrigin.Enhancement && modality == Modality.OPEN
|
if (it === unwrappedSymbol) {
|
||||||
|
result = candidateSymbol
|
||||||
|
ProcessorAction.STOP
|
||||||
|
} else {
|
||||||
|
ProcessorAction.NEXT
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
return result
|
||||||
|
}
|
||||||
|
|
||||||
fun bindDelegatedMembersOverriddenSymbols(irClass: IrClass) {
|
fun bindDelegatedMembersOverriddenSymbols(irClass: IrClass) {
|
||||||
val superClasses by lazy(LazyThreadSafetyMode.NONE) {
|
val superClasses by lazy(LazyThreadSafetyMode.NONE) {
|
||||||
@@ -275,36 +306,58 @@ class DelegatedMemberGenerator(
|
|||||||
declarationStorage,
|
declarationStorage,
|
||||||
fakeOverrideGenerator
|
fakeOverrideGenerator
|
||||||
)
|
)
|
||||||
annotationGenerator.generate(delegateProperty.getter!!, firDelegateProperty)
|
annotationGenerator.generate(getter, firDelegateProperty)
|
||||||
if (delegateProperty.isVar) {
|
if (delegateProperty.isVar) {
|
||||||
val setter = delegateProperty.setter!!
|
val setter = delegateProperty.setter!!
|
||||||
setter.overriddenSymbols =
|
setter.overriddenSymbols =
|
||||||
firDelegateProperty.generateOverriddenAccessorSymbols(
|
firDelegateProperty.generateOverriddenAccessorSymbols(
|
||||||
firSubClass, isGetter = false, session, scopeSession, declarationStorage, fakeOverrideGenerator
|
firSubClass, isGetter = false, session, scopeSession, declarationStorage, fakeOverrideGenerator
|
||||||
)
|
)
|
||||||
annotationGenerator.generate(delegateProperty.setter!!, firDelegateProperty)
|
annotationGenerator.generate(setter, firDelegateProperty)
|
||||||
}
|
}
|
||||||
|
|
||||||
return delegateProperty
|
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:x index:0 type:kotlin.Int
|
||||||
VALUE_PARAMETER name:s index:1 type:kotlin.String
|
VALUE_PARAMETER name:s index:1 type:kotlin.String
|
||||||
BLOCK_BODY
|
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
|
$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
|
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
|
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
|
$this: VALUE_PARAMETER name:<this> type:<root>.Test1
|
||||||
BLOCK_BODY
|
BLOCK_BODY
|
||||||
RETURN type=kotlin.Nothing from='public open fun bar (): kotlin.Int declared in <root>.Test1'
|
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
|
$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
|
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
|
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
|
$this: VALUE_PARAMETER name:<this> type:<root>.Test1
|
||||||
$receiver: VALUE_PARAMETER name:<this> type:kotlin.String
|
$receiver: VALUE_PARAMETER name:<this> type:kotlin.String
|
||||||
BLOCK_BODY
|
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
|
$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>: <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
|
$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:x index:0 type:kotlin.Int
|
||||||
VALUE_PARAMETER name:s index:1 type:kotlin.String
|
VALUE_PARAMETER name:s index:1 type:kotlin.String
|
||||||
BLOCK_BODY
|
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
|
$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
|
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
|
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
|
$this: VALUE_PARAMETER name:<this> type:<root>.Test2
|
||||||
BLOCK_BODY
|
BLOCK_BODY
|
||||||
RETURN type=kotlin.Nothing from='public open fun bar (): kotlin.Int declared in <root>.Test2'
|
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
|
$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
|
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
|
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
|
$this: VALUE_PARAMETER name:<this> type:<root>.Test2
|
||||||
$receiver: VALUE_PARAMETER name:<this> type:kotlin.String
|
$receiver: VALUE_PARAMETER name:<this> type:kotlin.String
|
||||||
BLOCK_BODY
|
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
|
$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>: <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
|
$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
|
public abstract fun foo (): kotlin.Unit declared in <root>.IFooBar
|
||||||
$this: VALUE_PARAMETER name:<this> type:<root>.C
|
$this: VALUE_PARAMETER name:<this> type:<root>.C
|
||||||
BLOCK_BODY
|
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
|
$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
|
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]
|
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
|
$this: VALUE_PARAMETER name:<this> type:<root>.TestJFoo
|
||||||
BLOCK_BODY
|
BLOCK_BODY
|
||||||
RETURN type=kotlin.Nothing from='public open fun foo (): kotlin.String declared in <root>.TestJFoo'
|
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
|
$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
|
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]
|
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
|
$this: VALUE_PARAMETER name:<this> type:<root>.TestK1
|
||||||
BLOCK_BODY
|
BLOCK_BODY
|
||||||
RETURN type=kotlin.Nothing from='public open fun foo (): kotlin.String declared in <root>.TestK1'
|
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
|
$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
|
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]
|
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
|
$this: VALUE_PARAMETER name:<this> type:<root>.TestK2
|
||||||
BLOCK_BODY
|
BLOCK_BODY
|
||||||
RETURN type=kotlin.Nothing from='public open fun foo (): kotlin.String declared in <root>.TestK2'
|
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
|
$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
|
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]
|
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
|
$this: VALUE_PARAMETER name:<this> type:<root>.TestK3
|
||||||
BLOCK_BODY
|
BLOCK_BODY
|
||||||
RETURN type=kotlin.Nothing from='public open fun foo (): kotlin.String declared in <root>.TestK3'
|
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
|
$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
|
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]
|
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
|
$this: VALUE_PARAMETER name:<this> type:<root>.TestK4
|
||||||
BLOCK_BODY
|
BLOCK_BODY
|
||||||
RETURN type=kotlin.Nothing from='public open fun foo (): kotlin.String declared in <root>.TestK4'
|
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
|
$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
|
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]
|
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
|
$this: VALUE_PARAMETER name:<this> type:<root>.C
|
||||||
BLOCK_BODY
|
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'
|
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
|
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
|
||||||
<C>: C of <root>.C.foo
|
|
||||||
$this: GET_FIELD 'FIELD DELEGATE name:<$$delegate_0> type:<root>.J visibility:local [final]' type=<root>.J 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
|
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]
|
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
|
$this: VALUE_PARAMETER name:<this> type:<root>.Delegated
|
||||||
BLOCK_BODY
|
BLOCK_BODY
|
||||||
RETURN type=kotlin.Nothing from='public open fun foo (): kotlin.String declared in <root>.Delegated'
|
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
|
$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
|
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]
|
FIELD DELEGATE name:<$$delegate_0> type:<root>.Derived visibility:local [final]
|
||||||
|
|||||||
Reference in New Issue
Block a user