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.KotlinBuiltIns
|
||||||
import org.jetbrains.kotlin.builtins.isFunctionType
|
import org.jetbrains.kotlin.builtins.isFunctionType
|
||||||
import org.jetbrains.kotlin.descriptors.*
|
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.incremental.components.NoLookupLocation
|
||||||
import org.jetbrains.kotlin.name.FqName
|
import org.jetbrains.kotlin.name.FqName
|
||||||
import org.jetbrains.kotlin.name.Name
|
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.descriptorUtil.*
|
||||||
import org.jetbrains.kotlin.resolve.scopes.MemberScope
|
import org.jetbrains.kotlin.resolve.scopes.MemberScope
|
||||||
import org.jetbrains.kotlin.types.KotlinType
|
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.TypeUtils
|
||||||
import org.jetbrains.kotlin.types.typeUtil.isUnit
|
import org.jetbrains.kotlin.types.typeUtil.isUnit
|
||||||
import org.jetbrains.kotlin.util.OperatorNameConventions
|
import org.jetbrains.kotlin.util.OperatorNameConventions
|
||||||
@@ -152,7 +158,7 @@ internal val FunctionDescriptor.isFunctionInvoke: Boolean
|
|||||||
|
|
||||||
internal fun ClassDescriptor.isUnit() = this.defaultType.isUnit()
|
internal fun ClassDescriptor.isUnit() = this.defaultType.isUnit()
|
||||||
|
|
||||||
internal val ClassDescriptor.сontributedMethods: List<FunctionDescriptor>
|
internal val ClassDescriptor.contributedMethods: List<FunctionDescriptor>
|
||||||
get() {
|
get() {
|
||||||
val contributedDescriptors = unsubstitutedMemberScope.getContributedDescriptors()
|
val contributedDescriptors = unsubstitutedMemberScope.getContributedDescriptors()
|
||||||
// (includes declarations from supers)
|
// (includes declarations from supers)
|
||||||
@@ -184,7 +190,7 @@ val ClassDescriptor.vtableEntries: List<FunctionDescriptor>
|
|||||||
this.getSuperClassOrAny().vtableEntries
|
this.getSuperClassOrAny().vtableEntries
|
||||||
}
|
}
|
||||||
|
|
||||||
val methods = this.сontributedMethods
|
val methods = this.contributedMethods
|
||||||
|
|
||||||
val inheritedVtableSlots = superVtableEntries.map { superMethod ->
|
val inheritedVtableSlots = superVtableEntries.map { superMethod ->
|
||||||
methods.singleOrNull { OverridingUtil.overrides(it, superMethod) } ?: superMethod
|
methods.singleOrNull { OverridingUtil.overrides(it, superMethod) } ?: superMethod
|
||||||
@@ -204,6 +210,6 @@ val ClassDescriptor.methodTableEntries: List<FunctionDescriptor>
|
|||||||
get() {
|
get() {
|
||||||
assert (!this.isAbstract())
|
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
|
// 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) {
|
when (descriptor) {
|
||||||
is IrBuiltinOperatorDescriptorBase -> return evaluateOperatorCall (callee, args)
|
is IrBuiltinOperatorDescriptorBase -> return evaluateOperatorCall (callee, args)
|
||||||
is ConstructorDescriptor -> return evaluateConstructorCall (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)}")
|
//context.log("evaluateSimpleFunctionCall : $tmpVariableName = ${ir2string(value)}")
|
||||||
if (descriptor.isOverridable)
|
if (descriptor.isOverridable && superClass == null)
|
||||||
return callVirtual(descriptor, args)
|
return callVirtual(descriptor, args)
|
||||||
else
|
else
|
||||||
return callDirect(descriptor, args)
|
return callDirect(descriptor, args)
|
||||||
@@ -1737,7 +1737,7 @@ internal class CodeGeneratorVisitor(val context: Context) : IrElementVisitorVoid
|
|||||||
if (descriptor.dispatchReceiverParameter != null)
|
if (descriptor.dispatchReceiverParameter != null)
|
||||||
args.add(evaluateExpression(value.dispatchReceiver!!)) //add this ptr
|
args.add(evaluateExpression(value.dispatchReceiver!!)) //add this ptr
|
||||||
args.add(evaluateExpression(value.getValueArgument(0)!!))
|
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"
|
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) {
|
task enum0(type: RunKonanTest) {
|
||||||
goldValue = "VALUE\n"
|
goldValue = "VALUE\n"
|
||||||
source = "codegen/enum/test0.kt"
|
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