From cdac6157a92f216637947b9c8b93f4133116b59c Mon Sep 17 00:00:00 2001 From: Mikhail Glukhikh Date: Thu, 14 May 2020 14:07:04 +0300 Subject: [PATCH] [FIR2IR] Force loading Java SAM from external classes --- .../kotlin/fir/backend/ConversionUtils.kt | 3 +++ .../fir/backend/Fir2IrDeclarationStorage.kt | 12 +++++++++++- .../testData/codegen/box/coroutines/async.kt | 1 - .../codegen/box/coroutines/asyncException.kt | 1 - .../testData/codegen/box/fullJdk/kt31757.kt | 1 - .../box/javaInterop/samUnboundTypeParameter.kt | 1 - .../samOnInterfaceWithDefaultMethod.kt | 1 - .../codegen/box/sam/equality/simpleLambdas.kt | 1 - .../codegen/box/synchronized/nonLocalReturn.kt | 1 - .../sam/genericSamProjectedOut.fir.txt | 13 +++++++------ .../sam/samConversionToGeneric.fir.txt | 13 +++++++------ .../expressions/sam/samConversions.fir.txt | 18 ++++++++++-------- 12 files changed, 38 insertions(+), 28 deletions(-) diff --git a/compiler/fir/fir2ir/src/org/jetbrains/kotlin/fir/backend/ConversionUtils.kt b/compiler/fir/fir2ir/src/org/jetbrains/kotlin/fir/backend/ConversionUtils.kt index d27c72e5437..d96ad2b864c 100644 --- a/compiler/fir/fir2ir/src/org/jetbrains/kotlin/fir/backend/ConversionUtils.kt +++ b/compiler/fir/fir2ir/src/org/jetbrains/kotlin/fir/backend/ConversionUtils.kt @@ -466,6 +466,9 @@ fun FirClass<*>.irOrigin(firProvider: FirProvider): IrDeclarationOrigin = when { else -> IrDeclarationOrigin.IR_EXTERNAL_DECLARATION_STUB } +fun FirClass<*>.getSamIfAny(): FirSimpleFunction? = + declarations.filterIsInstance().singleOrNull { it.modality == Modality.ABSTRACT } + val IrType.isSamType: Boolean get() { val irClass = classOrNull ?: return false diff --git a/compiler/fir/fir2ir/src/org/jetbrains/kotlin/fir/backend/Fir2IrDeclarationStorage.kt b/compiler/fir/fir2ir/src/org/jetbrains/kotlin/fir/backend/Fir2IrDeclarationStorage.kt index 14344cdf62b..8d46a7967d9 100644 --- a/compiler/fir/fir2ir/src/org/jetbrains/kotlin/fir/backend/Fir2IrDeclarationStorage.kt +++ b/compiler/fir/fir2ir/src/org/jetbrains/kotlin/fir/backend/Fir2IrDeclarationStorage.kt @@ -180,7 +180,17 @@ class Fir2IrDeclarationStorage( } internal fun addDeclarationsToExternalClass(regularClass: FirRegularClass, irClass: IrClass) { - if (regularClass.symbol.classId.packageFqName.startsWith(Name.identifier("kotlin"))) { + if (regularClass.origin == FirDeclarationOrigin.Java) { + val sam = regularClass.getSamIfAny() + if (sam != null) { + val scope = regularClass.buildUseSiteMemberScope(session, scopeSession)!! + scope.processFunctionsByName(sam.name) { + if (it is FirNamedFunctionSymbol && !it.isFakeOverride) { + irClass.declarations += createIrFunction(it.fir, irClass) + } + } + } + } else if (regularClass.symbol.classId.packageFqName.startsWith(Name.identifier("kotlin"))) { // Note: yet this is necessary only for *Range / *Progression classes // due to BE optimizations (for lowering) that use their first / last / step members // TODO: think how to refactor this piece of code and/or merge it with similar Fir2IrVisitor fragment diff --git a/compiler/testData/codegen/box/coroutines/async.kt b/compiler/testData/codegen/box/coroutines/async.kt index 27d6a570feb..c3a29497255 100644 --- a/compiler/testData/codegen/box/coroutines/async.kt +++ b/compiler/testData/codegen/box/coroutines/async.kt @@ -1,4 +1,3 @@ -// IGNORE_BACKEND_FIR: JVM_IR // SKIP_JDK6 // TARGET_BACKEND: JVM // WITH_RUNTIME diff --git a/compiler/testData/codegen/box/coroutines/asyncException.kt b/compiler/testData/codegen/box/coroutines/asyncException.kt index 2767170aa96..f7dd341c2b9 100644 --- a/compiler/testData/codegen/box/coroutines/asyncException.kt +++ b/compiler/testData/codegen/box/coroutines/asyncException.kt @@ -1,4 +1,3 @@ -// IGNORE_BACKEND_FIR: JVM_IR // SKIP_JDK6 // TARGET_BACKEND: JVM // WITH_RUNTIME diff --git a/compiler/testData/codegen/box/fullJdk/kt31757.kt b/compiler/testData/codegen/box/fullJdk/kt31757.kt index 05065818fe6..c3cde0c8023 100644 --- a/compiler/testData/codegen/box/fullJdk/kt31757.kt +++ b/compiler/testData/codegen/box/fullJdk/kt31757.kt @@ -1,5 +1,4 @@ // !LANGUAGE: +NewInference -// IGNORE_BACKEND_FIR: JVM_IR // TARGET_BACKEND: JVM // SKIP_JDK6 // FULL_JDK diff --git a/compiler/testData/codegen/box/javaInterop/samUnboundTypeParameter.kt b/compiler/testData/codegen/box/javaInterop/samUnboundTypeParameter.kt index b57197333d0..dbd0d0dfd4a 100644 --- a/compiler/testData/codegen/box/javaInterop/samUnboundTypeParameter.kt +++ b/compiler/testData/codegen/box/javaInterop/samUnboundTypeParameter.kt @@ -1,5 +1,4 @@ // TARGET_BACKEND: JVM -// IGNORE_BACKEND_FIR: JVM_IR // !LANGUAGE: -NewInference // WITH_RUNTIME // FILE: Base.java diff --git a/compiler/testData/codegen/box/jvm8/javaDefaults/samOnInterfaceWithDefaultMethod.kt b/compiler/testData/codegen/box/jvm8/javaDefaults/samOnInterfaceWithDefaultMethod.kt index 47ee735ed75..81e39577a10 100644 --- a/compiler/testData/codegen/box/jvm8/javaDefaults/samOnInterfaceWithDefaultMethod.kt +++ b/compiler/testData/codegen/box/jvm8/javaDefaults/samOnInterfaceWithDefaultMethod.kt @@ -1,4 +1,3 @@ -// IGNORE_BACKEND_FIR: JVM_IR // SKIP_JDK6 // TARGET_BACKEND: JVM // FILE: JavaCall.java diff --git a/compiler/testData/codegen/box/sam/equality/simpleLambdas.kt b/compiler/testData/codegen/box/sam/equality/simpleLambdas.kt index 3189601a54b..27db29fe4ae 100644 --- a/compiler/testData/codegen/box/sam/equality/simpleLambdas.kt +++ b/compiler/testData/codegen/box/sam/equality/simpleLambdas.kt @@ -1,5 +1,4 @@ // TARGET_BACKEND: JVM -// IGNORE_BACKEND_FIR: JVM_IR private fun id(f: Runnable): Any = f diff --git a/compiler/testData/codegen/box/synchronized/nonLocalReturn.kt b/compiler/testData/codegen/box/synchronized/nonLocalReturn.kt index 1113acd81da..7368d92fd82 100644 --- a/compiler/testData/codegen/box/synchronized/nonLocalReturn.kt +++ b/compiler/testData/codegen/box/synchronized/nonLocalReturn.kt @@ -1,4 +1,3 @@ -// IGNORE_BACKEND_FIR: JVM_IR // TARGET_BACKEND: JVM // WITH_RUNTIME diff --git a/compiler/testData/ir/irText/expressions/sam/genericSamProjectedOut.fir.txt b/compiler/testData/ir/irText/expressions/sam/genericSamProjectedOut.fir.txt index 26fe88043d3..3cbbf9c377e 100644 --- a/compiler/testData/ir/irText/expressions/sam/genericSamProjectedOut.fir.txt +++ b/compiler/testData/ir/irText/expressions/sam/genericSamProjectedOut.fir.txt @@ -4,12 +4,13 @@ FILE fqName: fileName:/genericSamProjectedOut.kt BLOCK_BODY CALL 'public open fun someFunction (hello: example.Hello?): kotlin.Unit declared in example.SomeJavaClass' type=kotlin.Unit origin=null $this: GET_VAR 'a: example.SomeJavaClass declared in .test' type=example.SomeJavaClass origin=null - hello: FUN_EXPR type=kotlin.Function1 origin=LAMBDA - FUN LOCAL_FUNCTION_FOR_LAMBDA name: visibility:local modality:FINAL <> (it:kotlin.String?) returnType:kotlin.Unit - VALUE_PARAMETER name:it index:0 type:kotlin.String? - BLOCK_BODY - RETURN type=kotlin.Nothing from='local final fun (it: kotlin.String?): kotlin.Unit declared in .test' - GET_OBJECT 'CLASS IR_EXTERNAL_DECLARATION_STUB OBJECT name:Unit modality:FINAL visibility:public superTypes:[kotlin.Any]' type=kotlin.Unit + hello: TYPE_OP type=example.Hello? origin=SAM_CONVERSION typeOperand=example.Hello? + FUN_EXPR type=kotlin.Function1 origin=LAMBDA + FUN LOCAL_FUNCTION_FOR_LAMBDA name: visibility:local modality:FINAL <> (it:kotlin.String?) returnType:kotlin.Unit + VALUE_PARAMETER name:it index:0 type:kotlin.String? + BLOCK_BODY + RETURN type=kotlin.Nothing from='local final fun (it: kotlin.String?): kotlin.Unit declared in .test' + GET_OBJECT 'CLASS IR_EXTERNAL_DECLARATION_STUB OBJECT name:Unit modality:FINAL visibility:public superTypes:[kotlin.Any]' type=kotlin.Unit CALL 'public open fun plus (hello: example.Hello?): kotlin.Unit [operator] declared in example.SomeJavaClass' type=kotlin.Unit origin=PLUS $this: GET_VAR 'a: example.SomeJavaClass declared in .test' type=example.SomeJavaClass origin=null hello: FUN_EXPR type=kotlin.Function1 origin=LAMBDA diff --git a/compiler/testData/ir/irText/expressions/sam/samConversionToGeneric.fir.txt b/compiler/testData/ir/irText/expressions/sam/samConversionToGeneric.fir.txt index 97463d5c167..97cce9f79d7 100644 --- a/compiler/testData/ir/irText/expressions/sam/samConversionToGeneric.fir.txt +++ b/compiler/testData/ir/irText/expressions/sam/samConversionToGeneric.fir.txt @@ -26,12 +26,13 @@ FILE fqName: fileName:/samConversionToGeneric.kt RETURN type=kotlin.Nothing from='public final fun test3 (): kotlin.Unit declared in ' CALL 'public open fun bar (j: .J.H.bar?>?): kotlin.Unit declared in .H' type=kotlin.Unit origin=null : kotlin.String? - j: FUN_EXPR type=kotlin.Function1 origin=LAMBDA - FUN LOCAL_FUNCTION_FOR_LAMBDA name: visibility:local modality:FINAL <> (x:kotlin.String) returnType:kotlin.String - VALUE_PARAMETER name:x index:0 type:kotlin.String - BLOCK_BODY - RETURN type=kotlin.Nothing from='local final fun (x: kotlin.String): kotlin.String declared in .test3' - GET_VAR 'x: kotlin.String declared in .test3.' type=kotlin.String origin=null + j: TYPE_OP type=.J.H.bar?>? origin=SAM_CONVERSION typeOperand=.J.H.bar?>? + FUN_EXPR type=kotlin.Function1 origin=LAMBDA + FUN LOCAL_FUNCTION_FOR_LAMBDA name: visibility:local modality:FINAL <> (x:kotlin.String) returnType:kotlin.String + VALUE_PARAMETER name:x index:0 type:kotlin.String + BLOCK_BODY + RETURN type=kotlin.Nothing from='local final fun (x: kotlin.String): kotlin.String declared in .test3' + GET_VAR 'x: kotlin.String declared in .test3.' type=kotlin.String origin=null FUN name:test4 visibility:public modality:FINAL <> (a:kotlin.Any) returnType:kotlin.Unit VALUE_PARAMETER name:a index:0 type:kotlin.Any BLOCK_BODY diff --git a/compiler/testData/ir/irText/expressions/sam/samConversions.fir.txt b/compiler/testData/ir/irText/expressions/sam/samConversions.fir.txt index 5b549a8beb5..7f5e1e5c824 100644 --- a/compiler/testData/ir/irText/expressions/sam/samConversions.fir.txt +++ b/compiler/testData/ir/irText/expressions/sam/samConversions.fir.txt @@ -11,19 +11,21 @@ FILE fqName: fileName:/samConversions.kt FUN name:test1 visibility:public modality:FINAL <> () returnType:kotlin.Unit BLOCK_BODY CALL 'public open fun runStatic (r: java.lang.Runnable?): kotlin.Unit declared in .J' type=kotlin.Unit origin=null - r: FUN_EXPR type=kotlin.Function0 origin=LAMBDA - FUN LOCAL_FUNCTION_FOR_LAMBDA name: visibility:local modality:FINAL <> () returnType:kotlin.Unit - BLOCK_BODY - CALL 'public final fun test1 (): kotlin.Unit declared in ' type=kotlin.Unit origin=null + r: TYPE_OP type=java.lang.Runnable? origin=SAM_CONVERSION typeOperand=java.lang.Runnable? + FUN_EXPR type=kotlin.Function0 origin=LAMBDA + FUN LOCAL_FUNCTION_FOR_LAMBDA name: visibility:local modality:FINAL <> () returnType:kotlin.Unit + BLOCK_BODY + CALL 'public final fun test1 (): kotlin.Unit declared in ' type=kotlin.Unit origin=null FUN name:test2 visibility:public modality:FINAL <> ($receiver:.J) returnType:kotlin.Unit $receiver: VALUE_PARAMETER name: type:.J BLOCK_BODY CALL 'public open fun runIt (r: java.lang.Runnable?): kotlin.Unit declared in .J' type=kotlin.Unit origin=null $this: GET_VAR ': .J declared in .test2' type=.J origin=null - r: FUN_EXPR type=kotlin.Function0 origin=LAMBDA - FUN LOCAL_FUNCTION_FOR_LAMBDA name: visibility:local modality:FINAL <> () returnType:kotlin.Unit - BLOCK_BODY - CALL 'public final fun test1 (): kotlin.Unit declared in ' type=kotlin.Unit origin=null + r: TYPE_OP type=java.lang.Runnable? origin=SAM_CONVERSION typeOperand=java.lang.Runnable? + FUN_EXPR type=kotlin.Function0 origin=LAMBDA + FUN LOCAL_FUNCTION_FOR_LAMBDA name: visibility:local modality:FINAL <> () returnType:kotlin.Unit + BLOCK_BODY + CALL 'public final fun test1 (): kotlin.Unit declared in ' type=kotlin.Unit origin=null FUN name:test3 visibility:public modality:FINAL <> ($receiver:.J, a:kotlin.Function0) returnType:kotlin.Unit $receiver: VALUE_PARAMETER name: type:.J VALUE_PARAMETER name:a index:0 type:kotlin.Function0