Uast: stop resolve parts of fqn to the full-name target

This commit is contained in:
Nicolay Mitropolsky
2019-03-20 20:01:27 +03:00
parent 403801b0b3
commit 90894176f9
9 changed files with 82 additions and 53 deletions
@@ -16,20 +16,17 @@
package org.jetbrains.uast.kotlin
import com.intellij.psi.PsiClassType
import com.intellij.psi.PsiElement
import com.intellij.psi.PsiMethod
import com.intellij.psi.PsiNamedElement
import com.intellij.psi.util.PsiTypesUtil
import com.intellij.psi.*
import org.jetbrains.kotlin.descriptors.CallableDescriptor
import org.jetbrains.kotlin.descriptors.ConstructorDescriptor
import org.jetbrains.kotlin.descriptors.DeclarationDescriptor
import org.jetbrains.kotlin.descriptors.PackageViewDescriptor
import org.jetbrains.kotlin.lexer.KtTokens
import org.jetbrains.kotlin.load.java.sam.SamConstructorDescriptor
import org.jetbrains.kotlin.psi.*
import org.jetbrains.kotlin.psi.psiUtil.getAssignmentByLHS
import org.jetbrains.kotlin.psi.psiUtil.getQualifiedExpressionForSelectorOrThis
import org.jetbrains.kotlin.psi.psiUtil.parents
import org.jetbrains.kotlin.resolve.BindingContext
import org.jetbrains.kotlin.resolve.calls.callUtil.getResolvedCall
import org.jetbrains.kotlin.resolve.calls.model.ResolvedCall
import org.jetbrains.kotlin.serialization.deserialization.descriptors.DeserializedCallableMemberDescriptor
@@ -42,14 +39,19 @@ import org.jetbrains.uast.kotlin.internal.DelegatedMultiResolve
import org.jetbrains.uast.visitor.UastVisitor
open class KotlinUSimpleReferenceExpression(
override val psi: KtSimpleNameExpression,
givenParent: UElement?
override val psi: KtSimpleNameExpression,
givenParent: UElement?
) : KotlinAbstractUExpression(givenParent), USimpleNameReferenceExpression, KotlinUElementWithType, KotlinEvaluatableUElement {
private val resolvedDeclaration by lz {
(psi.parents.dropWhile { it is KtTypeElement }.firstOrNull() as? KtTypeReference)
?.toPsiType(this, true)
?.let { return@lz PsiTypesUtil.getPsiClass(it) }
psi.resolveCallToDeclaration(this)
private val resolvedDeclaration: PsiElement? by lz {
psi.resolveCallToDeclaration(this)?.let { return@lz it }
val declarationDescriptor = psi.analyze()[BindingContext.REFERENCE_TARGET, psi] ?: return@lz null
if (declarationDescriptor is PackageViewDescriptor) {
return@lz JavaPsiFacade.getInstance(psi.project).findPackage(declarationDescriptor.fqName.asString())
}
resolveToPsiClass(this, declarationDescriptor, psi)
}
override val identifier get() = psi.getReferencedName()
@@ -198,7 +200,8 @@ open class KotlinUSimpleReferenceExpression(
}
return if ((expression.parent as? KtUnaryExpression)?.operationToken
in constant { setOf(KtTokens.PLUSPLUS, KtTokens.MINUSMINUS) })
in constant { setOf(KtTokens.PLUSPLUS, KtTokens.MINUSMINUS) }
)
ReferenceAccess.READ_WRITE
else
ReferenceAccess.READ
@@ -206,9 +209,9 @@ open class KotlinUSimpleReferenceExpression(
}
class KotlinClassViaConstructorUSimpleReferenceExpression(
override val psi: KtCallElement,
override val identifier: String,
givenParent: UElement?
override val psi: KtCallElement,
override val identifier: String,
givenParent: UElement?
) : KotlinAbstractUExpression(givenParent), USimpleNameReferenceExpression, KotlinUElementWithType {
override val resolvedName: String?
get() = (resolved as? PsiNamedElement)?.name
@@ -231,11 +234,12 @@ class KotlinClassViaConstructorUSimpleReferenceExpression(
}
class KotlinStringUSimpleReferenceExpression(
override val identifier: String,
givenParent: UElement?
override val identifier: String,
givenParent: UElement?
) : KotlinAbstractUExpression(givenParent), USimpleNameReferenceExpression {
override val psi: PsiElement?
get() = null
override fun resolve() = null
override val resolvedName: String?
get() = identifier
@@ -16,20 +16,17 @@
package org.jetbrains.uast.kotlin
import com.intellij.psi.PsiClassType
import com.intellij.psi.PsiElement
import com.intellij.psi.PsiMethod
import com.intellij.psi.PsiNamedElement
import com.intellij.psi.util.PsiTypesUtil
import com.intellij.psi.*
import org.jetbrains.kotlin.descriptors.CallableDescriptor
import org.jetbrains.kotlin.descriptors.ConstructorDescriptor
import org.jetbrains.kotlin.descriptors.DeclarationDescriptor
import org.jetbrains.kotlin.descriptors.PackageViewDescriptor
import org.jetbrains.kotlin.lexer.KtTokens
import org.jetbrains.kotlin.load.java.sam.SamConstructorDescriptor
import org.jetbrains.kotlin.psi.*
import org.jetbrains.kotlin.psi.psiUtil.getAssignmentByLHS
import org.jetbrains.kotlin.psi.psiUtil.getQualifiedExpressionForSelectorOrThis
import org.jetbrains.kotlin.psi.psiUtil.parents
import org.jetbrains.kotlin.resolve.BindingContext
import org.jetbrains.kotlin.resolve.calls.callUtil.getResolvedCall
import org.jetbrains.kotlin.resolve.calls.model.ResolvedCall
import org.jetbrains.kotlin.serialization.deserialization.descriptors.DeserializedCallableMemberDescriptor
@@ -42,14 +39,19 @@ import org.jetbrains.uast.kotlin.internal.DelegatedMultiResolve
import org.jetbrains.uast.visitor.UastVisitor
open class KotlinUSimpleReferenceExpression(
override val psi: KtSimpleNameExpression,
givenParent: UElement?
override val psi: KtSimpleNameExpression,
givenParent: UElement?
) : KotlinAbstractUExpression(givenParent), USimpleNameReferenceExpression, KotlinUElementWithType, KotlinEvaluatableUElement {
private val resolvedDeclaration by lz {
(psi.parents.dropWhile { it is KtTypeElement }.firstOrNull() as? KtTypeReference)
?.toPsiType(this, true)
?.let { return@lz PsiTypesUtil.getPsiClass(it) }
psi.resolveCallToDeclaration(this)
private val resolvedDeclaration: PsiElement? by lz {
psi.resolveCallToDeclaration(this)?.let { return@lz it }
val declarationDescriptor = psi.analyze()[BindingContext.REFERENCE_TARGET, psi] ?: return@lz null
if (declarationDescriptor is PackageViewDescriptor) {
return@lz JavaPsiFacade.getInstance(psi.project).findPackage(declarationDescriptor.fqName.asString())
}
resolveToPsiClass(this, declarationDescriptor, psi)
}
override val identifier get() = psi.getReferencedName()
@@ -200,7 +202,8 @@ open class KotlinUSimpleReferenceExpression(
}
return if ((expression.parent as? KtUnaryExpression)?.operationToken
in constant { setOf(KtTokens.PLUSPLUS, KtTokens.MINUSMINUS) })
in constant { setOf(KtTokens.PLUSPLUS, KtTokens.MINUSMINUS) }
)
ReferenceAccess.READ_WRITE
else
ReferenceAccess.READ
@@ -208,9 +211,9 @@ open class KotlinUSimpleReferenceExpression(
}
class KotlinClassViaConstructorUSimpleReferenceExpression(
override val psi: KtCallElement,
override val identifier: String,
givenParent: UElement?
override val psi: KtCallElement,
override val identifier: String,
givenParent: UElement?
) : KotlinAbstractUExpression(givenParent), USimpleNameReferenceExpression, KotlinUElementWithType {
override val resolvedName: String?
get() = (resolved as? PsiNamedElement)?.name
@@ -233,11 +236,12 @@ class KotlinClassViaConstructorUSimpleReferenceExpression(
}
class KotlinStringUSimpleReferenceExpression(
override val identifier: String,
givenParent: UElement?
override val identifier: String,
givenParent: UElement?
) : KotlinAbstractUExpression(givenParent), USimpleNameReferenceExpression {
override val psi: PsiElement?
get() = null
override fun resolve() = null
override val resolvedName: String?
get() = identifier
@@ -66,7 +66,7 @@ import java.text.StringCharacterIterator
internal val KOTLIN_CACHED_UELEMENT_KEY = Key.create<WeakReference<UElement>>("cached-kotlin-uelement")
@Suppress("NOTHING_TO_INLINE")
internal inline fun String?.orAnonymous(kind: String = ""): String = this ?: "<anonymous"+(if (kind.isNotBlank()) " $kind" else "")+">"
internal inline fun String?.orAnonymous(kind: String = ""): String = this ?: "<anonymous" + (if (kind.isNotBlank()) " $kind" else "") + ">"
internal fun DeclarationDescriptor.toSource(): PsiElement? {
return try {
@@ -116,6 +116,16 @@ internal fun resolveContainingDeserializedClass(context: KtElement, memberDescri
}
}
internal fun resolveToPsiClass(uElement: UElement, declarationDescriptor: DeclarationDescriptor, context: KtElement): PsiClass? =
when (declarationDescriptor) {
is ConstructorDescriptor -> declarationDescriptor.returnType
is ClassDescriptor -> declarationDescriptor.defaultType
is TypeParameterDescriptor -> declarationDescriptor.defaultType
is TypeAliasDescriptor -> declarationDescriptor.expandedType
else -> null
}?.toPsiType(uElement, context, true).let { PsiTypesUtil.getPsiClass(it) }
private fun resolveDeserialized(context: KtElement, descriptor: DeclarationDescriptor): PsiMethod? {
if (descriptor !is DeserializedCallableMemberDescriptor) return null
@@ -338,3 +348,5 @@ internal fun KotlinULambdaExpression.getFunctionalInterfaceType(): PsiType? {
}
internal fun unwrapFakeFileForLightClass(file: PsiFile): PsiFile = (file as? FakeFileForLightClass)?.ktFile ?: file
+7 -7
View File
@@ -1,13 +1,13 @@
UImportStatement (isOnDemand = false) -> UQualifiedReferenceExpression -> null: null
UQualifiedReferenceExpression -> UQualifiedReferenceExpression -> null: null
UQualifiedReferenceExpression -> USimpleNameReferenceExpression (identifier = java) -> null: null
UQualifiedReferenceExpression -> USimpleNameReferenceExpression (identifier = io) -> null: null
UQualifiedReferenceExpression -> USimpleNameReferenceExpression (identifier = Closeable) -> null: null
UQualifiedReferenceExpression -> USimpleNameReferenceExpression (identifier = java) -> PsiPackage:java: java
UQualifiedReferenceExpression -> USimpleNameReferenceExpression (identifier = io) -> PsiPackage:java.io: io
UQualifiedReferenceExpression -> USimpleNameReferenceExpression (identifier = Closeable) -> PsiClass:Closeable: Closeable
UImportStatement (isOnDemand = false) -> UQualifiedReferenceExpression -> null: null
UQualifiedReferenceExpression -> UQualifiedReferenceExpression -> null: null
UQualifiedReferenceExpression -> USimpleNameReferenceExpression (identifier = java) -> null: null
UQualifiedReferenceExpression -> USimpleNameReferenceExpression (identifier = io) -> null: null
UQualifiedReferenceExpression -> USimpleNameReferenceExpression (identifier = InputStream) -> null: null
UQualifiedReferenceExpression -> USimpleNameReferenceExpression (identifier = java) -> PsiPackage:java: java
UQualifiedReferenceExpression -> USimpleNameReferenceExpression (identifier = io) -> PsiPackage:java.io: io
UQualifiedReferenceExpression -> USimpleNameReferenceExpression (identifier = InputStream) -> PsiClass:InputStream: InputStream
UTypeReferenceExpression (name = java.lang.Runnable) -> USimpleNameReferenceExpression (identifier = Runnable) -> PsiClass:Runnable: Runnable
UBlockExpression -> UQualifiedReferenceExpression -> KtLightMethodImpl:run: run
UQualifiedReferenceExpression -> USimpleNameReferenceExpression (identifier = runnable) -> LightVariableBuilder:runnable: runnable
@@ -19,6 +19,6 @@ UQualifiedReferenceExpression -> USimpleNameReferenceExpression (identifier = In
UCallExpression (kind = UastCallKind(name='method_call'), argCount = 0)) -> USimpleNameReferenceExpression (identifier = run) -> PsiMethod:run: run
UTypeReferenceExpression (name = java.lang.Runnable) -> USimpleNameReferenceExpression (identifier = Runnable) -> PsiClass:Runnable: Runnable
UTypeReferenceExpression (name = java.io.Closeable) -> USimpleNameReferenceExpression (identifier = Closeable) -> PsiClass:Closeable: Closeable
UTypeReferenceExpression (name = java.io.InputStream) -> USimpleNameReferenceExpression (identifier = InputStream) -> PsiClass:InputStream: InputStream
UTypeReferenceExpression (name = java.io.InputStream) -> USimpleNameReferenceExpression (identifier = InputStream) -> PsiMethod:InputStream: InputStream
UTypeReferenceExpression (name = java.lang.Runnable) -> USimpleNameReferenceExpression (identifier = Runnable) -> PsiClass:Runnable: Runnable
UTypeReferenceExpression (name = int) -> USimpleNameReferenceExpression (identifier = Int) -> PsiClass:Integer: Integer
+1 -1
View File
@@ -1,5 +1,5 @@
UTypeReferenceExpression (name = kotlin.Suppress) -> USimpleNameReferenceExpression (identifier = Suppress) -> PsiClass:Suppress: Suppress
UCallExpression (kind = UastCallKind(name='method_call'), argCount = 1)) -> USimpleNameReferenceExpression (identifier = println) -> null: null
UTypeReferenceExpression (name = kotlin.SinceKotlin) -> USimpleNameReferenceExpression (identifier = kotlin) -> PsiClass:SinceKotlin: SinceKotlin
UTypeReferenceExpression (name = kotlin.SinceKotlin) -> USimpleNameReferenceExpression (identifier = kotlin) -> PsiPackage:kotlin: kotlin
UTypeReferenceExpression (name = kotlin.SinceKotlin) -> USimpleNameReferenceExpression (identifier = SinceKotlin) -> PsiClass:SinceKotlin: SinceKotlin
UTypeReferenceExpression (name = java.lang.String) -> USimpleNameReferenceExpression (identifier = String) -> PsiClass:String: String
+2
View File
@@ -5,6 +5,7 @@ fun foo(parameter: Int): String {
return result
}
typealias ListOfLists = List<List<String>>
fun <T> parameterizedFoo(arg: T?) {
val a = arg
@@ -13,6 +14,7 @@ fun <T> parameterizedFoo(arg: T?) {
val tl: List<T> = listOf(at)
val tsl: List<String> = tl.map { it.toString() }
val lls: List<List<String>>
val llsAliased: ListOfLists
val llt: List<List<T>>
parameterizedFoo<List<String>>(emptyList())
+5 -3
View File
@@ -28,14 +28,14 @@ UFile (package = )
ULocalVariable (name = at)
UExpressionList (elvis)
UDeclarationsExpression
ULocalVariable (name = var708e1d08)
ULocalVariable (name = var708e23eb)
UAnnotation (fqName = org.jetbrains.annotations.Nullable)
USimpleNameReferenceExpression (identifier = arg)
UIfExpression
UBinaryExpression (operator = !=)
USimpleNameReferenceExpression (identifier = var708e1d08)
USimpleNameReferenceExpression (identifier = var708e23eb)
ULiteralExpression (value = null)
USimpleNameReferenceExpression (identifier = var708e1d08)
USimpleNameReferenceExpression (identifier = var708e23eb)
UReturnExpression
UDeclarationsExpression
ULocalVariable (name = tl)
@@ -59,6 +59,8 @@ UFile (package = )
USimpleNameReferenceExpression (identifier = toString, resolvesTo = null)
UDeclarationsExpression
ULocalVariable (name = lls)
UDeclarationsExpression
ULocalVariable (name = llsAliased)
UDeclarationsExpression
ULocalVariable (name = llt)
UCallExpression (kind = UastCallKind(name='method_call'), argCount = 1))
+3 -2
View File
@@ -8,14 +8,15 @@ public final class TypeReferencesKt {
public static final fun parameterizedFoo(@org.jetbrains.annotations.Nullable arg: T) : void {
var a: T = arg
var at: T = elvis {
@org.jetbrains.annotations.Nullable var var708e1d08: T = arg
if (var708e1d08 != null) var708e1d08 else return
@org.jetbrains.annotations.Nullable var var708e23eb: T = arg
if (var708e23eb != null) var708e23eb else return
}
var tl: java.util.List<? extends T> = listOf(at)
var tsl: java.util.List<? extends java.lang.String> = tl.map({
it.toString()
})
var lls: java.util.List<? extends java.util.List<? extends java.lang.String>>
var llsAliased: java.util.List<? extends java.util.List<? extends java.lang.String>>
var llt: java.util.List<? extends java.util.List<? extends T>>
parameterizedFoo(emptyList())
}
+5 -1
View File
@@ -5,10 +5,13 @@ UTypeReferenceExpression (name = java.lang.String) -> USimpleNameReferenceExpres
UBinaryExpression (operator = +) -> USimpleNameReferenceExpression (identifier = +) -> null: null
UBinaryExpression (operator = +) -> USimpleNameReferenceExpression (identifier = varWithoutType) -> LightVariableBuilder:varWithoutType: varWithoutType
UReturnExpression -> USimpleNameReferenceExpression (identifier = result) -> LightVariableBuilder:result: result
UTypeReferenceExpression (name = <ErrorType>) -> USimpleNameReferenceExpression (identifier = List) -> PsiClass:List: List
UTypeReferenceExpression (name = <ErrorType>) -> USimpleNameReferenceExpression (identifier = List) -> PsiClass:List: List
UTypeReferenceExpression (name = <ErrorType>) -> USimpleNameReferenceExpression (identifier = String) -> PsiClass:String: String
UTypeReferenceExpression (name = T) -> USimpleNameReferenceExpression (identifier = T) -> KotlinLightTypeParameter:T: T
ULocalVariable (name = a) -> USimpleNameReferenceExpression (identifier = arg) -> Light Parameter: arg
UTypeReferenceExpression (name = T) -> USimpleNameReferenceExpression (identifier = T) -> KotlinLightTypeParameter:T: T
ULocalVariable (name = var708e1d08) -> USimpleNameReferenceExpression (identifier = arg) -> Light Parameter: arg
ULocalVariable (name = var708e23eb) -> USimpleNameReferenceExpression (identifier = arg) -> Light Parameter: arg
UExpressionList (elvis) -> USimpleNameReferenceExpression (identifier = ?:) -> null: null
UTypeReferenceExpression (name = java.util.List<? extends T>) -> USimpleNameReferenceExpression (identifier = List) -> PsiClass:List: List
UTypeReferenceExpression (name = T) -> USimpleNameReferenceExpression (identifier = T) -> KotlinLightTypeParameter:T: T
@@ -25,6 +28,7 @@ UTypeReferenceExpression (name = T) -> USimpleNameReferenceExpression (identifie
UTypeReferenceExpression (name = java.util.List<? extends java.util.List<? extends java.lang.String>>) -> USimpleNameReferenceExpression (identifier = List) -> PsiClass:List: List
UTypeReferenceExpression (name = java.util.List<? extends java.lang.String>) -> USimpleNameReferenceExpression (identifier = List) -> PsiClass:List: List
UTypeReferenceExpression (name = java.lang.String) -> USimpleNameReferenceExpression (identifier = String) -> PsiClass:String: String
UTypeReferenceExpression (name = java.util.List<? extends java.util.List<? extends java.lang.String>>) -> USimpleNameReferenceExpression (identifier = ListOfLists) -> PsiClass:List: List
UTypeReferenceExpression (name = java.util.List<? extends java.util.List<? extends T>>) -> USimpleNameReferenceExpression (identifier = List) -> PsiClass:List: List
UTypeReferenceExpression (name = java.util.List<? extends T>) -> USimpleNameReferenceExpression (identifier = List) -> PsiClass:List: List
UTypeReferenceExpression (name = T) -> USimpleNameReferenceExpression (identifier = T) -> KotlinLightTypeParameter:T: T