Search in sources :

Example 1 with JvmMethodParameterKind

use of org.jetbrains.kotlin.resolve.jvm.jvmSignature.JvmMethodParameterKind 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 JvmMethodParameterKind

use of org.jetbrains.kotlin.resolve.jvm.jvmSignature.JvmMethodParameterKind in project kotlin by JetBrains.

the class ImplementationBodyCodegen method generateSuperCallImplicitArguments.

@NotNull
private ArgumentGenerator generateSuperCallImplicitArguments(@NotNull InstructionAdapter iv, @NotNull ExpressionCodegen codegen, @NotNull ConstructorDescriptor constructorDescriptor, @NotNull ConstructorDescriptor superConstructor, @NotNull CallableMethod superCallable, @NotNull List<JvmMethodParameterSignature> superParameters, @NotNull List<JvmMethodParameterSignature> parameters) {
    int offset = 1;
    int superIndex = 0;
    // them all onto the stack and update "offset" variable so that in the end it points to the slot of the first VALUE argument
    for (JvmMethodParameterSignature parameter : parameters) {
        if (superIndex >= superParameters.size())
            break;
        JvmMethodParameterKind superKind = superParameters.get(superIndex).getKind();
        JvmMethodParameterKind kind = parameter.getKind();
        Type type = parameter.getAsmType();
        if (superKind == JvmMethodParameterKind.VALUE && kind == JvmMethodParameterKind.SUPER_CALL_PARAM) {
            // Stop when we reach the actual value parameters present in the code; they will be generated via ResolvedCall below
            break;
        }
        if (superKind == JvmMethodParameterKind.OUTER) {
            assert kind == JvmMethodParameterKind.OUTER || kind == JvmMethodParameterKind.SUPER_CALL_PARAM : String.format("Non-outer parameter incorrectly mapped to outer for %s: %s vs %s", constructorDescriptor, parameters, superParameters);
            // Super constructor requires OUTER parameter, but our OUTER instance may be different from what is expected by the super
            // constructor. We need to traverse our outer classes from the bottom up, to find the needed class. See innerExtendsOuter.kt
            ClassDescriptor outerForSuper = (ClassDescriptor) superConstructor.getContainingDeclaration().getContainingDeclaration();
            StackValue outer = codegen.generateThisOrOuter(outerForSuper, true, true);
            outer.put(outer.type, codegen.v);
            superIndex++;
        } else if (kind == JvmMethodParameterKind.SUPER_CALL_PARAM || kind == JvmMethodParameterKind.ENUM_NAME_OR_ORDINAL) {
            iv.load(offset, type);
            superIndex++;
        }
        offset += type.getSize();
    }
    if (isAnonymousObject(descriptor)) {
        List<JvmMethodParameterSignature> superValues = superParameters.subList(superIndex, superParameters.size());
        return new ObjectSuperCallArgumentGenerator(superValues, iv, offset);
    } else {
        return new CallBasedArgumentGenerator(codegen, codegen.defaultCallGenerator, superConstructor.getValueParameters(), superCallable.getValueParameterTypes());
    }
}
Also used : Type(org.jetbrains.org.objectweb.asm.Type) KotlinType(org.jetbrains.kotlin.types.KotlinType) Type.getObjectType(org.jetbrains.org.objectweb.asm.Type.getObjectType) JvmMethodParameterSignature(org.jetbrains.kotlin.resolve.jvm.jvmSignature.JvmMethodParameterSignature) JavaClassDescriptor(org.jetbrains.kotlin.load.java.descriptors.JavaClassDescriptor) JvmMethodParameterKind(org.jetbrains.kotlin.resolve.jvm.jvmSignature.JvmMethodParameterKind) NotNull(org.jetbrains.annotations.NotNull) BindingContextUtils.getNotNull(org.jetbrains.kotlin.resolve.BindingContextUtils.getNotNull)

Example 3 with JvmMethodParameterKind

use of org.jetbrains.kotlin.resolve.jvm.jvmSignature.JvmMethodParameterKind in project kotlin by JetBrains.

the class ImplementationBodyCodegen method generateThisCallImplicitArguments.

