191: Uast: UInjectionHost moved under flag kotlin.uast.force.uinjectionhost (KT-27283)
This commit is contained in:
@@ -79,9 +79,14 @@ abstract class KotlinAbstractUElement(private val givenParent: UElement?) : Kotl
|
||||
parent = parent.parent
|
||||
}
|
||||
|
||||
if (parent is KtBlockStringTemplateEntry) {
|
||||
parent = parent.parent
|
||||
}
|
||||
if (KotlinConverter.forceUInjectionHost) {
|
||||
if (parent is KtBlockStringTemplateEntry) {
|
||||
parent = parent.parent
|
||||
}
|
||||
} else
|
||||
while (parent is KtStringTemplateEntryWithExpression || parent is KtStringTemplateExpression && parent.entries.size == 1) {
|
||||
parent = parent.parent
|
||||
}
|
||||
|
||||
if (parent is KtWhenConditionWithExpression) {
|
||||
parent = parent.parent
|
||||
@@ -109,7 +114,7 @@ abstract class KotlinAbstractUElement(private val givenParent: UElement?) : Kotl
|
||||
|
||||
val result = doConvertParent(this, parent)
|
||||
if (result == this) {
|
||||
throw IllegalStateException("Loop in parent structure when converting a $psi of type ${psi?.javaClass} with parent $parent of type ${parent?.javaClass} text: [${parent?.text}]")
|
||||
throw IllegalStateException("Loop in parent structure when converting a $psi of type ${psi?.javaClass} with parent $parent of type ${parent?.javaClass} text: [${parent?.text}], result = $result")
|
||||
}
|
||||
|
||||
return result
|
||||
|
||||
@@ -19,9 +19,11 @@ package org.jetbrains.uast.kotlin
|
||||
import com.intellij.lang.Language
|
||||
import com.intellij.openapi.components.ServiceManager
|
||||
import com.intellij.openapi.util.Key
|
||||
import com.intellij.openapi.util.registry.Registry
|
||||
import com.intellij.psi.PsiElement
|
||||
import com.intellij.psi.PsiFile
|
||||
import com.intellij.psi.impl.source.tree.LeafPsiElement
|
||||
import org.jetbrains.annotations.TestOnly
|
||||
import org.jetbrains.kotlin.asJava.LightClassUtil
|
||||
import org.jetbrains.kotlin.asJava.classes.KtLightClass
|
||||
import org.jetbrains.kotlin.asJava.classes.KtLightClassForFacade
|
||||
@@ -394,6 +396,12 @@ internal object KotlinConverter {
|
||||
}
|
||||
}
|
||||
|
||||
var forceUInjectionHost = Registry.`is`("kotlin.uast.force.uinjectionhost", false)
|
||||
@TestOnly
|
||||
set(value) {
|
||||
field = value
|
||||
}
|
||||
|
||||
internal fun convertExpression(expression: KtExpression,
|
||||
givenParent: UElement?,
|
||||
requiredType: Class<out UElement>? = null): UExpression? {
|
||||
@@ -404,7 +412,20 @@ internal object KotlinConverter {
|
||||
return with (requiredType) { when (expression) {
|
||||
is KtVariableDeclaration -> expr<UDeclarationsExpression>(build(::convertVariablesDeclaration))
|
||||
|
||||
is KtStringTemplateExpression -> expr<UInjectionHost> { KotlinStringTemplateUPolyadicExpression(expression, givenParent) }
|
||||
is KtStringTemplateExpression -> {
|
||||
when {
|
||||
forceUInjectionHost || (requiredType != null && UInjectionHost::class.java.isAssignableFrom(requiredType)) ->
|
||||
expr<UInjectionHost> { KotlinStringTemplateUPolyadicExpression(expression, givenParent) }
|
||||
expression.entries.isEmpty() -> {
|
||||
expr<ULiteralExpression> { KotlinStringULiteralExpression(expression, givenParent, "") }
|
||||
}
|
||||
|
||||
expression.entries.size == 1 -> convertEntry(expression.entries[0], givenParent, requiredType)
|
||||
|
||||
else ->
|
||||
expr<KotlinStringTemplateUPolyadicExpression> { KotlinStringTemplateUPolyadicExpression(expression, givenParent) }
|
||||
}
|
||||
}
|
||||
is KtDestructuringDeclaration -> expr<UDeclarationsExpression> {
|
||||
val declarationsExpression = KotlinUDestructuringDeclarationExpression(givenParent, expression)
|
||||
declarationsExpression.apply {
|
||||
|
||||
@@ -0,0 +1,17 @@
|
||||
val muchRecur = "${"${"${"abc"}"}"}"
|
||||
|
||||
val case4 = "a ${"literal"} z"
|
||||
|
||||
val case5 = "a ${"literal"} ${"literal"} z"
|
||||
|
||||
val literalInLiteral = "a ${"literal$case4"} z"
|
||||
|
||||
val literalInLiteral2 = "a ${"literal$case4".repeat(4)} z"
|
||||
|
||||
fun simpleForTemplate(i: Int = 0) = "$i"
|
||||
|
||||
fun foo() {
|
||||
println("$baz")
|
||||
val template1 = "${simpleForTemplate()}"
|
||||
val template2 = ".${simpleForTemplate()}"
|
||||
}
|
||||
+80
@@ -0,0 +1,80 @@
|
||||
UFile (package = )
|
||||
UClass (name = StringTemplateComplexForUInjectionHostKt)
|
||||
UField (name = muchRecur)
|
||||
UAnnotation (fqName = org.jetbrains.annotations.NotNull)
|
||||
UPolyadicExpression (operator = +)
|
||||
UPolyadicExpression (operator = +)
|
||||
UPolyadicExpression (operator = +)
|
||||
UPolyadicExpression (operator = +)
|
||||
ULiteralExpression (value = "abc")
|
||||
UField (name = case4)
|
||||
UAnnotation (fqName = org.jetbrains.annotations.NotNull)
|
||||
UPolyadicExpression (operator = +)
|
||||
ULiteralExpression (value = "a ")
|
||||
UPolyadicExpression (operator = +)
|
||||
ULiteralExpression (value = "literal")
|
||||
ULiteralExpression (value = " z")
|
||||
UField (name = case5)
|
||||
UAnnotation (fqName = org.jetbrains.annotations.NotNull)
|
||||
UPolyadicExpression (operator = +)
|
||||
ULiteralExpression (value = "a ")
|
||||
UPolyadicExpression (operator = +)
|
||||
ULiteralExpression (value = "literal")
|
||||
ULiteralExpression (value = " ")
|
||||
UPolyadicExpression (operator = +)
|
||||
ULiteralExpression (value = "literal")
|
||||
ULiteralExpression (value = " z")
|
||||
UField (name = literalInLiteral)
|
||||
UAnnotation (fqName = org.jetbrains.annotations.NotNull)
|
||||
UPolyadicExpression (operator = +)
|
||||
ULiteralExpression (value = "a ")
|
||||
UPolyadicExpression (operator = +)
|
||||
ULiteralExpression (value = "literal")
|
||||
USimpleNameReferenceExpression (identifier = case4)
|
||||
ULiteralExpression (value = " z")
|
||||
UField (name = literalInLiteral2)
|
||||
UAnnotation (fqName = org.jetbrains.annotations.NotNull)
|
||||
UPolyadicExpression (operator = +)
|
||||
ULiteralExpression (value = "a ")
|
||||
UQualifiedReferenceExpression
|
||||
UPolyadicExpression (operator = +)
|
||||
ULiteralExpression (value = "literal")
|
||||
USimpleNameReferenceExpression (identifier = case4)
|
||||
UCallExpression (kind = UastCallKind(name='method_call'), argCount = 1))
|
||||
UIdentifier (Identifier (repeat))
|
||||
USimpleNameReferenceExpression (identifier = repeat)
|
||||
ULiteralExpression (value = 4)
|
||||
ULiteralExpression (value = " z")
|
||||
UAnnotationMethod (name = getMuchRecur)
|
||||
UAnnotationMethod (name = getCase4)
|
||||
UAnnotationMethod (name = getCase5)
|
||||
UAnnotationMethod (name = getLiteralInLiteral)
|
||||
UAnnotationMethod (name = getLiteralInLiteral2)
|
||||
UAnnotationMethod (name = simpleForTemplate)
|
||||
UParameter (name = i)
|
||||
UAnnotation (fqName = org.jetbrains.annotations.NotNull)
|
||||
ULiteralExpression (value = 0)
|
||||
UBlockExpression
|
||||
UReturnExpression
|
||||
UPolyadicExpression (operator = +)
|
||||
USimpleNameReferenceExpression (identifier = i)
|
||||
UAnnotationMethod (name = foo)
|
||||
UBlockExpression
|
||||
UCallExpression (kind = UastCallKind(name='method_call'), argCount = 1))
|
||||
UIdentifier (Identifier (println))
|
||||
USimpleNameReferenceExpression (identifier = println)
|
||||
UPolyadicExpression (operator = +)
|
||||
USimpleNameReferenceExpression (identifier = baz)
|
||||
UDeclarationsExpression
|
||||
ULocalVariable (name = template1)
|
||||
UPolyadicExpression (operator = +)
|
||||
UCallExpression (kind = UastCallKind(name='method_call'), argCount = 0))
|
||||
UIdentifier (Identifier (simpleForTemplate))
|
||||
USimpleNameReferenceExpression (identifier = simpleForTemplate)
|
||||
UDeclarationsExpression
|
||||
ULocalVariable (name = template2)
|
||||
UPolyadicExpression (operator = +)
|
||||
ULiteralExpression (value = ".")
|
||||
UCallExpression (kind = UastCallKind(name='method_call'), argCount = 0))
|
||||
UIdentifier (Identifier (simpleForTemplate))
|
||||
USimpleNameReferenceExpression (identifier = simpleForTemplate)
|
||||
+20
@@ -0,0 +1,20 @@
|
||||
public final class StringTemplateComplexForUInjectionHostKt {
|
||||
@org.jetbrains.annotations.NotNull private static final var muchRecur: java.lang.String = "abc"
|
||||
@org.jetbrains.annotations.NotNull private static final var case4: java.lang.String = "a " + "literal" + " z"
|
||||
@org.jetbrains.annotations.NotNull private static final var case5: java.lang.String = "a " + "literal" + " " + "literal" + " z"
|
||||
@org.jetbrains.annotations.NotNull private static final var literalInLiteral: java.lang.String = "a " + "literal" + case4 + " z"
|
||||
@org.jetbrains.annotations.NotNull private static final var literalInLiteral2: java.lang.String = "a " + "literal" + case4.repeat(4) + " z"
|
||||
public static final fun getMuchRecur() : java.lang.String = UastEmptyExpression
|
||||
public static final fun getCase4() : java.lang.String = UastEmptyExpression
|
||||
public static final fun getCase5() : java.lang.String = UastEmptyExpression
|
||||
public static final fun getLiteralInLiteral() : java.lang.String = UastEmptyExpression
|
||||
public static final fun getLiteralInLiteral2() : java.lang.String = UastEmptyExpression
|
||||
public static final fun simpleForTemplate(@org.jetbrains.annotations.NotNull i: int) : java.lang.String {
|
||||
return i
|
||||
}
|
||||
public static final fun foo() : void {
|
||||
println(baz)
|
||||
var template1: java.lang.String = simpleForTemplate()
|
||||
var template2: java.lang.String = "." + simpleForTemplate()
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,103 @@
|
||||
package org.jetbrains.uast.test.kotlin
|
||||
|
||||
import org.jetbrains.uast.kotlin.KotlinConverter
|
||||
import org.junit.Test
|
||||
|
||||
class SimpleKotlinRenderLogTest : AbstractKotlinRenderLogTest() {
|
||||
@Test fun testLocalDeclarations() = doTest("LocalDeclarations")
|
||||
|
||||
@Test fun testSimple() = doTest("Simple")
|
||||
|
||||
@Test fun testWhenIs() = doTest("WhenIs")
|
||||
|
||||
@Test fun testDefaultImpls() = doTest("DefaultImpls")
|
||||
|
||||
@Test fun testElvis() = doTest("Elvis")
|
||||
|
||||
@Test fun testPropertyAccessors() = doTest("PropertyAccessors")
|
||||
|
||||
@Test fun testPropertyInitializer() = doTest("PropertyInitializer")
|
||||
|
||||
@Test fun testPropertyInitializerWithoutSetter() = doTest("PropertyInitializerWithoutSetter")
|
||||
|
||||
@Test fun testAnnotationParameters() = doTest("AnnotationParameters")
|
||||
|
||||
@Test fun testEnumValueMembers() = doTest("EnumValueMembers")
|
||||
|
||||
@Test fun testStringTemplate() = doTest("StringTemplate")
|
||||
|
||||
@Test fun testStringTemplateComplex() = doTest("StringTemplateComplex")
|
||||
|
||||
@Test
|
||||
fun testStringTemplateComplexForUInjectionHost() = withForceUInjectionHostValue {
|
||||
doTest("StringTemplateComplexForUInjectionHost")
|
||||
}
|
||||
|
||||
@Test fun testQualifiedConstructorCall() = doTest("QualifiedConstructorCall")
|
||||
|
||||
@Test fun testPropertyDelegate() = doTest("PropertyDelegate")
|
||||
|
||||
@Test fun testLocalVariableWithAnnotation() = doTest("LocalVariableWithAnnotation")
|
||||
|
||||
@Test fun testPropertyWithAnnotation() = doTest("PropertyWithAnnotation")
|
||||
|
||||
@Test fun testIfStatement() = doTest("IfStatement")
|
||||
|
||||
@Test fun testInnerClasses() = doTest("InnerClasses")
|
||||
|
||||
@Test fun testSimpleScript() = doTest("SimpleScript") { testName, file -> check(testName, file, false) }
|
||||
|
||||
@Test fun testDestructuringDeclaration() = doTest("DestructuringDeclaration")
|
||||
|
||||
@Test fun testDefaultParameterValues() = doTest("DefaultParameterValues")
|
||||
|
||||
@Test fun testParameterPropertyWithAnnotation() = doTest("ParameterPropertyWithAnnotation")
|
||||
|
||||
@Test fun testParametersWithDefaultValues() = doTest("ParametersWithDefaultValues")
|
||||
|
||||
@Test
|
||||
fun testUnexpectedContainer() = doTest("UnexpectedContainerException")
|
||||
|
||||
@Test
|
||||
fun testWhenStringLiteral() = doTest("WhenStringLiteral")
|
||||
|
||||
@Test
|
||||
fun testWhenAndDestructing() = doTest("WhenAndDestructing") { testName, file -> check(testName, file, false) }
|
||||
|
||||
@Test
|
||||
fun testSuperCalls() = doTest("SuperCalls")
|
||||
|
||||
@Test
|
||||
fun testConstructors() = doTest("Constructors")
|
||||
|
||||
@Test
|
||||
fun testClassAnnotation() = doTest("ClassAnnotation")
|
||||
|
||||
@Test
|
||||
fun testReceiverFun() = doTest("ReceiverFun")
|
||||
|
||||
@Test
|
||||
fun testAnonymous() = doTest("Anonymous")
|
||||
|
||||
@Test
|
||||
fun testAnnotationComplex() = doTest("AnnotationComplex")
|
||||
|
||||
@Test
|
||||
fun testParametersDisorder() = doTest("ParametersDisorder") { testName, file ->
|
||||
// disabled due to inconsistent parents for 2-receivers call (KT-22344)
|
||||
check(testName, file, false)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun testLambdas() = doTest("Lambdas")
|
||||
}
|
||||
|
||||
fun withForceUInjectionHostValue(call: () -> Unit) {
|
||||
val prev = KotlinConverter.forceUInjectionHost
|
||||
KotlinConverter.forceUInjectionHost = true
|
||||
try {
|
||||
call.invoke()
|
||||
} finally {
|
||||
KotlinConverter.forceUInjectionHost = prev
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user