diff --git a/plugins/uast-kotlin-base/src/org/jetbrains/uast/kotlin/declarations/BaseKotlinConstructorUMethod.kt b/plugins/uast-kotlin-base/src/org/jetbrains/uast/kotlin/declarations/BaseKotlinConstructorUMethod.kt new file mode 100644 index 00000000000..68a5bb25f15 --- /dev/null +++ b/plugins/uast-kotlin-base/src/org/jetbrains/uast/kotlin/declarations/BaseKotlinConstructorUMethod.kt @@ -0,0 +1,70 @@ +/* + * Copyright 2010-2021 JetBrains s.r.o. and Kotlin Programming Language contributors. + * Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file. + */ + +package org.jetbrains.uast.kotlin + +import com.intellij.psi.PsiMethod +import org.jetbrains.kotlin.psi.* +import org.jetbrains.kotlin.utils.SmartList +import org.jetbrains.kotlin.utils.addToStdlib.firstIsInstanceOrNull +import org.jetbrains.uast.UElement +import org.jetbrains.uast.UExpression +import org.jetbrains.uast.UIdentifier + +abstract class BaseKotlinConstructorUMethod( + private val ktClass: KtClassOrObject?, + override val psi: PsiMethod, + kotlinOrigin: KtDeclaration?, + givenParent: UElement? +) : BaseKotlinUMethod(psi, kotlinOrigin, givenParent) { + + override val javaPsi = psi + + val isPrimary: Boolean + get() = sourcePsi is KtPrimaryConstructor || sourcePsi 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(buildDelegationCall(it, uastParent)) + } + bodyExpressions.forEach { + add(baseResolveProviderService.baseKotlinConverter.convertOrEmpty(it, uastParent)) + } + } + } + } + + abstract fun buildDelegationCall(delegationCall: KtCallElement, uastParent: UElement): UExpression + + override val uastAnchor: UIdentifier? by lz { + KotlinUIdentifier( + javaPsi.nameIdentifier, + if (isPrimary) ktClass?.nameIdentifier else (sourcePsi as? KtSecondaryConstructor)?.getConstructorKeyword(), + this + ) + } + + 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(): List { + return ktClass?.getAnonymousInitializers()?.mapNotNull { it.body } ?: emptyList() + } +} diff --git a/plugins/uast-kotlin-base/src/org/jetbrains/uast/kotlin/declarations/BaseKotlinSecondaryConstructorWithInitializersUMethod.kt b/plugins/uast-kotlin-base/src/org/jetbrains/uast/kotlin/declarations/BaseKotlinSecondaryConstructorWithInitializersUMethod.kt new file mode 100644 index 00000000000..af36dd02b6f --- /dev/null +++ b/plugins/uast-kotlin-base/src/org/jetbrains/uast/kotlin/declarations/BaseKotlinSecondaryConstructorWithInitializersUMethod.kt @@ -0,0 +1,25 @@ +/* + * Copyright 2010-2021 JetBrains s.r.o. and Kotlin Programming Language contributors. + * Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file. + */ + +package org.jetbrains.uast.kotlin + +import org.jetbrains.kotlin.asJava.elements.KtLightMethod +import org.jetbrains.kotlin.psi.KtClassOrObject +import org.jetbrains.kotlin.psi.KtExpression +import org.jetbrains.uast.UElement + +// 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. +abstract class BaseKotlinSecondaryConstructorWithInitializersUMethod( + ktClass: KtClassOrObject?, + psi: KtLightMethod, + givenParent: UElement? +) : BaseKotlinConstructorUMethod(ktClass, psi, psi.kotlinOrigin, givenParent) { + + override fun getBodyExpressions(): List { + return getInitializers() + super.getBodyExpressions() + } +} diff --git a/plugins/uast-kotlin-fir/src/org/jetbrains/uast/kotlin/declarations/FirKotlinConstructorUMethod.kt b/plugins/uast-kotlin-fir/src/org/jetbrains/uast/kotlin/declarations/FirKotlinConstructorUMethod.kt new file mode 100644 index 00000000000..0da9808f54f --- /dev/null +++ b/plugins/uast-kotlin-fir/src/org/jetbrains/uast/kotlin/declarations/FirKotlinConstructorUMethod.kt @@ -0,0 +1,35 @@ +/* + * Copyright 2010-2021 JetBrains s.r.o. and Kotlin Programming Language contributors. + * Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file. + */ + +package org.jetbrains.uast.kotlin + +import com.intellij.psi.PsiMethod +import org.jetbrains.kotlin.asJava.elements.KtLightMethod +import org.jetbrains.kotlin.psi.KtCallElement +import org.jetbrains.kotlin.psi.KtClassOrObject +import org.jetbrains.kotlin.psi.KtDeclaration +import org.jetbrains.uast.UElement +import org.jetbrains.uast.UExpression +import org.jetbrains.uast.UParameter +import org.jetbrains.uast.UastEmptyExpression + +class FirKotlinConstructorUMethod( + ktClass: KtClassOrObject?, + psi: PsiMethod, + kotlinOrigin: KtDeclaration?, + givenParent: UElement? +) : BaseKotlinConstructorUMethod(ktClass, psi, kotlinOrigin, givenParent), FirKotlinUMethodParametersProducer { + constructor( + ktClass: KtClassOrObject?, + psi: KtLightMethod, + givenParent: UElement? + ) : this(ktClass, psi, psi.kotlinOrigin, givenParent) + + override val uastParameters: List by lz { produceUastParameters(this, receiverTypeReference) } + + override fun buildDelegationCall(delegationCall: KtCallElement, uastParent: UElement): UExpression { + return UastEmptyExpression(uastParent) + } +} diff --git a/plugins/uast-kotlin-fir/src/org/jetbrains/uast/kotlin/declarations/FirKotlinSecondaryConstructorWithInitializersUMethod.kt b/plugins/uast-kotlin-fir/src/org/jetbrains/uast/kotlin/declarations/FirKotlinSecondaryConstructorWithInitializersUMethod.kt new file mode 100644 index 00000000000..60b088d8bf4 --- /dev/null +++ b/plugins/uast-kotlin-fir/src/org/jetbrains/uast/kotlin/declarations/FirKotlinSecondaryConstructorWithInitializersUMethod.kt @@ -0,0 +1,26 @@ +/* + * Copyright 2010-2021 JetBrains s.r.o. and Kotlin Programming Language contributors. + * Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file. + */ + +package org.jetbrains.uast.kotlin + +import org.jetbrains.kotlin.asJava.elements.KtLightMethod +import org.jetbrains.kotlin.psi.KtCallElement +import org.jetbrains.kotlin.psi.KtClassOrObject +import org.jetbrains.uast.UElement +import org.jetbrains.uast.UExpression +import org.jetbrains.uast.UParameter +import org.jetbrains.uast.UastEmptyExpression + +class FirKotlinSecondaryConstructorWithInitializersUMethod( + ktClass: KtClassOrObject?, + psi: KtLightMethod, + givenParent: UElement? +) : BaseKotlinSecondaryConstructorWithInitializersUMethod(ktClass, psi, givenParent), FirKotlinUMethodParametersProducer { + override val uastParameters: List by lz { produceUastParameters(this, receiverTypeReference) } + + override fun buildDelegationCall(delegationCall: KtCallElement, uastParent: UElement): UExpression { + return UastEmptyExpression(uastParent) + } +} diff --git a/plugins/uast-kotlin-fir/src/org/jetbrains/uast/kotlin/declarations/FirKotlinUMethod.kt b/plugins/uast-kotlin-fir/src/org/jetbrains/uast/kotlin/declarations/FirKotlinUMethod.kt index a1625ac709d..24f30462959 100644 --- a/plugins/uast-kotlin-fir/src/org/jetbrains/uast/kotlin/declarations/FirKotlinUMethod.kt +++ b/plugins/uast-kotlin-fir/src/org/jetbrains/uast/kotlin/declarations/FirKotlinUMethod.kt @@ -10,35 +10,25 @@ import org.jetbrains.kotlin.asJava.LightClassUtil import org.jetbrains.kotlin.asJava.elements.* import org.jetbrains.kotlin.psi.* import org.jetbrains.kotlin.psi.psiUtil.containingClassOrObject -import org.jetbrains.kotlin.utils.SmartList -import org.jetbrains.kotlin.utils.addToStdlib.firstIsInstanceOrNull import org.jetbrains.uast.* -open class FirKotlinUMethod( +class FirKotlinUMethod( psi: PsiMethod, sourcePsi: KtDeclaration?, givenParent: UElement? -) : BaseKotlinUMethod(psi, sourcePsi, givenParent) { +) : BaseKotlinUMethod(psi, sourcePsi, givenParent), FirKotlinUMethodParametersProducer { constructor( psi: KtLightMethod, givenParent: UElement? ) : this(psi, getKotlinMemberOrigin(psi), givenParent) - override val uastParameters: List by lz { - val lightParams = psi.parameterList.parameters - val receiverTypeReference = - receiverTypeReference ?: return@lz lightParams.map { FirKotlinUParameter(it, getKotlinMemberOrigin(it), this) } - val lightReceiver = lightParams.firstOrNull() ?: return@lz emptyList() - val uParameters = SmartList(FirKotlinReceiverUParameter(lightReceiver, receiverTypeReference, this)) - lightParams.drop(1).mapTo(uParameters) { FirKotlinUParameter(it, getKotlinMemberOrigin(it), this) } - uParameters - } + override val uastParameters: List by lz { produceUastParameters(this, receiverTypeReference) } companion object { fun create( psi: KtLightMethod, givenParent: UElement? - ): FirKotlinUMethod { + ): UMethod { return when (psi) { is KtConstructor<*> -> FirKotlinConstructorUMethod(psi.containingClassOrObject, psi, givenParent) @@ -51,7 +41,7 @@ open class FirKotlinUMethod( fun create( sourcePsi: KtDeclaration?, givenParent: UElement? - ): FirKotlinUMethod? { + ): UMethod? { val javaPsi = when (sourcePsi) { is KtPropertyAccessor -> LightClassUtil.getLightClassAccessorMethod(sourcePsi) @@ -69,76 +59,3 @@ open class FirKotlinUMethod( } } } - -// TODO: can be commonized if *KotlinUMethod is commonized -open class FirKotlinConstructorUMethod( - private val ktClass: KtClassOrObject?, - override val psi: PsiMethod, - kotlinOrigin: KtDeclaration?, - givenParent: UElement? -) : FirKotlinUMethod(psi, kotlinOrigin, givenParent) { - constructor( - ktClass: KtClassOrObject?, - psi: KtLightMethod, - givenParent: UElement? - ) : this(ktClass, psi, psi.kotlinOrigin, givenParent) - - override val javaPsi = psi - - val isPrimary: Boolean - get() = sourcePsi is KtPrimaryConstructor || sourcePsi 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 { - // TODO: function call for delegationCall - add(UastEmptyExpression(uastParent)) - } - bodyExpressions.forEach { - add(baseResolveProviderService.baseKotlinConverter.convertOrEmpty(it, uastParent)) - } - } - } - } - - override val uastAnchor: UIdentifier? by lz { - KotlinUIdentifier( - javaPsi.nameIdentifier, - if (isPrimary) ktClass?.nameIdentifier else (sourcePsi as? KtSecondaryConstructor)?.getConstructorKeyword(), - this - ) - } - - 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(): List { - return ktClass?.getAnonymousInitializers()?.mapNotNull { it.body } ?: emptyList() - } -} - -// TODO: can be commonized if *KotlinUMethod is commonized -// also reuse the comments there (about KT-21617) -class FirKotlinSecondaryConstructorWithInitializersUMethod( - ktClass: KtClassOrObject?, - psi: KtLightMethod, - givenParent: UElement? -) : FirKotlinConstructorUMethod(ktClass, psi, givenParent) { - override fun getBodyExpressions(): List { - return getInitializers() + super.getBodyExpressions() - } -} diff --git a/plugins/uast-kotlin-fir/src/org/jetbrains/uast/kotlin/declarations/FirKotlinUMethodParametersProducer.kt b/plugins/uast-kotlin-fir/src/org/jetbrains/uast/kotlin/declarations/FirKotlinUMethodParametersProducer.kt new file mode 100644 index 00000000000..2073efd1685 --- /dev/null +++ b/plugins/uast-kotlin-fir/src/org/jetbrains/uast/kotlin/declarations/FirKotlinUMethodParametersProducer.kt @@ -0,0 +1,21 @@ +/* + * Copyright 2010-2021 JetBrains s.r.o. and Kotlin Programming Language contributors. + * Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file. + */ + +package org.jetbrains.uast.kotlin + +import org.jetbrains.kotlin.psi.KtTypeReference +import org.jetbrains.kotlin.utils.SmartList +import org.jetbrains.uast.UParameter + +internal interface FirKotlinUMethodParametersProducer { + fun produceUastParameters(uMethod: BaseKotlinUMethod, receiverTypeReference: KtTypeReference?): List { + val lightParams = uMethod.psi.parameterList.parameters + val receiver = receiverTypeReference ?: return lightParams.map { FirKotlinUParameter(it, getKotlinMemberOrigin(it), uMethod) } + val lightReceiver = lightParams.firstOrNull() ?: return emptyList() + val uParameters = SmartList(FirKotlinReceiverUParameter(lightReceiver, receiver, uMethod)) + lightParams.drop(1).mapTo(uParameters) { FirKotlinUParameter(it, getKotlinMemberOrigin(it), uMethod) } + return uParameters + } +} diff --git a/plugins/uast-kotlin/src/org/jetbrains/uast/kotlin/declarations/KotlinConstructorUMethod.kt b/plugins/uast-kotlin/src/org/jetbrains/uast/kotlin/declarations/KotlinConstructorUMethod.kt new file mode 100644 index 00000000000..481863c9e55 --- /dev/null +++ b/plugins/uast-kotlin/src/org/jetbrains/uast/kotlin/declarations/KotlinConstructorUMethod.kt @@ -0,0 +1,33 @@ +/* + * Copyright 2010-2021 JetBrains s.r.o. and Kotlin Programming Language contributors. + * Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file. + */ + +package org.jetbrains.uast.kotlin + +import com.intellij.psi.PsiMethod +import org.jetbrains.kotlin.asJava.elements.KtLightMethod +import org.jetbrains.kotlin.psi.KtCallElement +import org.jetbrains.kotlin.psi.KtClassOrObject +import org.jetbrains.kotlin.psi.KtDeclaration +import org.jetbrains.uast.UElement +import org.jetbrains.uast.UExpression + +class KotlinConstructorUMethod( + ktClass: KtClassOrObject?, + psi: PsiMethod, + kotlinOrigin: KtDeclaration?, + givenParent: UElement? +) : BaseKotlinConstructorUMethod(ktClass, psi, kotlinOrigin, givenParent), KotlinUMethodParametersProducer { + constructor( + ktClass: KtClassOrObject?, + psi: KtLightMethod, + givenParent: UElement? + ) : this(ktClass, psi, psi.kotlinOrigin, givenParent) + + override val uastParameters by lz { produceUastParameters(this, receiverTypeReference) } + + override fun buildDelegationCall(delegationCall: KtCallElement, uastParent: UElement): UExpression { + return KotlinUFunctionCallExpression(delegationCall, uastParent) + } +} diff --git a/plugins/uast-kotlin/src/org/jetbrains/uast/kotlin/declarations/KotlinSecondaryConstructorWithInitializersUMethod.kt b/plugins/uast-kotlin/src/org/jetbrains/uast/kotlin/declarations/KotlinSecondaryConstructorWithInitializersUMethod.kt new file mode 100644 index 00000000000..7d07bf5931b --- /dev/null +++ b/plugins/uast-kotlin/src/org/jetbrains/uast/kotlin/declarations/KotlinSecondaryConstructorWithInitializersUMethod.kt @@ -0,0 +1,25 @@ +/* + * Copyright 2010-2021 JetBrains s.r.o. and Kotlin Programming Language contributors. + * Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file. + */ + +package org.jetbrains.uast.kotlin + +import org.jetbrains.kotlin.asJava.elements.KtLightMethod +import org.jetbrains.kotlin.psi.KtCallElement +import org.jetbrains.kotlin.psi.KtClassOrObject +import org.jetbrains.uast.UElement +import org.jetbrains.uast.UExpression + +class KotlinSecondaryConstructorWithInitializersUMethod( + ktClass: KtClassOrObject?, + psi: KtLightMethod, + givenParent: UElement? +) : BaseKotlinSecondaryConstructorWithInitializersUMethod(ktClass, psi, givenParent), KotlinUMethodParametersProducer { + + override val uastParameters by lz { produceUastParameters(this, receiverTypeReference) } + + override fun buildDelegationCall(delegationCall: KtCallElement, uastParent: UElement): UExpression { + return KotlinUFunctionCallExpression(delegationCall, uastParent) + } +} 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 4885fd47171..61b6abe8256 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 @@ -21,41 +21,24 @@ import org.jetbrains.kotlin.asJava.elements.* 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.kotlin.* import org.jetbrains.uast.kotlin.psi.UastFakeLightMethod -import org.jetbrains.uast.kotlin.psi.UastKotlinPsiParameter open class KotlinUMethod( psi: PsiMethod, sourcePsi: KtDeclaration?, givenParent: UElement? -) : BaseKotlinUMethod(psi, sourcePsi, givenParent) { +) : BaseKotlinUMethod(psi, sourcePsi, givenParent), KotlinUMethodParametersProducer { constructor( psi: KtLightMethod, givenParent: UElement? ) : this(psi, getKotlinMemberOrigin(psi), givenParent) - override val uastParameters by lz { - - fun parameterOrigin(psiParameter: PsiParameter?): KtElement? = when (psiParameter) { - is KtLightElement<*, *> -> psiParameter.kotlinOrigin - is UastKotlinPsiParameter -> psiParameter.ktParameter - else -> null - } - - val lightParams = psi.parameterList.parameters - val receiver = receiverTypeReference ?: return@lz lightParams.map { KotlinUParameter(it, parameterOrigin(it), this) } - val receiverLight = lightParams.firstOrNull() ?: return@lz emptyList() - val uParameters = SmartList(KotlinReceiverUParameter(receiverLight, receiver, this)) - lightParams.drop(1).mapTo(uParameters) { KotlinUParameter(it, parameterOrigin(it), this) } - uParameters - } + override val uastParameters by lz { produceUastParameters(this, receiverTypeReference) } companion object { - fun create(psi: KtLightMethod, containingElement: UElement?): KotlinUMethod { + fun create(psi: KtLightMethod, containingElement: UElement?): UMethod { val kotlinOrigin = psi.kotlinOrigin return if (kotlinOrigin is KtConstructor<*>) { KotlinConstructorUMethod( @@ -71,76 +54,6 @@ 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? diff --git a/plugins/uast-kotlin/src/org/jetbrains/uast/kotlin/declarations/KotlinUMethodParametersProducer.kt b/plugins/uast-kotlin/src/org/jetbrains/uast/kotlin/declarations/KotlinUMethodParametersProducer.kt new file mode 100644 index 00000000000..0f19fb21c98 --- /dev/null +++ b/plugins/uast-kotlin/src/org/jetbrains/uast/kotlin/declarations/KotlinUMethodParametersProducer.kt @@ -0,0 +1,32 @@ +/* + * Copyright 2010-2021 JetBrains s.r.o. and Kotlin Programming Language contributors. + * Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file. + */ + +package org.jetbrains.uast.kotlin + +import com.intellij.psi.PsiParameter +import org.jetbrains.kotlin.asJava.elements.KtLightElement +import org.jetbrains.kotlin.psi.KtElement +import org.jetbrains.kotlin.psi.KtTypeReference +import org.jetbrains.kotlin.utils.SmartList +import org.jetbrains.uast.UParameter +import org.jetbrains.uast.kotlin.psi.UastKotlinPsiParameter + +internal interface KotlinUMethodParametersProducer { + fun produceUastParameters(uMethod: BaseKotlinUMethod, receiverTypeReference: KtTypeReference?): List { + + fun parameterOrigin(psiParameter: PsiParameter?): KtElement? = when (psiParameter) { + is KtLightElement<*, *> -> psiParameter.kotlinOrigin + is UastKotlinPsiParameter -> psiParameter.ktParameter + else -> null + } + + val lightParams = uMethod.psi.parameterList.parameters + val receiver = receiverTypeReference ?: return lightParams.map { KotlinUParameter(it, parameterOrigin(it), uMethod) } + val receiverLight = lightParams.firstOrNull() ?: return emptyList() + val uParameters = SmartList(KotlinReceiverUParameter(receiverLight, receiver, uMethod)) + lightParams.drop(1).mapTo(uParameters) { KotlinUParameter(it, parameterOrigin(it), uMethod) } + return uParameters + } +}