From 3b37f6bd32c5afb444ca9e563051c2c018ba5c87 Mon Sep 17 00:00:00 2001 From: Ilmir Usmanov Date: Tue, 19 Nov 2019 21:57:14 +0300 Subject: [PATCH] JVM_IR: Add attributes to named suspend functions This is a prerequisite to moving continuation classes inside said functions, which is needed to support crossinline suspend lambdas. The logic of whether to copy attributes on lowerings or not is simple: - if the lowering moves function body to a new place, it should copy the attributes. - if the lowering just generates new declarations (i.e. bridges), it should leave attributes as is. --- .../kotlin/backend/common/ir/IrUtils.kt | 1 + .../lower/DefaultArgumentStubGenerator.kt | 7 +++++-- .../common/lower/LocalDeclarationsLowering.kt | 3 ++- .../jvm/descriptors/JvmDeclarationFactory.kt | 2 +- .../backend/jvm/lower/InterfaceLowering.kt | 2 +- .../jvm/lower/InventNamesForLocalClasses.kt | 10 ++++++++-- .../jvm/lower/JvmInlineClassLowering.kt | 1 + .../psi2ir/generators/FunctionGenerator.kt | 19 ++++++------------- .../ir/declarations/IrSimpleFunction.kt | 18 ++++-------------- .../ir/declarations/impl/IrFunctionImpl.kt | 4 +++- .../ir/declarations/lazy/IrLazyFunction.kt | 4 +++- .../kotlin/ir/descriptors/IrOperators.kt | 1 + 12 files changed, 36 insertions(+), 36 deletions(-) diff --git a/compiler/ir/backend.common/src/org/jetbrains/kotlin/backend/common/ir/IrUtils.kt b/compiler/ir/backend.common/src/org/jetbrains/kotlin/backend/common/ir/IrUtils.kt index f398bea1b84..4fa4dc02460 100644 --- a/compiler/ir/backend.common/src/org/jetbrains/kotlin/backend/common/ir/IrUtils.kt +++ b/compiler/ir/backend.common/src/org/jetbrains/kotlin/backend/common/ir/IrUtils.kt @@ -493,6 +493,7 @@ fun IrClass.addFakeOverrides() { parent = this@addFakeOverrides overriddenSymbols += overriddenFunctions.map { it.symbol } copyParameterDeclarationsFrom(irFunction) + copyAttributes(irFunction) } } diff --git a/compiler/ir/backend.common/src/org/jetbrains/kotlin/backend/common/lower/DefaultArgumentStubGenerator.kt b/compiler/ir/backend.common/src/org/jetbrains/kotlin/backend/common/lower/DefaultArgumentStubGenerator.kt index 4436602520c..6f34e50ab7a 100644 --- a/compiler/ir/backend.common/src/org/jetbrains/kotlin/backend/common/lower/DefaultArgumentStubGenerator.kt +++ b/compiler/ir/backend.common/src/org/jetbrains/kotlin/backend/common/lower/DefaultArgumentStubGenerator.kt @@ -6,7 +6,7 @@ package org.jetbrains.kotlin.backend.common.lower import org.jetbrains.kotlin.backend.common.* -import org.jetbrains.kotlin.backend.common.descriptors.* +import org.jetbrains.kotlin.backend.common.descriptors.synthesizedString import org.jetbrains.kotlin.backend.common.ir.* import org.jetbrains.kotlin.descriptors.Modality import org.jetbrains.kotlin.descriptors.Visibilities @@ -22,7 +22,10 @@ import org.jetbrains.kotlin.ir.expressions.impl.* import org.jetbrains.kotlin.ir.symbols.IrConstructorSymbol import org.jetbrains.kotlin.ir.symbols.IrFunctionSymbol import org.jetbrains.kotlin.ir.symbols.IrSimpleFunctionSymbol -import org.jetbrains.kotlin.ir.types.* +import org.jetbrains.kotlin.ir.types.IrType +import org.jetbrains.kotlin.ir.types.defaultType +import org.jetbrains.kotlin.ir.types.isNullable +import org.jetbrains.kotlin.ir.types.makeNullable import org.jetbrains.kotlin.ir.util.* import org.jetbrains.kotlin.ir.visitors.IrElementTransformerVoid import org.jetbrains.kotlin.ir.visitors.transformChildrenVoid diff --git a/compiler/ir/backend.common/src/org/jetbrains/kotlin/backend/common/lower/LocalDeclarationsLowering.kt b/compiler/ir/backend.common/src/org/jetbrains/kotlin/backend/common/lower/LocalDeclarationsLowering.kt index e385d00676d..364901d2c75 100644 --- a/compiler/ir/backend.common/src/org/jetbrains/kotlin/backend/common/lower/LocalDeclarationsLowering.kt +++ b/compiler/ir/backend.common/src/org/jetbrains/kotlin/backend/common/lower/LocalDeclarationsLowering.kt @@ -1,5 +1,5 @@ /* - * Copyright 2010-2018 JetBrains s.r.o. and Kotlin Programming Language contributors. + * Copyright 2010-2019 JetBrains s.r.o. and Kotlin Programming Language contributors. * Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file. */ @@ -543,6 +543,7 @@ class LocalDeclarationsLowering( newParameterToOld.putAbsentOrSame(it, this) } } + newDeclaration.copyAttributes(oldDeclaration) newDeclaration.valueParameters += createTransformedValueParameters(capturedValues, oldDeclaration, newDeclaration) newDeclaration.recordTransformedValueParameters(localFunctionContext) diff --git a/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/descriptors/JvmDeclarationFactory.kt b/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/descriptors/JvmDeclarationFactory.kt index f44cd88ecd1..21e427c5fa3 100644 --- a/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/descriptors/JvmDeclarationFactory.kt +++ b/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/descriptors/JvmDeclarationFactory.kt @@ -211,7 +211,7 @@ class JvmDeclarationFactory( }, // Old backend doesn't generate ACC_FINAL on DefaultImpls methods. modality = Modality.OPEN - ) + ).also { it.copyAttributes(interfaceFun) } } } diff --git a/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/lower/InterfaceLowering.kt b/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/lower/InterfaceLowering.kt index be34d816b69..801476bc7ec 100644 --- a/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/lower/InterfaceLowering.kt +++ b/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/lower/InterfaceLowering.kt @@ -1,5 +1,5 @@ /* - * Copyright 2010-2018 JetBrains s.r.o. and Kotlin Programming Language contributors. + * Copyright 2010-2019 JetBrains s.r.o. and Kotlin Programming Language contributors. * Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file. */ diff --git a/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/lower/InventNamesForLocalClasses.kt b/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/lower/InventNamesForLocalClasses.kt index 616816173a5..0eb8612d89f 100644 --- a/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/lower/InventNamesForLocalClasses.kt +++ b/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/lower/InventNamesForLocalClasses.kt @@ -1,6 +1,6 @@ /* - * Copyright 2010-2019 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license - * that can be found in the license/LICENSE.txt file. + * Copyright 2010-2019 JetBrains s.r.o. and Kotlin Programming Language contributors. + * Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file. */ package org.jetbrains.kotlin.backend.jvm.lower @@ -161,6 +161,12 @@ class InventNamesForLocalClasses(private val context: JvmBackendContext) : FileL declaration.acceptChildren(this, data.makeLocal()) return } + if (declaration.isSuspend && declaration.body != null && declaration.origin != IrDeclarationOrigin.LOCAL_FUNCTION_FOR_LAMBDA) { + // Suspend functions have a continuation, which is essentially a local class + val newData = data.withName(inventName(declaration.name, data)) + val internalName = inventName(null, newData) + context.putLocalClassType(declaration, Type.getObjectType(internalName)) + } super.visitSimpleFunction(declaration, data) } diff --git a/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/lower/JvmInlineClassLowering.kt b/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/lower/JvmInlineClassLowering.kt index 4066ea47441..437331d601e 100644 --- a/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/lower/JvmInlineClassLowering.kt +++ b/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/lower/JvmInlineClassLowering.kt @@ -111,6 +111,7 @@ private class JvmInlineClassLowering(private val context: JvmBackendContext) : F valueMap.putAll(replacement.valueParameterMap) worker.valueParameters.forEach { it.transformChildrenVoid() } worker.body = function.body?.transform(this, null)?.patchDeclarationParents(worker) + (worker as? IrAttributeContainer)?.copyAttributes(function) // Don't create a wrapper for functions which are only used in an unboxed context if (function.overriddenSymbols.isEmpty() || worker.dispatchReceiverParameter != null) diff --git a/compiler/ir/ir.psi2ir/src/org/jetbrains/kotlin/psi2ir/generators/FunctionGenerator.kt b/compiler/ir/ir.psi2ir/src/org/jetbrains/kotlin/psi2ir/generators/FunctionGenerator.kt index 355e25c90bc..6fdac531a5c 100644 --- a/compiler/ir/ir.psi2ir/src/org/jetbrains/kotlin/psi2ir/generators/FunctionGenerator.kt +++ b/compiler/ir/ir.psi2ir/src/org/jetbrains/kotlin/psi2ir/generators/FunctionGenerator.kt @@ -1,17 +1,6 @@ /* - * Copyright 2010-2017 JetBrains s.r.o. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Copyright 2010-2019 JetBrains s.r.o. and Kotlin Programming Language contributors. + * Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file. */ package org.jetbrains.kotlin.psi2ir.generators @@ -67,6 +56,10 @@ class FunctionGenerator(declarationGenerator: DeclarationGenerator) : Declaratio ?.let { declareSimpleFunctionInner(it, ktElement, IrDeclarationOrigin.FAKE_OVERRIDE).buildWithScope { irFunction -> generateFunctionParameterDeclarationsAndReturnType(irFunction, ktElement, null) + val overridenSymbol = irFunction.overriddenSymbols.first() + if (overridenSymbol.isBound) { + irFunction.copyAttributes(overridenSymbol.owner) + } } } diff --git a/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/declarations/IrSimpleFunction.kt b/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/declarations/IrSimpleFunction.kt index a62fc8d5ee5..6c2946fd45e 100644 --- a/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/declarations/IrSimpleFunction.kt +++ b/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/declarations/IrSimpleFunction.kt @@ -1,17 +1,6 @@ /* - * Copyright 2010-2017 JetBrains s.r.o. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Copyright 2010-2019 JetBrains s.r.o. and Kotlin Programming Language contributors. + * Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file. */ package org.jetbrains.kotlin.ir.declarations @@ -23,7 +12,8 @@ import org.jetbrains.kotlin.ir.symbols.IrSimpleFunctionSymbol interface IrSimpleFunction : IrFunction, IrSymbolDeclaration, - IrOverridableDeclaration { + IrOverridableDeclaration, + IrAttributeContainer { val modality: Modality val isTailrec: Boolean diff --git a/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/declarations/impl/IrFunctionImpl.kt b/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/declarations/impl/IrFunctionImpl.kt index a37710b351e..faa6f29c619 100644 --- a/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/declarations/impl/IrFunctionImpl.kt +++ b/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/declarations/impl/IrFunctionImpl.kt @@ -1,5 +1,5 @@ /* - * Copyright 2010-2018 JetBrains s.r.o. and Kotlin Programming Language contributors. + * Copyright 2010-2019 JetBrains s.r.o. and Kotlin Programming Language contributors. * Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file. */ @@ -8,6 +8,7 @@ package org.jetbrains.kotlin.ir.declarations.impl import org.jetbrains.kotlin.descriptors.FunctionDescriptor import org.jetbrains.kotlin.descriptors.Modality import org.jetbrains.kotlin.descriptors.Visibility +import org.jetbrains.kotlin.ir.declarations.IrAttributeContainer import org.jetbrains.kotlin.ir.declarations.IrDeclarationOrigin import org.jetbrains.kotlin.ir.declarations.IrSimpleFunction import org.jetbrains.kotlin.ir.symbols.IrPropertySymbol @@ -64,6 +65,7 @@ class IrFunctionImpl( override val descriptor: FunctionDescriptor = symbol.descriptor override val overriddenSymbols: MutableList = SmartList() + override var attributeOwnerId: IrAttributeContainer = this override var correspondingPropertySymbol: IrPropertySymbol? = null diff --git a/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/declarations/lazy/IrLazyFunction.kt b/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/declarations/lazy/IrLazyFunction.kt index 33464000aff..c8edc52d3b2 100644 --- a/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/declarations/lazy/IrLazyFunction.kt +++ b/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/declarations/lazy/IrLazyFunction.kt @@ -1,5 +1,5 @@ /* - * Copyright 2010-2018 JetBrains s.r.o. and Kotlin Programming Language contributors. + * Copyright 2010-2019 JetBrains s.r.o. and Kotlin Programming Language contributors. * Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file. */ @@ -8,6 +8,7 @@ package org.jetbrains.kotlin.ir.declarations.lazy import org.jetbrains.kotlin.descriptors.FunctionDescriptor import org.jetbrains.kotlin.descriptors.Modality import org.jetbrains.kotlin.descriptors.Visibility +import org.jetbrains.kotlin.ir.declarations.IrAttributeContainer import org.jetbrains.kotlin.ir.declarations.IrDeclarationOrigin import org.jetbrains.kotlin.ir.declarations.IrSimpleFunction import org.jetbrains.kotlin.ir.declarations.IrTypeParameter @@ -89,6 +90,7 @@ class IrLazyFunction( stubGenerator.generateFunctionStub(it.original).symbol } } + override var attributeOwnerId: IrAttributeContainer = this override var correspondingPropertySymbol: IrPropertySymbol? = null diff --git a/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/descriptors/IrOperators.kt b/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/descriptors/IrOperators.kt index 15e4d729eb3..972a543dff7 100644 --- a/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/descriptors/IrOperators.kt +++ b/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/descriptors/IrOperators.kt @@ -55,6 +55,7 @@ class IrBuiltInOperator( } override val overriddenSymbols: MutableList = SmartList() + override var attributeOwnerId: IrAttributeContainer = this override val mangle: String get() = "operator#$name@$suffix" init {