Minor. Reformat

This commit is contained in:
Mikhael Bogdanov
2018-05-04 13:21:00 +02:00
parent e82170a04e
commit fdbc863e60
11 changed files with 620 additions and 496 deletions
@@ -24,25 +24,25 @@ import org.jetbrains.kotlin.serialization.deserialization.descriptors.Deserializ
import org.jetbrains.kotlin.types.KotlinType
fun ClassDescriptor?.getter2Descriptor(methodName: Name) = this?.let {
this.unsubstitutedMemberScope.getContributedDescriptors{true}
.firstOrNull {
it.name == methodName
} ?.let {
return@let (it as? PropertyDescriptor)?.getter
}
this.unsubstitutedMemberScope.getContributedDescriptors { true }
.firstOrNull {
it.name == methodName
}?.let {
return@let (it as? PropertyDescriptor)?.getter
}
}
fun ClassDescriptor?.signature2Descriptor(methodName: Name, signature:Array<KotlinType> = emptyArray()) = this?.let {
fun ClassDescriptor?.signature2Descriptor(methodName: Name, signature: Array<KotlinType> = emptyArray()) = this?.let {
this
.unsubstitutedMemberScope
.getContributedFunctions(methodName, NoLookupLocation.FROM_BACKEND)
.firstOrNull {
return@firstOrNull it.valueParameters.size == signature.size
&& (signature.isEmpty() || it.valueParameters.any {
p -> val index = it.valueParameters.indexOf(p)
return@any p.type == signature[index]
})
}
.unsubstitutedMemberScope
.getContributedFunctions(methodName, NoLookupLocation.FROM_BACKEND)
.firstOrNull {
return@firstOrNull it.valueParameters.size == signature.size
&& (signature.isEmpty() || it.valueParameters.any { p ->
val index = it.valueParameters.indexOf(p)
return@any p.type == signature[index]
})
}
}
val String.synthesizedName get() = Name.identifier(this.synthesizedString)
@@ -51,13 +51,13 @@ val String.synthesizedString get() = "\$$this"
val DeclarationDescriptor.propertyIfAccessor
get() = if (this is PropertyAccessorDescriptor)
this.correspondingProperty
else this
this.correspondingProperty
else this
val CallableMemberDescriptor.propertyIfAccessor
get() = if (this is PropertyAccessorDescriptor)
this.correspondingProperty
else this
this.correspondingProperty
else this
val FunctionDescriptor.deserializedPropertyIfAccessor: DeserializedCallableMemberDescriptor
get() {
@@ -54,11 +54,12 @@ fun DeclarationDescriptor.createFakeOverrideDescriptor(owner: ClassDescriptor):
return when (this) {
is CallableMemberDescriptor ->
copy(
/* newOwner = */ owner,
/* modality = */ modality,
/* visibility = */ visibility,
/* kind = */ CallableMemberDescriptor.Kind.FAKE_OVERRIDE,
/* copyOverrides = */ true).apply {
/* newOwner = */ owner,
/* modality = */ modality,
/* visibility = */ visibility,
/* kind = */ CallableMemberDescriptor.Kind.FAKE_OVERRIDE,
/* copyOverrides = */ true
).apply {
overriddenDescriptors += this@createFakeOverrideDescriptor
}
else -> null
@@ -67,22 +68,26 @@ fun DeclarationDescriptor.createFakeOverrideDescriptor(owner: ClassDescriptor):
fun FunctionDescriptor.createOverriddenDescriptor(owner: ClassDescriptor, final: Boolean = true): FunctionDescriptor {
return this.newCopyBuilder()
.setOwner(owner)
.setCopyOverrides(true)
.setModality(if (final) Modality.FINAL else Modality.OPEN)
.setDispatchReceiverParameter(owner.thisAsReceiverParameter)
.build()!!.apply {
.setOwner(owner)
.setCopyOverrides(true)
.setModality(if (final) Modality.FINAL else Modality.OPEN)
.setDispatchReceiverParameter(owner.thisAsReceiverParameter)
.build()!!.apply {
overriddenDescriptors += this@createOverriddenDescriptor
}
}
fun ClassDescriptor.createSimpleDelegatingConstructorDescriptor(superConstructorDescriptor: ClassConstructorDescriptor, isPrimary: Boolean = false)
fun ClassDescriptor.createSimpleDelegatingConstructorDescriptor(
superConstructorDescriptor: ClassConstructorDescriptor,
isPrimary: Boolean = false
)
: ClassConstructorDescriptor {
val constructorDescriptor = ClassConstructorDescriptorImpl.createSynthesized(
/* containingDeclaration = */ this,
/* annotations = */ Annotations.EMPTY,
/* isPrimary = */ isPrimary,
/* source = */ SourceElement.NO_SOURCE)
/* containingDeclaration = */ this,
/* annotations = */ Annotations.EMPTY,
/* isPrimary = */ isPrimary,
/* source = */ SourceElement.NO_SOURCE
)
val valueParameters = superConstructorDescriptor.valueParameters.map {
it.copy(constructorDescriptor, it.name, it.index)
}
@@ -91,26 +96,29 @@ fun ClassDescriptor.createSimpleDelegatingConstructorDescriptor(superConstructor
return constructorDescriptor
}
fun IrClass.addSimpleDelegatingConstructor(superConstructorSymbol: IrConstructorSymbol,
constructorDescriptor: ClassConstructorDescriptor,
origin: IrDeclarationOrigin)
fun IrClass.addSimpleDelegatingConstructor(
superConstructorSymbol: IrConstructorSymbol,
constructorDescriptor: ClassConstructorDescriptor,
origin: IrDeclarationOrigin
)
: IrConstructor {
return IrConstructorImpl(startOffset, endOffset, origin, constructorDescriptor).also { constructor ->
constructor.createParameterDeclarations()
constructor.body = IrBlockBodyImpl(startOffset, endOffset,
listOf(
IrDelegatingConstructorCallImpl(
startOffset, endOffset,
superConstructorSymbol, superConstructorSymbol.descriptor
).apply {
constructor.valueParameters.forEachIndexed { idx, parameter ->
putValueArgument(idx, IrGetValueImpl(startOffset, endOffset, parameter.symbol))
}
},
IrInstanceInitializerCallImpl(startOffset, endOffset, this.symbol)
)
constructor.body = IrBlockBodyImpl(
startOffset, endOffset,
listOf(
IrDelegatingConstructorCallImpl(
startOffset, endOffset,
superConstructorSymbol, superConstructorSymbol.descriptor
).apply {
constructor.valueParameters.forEachIndexed { idx, parameter ->
putValueArgument(idx, IrGetValueImpl(startOffset, endOffset, parameter.symbol))
}
},
IrInstanceInitializerCallImpl(startOffset, endOffset, this.symbol)
)
)
constructor.parent = this
@@ -118,9 +126,11 @@ fun IrClass.addSimpleDelegatingConstructor(superConstructorSymbol: IrConstructor
}
}
fun CommonBackendContext.createArrayOfExpression(arrayElementType: KotlinType,
arrayElements: List<IrExpression>,
startOffset: Int, endOffset: Int): IrExpression {
fun CommonBackendContext.createArrayOfExpression(
arrayElementType: KotlinType,
arrayElements: List<IrExpression>,
startOffset: Int, endOffset: Int
): IrExpression {
val genericArrayOfFunSymbol = ir.symbols.arrayOf
val genericArrayOfFun = genericArrayOfFunSymbol.descriptor
@@ -55,7 +55,8 @@ import org.jetbrains.kotlin.resolve.descriptorUtil.builtIns
import org.jetbrains.kotlin.types.KotlinType
import org.jetbrains.kotlin.types.typeUtil.builtIns
open class DefaultArgumentStubGenerator constructor(val context: CommonBackendContext, private val skipInlineMethods: Boolean = true): DeclarationContainerLoweringPass {
open class DefaultArgumentStubGenerator constructor(val context: CommonBackendContext, private val skipInlineMethods: Boolean = true) :
DeclarationContainerLoweringPass {
override fun lower(irDeclarationContainer: IrDeclarationContainer) {
irDeclarationContainer.declarations.transformFlat { memberDeclaration ->
if (memberDeclaration is IrFunction)
@@ -75,11 +76,11 @@ open class DefaultArgumentStubGenerator constructor(val context: CommonBackendCo
return listOf(irFunction)
val bodies = functionDescriptor.valueParameters
.mapNotNull{irFunction.getDefault(it)}
.mapNotNull { irFunction.getDefault(it) }
log { "detected ${functionDescriptor.name.asString()} has got #${bodies.size} default expressions" }
functionDescriptor.overriddenDescriptors.forEach { context.log{"DEFAULT-REPLACER: $it"} }
functionDescriptor.overriddenDescriptors.forEach { context.log { "DEFAULT-REPLACER: $it" } }
if (bodies.isNotEmpty()) {
val newIrFunction = functionDescriptor.generateDefaultsFunction(context)
val descriptor = newIrFunction.descriptor
@@ -96,7 +97,7 @@ open class DefaultArgumentStubGenerator constructor(val context: CommonBackendCo
for (valueParameter in functionDescriptor.valueParameters) {
val parameterSymbol = newIrFunction.valueParameters[valueParameter.index].symbol
val temporaryVariableSymbol =
IrVariableSymbolImpl(scope.createTemporaryVariableDescriptor(parameterSymbol.descriptor))
IrVariableSymbolImpl(scope.createTemporaryVariableDescriptor(parameterSymbol.descriptor))
params.add(temporaryVariableSymbol)
variables.put(valueParameter, temporaryVariableSymbol)
if (valueParameter.hasDefaultValue()) {
@@ -108,7 +109,7 @@ open class DefaultArgumentStubGenerator constructor(val context: CommonBackendCo
val expressionBody = getDefaultParameterExpressionBody(irFunction, valueParameter)
/* Use previously calculated values in next expression. */
expressionBody.transformChildrenVoid(object: IrElementTransformerVoid() {
expressionBody.transformChildrenVoid(object : IrElementTransformerVoid() {
override fun visitGetValue(expression: IrGetValue): IrExpression {
log { "GetValue: ${expression.descriptor}" }
val valueSymbol = variables[expression.descriptor] ?: return expression
@@ -116,25 +117,28 @@ open class DefaultArgumentStubGenerator constructor(val context: CommonBackendCo
}
})
val variableInitialization = irIfThenElse(
type = temporaryVariableSymbol.descriptor.type,
condition = condition,
thenPart = expressionBody.expression,
elsePart = irGet(parameterSymbol))
+ scope.createTemporaryVariable(
symbol = temporaryVariableSymbol,
initializer = variableInitialization)
type = temporaryVariableSymbol.descriptor.type,
condition = condition,
thenPart = expressionBody.expression,
elsePart = irGet(parameterSymbol)
)
+scope.createTemporaryVariable(
symbol = temporaryVariableSymbol,
initializer = variableInitialization
)
/* Mapping calculated values with its origin variables. */
} else {
+ scope.createTemporaryVariable(
symbol = temporaryVariableSymbol,
initializer = irGet(parameterSymbol))
+scope.createTemporaryVariable(
symbol = temporaryVariableSymbol,
initializer = irGet(parameterSymbol)
)
}
}
if (irFunction is IrConstructor) {
+ IrDelegatingConstructorCallImpl(
startOffset = irFunction.startOffset,
endOffset = irFunction.endOffset,
symbol = irFunction.symbol, descriptor = irFunction.symbol.descriptor
+IrDelegatingConstructorCallImpl(
startOffset = irFunction.startOffset,
endOffset = irFunction.endOffset,
symbol = irFunction.symbol, descriptor = irFunction.symbol.descriptor
).apply {
params.forEachIndexed { i, variable ->
putValueArgument(i, irGet(variable))
@@ -173,48 +177,52 @@ open class DefaultArgumentStubGenerator constructor(val context: CommonBackendCo
}
private fun Scope.createTemporaryVariableDescriptor(parameterDescriptor: ParameterDescriptor?): VariableDescriptor =
IrTemporaryVariableDescriptorImpl(
containingDeclaration = this.scopeOwner,
name = parameterDescriptor!!.name.asString().synthesizedName,
outType = parameterDescriptor.type,
isMutable = false)
IrTemporaryVariableDescriptorImpl(
containingDeclaration = this.scopeOwner,
name = parameterDescriptor!!.name.asString().synthesizedName,
outType = parameterDescriptor.type,
isMutable = false
)
private fun Scope.createTemporaryVariable(symbol: IrVariableSymbol, initializer: IrExpression) =
IrVariableImpl(
startOffset = initializer.startOffset,
endOffset = initializer.endOffset,
origin = IrDeclarationOrigin.IR_TEMPORARY_VARIABLE,
symbol = symbol).apply {
IrVariableImpl(
startOffset = initializer.startOffset,
endOffset = initializer.endOffset,
origin = IrDeclarationOrigin.IR_TEMPORARY_VARIABLE,
symbol = symbol
).apply {
this.initializer = initializer
}
this.initializer = initializer
}
private fun getDefaultParameterExpressionBody(irFunction: IrFunction, valueParameter: ValueParameterDescriptor): IrExpressionBody {
return irFunction.getDefault(valueParameter) ?: TODO("FIXME!!!")
}
private fun maskParameterDescriptor(function: IrFunction, number: Int) =
maskParameterSymbol(function, number).descriptor as ValueParameterDescriptor
private fun maskParameterSymbol(function: IrFunction, number: Int) =
function.valueParameters.single { it.descriptor.name == parameterMaskName(number) }.symbol
maskParameterSymbol(function, number).descriptor as ValueParameterDescriptor
private fun markerParameterDescriptor(descriptor: FunctionDescriptor) = descriptor.valueParameters.single { it.name == kConstructorMarkerName }
private fun maskParameterSymbol(function: IrFunction, number: Int) =
function.valueParameters.single { it.descriptor.name == parameterMaskName(number) }.symbol
private fun markerParameterDescriptor(descriptor: FunctionDescriptor) =
descriptor.valueParameters.single { it.name == kConstructorMarkerName }
private fun nullConst(expression: IrElement, type: KotlinType): IrExpression? {
when {
KotlinBuiltIns.isFloat(type) -> return IrConstImpl.float (expression.startOffset, expression.endOffset, type, 0.0F)
KotlinBuiltIns.isDouble(type) -> return IrConstImpl.double (expression.startOffset, expression.endOffset, type, 0.0)
KotlinBuiltIns.isBoolean(type) -> return IrConstImpl.boolean (expression.startOffset, expression.endOffset, type, false)
KotlinBuiltIns.isByte(type) -> return IrConstImpl.byte (expression.startOffset, expression.endOffset, type, 0)
KotlinBuiltIns.isChar(type) -> return IrConstImpl.char (expression.startOffset, expression.endOffset, type, 0.toChar())
KotlinBuiltIns.isShort(type) -> return IrConstImpl.short (expression.startOffset, expression.endOffset, type, 0)
KotlinBuiltIns.isInt(type) -> return IrConstImpl.int (expression.startOffset, expression.endOffset, type, 0)
KotlinBuiltIns.isLong(type) -> return IrConstImpl.long (expression.startOffset, expression.endOffset, type, 0)
else -> return IrConstImpl.constNull (expression.startOffset, expression.endOffset, type.builtIns.nullableNothingType)
KotlinBuiltIns.isFloat(type) -> return IrConstImpl.float(expression.startOffset, expression.endOffset, type, 0.0F)
KotlinBuiltIns.isDouble(type) -> return IrConstImpl.double(expression.startOffset, expression.endOffset, type, 0.0)
KotlinBuiltIns.isBoolean(type) -> return IrConstImpl.boolean(expression.startOffset, expression.endOffset, type, false)
KotlinBuiltIns.isByte(type) -> return IrConstImpl.byte(expression.startOffset, expression.endOffset, type, 0)
KotlinBuiltIns.isChar(type) -> return IrConstImpl.char(expression.startOffset, expression.endOffset, type, 0.toChar())
KotlinBuiltIns.isShort(type) -> return IrConstImpl.short(expression.startOffset, expression.endOffset, type, 0)
KotlinBuiltIns.isInt(type) -> return IrConstImpl.int(expression.startOffset, expression.endOffset, type, 0)
KotlinBuiltIns.isLong(type) -> return IrConstImpl.long(expression.startOffset, expression.endOffset, type, 0)
else -> return IrConstImpl.constNull(expression.startOffset, expression.endOffset, type.builtIns.nullableNothingType)
}
}
class DefaultParameterInjector constructor(val context: CommonBackendContext, private val skipInline: Boolean = true): BodyLoweringPass {
class DefaultParameterInjector constructor(val context: CommonBackendContext, private val skipInline: Boolean = true) : BodyLoweringPass {
override fun lower(irBody: IrBody) {
irBody.transformChildrenVoid(object : IrElementTransformerVoid() {
@@ -228,17 +236,18 @@ class DefaultParameterInjector constructor(val context: CommonBackendContext, pr
return expression
val (symbolForCall, params) = parametersForCall(expression)
return IrDelegatingConstructorCallImpl(
startOffset = expression.startOffset,
endOffset = expression.endOffset,
symbol = symbolForCall as IrConstructorSymbol,
descriptor = symbolForCall.descriptor)
.apply {
params.forEach {
log { "call::params@${it.first.index}/${it.first.name.asString()}: ${ir2string(it.second)}" }
putValueArgument(it.first.index, it.second)
}
dispatchReceiver = expression.dispatchReceiver
startOffset = expression.startOffset,
endOffset = expression.endOffset,
symbol = symbolForCall as IrConstructorSymbol,
descriptor = symbolForCall.descriptor
)
.apply {
params.forEach {
log { "call::params@${it.first.index}/${it.first.name.asString()}: ${ir2string(it.second)}" }
putValueArgument(it.first.index, it.second)
}
dispatchReceiver = expression.dispatchReceiver
}
}
@@ -257,25 +266,28 @@ class DefaultParameterInjector constructor(val context: CommonBackendContext, pr
descriptor.typeParameters.forEach { log { "$descriptor [${it.index}]: $it" } }
descriptor.original.typeParameters.forEach { log { "${descriptor.original}[${it.index}] : $it" } }
return IrCallImpl(
startOffset = expression.startOffset,
endOffset = expression.endOffset,
symbol = symbol,
descriptor = descriptor,
typeArguments = expression.descriptor.typeParameters.map{it to (expression.getTypeArgument(it) ?: it.defaultType) }.toMap())
.apply {
params.forEach {
log { "call::params@${it.first.index}/${it.first.name.asString()}: ${ir2string(it.second)}" }
putValueArgument(it.first.index, it.second)
}
expression.extensionReceiver?.apply{
extensionReceiver = expression.extensionReceiver
}
expression.dispatchReceiver?.apply {
dispatchReceiver = expression.dispatchReceiver
}
log { "call::extension@: ${ir2string(expression.extensionReceiver)}" }
log { "call::dispatch@: ${ir2string(expression.dispatchReceiver)}" }
startOffset = expression.startOffset,
endOffset = expression.endOffset,
symbol = symbol,
descriptor = descriptor,
typeArguments = expression.descriptor.typeParameters.map {
it to (expression.getTypeArgument(it) ?: it.defaultType)
}.toMap()
)
.apply {
params.forEach {
log { "call::params@${it.first.index}/${it.first.name.asString()}: ${ir2string(it.second)}" }
putValueArgument(it.first.index, it.second)
}
expression.extensionReceiver?.apply {
extensionReceiver = expression.extensionReceiver
}
expression.dispatchReceiver?.apply {
dispatchReceiver = expression.dispatchReceiver
}
log { "call::extension@: ${ir2string(expression.extensionReceiver)}" }
log { "call::dispatch@: ${ir2string(expression.dispatchReceiver)}" }
}
}
private fun parametersForCall(expression: IrMemberAccessExpression): Pair<IrFunctionSymbol, List<Pair<ValueParameterDescriptor, IrExpression?>>> {
@@ -302,20 +314,21 @@ class DefaultParameterInjector constructor(val context: CommonBackendContext, pr
})
maskValues.forEachIndexed { i, maskValue ->
params += maskParameterDescriptor(realFunction, i) to IrConstImpl.int(
startOffset = irBody.startOffset,
endOffset = irBody.endOffset,
type = descriptor.builtIns.intType,
value = maskValue)
startOffset = irBody.startOffset,
endOffset = irBody.endOffset,
type = descriptor.builtIns.intType,
value = maskValue
)
}
if (expression.descriptor is ClassConstructorDescriptor) {
val defaultArgumentMarker = context.ir.symbols.defaultConstructorMarker
params += markerParameterDescriptor(realDescriptor) to IrGetObjectValueImpl(
startOffset = irBody.startOffset,
endOffset = irBody.endOffset,
type = defaultArgumentMarker.owner.defaultType,
symbol = defaultArgumentMarker)
}
else if (context.ir.shouldGenerateHandlerParameterForDefaultBodyFun()) {
startOffset = irBody.startOffset,
endOffset = irBody.endOffset,
type = defaultArgumentMarker.owner.defaultType,
symbol = defaultArgumentMarker
)
} else if (context.ir.shouldGenerateHandlerParameterForDefaultBodyFun()) {
params += realDescriptor.valueParameters.last() to
IrConstImpl.constNull(irBody.startOffset, irBody.endOffset, context.builtIns.any.defaultType)
}
@@ -326,7 +339,7 @@ class DefaultParameterInjector constructor(val context: CommonBackendContext, pr
}
private fun argumentCount(expression: IrMemberAccessExpression) =
expression.descriptor.valueParameters.count { expression.getValueArgument(it) != null }
expression.descriptor.valueParameters.count { expression.getValueArgument(it) != null }
})
}
@@ -341,19 +354,21 @@ private fun FunctionDescriptor.generateDefaultsFunction(context: CommonBackendCo
val descriptor = when (this) {
is ClassConstructorDescriptor ->
ClassConstructorDescriptorImpl.create(
/* containingDeclaration = */ containingDeclaration,
/* annotations = */ annotations,
/* isPrimary = */ false,
/* source = */ source)
/* containingDeclaration = */ containingDeclaration,
/* annotations = */ annotations,
/* isPrimary = */ false,
/* source = */ source
)
else -> {
val name = Name.identifier("$name\$default")
SimpleFunctionDescriptorImpl.create(
/* containingDeclaration = */ containingDeclaration,
/* annotations = */ annotations,
/* name = */ name,
/* kind = */ CallableMemberDescriptor.Kind.SYNTHESIZED,
/* source = */ source)
/* containingDeclaration = */ containingDeclaration,
/* annotations = */ annotations,
/* name = */ name,
/* kind = */ CallableMemberDescriptor.Kind.SYNTHESIZED,
/* source = */ source
)
}
}
@@ -361,21 +376,24 @@ private fun FunctionDescriptor.generateDefaultsFunction(context: CommonBackendCo
valueParameter(descriptor, valueParameters.size + i, parameterMaskName(i), descriptor.builtIns.intType)
}
if (this is ClassConstructorDescriptor) {
syntheticParameters += valueParameter(descriptor, syntheticParameters.last().index + 1,
kConstructorMarkerName,
context.ir.symbols.defaultConstructorMarker.owner.defaultType)
}
else if (context.ir.shouldGenerateHandlerParameterForDefaultBodyFun()) {
syntheticParameters += valueParameter(descriptor, syntheticParameters.last().index + 1,
"handler".synthesizedName,
context.ir.symbols.any.owner.defaultType)
syntheticParameters += valueParameter(
descriptor, syntheticParameters.last().index + 1,
kConstructorMarkerName,
context.ir.symbols.defaultConstructorMarker.owner.defaultType
)
} else if (context.ir.shouldGenerateHandlerParameterForDefaultBodyFun()) {
syntheticParameters += valueParameter(
descriptor, syntheticParameters.last().index + 1,
"handler".synthesizedName,
context.ir.symbols.any.owner.defaultType
)
}
descriptor.initialize(
/* receiverParameterType = */ extensionReceiverParameter?.type,
/* dispatchReceiverParameter = */ dispatchReceiverParameter,
/* typeParameters = */ typeParameters.map {
TypeParameterDescriptorImpl.createForFurtherModification(
/* receiverParameterType = */ extensionReceiverParameter?.type,
/* dispatchReceiverParameter = */ dispatchReceiverParameter,
/* typeParameters = */ typeParameters.map {
TypeParameterDescriptorImpl.createForFurtherModification(
/* containingDeclaration = */ descriptor,
/* annotations = */ it.annotations,
/* reified = */ it.isReified,
@@ -385,45 +403,46 @@ private fun FunctionDescriptor.generateDefaultsFunction(context: CommonBackendCo
/* source = */ it.source,
/* reportCycleError = */ null,
/* supertypeLoopsChecker = */ SupertypeLoopChecker.EMPTY
).apply {
it.upperBounds.forEach { addUpperBound(it) }
setInitialized()
}
},
/* unsubstitutedValueParameters = */ valueParameters.map {
ValueParameterDescriptorImpl(
).apply {
it.upperBounds.forEach { addUpperBound(it) }
setInitialized()
}
},
/* unsubstitutedValueParameters = */ valueParameters.map {
ValueParameterDescriptorImpl(
containingDeclaration = descriptor,
original = null, /* ValueParameterDescriptorImpl::copy do not save original. */
index = it.index,
annotations = it.annotations,
name = it.name,
outType = it.type,
declaresDefaultValue = false,
isCrossinline = it.isCrossinline,
isNoinline = it.isNoinline,
varargElementType = it.varargElementType,
source = it.source)
} + syntheticParameters,
/* unsubstitutedReturnType = */ returnType,
/* modality = */ Modality.FINAL,
/* visibility = */ this.visibility)
original = null, /* ValueParameterDescriptorImpl::copy do not save original. */
index = it.index,
annotations = it.annotations,
name = it.name,
outType = it.type,
declaresDefaultValue = false,
isCrossinline = it.isCrossinline,
isNoinline = it.isNoinline,
varargElementType = it.varargElementType,
source = it.source
)
} + syntheticParameters,
/* unsubstitutedReturnType = */ returnType,
/* modality = */ Modality.FINAL,
/* visibility = */ this.visibility)
descriptor.isSuspend = this.isSuspend
context.log{"adds to cache[$this] = $descriptor"}
context.log { "adds to cache[$this] = $descriptor" }
val startOffset = this.startOffsetOrUndefined
val endOffset = this.endOffsetOrUndefined
val result: IrFunction = when (descriptor) {
is ClassConstructorDescriptor -> IrConstructorImpl(
startOffset, endOffset,
DECLARATION_ORIGIN_FUNCTION_FOR_DEFAULT_PARAMETER,
descriptor
startOffset, endOffset,
DECLARATION_ORIGIN_FUNCTION_FOR_DEFAULT_PARAMETER,
descriptor
)
else -> IrFunctionImpl(
startOffset, endOffset,
DECLARATION_ORIGIN_FUNCTION_FOR_DEFAULT_PARAMETER,
descriptor
startOffset, endOffset,
DECLARATION_ORIGIN_FUNCTION_FOR_DEFAULT_PARAMETER,
descriptor
)
}
@@ -434,21 +453,21 @@ private fun FunctionDescriptor.generateDefaultsFunction(context: CommonBackendCo
}
object DECLARATION_ORIGIN_FUNCTION_FOR_DEFAULT_PARAMETER :
IrDeclarationOriginImpl("DEFAULT_PARAMETER_EXTENT")
IrDeclarationOriginImpl("DEFAULT_PARAMETER_EXTENT")
private fun valueParameter(descriptor: FunctionDescriptor, index: Int, name: Name, type: KotlinType): ValueParameterDescriptor {
return ValueParameterDescriptorImpl(
containingDeclaration = descriptor,
original = null,
index = index,
annotations = Annotations.EMPTY,
name = name,
outType = type,
declaresDefaultValue = false,
isCrossinline = false,
isNoinline = false,
varargElementType = null,
source = SourceElement.NO_SOURCE
containingDeclaration = descriptor,
original = null,
index = index,
annotations = Annotations.EMPTY,
name = name,
outType = type,
declaresDefaultValue = false,
isCrossinline = false,
isNoinline = false,
varargElementType = null,
source = SourceElement.NO_SOURCE
)
}
@@ -64,12 +64,12 @@ private class KCallableNamePropertyTransformer(val lower: KCallableNamePropertyL
}
statements.add(
IrConstImpl.string(
expression.startOffset,
expression.endOffset,
context.builtIns.stringType,
callableReference.descriptor.name.asString()
)
IrConstImpl.string(
expression.startOffset,
expression.endOffset,
context.builtIns.stringType,
callableReference.descriptor.name.asString()
)
)
}
@@ -85,20 +85,22 @@ private class KCallableNamePropertyTransformer(val lower: KCallableNamePropertyL
return kind == FunctionClassDescriptor.Kind.KFunction
}
fun BackendContext.createIrBuilder(symbol: IrSymbol,
startOffset: Int = UNDEFINED_OFFSET,
endOffset: Int = UNDEFINED_OFFSET) =
DeclarationIrBuilder(this, symbol, startOffset, endOffset)
fun BackendContext.createIrBuilder(
symbol: IrSymbol,
startOffset: Int = UNDEFINED_OFFSET,
endOffset: Int = UNDEFINED_OFFSET
) =
DeclarationIrBuilder(this, symbol, startOffset, endOffset)
class DeclarationIrBuilder(
backendContext: BackendContext,
symbol: IrSymbol,
startOffset: Int = UNDEFINED_OFFSET, endOffset: Int = UNDEFINED_OFFSET
backendContext: BackendContext,
symbol: IrSymbol,
startOffset: Int = UNDEFINED_OFFSET, endOffset: Int = UNDEFINED_OFFSET
) : IrBuilderWithScope(
IrLoweringContext(backendContext),
Scope(symbol),
startOffset,
endOffset
IrLoweringContext(backendContext),
Scope(symbol),
startOffset,
endOffset
)
class IrLoweringContext(backendContext: BackendContext) : IrGeneratorContext(backendContext.irBuiltIns)
@@ -40,7 +40,8 @@ import java.util.*
interface LocalNameProvider {
fun localName(descriptor: DeclarationDescriptor): String =
descriptor.name.asString()
descriptor.name.asString()
companion object {
val DEFAULT = object : LocalNameProvider {}
}
@@ -49,14 +50,15 @@ interface LocalNameProvider {
class LocalDeclarationsLowering(val context: BackendContext, val localNameProvider: LocalNameProvider = LocalNameProvider.DEFAULT) : DeclarationContainerLoweringPass {
private object DECLARATION_ORIGIN_FIELD_FOR_CAPTURED_VALUE :
IrDeclarationOriginImpl("FIELD_FOR_CAPTURED_VALUE") {}
IrDeclarationOriginImpl("FIELD_FOR_CAPTURED_VALUE") {}
private object STATEMENT_ORIGIN_INITIALIZER_OF_FIELD_FOR_CAPTURED_VALUE :
IrStatementOriginImpl("INITIALIZER_OF_FIELD_FOR_CAPTURED_VALUE") {}
IrStatementOriginImpl("INITIALIZER_OF_FIELD_FOR_CAPTURED_VALUE") {}
override fun lower(irDeclarationContainer: IrDeclarationContainer) {
if (irDeclarationContainer is IrDeclaration &&
irDeclarationContainer.descriptor.parents.any { it is CallableDescriptor }) {
irDeclarationContainer.descriptor.parents.any { it is CallableDescriptor }
) {
// Lowering of non-local declarations handles all local declarations inside.
// This declaration is local and shouldn't be considered.
@@ -73,7 +75,7 @@ class LocalDeclarationsLowering(val context: BackendContext, val localNameProvid
is IrProperty -> LocalDeclarationsTransformer(memberDeclaration).lowerLocalDeclarations()
is IrField -> LocalDeclarationsTransformer(memberDeclaration).lowerLocalDeclarations()
is IrAnonymousInitializer -> LocalDeclarationsTransformer(memberDeclaration).lowerLocalDeclarations()
// TODO: visit children as well
// TODO: visit children as well
else -> null
}
}
@@ -115,7 +117,7 @@ class LocalDeclarationsLowering(val context: BackendContext, val localNameProvid
var index: Int = -1
override fun toString(): String =
"LocalFunctionContext for $descriptor"
"LocalFunctionContext for $descriptor"
}
private class LocalClassConstructorContext(override val declaration: IrConstructor) : LocalContextWithClosureAsParameters() {
@@ -126,7 +128,7 @@ class LocalDeclarationsLowering(val context: BackendContext, val localNameProvid
override lateinit var transformedDeclaration: IrConstructor
override fun toString(): String =
"LocalClassConstructorContext for $descriptor"
"LocalClassConstructorContext for $descriptor"
}
private class LocalClassContext(val declaration: IrClass) : LocalContext() {
@@ -140,13 +142,14 @@ class LocalDeclarationsLowering(val context: BackendContext, val localNameProvid
override fun irGet(startOffset: Int, endOffset: Int, descriptor: ValueDescriptor): IrExpression? {
val field = capturedValueToField[descriptor] ?: return null
return IrGetFieldImpl(startOffset, endOffset, field.symbol,
receiver = IrGetValueImpl(startOffset, endOffset, declaration.thisReceiver!!.symbol)
return IrGetFieldImpl(
startOffset, endOffset, field.symbol,
receiver = IrGetValueImpl(startOffset, endOffset, declaration.thisReceiver!!.symbol)
)
}
override fun toString(): String =
"LocalClassContext for ${descriptor}"
"LocalClassContext for ${descriptor}"
}
private inner class LocalDeclarationsTransformer(val memberDeclaration: IrDeclaration) {
@@ -178,26 +181,26 @@ class LocalDeclarationsLowering(val context: BackendContext, val localNameProvid
}
private fun collectRewrittenDeclarations(): ArrayList<IrDeclaration> =
ArrayList<IrDeclaration>(localFunctions.size + localClasses.size + 1).apply {
localFunctions.values.mapTo(this) {
val original = it.declaration
it.transformedDeclaration.apply {
this.body = original.body
ArrayList<IrDeclaration>(localFunctions.size + localClasses.size + 1).apply {
localFunctions.values.mapTo(this) {
val original = it.declaration
it.transformedDeclaration.apply {
this.body = original.body
original.descriptor.valueParameters.filter { it.declaresDefaultValue() }.forEach { argument ->
val body = original.getDefault(argument)!!
oldParameterToNew[argument]!!.owner.defaultValue = body
}
original.descriptor.valueParameters.filter { it.declaresDefaultValue() }.forEach { argument ->
val body = original.getDefault(argument)!!
oldParameterToNew[argument]!!.owner.defaultValue = body
}
}
localClasses.values.mapTo(this) {
it.declaration
}
add(memberDeclaration)
}
localClasses.values.mapTo(this) {
it.declaration
}
add(memberDeclaration)
}
private inner class FunctionBodiesRewriter(val localContext: LocalContext?) : IrElementTransformerVoid() {
override fun visitClass(declaration: IrClass): IrStatement {
@@ -268,10 +271,10 @@ class LocalDeclarationsLowering(val context: BackendContext, val localNameProvid
val newCallee = transformedDeclarations[oldCallee] as IrConstructorSymbol? ?: return expression
val newExpression = IrDelegatingConstructorCallImpl(
expression.startOffset, expression.endOffset,
newCallee,
newCallee.descriptor,
remapTypeArguments(expression, newCallee.descriptor)
expression.startOffset, expression.endOffset,
newCallee,
newCallee.descriptor,
remapTypeArguments(expression, newCallee.descriptor)
).fillArguments(expression)
return newExpression
@@ -287,17 +290,19 @@ class LocalDeclarationsLowering(val context: BackendContext, val localNameProvid
} else {
// The callee expects captured value as argument.
val capturedValueSymbol =
newParameterToCaptured[newValueParameterDescriptor] ?:
throw AssertionError("Non-mapped parameter $newValueParameterDescriptor")
newParameterToCaptured[newValueParameterDescriptor]
?: throw AssertionError("Non-mapped parameter $newValueParameterDescriptor")
val capturedValueDescriptor = capturedValueSymbol.descriptor
localContext?.irGet(
oldExpression.startOffset, oldExpression.endOffset,
capturedValueDescriptor
oldExpression.startOffset, oldExpression.endOffset,
capturedValueDescriptor
) ?:
// Captured value is directly available for the caller.
IrGetValueImpl(oldExpression.startOffset, oldExpression.endOffset,
oldParameterToNew[capturedValueDescriptor] ?: capturedValueSymbol)
// Captured value is directly available for the caller.
IrGetValueImpl(
oldExpression.startOffset, oldExpression.endOffset,
oldParameterToNew[capturedValueDescriptor] ?: capturedValueSymbol
)
}
}
@@ -315,12 +320,12 @@ class LocalDeclarationsLowering(val context: BackendContext, val localNameProvid
val newCallee = oldCallee.transformed ?: return expression
val newCallableReference = IrFunctionReferenceImpl(
expression.startOffset, expression.endOffset,
expression.type, // TODO functional type for transformed descriptor
newCallee,
newCallee.descriptor,
remapTypeArguments(expression, newCallee.descriptor),
expression.origin
expression.startOffset, expression.endOffset,
expression.type, // TODO functional type for transformed descriptor
newCallee,
newCallee.descriptor,
remapTypeArguments(expression, newCallee.descriptor),
expression.origin
).fillArguments(expression)
return newCallableReference
@@ -359,8 +364,8 @@ class LocalDeclarationsLowering(val context: BackendContext, val localNameProvid
val classDescriptor = irClass.descriptor
val constructorsCallingSuper = classDescriptor.constructors
.map { localClassConstructors[it]!! }
.filter { it.declaration.callsSuper() }
.map { localClassConstructors[it]!! }
.filter { it.declaration.callsSuper() }
assert(constructorsCallingSuper.any(), { "Expected at least one constructor calling super; class: $classDescriptor" })
localClassContext.capturedValueToField.forEach { capturedValue, field ->
@@ -372,10 +377,14 @@ class LocalDeclarationsLowering(val context: BackendContext, val localNameProvid
val blockBody = constructorContext.declaration.body as? IrBlockBody
?: throw AssertionError("Unexpected constructor body: ${constructorContext.declaration.body}")
val capturedValueExpression = constructorContext.irGet(startOffset, endOffset, capturedValue)!!
blockBody.statements.add(0,
IrSetFieldImpl(startOffset, endOffset, field.symbol,
IrGetValueImpl(startOffset, endOffset, irClass.thisReceiver!!.symbol),
capturedValueExpression, STATEMENT_ORIGIN_INITIALIZER_OF_FIELD_FOR_CAPTURED_VALUE))
blockBody.statements.add(
0,
IrSetFieldImpl(
startOffset, endOffset, field.symbol,
IrGetValueImpl(startOffset, endOffset, irClass.thisReceiver!!.symbol),
capturedValueExpression, STATEMENT_ORIGIN_INITIALIZER_OF_FIELD_FOR_CAPTURED_VALUE
)
)
}
}
}
@@ -397,25 +406,28 @@ class LocalDeclarationsLowering(val context: BackendContext, val localNameProvid
}
private fun createNewCall(oldCall: IrCall, newCallee: IrFunctionSymbol) =
if (oldCall is IrCallWithShallowCopy)
oldCall.shallowCopy(oldCall.origin, newCallee, oldCall.superQualifierSymbol)
else
IrCallImpl(
oldCall.startOffset, oldCall.endOffset,
newCallee,
newCallee.descriptor,
remapTypeArguments(oldCall, newCallee.descriptor),
oldCall.origin, oldCall.superQualifierSymbol
)
if (oldCall is IrCallWithShallowCopy)
oldCall.shallowCopy(oldCall.origin, newCallee, oldCall.superQualifierSymbol)
else
IrCallImpl(
oldCall.startOffset, oldCall.endOffset,
newCallee,
newCallee.descriptor,
remapTypeArguments(oldCall, newCallee.descriptor),
oldCall.origin, oldCall.superQualifierSymbol
)
private fun remapTypeArguments(oldExpression: IrMemberAccessExpression, newCallee: CallableDescriptor): Map<TypeParameterDescriptor, KotlinType>? {
private fun remapTypeArguments(
oldExpression: IrMemberAccessExpression,
newCallee: CallableDescriptor
): Map<TypeParameterDescriptor, KotlinType>? {
val oldCallee = oldExpression.descriptor.original
return if (oldCallee.typeParameters.isEmpty())
null
else oldCallee.typeParameters.associateBy(
{ newCallee.typeParameters[it.index] },
{ oldExpression.getTypeArgumentOrDefault(it) }
{ newCallee.typeParameters[it.index] },
{ oldExpression.getTypeArgumentOrDefault(it) }
)
}
@@ -442,26 +454,28 @@ class LocalDeclarationsLowering(val context: BackendContext, val localNameProvid
return localNameProvider.localName(descriptor)
}
private fun generateNameForLiftedDeclaration(descriptor: DeclarationDescriptor,
newOwner: DeclarationDescriptor): Name =
Name.identifier(
descriptor.parentsWithSelf
.takeWhile { it != newOwner }
.toList().reversed()
.map { suggestLocalName(it) }
.joinToString(separator = "$")
)
private fun generateNameForLiftedDeclaration(
descriptor: DeclarationDescriptor,
newOwner: DeclarationDescriptor
): Name =
Name.identifier(
descriptor.parentsWithSelf
.takeWhile { it != newOwner }
.toList().reversed()
.map { suggestLocalName(it) }
.joinToString(separator = "$")
)
private fun createLiftedDescriptor(localFunctionContext: LocalFunctionContext) {
val oldDescriptor = localFunctionContext.descriptor
val memberOwner = memberDeclaration.descriptor.containingDeclaration!!
val newDescriptor = SimpleFunctionDescriptorImpl.create(
memberOwner,
oldDescriptor.annotations,
generateNameForLiftedDeclaration(oldDescriptor, memberOwner),
CallableMemberDescriptor.Kind.SYNTHESIZED,
oldDescriptor.source
memberOwner,
oldDescriptor.annotations,
generateNameForLiftedDeclaration(oldDescriptor, memberOwner),
CallableMemberDescriptor.Kind.SYNTHESIZED,
oldDescriptor.source
).apply {
isTailrec = oldDescriptor.isTailrec
isSuspend = oldDescriptor.isSuspend
@@ -485,13 +499,13 @@ class LocalDeclarationsLowering(val context: BackendContext, val localNameProvid
val newValueParameters = createTransformedValueParameters(localFunctionContext, capturedValues)
newDescriptor.initialize(
oldDescriptor.extensionReceiverParameter?.type,
newDispatchReceiverParameter,
newTypeParameters,
newValueParameters,
oldDescriptor.returnType,
Modality.FINAL,
Visibilities.PRIVATE
oldDescriptor.extensionReceiverParameter?.type,
newDispatchReceiverParameter,
newTypeParameters,
newValueParameters,
oldDescriptor.returnType,
Modality.FINAL,
Visibilities.PRIVATE
)
oldDescriptor.extensionReceiverParameter?.let {
@@ -507,8 +521,10 @@ class LocalDeclarationsLowering(val context: BackendContext, val localNameProvid
}
}
private fun createTransformedValueParameters(localContext: LocalContextWithClosureAsParameters,
capturedValues: List<IrValueSymbol>)
private fun createTransformedValueParameters(
localContext: LocalContextWithClosureAsParameters,
capturedValues: List<IrValueSymbol>
)
: List<ValueParameterDescriptor> {
val oldDescriptor = localContext.descriptor
@@ -555,8 +571,9 @@ class LocalDeclarationsLowering(val context: BackendContext, val localNameProvid
val oldDescriptor = constructorContext.descriptor
val localClassContext = localClasses[oldDescriptor.containingDeclaration]!!
val newDescriptor = ClassConstructorDescriptorImpl.create(
localClassContext.descriptor,
Annotations.EMPTY, oldDescriptor.isPrimary, oldDescriptor.source)
localClassContext.descriptor,
Annotations.EMPTY, oldDescriptor.isPrimary, oldDescriptor.source
)
constructorContext.transformedDescriptor = newDescriptor
@@ -568,9 +585,9 @@ class LocalDeclarationsLowering(val context: BackendContext, val localNameProvid
val newValueParameters = createTransformedValueParameters(constructorContext, capturedValues)
newDescriptor.initialize(
newValueParameters,
Visibilities.PRIVATE,
newTypeParameters
newValueParameters,
Visibilities.PRIVATE,
newTypeParameters
)
newDescriptor.returnType = oldDescriptor.returnType
@@ -596,35 +613,37 @@ class LocalDeclarationsLowering(val context: BackendContext, val localNameProvid
localClassContext.closure.capturedValues.forEach { capturedValue ->
val fieldDescriptor = PropertyDescriptorImpl.create(
classDescriptor,
Annotations.EMPTY,
Modality.FINAL,
Visibilities.PRIVATE,
/* isVar = */ false,
suggestNameForCapturedValue(capturedValue.descriptor),
CallableMemberDescriptor.Kind.SYNTHESIZED,
SourceElement.NO_SOURCE,
/* lateInit = */ false,
/* isConst = */ false,
/* isExpect = */ false,
/* isActual = */ false,
/* isExternal = */ false,
/* isDelegated = */ false)
classDescriptor,
Annotations.EMPTY,
Modality.FINAL,
Visibilities.PRIVATE,
/* isVar = */ false,
suggestNameForCapturedValue(capturedValue.descriptor),
CallableMemberDescriptor.Kind.SYNTHESIZED,
SourceElement.NO_SOURCE,
/* lateInit = */ false,
/* isConst = */ false,
/* isExpect = */ false,
/* isActual = */ false,
/* isExternal = */ false,
/* isDelegated = */ false
)
fieldDescriptor.initialize(/* getter = */ null, /* setter = */ null)
val extensionReceiverParameter: ReceiverParameterDescriptor? = null
fieldDescriptor.setType(
capturedValue.descriptor.type,
emptyList<TypeParameterDescriptor>(),
classDescriptor.thisAsReceiverParameter,
extensionReceiverParameter)
capturedValue.descriptor.type,
emptyList<TypeParameterDescriptor>(),
classDescriptor.thisAsReceiverParameter,
extensionReceiverParameter
)
localClassContext.capturedValueToField[capturedValue.descriptor] = IrFieldImpl(
localClassContext.declaration.startOffset, localClassContext.declaration.endOffset,
DECLARATION_ORIGIN_FIELD_FOR_CAPTURED_VALUE,
fieldDescriptor
localClassContext.declaration.startOffset, localClassContext.declaration.endOffset,
DECLARATION_ORIGIN_FIELD_FOR_CAPTURED_VALUE,
fieldDescriptor
)
}
}
@@ -638,31 +657,31 @@ class LocalDeclarationsLowering(val context: BackendContext, val localNameProvid
}
private fun suggestNameForCapturedValue(valueDescriptor: ValueDescriptor): Name =
if (valueDescriptor.name.isSpecial) {
val oldNameStr = valueDescriptor.name.asString()
oldNameStr.substring(1, oldNameStr.length - 1).synthesizedName
} else
valueDescriptor.name
if (valueDescriptor.name.isSpecial) {
val oldNameStr = valueDescriptor.name.asString()
oldNameStr.substring(1, oldNameStr.length - 1).synthesizedName
} else
valueDescriptor.name
private fun createUnsubstitutedCapturedValueParameter(
newParameterOwner: CallableMemberDescriptor,
valueDescriptor: ValueDescriptor,
index: Int
newParameterOwner: CallableMemberDescriptor,
valueDescriptor: ValueDescriptor,
index: Int
): ValueParameterDescriptor =
ValueParameterDescriptorImpl(
newParameterOwner, null, index,
valueDescriptor.annotations,
suggestNameForCapturedValue(valueDescriptor),
valueDescriptor.type,
false, false, false, null, valueDescriptor.source
)
ValueParameterDescriptorImpl(
newParameterOwner, null, index,
valueDescriptor.annotations,
suggestNameForCapturedValue(valueDescriptor),
valueDescriptor.type,
false, false, false, null, valueDescriptor.source
)
private fun createUnsubstitutedParameter(
newParameterOwner: CallableMemberDescriptor,
valueParameterDescriptor: ValueParameterDescriptor,
newIndex: Int
newParameterOwner: CallableMemberDescriptor,
valueParameterDescriptor: ValueParameterDescriptor,
newIndex: Int
): ValueParameterDescriptor =
valueParameterDescriptor.copy(newParameterOwner, valueParameterDescriptor.name, newIndex)
valueParameterDescriptor.copy(newParameterOwner, valueParameterDescriptor.name, newIndex)
private fun collectClosures() {
@@ -70,8 +70,10 @@ private fun lowerTailRecursionCalls(context: BackendContext, irFunction: IrFunct
it to irTemporary(irGet(variable), nameHint = it.suggestVariableName()).symbol
}
val transformer = BodyTransformer(builder, irFunction, loop,
parameterToNew, parameterToVariable, tailRecursionCalls)
val transformer = BodyTransformer(
builder, irFunction, loop,
parameterToNew, parameterToVariable, tailRecursionCalls
)
oldBody.statements.forEach {
+it.transform(transformer, null)
@@ -84,12 +86,12 @@ private fun lowerTailRecursionCalls(context: BackendContext, irFunction: IrFunct
}
private class BodyTransformer(
val builder: IrBuilderWithScope,
val irFunction: IrFunction,
val loop: IrLoop,
val parameterToNew: Map<IrValueParameterSymbol, IrValueSymbol>,
val parameterToVariable: Map<IrValueParameterSymbol, IrVariableSymbol>,
val tailRecursionCalls: Set<IrCall>
val builder: IrBuilderWithScope,
val irFunction: IrFunction,
val loop: IrLoop,
val parameterToNew: Map<IrValueParameterSymbol, IrValueSymbol>,
val parameterToVariable: Map<IrValueParameterSymbol, IrVariableSymbol>,
val tailRecursionCalls: Set<IrCall>
) : IrElementTransformerVoid() {
val parameters = irFunction.explicitParameters
@@ -128,24 +130,23 @@ private class BodyTransformer(
// For each unspecified argument set the corresponding variable to default:
parameters.filter { it !in specifiedParameters }.forEach { parameter ->
val originalDefaultValue = parameter.owner.defaultValue?.expression ?:
throw Error("no argument specified for $parameter")
val originalDefaultValue = parameter.owner.defaultValue?.expression ?: throw Error("no argument specified for $parameter")
// Copy default value, mapping parameters to variables containing freshly computed arguments:
val defaultValue = originalDefaultValue
.deepCopyWithVariables()
.transform(object : IrElementTransformerVoid() {
.deepCopyWithVariables()
.transform(object : IrElementTransformerVoid() {
override fun visitGetValue(expression: IrGetValue): IrExpression {
expression.transformChildrenVoid(this)
override fun visitGetValue(expression: IrGetValue): IrExpression {
expression.transformChildrenVoid(this)
val variableSymbol = parameterToVariable[expression.symbol] ?: return expression
return IrGetValueImpl(
expression.startOffset, expression.endOffset,
variableSymbol, expression.origin
)
}
}, data = null)
val variableSymbol = parameterToVariable[expression.symbol] ?: return expression
return IrGetValueImpl(
expression.startOffset, expression.endOffset,
variableSymbol, expression.origin
)
}
}, data = null)
+irSetVar(parameterToVariable[parameter]!!, defaultValue)
}
@@ -21,10 +21,10 @@ import org.jetbrains.kotlin.backend.jvm.JvmBackendContext
import org.jetbrains.kotlin.backend.jvm.JvmLoweredDeclarationOrigin
import org.jetbrains.kotlin.backend.jvm.descriptors.JvmDescriptorWithExtraFlags
import org.jetbrains.kotlin.codegen.*
import org.jetbrains.kotlin.codegen.MemberCodegen.badDescriptor
import org.jetbrains.kotlin.codegen.binding.CodegenBinding
import org.jetbrains.kotlin.descriptors.*
import org.jetbrains.kotlin.ir.declarations.*
import org.jetbrains.kotlin.ir.util.dump
import org.jetbrains.kotlin.load.java.JavaVisibilities
import org.jetbrains.kotlin.name.SpecialNames
import org.jetbrains.kotlin.psi.KtElement
@@ -40,9 +40,9 @@ import org.jetbrains.org.objectweb.asm.Type
import java.lang.RuntimeException
class ClassCodegen private constructor(
private val irClass: IrClass,
val context: JvmBackendContext,
private val parentClassCodegen: ClassCodegen? = null
private val irClass: IrClass,
val context: JvmBackendContext,
private val parentClassCodegen: ClassCodegen? = null
) : InnerClassConsumer {
private val innerClasses = mutableListOf<ClassDescriptor>()
@@ -55,7 +55,10 @@ class ClassCodegen private constructor(
private val isAnonymous = DescriptorUtils.isAnonymousObject(irClass.descriptor)
val type: Type = if (isAnonymous) CodegenBinding.asmTypeForAnonymousClass(state.bindingContext, descriptor.source.getPsi() as KtElement) else typeMapper.mapType(descriptor)
val type: Type = if (isAnonymous) CodegenBinding.asmTypeForAnonymousClass(
state.bindingContext,
descriptor.source.getPsi() as KtElement
) else typeMapper.mapType(descriptor)
val psiElement = irClass.descriptor.psiElement!!
@@ -66,13 +69,13 @@ class ClassCodegen private constructor(
val signature = ImplementationBodyCodegen.signature(descriptor, type, superClassInfo, typeMapper)
visitor.defineClass(
psiElement,
state.classFileVersion,
descriptor.calculateClassFlags(),
signature.name,
signature.javaGenericSignature,
signature.superclassName,
signature.interfaces.toTypedArray()
psiElement,
state.classFileVersion,
descriptor.calculateClassFlags(),
signature.name,
signature.javaGenericSignature,
signature.superclassName,
signature.interfaces.toTypedArray()
)
AnnotationCodegen.forClass(visitor.visitor, this, typeMapper).genAnnotations(descriptor, null)
@@ -91,16 +94,22 @@ class ClassCodegen private constructor(
val state = context.state
if (ErrorUtils.isError(descriptor)) {
badDescriptor(descriptor, state.classBuilderMode)
badDescriptor(irClass, state.classBuilderMode)
return
}
if (descriptor.name == SpecialNames.NO_NAME_PROVIDED) {
badDescriptor(descriptor, state.classBuilderMode)
if (irClass.name == SpecialNames.NO_NAME_PROVIDED) {
badDescriptor(irClass, state.classBuilderMode)
}
ClassCodegen(irClass, context).generate()
}
private fun badDescriptor(irClass: IrClass, mode: ClassBuilderMode) {
if (mode.generateBodies) {
throw IllegalStateException("Generating bad class in ClassBuilderMode = $mode: ${irClass.dump()}")
}
}
}
fun generateDeclaration(declaration: IrDeclaration) {
@@ -128,13 +137,14 @@ class ClassCodegen private constructor(
if (field.origin == IrDeclarationOrigin.FAKE_OVERRIDE) return
val fieldType = typeMapper.mapType(field.descriptor)
val fieldSignature = typeMapper.mapFieldSignature(field.descriptor.type, field.descriptor)
val fv = visitor.newField(field.OtherOrigin, field.descriptor.calculateCommonFlags(), field.descriptor.name.asString(), fieldType.descriptor,
fieldSignature, null/*TODO support default values*/)
val fv = visitor.newField(
field.OtherOrigin, field.descriptor.calculateCommonFlags(), field.descriptor.name.asString(), fieldType.descriptor,
fieldSignature, null/*TODO support default values*/
)
if (field.origin == JvmLoweredDeclarationOrigin.FIELD_FOR_ENUM_ENTRY) {
AnnotationCodegen.forField(fv, this, typeMapper).genAnnotations(field.descriptor, null)
}
else {
} else {
}
}
@@ -200,21 +210,17 @@ fun MemberDescriptor.calculateCommonFlags(): Int {
var flags = 0
if (Visibilities.isPrivate(visibility)) {
flags = flags.or(Opcodes.ACC_PRIVATE)
}
else if (visibility == Visibilities.PUBLIC || visibility == Visibilities.INTERNAL) {
} else if (visibility == Visibilities.PUBLIC || visibility == Visibilities.INTERNAL) {
flags = flags.or(Opcodes.ACC_PUBLIC)
}
else if (visibility == Visibilities.PROTECTED) {
} else if (visibility == Visibilities.PROTECTED) {
flags = flags.or(Opcodes.ACC_PROTECTED)
}
else if (visibility == JavaVisibilities.PACKAGE_VISIBILITY) {
} else if (visibility == JavaVisibilities.PACKAGE_VISIBILITY) {
// default visibility
}
else {
} else {
throw RuntimeException("Unsupported visibility $visibility for descriptor $this")
}
flags = flags.or(calcModalityFlag())
flags = flags.or(calcModalityFlag())
if (this is JvmDescriptorWithExtraFlags) {
flags = flags or extraFlags
@@ -257,7 +263,8 @@ private val MemberDescriptor.effectiveModality: Modality
}
if (DescriptorUtils.isSealedClass(this) ||
DescriptorUtils.isAnnotationClass(this) ||
DescriptorUtils.isAnnotationClass(this.containingDeclaration)) {
DescriptorUtils.isAnnotationClass(this.containingDeclaration)
) {
return Modality.ABSTRACT
}
@@ -37,42 +37,42 @@ import org.jetbrains.org.objectweb.asm.Opcodes
import java.util.*
class JvmDescriptorsFactory(
private val psiSourceManager: PsiSourceManager,
private val builtIns: KotlinBuiltIns
private val psiSourceManager: PsiSourceManager,
private val builtIns: KotlinBuiltIns
) : DescriptorsFactory {
private val singletonFieldDescriptors = HashMap<ClassDescriptor, PropertyDescriptor>()
private val outerThisDescriptors = HashMap<ClassDescriptor, PropertyDescriptor>()
private val innerClassConstructors = HashMap<ClassConstructorDescriptor, IrConstructorSymbol>()
override fun getFieldDescriptorForEnumEntry(enumEntryDescriptor: ClassDescriptor): PropertyDescriptor =
singletonFieldDescriptors.getOrPut(enumEntryDescriptor) {
createEnumEntryFieldDescriptor(enumEntryDescriptor)
}
singletonFieldDescriptors.getOrPut(enumEntryDescriptor) {
createEnumEntryFieldDescriptor(enumEntryDescriptor)
}
fun createFileClassDescriptor(fileEntry: SourceManager.FileEntry, packageFragment: PackageFragmentDescriptor): FileClassDescriptor {
val ktFile = psiSourceManager.getKtFile(fileEntry as PsiSourceManager.PsiFileEntry)
?: throw AssertionError("Unexpected file entry: $fileEntry")
?: throw AssertionError("Unexpected file entry: $fileEntry")
val fileClassInfo = JvmFileClassUtil.getFileClassInfoNoResolve(ktFile)
val sourceElement = KotlinSourceElement(ktFile)
return FileClassDescriptorImpl(
fileClassInfo.fileClassFqName.shortName(), packageFragment,
listOf(builtIns.anyType),
sourceElement,
Annotations.EMPTY // TODO file annotations
fileClassInfo.fileClassFqName.shortName(), packageFragment,
listOf(builtIns.anyType),
sourceElement,
Annotations.EMPTY // TODO file annotations
)
}
override fun getOuterThisFieldDescriptor(innerClassDescriptor: ClassDescriptor): PropertyDescriptor =
if (!innerClassDescriptor.isInner) throw AssertionError("Class is not inner: $innerClassDescriptor")
else outerThisDescriptors.getOrPut(innerClassDescriptor) {
val outerClassDescriptor = DescriptorUtils.getContainingClass(innerClassDescriptor) ?:
throw AssertionError("No containing class for inner class $innerClassDescriptor")
if (!innerClassDescriptor.isInner) throw AssertionError("Class is not inner: $innerClassDescriptor")
else outerThisDescriptors.getOrPut(innerClassDescriptor) {
val outerClassDescriptor = DescriptorUtils.getContainingClass(innerClassDescriptor)
?: throw AssertionError("No containing class for inner class $innerClassDescriptor")
JvmPropertyDescriptorImpl.createFinalField(
Name.identifier("this$0"), outerClassDescriptor.defaultType, innerClassDescriptor,
Annotations.EMPTY, JavaVisibilities.PACKAGE_VISIBILITY, Opcodes.ACC_SYNTHETIC, SourceElement.NO_SOURCE
)
}
JvmPropertyDescriptorImpl.createFinalField(
Name.identifier("this$0"), outerClassDescriptor.defaultType, innerClassDescriptor,
Annotations.EMPTY, JavaVisibilities.PACKAGE_VISIBILITY, Opcodes.ACC_SYNTHETIC, SourceElement.NO_SOURCE
)
}
override fun getInnerClassConstructorWithOuterThisParameter(innerClassConstructor: ClassConstructorDescriptor): IrConstructorSymbol {
val innerClass = innerClassConstructor.containingDeclaration
@@ -88,43 +88,42 @@ class JvmDescriptorsFactory(
val outerThisType = (classDescriptor.containingDeclaration as ClassDescriptor).defaultType
val newDescriptor = ClassConstructorDescriptorImpl.createSynthesized(
classDescriptor, oldDescriptor.annotations, oldDescriptor.isPrimary, oldDescriptor.source
classDescriptor, oldDescriptor.annotations, oldDescriptor.isPrimary, oldDescriptor.source
)
val outerThisValueParameter = newDescriptor.createValueParameter(0, "\$outer", outerThisType)
val newValueParameters =
listOf(outerThisValueParameter) +
oldDescriptor.valueParameters.map { it.copy(newDescriptor, it.name, it.index + 1) }
listOf(outerThisValueParameter) +
oldDescriptor.valueParameters.map { it.copy(newDescriptor, it.name, it.index + 1) }
newDescriptor.initialize(newValueParameters, oldDescriptor.visibility)
newDescriptor.returnType = oldDescriptor.returnType
return IrConstructorSymbolImpl(newDescriptor)
}
private fun createEnumEntryFieldDescriptor(enumEntryDescriptor: ClassDescriptor): PropertyDescriptor {
assert(enumEntryDescriptor.kind == ClassKind.ENUM_ENTRY) { "Should be enum entry: $enumEntryDescriptor" }
val enumClassDescriptor = enumEntryDescriptor.containingDeclaration as ClassDescriptor
assert(enumClassDescriptor.kind == ClassKind.ENUM_CLASS) { "Should be enum class: $enumClassDescriptor"}
assert(enumClassDescriptor.kind == ClassKind.ENUM_CLASS) { "Should be enum class: $enumClassDescriptor" }
return JvmPropertyDescriptorImpl.createStaticVal(
enumEntryDescriptor.name,
enumClassDescriptor.defaultType,
enumClassDescriptor,
enumEntryDescriptor.annotations,
Modality.FINAL,
Visibilities.PUBLIC,
Opcodes.ACC_ENUM,
enumEntryDescriptor.source
enumEntryDescriptor.name,
enumClassDescriptor.defaultType,
enumClassDescriptor,
enumEntryDescriptor.annotations,
Modality.FINAL,
Visibilities.PUBLIC,
Opcodes.ACC_ENUM,
enumEntryDescriptor.source
)
}
override fun getFieldDescriptorForObjectInstance(objectDescriptor: ClassDescriptor): PropertyDescriptor =
singletonFieldDescriptors.getOrPut(objectDescriptor) {
createObjectInstanceFieldDescriptor(objectDescriptor)
}
singletonFieldDescriptors.getOrPut(objectDescriptor) {
createObjectInstanceFieldDescriptor(objectDescriptor)
}
private fun createObjectInstanceFieldDescriptor(objectDescriptor: ClassDescriptor): PropertyDescriptor {
assert(objectDescriptor.kind == ClassKind.OBJECT) { "Should be an object: $objectDescriptor" }
@@ -133,11 +132,11 @@ class JvmDescriptorsFactory(
val name = if (isNotMappedCompanion) objectDescriptor.name else Name.identifier("INSTANCE")
val containingDeclaration = if (isNotMappedCompanion) objectDescriptor.containingDeclaration else objectDescriptor
return PropertyDescriptorImpl.create(
containingDeclaration,
Annotations.EMPTY, Modality.FINAL, Visibilities.PUBLIC, false,
name,
CallableMemberDescriptor.Kind.SYNTHESIZED, SourceElement.NO_SOURCE, /* lateInit = */ false, /* isConst = */ false,
/* isExpect = */ false, /* isActual = */ false, /* isExternal = */ false, /* isDelegated = */ false
containingDeclaration,
Annotations.EMPTY, Modality.FINAL, Visibilities.PUBLIC, false,
name,
CallableMemberDescriptor.Kind.SYNTHESIZED, SourceElement.NO_SOURCE, /* lateInit = */ false, /* isConst = */ false,
/* isExpect = */ false, /* isActual = */ false, /* isExternal = */ false, /* isDelegated = */ false
).initialize(objectDescriptor.defaultType)
}
}
@@ -67,12 +67,10 @@ class ConstAndJvmFieldPropertiesLowering : IrElementTransformerVoid(), FileLower
if (JvmCodegenUtil.isConstOrHasJvmFieldAnnotation(property)) {
return if (descriptor is PropertyGetterDescriptor) {
substituteGetter(descriptor, expression)
}
else {
} else {
substituteSetter(descriptor, expression)
}
}
else if (property is SyntheticJavaPropertyDescriptor) {
} else if (property is SyntheticJavaPropertyDescriptor) {
expression.dispatchReceiver = expression.extensionReceiver
expression.extensionReceiver = null
}
@@ -81,24 +79,24 @@ class ConstAndJvmFieldPropertiesLowering : IrElementTransformerVoid(), FileLower
private fun substituteSetter(descriptor: PropertyAccessorDescriptor, expression: IrCall): IrSetFieldImpl {
return IrSetFieldImpl(
expression.startOffset,
expression.endOffset,
descriptor.correspondingProperty,
expression.dispatchReceiver,
expression.getValueArgument(descriptor.valueParameters.lastIndex)!!,
expression.origin,
expression.superQualifier
expression.startOffset,
expression.endOffset,
descriptor.correspondingProperty,
expression.dispatchReceiver,
expression.getValueArgument(descriptor.valueParameters.lastIndex)!!,
expression.origin,
expression.superQualifier
)
}
private fun substituteGetter(descriptor: PropertyGetterDescriptor, expression: IrCall): IrGetFieldImpl {
return IrGetFieldImpl(
expression.startOffset,
expression.endOffset,
descriptor.correspondingProperty,
expression.dispatchReceiver,
expression.origin,
expression.superQualifier
expression.startOffset,
expression.endOffset,
descriptor.correspondingProperty,
expression.dispatchReceiver,
expression.origin,
expression.superQualifier
)
}
}
@@ -38,10 +38,14 @@ class StaticDefaultFunctionLowering(val state: GenerationState) : IrElementTrans
override fun visitFunction(declaration: IrFunction): IrStatement {
if (declaration.origin == DECLARATION_ORIGIN_FUNCTION_FOR_DEFAULT_PARAMETER && declaration.dispatchReceiverParameter != null) {
val newFunction = createStaticFunctionWithReceivers(declaration.descriptor.containingDeclaration as ClassDescriptor, declaration.descriptor.name, declaration.descriptor, declaration.descriptor.dispatchReceiverParameter!!.type)
val newFunction = createStaticFunctionWithReceivers(
declaration.descriptor.containingDeclaration as ClassDescriptor,
declaration.descriptor.name,
declaration.descriptor,
declaration.descriptor.dispatchReceiverParameter!!.type
)
return newFunction.createFunctionAndMapVariables(declaration)
}
else {
} else {
return super.visitFunction(declaration)
}
}
@@ -56,22 +56,22 @@ interface StubContext {
}
class StubCodegenContext(
contextDescriptor: ClassDescriptor,
parentContext: CodegenContext<*>?,
override val irClassContext: IrClassContext
) :StubContext, CodegenContext<DeclarationDescriptor>(
if (contextDescriptor is FileClassDescriptor) contextDescriptor.containingDeclaration else contextDescriptor,
OwnerKind.IMPLEMENTATION, parentContext, null,
if (contextDescriptor is FileClassDescriptor) null else contextDescriptor,
null
contextDescriptor: ClassDescriptor,
parentContext: CodegenContext<*>?,
override val irClassContext: IrClassContext
) : StubContext, CodegenContext<DeclarationDescriptor>(
if (contextDescriptor is FileClassDescriptor) contextDescriptor.containingDeclaration else contextDescriptor,
OwnerKind.IMPLEMENTATION, parentContext, null,
if (contextDescriptor is FileClassDescriptor) null else contextDescriptor,
null
)
class ClassStubContext(
contextDescriptor: ClassDescriptor,
parentContext: CodegenContext<*>?,
override val irClassContext: IrClassContext,
typeMapper: KotlinTypeMapper
) : StubContext, ClassContext( typeMapper, contextDescriptor, OwnerKind.IMPLEMENTATION, parentContext, null)
contextDescriptor: ClassDescriptor,
parentContext: CodegenContext<*>?,
override val irClassContext: IrClassContext,
typeMapper: KotlinTypeMapper
) : StubContext, ClassContext(typeMapper, contextDescriptor, OwnerKind.IMPLEMENTATION, parentContext, null)
class ContextAnnotator(val state: GenerationState) : ClassLowerWithContext() {
@@ -89,8 +89,7 @@ class ContextAnnotator(val state: GenerationState) : ClassLowerWithContext() {
val descriptor = irClass.descriptor
val newContext: CodegenContext<*> = if (descriptor is FileClassDescriptor) {
StubCodegenContext(descriptor, data.parent?.codegenContext, data)
}
else {
} else {
ClassStubContext(descriptor, data.parent?.codegenContext, data, state.typeMapper)
}
newContext.apply {
@@ -137,12 +136,15 @@ class SyntheticAccessorLowering(val context: JvmBackendContext) : FileLoweringPa
val codegenContext = data.codegenContext
val accessors = codegenContext.accessors
val allAccessors =
(
accessors.filterIsInstance<FunctionDescriptor>() +
accessors.filterIsInstance<AccessorForPropertyDescriptor>().flatMap {
listOfNotNull(if (it.isWithSyntheticGetterAccessor) it.getter else null, if (it.isWithSyntheticSetterAccessor) it.setter else null)
}
).filterIsInstance<AccessorForCallableDescriptor<*>>()
(
accessors.filterIsInstance<FunctionDescriptor>() +
accessors.filterIsInstance<AccessorForPropertyDescriptor>().flatMap {
listOfNotNull(
if (it.isWithSyntheticGetterAccessor) it.getter else null,
if (it.isWithSyntheticSetterAccessor) it.setter else null
)
}
).filterIsInstance<AccessorForCallableDescriptor<*>>()
val irClassToAddAccessor = data.irClass
allAccessors.forEach { accessor ->
@@ -157,30 +159,55 @@ class SyntheticAccessorLowering(val context: JvmBackendContext) : FileLoweringPa
}
companion object {
fun createSyntheticAccessorCallForFunction(superResult: IrElement, expression: IrMemberAccessExpression, codegenContext: CodegenContext<*>?, context: JvmBackendContext): IrElement {
fun createSyntheticAccessorCallForFunction(
superResult: IrElement,
expression: IrMemberAccessExpression,
codegenContext: CodegenContext<*>?,
context: JvmBackendContext
): IrElement {
val descriptor = expression.descriptor
if (descriptor is FunctionDescriptor && !expression.usesDefaultArguments()) {
val directAccessor = codegenContext!!.accessibleDescriptor(JvmCodegenUtil.getDirectMember(descriptor), (expression as? IrCall)?.superQualifier)
val directAccessor = codegenContext!!.accessibleDescriptor(
JvmCodegenUtil.getDirectMember(descriptor),
(expression as? IrCall)?.superQualifier
)
val accessor = Companion.actualAccessor(descriptor, directAccessor)
if (accessor is AccessorForCallableDescriptor<*> && descriptor !is AccessorForCallableDescriptor<*>) {
val isConstructor = descriptor is ConstructorDescriptor
val accessorOwner = accessor.containingDeclaration as ClassOrPackageFragmentDescriptor
val accessorForIr =
accessorToIrAccessorDescriptor(isConstructor, accessor, context, descriptor, accessorOwner) //TODO change call
accessorToIrAccessorDescriptor(isConstructor, accessor, context, descriptor, accessorOwner) //TODO change call
val call =
if (isConstructor && expression is IrDelegatingConstructorCall)
IrDelegatingConstructorCallImpl(expression.startOffset, expression.endOffset, accessorForIr as ClassConstructorDescriptor)
else IrCallImpl(expression.startOffset, expression.endOffset, accessorForIr, emptyMap(), expression.origin/*TODO super*/)
if (isConstructor && expression is IrDelegatingConstructorCall)
IrDelegatingConstructorCallImpl(
expression.startOffset,
expression.endOffset,
accessorForIr as ClassConstructorDescriptor
)
else IrCallImpl(
expression.startOffset,
expression.endOffset,
accessorForIr,
emptyMap(),
expression.origin/*TODO super*/
)
//copyAllArgsToValueParams(call, expression)
val receiverAndArgs = expression.receiverAndArgs()
receiverAndArgs.forEachIndexed { i, irExpression ->
call.putValueArgument(i, irExpression)
}
if (isConstructor) {
call.putValueArgument(receiverAndArgs.size, IrConstImpl.constNull(UNDEFINED_OFFSET, UNDEFINED_OFFSET, context.ir.symbols.defaultConstructorMarker.descriptor.defaultType))
call.putValueArgument(
receiverAndArgs.size,
IrConstImpl.constNull(
UNDEFINED_OFFSET,
UNDEFINED_OFFSET,
context.ir.symbols.defaultConstructorMarker.descriptor.defaultType
)
)
}
return call
}
@@ -188,12 +215,21 @@ class SyntheticAccessorLowering(val context: JvmBackendContext) : FileLoweringPa
return superResult
}
private fun accessorToIrAccessorDescriptor(isConstructor: Boolean, accessor: CallableMemberDescriptor, context: JvmBackendContext, descriptor: FunctionDescriptor, accessorOwner: ClassOrPackageFragmentDescriptor): FunctionDescriptor {
private fun accessorToIrAccessorDescriptor(
isConstructor: Boolean,
accessor: CallableMemberDescriptor,
context: JvmBackendContext,
descriptor: FunctionDescriptor,
accessorOwner: ClassOrPackageFragmentDescriptor
): FunctionDescriptor {
return if (isConstructor)
(accessor as AccessorForConstructorDescriptor).constructorDescriptorWithMarker(
context.ir.symbols.defaultConstructorMarker.descriptor.defaultType
context.ir.symbols.defaultConstructorMarker.descriptor.defaultType
)
else descriptor.toStatic(accessorOwner, Name.identifier(context.state.typeMapper.mapAsmMethod(accessor as FunctionDescriptor).name))
else descriptor.toStatic(
accessorOwner,
Name.identifier(context.state.typeMapper.mapAsmMethod(accessor as FunctionDescriptor).name)
)
}
fun addAccessorToClass(accessor: AccessorForCallableDescriptor<*>, irClassToAddAccessor: IrClass, context: JvmBackendContext) {
@@ -203,7 +239,8 @@ class SyntheticAccessorLowering(val context: JvmBackendContext) : FileLoweringPa
val accessorForIr = accessorToIrAccessorDescriptor(
isConstructor, accessor, context,
accessor.calleeDescriptor as? FunctionDescriptor ?: return,
accessorOwner)
accessorOwner
)
val syntheticFunction = if (isConstructor) IrConstructorImpl(
UNDEFINED_OFFSET, UNDEFINED_OFFSET, JvmLoweredDeclarationOrigin.SYNTHETIC_ACCESSOR,
accessorForIr as ClassConstructorDescriptor, body
@@ -255,28 +292,56 @@ class SyntheticAccessorLowering(val context: JvmBackendContext) : FileLoweringPa
var offset = 0
val delegateTo = call.descriptor
delegateTo.dispatchReceiverParameter?.let {
call.dispatchReceiver = IrGetValueImpl(UNDEFINED_OFFSET, UNDEFINED_OFFSET, syntheticFunction.valueParameters[offset++].symbol)
call.dispatchReceiver =
IrGetValueImpl(UNDEFINED_OFFSET, UNDEFINED_OFFSET, syntheticFunction.valueParameters[offset++].symbol)
}
delegateTo.extensionReceiverParameter?.let {
call.extensionReceiver = IrGetValueImpl(UNDEFINED_OFFSET, UNDEFINED_OFFSET, syntheticFunction.valueParameters[offset++].symbol)
call.extensionReceiver =
IrGetValueImpl(UNDEFINED_OFFSET, UNDEFINED_OFFSET, syntheticFunction.valueParameters[offset++].symbol)
}
call.descriptor.valueParameters.forEachIndexed { i, _ ->
call.putValueArgument(i, IrGetValueImpl(UNDEFINED_OFFSET, UNDEFINED_OFFSET, syntheticFunction.valueParameters[i + offset].symbol))
call.putValueArgument(
i,
IrGetValueImpl(
UNDEFINED_OFFSET,
UNDEFINED_OFFSET,
syntheticFunction.valueParameters[i + offset].symbol
)
)
}
}
private fun AccessorForConstructorDescriptor.constructorDescriptorWithMarker(marker: KotlinType) =
ClassConstructorDescriptorImpl.createSynthesized(containingDeclaration, annotations, false, source).also {
it.initialize(
DescriptorUtils.getReceiverParameterType(extensionReceiverParameter),
dispatchReceiverParameter,
emptyList()/*TODO*/,
calleeDescriptor.valueParameters.map { it.copy(this, it.name, it.index) } + ValueParameterDescriptorImpl.createWithDestructuringDeclarations(it, null, calleeDescriptor.valueParameters.size, Annotations.EMPTY, Name.identifier("marker"), marker, false, false, false, null, SourceElement.NO_SOURCE, null),
calleeDescriptor.returnType,
Modality.FINAL,
Visibilities.LOCAL
DescriptorUtils.getReceiverParameterType(extensionReceiverParameter),
dispatchReceiverParameter,
emptyList()/*TODO*/,
calleeDescriptor.valueParameters.map {
it.copy(
this,
it.name,
it.index
)
} + ValueParameterDescriptorImpl.createWithDestructuringDeclarations(
it,
null,
calleeDescriptor.valueParameters.size,
Annotations.EMPTY,
Name.identifier("marker"),
marker,
false,
false,
false,
null,
SourceElement.NO_SOURCE,
null
),
calleeDescriptor.returnType,
Modality.FINAL,
Visibilities.LOCAL
)
}
}