FIR: Support proper implicit return type computation for local classes

This commit is contained in:
Denis Zharkov
2020-03-20 16:43:16 +03:00
parent 94193c91a0
commit cdd7e41891
14 changed files with 377 additions and 38 deletions
@@ -5,11 +5,8 @@ FILE: localImplicitBodies.kt
super<R|kotlin/Any|>()
}
public final fun sss(): <ERROR TYPE REF: Cannot calculate return type during full-body resolution (local class/object?): public final fun abc(): <implicit> {
^abc IntegerLiteral(1)
}
> {
^sss R?C|/anonymous.abc|()
public final fun sss(): R|kotlin/Int| {
^sss this@R|/anonymous|.R|/anonymous.abc|()
}
public final fun abc(): R|kotlin/Int| {
@@ -18,8 +15,5 @@ FILE: localImplicitBodies.kt
}
lval g: <ERROR TYPE REF: Cannot calculate return type during full-body resolution (local class/object?): public final fun abc(): <implicit> {
^abc IntegerLiteral(1)
}
> = R|<local>/x|.R?C|/anonymous.sss|()
lval g: R|kotlin/Int| = R|<local>/x|.R|/anonymous.sss|()
}
@@ -45,7 +45,7 @@ FILE: O.kt
super<R|kotlin/Any|>()
}
public final val zz: R|kotlin/Boolean| = R|<local>/z|
public final val zz: R|kotlin/Boolean| = this@R|/O.Derived.Some|.R|/O.Derived.Some.z|
public get(): R|kotlin/Boolean|
}
@@ -0,0 +1,16 @@
private val x = object {
fun foo(x: Int) = /* here we have not computed return type for "bar" */bar(x)
fun bar(y: Int) = this.hashCode() + y > 0
val w get() = z
val z get() = this.hashCode() == 0
}
fun useBoolean(b: Boolean) {}
fun main() {
useBoolean(x.foo(1))
useBoolean(x.bar(2))
useBoolean(x.w)
useBoolean(x.z)
}
@@ -0,0 +1,35 @@
FILE: implicitInAnonymous.kt
private final val x: R|anonymous| = object : R|kotlin/Any| {
private constructor(): R|anonymous| {
super<R|kotlin/Any|>()
}
public final fun foo(x: R|kotlin/Int|): R|kotlin/Boolean| {
^foo this@R|/anonymous|.R|/anonymous.bar|(R|<local>/x|)
}
public final fun bar(y: R|kotlin/Int|): R|kotlin/Boolean| {
^bar CMP(>, this@R|/anonymous|.R|kotlin/Any.hashCode|().R|kotlin/Int.plus|(R|<local>/y|).R|kotlin/Int.compareTo|(Int(0)))
}
public final val w: R|kotlin/Boolean|
public get(): R|kotlin/Boolean| {
^ this@R|/anonymous|.R|/anonymous.z|
}
public final val z: R|kotlin/Boolean|
public get(): R|kotlin/Boolean| {
^ ==(this@R|/anonymous|.R|kotlin/Any.hashCode|(), Int(0))
}
}
private get(): R|anonymous|
public final fun useBoolean(b: R|kotlin/Boolean|): R|kotlin/Unit| {
}
public final fun main(): R|kotlin/Unit| {
R|/useBoolean|(R|/x|.R|/anonymous.foo|(Int(1)))
R|/useBoolean|(R|/x|.R|/anonymous.bar|(Int(2)))
R|/useBoolean|(R|/x|.R|/anonymous.w|)
R|/useBoolean|(R|/x|.R|/anonymous.z|)
}
@@ -0,0 +1,37 @@
fun useBoolean(b: Boolean) {}
fun main() {
class A {
fun foo(x: Int) = bar(x)
fun bar(y: Int) = this.hashCode() + y > 0
val w get() = z
val z get() = this.hashCode() == 0
}
val a = A()
useBoolean(a.foo(1))
useBoolean(a.bar(1))
useBoolean(a.w)
useBoolean(a.z)
class B {
fun foo(x: Int) = inner.w
fun bar(y: Int) = this.hashCode() + y > 0
val inner = Inner()
inner class Inner {
val w get() = z
val z get() = bar(1)
}
}
val b = B()
useBoolean(b.foo(1))
useBoolean(b.bar(1))
useBoolean(b.inner.w)
useBoolean(b.inner.z)
}
@@ -0,0 +1,75 @@
FILE: implicitInLocalClasses.kt
public final fun useBoolean(b: R|kotlin/Boolean|): R|kotlin/Unit| {
}
public final fun main(): R|kotlin/Unit| {
local final class A : R|kotlin/Any| {
public constructor(): R|A| {
super<R|kotlin/Any|>()
}
public final fun foo(x: R|kotlin/Int|): R|kotlin/Boolean| {
^foo this@R|/A|.R|/A.bar|(R|<local>/x|)
}
public final fun bar(y: R|kotlin/Int|): R|kotlin/Boolean| {
^bar CMP(>, this@R|/A|.R|kotlin/Any.hashCode|().R|kotlin/Int.plus|(R|<local>/y|).R|kotlin/Int.compareTo|(Int(0)))
}
public final val w: R|kotlin/Boolean|
public get(): R|kotlin/Boolean| {
^ this@R|/A|.R|/A.z|
}
public final val z: R|kotlin/Boolean|
public get(): R|kotlin/Boolean| {
^ ==(this@R|/A|.R|kotlin/Any.hashCode|(), Int(0))
}
}
lval a: R|A| = R|/A.A|()
R|/useBoolean|(R|<local>/a|.R|/A.foo|(Int(1)))
R|/useBoolean|(R|<local>/a|.R|/A.bar|(Int(1)))
R|/useBoolean|(R|<local>/a|.R|/A.w|)
R|/useBoolean|(R|<local>/a|.R|/A.z|)
local final class B : R|kotlin/Any| {
public constructor(): R|B| {
super<R|kotlin/Any|>()
}
public final fun foo(x: R|kotlin/Int|): R|kotlin/Boolean| {
^foo this@R|/B|.R|/B.inner|.R|/B.Inner.w|
}
public final fun bar(y: R|kotlin/Int|): R|kotlin/Boolean| {
^bar CMP(>, this@R|/B|.R|kotlin/Any.hashCode|().R|kotlin/Int.plus|(R|<local>/y|).R|kotlin/Int.compareTo|(Int(0)))
}
public final val inner: R|B.Inner| = this@R|/B|.R|/B.Inner.Inner|()
public get(): R|B.Inner|
local final inner class Inner : R|kotlin/Any| {
public constructor(): R|B.Inner| {
super<R|kotlin/Any|>()
}
public final val w: R|kotlin/Boolean|
public get(): R|kotlin/Boolean| {
^ this@R|/B.Inner|.R|/B.Inner.z|
}
public final val z: R|kotlin/Boolean|
public get(): R|kotlin/Boolean| {
^ this@R|/B|.R|/B.bar|(Int(1))
}
}
}
lval b: R|B| = R|/B.B|()
R|/useBoolean|(R|<local>/b|.R|/B.foo|(Int(1)))
R|/useBoolean|(R|<local>/b|.R|/B.bar|(Int(1)))
R|/useBoolean|(R|<local>/b|.R|/B.inner|.R|/B.Inner.w|)
R|/useBoolean|(R|<local>/b|.R|/B.inner|.R|/B.Inner.z|)
}
@@ -1314,6 +1314,29 @@ public class FirDiagnosticsTestGenerated extends AbstractFirDiagnosticsTest {
}
}
@TestMetadata("compiler/fir/analysis-tests/testData/resolve/localClasses")
@TestDataPath("$PROJECT_ROOT")
@RunWith(JUnit3RunnerWithInners.class)
public static class LocalClasses extends AbstractFirDiagnosticsTest {
private void runTest(String testDataFilePath) throws Exception {
KotlinTestUtils.runTest(this::doTest, this, testDataFilePath);
}
public void testAllFilesPresentInLocalClasses() throws Exception {
KotlinTestUtils.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("compiler/fir/analysis-tests/testData/resolve/localClasses"), Pattern.compile("^([^.]+)\\.kt$"), null, true);
}
@TestMetadata("implicitInAnonymous.kt")
public void testImplicitInAnonymous() throws Exception {
runTest("compiler/fir/analysis-tests/testData/resolve/localClasses/implicitInAnonymous.kt");
}
@TestMetadata("implicitInLocalClasses.kt")
public void testImplicitInLocalClasses() throws Exception {
runTest("compiler/fir/analysis-tests/testData/resolve/localClasses/implicitInLocalClasses.kt");
}
}
@TestMetadata("compiler/fir/analysis-tests/testData/resolve/multifile")
@TestDataPath("$PROJECT_ROOT")
@RunWith(JUnit3RunnerWithInners.class)
@@ -1314,6 +1314,29 @@ public class FirDiagnosticsWithLightTreeTestGenerated extends AbstractFirDiagnos
}
}
@TestMetadata("compiler/fir/analysis-tests/testData/resolve/localClasses")
@TestDataPath("$PROJECT_ROOT")
@RunWith(JUnit3RunnerWithInners.class)
public static class LocalClasses extends AbstractFirDiagnosticsWithLightTreeTest {
private void runTest(String testDataFilePath) throws Exception {
KotlinTestUtils.runTest(this::doTest, this, testDataFilePath);
}
public void testAllFilesPresentInLocalClasses() throws Exception {
KotlinTestUtils.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("compiler/fir/analysis-tests/testData/resolve/localClasses"), Pattern.compile("^([^.]+)\\.kt$"), null, true);
}
@TestMetadata("implicitInAnonymous.kt")
public void testImplicitInAnonymous() throws Exception {
runTest("compiler/fir/analysis-tests/testData/resolve/localClasses/implicitInAnonymous.kt");
}
@TestMetadata("implicitInLocalClasses.kt")
public void testImplicitInLocalClasses() throws Exception {
runTest("compiler/fir/analysis-tests/testData/resolve/localClasses/implicitInLocalClasses.kt");
}
}
@TestMetadata("compiler/fir/analysis-tests/testData/resolve/multifile")
@TestDataPath("$PROJECT_ROOT")
@RunWith(JUnit3RunnerWithInners.class)
@@ -99,7 +99,10 @@ abstract class FirAbstractBodyResolveTransformer(phase: FirResolvePhase) : FirAb
else -> null
}
class BodyResolveContext(val returnTypeCalculator: ReturnTypeCalculator) {
class BodyResolveContext(
val returnTypeCalculator: ReturnTypeCalculator,
val targetedLocalClasses: Set<FirClass<*>> = emptySet()
) {
val fileImportsScope: MutableList<FirScope> = mutableListOf()
@set:PrivateForInline
@@ -189,13 +192,27 @@ abstract class FirAbstractBodyResolveTransformer(phase: FirResolvePhase) : FirAb
val lastScope = localScopes.lastOrNull() ?: return
localScopes = localScopes.set(localScopes.size - 1, lastScope.transform())
}
@OptIn(PrivateForInline::class)
fun createSnapshotForLocalClasses(
returnTypeCalculator: ReturnTypeCalculator,
targetedLocalClasses: Set<FirClass<*>>
) = BodyResolveContext(returnTypeCalculator, targetedLocalClasses).apply {
fileImportsScope.addAll(this@BodyResolveContext.fileImportsScope)
typeParametersScopes = this@BodyResolveContext.typeParametersScopes
localScopes = this@BodyResolveContext.localScopes
file = this@BodyResolveContext.file
implicitReceiverStack = this@BodyResolveContext.implicitReceiverStack
localContextForAnonymousFunctions.putAll(this@BodyResolveContext.localContextForAnonymousFunctions)
containerIfAny = this@BodyResolveContext.containerIfAny
}
}
class BodyResolveTransformerComponents(
override val session: FirSession,
override val scopeSession: ScopeSession,
val transformer: FirBodyResolveTransformer,
private val context: BodyResolveContext
val context: BodyResolveContext
) : BodyResolveComponents {
override val fileImportsScope: List<FirScope> get() = context.fileImportsScope
override val typeParametersScopes: List<FirScope> get() = context.typeParametersScopes
@@ -309,6 +309,14 @@ class FirDeclarationsResolveTransformer(transformer: FirBodyResolveTransformer)
}
override fun transformRegularClass(regularClass: FirRegularClass, data: ResolutionMode): CompositeTransformResult<FirStatement> {
if (regularClass.symbol.classId.isLocal && regularClass !in context.targetedLocalClasses) {
return FirImplicitTypeBodyResolveTransformerAdapterForLocalClasses(
components, data
).transformRegularClass(regularClass, null).also {
context.storeClass(regularClass)
}
}
context.storeClass(regularClass)
return withTypeParametersOf(regularClass) {
if (regularClass.symbol.classId.isLocal) {
@@ -338,7 +346,16 @@ class FirDeclarationsResolveTransformer(transformer: FirBodyResolveTransformer)
}
}
override fun transformAnonymousObject(anonymousObject: FirAnonymousObject, data: ResolutionMode): CompositeTransformResult<FirStatement> {
override fun transformAnonymousObject(
anonymousObject: FirAnonymousObject,
data: ResolutionMode
): CompositeTransformResult<FirStatement> {
if (anonymousObject !in context.targetedLocalClasses) {
return FirImplicitTypeBodyResolveTransformerAdapterForLocalClasses(
components, data
).transformAnonymousObject(anonymousObject, null)
}
prepareLocalClassForBodyResolve(anonymousObject)
val type = anonymousObject.defaultType()
anonymousObject.resultType = buildResolvedTypeRef {
@@ -640,17 +657,17 @@ class FirDeclarationsResolveTransformer(transformer: FirBodyResolveTransformer)
): T {
val (implicitReceiverValue, implicitCompanionValues) = components.collectImplicitReceivers(type, owner)
implicitCompanionValues.forEach { value ->
implicitReceiverStack.add(null, value)
context.implicitReceiverStack.add(null, value)
}
implicitReceiverValue?.let { implicitReceiverStack.add(labelName, it) }
implicitReceiverValue?.let { context.implicitReceiverStack.add(labelName, it) }
try {
return block()
} finally {
if (type != null) {
implicitReceiverStack.pop(labelName)
context.implicitReceiverStack.pop(labelName)
for (i in implicitCompanionValues.indices)
implicitReceiverStack.pop(null)
context.implicitReceiverStack.pop(null)
}
}
}
@@ -7,12 +7,14 @@
package org.jetbrains.kotlin.fir.resolve.transformers.body.resolve
import kotlinx.collections.immutable.persistentListOf
import org.jetbrains.kotlin.fir.FirElement
import org.jetbrains.kotlin.fir.FirSession
import org.jetbrains.kotlin.fir.declarations.*
import org.jetbrains.kotlin.fir.declarations.synthetic.FirSyntheticProperty
import org.jetbrains.kotlin.fir.diagnostics.ConeSimpleDiagnostic
import org.jetbrains.kotlin.fir.diagnostics.DiagnosticKind
import org.jetbrains.kotlin.fir.expressions.FirStatement
import org.jetbrains.kotlin.fir.render
import org.jetbrains.kotlin.fir.resolve.ResolutionMode
import org.jetbrains.kotlin.fir.resolve.ScopeSession
@@ -25,6 +27,7 @@ import org.jetbrains.kotlin.fir.types.FirImplicitTypeRef
import org.jetbrains.kotlin.fir.types.FirResolvedTypeRef
import org.jetbrains.kotlin.fir.types.builder.buildErrorTypeRef
import org.jetbrains.kotlin.fir.visitors.CompositeTransformResult
import org.jetbrains.kotlin.fir.visitors.FirDefaultVisitorVoid
import org.jetbrains.kotlin.fir.visitors.FirTransformer
import org.jetbrains.kotlin.fir.visitors.compose
@@ -51,6 +54,95 @@ class FirImplicitTypeBodyResolveTransformerAdapter(private val scopeSession: Sco
}
}
class FirImplicitTypeBodyResolveTransformerAdapterForLocalClasses(
private val components: FirAbstractBodyResolveTransformer.BodyResolveTransformerComponents,
private val resolutionMode: ResolutionMode,
) : FirTransformer<Nothing?>() {
override fun <E : FirElement> transformElement(element: E, data: Nothing?): CompositeTransformResult<E> {
return element.compose()
}
override fun transformRegularClass(regularClass: FirRegularClass, data: Nothing?): CompositeTransformResult<FirStatement> {
return transformClass(regularClass, data)
}
override fun transformAnonymousObject(anonymousObject: FirAnonymousObject, data: Nothing?): CompositeTransformResult<FirStatement> {
return transformClass(anonymousObject, data)
}
override fun <F : FirClass<F>> transformClass(klass: FirClass<F>, data: Nothing?): CompositeTransformResult<FirStatement> {
val (designationMap, targetedClasses) = CollectingVisitor().run {
visitClass(klass)
resultingMap to targetedClasses
}
val implicitBodyResolveComputationSession =
((components.returnTypeCalculator as? ReturnTypeCalculatorWithJump)?.implicitBodyResolveComputationSession
?: ImplicitBodyResolveComputationSession())
val returnTypeCalculator = ReturnTypeCalculatorWithJump(
components.session,
components.scopeSession,
implicitBodyResolveComputationSession,
designationMap,
)
val newContext = components.context.createSnapshotForLocalClasses(returnTypeCalculator, targetedClasses)
returnTypeCalculator.outerBodyResolveContext = newContext
val transformer = FirImplicitAwareBodyResolveTransformer(
components.session, components.scopeSession,
implicitBodyResolveComputationSession,
FirResolvePhase.BODY_RESOLVE,
outerBodyResolveContext = newContext,
implicitTypeOnly = false,
returnTypeCalculator
)
return klass.transform(transformer, resolutionMode)
}
}
private class CollectingVisitor : FirDefaultVisitorVoid() {
val resultingMap = mutableMapOf<FirCallableMemberDeclaration<*>, List<FirClass<*>>>()
val targetedClasses = mutableSetOf<FirClass<*>>()
private var currentPath = persistentListOf<FirClass<*>>()
override fun visitElement(element: FirElement) {}
override fun visitRegularClass(regularClass: FirRegularClass) {
visitClass(regularClass)
}
override fun visitAnonymousObject(anonymousObject: FirAnonymousObject) {
visitClass(anonymousObject)
}
override fun <F : FirClass<F>> visitClass(klass: FirClass<F>) {
targetedClasses.add(klass)
val prev = currentPath
currentPath = currentPath.add(klass)
klass.acceptChildren(this)
currentPath = prev
}
override fun visitSimpleFunction(simpleFunction: FirSimpleFunction) {
visitCallableMemberDeclaration(simpleFunction)
}
override fun visitProperty(property: FirProperty) {
visitCallableMemberDeclaration(property)
}
override fun <F : FirCallableMemberDeclaration<F>> visitCallableMemberDeclaration(
callableMemberDeclaration: FirCallableMemberDeclaration<F>
) {
if (callableMemberDeclaration.returnTypeRef !is FirImplicitTypeRef) return
resultingMap[callableMemberDeclaration] = currentPath
}
}
fun createReturnTypeCalculatorForIDE(session: FirSession, scopeSession: ScopeSession): ReturnTypeCalculator =
ReturnTypeCalculatorWithJump(session, scopeSession, ImplicitBodyResolveComputationSession())
@@ -105,7 +197,7 @@ private open class FirImplicitAwareBodyResolveTransformer(
require(status is ImplicitBodyResolveComputationStatus.NotComputed) {
"Unexpected status in transformCallableMember ($status) for ${member.render()}"
}
implicitBodyResolveComputationSession.startComputing(symbol)
val result = transform()
implicitBodyResolveComputationSession.storeResult(symbol, result.single)
@@ -117,9 +209,12 @@ private open class FirImplicitAwareBodyResolveTransformer(
private class ReturnTypeCalculatorWithJump(
private val session: FirSession,
private val scopeSession: ScopeSession,
private val implicitBodyResolveComputationSession: ImplicitBodyResolveComputationSession
val implicitBodyResolveComputationSession: ImplicitBodyResolveComputationSession,
val designationMapForLocalClasses: Map<FirCallableMemberDeclaration<*>, List<FirClass<*>>> = mapOf()
) : ReturnTypeCalculator {
var outerBodyResolveContext: FirAbstractBodyResolveTransformer.BodyResolveContext? = null
override fun tryCalculateReturnType(declaration: FirTypedDeclaration): FirResolvedTypeRef {
if (declaration is FirValueParameter && declaration.returnTypeRef is FirImplicitTypeRef) {
// TODO?
@@ -150,29 +245,36 @@ private class ReturnTypeCalculatorWithJump(
val provider = session.firProvider
val file = provider.getFirCallableContainerFile(symbol)
val (designation, outerBodyResolveContext) = if (declaration in designationMapForLocalClasses) {
designationMapForLocalClasses.getValue(declaration) to outerBodyResolveContext
} else {
val file = provider.getFirCallableContainerFile(symbol)
val outerClasses = generateSequence(id.classId) { classId ->
classId.outerClassId
}.mapTo(mutableListOf()) { provider.getFirClassifierByFqName(it) }
val outerClasses = generateSequence(id.classId) { classId ->
classId.outerClassId
}.mapTo(mutableListOf()) { provider.getFirClassifierByFqName(it) }
if (file == null || outerClasses.any { it == null }) {
return buildErrorTypeRef {
diagnostic = ConeSimpleDiagnostic(
"Cannot calculate return type (local class/object?)",
DiagnosticKind.InferenceError
)
if (file == null || outerClasses.any { it == null }) {
return buildErrorTypeRef {
diagnostic = ConeSimpleDiagnostic(
"Cannot calculate return type (local class/object?)",
DiagnosticKind.InferenceError
)
}
}
(listOf(file) + outerClasses.filterNotNull().asReversed()) to null
}
val designation = (listOf(file) + outerClasses.filterNotNull().asReversed() + listOf(declaration))
val transformer = FirDesignatedBodyResolveTransformerForReturnTypeCalculator(
designation.iterator(),
file.session,
(designation.drop(1) + declaration).iterator(),
session,
scopeSession,
implicitBodyResolveComputationSession
implicitBodyResolveComputationSession,
this,
outerBodyResolveContext
)
file.transform<FirElement, ResolutionMode>(transformer, ResolutionMode.ContextDependent)
designation.first().transform<FirElement, ResolutionMode>(transformer, ResolutionMode.ContextDependent)
val transformedDeclaration = transformer.lastResult as? FirCallableMemberDeclaration<*>
?: error("Unexpected lastResult: ${transformer.lastResult?.render()}")
@@ -1,2 +0,0 @@
Failures detected in FirImplicitTypeBodyResolveTransformerAdapter, file: /localReturnInsidePropertyAccessor.fir.kt
Cause: java.lang.NullPointerException
+2 -1
View File
@@ -258,7 +258,8 @@ FILE fqName:<root> fileName:/enum.kt
BLOCK_BODY
SET_FIELD 'FIELD PROPERTY_BACKING_FIELD name:z type:kotlin.Int visibility:private [final]' type=kotlin.Unit origin=null
receiver: GET_VAR '<this>: <root>.TestEnum4.TEST2 declared in <root>.TestEnum4.TEST2' type=<root>.TestEnum4.TEST2 origin=null
value: GET_VAR 'x: kotlin.Int declared in <root>.TestEnum4.<init>' type=kotlin.Int origin=null
value: CALL 'public final fun <get-x> (): kotlin.Int declared in <root>.TestEnum4' type=kotlin.Int origin=GET_PROPERTY
$this: GET_VAR '<this>: <root>.TestEnum4.TEST2 declared in <root>.TestEnum4.TEST2' type=<root>.TestEnum4.TEST2 origin=null
FUN name:foo visibility:public modality:FINAL <> ($this:<root>.TestEnum4.TEST2) returnType:kotlin.Unit
$this: VALUE_PARAMETER name:<this> type:<root>.TestEnum4.TEST2
BLOCK_BODY
@@ -87,7 +87,8 @@ FILE fqName:<root> fileName:/multipleThisReferences.kt
CALL 'public final fun plus (other: kotlin.Int): kotlin.Int [operator] declared in kotlin.Int' type=kotlin.Int origin=PLUS
$this: CALL 'public final fun <get-x> (): kotlin.Int declared in <root>.Outer.Inner' type=kotlin.Int origin=GET_PROPERTY
$this: GET_VAR '<this>: <root>.Host.test.<no name provided> declared in <root>.Host.test.<no name provided>' type=<root>.Host.test.<no name provided> origin=null
other: GET_VAR 'y: kotlin.Int declared in <root>.Host.<init>' type=kotlin.Int origin=null
other: CALL 'public final fun <get-y> (): kotlin.Int declared in <root>.Host' type=kotlin.Int origin=GET_PROPERTY
$this: GET_VAR '<this>: <root>.Host declared in <root>.Host.test' type=<root>.Host origin=null
FUN DEFAULT_PROPERTY_ACCESSOR name:<get-xx> visibility:public modality:FINAL <> ($this:<root>.Host.test.<no name provided>) returnType:kotlin.Int
correspondingProperty: PROPERTY name:xx visibility:public modality:FINAL [val]
$this: VALUE_PARAMETER name:<this> type:<root>.Host.test.<no name provided>