JVM IR: remove dependencies of lowerings on codegen

Move out utilities which are used both in lowerings and codegen to
JvmIrUtils and JvmIrTypeUtils, and introduce new JvmIrCoroutineUtils and
JvmIrInlineUtils (probably can be renamed or moved somewhere more
appropriate in the future).
This commit is contained in:
Alexander Udalov
2021-09-14 23:47:26 +02:00
parent 8ed0c17ebd
commit b0c5ea4717
46 changed files with 348 additions and 347 deletions
@@ -11,8 +11,8 @@ import org.jetbrains.kotlin.backend.common.lower.*
import org.jetbrains.kotlin.backend.common.lower.loops.forLoopsPhase
import org.jetbrains.kotlin.backend.common.lower.optimizations.foldConstantLoweringPhase
import org.jetbrains.kotlin.backend.common.phaser.*
import org.jetbrains.kotlin.backend.jvm.codegen.shouldContainSuspendMarkers
import org.jetbrains.kotlin.backend.jvm.ir.constantValue
import org.jetbrains.kotlin.backend.jvm.ir.shouldContainSuspendMarkers
import org.jetbrains.kotlin.backend.jvm.lower.*
import org.jetbrains.kotlin.descriptors.DescriptorVisibilities
import org.jetbrains.kotlin.descriptors.DescriptorVisibility
@@ -16,12 +16,7 @@ import org.jetbrains.kotlin.backend.common.push
import org.jetbrains.kotlin.backend.jvm.JvmBackendContext
import org.jetbrains.kotlin.backend.jvm.JvmLoweredDeclarationOrigin
import org.jetbrains.kotlin.backend.jvm.JvmLoweredStatementOrigin
import org.jetbrains.kotlin.backend.jvm.codegen.continuationParameter
import org.jetbrains.kotlin.backend.jvm.codegen.hasContinuation
import org.jetbrains.kotlin.backend.jvm.codegen.isInvokeSuspendOfContinuation
import org.jetbrains.kotlin.backend.jvm.codegen.isJvmInterface
import org.jetbrains.kotlin.backend.jvm.ir.defaultValue
import org.jetbrains.kotlin.backend.jvm.ir.suspendFunctionOriginal
import org.jetbrains.kotlin.backend.jvm.ir.*
import org.jetbrains.kotlin.backend.jvm.localDeclarationsPhase
import org.jetbrains.kotlin.codegen.coroutines.*
import org.jetbrains.kotlin.codegen.inline.coroutines.FOR_INLINE_SUFFIX
@@ -8,7 +8,7 @@ package org.jetbrains.kotlin.backend.jvm.lower
import org.jetbrains.kotlin.backend.common.ClassLoweringPass
import org.jetbrains.kotlin.backend.common.phaser.makeIrFilePhase
import org.jetbrains.kotlin.backend.jvm.JvmBackendContext
import org.jetbrains.kotlin.backend.jvm.codegen.getAnnotationRetention
import org.jetbrains.kotlin.backend.jvm.ir.getAnnotationRetention
import org.jetbrains.kotlin.builtins.StandardNames
import org.jetbrains.kotlin.descriptors.annotations.KotlinTarget
import org.jetbrains.kotlin.ir.UNDEFINED_OFFSET
@@ -18,7 +18,6 @@ import org.jetbrains.kotlin.backend.common.phaser.makeIrFilePhase
import org.jetbrains.kotlin.backend.jvm.JvmBackendContext
import org.jetbrains.kotlin.backend.jvm.JvmLoweredDeclarationOrigin
import org.jetbrains.kotlin.backend.jvm.SpecialBridge
import org.jetbrains.kotlin.backend.jvm.codegen.isJvmInterface
import org.jetbrains.kotlin.backend.jvm.ir.*
import org.jetbrains.kotlin.codegen.AsmUtil
import org.jetbrains.kotlin.descriptors.DescriptorVisibilities
@@ -9,7 +9,8 @@ import org.jetbrains.kotlin.backend.common.FileLoweringPass
import org.jetbrains.kotlin.backend.common.phaser.makeIrModulePhase
import org.jetbrains.kotlin.backend.jvm.JvmBackendContext
import org.jetbrains.kotlin.ir.IrElement
import org.jetbrains.kotlin.ir.declarations.*
import org.jetbrains.kotlin.ir.declarations.IrDeclarationWithName
import org.jetbrains.kotlin.ir.declarations.IrFile
import org.jetbrains.kotlin.ir.expressions.IrLoop
import org.jetbrains.kotlin.ir.visitors.IrElementVisitor
@@ -10,7 +10,7 @@ import org.jetbrains.kotlin.backend.common.lower.createIrBuilder
import org.jetbrains.kotlin.backend.common.phaser.makeIrFilePhase
import org.jetbrains.kotlin.backend.jvm.JvmBackendContext
import org.jetbrains.kotlin.backend.jvm.caches.StubsForCollectionClass
import org.jetbrains.kotlin.backend.jvm.codegen.isJvmInterface
import org.jetbrains.kotlin.backend.jvm.ir.isJvmInterface
import org.jetbrains.kotlin.descriptors.Modality
import org.jetbrains.kotlin.ir.builders.declarations.buildFun
import org.jetbrains.kotlin.ir.builders.declarations.buildValueParameter
@@ -9,8 +9,8 @@ import org.jetbrains.kotlin.backend.common.FileLoweringPass
import org.jetbrains.kotlin.backend.common.lower.createIrBuilder
import org.jetbrains.kotlin.backend.common.phaser.makeIrFilePhase
import org.jetbrains.kotlin.backend.jvm.JvmBackendContext
import org.jetbrains.kotlin.backend.jvm.codegen.isInlineOnly
import org.jetbrains.kotlin.backend.jvm.ir.IrInlineReferenceLocator
import org.jetbrains.kotlin.backend.jvm.ir.isInlineOnly
import org.jetbrains.kotlin.codegen.inline.coroutines.FOR_INLINE_SUFFIX
import org.jetbrains.kotlin.ir.builders.createTmpVariable
import org.jetbrains.kotlin.ir.builders.irBlockBody
@@ -17,7 +17,7 @@ import org.jetbrains.kotlin.backend.common.phaser.makeCustomPhase
import org.jetbrains.kotlin.backend.jvm.JvmBackendContext
import org.jetbrains.kotlin.backend.jvm.JvmLoweredDeclarationOrigin
import org.jetbrains.kotlin.backend.jvm.MultifileFacadeFileEntry
import org.jetbrains.kotlin.backend.jvm.codegen.fileParent
import org.jetbrains.kotlin.backend.jvm.ir.fileParent
import org.jetbrains.kotlin.backend.jvm.ir.getKtFile
import org.jetbrains.kotlin.backend.jvm.isMultifileBridge
import org.jetbrains.kotlin.config.JvmAnalysisFlags
@@ -15,7 +15,6 @@ import org.jetbrains.kotlin.backend.common.lower.createIrBuilder
import org.jetbrains.kotlin.backend.common.phaser.makeIrFilePhase
import org.jetbrains.kotlin.backend.jvm.JvmBackendContext
import org.jetbrains.kotlin.backend.jvm.JvmLoweredDeclarationOrigin
import org.jetbrains.kotlin.backend.jvm.codegen.isJvmInterface
import org.jetbrains.kotlin.backend.jvm.ir.*
import org.jetbrains.kotlin.builtins.StandardNames
import org.jetbrains.kotlin.config.JvmDefaultMode
@@ -11,9 +11,9 @@ import org.jetbrains.kotlin.backend.common.phaser.makeIrFilePhase
import org.jetbrains.kotlin.backend.jvm.JvmBackendContext
import org.jetbrains.kotlin.backend.jvm.JvmLoweredDeclarationOrigin
import org.jetbrains.kotlin.backend.jvm.JvmLoweredStatementOrigin
import org.jetbrains.kotlin.backend.jvm.codegen.isInlineFunctionCall
import org.jetbrains.kotlin.backend.jvm.ir.createJvmIrBuilder
import org.jetbrains.kotlin.backend.jvm.ir.irArray
import org.jetbrains.kotlin.backend.jvm.ir.isInlineFunctionCall
import org.jetbrains.kotlin.backend.jvm.ir.isInlineParameter
import org.jetbrains.kotlin.descriptors.DescriptorVisibilities
import org.jetbrains.kotlin.ir.IrElement
@@ -10,20 +10,17 @@ import org.jetbrains.kotlin.backend.common.ir.isMethodOfAny
import org.jetbrains.kotlin.backend.common.ir.moveBodyTo
import org.jetbrains.kotlin.backend.jvm.JvmBackendContext
import org.jetbrains.kotlin.backend.jvm.JvmLoweredDeclarationOrigin
import org.jetbrains.kotlin.backend.jvm.codegen.isJvmInterface
import org.jetbrains.kotlin.backend.jvm.ir.*
import org.jetbrains.kotlin.config.JvmDefaultMode
import org.jetbrains.kotlin.descriptors.ClassKind
import org.jetbrains.kotlin.descriptors.Modality
import org.jetbrains.kotlin.descriptors.DescriptorVisibilities
import org.jetbrains.kotlin.descriptors.Visibilities
import org.jetbrains.kotlin.descriptors.Modality
import org.jetbrains.kotlin.ir.declarations.*
import org.jetbrains.kotlin.ir.expressions.IrCall
import org.jetbrains.kotlin.ir.expressions.IrExpression
import org.jetbrains.kotlin.ir.expressions.IrFunctionReference
import org.jetbrains.kotlin.ir.expressions.IrReturn
import org.jetbrains.kotlin.ir.expressions.impl.*
import org.jetbrains.kotlin.ir.symbols.IrLocalDelegatedPropertySymbol
import org.jetbrains.kotlin.ir.symbols.IrSimpleFunctionSymbol
import org.jetbrains.kotlin.ir.types.defaultType
import org.jetbrains.kotlin.ir.util.*
@@ -12,8 +12,8 @@ import org.jetbrains.kotlin.backend.common.phaser.makeIrModulePhase
import org.jetbrains.kotlin.backend.jvm.CachedFieldsForObjectInstances
import org.jetbrains.kotlin.backend.jvm.JvmBackendContext
import org.jetbrains.kotlin.backend.jvm.JvmLoweredDeclarationOrigin
import org.jetbrains.kotlin.backend.jvm.codegen.isEffectivelyInlineOnly
import org.jetbrains.kotlin.backend.jvm.codegen.isInlineFunctionCall
import org.jetbrains.kotlin.backend.jvm.ir.isEffectivelyInlineOnly
import org.jetbrains.kotlin.backend.jvm.ir.isInlineFunctionCall
import org.jetbrains.kotlin.backend.jvm.ir.replaceThisByStaticReference
import org.jetbrains.kotlin.descriptors.DescriptorVisibilities
import org.jetbrains.kotlin.ir.IrBuiltIns
@@ -8,7 +8,7 @@ package org.jetbrains.kotlin.backend.jvm.lower
import org.jetbrains.kotlin.backend.common.FileLoweringPass
import org.jetbrains.kotlin.backend.common.phaser.makeIrModulePhase
import org.jetbrains.kotlin.backend.jvm.JvmBackendContext
import org.jetbrains.kotlin.backend.jvm.codegen.isOptionalAnnotationClass
import org.jetbrains.kotlin.backend.jvm.ir.isOptionalAnnotationClass
import org.jetbrains.kotlin.ir.declarations.DescriptorMetadataSource
import org.jetbrains.kotlin.ir.declarations.IrClass
import org.jetbrains.kotlin.ir.declarations.IrFile
@@ -22,7 +22,7 @@ internal val processOptionalAnnotationsPhase = makeIrModulePhase(
class ProcessOptionalAnnotations(private val context: JvmBackendContext) : FileLoweringPass {
override fun lower(irFile: IrFile) {
for (declaration in irFile.declarations) {
if (declaration !is IrClass || !declaration.isOptionalAnnotationClass()) continue
if (declaration !is IrClass || !declaration.isOptionalAnnotationClass) continue
// TODO FirMetadataSource.Class
val metadataSource = (declaration.metadata as? DescriptorMetadataSource.Class)?.descriptor ?: continue
context.state.factory.packagePartRegistry.optionalAnnotations += metadataSource
@@ -10,8 +10,8 @@ import org.jetbrains.kotlin.backend.common.lower.createIrBuilder
import org.jetbrains.kotlin.backend.common.lower.parents
import org.jetbrains.kotlin.backend.common.phaser.makeIrFilePhase
import org.jetbrains.kotlin.backend.jvm.JvmBackendContext
import org.jetbrains.kotlin.backend.jvm.codegen.fileParent
import org.jetbrains.kotlin.backend.jvm.ir.createJvmIrBuilder
import org.jetbrains.kotlin.backend.jvm.ir.fileParent
import org.jetbrains.kotlin.backend.jvm.lower.JvmPropertiesLowering.Companion.createSyntheticMethodForPropertyDelegate
import org.jetbrains.kotlin.builtins.StandardNames
import org.jetbrains.kotlin.descriptors.Modality
@@ -13,7 +13,6 @@ import org.jetbrains.kotlin.backend.common.ir.createImplicitParameterDeclaration
import org.jetbrains.kotlin.backend.common.lower.createIrBuilder
import org.jetbrains.kotlin.backend.common.phaser.makeIrFilePhase
import org.jetbrains.kotlin.backend.jvm.*
import org.jetbrains.kotlin.backend.jvm.codegen.parentClassId
import org.jetbrains.kotlin.backend.jvm.ir.*
import org.jetbrains.kotlin.backend.jvm.lower.FunctionReferenceLowering.Companion.calculateOwner
import org.jetbrains.kotlin.backend.jvm.lower.FunctionReferenceLowering.Companion.calculateOwnerKClass
@@ -9,11 +9,10 @@ import org.jetbrains.kotlin.backend.common.FileLoweringPass
import org.jetbrains.kotlin.backend.common.IrElementTransformerVoidWithContext
import org.jetbrains.kotlin.backend.common.phaser.makeIrModulePhase
import org.jetbrains.kotlin.backend.jvm.JvmBackendContext
import org.jetbrains.kotlin.backend.jvm.JvmReflectSymbols
import org.jetbrains.kotlin.backend.jvm.codegen.isJvmInterface
import org.jetbrains.kotlin.backend.jvm.ir.IrInlineScopeResolver
import org.jetbrains.kotlin.backend.jvm.ir.createJvmIrBuilder
import org.jetbrains.kotlin.backend.jvm.ir.findInlineCallSites
import org.jetbrains.kotlin.backend.jvm.ir.isJvmInterface
import org.jetbrains.kotlin.backend.jvm.lower.SyntheticAccessorLowering.Companion.isAccessible
import org.jetbrains.kotlin.ir.builders.*
import org.jetbrains.kotlin.ir.declarations.IrFile
@@ -8,7 +8,6 @@ package org.jetbrains.kotlin.backend.jvm.lower
import org.jetbrains.kotlin.backend.common.FileLoweringPass
import org.jetbrains.kotlin.backend.common.phaser.makeIrModulePhase
import org.jetbrains.kotlin.backend.jvm.JvmBackendContext
import org.jetbrains.kotlin.backend.jvm.codegen.AnnotationCodegen.Companion.annotationClass
import org.jetbrains.kotlin.builtins.StandardNames
import org.jetbrains.kotlin.descriptors.ClassKind
import org.jetbrains.kotlin.ir.IrElement
@@ -22,10 +21,7 @@ import org.jetbrains.kotlin.ir.expressions.impl.IrConstructorCallImpl
import org.jetbrains.kotlin.ir.expressions.impl.IrVarargImpl
import org.jetbrains.kotlin.ir.symbols.IrClassSymbol
import org.jetbrains.kotlin.ir.types.typeWith
import org.jetbrains.kotlin.ir.util.defaultType
import org.jetbrains.kotlin.ir.util.hasAnnotation
import org.jetbrains.kotlin.ir.util.isAnnotation
import org.jetbrains.kotlin.ir.util.primaryConstructor
import org.jetbrains.kotlin.ir.util.*
import org.jetbrains.kotlin.ir.visitors.IrElementVisitorVoid
import org.jetbrains.kotlin.ir.visitors.acceptChildrenVoid
import org.jetbrains.kotlin.ir.visitors.acceptVoid
@@ -69,12 +65,12 @@ class RepeatedAnnotationLowering(private val context: JvmBackendContext) : FileL
private fun transformAnnotations(annotations: List<IrConstructorCall>): List<IrConstructorCall> {
if (annotations.size < 2) return annotations
val annotationsByClass = annotations.groupByTo(mutableMapOf()) { it.annotationClass }
val annotationsByClass = annotations.groupByTo(mutableMapOf()) { it.symbol.owner.constructedClass }
if (annotationsByClass.values.none { it.size > 1 }) return annotations
val result = mutableListOf<IrConstructorCall>()
for (annotation in annotations) {
val annotationClass = annotation.annotationClass
val annotationClass = annotation.symbol.owner.constructedClass
val grouped = annotationsByClass.remove(annotationClass) ?: continue
if (grouped.size < 2) {
result.add(grouped.single())
@@ -8,7 +8,7 @@ package org.jetbrains.kotlin.backend.jvm.lower
import org.jetbrains.kotlin.backend.common.FileLoweringPass
import org.jetbrains.kotlin.backend.common.phaser.makeIrModulePhase
import org.jetbrains.kotlin.backend.jvm.JvmBackendContext
import org.jetbrains.kotlin.backend.jvm.codegen.isInlineFunctionCall
import org.jetbrains.kotlin.backend.jvm.ir.isInlineFunctionCall
import org.jetbrains.kotlin.backend.jvm.isMultifileBridge
import org.jetbrains.kotlin.ir.declarations.IrFile
import org.jetbrains.kotlin.ir.declarations.IrFunction
@@ -7,15 +7,18 @@ package org.jetbrains.kotlin.backend.jvm.lower
import org.jetbrains.kotlin.backend.common.FileLoweringPass
import org.jetbrains.kotlin.backend.common.IrElementTransformerVoidWithContext
import org.jetbrains.kotlin.backend.common.ir.*
import org.jetbrains.kotlin.backend.common.ir.copyTo
import org.jetbrains.kotlin.backend.common.ir.createImplicitParameterDeclarationWithWrappedDescriptor
import org.jetbrains.kotlin.backend.common.ir.isSuspend
import org.jetbrains.kotlin.backend.common.ir.moveBodyTo
import org.jetbrains.kotlin.backend.common.lower.LocalDeclarationsLowering
import org.jetbrains.kotlin.backend.common.lower.createIrBuilder
import org.jetbrains.kotlin.backend.common.lower.parents
import org.jetbrains.kotlin.backend.common.phaser.makeIrFilePhase
import org.jetbrains.kotlin.backend.jvm.JvmBackendContext
import org.jetbrains.kotlin.backend.jvm.JvmLoweredDeclarationOrigin
import org.jetbrains.kotlin.backend.jvm.codegen.isReadOfCrossinline
import org.jetbrains.kotlin.backend.jvm.ir.hasChild
import org.jetbrains.kotlin.backend.jvm.ir.isReadOfCrossinline
import org.jetbrains.kotlin.codegen.coroutines.COROUTINE_LABEL_FIELD_NAME
import org.jetbrains.kotlin.codegen.coroutines.INVOKE_SUSPEND_METHOD_NAME
import org.jetbrains.kotlin.codegen.coroutines.SUSPEND_FUNCTION_COMPLETION_PARAMETER_NAME
@@ -28,18 +31,25 @@ import org.jetbrains.kotlin.ir.UNDEFINED_OFFSET
import org.jetbrains.kotlin.ir.builders.*
import org.jetbrains.kotlin.ir.builders.declarations.*
import org.jetbrains.kotlin.ir.declarations.*
import org.jetbrains.kotlin.ir.expressions.*
import org.jetbrains.kotlin.ir.expressions.IrBlock
import org.jetbrains.kotlin.ir.expressions.IrExpression
import org.jetbrains.kotlin.ir.expressions.IrFunctionReference
import org.jetbrains.kotlin.ir.expressions.IrGetValue
import org.jetbrains.kotlin.ir.expressions.impl.*
import org.jetbrains.kotlin.ir.symbols.IrSimpleFunctionSymbol
import org.jetbrains.kotlin.ir.symbols.IrValueParameterSymbol
import org.jetbrains.kotlin.ir.types.*
import org.jetbrains.kotlin.ir.util.*
import org.jetbrains.kotlin.ir.visitors.*
import org.jetbrains.kotlin.ir.visitors.IrElementTransformerVoid
import org.jetbrains.kotlin.ir.visitors.IrElementVisitorVoid
import org.jetbrains.kotlin.ir.visitors.acceptChildrenVoid
import org.jetbrains.kotlin.ir.visitors.transformChildrenVoid
import org.jetbrains.kotlin.load.java.JavaDescriptorVisibilities
import org.jetbrains.kotlin.name.Name
import org.jetbrains.kotlin.name.SpecialNames
import org.jetbrains.kotlin.resolve.jvm.AsmTypes
import org.jetbrains.org.objectweb.asm.Type
import kotlin.collections.set
internal val suspendLambdaPhase = makeIrFilePhase(
::SuspendLambdaLowering,
@@ -12,12 +12,8 @@ import org.jetbrains.kotlin.backend.common.descriptors.synthesizedString
import org.jetbrains.kotlin.backend.common.ir.*
import org.jetbrains.kotlin.backend.jvm.JvmBackendContext
import org.jetbrains.kotlin.backend.jvm.JvmLoweredDeclarationOrigin
import org.jetbrains.kotlin.backend.jvm.codegen.isJvmInterface
import org.jetbrains.kotlin.backend.jvm.hasMangledParameters
import org.jetbrains.kotlin.backend.jvm.intrinsics.receiverAndArgs
import org.jetbrains.kotlin.backend.jvm.ir.IrInlineScopeResolver
import org.jetbrains.kotlin.backend.jvm.ir.findInlineCallSites
import org.jetbrains.kotlin.backend.jvm.ir.isAssertionsDisabledField
import org.jetbrains.kotlin.backend.jvm.ir.*
import org.jetbrains.kotlin.codegen.AsmUtil
import org.jetbrains.kotlin.descriptors.DescriptorVisibilities
import org.jetbrains.kotlin.descriptors.DescriptorVisibility
@@ -10,7 +10,7 @@ import org.jetbrains.kotlin.backend.common.lower.createIrBuilder
import org.jetbrains.kotlin.backend.common.phaser.makeIrFilePhase
import org.jetbrains.kotlin.backend.jvm.JvmBackendContext
import org.jetbrains.kotlin.backend.jvm.JvmLoweredDeclarationOrigin
import org.jetbrains.kotlin.backend.jvm.codegen.isJvmInterface
import org.jetbrains.kotlin.backend.jvm.ir.isJvmInterface
import org.jetbrains.kotlin.descriptors.DescriptorVisibilities
import org.jetbrains.kotlin.descriptors.Modality
import org.jetbrains.kotlin.ir.builders.declarations.addDispatchReceiver
@@ -16,9 +16,7 @@ import org.jetbrains.kotlin.backend.common.pop
import org.jetbrains.kotlin.backend.common.push
import org.jetbrains.kotlin.backend.jvm.JvmBackendContext
import org.jetbrains.kotlin.backend.jvm.JvmLoweredDeclarationOrigin
import org.jetbrains.kotlin.backend.jvm.codegen.fileParent
import org.jetbrains.kotlin.backend.jvm.intrinsics.generateMethodHandle
import org.jetbrains.kotlin.backend.jvm.intrinsics.getBooleanConstArgument
import org.jetbrains.kotlin.backend.jvm.ir.*
import org.jetbrains.kotlin.backend.jvm.unboxInlineClass
import org.jetbrains.kotlin.descriptors.DescriptorVisibilities
@@ -8,9 +8,9 @@ package org.jetbrains.kotlin.backend.jvm
import org.jetbrains.kotlin.backend.common.ir.*
import org.jetbrains.kotlin.backend.common.lower.createIrBuilder
import org.jetbrains.kotlin.backend.jvm.codegen.AnnotationCodegen.Companion.annotationClass
import org.jetbrains.kotlin.backend.jvm.codegen.isJvmInterface
import org.jetbrains.kotlin.backend.jvm.ir.copyCorrespondingPropertyFrom
import org.jetbrains.kotlin.backend.jvm.ir.createJvmIrBuilder
import org.jetbrains.kotlin.backend.jvm.ir.isJvmInterface
import org.jetbrains.kotlin.backend.jvm.ir.replaceThisByStaticReference
import org.jetbrains.kotlin.builtins.CompanionObjectMapping
import org.jetbrains.kotlin.builtins.StandardNames
@@ -11,10 +11,10 @@ import org.jetbrains.kotlin.backend.common.ir.copyTypeParametersFrom
import org.jetbrains.kotlin.backend.common.ir.createDispatchReceiverParameter
import org.jetbrains.kotlin.backend.jvm.codegen.classFileContainsMethod
import org.jetbrains.kotlin.backend.jvm.codegen.extensionReceiverName
import org.jetbrains.kotlin.backend.jvm.codegen.isJvmInterface
import org.jetbrains.kotlin.backend.jvm.codegen.parentClassId
import org.jetbrains.kotlin.backend.jvm.ir.isCompiledToJvmDefault
import org.jetbrains.kotlin.backend.jvm.ir.isJvmInterface
import org.jetbrains.kotlin.backend.jvm.ir.isStaticInlineClassReplacement
import org.jetbrains.kotlin.backend.jvm.ir.parentClassId
import org.jetbrains.kotlin.codegen.state.KotlinTypeMapper
import org.jetbrains.kotlin.descriptors.DescriptorVisibilities
import org.jetbrains.kotlin.descriptors.Modality
@@ -22,16 +22,13 @@ import org.jetbrains.kotlin.backend.common.ir.ir2string
import org.jetbrains.kotlin.backend.jvm.JvmBackendContext
import org.jetbrains.kotlin.backend.jvm.JvmLoweredDeclarationOrigin
import org.jetbrains.kotlin.backend.jvm.JvmSymbols
import org.jetbrains.kotlin.backend.jvm.ir.erasedUpperBound
import org.jetbrains.kotlin.backend.jvm.ir.isInlineClassType
import org.jetbrains.kotlin.backend.jvm.ir.isWithFlexibleNullability
import org.jetbrains.kotlin.backend.jvm.ir.*
import org.jetbrains.kotlin.builtins.StandardNames
import org.jetbrains.kotlin.codegen.AsmUtil
import org.jetbrains.kotlin.codegen.TypeAnnotationCollector
import org.jetbrains.kotlin.codegen.TypePathInfo
import org.jetbrains.kotlin.config.JVMConfigurationKeys
import org.jetbrains.kotlin.config.JvmTarget.JVM_1_6
import org.jetbrains.kotlin.descriptors.ClassKind
import org.jetbrains.kotlin.descriptors.DescriptorVisibilities
import org.jetbrains.kotlin.descriptors.annotations.KotlinRetention
import org.jetbrains.kotlin.descriptors.annotations.KotlinTarget
@@ -39,12 +36,10 @@ import org.jetbrains.kotlin.ir.declarations.*
import org.jetbrains.kotlin.ir.expressions.*
import org.jetbrains.kotlin.ir.symbols.IrEnumEntrySymbol
import org.jetbrains.kotlin.ir.types.*
import org.jetbrains.kotlin.ir.types.impl.buildSimpleType
import org.jetbrains.kotlin.ir.util.*
import org.jetbrains.kotlin.load.java.JvmAnnotationNames
import org.jetbrains.kotlin.name.FqName
import org.jetbrains.kotlin.name.Name
import org.jetbrains.kotlin.resolve.multiplatform.OptionalAnnotationUtil
import org.jetbrains.kotlin.types.TypeSystemCommonBackendContext
import org.jetbrains.kotlin.types.model.KotlinTypeMarker
import org.jetbrains.org.objectweb.asm.AnnotationVisitor
@@ -198,9 +193,7 @@ abstract class AnnotationCodegen(
// We do not generate annotations whose classes are optional (annotated with `@OptionalExpectation`) because if an annotation entry
// is resolved to the expected declaration, this means that annotation has no actual class, and thus should not be generated.
// (Otherwise we would've resolved the entry to the actual annotation class.)
if (annotationClass.isOptionalAnnotationClass) {
return null
}
if (annotationClass.isOptionalAnnotationClass) return null
innerClassConsumer.addInnerClassInfoFromAnnotation(annotationClass)
@@ -450,22 +443,6 @@ private fun isBareTypeParameterWithNullableUpperBound(type: IrType): Boolean {
return type.classifierOrNull?.owner is IrTypeParameter && !type.isMarkedNullable() && type.isNullable()
}
private val RETENTION_PARAMETER_NAME = Name.identifier("value")
fun IrClass.getAnnotationRetention(): KotlinRetention? {
val retentionArgument =
getAnnotation(StandardNames.FqNames.retention)?.getValueArgument(RETENTION_PARAMETER_NAME)
as? IrGetEnumValue ?: return null
val retentionArgumentValue = retentionArgument.symbol.owner
return KotlinRetention.valueOf(retentionArgumentValue.name.asString())
}
// To be generalized to IrMemberAccessExpression as soon as properties get symbols.
private fun IrConstructorCall.getValueArgument(name: Name): IrExpression? {
val index = symbol.owner.valueParameters.find { it.name == name }?.index ?: return null
return getValueArgument(index)
}
// Copied and modified from AnnotationChecker.kt
private val TARGET_ALLOWED_TARGETS = Name.identifier("allowedTargets")
@@ -482,9 +459,3 @@ private fun loadAnnotationTargets(targetEntry: IrConstructorCall): Set<KotlinTar
KotlinTarget.valueOrNull(it.symbol.owner.name.asString())
}.toSet()
}
// From ExpectedActualDeclarationChecker
private val IrClass.isOptionalAnnotationClass: Boolean
get() = kind == ClassKind.ANNOTATION_CLASS &&
isExpect &&
hasAnnotation(OptionalAnnotationUtil.OPTIONAL_EXPECTATION_FQ_NAME)
@@ -7,19 +7,22 @@ package org.jetbrains.kotlin.backend.jvm.codegen
import org.jetbrains.kotlin.backend.common.CodegenUtil
import org.jetbrains.kotlin.backend.common.ir.allOverridden
import org.jetbrains.kotlin.backend.common.lower.LocalDeclarationsLowering
import org.jetbrains.kotlin.backend.jvm.*
import org.jetbrains.kotlin.backend.jvm.InlineClassAbi
import org.jetbrains.kotlin.backend.jvm.JvmLoweredDeclarationOrigin
import org.jetbrains.kotlin.backend.jvm.ir.erasedUpperBound
import org.jetbrains.kotlin.backend.jvm.ir.isStaticInlineClassReplacement
import org.jetbrains.kotlin.backend.jvm.ir.hasContinuation
import org.jetbrains.kotlin.backend.jvm.ir.isReadOfCrossinline
import org.jetbrains.kotlin.backend.jvm.ir.suspendFunctionOriginal
import org.jetbrains.kotlin.backend.jvm.unboxInlineClass
import org.jetbrains.kotlin.codegen.ClassBuilder
import org.jetbrains.kotlin.codegen.coroutines.CoroutineTransformerMethodVisitor
import org.jetbrains.kotlin.codegen.coroutines.INVOKE_SUSPEND_METHOD_NAME
import org.jetbrains.kotlin.codegen.coroutines.SUSPEND_IMPL_NAME_SUFFIX
import org.jetbrains.kotlin.codegen.coroutines.reportSuspensionPointInsideMonitor
import org.jetbrains.kotlin.config.LanguageFeature
import org.jetbrains.kotlin.ir.declarations.*
import org.jetbrains.kotlin.ir.expressions.*
import org.jetbrains.kotlin.ir.expressions.IrBlockBody
import org.jetbrains.kotlin.ir.expressions.IrExpression
import org.jetbrains.kotlin.ir.expressions.IrGetValue
import org.jetbrains.kotlin.ir.expressions.IrStatementOrigin
import org.jetbrains.kotlin.ir.types.*
import org.jetbrains.kotlin.ir.util.*
import org.jetbrains.kotlin.psi.KtElement
@@ -101,81 +104,6 @@ internal fun IrFunction.continuationClass(): IrClass? =
(body as? IrBlockBody)?.statements?.find { it is IrClass && it.origin == JvmLoweredDeclarationOrigin.CONTINUATION_CLASS }
as IrClass?
fun IrFunction.continuationParameter(): IrValueParameter? = when {
isInvokeSuspendOfLambda() || isInvokeSuspendForInlineOfLambda() -> dispatchReceiverParameter
else -> valueParameters.singleOrNull { it.origin == JvmLoweredDeclarationOrigin.CONTINUATION_CLASS }
}
internal fun IrFunction.isInvokeSuspendOfLambda(): Boolean =
name.asString() == INVOKE_SUSPEND_METHOD_NAME && parentAsClass.origin == JvmLoweredDeclarationOrigin.SUSPEND_LAMBDA
private fun IrFunction.isInvokeSuspendForInlineOfLambda(): Boolean =
origin == JvmLoweredDeclarationOrigin.FOR_INLINE_STATE_MACHINE_TEMPLATE
&& parentAsClass.origin == JvmLoweredDeclarationOrigin.SUSPEND_LAMBDA
fun IrFunction.isInvokeSuspendOfContinuation(): Boolean =
name.asString() == INVOKE_SUSPEND_METHOD_NAME && parentAsClass.origin == JvmLoweredDeclarationOrigin.CONTINUATION_CLASS
private fun IrFunction.isInvokeOfSuspendCallableReference(): Boolean =
isSuspend && name.asString().let { name -> name == "invoke" || name.startsWith("invoke-") }
&& parentAsClass.origin == JvmLoweredDeclarationOrigin.FUNCTION_REFERENCE_IMPL
private fun IrFunction.isBridgeToSuspendImplMethod(): Boolean =
isSuspend && this is IrSimpleFunction && parentAsClass.functions.any {
it.name.asString() == name.asString() + SUSPEND_IMPL_NAME_SUFFIX && it.attributeOwnerId == attributeOwnerId
}
private fun IrFunction.isStaticInlineClassReplacementDelegatingCall(): Boolean =
this is IrAttributeContainer && !isStaticInlineClassReplacement &&
(parent as? IrClass)?.declarations?.find { it is IrAttributeContainer && it.attributeOwnerId == attributeOwnerId && it !== this }
?.isStaticInlineClassReplacement == true
private val BRIDGE_ORIGINS = setOf(
IrDeclarationOrigin.FUNCTION_FOR_DEFAULT_PARAMETER,
JvmLoweredDeclarationOrigin.JVM_STATIC_WRAPPER,
JvmLoweredDeclarationOrigin.JVM_OVERLOADS_WRAPPER,
JvmLoweredDeclarationOrigin.SYNTHETIC_ACCESSOR,
JvmLoweredDeclarationOrigin.SYNTHETIC_ACCESSOR_FOR_HIDDEN_CONSTRUCTOR,
JvmLoweredDeclarationOrigin.SUPER_INTERFACE_METHOD_BRIDGE,
IrDeclarationOrigin.BRIDGE,
IrDeclarationOrigin.BRIDGE_SPECIAL,
)
// These functions contain a single `suspend` tail call, the value of which should be returned as is
// (i.e. if it's an unboxed inline class value, it should remain unboxed).
internal fun IrFunction.isNonBoxingSuspendDelegation(): Boolean =
origin in BRIDGE_ORIGINS ||
isMultifileBridge() ||
isBridgeToSuspendImplMethod() ||
isStaticInlineClassReplacementForDefaultInterfaceMethod()
// Suspend static inline class replacements for fake overrides have to be for interface methods as inline classes cannot have a
// non-Object super type.
fun IrFunction.isStaticInlineClassReplacementForDefaultInterfaceMethod(): Boolean =
isStaticInlineClassReplacement && this is IrSimpleFunction && (attributeOwnerId as IrSimpleFunction).isFakeOverride
fun IrFunction.shouldContainSuspendMarkers(): Boolean = !isNonBoxingSuspendDelegation() &&
// These functions also contain a single `suspend` tail call, but if it returns an unboxed inline class value,
// the return of it should be checked for a suspension and potentially boxed to satisfy an interface.
origin != IrDeclarationOrigin.DELEGATED_MEMBER &&
!isInvokeSuspendOfContinuation() &&
!isInvokeOfSuspendCallableReference() &&
!isStaticInlineClassReplacementDelegatingCall()
fun IrFunction.hasContinuation(): Boolean = isInvokeSuspendOfLambda() ||
isSuspend && shouldContainSuspendMarkers() &&
// These are templates for the inliner; the continuation is borrowed from the caller method.
!isEffectivelyInlineOnly() &&
origin != JvmLoweredDeclarationOrigin.INLINE_LAMBDA &&
origin != JvmLoweredDeclarationOrigin.FOR_INLINE_STATE_MACHINE_TEMPLATE &&
origin != JvmLoweredDeclarationOrigin.FOR_INLINE_STATE_MACHINE_TEMPLATE_CAPTURES_CROSSINLINE
fun IrExpression?.isReadOfCrossinline(): Boolean = when (this) {
is IrGetValue -> (symbol.owner as? IrValueParameter)?.isCrossinline == true
is IrGetField -> symbol.owner.origin == LocalDeclarationsLowering.DECLARATION_ORIGIN_FIELD_FOR_CROSSINLINE_CAPTURED_VALUE
else -> false
}
internal fun IrExpression?.isReadOfInlineLambda(): Boolean = isReadOfCrossinline() ||
(this is IrGetValue && origin == IrStatementOrigin.VARIABLE_AS_FUNCTION && (symbol.owner as? IrValueParameter)?.isNoinline == false)
@@ -10,9 +10,7 @@ import org.jetbrains.kotlin.backend.common.lower.LoweredStatementOrigins
import org.jetbrains.kotlin.backend.jvm.*
import org.jetbrains.kotlin.backend.jvm.intrinsics.IrIntrinsicMethods
import org.jetbrains.kotlin.backend.jvm.intrinsics.JavaClassProperty
import org.jetbrains.kotlin.backend.jvm.ir.constantValue
import org.jetbrains.kotlin.backend.jvm.ir.eraseTypeParameters
import org.jetbrains.kotlin.backend.jvm.ir.isInlineClassType
import org.jetbrains.kotlin.backend.jvm.ir.*
import org.jetbrains.kotlin.builtins.StandardNames
import org.jetbrains.kotlin.codegen.*
import org.jetbrains.kotlin.codegen.AsmUtil.*
@@ -11,6 +11,8 @@ import org.jetbrains.kotlin.backend.common.lower.BOUND_RECEIVER_PARAMETER
import org.jetbrains.kotlin.backend.common.lower.BOUND_VALUE_PARAMETER
import org.jetbrains.kotlin.backend.jvm.JvmBackendContext
import org.jetbrains.kotlin.backend.jvm.JvmLoweredDeclarationOrigin
import org.jetbrains.kotlin.backend.jvm.ir.isJvmInterface
import org.jetbrains.kotlin.backend.jvm.ir.isReifiable
import org.jetbrains.kotlin.backend.jvm.ir.suspendFunctionOriginal
import org.jetbrains.kotlin.codegen.AsmUtil
import org.jetbrains.kotlin.codegen.inline.*
@@ -5,24 +5,25 @@
package org.jetbrains.kotlin.backend.jvm.codegen
import org.jetbrains.kotlin.backend.jvm.JvmBackendContext
import org.jetbrains.kotlin.backend.jvm.JvmLoweredStatementOrigin
import org.jetbrains.kotlin.backend.jvm.ir.isInlineOnly
import org.jetbrains.kotlin.backend.jvm.ir.isInlineParameter
import org.jetbrains.kotlin.backend.jvm.ir.unwrapInlineLambda
import org.jetbrains.kotlin.codegen.IrExpressionLambda
import org.jetbrains.kotlin.codegen.JvmKotlinType
import org.jetbrains.kotlin.codegen.StackValue
import org.jetbrains.kotlin.codegen.ValueKind
import org.jetbrains.kotlin.codegen.inline.*
import org.jetbrains.kotlin.codegen.state.GenerationState
import org.jetbrains.kotlin.ir.IrStatement
import org.jetbrains.kotlin.ir.declarations.IrConstructor
import org.jetbrains.kotlin.ir.declarations.IrDeclarationOrigin
import org.jetbrains.kotlin.ir.declarations.IrFunction
import org.jetbrains.kotlin.ir.declarations.IrValueParameter
import org.jetbrains.kotlin.ir.descriptors.toIrBasedKotlinType
import org.jetbrains.kotlin.ir.expressions.*
import org.jetbrains.kotlin.ir.types.IrType
import org.jetbrains.kotlin.ir.util.*
import org.jetbrains.kotlin.ir.util.dump
import org.jetbrains.kotlin.ir.util.explicitParameters
import org.jetbrains.kotlin.ir.util.getArgumentsWithIr
import org.jetbrains.kotlin.ir.util.isSuspendFunction
import org.jetbrains.kotlin.resolve.jvm.AsmTypes
import org.jetbrains.kotlin.resolve.jvm.jvmSignature.JvmMethodSignature
import org.jetbrains.kotlin.types.KotlinType
@@ -213,18 +214,3 @@ class IrExpressionLambdaImpl(
invokeMethodReturnType = (unboxedReturnType ?: function.returnType).toIrBasedKotlinType()
}
}
fun IrStatement.unwrapInlineLambda(): IrFunctionReference? = when (this) {
is IrBlock -> statements.lastOrNull()?.unwrapInlineLambda()
is IrFunctionReference -> takeIf { it.origin == JvmLoweredStatementOrigin.INLINE_LAMBDA }
else -> null
}
fun IrFunction.isInlineFunctionCall(context: JvmBackendContext) =
(!context.state.isInlineDisabled || typeParameters.any { it.isReified }) && (isInline || isInlineArrayConstructor(context))
// Constructors can't be marked as inline in metadata, hence this hack.
private fun IrFunction.isInlineArrayConstructor(context: JvmBackendContext): Boolean =
this is IrConstructor && valueParameters.size == 2 && constructedClass.symbol.let {
it == context.irBuiltIns.arrayClass || it in context.irBuiltIns.primitiveArraysToPrimitiveTypes
}
@@ -9,8 +9,10 @@ import com.intellij.openapi.util.TextRange
import org.jetbrains.kotlin.backend.common.CodegenUtil
import org.jetbrains.kotlin.backend.common.ir.ir2string
import org.jetbrains.kotlin.backend.jvm.hasMangledReturnType
import org.jetbrains.kotlin.backend.jvm.ir.fileParent
import org.jetbrains.kotlin.backend.jvm.ir.getKtFile
import org.jetbrains.kotlin.backend.jvm.ir.inlineScopeVisibility
import org.jetbrains.kotlin.backend.jvm.ir.parentClassId
import org.jetbrains.kotlin.codegen.inline.*
import org.jetbrains.kotlin.codegen.state.GenerationState
import org.jetbrains.kotlin.diagnostics.DiagnosticUtils
@@ -12,6 +12,10 @@ import org.jetbrains.kotlin.backend.jvm.JvmBackendContext
import org.jetbrains.kotlin.backend.jvm.JvmLoweredDeclarationOrigin
import org.jetbrains.kotlin.backend.jvm.JvmSymbols
import org.jetbrains.kotlin.backend.jvm.MultifileFacadeFileEntry
import org.jetbrains.kotlin.backend.jvm.ir.fileParent
import org.jetbrains.kotlin.backend.jvm.ir.isInlineOnly
import org.jetbrains.kotlin.backend.jvm.ir.isJvmInterface
import org.jetbrains.kotlin.backend.jvm.ir.isPrivateInlineSuspend
import org.jetbrains.kotlin.builtins.StandardNames.FqNames
import org.jetbrains.kotlin.builtins.jvm.JavaToKotlinClassMap
import org.jetbrains.kotlin.codegen.*
@@ -33,13 +37,10 @@ import org.jetbrains.kotlin.ir.types.IrType
import org.jetbrains.kotlin.ir.types.getClass
import org.jetbrains.kotlin.ir.util.*
import org.jetbrains.kotlin.load.java.JavaDescriptorVisibilities
import org.jetbrains.kotlin.load.kotlin.JvmPackagePartSource
import org.jetbrains.kotlin.name.ClassId
import org.jetbrains.kotlin.name.FqName
import org.jetbrains.kotlin.resolve.inline.INLINE_ONLY_ANNOTATION_FQ_NAME
import org.jetbrains.kotlin.resolve.jvm.AsmTypes
import org.jetbrains.kotlin.resolve.jvm.jvmSignature.JvmClassSignature
import org.jetbrains.kotlin.resolve.multiplatform.OptionalAnnotationUtil
import org.jetbrains.kotlin.resolve.source.PsiSourceElement
import org.jetbrains.kotlin.utils.addIfNotNull
import org.jetbrains.kotlin.utils.addToStdlib.safeAs
@@ -75,16 +76,6 @@ fun IrFrameMap.leave(irDeclaration: IrSymbolOwner): Int {
return leave(irDeclaration.symbol)
}
val IrClass.isJvmInterface get() = isAnnotationClass || isInterface
val IrDeclaration.fileParent: IrFile
get() {
return when (val myParent = parent) {
is IrFile -> myParent
else -> (myParent as IrDeclaration).fileParent
}
}
internal val DeclarationDescriptorWithSource.psiElement: PsiElement?
get() = (source as? PsiSourceElement)?.psi
@@ -214,30 +205,15 @@ private fun IrDeclarationWithVisibility.specialCaseVisibility(kind: OwnerKind?):
return null
}
/* Borrowed from InlineUtil. */
private tailrec fun isInlineOrContainedInInline(declaration: IrDeclaration?): Boolean = when {
declaration === null -> false
declaration is IrFunction && declaration.isInline -> true
else -> isInlineOrContainedInInline(declaration.parent as? IrDeclaration)
}
/* Borrowed from inlineOnly.kt */
fun IrDeclarationWithVisibility.isEffectivelyInlineOnly(): Boolean =
this is IrFunction && (isReifiable() || isInlineOnly() || isPrivateInlineSuspend())
private fun IrDeclarationWithVisibility.isInlineOnlyPrivateInBytecode(): Boolean =
this is IrFunction && (isInlineOnly() || isPrivateInlineSuspend())
private fun IrFunction.isPrivateInlineSuspend(): Boolean =
isSuspend && isInline && visibility == DescriptorVisibilities.PRIVATE
fun IrFunction.isInlineOnly() =
(isInline && hasAnnotation(INLINE_ONLY_ANNOTATION_FQ_NAME)) ||
(this is IrSimpleFunction && correspondingPropertySymbol?.owner?.hasAnnotation(INLINE_ONLY_ANNOTATION_FQ_NAME) == true)
fun IrFunction.isReifiable() = typeParameters.any { it.isReified }
internal fun IrFunction.isBridge() = origin == IrDeclarationOrigin.BRIDGE || origin == IrDeclarationOrigin.BRIDGE_SPECIAL
// Borrowed with modifications from ImplementationBodyCodegen.java
@@ -322,12 +298,6 @@ fun IrClass.getVisibilityAccessFlagForClass(): Int {
} else AsmUtil.NO_FLAG_PACKAGE_PRIVATE
}
/* Borrowed and translated from ExpectedActualDeclarationChecker */
// TODO: Descriptor-based code also checks for `descriptor.isExpect`; we don't represent expect/actual distinction in IR thus far.
fun IrClass.isOptionalAnnotationClass(): Boolean =
isAnnotationClass &&
hasAnnotation(OptionalAnnotationUtil.OPTIONAL_EXPECTATION_FQ_NAME)
val IrDeclaration.isAnnotatedWithDeprecated: Boolean
get() = annotations.hasAnnotation(FqNames.deprecated)
@@ -382,18 +352,3 @@ internal fun classFileContainsMethod(classId: ClassId, function: IrFunction, con
else originalDescriptor
return classFileContainsMethod(classId, context.state, Method(originalSignature.name, descriptor))
}
val IrMemberWithContainerSource.parentClassId: ClassId?
get() = ((this as? IrSimpleFunction)?.correspondingPropertySymbol?.owner ?: this).let { directMember ->
(directMember.containerSource as? JvmPackagePartSource)?.classId ?: (directMember.parent as? IrClass)?.classId
}
// Translated into IR-based terms from classifierDescriptor?.classId
private val IrClass.classId: ClassId?
get() = when (val parent = parent) {
is IrExternalPackageFragment -> ClassId(parent.fqName, name)
// TODO: there's `context.classNameOverride`; theoretically it's only relevant for top-level members,
// where `containerSource` is a `JvmPackagePartSource` anyway, but I'm not 100% sure.
is IrClass -> parent.classId?.createNestedClassId(name)
else -> null
}
@@ -6,6 +6,7 @@
package org.jetbrains.kotlin.backend.jvm.intrinsics
import org.jetbrains.kotlin.backend.jvm.codegen.*
import org.jetbrains.kotlin.backend.jvm.ir.receiverAndArgs
import org.jetbrains.kotlin.ir.expressions.IrExpression
import org.jetbrains.kotlin.ir.expressions.IrFunctionAccessExpression
import org.jetbrains.org.objectweb.asm.Label
@@ -39,4 +40,4 @@ object AndAnd : IntrinsicMethod() {
val (left, right) = expression.receiverAndArgs()
return BooleanConjunction(left, right, codegen, data)
}
}
}
@@ -20,6 +20,7 @@ import com.intellij.psi.tree.IElementType
import org.jetbrains.kotlin.backend.jvm.JvmBackendContext
import org.jetbrains.kotlin.backend.jvm.codegen.*
import org.jetbrains.kotlin.backend.jvm.ir.isSmartcastFromHigherThanNullable
import org.jetbrains.kotlin.backend.jvm.ir.receiverAndArgs
import org.jetbrains.kotlin.builtins.PrimitiveType
import org.jetbrains.kotlin.codegen.AsmUtil
import org.jetbrains.kotlin.codegen.AsmUtil.comparisonOperandType
@@ -207,4 +208,3 @@ class PrimitiveComparison(
}
}
}
@@ -9,6 +9,7 @@ import com.intellij.psi.tree.IElementType
import org.jetbrains.kotlin.backend.jvm.JvmBackendContext
import org.jetbrains.kotlin.backend.jvm.codegen.*
import org.jetbrains.kotlin.backend.jvm.ir.isSmartcastFromHigherThanNullable
import org.jetbrains.kotlin.backend.jvm.ir.receiverAndArgs
import org.jetbrains.kotlin.codegen.AsmUtil
import org.jetbrains.kotlin.codegen.AsmUtil.isPrimitive
import org.jetbrains.kotlin.codegen.DescriptorAsmUtil.genAreEqualCall
@@ -183,4 +184,3 @@ class Ieee754Equals(val operandType: Type) : IntrinsicMethod() {
}
}
}
@@ -155,8 +155,3 @@ fun IrFunctionAccessExpression.argTypes(context: JvmBackendContext): ArrayList<T
addAll(signature.asmMethod.argumentTypes)
}
}
fun IrFunctionAccessExpression.receiverAndArgs(): List<IrExpression> {
return (arrayListOf(this.dispatchReceiver, this.extensionReceiver) +
symbol.owner.valueParameters.mapIndexed { i, _ -> getValueArgument(i) }).filterNotNull()
}
@@ -6,11 +6,9 @@
package org.jetbrains.kotlin.backend.jvm.intrinsics
import org.jetbrains.kotlin.backend.jvm.codegen.*
import org.jetbrains.kotlin.ir.expressions.IrConst
import org.jetbrains.kotlin.ir.expressions.IrConstKind
import org.jetbrains.kotlin.ir.expressions.IrExpression
import org.jetbrains.kotlin.backend.jvm.ir.getBooleanConstArgument
import org.jetbrains.kotlin.backend.jvm.ir.getStringConstArgument
import org.jetbrains.kotlin.ir.expressions.IrFunctionAccessExpression
import org.jetbrains.kotlin.ir.util.dump
import org.jetbrains.org.objectweb.asm.Type
// This intrinsic enables IR lowerings to force the generation of a particular
@@ -29,21 +27,14 @@ import org.jetbrains.org.objectweb.asm.Type
// lowerings in between.
object JvmDebuggerInvokeSpecial : IntrinsicMethod() {
override fun invoke(expression: IrFunctionAccessExpression, codegen: ExpressionCodegen, data: BlockInfo): PromisedValue {
fun fail(message: String): Nothing =
throw AssertionError("$message; expression:\n${expression.dump()}")
val owner = expression.getValueArgument(0)?.getStringConst()
?: fail("'owner' is expected to be a string const")
val name = expression.getValueArgument(1)?.getStringConst()
?: fail("'name' is expected to be a string const")
val descriptor = expression.getValueArgument(2)?.getStringConst()
?: fail("'descriptor' is expected to be a string const")
val isInterface = expression.getValueArgument(3)?.getBooleanConst()
?: fail("'isInterface' is expected to be a boolean const")
val owner = expression.getStringConstArgument(0)
val name = expression.getStringConstArgument(1)
val descriptor = expression.getStringConstArgument(2)
val isInterface = expression.getBooleanConstArgument(3)
expression.dispatchReceiver!!.accept(codegen, data).materialize()
codegen.mv.invokespecial(owner, name, descriptor, isInterface)
return MaterialValue(codegen, Type.getReturnType(descriptor), expression.type)
}
}
}
@@ -8,7 +8,7 @@ package org.jetbrains.kotlin.backend.jvm.intrinsics
import org.jetbrains.kotlin.backend.jvm.JvmBackendContext
import org.jetbrains.kotlin.backend.jvm.JvmLoweredDeclarationOrigin
import org.jetbrains.kotlin.backend.jvm.codegen.*
import org.jetbrains.kotlin.backend.jvm.ir.findSuperDeclaration
import org.jetbrains.kotlin.backend.jvm.ir.*
import org.jetbrains.kotlin.ir.declarations.IrClass
import org.jetbrains.kotlin.ir.declarations.IrConstructor
import org.jetbrains.kotlin.ir.declarations.IrFunction
@@ -130,37 +130,6 @@ object JvmInvokeDynamic : IntrinsicMethod() {
}
fun IrCall.getIntConstArgument(i: Int) =
getValueArgument(i)?.getIntConst()
?: throw AssertionError("Value argument #$i should be an Int const: ${dump()}")
fun IrCall.getStringConstArgument(i: Int) =
getValueArgument(i)?.getStringConst()
?: throw AssertionError("Value argument #$i should be a String const: ${dump()}")
fun IrCall.getBooleanConstArgument(i: Int) =
getValueArgument(i)?.getBooleanConst()
?: throw AssertionError("Value argument #$i should be a Boolean const: ${dump()}")
internal fun IrExpression.getIntConst() =
if (this is IrConst<*> && kind == IrConstKind.Int)
this.value as Int
else
null
internal fun IrExpression.getStringConst() =
if (this is IrConst<*> && kind == IrConstKind.String)
this.value as String
else
null
internal fun IrExpression.getBooleanConst() =
if (this is IrConst<*> && kind == IrConstKind.Boolean)
this.value as Boolean
else
null
internal fun generateMethodHandle(jvmBackendContext: JvmBackendContext, irRawFunctionReference: IrRawFunctionReference): Handle {
return generateMethodHandle(jvmBackendContext, irRawFunctionReference.symbol.owner)
}
@@ -198,5 +167,3 @@ internal fun getMethodKindTag(irFun: IrFunction) =
else ->
Opcodes.H_INVOKEVIRTUAL
}
@@ -6,6 +6,7 @@
package org.jetbrains.kotlin.backend.jvm.intrinsics
import org.jetbrains.kotlin.backend.jvm.codegen.*
import org.jetbrains.kotlin.backend.jvm.ir.receiverAndArgs
import org.jetbrains.kotlin.ir.expressions.IrExpression
import org.jetbrains.kotlin.ir.expressions.IrFunctionAccessExpression
import org.jetbrains.org.objectweb.asm.Label
@@ -40,4 +41,4 @@ object OrOr : IntrinsicMethod() {
val (left, right) = expression.receiverAndArgs()
return BooleanDisjunction(left, right, codegen, data)
}
}
}
@@ -8,7 +8,7 @@ package org.jetbrains.kotlin.backend.jvm.intrinsics
import org.jetbrains.kotlin.backend.jvm.codegen.BlockInfo
import org.jetbrains.kotlin.backend.jvm.codegen.ExpressionCodegen
import org.jetbrains.kotlin.backend.jvm.codegen.IrInlineIntrinsicsSupport
import org.jetbrains.kotlin.backend.jvm.codegen.fileParent
import org.jetbrains.kotlin.backend.jvm.ir.fileParent
import org.jetbrains.kotlin.codegen.inline.ReifiedTypeInliner
import org.jetbrains.kotlin.codegen.inline.generateTypeOf
import org.jetbrains.kotlin.codegen.putReifiedOperationMarkerIfTypeIsReifiedParameter
@@ -6,8 +6,6 @@
package org.jetbrains.kotlin.backend.jvm.ir
import org.jetbrains.kotlin.backend.jvm.JvmBackendContext
import org.jetbrains.kotlin.backend.jvm.codegen.isInlineFunctionCall
import org.jetbrains.kotlin.backend.jvm.codegen.unwrapInlineLambda
import org.jetbrains.kotlin.descriptors.DescriptorVisibilities
import org.jetbrains.kotlin.ir.IrElement
import org.jetbrains.kotlin.ir.declarations.*
@@ -0,0 +1,94 @@
/*
* Copyright 2010-2021 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.ir
import org.jetbrains.kotlin.backend.common.lower.LocalDeclarationsLowering
import org.jetbrains.kotlin.backend.jvm.JvmLoweredDeclarationOrigin
import org.jetbrains.kotlin.backend.jvm.isMultifileBridge
import org.jetbrains.kotlin.codegen.coroutines.INVOKE_SUSPEND_METHOD_NAME
import org.jetbrains.kotlin.codegen.coroutines.SUSPEND_IMPL_NAME_SUFFIX
import org.jetbrains.kotlin.ir.declarations.*
import org.jetbrains.kotlin.ir.expressions.IrExpression
import org.jetbrains.kotlin.ir.expressions.IrGetField
import org.jetbrains.kotlin.ir.expressions.IrGetValue
import org.jetbrains.kotlin.ir.util.functions
import org.jetbrains.kotlin.ir.util.isSuspend
import org.jetbrains.kotlin.ir.util.parentAsClass
fun IrFunction.continuationParameter(): IrValueParameter? = when {
isInvokeSuspendOfLambda() || isInvokeSuspendForInlineOfLambda() -> dispatchReceiverParameter
else -> valueParameters.singleOrNull { it.origin == JvmLoweredDeclarationOrigin.CONTINUATION_CLASS }
}
internal fun IrFunction.isInvokeSuspendOfLambda(): Boolean =
name.asString() == INVOKE_SUSPEND_METHOD_NAME && parentAsClass.origin == JvmLoweredDeclarationOrigin.SUSPEND_LAMBDA
private fun IrFunction.isInvokeSuspendForInlineOfLambda(): Boolean =
origin == JvmLoweredDeclarationOrigin.FOR_INLINE_STATE_MACHINE_TEMPLATE
&& parentAsClass.origin == JvmLoweredDeclarationOrigin.SUSPEND_LAMBDA
fun IrFunction.isInvokeSuspendOfContinuation(): Boolean =
name.asString() == INVOKE_SUSPEND_METHOD_NAME && parentAsClass.origin == JvmLoweredDeclarationOrigin.CONTINUATION_CLASS
private fun IrFunction.isInvokeOfSuspendCallableReference(): Boolean =
isSuspend && name.asString().let { name -> name == "invoke" || name.startsWith("invoke-") }
&& parentAsClass.origin == JvmLoweredDeclarationOrigin.FUNCTION_REFERENCE_IMPL
private fun IrFunction.isBridgeToSuspendImplMethod(): Boolean =
isSuspend && this is IrSimpleFunction && parentAsClass.functions.any {
it.name.asString() == name.asString() + SUSPEND_IMPL_NAME_SUFFIX && it.attributeOwnerId == attributeOwnerId
}
private fun IrFunction.isStaticInlineClassReplacementDelegatingCall(): Boolean =
this is IrAttributeContainer && !isStaticInlineClassReplacement &&
(parent as? IrClass)?.declarations?.find { it is IrAttributeContainer && it.attributeOwnerId == attributeOwnerId && it !== this }
?.isStaticInlineClassReplacement == true
private val BRIDGE_ORIGINS = setOf(
IrDeclarationOrigin.FUNCTION_FOR_DEFAULT_PARAMETER,
JvmLoweredDeclarationOrigin.JVM_STATIC_WRAPPER,
JvmLoweredDeclarationOrigin.JVM_OVERLOADS_WRAPPER,
JvmLoweredDeclarationOrigin.SYNTHETIC_ACCESSOR,
JvmLoweredDeclarationOrigin.SYNTHETIC_ACCESSOR_FOR_HIDDEN_CONSTRUCTOR,
JvmLoweredDeclarationOrigin.SUPER_INTERFACE_METHOD_BRIDGE,
IrDeclarationOrigin.BRIDGE,
IrDeclarationOrigin.BRIDGE_SPECIAL,
)
// These functions contain a single `suspend` tail call, the value of which should be returned as is
// (i.e. if it's an unboxed inline class value, it should remain unboxed).
fun IrFunction.isNonBoxingSuspendDelegation(): Boolean =
origin in BRIDGE_ORIGINS ||
isMultifileBridge() ||
isBridgeToSuspendImplMethod() ||
isStaticInlineClassReplacementForDefaultInterfaceMethod()
// Suspend static inline class replacements for fake overrides have to be for interface methods as inline classes cannot have a
// non-Object super type.
fun IrFunction.isStaticInlineClassReplacementForDefaultInterfaceMethod(): Boolean =
isStaticInlineClassReplacement && this is IrSimpleFunction && (attributeOwnerId as IrSimpleFunction).isFakeOverride
fun IrFunction.shouldContainSuspendMarkers(): Boolean = !isNonBoxingSuspendDelegation() &&
// These functions also contain a single `suspend` tail call, but if it returns an unboxed inline class value,
// the return of it should be checked for a suspension and potentially boxed to satisfy an interface.
origin != IrDeclarationOrigin.DELEGATED_MEMBER &&
!isInvokeSuspendOfContinuation() &&
!isInvokeOfSuspendCallableReference() &&
!isStaticInlineClassReplacementDelegatingCall()
fun IrFunction.hasContinuation(): Boolean = isInvokeSuspendOfLambda() ||
isSuspend && shouldContainSuspendMarkers() &&
// These are templates for the inliner; the continuation is borrowed from the caller method.
!isEffectivelyInlineOnly() &&
origin != JvmLoweredDeclarationOrigin.INLINE_LAMBDA &&
origin != JvmLoweredDeclarationOrigin.FOR_INLINE_STATE_MACHINE_TEMPLATE &&
origin != JvmLoweredDeclarationOrigin.FOR_INLINE_STATE_MACHINE_TEMPLATE_CAPTURES_CROSSINLINE
fun IrExpression?.isReadOfCrossinline(): Boolean = when (this) {
is IrGetValue -> (symbol.owner as? IrValueParameter)?.isCrossinline == true
is IrGetField -> symbol.owner.origin == LocalDeclarationsLowering.DECLARATION_ORIGIN_FIELD_FOR_CROSSINLINE_CAPTURED_VALUE
else -> false
}
@@ -0,0 +1,90 @@
/*
* Copyright 2010-2021 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.ir
import org.jetbrains.kotlin.backend.jvm.JvmBackendContext
import org.jetbrains.kotlin.backend.jvm.JvmLoweredStatementOrigin
import org.jetbrains.kotlin.descriptors.DescriptorVisibilities
import org.jetbrains.kotlin.descriptors.DescriptorVisibility
import org.jetbrains.kotlin.ir.IrStatement
import org.jetbrains.kotlin.ir.declarations.*
import org.jetbrains.kotlin.ir.expressions.IrBlock
import org.jetbrains.kotlin.ir.expressions.IrFunctionReference
import org.jetbrains.kotlin.ir.types.isNullable
import org.jetbrains.kotlin.ir.util.*
import org.jetbrains.kotlin.resolve.inline.INLINE_ONLY_ANNOTATION_FQ_NAME
import org.jetbrains.kotlin.utils.addToStdlib.safeAs
fun IrValueParameter.isInlineParameter(): Boolean =
index >= 0 && !isNoinline && (type.isFunction() || type.isSuspendFunction()) &&
// Parameters with default values are always nullable, so check the expression too.
// Note that the frontend has a diagnostic for nullable inline parameters, so actually
// making this return `false` requires using `@Suppress`.
(!type.isNullable() || defaultValue?.expression?.type?.isNullable() == false)
// Declarations in the scope of an externally visible inline function are implicitly part of the
// public ABI of a Kotlin module. This function returns the visibility of a containing inline function
// (determined *before* lowering), or null if the given declaration is not in the scope of an inline function.
//
// Currently, we mark all declarations in the scope of a public inline function as public, even if they are
// contained in a nested private inline function. This is an over approximation, since private declarations
// inside of a public inline function can still escape if they are used without being regenerated.
// See `plugins/jvm-abi-gen/testData/compile/inlineNoRegeneration` for an example.
val IrDeclaration.inlineScopeVisibility: DescriptorVisibility?
get() {
var owner: IrDeclaration? = original
var result: DescriptorVisibility? = null
while (owner != null) {
if (owner is IrFunction && owner.isInline) {
result = if (!DescriptorVisibilities.isPrivate(owner.visibility)) {
if (owner.parentClassOrNull?.visibility?.let(DescriptorVisibilities::isPrivate) == true)
DescriptorVisibilities.PRIVATE
else
return owner.visibility
} else {
owner.visibility
}
}
owner = owner.parent.safeAs<IrDeclaration>()?.original
}
return result
}
// True for declarations which are in the scope of an externally visible inline function.
val IrDeclaration.isInPublicInlineScope: Boolean
get() = inlineScopeVisibility?.let(DescriptorVisibilities::isPrivate) == false
// Map declarations to original declarations before lowering.
private val IrDeclaration.original: IrDeclaration
get() = (this as? IrAttributeContainer)?.attributeOwnerId as? IrDeclaration ?: this
fun IrStatement.unwrapInlineLambda(): IrFunctionReference? = when (this) {
is IrBlock -> statements.lastOrNull()?.unwrapInlineLambda()
is IrFunctionReference -> takeIf { it.origin == JvmLoweredStatementOrigin.INLINE_LAMBDA }
else -> null
}
fun IrFunction.isInlineFunctionCall(context: JvmBackendContext): Boolean =
(!context.state.isInlineDisabled || typeParameters.any { it.isReified }) && (isInline || isInlineArrayConstructor(context))
// Constructors can't be marked as inline in metadata, hence this hack.
private fun IrFunction.isInlineArrayConstructor(context: JvmBackendContext): Boolean =
this is IrConstructor && valueParameters.size == 2 && constructedClass.symbol.let {
it == context.irBuiltIns.arrayClass || it in context.irBuiltIns.primitiveArraysToPrimitiveTypes
}
fun IrFunction.isInlineOnly(): Boolean =
(isInline && hasAnnotation(INLINE_ONLY_ANNOTATION_FQ_NAME)) ||
(this is IrSimpleFunction && correspondingPropertySymbol?.owner?.hasAnnotation(INLINE_ONLY_ANNOTATION_FQ_NAME) == true)
fun IrDeclarationWithVisibility.isEffectivelyInlineOnly(): Boolean =
this is IrFunction && (isReifiable() || isInlineOnly() || isPrivateInlineSuspend())
fun IrFunction.isPrivateInlineSuspend(): Boolean =
isSuspend && isInline && visibility == DescriptorVisibilities.PRIVATE
fun IrFunction.isReifiable(): Boolean =
typeParameters.any { it.isReified }
@@ -6,7 +6,6 @@
package org.jetbrains.kotlin.backend.jvm.ir
import org.jetbrains.kotlin.backend.jvm.JvmBackendContext
import org.jetbrains.kotlin.backend.jvm.codegen.isJvmInterface
import org.jetbrains.kotlin.backend.jvm.codegen.representativeUpperBound
import org.jetbrains.kotlin.backend.jvm.unboxInlineClass
import org.jetbrains.kotlin.ir.declarations.IrClass
@@ -12,15 +12,14 @@ import org.jetbrains.kotlin.backend.common.lower.irNot
import org.jetbrains.kotlin.backend.jvm.CachedFieldsForObjectInstances
import org.jetbrains.kotlin.backend.jvm.JvmBackendContext
import org.jetbrains.kotlin.backend.jvm.JvmLoweredDeclarationOrigin
import org.jetbrains.kotlin.backend.jvm.codegen.isInlineOnly
import org.jetbrains.kotlin.backend.jvm.codegen.isJvmInterface
import org.jetbrains.kotlin.builtins.StandardNames
import org.jetbrains.kotlin.codegen.ASSERTIONS_DISABLED_FIELD_NAME
import org.jetbrains.kotlin.codegen.inline.coroutines.FOR_INLINE_SUFFIX
import org.jetbrains.kotlin.config.JvmDefaultMode
import org.jetbrains.kotlin.descriptors.ClassKind
import org.jetbrains.kotlin.descriptors.DescriptorVisibilities
import org.jetbrains.kotlin.descriptors.DescriptorVisibility
import org.jetbrains.kotlin.descriptors.Modality
import org.jetbrains.kotlin.descriptors.annotations.KotlinRetention
import org.jetbrains.kotlin.descriptors.deserialization.PLATFORM_DEPENDENT_ANNOTATION_FQ_NAME
import org.jetbrains.kotlin.ir.IrBuiltIns
import org.jetbrains.kotlin.ir.IrElement
@@ -49,15 +48,17 @@ import org.jetbrains.kotlin.ir.visitors.IrElementVisitorVoid
import org.jetbrains.kotlin.ir.visitors.transformChildrenVoid
import org.jetbrains.kotlin.load.java.JavaDescriptorVisibilities
import org.jetbrains.kotlin.load.java.JvmAbi
import org.jetbrains.kotlin.load.kotlin.JvmPackagePartSource
import org.jetbrains.kotlin.metadata.jvm.deserialization.JvmProtoBufUtil
import org.jetbrains.kotlin.name.ClassId
import org.jetbrains.kotlin.name.JvmNames.JVM_DEFAULT_FQ_NAME
import org.jetbrains.kotlin.name.JvmNames.JVM_DEFAULT_NO_COMPATIBILITY_FQ_NAME
import org.jetbrains.kotlin.name.JvmNames.JVM_DEFAULT_WITH_COMPATIBILITY_FQ_NAME
import org.jetbrains.kotlin.name.Name
import org.jetbrains.kotlin.psi.KtFile
import org.jetbrains.kotlin.resolve.DescriptorUtils
import org.jetbrains.kotlin.resolve.multiplatform.OptionalAnnotationUtil
import org.jetbrains.kotlin.utils.DFS
import org.jetbrains.kotlin.utils.addToStdlib.safeAs
fun IrDeclaration.getJvmNameFromAnnotation(): String? {
// TODO lower @JvmName?
@@ -101,13 +102,6 @@ fun IrFunction.hasPlatformDependent(): Boolean = propertyIfAccessor.hasAnnotatio
fun IrFunction.getJvmVisibilityOfDefaultArgumentStub() =
if (DescriptorVisibilities.isPrivate(visibility) || isInlineOnly()) JavaDescriptorVisibilities.PACKAGE_VISIBILITY else DescriptorVisibilities.PUBLIC
fun IrValueParameter.isInlineParameter() =
index >= 0 && !isNoinline && (type.isFunction() || type.isSuspendFunction()) &&
// Parameters with default values are always nullable, so check the expression too.
// Note that the frontend has a diagnostic for nullable inline parameters, so actually
// making this return `false` requires using `@Suppress`.
(!type.isNullable() || defaultValue?.expression?.type?.isNullable() == false)
fun IrDeclaration.isInCurrentModule(): Boolean =
getPackageFragment() is IrFile
@@ -262,6 +256,9 @@ private fun JvmBackendContext.makeRawTypeAnnotation() =
fun IrClass.rawType(context: JvmBackendContext): IrType =
defaultType.addAnnotations(listOf(context.makeRawTypeAnnotation()))
val IrClass.isJvmInterface: Boolean
get() = isAnnotationClass || isInterface
fun IrClass.getSingleAbstractMethod(): IrSimpleFunction? =
functions.singleOrNull { it.modality == Modality.ABSTRACT }
@@ -286,42 +283,6 @@ val IrClass.isSyntheticSingleton: Boolean
|| origin == JvmLoweredDeclarationOrigin.GENERATED_PROPERTY_REFERENCE)
&& primaryConstructor!!.valueParameters.isEmpty()
// Map declarations to original declarations before lowering.
private val IrDeclaration.original: IrDeclaration
get() = (this as? IrAttributeContainer)?.attributeOwnerId as? IrDeclaration ?: this
// Declarations in the scope of an externally visible inline function are implicitly part of the
// public ABI of a Kotlin module. This function returns the visibility of a containing inline function
// (determined *before* lowering), or null if the given declaration is not in the scope of an inline function.
//
// Currently, we mark all declarations in the scope of a public inline function as public, even if they are
// contained in a nested private inline function. This is an over approximation, since private declarations
// inside of a public inline function can still escape if they are used without being regenerated.
// See `plugins/jvm-abi-gen/testData/compile/inlineNoRegeneration` for an example.
val IrDeclaration.inlineScopeVisibility: DescriptorVisibility?
get() {
var owner: IrDeclaration? = original
var result: DescriptorVisibility? = null
while (owner != null) {
if (owner is IrFunction && owner.isInline) {
result = if (!DescriptorVisibilities.isPrivate(owner.visibility)) {
if (owner.parentClassOrNull?.visibility?.let(DescriptorVisibilities::isPrivate) == true)
DescriptorVisibilities.PRIVATE
else
return owner.visibility
} else {
owner.visibility
}
}
owner = owner.parent.safeAs<IrDeclaration>()?.original
}
return result
}
// True for declarations which are in the scope of an externally visible inline function.
val IrDeclaration.isInPublicInlineScope: Boolean
get() = inlineScopeVisibility?.let(DescriptorVisibilities::isPrivate) == false
fun IrSimpleFunction.suspendFunctionOriginal(): IrSimpleFunction =
if (isSuspend &&
!isStaticInlineClassReplacement &&
@@ -424,4 +385,77 @@ fun findSuperDeclaration(function: IrSimpleFunction, isSuperCall: Boolean, jvmDe
?: error("Fake override should have at least one overridden descriptor: ${current.render()}")
}
return current
}
}
fun IrMemberAccessExpression<*>.getIntConstArgument(i: Int): Int =
getValueArgument(i)?.let {
if (it is IrConst<*> && it.kind == IrConstKind.Int)
it.value as Int
else
null
} ?: throw AssertionError("Value argument #$i should be an Int const: ${dump()}")
fun IrMemberAccessExpression<*>.getStringConstArgument(i: Int): String =
getValueArgument(i)?.let {
if (it is IrConst<*> && it.kind == IrConstKind.String)
it.value as String
else
null
} ?: throw AssertionError("Value argument #$i should be a String const: ${dump()}")
fun IrMemberAccessExpression<*>.getBooleanConstArgument(i: Int): Boolean =
getValueArgument(i)?.let {
if (it is IrConst<*> && it.kind == IrConstKind.Boolean)
it.value as Boolean
else
null
} ?: throw AssertionError("Value argument #$i should be a Boolean const: ${dump()}")
val IrDeclaration.fileParent: IrFile
get() {
return when (val myParent = parent) {
is IrFile -> myParent
else -> (myParent as IrDeclaration).fileParent
}
}
private val RETENTION_PARAMETER_NAME = Name.identifier("value")
fun IrClass.getAnnotationRetention(): KotlinRetention? {
val retentionArgument =
getAnnotation(StandardNames.FqNames.retention)?.getValueArgument(RETENTION_PARAMETER_NAME)
as? IrGetEnumValue ?: return null
val retentionArgumentValue = retentionArgument.symbol.owner
return KotlinRetention.valueOf(retentionArgumentValue.name.asString())
}
// To be generalized to IrMemberAccessExpression as soon as properties get symbols.
fun IrConstructorCall.getValueArgument(name: Name): IrExpression? {
val index = symbol.owner.valueParameters.find { it.name == name }?.index ?: return null
return getValueArgument(index)
}
val IrMemberWithContainerSource.parentClassId: ClassId?
get() = ((this as? IrSimpleFunction)?.correspondingPropertySymbol?.owner ?: this).let { directMember ->
(directMember.containerSource as? JvmPackagePartSource)?.classId ?: (directMember.parent as? IrClass)?.classId
}
// Translated into IR-based terms from classifierDescriptor?.classId
private val IrClass.classId: ClassId?
get() = when (val parent = parent) {
is IrExternalPackageFragment -> ClassId(parent.fqName, name)
// TODO: there's `context.classNameOverride`; theoretically it's only relevant for top-level members,
// where `containerSource` is a `JvmPackagePartSource` anyway, but I'm not 100% sure.
is IrClass -> parent.classId?.createNestedClassId(name)
else -> null
}
val IrClass.isOptionalAnnotationClass: Boolean
get() = kind == ClassKind.ANNOTATION_CLASS &&
isExpect &&
hasAnnotation(OptionalAnnotationUtil.OPTIONAL_EXPECTATION_FQ_NAME)
fun IrFunctionAccessExpression.receiverAndArgs(): List<IrExpression> {
return (arrayListOf(this.dispatchReceiver, this.extensionReceiver) +
symbol.owner.valueParameters.mapIndexed { i, _ -> getValueArgument(i) }).filterNotNull()
}
@@ -6,8 +6,8 @@
package org.jetbrains.kotlin.android.parcel.ir
import org.jetbrains.kotlin.android.parcel.serializers.ParcelableExtensionBase.Companion.CREATOR_NAME
import org.jetbrains.kotlin.backend.jvm.codegen.isJvmInterface
import org.jetbrains.kotlin.backend.jvm.ir.erasedUpperBound
import org.jetbrains.kotlin.backend.jvm.ir.isJvmInterface
import org.jetbrains.kotlin.ir.builders.*
import org.jetbrains.kotlin.ir.declarations.IrClass
import org.jetbrains.kotlin.ir.declarations.IrValueDeclaration
@@ -5,8 +5,8 @@
package org.jetbrains.kotlin.parcelize.ir
import org.jetbrains.kotlin.backend.jvm.codegen.isJvmInterface
import org.jetbrains.kotlin.backend.jvm.ir.erasedUpperBound
import org.jetbrains.kotlin.backend.jvm.ir.isJvmInterface
import org.jetbrains.kotlin.ir.builders.*
import org.jetbrains.kotlin.ir.declarations.IrClass
import org.jetbrains.kotlin.ir.declarations.IrValueDeclaration