[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");
|
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
|
@Test
|
||||||
@TestMetadata("extensionFun.kt")
|
@TestMetadata("extensionFun.kt")
|
||||||
public void testExtensionFun() throws Exception {
|
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 classNameRef = className.makeRef()
|
||||||
private val baseClass: IrType? = irClass.superTypes.firstOrNull { !it.classifierOrFail.isInterface }
|
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
|
private val baseClassRef by lazy { // Lazy in case was not collected by namer during JsClassGenerator construction
|
||||||
baseClass?.let {
|
baseClass?.getClassRef(context)
|
||||||
context.getNameForClass(baseClass.classifierOrFail.owner as IrClass)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
private val classPrototypeRef = prototypeOf(classNameRef)
|
private val classPrototypeRef = prototypeOf(classNameRef)
|
||||||
private val classBlock = JsGlobalBlock()
|
private val classBlock = JsGlobalBlock()
|
||||||
@@ -49,7 +47,7 @@ class JsClassGenerator(private val irClass: IrClass, val context: JsGenerationCo
|
|||||||
val jsClass = JsClass(name = className)
|
val jsClass = JsClass(name = className)
|
||||||
|
|
||||||
if (baseClass != null && !baseClass.isAny()) {
|
if (baseClass != null && !baseClass.isAny()) {
|
||||||
jsClass.baseClass = baseClassName?.makeRef()
|
jsClass.baseClass = baseClassRef
|
||||||
}
|
}
|
||||||
|
|
||||||
if (es6mode) classModel.preDeclarationBlock.statements += jsClass.makeStmt()
|
if (es6mode) classModel.preDeclarationBlock.statements += jsClass.makeStmt()
|
||||||
@@ -197,7 +195,7 @@ class JsClassGenerator(private val irClass: IrClass, val context: JsGenerationCo
|
|||||||
}
|
}
|
||||||
|
|
||||||
val createCall = jsAssignment(
|
val createCall = jsAssignment(
|
||||||
classPrototypeRef, JsInvocation(Namer.JS_OBJECT_CREATE_FUNCTION, prototypeOf(baseClassName!!.makeRef()))
|
classPrototypeRef, JsInvocation(Namer.JS_OBJECT_CREATE_FUNCTION, prototypeOf(baseClassRef!!))
|
||||||
).makeStmt()
|
).makeStmt()
|
||||||
|
|
||||||
val ctorAssign = jsAssignment(JsNameRef(Namer.CONSTRUCTOR_NAME, classPrototypeRef), classNameRef).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.JsIrBackendContext
|
||||||
import org.jetbrains.kotlin.ir.backend.js.utils.JsGenerationContext
|
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.Namer
|
||||||
|
import org.jetbrains.kotlin.ir.backend.js.utils.getClassRef
|
||||||
import org.jetbrains.kotlin.ir.declarations.IrClass
|
import org.jetbrains.kotlin.ir.declarations.IrClass
|
||||||
import org.jetbrains.kotlin.ir.declarations.IrConstructor
|
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.declarations.IrSimpleFunction
|
||||||
import org.jetbrains.kotlin.ir.expressions.IrCall
|
import org.jetbrains.kotlin.ir.expressions.IrCall
|
||||||
import org.jetbrains.kotlin.ir.expressions.IrFunctionReference
|
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.IrSimpleFunctionSymbol
|
||||||
import org.jetbrains.kotlin.ir.symbols.IrSymbol
|
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.types.classifierOrFail
|
||||||
import org.jetbrains.kotlin.ir.util.getInlineClassBackingField
|
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.ir.util.render
|
||||||
import org.jetbrains.kotlin.js.backend.ast.*
|
import org.jetbrains.kotlin.js.backend.ast.*
|
||||||
|
|
||||||
@@ -92,18 +89,8 @@ class JsIntrinsicTransformers(backendContext: JsIrBackendContext) {
|
|||||||
|
|
||||||
add(intrinsics.jsClass) { call, context ->
|
add(intrinsics.jsClass) { call, context ->
|
||||||
val typeArgument = call.getTypeArgument(0)
|
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())
|
?: 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) { _, _ ->
|
add(intrinsics.jsNewTarget) { _, _ ->
|
||||||
@@ -124,16 +111,8 @@ class JsIntrinsicTransformers(backendContext: JsIrBackendContext) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
add(intrinsics.es6DefaultType) { call, context ->
|
add(intrinsics.es6DefaultType) { call, context ->
|
||||||
val classifier: IrClassifierSymbol = call.getTypeArgument(0)!!.classifierOrFail
|
val typeArgument = call.getTypeArgument(0)!!
|
||||||
val owner = classifier.owner
|
typeArgument.getClassRef(context)
|
||||||
|
|
||||||
when {
|
|
||||||
owner is IrClass && owner.isEffectivelyExternal() ->
|
|
||||||
context.getRefForExternalClass(owner)
|
|
||||||
|
|
||||||
else ->
|
|
||||||
context.getNameForStaticDeclaration(owner as IrDeclarationWithName).makeRef()
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
addIfNotNull(intrinsics.jsCode) { _, _ -> error("Should not be called") }
|
addIfNotNull(intrinsics.jsCode) { _, _ -> error("Should not be called") }
|
||||||
|
|||||||
@@ -6,6 +6,7 @@
|
|||||||
package org.jetbrains.kotlin.ir.backend.js.utils
|
package org.jetbrains.kotlin.ir.backend.js.utils
|
||||||
|
|
||||||
import org.jetbrains.kotlin.ir.declarations.IrClass
|
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.IrClassSymbol
|
||||||
import org.jetbrains.kotlin.ir.symbols.IrClassifierSymbol
|
import org.jetbrains.kotlin.ir.symbols.IrClassifierSymbol
|
||||||
import org.jetbrains.kotlin.ir.symbols.IrScriptSymbol
|
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.types.*
|
||||||
import org.jetbrains.kotlin.ir.util.fqNameWhenAvailable
|
import org.jetbrains.kotlin.ir.util.fqNameWhenAvailable
|
||||||
import org.jetbrains.kotlin.ir.util.getInlineClassUnderlyingType
|
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.types.Variance
|
||||||
import org.jetbrains.kotlin.utils.addToStdlib.ifNotEmpty
|
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?
|
// TODO: should each IrErrorType have own string representation?
|
||||||
is IrErrorType -> "\$ErrorType\$"
|
is IrErrorType -> "\$ErrorType\$"
|
||||||
// TODO: should we prohibit user classes called dynamic?
|
// 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)
|
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 IrStarProjection -> "*"
|
||||||
is IrTypeProjection -> variance.label + (if (variance != Variance.INVARIANT) " " else "") + type.asString()
|
is IrTypeProjection -> variance.label + (if (variance != Variance.INVARIANT) " " else "") + type.asString()
|
||||||
else -> error("Unexpected kind of IrTypeArgument: " + javaClass.simpleName)
|
else -> error("Unexpected kind of IrTypeArgument: " + javaClass.simpleName)
|
||||||
@@ -78,3 +81,14 @@ tailrec fun erase(type: IrType): IrClass? {
|
|||||||
else -> error(classifier)
|
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");
|
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
|
@Test
|
||||||
@TestMetadata("extensionFun.kt")
|
@TestMetadata("extensionFun.kt")
|
||||||
public void testExtensionFun() throws Exception {
|
public void testExtensionFun() throws Exception {
|
||||||
|
|||||||
+6
@@ -19512,6 +19512,12 @@ public class IrBlackBoxCodegenTestGenerated extends AbstractIrBlackBoxCodegenTes
|
|||||||
runTest("compiler/testData/codegen/box/innerNested/createdNestedInOuterMember.kt");
|
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
|
@Test
|
||||||
@TestMetadata("extensionFun.kt")
|
@TestMetadata("extensionFun.kt")
|
||||||
public void testExtensionFun() throws Exception {
|
public void testExtensionFun() throws Exception {
|
||||||
|
|||||||
+5
@@ -16306,6 +16306,11 @@ public class LightAnalysisModeTestGenerated extends AbstractLightAnalysisModeTes
|
|||||||
runTest("compiler/testData/codegen/box/innerNested/createdNestedInOuterMember.kt");
|
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")
|
@TestMetadata("extensionFun.kt")
|
||||||
public void testExtensionFun() throws Exception {
|
public void testExtensionFun() throws Exception {
|
||||||
runTest("compiler/testData/codegen/box/innerNested/extensionFun.kt");
|
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");
|
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")
|
@TestMetadata("extensionFun.kt")
|
||||||
public void testExtensionFun() throws Exception {
|
public void testExtensionFun() throws Exception {
|
||||||
runTest("compiler/testData/codegen/box/innerNested/extensionFun.kt");
|
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");
|
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")
|
@TestMetadata("extensionFun.kt")
|
||||||
public void testExtensionFun() throws Exception {
|
public void testExtensionFun() throws Exception {
|
||||||
runTest("compiler/testData/codegen/box/innerNested/extensionFun.kt");
|
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");
|
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")
|
@TestMetadata("extensionFun.kt")
|
||||||
public void testExtensionFun() throws Exception {
|
public void testExtensionFun() throws Exception {
|
||||||
runTest("compiler/testData/codegen/box/innerNested/extensionFun.kt");
|
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");
|
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")
|
@TestMetadata("extensionFun.kt")
|
||||||
public void testExtensionFun() throws Exception {
|
public void testExtensionFun() throws Exception {
|
||||||
runTest("compiler/testData/codegen/box/innerNested/extensionFun.kt");
|
runTest("compiler/testData/codegen/box/innerNested/extensionFun.kt");
|
||||||
|
|||||||
Reference in New Issue
Block a user