EA-214662: Support property accessors in UastLightIdentifier
This commit is contained in:
+5
-5
@@ -21,14 +21,12 @@ import com.intellij.psi.PsiCompiledElement
|
||||
import com.intellij.psi.PsiElement
|
||||
import com.intellij.psi.PsiNameIdentifierOwner
|
||||
import com.intellij.psi.impl.light.LightIdentifier
|
||||
import org.jetbrains.kotlin.psi.KtNamedDeclaration
|
||||
import org.jetbrains.kotlin.psi.KtPrimaryConstructor
|
||||
import org.jetbrains.kotlin.psi.KtSecondaryConstructor
|
||||
import org.jetbrains.kotlin.psi.*
|
||||
import org.jetbrains.kotlin.psi.psiUtil.containingClassOrObject
|
||||
|
||||
open class KtLightIdentifier(
|
||||
private val lightOwner: PsiElement,
|
||||
private val ktDeclaration: KtNamedDeclaration?
|
||||
private val ktDeclaration: KtDeclaration?
|
||||
) : LightIdentifier(lightOwner.manager, ktDeclaration?.name ?: ""), PsiCompiledElement,
|
||||
PsiElementWithOrigin<PsiElement> {
|
||||
override val origin: PsiElement?
|
||||
@@ -37,7 +35,9 @@ open class KtLightIdentifier(
|
||||
is KtPrimaryConstructor -> ktDeclaration.getConstructorKeyword()
|
||||
?: ktDeclaration.valueParameterList
|
||||
?: ktDeclaration.containingClassOrObject?.nameIdentifier
|
||||
else -> ktDeclaration?.nameIdentifier
|
||||
is KtPropertyAccessor -> ktDeclaration.namePlaceholder
|
||||
is KtNamedDeclaration -> ktDeclaration.nameIdentifier
|
||||
else -> null
|
||||
}
|
||||
|
||||
override fun getMirror() = ((lightOwner as? KtLightElement<*, *>)?.clsDelegate as? PsiNameIdentifierOwner)?.nameIdentifier
|
||||
|
||||
@@ -197,8 +197,11 @@ internal object KotlinConverter {
|
||||
else -> element
|
||||
}
|
||||
|
||||
private val identifiersTokens =
|
||||
setOf(KtTokens.IDENTIFIER, KtTokens.CONSTRUCTOR_KEYWORD, KtTokens.THIS_KEYWORD, KtTokens.SUPER_KEYWORD, KtTokens.OBJECT_KEYWORD)
|
||||
private val identifiersTokens = setOf(
|
||||
KtTokens.IDENTIFIER, KtTokens.CONSTRUCTOR_KEYWORD, KtTokens.OBJECT_KEYWORD,
|
||||
KtTokens.THIS_KEYWORD, KtTokens.SUPER_KEYWORD,
|
||||
KtTokens.GET_KEYWORD, KtTokens.SET_KEYWORD
|
||||
)
|
||||
|
||||
internal fun convertPsiElement(element: PsiElement?,
|
||||
givenParent: UElement?,
|
||||
|
||||
@@ -165,7 +165,10 @@ open class KotlinUClass private constructor(
|
||||
if (isDelegatedMethod(lightMethod)) continue
|
||||
val uMethod = createUMethod(lightMethod)
|
||||
result.add(uMethod)
|
||||
handledKtDeclarations.addIfNotNull(uMethod.sourcePsi)
|
||||
|
||||
// Ensure we pick the main Kotlin origin, not the auxiliary one
|
||||
val kotlinOrigin = (lightMethod as? KtLightMethod)?.kotlinOrigin ?: uMethod.sourcePsi
|
||||
handledKtDeclarations.addIfNotNull(kotlinOrigin)
|
||||
}
|
||||
|
||||
val ktDeclarations: List<KtDeclaration> = run ktDeclarations@{
|
||||
|
||||
@@ -39,7 +39,7 @@ open class KotlinUMethod(
|
||||
givenParent: UElement?
|
||||
) : KotlinAbstractUElement(givenParent), UMethodTypeSpecific, UAnchorOwner, JavaUElementWithComments, PsiMethod by psi {
|
||||
|
||||
constructor(psi: KtLightMethod, givenParent: UElement?) : this(psi, psi.kotlinOrigin, givenParent)
|
||||
constructor(psi: KtLightMethod, givenParent: UElement?) : this(psi, getKotlinMemberOrigin(psi), givenParent)
|
||||
|
||||
override val comments: List<UComment>
|
||||
get() = super<KotlinAbstractUElement>.comments
|
||||
@@ -50,14 +50,14 @@ open class KotlinUMethod(
|
||||
|
||||
override fun getSourceElement() = sourcePsi ?: this
|
||||
|
||||
private val kotlinOrigin = (psi.originalElement as? KtLightElement<*, *>)?.kotlinOrigin ?: sourcePsi
|
||||
private val kotlinOrigin = getKotlinMemberOrigin(psi.originalElement) ?: sourcePsi
|
||||
|
||||
override fun getContainingFile(): PsiFile? {
|
||||
kotlinOrigin?.containingFile?.let { return it }
|
||||
return unwrapFakeFileForLightClass(psi.containingFile)
|
||||
}
|
||||
|
||||
override fun getNameIdentifier() = UastLightIdentifier(psi, kotlinOrigin as KtNamedDeclaration?)
|
||||
override fun getNameIdentifier() = UastLightIdentifier(psi, kotlinOrigin as? KtDeclaration)
|
||||
|
||||
override val annotations: List<UAnnotation> by lz {
|
||||
psi.annotations
|
||||
@@ -85,6 +85,7 @@ open class KotlinUMethod(
|
||||
when (sourcePsi) {
|
||||
is PsiNameIdentifierOwner -> sourcePsi.nameIdentifier
|
||||
is KtObjectDeclaration -> sourcePsi.getObjectKeyword()
|
||||
is KtPropertyAccessor -> sourcePsi.namePlaceholder
|
||||
else -> sourcePsi?.navigationElement
|
||||
}
|
||||
},
|
||||
@@ -97,6 +98,7 @@ open class KotlinUMethod(
|
||||
if (kotlinOrigin?.canAnalyze() != true) return@lz null // EA-137193
|
||||
val bodyExpression = when (kotlinOrigin) {
|
||||
is KtFunction -> kotlinOrigin.bodyExpression
|
||||
is KtPropertyAccessor -> kotlinOrigin.bodyExpression
|
||||
is KtProperty -> when {
|
||||
psi is KtLightMethod && psi.isGetter -> kotlinOrigin.getter?.bodyExpression
|
||||
psi is KtLightMethod && psi.isSetter -> kotlinOrigin.setter?.bodyExpression
|
||||
@@ -118,6 +120,12 @@ open class KotlinUMethod(
|
||||
override fun equals(other: Any?) = other is KotlinUMethod && psi == other.psi
|
||||
|
||||
companion object {
|
||||
private fun getKotlinMemberOrigin(element: PsiElement?): KtDeclaration? {
|
||||
(element as? KtLightMember<*>)?.lightMemberOrigin?.auxiliaryOriginalElement?.let { return it }
|
||||
(element as? KtLightElement<*, *>)?.kotlinOrigin?.let { return it as? KtDeclaration }
|
||||
return null
|
||||
}
|
||||
|
||||
fun create(psi: KtLightMethod, containingElement: UElement?): KotlinUMethod {
|
||||
val kotlinOrigin = psi.kotlinOrigin
|
||||
return if (kotlinOrigin is KtConstructor<*>) {
|
||||
|
||||
+11
-3
@@ -40,7 +40,7 @@ open class KotlinUMethod(
|
||||
givenParent: UElement?
|
||||
) : KotlinAbstractUElement(givenParent), UMethodTypeSpecific, UAnchorOwner, JavaUElementWithComments, PsiMethod by psi {
|
||||
|
||||
constructor(psi: KtLightMethod, givenParent: UElement?) : this(psi, psi.kotlinOrigin, givenParent)
|
||||
constructor(psi: KtLightMethod, givenParent: UElement?) : this(psi, getKotlinMemberOrigin(psi), givenParent)
|
||||
|
||||
override val comments: List<UComment>
|
||||
get() = super<KotlinAbstractUElement>.comments
|
||||
@@ -51,14 +51,14 @@ open class KotlinUMethod(
|
||||
|
||||
override fun getSourceElement() = sourcePsi ?: this
|
||||
|
||||
private val kotlinOrigin = (psi.originalElement as? KtLightElement<*, *>)?.kotlinOrigin ?: sourcePsi
|
||||
private val kotlinOrigin = getKotlinMemberOrigin(psi.originalElement) ?: sourcePsi
|
||||
|
||||
override fun getContainingFile(): PsiFile? {
|
||||
kotlinOrigin?.containingFile?.let { return it }
|
||||
return unwrapFakeFileForLightClass(psi.containingFile)
|
||||
}
|
||||
|
||||
override fun getNameIdentifier() = UastLightIdentifier(psi, kotlinOrigin as KtNamedDeclaration?)
|
||||
override fun getNameIdentifier() = UastLightIdentifier(psi, kotlinOrigin as? KtDeclaration)
|
||||
|
||||
override val annotations: List<UAnnotation> by lz {
|
||||
psi.annotations
|
||||
@@ -86,6 +86,7 @@ open class KotlinUMethod(
|
||||
when (sourcePsi) {
|
||||
is PsiNameIdentifierOwner -> sourcePsi.nameIdentifier
|
||||
is KtObjectDeclaration -> sourcePsi.getObjectKeyword()
|
||||
is KtPropertyAccessor -> sourcePsi.namePlaceholder
|
||||
else -> sourcePsi?.navigationElement
|
||||
}
|
||||
},
|
||||
@@ -98,6 +99,7 @@ open class KotlinUMethod(
|
||||
if (kotlinOrigin?.canAnalyze() != true) return@lz null // EA-137193
|
||||
val bodyExpression = when (kotlinOrigin) {
|
||||
is KtFunction -> kotlinOrigin.bodyExpression
|
||||
is KtPropertyAccessor -> kotlinOrigin.bodyExpression
|
||||
is KtProperty -> when {
|
||||
psi is KtLightMethod && psi.isGetter -> kotlinOrigin.getter?.bodyExpression
|
||||
psi is KtLightMethod && psi.isSetter -> kotlinOrigin.setter?.bodyExpression
|
||||
@@ -121,6 +123,12 @@ open class KotlinUMethod(
|
||||
override fun equals(other: Any?) = other is KotlinUMethod && psi == other.psi
|
||||
|
||||
companion object {
|
||||
private fun getKotlinMemberOrigin(element: PsiElement?): KtDeclaration? {
|
||||
(element as? KtLightMember<*>)?.lightMemberOrigin?.auxiliaryOriginalElement?.let { return it }
|
||||
(element as? KtLightElement<*, *>)?.kotlinOrigin?.let { return it as? KtDeclaration }
|
||||
return null
|
||||
}
|
||||
|
||||
fun create(psi: KtLightMethod, containingElement: UElement?): KotlinUMethod {
|
||||
val kotlinOrigin = psi.kotlinOrigin
|
||||
return if (kotlinOrigin is KtConstructor<*>) {
|
||||
|
||||
@@ -75,7 +75,7 @@ abstract class AbstractKotlinUVariable(givenParent: UElement?) : KotlinAbstractU
|
||||
|
||||
override fun getNameIdentifier(): PsiIdentifier {
|
||||
val kotlinOrigin = (psi as? KtLightElement<*, *>)?.kotlinOrigin
|
||||
return UastLightIdentifier(psi, kotlinOrigin as KtNamedDeclaration?)
|
||||
return UastLightIdentifier(psi, kotlinOrigin as? KtDeclaration)
|
||||
}
|
||||
|
||||
override fun getContainingFile(): PsiFile = unwrapFakeFileForLightClass(psi.containingFile)
|
||||
|
||||
+1
-1
@@ -29,7 +29,7 @@ import org.jetbrains.uast.UIdentifier
|
||||
import org.jetbrains.uast.kotlin.unwrapFakeFileForLightClass
|
||||
import org.jetbrains.uast.toUElement
|
||||
|
||||
class UastLightIdentifier(lightOwner: PsiNameIdentifierOwner, ktDeclaration: KtNamedDeclaration?) :
|
||||
class UastLightIdentifier(lightOwner: PsiNameIdentifierOwner, ktDeclaration: KtDeclaration?) :
|
||||
KtLightIdentifier(lightOwner, ktDeclaration) {
|
||||
override fun getContainingFile(): PsiFile = unwrapFakeFileForLightClass(super.getContainingFile())
|
||||
}
|
||||
|
||||
@@ -29,11 +29,13 @@
|
||||
[1]:[UDeclarationsExpression]
|
||||
[4]:[UParameter (name = bar), UField (name = bar), UMethod (name = getBar), UMethod (name = setBar)]
|
||||
[1]:[UAnnotation (fqName = MyAnnotation)]
|
||||
[1]:[UIdentifier (Identifier (get))]
|
||||
[1]:[[!] UnknownKotlinExpression (CONSTRUCTOR_CALLEE)]
|
||||
[1]:[UTypeReferenceExpression (name = MyAnnotation)]
|
||||
[1]:[USimpleNameReferenceExpression (identifier = MyAnnotation)]
|
||||
[1]:[UIdentifier (Identifier (MyAnnotation))]
|
||||
[1]:[UAnnotation (fqName = MyAnnotation2)]
|
||||
[1]:[UIdentifier (Identifier (set))]
|
||||
[1]:[[!] UnknownKotlinExpression (CONSTRUCTOR_CALLEE)]
|
||||
[1]:[UTypeReferenceExpression (name = MyAnnotation2)]
|
||||
[1]:[USimpleNameReferenceExpression (identifier = MyAnnotation2)]
|
||||
|
||||
@@ -0,0 +1,9 @@
|
||||
TestPropertyInitializer -> UClass (name = TestPropertyInitializer)
|
||||
withSetter -> UField (name = withSetter)
|
||||
get -> UMethod (name = getWithSetter)
|
||||
field -> USimpleNameReferenceExpression (identifier = field)
|
||||
set -> UMethod (name = setWithSetter)
|
||||
p -> UParameter (name = p)
|
||||
field -> USimpleNameReferenceExpression (identifier = field)
|
||||
= -> USimpleNameReferenceExpression (identifier = =)
|
||||
p -> USimpleNameReferenceExpression (identifier = p)
|
||||
@@ -0,0 +1,3 @@
|
||||
field -> USimpleNameReferenceExpression (identifier = field) from KtNameReferenceExpression
|
||||
field -> USimpleNameReferenceExpression (identifier = field) from KtNameReferenceExpression
|
||||
p -> USimpleNameReferenceExpression (identifier = p) from KtNameReferenceExpression
|
||||
@@ -30,6 +30,9 @@ class KotlinUastIdentifiersTest : AbstractKotlinIdentifiersTest() {
|
||||
@Test
|
||||
fun testSuperCalls() = doTest("SuperCalls")
|
||||
|
||||
@Test
|
||||
fun testPropertyInitializer() = doTest("PropertyInitializer")
|
||||
|
||||
@Test
|
||||
fun testEnumValuesConstructors() = doTest("EnumValuesConstructors")
|
||||
|
||||
|
||||
Reference in New Issue
Block a user