Search in sources :

Example 1 with FunctionClassDescriptor

use of org.jetbrains.kotlin.builtins.functions.FunctionClassDescriptor in project kotlin by JetBrains.

the class KotlinTypeMapper method mapToCallableMethod.

@NotNull
public CallableMethod mapToCallableMethod(@NotNull FunctionDescriptor descriptor, boolean superCall) {
    if (descriptor instanceof ConstructorDescriptor) {
        JvmMethodSignature method = mapSignatureSkipGeneric(descriptor.getOriginal());
        Type owner = mapOwner(descriptor);
        String defaultImplDesc = mapDefaultMethod(descriptor.getOriginal(), OwnerKind.IMPLEMENTATION).getDescriptor();
        return new CallableMethod(owner, owner, defaultImplDesc, method, INVOKESPECIAL, null, null, null, false);
    }
    if (descriptor instanceof LocalVariableAccessorDescriptor) {
        ResolvedCall<FunctionDescriptor> delegateAccessorResolvedCall = bindingContext.get(BindingContext.DELEGATED_PROPERTY_RESOLVED_CALL, (VariableAccessorDescriptor) descriptor);
        //noinspection ConstantConditions
        return mapToCallableMethod(delegateAccessorResolvedCall.getResultingDescriptor(), false);
    }
    DeclarationDescriptor functionParent = descriptor.getOriginal().getContainingDeclaration();
    FunctionDescriptor functionDescriptor = findSuperDeclaration(descriptor.getOriginal(), superCall);
    JvmMethodSignature signature;
    Type owner;
    Type ownerForDefaultImpl;
    FunctionDescriptor baseMethodDescriptor;
    int invokeOpcode;
    Type thisClass;
    boolean isInterfaceMember = false;
    if (functionParent instanceof ClassDescriptor) {
        FunctionDescriptor declarationFunctionDescriptor = findAnyDeclaration(functionDescriptor);
        ClassDescriptor currentOwner = (ClassDescriptor) functionParent;
        ClassDescriptor declarationOwner = (ClassDescriptor) declarationFunctionDescriptor.getContainingDeclaration();
        boolean originalIsInterface = isJvmInterface(declarationOwner);
        boolean currentIsInterface = isJvmInterface(currentOwner);
        boolean isInterface = currentIsInterface && originalIsInterface;
        baseMethodDescriptor = findBaseDeclaration(functionDescriptor).getOriginal();
        ClassDescriptor ownerForDefault = (ClassDescriptor) baseMethodDescriptor.getContainingDeclaration();
        ownerForDefaultImpl = isJvmInterface(ownerForDefault) && !isJvm8InterfaceWithDefaults(ownerForDefault) ? mapDefaultImpls(ownerForDefault) : mapClass(ownerForDefault);
        if (isInterface && (superCall || descriptor.getVisibility() == Visibilities.PRIVATE || isAccessor(descriptor))) {
            thisClass = mapClass(currentOwner);
            if (declarationOwner instanceof JavaClassDescriptor || isJvm8InterfaceWithDefaults(declarationOwner)) {
                invokeOpcode = INVOKESPECIAL;
                signature = mapSignatureSkipGeneric(functionDescriptor);
                owner = thisClass;
                isInterfaceMember = true;
            } else {
                invokeOpcode = INVOKESTATIC;
                signature = mapSignatureSkipGeneric(descriptor.getOriginal(), OwnerKind.DEFAULT_IMPLS);
                owner = mapDefaultImpls(currentOwner);
            }
        } else {
            boolean isStaticInvocation = (isStaticDeclaration(functionDescriptor) && !(functionDescriptor instanceof ImportedFromObjectCallableDescriptor)) || isStaticAccessor(functionDescriptor) || CodegenUtilKt.isJvmStaticInObjectOrClass(functionDescriptor);
            if (isStaticInvocation) {
                invokeOpcode = INVOKESTATIC;
                isInterfaceMember = currentIsInterface && currentOwner instanceof JavaClassDescriptor;
            } else if (isInterface) {
                invokeOpcode = INVOKEINTERFACE;
                isInterfaceMember = true;
            } else {
                boolean isPrivateFunInvocation = Visibilities.isPrivate(functionDescriptor.getVisibility());
                invokeOpcode = superCall || isPrivateFunInvocation ? INVOKESPECIAL : INVOKEVIRTUAL;
                isInterfaceMember = superCall && currentIsInterface;
            }
            FunctionDescriptor overriddenSpecialBuiltinFunction = SpecialBuiltinMembers.getOverriddenBuiltinReflectingJvmDescriptor(functionDescriptor.getOriginal());
            FunctionDescriptor functionToCall = overriddenSpecialBuiltinFunction != null && !superCall ? overriddenSpecialBuiltinFunction.getOriginal() : functionDescriptor.getOriginal();
            signature = mapSignatureSkipGeneric(functionToCall);
            ClassDescriptor receiver = (currentIsInterface && !originalIsInterface) || currentOwner instanceof FunctionClassDescriptor ? declarationOwner : currentOwner;
            owner = mapClass(receiver);
            thisClass = owner;
        }
    } else {
        signature = mapSignatureSkipGeneric(functionDescriptor.getOriginal());
        owner = mapOwner(functionDescriptor);
        ownerForDefaultImpl = owner;
        baseMethodDescriptor = functionDescriptor;
        if (functionParent instanceof PackageFragmentDescriptor) {
            invokeOpcode = INVOKESTATIC;
            thisClass = null;
        } else if (functionDescriptor instanceof ConstructorDescriptor) {
            invokeOpcode = INVOKESPECIAL;
            thisClass = null;
        } else {
            invokeOpcode = INVOKEVIRTUAL;
            thisClass = owner;
        }
    }
    Type calleeType = isLocalFunction(functionDescriptor) ? owner : null;
    Type receiverParameterType;
    ReceiverParameterDescriptor receiverParameter = functionDescriptor.getOriginal().getExtensionReceiverParameter();
    if (receiverParameter != null) {
        receiverParameterType = mapType(receiverParameter.getType());
    } else {
        receiverParameterType = null;
    }
    String defaultImplDesc = mapDefaultMethod(baseMethodDescriptor, getKindForDefaultImplCall(baseMethodDescriptor)).getDescriptor();
    return new CallableMethod(owner, ownerForDefaultImpl, defaultImplDesc, signature, invokeOpcode, thisClass, receiverParameterType, calleeType, isJvm8Target ? isInterfaceMember : invokeOpcode == INVOKEINTERFACE);
}
Also used : LocalVariableAccessorDescriptor(org.jetbrains.kotlin.descriptors.impl.LocalVariableAccessorDescriptor) DeserializedClassDescriptor(org.jetbrains.kotlin.serialization.deserialization.descriptors.DeserializedClassDescriptor) FunctionClassDescriptor(org.jetbrains.kotlin.builtins.functions.FunctionClassDescriptor) JavaClassDescriptor(org.jetbrains.kotlin.load.java.descriptors.JavaClassDescriptor) TypeAliasConstructorDescriptor(org.jetbrains.kotlin.descriptors.impl.TypeAliasConstructorDescriptor) IrBuiltinsPackageFragmentDescriptor(org.jetbrains.kotlin.ir.descriptors.IrBuiltinsPackageFragmentDescriptor) JvmMethodSignature(org.jetbrains.kotlin.resolve.jvm.jvmSignature.JvmMethodSignature) FunctionClassDescriptor(org.jetbrains.kotlin.builtins.functions.FunctionClassDescriptor) Type(org.jetbrains.org.objectweb.asm.Type) JavaClassDescriptor(org.jetbrains.kotlin.load.java.descriptors.JavaClassDescriptor) NotNull(org.jetbrains.annotations.NotNull)

