Use annotation to distinct inline constructor

This commit is contained in:
Konstantin Anisimov
2017-05-10 17:35:45 +07:00
committed by KonstantinAnisimov
parent 31a24d4607
commit ba1f3d502e
5 changed files with 36 additions and 24 deletions
@@ -312,25 +312,13 @@ internal fun DeclarationDescriptor.getMemberScope(): MemberScope {
// It is possible to declare "external inline fun",
// but it doesn't have much sense for native,
// since externals don't have IR bodies.
// Enforce inlining of some constructors
private val mustInlineFunctions = setOf(
"kotlin.DoubleArray.<init>",
"kotlin.FloatArray.<init>",
"kotlin.ByteArray.<init>",
"kotlin.ShortArray.<init>",
"kotlin.IntArray.<init>",
"kotlin.LongArray.<init>",
"kotlin.CharArray.<init>",
"kotlin.BooleanArray.<init>"
)
// Enforce inlining of some constructors.
internal val FunctionDescriptor.needsInlining: Boolean
get() {
val needs = this.isInline && !this.isExternal
if (valueParameters.size != 2) return needs // Constructor must have two parameters.
if (mustInlineFunctions.contains(fqNameSafe.toString())) return true
return needs
val inlineConstructor = annotations.hasAnnotation(FqName("konan.internal.InlineConstructor"))
if (inlineConstructor) return true
return (this.isInline && !this.isExternal)
}
internal val FunctionDescriptor.needsSerializedIr: Boolean
@@ -40,11 +40,14 @@ import org.jetbrains.kotlin.ir.expressions.*
import org.jetbrains.kotlin.ir.expressions.impl.*
import org.jetbrains.kotlin.ir.visitors.IrElementTransformerVoid
import org.jetbrains.kotlin.ir.visitors.transformChildrenVoid
import org.jetbrains.kotlin.name.FqName
import org.jetbrains.kotlin.resolve.descriptorUtil.fqNameSafe
import org.jetbrains.kotlin.resolve.descriptorUtil.hasDefaultValue
import org.jetbrains.kotlin.types.TypeProjectionImpl
import org.jetbrains.kotlin.types.TypeSubstitutor
private val inlineConstructor = FqName("konan.internal.InlineConstructor")
//-----------------------------------------------------------------------------//
internal class FunctionInlining(val context: Context): IrElementTransformerVoidWithContext() {
@@ -99,12 +102,14 @@ private class Inliner(val currentScope: ScopeWithIr, val context: Context) {
val copyIrElement = DeepCopyIrTreeWithDescriptors(currentScope.scope.scopeOwner, context) // Create DeepCopy for current scope.
val substituteMap = mutableMapOf<ValueDescriptor, IrExpression>()
var isInlineConstructor = false
//-------------------------------------------------------------------------//
fun inline(irCall : IrCall, // Call to be substituted.
functionDeclaration: IrFunction): IrReturnableBlockImpl { // Function to substitute.
isInlineConstructor = irCall.descriptor.annotations.hasAnnotation(inlineConstructor)
val inlineFunctionBody = inlineFunction(irCall, functionDeclaration)
val descriptorSubstitutor = copyIrElement.descriptorSubstitutorForExternalScope
currentScope.irElement.transformChildrenVoid(descriptorSubstitutor) // Transform calls to object that might be returned from inline function call.
@@ -365,15 +370,15 @@ private class Inliner(val currentScope: ScopeWithIr, val context: Context) {
fun generateIrCall(expression: IrDelegatingConstructorCallImpl): IrStatement {
if (!expression.descriptor.fqNameSafe.toString().contains("kotlin.IntArray.<init>")) return expression
if (!isInlineConstructor) return expression
val newExpression = IrCallImpl(
startOffset = expression.startOffset,
endOffset = expression.endOffset,
type = expression.descriptor.returnType,
descriptor = expression.descriptor,
typeArguments = expression.typeArguments,
origin = expression.origin
expression.startOffset,
expression.endOffset,
expression.descriptor.returnType,
expression.descriptor,
expression.typeArguments,
expression.origin
).apply {
expression.descriptor.valueParameters.forEach {
val valueArgument = expression.getValueArgument(it)