Search in sources :

Example 1 with KotlinTypeMapper

use of org.jetbrains.kotlin.codegen.state.KotlinTypeMapper in project kotlin by JetBrains.

the class FunctionCodegen method generateParameterAnnotations.

public static void generateParameterAnnotations(@NotNull FunctionDescriptor functionDescriptor, @NotNull MethodVisitor mv, @NotNull JvmMethodSignature jvmSignature, @NotNull List<ValueParameterDescriptor> valueParameters, @NotNull InnerClassConsumer innerClassConsumer, @NotNull GenerationState state) {
    KotlinTypeMapper typeMapper = state.getTypeMapper();
    Iterator<ValueParameterDescriptor> iterator = valueParameters.iterator();
    List<JvmMethodParameterSignature> kotlinParameterTypes = jvmSignature.getValueParameters();
    for (int i = 0; i < kotlinParameterTypes.size(); i++) {
        JvmMethodParameterSignature parameterSignature = kotlinParameterTypes.get(i);
        JvmMethodParameterKind kind = parameterSignature.getKind();
        if (kind.isSkippedInGenericSignature()) {
            markEnumOrInnerConstructorParameterAsSynthetic(mv, i, state.getClassBuilderMode());
            continue;
        }
        if (kind == JvmMethodParameterKind.VALUE) {
            ValueParameterDescriptor parameter = iterator.next();
            AnnotationCodegen annotationCodegen = AnnotationCodegen.forParameter(i, mv, innerClassConsumer, typeMapper);
            if (functionDescriptor instanceof PropertySetterDescriptor) {
                PropertyDescriptor propertyDescriptor = ((PropertySetterDescriptor) functionDescriptor).getCorrespondingProperty();
                Annotated targetedAnnotations = new AnnotatedWithOnlyTargetedAnnotations(propertyDescriptor);
                annotationCodegen.genAnnotations(targetedAnnotations, parameterSignature.getAsmType(), SETTER_PARAMETER);
            }
            if (functionDescriptor instanceof ConstructorDescriptor) {
                annotationCodegen.genAnnotations(parameter, parameterSignature.getAsmType(), CONSTRUCTOR_PARAMETER);
            } else {
                annotationCodegen.genAnnotations(parameter, parameterSignature.getAsmType());
            }
        } else if (kind == JvmMethodParameterKind.RECEIVER) {
            ReceiverParameterDescriptor receiver = JvmCodegenUtil.getDirectMember(functionDescriptor).getExtensionReceiverParameter();
            if (receiver != null) {
                AnnotationCodegen annotationCodegen = AnnotationCodegen.forParameter(i, mv, innerClassConsumer, typeMapper);
                Annotated targetedAnnotations = new AnnotatedWithOnlyTargetedAnnotations(receiver.getType());
                annotationCodegen.genAnnotations(targetedAnnotations, parameterSignature.getAsmType(), RECEIVER);
                annotationCodegen.genAnnotations(receiver, parameterSignature.getAsmType());
            }
        }
    }
}
Also used : JvmMethodParameterSignature(org.jetbrains.kotlin.resolve.jvm.jvmSignature.JvmMethodParameterSignature) JvmMethodParameterKind(org.jetbrains.kotlin.resolve.jvm.jvmSignature.JvmMethodParameterKind) Annotated(org.jetbrains.kotlin.descriptors.annotations.Annotated) AnnotatedWithOnlyTargetedAnnotations(org.jetbrains.kotlin.codegen.annotation.AnnotatedWithOnlyTargetedAnnotations) KotlinTypeMapper(org.jetbrains.kotlin.codegen.state.KotlinTypeMapper)

Example 2 with KotlinTypeMapper

use of org.jetbrains.kotlin.codegen.state.KotlinTypeMapper in project kotlin by JetBrains.

the class FunctionCodegen method generateMethodBody.

