krzema12 / kotlin-python

Python target for the Kotlin Programming Language. See https://github.com/krzema12/kotlin-python/tree/python-backend/python
https://discuss.kotlinlang.org/t/idea-python-backend/19852
48 stars 1 forks source link

Improvements around constructors #37

Closed krzema12 closed 2 years ago

krzema12 commented 2 years ago

This PR tries to solve the problem described in this doc: https://github.com/krzema12/kotlin-python/wiki/Notes-on-getting-rid-of-%22NameError:-name-'Object_create'-is-not-defined%22

Regressions:

org.jetbrains.kotlin.python.test.ir.semantics.IrPythonCodegenBoxTestGenerated$Classes > testSelfcreate
org.jetbrains.kotlin.python.test.ir.semantics.IrPythonCodegenBoxTestGenerated$Classes$Inner > testProperOuter
org.jetbrains.kotlin.python.test.ir.semantics.IrPythonCodegenBoxTestGenerated$Closures$CaptureInSuperConstructorCall > testKt4174
org.jetbrains.kotlin.python.test.ir.semantics.IrPythonCodegenBoxTestGenerated$Closures$CaptureInSuperConstructorCall > testOuterAndLocalCapturedInLocalClass
org.jetbrains.kotlin.python.test.ir.semantics.IrPythonCodegenBoxTestGenerated$Closures$CaptureInSuperConstructorCall > testOuterEnumEntryCapturedInLambdaInInnerClass
org.jetbrains.kotlin.python.test.ir.semantics.IrPythonCodegenBoxTestGenerated$Closures$CaptureInSuperConstructorCall > testProperValueCapturedByClosure1
org.jetbrains.kotlin.python.test.ir.semantics.IrPythonCodegenInlineTestGenerated$AnonymousObject > testSuperConstructorWithObjectParameter
org.jetbrains.kotlin.python.test.ir.semantics.IrPythonCodegenInlineTestGenerated$Enum > testValueOf
org.jetbrains.kotlin.python.test.ir.semantics.IrPythonCodegenInlineTestGenerated$Enum > testValueOfCapturedType
org.jetbrains.kotlin.python.test.ir.semantics.IrPythonCodegenInlineTestGenerated$Enum > testValueOfChain
org.jetbrains.kotlin.python.test.ir.semantics.IrPythonCodegenInlineTestGenerated$Enum > testValueOfChainCapturedType

org.jetbrains.kotlin.python.test.ir.semantics.IrPythonCodegenBoxTestGenerated$Classes > testSelfcreate

Calling base class constructor inside the primary constructor got broken. To fix it, one has to check in which context the constructor is called, and create a relevant kind of call.

     def __init__(self, this_0):
         self.this_0 = this_0
-        A.__init__(self, this_0.b)
+        A(this_0.b)
SerVB commented 2 years ago

I'm testing with:

class MultiConstructors1(a: Int) {

    init {
        val s = "body 1"
    }

    constructor(b: String) : this(2) {
        val s = "body 2"
    }
}

class MultiConstructors2 {

    constructor(a: Int) {
        val s = "body 3"
    }

    constructor(b: String) {
        val s = "body 4"
    }
}

But compilation now fails with:

exception: java.lang.ClassCastException: org.jetbrains.kotlin.ir.declarations.impl.IrVariableImpl cannot be cast to org.jetbrains.kotlin.ir.expressions.IrExpression
        at org.jetbrains.kotlin.ir.backend.py.lower.SecondaryConstructorLowering$generateInitBody$1.invoke(SecondaryCtorLowering.kt:124)
...

I suggest adding e2e test for constructors.