[FIR2IR] Create fake one-time use properties for callable reference to synthetic properies

Previously fir2ir created real IR properties some getter and setter for
  such references, which lead to the situation that there might be a
  unbound fake override for synthetic property which wasn't stored in
  declaration storage (and code in FakeOverrideGenerator was a hack
  to cover this case)
In the same time K1 creates fake property for such cases, which is stored
  in IrPropertyReference along with original get... and set... functions
  as getter and setter of reference. And in this commit K2 does the same thing

^KT-61637
This commit is contained in:
Dmitriy Novozhilov
2023-09-01 12:32:17 +03:00
committed by Space Team
parent 7ea54ee87f
commit 36cb869ac2
6 changed files with 173 additions and 116 deletions
@@ -19,9 +19,7 @@ import org.jetbrains.kotlin.fir.builder.buildPackageDirective
import org.jetbrains.kotlin.fir.declarations.* import org.jetbrains.kotlin.fir.declarations.*
import org.jetbrains.kotlin.fir.declarations.builder.buildFile import org.jetbrains.kotlin.fir.declarations.builder.buildFile
import org.jetbrains.kotlin.fir.declarations.synthetic.FirSyntheticProperty import org.jetbrains.kotlin.fir.declarations.synthetic.FirSyntheticProperty
import org.jetbrains.kotlin.fir.declarations.utils.isInline import org.jetbrains.kotlin.fir.declarations.utils.*
import org.jetbrains.kotlin.fir.declarations.utils.isJava
import org.jetbrains.kotlin.fir.declarations.utils.isStatic
import org.jetbrains.kotlin.fir.expressions.* import org.jetbrains.kotlin.fir.expressions.*
import org.jetbrains.kotlin.fir.extensions.FirExtensionApiInternals import org.jetbrains.kotlin.fir.extensions.FirExtensionApiInternals
import org.jetbrains.kotlin.fir.extensions.declarationGenerators import org.jetbrains.kotlin.fir.extensions.declarationGenerators
@@ -162,7 +160,7 @@ fun FirClassifierSymbol<*>.toSymbol(
} }
context(Fir2IrComponents) context(Fir2IrComponents)
private fun FirBasedSymbol<*>.toSymbolForCall( fun FirBasedSymbol<*>.toSymbolForCall(
dispatchReceiver: FirExpression?, dispatchReceiver: FirExpression?,
preferGetter: Boolean, preferGetter: Boolean,
explicitReceiver: FirExpression? = null, explicitReceiver: FirExpression? = null,
@@ -181,6 +179,19 @@ private fun FirBasedSymbol<*>.toSymbolForCall(
else -> error("Unknown symbol: $this") else -> error("Unknown symbol: $this")
} }
fun FirReference.extractSymbolForCall(): FirBasedSymbol<*>? {
if (this !is FirResolvedNamedReference) {
return null
}
var symbol = resolvedSymbol
if (symbol is FirCallableSymbol<*> && symbol.origin == FirDeclarationOrigin.SubstitutionOverride.CallSite) {
symbol = symbol.fir.unwrapUseSiteSubstitutionOverrides<FirCallableDeclaration>().symbol
}
return symbol
}
context(Fir2IrComponents) context(Fir2IrComponents)
@OptIn(ExperimentalContracts::class) @OptIn(ExperimentalContracts::class)
fun FirReference.toSymbolForCall( fun FirReference.toSymbolForCall(
@@ -193,16 +204,8 @@ fun FirReference.toSymbolForCall(
contract { contract {
returnsNotNull() implies (this@toSymbolForCall is FirResolvedNamedReference) returnsNotNull() implies (this@toSymbolForCall is FirResolvedNamedReference)
} }
if (this !is FirResolvedNamedReference) {
return null
}
var symbol = resolvedSymbol
if (symbol is FirCallableSymbol<*> && symbol.origin == FirDeclarationOrigin.SubstitutionOverride.CallSite) { return extractSymbolForCall()?.toSymbolForCall(
symbol = symbol.fir.unwrapUseSiteSubstitutionOverrides<FirCallableDeclaration>().symbol
}
return symbol.toSymbolForCall(
dispatchReceiver, dispatchReceiver,
preferGetter, preferGetter,
explicitReceiver, explicitReceiver,
@@ -219,9 +222,9 @@ private fun FirResolvedQualifier.toLookupTag(session: FirSession): ConeClassLike
} }
context(Fir2IrComponents) context(Fir2IrComponents)
private fun FirCallableSymbol<*>.toSymbolForCall( fun FirCallableSymbol<*>.toSymbolForCall(
dispatchReceiver: FirExpression?, dispatchReceiver: FirExpression?,
preferGetter: Boolean, preferGetter: Boolean = true,
// Note: in fact LHS for callable references and explicit receiver for normal qualified accesses // Note: in fact LHS for callable references and explicit receiver for normal qualified accesses
explicitReceiver: FirExpression? = null, explicitReceiver: FirExpression? = null,
isDelegate: Boolean = false, isDelegate: Boolean = false,
@@ -21,6 +21,7 @@ import org.jetbrains.kotlin.fir.expressions.builder.buildAnnotationCall
import org.jetbrains.kotlin.fir.references.* import org.jetbrains.kotlin.fir.references.*
import org.jetbrains.kotlin.fir.references.builder.buildResolvedNamedReference import org.jetbrains.kotlin.fir.references.builder.buildResolvedNamedReference
import org.jetbrains.kotlin.fir.resolve.* import org.jetbrains.kotlin.fir.resolve.*
import org.jetbrains.kotlin.fir.resolve.calls.FirSimpleSyntheticPropertySymbol
import org.jetbrains.kotlin.fir.resolve.calls.FirSyntheticFunctionSymbol import org.jetbrains.kotlin.fir.resolve.calls.FirSyntheticFunctionSymbol
import org.jetbrains.kotlin.fir.resolve.calls.getExpectedType import org.jetbrains.kotlin.fir.resolve.calls.getExpectedType
import org.jetbrains.kotlin.fir.resolve.substitution.ConeSubstitutor import org.jetbrains.kotlin.fir.resolve.substitution.ConeSubstitutor
@@ -71,24 +72,18 @@ class CallAndReferenceGenerator(
): IrExpression { ): IrExpression {
val type = approximateFunctionReferenceType(callableReferenceAccess.resolvedType).toIrType() val type = approximateFunctionReferenceType(callableReferenceAccess.resolvedType).toIrType()
val callableSymbol = callableReferenceAccess.calleeReference.toResolvedCallableSymbol() val firSymbol = callableReferenceAccess.calleeReference.extractSymbolForCall()
if (callableSymbol?.origin == FirDeclarationOrigin.SamConstructor) { if (firSymbol?.origin == FirDeclarationOrigin.SamConstructor) {
assert(explicitReceiverExpression == null) { assert(explicitReceiverExpression == null) {
"Fun interface constructor reference should be unbound: ${explicitReceiverExpression?.dump()}" "Fun interface constructor reference should be unbound: ${explicitReceiverExpression?.dump()}"
} }
return adapterGenerator.generateFunInterfaceConstructorReference( return adapterGenerator.generateFunInterfaceConstructorReference(
callableReferenceAccess, callableReferenceAccess,
callableSymbol as FirSyntheticFunctionSymbol, firSymbol as FirSyntheticFunctionSymbol,
type type
) )
} }
val symbol = callableReferenceAccess.calleeReference.toSymbolForCall(
callableReferenceAccess.dispatchReceiver,
explicitReceiver = callableReferenceAccess.explicitReceiver,
isDelegate = isDelegate,
isReference = true
)
// val x by y -> // val x by y ->
// val `x$delegate` = y // val `x$delegate` = y
// val x get() = `x$delegate`.getValue(this, ::x) // val x get() = `x$delegate`.getValue(this, ::x)
@@ -96,90 +91,135 @@ class CallAndReferenceGenerator(
val isForDelegate = callableReferenceAccess.source?.kind == KtFakeSourceElementKind.DelegatedPropertyAccessor val isForDelegate = callableReferenceAccess.source?.kind == KtFakeSourceElementKind.DelegatedPropertyAccessor
val origin = if (isForDelegate) IrStatementOrigin.PROPERTY_REFERENCE_FOR_DELEGATE else null val origin = if (isForDelegate) IrStatementOrigin.PROPERTY_REFERENCE_FOR_DELEGATE else null
return callableReferenceAccess.convertWithOffsets { startOffset, endOffset -> return callableReferenceAccess.convertWithOffsets { startOffset, endOffset ->
when (symbol) {
is IrPropertySymbol -> {
val referencedPropertyGetterSymbol = declarationStorage.findGetterOfProperty(symbol)
val referencedPropertySetterSymbol = runIf(callableReferenceAccess.resolvedType.isKMutableProperty(session)) {
declarationStorage.findSetterOfProperty(symbol)
}
val backingFieldSymbol = when {
referencedPropertyGetterSymbol != null -> null
else -> declarationStorage.findBackingFieldOfProperty(symbol)
}
IrPropertyReferenceImpl(
startOffset, endOffset, type, symbol,
typeArgumentsCount = callableReferenceAccess.toResolvedCallableSymbol()?.fir?.typeParameters?.size ?: 0,
field = backingFieldSymbol,
getter = referencedPropertyGetterSymbol,
setter = referencedPropertySetterSymbol,
origin = origin
).applyTypeArguments(callableReferenceAccess).applyReceivers(callableReferenceAccess, explicitReceiverExpression)
}
is IrLocalDelegatedPropertySymbol -> { fun FirCallableSymbol<*>.toSymbolForCall(): IrSymbol? {
IrLocalDelegatedPropertyReferenceImpl( return toSymbolForCall(
startOffset, endOffset, type, symbol, callableReferenceAccess.dispatchReceiver,
delegate = declarationStorage.findDelegateVariableOfProperty(symbol), explicitReceiver = callableReferenceAccess.explicitReceiver,
getter = declarationStorage.findGetterOfProperty(symbol), isDelegate = isDelegate,
setter = declarationStorage.findSetterOfProperty(symbol), isReference = true
origin = origin )
) }
}
is IrFieldSymbol -> { fun convertReferenceToRegularProperty(propertySymbol: FirPropertySymbol): IrExpression? {
val field = (callableSymbol as FirFieldSymbol).fir val irPropertySymbol = propertySymbol.toSymbolForCall() as? IrPropertySymbol ?: return null
val propertySymbol = declarationStorage.findPropertyForBackingField(symbol) val referencedPropertyGetterSymbol = declarationStorage.findGetterOfProperty(irPropertySymbol)
?: run { val referencedPropertySetterSymbol = runIf(callableReferenceAccess.resolvedType.isKMutableProperty(session)) {
// In case of [IrField] without the corresponding property, we've created it directly from [FirField]. declarationStorage.findSetterOfProperty(irPropertySymbol)
// Since it's used as a field reference, we need a bogus property as a placeholder.
val firSymbol =
(callableReferenceAccess.calleeReference as FirResolvedNamedReference).resolvedSymbol as FirFieldSymbol
@OptIn(IrSymbolInternals::class)
declarationStorage.getOrCreateIrPropertyByPureField(firSymbol.fir, symbol.owner.parent).symbol
}
IrPropertyReferenceImpl(
startOffset, endOffset, type,
propertySymbol,
typeArgumentsCount = 0,
field = symbol,
getter = runIf(!field.isStatic) { declarationStorage.findGetterOfProperty(propertySymbol) },
setter = runIf(!field.isStatic) { declarationStorage.findSetterOfProperty(propertySymbol) },
origin
).applyReceivers(callableReferenceAccess, explicitReceiverExpression)
} }
val backingFieldSymbol = when {
referencedPropertyGetterSymbol != null -> null
else -> declarationStorage.findBackingFieldOfProperty(irPropertySymbol)
}
return IrPropertyReferenceImpl(
startOffset, endOffset, type, irPropertySymbol,
typeArgumentsCount = callableReferenceAccess.toResolvedCallableSymbol()?.fir?.typeParameters?.size ?: 0,
field = backingFieldSymbol,
getter = referencedPropertyGetterSymbol,
setter = referencedPropertySetterSymbol,
origin = origin
).applyTypeArguments(callableReferenceAccess).applyReceivers(callableReferenceAccess, explicitReceiverExpression)
}
is IrFunctionSymbol -> { fun convertReferenceToSyntheticProperty(propertySymbol: FirSimpleSyntheticPropertySymbol): IrExpression? {
require(type is IrSimpleType) val irPropertySymbol = callablesGenerator.generateIrPropertyForSyntheticPropertyReference(
var function = callableReferenceAccess.calleeReference.toResolvedFunctionSymbol()!!.fir propertySymbol,
if (function is FirConstructor) { conversionScope.parentFromStack()
// The number of type parameters of typealias constructor may mismatch with that number in the original constructor. ).symbol
// And for IR, we need to use the original constructor as a source of truth val property = propertySymbol.syntheticProperty
function = function.originalConstructorIfTypeAlias ?: function val referencedPropertyGetterSymbol = declarationStorage.getIrFunctionSymbol(property.getter.delegate.unwrapUseSiteSubstitutionOverrides().symbol) as? IrSimpleFunctionSymbol ?: return null
} val referencedPropertySetterSymbol = runIf(callableReferenceAccess.resolvedType.isKMutableProperty(session)) {
if (adapterGenerator.needToGenerateAdaptedCallableReference(callableReferenceAccess, type, function)) { property.setter?.delegate?.unwrapUseSiteSubstitutionOverrides()?.symbol?.let {
// Receivers are being applied inside declarationStorage.getIrFunctionSymbol(it) as? IrSimpleFunctionSymbol? ?: return null
with(adapterGenerator) {
// TODO: Figure out why `adaptedType` is different from the `type`?
val adaptedType = callableReferenceAccess.resolvedType.toIrType() as IrSimpleType
generateAdaptedCallableReference(callableReferenceAccess, explicitReceiverExpression, symbol, adaptedType)
}
} else {
IrFunctionReferenceImpl(
startOffset, endOffset, type, symbol,
typeArgumentsCount = function.typeParameters.size,
valueArgumentsCount = function.valueParameters.size + function.contextReceivers.size,
reflectionTarget = symbol
).applyTypeArguments(callableReferenceAccess)
.applyReceivers(callableReferenceAccess, explicitReceiverExpression)
} }
} }
return IrPropertyReferenceImpl(
startOffset, endOffset, type, irPropertySymbol,
typeArgumentsCount = callableReferenceAccess.toResolvedCallableSymbol()?.fir?.typeParameters?.size ?: 0,
field = null,
getter = referencedPropertyGetterSymbol,
setter = referencedPropertySetterSymbol,
origin = origin
).applyTypeArguments(callableReferenceAccess).applyReceivers(callableReferenceAccess, explicitReceiverExpression)
}
else -> { fun convertReferenceToLocalDelegatedProperty(propertySymbol: FirPropertySymbol): IrExpression? {
IrErrorCallExpressionImpl( val irPropertySymbol = propertySymbol.toSymbolForCall() as? IrLocalDelegatedPropertySymbol ?: return null
startOffset, endOffset, type, "Unsupported callable reference: ${callableReferenceAccess.render()}"
) return IrLocalDelegatedPropertyReferenceImpl(
startOffset, endOffset, type, irPropertySymbol,
delegate = declarationStorage.findDelegateVariableOfProperty(irPropertySymbol),
getter = declarationStorage.findGetterOfProperty(irPropertySymbol),
setter = declarationStorage.findSetterOfProperty(irPropertySymbol),
origin = origin
)
}
fun convertReferenceToField(fieldSymbol: FirFieldSymbol): IrExpression? {
val irFieldSymbol = fieldSymbol.toSymbolForCall() as? IrFieldSymbol ?: return null
val field = fieldSymbol.fir
val propertySymbol = declarationStorage.findPropertyForBackingField(irFieldSymbol)
?: run {
// In case of [IrField] without the corresponding property, we've created it directly from [FirField].
// Since it's used as a field reference, we need a bogus property as a placeholder.
@OptIn(IrSymbolInternals::class)
declarationStorage.getOrCreateIrPropertyByPureField(fieldSymbol.fir, irFieldSymbol.owner.parent).symbol
}
return IrPropertyReferenceImpl(
startOffset, endOffset, type,
propertySymbol,
typeArgumentsCount = 0,
field = irFieldSymbol,
getter = runIf(!field.isStatic) { declarationStorage.findGetterOfProperty(propertySymbol) },
setter = runIf(!field.isStatic) { declarationStorage.findSetterOfProperty(propertySymbol) },
origin
).applyReceivers(callableReferenceAccess, explicitReceiverExpression)
}
fun convertReferenceToFunction(functionSymbol: FirFunctionSymbol<*>): IrExpression? {
val irFunctionSymbol = functionSymbol.toSymbolForCall() as? IrFunctionSymbol ?: return null
require(type is IrSimpleType)
var function = callableReferenceAccess.calleeReference.toResolvedFunctionSymbol()!!.fir
if (function is FirConstructor) {
// The number of type parameters of typealias constructor may mismatch with that number in the original constructor.
// And for IR, we need to use the original constructor as a source of truth
function = function.originalConstructorIfTypeAlias ?: function
}
return if (adapterGenerator.needToGenerateAdaptedCallableReference(callableReferenceAccess, type, function)) {
// Receivers are being applied inside
with(adapterGenerator) {
// TODO: Figure out why `adaptedType` is different from the `type`?
val adaptedType = callableReferenceAccess.resolvedType.toIrType() as IrSimpleType
generateAdaptedCallableReference(callableReferenceAccess, explicitReceiverExpression, irFunctionSymbol, adaptedType)
}
} else {
IrFunctionReferenceImpl(
startOffset, endOffset, type, irFunctionSymbol,
typeArgumentsCount = function.typeParameters.size,
valueArgumentsCount = function.valueParameters.size + function.contextReceivers.size,
reflectionTarget = irFunctionSymbol
).applyTypeArguments(callableReferenceAccess)
.applyReceivers(callableReferenceAccess, explicitReceiverExpression)
} }
} }
when (firSymbol) {
is FirSimpleSyntheticPropertySymbol -> convertReferenceToSyntheticProperty(firSymbol)
is FirPropertySymbol -> when {
firSymbol.isLocal -> when {
firSymbol.hasDelegate -> convertReferenceToLocalDelegatedProperty(firSymbol)
else -> null
}
else -> convertReferenceToRegularProperty(firSymbol)
}
is FirFunctionSymbol<*> -> convertReferenceToFunction(firSymbol)
is FirFieldSymbol -> convertReferenceToField(firSymbol)
else -> null
} ?: IrErrorCallExpressionImpl(
startOffset, endOffset, type, "Unsupported callable reference: ${callableReferenceAccess.render()}"
)
} }
} }
@@ -84,21 +84,6 @@ class FakeOverrideGenerator(
// This parameter is only needed for data-class methods that is irrelevant for lazy library classes // This parameter is only needed for data-class methods that is irrelevant for lazy library classes
realDeclarationSymbols = emptySet() realDeclarationSymbols = emptySet()
) )
// Only add synthetic properties if no real properties were found. This can happen in a mixed hierarchy when a Java class
// inherits an @JvmField property. When a Kotlin class extends that Java class, CONFLICTING_INHERITED_JVM_DECLARATIONS will be
// reported otherwise. See KT-56538.
if (none { it is IrProperty }) {
FirSyntheticPropertiesScope.createIfSyntheticNamesProviderIsDefined(session, firClass.defaultType(), useSiteMemberScope)?.let {
generateFakeOverridesForName(
irClass, it, name, firClass,
// We pass result = null so that the IR declaration is not added to the class' list of declarations
// but is still cached in the declaration storage.
result = null,
// This parameter is only needed for data-class methods that is irrelevant for lazy library classes
realDeclarationSymbols = emptySet()
)
}
}
val staticScope = firClass.scopeProvider.getStaticMemberScopeForCallables(firClass, session, scopeSession) val staticScope = firClass.scopeProvider.getStaticMemberScopeForCallables(firClass, session, scopeSession)
if (staticScope != null) { if (staticScope != null) {
generateFakeOverridesForName( generateFakeOverridesForName(
@@ -22,6 +22,7 @@ import org.jetbrains.kotlin.fir.expressions.impl.FirExpressionStub
import org.jetbrains.kotlin.fir.lazy.Fir2IrLazyClass import org.jetbrains.kotlin.fir.lazy.Fir2IrLazyClass
import org.jetbrains.kotlin.fir.lazy.Fir2IrLazyProperty import org.jetbrains.kotlin.fir.lazy.Fir2IrLazyProperty
import org.jetbrains.kotlin.fir.references.toResolvedBaseSymbol import org.jetbrains.kotlin.fir.references.toResolvedBaseSymbol
import org.jetbrains.kotlin.fir.resolve.calls.FirSimpleSyntheticPropertySymbol
import org.jetbrains.kotlin.fir.resolve.dfa.cfg.isLocalClassOrAnonymousObject import org.jetbrains.kotlin.fir.resolve.dfa.cfg.isLocalClassOrAnonymousObject
import org.jetbrains.kotlin.fir.resolve.isKFunctionInvoke import org.jetbrains.kotlin.fir.resolve.isKFunctionInvoke
import org.jetbrains.kotlin.fir.symbols.ConeClassLikeLookupTag import org.jetbrains.kotlin.fir.symbols.ConeClassLikeLookupTag
@@ -386,6 +387,30 @@ class Fir2IrCallableDeclarationsGenerator(val components: Fir2IrComponents) : Fi
return initializer return initializer
} }
fun generateIrPropertyForSyntheticPropertyReference(
propertySymbol: FirSimpleSyntheticPropertySymbol,
parent: IrDeclarationParent,
): IrProperty {
val property = propertySymbol.fir
return irFactory.createProperty(
startOffset = UNDEFINED_OFFSET,
endOffset = UNDEFINED_OFFSET,
origin = IrDeclarationOrigin.SYNTHETIC_JAVA_PROPERTY_DELEGATE,
name = property.name,
visibility = visibilityConverter.convertToDescriptorVisibility(property.visibility),
modality = property.modality ?: Modality.FINAL,
symbol = IrPropertySymbolImpl(),
isVar = property.isVar,
isConst = false,
isLateinit = property.isLateInit,
isDelegated = property.delegate != null,
isExternal = property.isExternal,
isExpect = property.isExpect
).also {
it.parent = parent
}
}
// ------------------------------------ property accessors ------------------------------------ // ------------------------------------ property accessors ------------------------------------
private fun createIrPropertyAccessor( private fun createIrPropertyAccessor(
@@ -8,6 +8,7 @@ package org.jetbrains.kotlin.fir.symbols.impl
import org.jetbrains.kotlin.fir.FirLabel import org.jetbrains.kotlin.fir.FirLabel
import org.jetbrains.kotlin.fir.contracts.FirResolvedContractDescription import org.jetbrains.kotlin.fir.contracts.FirResolvedContractDescription
import org.jetbrains.kotlin.fir.declarations.* import org.jetbrains.kotlin.fir.declarations.*
import org.jetbrains.kotlin.fir.declarations.synthetic.FirSyntheticProperty
import org.jetbrains.kotlin.fir.expressions.FirDelegatedConstructorCall import org.jetbrains.kotlin.fir.expressions.FirDelegatedConstructorCall
import org.jetbrains.kotlin.fir.references.FirControlFlowGraphReference import org.jetbrains.kotlin.fir.references.FirControlFlowGraphReference
import org.jetbrains.kotlin.fir.references.toResolvedConstructorSymbol import org.jetbrains.kotlin.fir.references.toResolvedConstructorSymbol
@@ -81,6 +82,9 @@ class FirConstructorSymbol(callableId: CallableId) : FirFunctionSymbol<FirConstr
*/ */
abstract class FirSyntheticPropertySymbol(propertyId: CallableId, val getterId: CallableId) : FirPropertySymbol(propertyId) { abstract class FirSyntheticPropertySymbol(propertyId: CallableId, val getterId: CallableId) : FirPropertySymbol(propertyId) {
abstract fun copy(): FirSyntheticPropertySymbol abstract fun copy(): FirSyntheticPropertySymbol
val syntheticProperty: FirSyntheticProperty
get() = fir as FirSyntheticProperty
} }
// ------------------------ unnamed ------------------------ // ------------------------ unnamed ------------------------
@@ -2,7 +2,7 @@ FILE fqName:k fileName:/box.kt
PROPERTY name:p1 visibility:public modality:FINAL [delegated,var] PROPERTY name:p1 visibility:public modality:FINAL [delegated,var]
FIELD PROPERTY_DELEGATE name:p1$delegate type:kotlin.reflect.KMutableProperty0<@[FlexibleNullability] kotlin.String?> visibility:private [final,static] FIELD PROPERTY_DELEGATE name:p1$delegate type:kotlin.reflect.KMutableProperty0<@[FlexibleNullability] kotlin.String?> visibility:private [final,static]
EXPRESSION_BODY EXPRESSION_BODY
PROPERTY_REFERENCE 'public open foo: @[FlexibleNullability] kotlin.String?' field=null getter='public open fun <get-foo> (): @[FlexibleNullability] kotlin.String? declared in <root>.J' setter='public open fun <set-foo> (s: @[FlexibleNullability] kotlin.String?): kotlin.Unit declared in <root>.J' type=kotlin.reflect.KMutableProperty0<@[FlexibleNullability] kotlin.String?> origin=null PROPERTY_REFERENCE 'public open foo' field=null getter='public open fun getFoo (): @[FlexibleNullability] kotlin.String? declared in <root>.J' setter='public open fun setFoo (s: @[FlexibleNullability] kotlin.String?): kotlin.Unit declared in <root>.J' type=kotlin.reflect.KMutableProperty0<@[FlexibleNullability] kotlin.String?> origin=null
$this: CONSTRUCTOR_CALL 'public constructor <init> () declared in <root>.J' type=<root>.J origin=null $this: CONSTRUCTOR_CALL 'public constructor <init> () declared in <root>.J' type=<root>.J origin=null
FUN DELEGATED_PROPERTY_ACCESSOR name:<get-p1> visibility:public modality:FINAL <> () returnType:@[FlexibleNullability] kotlin.String? FUN DELEGATED_PROPERTY_ACCESSOR name:<get-p1> visibility:public modality:FINAL <> () returnType:@[FlexibleNullability] kotlin.String?
correspondingProperty: PROPERTY name:p1 visibility:public modality:FINAL [delegated,var] correspondingProperty: PROPERTY name:p1 visibility:public modality:FINAL [delegated,var]
@@ -27,7 +27,7 @@ FILE fqName:k fileName:/box.kt
PROPERTY name:p2 visibility:public modality:FINAL [delegated,var] PROPERTY name:p2 visibility:public modality:FINAL [delegated,var]
FIELD PROPERTY_DELEGATE name:p2$delegate type:kotlin.reflect.KMutableProperty0<@[FlexibleNullability] kotlin.String?> visibility:private [final,static] FIELD PROPERTY_DELEGATE name:p2$delegate type:kotlin.reflect.KMutableProperty0<@[FlexibleNullability] kotlin.String?> visibility:private [final,static]
EXPRESSION_BODY EXPRESSION_BODY
PROPERTY_REFERENCE 'public open foo: @[FlexibleNullability] kotlin.String?' field=null getter='public open fun <get-foo> (): @[FlexibleNullability] kotlin.String? declared in <root>.J' setter='public open fun <set-foo> (s: @[FlexibleNullability] kotlin.String?): kotlin.Unit declared in <root>.J' type=kotlin.reflect.KMutableProperty0<@[FlexibleNullability] kotlin.String?> origin=null PROPERTY_REFERENCE 'public open foo' field=null getter='public open fun getFoo (): @[FlexibleNullability] kotlin.String? declared in <root>.J' setter='public open fun setFoo (s: @[FlexibleNullability] kotlin.String?): kotlin.Unit declared in <root>.J' type=kotlin.reflect.KMutableProperty0<@[FlexibleNullability] kotlin.String?> origin=null
$this: CONSTRUCTOR_CALL 'public constructor <init> () declared in <root>.J' type=<root>.J origin=null $this: CONSTRUCTOR_CALL 'public constructor <init> () declared in <root>.J' type=<root>.J origin=null
FUN DELEGATED_PROPERTY_ACCESSOR name:<get-p2> visibility:public modality:FINAL <> () returnType:@[FlexibleNullability] kotlin.String? FUN DELEGATED_PROPERTY_ACCESSOR name:<get-p2> visibility:public modality:FINAL <> () returnType:@[FlexibleNullability] kotlin.String?
correspondingProperty: PROPERTY name:p2 visibility:public modality:FINAL [delegated,var] correspondingProperty: PROPERTY name:p2 visibility:public modality:FINAL [delegated,var]