KT-5963 Call to super shouldn't require type specification if there is no conflict
Implemented unqualified 'super' type resolution (in BasicExpressionTypingVisitor). No overload resolution of any kind is involved. Corresponding supertype is determined by the expected member name only: - 'super.foo(...)' - function or property (of possibly callable type) 'foo' - 'super.x' - property 'x' Supertype should provide a non-abstract implementation of such member. As a fall-back solution for diagnostics purposes, consider supertypes with abstract implementation of such member. Diagnostics: - AMBIGUOUS_SUPER on 'super', if multiple possible supertypes are available; - ABSTRACT_SUPER_CALL on selector expression, if the only available implementation is abstract. #KT-5963 Fixed
This commit is contained in:
@@ -0,0 +1,66 @@
|
||||
open class Base() {
|
||||
open fun baseFun(): String = "Base.baseFun()"
|
||||
|
||||
open fun unambiguous(): String = "Base.unambiguous()"
|
||||
|
||||
open val baseProp: String
|
||||
get() = "Base.baseProp"
|
||||
}
|
||||
|
||||
interface Interface {
|
||||
fun interfaceFun(): String = "Interface.interfaceFun()"
|
||||
|
||||
fun unambiguous(): String // NB abstract
|
||||
}
|
||||
|
||||
interface AnotherInterface
|
||||
|
||||
interface DerivedInterface: Interface, AnotherInterface {
|
||||
override fun interfaceFun(): String = "DerivedInterface.interfaceFun()"
|
||||
|
||||
override fun unambiguous(): String = "DerivedInterface.unambiguous()"
|
||||
|
||||
fun callsFunFromSuperInterface(): String = super.interfaceFun()
|
||||
}
|
||||
|
||||
class Derived : Base(), Interface {
|
||||
override fun baseFun(): String = "Derived.baseFun()"
|
||||
|
||||
override fun unambiguous(): String = "Derived.unambiguous()"
|
||||
|
||||
override fun interfaceFun(): String = "Derived.interfaceFun()"
|
||||
|
||||
override val baseProp: String
|
||||
get() = "Derived.baseProp"
|
||||
|
||||
fun callsBaseFun(): String = super.baseFun()
|
||||
|
||||
fun callsUnambiguousFun(): String = super.unambiguous()
|
||||
|
||||
fun getsBaseProp(): String = super.baseProp
|
||||
|
||||
fun callsInterfaceFun(): String = super.interfaceFun()
|
||||
}
|
||||
|
||||
fun box(): String {
|
||||
val d = Derived()
|
||||
|
||||
val test1 = d.callsBaseFun()
|
||||
if (test1 != "Base.baseFun()") return "Failed: d.callsBaseFun()==$test1"
|
||||
|
||||
val test2 = d.callsUnambiguousFun()
|
||||
if (test2 != "Base.unambiguous()") return "Failed: d.callsUnambiguousFun()==$test2"
|
||||
|
||||
val test3 = d.getsBaseProp()
|
||||
if (test3 != "Base.baseProp") return "Failed: d.getsBaseProp()==$test3"
|
||||
|
||||
val test4 = d.callsInterfaceFun()
|
||||
if (test4 != "Interface.interfaceFun()") return "Failed: d.callsInterfaceFun()==$test4"
|
||||
|
||||
val di = object : DerivedInterface {}
|
||||
|
||||
val test5 = di.callsFunFromSuperInterface()
|
||||
if (test5 != "Interface.interfaceFun()") return "Failed: di.callsFunFromSuperInterface()==$test5"
|
||||
|
||||
return "OK"
|
||||
}
|
||||
@@ -0,0 +1,63 @@
|
||||
open class DeeperBase {
|
||||
open fun deeperBaseFun(): String = "DeeperBase.deeperBaseFun()"
|
||||
|
||||
open val deeperBaseProp: String
|
||||
get() = "DeeperBase.deeperBaseProp"
|
||||
}
|
||||
|
||||
open class DeepBase : DeeperBase() {
|
||||
}
|
||||
|
||||
interface DeeperInterface {
|
||||
fun deeperInterfaceFun(): String = "DeeperInterface.deeperInterfaceFun()"
|
||||
|
||||
val deeperInterfaceProp: String
|
||||
get() = "DeeperInterface.deeperInterfaceProp"
|
||||
}
|
||||
|
||||
interface DeepInterface : DeeperInterface {
|
||||
fun deepInterfaceFun(): String = "DeepInterface.deepInterfaceFun()"
|
||||
}
|
||||
|
||||
class DeepDerived : DeepBase(), DeepInterface {
|
||||
override fun deeperBaseFun(): String = "DeepDerived.deeperBaseFun()"
|
||||
|
||||
override val deeperBaseProp: String
|
||||
get() = "DeepDerived.deeperBaseProp"
|
||||
|
||||
override fun deeperInterfaceFun(): String = "DeepDerived.deeperInterfaceFun()"
|
||||
|
||||
override val deeperInterfaceProp: String
|
||||
get() = "DeepDerived.deeperInterfaceProp"
|
||||
|
||||
override fun deepInterfaceFun(): String = "DeepDerived.deepInterfaceFun()"
|
||||
|
||||
fun callsSuperDeeperBaseFun(): String = super.deeperBaseFun()
|
||||
|
||||
fun getsSuperDeeperBaseProp(): String = super.deeperBaseProp
|
||||
|
||||
fun callsSuperDeepInterfaceFun(): String = super.deepInterfaceFun()
|
||||
fun callsSuperDeeperInterfaceFun(): String = super.deeperInterfaceFun()
|
||||
fun getsSuperDeeperInterfaceProp(): String = super.deeperInterfaceProp
|
||||
}
|
||||
|
||||
fun box(): String {
|
||||
val dd = DeepDerived()
|
||||
|
||||
val test1 = dd.callsSuperDeeperBaseFun()
|
||||
if (test1 != "DeeperBase.deeperBaseFun()") return "Failed: dd.callsSuperDeeperBaseFun()==$test1"
|
||||
|
||||
val test2 = dd.getsSuperDeeperBaseProp()
|
||||
if (test2 != "DeeperBase.deeperBaseProp") return "Failed: dd.getsSuperDeeperBaseProp()==$test2"
|
||||
|
||||
val test3 = dd.callsSuperDeepInterfaceFun()
|
||||
if (test3 != "DeepInterface.deepInterfaceFun()") return "Failed: dd.callsSuperDeepInterfaceFun()==$test3"
|
||||
|
||||
val test4 = dd.callsSuperDeeperInterfaceFun()
|
||||
if (test4 != "DeeperInterface.deeperInterfaceFun()") return "Failed: dd.callsSuperDeeperInterfaceFun()==$test4"
|
||||
|
||||
val test5 = dd.getsSuperDeeperInterfaceProp()
|
||||
if (test5 != "DeeperInterface.deeperInterfaceProp") return "Failed: dd.getsSuperDeeperInterfaceProp()==$test5"
|
||||
|
||||
return "OK"
|
||||
}
|
||||
@@ -0,0 +1,30 @@
|
||||
interface Interface {
|
||||
fun foo(x: Int): Int
|
||||
}
|
||||
|
||||
fun withLocalClasses(param: Int): Interface {
|
||||
open class LocalBase {
|
||||
open val param: Int
|
||||
get() = 100
|
||||
}
|
||||
|
||||
interface LocalInterface : Interface {
|
||||
override fun foo(x: Int): Int =
|
||||
x + param
|
||||
}
|
||||
|
||||
return object : LocalBase(), LocalInterface {
|
||||
override fun foo(x: Int): Int =
|
||||
x + super.param
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
fun box(): String {
|
||||
val t = withLocalClasses(1)
|
||||
|
||||
val test1 = t.foo(10)
|
||||
if (test1 != 110) return "Fail: t.foo(10)==$test1"
|
||||
|
||||
return "OK"
|
||||
}
|
||||
Reference in New Issue
Block a user