Minor: reformat code in InlineCodegen

This commit is contained in:
Dmitry Petrov
2018-03-15 12:54:28 +03:00
parent c86e157a48
commit 7be4f5d31f
@@ -51,12 +51,12 @@ import org.jetbrains.org.objectweb.asm.tree.*
import java.util.* import java.util.*
import kotlin.collections.HashSet import kotlin.collections.HashSet
abstract class InlineCodegen<out T: BaseExpressionCodegen>( abstract class InlineCodegen<out T : BaseExpressionCodegen>(
protected val codegen: T, protected val codegen: T,
protected val state: GenerationState, protected val state: GenerationState,
function: FunctionDescriptor, function: FunctionDescriptor,
private val typeParameterMappings: TypeParameterMappings, private val typeParameterMappings: TypeParameterMappings,
protected val sourceCompiler: SourceCompilerForInline protected val sourceCompiler: SourceCompilerForInline
) { ) {
init { init {
assert(InlineUtil.isInline(function) || InlineUtil.isArrayConstructorWithLambda(function)) { assert(InlineUtil.isInline(function) || InlineUtil.isArrayConstructorWithLambda(function)) {
@@ -74,10 +74,10 @@ abstract class InlineCodegen<out T: BaseExpressionCodegen>(
private val reifiedTypeInliner = ReifiedTypeInliner(typeParameterMappings) private val reifiedTypeInliner = ReifiedTypeInliner(typeParameterMappings)
protected val functionDescriptor: FunctionDescriptor = protected val functionDescriptor: FunctionDescriptor =
if (InlineUtil.isArrayConstructorWithLambda(function)) if (InlineUtil.isArrayConstructorWithLambda(function))
FictitiousArrayConstructor.create(function as ConstructorDescriptor) FictitiousArrayConstructor.create(function as ConstructorDescriptor)
else else
function.original function.original
protected val jvmSignature: JvmMethodGenericSignature protected val jvmSignature: JvmMethodGenericSignature
@@ -116,17 +116,17 @@ abstract class InlineCodegen<out T: BaseExpressionCodegen>(
protected fun throwCompilationException( protected fun throwCompilationException(
nodeAndSmap: SMAPAndMethodNode?, e: Exception, generateNodeText: Boolean nodeAndSmap: SMAPAndMethodNode?, e: Exception, generateNodeText: Boolean
): CompilationException { ): CompilationException {
val contextDescriptor = sourceCompiler.compilationContextDescriptor val contextDescriptor = sourceCompiler.compilationContextDescriptor
val element = DescriptorToSourceUtils.descriptorToDeclaration(contextDescriptor) val element = DescriptorToSourceUtils.descriptorToDeclaration(contextDescriptor)
val node = nodeAndSmap?.node val node = nodeAndSmap?.node
throw CompilationException( throw CompilationException(
"Couldn't inline method call '" + functionDescriptor.name + "' into\n" + "Couldn't inline method call '" + functionDescriptor.name + "' into\n" +
DescriptorRenderer.DEBUG_TEXT.render(contextDescriptor) + "\n" + DescriptorRenderer.DEBUG_TEXT.render(contextDescriptor) + "\n" +
(element?.text ?: "<no source>") + (element?.text ?: "<no source>") +
if (generateNodeText) "\nCause: " + node.nodeText else "", if (generateNodeText) "\nCause: " + node.nodeText else "",
e, sourceCompiler.callElement as? PsiElement e, sourceCompiler.callElement as? PsiElement
) )
} }
@@ -148,22 +148,19 @@ abstract class InlineCodegen<out T: BaseExpressionCodegen>(
} }
fun performInline( fun performInline(
typeArguments: Map<TypeParameterDescriptor, KotlinType>?, typeArguments: Map<TypeParameterDescriptor, KotlinType>?,
callDefault: Boolean, callDefault: Boolean,
codegen: BaseExpressionCodegen codegen: BaseExpressionCodegen
) { ) {
var nodeAndSmap: SMAPAndMethodNode? = null var nodeAndSmap: SMAPAndMethodNode? = null
try { try {
nodeAndSmap = createInlineMethodNode(functionDescriptor, jvmSignature, callDefault, typeArguments, state, sourceCompiler) nodeAndSmap = createInlineMethodNode(functionDescriptor, jvmSignature, callDefault, typeArguments, state, sourceCompiler)
endCall(inlineCall(nodeAndSmap, callDefault)) endCall(inlineCall(nodeAndSmap, callDefault))
} } catch (e: CompilationException) {
catch (e: CompilationException) {
throw e throw e
} } catch (e: InlineException) {
catch (e: InlineException) {
throw throwCompilationException(nodeAndSmap, e, false) throw throwCompilationException(nodeAndSmap, e, false)
} } catch (e: Exception) {
catch (e: Exception) {
throw throwCompilationException(nodeAndSmap, e, true) throw throwCompilationException(nodeAndSmap, e, true)
} }
} }
@@ -186,7 +183,7 @@ abstract class InlineCodegen<out T: BaseExpressionCodegen>(
if (methodNode.tryCatchBlocks.isNotEmpty()) return false if (methodNode.tryCatchBlocks.isNotEmpty()) return false
fun isBackwardJump(fromIndex: Int, toLabel: LabelNode) = fun isBackwardJump(fromIndex: Int, toLabel: LabelNode) =
methodNode.instructions.indexOf(toLabel) < fromIndex methodNode.instructions.indexOf(toLabel) < fromIndex
val insns = methodNode.instructions.toArray() val insns = methodNode.instructions.toArray()
for (i in insns.indices) { for (i in insns.indices) {
@@ -220,11 +217,13 @@ abstract class InlineCodegen<out T: BaseExpressionCodegen>(
val parentContext = codegen.context.parentContext val parentContext = codegen.context.parentContext
return if (parentContext is ClosureContext) { return if (parentContext is ClosureContext) {
val originalSuspendLambdaDescriptor = parentContext.originalSuspendLambdaDescriptor ?: error("No original lambda descriptor found") val originalSuspendLambdaDescriptor =
codegen.genCoroutineInstanceForSuspendLambda(originalSuspendLambdaDescriptor) ?: error("No stack value for coroutine instance of lambda found") parentContext.originalSuspendLambdaDescriptor ?: error("No original lambda descriptor found")
} codegen.genCoroutineInstanceForSuspendLambda(originalSuspendLambdaDescriptor)
else ?: error("No stack value for coroutine instance of lambda found")
codegen.getContinuationParameterFromEnclosingSuspendFunctionDescriptor(codegen.context.functionDescriptor) ?: error("No stack value for continuation parameter of suspend function") } else
codegen.getContinuationParameterFromEnclosingSuspendFunctionDescriptor(codegen.context.functionDescriptor)
?: error("No stack value for continuation parameter of suspend function")
} }
protected fun inlineCall(nodeAndSmap: SMAPAndMethodNode, callDefault: Boolean): InlineResult { protected fun inlineCall(nodeAndSmap: SMAPAndMethodNode, callDefault: Boolean): InlineResult {
@@ -233,8 +232,8 @@ abstract class InlineCodegen<out T: BaseExpressionCodegen>(
val node = nodeAndSmap.node val node = nodeAndSmap.node
if (callDefault) { if (callDefault) {
val defaultLambdas = expandMaskConditionsAndUpdateVariableNodes( val defaultLambdas = expandMaskConditionsAndUpdateVariableNodes(
node, maskStartIndex, maskValues, methodHandleInDefaultMethodIndex, node, maskStartIndex, maskValues, methodHandleInDefaultMethodIndex,
extractDefaultLambdaOffsetAndDescriptor(jvmSignature, functionDescriptor) extractDefaultLambdaOffsetAndDescriptor(jvmSignature, functionDescriptor)
) )
for (lambda in defaultLambdas) { for (lambda in defaultLambdas) {
invocationParamBuilder.buildParameters().getParameterByDeclarationSlot(lambda.offset).lambda = lambda invocationParamBuilder.buildParameters().getParameterByDeclarationSlot(lambda.offset).lambda = lambda
@@ -257,16 +256,16 @@ abstract class InlineCodegen<out T: BaseExpressionCodegen>(
val parameters = invocationParamBuilder.buildParameters() val parameters = invocationParamBuilder.buildParameters()
val info = RootInliningContext( val info = RootInliningContext(
expressionMap, state, codegen.inlineNameGenerator.subGenerator(jvmSignature.asmMethod.name), expressionMap, state, codegen.inlineNameGenerator.subGenerator(jvmSignature.asmMethod.name),
sourceCompiler, sourceCompiler.inlineCallSiteInfo, reifiedTypeInliner, typeParameterMappings sourceCompiler, sourceCompiler.inlineCallSiteInfo, reifiedTypeInliner, typeParameterMappings
) )
val inliner = MethodInliner( val inliner = MethodInliner(
node, parameters, info, FieldRemapper(null, null, parameters), isSameModule, node, parameters, info, FieldRemapper(null, null, parameters), isSameModule,
"Method inlining " + sourceCompiler.callElementText, "Method inlining " + sourceCompiler.callElementText,
createNestedSourceMapper(nodeAndSmap, defaultSourceMapper), info.callSiteInfo, createNestedSourceMapper(nodeAndSmap, defaultSourceMapper), info.callSiteInfo,
if (functionDescriptor.isInlineOnly()) InlineOnlySmapSkipper(codegen) else null, if (functionDescriptor.isInlineOnly()) InlineOnlySmapSkipper(codegen) else null,
!isInlinedToInlineFunInKotlinRuntime() !isInlinedToInlineFunInKotlinRuntime()
) //with captured ) //with captured
val remapper = LocalVarRemapper(parameters, initialFrameSize) val remapper = LocalVarRemapper(parameters, initialFrameSize)
@@ -282,7 +281,7 @@ abstract class InlineCodegen<out T: BaseExpressionCodegen>(
val infos = MethodInliner.processReturns(adapter, LabelOwner { labels.contains(it) }, true, null) val infos = MethodInliner.processReturns(adapter, LabelOwner { labels.contains(it) }, true, null)
sourceCompiler.generateAndInsertFinallyBlocks( sourceCompiler.generateAndInsertFinallyBlocks(
adapter, infos, (remapper.remap(parameters.argsSizeOnStack + 1).value as StackValue.Local).index adapter, infos, (remapper.remap(parameters.argsSizeOnStack + 1).value as StackValue.Local).index
) )
removeStaticInitializationTrigger(adapter) removeStaticInitializationTrigger(adapter)
if (!sourceCompiler.isFinallyMarkerRequired()) { if (!sourceCompiler.isFinallyMarkerRequired()) {
@@ -337,25 +336,27 @@ abstract class InlineCodegen<out T: BaseExpressionCodegen>(
val capturedParamInfoInLambda = activeLambda!!.capturedVars[capturedParamIndex] val capturedParamInfoInLambda = activeLambda!!.capturedVars[capturedParamIndex]
info = invocationParamBuilder.addCapturedParam(capturedParamInfoInLambda, capturedParamInfoInLambda.fieldName, false) info = invocationParamBuilder.addCapturedParam(capturedParamInfoInLambda, capturedParamInfoInLambda.fieldName, false)
info.setRemapValue(remappedValue) info.setRemapValue(remappedValue)
} } else {
else {
info = invocationParamBuilder.addNextValueParameter(jvmType, false, remappedValue, parameterIndex) info = invocationParamBuilder.addNextValueParameter(jvmType, false, remappedValue, parameterIndex)
} }
recordParameterValueInLocalVal( recordParameterValueInLocalVal(
false, false,
isDefaultParameter || kind === ValueKind.DEFAULT_LAMBDA_CAPTURED_PARAMETER, isDefaultParameter || kind === ValueKind.DEFAULT_LAMBDA_CAPTURED_PARAMETER,
info info
) )
} }
} }
protected fun recordParameterValueInLocalVal(delayedWritingToLocals: Boolean, skipStore: Boolean, vararg infos: ParameterInfo): Function0<Unit>? { protected fun recordParameterValueInLocalVal(
delayedWritingToLocals: Boolean,
skipStore: Boolean,
vararg infos: ParameterInfo
): Function0<Unit>? {
val index = IntArray(infos.size) { i -> val index = IntArray(infos.size) { i ->
if (!infos[i].isSkippedOrRemapped) { if (!infos[i].isSkippedOrRemapped) {
codegen.frameMap.enterTemp(infos[i].getType()) codegen.frameMap.enterTemp(infos[i].getType())
} } else -1
else -1
} }
val possibleLazyTask = { val possibleLazyTask = {
@@ -382,8 +383,7 @@ abstract class InlineCodegen<out T: BaseExpressionCodegen>(
private fun leaveTemps() { private fun leaveTemps() {
invocationParamBuilder.listAllParams().asReversed().forEach { invocationParamBuilder.listAllParams().asReversed().forEach { param ->
param ->
if (!param.isSkippedOrRemapped || CapturedParamInfo.isSynthetic(param)) { if (!param.isSkippedOrRemapped || CapturedParamInfo.isSynthetic(param)) {
codegen.frameMap.leaveTemp(param.type) codegen.frameMap.leaveTemp(param.type)
} }
@@ -403,13 +403,13 @@ abstract class InlineCodegen<out T: BaseExpressionCodegen>(
protected fun rememberCapturedForDefaultLambda(defaultLambda: DefaultLambda) { protected fun rememberCapturedForDefaultLambda(defaultLambda: DefaultLambda) {
for ((paramIndex, captured) in defaultLambda.capturedVars.withIndex()) { for ((paramIndex, captured) in defaultLambda.capturedVars.withIndex()) {
putArgumentOrCapturedToLocalVal( putArgumentOrCapturedToLocalVal(
JvmKotlinType(captured.type), JvmKotlinType(captured.type),
//HACK: actually parameter would be placed on stack in default function //HACK: actually parameter would be placed on stack in default function
// also see ValueKind.DEFAULT_LAMBDA_CAPTURED_PARAMETER check // also see ValueKind.DEFAULT_LAMBDA_CAPTURED_PARAMETER check
StackValue.onStack(captured.type), StackValue.onStack(captured.type),
paramIndex, paramIndex,
paramIndex, paramIndex,
ValueKind.DEFAULT_LAMBDA_CAPTURED_PARAMETER ValueKind.DEFAULT_LAMBDA_CAPTURED_PARAMETER
) )
defaultLambda.parameterOffsetsInDefault.add(invocationParamBuilder.nextParameterOffset) defaultLambda.parameterOffsetsInDefault.add(invocationParamBuilder.nextParameterOffset)
@@ -431,8 +431,7 @@ abstract class InlineCodegen<out T: BaseExpressionCodegen>(
if (it is CapturedParamInfo) 0 else it.type.size if (it is CapturedParamInfo) 0 else it.type.size
} }
} }
} } else {
else {
assert(constantValue == null) { "Additional method handle for default argument should be null, but " + constantValue!! } assert(constantValue == null) { "Additional method handle for default argument should be null, but " + constantValue!! }
methodHandleInDefaultMethodIndex = maskStartIndex + maskValues.size methodHandleInDefaultMethodIndex = maskStartIndex + maskValues.size
} }
@@ -453,20 +452,20 @@ abstract class InlineCodegen<out T: BaseExpressionCodegen>(
} }
internal fun createInlineMethodNode( internal fun createInlineMethodNode(
functionDescriptor: FunctionDescriptor, functionDescriptor: FunctionDescriptor,
jvmSignature: JvmMethodSignature, jvmSignature: JvmMethodSignature,
callDefault: Boolean, callDefault: Boolean,
typeArguments: Map<TypeParameterDescriptor, KotlinType>?, typeArguments: Map<TypeParameterDescriptor, KotlinType>?,
state: GenerationState, state: GenerationState,
sourceCompilerForInline: SourceCompilerForInline sourceCompilerForInline: SourceCompilerForInline
): SMAPAndMethodNode { ): SMAPAndMethodNode {
val languageVersionSettings = state.languageVersionSettings val languageVersionSettings = state.languageVersionSettings
when { when {
isSpecialEnumMethod(functionDescriptor) -> { isSpecialEnumMethod(functionDescriptor) -> {
val node = createSpecialEnumMethodBody( val node = createSpecialEnumMethodBody(
functionDescriptor.name.asString(), functionDescriptor.name.asString(),
typeArguments!!.keys.single().defaultType, typeArguments!!.keys.single().defaultType,
state.typeMapper state.typeMapper
) )
return SMAPAndMethodNode(node, SMAPParser.parseOrCreateDefault(null, null, "fake", -1, -1)) return SMAPAndMethodNode(node, SMAPParser.parseOrCreateDefault(null, null, "fake", -1, -1))
} }
@@ -507,10 +506,11 @@ abstract class InlineCodegen<out T: BaseExpressionCodegen>(
return sourceCompilerForInline.doCreateMethodNodeFromSource(functionDescriptor, jvmSignature, callDefault, asmMethod) return sourceCompilerForInline.doCreateMethodNodeFromSource(functionDescriptor, jvmSignature, callDefault, asmMethod)
} }
val resultInCache = state.inlineCache.methodNodeById.getOrPut(methodId val resultInCache = state.inlineCache.methodNodeById.getOrPut(
methodId
) { ) {
doCreateMethodNodeFromCompiled(directMember, state, asmMethod) doCreateMethodNodeFromCompiled(directMember, state, asmMethod)
?: throw IllegalStateException("Couldn't obtain compiled function body for " + functionDescriptor) ?: throw IllegalStateException("Couldn't obtain compiled function body for " + functionDescriptor)
} }
return resultInCache.copyWithNewNode(cloneMethodNode(resultInCache.node)) return resultInCache.copyWithNewNode(cloneMethodNode(resultInCache.node))
@@ -524,15 +524,15 @@ abstract class InlineCodegen<out T: BaseExpressionCodegen>(
private fun cloneMethodNode(methodNode: MethodNode): MethodNode { private fun cloneMethodNode(methodNode: MethodNode): MethodNode {
methodNode.instructions.resetLabels() methodNode.instructions.resetLabels()
return MethodNode( return MethodNode(
API, methodNode.access, methodNode.name, methodNode.desc, methodNode.signature, API, methodNode.access, methodNode.name, methodNode.desc, methodNode.signature,
ArrayUtil.toStringArray(methodNode.exceptions) ArrayUtil.toStringArray(methodNode.exceptions)
).also(methodNode::accept) ).also(methodNode::accept)
} }
private fun doCreateMethodNodeFromCompiled( private fun doCreateMethodNodeFromCompiled(
callableDescriptor: CallableMemberDescriptor, callableDescriptor: CallableMemberDescriptor,
state: GenerationState, state: GenerationState,
asmMethod: Method asmMethod: Method
): SMAPAndMethodNode? { ): SMAPAndMethodNode? {
if (isBuiltInArrayIntrinsic(callableDescriptor)) { if (isBuiltInArrayIntrinsic(callableDescriptor)) {
val classId = classId val classId = classId
@@ -542,16 +542,18 @@ abstract class InlineCodegen<out T: BaseExpressionCodegen>(
assert(callableDescriptor is DeserializedCallableMemberDescriptor) { "Not a deserialized function or proper: " + callableDescriptor } assert(callableDescriptor is DeserializedCallableMemberDescriptor) { "Not a deserialized function or proper: " + callableDescriptor }
val containingClasses = KotlinTypeMapper.getContainingClassesForDeserializedCallable(callableDescriptor as DeserializedCallableMemberDescriptor) val containingClasses =
KotlinTypeMapper.getContainingClassesForDeserializedCallable(callableDescriptor as DeserializedCallableMemberDescriptor)
val containerId = containingClasses.implClassId val containerId = containingClasses.implClassId
val bytes = state.inlineCache.classBytes.getOrPut(containerId) { val bytes = state.inlineCache.classBytes.getOrPut(containerId) {
findVirtualFile(state, containerId)?.contentsToByteArray() ?: findVirtualFile(state, containerId)?.contentsToByteArray()
throw IllegalStateException("Couldn't find declaration file for " + containerId) ?: throw IllegalStateException("Couldn't find declaration file for " + containerId)
} }
val methodNode = getMethodNode(bytes, asmMethod.name, asmMethod.descriptor, AsmUtil.asmTypeByClassId(containerId)) ?: return null val methodNode =
getMethodNode(bytes, asmMethod.name, asmMethod.descriptor, AsmUtil.asmTypeByClassId(containerId)) ?: return null
// KLUDGE: Inline suspend function built with compiler version less than 1.1.4/1.2-M1 did not contain proper // KLUDGE: Inline suspend function built with compiler version less than 1.1.4/1.2-M1 did not contain proper
// before/after suspension point marks, so we detect those functions here and insert the corresponding marks // before/after suspension point marks, so we detect those functions here and insert the corresponding marks
@@ -576,8 +578,7 @@ abstract class InlineCodegen<out T: BaseExpressionCodegen>(
val clinitTriggerCall = insn val clinitTriggerCall = insn
insn = insn.next insn = insn.next
insnList.remove(clinitTriggerCall) insnList.remove(clinitTriggerCall)
} } else {
else {
insn = insn.next insn = insn.next
} }
} }
@@ -607,8 +608,8 @@ abstract class InlineCodegen<out T: BaseExpressionCodegen>(
val varDescriptor = field.descriptor val varDescriptor = field.descriptor
//check that variable is inline function parameter //check that variable is inline function parameter
return !(varDescriptor is ParameterDescriptor && return !(varDescriptor is ParameterDescriptor &&
InlineUtil.isInlineParameter(varDescriptor) && InlineUtil.isInlineParameter(varDescriptor) &&
InlineUtil.isInline(varDescriptor.containingDeclaration)) InlineUtil.isInline(varDescriptor.containingDeclaration))
} }
return true return true
@@ -645,18 +646,18 @@ val BaseExpressionCodegen.v: InstructionAdapter
get() = visitor get() = visitor
class PsiInlineCodegen( class PsiInlineCodegen(
codegen: ExpressionCodegen, codegen: ExpressionCodegen,
state: GenerationState, state: GenerationState,
function: FunctionDescriptor, function: FunctionDescriptor,
typeParameterMappings: TypeParameterMappings, typeParameterMappings: TypeParameterMappings,
sourceCompiler: SourceCompilerForInline sourceCompiler: SourceCompilerForInline
) : InlineCodegen<ExpressionCodegen>(codegen, state, function, typeParameterMappings, sourceCompiler), CallGenerator { ) : InlineCodegen<ExpressionCodegen>(codegen, state, function, typeParameterMappings, sourceCompiler), CallGenerator {
override fun genCallInner( override fun genCallInner(
callableMethod: Callable, callableMethod: Callable,
resolvedCall: ResolvedCall<*>?, resolvedCall: ResolvedCall<*>?,
callDefault: Boolean, callDefault: Boolean,
codegen: ExpressionCodegen codegen: ExpressionCodegen
) { ) {
if (!state.globalInlineContext.enterIntoInlining(resolvedCall)) { if (!state.globalInlineContext.enterIntoInlining(resolvedCall)) {
generateStub(resolvedCall, codegen) generateStub(resolvedCall, codegen)
@@ -712,10 +713,10 @@ class PsiInlineCodegen(
} }
override fun genValueAndPut( override fun genValueAndPut(
valueParameterDescriptor: ValueParameterDescriptor, valueParameterDescriptor: ValueParameterDescriptor,
argumentExpression: KtExpression, argumentExpression: KtExpression,
parameterType: Type, parameterType: Type,
parameterIndex: Int parameterIndex: Int
) { ) {
if (isInliningParameter(argumentExpression, valueParameterDescriptor)) { if (isInliningParameter(argumentExpression, valueParameterDescriptor)) {
val lambdaInfo = rememberClosure(argumentExpression, parameterType, valueParameterDescriptor) val lambdaInfo = rememberClosure(argumentExpression, parameterType, valueParameterDescriptor)
@@ -728,8 +729,7 @@ class PsiInlineCodegen(
StackValue.coercion(receiver, receiver.type.boxReceiverForBoundReference(), null) StackValue.coercion(receiver, receiver.type.boxReceiverForBoundReference(), null)
) )
} }
} } else {
else {
val value = codegen.gen(argumentExpression) val value = codegen.gen(argumentExpression)
putValueIfNeeded( putValueIfNeeded(
JvmKotlinType(parameterType, valueParameterDescriptor.original.type), JvmKotlinType(parameterType, valueParameterDescriptor.original.type),
@@ -745,7 +745,7 @@ class PsiInlineCodegen(
assert(isInlinableParameterExpression(ktLambda)) { "Couldn't find inline expression in ${expression.text}" } assert(isInlinableParameterExpression(ktLambda)) { "Couldn't find inline expression in ${expression.text}" }
return PsiExpressionLambda( return PsiExpressionLambda(
ktLambda!!, typeMapper, parameter.isCrossinline, getBoundCallableReferenceReceiver(expression) != null ktLambda!!, typeMapper, parameter.isCrossinline, getBoundCallableReferenceReceiver(expression) != null
).also { lambda -> ).also { lambda ->
val closureInfo = invocationParamBuilder.addNextValueParameter(type, true, null, parameter.index) val closureInfo = invocationParamBuilder.addNextValueParameter(type, true, null, parameter.index)
closureInfo.lambda = lambda closureInfo.lambda = lambda