From 72860fb6955896bf568b7274bd6fa9f6657b520f Mon Sep 17 00:00:00 2001 From: Nicolay Mitropolsky Date: Tue, 26 Feb 2019 20:16:05 +0300 Subject: [PATCH] Uast: making `KotlinUSimpleReferenceExpression` able to resolve to types --- .../KotlinUSimpleReferenceExpression.kt | 9 +++- .../KotlinUSimpleReferenceExpression.kt.191 | 10 +++- .../testData/Anonymous.resolved.txt | 24 ++++++++++ .../testData/ClassAnnotation.resolved.txt | 6 +++ .../testData/Constructors.resolved.txt | 48 +++++++++++++++++++ .../testData/LocalDeclarations.resolved.txt | 8 ++++ .../testData/SimpleAnnotated.resolved.txt | 5 ++ .../uast-kotlin/testData/TypeReferences.kt | 4 +- .../testData/TypeReferences.resolved.txt | 7 +++ 9 files changed, 117 insertions(+), 4 deletions(-) create mode 100644 plugins/uast-kotlin/testData/Anonymous.resolved.txt create mode 100644 plugins/uast-kotlin/testData/ClassAnnotation.resolved.txt create mode 100644 plugins/uast-kotlin/testData/Constructors.resolved.txt create mode 100644 plugins/uast-kotlin/testData/LocalDeclarations.resolved.txt create mode 100644 plugins/uast-kotlin/testData/SimpleAnnotated.resolved.txt create mode 100644 plugins/uast-kotlin/testData/TypeReferences.resolved.txt 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 973580ce043..fd722e7fbc2 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 @@ -20,6 +20,7 @@ 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 org.jetbrains.kotlin.descriptors.CallableDescriptor import org.jetbrains.kotlin.descriptors.ConstructorDescriptor import org.jetbrains.kotlin.descriptors.DeclarationDescriptor @@ -28,6 +29,7 @@ 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.calls.callUtil.getResolvedCall import org.jetbrains.kotlin.resolve.calls.model.ResolvedCall import org.jetbrains.kotlin.serialization.deserialization.descriptors.DeserializedCallableMemberDescriptor @@ -43,7 +45,12 @@ open class KotlinUSimpleReferenceExpression( override val psi: KtSimpleNameExpression, givenParent: UElement? ) : KotlinAbstractUExpression(givenParent), USimpleNameReferenceExpression, KotlinUElementWithType, KotlinEvaluatableUElement { - private val resolvedDeclaration by lz { psi.resolveCallToDeclaration(this) } + 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) + } override val identifier get() = psi.getReferencedName() 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 1f7b3003b55..5e621b471a9 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 @@ -20,6 +20,7 @@ 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 org.jetbrains.kotlin.descriptors.CallableDescriptor import org.jetbrains.kotlin.descriptors.ConstructorDescriptor import org.jetbrains.kotlin.descriptors.DeclarationDescriptor @@ -28,6 +29,7 @@ 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.calls.callUtil.getResolvedCall import org.jetbrains.kotlin.resolve.calls.model.ResolvedCall import org.jetbrains.kotlin.serialization.deserialization.descriptors.DeserializedCallableMemberDescriptor @@ -43,8 +45,12 @@ open class KotlinUSimpleReferenceExpression( override val psi: KtSimpleNameExpression, givenParent: UElement? ) : KotlinAbstractUExpression(givenParent), USimpleNameReferenceExpression, KotlinUElementWithType, KotlinEvaluatableUElement { - - private val resolvedDeclaration by lz { psi.resolveCallToDeclaration(this) } + 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) + } override val identifier get() = psi.getReferencedName() diff --git a/plugins/uast-kotlin/testData/Anonymous.resolved.txt b/plugins/uast-kotlin/testData/Anonymous.resolved.txt new file mode 100644 index 00000000000..bd16b1e0b71 --- /dev/null +++ b/plugins/uast-kotlin/testData/Anonymous.resolved.txt @@ -0,0 +1,24 @@ +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 +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 + UTypeReferenceExpression (name = java.lang.Runnable) -> USimpleNameReferenceExpression (identifier = Runnable) -> PsiClass:Runnable: Runnable + UBlockExpression -> UQualifiedReferenceExpression -> KtLightMethodImpl:run: run + UQualifiedReferenceExpression -> USimpleNameReferenceExpression (identifier = runnable) -> LightVariableBuilder:runnable: runnable + UCallExpression (kind = UastCallKind(name='method_call'), argCount = 0)) -> USimpleNameReferenceExpression (identifier = run) -> KtLightMethodImpl:run: run + UCallExpression (kind = UastCallKind(name='method_call'), argCount = 1)) -> USimpleNameReferenceExpression (identifier = Runnable) -> PsiClass:Runnable: Runnable + UCallExpression (kind = UastCallKind(name='method_call'), argCount = 0)) -> USimpleNameReferenceExpression (identifier = println) -> null: null + UBlockExpression -> UQualifiedReferenceExpression -> PsiMethod:run: run + UQualifiedReferenceExpression -> USimpleNameReferenceExpression (identifier = runnable2) -> LightVariableBuilder:runnable2: runnable2 + 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.lang.Runnable) -> USimpleNameReferenceExpression (identifier = Runnable) -> PsiClass:Runnable: Runnable + UTypeReferenceExpression (name = int) -> USimpleNameReferenceExpression (identifier = Int) -> PsiClass:Integer: Integer diff --git a/plugins/uast-kotlin/testData/ClassAnnotation.resolved.txt b/plugins/uast-kotlin/testData/ClassAnnotation.resolved.txt new file mode 100644 index 00000000000..a876ad46419 --- /dev/null +++ b/plugins/uast-kotlin/testData/ClassAnnotation.resolved.txt @@ -0,0 +1,6 @@ +UTypeReferenceExpression (name = ) -> USimpleNameReferenceExpression (identifier = Test) -> null: null +UTypeReferenceExpression (name = java.lang.String) -> USimpleNameReferenceExpression (identifier = String) -> PsiClass:String: String +UTypeReferenceExpression (name = MyAnnotation) -> USimpleNameReferenceExpression (identifier = MyAnnotation) -> KtLightClassImpl:annotation class MyAnnotation(val text: String): MyAnnotation +UTypeReferenceExpression (name = MyAnnotation) -> USimpleNameReferenceExpression (identifier = MyAnnotation) -> KtLightClassImpl:annotation class MyAnnotation(val text: String): MyAnnotation +UTypeReferenceExpression (name = MyAnnotation) -> USimpleNameReferenceExpression (identifier = MyAnnotation) -> KtLightClassImpl:annotation class MyAnnotation(val text: String): MyAnnotation +UTypeReferenceExpression (name = MyAnnotation) -> USimpleNameReferenceExpression (identifier = MyAnnotation) -> KtLightClassImpl:annotation class MyAnnotation(val text: String): MyAnnotation diff --git a/plugins/uast-kotlin/testData/Constructors.resolved.txt b/plugins/uast-kotlin/testData/Constructors.resolved.txt new file mode 100644 index 00000000000..f4382442c5c --- /dev/null +++ b/plugins/uast-kotlin/testData/Constructors.resolved.txt @@ -0,0 +1,48 @@ +UTypeReferenceExpression (name = java.lang.String) -> USimpleNameReferenceExpression (identifier = String) -> PsiClass:String: String +UTypeReferenceExpression (name = int) -> USimpleNameReferenceExpression (identifier = Int) -> PsiClass:Integer: Integer +UCallExpression (kind = UastCallKind(name='constructor_call'), argCount = 1)) -> UQualifiedReferenceExpression -> null: null +UQualifiedReferenceExpression -> USimpleNameReferenceExpression (identifier = i) -> Light Parameter: i +UCallExpression (kind = UastCallKind(name='method_call'), argCount = 0)) -> USimpleNameReferenceExpression (identifier = toString) -> null: null +UTypeReferenceExpression (name = java.lang.String) -> USimpleNameReferenceExpression (identifier = String) -> PsiClass:String: String + UCallExpression (kind = UastCallKind(name='method_call'), argCount = 0)) -> USimpleNameReferenceExpression (identifier = println) -> null: null +UTypeReferenceExpression (name = int) -> USimpleNameReferenceExpression (identifier = Int) -> PsiClass:Integer: Integer +UCallExpression (kind = UastCallKind(name='constructor_call'), argCount = 1)) -> UQualifiedReferenceExpression -> null: null +UQualifiedReferenceExpression -> USimpleNameReferenceExpression (identifier = i) -> Light Parameter: i +UCallExpression (kind = UastCallKind(name='method_call'), argCount = 0)) -> USimpleNameReferenceExpression (identifier = toString) -> null: null +UTypeReferenceExpression (name = java.lang.String) -> USimpleNameReferenceExpression (identifier = String) -> PsiClass:String: String + UCallExpression (kind = UastCallKind(name='method_call'), argCount = 1)) -> USimpleNameReferenceExpression (identifier = println) -> null: null + UCallExpression (kind = UastCallKind(name='method_call'), argCount = 1)) -> USimpleNameReferenceExpression (identifier = println) -> null: null +UTypeReferenceExpression (name = int) -> USimpleNameReferenceExpression (identifier = Int) -> PsiClass:Integer: Integer +UCallExpression (kind = UastCallKind(name='constructor_call'), argCount = 1)) -> UQualifiedReferenceExpression -> null: null +UQualifiedReferenceExpression -> USimpleNameReferenceExpression (identifier = i) -> Light Parameter: i +UCallExpression (kind = UastCallKind(name='method_call'), argCount = 0)) -> USimpleNameReferenceExpression (identifier = toString) -> null: null + UCallExpression (kind = UastCallKind(name='method_call'), argCount = 1)) -> USimpleNameReferenceExpression (identifier = println) -> null: null + UCallExpression (kind = UastCallKind(name='method_call'), argCount = 1)) -> USimpleNameReferenceExpression (identifier = println) -> null: null +UTypeReferenceExpression (name = java.lang.String) -> USimpleNameReferenceExpression (identifier = String) -> PsiClass:String: String +UTypeReferenceExpression (name = int) -> USimpleNameReferenceExpression (identifier = Int) -> PsiClass:Integer: Integer + UBinaryExpression (operator = =) -> USimpleNameReferenceExpression (identifier = a) -> KtLightMethodImpl:getA: getA + UBinaryExpression (operator = =) -> USimpleNameReferenceExpression (identifier = =) -> null: null + UBinaryExpression (operator = =) -> UQualifiedReferenceExpression -> null: null + UQualifiedReferenceExpression -> USimpleNameReferenceExpression (identifier = i) -> Light Parameter: i + UCallExpression (kind = UastCallKind(name='method_call'), argCount = 0)) -> USimpleNameReferenceExpression (identifier = toString) -> null: null +UTypeReferenceExpression (name = java.lang.String) -> USimpleNameReferenceExpression (identifier = String) -> PsiClass:String: String + UBinaryExpression (operator = =) -> USimpleNameReferenceExpression (identifier = a) -> KtLightMethodImpl:getA: getA + UBinaryExpression (operator = =) -> USimpleNameReferenceExpression (identifier = =) -> null: null + UBinaryExpression (operator = =) -> USimpleNameReferenceExpression (identifier = s) -> Light Parameter: s +UTypeReferenceExpression (name = java.lang.String) -> USimpleNameReferenceExpression (identifier = String) -> PsiClass:String: String + UCallExpression (kind = UastCallKind(name='method_call'), argCount = 0)) -> USimpleNameReferenceExpression (identifier = println) -> null: null +UTypeReferenceExpression (name = int) -> USimpleNameReferenceExpression (identifier = Int) -> PsiClass:Integer: Integer + UBinaryExpression (operator = =) -> USimpleNameReferenceExpression (identifier = a) -> KtLightMethodImpl:getA: getA + UBinaryExpression (operator = =) -> USimpleNameReferenceExpression (identifier = =) -> null: null + UBinaryExpression (operator = =) -> UQualifiedReferenceExpression -> null: null + UQualifiedReferenceExpression -> USimpleNameReferenceExpression (identifier = i) -> Light Parameter: i + UCallExpression (kind = UastCallKind(name='method_call'), argCount = 0)) -> USimpleNameReferenceExpression (identifier = toString) -> null: null +UTypeReferenceExpression (name = java.lang.String) -> USimpleNameReferenceExpression (identifier = String) -> PsiClass:String: String + UBinaryExpression (operator = =) -> USimpleNameReferenceExpression (identifier = a) -> KtLightMethodImpl:getA: getA + UBinaryExpression (operator = =) -> USimpleNameReferenceExpression (identifier = =) -> null: null + UBinaryExpression (operator = =) -> USimpleNameReferenceExpression (identifier = s) -> Light Parameter: s + UTypeReferenceExpression (name = java.lang.String) -> USimpleNameReferenceExpression (identifier = String) -> PsiClass:String: String + ULocalVariable (name = local) -> USimpleNameReferenceExpression (identifier = s) -> Light Parameter: s + UBlockExpression -> UQualifiedReferenceExpression -> null: null + UQualifiedReferenceExpression -> USimpleNameReferenceExpression (identifier = local) -> LightVariableBuilder:local: local + UCallExpression (kind = UastCallKind(name='method_call'), argCount = 0)) -> USimpleNameReferenceExpression (identifier = toString) -> null: null diff --git a/plugins/uast-kotlin/testData/LocalDeclarations.resolved.txt b/plugins/uast-kotlin/testData/LocalDeclarations.resolved.txt new file mode 100644 index 00000000000..af61d785282 --- /dev/null +++ b/plugins/uast-kotlin/testData/LocalDeclarations.resolved.txt @@ -0,0 +1,8 @@ +UTypeReferenceExpression (name = boolean) -> USimpleNameReferenceExpression (identifier = Boolean) -> PsiClass:Boolean: Boolean + UCallExpression (kind = UastCallKind(name='constructor_call'), argCount = 0)) -> USimpleNameReferenceExpression (identifier = Local) -> KtLightClassForLocalDeclaration:class Local: Local + UCallExpression (kind = UastCallKind(name='constructor_call'), argCount = 0)) -> USimpleNameReferenceExpression (identifier = Local) -> KtLightClassForLocalDeclaration:class Local: Local + UTypeReferenceExpression (name = int) -> USimpleNameReferenceExpression (identifier = Int) -> PsiClass:Integer: Integer + UTypeReferenceExpression (name = java.lang.String) -> USimpleNameReferenceExpression (identifier = String) -> PsiClass:String: String + UCallExpression (kind = UastCallKind(name='method_call'), argCount = 0)) -> USimpleNameReferenceExpression (identifier = bar) -> null: null + UBinaryExpression (operator = ==) -> USimpleNameReferenceExpression (identifier = ==) -> null: null + UCallExpression (kind = UastCallKind(name='constructor_call'), argCount = 0)) -> USimpleNameReferenceExpression (identifier = Local) -> KtLightClassForLocalDeclaration:class Local: Local diff --git a/plugins/uast-kotlin/testData/SimpleAnnotated.resolved.txt b/plugins/uast-kotlin/testData/SimpleAnnotated.resolved.txt new file mode 100644 index 00000000000..39b17830316 --- /dev/null +++ b/plugins/uast-kotlin/testData/SimpleAnnotated.resolved.txt @@ -0,0 +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 = 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 a4cf705ab6f..e55a777cafd 100644 --- a/plugins/uast-kotlin/testData/TypeReferences.kt +++ b/plugins/uast-kotlin/testData/TypeReferences.kt @@ -1,4 +1,6 @@ -fun foo(parameter: Int) { +fun foo(parameter: Int): String { val varWithType: String? = "Not Null" val varWithoutType = "lorem ipsum" + var result = varWithType + varWithoutType + return result } diff --git a/plugins/uast-kotlin/testData/TypeReferences.resolved.txt b/plugins/uast-kotlin/testData/TypeReferences.resolved.txt new file mode 100644 index 00000000000..7aefa9b9a05 --- /dev/null +++ b/plugins/uast-kotlin/testData/TypeReferences.resolved.txt @@ -0,0 +1,7 @@ +UTypeReferenceExpression (name = int) -> USimpleNameReferenceExpression (identifier = Int) -> PsiClass:Integer: Integer +UTypeReferenceExpression (name = java.lang.String) -> USimpleNameReferenceExpression (identifier = String) -> PsiClass:String: String + UTypeReferenceExpression (name = java.lang.String) -> USimpleNameReferenceExpression (identifier = String) -> PsiClass:String: String + UBinaryExpression (operator = +) -> USimpleNameReferenceExpression (identifier = varWithType) -> LightVariableBuilder:varWithType: varWithType + UBinaryExpression (operator = +) -> USimpleNameReferenceExpression (identifier = +) -> null: null + UBinaryExpression (operator = +) -> USimpleNameReferenceExpression (identifier = varWithoutType) -> LightVariableBuilder:varWithoutType: varWithoutType + UReturnExpression -> USimpleNameReferenceExpression (identifier = result) -> LightVariableBuilder:result: result