Proper param propagation in inline
This commit is contained in:
@@ -21,7 +21,7 @@ import org.jetbrains.kotlin.utils.mapToIndex
|
|||||||
import org.jetbrains.org.objectweb.asm.Type
|
import org.jetbrains.org.objectweb.asm.Type
|
||||||
import java.util.*
|
import java.util.*
|
||||||
|
|
||||||
private class ArgumentAndIndex(val arg: ResolvedValueArgument, val declIndex: Int, var type: Type? = null, var reoder: Boolean = false, var tempValue: StackValue? = null)
|
class ArgumentAndIndex(val arg: ResolvedValueArgument, val declIndex: Int, var type: Type? = null, var reorder: Boolean = false, var tempValue: StackValue? = null)
|
||||||
|
|
||||||
abstract class ArgumentGenerator {
|
abstract class ArgumentGenerator {
|
||||||
/**
|
/**
|
||||||
@@ -78,26 +78,12 @@ abstract class ArgumentGenerator {
|
|||||||
|
|
||||||
if (actualIndex != declIndex || orderChanged) {
|
if (actualIndex != declIndex || orderChanged) {
|
||||||
orderChanged = true
|
orderChanged = true
|
||||||
argumentWithDeclIndex.reoder = true
|
argumentWithDeclIndex.reorder = true
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
val mark = codegen.myFrameMap.mark()
|
reorderArgumentsIfNeeded(actualArgsWithDeclIndex)
|
||||||
actualArgsWithDeclIndex.reversed().forEach {
|
|
||||||
if (it.reoder) {
|
|
||||||
val type = it.type!!
|
|
||||||
it.tempValue = StackValue.local(codegen.frameMap.enterTemp(type), type)
|
|
||||||
it.tempValue?.store(StackValue.onStack(type), codegen.v)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
actualArgsWithDeclIndex.sortedBy { it.declIndex }.forEach {
|
|
||||||
it.tempValue?.let {
|
|
||||||
it.put(it.type, codegen.v)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
mark.dropTo()
|
|
||||||
return masks
|
return masks
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -116,4 +102,8 @@ abstract class ArgumentGenerator {
|
|||||||
protected open fun generateOther(i: Int, argument: ResolvedValueArgument): Type {
|
protected open fun generateOther(i: Int, argument: ResolvedValueArgument): Type {
|
||||||
throw UnsupportedOperationException("Unsupported value argument #$i: $argument")
|
throw UnsupportedOperationException("Unsupported value argument #$i: $argument")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
protected open fun reorderArgumentsIfNeeded(args: ArrayList<ArgumentAndIndex>) {
|
||||||
|
throw UnsupportedOperationException("Unsupported operation")
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -23,6 +23,7 @@ import org.jetbrains.kotlin.psi.ValueArgument;
|
|||||||
import org.jetbrains.kotlin.resolve.calls.model.*;
|
import org.jetbrains.kotlin.resolve.calls.model.*;
|
||||||
import org.jetbrains.org.objectweb.asm.Type;
|
import org.jetbrains.org.objectweb.asm.Type;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
import static org.jetbrains.kotlin.codegen.AsmUtil.pushDefaultValueOnStack;
|
import static org.jetbrains.kotlin.codegen.AsmUtil.pushDefaultValueOnStack;
|
||||||
@@ -72,7 +73,7 @@ public class CallBasedArgumentGenerator extends ArgumentGenerator {
|
|||||||
assert valueArgument != null;
|
assert valueArgument != null;
|
||||||
JetExpression argumentExpression = valueArgument.getArgumentExpression();
|
JetExpression argumentExpression = valueArgument.getArgumentExpression();
|
||||||
assert argumentExpression != null : valueArgument.asElement().getText();
|
assert argumentExpression != null : valueArgument.asElement().getText();
|
||||||
callGenerator.genValueAndPut(parameter, argumentExpression, type);
|
callGenerator.genValueAndPut(parameter, argumentExpression, type, i);
|
||||||
return type;
|
return type;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -82,7 +83,7 @@ public class CallBasedArgumentGenerator extends ArgumentGenerator {
|
|||||||
ValueParameterDescriptor parameter = valueParameters.get(i);
|
ValueParameterDescriptor parameter = valueParameters.get(i);
|
||||||
Type type = valueParameterTypes.get(i);
|
Type type = valueParameterTypes.get(i);
|
||||||
pushDefaultValueOnStack(type, codegen.v);
|
pushDefaultValueOnStack(type, codegen.v);
|
||||||
callGenerator.afterParameterPut(type, null, parameter);
|
callGenerator.afterParameterPut(type, null, parameter, i);
|
||||||
return type;
|
return type;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -92,7 +93,12 @@ public class CallBasedArgumentGenerator extends ArgumentGenerator {
|
|||||||
ValueParameterDescriptor parameter = valueParameters.get(i);
|
ValueParameterDescriptor parameter = valueParameters.get(i);
|
||||||
Type type = valueParameterTypes.get(i);
|
Type type = valueParameterTypes.get(i);
|
||||||
codegen.genVarargs(argument, parameter.getType());
|
codegen.genVarargs(argument, parameter.getType());
|
||||||
callGenerator.afterParameterPut(type, null, parameter);
|
callGenerator.afterParameterPut(type, null, parameter, i);
|
||||||
return type;
|
return type;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void reorderArgumentsIfNeeded(@NotNull ArrayList<ArgumentAndIndex> actualArgsWithDeclIndex) {
|
||||||
|
callGenerator.reorderArgumentsIfNeeded(actualArgsWithDeclIndex);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,124 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright 2010-2015 JetBrains s.r.o.
|
|
||||||
*
|
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
||||||
* you may not use this file except in compliance with the License.
|
|
||||||
* You may obtain a copy of the License at
|
|
||||||
*
|
|
||||||
* http://www.apache.org/licenses/LICENSE-2.0
|
|
||||||
*
|
|
||||||
* Unless required by applicable law or agreed to in writing, software
|
|
||||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
||||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
||||||
* See the License for the specific language governing permissions and
|
|
||||||
* limitations under the License.
|
|
||||||
*/
|
|
||||||
|
|
||||||
package org.jetbrains.kotlin.codegen;
|
|
||||||
|
|
||||||
import org.jetbrains.annotations.NotNull;
|
|
||||||
import org.jetbrains.annotations.Nullable;
|
|
||||||
import org.jetbrains.kotlin.descriptors.ValueParameterDescriptor;
|
|
||||||
import org.jetbrains.kotlin.psi.JetExpression;
|
|
||||||
import org.jetbrains.kotlin.resolve.calls.model.ResolvedCall;
|
|
||||||
import org.jetbrains.org.objectweb.asm.Type;
|
|
||||||
|
|
||||||
public abstract class CallGenerator {
|
|
||||||
|
|
||||||
static class DefaultCallGenerator extends CallGenerator {
|
|
||||||
|
|
||||||
private final ExpressionCodegen codegen;
|
|
||||||
|
|
||||||
public DefaultCallGenerator(ExpressionCodegen codegen) {
|
|
||||||
this.codegen = codegen;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void genCallInner(
|
|
||||||
@NotNull Callable callableMethod,
|
|
||||||
ResolvedCall<?> resolvedCall,
|
|
||||||
boolean callDefault,
|
|
||||||
@NotNull ExpressionCodegen codegen
|
|
||||||
) {
|
|
||||||
if (!callDefault) {
|
|
||||||
callableMethod.genInvokeInstruction(codegen.v);
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
((CallableMethod)callableMethod).genInvokeDefaultInstruction(codegen.v);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void genCallWithoutAssertions(
|
|
||||||
@NotNull CallableMethod method, @NotNull ExpressionCodegen codegen
|
|
||||||
) {
|
|
||||||
method.genInvokeInstruction(codegen.v);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void afterParameterPut(@NotNull Type type, StackValue stackValue, @NotNull ValueParameterDescriptor valueParameterDescriptor) {
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void putHiddenParams() {
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void genValueAndPut(
|
|
||||||
@NotNull ValueParameterDescriptor valueParameterDescriptor,
|
|
||||||
@NotNull JetExpression argumentExpression,
|
|
||||||
@NotNull Type parameterType
|
|
||||||
) {
|
|
||||||
StackValue value = codegen.gen(argumentExpression);
|
|
||||||
value.put(parameterType, codegen.v);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void putCapturedValueOnStack(
|
|
||||||
@NotNull StackValue stackValue, @NotNull Type valueType, int paramIndex
|
|
||||||
) {
|
|
||||||
stackValue.put(stackValue.type, codegen.v);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void putValueIfNeeded(
|
|
||||||
@Nullable ValueParameterDescriptor valueParameterDescriptor, @NotNull Type parameterType, @NotNull StackValue value
|
|
||||||
) {
|
|
||||||
value.put(value.type, codegen.v);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public void genCall(@NotNull Callable callableMethod, @Nullable ResolvedCall<?> resolvedCall, boolean callDefault, @NotNull ExpressionCodegen codegen) {
|
|
||||||
if (resolvedCall != null) {
|
|
||||||
JetExpression calleeExpression = resolvedCall.getCall().getCalleeExpression();
|
|
||||||
if (calleeExpression != null) {
|
|
||||||
codegen.markStartLineNumber(calleeExpression);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
genCallInner(callableMethod, resolvedCall, callDefault, codegen);
|
|
||||||
}
|
|
||||||
|
|
||||||
public abstract void genCallInner(@NotNull Callable callableMethod, @Nullable ResolvedCall<?> resolvedCall, boolean callDefault, @NotNull ExpressionCodegen codegen);
|
|
||||||
|
|
||||||
public abstract void genCallWithoutAssertions(@NotNull CallableMethod callableMethod, @NotNull ExpressionCodegen codegen);
|
|
||||||
|
|
||||||
public abstract void afterParameterPut(@NotNull Type type, StackValue stackValue, @NotNull ValueParameterDescriptor valueParameterDescriptor);
|
|
||||||
|
|
||||||
public abstract void genValueAndPut(
|
|
||||||
@NotNull ValueParameterDescriptor valueParameterDescriptor,
|
|
||||||
@NotNull JetExpression argumentExpression,
|
|
||||||
@NotNull Type parameterType
|
|
||||||
);
|
|
||||||
|
|
||||||
public abstract void putValueIfNeeded(@Nullable ValueParameterDescriptor valueParameterDescriptor, @NotNull Type parameterType, @NotNull StackValue value);
|
|
||||||
|
|
||||||
public abstract void putCapturedValueOnStack(
|
|
||||||
@NotNull StackValue stackValue,
|
|
||||||
@NotNull Type valueType, int paramIndex
|
|
||||||
);
|
|
||||||
|
|
||||||
public abstract void putHiddenParams();
|
|
||||||
}
|
|
||||||
@@ -0,0 +1,138 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2010-2015 JetBrains s.r.o.
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package org.jetbrains.kotlin.codegen
|
||||||
|
|
||||||
|
import org.jetbrains.kotlin.descriptors.ValueParameterDescriptor
|
||||||
|
import org.jetbrains.kotlin.psi.JetExpression
|
||||||
|
import org.jetbrains.kotlin.resolve.calls.model.ResolvedCall
|
||||||
|
import org.jetbrains.org.objectweb.asm.Type
|
||||||
|
|
||||||
|
import java.util.ArrayList
|
||||||
|
|
||||||
|
abstract class CallGenerator {
|
||||||
|
|
||||||
|
internal class DefaultCallGenerator(private val codegen: ExpressionCodegen) : CallGenerator() {
|
||||||
|
|
||||||
|
override fun genCallInner(
|
||||||
|
callableMethod: Callable,
|
||||||
|
resolvedCall: ResolvedCall<*>?,
|
||||||
|
callDefault: Boolean,
|
||||||
|
codegen: ExpressionCodegen) {
|
||||||
|
if (!callDefault) {
|
||||||
|
callableMethod.genInvokeInstruction(codegen.v)
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
(callableMethod as CallableMethod).genInvokeDefaultInstruction(codegen.v)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun genCallWithoutAssertions(
|
||||||
|
method: CallableMethod, codegen: ExpressionCodegen) {
|
||||||
|
method.genInvokeInstruction(codegen.v)
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun afterParameterPut(
|
||||||
|
type: Type,
|
||||||
|
stackValue: StackValue?,
|
||||||
|
valueParameterDescriptor: ValueParameterDescriptor,
|
||||||
|
parameterIndex: Int) {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun putHiddenParams() {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun genValueAndPut(
|
||||||
|
valueParameterDescriptor: ValueParameterDescriptor,
|
||||||
|
argumentExpression: JetExpression,
|
||||||
|
parameterType: Type,
|
||||||
|
index: Int) {
|
||||||
|
val value = codegen.gen(argumentExpression)
|
||||||
|
value.put(parameterType, codegen.v)
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun putCapturedValueOnStack(
|
||||||
|
stackValue: StackValue, valueType: Type, paramIndex: Int) {
|
||||||
|
stackValue.put(stackValue.type, codegen.v)
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun putValueIfNeeded(
|
||||||
|
valueParameterDescriptor: ValueParameterDescriptor?, parameterType: Type, value: StackValue) {
|
||||||
|
value.put(value.type, codegen.v)
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun reorderArgumentsIfNeeded(actualArgsWithDeclIndex: ArrayList<ArgumentAndIndex>) {
|
||||||
|
val mark = codegen.myFrameMap.mark()
|
||||||
|
actualArgsWithDeclIndex.reversed().forEach {
|
||||||
|
if (it.reorder) {
|
||||||
|
val type = it.type!!
|
||||||
|
it.tempValue = StackValue.local(codegen.frameMap.enterTemp(type), type)
|
||||||
|
it.tempValue?.store(StackValue.onStack(type), codegen.v)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
actualArgsWithDeclIndex.sortedBy { it.declIndex }.forEach {
|
||||||
|
it.tempValue?.let {
|
||||||
|
it.put(it.type, codegen.v)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
mark.dropTo()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fun genCall(callableMethod: Callable, resolvedCall: ResolvedCall<*>?, callDefault: Boolean, codegen: ExpressionCodegen) {
|
||||||
|
if (resolvedCall != null) {
|
||||||
|
val calleeExpression = resolvedCall.call.calleeExpression
|
||||||
|
if (calleeExpression != null) {
|
||||||
|
codegen.markStartLineNumber(calleeExpression)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
genCallInner(callableMethod, resolvedCall, callDefault, codegen)
|
||||||
|
}
|
||||||
|
|
||||||
|
abstract fun genCallInner(callableMethod: Callable, resolvedCall: ResolvedCall<*>?, callDefault: Boolean, codegen: ExpressionCodegen)
|
||||||
|
|
||||||
|
abstract fun genCallWithoutAssertions(callableMethod: CallableMethod, codegen: ExpressionCodegen)
|
||||||
|
|
||||||
|
abstract fun afterParameterPut(
|
||||||
|
type: Type,
|
||||||
|
stackValue: StackValue?,
|
||||||
|
valueParameterDescriptor: ValueParameterDescriptor,
|
||||||
|
parameterIndex: Int)
|
||||||
|
|
||||||
|
abstract fun genValueAndPut(
|
||||||
|
valueParameterDescriptor: ValueParameterDescriptor,
|
||||||
|
argumentExpression: JetExpression,
|
||||||
|
parameterType: Type,
|
||||||
|
parameterIndex: Int)
|
||||||
|
|
||||||
|
abstract fun putValueIfNeeded(
|
||||||
|
valueParameterDescriptor: ValueParameterDescriptor?,
|
||||||
|
parameterType: Type,
|
||||||
|
value: StackValue)
|
||||||
|
|
||||||
|
abstract fun putCapturedValueOnStack(
|
||||||
|
stackValue: StackValue,
|
||||||
|
valueType: Type, paramIndex: Int)
|
||||||
|
|
||||||
|
abstract fun putHiddenParams()
|
||||||
|
|
||||||
|
abstract fun reorderArgumentsIfNeeded(actualArgsWithDeclIndex: ArrayList<ArgumentAndIndex>)
|
||||||
|
}
|
||||||
@@ -1669,6 +1669,11 @@ public class ImplementationBodyCodegen extends ClassBodyCodegen {
|
|||||||
offset += type.getSize();
|
offset += type.getSize();
|
||||||
return type;
|
return type;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void reorderArgumentsIfNeeded(@NotNull ArrayList<ArgumentAndIndex> args) {
|
||||||
|
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void generateEnumEntries() {
|
private void generateEnumEntries() {
|
||||||
|
|||||||
@@ -38,13 +38,13 @@ public class CapturedParamInfo extends ParameterInfo {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public CapturedParamInfo(@NotNull CapturedParamDesc desc, @NotNull String newFieldName, boolean skipped, int index, int remapIndex) {
|
public CapturedParamInfo(@NotNull CapturedParamDesc desc, @NotNull String newFieldName, boolean skipped, int index, int remapIndex) {
|
||||||
super(desc.getType(), skipped, index, remapIndex);
|
super(desc.getType(), skipped, index, remapIndex, index);
|
||||||
this.desc = desc;
|
this.desc = desc;
|
||||||
this.newFieldName = newFieldName;
|
this.newFieldName = newFieldName;
|
||||||
}
|
}
|
||||||
|
|
||||||
public CapturedParamInfo(@NotNull CapturedParamDesc desc, @NotNull String newFieldName, boolean skipped, int index, StackValue remapIndex) {
|
public CapturedParamInfo(@NotNull CapturedParamDesc desc, @NotNull String newFieldName, boolean skipped, int index, StackValue remapIndex) {
|
||||||
super(desc.getType(), skipped, index, remapIndex);
|
super(desc.getType(), skipped, index, remapIndex, index);
|
||||||
this.desc = desc;
|
this.desc = desc;
|
||||||
this.newFieldName = newFieldName;
|
this.newFieldName = newFieldName;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -410,14 +410,20 @@ public class InlineCodegen extends CallGenerator {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void afterParameterPut(@NotNull Type type, @Nullable StackValue stackValue, @Nullable ValueParameterDescriptor valueParameterDescriptor) {
|
public void afterParameterPut(
|
||||||
putArgumentOrCapturedToLocalVal(type, stackValue, -1);
|
@NotNull Type type,
|
||||||
|
@Nullable StackValue stackValue,
|
||||||
|
@Nullable ValueParameterDescriptor valueParameterDescriptor,
|
||||||
|
int parameterIndex
|
||||||
|
) {
|
||||||
|
putArgumentOrCapturedToLocalVal(type, stackValue, -1, parameterIndex);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void putArgumentOrCapturedToLocalVal(
|
private void putArgumentOrCapturedToLocalVal(
|
||||||
@NotNull Type type,
|
@NotNull Type type,
|
||||||
@Nullable StackValue stackValue,
|
@Nullable StackValue stackValue,
|
||||||
int capturedParamIndex
|
int capturedParamIndex,
|
||||||
|
int parameterIndex
|
||||||
) {
|
) {
|
||||||
if (!asFunctionInline && Type.VOID_TYPE != type) {
|
if (!asFunctionInline && Type.VOID_TYPE != type) {
|
||||||
//TODO remap only inlinable closure => otherwise we could get a lot of problem
|
//TODO remap only inlinable closure => otherwise we could get a lot of problem
|
||||||
@@ -431,7 +437,7 @@ public class InlineCodegen extends CallGenerator {
|
|||||||
info.setRemapValue(remappedIndex);
|
info.setRemapValue(remappedIndex);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
info = invocationParamBuilder.addNextParameter(type, false, remappedIndex);
|
info = invocationParamBuilder.addNextValueParameter(type, false, remappedIndex, parameterIndex);
|
||||||
}
|
}
|
||||||
|
|
||||||
recordParameterValueInLocalVal(info);
|
recordParameterValueInLocalVal(info);
|
||||||
@@ -513,6 +519,7 @@ public class InlineCodegen extends CallGenerator {
|
|||||||
invocationParamBuilder.addNextParameter(param.getAsmType(), false, null);
|
invocationParamBuilder.addNextParameter(param.getAsmType(), false, null);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
invocationParamBuilder.markValueParametesStart();
|
||||||
List<ParameterInfo> infos = invocationParamBuilder.listNotCaptured();
|
List<ParameterInfo> infos = invocationParamBuilder.listNotCaptured();
|
||||||
recordParameterValueInLocalVal(infos.toArray(new ParameterInfo[infos.size()]));
|
recordParameterValueInLocalVal(infos.toArray(new ParameterInfo[infos.size()]));
|
||||||
}
|
}
|
||||||
@@ -542,13 +549,13 @@ public class InlineCodegen extends CallGenerator {
|
|||||||
deparenthesized instanceof JetCallableReferenceExpression;
|
deparenthesized instanceof JetCallableReferenceExpression;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void rememberClosure(JetExpression expression, Type type) {
|
public void rememberClosure(JetExpression expression, Type type, int parameterIndex) {
|
||||||
JetExpression lambda = JetPsiUtil.deparenthesize(expression);
|
JetExpression lambda = JetPsiUtil.deparenthesize(expression);
|
||||||
assert isInlinableParameterExpression(lambda) : "Couldn't find inline expression in " + expression.getText();
|
assert isInlinableParameterExpression(lambda) : "Couldn't find inline expression in " + expression.getText();
|
||||||
|
|
||||||
LambdaInfo info = new LambdaInfo(lambda, typeMapper);
|
LambdaInfo info = new LambdaInfo(lambda, typeMapper);
|
||||||
|
|
||||||
ParameterInfo closureInfo = invocationParamBuilder.addNextParameter(type, true, null);
|
ParameterInfo closureInfo = invocationParamBuilder.addNextValueParameter(type, true, null, parameterIndex);
|
||||||
closureInfo.setLambda(info);
|
closureInfo.setLambda(info);
|
||||||
expressionMap.put(closureInfo.getIndex(), info);
|
expressionMap.put(closureInfo.getIndex(), info);
|
||||||
}
|
}
|
||||||
@@ -619,23 +626,37 @@ public class InlineCodegen extends CallGenerator {
|
|||||||
public void genValueAndPut(
|
public void genValueAndPut(
|
||||||
@NotNull ValueParameterDescriptor valueParameterDescriptor,
|
@NotNull ValueParameterDescriptor valueParameterDescriptor,
|
||||||
@NotNull JetExpression argumentExpression,
|
@NotNull JetExpression argumentExpression,
|
||||||
@NotNull Type parameterType
|
@NotNull Type parameterType,
|
||||||
|
int parameterIndex
|
||||||
) {
|
) {
|
||||||
if (isInliningParameter(argumentExpression, valueParameterDescriptor)) {
|
if (isInliningParameter(argumentExpression, valueParameterDescriptor)) {
|
||||||
rememberClosure(argumentExpression, parameterType);
|
rememberClosure(argumentExpression, parameterType, valueParameterDescriptor.getIndex());
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
StackValue value = codegen.gen(argumentExpression);
|
StackValue value = codegen.gen(argumentExpression);
|
||||||
putValueIfNeeded(valueParameterDescriptor, parameterType, value);
|
putValueIfNeeded(valueParameterDescriptor, parameterType, value, valueParameterDescriptor.getIndex());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void putValueIfNeeded(@Nullable ValueParameterDescriptor valueParameterDescriptor, @NotNull Type parameterType, @NotNull StackValue value) {
|
public void putValueIfNeeded(
|
||||||
|
@Nullable ValueParameterDescriptor valueParameterDescriptor,
|
||||||
|
@NotNull Type parameterType,
|
||||||
|
@NotNull StackValue value
|
||||||
|
) {
|
||||||
|
putValueIfNeeded(valueParameterDescriptor, parameterType, value, -1);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void putValueIfNeeded(
|
||||||
|
@Nullable ValueParameterDescriptor valueParameterDescriptor,
|
||||||
|
@NotNull Type parameterType,
|
||||||
|
@NotNull StackValue value,
|
||||||
|
int index
|
||||||
|
) {
|
||||||
if (shouldPutValue(parameterType, value)) {
|
if (shouldPutValue(parameterType, value)) {
|
||||||
value.put(parameterType, codegen.v);
|
value.put(parameterType, codegen.v);
|
||||||
}
|
}
|
||||||
afterParameterPut(parameterType, value, valueParameterDescriptor);
|
afterParameterPut(parameterType, value, valueParameterDescriptor, index);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -645,7 +666,7 @@ public class InlineCodegen extends CallGenerator {
|
|||||||
if (shouldPutValue(stackValue.type, stackValue)) {
|
if (shouldPutValue(stackValue.type, stackValue)) {
|
||||||
stackValue.put(stackValue.type, codegen.v);
|
stackValue.put(stackValue.type, codegen.v);
|
||||||
}
|
}
|
||||||
putArgumentOrCapturedToLocalVal(stackValue.type, stackValue, paramIndex);
|
putArgumentOrCapturedToLocalVal(stackValue.type, stackValue, paramIndex, paramIndex);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -749,4 +770,9 @@ public class InlineCodegen extends CallGenerator {
|
|||||||
String targetFile = getSourceFilePath(targetDescriptor);
|
String targetFile = getSourceFilePath(targetDescriptor);
|
||||||
incrementalCache.registerInline(sourceFile, jvmSignature.toString(), targetFile);
|
incrementalCache.registerInline(sourceFile, jvmSignature.toString(), targetFile);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void reorderArgumentsIfNeeded(@NotNull ArrayList<ArgumentAndIndex> actualArgsWithDeclIndex) {
|
||||||
|
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -34,7 +34,6 @@ public class LocalVarRemapper {
|
|||||||
private final int actualParamsSize;
|
private final int actualParamsSize;
|
||||||
|
|
||||||
private final StackValue[] remapValues;
|
private final StackValue[] remapValues;
|
||||||
|
|
||||||
private final int additionalShift;
|
private final int additionalShift;
|
||||||
|
|
||||||
public LocalVarRemapper(Parameters params, int additionalShift) {
|
public LocalVarRemapper(Parameters params, int additionalShift) {
|
||||||
@@ -42,20 +41,40 @@ public class LocalVarRemapper {
|
|||||||
this.allParamsSize = params.totalSize();
|
this.allParamsSize = params.totalSize();
|
||||||
this.params = params;
|
this.params = params;
|
||||||
|
|
||||||
int realSize = 0;
|
|
||||||
remapValues = new StackValue [params.totalSize()];
|
remapValues = new StackValue [params.totalSize()];
|
||||||
|
Integer [] declIndexesToActual = new Integer [params.totalSize()];
|
||||||
|
Integer [] actualDeclShifts = new Integer [params.totalSize()];
|
||||||
|
|
||||||
int index = 0;
|
int index = 0;
|
||||||
for (ParameterInfo info : params) {
|
for (ParameterInfo param : params) {
|
||||||
if (!info.isSkippedOrRemapped()) {
|
if (param != ParameterInfo.STUB && param != CapturedParamInfo.STUB) {
|
||||||
remapValues[index] = StackValue.local(realSize, AsmTypes.OBJECT_TYPE);
|
declIndexesToActual[param.declarationIndex] = index;
|
||||||
realSize += info.getType().getSize();
|
|
||||||
} else {
|
|
||||||
remapValues[index] = info.isRemapped() ? info.getRemapValue() : null;
|
|
||||||
}
|
}
|
||||||
index++;
|
index++;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int realSize = 0;
|
||||||
|
for (int i = 0; i < declIndexesToActual.length; i++) {
|
||||||
|
Integer declIndexToActual = declIndexesToActual[i];
|
||||||
|
if (declIndexToActual != null) {
|
||||||
|
actualDeclShifts[i] = realSize;
|
||||||
|
realSize += params.get(declIndexToActual).getType().getSize();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
realSize = 0;
|
||||||
|
for (ParameterInfo info : params) {
|
||||||
|
if (info != ParameterInfo.STUB && info != CapturedParamInfo.STUB) {
|
||||||
|
if (!info.isSkippedOrRemapped()) {
|
||||||
|
remapValues[actualDeclShifts[info.declarationIndex]] = StackValue.local(realSize, AsmTypes.OBJECT_TYPE);
|
||||||
|
realSize += info.getType().getSize();
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
remapValues[actualDeclShifts[info.declarationIndex]] = info.isRemapped() ? info.getRemapValue() : null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
actualParamsSize = realSize;
|
actualParamsSize = realSize;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -63,7 +82,7 @@ public class LocalVarRemapper {
|
|||||||
int remappedIndex;
|
int remappedIndex;
|
||||||
|
|
||||||
if (index < allParamsSize) {
|
if (index < allParamsSize) {
|
||||||
ParameterInfo info = params.get(index);
|
ParameterInfo info = params.getByByteCodeIndex(index);
|
||||||
StackValue remapped = remapValues[index];
|
StackValue remapped = remapValues[index];
|
||||||
if (info.isSkipped || remapped == null) {
|
if (info.isSkipped || remapped == null) {
|
||||||
return new RemapInfo(info);
|
return new RemapInfo(info);
|
||||||
|
|||||||
@@ -559,7 +559,7 @@ public class MethodInliner {
|
|||||||
|
|
||||||
private LambdaInfo getLambdaIfExists(int varIndex) {
|
private LambdaInfo getLambdaIfExists(int varIndex) {
|
||||||
if (varIndex < parameters.totalSize()) {
|
if (varIndex < parameters.totalSize()) {
|
||||||
return parameters.get(varIndex).getLambda();
|
return parameters.getByByteCodeIndex(varIndex).getLambda();
|
||||||
}
|
}
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -24,31 +24,34 @@ import org.jetbrains.org.objectweb.asm.Type;
|
|||||||
|
|
||||||
class ParameterInfo {
|
class ParameterInfo {
|
||||||
|
|
||||||
public static final ParameterInfo STUB = new ParameterInfo(AsmTypes.OBJECT_TYPE, true, -1, -1);
|
public static final ParameterInfo STUB = new ParameterInfo(AsmTypes.OBJECT_TYPE, true, -1, -1, -1);
|
||||||
|
|
||||||
protected final int index;
|
protected final int index;
|
||||||
|
|
||||||
|
protected final int declarationIndex;
|
||||||
|
|
||||||
private boolean isCaptured;
|
private boolean isCaptured;
|
||||||
|
|
||||||
public final Type type;
|
public final Type type;
|
||||||
|
|
||||||
//for skipped parameter: e.g. inlined lambda
|
//for skipped parameter: e.g. inlined lambda
|
||||||
public final boolean isSkipped;
|
public boolean isSkipped;
|
||||||
|
|
||||||
//in case when parameter could be extracted from outer context (e.g. from local var)
|
//in case when parameter could be extracted from outer context (e.g. from local var)
|
||||||
private StackValue remapValue;
|
private StackValue remapValue;
|
||||||
|
|
||||||
public LambdaInfo lambda;
|
public LambdaInfo lambda;
|
||||||
|
|
||||||
ParameterInfo(Type type, boolean skipped, int index, int remapValue) {
|
ParameterInfo(Type type, boolean skipped, int index, int remapValue, int declarationIndex) {
|
||||||
this(type, skipped, index, remapValue == -1 ? null : StackValue.local(remapValue, type));
|
this(type, skipped, index, remapValue == -1 ? null : StackValue.local(remapValue, type), declarationIndex);
|
||||||
}
|
}
|
||||||
|
|
||||||
ParameterInfo(@NotNull Type type, boolean skipped, int index, @Nullable StackValue remapValue) {
|
ParameterInfo(@NotNull Type type, boolean skipped, int index, @Nullable StackValue remapValue, int declarationIndex) {
|
||||||
this.type = type;
|
this.type = type;
|
||||||
this.isSkipped = skipped;
|
this.isSkipped = skipped;
|
||||||
this.remapValue = remapValue;
|
this.remapValue = remapValue;
|
||||||
this.index = index;
|
this.index = index;
|
||||||
|
this.declarationIndex = declarationIndex;
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean isSkippedOrRemapped() {
|
public boolean isSkippedOrRemapped() {
|
||||||
@@ -82,19 +85,27 @@ class ParameterInfo {
|
|||||||
return lambda;
|
return lambda;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setLambda(@Nullable LambdaInfo lambda) {
|
public ParameterInfo setLambda(@Nullable LambdaInfo lambda) {
|
||||||
this.lambda = lambda;
|
this.lambda = lambda;
|
||||||
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setRemapValue(StackValue remapValue) {
|
public ParameterInfo setRemapValue(StackValue remapValue) {
|
||||||
this.remapValue = remapValue;
|
this.remapValue = remapValue;
|
||||||
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean isCaptured() {
|
public boolean isCaptured() {
|
||||||
return isCaptured;
|
return isCaptured;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public ParameterInfo setSkipped(boolean skipped) {
|
||||||
|
isSkipped = skipped;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
public void setCaptured(boolean isCaptured) {
|
public void setCaptured(boolean isCaptured) {
|
||||||
this.isCaptured = isCaptured;
|
this.isCaptured = isCaptured;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -29,9 +29,32 @@ public class Parameters implements Iterable<ParameterInfo> {
|
|||||||
private final List<ParameterInfo> real;
|
private final List<ParameterInfo> real;
|
||||||
private final List<CapturedParamInfo> captured;
|
private final List<CapturedParamInfo> captured;
|
||||||
|
|
||||||
|
private final Integer [] declIndexesToActual;
|
||||||
|
private final ParameterInfo [] actualDeclShifts;
|
||||||
|
|
||||||
public Parameters(List<ParameterInfo> real, List<CapturedParamInfo> captured) {
|
public Parameters(List<ParameterInfo> real, List<CapturedParamInfo> captured) {
|
||||||
this.real = real;
|
this.real = real;
|
||||||
this.captured = captured;
|
this.captured = captured;
|
||||||
|
|
||||||
|
declIndexesToActual = new Integer [totalSize()];
|
||||||
|
|
||||||
|
int index = 0;
|
||||||
|
for (ParameterInfo param : this) {
|
||||||
|
if (param != ParameterInfo.STUB && param != CapturedParamInfo.STUB) {
|
||||||
|
declIndexesToActual[param.declarationIndex] = index;
|
||||||
|
}
|
||||||
|
index++;
|
||||||
|
}
|
||||||
|
|
||||||
|
actualDeclShifts = new ParameterInfo [totalSize()];
|
||||||
|
int realSize = 0;
|
||||||
|
for (int i = 0; i < declIndexesToActual.length; i++) {
|
||||||
|
Integer declIndexToActual = declIndexesToActual[i];
|
||||||
|
if (declIndexToActual != null) {
|
||||||
|
actualDeclShifts[realSize] = getByDeclarationIndex(i);
|
||||||
|
realSize += get(declIndexToActual).getType().getSize();
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public List<ParameterInfo> getReal() {
|
public List<ParameterInfo> getReal() {
|
||||||
@@ -46,6 +69,17 @@ public class Parameters implements Iterable<ParameterInfo> {
|
|||||||
return real.size() + captured.size();
|
return real.size() + captured.size();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public ParameterInfo getByDeclarationIndex(int index) {
|
||||||
|
if (index < real.size()) {
|
||||||
|
return real.get(declIndexesToActual[index]);
|
||||||
|
}
|
||||||
|
return captured.get(index - real.size());
|
||||||
|
}
|
||||||
|
|
||||||
|
public ParameterInfo getByByteCodeIndex(int index) {
|
||||||
|
return actualDeclShifts[index];
|
||||||
|
}
|
||||||
|
|
||||||
public ParameterInfo get(int index) {
|
public ParameterInfo get(int index) {
|
||||||
if (index < real.size()) {
|
if (index < real.size()) {
|
||||||
return real.get(index);
|
return real.get(index);
|
||||||
|
|||||||
@@ -22,43 +22,54 @@ import org.jetbrains.org.objectweb.asm.Type
|
|||||||
import java.util.ArrayList
|
import java.util.ArrayList
|
||||||
import java.util.Collections
|
import java.util.Collections
|
||||||
|
|
||||||
class ParametersBuilder {
|
class ParametersBuilder private constructor(){
|
||||||
|
|
||||||
private val params = ArrayList<ParameterInfo>()
|
private val valueAndHiddenParams = arrayListOf<ParameterInfo>()
|
||||||
private val capturedParams = ArrayList<CapturedParamInfo>()
|
private val capturedParams = arrayListOf<CapturedParamInfo>()
|
||||||
|
private var valueParamStart = 0
|
||||||
|
|
||||||
var nextValueParameterIndex = 0
|
var nextValueParameterIndex = 0
|
||||||
private set
|
private set
|
||||||
|
|
||||||
private var nextCaptured = 0
|
private var nextCaptured = 0
|
||||||
|
|
||||||
fun addThis(type: Type, skipped: Boolean): ParameterInfo {
|
fun addThis(type: Type, skipped: Boolean): ParameterInfo {
|
||||||
val info = ParameterInfo(type, skipped, nextValueParameterIndex, -1)
|
val info = ParameterInfo(type, skipped, nextValueParameterIndex, -1, valueAndHiddenParams.size())
|
||||||
addParameter(info)
|
addParameter(info)
|
||||||
return info
|
return info
|
||||||
}
|
}
|
||||||
|
|
||||||
fun addNextParameter(type: Type, skipped: Boolean, remapValue: StackValue?): ParameterInfo {
|
fun addNextParameter(type: Type, skipped: Boolean, remapValue: StackValue?): ParameterInfo {
|
||||||
return addParameter(ParameterInfo(type, skipped, nextValueParameterIndex, remapValue))
|
return addParameter(ParameterInfo(type, skipped, nextValueParameterIndex, remapValue, valueAndHiddenParams.size()))
|
||||||
|
}
|
||||||
|
|
||||||
|
fun addNextValueParameter(type: Type, skipped: Boolean, remapValue: StackValue?, parameterIndex: Int): ParameterInfo {
|
||||||
|
return addParameter(ParameterInfo(type, skipped, nextValueParameterIndex, remapValue,
|
||||||
|
if (parameterIndex == -1) valueAndHiddenParams.size() else { parameterIndex + valueParamStart }))
|
||||||
}
|
}
|
||||||
|
|
||||||
fun addCapturedParam(
|
fun addCapturedParam(
|
||||||
original: CapturedParamInfo,
|
original: CapturedParamInfo,
|
||||||
newFieldName: String): CapturedParamInfo {
|
newFieldName: String): CapturedParamInfo {
|
||||||
val info = CapturedParamInfo(original.desc, newFieldName, original.isSkipped, nextCaptured, original.getIndex())
|
val info = CapturedParamInfo(original.desc, newFieldName, original.isSkipped, nextCapturedIndex(), original.getIndex())
|
||||||
info.setLambda(original.getLambda())
|
info.setLambda(original.getLambda())
|
||||||
return addCapturedParameter(info)
|
return addCapturedParameter(info)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private fun nextCapturedIndex(): Int {
|
||||||
|
return nextCaptured
|
||||||
|
}
|
||||||
|
|
||||||
fun addCapturedParam(
|
fun addCapturedParam(
|
||||||
desc: CapturedParamDesc,
|
desc: CapturedParamDesc,
|
||||||
newFieldName: String): CapturedParamInfo {
|
newFieldName: String): CapturedParamInfo {
|
||||||
val info = CapturedParamInfo(desc, newFieldName, false, nextCaptured, null)
|
val info = CapturedParamInfo(desc, newFieldName, false, nextCapturedIndex(), null)
|
||||||
return addCapturedParameter(info)
|
return addCapturedParameter(info)
|
||||||
}
|
}
|
||||||
|
|
||||||
fun addCapturedParamCopy(
|
fun addCapturedParamCopy(
|
||||||
copyFrom: CapturedParamInfo): CapturedParamInfo {
|
copyFrom: CapturedParamInfo): CapturedParamInfo {
|
||||||
val info = copyFrom.newIndex(nextCaptured)
|
val info = copyFrom.newIndex(nextCapturedIndex())
|
||||||
return addCapturedParameter(info)
|
return addCapturedParameter(info)
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -68,7 +79,7 @@ class ParametersBuilder {
|
|||||||
type: Type,
|
type: Type,
|
||||||
skipped: Boolean,
|
skipped: Boolean,
|
||||||
original: ParameterInfo?): CapturedParamInfo {
|
original: ParameterInfo?): CapturedParamInfo {
|
||||||
val info = CapturedParamInfo(CapturedParamDesc.createDesc(containingLambda, fieldName, type), skipped, nextCaptured,
|
val info = CapturedParamInfo(CapturedParamDesc.createDesc(containingLambda, fieldName, type), skipped, nextCapturedIndex(),
|
||||||
if (original != null) original.getIndex() else -1)
|
if (original != null) original.getIndex() else -1)
|
||||||
if (original != null) {
|
if (original != null) {
|
||||||
info.setLambda(original.getLambda())
|
info.setLambda(original.getLambda())
|
||||||
@@ -77,7 +88,7 @@ class ParametersBuilder {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private fun addParameter(info: ParameterInfo): ParameterInfo {
|
private fun addParameter(info: ParameterInfo): ParameterInfo {
|
||||||
params.add(info)
|
valueAndHiddenParams.add(info)
|
||||||
nextValueParameterIndex += info.getType().size
|
nextValueParameterIndex += info.getType().size
|
||||||
return info
|
return info
|
||||||
}
|
}
|
||||||
@@ -89,7 +100,11 @@ class ParametersBuilder {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fun listNotCaptured(): List<ParameterInfo> {
|
fun listNotCaptured(): List<ParameterInfo> {
|
||||||
return Collections.unmodifiableList(params)
|
return Collections.unmodifiableList(valueAndHiddenParams)
|
||||||
|
}
|
||||||
|
|
||||||
|
fun markValueParametesStart(){
|
||||||
|
this.valueParamStart = valueAndHiddenParams.size()
|
||||||
}
|
}
|
||||||
|
|
||||||
fun listCaptured(): List<CapturedParamInfo> {
|
fun listCaptured(): List<CapturedParamInfo> {
|
||||||
@@ -97,9 +112,7 @@ class ParametersBuilder {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fun listAllParams(): List<ParameterInfo> {
|
fun listAllParams(): List<ParameterInfo> {
|
||||||
val list = ArrayList(params)
|
return valueAndHiddenParams + capturedParams
|
||||||
list.addAll(capturedParams)
|
|
||||||
return list
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun buildWithStubs(): List<ParameterInfo> {
|
private fun buildWithStubs(): List<ParameterInfo> {
|
||||||
@@ -114,16 +127,24 @@ class ParametersBuilder {
|
|||||||
return Parameters(buildWithStubs(), buildCapturedWithStubs())
|
return Parameters(buildWithStubs(), buildCapturedWithStubs())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// public fun getValueParameter(index: Int): ParameterInfo {
|
||||||
|
// return valueAndHiddenParams[index + valueParamStart]
|
||||||
|
// }
|
||||||
|
|
||||||
companion object {
|
companion object {
|
||||||
|
|
||||||
@JvmStatic fun newBuilder(): ParametersBuilder {
|
@JvmStatic
|
||||||
|
fun newBuilder(): ParametersBuilder {
|
||||||
return ParametersBuilder()
|
return ParametersBuilder()
|
||||||
}
|
}
|
||||||
|
|
||||||
@JvmOverloads @JvmStatic fun initializeBuilderFrom(objectType: Type, descriptor: String, inlineLambda: LambdaInfo? = null): ParametersBuilder {
|
@JvmOverloads @JvmStatic
|
||||||
|
fun initializeBuilderFrom(objectType: Type, descriptor: String, inlineLambda: LambdaInfo? = null, addThis: Boolean = true): ParametersBuilder {
|
||||||
val builder = newBuilder()
|
val builder = newBuilder()
|
||||||
//skipped this for inlined lambda cause it will be removed
|
if (addThis) {
|
||||||
builder.addThis(objectType, inlineLambda != null).setLambda(inlineLambda)
|
//skipped this for inlined lambda cause it will be removed
|
||||||
|
builder.addThis(objectType, inlineLambda != null).setLambda(inlineLambda)
|
||||||
|
}
|
||||||
|
|
||||||
val types = Type.getArgumentTypes(descriptor)
|
val types = Type.getArgumentTypes(descriptor)
|
||||||
for (type in types) {
|
for (type in types) {
|
||||||
|
|||||||
@@ -0,0 +1,19 @@
|
|||||||
|
import test.*
|
||||||
|
|
||||||
|
fun box(): String {
|
||||||
|
var res = "";
|
||||||
|
var call = test(a = {res += "K"; "K"}(), b = {res+="O"; "O"}(), c = {res += "L"; "L"})
|
||||||
|
if (res != "KOL" || call != "KOL") return "fail 1: $res != KOL or $call != KOL"
|
||||||
|
|
||||||
|
res = "";
|
||||||
|
call = test(a = {res += "K"; "K"}(), c = {res += "L"; "L"}, b = {res+="O"; "O"}())
|
||||||
|
if (res != "KOL" || call != "KOL") return "fail 2: $res != KOL or $call != KOL"
|
||||||
|
|
||||||
|
|
||||||
|
res = "";
|
||||||
|
call = test(c = {res += "L"; "L"}, a = {res += "K"; "K"}(), b = {res+="O"; "O"}())
|
||||||
|
if (res != "KOL" || call != "KOL") return "fail 3: $res != KOL or $call != KOL"
|
||||||
|
|
||||||
|
return "OK"
|
||||||
|
|
||||||
|
}
|
||||||
@@ -0,0 +1,5 @@
|
|||||||
|
package test
|
||||||
|
|
||||||
|
inline fun test(a: String, b: String, c: () -> String): String {
|
||||||
|
return a + b + c();
|
||||||
|
}
|
||||||
@@ -0,0 +1,19 @@
|
|||||||
|
import test.*
|
||||||
|
|
||||||
|
fun box(): String {
|
||||||
|
var res = "";
|
||||||
|
var call = test(b = {res += "K"; "K"}(), a = {res+="O"; "O"}(), c = {res += "L"; "L"})
|
||||||
|
if (res != "KOL" || call != "OKL") return "fail 1: $res != KOL or $call != OKL"
|
||||||
|
|
||||||
|
res = "";
|
||||||
|
call = test(b = {res += "K"; "K"}(), c = {res += "L"; "L"}, a = {res+="O"; "O"}())
|
||||||
|
if (res != "KOL" || call != "OKL") return "fail 2: $res != KOL or $call != OKL"
|
||||||
|
|
||||||
|
|
||||||
|
res = "";
|
||||||
|
call = test(c = {res += "L"; "L"}, b = {res += "K"; "K"}(), a = {res+="O"; "O"}())
|
||||||
|
if (res != "KOL" || call != "OKL") return "fail 3: $res != KOL or $call != OKL"
|
||||||
|
|
||||||
|
return "OK"
|
||||||
|
|
||||||
|
}
|
||||||
@@ -0,0 +1,5 @@
|
|||||||
|
package test
|
||||||
|
|
||||||
|
inline fun test(a: String, b: String, c: () -> String): String {
|
||||||
|
return a + b + c();
|
||||||
|
}
|
||||||
+21
@@ -116,6 +116,27 @@ public class BlackBoxInlineCodegenTestGenerated extends AbstractBlackBoxInlineCo
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@TestMetadata("compiler/testData/codegen/boxInline/argumentOrder")
|
||||||
|
@TestDataPath("$PROJECT_ROOT")
|
||||||
|
@RunWith(JUnit3RunnerWithInners.class)
|
||||||
|
public static class ArgumentOrder extends AbstractBlackBoxInlineCodegenTest {
|
||||||
|
public void testAllFilesPresentInArgumentOrder() throws Exception {
|
||||||
|
JetTestUtils.assertAllTestsPresentByMetadata(this.getClass(), new File("compiler/testData/codegen/boxInline/argumentOrder"), Pattern.compile("^(.+)\\.1.kt$"), true);
|
||||||
|
}
|
||||||
|
|
||||||
|
@TestMetadata("justLambda.1.kt")
|
||||||
|
public void testJustLambda() throws Exception {
|
||||||
|
String fileName = JetTestUtils.navigationMetadata("compiler/testData/codegen/boxInline/argumentOrder/justLambda.1.kt");
|
||||||
|
doTestMultiFileWithInlineCheck(fileName);
|
||||||
|
}
|
||||||
|
|
||||||
|
@TestMetadata("simple.1.kt")
|
||||||
|
public void testSimple() throws Exception {
|
||||||
|
String fileName = JetTestUtils.navigationMetadata("compiler/testData/codegen/boxInline/argumentOrder/simple.1.kt");
|
||||||
|
doTestMultiFileWithInlineCheck(fileName);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@TestMetadata("compiler/testData/codegen/boxInline/builders")
|
@TestMetadata("compiler/testData/codegen/boxInline/builders")
|
||||||
@TestDataPath("$PROJECT_ROOT")
|
@TestDataPath("$PROJECT_ROOT")
|
||||||
@RunWith(JUnit3RunnerWithInners.class)
|
@RunWith(JUnit3RunnerWithInners.class)
|
||||||
|
|||||||
+21
@@ -116,6 +116,27 @@ public class CompileKotlinAgainstInlineKotlinTestGenerated extends AbstractCompi
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@TestMetadata("compiler/testData/codegen/boxInline/argumentOrder")
|
||||||
|
@TestDataPath("$PROJECT_ROOT")
|
||||||
|
@RunWith(JUnit3RunnerWithInners.class)
|
||||||
|
public static class ArgumentOrder extends AbstractCompileKotlinAgainstInlineKotlinTest {
|
||||||
|
public void testAllFilesPresentInArgumentOrder() throws Exception {
|
||||||
|
JetTestUtils.assertAllTestsPresentByMetadata(this.getClass(), new File("compiler/testData/codegen/boxInline/argumentOrder"), Pattern.compile("^(.+)\\.1.kt$"), true);
|
||||||
|
}
|
||||||
|
|
||||||
|
@TestMetadata("justLambda.1.kt")
|
||||||
|
public void testJustLambda() throws Exception {
|
||||||
|
String fileName = JetTestUtils.navigationMetadata("compiler/testData/codegen/boxInline/argumentOrder/justLambda.1.kt");
|
||||||
|
doBoxTestWithInlineCheck(fileName);
|
||||||
|
}
|
||||||
|
|
||||||
|
@TestMetadata("simple.1.kt")
|
||||||
|
public void testSimple() throws Exception {
|
||||||
|
String fileName = JetTestUtils.navigationMetadata("compiler/testData/codegen/boxInline/argumentOrder/simple.1.kt");
|
||||||
|
doBoxTestWithInlineCheck(fileName);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@TestMetadata("compiler/testData/codegen/boxInline/builders")
|
@TestMetadata("compiler/testData/codegen/boxInline/builders")
|
||||||
@TestDataPath("$PROJECT_ROOT")
|
@TestDataPath("$PROJECT_ROOT")
|
||||||
@RunWith(JUnit3RunnerWithInners.class)
|
@RunWith(JUnit3RunnerWithInners.class)
|
||||||
|
|||||||
Reference in New Issue
Block a user