Parameter processing rewrote with parameter builder

Split capture parameter descriptor and it representation
This commit is contained in:
Mikhael Bogdanov
2014-06-03 14:08:57 +04:00
committed by Michael Bogdanov
parent 98e87f2f95
commit 30ddbb0682
9 changed files with 99 additions and 122 deletions
@@ -384,20 +384,19 @@ public class AnonymousObjectTransformer {
//For all inlined lambdas add their captured parameters //For all inlined lambdas add their captured parameters
//TODO: some of such parameters could be skipped - we should perform additional analysis //TODO: some of such parameters could be skipped - we should perform additional analysis
Map<String, LambdaInfo> capturedLambdasToInline = new HashMap<String, LambdaInfo>(); //captured var of inlined parameter Map<String, LambdaInfo> capturedLambdasToInline = new HashMap<String, LambdaInfo>(); //captured var of inlined parameter
List<CapturedParamInfo> allRecapturedParameters = new ArrayList<CapturedParamInfo>(); List<CapturedParamDesc> allRecapturedParameters = new ArrayList<CapturedParamDesc>();
for (LambdaInfo info : capturedLambdas) { for (LambdaInfo info : capturedLambdas) {
for (CapturedParamInfo var : info.getCapturedVars()) { for (CapturedParamDesc desc : info.getCapturedVars()) {
CapturedParamInfo recapturedParamInfo = capturedParamBuilder.addCapturedParam(var, CapturedParamInfo recapturedParamInfo = capturedParamBuilder.addCapturedParam(desc, getNewFieldName(desc.getFieldName()));
getNewFieldName(var.getOriginalFieldName()));
StackValue composed = StackValue.composed(StackValue.local(0, oldObjectType), StackValue composed = StackValue.composed(StackValue.local(0, oldObjectType),
StackValue.field(var.getType(), StackValue.field(desc.getType(),
oldObjectType, /*TODO owner type*/ oldObjectType, /*TODO owner type*/
recapturedParamInfo.getNewFieldName(), false) recapturedParamInfo.getNewFieldName(), false)
); );
recapturedParamInfo.setRemapValue(composed); recapturedParamInfo.setRemapValue(composed);
allRecapturedParameters.add(var); allRecapturedParameters.add(desc);
constructorParamBuilder.addCapturedParam(var, recapturedParamInfo.getNewFieldName()).setRemapValue(composed); constructorParamBuilder.addCapturedParam(recapturedParamInfo, recapturedParamInfo.getNewFieldName()).setRemapValue(composed);
} }
capturedLambdasToInline.put(info.getLambdaClassType().getInternalName(), info); capturedLambdasToInline.put(info.getLambdaClassType().getInternalName(), info);
} }
@@ -56,4 +56,9 @@ public class CapturedParamDesc {
public static CapturedParamDesc createDesc(@NotNull CapturedParamOwner containingLambdaInfo, @NotNull String fieldName, @NotNull Type type) { public static CapturedParamDesc createDesc(@NotNull CapturedParamOwner containingLambdaInfo, @NotNull String fieldName, @NotNull Type type) {
return new CapturedParamDesc(containingLambdaInfo, fieldName, type); return new CapturedParamDesc(containingLambdaInfo, fieldName, type);
} }
@NotNull
public String getContainingLambdaName() {
return containingLambda.getType().getInternalName();
}
} }
@@ -31,8 +31,6 @@ public class CapturedParamInfo extends ParameterInfo {
public final CapturedParamDesc desc; public final CapturedParamDesc desc;
private int shift = 0;
private final String newFieldName; private final String newFieldName;
public CapturedParamInfo(@NotNull CapturedParamDesc desc, boolean skipped, int index, int remapIndex) { public CapturedParamInfo(@NotNull CapturedParamDesc desc, boolean skipped, int index, int remapIndex) {
@@ -61,15 +59,6 @@ public class CapturedParamInfo extends ParameterInfo {
return desc.getFieldName(); return desc.getFieldName();
} }
@Override
public int getIndex() {
return shift + super.getIndex();
}
public void setShift(int shift) {
this.shift = shift;
}
@NotNull @NotNull
public CapturedParamInfo newIndex(int newIndex) { public CapturedParamInfo newIndex(int newIndex) {
return clone(newIndex, getRemapValue()); return clone(newIndex, getRemapValue());
@@ -36,7 +36,7 @@ public class ConstructorInvocation {
private String newConstructorDescriptor; private String newConstructorDescriptor;
private List<CapturedParamInfo> allRecapturedParameters; private List<CapturedParamDesc> allRecapturedParameters;
private Map<String, LambdaInfo> capturedLambdasToInline; private Map<String, LambdaInfo> capturedLambdasToInline;
@@ -84,11 +84,11 @@ public class ConstructorInvocation {
this.newConstructorDescriptor = newConstructorDescriptor; this.newConstructorDescriptor = newConstructorDescriptor;
} }
public List<CapturedParamInfo> getAllRecapturedParameters() { public List<CapturedParamDesc> getAllRecapturedParameters() {
return allRecapturedParameters; return allRecapturedParameters;
} }
public void setAllRecapturedParameters(List<CapturedParamInfo> allRecapturedParameters) { public void setAllRecapturedParameters(List<CapturedParamDesc> allRecapturedParameters) {
this.allRecapturedParameters = allRecapturedParameters; this.allRecapturedParameters = allRecapturedParameters;
} }
@@ -68,12 +68,12 @@ public class InlineCodegen implements CallGenerator {
private final JetElement callElement; private final JetElement callElement;
private final MethodContext context; private final MethodContext context;
private final ExpressionCodegen codegen; private final ExpressionCodegen codegen;
private final FrameMap originalFunctionFrame;
private final boolean asFunctionInline; private final boolean asFunctionInline;
private final int initialFrameSize; private final int initialFrameSize;
private final boolean isSameModule; private final boolean isSameModule;
protected final List<ParameterInfo> actualParameters = new ArrayList<ParameterInfo>(); protected final ParametersBuilder invocationParamBuilder = ParametersBuilder.newBuilder();
protected final Map<Integer, LambdaInfo> expressionMap = new HashMap<Integer, LambdaInfo>(); protected final Map<Integer, LambdaInfo> expressionMap = new HashMap<Integer, LambdaInfo>();
private LambdaInfo activeLambda; private LambdaInfo activeLambda;
@@ -95,7 +95,6 @@ public class InlineCodegen implements CallGenerator {
initialFrameSize = codegen.getFrameMap().getCurrentSize(); initialFrameSize = codegen.getFrameMap().getCurrentSize();
context = (MethodContext) getContext(functionDescriptor, state); context = (MethodContext) getContext(functionDescriptor, state);
originalFunctionFrame = context.prepareFrame(typeMapper);
jvmSignature = typeMapper.mapSignature(functionDescriptor, context.getContextKind()); jvmSignature = typeMapper.mapSignature(functionDescriptor, context.getContextKind());
InlineStrategy inlineStrategy = InlineStrategy inlineStrategy =
@@ -205,13 +204,10 @@ public class InlineCodegen implements CallGenerator {
private InlineResult inlineCall(MethodNode node) { private InlineResult inlineCall(MethodNode node) {
generateClosuresBodies(); generateClosuresBodies();
List<ParameterInfo> realParams = new ArrayList<ParameterInfo>(actualParameters); //through generation captured parameters will be added to invocationParamBuilder
putClosureParametersOnStack(); putClosureParametersOnStack();
List<CapturedParamInfo> captured = getAllCaptured(); Parameters parameters = invocationParamBuilder.buildParameters();
Parameters parameters = new Parameters(realParams, Parameters.shiftAndAddStubs(captured, realParams.size()));
InliningContext info = new RootInliningContext(expressionMap, InliningContext info = new RootInliningContext(expressionMap,
state, state,
@@ -269,14 +265,16 @@ public class InlineCodegen implements CallGenerator {
boolean couldBeRemapped = !shouldPutValue(type, stackValue, valueParameterDescriptor); boolean couldBeRemapped = !shouldPutValue(type, stackValue, valueParameterDescriptor);
StackValue remappedIndex = couldBeRemapped ? stackValue : null; StackValue remappedIndex = couldBeRemapped ? stackValue : null;
ParameterInfo info = new ParameterInfo(type, false, couldBeRemapped ? -1 : codegen.getFrameMap().enterTemp(type), remappedIndex); ParameterInfo info;
if (capturedParamIndex >= 0) {
if (capturedParamIndex >= 0 && couldBeRemapped) { CapturedParamDesc capturedParamInfoInLambda = activeLambda.getCapturedVars().get(capturedParamIndex);
CapturedParamInfo capturedParamInfo = activeLambda.getCapturedVars().get(capturedParamIndex); info = invocationParamBuilder.addCapturedParam(capturedParamInfoInLambda, capturedParamInfoInLambda.getFieldName());
capturedParamInfo.setRemapValue(remappedIndex != null ? remappedIndex : StackValue.local(info.getIndex(), info.getType())); info.setRemapValue(remappedIndex);
} else {
info = invocationParamBuilder.addNextParameter(type, false, remappedIndex);
} }
doWithParameter(info); putParameterOnStack(info);
} }
} }
@@ -315,59 +313,49 @@ public class InlineCodegen implements CallGenerator {
return true; return true;
} }
private void doWithParameter(ParameterInfo info) { private void putParameterOnStack(ParameterInfo ... infos) {
recordParamInfo(info, true); int [] index = new int[infos.length];
putParameterOnStack(info); for (int i = 0; i < infos.length; i++) {
} ParameterInfo info = infos[i];
if (!info.isSkippedOrRemapped()) {
private int recordParamInfo(ParameterInfo info, boolean addToFrame) { index[i] = codegen.getFrameMap().enterTemp(info.getType());
Type type = info.type; } else {
actualParameters.add(info); index[i] = -1;
if (info.getType().getSize() == 2) { }
actualParameters.add(ParameterInfo.STUB);
} }
if (addToFrame) {
return originalFunctionFrame.enterTemp(type);
}
return -1;
}
private void putParameterOnStack(ParameterInfo info) { for (int i = infos.length - 1; i >= 0; i--) {
if (!info.isSkippedOrRemapped()) { ParameterInfo info = infos[i];
int index = info.getIndex(); if (!info.isSkippedOrRemapped()) {
Type type = info.type; Type type = info.type;
StackValue.local(index, type).store(type, codegen.v); StackValue.local(index[i], type).store(type, codegen.v);
}
} }
} }
@Override @Override
public void putHiddenParams() { public void putHiddenParams() {
List<JvmMethodParameterSignature> types = jvmSignature.getValueParameters(); List<JvmMethodParameterSignature> valueParameters = jvmSignature.getValueParameters();
if (!isStaticMethod(functionDescriptor, context)) { if (!isStaticMethod(functionDescriptor, context)) {
Type type = AsmTypeConstants.OBJECT_TYPE; invocationParamBuilder.addNextParameter(AsmTypeConstants.OBJECT_TYPE, false, null);
ParameterInfo info = new ParameterInfo(type, false, codegen.getFrameMap().enterTemp(type), -1);
recordParamInfo(info, false);
} }
for (JvmMethodParameterSignature param : types) { for (JvmMethodParameterSignature param : valueParameters) {
if (param.getKind() == JvmMethodParameterKind.VALUE) { if (param.getKind() == JvmMethodParameterKind.VALUE) {
break; break;
} }
Type type = param.getAsmType(); invocationParamBuilder.addNextParameter(param.getAsmType(), false, null);
ParameterInfo info = new ParameterInfo(type, false, codegen.getFrameMap().enterTemp(type), -1);
recordParamInfo(info, false);
} }
for (ListIterator<? extends ParameterInfo> iterator = actualParameters.listIterator(actualParameters.size()); iterator.hasPrevious(); ) { List<ParameterInfo> infos = invocationParamBuilder.listNotCaptured();
ParameterInfo param = iterator.previous(); putParameterOnStack(infos.toArray(new ParameterInfo[infos.size()]));
putParameterOnStack(param);
}
} }
public void leaveTemps() { public void leaveTemps() {
FrameMap frameMap = codegen.getFrameMap(); FrameMap frameMap = codegen.getFrameMap();
for (ListIterator<? extends ParameterInfo> iterator = actualParameters.listIterator(actualParameters.size()); iterator.hasPrevious(); ) { List<ParameterInfo> infos = invocationParamBuilder.listAllParams();
for (ListIterator<? extends ParameterInfo> iterator = infos.listIterator(infos.size()); iterator.hasPrevious(); ) {
ParameterInfo param = iterator.previous(); ParameterInfo param = iterator.previous();
if (!param.isSkippedOrRemapped()) { if (!param.isSkippedOrRemapped()) {
frameMap.leaveTemp(param.type); frameMap.leaveTemp(param.type);
@@ -382,40 +370,24 @@ public class InlineCodegen implements CallGenerator {
} }
public void rememberClosure(JetFunctionLiteralExpression expression, Type type) { public void rememberClosure(JetFunctionLiteralExpression expression, Type type) {
ParameterInfo closureInfo = new ParameterInfo(type, true, -1, -1); ParameterInfo closureInfo = invocationParamBuilder.addNextParameter(type, true, null);
int index = recordParamInfo(closureInfo, true);
LambdaInfo info = new LambdaInfo(expression, typeMapper); LambdaInfo info = new LambdaInfo(expression, typeMapper);
expressionMap.put(index, info); expressionMap.put(closureInfo.getIndex(), info);
closureInfo.setLambda(info); closureInfo.setLambda(info);
} }
private void putClosureParametersOnStack() { private void putClosureParametersOnStack() {
//TODO: SORT
int currentSize = actualParameters.size();
for (LambdaInfo next : expressionMap.values()) { for (LambdaInfo next : expressionMap.values()) {
if (next.closure != null) { if (next.closure != null) {
activeLambda = next; activeLambda = next;
next.setParamOffset(currentSize);
codegen.pushClosureOnStack(next.closure, false, this); codegen.pushClosureOnStack(next.closure, false, this);
currentSize += next.getCapturedVarsSize();
} }
} }
activeLambda = null; activeLambda = null;
} }
private List<CapturedParamInfo> getAllCaptured() {
//TODO: SORT
List<CapturedParamInfo> result = new ArrayList<CapturedParamInfo>();
for (LambdaInfo next : expressionMap.values()) {
if (next.closure != null) {
result.addAll(next.getCapturedVars());
}
}
return result;
}
public static CodegenContext getContext(DeclarationDescriptor descriptor, GenerationState state) { public static CodegenContext getContext(DeclarationDescriptor descriptor, GenerationState state) {
if (descriptor instanceof PackageFragmentDescriptor) { if (descriptor instanceof PackageFragmentDescriptor) {
return new PackageContext((PackageFragmentDescriptor) descriptor, null, null); return new PackageContext((PackageFragmentDescriptor) descriptor, null, null);
@@ -18,6 +18,7 @@ package org.jetbrains.jet.codegen.inline;
import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.NotNull;
import org.jetbrains.org.objectweb.asm.Type; import org.jetbrains.org.objectweb.asm.Type;
import org.jetbrains.org.objectweb.asm.tree.FieldInsnNode;
import org.jetbrains.org.objectweb.asm.tree.MethodNode; import org.jetbrains.org.objectweb.asm.tree.MethodNode;
import org.jetbrains.jet.codegen.AsmUtil; import org.jetbrains.jet.codegen.AsmUtil;
import org.jetbrains.jet.codegen.binding.CalculatedClosure; import org.jetbrains.jet.codegen.binding.CalculatedClosure;
@@ -48,7 +49,7 @@ public class LambdaInfo implements CapturedParamOwner {
private MethodNode node; private MethodNode node;
private List<CapturedParamInfo> capturedVars; private List<CapturedParamDesc> capturedVars;
private final FunctionDescriptor functionDescriptor; private final FunctionDescriptor functionDescriptor;
@@ -67,7 +68,6 @@ public class LambdaInfo implements CapturedParamOwner {
closureClassType = asmTypeForAnonymousClass(bindingContext, functionDescriptor); closureClassType = asmTypeForAnonymousClass(bindingContext, functionDescriptor);
closure = bindingContext.get(CLOSURE, classDescriptor); closure = bindingContext.get(CLOSURE, classDescriptor);
} }
public MethodNode getNode() { public MethodNode getNode() {
@@ -94,11 +94,12 @@ public class LambdaInfo implements CapturedParamOwner {
return closureClassType; return closureClassType;
} }
public List<CapturedParamInfo> getCapturedVars() { public List<CapturedParamDesc> getCapturedVars() {
//lazy initialization cause it would be calculated after object creation //lazy initialization cause it would be calculated after object creation
int index = 0; int index = 0;
if (capturedVars == null) { if (capturedVars == null) {
capturedVars = new ArrayList<CapturedParamInfo>(); capturedVars = new ArrayList<CapturedParamDesc>();
assert closure != null : "Closure for lambda should be not null " + expression.getText();
if (closure.getCaptureThis() != null) { if (closure.getCaptureThis() != null) {
EnclosedValueDescriptor descriptor = new EnclosedValueDescriptor(AsmUtil.CAPTURED_THIS_FIELD, null, null, typeMapper.mapType(closure.getCaptureThis())); EnclosedValueDescriptor descriptor = new EnclosedValueDescriptor(AsmUtil.CAPTURED_THIS_FIELD, null, null, typeMapper.mapType(closure.getCaptureThis()));
@@ -112,33 +113,28 @@ public class LambdaInfo implements CapturedParamOwner {
index += descriptor.getType().getSize(); index += descriptor.getType().getSize();
} }
if (closure != null) { for (EnclosedValueDescriptor descriptor : closure.getCaptureVariables().values()) {
for (EnclosedValueDescriptor descriptor : closure.getCaptureVariables().values()) { capturedVars.add(getCapturedParamInfo(descriptor, index));
capturedVars.add(getCapturedParamInfo(descriptor, index)); index += descriptor.getType().getSize();
index += descriptor.getType().getSize();
}
} }
} }
return capturedVars; return capturedVars;
} }
@NotNull @NotNull
public CapturedParamInfo getCapturedParamInfo(@NotNull EnclosedValueDescriptor descriptor, int index) { private CapturedParamDesc getCapturedParamInfo(@NotNull EnclosedValueDescriptor descriptor, int index) {
return new CapturedParamInfo(CapturedParamDesc.createDesc(this, descriptor.getFieldName(), descriptor.getType()), false, index, -1); //return new CapturedParamInfo(CapturedParamDesc.createDesc(this, descriptor.getFieldName(), descriptor.getType()), false, index, -1);
} return CapturedParamDesc.createDesc(this, descriptor.getFieldName(), descriptor.getType());
public void setParamOffset(int paramOffset) {
for (CapturedParamInfo var : getCapturedVars()) {
var.setShift(paramOffset);
}
} }
@NotNull
public List<Type> getParamsWithoutCapturedValOrVar() { public List<Type> getParamsWithoutCapturedValOrVar() {
Type[] types = typeMapper.mapSignature(functionDescriptor).getAsmMethod().getArgumentTypes(); Type[] types = typeMapper.mapSignature(functionDescriptor).getAsmMethod().getArgumentTypes();
return Arrays.asList(types); return Arrays.asList(types);
} }
public Parameters addAllParameters() { @NotNull
public Parameters addAllParameters(FieldRemapper remapper) {
ParametersBuilder builder = ParametersBuilder.newBuilder(); ParametersBuilder builder = ParametersBuilder.newBuilder();
//add skipped this cause inlined lambda doesn't have it //add skipped this cause inlined lambda doesn't have it
builder.addThis(AsmTypeConstants.OBJECT_TYPE, true).setLambda(this); builder.addThis(AsmTypeConstants.OBJECT_TYPE, true).setLambda(this);
@@ -149,21 +145,14 @@ public class LambdaInfo implements CapturedParamOwner {
builder.addNextParameter(type, false, null); builder.addNextParameter(type, false, null);
} }
for (CapturedParamInfo info : getCapturedVars()) { for (CapturedParamDesc info : getCapturedVars()) {
builder.addCapturedParam(info, info.getOriginalFieldName()); CapturedParamInfo field = remapper.findField(new FieldInsnNode(0, info.getContainingLambdaName(), info.getFieldName(), ""));
builder.addCapturedParam(field, info.getFieldName());
} }
return builder.buildParameters(); return builder.buildParameters();
} }
public int getCapturedVarsSize() {
int size = 0;
for (CapturedParamInfo next : getCapturedVars()) {
size += next.getType().getSize();
}
return size;
}
@Override @Override
public Type getType() { public Type getType() {
return closureClassType; return closureClassType;
@@ -181,7 +181,7 @@ public class MethodInliner {
int valueParamShift = getNextLocalIndex();//NB: don't inline cause it changes int valueParamShift = getNextLocalIndex();//NB: don't inline cause it changes
putStackValuesIntoLocals(info.getParamsWithoutCapturedValOrVar(), valueParamShift, this, desc); putStackValuesIntoLocals(info.getParamsWithoutCapturedValOrVar(), valueParamShift, this, desc);
Parameters lambdaParameters = info.addAllParameters(); Parameters lambdaParameters = info.addAllParameters(nodeRemapper);
InlinedLambdaRemapper newCapturedRemapper = InlinedLambdaRemapper newCapturedRemapper =
new InlinedLambdaRemapper(info.getLambdaClassType().getInternalName(), nodeRemapper, lambdaParameters); new InlinedLambdaRemapper(info.getLambdaClassType().getInternalName(), nodeRemapper, lambdaParameters);
@@ -207,8 +207,9 @@ public class MethodInliner {
assert invocation != null : "<init> call not corresponds to new call" + owner + " " + name; assert invocation != null : "<init> call not corresponds to new call" + owner + " " + name;
if (invocation.shouldRegenerate()) { if (invocation.shouldRegenerate()) {
//put additional captured parameters on stack //put additional captured parameters on stack
for (CapturedParamInfo capturedParamInfo : invocation.getAllRecapturedParameters()) { for (CapturedParamDesc capturedParamDesc : invocation.getAllRecapturedParameters()) {
visitFieldInsn(Opcodes.GETSTATIC, capturedParamInfo.getContainingLambdaName(), "$$$" + capturedParamInfo.getOriginalFieldName(), capturedParamInfo.getType().getDescriptor()); visitFieldInsn(Opcodes.GETSTATIC, capturedParamDesc.getContainingLambdaName(),
"$$$" + capturedParamDesc.getFieldName(), capturedParamDesc.getType().getDescriptor());
} }
super.visitMethodInsn(opcode, invocation.getNewLambdaType().getInternalName(), name, invocation.getNewConstructorDescriptor(), itf); super.visitMethodInsn(opcode, invocation.getNewLambdaType().getInternalName(), name, invocation.getNewConstructorDescriptor(), itf);
invocation = null; invocation = null;
@@ -44,10 +44,10 @@ class ParameterInfo {
this(type, skipped, index, remapValue == -1 ? null : StackValue.local(remapValue, type)); this(type, skipped, index, remapValue == -1 ? null : StackValue.local(remapValue, type));
} }
ParameterInfo(Type type, boolean skipped, int index, StackValue stackValue) { ParameterInfo(@NotNull Type type, boolean skipped, int index, @Nullable StackValue remapValue) {
this.type = type; this.type = type;
this.isSkipped = skipped; this.isSkipped = skipped;
this.remapValue = stackValue; this.remapValue = remapValue;
this.index = index; this.index = index;
} }
@@ -18,6 +18,8 @@ package org.jetbrains.jet.codegen.inline;
import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable; import org.jetbrains.annotations.Nullable;
import org.jetbrains.jet.codegen.FrameMap;
import org.jetbrains.jet.codegen.StackValue;
import org.jetbrains.org.objectweb.asm.Type; import org.jetbrains.org.objectweb.asm.Type;
import java.util.ArrayList; import java.util.ArrayList;
@@ -32,19 +34,21 @@ public class ParametersBuilder {
private int nextIndex = 0; private int nextIndex = 0;
private int nextCaptured = 0; private int nextCaptured = 0;
@NotNull
public static ParametersBuilder newBuilder() { public static ParametersBuilder newBuilder() {
return new ParametersBuilder(); return new ParametersBuilder();
} }
public ParameterInfo addThis(Type type, boolean skipped) { @NotNull
public ParameterInfo addThis(@NotNull Type type, boolean skipped) {
ParameterInfo info = new ParameterInfo(type, skipped, nextIndex, -1); ParameterInfo info = new ParameterInfo(type, skipped, nextIndex, -1);
addParameter(info); addParameter(info);
return info; return info;
} }
@NotNull @NotNull
public ParameterInfo addNextParameter(@NotNull Type type, boolean skipped, @Nullable ParameterInfo original) { public ParameterInfo addNextParameter(@NotNull Type type, boolean skipped, @Nullable StackValue remapValue) {
return addParameter(new ParameterInfo(type, skipped, nextIndex, original != null ? original.getIndex() : -1)); return addParameter(new ParameterInfo(type, skipped, nextIndex, remapValue));
} }
@NotNull @NotNull
@@ -57,6 +61,15 @@ public class ParametersBuilder {
return addCapturedParameter(info); return addCapturedParameter(info);
} }
@NotNull
public CapturedParamInfo addCapturedParam(
@NotNull CapturedParamDesc desc,
@NotNull String newFieldName
) {
CapturedParamInfo info = new CapturedParamInfo(desc, newFieldName, false, nextCaptured, null);
return addCapturedParameter(info);
}
@NotNull @NotNull
public CapturedParamInfo addCapturedParamCopy( public CapturedParamInfo addCapturedParamCopy(
@NotNull CapturedParamInfo copyFrom @NotNull CapturedParamInfo copyFrom
@@ -82,12 +95,14 @@ public class ParametersBuilder {
return addCapturedParameter(info); return addCapturedParameter(info);
} }
@NotNull
private ParameterInfo addParameter(ParameterInfo info) { private ParameterInfo addParameter(ParameterInfo info) {
params.add(info); params.add(info);
nextIndex += info.getType().getSize(); nextIndex += info.getType().getSize();
return info; return info;
} }
@NotNull
private CapturedParamInfo addCapturedParameter(CapturedParamInfo info) { private CapturedParamInfo addCapturedParameter(CapturedParamInfo info) {
capturedParams.add(info); capturedParams.add(info);
nextCaptured += info.getType().getSize(); nextCaptured += info.getType().getSize();
@@ -104,6 +119,13 @@ public class ParametersBuilder {
return Collections.unmodifiableList(capturedParams); return Collections.unmodifiableList(capturedParams);
} }
@NotNull
public List<ParameterInfo> listAllParams() {
List<ParameterInfo> list = new ArrayList<ParameterInfo>(params);
list.addAll(capturedParams);
return list;
}
@NotNull @NotNull
private List<ParameterInfo> buildWithStubs() { private List<ParameterInfo> buildWithStubs() {
return Parameters.addStubs(listNotCaptured()); return Parameters.addStubs(listNotCaptured());