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
@@ -38,8 +38,8 @@ fun ClassDescriptor?.signature2Descriptor(methodName: Name, signature:Array<Kotl
.getContributedFunctions(methodName, NoLookupLocation.FROM_BACKEND) .getContributedFunctions(methodName, NoLookupLocation.FROM_BACKEND)
.firstOrNull { .firstOrNull {
return@firstOrNull it.valueParameters.size == signature.size return@firstOrNull it.valueParameters.size == signature.size
&& (signature.isEmpty() || it.valueParameters.any { && (signature.isEmpty() || it.valueParameters.any { p ->
p -> val index = it.valueParameters.indexOf(p) val index = it.valueParameters.indexOf(p)
return@any p.type == signature[index] return@any p.type == signature[index]
}) })
} }
@@ -58,7 +58,8 @@ fun DeclarationDescriptor.createFakeOverrideDescriptor(owner: ClassDescriptor):
/* modality = */ modality, /* modality = */ modality,
/* visibility = */ visibility, /* visibility = */ visibility,
/* kind = */ CallableMemberDescriptor.Kind.FAKE_OVERRIDE, /* kind = */ CallableMemberDescriptor.Kind.FAKE_OVERRIDE,
/* copyOverrides = */ true).apply { /* copyOverrides = */ true
).apply {
overriddenDescriptors += this@createFakeOverrideDescriptor overriddenDescriptors += this@createFakeOverrideDescriptor
} }
else -> null else -> null
@@ -76,13 +77,17 @@ fun FunctionDescriptor.createOverriddenDescriptor(owner: ClassDescriptor, final:
} }
} }
fun ClassDescriptor.createSimpleDelegatingConstructorDescriptor(superConstructorDescriptor: ClassConstructorDescriptor, isPrimary: Boolean = false) fun ClassDescriptor.createSimpleDelegatingConstructorDescriptor(
superConstructorDescriptor: ClassConstructorDescriptor,
isPrimary: Boolean = false
)
: ClassConstructorDescriptor { : ClassConstructorDescriptor {
val constructorDescriptor = ClassConstructorDescriptorImpl.createSynthesized( val constructorDescriptor = ClassConstructorDescriptorImpl.createSynthesized(
/* containingDeclaration = */ this, /* containingDeclaration = */ this,
/* annotations = */ Annotations.EMPTY, /* annotations = */ Annotations.EMPTY,
/* isPrimary = */ isPrimary, /* isPrimary = */ isPrimary,
/* source = */ SourceElement.NO_SOURCE) /* source = */ SourceElement.NO_SOURCE
)
val valueParameters = superConstructorDescriptor.valueParameters.map { val valueParameters = superConstructorDescriptor.valueParameters.map {
it.copy(constructorDescriptor, it.name, it.index) it.copy(constructorDescriptor, it.name, it.index)
} }
@@ -91,15 +96,18 @@ fun ClassDescriptor.createSimpleDelegatingConstructorDescriptor(superConstructor
return constructorDescriptor return constructorDescriptor
} }
fun IrClass.addSimpleDelegatingConstructor(superConstructorSymbol: IrConstructorSymbol, fun IrClass.addSimpleDelegatingConstructor(
superConstructorSymbol: IrConstructorSymbol,
constructorDescriptor: ClassConstructorDescriptor, constructorDescriptor: ClassConstructorDescriptor,
origin: IrDeclarationOrigin) origin: IrDeclarationOrigin
)
: IrConstructor { : IrConstructor {
return IrConstructorImpl(startOffset, endOffset, origin, constructorDescriptor).also { constructor -> return IrConstructorImpl(startOffset, endOffset, origin, constructorDescriptor).also { constructor ->
constructor.createParameterDeclarations() constructor.createParameterDeclarations()
constructor.body = IrBlockBodyImpl(startOffset, endOffset, constructor.body = IrBlockBodyImpl(
startOffset, endOffset,
listOf( listOf(
IrDelegatingConstructorCallImpl( IrDelegatingConstructorCallImpl(
startOffset, endOffset, startOffset, endOffset,
@@ -118,9 +126,11 @@ fun IrClass.addSimpleDelegatingConstructor(superConstructorSymbol: IrConstructor
} }
} }
fun CommonBackendContext.createArrayOfExpression(arrayElementType: KotlinType, fun CommonBackendContext.createArrayOfExpression(
arrayElementType: KotlinType,
arrayElements: List<IrExpression>, arrayElements: List<IrExpression>,
startOffset: Int, endOffset: Int): IrExpression { startOffset: Int, endOffset: Int
): IrExpression {
val genericArrayOfFunSymbol = ir.symbols.arrayOf val genericArrayOfFunSymbol = ir.symbols.arrayOf
val genericArrayOfFun = genericArrayOfFunSymbol.descriptor 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.KotlinType
import org.jetbrains.kotlin.types.typeUtil.builtIns 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) { override fun lower(irDeclarationContainer: IrDeclarationContainer) {
irDeclarationContainer.declarations.transformFlat { memberDeclaration -> irDeclarationContainer.declarations.transformFlat { memberDeclaration ->
if (memberDeclaration is IrFunction) if (memberDeclaration is IrFunction)
@@ -119,15 +120,18 @@ open class DefaultArgumentStubGenerator constructor(val context: CommonBackendCo
type = temporaryVariableSymbol.descriptor.type, type = temporaryVariableSymbol.descriptor.type,
condition = condition, condition = condition,
thenPart = expressionBody.expression, thenPart = expressionBody.expression,
elsePart = irGet(parameterSymbol)) elsePart = irGet(parameterSymbol)
)
+scope.createTemporaryVariable( +scope.createTemporaryVariable(
symbol = temporaryVariableSymbol, symbol = temporaryVariableSymbol,
initializer = variableInitialization) initializer = variableInitialization
)
/* Mapping calculated values with its origin variables. */ /* Mapping calculated values with its origin variables. */
} else { } else {
+scope.createTemporaryVariable( +scope.createTemporaryVariable(
symbol = temporaryVariableSymbol, symbol = temporaryVariableSymbol,
initializer = irGet(parameterSymbol)) initializer = irGet(parameterSymbol)
)
} }
} }
if (irFunction is IrConstructor) { if (irFunction is IrConstructor) {
@@ -177,14 +181,16 @@ private fun Scope.createTemporaryVariableDescriptor(parameterDescriptor: Paramet
containingDeclaration = this.scopeOwner, containingDeclaration = this.scopeOwner,
name = parameterDescriptor!!.name.asString().synthesizedName, name = parameterDescriptor!!.name.asString().synthesizedName,
outType = parameterDescriptor.type, outType = parameterDescriptor.type,
isMutable = false) isMutable = false
)
private fun Scope.createTemporaryVariable(symbol: IrVariableSymbol, initializer: IrExpression) = private fun Scope.createTemporaryVariable(symbol: IrVariableSymbol, initializer: IrExpression) =
IrVariableImpl( IrVariableImpl(
startOffset = initializer.startOffset, startOffset = initializer.startOffset,
endOffset = initializer.endOffset, endOffset = initializer.endOffset,
origin = IrDeclarationOrigin.IR_TEMPORARY_VARIABLE, origin = IrDeclarationOrigin.IR_TEMPORARY_VARIABLE,
symbol = symbol).apply { symbol = symbol
).apply {
this.initializer = initializer this.initializer = initializer
} }
@@ -195,10 +201,12 @@ private fun getDefaultParameterExpressionBody(irFunction: IrFunction, valueParam
private fun maskParameterDescriptor(function: IrFunction, number: Int) = private fun maskParameterDescriptor(function: IrFunction, number: Int) =
maskParameterSymbol(function, number).descriptor as ValueParameterDescriptor maskParameterSymbol(function, number).descriptor as ValueParameterDescriptor
private fun maskParameterSymbol(function: IrFunction, number: Int) = private fun maskParameterSymbol(function: IrFunction, number: Int) =
function.valueParameters.single { it.descriptor.name == parameterMaskName(number) }.symbol function.valueParameters.single { it.descriptor.name == parameterMaskName(number) }.symbol
private fun markerParameterDescriptor(descriptor: FunctionDescriptor) = descriptor.valueParameters.single { it.name == kConstructorMarkerName } private fun markerParameterDescriptor(descriptor: FunctionDescriptor) =
descriptor.valueParameters.single { it.name == kConstructorMarkerName }
private fun nullConst(expression: IrElement, type: KotlinType): IrExpression? { private fun nullConst(expression: IrElement, type: KotlinType): IrExpression? {
when { when {
@@ -231,7 +239,8 @@ class DefaultParameterInjector constructor(val context: CommonBackendContext, pr
startOffset = expression.startOffset, startOffset = expression.startOffset,
endOffset = expression.endOffset, endOffset = expression.endOffset,
symbol = symbolForCall as IrConstructorSymbol, symbol = symbolForCall as IrConstructorSymbol,
descriptor = symbolForCall.descriptor) descriptor = symbolForCall.descriptor
)
.apply { .apply {
params.forEach { params.forEach {
log { "call::params@${it.first.index}/${it.first.name.asString()}: ${ir2string(it.second)}" } log { "call::params@${it.first.index}/${it.first.name.asString()}: ${ir2string(it.second)}" }
@@ -261,7 +270,10 @@ class DefaultParameterInjector constructor(val context: CommonBackendContext, pr
endOffset = expression.endOffset, endOffset = expression.endOffset,
symbol = symbol, symbol = symbol,
descriptor = descriptor, descriptor = descriptor,
typeArguments = expression.descriptor.typeParameters.map{it to (expression.getTypeArgument(it) ?: it.defaultType) }.toMap()) typeArguments = expression.descriptor.typeParameters.map {
it to (expression.getTypeArgument(it) ?: it.defaultType)
}.toMap()
)
.apply { .apply {
params.forEach { params.forEach {
log { "call::params@${it.first.index}/${it.first.name.asString()}: ${ir2string(it.second)}" } log { "call::params@${it.first.index}/${it.first.name.asString()}: ${ir2string(it.second)}" }
@@ -305,7 +317,8 @@ class DefaultParameterInjector constructor(val context: CommonBackendContext, pr
startOffset = irBody.startOffset, startOffset = irBody.startOffset,
endOffset = irBody.endOffset, endOffset = irBody.endOffset,
type = descriptor.builtIns.intType, type = descriptor.builtIns.intType,
value = maskValue) value = maskValue
)
} }
if (expression.descriptor is ClassConstructorDescriptor) { if (expression.descriptor is ClassConstructorDescriptor) {
val defaultArgumentMarker = context.ir.symbols.defaultConstructorMarker val defaultArgumentMarker = context.ir.symbols.defaultConstructorMarker
@@ -313,9 +326,9 @@ class DefaultParameterInjector constructor(val context: CommonBackendContext, pr
startOffset = irBody.startOffset, startOffset = irBody.startOffset,
endOffset = irBody.endOffset, endOffset = irBody.endOffset,
type = defaultArgumentMarker.owner.defaultType, type = defaultArgumentMarker.owner.defaultType,
symbol = defaultArgumentMarker) symbol = defaultArgumentMarker
} )
else if (context.ir.shouldGenerateHandlerParameterForDefaultBodyFun()) { } else if (context.ir.shouldGenerateHandlerParameterForDefaultBodyFun()) {
params += realDescriptor.valueParameters.last() to params += realDescriptor.valueParameters.last() to
IrConstImpl.constNull(irBody.startOffset, irBody.endOffset, context.builtIns.any.defaultType) IrConstImpl.constNull(irBody.startOffset, irBody.endOffset, context.builtIns.any.defaultType)
} }
@@ -344,7 +357,8 @@ private fun FunctionDescriptor.generateDefaultsFunction(context: CommonBackendCo
/* containingDeclaration = */ containingDeclaration, /* containingDeclaration = */ containingDeclaration,
/* annotations = */ annotations, /* annotations = */ annotations,
/* isPrimary = */ false, /* isPrimary = */ false,
/* source = */ source) /* source = */ source
)
else -> { else -> {
val name = Name.identifier("$name\$default") val name = Name.identifier("$name\$default")
@@ -353,7 +367,8 @@ private fun FunctionDescriptor.generateDefaultsFunction(context: CommonBackendCo
/* annotations = */ annotations, /* annotations = */ annotations,
/* name = */ name, /* name = */ name,
/* kind = */ CallableMemberDescriptor.Kind.SYNTHESIZED, /* kind = */ CallableMemberDescriptor.Kind.SYNTHESIZED,
/* source = */ source) /* source = */ source
)
} }
} }
@@ -361,14 +376,17 @@ private fun FunctionDescriptor.generateDefaultsFunction(context: CommonBackendCo
valueParameter(descriptor, valueParameters.size + i, parameterMaskName(i), descriptor.builtIns.intType) valueParameter(descriptor, valueParameters.size + i, parameterMaskName(i), descriptor.builtIns.intType)
} }
if (this is ClassConstructorDescriptor) { if (this is ClassConstructorDescriptor) {
syntheticParameters += valueParameter(descriptor, syntheticParameters.last().index + 1, syntheticParameters += valueParameter(
descriptor, syntheticParameters.last().index + 1,
kConstructorMarkerName, kConstructorMarkerName,
context.ir.symbols.defaultConstructorMarker.owner.defaultType) context.ir.symbols.defaultConstructorMarker.owner.defaultType
} )
else if (context.ir.shouldGenerateHandlerParameterForDefaultBodyFun()) { } else if (context.ir.shouldGenerateHandlerParameterForDefaultBodyFun()) {
syntheticParameters += valueParameter(descriptor, syntheticParameters.last().index + 1, syntheticParameters += valueParameter(
descriptor, syntheticParameters.last().index + 1,
"handler".synthesizedName, "handler".synthesizedName,
context.ir.symbols.any.owner.defaultType) context.ir.symbols.any.owner.defaultType
)
} }
descriptor.initialize( descriptor.initialize(
@@ -402,7 +420,8 @@ private fun FunctionDescriptor.generateDefaultsFunction(context: CommonBackendCo
isCrossinline = it.isCrossinline, isCrossinline = it.isCrossinline,
isNoinline = it.isNoinline, isNoinline = it.isNoinline,
varargElementType = it.varargElementType, varargElementType = it.varargElementType,
source = it.source) source = it.source
)
} + syntheticParameters, } + syntheticParameters,
/* unsubstitutedReturnType = */ returnType, /* unsubstitutedReturnType = */ returnType,
/* modality = */ Modality.FINAL, /* modality = */ Modality.FINAL,
@@ -85,9 +85,11 @@ private class KCallableNamePropertyTransformer(val lower: KCallableNamePropertyL
return kind == FunctionClassDescriptor.Kind.KFunction return kind == FunctionClassDescriptor.Kind.KFunction
} }
fun BackendContext.createIrBuilder(symbol: IrSymbol, fun BackendContext.createIrBuilder(
symbol: IrSymbol,
startOffset: Int = UNDEFINED_OFFSET, startOffset: Int = UNDEFINED_OFFSET,
endOffset: Int = UNDEFINED_OFFSET) = endOffset: Int = UNDEFINED_OFFSET
) =
DeclarationIrBuilder(this, symbol, startOffset, endOffset) DeclarationIrBuilder(this, symbol, startOffset, endOffset)
class DeclarationIrBuilder( class DeclarationIrBuilder(
@@ -41,6 +41,7 @@ import java.util.*
interface LocalNameProvider { interface LocalNameProvider {
fun localName(descriptor: DeclarationDescriptor): String = fun localName(descriptor: DeclarationDescriptor): String =
descriptor.name.asString() descriptor.name.asString()
companion object { companion object {
val DEFAULT = object : LocalNameProvider {} val DEFAULT = object : LocalNameProvider {}
} }
@@ -56,7 +57,8 @@ class LocalDeclarationsLowering(val context: BackendContext, val localNameProvid
override fun lower(irDeclarationContainer: IrDeclarationContainer) { override fun lower(irDeclarationContainer: IrDeclarationContainer) {
if (irDeclarationContainer is IrDeclaration && 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. // Lowering of non-local declarations handles all local declarations inside.
// This declaration is local and shouldn't be considered. // This declaration is local and shouldn't be considered.
@@ -140,7 +142,8 @@ class LocalDeclarationsLowering(val context: BackendContext, val localNameProvid
override fun irGet(startOffset: Int, endOffset: Int, descriptor: ValueDescriptor): IrExpression? { override fun irGet(startOffset: Int, endOffset: Int, descriptor: ValueDescriptor): IrExpression? {
val field = capturedValueToField[descriptor] ?: return null val field = capturedValueToField[descriptor] ?: return null
return IrGetFieldImpl(startOffset, endOffset, field.symbol, return IrGetFieldImpl(
startOffset, endOffset, field.symbol,
receiver = IrGetValueImpl(startOffset, endOffset, declaration.thisReceiver!!.symbol) receiver = IrGetValueImpl(startOffset, endOffset, declaration.thisReceiver!!.symbol)
) )
} }
@@ -287,8 +290,8 @@ class LocalDeclarationsLowering(val context: BackendContext, val localNameProvid
} else { } else {
// The callee expects captured value as argument. // The callee expects captured value as argument.
val capturedValueSymbol = val capturedValueSymbol =
newParameterToCaptured[newValueParameterDescriptor] ?: newParameterToCaptured[newValueParameterDescriptor]
throw AssertionError("Non-mapped parameter $newValueParameterDescriptor") ?: throw AssertionError("Non-mapped parameter $newValueParameterDescriptor")
val capturedValueDescriptor = capturedValueSymbol.descriptor val capturedValueDescriptor = capturedValueSymbol.descriptor
localContext?.irGet( localContext?.irGet(
@@ -296,8 +299,10 @@ class LocalDeclarationsLowering(val context: BackendContext, val localNameProvid
capturedValueDescriptor capturedValueDescriptor
) ?: ) ?:
// Captured value is directly available for the caller. // Captured value is directly available for the caller.
IrGetValueImpl(oldExpression.startOffset, oldExpression.endOffset, IrGetValueImpl(
oldParameterToNew[capturedValueDescriptor] ?: capturedValueSymbol) oldExpression.startOffset, oldExpression.endOffset,
oldParameterToNew[capturedValueDescriptor] ?: capturedValueSymbol
)
} }
} }
@@ -372,10 +377,14 @@ class LocalDeclarationsLowering(val context: BackendContext, val localNameProvid
val blockBody = constructorContext.declaration.body as? IrBlockBody val blockBody = constructorContext.declaration.body as? IrBlockBody
?: throw AssertionError("Unexpected constructor body: ${constructorContext.declaration.body}") ?: throw AssertionError("Unexpected constructor body: ${constructorContext.declaration.body}")
val capturedValueExpression = constructorContext.irGet(startOffset, endOffset, capturedValue)!! val capturedValueExpression = constructorContext.irGet(startOffset, endOffset, capturedValue)!!
blockBody.statements.add(0, blockBody.statements.add(
IrSetFieldImpl(startOffset, endOffset, field.symbol, 0,
IrSetFieldImpl(
startOffset, endOffset, field.symbol,
IrGetValueImpl(startOffset, endOffset, irClass.thisReceiver!!.symbol), IrGetValueImpl(startOffset, endOffset, irClass.thisReceiver!!.symbol),
capturedValueExpression, STATEMENT_ORIGIN_INITIALIZER_OF_FIELD_FOR_CAPTURED_VALUE)) capturedValueExpression, STATEMENT_ORIGIN_INITIALIZER_OF_FIELD_FOR_CAPTURED_VALUE
)
)
} }
} }
} }
@@ -408,7 +417,10 @@ class LocalDeclarationsLowering(val context: BackendContext, val localNameProvid
oldCall.origin, oldCall.superQualifierSymbol 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 val oldCallee = oldExpression.descriptor.original
return if (oldCallee.typeParameters.isEmpty()) return if (oldCallee.typeParameters.isEmpty())
@@ -442,8 +454,10 @@ class LocalDeclarationsLowering(val context: BackendContext, val localNameProvid
return localNameProvider.localName(descriptor) return localNameProvider.localName(descriptor)
} }
private fun generateNameForLiftedDeclaration(descriptor: DeclarationDescriptor, private fun generateNameForLiftedDeclaration(
newOwner: DeclarationDescriptor): Name = descriptor: DeclarationDescriptor,
newOwner: DeclarationDescriptor
): Name =
Name.identifier( Name.identifier(
descriptor.parentsWithSelf descriptor.parentsWithSelf
.takeWhile { it != newOwner } .takeWhile { it != newOwner }
@@ -507,8 +521,10 @@ class LocalDeclarationsLowering(val context: BackendContext, val localNameProvid
} }
} }
private fun createTransformedValueParameters(localContext: LocalContextWithClosureAsParameters, private fun createTransformedValueParameters(
capturedValues: List<IrValueSymbol>) localContext: LocalContextWithClosureAsParameters,
capturedValues: List<IrValueSymbol>
)
: List<ValueParameterDescriptor> { : List<ValueParameterDescriptor> {
val oldDescriptor = localContext.descriptor val oldDescriptor = localContext.descriptor
@@ -556,7 +572,8 @@ class LocalDeclarationsLowering(val context: BackendContext, val localNameProvid
val localClassContext = localClasses[oldDescriptor.containingDeclaration]!! val localClassContext = localClasses[oldDescriptor.containingDeclaration]!!
val newDescriptor = ClassConstructorDescriptorImpl.create( val newDescriptor = ClassConstructorDescriptorImpl.create(
localClassContext.descriptor, localClassContext.descriptor,
Annotations.EMPTY, oldDescriptor.isPrimary, oldDescriptor.source) Annotations.EMPTY, oldDescriptor.isPrimary, oldDescriptor.source
)
constructorContext.transformedDescriptor = newDescriptor constructorContext.transformedDescriptor = newDescriptor
@@ -609,7 +626,8 @@ class LocalDeclarationsLowering(val context: BackendContext, val localNameProvid
/* isExpect = */ false, /* isExpect = */ false,
/* isActual = */ false, /* isActual = */ false,
/* isExternal = */ false, /* isExternal = */ false,
/* isDelegated = */ false) /* isDelegated = */ false
)
fieldDescriptor.initialize(/* getter = */ null, /* setter = */ null) fieldDescriptor.initialize(/* getter = */ null, /* setter = */ null)
@@ -619,7 +637,8 @@ class LocalDeclarationsLowering(val context: BackendContext, val localNameProvid
capturedValue.descriptor.type, capturedValue.descriptor.type,
emptyList<TypeParameterDescriptor>(), emptyList<TypeParameterDescriptor>(),
classDescriptor.thisAsReceiverParameter, classDescriptor.thisAsReceiverParameter,
extensionReceiverParameter) extensionReceiverParameter
)
localClassContext.capturedValueToField[capturedValue.descriptor] = IrFieldImpl( localClassContext.capturedValueToField[capturedValue.descriptor] = IrFieldImpl(
localClassContext.declaration.startOffset, localClassContext.declaration.endOffset, localClassContext.declaration.startOffset, localClassContext.declaration.endOffset,
@@ -70,8 +70,10 @@ private fun lowerTailRecursionCalls(context: BackendContext, irFunction: IrFunct
it to irTemporary(irGet(variable), nameHint = it.suggestVariableName()).symbol it to irTemporary(irGet(variable), nameHint = it.suggestVariableName()).symbol
} }
val transformer = BodyTransformer(builder, irFunction, loop, val transformer = BodyTransformer(
parameterToNew, parameterToVariable, tailRecursionCalls) builder, irFunction, loop,
parameterToNew, parameterToVariable, tailRecursionCalls
)
oldBody.statements.forEach { oldBody.statements.forEach {
+it.transform(transformer, null) +it.transform(transformer, null)
@@ -128,8 +130,7 @@ private class BodyTransformer(
// For each unspecified argument set the corresponding variable to default: // For each unspecified argument set the corresponding variable to default:
parameters.filter { it !in specifiedParameters }.forEach { parameter -> parameters.filter { it !in specifiedParameters }.forEach { parameter ->
val originalDefaultValue = parameter.owner.defaultValue?.expression ?: val originalDefaultValue = parameter.owner.defaultValue?.expression ?: throw Error("no argument specified for $parameter")
throw Error("no argument specified for $parameter")
// Copy default value, mapping parameters to variables containing freshly computed arguments: // Copy default value, mapping parameters to variables containing freshly computed arguments:
val defaultValue = originalDefaultValue val defaultValue = originalDefaultValue
@@ -21,10 +21,10 @@ import org.jetbrains.kotlin.backend.jvm.JvmBackendContext
import org.jetbrains.kotlin.backend.jvm.JvmLoweredDeclarationOrigin import org.jetbrains.kotlin.backend.jvm.JvmLoweredDeclarationOrigin
import org.jetbrains.kotlin.backend.jvm.descriptors.JvmDescriptorWithExtraFlags import org.jetbrains.kotlin.backend.jvm.descriptors.JvmDescriptorWithExtraFlags
import org.jetbrains.kotlin.codegen.* import org.jetbrains.kotlin.codegen.*
import org.jetbrains.kotlin.codegen.MemberCodegen.badDescriptor
import org.jetbrains.kotlin.codegen.binding.CodegenBinding import org.jetbrains.kotlin.codegen.binding.CodegenBinding
import org.jetbrains.kotlin.descriptors.* import org.jetbrains.kotlin.descriptors.*
import org.jetbrains.kotlin.ir.declarations.* import org.jetbrains.kotlin.ir.declarations.*
import org.jetbrains.kotlin.ir.util.dump
import org.jetbrains.kotlin.load.java.JavaVisibilities import org.jetbrains.kotlin.load.java.JavaVisibilities
import org.jetbrains.kotlin.name.SpecialNames import org.jetbrains.kotlin.name.SpecialNames
import org.jetbrains.kotlin.psi.KtElement import org.jetbrains.kotlin.psi.KtElement
@@ -55,7 +55,10 @@ class ClassCodegen private constructor(
private val isAnonymous = DescriptorUtils.isAnonymousObject(irClass.descriptor) 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!! val psiElement = irClass.descriptor.psiElement!!
@@ -91,16 +94,22 @@ class ClassCodegen private constructor(
val state = context.state val state = context.state
if (ErrorUtils.isError(descriptor)) { if (ErrorUtils.isError(descriptor)) {
badDescriptor(descriptor, state.classBuilderMode) badDescriptor(irClass, state.classBuilderMode)
return return
} }
if (descriptor.name == SpecialNames.NO_NAME_PROVIDED) { if (irClass.name == SpecialNames.NO_NAME_PROVIDED) {
badDescriptor(descriptor, state.classBuilderMode) badDescriptor(irClass, state.classBuilderMode)
} }
ClassCodegen(irClass, context).generate() 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) { fun generateDeclaration(declaration: IrDeclaration) {
@@ -128,13 +137,14 @@ class ClassCodegen private constructor(
if (field.origin == IrDeclarationOrigin.FAKE_OVERRIDE) return if (field.origin == IrDeclarationOrigin.FAKE_OVERRIDE) return
val fieldType = typeMapper.mapType(field.descriptor) val fieldType = typeMapper.mapType(field.descriptor)
val fieldSignature = typeMapper.mapFieldSignature(field.descriptor.type, 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, val fv = visitor.newField(
fieldSignature, null/*TODO support default values*/) 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) { if (field.origin == JvmLoweredDeclarationOrigin.FIELD_FOR_ENUM_ENTRY) {
AnnotationCodegen.forField(fv, this, typeMapper).genAnnotations(field.descriptor, null) AnnotationCodegen.forField(fv, this, typeMapper).genAnnotations(field.descriptor, null)
} } else {
else {
} }
} }
@@ -200,17 +210,13 @@ fun MemberDescriptor.calculateCommonFlags(): Int {
var flags = 0 var flags = 0
if (Visibilities.isPrivate(visibility)) { if (Visibilities.isPrivate(visibility)) {
flags = flags.or(Opcodes.ACC_PRIVATE) 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) flags = flags.or(Opcodes.ACC_PUBLIC)
} } else if (visibility == Visibilities.PROTECTED) {
else if (visibility == Visibilities.PROTECTED) {
flags = flags.or(Opcodes.ACC_PROTECTED) flags = flags.or(Opcodes.ACC_PROTECTED)
} } else if (visibility == JavaVisibilities.PACKAGE_VISIBILITY) {
else if (visibility == JavaVisibilities.PACKAGE_VISIBILITY) {
// default visibility // default visibility
} } else {
else {
throw RuntimeException("Unsupported visibility $visibility for descriptor $this") throw RuntimeException("Unsupported visibility $visibility for descriptor $this")
} }
@@ -257,7 +263,8 @@ private val MemberDescriptor.effectiveModality: Modality
} }
if (DescriptorUtils.isSealedClass(this) || if (DescriptorUtils.isSealedClass(this) ||
DescriptorUtils.isAnnotationClass(this) || DescriptorUtils.isAnnotationClass(this) ||
DescriptorUtils.isAnnotationClass(this.containingDeclaration)) { DescriptorUtils.isAnnotationClass(this.containingDeclaration)
) {
return Modality.ABSTRACT return Modality.ABSTRACT
} }
@@ -65,8 +65,8 @@ class JvmDescriptorsFactory(
override fun getOuterThisFieldDescriptor(innerClassDescriptor: ClassDescriptor): PropertyDescriptor = override fun getOuterThisFieldDescriptor(innerClassDescriptor: ClassDescriptor): PropertyDescriptor =
if (!innerClassDescriptor.isInner) throw AssertionError("Class is not inner: $innerClassDescriptor") if (!innerClassDescriptor.isInner) throw AssertionError("Class is not inner: $innerClassDescriptor")
else outerThisDescriptors.getOrPut(innerClassDescriptor) { else outerThisDescriptors.getOrPut(innerClassDescriptor) {
val outerClassDescriptor = DescriptorUtils.getContainingClass(innerClassDescriptor) ?: val outerClassDescriptor = DescriptorUtils.getContainingClass(innerClassDescriptor)
throw AssertionError("No containing class for inner class $innerClassDescriptor") ?: throw AssertionError("No containing class for inner class $innerClassDescriptor")
JvmPropertyDescriptorImpl.createFinalField( JvmPropertyDescriptorImpl.createFinalField(
Name.identifier("this$0"), outerClassDescriptor.defaultType, innerClassDescriptor, Name.identifier("this$0"), outerClassDescriptor.defaultType, innerClassDescriptor,
@@ -102,7 +102,6 @@ class JvmDescriptorsFactory(
} }
private fun createEnumEntryFieldDescriptor(enumEntryDescriptor: ClassDescriptor): PropertyDescriptor { private fun createEnumEntryFieldDescriptor(enumEntryDescriptor: ClassDescriptor): PropertyDescriptor {
assert(enumEntryDescriptor.kind == ClassKind.ENUM_ENTRY) { "Should be enum entry: $enumEntryDescriptor" } assert(enumEntryDescriptor.kind == ClassKind.ENUM_ENTRY) { "Should be enum entry: $enumEntryDescriptor" }
@@ -67,12 +67,10 @@ class ConstAndJvmFieldPropertiesLowering : IrElementTransformerVoid(), FileLower
if (JvmCodegenUtil.isConstOrHasJvmFieldAnnotation(property)) { if (JvmCodegenUtil.isConstOrHasJvmFieldAnnotation(property)) {
return if (descriptor is PropertyGetterDescriptor) { return if (descriptor is PropertyGetterDescriptor) {
substituteGetter(descriptor, expression) substituteGetter(descriptor, expression)
} } else {
else {
substituteSetter(descriptor, expression) substituteSetter(descriptor, expression)
} }
} } else if (property is SyntheticJavaPropertyDescriptor) {
else if (property is SyntheticJavaPropertyDescriptor) {
expression.dispatchReceiver = expression.extensionReceiver expression.dispatchReceiver = expression.extensionReceiver
expression.extensionReceiver = null expression.extensionReceiver = null
} }
@@ -38,10 +38,14 @@ class StaticDefaultFunctionLowering(val state: GenerationState) : IrElementTrans
override fun visitFunction(declaration: IrFunction): IrStatement { override fun visitFunction(declaration: IrFunction): IrStatement {
if (declaration.origin == DECLARATION_ORIGIN_FUNCTION_FOR_DEFAULT_PARAMETER && declaration.dispatchReceiverParameter != null) { 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) return newFunction.createFunctionAndMapVariables(declaration)
} } else {
else {
return super.visitFunction(declaration) return super.visitFunction(declaration)
} }
} }
@@ -89,8 +89,7 @@ class ContextAnnotator(val state: GenerationState) : ClassLowerWithContext() {
val descriptor = irClass.descriptor val descriptor = irClass.descriptor
val newContext: CodegenContext<*> = if (descriptor is FileClassDescriptor) { val newContext: CodegenContext<*> = if (descriptor is FileClassDescriptor) {
StubCodegenContext(descriptor, data.parent?.codegenContext, data) StubCodegenContext(descriptor, data.parent?.codegenContext, data)
} } else {
else {
ClassStubContext(descriptor, data.parent?.codegenContext, data, state.typeMapper) ClassStubContext(descriptor, data.parent?.codegenContext, data, state.typeMapper)
} }
newContext.apply { newContext.apply {
@@ -140,7 +139,10 @@ class SyntheticAccessorLowering(val context: JvmBackendContext) : FileLoweringPa
( (
accessors.filterIsInstance<FunctionDescriptor>() + accessors.filterIsInstance<FunctionDescriptor>() +
accessors.filterIsInstance<AccessorForPropertyDescriptor>().flatMap { accessors.filterIsInstance<AccessorForPropertyDescriptor>().flatMap {
listOfNotNull(if (it.isWithSyntheticGetterAccessor) it.getter else null, if (it.isWithSyntheticSetterAccessor) it.setter else null) listOfNotNull(
if (it.isWithSyntheticGetterAccessor) it.getter else null,
if (it.isWithSyntheticSetterAccessor) it.setter else null
)
} }
).filterIsInstance<AccessorForCallableDescriptor<*>>() ).filterIsInstance<AccessorForCallableDescriptor<*>>()
@@ -157,11 +159,19 @@ class SyntheticAccessorLowering(val context: JvmBackendContext) : FileLoweringPa
} }
companion object { 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 val descriptor = expression.descriptor
if (descriptor is FunctionDescriptor && !expression.usesDefaultArguments()) { 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) val accessor = Companion.actualAccessor(descriptor, directAccessor)
if (accessor is AccessorForCallableDescriptor<*> && descriptor !is AccessorForCallableDescriptor<*>) { if (accessor is AccessorForCallableDescriptor<*> && descriptor !is AccessorForCallableDescriptor<*>) {
@@ -172,15 +182,32 @@ class SyntheticAccessorLowering(val context: JvmBackendContext) : FileLoweringPa
val call = val call =
if (isConstructor && expression is IrDelegatingConstructorCall) if (isConstructor && expression is IrDelegatingConstructorCall)
IrDelegatingConstructorCallImpl(expression.startOffset, expression.endOffset, accessorForIr as ClassConstructorDescriptor) IrDelegatingConstructorCallImpl(
else IrCallImpl(expression.startOffset, expression.endOffset, accessorForIr, emptyMap(), expression.origin/*TODO super*/) expression.startOffset,
expression.endOffset,
accessorForIr as ClassConstructorDescriptor
)
else IrCallImpl(
expression.startOffset,
expression.endOffset,
accessorForIr,
emptyMap(),
expression.origin/*TODO super*/
)
//copyAllArgsToValueParams(call, expression) //copyAllArgsToValueParams(call, expression)
val receiverAndArgs = expression.receiverAndArgs() val receiverAndArgs = expression.receiverAndArgs()
receiverAndArgs.forEachIndexed { i, irExpression -> receiverAndArgs.forEachIndexed { i, irExpression ->
call.putValueArgument(i, irExpression) call.putValueArgument(i, irExpression)
} }
if (isConstructor) { 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 return call
} }
@@ -188,12 +215,21 @@ class SyntheticAccessorLowering(val context: JvmBackendContext) : FileLoweringPa
return superResult 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) return if (isConstructor)
(accessor as AccessorForConstructorDescriptor).constructorDescriptorWithMarker( (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) { fun addAccessorToClass(accessor: AccessorForCallableDescriptor<*>, irClassToAddAccessor: IrClass, context: JvmBackendContext) {
@@ -203,7 +239,8 @@ class SyntheticAccessorLowering(val context: JvmBackendContext) : FileLoweringPa
val accessorForIr = accessorToIrAccessorDescriptor( val accessorForIr = accessorToIrAccessorDescriptor(
isConstructor, accessor, context, isConstructor, accessor, context,
accessor.calleeDescriptor as? FunctionDescriptor ?: return, accessor.calleeDescriptor as? FunctionDescriptor ?: return,
accessorOwner) accessorOwner
)
val syntheticFunction = if (isConstructor) IrConstructorImpl( val syntheticFunction = if (isConstructor) IrConstructorImpl(
UNDEFINED_OFFSET, UNDEFINED_OFFSET, JvmLoweredDeclarationOrigin.SYNTHETIC_ACCESSOR, UNDEFINED_OFFSET, UNDEFINED_OFFSET, JvmLoweredDeclarationOrigin.SYNTHETIC_ACCESSOR,
accessorForIr as ClassConstructorDescriptor, body accessorForIr as ClassConstructorDescriptor, body
@@ -255,15 +292,24 @@ class SyntheticAccessorLowering(val context: JvmBackendContext) : FileLoweringPa
var offset = 0 var offset = 0
val delegateTo = call.descriptor val delegateTo = call.descriptor
delegateTo.dispatchReceiverParameter?.let { 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 { 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.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
)
)
} }
} }
@@ -273,7 +319,26 @@ class SyntheticAccessorLowering(val context: JvmBackendContext) : FileLoweringPa
DescriptorUtils.getReceiverParameterType(extensionReceiverParameter), DescriptorUtils.getReceiverParameterType(extensionReceiverParameter),
dispatchReceiverParameter, dispatchReceiverParameter,
emptyList()/*TODO*/, 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.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, calleeDescriptor.returnType,
Modality.FINAL, Modality.FINAL,
Visibilities.LOCAL Visibilities.LOCAL