[devirtualization] Removed redundant code with associated objects + test
It turned out that it is not needed to explicitly add all associated objects to instantiating classes since their constructors have been already added to the root set and all constructors have additional parameter (<this>) and its type will be added to instantiating classes since it is final for all objects
This commit is contained in:
+5
-15
@@ -97,7 +97,9 @@ internal object Devirtualization {
|
||||
moduleDFG.symbolTable.functionMap.values.filter { it.explicitlyExported } +
|
||||
externalModulesDFG.functionDFGs.keys.filter { it.explicitlyExported }
|
||||
|
||||
// Conservatively assume each associated object could be instantiated.
|
||||
// Conservatively assume each associated object could be called.
|
||||
// Note: for constructors there is additional parameter (<this>) and its type will be added
|
||||
// to instantiating classes since all objects are final types.
|
||||
val associatedObjects = mutableListOf<DataFlowIR.FunctionSymbol>()
|
||||
context.irModule!!.acceptChildrenVoid(object: IrElementVisitorVoid {
|
||||
override fun visitElement(element: IrElement) {
|
||||
@@ -898,6 +900,8 @@ internal object Devirtualization {
|
||||
}
|
||||
if (entryPoint == null) {
|
||||
// For library assume all public non-abstract classes could be instantiated.
|
||||
// Note: for constructors there is additional parameter (<this>) and for associated objects
|
||||
// its type will be added to instantiating classes since all objects are final types.
|
||||
symbolTable.classMap.values
|
||||
.filterIsInstance<DataFlowIR.Type.Public>()
|
||||
.filter { !it.isAbstract }
|
||||
@@ -907,20 +911,6 @@ internal object Devirtualization {
|
||||
addInstantiatingClass(symbolTable.mapType(context.irBuiltIns.stringType).resolved())
|
||||
addEdge(concreteClass(symbolTable.mapType(context.irBuiltIns.stringType).resolved()),
|
||||
fieldNode(constraintGraph.arrayItemField))
|
||||
// Conservatively assume each associated object could be instantiated.
|
||||
context.irModule!!.acceptChildrenVoid(object: IrElementVisitorVoid {
|
||||
override fun visitElement(element: IrElement) {
|
||||
element.acceptChildrenVoid(this)
|
||||
}
|
||||
|
||||
override fun visitClass(declaration: IrClass) {
|
||||
context.getLayoutBuilder(declaration).associatedObjects.values.forEach {
|
||||
assert (it.kind == ClassKind.OBJECT) { "An object expected but was ${it.dump()}" }
|
||||
addInstantiatingClass(symbolTable.mapType(it.defaultType).resolved())
|
||||
}
|
||||
super.visitClass(declaration)
|
||||
}
|
||||
})
|
||||
}
|
||||
rootSet.forEach { createFunctionConstraintGraph(it, true) }
|
||||
while (stack.isNotEmpty()) {
|
||||
|
||||
@@ -204,6 +204,12 @@ __attribute__((swift_name("GH4002Argument")))
|
||||
+ (instancetype)new __attribute__((availability(swift, unavailable, message="use object initializers instead")));
|
||||
@end;
|
||||
|
||||
__attribute__((objc_subclassing_restricted))
|
||||
__attribute__((swift_name("Kt35940Kt")))
|
||||
@interface KtKt35940Kt : KtBase
|
||||
+ (NSString *)testKt35940 __attribute__((swift_name("testKt35940()")));
|
||||
@end;
|
||||
|
||||
__attribute__((objc_subclassing_restricted))
|
||||
__attribute__((swift_name("LibraryKt")))
|
||||
@interface KtLibraryKt : KtBase
|
||||
|
||||
@@ -0,0 +1,44 @@
|
||||
/*
|
||||
* Copyright 2010-2020 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license
|
||||
* that can be found in the LICENSE file.
|
||||
*/
|
||||
|
||||
package kt35940
|
||||
|
||||
import kotlin.reflect.*
|
||||
|
||||
@OptIn(ExperimentalAssociatedObjects::class)
|
||||
@AssociatedObjectKey
|
||||
@Retention(AnnotationRetention.BINARY)
|
||||
annotation class Associated(val kClass: KClass<*>)
|
||||
|
||||
private interface I1 {
|
||||
val s: String
|
||||
}
|
||||
|
||||
private class I1Impl : I1 {
|
||||
override val s = "zzz"
|
||||
}
|
||||
|
||||
private class C(var i1: I1?)
|
||||
|
||||
private interface I2 {
|
||||
fun bar(c: C)
|
||||
}
|
||||
|
||||
private object I2Impl : I2 {
|
||||
override fun bar(c: C) {
|
||||
c.i1 = I1Impl()
|
||||
}
|
||||
}
|
||||
|
||||
@Associated(I2Impl::class)
|
||||
private class I2ImplHolder
|
||||
|
||||
@OptIn(ExperimentalAssociatedObjects::class)
|
||||
fun testKt35940(): String {
|
||||
val i2 = I2ImplHolder::class.findAssociatedObject<Associated>()!! as I2
|
||||
val c = C(null)
|
||||
i2.bar(c)
|
||||
return c.i1!!.s
|
||||
}
|
||||
@@ -0,0 +1,18 @@
|
||||
/*
|
||||
* Copyright 2010-2020 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license
|
||||
* that can be found in the LICENSE file.
|
||||
*/
|
||||
|
||||
import Kt
|
||||
|
||||
private func test1() throws {
|
||||
try assertEquals(actual: Kt35940Kt.testKt35940(), expected: "zzz")
|
||||
}
|
||||
|
||||
class Kt35940Tests : SimpleTestProvider {
|
||||
override init() {
|
||||
super.init()
|
||||
|
||||
test("Test1", test1)
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user