@NotNull
private static ArgumentGenerator generateThisCallImplicitArguments(@NotNull InstructionAdapter iv, @NotNull ExpressionCodegen codegen, @NotNull ConstructorDescriptor delegatingConstructor, @NotNull CallableMethod delegatingCallable, @NotNull List<JvmMethodParameterSignature> delegatingParameters, @NotNull List<JvmMethodParameterSignature> parameters) {
    int offset = 1;
    int index = 0;
    for (; index < delegatingParameters.size(); index++) {
        JvmMethodParameterKind delegatingKind = delegatingParameters.get(index).getKind();
        if (delegatingKind == JvmMethodParameterKind.VALUE) {
            assert index == parameters.size() || parameters.get(index).getKind() == JvmMethodParameterKind.VALUE : "Delegating constructor has not enough implicit parameters";
            break;
        }
        assert index < parameters.size() && parameters.get(index).getKind() == delegatingKind : "Constructors of the same class should have the same set of implicit arguments";
        JvmMethodParameterSignature parameter = parameters.get(index);
        iv.load(offset, parameter.getAsmType());
        offset += parameter.getAsmType().getSize();
    }
    assert index == parameters.size() || parameters.get(index).getKind() == JvmMethodParameterKind.VALUE : "Delegating constructor has not enough parameters";
    return new CallBasedArgumentGenerator(codegen, codegen.defaultCallGenerator, delegatingConstructor.getValueParameters(), delegatingCallable.getValueParameterTypes());
}
Also used : JvmMethodParameterSignature(org.jetbrains.kotlin.resolve.jvm.jvmSignature.JvmMethodParameterSignature) JvmMethodParameterKind(org.jetbrains.kotlin.resolve.jvm.jvmSignature.JvmMethodParameterKind) NotNull(org.jetbrains.annotations.NotNull) BindingContextUtils.getNotNull(org.jetbrains.kotlin.resolve.BindingContextUtils.getNotNull)

Example 4 with JvmMethodParameterKind

use of org.jetbrains.kotlin.resolve.jvm.jvmSignature.JvmMethodParameterKind in project kotlin by JetBrains.

the class FunctionCodegen method generateLocalVariablesForParameters.

private static void generateLocalVariablesForParameters(@NotNull MethodVisitor mv, @NotNull JvmMethodSignature jvmMethodSignature, @Nullable Type thisType, @NotNull Label methodBegin, @NotNull Label methodEnd, Collection<ValueParameterDescriptor> valueParameters, boolean isStatic, KotlinTypeMapper typeMapper, int shiftForDestructuringVariables) {
    Iterator<ValueParameterDescriptor> valueParameterIterator = valueParameters.iterator();
    List<JvmMethodParameterSignature> params = jvmMethodSignature.getValueParameters();
    int shift = 0;
    if (!isStatic) {
        //add this
        if (thisType != null) {
            mv.visitLocalVariable("this", thisType.getDescriptor(), null, methodBegin, methodEnd, shift);
        } else {
        //TODO: provide thisType for callable reference
        }
        shift++;
    }
    for (int i = 0; i < params.size(); i++) {
        JvmMethodParameterSignature param = params.get(i);
        JvmMethodParameterKind kind = param.getKind();
        String parameterName;
        if (kind == JvmMethodParameterKind.VALUE) {
            ValueParameterDescriptor parameter = valueParameterIterator.next();
            List<VariableDescriptor> destructuringVariables = ValueParameterDescriptorImpl.getDestructuringVariablesOrNull(parameter);
            parameterName = destructuringVariables == null ? computeParameterName(i, parameter) : "$" + joinParameterNames(destructuringVariables);
        } else {
            String lowercaseKind = kind.name().toLowerCase();
            parameterName = needIndexForVar(kind) ? "$" + lowercaseKind + "$" + i : "$" + lowercaseKind;
        }
        Type type = param.getAsmType();
        mv.visitLocalVariable(parameterName, type.getDescriptor(), null, methodBegin, methodEnd, shift);
        shift += type.getSize();
    }
    shift += shiftForDestructuringVariables;
    for (ValueParameterDescriptor parameter : valueParameters) {
        List<VariableDescriptor> destructuringVariables = ValueParameterDescriptorImpl.getDestructuringVariablesOrNull(parameter);
        if (destructuringVariables == null)
            continue;
        for (VariableDescriptor entry : CodegenUtilKt.filterOutDescriptorsWithSpecialNames(destructuringVariables)) {
            Type type = typeMapper.mapType(entry.getType());
            mv.visitLocalVariable(entry.getName().asString(), type.getDescriptor(), null, methodBegin, methodEnd, shift);
            shift += type.getSize();
        }
    }
}
Also used : KotlinType(org.jetbrains.kotlin.types.KotlinType) JvmMethodParameterSignature(org.jetbrains.kotlin.resolve.jvm.jvmSignature.JvmMethodParameterSignature) JvmMethodParameterKind(org.jetbrains.kotlin.resolve.jvm.jvmSignature.JvmMethodParameterKind)

