[JS IR] Fix creating of classes extended from nested one
[JS IR] Extract getClassRef method ^KT-44950 fixed
This commit is contained in:
committed by
TeamCityServer
parent
a61312120b
commit
88abb3d6c9
+6
@@ -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 {
|
||||
|
||||
+4
-6
@@ -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()
|
||||
|
||||
+4
-25
@@ -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") }
|
||||
|
||||
@@ -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()
|
||||
}
|
||||
@@ -0,0 +1,9 @@
|
||||
object Foo {
|
||||
open class Bar(val bar: String)
|
||||
}
|
||||
|
||||
class Baz: Foo.Bar("OK")
|
||||
|
||||
fun box(): String {
|
||||
return Baz().bar
|
||||
}
|
||||
+6
@@ -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 {
|
||||
|
||||
+6
@@ -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 {
|
||||
|
||||
+5
@@ -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");
|
||||
|
||||
js/js.tests/tests-gen/org/jetbrains/kotlin/js/test/es6/semantics/IrJsCodegenBoxES6TestGenerated.java
Generated
+5
@@ -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");
|
||||
|
||||
Generated
+5
@@ -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");
|
||||
|
||||
Generated
+5
@@ -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");
|
||||
|
||||
js/js.tests/tests-gen/org/jetbrains/kotlin/js/test/wasm/semantics/IrCodegenBoxWasmTestGenerated.java
Generated
+5
@@ -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");
|
||||
|
||||
Reference in New Issue
Block a user