[JS IR] Support init blocks in inline classes
This commit is contained in:
@@ -370,6 +370,13 @@ private val propertyAccessorInlinerLoweringPhase = makeBodyLoweringPhase(
|
||||
description = "[Optimization] Inline property accessors"
|
||||
)
|
||||
|
||||
private val copyPropertyAccessorBodiesLoweringPass = makeDeclarationTransformerPhase(
|
||||
::CopyAccessorBodyLowerings,
|
||||
name = "CopyAccessorBodyLowering",
|
||||
description = "Copy accessor bodies so that ist can be safely read in PropertyAccessorInlineLowering",
|
||||
prerequisite = setOf(propertyAccessorInlinerLoweringPhase)
|
||||
)
|
||||
|
||||
private val foldConstantLoweringPhase = makeBodyLoweringPhase(
|
||||
{ FoldConstantLowering(it, true) },
|
||||
name = "FoldConstantLowering",
|
||||
@@ -603,6 +610,12 @@ private val secondaryFactoryInjectorLoweringPhase = makeBodyLoweringPhase(
|
||||
prerequisite = setOf(innerClassesLoweringPhase)
|
||||
)
|
||||
|
||||
private val constLoweringPhase = makeBodyLoweringPhase(
|
||||
::ConstLowering,
|
||||
name = "ConstLowering",
|
||||
description = "Wrap Long and Char constants into constructor invocation"
|
||||
)
|
||||
|
||||
private val inlineClassDeclarationLoweringPhase = makeDeclarationTransformerPhase(
|
||||
{ InlineClassLowering(it).inlineClassDeclarationLowering },
|
||||
name = "InlineClassDeclarationLowering",
|
||||
@@ -612,7 +625,12 @@ private val inlineClassDeclarationLoweringPhase = makeDeclarationTransformerPhas
|
||||
private val inlineClassUsageLoweringPhase = makeBodyLoweringPhase(
|
||||
{ InlineClassLowering(it).inlineClassUsageLowering },
|
||||
name = "InlineClassUsageLowering",
|
||||
description = "Handle inline class usages"
|
||||
description = "Handle inline class usages",
|
||||
prerequisite = setOf(
|
||||
// Const lowering generates inline class constructors for unsigned integers
|
||||
// which should be lowered by this lowering
|
||||
constLoweringPhase
|
||||
)
|
||||
)
|
||||
|
||||
private val autoboxingTransformerPhase = makeBodyLoweringPhase(
|
||||
@@ -640,12 +658,6 @@ private val primitiveCompanionLoweringPhase = makeBodyLoweringPhase(
|
||||
description = "Replace common companion object access with platform one"
|
||||
)
|
||||
|
||||
private val constLoweringPhase = makeBodyLoweringPhase(
|
||||
::ConstLowering,
|
||||
name = "ConstLowering",
|
||||
description = "Wrap Long and Char constants into constructor invocation"
|
||||
)
|
||||
|
||||
private val callsLoweringPhase = makeBodyLoweringPhase(
|
||||
::CallsLowering,
|
||||
name = "CallsLowering",
|
||||
@@ -743,6 +755,7 @@ val loweringList = listOf<Lowering>(
|
||||
propertyLazyInitLoweringPhase,
|
||||
removeInitializersForLazyProperties,
|
||||
propertyAccessorInlinerLoweringPhase,
|
||||
copyPropertyAccessorBodiesLoweringPass,
|
||||
foldConstantLoweringPhase,
|
||||
privateMembersLoweringPhase,
|
||||
privateMemberUsagesLoweringPhase,
|
||||
@@ -763,11 +776,11 @@ val loweringList = listOf<Lowering>(
|
||||
secondaryConstructorLoweringPhase,
|
||||
secondaryFactoryInjectorLoweringPhase,
|
||||
classReferenceLoweringPhase,
|
||||
constLoweringPhase,
|
||||
inlineClassDeclarationLoweringPhase,
|
||||
inlineClassUsageLoweringPhase,
|
||||
autoboxingTransformerPhase,
|
||||
blockDecomposerLoweringPhase,
|
||||
constLoweringPhase,
|
||||
objectDeclarationLoweringPhase,
|
||||
invokeStaticInitializersPhase,
|
||||
objectUsageLoweringPhase,
|
||||
|
||||
+37
@@ -0,0 +1,37 @@
|
||||
/*
|
||||
* Copyright 2010-2020 JetBrains s.r.o. and Kotlin Programming Language contributors.
|
||||
* Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
|
||||
*/
|
||||
|
||||
package org.jetbrains.kotlin.ir.backend.js.lower
|
||||
|
||||
import org.jetbrains.kotlin.backend.common.CommonBackendContext
|
||||
import org.jetbrains.kotlin.backend.common.DeclarationTransformer
|
||||
import org.jetbrains.kotlin.ir.declarations.IrDeclaration
|
||||
import org.jetbrains.kotlin.ir.declarations.IrField
|
||||
import org.jetbrains.kotlin.ir.declarations.IrSimpleFunction
|
||||
import org.jetbrains.kotlin.ir.expressions.IrBlockBody
|
||||
import org.jetbrains.kotlin.ir.util.deepCopyWithSymbols
|
||||
|
||||
// Copies property accessors and initializers so that the PropertyAccessorInilineLowering may access them safely.
|
||||
class CopyAccessorBodyLowerings(private val context: CommonBackendContext) : DeclarationTransformer {
|
||||
override fun transformFlat(declaration: IrDeclaration): List<IrDeclaration>? {
|
||||
if (declaration is IrSimpleFunction && declaration.correspondingPropertySymbol != null) {
|
||||
declaration.body?.let { originalBody ->
|
||||
declaration.body = context.irFactory.createBlockBody(originalBody.startOffset, originalBody.endOffset) {
|
||||
statements += (originalBody.deepCopyWithSymbols(declaration) as IrBlockBody).statements
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (declaration is IrField) {
|
||||
declaration.initializer?.let { originalBody ->
|
||||
declaration.initializer = context.irFactory.createExpressionBody(originalBody.startOffset, originalBody.endOffset) {
|
||||
this.expression = originalBody.expression.deepCopyWithSymbols(declaration)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return null
|
||||
}
|
||||
}
|
||||
+29
-32
@@ -161,39 +161,36 @@ class IrElementToJsExpressionTransformer : BaseIrElementToJsNodeTransformer<JsEx
|
||||
val function = expression.symbol.owner
|
||||
val arguments = translateCallArguments(expression, context, this)
|
||||
val klass = function.parentAsClass
|
||||
return if (klass.isInline) {
|
||||
assert(function.isPrimary) {
|
||||
"Inline class secondary constructors must be lowered into static methods"
|
||||
|
||||
require(!klass.isInline) {
|
||||
"All inline class constructor calls must be lowered to static function calls"
|
||||
}
|
||||
|
||||
return when {
|
||||
klass.isEffectivelyExternal() -> {
|
||||
val refForExternalClass = context.getRefForExternalClass(klass)
|
||||
val varargParameterIndex = expression.symbol.owner.varargParameterIndex()
|
||||
if (varargParameterIndex == -1) {
|
||||
JsNew(refForExternalClass, arguments)
|
||||
} else {
|
||||
val argumentsAsSingleArray = argumentsWithVarargAsSingleArray(
|
||||
JsNullLiteral(),
|
||||
arguments,
|
||||
varargParameterIndex
|
||||
)
|
||||
JsNew(
|
||||
JsInvocation(
|
||||
JsNameRef("apply", JsNameRef("bind", JsNameRef("Function"))),
|
||||
refForExternalClass,
|
||||
argumentsAsSingleArray
|
||||
),
|
||||
emptyList()
|
||||
)
|
||||
}
|
||||
}
|
||||
// Argument value constructs unboxed inline class instance
|
||||
arguments.single()
|
||||
} else {
|
||||
when {
|
||||
klass.isEffectivelyExternal() -> {
|
||||
val refForExternalClass = context.getRefForExternalClass(klass)
|
||||
val varargParameterIndex = expression.symbol.owner.varargParameterIndex()
|
||||
if (varargParameterIndex == -1) {
|
||||
JsNew(refForExternalClass, arguments)
|
||||
} else {
|
||||
val argumentsAsSingleArray = argumentsWithVarargAsSingleArray(
|
||||
JsNullLiteral(),
|
||||
arguments,
|
||||
varargParameterIndex
|
||||
)
|
||||
JsNew(
|
||||
JsInvocation(
|
||||
JsNameRef("apply", JsNameRef("bind", JsNameRef("Function"))),
|
||||
refForExternalClass,
|
||||
argumentsAsSingleArray
|
||||
),
|
||||
emptyList()
|
||||
)
|
||||
}
|
||||
}
|
||||
else -> {
|
||||
val ref = context.getNameForClass(klass).makeRef()
|
||||
JsNew(ref, arguments)
|
||||
}
|
||||
else -> {
|
||||
val ref = context.getNameForClass(klass).makeRef()
|
||||
JsNew(ref, arguments)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user