use of org.jetbrains.kotlin.codegen.FieldInfo in project kotlin by JetBrains.
the class AnonymousObjectTransformer method generateConstructorAndFields.
private void generateConstructorAndFields(@NotNull ClassBuilder classBuilder, @NotNull ParametersBuilder allCapturedBuilder, @NotNull ParametersBuilder constructorInlineBuilder, @NotNull FieldRemapper parentRemapper, @NotNull List<CapturedParamInfo> constructorAdditionalFakeParams) {
List<Type> descTypes = new ArrayList<Type>();
Parameters constructorParams = constructorInlineBuilder.buildParameters();
int[] capturedIndexes = new int[constructorParams.getParameters().size()];
int index = 0;
int size = 0;
//complex processing cause it could have super constructor call params
for (ParameterInfo info : constructorParams) {
if (!info.isSkipped) {
//not inlined
if (info.isCaptured() || info instanceof CapturedParamInfo) {
capturedIndexes[index] = size;
index++;
}
if (size != 0) {
//skip this
descTypes.add(info.getType());
}
size += info.getType().getSize();
}
}
String constructorDescriptor = Type.getMethodDescriptor(Type.VOID_TYPE, descTypes.toArray(new Type[descTypes.size()]));
//TODO for inline method make public class
transformationInfo.setNewConstructorDescriptor(constructorDescriptor);
MethodVisitor constructorVisitor = classBuilder.newMethod(NO_ORIGIN, constructor.access, "<init>", constructorDescriptor, null, ArrayUtil.EMPTY_STRING_ARRAY);
final Label newBodyStartLabel = new Label();
constructorVisitor.visitLabel(newBodyStartLabel);
//initialize captured fields
List<NewJavaField> newFieldsWithSkipped = TransformationUtilsKt.getNewFieldsToGenerate(allCapturedBuilder.listCaptured());
List<FieldInfo> fieldInfoWithSkipped = TransformationUtilsKt.transformToFieldInfo(Type.getObjectType(transformationInfo.getNewClassName()), newFieldsWithSkipped);
int paramIndex = 0;
InstructionAdapter capturedFieldInitializer = new InstructionAdapter(constructorVisitor);
for (int i = 0; i < fieldInfoWithSkipped.size(); i++) {
FieldInfo fieldInfo = fieldInfoWithSkipped.get(i);
if (!newFieldsWithSkipped.get(i).getSkip()) {
AsmUtil.genAssignInstanceFieldFromParam(fieldInfo, capturedIndexes[paramIndex], capturedFieldInitializer);
}
paramIndex++;
}
//so we need to add them to captured params
for (CapturedParamInfo info : constructorAdditionalFakeParams) {
CapturedParamInfo fake = constructorInlineBuilder.addCapturedParamCopy(info);
if (fake.getLambda() != null) {
//set remap value to skip this fake (captured with lambda already skipped)
StackValue composed = StackValue.field(fake.getType(), oldObjectType, fake.getNewFieldName(), false, StackValue.LOCAL_0);
fake.setRemapValue(composed);
}
}
MethodNode intermediateMethodNode = new MethodNode(constructor.access, "<init>", constructorDescriptor, null, ArrayUtil.EMPTY_STRING_ARRAY);
inlineMethodAndUpdateGlobalResult(parentRemapper, intermediateMethodNode, constructor, constructorInlineBuilder, true);
InlineCodegenUtil.removeFinallyMarkers(intermediateMethodNode);
AbstractInsnNode first = intermediateMethodNode.instructions.getFirst();
final Label oldStartLabel = first instanceof LabelNode ? ((LabelNode) first).getLabel() : null;
intermediateMethodNode.accept(new MethodBodyVisitor(capturedFieldInitializer) {
@Override
public void visitLocalVariable(@NotNull String name, @NotNull String desc, String signature, @NotNull Label start, @NotNull Label end, int index) {
if (oldStartLabel == start) {
//patch for jack&jill
start = newBodyStartLabel;
}
super.visitLocalVariable(name, desc, signature, start, end, index);
}
});
constructorVisitor.visitEnd();
AsmUtil.genClosureFields(TransformationUtilsKt.toNameTypePair(TransformationUtilsKt.filterSkipped(newFieldsWithSkipped)), classBuilder);
}
Aggregations