From 90894176f990689a9f104b200ed7f700082cdb69 Mon Sep 17 00:00:00 2001 From: Nicolay Mitropolsky Date: Wed, 20 Mar 2019 20:01:27 +0300 Subject: [PATCH] Uast: stop resolve parts of fqn to the full-name target --- .../KotlinUSimpleReferenceExpression.kt | 42 ++++++++++--------- .../KotlinUSimpleReferenceExpression.kt.191 | 42 ++++++++++--------- .../internal/kotlinInternalUastUtils.kt | 14 ++++++- .../testData/Anonymous.resolved.txt | 14 +++---- .../testData/SimpleAnnotated.resolved.txt | 2 +- .../uast-kotlin/testData/TypeReferences.kt | 2 + .../testData/TypeReferences.log.txt | 8 ++-- .../testData/TypeReferences.render.txt | 5 ++- .../testData/TypeReferences.resolved.txt | 6 ++- 9 files changed, 82 insertions(+), 53 deletions(-) diff --git a/plugins/uast-kotlin/src/org/jetbrains/uast/kotlin/expressions/KotlinUSimpleReferenceExpression.kt b/plugins/uast-kotlin/src/org/jetbrains/uast/kotlin/expressions/KotlinUSimpleReferenceExpression.kt index 9a2dcebe3af..ad65264834a 100644 --- a/plugins/uast-kotlin/src/org/jetbrains/uast/kotlin/expressions/KotlinUSimpleReferenceExpression.kt +++ b/plugins/uast-kotlin/src/org/jetbrains/uast/kotlin/expressions/KotlinUSimpleReferenceExpression.kt @@ -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 diff --git a/plugins/uast-kotlin/src/org/jetbrains/uast/kotlin/expressions/KotlinUSimpleReferenceExpression.kt.191 b/plugins/uast-kotlin/src/org/jetbrains/uast/kotlin/expressions/KotlinUSimpleReferenceExpression.kt.191 index 6ce62734c92..b8ae2493eb5 100644 --- a/plugins/uast-kotlin/src/org/jetbrains/uast/kotlin/expressions/KotlinUSimpleReferenceExpression.kt.191 +++ b/plugins/uast-kotlin/src/org/jetbrains/uast/kotlin/expressions/KotlinUSimpleReferenceExpression.kt.191 @@ -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 diff --git a/plugins/uast-kotlin/src/org/jetbrains/uast/kotlin/internal/kotlinInternalUastUtils.kt b/plugins/uast-kotlin/src/org/jetbrains/uast/kotlin/internal/kotlinInternalUastUtils.kt index 06b0b9dd73f..7a317c3a10c 100644 --- a/plugins/uast-kotlin/src/org/jetbrains/uast/kotlin/internal/kotlinInternalUastUtils.kt +++ b/plugins/uast-kotlin/src/org/jetbrains/uast/kotlin/internal/kotlinInternalUastUtils.kt @@ -66,7 +66,7 @@ import java.text.StringCharacterIterator internal val KOTLIN_CACHED_UELEMENT_KEY = Key.create>("cached-kotlin-uelement") @Suppress("NOTHING_TO_INLINE") -internal inline fun String?.orAnonymous(kind: String = ""): String = this ?: "" +internal inline fun String?.orAnonymous(kind: String = ""): String = this ?: "" 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 + + diff --git a/plugins/uast-kotlin/testData/Anonymous.resolved.txt b/plugins/uast-kotlin/testData/Anonymous.resolved.txt index bd16b1e0b71..118c7aed23f 100644 --- a/plugins/uast-kotlin/testData/Anonymous.resolved.txt +++ b/plugins/uast-kotlin/testData/Anonymous.resolved.txt @@ -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 diff --git a/plugins/uast-kotlin/testData/SimpleAnnotated.resolved.txt b/plugins/uast-kotlin/testData/SimpleAnnotated.resolved.txt index 39b17830316..04be645d0ff 100644 --- a/plugins/uast-kotlin/testData/SimpleAnnotated.resolved.txt +++ b/plugins/uast-kotlin/testData/SimpleAnnotated.resolved.txt @@ -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 diff --git a/plugins/uast-kotlin/testData/TypeReferences.kt b/plugins/uast-kotlin/testData/TypeReferences.kt index 43823a90f55..ab79a5175b0 100644 --- a/plugins/uast-kotlin/testData/TypeReferences.kt +++ b/plugins/uast-kotlin/testData/TypeReferences.kt @@ -5,6 +5,7 @@ fun foo(parameter: Int): String { return result } +typealias ListOfLists = List> fun parameterizedFoo(arg: T?) { val a = arg @@ -13,6 +14,7 @@ fun parameterizedFoo(arg: T?) { val tl: List = listOf(at) val tsl: List = tl.map { it.toString() } val lls: List> + val llsAliased: ListOfLists val llt: List> parameterizedFoo>(emptyList()) diff --git a/plugins/uast-kotlin/testData/TypeReferences.log.txt b/plugins/uast-kotlin/testData/TypeReferences.log.txt index 56df6e6760c..3409cf0f55c 100644 --- a/plugins/uast-kotlin/testData/TypeReferences.log.txt +++ b/plugins/uast-kotlin/testData/TypeReferences.log.txt @@ -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)) diff --git a/plugins/uast-kotlin/testData/TypeReferences.render.txt b/plugins/uast-kotlin/testData/TypeReferences.render.txt index cdd782cf975..d5037fdf807 100644 --- a/plugins/uast-kotlin/testData/TypeReferences.render.txt +++ b/plugins/uast-kotlin/testData/TypeReferences.render.txt @@ -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 = listOf(at) var tsl: java.util.List = tl.map({ it.toString() }) var lls: java.util.List> + var llsAliased: java.util.List> var llt: java.util.List> parameterizedFoo(emptyList()) } diff --git a/plugins/uast-kotlin/testData/TypeReferences.resolved.txt b/plugins/uast-kotlin/testData/TypeReferences.resolved.txt index 564ade2c819..f1f5f7febdf 100644 --- a/plugins/uast-kotlin/testData/TypeReferences.resolved.txt +++ b/plugins/uast-kotlin/testData/TypeReferences.resolved.txt @@ -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 = ) -> USimpleNameReferenceExpression (identifier = List) -> PsiClass:List: List +UTypeReferenceExpression (name = ) -> USimpleNameReferenceExpression (identifier = List) -> PsiClass:List: List +UTypeReferenceExpression (name = ) -> 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) -> 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>) -> USimpleNameReferenceExpression (identifier = List) -> PsiClass:List: List UTypeReferenceExpression (name = java.util.List) -> USimpleNameReferenceExpression (identifier = List) -> PsiClass:List: List UTypeReferenceExpression (name = java.lang.String) -> USimpleNameReferenceExpression (identifier = String) -> PsiClass:String: String + UTypeReferenceExpression (name = java.util.List>) -> USimpleNameReferenceExpression (identifier = ListOfLists) -> PsiClass:List: List UTypeReferenceExpression (name = java.util.List>) -> USimpleNameReferenceExpression (identifier = List) -> PsiClass:List: List UTypeReferenceExpression (name = java.util.List) -> USimpleNameReferenceExpression (identifier = List) -> PsiClass:List: List UTypeReferenceExpression (name = T) -> USimpleNameReferenceExpression (identifier = T) -> KotlinLightTypeParameter:T: T