public static void generateMethodBody(@NotNull MethodVisitor mv, @NotNull FunctionDescriptor functionDescriptor, @NotNull MethodContext context, @NotNull JvmMethodSignature signature, @NotNull FunctionGenerationStrategy strategy, @NotNull MemberCodegen<?> parentCodegen) {
    mv.visitCode();
    Label methodBegin = new Label();
    mv.visitLabel(methodBegin);
    KotlinTypeMapper typeMapper = parentCodegen.typeMapper;
    if (BuiltinSpecialBridgesUtil.shouldHaveTypeSafeBarrier(functionDescriptor, getSignatureMapper(typeMapper))) {
        generateTypeCheckBarrierIfNeeded(new InstructionAdapter(mv), functionDescriptor, signature.getReturnType(), /* delegateParameterTypes = */
        null);
    }
    Label methodEnd;
    int functionFakeIndex = -1;
    int lambdaFakeIndex = -1;
    if (context.getParentContext() instanceof MultifileClassFacadeContext) {
        generateFacadeDelegateMethodBody(mv, signature.getAsmMethod(), (MultifileClassFacadeContext) context.getParentContext());
        methodEnd = new Label();
    } else if (OwnerKind.DEFAULT_IMPLS == context.getContextKind() && isJvm8InterfaceWithDefaultsMember(functionDescriptor, parentCodegen.state)) {
        int flags = AsmUtil.getMethodAsmFlags(functionDescriptor, OwnerKind.DEFAULT_IMPLS, context.getState());
        assert (flags & Opcodes.ACC_ABSTRACT) == 0 : "Interface method with body should be non-abstract" + functionDescriptor;
        Type type = typeMapper.mapOwner(functionDescriptor);
        Method asmMethod = typeMapper.mapAsmMethod(functionDescriptor, OwnerKind.DEFAULT_IMPLS);
        generateDelegateToStaticMethodBody(true, mv, new Method(asmMethod.getName() + JvmAbi.DEFAULT_IMPLS_DELEGATE_SUFFIX, asmMethod.getDescriptor()), type.getInternalName());
        methodEnd = new Label();
    } else {
        FrameMap frameMap = createFrameMap(parentCodegen.state, functionDescriptor, signature, isStaticMethod(context.getContextKind(), functionDescriptor));
        if (context.isInlineMethodContext()) {
            functionFakeIndex = frameMap.enterTemp(Type.INT_TYPE);
        }
        if (context instanceof InlineLambdaContext) {
            lambdaFakeIndex = frameMap.enterTemp(Type.INT_TYPE);
        }
        Label methodEntry = new Label();
        mv.visitLabel(methodEntry);
        context.setMethodStartLabel(methodEntry);
        if (!KotlinTypeMapper.isAccessor(functionDescriptor)) {
            genNotNullAssertionsForParameters(new InstructionAdapter(mv), parentCodegen.state, functionDescriptor, frameMap);
        }
        parentCodegen.beforeMethodBody(mv);
        methodEnd = new Label();
        context.setMethodEndLabel(methodEnd);
        strategy.generateBody(mv, frameMap, signature, context, parentCodegen);
    }
    mv.visitLabel(methodEnd);
    Type thisType = getThisTypeForFunction(functionDescriptor, context, typeMapper);
    generateLocalVariableTable(mv, signature, functionDescriptor, thisType, methodBegin, methodEnd, context.getContextKind(), typeMapper, (functionFakeIndex >= 0 ? 1 : 0) + (lambdaFakeIndex >= 0 ? 1 : 0));
    //TODO: it's best to move all below logic to 'generateLocalVariableTable' method
    if (context.isInlineMethodContext() && functionFakeIndex != -1) {
        mv.visitLocalVariable(JvmAbi.LOCAL_VARIABLE_NAME_PREFIX_INLINE_FUNCTION + typeMapper.mapAsmMethod(functionDescriptor).getName(), Type.INT_TYPE.getDescriptor(), null, methodBegin, methodEnd, functionFakeIndex);
    }
    if (context instanceof InlineLambdaContext && thisType != null && lambdaFakeIndex != -1) {
        String name = thisType.getClassName();
        int indexOfLambdaOrdinal = name.lastIndexOf("$");
        if (indexOfLambdaOrdinal > 0) {
            int lambdaOrdinal = Integer.parseInt(name.substring(indexOfLambdaOrdinal + 1));
            KtPureElement functionArgument = parentCodegen.element;
            String functionName = "unknown";
            if (functionArgument instanceof KtFunction) {
                ValueParameterDescriptor inlineArgumentDescriptor = InlineUtil.getInlineArgumentDescriptor((KtFunction) functionArgument, parentCodegen.bindingContext);
                if (inlineArgumentDescriptor != null) {
                    functionName = inlineArgumentDescriptor.getContainingDeclaration().getName().asString();
                }
            }
            mv.visitLocalVariable(JvmAbi.LOCAL_VARIABLE_NAME_PREFIX_INLINE_ARGUMENT + lambdaOrdinal + "$" + functionName, Type.INT_TYPE.getDescriptor(), null, methodBegin, methodEnd, lambdaFakeIndex);
        }
    }
}
Also used : Method(org.jetbrains.org.objectweb.asm.commons.Method) KotlinType(org.jetbrains.kotlin.types.KotlinType) InstructionAdapter(org.jetbrains.org.objectweb.asm.commons.InstructionAdapter) KotlinTypeMapper(org.jetbrains.kotlin.codegen.state.KotlinTypeMapper)

Aggregations

KotlinTypeMapper (org.jetbrains.kotlin.codegen.state.KotlinTypeMapper)2 AnnotatedWithOnlyTargetedAnnotations (org.jetbrains.kotlin.codegen.annotation.AnnotatedWithOnlyTargetedAnnotations)1 Annotated (org.jetbrains.kotlin.descriptors.annotations.Annotated)1 JvmMethodParameterKind (org.jetbrains.kotlin.resolve.jvm.jvmSignature.JvmMethodParameterKind)1 JvmMethodParameterSignature (org.jetbrains.kotlin.resolve.jvm.jvmSignature.JvmMethodParameterSignature)1 KotlinType (org.jetbrains.kotlin.types.KotlinType)1 InstructionAdapter (org.jetbrains.org.objectweb.asm.commons.InstructionAdapter)1 Method (org.jetbrains.org.objectweb.asm.commons.Method)1