Implementation of super methods calling (#203)
* implemented super call * tests * removed redundant code
This commit is contained in:
+9
-3
@@ -5,6 +5,10 @@ import org.jetbrains.kotlin.backend.konan.llvm.functionName
|
||||
import org.jetbrains.kotlin.builtins.KotlinBuiltIns
|
||||
import org.jetbrains.kotlin.builtins.isFunctionType
|
||||
import org.jetbrains.kotlin.descriptors.*
|
||||
import org.jetbrains.kotlin.descriptors.annotations.Annotations
|
||||
import org.jetbrains.kotlin.descriptors.impl.PropertyDescriptorImpl
|
||||
import org.jetbrains.kotlin.descriptors.impl.PropertyGetterDescriptorImpl
|
||||
import org.jetbrains.kotlin.descriptors.impl.PropertySetterDescriptorImpl
|
||||
import org.jetbrains.kotlin.incremental.components.NoLookupLocation
|
||||
import org.jetbrains.kotlin.name.FqName
|
||||
import org.jetbrains.kotlin.name.Name
|
||||
@@ -12,6 +16,8 @@ import org.jetbrains.kotlin.resolve.OverridingUtil
|
||||
import org.jetbrains.kotlin.resolve.descriptorUtil.*
|
||||
import org.jetbrains.kotlin.resolve.scopes.MemberScope
|
||||
import org.jetbrains.kotlin.types.KotlinType
|
||||
import org.jetbrains.kotlin.types.TypeSubstitution
|
||||
import org.jetbrains.kotlin.types.TypeSubstitutor
|
||||
import org.jetbrains.kotlin.types.TypeUtils
|
||||
import org.jetbrains.kotlin.types.typeUtil.isUnit
|
||||
import org.jetbrains.kotlin.util.OperatorNameConventions
|
||||
@@ -152,7 +158,7 @@ internal val FunctionDescriptor.isFunctionInvoke: Boolean
|
||||
|
||||
internal fun ClassDescriptor.isUnit() = this.defaultType.isUnit()
|
||||
|
||||
internal val ClassDescriptor.сontributedMethods: List<FunctionDescriptor>
|
||||
internal val ClassDescriptor.contributedMethods: List<FunctionDescriptor>
|
||||
get() {
|
||||
val contributedDescriptors = unsubstitutedMemberScope.getContributedDescriptors()
|
||||
// (includes declarations from supers)
|
||||
@@ -184,7 +190,7 @@ val ClassDescriptor.vtableEntries: List<FunctionDescriptor>
|
||||
this.getSuperClassOrAny().vtableEntries
|
||||
}
|
||||
|
||||
val methods = this.сontributedMethods
|
||||
val methods = this.contributedMethods
|
||||
|
||||
val inheritedVtableSlots = superVtableEntries.map { superMethod ->
|
||||
methods.singleOrNull { OverridingUtil.overrides(it, superMethod) } ?: superMethod
|
||||
@@ -204,6 +210,6 @@ val ClassDescriptor.methodTableEntries: List<FunctionDescriptor>
|
||||
get() {
|
||||
assert (!this.isAbstract())
|
||||
|
||||
return this.сontributedMethods.filter { it.isOverridableOrOverrides }
|
||||
return this.contributedMethods.filter { it.isOverridableOrOverrides }
|
||||
// TODO: probably method table should contain all accessible methods to improve binary compatibility
|
||||
}
|
||||
+4
-4
@@ -1681,7 +1681,7 @@ internal class CodeGeneratorVisitor(val context: Context) : IrElementVisitorVoid
|
||||
when (descriptor) {
|
||||
is IrBuiltinOperatorDescriptorBase -> return evaluateOperatorCall (callee, args)
|
||||
is ConstructorDescriptor -> return evaluateConstructorCall (callee, args)
|
||||
else -> return evaluateSimpleFunctionCall(descriptor, args)
|
||||
else -> return evaluateSimpleFunctionCall(descriptor, args, callee.superQualifier)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1721,9 +1721,9 @@ internal class CodeGeneratorVisitor(val context: Context) : IrElementVisitorVoid
|
||||
|
||||
//-------------------------------------------------------------------------//
|
||||
|
||||
private fun evaluateSimpleFunctionCall(descriptor: FunctionDescriptor, args: List<LLVMValueRef>): LLVMValueRef {
|
||||
private fun evaluateSimpleFunctionCall(descriptor: FunctionDescriptor, args: List<LLVMValueRef>, superClass: ClassDescriptor? = null): LLVMValueRef {
|
||||
//context.log("evaluateSimpleFunctionCall : $tmpVariableName = ${ir2string(value)}")
|
||||
if (descriptor.isOverridable)
|
||||
if (descriptor.isOverridable && superClass == null)
|
||||
return callVirtual(descriptor, args)
|
||||
else
|
||||
return callDirect(descriptor, args)
|
||||
@@ -1737,7 +1737,7 @@ internal class CodeGeneratorVisitor(val context: Context) : IrElementVisitorVoid
|
||||
if (descriptor.dispatchReceiverParameter != null)
|
||||
args.add(evaluateExpression(value.dispatchReceiver!!)) //add this ptr
|
||||
args.add(evaluateExpression(value.getValueArgument(0)!!))
|
||||
return evaluateSimpleFunctionCall(descriptor, args)
|
||||
return evaluateSimpleFunctionCall(descriptor, args, value.superQualifier)
|
||||
}
|
||||
|
||||
//-------------------------------------------------------------------------//
|
||||
|
||||
@@ -292,6 +292,21 @@ task empty_substring(type: RunKonanTest) {
|
||||
source = "runtime/basic/empty_substring.kt"
|
||||
}
|
||||
|
||||
task superFunCall(type: RunKonanTest) {
|
||||
goldValue = "<fun:C><fun:C1>\n<fun:C><fun:C3>\n"
|
||||
source = "codegen/basics/superFunCall.kt"
|
||||
}
|
||||
|
||||
task superGetterCall(type: RunKonanTest) {
|
||||
goldValue = "<prop:C><prop:C1>\n<prop:C><prop:C3>\n"
|
||||
source = "codegen/basics/superGetterCall.kt"
|
||||
}
|
||||
|
||||
task superSetterCall(type: RunKonanTest) {
|
||||
goldValue = "<prop:C1><prop:C>zzz\n<prop:C3><prop:C>zzz\n"
|
||||
source = "codegen/basics/superSetterCall.kt"
|
||||
}
|
||||
|
||||
task enum0(type: RunKonanTest) {
|
||||
goldValue = "VALUE\n"
|
||||
source = "codegen/enum/test0.kt"
|
||||
|
||||
@@ -0,0 +1,19 @@
|
||||
open class C {
|
||||
open fun f() = "<fun:C>"
|
||||
}
|
||||
|
||||
class C1: C() {
|
||||
override fun f() = super<C>.f() + "<fun:C1>"
|
||||
}
|
||||
|
||||
open class C2: C() {
|
||||
}
|
||||
|
||||
class C3: C2() {
|
||||
override fun f() = super<C2>.f() + "<fun:C3>"
|
||||
}
|
||||
|
||||
fun main(args: Array<String>) {
|
||||
println(C1().f())
|
||||
println(C3().f())
|
||||
}
|
||||
@@ -0,0 +1,19 @@
|
||||
open class C {
|
||||
open val p1 = "<prop:C>"
|
||||
}
|
||||
|
||||
class C1: C() {
|
||||
override val p1 = super<C>.p1 + "<prop:C1>"
|
||||
}
|
||||
|
||||
open class C2: C() {
|
||||
}
|
||||
|
||||
class C3: C2() {
|
||||
override val p1 = super<C2>.p1 + "<prop:C3>"
|
||||
}
|
||||
|
||||
fun main(args: Array<String>) {
|
||||
println(C1().p1)
|
||||
println(C3().p1)
|
||||
}
|
||||
@@ -0,0 +1,32 @@
|
||||
open class C {
|
||||
open var p2 = "<prop:C>"
|
||||
set(value) { field = "<prop:C>" + value }
|
||||
}
|
||||
|
||||
class C1: C() {
|
||||
override var p2 = super<C>.p2 + "<prop:C1>"
|
||||
set(value) {
|
||||
super<C>.p2 = value
|
||||
field = "<prop:C1>" + super<C>.p2
|
||||
}
|
||||
}
|
||||
|
||||
open class C2: C() {
|
||||
}
|
||||
|
||||
class C3: C2() {
|
||||
override var p2 = super<C2>.p2 + "<prop:C3>"
|
||||
set(value) {
|
||||
super<C2>.p2 = value
|
||||
field = "<prop:C3>" + super<C2>.p2
|
||||
}
|
||||
}
|
||||
|
||||
fun main(args: Array<String>) {
|
||||
val c1 = C1()
|
||||
val c3 = C3()
|
||||
c1.p2 = "zzz"
|
||||
c3.p2 = "zzz"
|
||||
println(c1.p2)
|
||||
println(c3.p2)
|
||||
}
|
||||
Reference in New Issue
Block a user