UAST: place method declarations together
This commit is contained in:
committed by
Ilya Kirillov
parent
beddf03f74
commit
0c011f4e73
@@ -22,8 +22,6 @@ import org.jetbrains.kotlin.psi.psiUtil.getParentOfType
|
|||||||
import org.jetbrains.kotlin.utils.addToStdlib.safeAs
|
import org.jetbrains.kotlin.utils.addToStdlib.safeAs
|
||||||
import org.jetbrains.uast.*
|
import org.jetbrains.uast.*
|
||||||
import org.jetbrains.uast.expressions.UInjectionHost
|
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.expressions.*
|
||||||
import org.jetbrains.uast.kotlin.psi.*
|
import org.jetbrains.uast.kotlin.psi.*
|
||||||
|
|
||||||
|
|||||||
@@ -22,7 +22,6 @@ import org.jetbrains.kotlin.types.ErrorUtils
|
|||||||
import org.jetbrains.kotlin.utils.addToStdlib.firstIsInstanceOrNull
|
import org.jetbrains.kotlin.utils.addToStdlib.firstIsInstanceOrNull
|
||||||
import org.jetbrains.kotlin.utils.addToStdlib.safeAs
|
import org.jetbrains.kotlin.utils.addToStdlib.safeAs
|
||||||
import org.jetbrains.uast.*
|
import org.jetbrains.uast.*
|
||||||
import org.jetbrains.uast.kotlin.declarations.KotlinUMethod
|
|
||||||
import org.jetbrains.uast.kotlin.internal.multiResolveResults
|
import org.jetbrains.uast.kotlin.internal.multiResolveResults
|
||||||
|
|
||||||
abstract class KotlinUAnnotationBase<T : KtCallElement>(
|
abstract class KotlinUAnnotationBase<T : KtCallElement>(
|
||||||
|
|||||||
@@ -24,12 +24,9 @@ import org.jetbrains.kotlin.asJava.classes.KtLightClassForScript
|
|||||||
import org.jetbrains.kotlin.asJava.elements.KtLightMethod
|
import org.jetbrains.kotlin.asJava.elements.KtLightMethod
|
||||||
import org.jetbrains.kotlin.load.java.JvmAbi
|
import org.jetbrains.kotlin.load.java.JvmAbi
|
||||||
import org.jetbrains.kotlin.psi.*
|
import org.jetbrains.kotlin.psi.*
|
||||||
import org.jetbrains.kotlin.utils.SmartList
|
|
||||||
import org.jetbrains.kotlin.utils.addIfNotNull
|
import org.jetbrains.kotlin.utils.addIfNotNull
|
||||||
import org.jetbrains.kotlin.utils.addToStdlib.firstIsInstanceOrNull
|
|
||||||
import org.jetbrains.uast.*
|
import org.jetbrains.uast.*
|
||||||
import org.jetbrains.uast.internal.acceptList
|
import org.jetbrains.uast.internal.acceptList
|
||||||
import org.jetbrains.uast.kotlin.declarations.KotlinUMethod
|
|
||||||
import org.jetbrains.uast.visitor.UastVisitor
|
import org.jetbrains.uast.visitor.UastVisitor
|
||||||
|
|
||||||
abstract class AbstractKotlinUClass(givenParent: UElement?) : KotlinAbstractUElement(givenParent), UClassTypeSpecific, UAnchorOwner {
|
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<KtSuperTypeCallEntry>()
|
|
||||||
it is KtSecondaryConstructor -> it.getDelegationCall()
|
|
||||||
else -> null
|
|
||||||
}
|
|
||||||
}
|
|
||||||
val bodyExpressions = getBodyExpressions()
|
|
||||||
if (delegationCall == null && bodyExpressions.isEmpty()) return@lz null
|
|
||||||
KotlinLazyUBlockExpression(this) { uastParent ->
|
|
||||||
SmartList<UExpression>().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<KtExpression> {
|
|
||||||
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<KtExpression> = getInitializers() + super.getBodyExpressions()
|
|
||||||
}
|
|
||||||
|
|
||||||
class KotlinUAnonymousClass(
|
class KotlinUAnonymousClass(
|
||||||
psi: PsiAnonymousClass,
|
psi: PsiAnonymousClass,
|
||||||
givenParent: UElement?
|
givenParent: UElement?
|
||||||
|
|||||||
@@ -14,7 +14,7 @@
|
|||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
package org.jetbrains.uast.kotlin.declarations
|
package org.jetbrains.uast.kotlin
|
||||||
|
|
||||||
import com.intellij.psi.*
|
import com.intellij.psi.*
|
||||||
import org.jetbrains.kotlin.asJava.elements.*
|
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.containingClassOrObject
|
||||||
import org.jetbrains.kotlin.psi.psiUtil.getParentOfType
|
import org.jetbrains.kotlin.psi.psiUtil.getParentOfType
|
||||||
import org.jetbrains.kotlin.utils.SmartList
|
import org.jetbrains.kotlin.utils.SmartList
|
||||||
|
import org.jetbrains.kotlin.utils.addToStdlib.firstIsInstanceOrNull
|
||||||
import org.jetbrains.uast.*
|
import org.jetbrains.uast.*
|
||||||
import org.jetbrains.uast.java.internal.JavaUElementWithComments
|
import org.jetbrains.uast.java.internal.JavaUElementWithComments
|
||||||
import org.jetbrains.uast.kotlin.*
|
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<KtSuperTypeCallEntry>()
|
||||||
|
it is KtSecondaryConstructor -> it.getDelegationCall()
|
||||||
|
else -> null
|
||||||
|
}
|
||||||
|
}
|
||||||
|
val bodyExpressions = getBodyExpressions()
|
||||||
|
if (delegationCall == null && bodyExpressions.isEmpty()) return@lz null
|
||||||
|
KotlinLazyUBlockExpression(this) { uastParent ->
|
||||||
|
SmartList<UExpression>().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<KtExpression> {
|
||||||
|
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<KtExpression> = getInitializers() + super.getBodyExpressions()
|
||||||
|
}
|
||||||
|
|
||||||
open class KotlinUAnnotationMethod(
|
open class KotlinUAnnotationMethod(
|
||||||
psi: KtLightMethod,
|
psi: KtLightMethod,
|
||||||
givenParent: UElement?
|
givenParent: UElement?
|
||||||
|
|||||||
Reference in New Issue
Block a user