Example 2 with FunctionClassDescriptor

use of org.jetbrains.kotlin.builtins.functions.FunctionClassDescriptor in project kotlin by JetBrains.

the class KotlinTypeMapper method writeGenericArguments.

private void writeGenericArguments(@NotNull JvmSignatureWriter signatureVisitor, @NotNull PossiblyInnerType type, @NotNull TypeMappingMode mode) {
    ClassDescriptor classDescriptor = type.getClassDescriptor();
    List<TypeParameterDescriptor> parameters = classDescriptor.getDeclaredTypeParameters();
    List<TypeProjection> arguments = type.getArguments();
    if (classDescriptor instanceof FunctionClassDescriptor && ((FunctionClassDescriptor) classDescriptor).getFunctionKind() == FunctionClassDescriptor.Kind.KFunction) {
        // kotlin.reflect.KFunction{n}<P1, ... Pn, R> is mapped to kotlin.reflect.KFunction<R> on JVM (see JavaToKotlinClassMap).
        // So for these classes, we need to skip all type arguments except the very last one
        writeGenericArguments(signatureVisitor, Collections.singletonList(CollectionsKt.last(arguments)), Collections.singletonList(CollectionsKt.last(parameters)), mode);
        return;
    }
    writeGenericArguments(signatureVisitor, arguments, parameters, mode);
}
Also used : FunctionClassDescriptor(org.jetbrains.kotlin.builtins.functions.FunctionClassDescriptor) DeserializedClassDescriptor(org.jetbrains.kotlin.serialization.deserialization.descriptors.DeserializedClassDescriptor) FunctionClassDescriptor(org.jetbrains.kotlin.builtins.functions.FunctionClassDescriptor) JavaClassDescriptor(org.jetbrains.kotlin.load.java.descriptors.JavaClassDescriptor)

Aggregations

FunctionClassDescriptor (org.jetbrains.kotlin.builtins.functions.FunctionClassDescriptor)2 JavaClassDescriptor (org.jetbrains.kotlin.load.java.descriptors.JavaClassDescriptor)2 DeserializedClassDescriptor (org.jetbrains.kotlin.serialization.deserialization.descriptors.DeserializedClassDescriptor)2 NotNull (org.jetbrains.annotations.NotNull)1 LocalVariableAccessorDescriptor (org.jetbrains.kotlin.descriptors.impl.LocalVariableAccessorDescriptor)1 TypeAliasConstructorDescriptor (org.jetbrains.kotlin.descriptors.impl.TypeAliasConstructorDescriptor)1 IrBuiltinsPackageFragmentDescriptor (org.jetbrains.kotlin.ir.descriptors.IrBuiltinsPackageFragmentDescriptor)1 JvmMethodSignature (org.jetbrains.kotlin.resolve.jvm.jvmSignature.JvmMethodSignature)1 Type (org.jetbrains.org.objectweb.asm.Type)1