JVM_IR: Fix check for whether classes are from Java.

This allows us to not generate redundant immutable collection
stubs. The code to generate the immutable collection stubs does
not deal well with thinking that all external declarations
come from Java.
This commit is contained in:
Mads Ager
2019-12-19 15:38:21 +01:00
committed by max-kammerer
parent e261b1e2de
commit 51f726be9b
5 changed files with 16 additions and 8 deletions
@@ -72,7 +72,7 @@ class JvmGeneratorExtensions(private val generateFacades: Boolean = true) : Gene
null null
override fun computeExternalDeclarationOrigin(descriptor: DeclarationDescriptor): IrDeclarationOrigin? = override fun computeExternalDeclarationOrigin(descriptor: DeclarationDescriptor): IrDeclarationOrigin? =
if (descriptor is JavaCallableMemberDescriptor) if (descriptor is JavaCallableMemberDescriptor || descriptor is JavaClassDescriptor)
IrDeclarationOrigin.IR_EXTERNAL_JAVA_DECLARATION_STUB IrDeclarationOrigin.IR_EXTERNAL_JAVA_DECLARATION_STUB
else else
IrDeclarationOrigin.IR_EXTERNAL_DECLARATION_STUB IrDeclarationOrigin.IR_EXTERNAL_DECLARATION_STUB
@@ -108,7 +108,7 @@ private class BridgeLowering(val context: JvmBackendContext) : ClassLoweringPass
irFunction.modality !== Modality.ABSTRACT && irFunction.modality !== Modality.ABSTRACT &&
irFunction.visibility !== Visibilities.INVISIBLE_FAKE && irFunction.visibility !== Visibilities.INVISIBLE_FAKE &&
irFunction.overriddenInClasses().firstOrNull { it.getJvmSignature() != ourSignature || it.origin != IrDeclarationOrigin.FAKE_OVERRIDE } irFunction.overriddenInClasses().firstOrNull { it.getJvmSignature() != ourSignature || it.origin != IrDeclarationOrigin.FAKE_OVERRIDE }
?.let { (it.getJvmName() != ourMethodName || it.getJvmSignature() == specialOverrideSignature) && it.comesFromJava() } == true ?.let { (it.getJvmName() != ourMethodName || it.getJvmSignature() == specialOverrideSignature) && it.isExternalDeclaration() } == true
) { ) {
val resolved = irFunction.findConcreteSuperDeclaration()!! val resolved = irFunction.findConcreteSuperDeclaration()!!
val resolvedSignature = resolved.getJvmSignature() val resolvedSignature = resolved.getJvmSignature()
@@ -492,10 +492,11 @@ fun IrSimpleFunction.overriddenInClasses(): Sequence<IrSimpleFunction> =
fun IrSimpleFunction.isCollectionStub(): Boolean = fun IrSimpleFunction.isCollectionStub(): Boolean =
origin == IrDeclarationOrigin.IR_BUILTINS_STUB origin == IrDeclarationOrigin.IR_BUILTINS_STUB
// TODO: At present, there is no reliable way to distinguish Java imports from Kotlin cross-module imports. val EXTERNAL_ORIGIN = setOf(IrDeclarationOrigin.IR_EXTERNAL_JAVA_DECLARATION_STUB, IrDeclarationOrigin.IR_EXTERNAL_DECLARATION_STUB)
val ORIGINS_FROM_JAVA = setOf(IrDeclarationOrigin.IR_EXTERNAL_JAVA_DECLARATION_STUB, IrDeclarationOrigin.IR_EXTERNAL_DECLARATION_STUB)
fun IrDeclaration.comesFromJava() = parentAsClass.origin in ORIGINS_FROM_JAVA fun IrDeclaration.comesFromJava() = parentAsClass.origin == IrDeclarationOrigin.IR_EXTERNAL_JAVA_DECLARATION_STUB
fun IrDeclaration.isExternalDeclaration() = parentAsClass.origin in EXTERNAL_ORIGIN
// Method has the same name, same arguments as `other`. Return types may differ. // Method has the same name, same arguments as `other`. Return types may differ.
fun Method.sameCallAs(other: Method) = fun Method.sameCallAs(other: Method) =
@@ -204,7 +204,7 @@ private class CollectionStubMethodLowering(val context: JvmBackendContext) : Cla
}.toHashSet() }.toHashSet()
} }
fun IrClass.comesFromJava() = origin in ORIGINS_FROM_JAVA fun IrClass.comesFromJava() = origin == IrDeclarationOrigin.IR_EXTERNAL_JAVA_DECLARATION_STUB
private fun Collection<IrType>.findMostSpecificTypeForClass(classifier: IrClassSymbol): IrType { private fun Collection<IrType>.findMostSpecificTypeForClass(classifier: IrClassSymbol): IrType {
val types = this.filter { it.classifierOrNull == classifier } val types = this.filter { it.classifierOrNull == classifier }
@@ -1,5 +1,4 @@
// IGNORE_BACKEND_FIR: JVM_IR // IGNORE_BACKEND_FIR: JVM_IR
// IGNORE_BACKEND: JVM_IR
// TARGET_BACKEND: JVM // TARGET_BACKEND: JVM
// WITH_RUNTIME // WITH_RUNTIME
// IGNORE_LIGHT_ANALYSIS // IGNORE_LIGHT_ANALYSIS
+9 -1
View File
@@ -14,9 +14,12 @@ var v: Int = 1
fun consumeInt(x: Int) {} fun consumeInt(x: Int) {}
class A { open class A {
val OK: String = "OK" val OK: String = "OK"
@JvmName("OK") get @JvmName("OK") get
@JvmName("g")
fun <T> f(x: T, y: Int = 1) = x
} }
annotation class Anno(@get:JvmName("uglyJvmName") val value: String) annotation class Anno(@get:JvmName("uglyJvmName") val value: String)
@@ -25,6 +28,8 @@ annotation class Anno(@get:JvmName("uglyJvmName") val value: String)
import lib.* import lib.*
class B : A()
@Anno("OK") @Anno("OK")
fun annotated() {} fun annotated() {}
@@ -36,5 +41,8 @@ fun box(): String {
val annoValue = (::annotated.annotations.single() as Anno).value val annoValue = (::annotated.annotations.single() as Anno).value
if (annoValue != "OK") return "Fail annotation value: $annoValue" if (annoValue != "OK") return "Fail annotation value: $annoValue"
val b = B()
if (b.f("OK") != "OK") return "Fail call of annotated method"
return A().OK return A().OK
} }