Fixed CallableReferenceLowering to visit all nodes.

This commit is contained in:
Igor Chevdar
2017-02-28 12:09:53 +03:00
parent 00e5e070d7
commit 108f2132b6
@@ -2,22 +2,25 @@ package org.jetbrains.kotlin.backend.konan.lower
import org.jetbrains.kotlin.backend.common.DeclarationContainerLoweringPass import org.jetbrains.kotlin.backend.common.DeclarationContainerLoweringPass
import org.jetbrains.kotlin.backend.common.lower.createIrBuilder import org.jetbrains.kotlin.backend.common.lower.createIrBuilder
import org.jetbrains.kotlin.backend.konan.* import org.jetbrains.kotlin.backend.konan.KonanBackendContext
import org.jetbrains.kotlin.backend.konan.descriptors.* import org.jetbrains.kotlin.backend.konan.descriptors.getKonanInternalClass
import org.jetbrains.kotlin.backend.konan.ir.* import org.jetbrains.kotlin.backend.konan.descriptors.isFunctionOrKFunctionType
import org.jetbrains.kotlin.builtins.getFunctionalClassKind import org.jetbrains.kotlin.backend.konan.ir.addArguments
import org.jetbrains.kotlin.builtins.isFunctionType import org.jetbrains.kotlin.backend.konan.ir.getArguments
import org.jetbrains.kotlin.descriptors.* import org.jetbrains.kotlin.descriptors.*
import org.jetbrains.kotlin.descriptors.annotations.Annotations import org.jetbrains.kotlin.descriptors.annotations.Annotations
import org.jetbrains.kotlin.descriptors.impl.SimpleFunctionDescriptorImpl import org.jetbrains.kotlin.descriptors.impl.SimpleFunctionDescriptorImpl
import org.jetbrains.kotlin.descriptors.impl.ValueParameterDescriptorImpl import org.jetbrains.kotlin.descriptors.impl.ValueParameterDescriptorImpl
import org.jetbrains.kotlin.ir.IrElement import org.jetbrains.kotlin.ir.IrElement
import org.jetbrains.kotlin.ir.IrStatement
import org.jetbrains.kotlin.ir.builders.* import org.jetbrains.kotlin.ir.builders.*
import org.jetbrains.kotlin.ir.declarations.* import org.jetbrains.kotlin.ir.declarations.*
import org.jetbrains.kotlin.ir.declarations.impl.IrFunctionImpl import org.jetbrains.kotlin.ir.declarations.impl.IrFunctionImpl
import org.jetbrains.kotlin.ir.expressions.IrCallableReference import org.jetbrains.kotlin.ir.expressions.IrCallableReference
import org.jetbrains.kotlin.ir.expressions.IrExpression import org.jetbrains.kotlin.ir.expressions.IrExpression
import org.jetbrains.kotlin.ir.expressions.impl.* import org.jetbrains.kotlin.ir.expressions.impl.IrCallImpl
import org.jetbrains.kotlin.ir.expressions.impl.IrCallableReferenceImpl
import org.jetbrains.kotlin.ir.expressions.impl.IrVarargImpl
import org.jetbrains.kotlin.ir.util.transformFlat import org.jetbrains.kotlin.ir.util.transformFlat
import org.jetbrains.kotlin.ir.visitors.IrElementTransformerVoid import org.jetbrains.kotlin.ir.visitors.IrElementTransformerVoid
import org.jetbrains.kotlin.ir.visitors.transformChildrenVoid import org.jetbrains.kotlin.ir.visitors.transformChildrenVoid
@@ -32,9 +35,9 @@ internal class CallableReferenceLowering(val context: KonanBackendContext) : Dec
var callableReferenceCount = 0 var callableReferenceCount = 0
override fun lower(irDeclarationContainer: IrDeclarationContainer) { override fun lower(irDeclarationContainer: IrDeclarationContainer) {
irDeclarationContainer.declarations.transformFlat { memberDeclaration -> irDeclarationContainer.declarations.transformFlat { declaration ->
if (memberDeclaration is IrFunction || memberDeclaration is IrProperty) if (declaration !is IrDeclarationContainer)
lowerCallableReferences(this, memberDeclaration) lowerCallableReferences(this, irDeclarationContainer, declaration)
else else
null null
} }
@@ -45,8 +48,15 @@ internal class CallableReferenceLowering(val context: KonanBackendContext) : Dec
* Replaces all callable references in the function body to unbound ones. * Replaces all callable references in the function body to unbound ones.
* Returns the list of this function and all created ones. * Returns the list of this function and all created ones.
*/ */
private fun lowerCallableReferences(lower: CallableReferenceLowering, declaration: IrDeclaration): List<IrDeclaration> { private fun lowerCallableReferences(lower: CallableReferenceLowering,
val transformer = CallableReferencesUnbinder(lower, declaration) irDeclarationContainer: IrDeclarationContainer,
declaration: IrDeclaration): List<IrDeclaration> {
val containingDeclaration = when (irDeclarationContainer) {
is IrClass -> irDeclarationContainer.descriptor
is IrFile -> irDeclarationContainer.packageFragmentDescriptor
else -> throw AssertionError("Unexpected declaration container: $irDeclarationContainer")
}
val transformer = CallableReferencesUnbinder(lower, containingDeclaration)
declaration.transformChildrenVoid(transformer) declaration.transformChildrenVoid(transformer)
return declaration.singletonList() + transformer.createdFunctions return declaration.singletonList() + transformer.createdFunctions
} }
@@ -59,7 +69,7 @@ private object DECLARATION_ORIGIN_FUNCTION_FOR_CALLABLE_REFERENCE :
* Adds all created functions to [createdFunctions]. * Adds all created functions to [createdFunctions].
*/ */
private class CallableReferencesUnbinder(val lower: CallableReferenceLowering, private class CallableReferencesUnbinder(val lower: CallableReferenceLowering,
val declaration: IrDeclaration) : IrElementTransformerVoid() { val containingDeclaration: DeclarationDescriptor) : IrElementTransformerVoid() {
val createdFunctions = mutableListOf<IrFunction>() val createdFunctions = mutableListOf<IrFunction>()
@@ -84,6 +94,11 @@ private class CallableReferencesUnbinder(val lower: CallableReferenceLowering,
.getter!! .getter!!
} }
override fun visitClass(declaration: IrClass): IrStatement {
// Class is a declaration container - it will be visited by the main visitor (CallableReferenceLowering).
return declaration
}
override fun visitCallableReference(expression: IrCallableReference): IrExpression { override fun visitCallableReference(expression: IrCallableReference): IrExpression {
assert (expression.type.isFunctionOrKFunctionType) assert (expression.type.isFunctionOrKFunctionType)
@@ -191,7 +206,7 @@ private class CallableReferencesUnbinder(val lower: CallableReferenceLowering,
val newName = Name.identifier("${descriptor.name}\$bound-${lower.callableReferenceCount++}") val newName = Name.identifier("${descriptor.name}\$bound-${lower.callableReferenceCount++}")
val newDescriptor = SimpleFunctionDescriptorImpl.create( val newDescriptor = SimpleFunctionDescriptorImpl.create(
declaration.descriptor.containingDeclaration!!, Annotations.EMPTY, containingDeclaration, Annotations.EMPTY,
newName, CallableMemberDescriptor.Kind.SYNTHESIZED, SourceElement.NO_SOURCE) newName, CallableMemberDescriptor.Kind.SYNTHESIZED, SourceElement.NO_SOURCE)
val simpleFunctionImplType = simpleFunctionImplClass.defaultType val simpleFunctionImplType = simpleFunctionImplClass.defaultType