Correctly honor expected type when converting string templates to UAST
#KT-17315 Fixed #KT-17316 Fixed
This commit is contained in:
@@ -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)
|
||||||
|
|||||||
+1
-1
@@ -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
|
||||||
}
|
}
|
||||||
@@ -0,0 +1,2 @@
|
|||||||
|
val bar = "bar"
|
||||||
|
val f = "foo$bar"
|
||||||
@@ -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)
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user