Search in sources :

Example 1 with JavaClassDescriptor

use of org.jetbrains.kotlin.load.java.descriptors.JavaClassDescriptor 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 JavaClassDescriptor

use of org.jetbrains.kotlin.load.java.descriptors.JavaClassDescriptor in project kotlin by JetBrains.

the class SamWrapperCodegen method getWrapperName.

@NotNull
private FqName getWrapperName(@NotNull KtFile containingFile) {
    FqName fileClassFqName = JvmFileClassUtil.getFileClassInfoNoResolve(containingFile).getFileClassFqName();
    JavaClassDescriptor descriptor = samType.getJavaClassDescriptor();
    int hash = PackagePartClassUtils.getPathHashCode(containingFile.getVirtualFile()) * 31 + DescriptorUtils.getFqNameSafe(descriptor).hashCode();
    String shortName = String.format("%s$sam$%s%s$%08x", fileClassFqName.shortName().asString(), descriptor.getName().asString(), (isInsideInline ? "$i" : ""), hash);
    return fileClassFqName.parent().child(Name.identifier(shortName));
}
Also used : FqName(org.jetbrains.kotlin.name.FqName) JavaClassDescriptor(org.jetbrains.kotlin.load.java.descriptors.JavaClassDescriptor) NotNull(org.jetbrains.annotations.NotNull)

Example 3 with JavaClassDescriptor

use of org.jetbrains.kotlin.load.java.descriptors.JavaClassDescriptor in project kotlin by JetBrains.

the class ImplementationBodyCodegen method generateToArray.

private void generateToArray() {
    if (descriptor.getKind() == ClassKind.INTERFACE)
        return;
    final KotlinBuiltIns builtIns = DescriptorUtilsKt.getBuiltIns(descriptor);
    if (!isSubclass(descriptor, builtIns.getCollection()))
        return;
    if (CollectionsKt.any(DescriptorUtilsKt.getAllSuperclassesWithoutAny(descriptor), new Function1<ClassDescriptor, Boolean>() {

        @Override
        public Boolean invoke(ClassDescriptor classDescriptor) {
            return !(classDescriptor instanceof JavaClassDescriptor) && isSubclass(classDescriptor, builtIns.getCollection());
        }
    }))
        return;
    Collection<SimpleFunctionDescriptor> functions = descriptor.getDefaultType().getMemberScope().getContributedFunctions(Name.identifier("toArray"), NoLookupLocation.FROM_BACKEND);
    boolean hasGenericToArray = false;
    boolean hasNonGenericToArray = false;
    for (FunctionDescriptor function : functions) {
        hasGenericToArray |= isGenericToArray(function);
        hasNonGenericToArray |= isNonGenericToArray(function);
    }
    if (!hasNonGenericToArray) {
        MethodVisitor mv = v.newMethod(NO_ORIGIN, ACC_PUBLIC, "toArray", "()[Ljava/lang/Object;", null, null);
        InstructionAdapter iv = new InstructionAdapter(mv);
        mv.visitCode();
        iv.load(0, classAsmType);
        iv.invokestatic("kotlin/jvm/internal/CollectionToArray", "toArray", "(Ljava/util/Collection;)[Ljava/lang/Object;", false);
        iv.areturn(Type.getType("[Ljava/lang/Object;"));
        FunctionCodegen.endVisit(mv, "toArray", myClass);
    }
    if (!hasGenericToArray) {
        MethodVisitor mv = v.newMethod(NO_ORIGIN, ACC_PUBLIC, "toArray", "([Ljava/lang/Object;)[Ljava/lang/Object;", "<T:Ljava/lang/Object;>([TT;)[TT;", null);
        InstructionAdapter iv = new InstructionAdapter(mv);
        mv.visitCode();
        iv.load(0, classAsmType);
        iv.load(1, Type.getType("[Ljava/lang/Object;"));
        iv.invokestatic("kotlin/jvm/internal/CollectionToArray", "toArray", "(Ljava/util/Collection;[Ljava/lang/Object;)[Ljava/lang/Object;", false);
        iv.areturn(Type.getType("[Ljava/lang/Object;"));
        FunctionCodegen.endVisit(mv, "toArray", myClass);
    }
}
Also used : JavaClassDescriptor(org.jetbrains.kotlin.load.java.descriptors.JavaClassDescriptor) InstructionAdapter(org.jetbrains.org.objectweb.asm.commons.InstructionAdapter) KotlinBuiltIns(org.jetbrains.kotlin.builtins.KotlinBuiltIns) JavaClassDescriptor(org.jetbrains.kotlin.load.java.descriptors.JavaClassDescriptor) MethodVisitor(org.jetbrains.org.objectweb.asm.MethodVisitor)

Aggregations

JavaClassDescriptor (org.jetbrains.kotlin.load.java.descriptors.JavaClassDescriptor)3 NotNull (org.jetbrains.annotations.NotNull)2 KotlinBuiltIns (org.jetbrains.kotlin.builtins.KotlinBuiltIns)1 FunctionClassDescriptor (org.jetbrains.kotlin.builtins.functions.FunctionClassDescriptor)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 FqName (org.jetbrains.kotlin.name.FqName)1 JvmMethodSignature (org.jetbrains.kotlin.resolve.jvm.jvmSignature.JvmMethodSignature)1 DeserializedClassDescriptor (org.jetbrains.kotlin.serialization.deserialization.descriptors.DeserializedClassDescriptor)1 MethodVisitor (org.jetbrains.org.objectweb.asm.MethodVisitor)1 Type (org.jetbrains.org.objectweb.asm.Type)1 InstructionAdapter (org.jetbrains.org.objectweb.asm.commons.InstructionAdapter)1