Implementation of super methods calling (#203)

* implemented super call

* tests

* removed redundant code
This commit is contained in:
Igor Chevdar
2017-01-27 16:38:48 +05:00
committed by GitHub
parent 36c90ac47d
commit 01cb9d4cac
6 changed files with 98 additions and 7 deletions
@@ -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
}
@@ -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)
}
//-------------------------------------------------------------------------//
+15
View File
@@ -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)
}