Uast: KotlinSecondaryConstructorWithInitializersUMethod introduced as workaround for KT-21617
to be the only constructor which includes `init` block when there is no primary constructors in the class
This commit is contained in:
committed by
xiexed
parent
b8069b48c5
commit
209ba89a49
@@ -81,11 +81,16 @@ open class KotlinUClass private constructor(
|
||||
override fun getInitializers(): Array<UClassInitializer> = super.getInitializers()
|
||||
|
||||
override fun getMethods(): Array<UMethod> {
|
||||
val hasPrimaryConstructor = ktClass?.hasPrimaryConstructor() ?: false
|
||||
var secondaryConstructorsCount = 0
|
||||
|
||||
fun createUMethod(psiMethod: PsiMethod): UMethod {
|
||||
return if (psiMethod is KtLightMethod &&
|
||||
psiMethod.isConstructor) {
|
||||
KotlinConstructorUMethod(ktClass, psiMethod, this)
|
||||
if (!hasPrimaryConstructor && secondaryConstructorsCount++ == 0)
|
||||
KotlinSecondaryConstructorWithInitializersUMethod(ktClass, psiMethod, this)
|
||||
else
|
||||
KotlinConstructorUMethod(ktClass, psiMethod, this)
|
||||
} else {
|
||||
getLanguagePlugin().convert(psiMethod, this)
|
||||
}
|
||||
@@ -111,7 +116,7 @@ open class KotlinUClass private constructor(
|
||||
}
|
||||
}
|
||||
|
||||
class KotlinConstructorUMethod(
|
||||
open class KotlinConstructorUMethod(
|
||||
private val ktClass: KtClassOrObject?,
|
||||
override val psi: KtLightMethod,
|
||||
givenParent: UElement?
|
||||
@@ -143,17 +148,28 @@ class KotlinConstructorUMethod(
|
||||
}
|
||||
}
|
||||
|
||||
private fun getBodyExpressions(): List<KtExpression> {
|
||||
open protected fun getBodyExpressions(): List<KtExpression> {
|
||||
if (isPrimary) return getInitializers()
|
||||
val bodyExpression = (psi.kotlinOrigin as? KtFunction)?.bodyExpression ?: return emptyList()
|
||||
if (bodyExpression is KtBlockExpression) return bodyExpression.statements
|
||||
return listOf(bodyExpression)
|
||||
}
|
||||
|
||||
private fun getInitializers() = ktClass?.getAnonymousInitializers()?.mapNotNull { it.body } ?: emptyList()
|
||||
protected fun getInitializers() = ktClass?.getAnonymousInitializers()?.mapNotNull { it.body } ?: emptyList()
|
||||
|
||||
}
|
||||
|
||||
// This class was created as a workaround for KT-21617 to be the only constructor which includes `init` block
|
||||
// when there is no primary constructors in the class.
|
||||
// It is expected to have only one constructor of this type in a UClass.
|
||||
class KotlinSecondaryConstructorWithInitializersUMethod(
|
||||
ktClass: KtClassOrObject?,
|
||||
psi: KtLightMethod,
|
||||
givenParent: UElement?
|
||||
) : KotlinConstructorUMethod(ktClass, psi, givenParent) {
|
||||
override fun getBodyExpressions(): List<KtExpression> = getInitializers() + super.getBodyExpressions()
|
||||
}
|
||||
|
||||
class KotlinUAnonymousClass(
|
||||
psi: PsiAnonymousClass,
|
||||
givenParent: UElement?
|
||||
|
||||
+12
@@ -44,4 +44,16 @@ class KotlinUBlockExpression(
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
override fun convertParent(): UElement? {
|
||||
val directParent = super.convertParent()
|
||||
if (directParent is UnknownKotlinExpression && directParent.psi is KtAnonymousInitializer) {
|
||||
val containingUClass = directParent.getContainingUClass() ?: return directParent
|
||||
containingUClass.methods
|
||||
.find { it is KotlinConstructorUMethod && it.isPrimary || it is KotlinSecondaryConstructorWithInitializersUMethod }?.let {
|
||||
return it.uastBody
|
||||
}
|
||||
}
|
||||
return directParent
|
||||
}
|
||||
}
|
||||
@@ -58,8 +58,6 @@ class AWithSecondaryInit {
|
||||
lateinit var a: String
|
||||
|
||||
init {
|
||||
// This body will not be picked by UAST because no lightMethod contains it.
|
||||
// Of course it is not a desired behaviour, so fix it if you know how
|
||||
println()
|
||||
}
|
||||
|
||||
|
||||
@@ -130,6 +130,10 @@ UFile (package = )
|
||||
UCallExpression (kind = UastCallKind(name='constructor_call'), argCount = 0))
|
||||
UIdentifier (Identifier ())
|
||||
USimpleNameReferenceExpression (identifier = <init>)
|
||||
UBlockExpression
|
||||
UCallExpression (kind = UastCallKind(name='method_call'), argCount = 0))
|
||||
UIdentifier (Identifier (println))
|
||||
USimpleNameReferenceExpression (identifier = println)
|
||||
UBinaryExpression (operator = =)
|
||||
USimpleNameReferenceExpression (identifier = a)
|
||||
UQualifiedReferenceExpression
|
||||
|
||||
@@ -67,6 +67,9 @@ public final class AWithSecondaryInit {
|
||||
public final fun setA(p: java.lang.String) : void = UastEmptyExpression
|
||||
public fun AWithSecondaryInit(i: int) {
|
||||
<init>()
|
||||
{
|
||||
println()
|
||||
}
|
||||
a = i.toString()
|
||||
}
|
||||
public fun AWithSecondaryInit(s: java.lang.String) {
|
||||
|
||||
Reference in New Issue
Block a user