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

org.jetbrains.kotlin.backend.jvm.extensions.JvmIrDeclarationOrigin.kt Maven / Gradle / Ivy

There is a newer version: 2.1.0-RC
Show newest version
/*
 * Copyright 2010-2023 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.backend.jvm.extensions

import com.intellij.psi.PsiElement
import org.jetbrains.kotlin.backend.common.psi.PsiSourceManager
import org.jetbrains.kotlin.backend.jvm.JvmLoweredDeclarationOrigin
import org.jetbrains.kotlin.backend.jvm.ir.isEffectivelyInlineOnly
import org.jetbrains.kotlin.backend.jvm.ir.psiElement
import org.jetbrains.kotlin.ir.declarations.*
import org.jetbrains.kotlin.ir.descriptors.toIrBasedDescriptor
import org.jetbrains.kotlin.psi.KtPropertyDelegate
import org.jetbrains.kotlin.resolve.jvm.diagnostics.JvmDeclarationOrigin
import org.jetbrains.kotlin.resolve.jvm.diagnostics.JvmDeclarationOriginKind

class JvmIrDeclarationOrigin(
    originKind: JvmDeclarationOriginKind,
    element: PsiElement?,
    val declaration: IrDeclaration?,
) : JvmDeclarationOrigin(originKind, element, declaration?.toIrBasedDescriptor(), null) {
    override val originalSourceElement: Any?
        get() = (declaration as? IrAttributeContainer)?.attributeOwnerId
}

val IrDeclaration.descriptorOrigin: JvmIrDeclarationOrigin
    get() {
        val psiElement = findPsiElementForDeclarationOrigin()
        return when {
            origin == IrDeclarationOrigin.FILE_CLASS ->
                JvmIrDeclarationOrigin(JvmDeclarationOriginKind.PACKAGE_PART, psiElement, this)
            (this is IrSimpleFunction && isSuspend && isEffectivelyInlineOnly()) ||
                    origin == JvmLoweredDeclarationOrigin.FOR_INLINE_STATE_MACHINE_TEMPLATE ||
                    origin == JvmLoweredDeclarationOrigin.FOR_INLINE_STATE_MACHINE_TEMPLATE_CAPTURES_CROSSINLINE ->
                JvmIrDeclarationOrigin(JvmDeclarationOriginKind.INLINE_VERSION_OF_SUSPEND_FUN, psiElement, this)
            else -> JvmIrDeclarationOrigin(JvmDeclarationOriginKind.OTHER, psiElement, this)
        }
    }

private fun IrDeclaration.findPsiElementForDeclarationOrigin(): PsiElement? {
    // For synthetic $annotations methods for properties, use the PSI for the property or the constructor parameter.
    // It's used in KAPT stub generation to sort the properties correctly based on their source position (see KT-44130).
    if (this is IrFunction && name.asString().endsWith("\$annotations")) {
        val metadata = metadata as? DescriptorMetadataSource.Property
        if (metadata != null) {
            return metadata.descriptor.psiElement
        }
    }

    val element = PsiSourceManager.findPsiElement(this)

    // Offsets for accessors and field of delegated property in IR point to the 'by' keyword, so the closest PSI element is the
    // KtPropertyDelegate (`by ...` expression). However, old JVM backend passed the PSI element of the property instead.
    // This is important for example in case of KAPT stub generation in the "correct error types" mode, which tries to find the
    // PSI element for each declaration with unresolved types and tries to heuristically "resolve" those unresolved types to
    // generate them into the Java stub. In case of delegated property accessors, it should look for the property declaration,
    // since the type can only be provided there, and not in the `by ...` expression.
    return if (element is KtPropertyDelegate) element.parent else element
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy