Search in sources :

Example 1 with FieldInfo

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);
}
Also used : StackValue(org.jetbrains.kotlin.codegen.StackValue) InstructionAdapter(org.jetbrains.org.objectweb.asm.commons.InstructionAdapter) FieldInfo(org.jetbrains.kotlin.codegen.FieldInfo)

Aggregations

FieldInfo (org.jetbrains.kotlin.codegen.FieldInfo)1 StackValue (org.jetbrains.kotlin.codegen.StackValue)1 InstructionAdapter (org.jetbrains.org.objectweb.asm.commons.InstructionAdapter)1