Example 5 with JvmMethodParameterKind

use of org.jetbrains.kotlin.resolve.jvm.jvmSignature.JvmMethodParameterKind in project kotlin by JetBrains.

the class KotlinTypeMapper method writeSuperConstructorCallParameters.

private void writeSuperConstructorCallParameters(@NotNull JvmSignatureWriter sw, @NotNull ClassConstructorDescriptor descriptor, @NotNull ResolvedCall<ConstructorDescriptor> superCall, boolean hasOuter) {
    ConstructorDescriptor superDescriptor = SamCodegenUtil.resolveSamAdapter(superCall.getResultingDescriptor());
    List<ResolvedValueArgument> valueArguments = superCall.getValueArgumentsByIndex();
    assert valueArguments != null : "Failed to arrange value arguments by index: " + superDescriptor;
    List<JvmMethodParameterSignature> parameters = mapSignatureSkipGeneric(superDescriptor.getOriginal()).getValueParameters();
    int params = parameters.size();
    int args = valueArguments.size();
    // Mapped parameters should consist of captured values plus all of valueArguments
    assert params >= args : String.format("Incorrect number of mapped parameters vs arguments: %d < %d for %s", params, args, descriptor);
    // Include all captured values, i.e. those parameters for which there are no resolved value arguments
    for (int i = 0; i < params - args; i++) {
        JvmMethodParameterSignature parameter = parameters.get(i);
        JvmMethodParameterKind kind = parameter.getKind();
        if (kind == JvmMethodParameterKind.ENUM_NAME_OR_ORDINAL)
            continue;
        if (hasOuter && kind == JvmMethodParameterKind.OUTER)
            continue;
        writeParameter(sw, JvmMethodParameterKind.SUPER_CALL_PARAM, parameter.getAsmType());
    }
    if (isAnonymousObject(descriptor.getContainingDeclaration())) {
        // For anonymous objects, also add all real non-default value arguments passed to the super constructor
        for (int i = 0; i < args; i++) {
            ResolvedValueArgument valueArgument = valueArguments.get(i);
            JvmMethodParameterSignature parameter = parameters.get(params - args + i);
            if (!(valueArgument instanceof DefaultValueArgument)) {
                writeParameter(sw, JvmMethodParameterKind.SUPER_CALL_PARAM, parameter.getAsmType());
            }
        }
    }
}
Also used : ResolvedValueArgument(org.jetbrains.kotlin.resolve.calls.model.ResolvedValueArgument) JvmMethodParameterSignature(org.jetbrains.kotlin.resolve.jvm.jvmSignature.JvmMethodParameterSignature) JvmMethodParameterKind(org.jetbrains.kotlin.resolve.jvm.jvmSignature.JvmMethodParameterKind) TypeAliasConstructorDescriptor(org.jetbrains.kotlin.descriptors.impl.TypeAliasConstructorDescriptor) DefaultValueArgument(org.jetbrains.kotlin.resolve.calls.model.DefaultValueArgument)

Aggregations

JvmMethodParameterKind (org.jetbrains.kotlin.resolve.jvm.jvmSignature.JvmMethodParameterKind)5 JvmMethodParameterSignature (org.jetbrains.kotlin.resolve.jvm.jvmSignature.JvmMethodParameterSignature)5 NotNull (org.jetbrains.annotations.NotNull)2 BindingContextUtils.getNotNull (org.jetbrains.kotlin.resolve.BindingContextUtils.getNotNull)2 KotlinType (org.jetbrains.kotlin.types.KotlinType)2 AnnotatedWithOnlyTargetedAnnotations (org.jetbrains.kotlin.codegen.annotation.AnnotatedWithOnlyTargetedAnnotations)1 KotlinTypeMapper (org.jetbrains.kotlin.codegen.state.KotlinTypeMapper)1 Annotated (org.jetbrains.kotlin.descriptors.annotations.Annotated)1 TypeAliasConstructorDescriptor (org.jetbrains.kotlin.descriptors.impl.TypeAliasConstructorDescriptor)1 JavaClassDescriptor (org.jetbrains.kotlin.load.java.descriptors.JavaClassDescriptor)1 DefaultValueArgument (org.jetbrains.kotlin.resolve.calls.model.DefaultValueArgument)1 ResolvedValueArgument (org.jetbrains.kotlin.resolve.calls.model.ResolvedValueArgument)1 Type (org.jetbrains.org.objectweb.asm.Type)1 Type.getObjectType (org.jetbrains.org.objectweb.asm.Type.getObjectType)1