All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.jetbrains.kotlin.codegen.inlineClassesCodegenUtil.kt Maven / Gradle / Ivy

There is a newer version: 2.1.0-RC
Show newest version
/*
 * Copyright 2010-2020 JetBrains s.r.o. and Kotlin Programming Language contributors.
 * Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
 */

package org.jetbrains.kotlin.codegen

import org.jetbrains.kotlin.codegen.state.GenerationState
import org.jetbrains.kotlin.descriptors.*
import org.jetbrains.kotlin.descriptors.impl.AnonymousFunctionDescriptor
import org.jetbrains.kotlin.load.kotlin.JvmPackagePartSource
import org.jetbrains.kotlin.load.kotlin.VirtualFileFinder
import org.jetbrains.kotlin.name.ClassId
import org.jetbrains.kotlin.resolve.descriptorUtil.classId
import org.jetbrains.kotlin.resolve.descriptorUtil.inlineClassRepresentation
import org.jetbrains.kotlin.serialization.deserialization.descriptors.DeserializedClassDescriptor
import org.jetbrains.kotlin.serialization.deserialization.descriptors.DeserializedSimpleFunctionDescriptor
import org.jetbrains.kotlin.types.KotlinType
import org.jetbrains.kotlin.types.typeUtil.isAnyOrNullableAny
import org.jetbrains.kotlin.types.typeUtil.isTypeParameter
import org.jetbrains.org.objectweb.asm.ClassReader
import org.jetbrains.org.objectweb.asm.ClassVisitor
import org.jetbrains.org.objectweb.asm.MethodVisitor
import org.jetbrains.org.objectweb.asm.Opcodes
import org.jetbrains.org.objectweb.asm.commons.Method

fun KotlinType.isInlineClassWithUnderlyingTypeAnyOrAnyN(): Boolean {
    val classDescriptor = constructor.declarationDescriptor
    return classDescriptor is ClassDescriptor && classDescriptor.inlineClassRepresentation?.underlyingType?.isAnyOrNullableAny() == true
}

fun CallableDescriptor.isGenericParameter(): Boolean {
    if (this !is ValueParameterDescriptor) return false
    if (containingDeclaration is AnonymousFunctionDescriptor) return true
    val index = containingDeclaration.valueParameters.indexOf(this)
    return containingDeclaration.overriddenDescriptors.any { it.original.valueParameters[index].type.isTypeParameter() }
}

fun classFileContainsMethod(descriptor: FunctionDescriptor, state: GenerationState, method: Method): Boolean? {
    if (descriptor !is DeserializedSimpleFunctionDescriptor) return null

    if (descriptor.kind == CallableMemberDescriptor.Kind.FAKE_OVERRIDE) {
        return descriptor.overriddenDescriptors.any { classFileContainsMethod(it, state, method) == true }
    }

    val classId: ClassId = when {
        descriptor.containingDeclaration is DeserializedClassDescriptor -> {
            (descriptor.containingDeclaration as DeserializedClassDescriptor).classId ?: return null
        }
        descriptor.containerSource is JvmPackagePartSource -> {
            (descriptor.containerSource as JvmPackagePartSource).classId
        }
        else -> {
            return null
        }
    }

    return classFileContainsMethod(classId, state, method)
}

fun classFileContainsMethod(classId: ClassId, state: GenerationState, method: Method): Boolean? {
    val bytes = VirtualFileFinder.getInstance(state.project, state.module).findVirtualFileWithHeader(classId)
        ?.contentsToByteArray() ?: return null
    var found = false
    ClassReader(bytes).accept(object : ClassVisitor(Opcodes.API_VERSION) {
        override fun visitMethod(
            access: Int,
            name: String?,
            descriptor: String?,
            signature: String?,
            exceptions: Array?
        ): MethodVisitor? {
            if (name == method.name && descriptor == method.descriptor) {
                found = true
            }
            return super.visitMethod(access, name, descriptor, signature, exceptions)
        }
    }, ClassReader.SKIP_FRAMES)
    return found
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy