diff --git a/compiler/fir/fir2ir/tests-gen/org/jetbrains/kotlin/test/runners/codegen/FirBlackBoxCodegenTestGenerated.java b/compiler/fir/fir2ir/tests-gen/org/jetbrains/kotlin/test/runners/codegen/FirBlackBoxCodegenTestGenerated.java index d94d4974328..056ad73d115 100644 --- a/compiler/fir/fir2ir/tests-gen/org/jetbrains/kotlin/test/runners/codegen/FirBlackBoxCodegenTestGenerated.java +++ b/compiler/fir/fir2ir/tests-gen/org/jetbrains/kotlin/test/runners/codegen/FirBlackBoxCodegenTestGenerated.java @@ -19512,6 +19512,12 @@ public class FirBlackBoxCodegenTestGenerated extends AbstractFirBlackBoxCodegenT runTest("compiler/testData/codegen/box/innerNested/createdNestedInOuterMember.kt"); } + @Test + @TestMetadata("extenderNestedClass.kt") + public void testExtenderNestedClass() throws Exception { + runTest("compiler/testData/codegen/box/innerNested/extenderNestedClass.kt"); + } + @Test @TestMetadata("extensionFun.kt") public void testExtensionFun() throws Exception { diff --git a/compiler/ir/backend.js/src/org/jetbrains/kotlin/ir/backend/js/transformers/irToJs/JsClassGenerator.kt b/compiler/ir/backend.js/src/org/jetbrains/kotlin/ir/backend/js/transformers/irToJs/JsClassGenerator.kt index 13ff53bbc25..00b91f00796 100644 --- a/compiler/ir/backend.js/src/org/jetbrains/kotlin/ir/backend/js/transformers/irToJs/JsClassGenerator.kt +++ b/compiler/ir/backend.js/src/org/jetbrains/kotlin/ir/backend/js/transformers/irToJs/JsClassGenerator.kt @@ -25,10 +25,8 @@ class JsClassGenerator(private val irClass: IrClass, val context: JsGenerationCo private val classNameRef = className.makeRef() private val baseClass: IrType? = irClass.superTypes.firstOrNull { !it.classifierOrFail.isInterface } - private val baseClassName by lazy { // Lazy in case was not collected by namer during JsClassGenerator construction - baseClass?.let { - context.getNameForClass(baseClass.classifierOrFail.owner as IrClass) - } + private val baseClassRef by lazy { // Lazy in case was not collected by namer during JsClassGenerator construction + baseClass?.getClassRef(context) } private val classPrototypeRef = prototypeOf(classNameRef) private val classBlock = JsGlobalBlock() @@ -49,7 +47,7 @@ class JsClassGenerator(private val irClass: IrClass, val context: JsGenerationCo val jsClass = JsClass(name = className) if (baseClass != null && !baseClass.isAny()) { - jsClass.baseClass = baseClassName?.makeRef() + jsClass.baseClass = baseClassRef } if (es6mode) classModel.preDeclarationBlock.statements += jsClass.makeStmt() @@ -197,7 +195,7 @@ class JsClassGenerator(private val irClass: IrClass, val context: JsGenerationCo } val createCall = jsAssignment( - classPrototypeRef, JsInvocation(Namer.JS_OBJECT_CREATE_FUNCTION, prototypeOf(baseClassName!!.makeRef())) + classPrototypeRef, JsInvocation(Namer.JS_OBJECT_CREATE_FUNCTION, prototypeOf(baseClassRef!!)) ).makeStmt() val ctorAssign = jsAssignment(JsNameRef(Namer.CONSTRUCTOR_NAME, classPrototypeRef), classNameRef).makeStmt() diff --git a/compiler/ir/backend.js/src/org/jetbrains/kotlin/ir/backend/js/transformers/irToJs/JsIntrinsicTransformers.kt b/compiler/ir/backend.js/src/org/jetbrains/kotlin/ir/backend/js/transformers/irToJs/JsIntrinsicTransformers.kt index 22f1aa5ab77..0cca8e77a95 100644 --- a/compiler/ir/backend.js/src/org/jetbrains/kotlin/ir/backend/js/transformers/irToJs/JsIntrinsicTransformers.kt +++ b/compiler/ir/backend.js/src/org/jetbrains/kotlin/ir/backend/js/transformers/irToJs/JsIntrinsicTransformers.kt @@ -8,19 +8,16 @@ package org.jetbrains.kotlin.ir.backend.js.transformers.irToJs import org.jetbrains.kotlin.ir.backend.js.JsIrBackendContext import org.jetbrains.kotlin.ir.backend.js.utils.JsGenerationContext import org.jetbrains.kotlin.ir.backend.js.utils.Namer +import org.jetbrains.kotlin.ir.backend.js.utils.getClassRef import org.jetbrains.kotlin.ir.declarations.IrClass import org.jetbrains.kotlin.ir.declarations.IrConstructor -import org.jetbrains.kotlin.ir.declarations.IrDeclarationWithName import org.jetbrains.kotlin.ir.declarations.IrSimpleFunction import org.jetbrains.kotlin.ir.expressions.IrCall import org.jetbrains.kotlin.ir.expressions.IrFunctionReference -import org.jetbrains.kotlin.ir.symbols.IrClassifierSymbol import org.jetbrains.kotlin.ir.symbols.IrSimpleFunctionSymbol import org.jetbrains.kotlin.ir.symbols.IrSymbol -import org.jetbrains.kotlin.ir.types.classOrNull import org.jetbrains.kotlin.ir.types.classifierOrFail import org.jetbrains.kotlin.ir.util.getInlineClassBackingField -import org.jetbrains.kotlin.ir.util.isEffectivelyExternal import org.jetbrains.kotlin.ir.util.render import org.jetbrains.kotlin.js.backend.ast.* @@ -92,18 +89,8 @@ class JsIntrinsicTransformers(backendContext: JsIrBackendContext) { add(intrinsics.jsClass) { call, context -> val typeArgument = call.getTypeArgument(0) - val classSymbol = typeArgument?.classOrNull + typeArgument?.getClassRef(context) ?: error("Type argument of jsClass must be statically known class, but " + typeArgument?.render()) - - val klass = classSymbol.owner - - when { - klass.isEffectivelyExternal() -> - context.getRefForExternalClass(klass) - - else -> - context.getNameForStaticDeclaration(klass as IrDeclarationWithName).makeRef() - } } add(intrinsics.jsNewTarget) { _, _ -> @@ -124,16 +111,8 @@ class JsIntrinsicTransformers(backendContext: JsIrBackendContext) { } add(intrinsics.es6DefaultType) { call, context -> - val classifier: IrClassifierSymbol = call.getTypeArgument(0)!!.classifierOrFail - val owner = classifier.owner - - when { - owner is IrClass && owner.isEffectivelyExternal() -> - context.getRefForExternalClass(owner) - - else -> - context.getNameForStaticDeclaration(owner as IrDeclarationWithName).makeRef() - } + val typeArgument = call.getTypeArgument(0)!! + typeArgument.getClassRef(context) } addIfNotNull(intrinsics.jsCode) { _, _ -> error("Should not be called") } diff --git a/compiler/ir/backend.js/src/org/jetbrains/kotlin/ir/backend/js/utils/IrTypeUtils.kt b/compiler/ir/backend.js/src/org/jetbrains/kotlin/ir/backend/js/utils/IrTypeUtils.kt index 04dab5665ce..fe23c23939f 100644 --- a/compiler/ir/backend.js/src/org/jetbrains/kotlin/ir/backend/js/utils/IrTypeUtils.kt +++ b/compiler/ir/backend.js/src/org/jetbrains/kotlin/ir/backend/js/utils/IrTypeUtils.kt @@ -6,6 +6,7 @@ package org.jetbrains.kotlin.ir.backend.js.utils import org.jetbrains.kotlin.ir.declarations.IrClass +import org.jetbrains.kotlin.ir.declarations.IrDeclarationWithName import org.jetbrains.kotlin.ir.symbols.IrClassSymbol import org.jetbrains.kotlin.ir.symbols.IrClassifierSymbol import org.jetbrains.kotlin.ir.symbols.IrScriptSymbol @@ -13,10 +14,12 @@ import org.jetbrains.kotlin.ir.symbols.IrTypeParameterSymbol import org.jetbrains.kotlin.ir.types.* import org.jetbrains.kotlin.ir.util.fqNameWhenAvailable import org.jetbrains.kotlin.ir.util.getInlineClassUnderlyingType +import org.jetbrains.kotlin.ir.util.isEffectivelyExternal +import org.jetbrains.kotlin.js.backend.ast.JsNameRef import org.jetbrains.kotlin.types.Variance import org.jetbrains.kotlin.utils.addToStdlib.ifNotEmpty -fun IrType.asString(): String = when(this) { +fun IrType.asString(): String = when (this) { // TODO: should each IrErrorType have own string representation? is IrErrorType -> "\$ErrorType\$" // TODO: should we prohibit user classes called dynamic? @@ -30,7 +33,7 @@ fun IrType.asString(): String = when(this) { else -> error("Unexpected kind of IrType: " + javaClass.typeName) } -private fun IrTypeArgument.asString(): String = when(this) { +private fun IrTypeArgument.asString(): String = when (this) { is IrStarProjection -> "*" is IrTypeProjection -> variance.label + (if (variance != Variance.INVARIANT) " " else "") + type.asString() else -> error("Unexpected kind of IrTypeArgument: " + javaClass.simpleName) @@ -78,3 +81,14 @@ tailrec fun erase(type: IrType): IrClass? { else -> error(classifier) } } + +fun IrType.getClassRef(context: JsGenerationContext): JsNameRef = + when (val klass = classifierOrFail.owner) { + is IrClass -> + if (klass.isEffectivelyExternal()) + context.getRefForExternalClass(klass) + else + context.getNameForClass(klass).makeRef() + + else -> context.getNameForStaticDeclaration(klass as IrDeclarationWithName).makeRef() + } \ No newline at end of file diff --git a/compiler/testData/codegen/box/innerNested/extenderNestedClass.kt b/compiler/testData/codegen/box/innerNested/extenderNestedClass.kt new file mode 100644 index 00000000000..b2cb4de6ae0 --- /dev/null +++ b/compiler/testData/codegen/box/innerNested/extenderNestedClass.kt @@ -0,0 +1,9 @@ +object Foo { + open class Bar(val bar: String) +} + +class Baz: Foo.Bar("OK") + +fun box(): String { + return Baz().bar +} diff --git a/compiler/tests-common-new/tests-gen/org/jetbrains/kotlin/test/runners/codegen/BlackBoxCodegenTestGenerated.java b/compiler/tests-common-new/tests-gen/org/jetbrains/kotlin/test/runners/codegen/BlackBoxCodegenTestGenerated.java index eaca48c4d5f..e648586b4c0 100644 --- a/compiler/tests-common-new/tests-gen/org/jetbrains/kotlin/test/runners/codegen/BlackBoxCodegenTestGenerated.java +++ b/compiler/tests-common-new/tests-gen/org/jetbrains/kotlin/test/runners/codegen/BlackBoxCodegenTestGenerated.java @@ -19512,6 +19512,12 @@ public class BlackBoxCodegenTestGenerated extends AbstractBlackBoxCodegenTest { runTest("compiler/testData/codegen/box/innerNested/createdNestedInOuterMember.kt"); } + @Test + @TestMetadata("extenderNestedClass.kt") + public void testExtenderNestedClass() throws Exception { + runTest("compiler/testData/codegen/box/innerNested/extenderNestedClass.kt"); + } + @Test @TestMetadata("extensionFun.kt") public void testExtensionFun() throws Exception { diff --git a/compiler/tests-common-new/tests-gen/org/jetbrains/kotlin/test/runners/codegen/IrBlackBoxCodegenTestGenerated.java b/compiler/tests-common-new/tests-gen/org/jetbrains/kotlin/test/runners/codegen/IrBlackBoxCodegenTestGenerated.java index fdda20756f3..04ff891eab6 100644 --- a/compiler/tests-common-new/tests-gen/org/jetbrains/kotlin/test/runners/codegen/IrBlackBoxCodegenTestGenerated.java +++ b/compiler/tests-common-new/tests-gen/org/jetbrains/kotlin/test/runners/codegen/IrBlackBoxCodegenTestGenerated.java @@ -19512,6 +19512,12 @@ public class IrBlackBoxCodegenTestGenerated extends AbstractIrBlackBoxCodegenTes runTest("compiler/testData/codegen/box/innerNested/createdNestedInOuterMember.kt"); } + @Test + @TestMetadata("extenderNestedClass.kt") + public void testExtenderNestedClass() throws Exception { + runTest("compiler/testData/codegen/box/innerNested/extenderNestedClass.kt"); + } + @Test @TestMetadata("extensionFun.kt") public void testExtensionFun() throws Exception { diff --git a/compiler/tests-gen/org/jetbrains/kotlin/codegen/LightAnalysisModeTestGenerated.java b/compiler/tests-gen/org/jetbrains/kotlin/codegen/LightAnalysisModeTestGenerated.java index 9ebf2b24ca0..fd8c712c63a 100644 --- a/compiler/tests-gen/org/jetbrains/kotlin/codegen/LightAnalysisModeTestGenerated.java +++ b/compiler/tests-gen/org/jetbrains/kotlin/codegen/LightAnalysisModeTestGenerated.java @@ -16306,6 +16306,11 @@ public class LightAnalysisModeTestGenerated extends AbstractLightAnalysisModeTes runTest("compiler/testData/codegen/box/innerNested/createdNestedInOuterMember.kt"); } + @TestMetadata("extenderNestedClass.kt") + public void testExtenderNestedClass() throws Exception { + runTest("compiler/testData/codegen/box/innerNested/extenderNestedClass.kt"); + } + @TestMetadata("extensionFun.kt") public void testExtensionFun() throws Exception { runTest("compiler/testData/codegen/box/innerNested/extensionFun.kt"); diff --git a/js/js.tests/tests-gen/org/jetbrains/kotlin/js/test/es6/semantics/IrJsCodegenBoxES6TestGenerated.java b/js/js.tests/tests-gen/org/jetbrains/kotlin/js/test/es6/semantics/IrJsCodegenBoxES6TestGenerated.java index 125c7dea68e..648e4ca8177 100644 --- a/js/js.tests/tests-gen/org/jetbrains/kotlin/js/test/es6/semantics/IrJsCodegenBoxES6TestGenerated.java +++ b/js/js.tests/tests-gen/org/jetbrains/kotlin/js/test/es6/semantics/IrJsCodegenBoxES6TestGenerated.java @@ -14349,6 +14349,11 @@ public class IrJsCodegenBoxES6TestGenerated extends AbstractIrJsCodegenBoxES6Tes runTest("compiler/testData/codegen/box/innerNested/createdNestedInOuterMember.kt"); } + @TestMetadata("extenderNestedClass.kt") + public void testExtenderNestedClass() throws Exception { + runTest("compiler/testData/codegen/box/innerNested/extenderNestedClass.kt"); + } + @TestMetadata("extensionFun.kt") public void testExtensionFun() throws Exception { runTest("compiler/testData/codegen/box/innerNested/extensionFun.kt"); diff --git a/js/js.tests/tests-gen/org/jetbrains/kotlin/js/test/ir/semantics/IrJsCodegenBoxTestGenerated.java b/js/js.tests/tests-gen/org/jetbrains/kotlin/js/test/ir/semantics/IrJsCodegenBoxTestGenerated.java index 29381784b2f..13e8b6d6de1 100644 --- a/js/js.tests/tests-gen/org/jetbrains/kotlin/js/test/ir/semantics/IrJsCodegenBoxTestGenerated.java +++ b/js/js.tests/tests-gen/org/jetbrains/kotlin/js/test/ir/semantics/IrJsCodegenBoxTestGenerated.java @@ -13806,6 +13806,11 @@ public class IrJsCodegenBoxTestGenerated extends AbstractIrJsCodegenBoxTest { runTest("compiler/testData/codegen/box/innerNested/createdNestedInOuterMember.kt"); } + @TestMetadata("extenderNestedClass.kt") + public void testExtenderNestedClass() throws Exception { + runTest("compiler/testData/codegen/box/innerNested/extenderNestedClass.kt"); + } + @TestMetadata("extensionFun.kt") public void testExtensionFun() throws Exception { runTest("compiler/testData/codegen/box/innerNested/extensionFun.kt"); diff --git a/js/js.tests/tests-gen/org/jetbrains/kotlin/js/test/semantics/JsCodegenBoxTestGenerated.java b/js/js.tests/tests-gen/org/jetbrains/kotlin/js/test/semantics/JsCodegenBoxTestGenerated.java index bb308cc290b..4da07532996 100644 --- a/js/js.tests/tests-gen/org/jetbrains/kotlin/js/test/semantics/JsCodegenBoxTestGenerated.java +++ b/js/js.tests/tests-gen/org/jetbrains/kotlin/js/test/semantics/JsCodegenBoxTestGenerated.java @@ -13871,6 +13871,11 @@ public class JsCodegenBoxTestGenerated extends AbstractJsCodegenBoxTest { runTest("compiler/testData/codegen/box/innerNested/createdNestedInOuterMember.kt"); } + @TestMetadata("extenderNestedClass.kt") + public void testExtenderNestedClass() throws Exception { + runTest("compiler/testData/codegen/box/innerNested/extenderNestedClass.kt"); + } + @TestMetadata("extensionFun.kt") public void testExtensionFun() throws Exception { runTest("compiler/testData/codegen/box/innerNested/extensionFun.kt"); diff --git a/js/js.tests/tests-gen/org/jetbrains/kotlin/js/test/wasm/semantics/IrCodegenBoxWasmTestGenerated.java b/js/js.tests/tests-gen/org/jetbrains/kotlin/js/test/wasm/semantics/IrCodegenBoxWasmTestGenerated.java index 0226cca6407..18605827157 100644 --- a/js/js.tests/tests-gen/org/jetbrains/kotlin/js/test/wasm/semantics/IrCodegenBoxWasmTestGenerated.java +++ b/js/js.tests/tests-gen/org/jetbrains/kotlin/js/test/wasm/semantics/IrCodegenBoxWasmTestGenerated.java @@ -7927,6 +7927,11 @@ public class IrCodegenBoxWasmTestGenerated extends AbstractIrCodegenBoxWasmTest runTest("compiler/testData/codegen/box/innerNested/createdNestedInOuterMember.kt"); } + @TestMetadata("extenderNestedClass.kt") + public void testExtenderNestedClass() throws Exception { + runTest("compiler/testData/codegen/box/innerNested/extenderNestedClass.kt"); + } + @TestMetadata("extensionFun.kt") public void testExtensionFun() throws Exception { runTest("compiler/testData/codegen/box/innerNested/extensionFun.kt");