diff --git a/compiler/ir/backend.js/src/org/jetbrains/kotlin/ir/backend/js/lower/PrivateMembersLowering.kt b/compiler/ir/backend.js/src/org/jetbrains/kotlin/ir/backend/js/lower/PrivateMembersLowering.kt index c9e45cb13e7..99bcc83a645 100644 --- a/compiler/ir/backend.js/src/org/jetbrains/kotlin/ir/backend/js/lower/PrivateMembersLowering.kt +++ b/compiler/ir/backend.js/src/org/jetbrains/kotlin/ir/backend/js/lower/PrivateMembersLowering.kt @@ -5,17 +5,15 @@ package org.jetbrains.kotlin.ir.backend.js.lower -import org.jetbrains.kotlin.backend.common.ClassLoweringPass +import org.jetbrains.kotlin.backend.common.FileLoweringPass import org.jetbrains.kotlin.backend.common.descriptors.WrappedSimpleFunctionDescriptor import org.jetbrains.kotlin.backend.common.descriptors.WrappedValueParameterDescriptor import org.jetbrains.kotlin.backend.common.ir.copyTo import org.jetbrains.kotlin.descriptors.Visibilities +import org.jetbrains.kotlin.ir.IrStatement import org.jetbrains.kotlin.ir.UNDEFINED_OFFSET import org.jetbrains.kotlin.ir.backend.js.JsIrBackendContext -import org.jetbrains.kotlin.ir.declarations.IrClass -import org.jetbrains.kotlin.ir.declarations.IrDeclarationOriginImpl -import org.jetbrains.kotlin.ir.declarations.IrProperty -import org.jetbrains.kotlin.ir.declarations.IrSimpleFunction +import org.jetbrains.kotlin.ir.declarations.* import org.jetbrains.kotlin.ir.declarations.impl.IrFunctionImpl import org.jetbrains.kotlin.ir.declarations.impl.IrValueParameterImpl import org.jetbrains.kotlin.ir.expressions.* @@ -29,31 +27,45 @@ import org.jetbrains.kotlin.ir.symbols.impl.IrValueParameterSymbolImpl import org.jetbrains.kotlin.ir.util.deepCopyWithSymbols import org.jetbrains.kotlin.ir.util.transformFlat import org.jetbrains.kotlin.ir.visitors.IrElementTransformerVoid +import org.jetbrains.kotlin.ir.visitors.transformChildrenVoid import org.jetbrains.kotlin.name.Name -val STATIC_THIS_PARAMETER = object : IrDeclarationOriginImpl("STATIC_THIS_PARAMETER") {} +private val STATIC_THIS_PARAMETER = object : IrDeclarationOriginImpl("STATIC_THIS_PARAMETER") {} -class PrivateMembersLowering(val context: JsIrBackendContext) : ClassLoweringPass { +class PrivateMembersLowering(val context: JsIrBackendContext) : FileLoweringPass { private val memberMap = mutableMapOf() - override fun lower(irClass: IrClass) { + override fun lower(irFile: IrFile) { + transformPrivateDeclarations(irFile) + transformPrivateUseSites(irFile) + memberMap.clear() + } - irClass.declarations.transformFlat { - when (it) { - is IrSimpleFunction -> transformMemberToStaticFunction(it)?.let { staticFunction -> - memberMap[it.symbol] = staticFunction - listOf(staticFunction) + private fun transformPrivateDeclarations(irFile: IrFile) { + irFile.transformChildrenVoid(object : IrElementTransformerVoid() { + override fun visitClass(declaration: IrClass): IrStatement { + declaration.transformChildrenVoid(this) + declaration.declarations.transformFlat { + when (it) { + is IrSimpleFunction -> transformMemberToStaticFunction(it)?.let { staticFunction -> + memberMap[it.symbol] = staticFunction + listOf(staticFunction) + } + is IrProperty -> listOf(it.apply { + this.getter = this.getter?.let { g -> transformAccessor(g) } + this.setter = this.setter?.let { s -> transformAccessor(s) } + }) + else -> null + } } - is IrProperty -> listOf(it.apply { - getter = getter?.let { g -> transformAccessor(g) } - setter = setter?.let { s -> transformAccessor(s) } - }) - else -> null + return declaration } - } + }) + } - irClass.transform(object : IrElementTransformerVoid() { + private fun transformPrivateUseSites(irFile: IrFile) { + irFile.transform(object : IrElementTransformerVoid() { override fun visitCall(expression: IrCall): IrExpression { super.visitCall(expression) @@ -97,7 +109,6 @@ class PrivateMembersLowering(val context: JsIrBackendContext) : ClassLoweringPas } else expression } - private fun transformPrivateToStaticCall(expression: IrCall, staticTarget: IrSimpleFunction): IrCall { val newExpression = IrCallImpl( expression.startOffset, expression.endOffset, diff --git a/js/js.tests/test/org/jetbrains/kotlin/js/test/ir/semantics/IrBoxJsTestGenerated.java b/js/js.tests/test/org/jetbrains/kotlin/js/test/ir/semantics/IrBoxJsTestGenerated.java index 5ef9c44cbc7..6ff215bd115 100644 --- a/js/js.tests/test/org/jetbrains/kotlin/js/test/ir/semantics/IrBoxJsTestGenerated.java +++ b/js/js.tests/test/org/jetbrains/kotlin/js/test/ir/semantics/IrBoxJsTestGenerated.java @@ -6494,6 +6494,11 @@ public class IrBoxJsTestGenerated extends AbstractIrBoxJsTest { runTest("js/js.translator/testData/box/propertyAccess/packagePropertySet.kt"); } + @TestMetadata("privateClassesWithPrivateMembers.kt") + public void testPrivateClassesWithPrivateMembers() throws Exception { + runTest("js/js.translator/testData/box/propertyAccess/privateClassesWithPrivateMembers.kt"); + } + @TestMetadata("privatePropertyAccessFromMethod.kt") public void testPrivatePropertyAccessFromMethod() throws Exception { runTest("js/js.translator/testData/box/propertyAccess/privatePropertyAccessFromMethod.kt"); diff --git a/js/js.tests/test/org/jetbrains/kotlin/js/test/semantics/BoxJsTestGenerated.java b/js/js.tests/test/org/jetbrains/kotlin/js/test/semantics/BoxJsTestGenerated.java index 3795bfc35fa..127c9bec5b9 100644 --- a/js/js.tests/test/org/jetbrains/kotlin/js/test/semantics/BoxJsTestGenerated.java +++ b/js/js.tests/test/org/jetbrains/kotlin/js/test/semantics/BoxJsTestGenerated.java @@ -6514,6 +6514,11 @@ public class BoxJsTestGenerated extends AbstractBoxJsTest { runTest("js/js.translator/testData/box/propertyAccess/packagePropertySet.kt"); } + @TestMetadata("privateClassesWithPrivateMembers.kt") + public void testPrivateClassesWithPrivateMembers() throws Exception { + runTest("js/js.translator/testData/box/propertyAccess/privateClassesWithPrivateMembers.kt"); + } + @TestMetadata("privatePropertyAccessFromMethod.kt") public void testPrivatePropertyAccessFromMethod() throws Exception { runTest("js/js.translator/testData/box/propertyAccess/privatePropertyAccessFromMethod.kt"); diff --git a/js/js.translator/testData/box/propertyAccess/privateClassesWithPrivateMembers.kt b/js/js.translator/testData/box/propertyAccess/privateClassesWithPrivateMembers.kt new file mode 100644 index 00000000000..d954836b5ba --- /dev/null +++ b/js/js.translator/testData/box/propertyAccess/privateClassesWithPrivateMembers.kt @@ -0,0 +1,14 @@ +// EXPECTED_REACHABLE_NODES: 1305 + +private class A { + private val f = "OK" + inline fun ii() = f +} + + +private class B { + private val a = A() + fun foo() = a.ii() +} + +fun box() = B().foo() \ No newline at end of file