Refactor FunctionHandle::isInterfaceDeclaration
- Give it more clear name mayBeUsedAsSuperImplementation because defining if it can be used as super-implementation this is what it used for - The meaning is negated, so it's needed to negate its usages and impls - Also, reuse it in findSuperImplementationForStubDelegation
This commit is contained in:
@@ -27,7 +27,7 @@ interface FunctionHandle {
|
|||||||
* class ones (see [findConcreteSuperDeclaration] method in bridges.kt).
|
* class ones (see [findConcreteSuperDeclaration] method in bridges.kt).
|
||||||
* Note that interface methods with body compiled to jvm 8 target are assumed to be non-abstract in bridges method calculation
|
* Note that interface methods with body compiled to jvm 8 target are assumed to be non-abstract in bridges method calculation
|
||||||
* (more details in [DescriptorBasedFunctionHandle.isBodyOwner] comment).*/
|
* (more details in [DescriptorBasedFunctionHandle.isBodyOwner] comment).*/
|
||||||
val isInterfaceDeclaration: Boolean
|
val mayBeUsedAsSuperImplementation: Boolean
|
||||||
|
|
||||||
fun getOverridden(): Iterable<FunctionHandle>
|
fun getOverridden(): Iterable<FunctionHandle>
|
||||||
}
|
}
|
||||||
@@ -114,7 +114,7 @@ fun <Function : FunctionHandle> findConcreteSuperDeclaration(function: Function)
|
|||||||
}
|
}
|
||||||
result.removeAll(toRemove)
|
result.removeAll(toRemove)
|
||||||
|
|
||||||
val concreteRelevantDeclarations = result.filter { !it.isAbstract && !it.isInterfaceDeclaration }
|
val concreteRelevantDeclarations = result.filter { !it.isAbstract && it.mayBeUsedAsSuperImplementation }
|
||||||
if (concreteRelevantDeclarations.size != 1) {
|
if (concreteRelevantDeclarations.size != 1) {
|
||||||
error("Concrete fake override $function should have exactly one concrete super-declaration: $concreteRelevantDeclarations")
|
error("Concrete fake override $function should have exactly one concrete super-declaration: $concreteRelevantDeclarations")
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -72,8 +72,8 @@ class DescriptorBasedFunctionHandle(
|
|||||||
override val isAbstract: Boolean =
|
override val isAbstract: Boolean =
|
||||||
descriptor.modality == Modality.ABSTRACT || !areDeclarationAndDefinitionSame(descriptor)
|
descriptor.modality == Modality.ABSTRACT || !areDeclarationAndDefinitionSame(descriptor)
|
||||||
|
|
||||||
override val isInterfaceDeclaration: Boolean
|
override val mayBeUsedAsSuperImplementation: Boolean =
|
||||||
get() = DescriptorUtils.isInterface(descriptor.containingDeclaration)
|
!DescriptorUtils.isInterface(descriptor.containingDeclaration)
|
||||||
|
|
||||||
override fun getOverridden() = overridden
|
override fun getOverridden() = overridden
|
||||||
|
|
||||||
|
|||||||
@@ -153,19 +153,19 @@ private fun <Signature> findSuperImplementationForStubDelegation(
|
|||||||
areDeclarationAndDefinitionSame: (CallableMemberDescriptor) -> Boolean,
|
areDeclarationAndDefinitionSame: (CallableMemberDescriptor) -> Boolean,
|
||||||
signatureByDescriptor: (FunctionDescriptor) -> Signature
|
signatureByDescriptor: (FunctionDescriptor) -> Signature
|
||||||
): FunctionDescriptor? {
|
): FunctionDescriptor? {
|
||||||
val implementation = findConcreteSuperDeclaration(DescriptorBasedFunctionHandle(function, areDeclarationAndDefinitionSame)).descriptor
|
val implementation = findConcreteSuperDeclaration(DescriptorBasedFunctionHandle(function, areDeclarationAndDefinitionSame))
|
||||||
|
|
||||||
// Implementation from interface will be generated by common mechanism
|
// Implementation from interface will be generated by common mechanism
|
||||||
if (DescriptorUtils.isInterface(implementation.containingDeclaration)) return null
|
if (!implementation.mayBeUsedAsSuperImplementation) return null
|
||||||
|
|
||||||
// Implementation in super-class already has proper signature
|
// Implementation in super-class already has proper signature
|
||||||
if (signatureByDescriptor(function) == signatureByDescriptor(implementation)) return null
|
if (signatureByDescriptor(function) == signatureByDescriptor(implementation.descriptor)) return null
|
||||||
|
|
||||||
assert(function.modality == Modality.OPEN) {
|
assert(function.modality == Modality.OPEN) {
|
||||||
"Should generate stubs only for non-abstract built-ins, but ${function.name} is ${function.modality}"
|
"Should generate stubs only for non-abstract built-ins, but ${function.name} is ${function.modality}"
|
||||||
}
|
}
|
||||||
|
|
||||||
return implementation
|
return implementation.descriptor
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun findAllReachableDeclarations(
|
private fun findAllReachableDeclarations(
|
||||||
|
|||||||
+2
-2
@@ -171,8 +171,8 @@ data class IrBasedFunctionHandle(val function: IrSimpleFunction) : FunctionHandl
|
|||||||
override val isAbstract: Boolean =
|
override val isAbstract: Boolean =
|
||||||
function.modality == Modality.ABSTRACT
|
function.modality == Modality.ABSTRACT
|
||||||
|
|
||||||
override val isInterfaceDeclaration =
|
override val mayBeUsedAsSuperImplementation =
|
||||||
function.parentAsClass.isInterface
|
!function.parentAsClass.isInterface
|
||||||
|
|
||||||
override fun getOverridden() =
|
override fun getOverridden() =
|
||||||
function.overriddenSymbols.map { IrBasedFunctionHandle(it.owner) }
|
function.overriddenSymbols.map { IrBasedFunctionHandle(it.owner) }
|
||||||
|
|||||||
@@ -28,7 +28,7 @@ class BridgeTest : TestCase() {
|
|||||||
private class Fun(val text: String) : FunctionHandle {
|
private class Fun(val text: String) : FunctionHandle {
|
||||||
override val isDeclaration: Boolean get() = text[1] == 'D'
|
override val isDeclaration: Boolean get() = text[1] == 'D'
|
||||||
override val isAbstract: Boolean get() = text[0] == '-'
|
override val isAbstract: Boolean get() = text[0] == '-'
|
||||||
override val isInterfaceDeclaration: Boolean get() = false
|
override val mayBeUsedAsSuperImplementation: Boolean get() = true
|
||||||
val signature: Char get() = text[2]
|
val signature: Char get() = text[2]
|
||||||
|
|
||||||
val overriddenFunctions: MutableList<Fun> = arrayListOf()
|
val overriddenFunctions: MutableList<Fun> = arrayListOf()
|
||||||
@@ -150,7 +150,7 @@ class BridgeTest : TestCase() {
|
|||||||
graph()
|
graph()
|
||||||
doTest(a, setOf())
|
doTest(a, setOf())
|
||||||
}
|
}
|
||||||
|
|
||||||
fun testSimpleFakeOverrideSameSignature() {
|
fun testSimpleFakeOverrideSameSignature() {
|
||||||
val a = v("+D1")
|
val a = v("+D1")
|
||||||
val b = v("+F1")
|
val b = v("+F1")
|
||||||
@@ -190,7 +190,7 @@ class BridgeTest : TestCase() {
|
|||||||
doTest(a, setOf())
|
doTest(a, setOf())
|
||||||
doTest(b, setOf())
|
doTest(b, setOf())
|
||||||
}
|
}
|
||||||
|
|
||||||
// Simple tests where declaration "a" is inherited by declaration "b" with a different signature.
|
// Simple tests where declaration "a" is inherited by declaration "b" with a different signature.
|
||||||
// Note that we don't generate bridges near abstract declarations in contrast to javac
|
// Note that we don't generate bridges near abstract declarations in contrast to javac
|
||||||
|
|
||||||
@@ -200,7 +200,7 @@ class BridgeTest : TestCase() {
|
|||||||
graph(b to a)
|
graph(b to a)
|
||||||
doTest(b, setOf(bridge(a, b)))
|
doTest(b, setOf(bridge(a, b)))
|
||||||
}
|
}
|
||||||
|
|
||||||
fun testSimpleAbstractDeclarationDifferentSignature() {
|
fun testSimpleAbstractDeclarationDifferentSignature() {
|
||||||
val a = v("-D1")
|
val a = v("-D1")
|
||||||
val b = v("-D2")
|
val b = v("-D2")
|
||||||
@@ -221,7 +221,7 @@ class BridgeTest : TestCase() {
|
|||||||
graph(b to a)
|
graph(b to a)
|
||||||
doTest(b, setOf(bridge(a, b)))
|
doTest(b, setOf(bridge(a, b)))
|
||||||
}
|
}
|
||||||
|
|
||||||
// Simple tests where declaration overrides declaration through a fake override in the super class, with a different signature
|
// Simple tests where declaration overrides declaration through a fake override in the super class, with a different signature
|
||||||
|
|
||||||
fun testSimpleConcreteDeclarationOverridesConcreteThroughFakeOverride() {
|
fun testSimpleConcreteDeclarationOverridesConcreteThroughFakeOverride() {
|
||||||
@@ -263,7 +263,7 @@ class BridgeTest : TestCase() {
|
|||||||
doTest(b, setOf())
|
doTest(b, setOf())
|
||||||
doTest(c, setOf())
|
doTest(c, setOf())
|
||||||
}
|
}
|
||||||
|
|
||||||
// Declaration "c" overrides two declarations "a" and "b"
|
// Declaration "c" overrides two declarations "a" and "b"
|
||||||
|
|
||||||
fun testAbstractDeclarationOverridesTwoAbstractDeclarations() {
|
fun testAbstractDeclarationOverridesTwoAbstractDeclarations() {
|
||||||
@@ -320,7 +320,7 @@ class BridgeTest : TestCase() {
|
|||||||
doTest(b, setOf())
|
doTest(b, setOf())
|
||||||
doTest(c, setOf(bridge(a, c), bridge(b, c)))
|
doTest(c, setOf(bridge(a, c), bridge(b, c)))
|
||||||
}
|
}
|
||||||
|
|
||||||
// Diamonds where the sink (vertex "d") is a declaration: bridges from all super-declarations to "d" should be present
|
// Diamonds where the sink (vertex "d") is a declaration: bridges from all super-declarations to "d" should be present
|
||||||
|
|
||||||
fun testDiamondAbstractDeclarations() {
|
fun testDiamondAbstractDeclarations() {
|
||||||
@@ -334,7 +334,7 @@ class BridgeTest : TestCase() {
|
|||||||
doTest(c, setOf())
|
doTest(c, setOf())
|
||||||
doTest(d, setOf())
|
doTest(d, setOf())
|
||||||
}
|
}
|
||||||
|
|
||||||
fun testDiamondMixedDeclarations() {
|
fun testDiamondMixedDeclarations() {
|
||||||
val a = v("-D1")
|
val a = v("-D1")
|
||||||
val b = v("+D2")
|
val b = v("+D2")
|
||||||
@@ -346,7 +346,7 @@ class BridgeTest : TestCase() {
|
|||||||
doTest(c, setOf())
|
doTest(c, setOf())
|
||||||
doTest(d, setOf(bridge(a, d), bridge(b, d), bridge(c, d)))
|
doTest(d, setOf(bridge(a, d), bridge(b, d), bridge(c, d)))
|
||||||
}
|
}
|
||||||
|
|
||||||
fun testDiamondAbstractFakeOverridesInTheMiddle() {
|
fun testDiamondAbstractFakeOverridesInTheMiddle() {
|
||||||
val a = v("-D1")
|
val a = v("-D1")
|
||||||
val b = v("-F2")
|
val b = v("-F2")
|
||||||
@@ -360,7 +360,7 @@ class BridgeTest : TestCase() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Fake override "c" overrides declarations "a" and "b": a bridge is needed if signatures are different and there's an implementation
|
// Fake override "c" overrides declarations "a" and "b": a bridge is needed if signatures are different and there's an implementation
|
||||||
|
|
||||||
fun testAbstractFakeOverride() {
|
fun testAbstractFakeOverride() {
|
||||||
val a = v("-D1")
|
val a = v("-D1")
|
||||||
val b = v("-D2")
|
val b = v("-D2")
|
||||||
@@ -384,7 +384,7 @@ class BridgeTest : TestCase() {
|
|||||||
graph(c to a, c to b)
|
graph(c to a, c to b)
|
||||||
doTest(c, setOf(bridge(a, b)))
|
doTest(c, setOf(bridge(a, b)))
|
||||||
}
|
}
|
||||||
|
|
||||||
fun testFakeOverrideInheritingDeclarations() {
|
fun testFakeOverrideInheritingDeclarations() {
|
||||||
val a = v("-D1")
|
val a = v("-D1")
|
||||||
val b = v("+D2")
|
val b = v("+D2")
|
||||||
|
|||||||
Reference in New Issue
Block a user