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:
@@ -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
|
||||
|
||||
+1
-6
@@ -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
|
||||
|
||||
+1
-1
@@ -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
|
||||
|
||||
-1
@@ -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
|
||||
|
||||
+2
-1
@@ -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
|
||||
|
||||
|
||||
+1
-1
@@ -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
|
||||
|
||||
+1
-1
@@ -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
|
||||
|
||||
+1
-1
@@ -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
|
||||
|
||||
-1
@@ -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
|
||||
|
||||
+1
-1
@@ -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
|
||||
|
||||
+1
-4
@@ -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.*
|
||||
|
||||
+2
-2
@@ -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
|
||||
|
||||
+2
-2
@@ -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
|
||||
|
||||
+1
-1
@@ -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
|
||||
|
||||
-1
@@ -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
|
||||
|
||||
+1
-2
@@ -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
|
||||
|
||||
+3
-7
@@ -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())
|
||||
|
||||
+1
-1
@@ -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
|
||||
|
||||
+14
-4
@@ -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,
|
||||
|
||||
+1
-5
@@ -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
|
||||
|
||||
+1
-1
@@ -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
|
||||
|
||||
-2
@@ -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
|
||||
|
||||
+1
-1
@@ -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
|
||||
|
||||
+2
-2
@@ -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
|
||||
|
||||
+2
-31
@@ -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)
|
||||
|
||||
+9
-81
@@ -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)
|
||||
|
||||
|
||||
+1
-3
@@ -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.*
|
||||
|
||||
+2
@@ -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.*
|
||||
|
||||
+6
-20
@@ -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
|
||||
}
|
||||
|
||||
+2
@@ -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
|
||||
|
||||
+4
-49
@@ -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)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
+1
-1
@@ -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() {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
-5
@@ -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()
|
||||
}
|
||||
|
||||
+7
-16
@@ -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)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
+1
-34
@@ -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
|
||||
|
||||
-2
@@ -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.*
|
||||
|
||||
+94
@@ -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()
|
||||
}
|
||||
|
||||
+1
-1
@@ -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
|
||||
|
||||
+1
-1
@@ -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
|
||||
|
||||
Reference in New Issue
Block a user