[JS IR] JsIrBuilder - add returnType and parent to buildFunction

This commit is contained in:
Svyatoslav Kuzmich
2018-11-08 17:17:07 +03:00
parent 0934db8fbd
commit fe6b36391d
9 changed files with 107 additions and 67 deletions
@@ -10,6 +10,7 @@ import org.jetbrains.kotlin.ir.backend.js.ir.JsIrBuilder
import org.jetbrains.kotlin.ir.backend.js.utils.Namer
import org.jetbrains.kotlin.ir.declarations.IrFunction
import org.jetbrains.kotlin.ir.declarations.IrProperty
import org.jetbrains.kotlin.ir.declarations.IrSimpleFunction
import org.jetbrains.kotlin.ir.declarations.impl.IrExternalPackageFragmentImpl
import org.jetbrains.kotlin.ir.descriptors.IrBuiltIns
import org.jetbrains.kotlin.ir.symbols.impl.IrExternalPackageFragmentSymbolImpl
@@ -193,7 +194,8 @@ class JsIntrinsics(private val irBuiltIns: IrBuiltIns, val context: JsIrBackendC
// Arrays:
val array = context.symbolTable.referenceClass(irBuiltIns.builtIns.array)
val primitiveArrays = PrimitiveType.values().associate { context.symbolTable.referenceClass(irBuiltIns.builtIns.getPrimitiveArrayClassDescriptor(it)) to it }
val primitiveArrays = PrimitiveType.values()
.associate { context.symbolTable.referenceClass(irBuiltIns.builtIns.getPrimitiveArrayClassDescriptor(it)) to it }
val jsArray = getInternalFunction("arrayWithFun")
val jsFillArray = getInternalFunction("fillArrayFun")
@@ -209,12 +211,15 @@ class JsIntrinsics(private val irBuiltIns: IrBuiltIns, val context: JsIrBackendC
val arrayLiteral = unOp("arrayLiteral").symbol
val primitiveToTypedArrayMap = EnumMap(mapOf(
PrimitiveType.BYTE to "Int8",
PrimitiveType.SHORT to "Int16",
PrimitiveType.INT to "Int32",
PrimitiveType.FLOAT to "Float32",
PrimitiveType.DOUBLE to "Float64"))
val primitiveToTypedArrayMap = EnumMap(
mapOf(
PrimitiveType.BYTE to "Int8",
PrimitiveType.SHORT to "Int16",
PrimitiveType.INT to "Int32",
PrimitiveType.FLOAT to "Float32",
PrimitiveType.DOUBLE to "Float64"
)
)
val primitiveToSizeConstructor =
PrimitiveType.values().associate { type ->
@@ -241,9 +246,12 @@ class JsIntrinsics(private val irBuiltIns: IrBuiltIns, val context: JsIrBackendC
// TODO move CharSequence-related stiff to IntrinsifyCallsLowering
val charSequenceClassSymbol = context.symbolTable.referenceClass(context.getClass(FqName("kotlin.CharSequence")))
val charSequenceLengthPropertyGetterSymbol = charSequenceClassSymbol.owner.declarations.filterIsInstance<IrProperty>().first { it.name.asString() == "length" }.getter!!.symbol
val charSequenceGetFunctionSymbol = charSequenceClassSymbol.owner.declarations.filterIsInstance<IrFunction>().single { it.name.asString() == "get"}.symbol
val charSequenceSubSequenceFunctionSymbol = charSequenceClassSymbol.owner.declarations.filterIsInstance<IrFunction>().single { it.name.asString() == "subSequence"}.symbol
val charSequenceLengthPropertyGetterSymbol =
charSequenceClassSymbol.owner.declarations.filterIsInstance<IrProperty>().first { it.name.asString() == "length" }.getter!!.symbol
val charSequenceGetFunctionSymbol =
charSequenceClassSymbol.owner.declarations.filterIsInstance<IrFunction>().single { it.name.asString() == "get" }.symbol
val charSequenceSubSequenceFunctionSymbol =
charSequenceClassSymbol.owner.declarations.filterIsInstance<IrFunction>().single { it.name.asString() == "subSequence" }.symbol
val jsCharSequenceGet = getInternalFunction("charSequenceGet")
@@ -265,42 +273,55 @@ class JsIntrinsics(private val irBuiltIns: IrBuiltIns, val context: JsIrBackendC
context.symbolTable.referenceClass(context.getClass(FqName(fqName)))
// TODO: unify how we create intrinsic symbols
private fun defineObjectCreateIntrinsic() =
JsIrBuilder.buildFunction("Object\$create", isInline = true, origin = JsLoweredDeclarationOrigin.JS_INTRINSICS_STUB).also {
private fun defineObjectCreateIntrinsic(): IrSimpleFunction {
return JsIrBuilder.buildFunction(
"Object\$create",
returnType = irBuiltIns.anyType,
parent = externalPackageFragment,
isInline = true,
origin = JsLoweredDeclarationOrigin.JS_INTRINSICS_STUB
).also {
val typeParameter = JsIrBuilder.buildTypeParameter(Name.identifier("T"), 0, true)
val anyType = irBuiltIns.anyType
typeParameter.parent = it
typeParameter.superTypes += anyType
typeParameter.superTypes += irBuiltIns.anyType
it.typeParameters += typeParameter
it.returnType = anyType
it.parent = externalPackageFragment
externalPackageFragment.declarations += it
}
}
private fun defineGetJSPropertyIntrinsic() =
JsIrBuilder.buildFunction("\$getJSProperty\$", origin = JsLoweredDeclarationOrigin.JS_INTRINSICS_STUB).also {
it.returnType = irBuiltIns.anyNType
JsIrBuilder.buildFunction(
"\$getJSProperty\$",
returnType = irBuiltIns.anyNType,
parent = externalPackageFragment,
origin = JsLoweredDeclarationOrigin.JS_INTRINSICS_STUB
).also {
listOf("receiver", "fieldName").mapIndexedTo(it.valueParameters) { i, p ->
JsIrBuilder.buildValueParameter(p, i, irBuiltIns.anyType).also { v -> v.parent = it }
}
it.parent = externalPackageFragment
externalPackageFragment.declarations += it
}
private fun defineSetJSPropertyIntrinsic() =
JsIrBuilder.buildFunction("\$setJSProperty\$", origin = JsLoweredDeclarationOrigin.JS_INTRINSICS_STUB).also {
it.returnType = irBuiltIns.unitType
JsIrBuilder.buildFunction(
"\$setJSProperty\$",
returnType = irBuiltIns.unitType,
parent = externalPackageFragment,
origin = JsLoweredDeclarationOrigin.JS_INTRINSICS_STUB
).also {
listOf("receiver", "fieldName", "fieldValue").mapIndexedTo(it.valueParameters) { i, p ->
JsIrBuilder.buildValueParameter(p, i, irBuiltIns.anyType).also { v -> v.parent = it }
}
it.parent = externalPackageFragment
externalPackageFragment.declarations += it
}
private fun defineUnreachableIntrinsic() =
JsIrBuilder.buildFunction(Namer.UNREACHABLE_NAME, origin = JsLoweredDeclarationOrigin.JS_INTRINSICS_STUB).also {
it.returnType = irBuiltIns.nothingType
it.parent = externalPackageFragment
JsIrBuilder.buildFunction(
Namer.UNREACHABLE_NAME,
returnType = irBuiltIns.nothingType,
parent = externalPackageFragment,
origin = JsLoweredDeclarationOrigin.JS_INTRINSICS_STUB
).also {
externalPackageFragment.declarations += it
}
@@ -97,6 +97,8 @@ object JsIrBuilder {
fun buildFunction(
name: String,
returnType: IrType,
parent: IrDeclarationParent,
visibility: Visibility = Visibilities.PUBLIC,
modality: Modality = Modality.FINAL,
isInline: Boolean = false,
@@ -104,10 +106,23 @@ object JsIrBuilder {
isTailrec: Boolean = false,
isSuspend: Boolean = false,
origin: IrDeclarationOrigin = SYNTHESIZED_DECLARATION
) = JsIrBuilder.buildFunction(Name.identifier(name), visibility, modality, isInline, isExternal, isTailrec, isSuspend, origin)
) = JsIrBuilder.buildFunction(
Name.identifier(name),
returnType,
parent,
visibility,
modality,
isInline,
isExternal,
isTailrec,
isSuspend,
origin
)
fun buildFunction(
name: Name,
returnType: IrType,
parent: IrDeclarationParent,
visibility: Visibility = Visibilities.PUBLIC,
modality: Modality = Modality.FINAL,
isInline: Boolean = false,
@@ -129,7 +144,11 @@ object JsIrBuilder {
isExternal,
isTailrec,
isSuspend
).also { descriptor.bind(it) }
).also {
descriptor.bind(it)
it.returnType = returnType
it.parent = parent
}
}
fun buildGetObjectValue(type: IrType, classSymbol: IrClassSymbol) =
@@ -55,10 +55,12 @@ class BlockDecomposerLowering(context: JsIrBackendContext) : DeclarationContaine
fun lower(irField: IrField, container: IrDeclarationContainer): List<IrDeclaration> {
irField.initializer?.apply {
val initFunction = JsIrBuilder.buildFunction(irField.name.asString() + "\$init\$", irField.visibility).also {
it.parent = container
it.returnType = expression.type
}
val initFunction = JsIrBuilder.buildFunction(
irField.name.asString() + "\$init\$",
expression.type,
container,
irField.visibility
)
val newBody = toBlockBody(initFunction)
@@ -425,11 +427,14 @@ class BlockDecomposerTransformer(context: JsIrBackendContext) : IrElementTransfo
override fun visitSetField(expression: IrSetField) = expression.asExpression(unitValue)
override fun visitBreakContinue(jump: IrBreakContinue) = jump.asExpression(JsIrBuilder.buildCall(unreachableFunction.symbol, nothingType))
override fun visitBreakContinue(jump: IrBreakContinue) =
jump.asExpression(JsIrBuilder.buildCall(unreachableFunction.symbol, nothingType))
override fun visitThrow(expression: IrThrow) = expression.asExpression(JsIrBuilder.buildCall(unreachableFunction.symbol, nothingType))
override fun visitThrow(expression: IrThrow) =
expression.asExpression(JsIrBuilder.buildCall(unreachableFunction.symbol, nothingType))
override fun visitReturn(expression: IrReturn) = expression.asExpression(JsIrBuilder.buildCall(unreachableFunction.symbol, nothingType))
override fun visitReturn(expression: IrReturn) =
expression.asExpression(JsIrBuilder.buildCall(unreachableFunction.symbol, nothingType))
override fun visitVariable(declaration: IrVariable) = declaration.asExpression(unitValue)
@@ -104,6 +104,8 @@ class BridgesConstruction(val context: JsIrBackendContext) : ClassLoweringPass {
// TODO: Support offsets for debug info
val irFunction = JsIrBuilder.buildFunction(
bridge.name,
bridge.returnType,
delegateTo.parent,
bridge.visibility,
bridge.modality, // TODO: should copy modality?
bridge.isInline,
@@ -121,8 +123,6 @@ class BridgesConstruction(val context: JsIrBackendContext) : ClassLoweringPass {
typeParameters += bridge.typeParameters
valueParameters += bridge.valueParameters.map { p -> p.copyTo(this) }
annotations += bridge.annotations
returnType = bridge.returnType
parent = delegateTo.parent
overriddenSymbols.addAll(delegateTo.overriddenSymbols)
}
@@ -394,7 +394,9 @@ class CallableReferenceLowering(val context: JsIrBackendContext) : FileLoweringP
callable.dispatchReceiverParameter?.let { dispatch ->
if (reference.dispatchReceiver == null) {
result.add(JsIrBuilder.buildValueParameter(dispatch.name, result.size, dispatch.type.boxIfInlined()).also { it.parent = closure })
result.add(JsIrBuilder.buildValueParameter(dispatch.name, result.size, dispatch.type.boxIfInlined()).also {
it.parent = closure
})
} else {
// do not add dispatch receiver in result signature if it is bound
capturedParams--
@@ -434,10 +436,7 @@ class CallableReferenceLowering(val context: JsIrBackendContext) : FileLoweringP
val boundValueParameters = receivers + declaration.valueParameters.filter { it.origin == BOUND_VALUE_PARAMETER }
val factoryDeclaration = JsIrBuilder.buildFunction(getterName, declaration.visibility)
factoryDeclaration.parent = implicitDeclarationFile
factoryDeclaration.returnType = reference.type
val factoryDeclaration = JsIrBuilder.buildFunction(getterName, reference.type, implicitDeclarationFile, declaration.visibility)
for ((i, p) in boundValueParameters.withIndex()) {
val descriptor = WrappedValueParameterDescriptor()
@@ -491,18 +490,22 @@ class CallableReferenceLowering(val context: JsIrBackendContext) : FileLoweringP
arity: Int
): IrFunction {
val closureName = createClosureInstanceName(declaration)
val returnType = declaration.returnType.boxIfInlined()
val closureFunction =
JsIrBuilder.buildFunction(closureName, Visibilities.LOCAL, origin = JsIrBackendContext.callableClosureOrigin)
.also { it.parent = factoryFunction }
JsIrBuilder.buildFunction(
closureName,
returnType,
factoryFunction,
Visibilities.LOCAL,
origin = JsIrBackendContext.callableClosureOrigin
)
// the params which are passed to closure
val boundParamSymbols = factoryFunction.valueParameters.map { it.symbol }
val unboundParamDeclarations = generateSignatureForClosure(declaration, factoryFunction, closureFunction, reference, arity)
val unboundParamSymbols = unboundParamDeclarations.map { it.symbol }
val returnType = declaration.returnType.boxIfInlined()
closureFunction.valueParameters += unboundParamDeclarations
closureFunction.returnType = returnType
val callTarget = context.ir.defaultParameterDeclarationsCache[declaration] ?: declaration
@@ -72,10 +72,11 @@ class EnumUsageLowering(val context: JsIrBackendContext) : FileLoweringPass {
private fun lowerEnumEntry(enumEntry: IrEnumEntry, klass: IrClass) =
context.enumEntryToGetInstanceFunction.getOrPut(enumEntry.symbol) {
JsIrBuilder.buildFunction(createEntryAccessorName(klass.name.identifier, enumEntry)).also {
it.returnType = enumEntry.getType(klass)
it.parent = klass
}
JsIrBuilder.buildFunction(
createEntryAccessorName(klass.name.identifier, enumEntry),
returnType = enumEntry.getType(klass),
parent = klass
)
}.run { JsIrBuilder.buildCall(symbol) }
}
@@ -442,18 +443,13 @@ class EnumClassTransformer(val context: JsIrBackendContext, private val irClass:
private fun buildFunction(
name: String,
returnType: IrType = context.irBuiltIns.unitType
) = JsIrBuilder.buildFunction(name).also {
it.returnType = returnType
it.parent = irClass
}
) = JsIrBuilder.buildFunction(name, returnType, irClass)
private fun buildFunction(
name: String,
returnType: IrType = context.irBuiltIns.unitType,
bodyBuilder: IrBlockBodyBuilder.() -> Unit
) = JsIrBuilder.buildFunction(name).also {
it.returnType = returnType
it.parent = irClass
) = JsIrBuilder.buildFunction(name, returnType, irClass).also {
it.body = context.createIrBuilder(it.symbol).irBlockBody(it, bodyBuilder)
}
@@ -149,6 +149,8 @@ class SecondaryCtorLowering(val context: JsIrBackendContext) {
return JsIrBuilder.buildFunction(
functionName,
type,
declaration.parent,
declaration.visibility,
Modality.FINAL,
declaration.isInline,
@@ -163,9 +165,6 @@ class SecondaryCtorLowering(val context: JsIrBackendContext) {
val newValueParameters = declaration.valueParameters.map { p -> p.copyTo(it) }
it.valueParameters += (newValueParameters + thisParam)
it.returnType = type
it.parent = declaration.parent
val oldValueParameters = declaration.valueParameters + oldThisReceiver
// TODO: replace parameters as well
@@ -186,6 +185,8 @@ class SecondaryCtorLowering(val context: JsIrBackendContext) {
return JsIrBuilder.buildFunction(
functionName,
type,
declaration.parent,
declaration.visibility,
Modality.FINAL,
declaration.isInline,
@@ -193,9 +194,6 @@ class SecondaryCtorLowering(val context: JsIrBackendContext) {
).also {
it.copyTypeParametersFrom(declaration)
it.valueParameters += declaration.valueParameters.map { p -> p.copyTo(it) }
it.parent = declaration.parent
it.returnType = type
val createFunctionIntrinsic = context.intrinsics.jsObjectCreate
val irCreateCall = JsIrBuilder.buildCall(createFunctionIntrinsic.symbol, type, listOf(type))
@@ -180,10 +180,8 @@ class ThrowableSuccessorsLowering(context: JsIrBackendContext) : FileLoweringPas
private fun createPropertyAccessor(fakeAccessor: IrSimpleFunction, field: IrField) {
val name = fakeAccessor.name
val function = JsIrBuilder.buildFunction(name).apply {
parent = fakeAccessor.parent
val function = JsIrBuilder.buildFunction(name, fakeAccessor.returnType, fakeAccessor.parent).apply {
overriddenSymbols += fakeAccessor.overriddenSymbols
returnType = fakeAccessor.returnType
correspondingProperty = fakeAccessor.correspondingProperty
dispatchReceiverParameter = fakeAccessor.dispatchReceiverParameter
}
@@ -440,6 +440,8 @@ internal class SuspendFunctionsLowering(val context: JsIrBackendContext): FileLo
fun createFakeOverride(irFunction: IrSimpleFunction) = JsIrBuilder.buildFunction(
irFunction.name,
irFunction.returnType,
this,
irFunction.visibility,
Modality.FINAL,
irFunction.isInline,
@@ -448,8 +450,6 @@ internal class SuspendFunctionsLowering(val context: JsIrBackendContext): FileLo
irFunction.isSuspend,
IrDeclarationOrigin.FAKE_OVERRIDE
).apply {
parent = this@setSuperSymbolsAndAddFakeOverrides
returnType = irFunction.returnType
overriddenSymbols += irFunction.symbol
copyParameterDeclarationsFrom(irFunction)
}