Correctly honor expected type when converting string templates to UAST

#KT-17315 Fixed
 #KT-17316 Fixed
This commit is contained in:
Dmitry Jemerov
2017-04-18 16:57:12 +02:00
parent f801c5f3f8
commit 03cef30717
4 changed files with 44 additions and 18 deletions
@@ -250,15 +250,28 @@ internal object KotlinConverter {
} }
internal fun convert(entry: KtStringTemplateEntry, parent: UElement?): UExpression = when (entry) { internal fun convertEntry(entry: KtStringTemplateEntry,
is KtStringTemplateEntryWithExpression -> KotlinConverter.convertOrEmpty(entry.expression, parent) parentCallback: (() -> UElement?)?,
is KtEscapeStringTemplateEntry -> KotlinStringULiteralExpression(entry, parent, entry.unescapedValue) requiredType: Class<out UElement>? = null): UExpression? {
else -> { return with(requiredType) {
KotlinStringULiteralExpression(entry, parent) if (entry is KtStringTemplateEntryWithExpression) {
expr<UExpression> {
val parent = if (parentCallback == null) null else (parentCallback() ?: return null)
KotlinConverter.convertOrEmpty(entry.expression, parent)
}
}
else {
expr<ULiteralExpression> {
val parent = if (parentCallback == null) null else (parentCallback() ?: return null)
if (entry is KtEscapeStringTemplateEntry)
KotlinStringULiteralExpression(entry, parent, entry.unescapedValue)
else
KotlinStringULiteralExpression(entry, parent)
}
}
} }
} }
internal fun convertExpression(expression: KtExpression, internal fun convertExpression(expression: KtExpression,
parentCallback: (() -> UElement?)?, parentCallback: (() -> UElement?)?,
requiredType: Class<out UElement>? = null): UExpression? { requiredType: Class<out UElement>? = null): UExpression? {
@@ -272,14 +285,17 @@ internal object KotlinConverter {
return with (requiredType) { when (expression) { return with (requiredType) { when (expression) {
is KtVariableDeclaration -> expr<UDeclarationsExpression>(build(::convertVariablesDeclaration)) is KtVariableDeclaration -> expr<UDeclarationsExpression>(build(::convertVariablesDeclaration))
is KtStringTemplateExpression -> expr<ULiteralExpression> { is KtStringTemplateExpression -> {
val parent = if (parentCallback == null) null else (parentCallback() ?: return null) if (expression.entries.isEmpty()) {
if (expression.entries.isEmpty()) val parent = if (parentCallback == null) null else (parentCallback() ?: return null)
KotlinStringULiteralExpression(expression, parent, "") expr<ULiteralExpression> { KotlinStringULiteralExpression(expression, parent, "") }
}
else if (expression.entries.size == 1) else if (expression.entries.size == 1)
convert(expression.entries[0], parent) convertEntry(expression.entries[0], parentCallback, requiredType)
else else {
KotlinStringTemplateUPolyadicExpression(expression, parent) val parent = if (parentCallback == null) null else (parentCallback() ?: return null)
expr<UExpression> { KotlinStringTemplateUPolyadicExpression(expression, parent) }
}
} }
is KtDestructuringDeclaration -> expr<UDeclarationsExpression> { is KtDestructuringDeclaration -> expr<UDeclarationsExpression> {
val parent = if (parentCallback == null) null else (parentCallback() ?: return null) val parent = if (parentCallback == null) null else (parentCallback() ?: return null)
@@ -29,6 +29,6 @@ class KotlinStringTemplateUPolyadicExpression(
UPolyadicExpression, UPolyadicExpression,
KotlinUElementWithType, KotlinUElementWithType,
KotlinEvaluatableUElement { KotlinEvaluatableUElement {
override val operands: List<UExpression> by lz { psi.entries.map { KotlinConverter.convert(it, this) } } override val operands: List<UExpression> by lz { psi.entries.map { KotlinConverter.convertEntry(it, { this })!! } }
override val operator = UastBinaryOperator.PLUS override val operator = UastBinaryOperator.PLUS
} }
+2
View File
@@ -0,0 +1,2 @@
val bar = "bar"
val f = "foo$bar"
+12 -4
View File
@@ -1,11 +1,10 @@
package org.jetbrains.uast.test.kotlin package org.jetbrains.uast.test.kotlin
import org.jetbrains.kotlin.psi.KtLiteralStringTemplateEntry import org.jetbrains.kotlin.psi.KtLiteralStringTemplateEntry
import org.jetbrains.uast.UAnnotation import org.jetbrains.kotlin.psi.KtStringTemplateExpression
import org.jetbrains.uast.UFile import org.jetbrains.kotlin.psi.psiUtil.getParentOfType
import org.jetbrains.uast.ULiteralExpression import org.jetbrains.uast.*
import org.jetbrains.uast.test.env.findElementByText import org.jetbrains.uast.test.env.findElementByText
import org.jetbrains.uast.toUElement
import org.junit.Assert import org.junit.Assert
import org.junit.Test import org.junit.Test
@@ -32,4 +31,13 @@ class KotlinUastApiTest : AbstractKotlinUastTest() {
} }
} }
@Test fun testConvertStringTemplateWithExpectedType() {
doTest("StringTemplateWithVar") { _, file ->
val index = file.psi.text.indexOf("foo")
val stringTemplate = file.psi.findElementAt(index)!!.getParentOfType<KtStringTemplateExpression>(false)
val uLiteral = stringTemplate.toUElementOfType<ULiteralExpression>()
assertNull(uLiteral)
}
}
} }