KTIJ-33579 [kotlin] Introduce separate ImportPositionType class

`ImportPositionTypeWithReceiver` is
too rigid for some cases, because
there might be no explicit receiver
expression in the code, but we still need
to differentiate between different types
of calls

GitOrigin-RevId: 8137cdfb1b19b39fdbe96d27c4544b3383294177
This commit is contained in:
Roman Golyshev
2025-04-12 14:32:17 +00:00
committed by intellij-monorepo-bot
parent 792f2eabba
commit 2c21e95098
3 changed files with 38 additions and 17 deletions
@@ -64,6 +64,6 @@ internal abstract class AbstractImportCandidatesProvider(): ImportCandidatesProv
private val KtClassLikeDeclaration.isInner: Boolean get() = hasModifier(KtTokens.INNER_KEYWORD)
private fun ImportPositionTypeAndReceiver<*>.acceptsInnerClasses(): Boolean =
private fun ImportPositionTypeAndReceiver<*, *>.acceptsInnerClasses(): Boolean =
this is ImportPositionTypeAndReceiver.TypeReference || this is ImportPositionTypeAndReceiver.KDocNameReference
}
@@ -5,5 +5,5 @@ import org.jetbrains.kotlin.psi.KtElement
internal class ImportContext(
val position: KtElement,
val positionTypeAndReceiver: ImportPositionTypeAndReceiver<*>,
val positionTypeAndReceiver: ImportPositionTypeAndReceiver<*, *>,
)
@@ -6,57 +6,78 @@ import org.jetbrains.kotlin.psi.*
import org.jetbrains.kotlin.psi.psiUtil.getReceiverExpression
import org.jetbrains.kotlin.psi.psiUtil.parents
/**
* N.B. This class is heavily copied from [org.jetbrains.kotlin.idea.util.CallType].
* It is currently used only in an auto-import subsystem, so it has a very narrow name.
*/
internal sealed interface ImportPositionType {
object Unknown : ImportPositionType
object DefaultCall : ImportPositionType
object DotCall : ImportPositionType
object SafeCall : ImportPositionType
object SuperMembers : ImportPositionType
object InfixCall : ImportPositionType
object OperatorCall : ImportPositionType
object CallableReference : ImportPositionType
object ImportDirective : ImportPositionType
object PackageDirective : ImportPositionType
object TypeReference : ImportPositionType
object Annotation : ImportPositionType
object KDocNameReference : ImportPositionType
}
/**
* N.B. This class is heavily copied from [org.jetbrains.kotlin.idea.util.CallTypeAndReceiver].
* It is currently used only in an auto-import subsystem, so it has a very narrow name.
*/
internal sealed class ImportPositionTypeAndReceiver<out TReceiver : KtElement?>(
internal sealed class ImportPositionTypeAndReceiver<out TPositionType : ImportPositionType, out TReceiver : KtElement?>(
val positionType: TPositionType,
val receiver: TReceiver,
) {
class Unknown() :
ImportPositionTypeAndReceiver<Nothing?>(null)
ImportPositionTypeAndReceiver<ImportPositionType.Unknown, Nothing?>(ImportPositionType.Unknown, null)
class DefaultCall() :
ImportPositionTypeAndReceiver<Nothing?>(null)
ImportPositionTypeAndReceiver<ImportPositionType.DefaultCall, Nothing?>(ImportPositionType.DefaultCall, null)
class DotCall(receiver: KtExpression) :
ImportPositionTypeAndReceiver<KtExpression>(receiver)
ImportPositionTypeAndReceiver<ImportPositionType.DotCall, KtExpression>(ImportPositionType.DotCall, receiver)
class SafeCall(receiver: KtExpression) :
ImportPositionTypeAndReceiver<KtExpression>(receiver)
ImportPositionTypeAndReceiver<ImportPositionType.SafeCall, KtExpression>(ImportPositionType.SafeCall, receiver)
class SuperMembers(receiver: KtSuperExpression) :
ImportPositionTypeAndReceiver<KtSuperExpression>(receiver)
ImportPositionTypeAndReceiver<ImportPositionType.SuperMembers, KtSuperExpression>(ImportPositionType.SuperMembers, receiver)
class InfixCall(receiver: KtExpression) :
ImportPositionTypeAndReceiver<KtExpression>(receiver)
ImportPositionTypeAndReceiver<ImportPositionType.InfixCall, KtExpression>(ImportPositionType.InfixCall, receiver)
class OperatorCall(receiver: KtExpression) :
ImportPositionTypeAndReceiver<KtExpression>(receiver)
ImportPositionTypeAndReceiver<ImportPositionType.OperatorCall, KtExpression>(ImportPositionType.OperatorCall, receiver)
class CallableReference(receiver: KtExpression?) :
ImportPositionTypeAndReceiver<KtExpression?>(receiver)
ImportPositionTypeAndReceiver<ImportPositionType.CallableReference, KtExpression?>(ImportPositionType.CallableReference, receiver)
class ImportDirective(receiver: KtExpression?) :
ImportPositionTypeAndReceiver<KtExpression?>(receiver)
ImportPositionTypeAndReceiver<ImportPositionType.ImportDirective, KtExpression?>(ImportPositionType.ImportDirective, receiver)
class PackageDirective(receiver: KtExpression?) :
ImportPositionTypeAndReceiver<KtExpression?>(receiver)
ImportPositionTypeAndReceiver<ImportPositionType.PackageDirective, KtExpression?>(ImportPositionType.PackageDirective, receiver)
class TypeReference(receiver: KtExpression?) :
ImportPositionTypeAndReceiver<KtExpression?>(receiver)
ImportPositionTypeAndReceiver<ImportPositionType.TypeReference, KtExpression?>(ImportPositionType.TypeReference, receiver)
class Annotation(receiver: KtExpression?) :
ImportPositionTypeAndReceiver<KtExpression?>(receiver)
ImportPositionTypeAndReceiver<ImportPositionType.Annotation, KtExpression?>(ImportPositionType.Annotation, receiver)
/**
* Important: this position is not detected by [detect] function.
*/
class KDocNameReference(receiver: KDocName?) :
ImportPositionTypeAndReceiver<KDocName?>(receiver)
ImportPositionTypeAndReceiver<ImportPositionType.KDocNameReference, KDocName?>(ImportPositionType.KDocNameReference, receiver)
companion object {
fun detect(expression: KtElement): ImportPositionTypeAndReceiver<*> {
fun detect(expression: KtElement): ImportPositionTypeAndReceiver<*, *> {
if (expression !is KtSimpleNameExpression) return Unknown()
val parent = expression.parent