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
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
|
// 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 org.jetbrains.kotlin.asJava.elements.KtLightAbstractAnnotation
import org.jetbrains.kotlin.asJava.elements.KtLightElement
import org.jetbrains.kotlin.descriptors.annotations.AnnotationUseSiteTarget
import org.jetbrains.kotlin.psi.*
import org.jetbrains.kotlin.utils.SmartList
import org.jetbrains.kotlin.utils.addToStdlib.safeAs
import org.jetbrains.uast.*
import org.jetbrains.uast.kotlin.internal.DelegatedMultiResolve
import org.jetbrains.uast.kotlin.psi.UastKotlinPsiParameter
import org.jetbrains.uast.kotlin.psi.UastKotlinPsiVariable
abstract class AbstractKotlinUVariable(
givenParent: UElement?
) : KotlinAbstractUElement(givenParent), PsiVariable, UVariableEx, UAnchorOwner {
override val uastInitializer: UExpression?
get() {
val psi = psi
val initializerExpression = when (psi) {
is UastKotlinPsiVariable -> psi.ktInitializer
is UastKotlinPsiParameter -> psi.ktDefaultValue
is KtLightElement<*, *> -> {
val origin = psi.kotlinOrigin?.takeIf { it.canAnalyze() } // EA-137191
when (origin) {
is KtVariableDeclaration -> origin.initializer
is KtParameter -> origin.defaultValue
else -> null
}
}
else -> null
} ?: return null
return languagePlugin?.convertElement(initializerExpression, this) as? UExpression ?: UastEmptyExpression(null)
}
val delegateExpression: UExpression? by lz {
val psi = psi
val expression = when (psi) {
is KtLightElement<*, *> -> (psi.kotlinOrigin as? KtProperty)?.delegateExpression
is UastKotlinPsiVariable -> (psi.ktElement as? KtProperty)?.delegateExpression
else -> null
}
expression?.let { languagePlugin?.convertElement(it, this) as? UExpression }
}
override fun getNameIdentifier(): PsiIdentifier {
val kotlinOrigin = (psi as? KtLightElement<*, *>)?.kotlinOrigin
return UastLightIdentifier(psi, kotlinOrigin as? KtDeclaration)
}
override fun getContainingFile(): PsiFile = unwrapFakeFileForLightClass(psi.containingFile)
override val uAnnotations by lz {
val sourcePsi = sourcePsi ?: return@lz psi.annotations.map { WrappedUAnnotation(it, this) }
val annotations = SmartList<UAnnotation>(KotlinNullabilityUAnnotation(baseResolveProviderService, sourcePsi, this))
if (sourcePsi is KtModifierListOwner) {
sourcePsi.annotationEntries
.filter { acceptsAnnotationTarget(it.useSiteTarget?.getAnnotationUseSiteTarget()) }
.mapTo(annotations) { baseResolveProviderService.baseKotlinConverter.convertAnnotation(it, this) }
}
annotations
}
protected abstract fun acceptsAnnotationTarget(target: AnnotationUseSiteTarget?): Boolean
override val typeReference: UTypeReferenceExpression? by lz {
KotlinUTypeReferenceExpression((sourcePsi as? KtCallableDeclaration)?.typeReference, this) { type }
}
override val uastAnchor: UIdentifier?
get() {
val identifierSourcePsi = when (val sourcePsi = sourcePsi) {
is KtNamedDeclaration -> sourcePsi.nameIdentifier
is KtTypeReference -> sourcePsi.typeElement?.let {
// receiver param in extension function
(it as? KtUserType)?.referenceExpression?.getIdentifier() ?: it
} ?: sourcePsi
is KtNameReferenceExpression -> sourcePsi.getReferencedNameElement()
is KtBinaryExpression, is KtCallExpression -> null // e.g. `foo("Lorem ipsum") ?: foo("dolor sit amet")`
is KtDestructuringDeclaration -> sourcePsi.valOrVarKeyword
is KtLambdaExpression -> sourcePsi.functionLiteral.lBrace
else -> sourcePsi
} ?: return null
return KotlinUIdentifier(nameIdentifier, identifierSourcePsi, this)
}
override fun equals(other: Any?) = other is AbstractKotlinUVariable && psi == other.psi
class WrappedUAnnotation(
psiAnnotation: PsiAnnotation,
override val uastParent: UElement
) : UAnnotation, UAnchorOwner, DelegatedMultiResolve {
override val javaPsi: PsiAnnotation = psiAnnotation
override val psi: PsiAnnotation = javaPsi
override val sourcePsi: PsiElement? = psiAnnotation.safeAs<KtLightAbstractAnnotation>()?.kotlinOrigin
override val attributeValues: List<UNamedExpression> by lz {
psi.parameterList.attributes.map { WrappedUNamedExpression(it, this) }
}
override val uastAnchor by lazy {
KotlinUIdentifier(
{ javaPsi.nameReferenceElement?.referenceNameElement },
sourcePsi.safeAs<KtAnnotationEntry>()?.typeReference?.nameElement,
this
)
}
class WrappedUNamedExpression(
pair: PsiNameValuePair,
override val uastParent: UElement?
) : UNamedExpression {
override val name: String? = pair.name
override val psi = pair
override val javaPsi: PsiElement = psi
override val sourcePsi: PsiElement? = null
override val uAnnotations: List<UAnnotation> = emptyList()
override val expression: UExpression by lz { toUExpression(psi.value) }
}
override val qualifiedName: String? = psi.qualifiedName
override fun findAttributeValue(name: String?): UExpression? =
psi.findAttributeValue(name)?.let { toUExpression(it) }
override fun findDeclaredAttributeValue(name: String?): UExpression? =
psi.findDeclaredAttributeValue(name)?.let { toUExpression(it) }
override fun resolve(): PsiClass? =
psi.nameReferenceElement?.resolve() as? PsiClass
}
}
private fun toUExpression(psi: PsiElement?): UExpression = psi.toUElementOfType() ?: UastEmptyExpression(null)
|