From 4c01614136177a878e9aa85af628dec10f0bad9f Mon Sep 17 00:00:00 2001 From: pyos Date: Wed, 3 Apr 2019 13:17:01 +0200 Subject: [PATCH] Avoid leaking SamConstructorDescriptors from psi2ir --- .../jvm/lower/SingleAbstractMethodLowering.kt | 20 ++----------------- .../kotlin/psi2ir/generators/CallGenerator.kt | 2 +- .../irText/expressions/sam/samConstructors.kt | 4 +++- .../expressions/sam/samConstructors.txt | 15 ++++++++++++++ 4 files changed, 21 insertions(+), 20 deletions(-) diff --git a/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/lower/SingleAbstractMethodLowering.kt b/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/lower/SingleAbstractMethodLowering.kt index 6cee540af55..dd237b77e9a 100644 --- a/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/lower/SingleAbstractMethodLowering.kt +++ b/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/lower/SingleAbstractMethodLowering.kt @@ -44,27 +44,11 @@ class SingleAbstractMethodLowering(val context: CommonBackendContext) : ClassLow val cachedImplementations = mutableMapOf, IrClass>() val localImplementations = mutableListOf() irClass.transformChildrenVoid(object : IrElementTransformerVoidWithContext() { - override fun visitCall(expression: IrCall): IrExpression { - if (expression.symbol.owner.descriptor !is SamConstructorDescriptor) - return super.visitCall(expression) - // Direct construction of an interface: - // Runnable { print("Hello, World!") } - return createInstance(expression.type, expression.getValueArgument(0)!!.transform(this, null)) - } - override fun visitTypeOperator(expression: IrTypeOperatorCall): IrExpression { if (expression.operator != IrTypeOperator.SAM_CONVERSION) return super.visitTypeOperator(expression) - // Implicit conversion to an interface: - // // FILE: 1.java - // class A { public static void f(Runnable r) { r.run() } } - // // FILE: 2.kt - // A.f { print("Hello, World!") } - return createInstance(expression.typeOperand, expression.argument.transform(this, null)) - } - - // Replace a SAM-conversion of a callable object with an instance of an appropriate implementation. - private fun createInstance(superType: IrType, invokable: IrExpression): IrExpression { + val superType = expression.typeOperand + val invokable = expression.argument.transform(this, null) // Running in the class context, so empty scope means this is a field/anonymous initializer. val scopeOwnerSymbol = currentScope?.scope?.scopeOwnerSymbol ?: irClass.symbol return context.createIrBuilder(scopeOwnerSymbol).irBlock(invokable, null, superType) { diff --git a/compiler/ir/ir.psi2ir/src/org/jetbrains/kotlin/psi2ir/generators/CallGenerator.kt b/compiler/ir/ir.psi2ir/src/org/jetbrains/kotlin/psi2ir/generators/CallGenerator.kt index e429d9a5427..eee77450ccc 100644 --- a/compiler/ir/ir.psi2ir/src/org/jetbrains/kotlin/psi2ir/generators/CallGenerator.kt +++ b/compiler/ir/ir.psi2ir/src/org/jetbrains/kotlin/psi2ir/generators/CallGenerator.kt @@ -43,7 +43,7 @@ class CallGenerator(statementGenerator: StatementGenerator) : StatementGenerator fun generateCall(startOffset: Int, endOffset: Int, call: CallBuilder, origin: IrStatementOrigin? = null): IrExpression { val descriptor = call.descriptor - if (context.extensions.samConversion.isSamConstructor(descriptor)) { + if (context.extensions.samConversion.isSamConstructor(descriptor.original)) { return generateSamConstructorCall(descriptor, startOffset, endOffset, call) } diff --git a/compiler/testData/ir/irText/expressions/sam/samConstructors.kt b/compiler/testData/ir/irText/expressions/sam/samConstructors.kt index 656af50977d..4a862ea4e57 100644 --- a/compiler/testData/ir/irText/expressions/sam/samConstructors.kt +++ b/compiler/testData/ir/irText/expressions/sam/samConstructors.kt @@ -4,4 +4,6 @@ fun test1() = Runnable { } fun test2(a: () -> Unit) = Runnable(a) fun foo() {} -fun test3() = Runnable(::foo) \ No newline at end of file +fun test3() = Runnable(::foo) + +fun test4() = Comparator { a, b -> a - b } \ No newline at end of file diff --git a/compiler/testData/ir/irText/expressions/sam/samConstructors.txt b/compiler/testData/ir/irText/expressions/sam/samConstructors.txt index aef280f7d04..a41154b7541 100644 --- a/compiler/testData/ir/irText/expressions/sam/samConstructors.txt +++ b/compiler/testData/ir/irText/expressions/sam/samConstructors.txt @@ -22,3 +22,18 @@ FILE fqName: fileName:/samConstructors.kt RETURN type=kotlin.Nothing from='public final fun test3 (): java.lang.Runnable declared in ' TYPE_OP type=java.lang.Runnable origin=SAM_CONVERSION typeOperand=java.lang.Runnable FUNCTION_REFERENCE 'public final fun foo (): kotlin.Unit declared in ' type=kotlin.reflect.KFunction0 origin=null + FUN name:test4 visibility:public modality:FINAL <> () returnType:java.util.Comparator + BLOCK_BODY + RETURN type=kotlin.Nothing from='public final fun test4 (): java.util.Comparator declared in ' + TYPE_OP type=java.util.Comparator origin=SAM_CONVERSION typeOperand=java.util.Comparator + TYPE_OP type=kotlin.Function2 origin=IMPLICIT_CAST typeOperand=kotlin.Function2 + BLOCK type=kotlin.Function2 origin=LAMBDA + FUN LOCAL_FUNCTION_FOR_LAMBDA name: visibility:local modality:FINAL <> (a:kotlin.Int?, b:kotlin.Int?) returnType:kotlin.Int + VALUE_PARAMETER name:a index:0 type:kotlin.Int? + VALUE_PARAMETER name:b index:1 type:kotlin.Int? + BLOCK_BODY + RETURN type=kotlin.Nothing from='local final fun (a: kotlin.Int?, b: kotlin.Int?): kotlin.Int declared in .test4' + CALL 'public final fun minus (other: kotlin.Int): kotlin.Int declared in kotlin.Int' type=kotlin.Int origin=MINUS + $this: GET_VAR 'a: kotlin.Int? declared in .test4.' type=kotlin.Int? origin=null + other: GET_VAR 'b: kotlin.Int? declared in .test4.' type=kotlin.Int? origin=null + FUNCTION_REFERENCE 'local final fun (a: kotlin.Int?, b: kotlin.Int?): kotlin.Int declared in .test4' type=kotlin.Function2 origin=LAMBDA