summaryrefslogtreecommitdiff
path: root/plugins/kotlin/uast/uast-kotlin-base/src/org/jetbrains/uast/kotlin/declarations/KotlinUEnumConstant.kt
blob: 97b480d86945be1ffb37f48881e46a6955b9b9f2 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
// Copyright 2000-2021 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file.
package org.jetbrains.uast.kotlin

import com.intellij.psi.*
import com.intellij.psi.util.PsiTypesUtil
import org.jetbrains.annotations.ApiStatus
import org.jetbrains.kotlin.asJava.classes.KtLightClass
import org.jetbrains.kotlin.descriptors.annotations.AnnotationUseSiteTarget
import org.jetbrains.kotlin.psi.KtElement
import org.jetbrains.kotlin.psi.KtEnumEntry
import org.jetbrains.kotlin.psi.KtSuperTypeCallEntry
import org.jetbrains.uast.*
import org.jetbrains.uast.kotlin.internal.DelegatedMultiResolve

@ApiStatus.Internal
class KotlinUEnumConstant(
    psi: PsiEnumConstant,
    override val sourcePsi: KtElement?,
    givenParent: UElement?
) : AbstractKotlinUVariable(givenParent), UEnumConstantEx, UCallExpression, DelegatedMultiResolve, PsiEnumConstant by psi {

    override val initializingClass: UClass? by lz {
        (psi.initializingClass as? KtLightClass)?.let { initializingClass ->
            KotlinUClass.create(initializingClass, this)
        }
    }

    override fun getInitializer(): PsiExpression? = super<AbstractKotlinUVariable>.getInitializer()

    override fun getOriginalElement(): PsiElement? = super<AbstractKotlinUVariable>.getOriginalElement()

    override val javaPsi = unwrap<UEnumConstant, PsiEnumConstant>(psi)

    override val psi = javaPsi

    override fun acceptsAnnotationTarget(target: AnnotationUseSiteTarget?): Boolean = true

    override fun getContainingFile(): PsiFile {
        return super.getContainingFile()
    }

    override fun getNameIdentifier(): PsiIdentifier {
        return super.getNameIdentifier()
    }

    override val kind: UastCallKind
        get() = UastCallKind.CONSTRUCTOR_CALL

    override val receiver: UExpression?
        get() = null

    override val receiverType: PsiType?
        get() = null

    override val methodIdentifier: UIdentifier?
        get() = null

    override val classReference: UReferenceExpression
        get() = KotlinEnumConstantClassReference(psi, sourcePsi, this)

    override val typeArgumentCount: Int
        get() = 0

    override val typeArguments: List<PsiType>
        get() = emptyList()

    override val valueArgumentCount: Int
        get() = psi.argumentList?.expressions?.size ?: 0

    override val valueArguments: List<UExpression> by lz {
        val ktEnumEntry = sourcePsi as? KtEnumEntry ?: return@lz emptyList()
        val ktSuperTypeCallEntry =
            ktEnumEntry.initializerList?.initializers?.firstOrNull() as? KtSuperTypeCallEntry ?: return@lz emptyList()
        ktSuperTypeCallEntry.valueArguments.map { valueArgument ->
            valueArgument.getArgumentExpression()?.let { languagePlugin?.convertElement(it, this) } as? UExpression
                ?: UastEmptyExpression(this)
        }
    }

    override val returnType: PsiType?
        get() = uastParent?.getAsJavaPsiElement(PsiClass::class.java)?.let { PsiTypesUtil.getClassType(it) }

    override fun resolve() = psi.resolveMethod()

    override val methodName: String?
        get() = null

    private class KotlinEnumConstantClassReference(
        override val psi: PsiEnumConstant,
        override val sourcePsi: KtElement?,
        givenParent: UElement?
    ) : KotlinAbstractUExpression(givenParent), USimpleNameReferenceExpression {
        override val javaPsi: PsiElement
            get() = psi

        override fun resolve() = psi.containingClass
        override val resolvedName: String?
            get() = psi.containingClass?.name
        override val identifier: String
            get() = psi.containingClass?.name ?: "<error>"
    }

    override fun getArgumentForParameter(i: Int): UExpression? = valueArguments.getOrNull(i)

}