From 0c011f4e73874d7512862a9358609e4f8d9ad784 Mon Sep 17 00:00:00 2001 From: Jinseong Jeon Date: Thu, 17 Jun 2021 15:47:03 -0700 Subject: [PATCH] UAST: place method declarations together --- .../jetbrains/uast/kotlin/KotlinConverter.kt | 2 - .../kotlin/declarations/KotlinUAnnotation.kt | 1 - .../uast/kotlin/declarations/KotlinUClass.kt | 73 ------------------- .../uast/kotlin/declarations/KotlinUMethod.kt | 73 ++++++++++++++++++- 4 files changed, 72 insertions(+), 77 deletions(-) diff --git a/plugins/uast-kotlin/src/org/jetbrains/uast/kotlin/KotlinConverter.kt b/plugins/uast-kotlin/src/org/jetbrains/uast/kotlin/KotlinConverter.kt index b661f378e2b..7261a1954da 100644 --- a/plugins/uast-kotlin/src/org/jetbrains/uast/kotlin/KotlinConverter.kt +++ b/plugins/uast-kotlin/src/org/jetbrains/uast/kotlin/KotlinConverter.kt @@ -22,8 +22,6 @@ import org.jetbrains.kotlin.psi.psiUtil.getParentOfType import org.jetbrains.kotlin.utils.addToStdlib.safeAs import org.jetbrains.uast.* import org.jetbrains.uast.expressions.UInjectionHost -import org.jetbrains.uast.kotlin.declarations.KotlinUMethod -import org.jetbrains.uast.kotlin.declarations.KotlinUMethodWithFakeLightDelegate import org.jetbrains.uast.kotlin.expressions.* import org.jetbrains.uast.kotlin.psi.* diff --git a/plugins/uast-kotlin/src/org/jetbrains/uast/kotlin/declarations/KotlinUAnnotation.kt b/plugins/uast-kotlin/src/org/jetbrains/uast/kotlin/declarations/KotlinUAnnotation.kt index bc079d13386..9d4311426cf 100644 --- a/plugins/uast-kotlin/src/org/jetbrains/uast/kotlin/declarations/KotlinUAnnotation.kt +++ b/plugins/uast-kotlin/src/org/jetbrains/uast/kotlin/declarations/KotlinUAnnotation.kt @@ -22,7 +22,6 @@ import org.jetbrains.kotlin.types.ErrorUtils import org.jetbrains.kotlin.utils.addToStdlib.firstIsInstanceOrNull import org.jetbrains.kotlin.utils.addToStdlib.safeAs import org.jetbrains.uast.* -import org.jetbrains.uast.kotlin.declarations.KotlinUMethod import org.jetbrains.uast.kotlin.internal.multiResolveResults abstract class KotlinUAnnotationBase( diff --git a/plugins/uast-kotlin/src/org/jetbrains/uast/kotlin/declarations/KotlinUClass.kt b/plugins/uast-kotlin/src/org/jetbrains/uast/kotlin/declarations/KotlinUClass.kt index 12d609b0a41..074972890d9 100644 --- a/plugins/uast-kotlin/src/org/jetbrains/uast/kotlin/declarations/KotlinUClass.kt +++ b/plugins/uast-kotlin/src/org/jetbrains/uast/kotlin/declarations/KotlinUClass.kt @@ -24,12 +24,9 @@ import org.jetbrains.kotlin.asJava.classes.KtLightClassForScript import org.jetbrains.kotlin.asJava.elements.KtLightMethod import org.jetbrains.kotlin.load.java.JvmAbi import org.jetbrains.kotlin.psi.* -import org.jetbrains.kotlin.utils.SmartList import org.jetbrains.kotlin.utils.addIfNotNull -import org.jetbrains.kotlin.utils.addToStdlib.firstIsInstanceOrNull import org.jetbrains.uast.* import org.jetbrains.uast.internal.acceptList -import org.jetbrains.uast.kotlin.declarations.KotlinUMethod import org.jetbrains.uast.visitor.UastVisitor abstract class AbstractKotlinUClass(givenParent: UElement?) : KotlinAbstractUElement(givenParent), UClassTypeSpecific, UAnchorOwner { @@ -175,76 +172,6 @@ open class KotlinUClass private constructor( } -open class KotlinConstructorUMethod( - private val ktClass: KtClassOrObject?, - override val psi: PsiMethod, - kotlinOrigin: KtDeclaration?, - givenParent: UElement? -) : KotlinUMethod(psi, kotlinOrigin, givenParent) { - - constructor( - ktClass: KtClassOrObject?, - psi: KtLightMethod, - givenParent: UElement? - ):this(ktClass, psi, psi.kotlinOrigin, givenParent) - - val isPrimary: Boolean - get() = sourcePsi.let { it is KtPrimaryConstructor || it is KtClassOrObject } - - override val uastBody: UExpression? by lz { - val delegationCall: KtCallElement? = sourcePsi.let { - when { - isPrimary -> ktClass?.superTypeListEntries?.firstIsInstanceOrNull() - it is KtSecondaryConstructor -> it.getDelegationCall() - else -> null - } - } - val bodyExpressions = getBodyExpressions() - if (delegationCall == null && bodyExpressions.isEmpty()) return@lz null - KotlinLazyUBlockExpression(this) { uastParent -> - SmartList().apply { - delegationCall?.let { - add(KotlinUFunctionCallExpression(it, uastParent)) - } - bodyExpressions.forEach { - add(KotlinConverter.convertOrEmpty(it, uastParent)) - } - } - } - } - - override val uastAnchor: KotlinUIdentifier by lazy { - KotlinUIdentifier( - psi.nameIdentifier, - if (isPrimary) ktClass?.nameIdentifier else (sourcePsi as? KtSecondaryConstructor)?.getConstructorKeyword(), - this - ) - } - - override val javaPsi = psi - - open protected fun getBodyExpressions(): List { - if (isPrimary) return getInitializers() - val bodyExpression = (sourcePsi as? KtFunction)?.bodyExpression ?: return emptyList() - if (bodyExpression is KtBlockExpression) return bodyExpression.statements - return listOf(bodyExpression) - } - - 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 = getInitializers() + super.getBodyExpressions() -} - class KotlinUAnonymousClass( psi: PsiAnonymousClass, givenParent: UElement? diff --git a/plugins/uast-kotlin/src/org/jetbrains/uast/kotlin/declarations/KotlinUMethod.kt b/plugins/uast-kotlin/src/org/jetbrains/uast/kotlin/declarations/KotlinUMethod.kt index 936b52a8b7a..1d6218540d8 100644 --- a/plugins/uast-kotlin/src/org/jetbrains/uast/kotlin/declarations/KotlinUMethod.kt +++ b/plugins/uast-kotlin/src/org/jetbrains/uast/kotlin/declarations/KotlinUMethod.kt @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.jetbrains.uast.kotlin.declarations +package org.jetbrains.uast.kotlin import com.intellij.psi.* import org.jetbrains.kotlin.asJava.elements.* @@ -22,6 +22,7 @@ import org.jetbrains.kotlin.psi.* import org.jetbrains.kotlin.psi.psiUtil.containingClassOrObject import org.jetbrains.kotlin.psi.psiUtil.getParentOfType import org.jetbrains.kotlin.utils.SmartList +import org.jetbrains.kotlin.utils.addToStdlib.firstIsInstanceOrNull import org.jetbrains.uast.* import org.jetbrains.uast.java.internal.JavaUElementWithComments import org.jetbrains.uast.kotlin.* @@ -140,6 +141,76 @@ open class KotlinUMethod( } } +open class KotlinConstructorUMethod( + private val ktClass: KtClassOrObject?, + override val psi: PsiMethod, + kotlinOrigin: KtDeclaration?, + givenParent: UElement? +) : KotlinUMethod(psi, kotlinOrigin, givenParent) { + + constructor( + ktClass: KtClassOrObject?, + psi: KtLightMethod, + givenParent: UElement? + ) : this(ktClass, psi, psi.kotlinOrigin, givenParent) + + val isPrimary: Boolean + get() = sourcePsi.let { it is KtPrimaryConstructor || it is KtClassOrObject } + + override val uastBody: UExpression? by lz { + val delegationCall: KtCallElement? = sourcePsi.let { + when { + isPrimary -> ktClass?.superTypeListEntries?.firstIsInstanceOrNull() + it is KtSecondaryConstructor -> it.getDelegationCall() + else -> null + } + } + val bodyExpressions = getBodyExpressions() + if (delegationCall == null && bodyExpressions.isEmpty()) return@lz null + KotlinLazyUBlockExpression(this) { uastParent -> + SmartList().apply { + delegationCall?.let { + add(KotlinUFunctionCallExpression(it, uastParent)) + } + bodyExpressions.forEach { + add(KotlinConverter.convertOrEmpty(it, uastParent)) + } + } + } + } + + override val uastAnchor: KotlinUIdentifier by lz { + KotlinUIdentifier( + psi.nameIdentifier, + if (isPrimary) ktClass?.nameIdentifier else (sourcePsi as? KtSecondaryConstructor)?.getConstructorKeyword(), + this + ) + } + + override val javaPsi = psi + + protected open fun getBodyExpressions(): List { + if (isPrimary) return getInitializers() + val bodyExpression = (sourcePsi as? KtFunction)?.bodyExpression ?: return emptyList() + if (bodyExpression is KtBlockExpression) return bodyExpression.statements + return listOf(bodyExpression) + } + + 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 = getInitializers() + super.getBodyExpressions() +} + open class KotlinUAnnotationMethod( psi: KtLightMethod, givenParent: UElement?