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

org.jetbrains.kotlin.analysis.api.symbols.KtSymbol.kt Maven / Gradle / Ivy

There is a newer version: 2.1.0-Beta1
Show newest version
/*
 * Copyright 2010-2022 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.analysis.api.symbols

import com.intellij.psi.PsiElement
import org.jetbrains.kotlin.analysis.api.KtAnalysisSession
import org.jetbrains.kotlin.analysis.api.lifetime.KtLifetimeOwner
import org.jetbrains.kotlin.analysis.api.symbols.pointers.KtSymbolPointer

public interface KtSymbol : KtLifetimeOwner {
    public val origin: KtSymbolOrigin

    /**
     * [PsiElement] which corresponds to given [KtSymbol]
     * If [origin] is one of [KtSymbolOrigin.SOURCE], [KtSymbolOrigin.JAVA], [KtSymbolOrigin.LIBRARY] then the source is not null
     * For other [KtSymbolOrigin] behaviour is undefined
     *
     * For [KtSymbolOrigin.LIBRARY] the generated by Kotlin class file source element is returned
     */
    public val psi: PsiElement?

    context(KtAnalysisSession)
    public fun createPointer(): KtSymbolPointer
}

/**
 * Get symbol [PsiElement] if its type is [PSI], otherwise throws ClassCastException
 *
 * @see KtSymbol.psi
 */
public inline fun  KtSymbol.psi(): PSI =
    psi as PSI

/**
 * Get symbol [PsiElement] if its type is [PSI], otherwise null
 *
 * @see KtSymbol.psi
 */
public inline fun  KtSymbol.psiSafe(): PSI? =
    psi as? PSI

/**
 * Get symbol [PsiElement]. **null** if its [KtSymbol.origin] !is [KtSymbolOrigin.SOURCE]. throws **ClassCastException** if its type !is [PSI]
 *
 * @see KtSymbol.psi
 */
public inline fun  KtSymbol.sourcePsi(): PSI? {
    // TODO: support Java sources after KT-53669
    if (origin != KtSymbolOrigin.SOURCE) return null

    return psi as PSI
}

/**
 * Get symbol [PsiElement] if its type is [PSI] and [KtSymbol.origin] is [KtSymbolOrigin.SOURCE], otherwise null
 *
 * @see KtSymbol.psiSafe
 */
public inline fun  KtSymbol.sourcePsiSafe(): PSI? {
    // TODO: support Java sources after KT-53669
    if (origin != KtSymbolOrigin.SOURCE) return null

    return psi as? PSI
}

/**
 * A place where [KtSymbol] came from
 */
public enum class KtSymbolOrigin {
    /**
     * Declaration from Kotlin sources
     */
    SOURCE,

    /**
     * Declaration which do not have its PSI source and was generated, they are:
     * For regular classes, implicit default constructor is generated
     * For data classes the `copy`, `component{N}`, `toString`, `equals`, `hashCode` functions are generated
     * For enum classes the `valueOf` & `values` functions are generated
     * For lambda the `it` implicit parameter is generated
     */
    SOURCE_MEMBER_GENERATED,

    /**
     * A Kotlin declaration came from some .class file
     */
    LIBRARY,

    /**
     * A Kotlin declaration came from some Java source file or from some Java library
     */
    JAVA,

    /**
     * A synthetic function that is called as a lambda argument when creating a SAM interface object, e.g.,
     * ```
     * val isEven = IntPredicate { it % 2 == 0 }
     * ```
     */
    SAM_CONSTRUCTOR,

    /**
     * Consider the following code:
     * ```
     * interface A { fun x() }
     * interface B { fun x() }
     *
     * interface C : A, B
     * ```
     * The intersection of functions A.foo & B.foo will create a function C.foo which will be marked with [INTERSECTION_OVERRIDE]
     */
    INTERSECTION_OVERRIDE,

    /**
     * Consider the following code:
     * ```
     * interface A { fun x(): T }
     * interface B : A { }
     * ```
     *
     * The B will have a member B.foo(): Int, this member is generated inside interface B with substitution T -> Int,
     * such members are SUBSTITUTION_OVERRIDE
     */
    SUBSTITUTION_OVERRIDE,

    /**
     * Member symbol which was generated by compiler when using `by` interface delegation
     * e.g,
     * ```
     * interface A { fun x() }
     * class B(a: A) : A by a
     * ```
     * the `B.foo` function will be generated by Kotlin compiler
     */
    DELEGATED,


    JAVA_SYNTHETIC_PROPERTY,

    /**
     * Declaration is backing field of some member property
     * A symbol kind of [KtBackingFieldSymbol]
     *
     * @see KtBackingFieldSymbol
     */
    PROPERTY_BACKING_FIELD,

    /**
     * Declaration generated by the compiler plugin.
     *
     * @see org.jetbrains.kotlin.fir.declarations.FirDeclarationOrigin.Plugin
     */
    PLUGIN,


    /**
     * Declaration from dynamic Kotlin/JS scope.
     *
     * See: [Dynamic type Kotlin documentation](https://kotlinlang.org/docs/dynamic-type.html)
     */
    JS_DYNAMIC,
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy