Uast: Fix getExpressionType for elvis expression

#KT-18997 Fixed Target Versions 1.1.5
This commit is contained in:
Vyacheslav Gerasimov
2017-08-21 23:55:43 +03:00
parent e06cb1ec39
commit 2e1edaf3d4
3 changed files with 31 additions and 6 deletions
@@ -2,8 +2,11 @@ package org.jetbrains.uast.kotlin.expressions
import com.intellij.psi.PsiElement import com.intellij.psi.PsiElement
import com.intellij.psi.PsiMethod import com.intellij.psi.PsiMethod
import com.intellij.psi.PsiType
import org.jetbrains.kotlin.psi.KtBinaryExpression import org.jetbrains.kotlin.psi.KtBinaryExpression
import org.jetbrains.kotlin.psi.KtExpression import org.jetbrains.kotlin.psi.KtExpression
import org.jetbrains.kotlin.resolve.BindingContext
import org.jetbrains.kotlin.types.CommonSupertypes
import org.jetbrains.uast.* import org.jetbrains.uast.*
import org.jetbrains.uast.kotlin.* import org.jetbrains.uast.kotlin.*
import org.jetbrains.uast.kotlin.kinds.KotlinSpecialExpressionKinds import org.jetbrains.uast.kotlin.kinds.KotlinSpecialExpressionKinds
@@ -69,7 +72,7 @@ fun createElvisExpression(elvisExpression: KtBinaryExpression, containingElement
val left = elvisExpression.left ?: return UastEmptyExpression val left = elvisExpression.left ?: return UastEmptyExpression
val right = elvisExpression.right ?: return UastEmptyExpression val right = elvisExpression.right ?: return UastEmptyExpression
return object : UExpressionList, KotlinEvaluatableUElement, KotlinUElementWithType { return object : UExpressionList, KotlinEvaluatableUElement {
override val psi: PsiElement? = elvisExpression override val psi: PsiElement? = elvisExpression
override val kind = KotlinSpecialExpressionKinds.ELVIS override val kind = KotlinSpecialExpressionKinds.ELVIS
override val uastParent: UElement? = containingElement override val uastParent: UElement? = containingElement
@@ -77,9 +80,19 @@ fun createElvisExpression(elvisExpression: KtBinaryExpression, containingElement
override val expressions: List<UExpression> by lz { override val expressions: List<UExpression> by lz {
createElvisExpressions(left, right, this, elvisExpression.parent) createElvisExpressions(left, right, this, elvisExpression.parent)
} }
override fun asRenderString(): String = kind.name + " " + override fun asRenderString(): String {
expressions.joinToString(separator = "\n", prefix = "{\n", postfix = "\n}") { return kind.name + " " +
it.asRenderString().withMargin expressions.joinToString(separator = "\n", prefix = "{\n", postfix = "\n}") {
} it.asRenderString().withMargin
}
}
override fun getExpressionType(): PsiType? {
val leftType = left.analyze()[BindingContext.EXPRESSION_TYPE_INFO, left]?.type ?: return null
val rightType = right.analyze()[BindingContext.EXPRESSION_TYPE_INFO, right]?.type ?: return null
return CommonSupertypes
.commonSupertype(listOf(leftType, rightType))
.toPsiType(this, elvisExpression, boxed = false)
}
} }
} }
+6
View File
@@ -0,0 +1,6 @@
fun foo(text: String?) = bar(text ?: return)
fun bar(o: Any) {
}
@@ -7,7 +7,6 @@ import org.jetbrains.kotlin.psi.psiUtil.getParentOfType
import org.jetbrains.kotlin.test.testFramework.KtUsefulTestCase import org.jetbrains.kotlin.test.testFramework.KtUsefulTestCase
import org.jetbrains.uast.* import org.jetbrains.uast.*
import org.jetbrains.uast.test.env.findElementByText import org.jetbrains.uast.test.env.findElementByText
import org.jetbrains.uast.visitor.UastVisitor
import org.junit.Assert import org.junit.Assert
import org.junit.Test import org.junit.Test
@@ -98,4 +97,11 @@ class KotlinUastApiTest : AbstractKotlinUastTest() {
test2.fields.find { it.name == "bar" }!!.annotations.single { it.qualifiedName == "MyAnnotation" } test2.fields.find { it.name == "bar" }!!.annotations.single { it.qualifiedName == "MyAnnotation" }
} }
} }
@Test fun testElvisType() {
doTest("ElvisType") { _, file ->
val elvisExpression = file.findElementByText<UExpression>("text ?: return")
assertEquals("String", elvisExpression.getExpressionType()!!.presentableText)
}
}
} }