Switch to 191 platform
This commit is contained in:
@@ -79,10 +79,14 @@ abstract class KotlinAbstractUElement(private val givenParent: UElement?) : Kotl
|
||||
parent = parent.parent
|
||||
}
|
||||
|
||||
while (parent is KtStringTemplateEntryWithExpression ||
|
||||
parent is KtStringTemplateExpression && parent.entries.size == 1) {
|
||||
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
|
||||
@@ -110,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
|
||||
|
||||
+5
-9
@@ -79,14 +79,10 @@ abstract class KotlinAbstractUElement(private val givenParent: UElement?) : Kotl
|
||||
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
|
||||
}
|
||||
while (parent is KtStringTemplateEntryWithExpression ||
|
||||
parent is KtStringTemplateExpression && parent.entries.size == 1) {
|
||||
parent = parent.parent
|
||||
}
|
||||
|
||||
if (parent is KtWhenConditionWithExpression) {
|
||||
parent = parent.parent
|
||||
@@ -114,7 +110,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}], result = $result")
|
||||
throw IllegalStateException("Loop in parent structure when converting a $psi of type ${psi?.javaClass} with parent $parent of type ${parent?.javaClass} text: [${parent?.text}]")
|
||||
}
|
||||
|
||||
return result
|
||||
@@ -19,13 +19,16 @@ 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
|
||||
import org.jetbrains.kotlin.asJava.elements.*
|
||||
import org.jetbrains.kotlin.asJava.findFacadeClass
|
||||
import org.jetbrains.kotlin.asJava.toLightClass
|
||||
import org.jetbrains.kotlin.codegen.state.KotlinTypeMapper
|
||||
import org.jetbrains.kotlin.config.LanguageVersionSettings
|
||||
@@ -39,6 +42,7 @@ import org.jetbrains.kotlin.psi.psiUtil.getParentOfType
|
||||
import org.jetbrains.kotlin.resolve.BindingContext
|
||||
import org.jetbrains.kotlin.resolve.calls.callUtil.getResolvedCall
|
||||
import org.jetbrains.uast.*
|
||||
import org.jetbrains.uast.expressions.UInjectionHost
|
||||
import org.jetbrains.uast.kotlin.KotlinConverter.convertDeclaration
|
||||
import org.jetbrains.uast.kotlin.KotlinConverter.convertDeclarationOrElement
|
||||
import org.jetbrains.uast.kotlin.declarations.KotlinUIdentifier
|
||||
@@ -75,15 +79,15 @@ class KotlinUastLanguagePlugin : UastLanguagePlugin {
|
||||
|
||||
override fun convertElement(element: PsiElement, parent: UElement?, requiredType: Class<out UElement>?): UElement? {
|
||||
if (!element.isJvmElement) return null
|
||||
return convertDeclarationOrElement(element, parent, requiredType)
|
||||
return convertDeclarationOrElement(element, parent, elementTypes(requiredType))
|
||||
}
|
||||
|
||||
override fun convertElementWithParent(element: PsiElement, requiredType: Class<out UElement>?): UElement? {
|
||||
if (!element.isJvmElement) return null
|
||||
if (element is PsiFile) return convertDeclaration(element, null, requiredType)
|
||||
if (element is KtLightClassForFacade) return convertDeclaration(element, null, requiredType)
|
||||
if (element is PsiFile) return convertDeclaration(element, null, elementTypes(requiredType))
|
||||
if (element is KtLightClassForFacade) return convertDeclaration(element, null, elementTypes(requiredType))
|
||||
|
||||
return convertDeclarationOrElement(element, null, requiredType)
|
||||
return convertDeclarationOrElement(element, null, elementTypes(requiredType))
|
||||
}
|
||||
|
||||
override fun getMethodCallExpression(
|
||||
@@ -136,16 +140,45 @@ class KotlinUastLanguagePlugin : UastLanguagePlugin {
|
||||
else -> false
|
||||
}
|
||||
}
|
||||
|
||||
@Suppress("UNCHECKED_CAST")
|
||||
fun <T : UElement> convertElement(element: PsiElement, parent: UElement?, expectedTypes: Array<out Class<out T>>): T? {
|
||||
if (!element.isJvmElement) return null
|
||||
val nonEmptyExpectedTypes = expectedTypes.nonEmptyOr(DEFAULT_TYPES_LIST)
|
||||
return (convertDeclaration(element, parent, nonEmptyExpectedTypes)
|
||||
?: KotlinConverter.convertPsiElement(element, parent, nonEmptyExpectedTypes)) as? T
|
||||
}
|
||||
|
||||
override fun <T : UElement> convertElementWithParent(element: PsiElement, requiredTypes: Array<out Class<out T>>): T? {
|
||||
return convertElement(element, null, requiredTypes)
|
||||
}
|
||||
|
||||
@Suppress("UNCHECKED_CAST")
|
||||
override fun <T : UElement> convertToAlternatives(element: PsiElement, requiredTypes: Array<out Class<out T>>): Sequence<T> =
|
||||
if (!element.isJvmElement) emptySequence() else when {
|
||||
element is KtFile -> KotlinConverter.convertKtFile(element, null, requiredTypes) as Sequence<T>
|
||||
(element is KtProperty && !element.isLocal) ->
|
||||
KotlinConverter.convertNonLocalProperty(element, null, requiredTypes) as Sequence<T>
|
||||
element is KtParameter -> KotlinConverter.convertParameter(element, null, requiredTypes) as Sequence<T>
|
||||
element is KtClassOrObject -> KotlinConverter.convertClassOrObject(element, null, requiredTypes) as Sequence<T>
|
||||
else -> sequenceOf(convertElementWithParent(element, requiredTypes.nonEmptyOr(DEFAULT_TYPES_LIST)) as? T).filterNotNull()
|
||||
}
|
||||
}
|
||||
|
||||
internal inline fun <reified ActualT : UElement> Class<out UElement>?.el(f: () -> UElement?): UElement? {
|
||||
internal inline fun <reified ActualT : UElement> Class<*>?.el(f: () -> UElement?): UElement? {
|
||||
return if (this == null || isAssignableFrom(ActualT::class.java)) f() else null
|
||||
}
|
||||
|
||||
internal inline fun <reified ActualT : UElement> Class<out UElement>?.expr(f: () -> UExpression?): UExpression? {
|
||||
return if (this == null || isAssignableFrom(ActualT::class.java)) f() else null
|
||||
internal inline fun <reified ActualT : UElement> Array<out Class<out UElement>>.el(f: () -> UElement?): UElement? {
|
||||
return if (isAssignableFrom(ActualT::class.java)) f() else null
|
||||
}
|
||||
|
||||
internal inline fun <reified ActualT : UElement> Array<out Class<out UElement>>.expr(f: () -> UExpression?): UExpression? {
|
||||
return if (isAssignableFrom(ActualT::class.java)) f() else null
|
||||
}
|
||||
|
||||
internal fun Array<out Class<out UElement>>.isAssignableFrom(cls: Class<*>) = any { it.isAssignableFrom(cls) }
|
||||
|
||||
|
||||
|
||||
internal object KotlinConverter {
|
||||
@@ -166,12 +199,13 @@ internal object KotlinConverter {
|
||||
|
||||
internal fun convertPsiElement(element: PsiElement?,
|
||||
givenParent: UElement?,
|
||||
requiredType: Class<out UElement>?): UElement? {
|
||||
expectedTypes: Array<out Class<out UElement>>
|
||||
): UElement? {
|
||||
fun <P : PsiElement> build(ctor: (P, UElement?) -> UElement): () -> UElement? {
|
||||
return { ctor(element as P, givenParent) }
|
||||
}
|
||||
|
||||
return with (requiredType) { when (element) {
|
||||
return with (expectedTypes) { when (element) {
|
||||
is KtParameterList -> el<UDeclarationsExpression> {
|
||||
val declarationsExpression = KotlinUDeclarationsExpression(givenParent)
|
||||
declarationsExpression.apply {
|
||||
@@ -184,11 +218,7 @@ internal object KotlinConverter {
|
||||
is KtCatchClause -> el<UCatchClause>(build(::KotlinUCatchClause))
|
||||
is KtVariableDeclaration ->
|
||||
if (element is KtProperty && !element.isLocal) {
|
||||
el<UField> {
|
||||
LightClassUtil.getLightClassBackingField(element)?.let {
|
||||
KotlinUField(it, element, givenParent)
|
||||
}
|
||||
}
|
||||
convertNonLocalProperty(element, givenParent, this).firstOrNull()
|
||||
}
|
||||
else {
|
||||
el<UVariable> {
|
||||
@@ -196,19 +226,19 @@ internal object KotlinConverter {
|
||||
}
|
||||
}
|
||||
|
||||
is KtExpression -> KotlinConverter.convertExpression(element, givenParent, requiredType)
|
||||
is KtLambdaArgument -> element.getLambdaExpression()?.let { KotlinConverter.convertExpression(it, givenParent, requiredType) }
|
||||
is KtExpression -> KotlinConverter.convertExpression(element, givenParent, expectedTypes)
|
||||
is KtLambdaArgument -> element.getLambdaExpression()?.let { KotlinConverter.convertExpression(it, givenParent, expectedTypes) }
|
||||
is KtLightElementBase -> {
|
||||
val expression = element.kotlinOrigin
|
||||
when (expression) {
|
||||
is KtExpression -> KotlinConverter.convertExpression(expression, givenParent, requiredType)
|
||||
is KtExpression -> KotlinConverter.convertExpression(expression, givenParent, expectedTypes)
|
||||
else -> el<UExpression> { UastEmptyExpression(givenParent) }
|
||||
}
|
||||
}
|
||||
is KtLiteralStringTemplateEntry, is KtEscapeStringTemplateEntry -> el<ULiteralExpression>(build(::KotlinStringULiteralExpression))
|
||||
is KtStringTemplateEntry -> element.expression?.let { convertExpression(it, givenParent, requiredType) } ?: expr<UExpression> { UastEmptyExpression }
|
||||
is KtStringTemplateEntry -> element.expression?.let { convertExpression(it, givenParent, expectedTypes) } ?: expr<UExpression> { UastEmptyExpression }
|
||||
is KtWhenEntry -> el<USwitchClauseExpressionWithBody>(build(::KotlinUSwitchEntry))
|
||||
is KtWhenCondition -> convertWhenCondition(element, givenParent, requiredType)
|
||||
is KtWhenCondition -> convertWhenCondition(element, givenParent, expectedTypes)
|
||||
is KtTypeReference -> el<UTypeReferenceExpression> { LazyKotlinUTypeReferenceExpression(element, givenParent) }
|
||||
is KtConstructorDelegationCall ->
|
||||
el<UCallExpression> { KotlinUFunctionCallExpression(element, givenParent) }
|
||||
@@ -246,7 +276,8 @@ internal object KotlinConverter {
|
||||
|
||||
internal fun convertEntry(entry: KtStringTemplateEntry,
|
||||
givenParent: UElement?,
|
||||
requiredType: Class<out UElement>? = null): UExpression? {
|
||||
requiredType: Array<out Class<out UElement>>
|
||||
): UExpression? {
|
||||
return with(requiredType) {
|
||||
if (entry is KtStringTemplateEntryWithExpression) {
|
||||
expr<UExpression> {
|
||||
@@ -264,9 +295,16 @@ 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? {
|
||||
requiredType: Array<out Class<out UElement>>
|
||||
): UExpression? {
|
||||
fun <P : PsiElement> build(ctor: (P, UElement?) -> UExpression): () -> UExpression? {
|
||||
return { ctor(expression as P, givenParent) }
|
||||
}
|
||||
@@ -276,13 +314,16 @@ internal object KotlinConverter {
|
||||
|
||||
is KtStringTemplateExpression -> {
|
||||
when {
|
||||
forceUInjectionHost || requiredType.contains(UInjectionHost::class.java) ->
|
||||
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<UExpression> { KotlinStringTemplateUPolyadicExpression(expression, givenParent) }
|
||||
}
|
||||
|
||||
else ->
|
||||
expr<KotlinStringTemplateUPolyadicExpression> { KotlinStringTemplateUPolyadicExpression(expression, givenParent) }
|
||||
}
|
||||
}
|
||||
is KtDestructuringDeclaration -> expr<UDeclarationsExpression> {
|
||||
@@ -355,7 +396,7 @@ internal object KotlinConverter {
|
||||
|
||||
internal fun convertWhenCondition(condition: KtWhenCondition,
|
||||
givenParent: UElement?,
|
||||
requiredType: Class<out UElement>? = null
|
||||
requiredType: Array<out Class<out UElement>>
|
||||
): UExpression? {
|
||||
return with(requiredType) {
|
||||
when (condition) {
|
||||
@@ -405,7 +446,7 @@ internal object KotlinConverter {
|
||||
internal fun convertDeclaration(
|
||||
element: PsiElement,
|
||||
givenParent: UElement?,
|
||||
requiredType: Class<out UElement>?
|
||||
expectedTypes: Array<out Class<out UElement>>
|
||||
): UElement? {
|
||||
fun <P : PsiElement> build(ctor: (P, UElement?) -> UElement): () -> UElement? = { ctor(element as P, givenParent) }
|
||||
|
||||
@@ -416,7 +457,7 @@ internal object KotlinConverter {
|
||||
{ ctor(element as P, ktElement, givenParent) }
|
||||
|
||||
val original = element.originalElement
|
||||
return with(requiredType) {
|
||||
return with(expectedTypes) {
|
||||
when (original) {
|
||||
is KtLightMethod -> el<UMethod>(build(KotlinUMethod.Companion::create)) // .Companion is needed because of KT-13934
|
||||
is KtLightClass -> when (original.kotlinOrigin) {
|
||||
@@ -434,11 +475,7 @@ internal object KotlinConverter {
|
||||
is KtEnumEntry -> el<UEnumConstant> {
|
||||
convertEnumEntry(original, givenParent)
|
||||
}
|
||||
is KtClassOrObject -> el<UClass> {
|
||||
original.toLightClass()?.let { lightClass ->
|
||||
KotlinUClass.create(lightClass, givenParent)
|
||||
}
|
||||
}
|
||||
is KtClassOrObject -> convertClassOrObject(original, givenParent, this).firstOrNull()
|
||||
is KtFunction ->
|
||||
if (original.isLocal) {
|
||||
el<ULambdaExpression> {
|
||||
@@ -447,49 +484,41 @@ internal object KotlinConverter {
|
||||
KotlinULambdaExpression(parent, givenParent) // your parent is the ULambdaExpression
|
||||
} else if (original.name.isNullOrEmpty()) {
|
||||
createLocalFunctionLambdaExpression(original, givenParent)
|
||||
}
|
||||
else {
|
||||
} else {
|
||||
val uDeclarationsExpression = createLocalFunctionDeclaration(original, givenParent)
|
||||
val localFunctionVar = uDeclarationsExpression.declarations.single() as KotlinLocalFunctionUVariable
|
||||
localFunctionVar.uastInitializer
|
||||
}
|
||||
}
|
||||
}
|
||||
else {
|
||||
} else {
|
||||
el<UMethod> {
|
||||
val lightMethod = LightClassUtil.getLightClassMethod(original) ?: return null
|
||||
convertDeclaration(lightMethod, givenParent, requiredType)
|
||||
convertDeclaration(lightMethod, givenParent, expectedTypes)
|
||||
}
|
||||
}
|
||||
|
||||
is KtPropertyAccessor -> el<UMethod> {
|
||||
val lightMethod = LightClassUtil.getLightClassAccessorMethod(original) ?: return null
|
||||
convertDeclaration(lightMethod, givenParent, requiredType)
|
||||
convertDeclaration(lightMethod, givenParent, expectedTypes)
|
||||
}
|
||||
|
||||
is KtProperty ->
|
||||
if (original.isLocal) {
|
||||
KotlinConverter.convertPsiElement(element, givenParent, requiredType)
|
||||
}
|
||||
else {
|
||||
convertNonLocalProperty(original, givenParent, requiredType)
|
||||
KotlinConverter.convertPsiElement(element, givenParent, expectedTypes)
|
||||
} else {
|
||||
convertNonLocalProperty(original, givenParent, expectedTypes).firstOrNull()
|
||||
}
|
||||
|
||||
is KtParameter -> el<UParameter> {
|
||||
val ownerFunction = original.ownerFunction as? KtFunction ?: return null
|
||||
val lightMethod = LightClassUtil.getLightClassMethod(ownerFunction) ?: return null
|
||||
val lightParameter = lightMethod.parameterList.parameters.find { it.name == original.name } ?: return null
|
||||
KotlinUParameter(lightParameter, original, givenParent)
|
||||
}
|
||||
is KtParameter -> convertParameter(original, givenParent, this).firstOrNull()
|
||||
|
||||
is KtFile -> el<UFile> { KotlinUFile(original) }
|
||||
is KtFile -> convertKtFile(original, givenParent, this).firstOrNull()
|
||||
is FakeFileForLightClass -> el<UFile> { KotlinUFile(original.navigationElement) }
|
||||
is KtAnnotationEntry -> el<UAnnotation>(build(::KotlinUAnnotation))
|
||||
is KtCallExpression ->
|
||||
if (requiredType != null && UAnnotation::class.java.isAssignableFrom(requiredType)) {
|
||||
if (expectedTypes.isAssignableFrom(KotlinUNestedAnnotation::class.java) && !expectedTypes.isAssignableFrom(UCallExpression::class.java)) {
|
||||
el<UAnnotation> { KotlinUNestedAnnotation.tryCreate(original, givenParent) }
|
||||
} else null
|
||||
is KtLightAnnotationForSourceEntry -> convertDeclarationOrElement(original.kotlinOrigin, givenParent, requiredType)
|
||||
is KtLightAnnotationForSourceEntry -> convertDeclarationOrElement(original.kotlinOrigin, givenParent, expectedTypes)
|
||||
is KtDelegatedSuperTypeEntry -> el<KotlinSupertypeDelegationUExpression> {
|
||||
KotlinSupertypeDelegationUExpression(original, givenParent)
|
||||
}
|
||||
@@ -499,17 +528,21 @@ internal object KotlinConverter {
|
||||
}
|
||||
|
||||
|
||||
fun convertDeclarationOrElement(element: PsiElement, givenParent: UElement?, requiredType: Class<out UElement>?): UElement? {
|
||||
fun convertDeclarationOrElement(
|
||||
element: PsiElement,
|
||||
givenParent: UElement?,
|
||||
expectedTypes: Array<out Class<out UElement>>
|
||||
): UElement? {
|
||||
if (element is UElement) return element
|
||||
|
||||
if (element.isValid) {
|
||||
element.getUserData(KOTLIN_CACHED_UELEMENT_KEY)?.get()?.let { cachedUElement ->
|
||||
return if (requiredType == null || requiredType.isInstance(cachedUElement)) cachedUElement else null
|
||||
return if (expectedTypes.isAssignableFrom(cachedUElement.javaClass)) cachedUElement else null
|
||||
}
|
||||
}
|
||||
|
||||
val uElement = convertDeclaration(element, givenParent, requiredType)
|
||||
?: KotlinConverter.convertPsiElement(element, givenParent, requiredType)
|
||||
val uElement = convertDeclaration(element, givenParent, expectedTypes)
|
||||
?: KotlinConverter.convertPsiElement(element, givenParent, expectedTypes)
|
||||
/*
|
||||
if (uElement != null) {
|
||||
element.putUserData(KOTLIN_CACHED_UELEMENT_KEY, WeakReference(uElement))
|
||||
@@ -518,27 +551,71 @@ internal object KotlinConverter {
|
||||
return uElement
|
||||
}
|
||||
|
||||
private fun convertNonLocalProperty(
|
||||
private fun convertToPropertyAlternatives(
|
||||
methods: LightClassUtil.PropertyAccessorsPsiMethods?,
|
||||
givenParent: UElement?
|
||||
): Array<UElementAlternative<*>> = if (methods != null) arrayOf(
|
||||
alternative { methods.backingField?.let { KotlinUField(it, (it as? KtLightElement<*, *>)?.kotlinOrigin, givenParent) } },
|
||||
alternative { methods.getter?.let { convertDeclaration(it, givenParent, arrayOf(UMethod::class.java)) as? UMethod } },
|
||||
alternative { methods.setter?.let { convertDeclaration(it, givenParent, arrayOf(UMethod::class.java)) as? UMethod } }
|
||||
) else emptyArray()
|
||||
|
||||
fun convertNonLocalProperty(
|
||||
property: KtProperty,
|
||||
givenParent: UElement?,
|
||||
requiredType: Class<out UElement>?
|
||||
): UElement? {
|
||||
val methods = LightClassUtil.getLightClassPropertyMethods(property)
|
||||
return methods.backingField?.let { backingField ->
|
||||
with(requiredType) {
|
||||
el<UField> { KotlinUField(backingField, (backingField as? KtLightElement<*,*>)?.kotlinOrigin, givenParent) }
|
||||
expectedTypes: Array<out Class<out UElement>>
|
||||
): Sequence<UElement> =
|
||||
expectedTypes.accommodate(*convertToPropertyAlternatives(LightClassUtil.getLightClassPropertyMethods(property), givenParent))
|
||||
|
||||
|
||||
fun convertParameter(
|
||||
element: KtParameter,
|
||||
givenParent: UElement?,
|
||||
expectedTypes: Array<out Class<out UElement>>
|
||||
): Sequence<UElement> = expectedTypes.accommodate(
|
||||
alternative uParam@{
|
||||
val ownerFunction = element.ownerFunction as? KtFunction ?: return@uParam null
|
||||
val lightMethod = LightClassUtil.getLightClassMethod(ownerFunction) ?: return@uParam null
|
||||
val lightParameter = lightMethod.parameterList.parameters.find { it.name == element.name } ?: return@uParam null
|
||||
KotlinUParameter(lightParameter, element, givenParent)
|
||||
},
|
||||
*convertToPropertyAlternatives(LightClassUtil.getLightClassPropertyMethods(element), givenParent)
|
||||
)
|
||||
|
||||
fun convertClassOrObject(
|
||||
element: KtClassOrObject,
|
||||
givenParent: UElement?,
|
||||
expectedTypes: Array<out Class<out UElement>>
|
||||
): Sequence<UElement> {
|
||||
val ktLightClass = element.toLightClass() ?: return emptySequence()
|
||||
val uClass = KotlinUClass.create(ktLightClass, givenParent)
|
||||
return expectedTypes.accommodate(
|
||||
alternative { uClass },
|
||||
alternative primaryConstructor@{
|
||||
val primaryConstructor = element.primaryConstructor ?: return@primaryConstructor null
|
||||
uClass.methods.asSequence()
|
||||
.filter { it.sourcePsi == primaryConstructor }
|
||||
.firstOrNull()
|
||||
}
|
||||
} ?: methods.getter?.let { getter ->
|
||||
convertDeclaration(getter, givenParent, requiredType)
|
||||
}
|
||||
)
|
||||
}
|
||||
|
||||
fun convertKtFile(
|
||||
element: KtFile,
|
||||
givenParent: UElement?,
|
||||
requiredTypes: Array<out Class<out UElement>>
|
||||
): Sequence<UElement> = requiredTypes.accommodate(
|
||||
alternative { KotlinUFile(element) },
|
||||
alternative { element.findFacadeClass()?.let { KotlinUClass.create(it, givenParent) } }
|
||||
)
|
||||
|
||||
|
||||
internal fun convertOrEmpty(expression: KtExpression?, parent: UElement?): UExpression {
|
||||
return expression?.let { convertExpression(it, parent, null) } ?: UastEmptyExpression
|
||||
return expression?.let { convertExpression(it, parent, DEFAULT_EXPRESSION_TYPES_LIST) } ?: UastEmptyExpression
|
||||
}
|
||||
|
||||
internal fun convertOrNull(expression: KtExpression?, parent: UElement?): UExpression? {
|
||||
return if (expression != null) convertExpression(expression, parent, null) else null
|
||||
return if (expression != null) convertExpression(expression, parent, DEFAULT_EXPRESSION_TYPES_LIST) else null
|
||||
}
|
||||
|
||||
internal fun KtPsiFactory.createAnalyzableExpression(text: String, context: PsiElement): KtExpression =
|
||||
@@ -571,3 +648,22 @@ private fun convertVariablesDeclaration(
|
||||
}
|
||||
|
||||
val kotlinUastPlugin get() = UastLanguagePlugin.getInstances().find { it.language == KotlinLanguage.INSTANCE } ?: KotlinUastLanguagePlugin()
|
||||
|
||||
private fun expressionTypes(requiredType: Class<out UElement>?) = requiredType?.let { arrayOf(it) } ?: DEFAULT_EXPRESSION_TYPES_LIST
|
||||
|
||||
private fun elementTypes(requiredType: Class<out UElement>?) = requiredType?.let { arrayOf(it) } ?: DEFAULT_TYPES_LIST
|
||||
|
||||
private fun <T : UElement> Array<out Class<out T>>.nonEmptyOr(default: Array<out Class<out UElement>>) = takeIf { it.isNotEmpty() }
|
||||
?: default
|
||||
|
||||
private fun <U : UElement> Array<out Class<out UElement>>.accommodate(vararg makers: UElementAlternative<out U>): Sequence<UElement> {
|
||||
val makersSeq = makers.asSequence()
|
||||
return this.asSequence()
|
||||
.flatMap { requiredType -> makersSeq.filter { requiredType.isAssignableFrom(it.uType) } }
|
||||
.distinct()
|
||||
.mapNotNull { it.make.invoke() }
|
||||
}
|
||||
|
||||
private inline fun <reified U : UElement> alternative(noinline make: () -> U?) = UElementAlternative(U::class.java, make)
|
||||
|
||||
private class UElementAlternative<U : UElement>(val uType: Class<U>, val make: () -> U?)
|
||||
+67
-163
@@ -19,16 +19,13 @@ 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
|
||||
import org.jetbrains.kotlin.asJava.elements.*
|
||||
import org.jetbrains.kotlin.asJava.findFacadeClass
|
||||
import org.jetbrains.kotlin.asJava.toLightClass
|
||||
import org.jetbrains.kotlin.codegen.state.KotlinTypeMapper
|
||||
import org.jetbrains.kotlin.config.LanguageVersionSettings
|
||||
@@ -42,7 +39,6 @@ import org.jetbrains.kotlin.psi.psiUtil.getParentOfType
|
||||
import org.jetbrains.kotlin.resolve.BindingContext
|
||||
import org.jetbrains.kotlin.resolve.calls.callUtil.getResolvedCall
|
||||
import org.jetbrains.uast.*
|
||||
import org.jetbrains.uast.expressions.UInjectionHost
|
||||
import org.jetbrains.uast.kotlin.KotlinConverter.convertDeclaration
|
||||
import org.jetbrains.uast.kotlin.KotlinConverter.convertDeclarationOrElement
|
||||
import org.jetbrains.uast.kotlin.declarations.KotlinUIdentifier
|
||||
@@ -79,15 +75,15 @@ class KotlinUastLanguagePlugin : UastLanguagePlugin {
|
||||
|
||||
override fun convertElement(element: PsiElement, parent: UElement?, requiredType: Class<out UElement>?): UElement? {
|
||||
if (!element.isJvmElement) return null
|
||||
return convertDeclarationOrElement(element, parent, elementTypes(requiredType))
|
||||
return convertDeclarationOrElement(element, parent, requiredType)
|
||||
}
|
||||
|
||||
override fun convertElementWithParent(element: PsiElement, requiredType: Class<out UElement>?): UElement? {
|
||||
if (!element.isJvmElement) return null
|
||||
if (element is PsiFile) return convertDeclaration(element, null, elementTypes(requiredType))
|
||||
if (element is KtLightClassForFacade) return convertDeclaration(element, null, elementTypes(requiredType))
|
||||
if (element is PsiFile) return convertDeclaration(element, null, requiredType)
|
||||
if (element is KtLightClassForFacade) return convertDeclaration(element, null, requiredType)
|
||||
|
||||
return convertDeclarationOrElement(element, null, elementTypes(requiredType))
|
||||
return convertDeclarationOrElement(element, null, requiredType)
|
||||
}
|
||||
|
||||
override fun getMethodCallExpression(
|
||||
@@ -140,45 +136,16 @@ class KotlinUastLanguagePlugin : UastLanguagePlugin {
|
||||
else -> false
|
||||
}
|
||||
}
|
||||
|
||||
@Suppress("UNCHECKED_CAST")
|
||||
fun <T : UElement> convertElement(element: PsiElement, parent: UElement?, expectedTypes: Array<out Class<out T>>): T? {
|
||||
if (!element.isJvmElement) return null
|
||||
val nonEmptyExpectedTypes = expectedTypes.nonEmptyOr(DEFAULT_TYPES_LIST)
|
||||
return (convertDeclaration(element, parent, nonEmptyExpectedTypes)
|
||||
?: KotlinConverter.convertPsiElement(element, parent, nonEmptyExpectedTypes)) as? T
|
||||
}
|
||||
|
||||
override fun <T : UElement> convertElementWithParent(element: PsiElement, requiredTypes: Array<out Class<out T>>): T? {
|
||||
return convertElement(element, null, requiredTypes)
|
||||
}
|
||||
|
||||
@Suppress("UNCHECKED_CAST")
|
||||
override fun <T : UElement> convertToAlternatives(element: PsiElement, requiredTypes: Array<out Class<out T>>): Sequence<T> =
|
||||
if (!element.isJvmElement) emptySequence() else when {
|
||||
element is KtFile -> KotlinConverter.convertKtFile(element, null, requiredTypes) as Sequence<T>
|
||||
(element is KtProperty && !element.isLocal) ->
|
||||
KotlinConverter.convertNonLocalProperty(element, null, requiredTypes) as Sequence<T>
|
||||
element is KtParameter -> KotlinConverter.convertParameter(element, null, requiredTypes) as Sequence<T>
|
||||
element is KtClassOrObject -> KotlinConverter.convertClassOrObject(element, null, requiredTypes) as Sequence<T>
|
||||
else -> sequenceOf(convertElementWithParent(element, requiredTypes.nonEmptyOr(DEFAULT_TYPES_LIST)) as? T).filterNotNull()
|
||||
}
|
||||
}
|
||||
|
||||
internal inline fun <reified ActualT : UElement> Class<*>?.el(f: () -> UElement?): UElement? {
|
||||
internal inline fun <reified ActualT : UElement> Class<out UElement>?.el(f: () -> UElement?): UElement? {
|
||||
return if (this == null || isAssignableFrom(ActualT::class.java)) f() else null
|
||||
}
|
||||
|
||||
internal inline fun <reified ActualT : UElement> Array<out Class<out UElement>>.el(f: () -> UElement?): UElement? {
|
||||
return if (isAssignableFrom(ActualT::class.java)) f() else null
|
||||
internal inline fun <reified ActualT : UElement> Class<out UElement>?.expr(f: () -> UExpression?): UExpression? {
|
||||
return if (this == null || isAssignableFrom(ActualT::class.java)) f() else null
|
||||
}
|
||||
|
||||
internal inline fun <reified ActualT : UElement> Array<out Class<out UElement>>.expr(f: () -> UExpression?): UExpression? {
|
||||
return if (isAssignableFrom(ActualT::class.java)) f() else null
|
||||
}
|
||||
|
||||
internal fun Array<out Class<out UElement>>.isAssignableFrom(cls: Class<*>) = any { it.isAssignableFrom(cls) }
|
||||
|
||||
|
||||
|
||||
internal object KotlinConverter {
|
||||
@@ -199,13 +166,12 @@ internal object KotlinConverter {
|
||||
|
||||
internal fun convertPsiElement(element: PsiElement?,
|
||||
givenParent: UElement?,
|
||||
expectedTypes: Array<out Class<out UElement>>
|
||||
): UElement? {
|
||||
requiredType: Class<out UElement>?): UElement? {
|
||||
fun <P : PsiElement> build(ctor: (P, UElement?) -> UElement): () -> UElement? {
|
||||
return { ctor(element as P, givenParent) }
|
||||
}
|
||||
|
||||
return with (expectedTypes) { when (element) {
|
||||
return with (requiredType) { when (element) {
|
||||
is KtParameterList -> el<UDeclarationsExpression> {
|
||||
val declarationsExpression = KotlinUDeclarationsExpression(givenParent)
|
||||
declarationsExpression.apply {
|
||||
@@ -218,7 +184,11 @@ internal object KotlinConverter {
|
||||
is KtCatchClause -> el<UCatchClause>(build(::KotlinUCatchClause))
|
||||
is KtVariableDeclaration ->
|
||||
if (element is KtProperty && !element.isLocal) {
|
||||
convertNonLocalProperty(element, givenParent, this).firstOrNull()
|
||||
el<UField> {
|
||||
LightClassUtil.getLightClassBackingField(element)?.let {
|
||||
KotlinUField(it, element, givenParent)
|
||||
}
|
||||
}
|
||||
}
|
||||
else {
|
||||
el<UVariable> {
|
||||
@@ -226,19 +196,19 @@ internal object KotlinConverter {
|
||||
}
|
||||
}
|
||||
|
||||
is KtExpression -> KotlinConverter.convertExpression(element, givenParent, expectedTypes)
|
||||
is KtLambdaArgument -> element.getLambdaExpression()?.let { KotlinConverter.convertExpression(it, givenParent, expectedTypes) }
|
||||
is KtExpression -> KotlinConverter.convertExpression(element, givenParent, requiredType)
|
||||
is KtLambdaArgument -> element.getLambdaExpression()?.let { KotlinConverter.convertExpression(it, givenParent, requiredType) }
|
||||
is KtLightElementBase -> {
|
||||
val expression = element.kotlinOrigin
|
||||
when (expression) {
|
||||
is KtExpression -> KotlinConverter.convertExpression(expression, givenParent, expectedTypes)
|
||||
is KtExpression -> KotlinConverter.convertExpression(expression, givenParent, requiredType)
|
||||
else -> el<UExpression> { UastEmptyExpression(givenParent) }
|
||||
}
|
||||
}
|
||||
is KtLiteralStringTemplateEntry, is KtEscapeStringTemplateEntry -> el<ULiteralExpression>(build(::KotlinStringULiteralExpression))
|
||||
is KtStringTemplateEntry -> element.expression?.let { convertExpression(it, givenParent, expectedTypes) } ?: expr<UExpression> { UastEmptyExpression }
|
||||
is KtStringTemplateEntry -> element.expression?.let { convertExpression(it, givenParent, requiredType) } ?: expr<UExpression> { UastEmptyExpression }
|
||||
is KtWhenEntry -> el<USwitchClauseExpressionWithBody>(build(::KotlinUSwitchEntry))
|
||||
is KtWhenCondition -> convertWhenCondition(element, givenParent, expectedTypes)
|
||||
is KtWhenCondition -> convertWhenCondition(element, givenParent, requiredType)
|
||||
is KtTypeReference -> el<UTypeReferenceExpression> { LazyKotlinUTypeReferenceExpression(element, givenParent) }
|
||||
is KtConstructorDelegationCall ->
|
||||
el<UCallExpression> { KotlinUFunctionCallExpression(element, givenParent) }
|
||||
@@ -276,8 +246,7 @@ internal object KotlinConverter {
|
||||
|
||||
internal fun convertEntry(entry: KtStringTemplateEntry,
|
||||
givenParent: UElement?,
|
||||
requiredType: Array<out Class<out UElement>>
|
||||
): UExpression? {
|
||||
requiredType: Class<out UElement>? = null): UExpression? {
|
||||
return with(requiredType) {
|
||||
if (entry is KtStringTemplateEntryWithExpression) {
|
||||
expr<UExpression> {
|
||||
@@ -295,16 +264,9 @@ 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: Array<out Class<out UElement>>
|
||||
): UExpression? {
|
||||
requiredType: Class<out UElement>? = null): UExpression? {
|
||||
fun <P : PsiElement> build(ctor: (P, UElement?) -> UExpression): () -> UExpression? {
|
||||
return { ctor(expression as P, givenParent) }
|
||||
}
|
||||
@@ -314,16 +276,13 @@ internal object KotlinConverter {
|
||||
|
||||
is KtStringTemplateExpression -> {
|
||||
when {
|
||||
forceUInjectionHost || requiredType.contains(UInjectionHost::class.java) ->
|
||||
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) }
|
||||
else -> {
|
||||
expr<UExpression> { KotlinStringTemplateUPolyadicExpression(expression, givenParent) }
|
||||
}
|
||||
}
|
||||
}
|
||||
is KtDestructuringDeclaration -> expr<UDeclarationsExpression> {
|
||||
@@ -396,7 +355,7 @@ internal object KotlinConverter {
|
||||
|
||||
internal fun convertWhenCondition(condition: KtWhenCondition,
|
||||
givenParent: UElement?,
|
||||
requiredType: Array<out Class<out UElement>>
|
||||
requiredType: Class<out UElement>? = null
|
||||
): UExpression? {
|
||||
return with(requiredType) {
|
||||
when (condition) {
|
||||
@@ -446,7 +405,7 @@ internal object KotlinConverter {
|
||||
internal fun convertDeclaration(
|
||||
element: PsiElement,
|
||||
givenParent: UElement?,
|
||||
expectedTypes: Array<out Class<out UElement>>
|
||||
requiredType: Class<out UElement>?
|
||||
): UElement? {
|
||||
fun <P : PsiElement> build(ctor: (P, UElement?) -> UElement): () -> UElement? = { ctor(element as P, givenParent) }
|
||||
|
||||
@@ -457,7 +416,7 @@ internal object KotlinConverter {
|
||||
{ ctor(element as P, ktElement, givenParent) }
|
||||
|
||||
val original = element.originalElement
|
||||
return with(expectedTypes) {
|
||||
return with(requiredType) {
|
||||
when (original) {
|
||||
is KtLightMethod -> el<UMethod>(build(KotlinUMethod.Companion::create)) // .Companion is needed because of KT-13934
|
||||
is KtLightClass -> when (original.kotlinOrigin) {
|
||||
@@ -475,7 +434,11 @@ internal object KotlinConverter {
|
||||
is KtEnumEntry -> el<UEnumConstant> {
|
||||
convertEnumEntry(original, givenParent)
|
||||
}
|
||||
is KtClassOrObject -> convertClassOrObject(original, givenParent, this).firstOrNull()
|
||||
is KtClassOrObject -> el<UClass> {
|
||||
original.toLightClass()?.let { lightClass ->
|
||||
KotlinUClass.create(lightClass, givenParent)
|
||||
}
|
||||
}
|
||||
is KtFunction ->
|
||||
if (original.isLocal) {
|
||||
el<ULambdaExpression> {
|
||||
@@ -484,41 +447,49 @@ internal object KotlinConverter {
|
||||
KotlinULambdaExpression(parent, givenParent) // your parent is the ULambdaExpression
|
||||
} else if (original.name.isNullOrEmpty()) {
|
||||
createLocalFunctionLambdaExpression(original, givenParent)
|
||||
} else {
|
||||
}
|
||||
else {
|
||||
val uDeclarationsExpression = createLocalFunctionDeclaration(original, givenParent)
|
||||
val localFunctionVar = uDeclarationsExpression.declarations.single() as KotlinLocalFunctionUVariable
|
||||
localFunctionVar.uastInitializer
|
||||
}
|
||||
}
|
||||
} else {
|
||||
}
|
||||
else {
|
||||
el<UMethod> {
|
||||
val lightMethod = LightClassUtil.getLightClassMethod(original) ?: return null
|
||||
convertDeclaration(lightMethod, givenParent, expectedTypes)
|
||||
convertDeclaration(lightMethod, givenParent, requiredType)
|
||||
}
|
||||
}
|
||||
|
||||
is KtPropertyAccessor -> el<UMethod> {
|
||||
val lightMethod = LightClassUtil.getLightClassAccessorMethod(original) ?: return null
|
||||
convertDeclaration(lightMethod, givenParent, expectedTypes)
|
||||
convertDeclaration(lightMethod, givenParent, requiredType)
|
||||
}
|
||||
|
||||
is KtProperty ->
|
||||
if (original.isLocal) {
|
||||
KotlinConverter.convertPsiElement(element, givenParent, expectedTypes)
|
||||
} else {
|
||||
convertNonLocalProperty(original, givenParent, expectedTypes).firstOrNull()
|
||||
KotlinConverter.convertPsiElement(element, givenParent, requiredType)
|
||||
}
|
||||
else {
|
||||
convertNonLocalProperty(original, givenParent, requiredType)
|
||||
}
|
||||
|
||||
is KtParameter -> convertParameter(original, givenParent, this).firstOrNull()
|
||||
is KtParameter -> el<UParameter> {
|
||||
val ownerFunction = original.ownerFunction as? KtFunction ?: return null
|
||||
val lightMethod = LightClassUtil.getLightClassMethod(ownerFunction) ?: return null
|
||||
val lightParameter = lightMethod.parameterList.parameters.find { it.name == original.name } ?: return null
|
||||
KotlinUParameter(lightParameter, original, givenParent)
|
||||
}
|
||||
|
||||
is KtFile -> convertKtFile(original, givenParent, this).firstOrNull()
|
||||
is KtFile -> el<UFile> { KotlinUFile(original) }
|
||||
is FakeFileForLightClass -> el<UFile> { KotlinUFile(original.navigationElement) }
|
||||
is KtAnnotationEntry -> el<UAnnotation>(build(::KotlinUAnnotation))
|
||||
is KtCallExpression ->
|
||||
if (expectedTypes.isAssignableFrom(KotlinUNestedAnnotation::class.java) && !expectedTypes.isAssignableFrom(UCallExpression::class.java)) {
|
||||
if (requiredType != null && UAnnotation::class.java.isAssignableFrom(requiredType)) {
|
||||
el<UAnnotation> { KotlinUNestedAnnotation.tryCreate(original, givenParent) }
|
||||
} else null
|
||||
is KtLightAnnotationForSourceEntry -> convertDeclarationOrElement(original.kotlinOrigin, givenParent, expectedTypes)
|
||||
is KtLightAnnotationForSourceEntry -> convertDeclarationOrElement(original.kotlinOrigin, givenParent, requiredType)
|
||||
is KtDelegatedSuperTypeEntry -> el<KotlinSupertypeDelegationUExpression> {
|
||||
KotlinSupertypeDelegationUExpression(original, givenParent)
|
||||
}
|
||||
@@ -528,21 +499,17 @@ internal object KotlinConverter {
|
||||
}
|
||||
|
||||
|
||||
fun convertDeclarationOrElement(
|
||||
element: PsiElement,
|
||||
givenParent: UElement?,
|
||||
expectedTypes: Array<out Class<out UElement>>
|
||||
): UElement? {
|
||||
fun convertDeclarationOrElement(element: PsiElement, givenParent: UElement?, requiredType: Class<out UElement>?): UElement? {
|
||||
if (element is UElement) return element
|
||||
|
||||
if (element.isValid) {
|
||||
element.getUserData(KOTLIN_CACHED_UELEMENT_KEY)?.get()?.let { cachedUElement ->
|
||||
return if (expectedTypes.isAssignableFrom(cachedUElement.javaClass)) cachedUElement else null
|
||||
return if (requiredType == null || requiredType.isInstance(cachedUElement)) cachedUElement else null
|
||||
}
|
||||
}
|
||||
|
||||
val uElement = convertDeclaration(element, givenParent, expectedTypes)
|
||||
?: KotlinConverter.convertPsiElement(element, givenParent, expectedTypes)
|
||||
val uElement = convertDeclaration(element, givenParent, requiredType)
|
||||
?: KotlinConverter.convertPsiElement(element, givenParent, requiredType)
|
||||
/*
|
||||
if (uElement != null) {
|
||||
element.putUserData(KOTLIN_CACHED_UELEMENT_KEY, WeakReference(uElement))
|
||||
@@ -551,71 +518,27 @@ internal object KotlinConverter {
|
||||
return uElement
|
||||
}
|
||||
|
||||
private fun convertToPropertyAlternatives(
|
||||
methods: LightClassUtil.PropertyAccessorsPsiMethods?,
|
||||
givenParent: UElement?
|
||||
): Array<UElementAlternative<*>> = if (methods != null) arrayOf(
|
||||
alternative { methods.backingField?.let { KotlinUField(it, (it as? KtLightElement<*, *>)?.kotlinOrigin, givenParent) } },
|
||||
alternative { methods.getter?.let { convertDeclaration(it, givenParent, arrayOf(UMethod::class.java)) as? UMethod } },
|
||||
alternative { methods.setter?.let { convertDeclaration(it, givenParent, arrayOf(UMethod::class.java)) as? UMethod } }
|
||||
) else emptyArray()
|
||||
|
||||
fun convertNonLocalProperty(
|
||||
private fun convertNonLocalProperty(
|
||||
property: KtProperty,
|
||||
givenParent: UElement?,
|
||||
expectedTypes: Array<out Class<out UElement>>
|
||||
): Sequence<UElement> =
|
||||
expectedTypes.accommodate(*convertToPropertyAlternatives(LightClassUtil.getLightClassPropertyMethods(property), givenParent))
|
||||
|
||||
|
||||
fun convertParameter(
|
||||
element: KtParameter,
|
||||
givenParent: UElement?,
|
||||
expectedTypes: Array<out Class<out UElement>>
|
||||
): Sequence<UElement> = expectedTypes.accommodate(
|
||||
alternative uParam@{
|
||||
val ownerFunction = element.ownerFunction as? KtFunction ?: return@uParam null
|
||||
val lightMethod = LightClassUtil.getLightClassMethod(ownerFunction) ?: return@uParam null
|
||||
val lightParameter = lightMethod.parameterList.parameters.find { it.name == element.name } ?: return@uParam null
|
||||
KotlinUParameter(lightParameter, element, givenParent)
|
||||
},
|
||||
*convertToPropertyAlternatives(LightClassUtil.getLightClassPropertyMethods(element), givenParent)
|
||||
)
|
||||
|
||||
fun convertClassOrObject(
|
||||
element: KtClassOrObject,
|
||||
givenParent: UElement?,
|
||||
expectedTypes: Array<out Class<out UElement>>
|
||||
): Sequence<UElement> {
|
||||
val ktLightClass = element.toLightClass() ?: return emptySequence()
|
||||
val uClass = KotlinUClass.create(ktLightClass, givenParent)
|
||||
return expectedTypes.accommodate(
|
||||
alternative { uClass },
|
||||
alternative primaryConstructor@{
|
||||
val primaryConstructor = element.primaryConstructor ?: return@primaryConstructor null
|
||||
uClass.methods.asSequence()
|
||||
.filter { it.sourcePsi == primaryConstructor }
|
||||
.firstOrNull()
|
||||
requiredType: Class<out UElement>?
|
||||
): UElement? {
|
||||
val methods = LightClassUtil.getLightClassPropertyMethods(property)
|
||||
return methods.backingField?.let { backingField ->
|
||||
with(requiredType) {
|
||||
el<UField> { KotlinUField(backingField, (backingField as? KtLightElement<*,*>)?.kotlinOrigin, givenParent) }
|
||||
}
|
||||
)
|
||||
} ?: methods.getter?.let { getter ->
|
||||
convertDeclaration(getter, givenParent, requiredType)
|
||||
}
|
||||
}
|
||||
|
||||
fun convertKtFile(
|
||||
element: KtFile,
|
||||
givenParent: UElement?,
|
||||
requiredTypes: Array<out Class<out UElement>>
|
||||
): Sequence<UElement> = requiredTypes.accommodate(
|
||||
alternative { KotlinUFile(element) },
|
||||
alternative { element.findFacadeClass()?.let { KotlinUClass.create(it, givenParent) } }
|
||||
)
|
||||
|
||||
|
||||
internal fun convertOrEmpty(expression: KtExpression?, parent: UElement?): UExpression {
|
||||
return expression?.let { convertExpression(it, parent, DEFAULT_EXPRESSION_TYPES_LIST) } ?: UastEmptyExpression
|
||||
return expression?.let { convertExpression(it, parent, null) } ?: UastEmptyExpression
|
||||
}
|
||||
|
||||
internal fun convertOrNull(expression: KtExpression?, parent: UElement?): UExpression? {
|
||||
return if (expression != null) convertExpression(expression, parent, DEFAULT_EXPRESSION_TYPES_LIST) else null
|
||||
return if (expression != null) convertExpression(expression, parent, null) else null
|
||||
}
|
||||
|
||||
internal fun KtPsiFactory.createAnalyzableExpression(text: String, context: PsiElement): KtExpression =
|
||||
@@ -648,22 +571,3 @@ private fun convertVariablesDeclaration(
|
||||
}
|
||||
|
||||
val kotlinUastPlugin get() = UastLanguagePlugin.getInstances().find { it.language == KotlinLanguage.INSTANCE } ?: KotlinUastLanguagePlugin()
|
||||
|
||||
private fun expressionTypes(requiredType: Class<out UElement>?) = requiredType?.let { arrayOf(it) } ?: DEFAULT_EXPRESSION_TYPES_LIST
|
||||
|
||||
private fun elementTypes(requiredType: Class<out UElement>?) = requiredType?.let { arrayOf(it) } ?: DEFAULT_TYPES_LIST
|
||||
|
||||
private fun <T : UElement> Array<out Class<out T>>.nonEmptyOr(default: Array<out Class<out UElement>>) = takeIf { it.isNotEmpty() }
|
||||
?: default
|
||||
|
||||
private fun <U : UElement> Array<out Class<out UElement>>.accommodate(vararg makers: UElementAlternative<out U>): Sequence<UElement> {
|
||||
val makersSeq = makers.asSequence()
|
||||
return this.asSequence()
|
||||
.flatMap { requiredType -> makersSeq.filter { requiredType.isAssignableFrom(it.uType) } }
|
||||
.distinct()
|
||||
.mapNotNull { it.make.invoke() }
|
||||
}
|
||||
|
||||
private inline fun <reified U : UElement> alternative(noinline make: () -> U?) = UElementAlternative(U::class.java, make)
|
||||
|
||||
private class UElementAlternative<U : UElement>(val uType: Class<U>, val make: () -> U?)
|
||||
@@ -107,7 +107,7 @@ open class KotlinUMethod(
|
||||
KotlinUBlockExpression.KotlinLazyUBlockExpression(this, { block ->
|
||||
val implicitReturn = KotlinUImplicitReturnExpression(block)
|
||||
val uBody = getLanguagePlugin().convertElement(bodyExpression, implicitReturn) as? UExpression
|
||||
?: return@KotlinLazyUBlockExpression emptyList()
|
||||
?: return@KotlinLazyUBlockExpression emptyList()
|
||||
listOf(implicitReturn.apply { returnExpression = uBody })
|
||||
})
|
||||
|
||||
@@ -123,6 +123,12 @@ open class KotlinUMethod(
|
||||
|
||||
override fun getOriginalElement(): PsiElement? = super<UAnnotationMethod>.getOriginalElement()
|
||||
|
||||
override val returnTypeReference: UTypeReferenceExpression? by lz {
|
||||
(sourcePsi as? KtCallableDeclaration)?.typeReference?.let {
|
||||
LazyKotlinUTypeReferenceExpression(it, this) { javaPsi.returnType ?: UastErrorType }
|
||||
}
|
||||
}
|
||||
|
||||
override fun equals(other: Any?) = other is KotlinUMethod && psi == other.psi
|
||||
|
||||
companion object {
|
||||
|
||||
+1
-7
@@ -107,7 +107,7 @@ open class KotlinUMethod(
|
||||
KotlinUBlockExpression.KotlinLazyUBlockExpression(this, { block ->
|
||||
val implicitReturn = KotlinUImplicitReturnExpression(block)
|
||||
val uBody = getLanguagePlugin().convertElement(bodyExpression, implicitReturn) as? UExpression
|
||||
?: return@KotlinLazyUBlockExpression emptyList()
|
||||
?: return@KotlinLazyUBlockExpression emptyList()
|
||||
listOf(implicitReturn.apply { returnExpression = uBody })
|
||||
})
|
||||
|
||||
@@ -123,12 +123,6 @@ open class KotlinUMethod(
|
||||
|
||||
override fun getOriginalElement(): PsiElement? = super<UAnnotationMethod>.getOriginalElement()
|
||||
|
||||
override val returnTypeReference: UTypeReferenceExpression? by lz {
|
||||
(sourcePsi as? KtCallableDeclaration)?.typeReference?.let {
|
||||
LazyKotlinUTypeReferenceExpression(it, this) { javaPsi.returnType ?: UastErrorType }
|
||||
}
|
||||
}
|
||||
|
||||
override fun equals(other: Any?) = other is KotlinUMethod && psi == other.psi
|
||||
|
||||
companion object {
|
||||
+1
@@ -9,6 +9,7 @@ import org.jetbrains.uast.evaluation.UEvaluationState
|
||||
import org.jetbrains.uast.kotlin.KotlinBinaryOperators
|
||||
import org.jetbrains.uast.kotlin.KotlinPostfixOperators
|
||||
import org.jetbrains.uast.values.*
|
||||
import org.jetbrains.uast.evaluation.to
|
||||
|
||||
class KotlinEvaluatorExtension : AbstractEvaluatorExtension(KotlinLanguage.INSTANCE) {
|
||||
|
||||
|
||||
-1
@@ -9,7 +9,6 @@ import org.jetbrains.uast.evaluation.UEvaluationState
|
||||
import org.jetbrains.uast.kotlin.KotlinBinaryOperators
|
||||
import org.jetbrains.uast.kotlin.KotlinPostfixOperators
|
||||
import org.jetbrains.uast.values.*
|
||||
import org.jetbrains.uast.evaluation.to
|
||||
|
||||
class KotlinEvaluatorExtension : AbstractEvaluatorExtension(KotlinLanguage.INSTANCE) {
|
||||
|
||||
@@ -67,7 +67,7 @@ private fun createElvisExpressions(
|
||||
override val sourcePsi: PsiElement? = null
|
||||
override val condition: UExpression by lz { createNotEqWithNullExpression(tempVariable, this) }
|
||||
override val thenExpression: UExpression? by lz { createVariableReferenceExpression(tempVariable, this) }
|
||||
override val elseExpression: UExpression? by lz { KotlinConverter.convertExpression(right, this ) }
|
||||
override val elseExpression: UExpression? by lz { KotlinConverter.convertExpression(right, this, DEFAULT_EXPRESSION_TYPES_LIST) }
|
||||
override val isTernary: Boolean = false
|
||||
override val annotations: List<UAnnotation> = emptyList()
|
||||
override val ifIdentifier: UIdentifier = KotlinUIdentifier(null, this)
|
||||
|
||||
+1
-1
@@ -67,7 +67,7 @@ private fun createElvisExpressions(
|
||||
override val sourcePsi: PsiElement? = null
|
||||
override val condition: UExpression by lz { createNotEqWithNullExpression(tempVariable, this) }
|
||||
override val thenExpression: UExpression? by lz { createVariableReferenceExpression(tempVariable, this) }
|
||||
override val elseExpression: UExpression? by lz { KotlinConverter.convertExpression(right, this, DEFAULT_EXPRESSION_TYPES_LIST) }
|
||||
override val elseExpression: UExpression? by lz { KotlinConverter.convertExpression(right, this ) }
|
||||
override val isTernary: Boolean = false
|
||||
override val annotations: List<UAnnotation> = emptyList()
|
||||
override val ifIdentifier: UIdentifier = KotlinUIdentifier(null, this)
|
||||
+24
-10
@@ -16,19 +16,33 @@
|
||||
|
||||
package org.jetbrains.uast.kotlin
|
||||
|
||||
import com.intellij.psi.PsiLanguageInjectionHost
|
||||
import org.jetbrains.kotlin.psi.KtStringTemplateExpression
|
||||
import org.jetbrains.uast.UElement
|
||||
import org.jetbrains.uast.UExpression
|
||||
import org.jetbrains.uast.UPolyadicExpression
|
||||
import org.jetbrains.uast.UastBinaryOperator
|
||||
import org.jetbrains.uast.*
|
||||
import org.jetbrains.uast.expressions.UInjectionHost
|
||||
|
||||
class KotlinStringTemplateUPolyadicExpression(
|
||||
override val psi: KtStringTemplateExpression,
|
||||
givenParent: UElement?
|
||||
override val psi: KtStringTemplateExpression,
|
||||
givenParent: UElement?
|
||||
) : KotlinAbstractUExpression(givenParent),
|
||||
UPolyadicExpression,
|
||||
KotlinUElementWithType,
|
||||
KotlinEvaluatableUElement {
|
||||
override val operands: List<UExpression> by lz { psi.entries.map { KotlinConverter.convertEntry(it, this)!! } }
|
||||
UPolyadicExpression,
|
||||
KotlinUElementWithType,
|
||||
KotlinEvaluatableUElement,
|
||||
UInjectionHost {
|
||||
override val operands: List<UExpression> by lz {
|
||||
psi.entries.map {
|
||||
KotlinConverter.convertEntry(
|
||||
it,
|
||||
this,
|
||||
DEFAULT_EXPRESSION_TYPES_LIST
|
||||
)!!
|
||||
}
|
||||
}
|
||||
override val operator = UastBinaryOperator.PLUS
|
||||
|
||||
override val psiLanguageInjectionHost: PsiLanguageInjectionHost get() = psi
|
||||
override val isString: Boolean get() = true
|
||||
|
||||
override fun asRenderString(): String = if (operands.isEmpty()) "\"\"" else super<UPolyadicExpression>.asRenderString()
|
||||
override fun asLogString(): String = if (operands.isEmpty()) "UPolyadicExpression (value = \"\")" else super.asLogString()
|
||||
}
|
||||
+34
@@ -0,0 +1,34 @@
|
||||
/*
|
||||
* Copyright 2010-2016 JetBrains s.r.o.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.jetbrains.uast.kotlin
|
||||
|
||||
import org.jetbrains.kotlin.psi.KtStringTemplateExpression
|
||||
import org.jetbrains.uast.UElement
|
||||
import org.jetbrains.uast.UExpression
|
||||
import org.jetbrains.uast.UPolyadicExpression
|
||||
import org.jetbrains.uast.UastBinaryOperator
|
||||
|
||||
class KotlinStringTemplateUPolyadicExpression(
|
||||
override val psi: KtStringTemplateExpression,
|
||||
givenParent: UElement?
|
||||
) : KotlinAbstractUExpression(givenParent),
|
||||
UPolyadicExpression,
|
||||
KotlinUElementWithType,
|
||||
KotlinEvaluatableUElement {
|
||||
override val operands: List<UExpression> by lz { psi.entries.map { KotlinConverter.convertEntry(it, this)!! } }
|
||||
override val operator = UastBinaryOperator.PLUS
|
||||
}
|
||||
-48
@@ -1,48 +0,0 @@
|
||||
/*
|
||||
* Copyright 2010-2016 JetBrains s.r.o.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.jetbrains.uast.kotlin
|
||||
|
||||
import com.intellij.psi.PsiLanguageInjectionHost
|
||||
import org.jetbrains.kotlin.psi.KtStringTemplateExpression
|
||||
import org.jetbrains.uast.*
|
||||
import org.jetbrains.uast.expressions.UInjectionHost
|
||||
|
||||
class KotlinStringTemplateUPolyadicExpression(
|
||||
override val psi: KtStringTemplateExpression,
|
||||
givenParent: UElement?
|
||||
) : KotlinAbstractUExpression(givenParent),
|
||||
UPolyadicExpression,
|
||||
KotlinUElementWithType,
|
||||
KotlinEvaluatableUElement,
|
||||
UInjectionHost {
|
||||
override val operands: List<UExpression> by lz {
|
||||
psi.entries.map {
|
||||
KotlinConverter.convertEntry(
|
||||
it,
|
||||
this,
|
||||
DEFAULT_EXPRESSION_TYPES_LIST
|
||||
)!!
|
||||
}
|
||||
}
|
||||
override val operator = UastBinaryOperator.PLUS
|
||||
|
||||
override val psiLanguageInjectionHost: PsiLanguageInjectionHost get() = psi
|
||||
override val isString: Boolean get() = true
|
||||
|
||||
override fun asRenderString(): String = if (operands.isEmpty()) "\"\"" else super<UPolyadicExpression>.asRenderString()
|
||||
override fun asLogString(): String = if (operands.isEmpty()) "UPolyadicExpression (value = \"\")" else super.asLogString()
|
||||
}
|
||||
+2
-5
@@ -20,10 +20,7 @@ import com.intellij.psi.PsiNamedElement
|
||||
import com.intellij.psi.ResolveResult
|
||||
import org.jetbrains.kotlin.psi.KtCallableReferenceExpression
|
||||
import org.jetbrains.kotlin.resolve.BindingContext.DOUBLE_COLON_LHS
|
||||
import org.jetbrains.uast.UCallableReferenceExpression
|
||||
import org.jetbrains.uast.UElement
|
||||
import org.jetbrains.uast.UExpression
|
||||
import org.jetbrains.uast.UMultiResolvable
|
||||
import org.jetbrains.uast.*
|
||||
import org.jetbrains.uast.kotlin.internal.getResolveResultVariants
|
||||
|
||||
class KotlinUCallableReferenceExpression(
|
||||
@@ -34,7 +31,7 @@ class KotlinUCallableReferenceExpression(
|
||||
get() {
|
||||
if (qualifierType != null) return null
|
||||
val receiverExpression = psi.receiverExpression ?: return null
|
||||
return KotlinConverter.convertExpression(receiverExpression, this)
|
||||
return KotlinConverter.convertExpression(receiverExpression, this, DEFAULT_EXPRESSION_TYPES_LIST)
|
||||
}
|
||||
|
||||
override val qualifierType by lz {
|
||||
|
||||
+5
-2
@@ -20,7 +20,10 @@ import com.intellij.psi.PsiNamedElement
|
||||
import com.intellij.psi.ResolveResult
|
||||
import org.jetbrains.kotlin.psi.KtCallableReferenceExpression
|
||||
import org.jetbrains.kotlin.resolve.BindingContext.DOUBLE_COLON_LHS
|
||||
import org.jetbrains.uast.*
|
||||
import org.jetbrains.uast.UCallableReferenceExpression
|
||||
import org.jetbrains.uast.UElement
|
||||
import org.jetbrains.uast.UExpression
|
||||
import org.jetbrains.uast.UMultiResolvable
|
||||
import org.jetbrains.uast.kotlin.internal.getResolveResultVariants
|
||||
|
||||
class KotlinUCallableReferenceExpression(
|
||||
@@ -31,7 +34,7 @@ class KotlinUCallableReferenceExpression(
|
||||
get() {
|
||||
if (qualifierType != null) return null
|
||||
val receiverExpression = psi.receiverExpression ?: return null
|
||||
return KotlinConverter.convertExpression(receiverExpression, this, DEFAULT_EXPRESSION_TYPES_LIST)
|
||||
return KotlinConverter.convertExpression(receiverExpression, this)
|
||||
}
|
||||
|
||||
override val qualifierType by lz {
|
||||
+2
-1
@@ -18,6 +18,7 @@ package org.jetbrains.uast.kotlin
|
||||
|
||||
import org.jetbrains.kotlin.psi.KtClassLiteralExpression
|
||||
import org.jetbrains.kotlin.resolve.BindingContext.DOUBLE_COLON_LHS
|
||||
import org.jetbrains.uast.DEFAULT_EXPRESSION_TYPES_LIST
|
||||
import org.jetbrains.uast.UClassLiteralExpression
|
||||
import org.jetbrains.uast.UElement
|
||||
import org.jetbrains.uast.UExpression
|
||||
@@ -35,6 +36,6 @@ class KotlinUClassLiteralExpression(
|
||||
get() {
|
||||
if (type != null) return null
|
||||
val receiverExpression = psi.receiverExpression ?: return null
|
||||
return KotlinConverter.convertExpression(receiverExpression, this)
|
||||
return KotlinConverter.convertExpression(receiverExpression, this, DEFAULT_EXPRESSION_TYPES_LIST)
|
||||
}
|
||||
}
|
||||
+1
-2
@@ -18,7 +18,6 @@ package org.jetbrains.uast.kotlin
|
||||
|
||||
import org.jetbrains.kotlin.psi.KtClassLiteralExpression
|
||||
import org.jetbrains.kotlin.resolve.BindingContext.DOUBLE_COLON_LHS
|
||||
import org.jetbrains.uast.DEFAULT_EXPRESSION_TYPES_LIST
|
||||
import org.jetbrains.uast.UClassLiteralExpression
|
||||
import org.jetbrains.uast.UElement
|
||||
import org.jetbrains.uast.UExpression
|
||||
@@ -36,6 +35,6 @@ class KotlinUClassLiteralExpression(
|
||||
get() {
|
||||
if (type != null) return null
|
||||
val receiverExpression = psi.receiverExpression ?: return null
|
||||
return KotlinConverter.convertExpression(receiverExpression, this, DEFAULT_EXPRESSION_TYPES_LIST)
|
||||
return KotlinConverter.convertExpression(receiverExpression, this)
|
||||
}
|
||||
}
|
||||
+5
-1
@@ -23,6 +23,7 @@ import org.jetbrains.kotlin.psi.KtObjectLiteralExpression
|
||||
import org.jetbrains.kotlin.psi.KtSuperTypeCallEntry
|
||||
import org.jetbrains.kotlin.resolve.calls.callUtil.getResolvedCall
|
||||
import org.jetbrains.uast.*
|
||||
import org.jetbrains.uast.kotlin.declarations.KotlinUIdentifier
|
||||
import org.jetbrains.uast.kotlin.internal.DelegatedMultiResolve
|
||||
|
||||
class KotlinUObjectLiteralExpression(
|
||||
@@ -82,7 +83,10 @@ class KotlinUObjectLiteralExpression(
|
||||
get() = identifier
|
||||
|
||||
override val identifier: String
|
||||
get() = psi.name ?: "<error>"
|
||||
get() = psi.name ?: referenceNameElement.sourcePsi?.text ?: "<error>"
|
||||
|
||||
override val referenceNameElement: UElement
|
||||
get() = KotlinUIdentifier(psi.typeReference?.nameElement, this)
|
||||
}
|
||||
|
||||
}
|
||||
+1
-5
@@ -23,7 +23,6 @@ import org.jetbrains.kotlin.psi.KtObjectLiteralExpression
|
||||
import org.jetbrains.kotlin.psi.KtSuperTypeCallEntry
|
||||
import org.jetbrains.kotlin.resolve.calls.callUtil.getResolvedCall
|
||||
import org.jetbrains.uast.*
|
||||
import org.jetbrains.uast.kotlin.declarations.KotlinUIdentifier
|
||||
import org.jetbrains.uast.kotlin.internal.DelegatedMultiResolve
|
||||
|
||||
class KotlinUObjectLiteralExpression(
|
||||
@@ -83,10 +82,7 @@ class KotlinUObjectLiteralExpression(
|
||||
get() = identifier
|
||||
|
||||
override val identifier: String
|
||||
get() = psi.name ?: referenceNameElement.sourcePsi?.text ?: "<error>"
|
||||
|
||||
override val referenceNameElement: UElement
|
||||
get() = KotlinUIdentifier(psi.typeReference?.nameElement, this)
|
||||
get() = psi.name ?: "<error>"
|
||||
}
|
||||
|
||||
}
|
||||
+7
@@ -18,6 +18,7 @@ package org.jetbrains.uast.kotlin
|
||||
|
||||
import com.intellij.psi.PsiNamedElement
|
||||
import org.jetbrains.kotlin.psi.KtDotQualifiedExpression
|
||||
import org.jetbrains.uast.UCallExpression
|
||||
import org.jetbrains.uast.UElement
|
||||
import org.jetbrains.uast.UQualifiedReferenceExpression
|
||||
import org.jetbrains.uast.UastQualifiedExpressionAccessType
|
||||
@@ -36,4 +37,10 @@ class KotlinUQualifiedReferenceExpression(
|
||||
|
||||
override val resolvedName: String?
|
||||
get() = (resolve() as? PsiNamedElement)?.name
|
||||
|
||||
override val referenceNameElement: UElement?
|
||||
get() = when (val selector = selector) {
|
||||
is UCallExpression -> selector.methodIdentifier
|
||||
else -> super.referenceNameElement
|
||||
}
|
||||
}
|
||||
|
||||
-7
@@ -18,7 +18,6 @@ package org.jetbrains.uast.kotlin
|
||||
|
||||
import com.intellij.psi.PsiNamedElement
|
||||
import org.jetbrains.kotlin.psi.KtDotQualifiedExpression
|
||||
import org.jetbrains.uast.UCallExpression
|
||||
import org.jetbrains.uast.UElement
|
||||
import org.jetbrains.uast.UQualifiedReferenceExpression
|
||||
import org.jetbrains.uast.UastQualifiedExpressionAccessType
|
||||
@@ -37,10 +36,4 @@ class KotlinUQualifiedReferenceExpression(
|
||||
|
||||
override val resolvedName: String?
|
||||
get() = (resolve() as? PsiNamedElement)?.name
|
||||
|
||||
override val referenceNameElement: UElement?
|
||||
get() = when (val selector = selector) {
|
||||
is UCallExpression -> selector.methodIdentifier
|
||||
else -> super.referenceNameElement
|
||||
}
|
||||
}
|
||||
+2
@@ -71,6 +71,8 @@ open class KotlinUSimpleReferenceExpression(
|
||||
visitor.afterVisitSimpleNameReferenceExpression(this)
|
||||
}
|
||||
|
||||
override val referenceNameElement: UElement? by lz { psi.getIdentifier()?.toUElement() }
|
||||
|
||||
private fun visitAccessorCalls(visitor: UastVisitor) {
|
||||
// Visit Kotlin get-set synthetic Java property calls as function calls
|
||||
val bindingContext = psi.analyze()
|
||||
|
||||
-2
@@ -71,8 +71,6 @@ open class KotlinUSimpleReferenceExpression(
|
||||
visitor.afterVisitSimpleNameReferenceExpression(this)
|
||||
}
|
||||
|
||||
override val referenceNameElement: UElement? by lz { psi.getIdentifier()?.toUElement() }
|
||||
|
||||
private fun visitAccessorCalls(visitor: UastVisitor) {
|
||||
// Visit Kotlin get-set synthetic Java property calls as function calls
|
||||
val bindingContext = psi.analyze()
|
||||
+1
-1
@@ -54,7 +54,7 @@ class KotlinUSwitchEntry(
|
||||
givenParent: UElement?
|
||||
) : KotlinAbstractUExpression(givenParent), USwitchClauseExpressionWithBody {
|
||||
override val caseValues by lz {
|
||||
psi.conditions.map { KotlinConverter.convertWhenCondition(it, this) ?: UastEmptyExpression }
|
||||
psi.conditions.map { KotlinConverter.convertWhenCondition(it, this, DEFAULT_EXPRESSION_TYPES_LIST) ?: UastEmptyExpression }
|
||||
}
|
||||
|
||||
override val body: UExpressionList by lz {
|
||||
|
||||
+1
-1
@@ -54,7 +54,7 @@ class KotlinUSwitchEntry(
|
||||
givenParent: UElement?
|
||||
) : KotlinAbstractUExpression(givenParent), USwitchClauseExpressionWithBody {
|
||||
override val caseValues by lz {
|
||||
psi.conditions.map { KotlinConverter.convertWhenCondition(it, this, DEFAULT_EXPRESSION_TYPES_LIST) ?: UastEmptyExpression }
|
||||
psi.conditions.map { KotlinConverter.convertWhenCondition(it, this) ?: UastEmptyExpression }
|
||||
}
|
||||
|
||||
override val body: UExpressionList by lz {
|
||||
+10
-5
@@ -17,10 +17,7 @@
|
||||
package org.jetbrains.uast.kotlin
|
||||
|
||||
import org.jetbrains.kotlin.psi.KtTryExpression
|
||||
import org.jetbrains.uast.UElement
|
||||
import org.jetbrains.uast.UIdentifier
|
||||
import org.jetbrains.uast.UTryExpression
|
||||
import org.jetbrains.uast.UVariable
|
||||
import org.jetbrains.uast.*
|
||||
import org.jetbrains.uast.kotlin.declarations.KotlinUIdentifier
|
||||
|
||||
class KotlinUTryExpression(
|
||||
@@ -29,7 +26,15 @@ class KotlinUTryExpression(
|
||||
) : KotlinAbstractUExpression(givenParent), UTryExpression, KotlinUElementWithType {
|
||||
override val tryClause by lz { KotlinConverter.convertOrEmpty(psi.tryBlock, this) }
|
||||
override val catchClauses by lz { psi.catchClauses.map { KotlinUCatchClause(it, this) } }
|
||||
override val finallyClause by lz { psi.finallyBlock?.finalExpression?.let { KotlinConverter.convertExpression(it, this) } }
|
||||
override val finallyClause by lz {
|
||||
psi.finallyBlock?.finalExpression?.let {
|
||||
KotlinConverter.convertExpression(
|
||||
it,
|
||||
this,
|
||||
DEFAULT_EXPRESSION_TYPES_LIST
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
override val resourceVariables: List<UVariable>
|
||||
get() = emptyList()
|
||||
|
||||
+5
-10
@@ -17,7 +17,10 @@
|
||||
package org.jetbrains.uast.kotlin
|
||||
|
||||
import org.jetbrains.kotlin.psi.KtTryExpression
|
||||
import org.jetbrains.uast.*
|
||||
import org.jetbrains.uast.UElement
|
||||
import org.jetbrains.uast.UIdentifier
|
||||
import org.jetbrains.uast.UTryExpression
|
||||
import org.jetbrains.uast.UVariable
|
||||
import org.jetbrains.uast.kotlin.declarations.KotlinUIdentifier
|
||||
|
||||
class KotlinUTryExpression(
|
||||
@@ -26,15 +29,7 @@ class KotlinUTryExpression(
|
||||
) : KotlinAbstractUExpression(givenParent), UTryExpression, KotlinUElementWithType {
|
||||
override val tryClause by lz { KotlinConverter.convertOrEmpty(psi.tryBlock, this) }
|
||||
override val catchClauses by lz { psi.catchClauses.map { KotlinUCatchClause(it, this) } }
|
||||
override val finallyClause by lz {
|
||||
psi.finallyBlock?.finalExpression?.let {
|
||||
KotlinConverter.convertExpression(
|
||||
it,
|
||||
this,
|
||||
DEFAULT_EXPRESSION_TYPES_LIST
|
||||
)
|
||||
}
|
||||
}
|
||||
override val finallyClause by lz { psi.finallyBlock?.finalExpression?.let { KotlinConverter.convertExpression(it, this) } }
|
||||
|
||||
override val resourceVariables: List<UVariable>
|
||||
get() = emptyList()
|
||||
@@ -1,7 +1,7 @@
|
||||
Test -> UAnnotation (fqName = null)
|
||||
A -> UClass (name = A)
|
||||
MyAnnotation -> UClass (name = MyAnnotation)
|
||||
text -> [!] UnknownKotlinExpression (VALUE_PARAMETER)
|
||||
text -> UAnnotationMethod (name = text)
|
||||
String -> USimpleNameReferenceExpression (identifier = String)
|
||||
MyAnnotation -> UAnnotation (fqName = MyAnnotation)
|
||||
B -> UClass (name = B)
|
||||
|
||||
+1
-1
@@ -1,7 +1,7 @@
|
||||
Test -> UAnnotation (fqName = null)
|
||||
A -> UClass (name = A)
|
||||
MyAnnotation -> UClass (name = MyAnnotation)
|
||||
text -> UAnnotationMethod (name = text)
|
||||
text -> [!] UnknownKotlinExpression (VALUE_PARAMETER)
|
||||
String -> USimpleNameReferenceExpression (identifier = String)
|
||||
MyAnnotation -> UAnnotation (fqName = MyAnnotation)
|
||||
B -> UClass (name = B)
|
||||
@@ -1,7 +1,12 @@
|
||||
package org.jetbrains.uast.test.kotlin
|
||||
|
||||
import com.intellij.psi.PsiElement
|
||||
import org.jetbrains.uast.*
|
||||
import org.jetbrains.uast.test.common.UElementToParentMap
|
||||
import org.jetbrains.uast.test.common.kotlin.IdentifiersTestBase
|
||||
import org.jetbrains.uast.test.env.assertEqualsToFile
|
||||
import java.io.File
|
||||
import kotlin.test.assertNotNull
|
||||
|
||||
|
||||
abstract class AbstractKotlinIdentifiersTest : AbstractKotlinUastTest(), IdentifiersTestBase {
|
||||
@@ -11,5 +16,21 @@ abstract class AbstractKotlinIdentifiersTest : AbstractKotlinUastTest(), Identif
|
||||
|
||||
override fun getIdentifiersFile(testName: String): File = getTestFile(testName, "identifiers.txt")
|
||||
|
||||
override fun check(testName: String, file: UFile) {
|
||||
super.check(testName, file)
|
||||
assertEqualsToFile("refNames", getTestFile(testName, "refNames.txt"), file.asRefNames())
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
private fun refNameRetriever(psiElement: PsiElement): UElement? =
|
||||
when (val uElement = psiElement.toUElementOfExpectedTypes(UCallExpression::class.java, UReferenceExpression::class.java)) {
|
||||
is UReferenceExpression -> uElement.referenceNameElement
|
||||
is UCallExpression -> uElement.classReference?.referenceNameElement
|
||||
else -> null
|
||||
}?.also {
|
||||
assertNotNull(it.sourcePsi, "referenceNameElement should have physical source, origin = $psiElement")
|
||||
}
|
||||
|
||||
fun UFile.asRefNames() = object : UElementToParentMap(::refNameRetriever) {
|
||||
override fun renderSource(element: PsiElement): String = element.javaClass.simpleName
|
||||
}.visitUFileAndGetResult(this)
|
||||
@@ -0,0 +1,15 @@
|
||||
package org.jetbrains.uast.test.kotlin
|
||||
|
||||
import org.jetbrains.uast.test.common.kotlin.IdentifiersTestBase
|
||||
import java.io.File
|
||||
|
||||
|
||||
abstract class AbstractKotlinIdentifiersTest : AbstractKotlinUastTest(), IdentifiersTestBase {
|
||||
|
||||
private fun getTestFile(testName: String, ext: String) =
|
||||
File(File(AbstractKotlinUastTest.TEST_KOTLIN_MODEL_DIR, testName).canonicalPath + '.' + ext)
|
||||
|
||||
override fun getIdentifiersFile(testName: String): File = getTestFile(testName, "identifiers.txt")
|
||||
|
||||
|
||||
}
|
||||
@@ -1,36 +0,0 @@
|
||||
package org.jetbrains.uast.test.kotlin
|
||||
|
||||
import com.intellij.psi.PsiElement
|
||||
import org.jetbrains.uast.*
|
||||
import org.jetbrains.uast.test.common.UElementToParentMap
|
||||
import org.jetbrains.uast.test.common.kotlin.IdentifiersTestBase
|
||||
import org.jetbrains.uast.test.env.assertEqualsToFile
|
||||
import java.io.File
|
||||
import kotlin.test.assertNotNull
|
||||
|
||||
|
||||
abstract class AbstractKotlinIdentifiersTest : AbstractKotlinUastTest(), IdentifiersTestBase {
|
||||
|
||||
private fun getTestFile(testName: String, ext: String) =
|
||||
File(File(AbstractKotlinUastTest.TEST_KOTLIN_MODEL_DIR, testName).canonicalPath + '.' + ext)
|
||||
|
||||
override fun getIdentifiersFile(testName: String): File = getTestFile(testName, "identifiers.txt")
|
||||
|
||||
override fun check(testName: String, file: UFile) {
|
||||
super.check(testName, file)
|
||||
assertEqualsToFile("refNames", getTestFile(testName, "refNames.txt"), file.asRefNames())
|
||||
}
|
||||
}
|
||||
|
||||
private fun refNameRetriever(psiElement: PsiElement): UElement? =
|
||||
when (val uElement = psiElement.toUElementOfExpectedTypes(UCallExpression::class.java, UReferenceExpression::class.java)) {
|
||||
is UReferenceExpression -> uElement.referenceNameElement
|
||||
is UCallExpression -> uElement.classReference?.referenceNameElement
|
||||
else -> null
|
||||
}?.also {
|
||||
assertNotNull(it.sourcePsi, "referenceNameElement should have physical source, origin = $psiElement")
|
||||
}
|
||||
|
||||
fun UFile.asRefNames() = object : UElementToParentMap(::refNameRetriever) {
|
||||
override fun renderSource(element: PsiElement): String = element.javaClass.simpleName
|
||||
}.visitUFileAndGetResult(this)
|
||||
@@ -14,6 +14,7 @@ import org.jetbrains.kotlin.utils.addToStdlib.assertedCast
|
||||
import org.jetbrains.kotlin.utils.addToStdlib.cast
|
||||
import org.jetbrains.kotlin.utils.sure
|
||||
import org.jetbrains.uast.*
|
||||
import org.jetbrains.uast.expressions.UInjectionHost
|
||||
import org.jetbrains.uast.kotlin.KotlinUastLanguagePlugin
|
||||
import org.jetbrains.uast.test.env.kotlin.findElementByText
|
||||
import org.jetbrains.uast.test.env.kotlin.findElementByTextFromPsi
|
||||
@@ -216,21 +217,21 @@ class KotlinUastApiTest : AbstractKotlinUastTest() {
|
||||
fun testWhenStringLiteral() {
|
||||
doTest("WhenStringLiteral") { _, file ->
|
||||
|
||||
file.findElementByTextFromPsi<ULiteralExpression>("abc").let { literalExpression ->
|
||||
file.findElementByTextFromPsi<UInjectionHost>("\"abc\"").let { literalExpression ->
|
||||
val psi = literalExpression.psi!!
|
||||
Assert.assertTrue(psi is KtLiteralStringTemplateEntry)
|
||||
Assert.assertTrue(psi is KtStringTemplateExpression)
|
||||
UsefulTestCase.assertInstanceOf(literalExpression.uastParent, USwitchClauseExpressionWithBody::class.java)
|
||||
}
|
||||
|
||||
file.findElementByTextFromPsi<ULiteralExpression>("def").let { literalExpression ->
|
||||
file.findElementByTextFromPsi<UInjectionHost>("\"def\"").let { literalExpression ->
|
||||
val psi = literalExpression.psi!!
|
||||
Assert.assertTrue(psi is KtLiteralStringTemplateEntry)
|
||||
Assert.assertTrue(psi is KtStringTemplateExpression)
|
||||
UsefulTestCase.assertInstanceOf(literalExpression.uastParent, USwitchClauseExpressionWithBody::class.java)
|
||||
}
|
||||
|
||||
file.findElementByTextFromPsi<ULiteralExpression>("def1").let { literalExpression ->
|
||||
file.findElementByTextFromPsi<UInjectionHost>("\"def1\"").let { literalExpression ->
|
||||
val psi = literalExpression.psi!!
|
||||
Assert.assertTrue(psi is KtLiteralStringTemplateEntry)
|
||||
Assert.assertTrue(psi is KtStringTemplateExpression)
|
||||
UsefulTestCase.assertInstanceOf(literalExpression.uastParent, UBlockExpression::class.java)
|
||||
}
|
||||
|
||||
@@ -549,6 +550,21 @@ class KotlinUastApiTest : AbstractKotlinUastTest() {
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
fun testMethodReturnTypeReference() {
|
||||
doTest("Elvis") { _, file ->
|
||||
assertEquals(
|
||||
"UTypeReferenceExpression (name = java.lang.String)",
|
||||
file.findElementByTextFromPsi<UMethod>("fun foo(bar: String): String? = null").returnTypeReference?.asLogString()
|
||||
)
|
||||
assertEquals(
|
||||
null,
|
||||
file.findElementByTextFromPsi<UMethod>("fun bar() = 42").returnTypeReference?.asLogString()
|
||||
)
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
fun testVariablesTypeReferences() {
|
||||
doTest("TypeReferences") { _, file ->
|
||||
|
||||
+6
-22
@@ -14,7 +14,6 @@ import org.jetbrains.kotlin.utils.addToStdlib.assertedCast
|
||||
import org.jetbrains.kotlin.utils.addToStdlib.cast
|
||||
import org.jetbrains.kotlin.utils.sure
|
||||
import org.jetbrains.uast.*
|
||||
import org.jetbrains.uast.expressions.UInjectionHost
|
||||
import org.jetbrains.uast.kotlin.KotlinUastLanguagePlugin
|
||||
import org.jetbrains.uast.test.env.kotlin.findElementByText
|
||||
import org.jetbrains.uast.test.env.kotlin.findElementByTextFromPsi
|
||||
@@ -217,21 +216,21 @@ class KotlinUastApiTest : AbstractKotlinUastTest() {
|
||||
fun testWhenStringLiteral() {
|
||||
doTest("WhenStringLiteral") { _, file ->
|
||||
|
||||
file.findElementByTextFromPsi<UInjectionHost>("\"abc\"").let { literalExpression ->
|
||||
file.findElementByTextFromPsi<ULiteralExpression>("abc").let { literalExpression ->
|
||||
val psi = literalExpression.psi!!
|
||||
Assert.assertTrue(psi is KtStringTemplateExpression)
|
||||
Assert.assertTrue(psi is KtLiteralStringTemplateEntry)
|
||||
UsefulTestCase.assertInstanceOf(literalExpression.uastParent, USwitchClauseExpressionWithBody::class.java)
|
||||
}
|
||||
|
||||
file.findElementByTextFromPsi<UInjectionHost>("\"def\"").let { literalExpression ->
|
||||
file.findElementByTextFromPsi<ULiteralExpression>("def").let { literalExpression ->
|
||||
val psi = literalExpression.psi!!
|
||||
Assert.assertTrue(psi is KtStringTemplateExpression)
|
||||
Assert.assertTrue(psi is KtLiteralStringTemplateEntry)
|
||||
UsefulTestCase.assertInstanceOf(literalExpression.uastParent, USwitchClauseExpressionWithBody::class.java)
|
||||
}
|
||||
|
||||
file.findElementByTextFromPsi<UInjectionHost>("\"def1\"").let { literalExpression ->
|
||||
file.findElementByTextFromPsi<ULiteralExpression>("def1").let { literalExpression ->
|
||||
val psi = literalExpression.psi!!
|
||||
Assert.assertTrue(psi is KtStringTemplateExpression)
|
||||
Assert.assertTrue(psi is KtLiteralStringTemplateEntry)
|
||||
UsefulTestCase.assertInstanceOf(literalExpression.uastParent, UBlockExpression::class.java)
|
||||
}
|
||||
|
||||
@@ -550,21 +549,6 @@ class KotlinUastApiTest : AbstractKotlinUastTest() {
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
fun testMethodReturnTypeReference() {
|
||||
doTest("Elvis") { _, file ->
|
||||
assertEquals(
|
||||
"UTypeReferenceExpression (name = java.lang.String)",
|
||||
file.findElementByTextFromPsi<UMethod>("fun foo(bar: String): String? = null").returnTypeReference?.asLogString()
|
||||
)
|
||||
assertEquals(
|
||||
null,
|
||||
file.findElementByTextFromPsi<UMethod>("fun bar() = 42").returnTypeReference?.asLogString()
|
||||
)
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
fun testVariablesTypeReferences() {
|
||||
doTest("TypeReferences") { _, file ->
|
||||
@@ -9,7 +9,7 @@ import com.intellij.openapi.Disposable
|
||||
import com.intellij.openapi.application.ApplicationManager
|
||||
import com.intellij.openapi.extensions.Extensions
|
||||
import com.intellij.openapi.util.Disposer
|
||||
import com.intellij.patterns.uast.literalExpression
|
||||
import com.intellij.patterns.uast.injectionHostUExpression
|
||||
import com.intellij.psi.*
|
||||
import com.intellij.psi.impl.source.resolve.reference.PsiReferenceContributorEP
|
||||
import com.intellij.psi.impl.source.resolve.reference.ReferenceProvidersRegistry
|
||||
@@ -35,7 +35,7 @@ class KotlinUastReferencesTest : KotlinLightCodeInsightFixtureTestCase() {
|
||||
fun `test original getter is visible when reference is under renaming`() {
|
||||
|
||||
registerReferenceProviders(testRootDisposable) {
|
||||
registerUastReferenceProvider(literalExpression(), uastLiteralReferenceProvider { _, psiLanguageInjectionHost ->
|
||||
registerUastReferenceProvider(injectionHostUExpression(), uastInjectionHostReferenceProvider { _, psiLanguageInjectionHost ->
|
||||
arrayOf(GetterReference("KotlinBean", psiLanguageInjectionHost))
|
||||
})
|
||||
}
|
||||
|
||||
+2
-2
@@ -9,7 +9,7 @@ import com.intellij.openapi.Disposable
|
||||
import com.intellij.openapi.application.ApplicationManager
|
||||
import com.intellij.openapi.extensions.Extensions
|
||||
import com.intellij.openapi.util.Disposer
|
||||
import com.intellij.patterns.uast.injectionHostUExpression
|
||||
import com.intellij.patterns.uast.literalExpression
|
||||
import com.intellij.psi.*
|
||||
import com.intellij.psi.impl.source.resolve.reference.PsiReferenceContributorEP
|
||||
import com.intellij.psi.impl.source.resolve.reference.ReferenceProvidersRegistry
|
||||
@@ -35,7 +35,7 @@ class KotlinUastReferencesTest : KotlinLightCodeInsightFixtureTestCase() {
|
||||
fun `test original getter is visible when reference is under renaming`() {
|
||||
|
||||
registerReferenceProviders(testRootDisposable) {
|
||||
registerUastReferenceProvider(injectionHostUExpression(), uastInjectionHostReferenceProvider { _, psiLanguageInjectionHost ->
|
||||
registerUastReferenceProvider(literalExpression(), uastLiteralReferenceProvider { _, psiLanguageInjectionHost ->
|
||||
arrayOf(GetterReference("KotlinBean", psiLanguageInjectionHost))
|
||||
})
|
||||
}
|
||||
@@ -1,5 +1,6 @@
|
||||
package org.jetbrains.uast.test.kotlin
|
||||
|
||||
import org.jetbrains.uast.kotlin.KotlinConverter
|
||||
import org.junit.Test
|
||||
|
||||
class SimpleKotlinRenderLogTest : AbstractKotlinRenderLogTest() {
|
||||
@@ -27,6 +28,11 @@ class SimpleKotlinRenderLogTest : AbstractKotlinRenderLogTest() {
|
||||
|
||||
@Test fun testStringTemplateComplex() = doTest("StringTemplateComplex")
|
||||
|
||||
@Test
|
||||
fun testStringTemplateComplexForUInjectionHost() = withForceUInjectionHostValue {
|
||||
doTest("StringTemplateComplexForUInjectionHost")
|
||||
}
|
||||
|
||||
@Test fun testQualifiedConstructorCall() = doTest("QualifiedConstructorCall")
|
||||
|
||||
@Test fun testPropertyDelegate() = doTest("PropertyDelegate")
|
||||
@@ -94,3 +100,13 @@ class SimpleKotlinRenderLogTest : AbstractKotlinRenderLogTest() {
|
||||
@Test
|
||||
fun testConstructorDelegate() = doTest("ConstructorDelegate")
|
||||
}
|
||||
|
||||
fun withForceUInjectionHostValue(call: () -> Unit) {
|
||||
val prev = KotlinConverter.forceUInjectionHost
|
||||
KotlinConverter.forceUInjectionHost = true
|
||||
try {
|
||||
call.invoke()
|
||||
} finally {
|
||||
KotlinConverter.forceUInjectionHost = prev
|
||||
}
|
||||
}
|
||||
-16
@@ -1,6 +1,5 @@
|
||||
package org.jetbrains.uast.test.kotlin
|
||||
|
||||
import org.jetbrains.uast.kotlin.KotlinConverter
|
||||
import org.junit.Test
|
||||
|
||||
class SimpleKotlinRenderLogTest : AbstractKotlinRenderLogTest() {
|
||||
@@ -28,11 +27,6 @@ class SimpleKotlinRenderLogTest : AbstractKotlinRenderLogTest() {
|
||||
|
||||
@Test fun testStringTemplateComplex() = doTest("StringTemplateComplex")
|
||||
|
||||
@Test
|
||||
fun testStringTemplateComplexForUInjectionHost() = withForceUInjectionHostValue {
|
||||
doTest("StringTemplateComplexForUInjectionHost")
|
||||
}
|
||||
|
||||
@Test fun testQualifiedConstructorCall() = doTest("QualifiedConstructorCall")
|
||||
|
||||
@Test fun testPropertyDelegate() = doTest("PropertyDelegate")
|
||||
@@ -100,13 +94,3 @@ class SimpleKotlinRenderLogTest : AbstractKotlinRenderLogTest() {
|
||||
@Test
|
||||
fun testConstructorDelegate() = doTest("ConstructorDelegate")
|
||||
}
|
||||
|
||||
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