IR: enhancements in default parameter extension
- simplify argument count - refactoring - inner class support
This commit is contained in:
committed by
vvlevchenko
parent
fca160d09d
commit
2a6450446d
+1
-1
@@ -31,7 +31,7 @@ internal class KonanLower(val context: Context) {
|
|||||||
VarargInjectionLowering(context).runOnFilePostfix(irFile)
|
VarargInjectionLowering(context).runOnFilePostfix(irFile)
|
||||||
}
|
}
|
||||||
phaser.phase(KonanPhase.LOWER_DEFAULT_PARAMETER_EXTENT) {
|
phaser.phase(KonanPhase.LOWER_DEFAULT_PARAMETER_EXTENT) {
|
||||||
DefaultParameterStubGenerator(context).runOnFilePostfix(irFile)
|
DefaultArgumentStubGenerator(context).runOnFilePostfix(irFile)
|
||||||
DefaultParameterInjector(context).runOnFilePostfix(irFile)
|
DefaultParameterInjector(context).runOnFilePostfix(irFile)
|
||||||
}
|
}
|
||||||
phaser.phase(KonanPhase.LOWER_BUILTIN_OPERATORS) {
|
phaser.phase(KonanPhase.LOWER_BUILTIN_OPERATORS) {
|
||||||
|
|||||||
+1
-2
@@ -1,7 +1,6 @@
|
|||||||
package org.jetbrains.kotlin.backend.konan.ir
|
package org.jetbrains.kotlin.backend.konan.ir
|
||||||
|
|
||||||
import org.jetbrains.kotlin.backend.konan.Context
|
import org.jetbrains.kotlin.backend.konan.Context
|
||||||
import org.jetbrains.kotlin.backend.konan.lower.DefaultParameterDescription
|
|
||||||
import org.jetbrains.kotlin.descriptors.FunctionDescriptor
|
import org.jetbrains.kotlin.descriptors.FunctionDescriptor
|
||||||
import org.jetbrains.kotlin.ir.declarations.IrModuleFragment
|
import org.jetbrains.kotlin.ir.declarations.IrModuleFragment
|
||||||
import org.jetbrains.kotlin.descriptors.PropertyDescriptor
|
import org.jetbrains.kotlin.descriptors.PropertyDescriptor
|
||||||
@@ -10,7 +9,7 @@ import org.jetbrains.kotlin.descriptors.PropertyDescriptor
|
|||||||
internal class Ir(val context: Context, val irModule: IrModuleFragment) {
|
internal class Ir(val context: Context, val irModule: IrModuleFragment) {
|
||||||
val propertiesWithBackingFields = mutableSetOf<PropertyDescriptor>()
|
val propertiesWithBackingFields = mutableSetOf<PropertyDescriptor>()
|
||||||
|
|
||||||
val defaultParameterDescriptions = mutableMapOf<FunctionDescriptor, DefaultParameterDescription>()
|
val defaultParameterDescriptorsCache = mutableMapOf<FunctionDescriptor, FunctionDescriptor>()
|
||||||
|
|
||||||
val originalModuleIndex = ModuleIndex(irModule)
|
val originalModuleIndex = ModuleIndex(irModule)
|
||||||
|
|
||||||
|
|||||||
+391
@@ -0,0 +1,391 @@
|
|||||||
|
package org.jetbrains.kotlin.backend.konan.lower
|
||||||
|
|
||||||
|
import org.jetbrains.kotlin.backend.common.BodyLoweringPass
|
||||||
|
import org.jetbrains.kotlin.backend.common.DeclarationContainerLoweringPass
|
||||||
|
import org.jetbrains.kotlin.backend.common.lower.createIrBuilder
|
||||||
|
import org.jetbrains.kotlin.backend.common.lower.irBlockBody
|
||||||
|
import org.jetbrains.kotlin.backend.konan.Context
|
||||||
|
import org.jetbrains.kotlin.backend.konan.KonanPlatform
|
||||||
|
import org.jetbrains.kotlin.backend.konan.ir.ir2string
|
||||||
|
import org.jetbrains.kotlin.builtins.KotlinBuiltIns
|
||||||
|
import org.jetbrains.kotlin.descriptors.*
|
||||||
|
import org.jetbrains.kotlin.descriptors.annotations.Annotations
|
||||||
|
import org.jetbrains.kotlin.descriptors.impl.ClassConstructorDescriptorImpl
|
||||||
|
import org.jetbrains.kotlin.descriptors.impl.SimpleFunctionDescriptorImpl
|
||||||
|
import org.jetbrains.kotlin.descriptors.impl.TypeParameterDescriptorImpl
|
||||||
|
import org.jetbrains.kotlin.descriptors.impl.ValueParameterDescriptorImpl
|
||||||
|
import org.jetbrains.kotlin.ir.IrElement
|
||||||
|
import org.jetbrains.kotlin.ir.builders.*
|
||||||
|
import org.jetbrains.kotlin.ir.declarations.IrDeclarationContainer
|
||||||
|
import org.jetbrains.kotlin.ir.declarations.IrDeclarationOriginImpl
|
||||||
|
import org.jetbrains.kotlin.ir.declarations.IrFunction
|
||||||
|
import org.jetbrains.kotlin.ir.declarations.impl.IrConstructorImpl
|
||||||
|
import org.jetbrains.kotlin.ir.declarations.impl.IrFunctionImpl
|
||||||
|
import org.jetbrains.kotlin.ir.expressions.*
|
||||||
|
import org.jetbrains.kotlin.ir.expressions.impl.*
|
||||||
|
import org.jetbrains.kotlin.ir.util.transformFlat
|
||||||
|
import org.jetbrains.kotlin.ir.visitors.IrElementTransformerVoid
|
||||||
|
import org.jetbrains.kotlin.ir.visitors.transformChildrenVoid
|
||||||
|
import org.jetbrains.kotlin.name.FqName
|
||||||
|
import org.jetbrains.kotlin.name.Name
|
||||||
|
import org.jetbrains.kotlin.resolve.DescriptorUtils
|
||||||
|
import org.jetbrains.kotlin.resolve.descriptorUtil.hasDefaultValue
|
||||||
|
import org.jetbrains.kotlin.types.KotlinType
|
||||||
|
import org.jetbrains.kotlin.utils.addToStdlib.singletonList
|
||||||
|
|
||||||
|
class DefaultArgumentStubGenerator internal constructor(val context: Context): DeclarationContainerLoweringPass {
|
||||||
|
override fun lower(irDeclarationContainer: IrDeclarationContainer) {
|
||||||
|
irDeclarationContainer.declarations.transformFlat { memberDeclaration ->
|
||||||
|
if (memberDeclaration is IrFunction)
|
||||||
|
lower(memberDeclaration)
|
||||||
|
else
|
||||||
|
null
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
object DECLARATION_ORIGIN_FUNCTION_FOR_DEFAULT_PARAMETER :
|
||||||
|
IrDeclarationOriginImpl("DEFAULT_PARAMETER_EXTENT")
|
||||||
|
|
||||||
|
private fun lower(irFunction: IrFunction): List<IrFunction> {
|
||||||
|
val functionDescriptor = irFunction.descriptor
|
||||||
|
|
||||||
|
if (hasNotDefaultParameters(functionDescriptor))
|
||||||
|
return irFunction.singletonList()
|
||||||
|
|
||||||
|
val bodies = functionDescriptor.valueParameters
|
||||||
|
.mapNotNull{irFunction.getDefault(it)}
|
||||||
|
|
||||||
|
|
||||||
|
log("detected ${functionDescriptor.name.asString()} has got #${bodies.size} default expressions")
|
||||||
|
functionDescriptor.overriddenDescriptors.forEach { context.log("DEFAULT-REPLACER: $it") }
|
||||||
|
if (bodies.isNotEmpty()) {
|
||||||
|
val descriptor = functionDescriptor.generateDefaultsDescription(context)
|
||||||
|
log("$functionDescriptor -> $descriptor")
|
||||||
|
val builder = context.createIrBuilder(descriptor)
|
||||||
|
val body = builder.irBlockBody(irFunction) {
|
||||||
|
val params = mutableListOf<VariableDescriptor>()
|
||||||
|
val variables = mutableMapOf<VariableDescriptor, VariableDescriptor>()
|
||||||
|
|
||||||
|
val newExtensionReceiver =
|
||||||
|
if (descriptor.extensionReceiverParameter == null) {
|
||||||
|
null
|
||||||
|
} else {
|
||||||
|
IrGetValueImpl(
|
||||||
|
startOffset = irFunction.startOffset,
|
||||||
|
endOffset = irFunction.endOffset,
|
||||||
|
descriptor = descriptor.extensionReceiverParameter!!,
|
||||||
|
origin = null
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
for (valueParameter in functionDescriptor.valueParameters) {
|
||||||
|
val parameterDescriptor = descriptor.valueParameters[valueParameter.index]
|
||||||
|
if (valueParameter.hasDefaultValue()) {
|
||||||
|
val variable = scope.createTemporaryVariable(
|
||||||
|
irExpression = nullConst(irFunction, valueParameter.type)!!,
|
||||||
|
isMutable = true)
|
||||||
|
val variableDescriptor = variable.descriptor
|
||||||
|
params.add(variableDescriptor)
|
||||||
|
+variable
|
||||||
|
val condition = irNotEquals(irCall(Helper.kIntAnd).apply {
|
||||||
|
dispatchReceiver = irGet(maskParameterDescriptor(descriptor))
|
||||||
|
putValueArgument(0, irInt(1 shl valueParameter.index))
|
||||||
|
}, irInt(0))
|
||||||
|
val expressionBody = getDefaultParameterExpressionBody(irFunction, valueParameter)
|
||||||
|
/* Use previously calculated values in next expression. */
|
||||||
|
expressionBody.expression.transformChildrenVoid(object:IrElementTransformerVoid() {
|
||||||
|
override fun visitGetValue(expression: IrGetValue): IrExpression {
|
||||||
|
if (expression.descriptor == functionDescriptor.extensionReceiverParameter)
|
||||||
|
return newExtensionReceiver!!
|
||||||
|
if (!variables.containsKey(expression.descriptor))
|
||||||
|
return expression
|
||||||
|
return irGet(variables[expression.descriptor] as VariableDescriptor)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
/* Mapping calculated values with its origin variables. */
|
||||||
|
variables.put(valueParameter, variableDescriptor)
|
||||||
|
+irIfThenElse(
|
||||||
|
type = KonanPlatform.builtIns.unitType,
|
||||||
|
condition = condition,
|
||||||
|
thenPart = irSetVar(variableDescriptor, expressionBody.expression),
|
||||||
|
elsePart = irSetVar(variableDescriptor, irGet(parameterDescriptor)))
|
||||||
|
} else {
|
||||||
|
params.add(parameterDescriptor)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (functionDescriptor is ClassConstructorDescriptor) {
|
||||||
|
+ irReturn(IrDelegatingConstructorCallImpl(
|
||||||
|
startOffset = irFunction.startOffset,
|
||||||
|
endOffset = irFunction.endOffset,
|
||||||
|
descriptor = functionDescriptor
|
||||||
|
).apply {
|
||||||
|
params.forEachIndexed { i, variable ->
|
||||||
|
putValueArgument(i, irGet(variable))
|
||||||
|
}
|
||||||
|
if (functionDescriptor.dispatchReceiverParameter != null) {
|
||||||
|
dispatchReceiver = irThis()
|
||||||
|
}
|
||||||
|
})
|
||||||
|
} else {
|
||||||
|
+irReturn(irCall(functionDescriptor).apply {
|
||||||
|
if (functionDescriptor.dispatchReceiverParameter != null) {
|
||||||
|
dispatchReceiver = irThis()
|
||||||
|
}
|
||||||
|
if (functionDescriptor.extensionReceiverParameter != null) {
|
||||||
|
extensionReceiver = newExtensionReceiver
|
||||||
|
}
|
||||||
|
params.forEachIndexed { i, variable ->
|
||||||
|
putValueArgument(i, irGet(variable))
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return if (functionDescriptor is ClassConstructorDescriptor)
|
||||||
|
listOf(irFunction, IrConstructorImpl(
|
||||||
|
startOffset = irFunction.startOffset,
|
||||||
|
endOffset = irFunction.endOffset,
|
||||||
|
descriptor = descriptor as ClassConstructorDescriptor,
|
||||||
|
origin = DECLARATION_ORIGIN_FUNCTION_FOR_DEFAULT_PARAMETER,
|
||||||
|
body = body))
|
||||||
|
else
|
||||||
|
listOf(irFunction, IrFunctionImpl(
|
||||||
|
startOffset = irFunction.startOffset,
|
||||||
|
endOffset = irFunction.endOffset,
|
||||||
|
descriptor = descriptor,
|
||||||
|
origin = DECLARATION_ORIGIN_FUNCTION_FOR_DEFAULT_PARAMETER,
|
||||||
|
body = body))
|
||||||
|
}
|
||||||
|
return irFunction.singletonList()
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
private fun log(msg:String) = context.log("DEFAULT-REPLACER: $msg")
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun getDefaultParameterExpressionBody(irFunction: IrFunction, valueParameter: ValueParameterDescriptor):IrExpressionBody {
|
||||||
|
return irFunction.getDefault(valueParameter) as? IrExpressionBody ?: TODO("FIXME!!!")
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun maskParameterDescriptor(descriptor: FunctionDescriptor) = descriptor.valueParameters.single { it.name == Helper.kParameterMaskName }
|
||||||
|
|
||||||
|
private fun markerParameterDescriptor(descriptor: FunctionDescriptor) = descriptor.valueParameters.single {it.name == Helper.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)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class DefaultParameterInjector internal constructor(val context: Context): BodyLoweringPass {
|
||||||
|
override fun lower(irBody: IrBody) {
|
||||||
|
|
||||||
|
irBody.transformChildrenVoid(object : IrElementTransformerVoid() {
|
||||||
|
override fun visitDelegatingConstructorCall(expression: IrDelegatingConstructorCall): IrExpression {
|
||||||
|
super.visitDelegatingConstructorCall(expression)
|
||||||
|
val descriptor = expression.descriptor
|
||||||
|
if (hasNotDefaultParameters(descriptor))
|
||||||
|
return expression
|
||||||
|
val argumentsCount = argumentCount(expression)
|
||||||
|
if (argumentsCount == descriptor.valueParameters.size)
|
||||||
|
return expression
|
||||||
|
val (desc, params) = parametersForCall(expression)
|
||||||
|
return IrDelegatingConstructorCallImpl(
|
||||||
|
startOffset = expression.startOffset,
|
||||||
|
endOffset = expression.endOffset,
|
||||||
|
descriptor = desc as ClassConstructorDescriptor)
|
||||||
|
.apply {
|
||||||
|
params.forEach {
|
||||||
|
log("call::params@${it.first.index}/${it.first.name.asString()}: ${ir2string(it.second)}")
|
||||||
|
putValueArgument(it.first.index, it.second)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun visitCall(expression: IrCall): IrExpression {
|
||||||
|
super.visitCall(expression)
|
||||||
|
val functionDescriptor = expression.descriptor as FunctionDescriptor
|
||||||
|
|
||||||
|
if (hasNotDefaultParameters(functionDescriptor))
|
||||||
|
return expression
|
||||||
|
|
||||||
|
val argumentsCount = argumentCount(expression)
|
||||||
|
if (argumentsCount == functionDescriptor.valueParameters.size)
|
||||||
|
return expression
|
||||||
|
val (descriptor, params) = parametersForCall(expression)
|
||||||
|
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,
|
||||||
|
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<FunctionDescriptor, List<Pair<ValueParameterDescriptor, IrExpression?>>> {
|
||||||
|
val descriptor = expression.descriptor as FunctionDescriptor
|
||||||
|
val keyDescriptor = if (DescriptorUtils.isOverride(descriptor))
|
||||||
|
DescriptorUtils.getAllOverriddenDescriptors(descriptor).first()
|
||||||
|
else
|
||||||
|
descriptor.original
|
||||||
|
val realDescriptor = keyDescriptor.generateDefaultsDescription(context)
|
||||||
|
|
||||||
|
log("$descriptor -> $realDescriptor")
|
||||||
|
var maskValue = 0
|
||||||
|
val params = mutableListOf<Pair<ValueParameterDescriptor, IrExpression?>>()
|
||||||
|
params.addAll(descriptor.valueParameters.mapIndexed { i, _ ->
|
||||||
|
val valueArgument = expression.getValueArgument(i)
|
||||||
|
if (valueArgument == null) maskValue = maskValue or (1 shl i)
|
||||||
|
val valueParameterDescriptor = realDescriptor.valueParameters[i]
|
||||||
|
val pair = valueParameterDescriptor to (valueArgument ?: nullConst(expression, valueParameterDescriptor.type))
|
||||||
|
return@mapIndexed pair
|
||||||
|
})
|
||||||
|
params += maskParameterDescriptor(realDescriptor) to IrConstImpl<Int>(
|
||||||
|
startOffset = irBody.startOffset,
|
||||||
|
endOffset = irBody.endOffset,
|
||||||
|
type = KonanPlatform.builtIns.intType,
|
||||||
|
kind = IrConstKind.Int,
|
||||||
|
value = maskValue)
|
||||||
|
if (expression.descriptor is ClassConstructorDescriptor) {
|
||||||
|
params += markerParameterDescriptor(realDescriptor) to IrGetObjectValueImpl(
|
||||||
|
irBody.startOffset,
|
||||||
|
irBody.endOffset,
|
||||||
|
Helper.kDefaultArgumentMarkerClassDescriptor.defaultType,
|
||||||
|
Helper.kDefaultArgumentMarkerClassDescriptor)
|
||||||
|
}
|
||||||
|
params.forEach {
|
||||||
|
log("descriptor::${realDescriptor.name.asString()}#${it.first.index}: ${it.first.name.asString()}")
|
||||||
|
}
|
||||||
|
return Pair(realDescriptor, params)
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun argumentCount(expression: IrMemberAccessExpression) =
|
||||||
|
expression.descriptor.valueParameters.count { expression.getValueArgument(it) != null }
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun log(msg: String) = context.log("DEFAULT-INJECTOR: $msg")
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun hasNotDefaultParameters(descriptor: CallableDescriptor) = descriptor.valueParameters.none { it.hasDefaultValue() }
|
||||||
|
|
||||||
|
|
||||||
|
private fun FunctionDescriptor.generateDefaultsDescription(context: Context): FunctionDescriptor {
|
||||||
|
return context.ir.defaultParameterDescriptorsCache.getOrPut(this) {
|
||||||
|
val descriptor = when (this) {
|
||||||
|
is ClassConstructorDescriptor ->
|
||||||
|
ClassConstructorDescriptorImpl.create(
|
||||||
|
/* containingDeclaration = */ containingDeclaration,
|
||||||
|
/* annotations = */ annotations,
|
||||||
|
/* isPrimary = */ false,
|
||||||
|
/* source = */ SourceElement.NO_SOURCE)
|
||||||
|
is FunctionDescriptor -> {
|
||||||
|
val name = Name.identifier("$name\$default")
|
||||||
|
|
||||||
|
SimpleFunctionDescriptorImpl.create(
|
||||||
|
/* containingDeclaration = */ if (DescriptorUtils.isOverride(this)) this.overriddenDescriptors.first().containingDeclaration as ClassDescriptor else containingDeclaration,
|
||||||
|
/* annotations = */ annotations,
|
||||||
|
/* name = */ name,
|
||||||
|
/* kind = */ CallableMemberDescriptor.Kind.SYNTHESIZED,
|
||||||
|
/* source = */ SourceElement.NO_SOURCE)
|
||||||
|
}
|
||||||
|
else -> TODO("FIXME: $this")
|
||||||
|
}
|
||||||
|
|
||||||
|
val syntheticParameters = mutableListOf(valueParameter(descriptor, valueParameters.size, Helper.kParameterMaskName, KonanPlatform.builtIns.intType))
|
||||||
|
if (this is ClassConstructorDescriptor) {
|
||||||
|
syntheticParameters += valueParameter(descriptor, syntheticParameters.last().index + 1,
|
||||||
|
Helper.kConstructorMarkerName,
|
||||||
|
Helper.kDefaultArgumentMarkerClassDescriptor.defaultType)
|
||||||
|
}
|
||||||
|
descriptor.initialize(
|
||||||
|
/* receiverParameterType = */ extensionReceiverParameter?.type,
|
||||||
|
/* dispatchReceiverParameter = */ dispatchReceiverParameter,
|
||||||
|
/* typeParameters = */ typeParameters.map {
|
||||||
|
TypeParameterDescriptorImpl.createForFurtherModification(
|
||||||
|
/* containingDeclaration = */ descriptor,
|
||||||
|
/* annotations = */ it.annotations,
|
||||||
|
/* reified = */ it.isReified,
|
||||||
|
/* variance = */ it.variance,
|
||||||
|
/* name = */ it.name,
|
||||||
|
/* index = */ it.index,
|
||||||
|
/* source = */ it.source,
|
||||||
|
/* reportCycleError = */ null,
|
||||||
|
/* supertypeLoopsChecker = */ SupertypeLoopChecker.EMPTY
|
||||||
|
).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)
|
||||||
|
context.log("adds to cache[$this] = $descriptor")
|
||||||
|
descriptor
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
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
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
internal object Helper {
|
||||||
|
val kIntDesctiptor = DescriptorUtils.getClassDescriptorForType(KonanPlatform.builtIns.intType)
|
||||||
|
val kIntAnd = DescriptorUtils.getFunctionByName(kIntDesctiptor.unsubstitutedMemberScope, Name.identifier("and"))
|
||||||
|
|
||||||
|
val kKonanInternalPackageDescriptor = KonanPlatform.builtIns.builtInsModule.getPackage(FqName("konan.internal"))
|
||||||
|
val kDefaultArgumentMarkerName = Name.identifier("DefaultArgumentMarker")
|
||||||
|
val kParameterMaskName = Name.identifier("__\$mask\$__")
|
||||||
|
val kConstructorMarkerName = Name.identifier("__\$marker\$__")
|
||||||
|
val kDefaultArgumentMarkerClassDescriptor = DescriptorUtils.getAllDescriptors(kKonanInternalPackageDescriptor.memberScope)
|
||||||
|
.first{ it is ClassDescriptor && it.name == kDefaultArgumentMarkerName} as ClassDescriptor
|
||||||
|
}
|
||||||
-379
@@ -1,379 +0,0 @@
|
|||||||
package org.jetbrains.kotlin.backend.konan.lower
|
|
||||||
|
|
||||||
import org.jetbrains.kotlin.backend.common.BodyLoweringPass
|
|
||||||
import org.jetbrains.kotlin.backend.common.DeclarationContainerLoweringPass
|
|
||||||
import org.jetbrains.kotlin.backend.common.lower.createIrBuilder
|
|
||||||
import org.jetbrains.kotlin.backend.common.lower.irBlockBody
|
|
||||||
import org.jetbrains.kotlin.backend.konan.Context
|
|
||||||
import org.jetbrains.kotlin.backend.konan.KonanPlatform
|
|
||||||
import org.jetbrains.kotlin.backend.konan.ir.ir2string
|
|
||||||
import org.jetbrains.kotlin.builtins.KotlinBuiltIns
|
|
||||||
import org.jetbrains.kotlin.descriptors.*
|
|
||||||
import org.jetbrains.kotlin.descriptors.annotations.Annotations
|
|
||||||
import org.jetbrains.kotlin.descriptors.impl.ClassConstructorDescriptorImpl
|
|
||||||
import org.jetbrains.kotlin.descriptors.impl.SimpleFunctionDescriptorImpl
|
|
||||||
import org.jetbrains.kotlin.descriptors.impl.ValueParameterDescriptorImpl
|
|
||||||
import org.jetbrains.kotlin.ir.IrElement
|
|
||||||
import org.jetbrains.kotlin.ir.builders.*
|
|
||||||
import org.jetbrains.kotlin.ir.declarations.IrDeclarationContainer
|
|
||||||
import org.jetbrains.kotlin.ir.declarations.IrDeclarationOriginImpl
|
|
||||||
import org.jetbrains.kotlin.ir.declarations.IrFunction
|
|
||||||
import org.jetbrains.kotlin.ir.declarations.impl.IrFunctionImpl
|
|
||||||
import org.jetbrains.kotlin.ir.expressions.*
|
|
||||||
import org.jetbrains.kotlin.ir.expressions.impl.IrCallImpl
|
|
||||||
import org.jetbrains.kotlin.ir.expressions.impl.IrConstImpl
|
|
||||||
import org.jetbrains.kotlin.ir.expressions.impl.IrDelegatingConstructorCallImpl
|
|
||||||
import org.jetbrains.kotlin.ir.expressions.impl.IrGetValueImpl
|
|
||||||
import org.jetbrains.kotlin.ir.util.transformFlat
|
|
||||||
import org.jetbrains.kotlin.ir.visitors.IrElementTransformerVoid
|
|
||||||
import org.jetbrains.kotlin.ir.visitors.IrElementVisitorVoid
|
|
||||||
import org.jetbrains.kotlin.ir.visitors.acceptChildrenVoid
|
|
||||||
import org.jetbrains.kotlin.ir.visitors.transformChildrenVoid
|
|
||||||
import org.jetbrains.kotlin.name.Name
|
|
||||||
import org.jetbrains.kotlin.resolve.DescriptorUtils
|
|
||||||
import org.jetbrains.kotlin.resolve.descriptorUtil.hasDefaultValue
|
|
||||||
import org.jetbrains.kotlin.types.KotlinType
|
|
||||||
import org.jetbrains.kotlin.utils.addToStdlib.singletonList
|
|
||||||
|
|
||||||
class DefaultParameterStubGenerator internal constructor(val context: Context): DeclarationContainerLoweringPass {
|
|
||||||
override fun lower(irDeclarationContainer: IrDeclarationContainer) {
|
|
||||||
irDeclarationContainer.declarations.transformFlat { memberDeclaration ->
|
|
||||||
if (memberDeclaration is IrFunction)
|
|
||||||
lower(memberDeclaration)
|
|
||||||
else
|
|
||||||
null
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
object DECLARATION_ORIGIN_FUNCTION_FOR_DEFAULT_PARAMETER :
|
|
||||||
IrDeclarationOriginImpl("DEFAULT_PARAMETER_EXTENT")
|
|
||||||
|
|
||||||
private fun lower(irFunction: IrFunction): List<IrFunction> {
|
|
||||||
val bodies = mutableListOf<IrExpressionBody>()
|
|
||||||
val functionDescriptor = irFunction.descriptor
|
|
||||||
|
|
||||||
if (hasNotDefaultParameters(functionDescriptor))
|
|
||||||
return irFunction.singletonList()
|
|
||||||
|
|
||||||
irFunction.acceptChildrenVoid(object:IrElementVisitorVoid{
|
|
||||||
override fun visitExpressionBody(body: IrExpressionBody) {
|
|
||||||
bodies.add(body)
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun visitElement(element: IrElement) {
|
|
||||||
element.acceptChildrenVoid(this)
|
|
||||||
}
|
|
||||||
})
|
|
||||||
|
|
||||||
log("detected ${functionDescriptor.name.asString()} has got #${bodies.size} default expressions")
|
|
||||||
functionDescriptor.overriddenDescriptors.forEach { context.log("DEFAULT-REPLACER: $it") }
|
|
||||||
if (bodies.isNotEmpty()) {
|
|
||||||
val description = functionDescriptor.getOrCreateDefaultsDescription(context)
|
|
||||||
val builder = context.createIrBuilder(description.function)
|
|
||||||
val body = builder.irBlockBody(irFunction) {
|
|
||||||
val params = mutableListOf<VariableDescriptor>()
|
|
||||||
val variables = mutableMapOf<VariableDescriptor, VariableDescriptor>()
|
|
||||||
|
|
||||||
val newExtensionReceiver =
|
|
||||||
if (description.function.extensionReceiverParameter == null) {
|
|
||||||
null
|
|
||||||
} else {
|
|
||||||
IrGetValueImpl(
|
|
||||||
startOffset = irFunction.startOffset,
|
|
||||||
endOffset = irFunction.endOffset,
|
|
||||||
descriptor = description.function.extensionReceiverParameter!!,
|
|
||||||
origin = null
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
for (valueParameter in functionDescriptor.valueParameters) {
|
|
||||||
val parameterDescriptor = description.function.valueParameters[valueParameter.index]
|
|
||||||
if (valueParameter.hasDefaultValue()) {
|
|
||||||
val variable = scope.createTemporaryVariable(
|
|
||||||
irExpression = nullConst(valueParameter.type)!!,
|
|
||||||
isMutable = true)
|
|
||||||
val variableDescriptor = variable.descriptor
|
|
||||||
params.add(variableDescriptor)
|
|
||||||
+variable
|
|
||||||
val condition = irNotEquals(irCall(intAnd).apply {
|
|
||||||
dispatchReceiver = irGet(description.mask)
|
|
||||||
putValueArgument(0, irInt(1 shl valueParameter.index))
|
|
||||||
}, irInt(0))
|
|
||||||
val exprBody = getDefaultParameterExpressionBody(irFunction, valueParameter)
|
|
||||||
/* Use previously calculated values in next expression. */
|
|
||||||
exprBody.expression.transformChildrenVoid(object:IrElementTransformerVoid() {
|
|
||||||
override fun visitGetValue(expression: IrGetValue): IrExpression {
|
|
||||||
if (expression.descriptor == functionDescriptor.extensionReceiverParameter)
|
|
||||||
return newExtensionReceiver!!
|
|
||||||
if (!variables.containsKey(expression.descriptor))
|
|
||||||
return expression
|
|
||||||
return irGet(variables[expression.descriptor] as VariableDescriptor)
|
|
||||||
}
|
|
||||||
})
|
|
||||||
/* Mapping calculated values with its origin variables. */
|
|
||||||
variables.put(valueParameter, variableDescriptor)
|
|
||||||
+irIfThenElse(
|
|
||||||
type = KonanPlatform.builtIns.unitType,
|
|
||||||
condition = condition,
|
|
||||||
thenPart = irSetVar(variableDescriptor, exprBody.expression),
|
|
||||||
elsePart = irSetVar(variableDescriptor, irGet(parameterDescriptor)))
|
|
||||||
} else {
|
|
||||||
params.add(parameterDescriptor)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (functionDescriptor !is ClassConstructorDescriptor) {
|
|
||||||
+irReturn(irCall(functionDescriptor).apply {
|
|
||||||
if (functionDescriptor.dispatchReceiverParameter != null) {
|
|
||||||
dispatchReceiver = irThis()
|
|
||||||
}
|
|
||||||
if (functionDescriptor.extensionReceiverParameter != null) {
|
|
||||||
extensionReceiver = newExtensionReceiver
|
|
||||||
}
|
|
||||||
params.forEachIndexed { i, variable ->
|
|
||||||
putValueArgument(i, irGet(variable))
|
|
||||||
}
|
|
||||||
})
|
|
||||||
} else {
|
|
||||||
+ irReturn(IrDelegatingConstructorCallImpl(
|
|
||||||
startOffset = irFunction.startOffset,
|
|
||||||
endOffset = irFunction.endOffset,
|
|
||||||
descriptor = functionDescriptor
|
|
||||||
).apply {
|
|
||||||
params.forEachIndexed { i, variable ->
|
|
||||||
putValueArgument(i, irGet(variable))
|
|
||||||
}
|
|
||||||
})
|
|
||||||
}
|
|
||||||
}
|
|
||||||
// TODO: replace irFunction with new one without expression bodies.
|
|
||||||
return listOf(irFunction, IrFunctionImpl(
|
|
||||||
irFunction.startOffset,
|
|
||||||
irFunction.endOffset,
|
|
||||||
DECLARATION_ORIGIN_FUNCTION_FOR_DEFAULT_PARAMETER,
|
|
||||||
description.function, body))
|
|
||||||
}
|
|
||||||
return irFunction.singletonList()
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun log(msg:String) = context.log("DEFAULT-REPLACER: $msg")
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun getDefaultParameterExpressionBody(irFunction: IrFunction, valueParameter: ValueParameterDescriptor):IrExpressionBody {
|
|
||||||
return irFunction.getDefault(valueParameter) as? IrExpressionBody ?: TODO("FIXME!!!")
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun nullConst(type: KotlinType): IrExpression? {
|
|
||||||
when {
|
|
||||||
KotlinBuiltIns.isFloat(type) -> return IrConstImpl<Float> (0, 0, type, IrConstKind.Float, 0.0F)
|
|
||||||
KotlinBuiltIns.isDouble(type) -> return IrConstImpl<Double> (0, 0, type, IrConstKind.Double, 0.0)
|
|
||||||
KotlinBuiltIns.isBoolean(type) -> return IrConstImpl<Boolean> (0, 0, type, IrConstKind.Boolean, false)
|
|
||||||
KotlinBuiltIns.isByte(type) -> return IrConstImpl<Byte> (0, 0, type, IrConstKind.Byte, 0)
|
|
||||||
KotlinBuiltIns.isShort(type) -> return IrConstImpl<Short> (0, 0, type, IrConstKind.Short, 0)
|
|
||||||
KotlinBuiltIns.isInt(type) -> return IrConstImpl<Int> (0, 0, type, IrConstKind.Int, 0)
|
|
||||||
KotlinBuiltIns.isLong(type) -> return IrConstImpl<Long> (0, 0, type, IrConstKind.Long, 0)
|
|
||||||
else -> return IrConstImpl<Nothing?>(0, 0, type, IrConstKind.Null, null)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
class DefaultParameterInjector internal constructor(val context: Context): BodyLoweringPass {
|
|
||||||
override fun lower(irBody: IrBody) {
|
|
||||||
irBody.transformChildrenVoid(object : IrElementTransformerVoid() {
|
|
||||||
override fun visitDelegatingConstructorCall(expression: IrDelegatingConstructorCall): IrExpression {
|
|
||||||
super.visitDelegatingConstructorCall(expression)
|
|
||||||
val descriptor = expression.descriptor
|
|
||||||
if (hasNotDefaultParameters(descriptor))
|
|
||||||
return expression
|
|
||||||
val argumentsCount = argumentCount(expression)
|
|
||||||
if (argumentsCount == descriptor.valueParameters.size)
|
|
||||||
return expression
|
|
||||||
val (desc, params) = parametersForCall(expression)
|
|
||||||
return IrDelegatingConstructorCallImpl(
|
|
||||||
startOffset = irBody.startOffset,
|
|
||||||
endOffset = irBody.endOffset,
|
|
||||||
descriptor = desc.function as ClassConstructorDescriptor)
|
|
||||||
.apply {
|
|
||||||
params.forEach {
|
|
||||||
log("call::params@${it.first.index}/${it.first.name.asString()}: ${ir2string(it.second)}")
|
|
||||||
putValueArgument(it.first.index, it.second)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun visitCall(expression: IrCall): IrExpression {
|
|
||||||
super.visitCall(expression)
|
|
||||||
val functionDescriptor = expression.descriptor as FunctionDescriptor
|
|
||||||
|
|
||||||
if (hasNotDefaultParameters(functionDescriptor))
|
|
||||||
return expression
|
|
||||||
|
|
||||||
val argumentsCount = argumentCount(expression)
|
|
||||||
if (argumentsCount == functionDescriptor.valueParameters.size)
|
|
||||||
return expression
|
|
||||||
val (desc, params) = parametersForCall(expression)
|
|
||||||
return IrCallImpl(
|
|
||||||
startOffset = irBody.startOffset,
|
|
||||||
endOffset = irBody.endOffset,
|
|
||||||
type = desc.function.returnType!!,
|
|
||||||
descriptor = desc.function,
|
|
||||||
typeArguments = null)
|
|
||||||
.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<DefaultParameterDescription, List<Pair<ValueParameterDescriptor, IrExpression?>>> {
|
|
||||||
var maskValue = 0
|
|
||||||
val rawDescriptor = expression.descriptor as FunctionDescriptor
|
|
||||||
val descriptor = rawDescriptor.overriddenDescriptors.firstOrNull()?:rawDescriptor
|
|
||||||
val desc = descriptor.getOrCreateDefaultsDescription(context)
|
|
||||||
descriptor.valueParameters.forEach {
|
|
||||||
log("descriptor::${descriptor.name.asString()}#${it.index}: ${it.name.asString()}")
|
|
||||||
}
|
|
||||||
val params = descriptor.valueParameters.mapIndexed { i, _ ->
|
|
||||||
val valueArgument = expression.getValueArgument(i)
|
|
||||||
if (valueArgument == null) maskValue = maskValue or (1 shl i)
|
|
||||||
val valueParameterDescriptor = desc.function.valueParameters[i]
|
|
||||||
val pair = valueParameterDescriptor to (valueArgument ?: nullConst(valueParameterDescriptor.type))
|
|
||||||
return@mapIndexed pair
|
|
||||||
} + (desc.mask to IrConstImpl<Int>(
|
|
||||||
startOffset = irBody.startOffset,
|
|
||||||
endOffset = irBody.endOffset,
|
|
||||||
type = KonanPlatform.builtIns.intType,
|
|
||||||
kind = IrConstKind.Int,
|
|
||||||
value = maskValue))
|
|
||||||
params.forEach {
|
|
||||||
log("descriptor::${desc.function.name.asString()}#${it.first.index}: ${it.first.name.asString()}")
|
|
||||||
}
|
|
||||||
return Pair(desc, params)
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun argumentCount(expression: IrMemberAccessExpression): Int {
|
|
||||||
var argumentsCount = 0
|
|
||||||
expression.acceptChildrenVoid(object : IrElementVisitorVoid {
|
|
||||||
override fun visitElement(element: IrElement) {
|
|
||||||
argumentsCount++
|
|
||||||
}
|
|
||||||
})
|
|
||||||
val descriptor = expression.descriptor
|
|
||||||
if (descriptor !is ConstructorDescriptor && (descriptor.dispatchReceiverParameter != null || descriptor.extensionReceiverParameter != null))
|
|
||||||
argumentsCount--
|
|
||||||
return argumentsCount
|
|
||||||
}
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun log(msg: String) = context.log("DEFAULT-INJECTOR: $msg")
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun hasNotDefaultParameters(descriptor: CallableDescriptor) = descriptor.valueParameters.none { it.hasDefaultValue() }
|
|
||||||
|
|
||||||
val intDesctiptor = DescriptorUtils.getClassDescriptorForType(KonanPlatform.builtIns.intType)
|
|
||||||
val intAnd = DescriptorUtils.getFunctionByName(intDesctiptor.unsubstitutedMemberScope, Name.identifier("and"))
|
|
||||||
|
|
||||||
data class DefaultParameterDescription(val function: FunctionDescriptor, val mask:ValueParameterDescriptor,
|
|
||||||
val hasExtensionReceiver:Boolean, val hasDispatchReceiver: Boolean)
|
|
||||||
|
|
||||||
private fun FunctionDescriptor.getOrCreateDefaultsDescription(context: Context): DefaultParameterDescription {
|
|
||||||
return context.ir.defaultParameterDescriptions.getOrPut(this) {
|
|
||||||
this.generateDefaultsDescription(context)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun FunctionDescriptor.generateDefaultsDescription(context: Context): DefaultParameterDescription {
|
|
||||||
val descriptor = when (this){
|
|
||||||
is ConstructorDescriptor -> DefaultParameterClassConstructorDescriptor(
|
|
||||||
containingDeclaration = this.containingDeclaration as ClassDescriptor,
|
|
||||||
annotations = annotations,
|
|
||||||
original = null,
|
|
||||||
isPrimary = false,
|
|
||||||
source = SourceElement.NO_SOURCE,
|
|
||||||
kind = CallableMemberDescriptor.Kind.SYNTHESIZED)
|
|
||||||
|
|
||||||
is FunctionDescriptor -> SimpleFunctionDescriptorImpl.create(
|
|
||||||
/* containingDeclaration = */ this.containingDeclaration,
|
|
||||||
/* annotations = */ Annotations.EMPTY,
|
|
||||||
/* name = */ name,
|
|
||||||
/* kind = */ CallableMemberDescriptor.Kind.SYNTHESIZED,
|
|
||||||
/* source = */ SourceElement.NO_SOURCE)
|
|
||||||
else -> TODO("FIXME!!!")
|
|
||||||
}
|
|
||||||
|
|
||||||
val parameterList = mutableListOf<ValueParameterDescriptor>()
|
|
||||||
|
|
||||||
val maskVariable = valueParameter(descriptor, valueParameters.size , "__\$mask\$__", KonanPlatform.builtIns.intType)
|
|
||||||
|
|
||||||
parameterList += valueParameters.map{
|
|
||||||
ValueParameterDescriptorImpl(
|
|
||||||
containingDeclaration = it.containingDeclaration,
|
|
||||||
original = it.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)
|
|
||||||
}
|
|
||||||
|
|
||||||
parameterList.add(maskVariable)
|
|
||||||
descriptor.initialize(
|
|
||||||
/* receiverParameterType = */ extensionReceiverParameter?.type,
|
|
||||||
/* dispatchReceiverParameter = */ dispatchReceiverParameter,
|
|
||||||
/* typeParameters = */ typeParameters,
|
|
||||||
/* unsubstitutedValueParameters = */ parameterList,
|
|
||||||
/* unsubstitutedReturnType = */ returnType,
|
|
||||||
/* modality = */ Modality.FINAL,
|
|
||||||
/* visibility = */ this.visibility)
|
|
||||||
return DefaultParameterDescription(
|
|
||||||
function = descriptor,
|
|
||||||
mask = maskVariable,
|
|
||||||
hasDispatchReceiver = (extensionReceiverParameter != null),
|
|
||||||
hasExtensionReceiver = (dispatchReceiverParameter != null))
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun valueParameter(descriptor: FunctionDescriptor, index: Int, name: String, type: KotlinType):ValueParameterDescriptor {
|
|
||||||
return ValueParameterDescriptorImpl(
|
|
||||||
containingDeclaration = descriptor,
|
|
||||||
original = null,
|
|
||||||
index = index,
|
|
||||||
annotations = Annotations.EMPTY,
|
|
||||||
name = Name.identifier(name),
|
|
||||||
outType = type,
|
|
||||||
declaresDefaultValue = false,
|
|
||||||
isCrossinline = false,
|
|
||||||
isNoinline = false,
|
|
||||||
varargElementType = null,
|
|
||||||
source = SourceElement.NO_SOURCE
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* This descriptor overrides name property, for class constructor : instead of <init> -> <init>$defeult symbol.
|
|
||||||
*/
|
|
||||||
class DefaultParameterClassConstructorDescriptor(
|
|
||||||
containingDeclaration: ClassDescriptor,
|
|
||||||
original: ConstructorDescriptor?,
|
|
||||||
annotations: Annotations,
|
|
||||||
isPrimary: Boolean,
|
|
||||||
kind: CallableMemberDescriptor.Kind,
|
|
||||||
source: SourceElement
|
|
||||||
) : ClassConstructorDescriptorImpl(containingDeclaration, original, annotations, isPrimary, kind, source) {
|
|
||||||
|
|
||||||
override fun getName(): Name {
|
|
||||||
return Name.identifier("${super.getName().asString()}\$default")
|
|
||||||
}
|
|
||||||
}
|
|
||||||
Reference in New Issue
Block a user