IR: declaration builders, initial iteration, use in some JVM lowerings

This commit is contained in:
Dmitry Petrov
2019-02-19 17:43:44 +03:00
parent 1846ec83e1
commit c248dd29c2
9 changed files with 459 additions and 279 deletions
@@ -0,0 +1,121 @@
/*
* Copyright 2010-2019 JetBrains s.r.o. 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.builders.declarations
import org.jetbrains.kotlin.backend.common.descriptors.*
import org.jetbrains.kotlin.ir.declarations.*
import org.jetbrains.kotlin.ir.declarations.impl.*
import org.jetbrains.kotlin.ir.symbols.impl.*
import org.jetbrains.kotlin.ir.types.IrType
import org.jetbrains.kotlin.name.Name
fun IrClassBuilder.buildClass(): IrClass {
val wrappedDescriptor = WrappedClassDescriptor()
return IrClassImpl(
startOffset, endOffset, origin,
IrClassSymbolImpl(wrappedDescriptor),
name, kind, visibility, modality, isCompanion, isInner, isData, isExternal, isInline
).also {
wrappedDescriptor.bind(it)
}
}
inline fun buildClass(b: IrClassBuilder.() -> Unit) =
IrClassBuilder().run {
b()
buildClass()
}
fun IrFieldBuilder.buildField(): IrField {
val wrappedDescriptor = WrappedFieldDescriptor()
return IrFieldImpl(
startOffset, endOffset, origin,
IrFieldSymbolImpl(wrappedDescriptor),
name, type, visibility, isFinal, isExternal, isStatic
).also {
wrappedDescriptor.bind(it)
}
}
inline fun buildField(b: IrFieldBuilder.() -> Unit) =
IrFieldBuilder().run {
b()
buildField()
}
fun IrFunctionBuilder.buildFun(): IrSimpleFunction {
val wrappedDescriptor = WrappedSimpleFunctionDescriptor()
return IrFunctionImpl(
startOffset, endOffset, origin,
IrSimpleFunctionSymbolImpl(wrappedDescriptor),
name, visibility, modality, returnType,
isInline = isInline, isExternal = isExternal, isTailrec = isTailrec, isSuspend = isSuspend
).also {
wrappedDescriptor.bind(it)
}
}
fun IrFunctionBuilder.buildConstructor(): IrConstructor {
val wrappedDescriptor = WrappedClassConstructorDescriptor()
return IrConstructorImpl(
startOffset, endOffset, origin,
IrConstructorSymbolImpl(wrappedDescriptor),
Name.special("<init>"),
visibility, returnType,
isInline = isInline, isExternal = isExternal, isPrimary = isPrimary
).also {
wrappedDescriptor.bind(it)
}
}
inline fun buildFun(b: IrFunctionBuilder.() -> Unit): IrSimpleFunction =
IrFunctionBuilder().run {
b()
buildFun()
}
inline fun buildConstructor(b: IrFunctionBuilder.() -> Unit): IrConstructor =
IrFunctionBuilder().run {
b()
buildConstructor()
}
fun IrValueParameterBuilder.build(): IrValueParameter {
val wrappedDescriptor = WrappedValueParameterDescriptor()
return IrValueParameterImpl(
startOffset, endOffset, origin,
IrValueParameterSymbolImpl(wrappedDescriptor),
name, index, type, varargElementType, isCrossInline, isNoinline
).also {
wrappedDescriptor.bind(it)
}
}
inline fun buildValueParameter(b: IrValueParameterBuilder.() -> Unit): IrValueParameter =
IrValueParameterBuilder().run {
b()
build()
}
inline fun IrFunction.addValueParameter(b: IrValueParameterBuilder.() -> Unit): IrValueParameter =
IrValueParameterBuilder().run {
b()
if (index == UNDEFINED_PARAMETER_INDEX) {
index = valueParameters.size
}
build().also { valueParameter ->
valueParameters.add(valueParameter)
valueParameter.parent = this@addValueParameter
}
}
fun IrFunction.addValueParameter(name: Name, type: IrType, origin: IrDeclarationOrigin): IrValueParameter =
addValueParameter {
this.name = name
this.type = type
this.origin = origin
}
@@ -18,24 +18,31 @@ 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.descriptors.*
import org.jetbrains.kotlin.backend.common.descriptors.isFunctionOrKFunctionType
import org.jetbrains.kotlin.backend.common.descriptors.synthesizedName
import org.jetbrains.kotlin.backend.common.ir.copyTo
import org.jetbrains.kotlin.backend.common.ir.createImplicitParameterDeclarationWithWrappedDescriptor
import org.jetbrains.kotlin.backend.common.lower.*
import org.jetbrains.kotlin.backend.common.lower.createIrBuilder
import org.jetbrains.kotlin.backend.common.lower.irBlock
import org.jetbrains.kotlin.backend.common.lower.irIfThen
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.isInlineIrExpression
import org.jetbrains.kotlin.codegen.PropertyReferenceCodegen
import org.jetbrains.kotlin.descriptors.*
import org.jetbrains.kotlin.descriptors.ClassKind
import org.jetbrains.kotlin.descriptors.Modality
import org.jetbrains.kotlin.descriptors.Visibilities
import org.jetbrains.kotlin.ir.UNDEFINED_OFFSET
import org.jetbrains.kotlin.ir.builders.*
import org.jetbrains.kotlin.ir.builders.declarations.buildClass
import org.jetbrains.kotlin.ir.builders.declarations.buildConstructor
import org.jetbrains.kotlin.ir.builders.declarations.buildField
import org.jetbrains.kotlin.ir.builders.declarations.buildFun
import org.jetbrains.kotlin.ir.declarations.*
import org.jetbrains.kotlin.ir.declarations.impl.*
import org.jetbrains.kotlin.ir.expressions.*
import org.jetbrains.kotlin.ir.expressions.impl.*
import org.jetbrains.kotlin.ir.symbols.*
import org.jetbrains.kotlin.ir.symbols.impl.*
import org.jetbrains.kotlin.ir.symbols.IrValueParameterSymbol
import org.jetbrains.kotlin.ir.types.*
import org.jetbrains.kotlin.ir.types.impl.IrSimpleTypeImpl
import org.jetbrains.kotlin.ir.types.impl.makeTypeProjection
@@ -177,9 +184,6 @@ internal class CallableReferenceLowering(val context: JvmBackendContext) : FileL
var useVararg: Boolean = false
fun build(): BuiltFunctionReference {
val startOffset = irFunctionReference.startOffset
val endOffset = irFunctionReference.endOffset
val returnType = irFunctionReference.symbol.owner.returnType
val functionReferenceClassSuperTypes: MutableList<IrType> = mutableListOf(
functionReferenceOrLambda.owner.defaultType // type arguments?
@@ -206,12 +210,11 @@ internal class CallableReferenceLowering(val context: JvmBackendContext) : FileL
)
var suspendFunctionClass: IrClass? = null
var suspendFunctionClassTypeParameters: List<IrType>? = null
val lastParameterType = unboundCalleeParameters.lastOrNull()?.type
if ((lastParameterType as? IrSimpleType)?.classifier == continuationClass) {
// If the last parameter is Continuation<> inherit from SuspendFunction.
suspendFunctionClass = context.getIrClass(FqName("kotlin.Suspendfunction${numberOfParameters - 1}")).owner
suspendFunctionClassTypeParameters = functionParameterTypes.dropLast(1) +
val suspendFunctionClassTypeParameters = functionParameterTypes.dropLast(1) +
(lastParameterType.arguments.single() as IrTypeProjection).type
functionReferenceClassSuperTypes += IrSimpleTypeImpl(
suspendFunctionClass.symbol,
@@ -221,22 +224,14 @@ internal class CallableReferenceLowering(val context: JvmBackendContext) : FileL
)
}
val functionReferenceClassDescriptor = WrappedClassDescriptor()
functionReferenceClass = IrClassImpl(
startOffset, endOffset,
JvmLoweredDeclarationOrigin.FUNCTION_REFERENCE_IMPL,
IrClassSymbolImpl(functionReferenceClassDescriptor),
name = "${callee.name}\$${functionReferenceCount++}".synthesizedName,
kind = ClassKind.CLASS,
visibility = Visibilities.PUBLIC,
modality = Modality.FINAL,
isCompanion = false,
isInner = false,
isData = false,
isExternal = false,
isInline = false
).apply {
functionReferenceClassDescriptor.bind(this)
functionReferenceClass = buildClass {
setSourceRange(irFunctionReference)
origin = JvmLoweredDeclarationOrigin.FUNCTION_REFERENCE_IMPL
name = "${callee.name}\$${functionReferenceCount++}".synthesizedName
kind = ClassKind.CLASS
visibility = Visibilities.PUBLIC
modality = Modality.FINAL
}.apply {
parent = referenceParent
superTypes.addAll(functionReferenceClassSuperTypes)
createImplicitParameterDeclarationWithWrappedDescriptor()
@@ -256,9 +251,12 @@ internal class CallableReferenceLowering(val context: JvmBackendContext) : FileL
functionReferenceClass.declarations.add(invokeMethod)
if (!isLambda) {
val getSignatureMethod = createGetSignatureMethod(functionReferenceOrLambda.owner.functions.find { it.name.asString() == "getSignature"}!!)
val getNameMethod = createGetNameMethod(functionReferenceOrLambda.owner.properties.find { it.name.asString() == "name" }!!)
val getOwnerMethod = createGetOwnerMethod(functionReferenceOrLambda.owner.functions.find { it.name.asString() == "getOwner" }!!)
val getSignatureMethod =
createGetSignatureMethod(functionReferenceOrLambda.owner.functions.find { it.name.asString() == "getSignature"}!!)
val getNameMethod =
createGetNameMethod(functionReferenceOrLambda.owner.properties.find { it.name.asString() == "name" }!!)
val getOwnerMethod =
createGetOwnerMethod(functionReferenceOrLambda.owner.functions.find { it.name.asString() == "getOwner" }!!)
val suspendInvokeMethod =
if (suspendFunctionClass != null) {
@@ -276,21 +274,15 @@ internal class CallableReferenceLowering(val context: JvmBackendContext) : FileL
return BuiltFunctionReference(functionReferenceClass, constructor)
}
private fun createConstructor(): IrConstructor {
val descriptor = WrappedClassConstructorDescriptor()
return IrConstructorImpl(
irFunctionReference.startOffset, irFunctionReference.endOffset,
JvmLoweredDeclarationOrigin.FUNCTION_REFERENCE_IMPL,
IrConstructorSymbolImpl(descriptor),
name = Name.special("<init>"),
visibility = Visibilities.PUBLIC,
returnType = functionReferenceClass.defaultType,
isInline = false,
isExternal = false,
private fun createConstructor(): IrConstructor =
buildConstructor {
setSourceRange(irFunctionReference)
origin = JvmLoweredDeclarationOrigin.FUNCTION_REFERENCE_IMPL
visibility = Visibilities.PUBLIC
returnType = functionReferenceClass.defaultType
isPrimary = true
).apply {
}.apply {
val constructor = this
descriptor.bind(this)
parent = functionReferenceClass
val boundArgsSet = boundCalleeParameters.toSet()
@@ -341,25 +333,17 @@ internal class CallableReferenceLowering(val context: JvmBackendContext) : FileL
+IrInstanceInitializerCallImpl(startOffset, endOffset, functionReferenceClass.symbol, context.irBuiltIns.unitType)
}
}
}
private fun createInvokeMethod(superFunction: IrSimpleFunction) : IrSimpleFunction {
val descriptor = WrappedSimpleFunctionDescriptor()
return IrFunctionImpl(
irFunctionReference.startOffset, irFunctionReference.endOffset,
JvmLoweredDeclarationOrigin.FUNCTION_REFERENCE_IMPL,
IrSimpleFunctionSymbolImpl(descriptor),
Name.identifier("invoke"),
Visibilities.PUBLIC,
Modality.FINAL,
returnType = callee.returnType,
isInline = false, // not sure
isExternal = false,
isTailrec = false,
private fun createInvokeMethod(superFunction: IrSimpleFunction): IrSimpleFunction =
buildFun {
setSourceRange(irFunctionReference)
origin = JvmLoweredDeclarationOrigin.FUNCTION_REFERENCE_IMPL
name = Name.identifier("invoke")
visibility = Visibilities.PUBLIC
returnType = callee.returnType
isSuspend = superFunction.isSuspend
).apply {
}.apply {
val function = this
descriptor.bind(this)
parent = functionReferenceClass
overriddenSymbols.add(superFunction.symbol)
dispatchReceiverParameter = functionReferenceClass.thisReceiver?.copyTo(function)
@@ -448,47 +432,29 @@ internal class CallableReferenceLowering(val context: JvmBackendContext) : FileL
}
}
}
private fun buildField(name: Name, type: IrType): IrField {
val descriptor = WrappedFieldDescriptor()
// TODO: make it synthetic
val field = IrFieldImpl(
irFunctionReference.startOffset,
irFunctionReference.endOffset,
JvmLoweredDeclarationOrigin.FUNCTION_REFERENCE_IMPL,
IrFieldSymbolImpl(descriptor),
name,
type,
JavaVisibilities.PACKAGE_VISIBILITY,
isFinal = true,
isExternal = false,
isStatic = false
).apply {
descriptor.bind(this)
private fun buildField(fieldName: Name, fieldType: IrType): IrField =
buildField {
setSourceRange(irFunctionReference)
origin = JvmLoweredDeclarationOrigin.FUNCTION_REFERENCE_IMPL
name = fieldName
type = fieldType
visibility = JavaVisibilities.PACKAGE_VISIBILITY
isFinal = true
}.also {
functionReferenceClass.declarations.add(it)
}
functionReferenceClass.declarations.add(field)
return field
}
private fun createGetSignatureMethod(superFunction: IrSimpleFunction): IrSimpleFunction {
val descriptor = WrappedSimpleFunctionDescriptor()
return IrFunctionImpl(
irFunctionReference.startOffset, irFunctionReference.endOffset,
JvmLoweredDeclarationOrigin.FUNCTION_REFERENCE_IMPL,
IrSimpleFunctionSymbolImpl(descriptor),
Name.identifier("getSignature"),
superFunction.visibility,
superFunction.modality,
returnType = superFunction.returnType,
isInline = false,
isExternal = false,
isTailrec = false,
isSuspend = false
).apply {
private fun createGetSignatureMethod(superFunction: IrSimpleFunction): IrSimpleFunction =
buildFun {
setSourceRange(irFunctionReference)
origin = JvmLoweredDeclarationOrigin.FUNCTION_REFERENCE_IMPL
name = Name.identifier("getSignature")
returnType = superFunction.returnType
visibility = superFunction.visibility
modality = superFunction.modality
}.apply {
val function = this
descriptor.bind(this)
parent = functionReferenceClass
overriddenSymbols.add(superFunction.symbol)
dispatchReceiverParameter = functionReferenceClass.thisReceiver!!.copyTo(function)
@@ -505,26 +471,18 @@ internal class CallableReferenceLowering(val context: JvmBackendContext) : FileL
)
}
}
}
private fun createGetNameMethod(superNameProperty: IrProperty): IrSimpleFunction {
val superGetter = superNameProperty.getter!!
val descriptor = WrappedSimpleFunctionDescriptor()
return IrFunctionImpl(
irFunctionReference.startOffset, irFunctionReference.endOffset,
JvmLoweredDeclarationOrigin.FUNCTION_REFERENCE_IMPL,
IrSimpleFunctionSymbolImpl(descriptor),
Name.identifier("getName"),
superGetter.visibility,
superGetter.modality,
returnType = superGetter.returnType,
isInline = false,
isExternal = false,
isTailrec = false,
isSuspend = false
).apply {
return buildFun {
setSourceRange(irFunctionReference)
origin = JvmLoweredDeclarationOrigin.FUNCTION_REFERENCE_IMPL
name = Name.identifier("getName")
returnType = superGetter.returnType
visibility = superGetter.visibility
modality = superGetter.modality
}.apply {
val function = this
descriptor.bind(this)
parent = functionReferenceClass
overriddenSymbols.add(superGetter.symbol)
dispatchReceiverParameter = functionReferenceClass.thisReceiver?.copyTo(function)
@@ -538,23 +496,16 @@ internal class CallableReferenceLowering(val context: JvmBackendContext) : FileL
}
}
private fun createGetOwnerMethod(superFunction: IrSimpleFunction): IrSimpleFunction {
val descriptor = WrappedSimpleFunctionDescriptor()
return IrFunctionImpl(
functionReferenceClass.startOffset, functionReferenceClass.endOffset,
JvmLoweredDeclarationOrigin.FUNCTION_REFERENCE_IMPL,
IrSimpleFunctionSymbolImpl(descriptor),
Name.identifier("getOwner"),
superFunction.visibility,
superFunction.modality,
returnType = superFunction.returnType,
isInline = false,
isExternal = false,
isTailrec = false,
isSuspend = false
).apply {
private fun createGetOwnerMethod(superFunction: IrSimpleFunction): IrSimpleFunction =
buildFun {
setSourceRange(functionReferenceClass)
origin = JvmLoweredDeclarationOrigin.FUNCTION_REFERENCE_IMPL
name = Name.identifier("getOwner")
returnType = superFunction.returnType
visibility = superFunction.visibility
modality = superFunction.modality
}.apply {
val function = this
descriptor.bind(this)
parent = functionReferenceClass
overriddenSymbols.add(superFunction.symbol)
dispatchReceiverParameter = functionReferenceClass.thisReceiver?.copyTo(function)
@@ -566,7 +517,6 @@ internal class CallableReferenceLowering(val context: JvmBackendContext) : FileL
)
}
}
}
fun IrBuilderWithScope.generateCallableReferenceDeclarationContainer(): IrExpression {
val globalContext = this@CallableReferenceLowering.context
@@ -5,31 +5,32 @@
package org.jetbrains.kotlin.backend.jvm.lower
import org.jetbrains.kotlin.backend.common.*
import org.jetbrains.kotlin.backend.common.descriptors.WrappedClassConstructorDescriptor
import org.jetbrains.kotlin.backend.common.descriptors.WrappedSimpleFunctionDescriptor
import org.jetbrains.kotlin.backend.common.descriptors.WrappedValueParameterDescriptor
import org.jetbrains.kotlin.backend.common.ir.*
import org.jetbrains.kotlin.backend.common.FileLoweringPass
import org.jetbrains.kotlin.backend.common.IrElementTransformerVoidWithContext
import org.jetbrains.kotlin.backend.common.IrElementVisitorVoidWithContext
import org.jetbrains.kotlin.backend.common.ScopeWithIr
import org.jetbrains.kotlin.backend.common.ir.copyTypeParametersFrom
import org.jetbrains.kotlin.backend.common.ir.copyValueParametersToStatic
import org.jetbrains.kotlin.backend.common.ir.remapTypeParameters
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.intrinsics.receiverAndArgs
import org.jetbrains.kotlin.codegen.OwnerKind
import org.jetbrains.kotlin.descriptors.*
import org.jetbrains.kotlin.descriptors.FunctionDescriptor
import org.jetbrains.kotlin.descriptors.Modality
import org.jetbrains.kotlin.descriptors.PropertyDescriptor
import org.jetbrains.kotlin.descriptors.Visibilities
import org.jetbrains.kotlin.ir.IrElement
import org.jetbrains.kotlin.ir.UNDEFINED_OFFSET
import org.jetbrains.kotlin.ir.builders.declarations.addValueParameter
import org.jetbrains.kotlin.ir.builders.declarations.buildConstructor
import org.jetbrains.kotlin.ir.builders.declarations.buildFun
import org.jetbrains.kotlin.ir.declarations.*
import org.jetbrains.kotlin.ir.declarations.impl.IrConstructorImpl
import org.jetbrains.kotlin.ir.declarations.impl.IrFunctionImpl
import org.jetbrains.kotlin.ir.declarations.impl.IrValueParameterImpl
import org.jetbrains.kotlin.ir.expressions.*
import org.jetbrains.kotlin.ir.expressions.impl.*
import org.jetbrains.kotlin.ir.symbols.*
import org.jetbrains.kotlin.ir.symbols.impl.IrConstructorSymbolImpl
import org.jetbrains.kotlin.ir.symbols.impl.IrSimpleFunctionSymbolImpl
import org.jetbrains.kotlin.ir.symbols.impl.IrValueParameterSymbolImpl
import org.jetbrains.kotlin.ir.types.impl.IrSimpleTypeImpl
import org.jetbrains.kotlin.ir.types.impl.IrUninitializedType
import org.jetbrains.kotlin.ir.util.*
import org.jetbrains.kotlin.ir.visitors.acceptChildrenVoid
import org.jetbrains.kotlin.ir.visitors.acceptVoid
@@ -82,14 +83,13 @@ private class SyntheticAccessorLowering(val context: JvmBackendContext) : IrElem
accumMap: MutableMap<FromSyT, ToSyT>,
symbolConverter: (FromSyT) -> ToSyT,
exprConverter: (ExprT, ToSyT) -> IrDeclarationReference
): IrExpression {
): IrExpression =
if (!symbol.isAccessible()) {
val accessorSymbol = accumMap.getOrPut(symbol, { symbolConverter(symbol) })
return exprConverter(expression, accessorSymbol)
val accessorSymbol = accumMap.getOrPut(symbol) { symbolConverter(symbol) }
exprConverter(expression, accessorSymbol)
} else {
return expression
expression
}
}
private fun makeFunctionAccessorSymbol(functionSymbol: IrFunctionSymbol): IrFunctionSymbol = when (functionSymbol) {
is IrConstructorSymbol -> functionSymbol.owner.makeConstructorAccessor().symbol
@@ -99,19 +99,13 @@ private class SyntheticAccessorLowering(val context: JvmBackendContext) : IrElem
private fun IrConstructor.makeConstructorAccessor(): IrConstructor {
val source = this
val accessorDescriptor = WrappedClassConstructorDescriptor()
return IrConstructorImpl(
UNDEFINED_OFFSET, UNDEFINED_OFFSET,
JvmLoweredDeclarationOrigin.SYNTHETIC_ACCESSOR,
IrConstructorSymbolImpl(accessorDescriptor),
name,
Visibilities.PUBLIC,
IrUninitializedType,
isInline = false,
isExternal = false,
isPrimary = false
).also { accessor ->
accessorDescriptor.bind(accessor)
return buildConstructor {
origin = JvmLoweredDeclarationOrigin.SYNTHETIC_ACCESSOR
name = source.name
visibility = Visibilities.PUBLIC
}.also { accessor ->
accessor.parent = source.parent
pendingTransformations.add { (accessor.parent as IrDeclarationContainer).declarations.add(accessor) }
@@ -119,22 +113,11 @@ private class SyntheticAccessorLowering(val context: JvmBackendContext) : IrElem
accessor.copyValueParametersToStatic(source, JvmLoweredDeclarationOrigin.SYNTHETIC_ACCESSOR)
accessor.returnType = source.returnType.remapTypeParameters(source, accessor)
val markerParameterDescriptor = WrappedValueParameterDescriptor()
val markerParameter = IrValueParameterImpl(
UNDEFINED_OFFSET, UNDEFINED_OFFSET,
JvmLoweredDeclarationOrigin.SYNTHETIC_ACCESSOR,
IrValueParameterSymbolImpl(markerParameterDescriptor),
accessor.addValueParameter(
Name.identifier("marker"),
index = accessor.valueParameters.size,
type = context.ir.symbols.defaultConstructorMarker.owner.defaultType,
varargElementType = null,
isCrossinline = false,
isNoinline = false
).apply {
markerParameterDescriptor.bind(this)
parent = accessor
}
accessor.valueParameters.add(markerParameter)
context.ir.symbols.defaultConstructorMarker.owner.defaultType,
JvmLoweredDeclarationOrigin.SYNTHETIC_ACCESSOR
)
accessor.body = IrExpressionBodyImpl(
UNDEFINED_OFFSET, UNDEFINED_OFFSET,
@@ -154,21 +137,12 @@ private class SyntheticAccessorLowering(val context: JvmBackendContext) : IrElem
private fun IrSimpleFunction.makeSimpleFunctionAccessor(): IrSimpleFunction {
val source = this
val accessorDescriptor = WrappedSimpleFunctionDescriptor()
return IrFunctionImpl(
UNDEFINED_OFFSET, UNDEFINED_OFFSET,
JvmLoweredDeclarationOrigin.SYNTHETIC_ACCESSOR,
IrSimpleFunctionSymbolImpl(accessorDescriptor),
source.descriptor.accessorName(),
Visibilities.PUBLIC,
Modality.FINAL,
IrUninitializedType,
isInline = false,
isExternal = false,
isTailrec = false,
return buildFun {
origin = JvmLoweredDeclarationOrigin.SYNTHETIC_ACCESSOR
name = source.descriptor.accessorName()
visibility = Visibilities.PUBLIC
isSuspend = source.isSuspend
).also { accessor ->
accessorDescriptor.bind(accessor)
}.also { accessor ->
accessor.parent = source.parent
pendingTransformations.add { (accessor.parent as IrDeclarationContainer).declarations.add(accessor) }
@@ -193,48 +167,27 @@ private class SyntheticAccessorLowering(val context: JvmBackendContext) : IrElem
copyAllParamsToArgs(it, accessor)
}
private fun makeGetterAccessorSymbol(fieldSymbol: IrFieldSymbol): IrSimpleFunctionSymbol {
val accessorDescriptor = WrappedSimpleFunctionDescriptor()
return IrFunctionImpl(
UNDEFINED_OFFSET, UNDEFINED_OFFSET,
JvmLoweredDeclarationOrigin.SYNTHETIC_ACCESSOR,
IrSimpleFunctionSymbolImpl(accessorDescriptor),
fieldSymbol.descriptor.accessorNameForGetter(),
Visibilities.PUBLIC,
Modality.FINAL,
fieldSymbol.owner.type,
isInline = false,
isExternal = false,
isTailrec = false,
isSuspend = false
).also { accessor ->
accessorDescriptor.bind(accessor)
private fun makeGetterAccessorSymbol(fieldSymbol: IrFieldSymbol): IrSimpleFunctionSymbol =
buildFun {
origin = JvmLoweredDeclarationOrigin.SYNTHETIC_ACCESSOR
name = fieldSymbol.descriptor.accessorNameForGetter()
visibility = Visibilities.PUBLIC
modality = Modality.FINAL
returnType = fieldSymbol.owner.type
}.also { accessor ->
accessor.parent = fieldSymbol.owner.parent
pendingTransformations.add { (accessor.parent as IrDeclarationContainer).declarations.add(accessor) }
if (!fieldSymbol.owner.isStatic) {
val receiverDescriptor = WrappedValueParameterDescriptor()
accessor.valueParameters.add(
IrValueParameterImpl(
UNDEFINED_OFFSET, UNDEFINED_OFFSET,
JvmLoweredDeclarationOrigin.SYNTHETIC_ACCESSOR,
IrValueParameterSymbolImpl(receiverDescriptor),
Name.identifier("\$this"),
index = 0,
type = (fieldSymbol.owner.parent as IrClass).defaultType,
varargElementType = null,
isCrossinline = false,
isNoinline = false
).apply {
receiverDescriptor.bind(this)
parent = accessor
}
accessor.addValueParameter(
Name.identifier("\$this"),
(fieldSymbol.owner.parent as IrClass).defaultType,
JvmLoweredDeclarationOrigin.SYNTHETIC_ACCESSOR
)
}
accessor.body = createAccessorBodyForGetter(fieldSymbol.owner, accessor)
}.symbol
}
private fun createAccessorBodyForGetter(targetField: IrField, accessor: IrSimpleFunction): IrBody {
val resolvedTargetField = targetField.resolveFakeOverride()!!
@@ -252,65 +205,29 @@ private class SyntheticAccessorLowering(val context: JvmBackendContext) : IrElem
)
}
private fun makeSetterAccessorSymbol(fieldSymbol: IrFieldSymbol): IrSimpleFunctionSymbol {
val accessorDescriptor = WrappedSimpleFunctionDescriptor()
return IrFunctionImpl(
UNDEFINED_OFFSET, UNDEFINED_OFFSET,
JvmLoweredDeclarationOrigin.SYNTHETIC_ACCESSOR,
IrSimpleFunctionSymbolImpl(accessorDescriptor),
fieldSymbol.descriptor.accessorNameForSetter(),
Visibilities.PUBLIC,
Modality.FINAL,
returnType = context.irBuiltIns.unitType,
isInline = false,
isExternal = false,
isTailrec = false,
isSuspend = false
).also { accessor ->
accessorDescriptor.bind(accessor)
private fun makeSetterAccessorSymbol(fieldSymbol: IrFieldSymbol): IrSimpleFunctionSymbol =
buildFun {
origin = JvmLoweredDeclarationOrigin.SYNTHETIC_ACCESSOR
name = fieldSymbol.descriptor.accessorNameForSetter()
visibility = Visibilities.PUBLIC
modality = Modality.FINAL
returnType = context.irBuiltIns.unitType
}.also { accessor ->
accessor.parent = fieldSymbol.owner.parent
pendingTransformations.add { (accessor.parent as IrDeclarationContainer).declarations.add(accessor) }
if (!fieldSymbol.owner.isStatic) {
val receiverDescriptor = WrappedValueParameterDescriptor()
accessor.valueParameters.add(
IrValueParameterImpl(
UNDEFINED_OFFSET, UNDEFINED_OFFSET,
JvmLoweredDeclarationOrigin.SYNTHETIC_ACCESSOR,
IrValueParameterSymbolImpl(receiverDescriptor),
Name.identifier("\$this"),
index = 0,
type = (fieldSymbol.owner.parent as IrClass).defaultType,
varargElementType = null,
isCrossinline = false,
isNoinline = false
).apply {
receiverDescriptor.bind(this)
parent = accessor
}
accessor.addValueParameter(
Name.identifier("\$this"),
(fieldSymbol.owner.parent as IrClass).defaultType,
JvmLoweredDeclarationOrigin.SYNTHETIC_ACCESSOR
)
}
val valueDescriptor = WrappedValueParameterDescriptor()
accessor.valueParameters.add(
IrValueParameterImpl(
UNDEFINED_OFFSET, UNDEFINED_OFFSET,
JvmLoweredDeclarationOrigin.SYNTHETIC_ACCESSOR,
IrValueParameterSymbolImpl(valueDescriptor),
Name.identifier("value"),
index = if (fieldSymbol.owner.isStatic) 0 else 1,
type = fieldSymbol.owner.type,
varargElementType = null,
isCrossinline = false,
isNoinline = false
).apply {
valueDescriptor.bind(this)
parent = accessor
}
)
accessor.addValueParameter(Name.identifier("value"), fieldSymbol.owner.type, JvmLoweredDeclarationOrigin.SYNTHETIC_ACCESSOR)
accessor.body = createAccessorBodyForSetter(fieldSymbol.owner, accessor)
}.symbol
}
private fun createAccessorBodyForSetter(targetField: IrField, accessor: IrSimpleFunction): IrBody {
val resolvedTargetField = targetField.resolveFakeOverride()!!
@@ -418,12 +335,12 @@ private class SyntheticAccessorLowering(val context: JvmBackendContext) : IrElem
}
delegateTo.dispatchReceiverParameter?.let {
call.dispatchReceiver =
IrGetValueImpl(UNDEFINED_OFFSET, UNDEFINED_OFFSET, syntheticFunction.valueParameters[offset++].symbol)
IrGetValueImpl(UNDEFINED_OFFSET, UNDEFINED_OFFSET, syntheticFunction.valueParameters[offset++].symbol)
}
delegateTo.extensionReceiverParameter?.let {
call.extensionReceiver =
IrGetValueImpl(UNDEFINED_OFFSET, UNDEFINED_OFFSET, syntheticFunction.valueParameters[offset++].symbol)
IrGetValueImpl(UNDEFINED_OFFSET, UNDEFINED_OFFSET, syntheticFunction.valueParameters[offset++].symbol)
}
delegateTo.valueParameters.forEachIndexed { i, _ ->
@@ -472,9 +389,8 @@ private class SyntheticAccessorLowering(val context: JvmBackendContext) : IrElem
// The only two visibilities where Kotlin rules differ from JVM rules.
if (!Visibilities.isPrivate(declaration.visibility) && declaration.visibility != Visibilities.PROTECTED) return true
val symbolDeclarationContainer = (declaration.parent as? IrDeclarationContainer) as? IrElement
// If local variables are accessible by Kotlin rules, they also are by Java rules.
if (symbolDeclarationContainer == null) return true
val symbolDeclarationContainer = (declaration.parent as? IrDeclarationContainer) as? IrElement ?: return true
// Within inline functions, we have to assume the worst.
if (inlinedLambdasCollector.isInlineNonpublicContext(allScopes))
@@ -497,8 +413,8 @@ private class InlinedLambdasCollector : IrElementVisitorVoidWithContext() {
private val inlinedLambdasInNonPublicContexts = mutableSetOf<IrFunction>()
fun isInlineNonpublicContext(scopeStack: List<ScopeWithIr>): Boolean {
val currentFunction = scopeStack.map { it.irElement }. lastOrNull { it is IrFunction } as? IrFunction ?: return false
return (currentFunction.isInline == true && currentFunction.visibility in setOf(Visibilities.PRIVATE, Visibilities.PROTECTED))
val currentFunction = scopeStack.map { it.irElement }.lastOrNull { it is IrFunction } as? IrFunction ?: return false
return (currentFunction.isInline && currentFunction.visibility in setOf(Visibilities.PRIVATE, Visibilities.PROTECTED))
|| currentFunction in inlinedLambdasInNonPublicContexts
}
@@ -513,7 +429,8 @@ private class InlinedLambdasCollector : IrElementVisitorVoidWithContext() {
val argument = expression.getValueArgument(i)?.removeBlocks()
if (argument is IrFunctionReference &&
argument.symbol.owner.origin == IrDeclarationOrigin.LOCAL_FUNCTION_FOR_LAMBDA &&
!callTarget.valueParameters[i].isNoinline) {
!callTarget.valueParameters[i].isNoinline
) {
inlinedLambdasInNonPublicContexts.add(argument.symbol.owner)
}
}
@@ -0,0 +1,26 @@
/*
* Copyright 2010-2019 JetBrains s.r.o. 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.builders
import org.jetbrains.kotlin.ir.IrElement
import org.jetbrains.kotlin.ir.UNDEFINED_OFFSET
abstract class IrElementBuilder {
var startOffset: Int = UNDEFINED_OFFSET
var endOffset: Int = UNDEFINED_OFFSET
fun updateFrom(from: IrElement) {
startOffset = from.startOffset
endOffset = from.endOffset
}
}
fun IrElementBuilder.setSourceRange(from: IrElement) {
startOffset = from.startOffset
endOffset = from.endOffset
}
@@ -0,0 +1,33 @@
/*
* Copyright 2010-2019 JetBrains s.r.o. 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.builders.declarations
import org.jetbrains.kotlin.descriptors.ClassKind
import org.jetbrains.kotlin.descriptors.Modality
import org.jetbrains.kotlin.ir.declarations.IrClass
class IrClassBuilder : IrDeclarationBuilder() {
var kind: ClassKind = ClassKind.CLASS
var modality: Modality = Modality.FINAL
var isCompanion: Boolean = false
var isInner: Boolean = false
var isData: Boolean = false
var isExternal: Boolean = false
var isInline: Boolean = false
fun updateFrom(from: IrClass) {
super.updateFrom(from)
kind = from.kind
modality = from.modality
isCompanion = from.isCompanion
isInner = from.isInner
isData = from.isData
isExternal = from.isExternal
isInline = from.isInline
}
}
@@ -0,0 +1,28 @@
/*
* Copyright 2010-2019 JetBrains s.r.o. 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.builders.declarations
import org.jetbrains.kotlin.descriptors.Visibilities
import org.jetbrains.kotlin.descriptors.Visibility
import org.jetbrains.kotlin.ir.builders.IrElementBuilder
import org.jetbrains.kotlin.ir.declarations.*
import org.jetbrains.kotlin.name.Name
abstract class IrDeclarationBuilder : IrElementBuilder() {
var origin: IrDeclarationOrigin = IrDeclarationOrigin.DEFINED
var visibility: Visibility = Visibilities.PUBLIC
lateinit var name: Name
fun updateFrom(from: IrDeclaration) {
super.updateFrom(from)
origin = from.origin
visibility = if (from is IrDeclarationWithVisibility) from.visibility else Visibilities.PUBLIC
}
}
@@ -0,0 +1,27 @@
/*
* Copyright 2010-2019 JetBrains s.r.o. 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.builders.declarations
import org.jetbrains.kotlin.ir.declarations.IrField
import org.jetbrains.kotlin.ir.types.IrType
class IrFieldBuilder : IrDeclarationBuilder() {
lateinit var type: IrType
var isFinal: Boolean = false
var isExternal: Boolean = false
var isStatic: Boolean = false
fun updateFrom(from: IrField) {
super.updateFrom(from)
type = from.type
isFinal = from.isFinal
isExternal = from.isExternal
isStatic = from.isStatic
}
}
@@ -0,0 +1,48 @@
/*
* Copyright 2010-2019 JetBrains s.r.o. 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.builders.declarations
import org.jetbrains.kotlin.descriptors.Modality
import org.jetbrains.kotlin.ir.declarations.IrConstructor
import org.jetbrains.kotlin.ir.declarations.IrFunction
import org.jetbrains.kotlin.ir.declarations.IrSimpleFunction
import org.jetbrains.kotlin.ir.types.IrType
import org.jetbrains.kotlin.ir.types.impl.IrUninitializedType
class IrFunctionBuilder : IrDeclarationBuilder() {
var isInline: Boolean = false
var isExternal: Boolean = false
var returnType: IrType = IrUninitializedType
var modality: Modality = Modality.FINAL
var isTailrec: Boolean = false
var isSuspend: Boolean = false
var isPrimary: Boolean = false
fun updateFrom(from: IrFunction) {
super.updateFrom(from)
isInline = from.isInline
isExternal = from.isExternal
if (from is IrSimpleFunction) {
modality = from.modality
isTailrec = from.isTailrec
isSuspend = from.isSuspend
} else {
modality = Modality.FINAL
isTailrec = false
isSuspend = false
}
if (from is IrConstructor) {
isPrimary = from.isPrimary
}
}
}
@@ -0,0 +1,30 @@
/*
* Copyright 2010-2019 JetBrains s.r.o. 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.builders.declarations
import org.jetbrains.kotlin.ir.declarations.IrValueParameter
import org.jetbrains.kotlin.ir.types.IrType
const val UNDEFINED_PARAMETER_INDEX = -1
class IrValueParameterBuilder : IrDeclarationBuilder() {
lateinit var type: IrType
var index: Int = UNDEFINED_PARAMETER_INDEX
var varargElementType: IrType? = null
var isCrossInline = false
var isNoinline = false
fun updateFrom(from: IrValueParameter) {
super.updateFrom(from)
type = from.type
index = from.index
varargElementType = from.varargElementType
isCrossInline = from.isCrossinline
isNoinline = from.isNoinline
}
}