181: Uast: fixes for non-leaf identifiers
This commit is contained in:
committed by
Nikolay Krasko
parent
8a4ef83b3d
commit
036c0fd6a4
@@ -297,6 +297,8 @@ internal object KotlinConverter {
|
||||
else -> element
|
||||
}
|
||||
|
||||
private val identifiersTokens = setOf(KtTokens.IDENTIFIER, KtTokens.CONSTRUCTOR_KEYWORD, KtTokens.THIS_KEYWORD, KtTokens.SUPER_KEYWORD)
|
||||
|
||||
internal fun convertPsiElement(element: PsiElement?,
|
||||
givenParent: UElement?,
|
||||
requiredType: Class<out UElement>?): UElement? {
|
||||
@@ -354,7 +356,7 @@ internal object KotlinConverter {
|
||||
is KtImportDirective -> el<UImportStatement>(build(::KotlinUImportStatement))
|
||||
else -> {
|
||||
if (element is LeafPsiElement) {
|
||||
if (element.elementType == KtTokens.IDENTIFIER || element.elementType == KtTokens.CONSTRUCTOR_KEYWORD)
|
||||
if (element.elementType in identifiersTokens)
|
||||
el<UIdentifier>(build(::KotlinUIdentifier))
|
||||
else if (element.elementType == KtTokens.LBRACKET && element.parent is KtCollectionLiteralExpression)
|
||||
el<UIdentifier> {
|
||||
|
||||
+14
-1
@@ -96,7 +96,20 @@ abstract class AbstractKotlinUVariable(givenParent: UElement?) : KotlinAbstractU
|
||||
override val typeReference by lz { getLanguagePlugin().convertOpt<UTypeReferenceExpression>(psi.typeElement, this) }
|
||||
|
||||
override val uastAnchor: UIdentifier?
|
||||
get() = KotlinUIdentifier(nameIdentifier, (sourcePsi as? KtNamedDeclaration)?.nameIdentifier ?: sourcePsi, this)
|
||||
get() {
|
||||
val sourcePsi = sourcePsi
|
||||
val identifierSourcePsi = when (sourcePsi) {
|
||||
is KtNamedDeclaration -> sourcePsi.nameIdentifier
|
||||
is KtTypeReference -> sourcePsi.typeElement?.let {
|
||||
// receiver param in extension function
|
||||
(it as? KtUserType)?.referenceExpression?.getIdentifier() ?: it
|
||||
} ?: sourcePsi
|
||||
is KtBinaryExpression, is KtCallExpression -> null // e.g. `foo("Lorem ipsum") ?: foo("dolor sit amet")`
|
||||
is KtDestructuringDeclaration -> sourcePsi.valOrVarKeyword
|
||||
else -> sourcePsi
|
||||
} ?: return null
|
||||
return KotlinUIdentifier(nameIdentifier, identifierSourcePsi, this)
|
||||
}
|
||||
|
||||
override fun equals(other: Any?) = other is AbstractKotlinUVariable && psi == other.psi
|
||||
|
||||
|
||||
+20
-8
@@ -21,10 +21,9 @@ import com.intellij.psi.PsiElement
|
||||
import com.intellij.psi.PsiFile
|
||||
import com.intellij.psi.PsiNameIdentifierOwner
|
||||
import com.intellij.psi.impl.source.tree.LeafPsiElement
|
||||
import com.intellij.psi.util.parents
|
||||
import org.jetbrains.kotlin.asJava.elements.KtLightIdentifier
|
||||
import org.jetbrains.kotlin.psi.KtCallElement
|
||||
import org.jetbrains.kotlin.psi.KtElement
|
||||
import org.jetbrains.kotlin.psi.KtNamedDeclaration
|
||||
import org.jetbrains.kotlin.psi.*
|
||||
import org.jetbrains.uast.UElement
|
||||
import org.jetbrains.uast.UIdentifier
|
||||
import org.jetbrains.uast.kotlin.unwrapFakeFileForLightClass
|
||||
@@ -43,19 +42,32 @@ class KotlinUIdentifier private constructor(
|
||||
) : UIdentifier(psi, givenParent) {
|
||||
|
||||
init {
|
||||
if (ApplicationManager.getApplication().isUnitTestMode)
|
||||
assert(sourcePsi == null || sourcePsi is LeafPsiElement || (sourcePsi is KtElement && sourcePsi.firstChild == null),
|
||||
{ "sourcePsi should be physical leaf element but got $sourcePsi of (${sourcePsi?.javaClass})" })
|
||||
if (ApplicationManager.getApplication().isUnitTestMode && !acceptableSourcePsi(sourcePsi))
|
||||
throw AssertionError("sourcePsi should be physical leaf element but got $sourcePsi of (${sourcePsi?.javaClass})")
|
||||
}
|
||||
|
||||
private fun acceptableSourcePsi(sourcePsi: PsiElement?): Boolean {
|
||||
if (sourcePsi == null) return true
|
||||
if (sourcePsi is LeafPsiElement) return true
|
||||
if (sourcePsi is KtElement && sourcePsi.firstChild == null) return true
|
||||
return false
|
||||
}
|
||||
|
||||
override val uastParent: UElement? by lazy {
|
||||
if (givenParent != null) return@lazy givenParent
|
||||
val parent = sourcePsi?.parent ?: return@lazy null
|
||||
getIdentifierParentForCall(parent) ?: parent.toUElement()
|
||||
}
|
||||
|
||||
private fun getIdentifierParentForCall(parent: PsiElement): UElement? {
|
||||
val parentParent = parent.parent
|
||||
if (parentParent is KtCallElement && parentParent.calleeExpression == parent) { // method identifiers in calls
|
||||
return@lazy parentParent.toUElement()
|
||||
return parentParent.toUElement()
|
||||
}
|
||||
return@lazy parent.toUElement()
|
||||
(parent.parents().take(3).find { it is KtTypeReference && it.parent is KtConstructorCalleeExpression })?.let {
|
||||
return it.parent.parent.toUElement()
|
||||
}
|
||||
return null
|
||||
}
|
||||
|
||||
constructor(javaPsi: PsiElement?, sourcePsi: PsiElement?, uastParent: UElement?) : this(javaPsi, sourcePsi, javaPsi, uastParent)
|
||||
|
||||
+7
-1
@@ -77,7 +77,13 @@ class KotlinUFunctionCallExpression(
|
||||
when (calleeExpression) {
|
||||
null -> null
|
||||
is KtNameReferenceExpression ->
|
||||
KotlinUIdentifier(calleeExpression.getReferencedNameElement(), this /* ReferenceExpression will be the parent */)
|
||||
KotlinUIdentifier(calleeExpression.getReferencedNameElement(), this)
|
||||
is KtConstructorDelegationReferenceExpression ->
|
||||
KotlinUIdentifier(calleeExpression.firstChild ?: calleeExpression, this)
|
||||
is KtConstructorCalleeExpression ->
|
||||
KotlinUIdentifier(
|
||||
calleeExpression.constructorReferenceExpression?.getReferencedNameElement() ?: calleeExpression, this
|
||||
)
|
||||
else -> KotlinUIdentifier(calleeExpression, this)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,12 +1,12 @@
|
||||
Test -> USimpleNameReferenceExpression (identifier = Test)
|
||||
Test -> UAnnotation (fqName = null)
|
||||
A -> UClass (name = A)
|
||||
MyAnnotation -> UClass (name = MyAnnotation)
|
||||
text -> [!] UnknownKotlinExpression (VALUE_PARAMETER)
|
||||
String -> USimpleNameReferenceExpression (identifier = String)
|
||||
MyAnnotation -> USimpleNameReferenceExpression (identifier = MyAnnotation)
|
||||
MyAnnotation -> UAnnotation (fqName = MyAnnotation)
|
||||
B -> UClass (name = B)
|
||||
MyAnnotation -> USimpleNameReferenceExpression (identifier = MyAnnotation)
|
||||
MyAnnotation -> UAnnotation (fqName = MyAnnotation)
|
||||
InB -> UClass (name = InB)
|
||||
MyAnnotation -> USimpleNameReferenceExpression (identifier = MyAnnotation)
|
||||
MyAnnotation -> USimpleNameReferenceExpression (identifier = MyAnnotation)
|
||||
MyAnnotation -> UAnnotation (fqName = MyAnnotation)
|
||||
MyAnnotation -> UAnnotation (fqName = MyAnnotation)
|
||||
Obj -> UClass (name = Obj)
|
||||
|
||||
@@ -4,6 +4,7 @@ String -> USimpleNameReferenceExpression (identifier = String)
|
||||
constructor -> UAnnotationMethod (name = A)
|
||||
i -> UParameter (name = i)
|
||||
Int -> USimpleNameReferenceExpression (identifier = Int)
|
||||
this -> UCallExpression (kind = UastCallKind(name='constructor_call'), argCount = 1))
|
||||
i -> USimpleNameReferenceExpression (identifier = i)
|
||||
toString -> UCallExpression (kind = UastCallKind(name='method_call'), argCount = 0))
|
||||
AWithInit -> UClass (name = AWithInit)
|
||||
@@ -13,6 +14,7 @@ String -> USimpleNameReferenceExpression (identifier = String)
|
||||
constructor -> UAnnotationMethod (name = AWithInit)
|
||||
i -> UParameter (name = i)
|
||||
Int -> USimpleNameReferenceExpression (identifier = Int)
|
||||
this -> UCallExpression (kind = UastCallKind(name='constructor_call'), argCount = 1))
|
||||
i -> USimpleNameReferenceExpression (identifier = i)
|
||||
toString -> UCallExpression (kind = UastCallKind(name='method_call'), argCount = 0))
|
||||
AWith2Init -> UClass (name = AWith2Init)
|
||||
@@ -23,6 +25,7 @@ String -> USimpleNameReferenceExpression (identifier = String)
|
||||
constructor -> UAnnotationMethod (name = AWith2Init)
|
||||
i -> UParameter (name = i)
|
||||
Int -> USimpleNameReferenceExpression (identifier = Int)
|
||||
this -> UCallExpression (kind = UastCallKind(name='constructor_call'), argCount = 1))
|
||||
i -> USimpleNameReferenceExpression (identifier = i)
|
||||
toString -> UCallExpression (kind = UastCallKind(name='method_call'), argCount = 0))
|
||||
AOnlyInit -> UClass (name = AOnlyInit)
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
SimpleAnnotated -> UClass (name = SimpleAnnotated)
|
||||
Suppress -> USimpleNameReferenceExpression (identifier = Suppress)
|
||||
Suppress -> UAnnotation (fqName = kotlin.Suppress)
|
||||
method -> UAnnotationMethod (name = method)
|
||||
println -> UCallExpression (kind = UastCallKind(name='method_call'), argCount = 1))
|
||||
kotlin -> USimpleNameReferenceExpression (identifier = kotlin)
|
||||
SinceKotlin -> USimpleNameReferenceExpression (identifier = SinceKotlin)
|
||||
SinceKotlin -> UAnnotation (fqName = kotlin.SinceKotlin)
|
||||
property -> UField (name = property)
|
||||
String -> USimpleNameReferenceExpression (identifier = String)
|
||||
|
||||
Reference in New Issue
Block a user