1
+ package org.jetbrains.kotlin.test.helper.intentions
2
+
3
+ import com.intellij.codeInsight.intention.PsiElementBaseIntentionAction
4
+ import com.intellij.codeInsight.intention.preview.IntentionPreviewInfo
5
+ import com.intellij.codeInspection.util.IntentionFamilyName
6
+ import com.intellij.codeInspection.util.IntentionName
7
+ import com.intellij.openapi.editor.Editor
8
+ import com.intellij.openapi.project.Project
9
+ import com.intellij.psi.PsiElement
10
+ import com.intellij.psi.PsiFile
11
+ import com.intellij.psi.util.parents
12
+ import org.jetbrains.kotlin.analysis.api.KaIdeApi
13
+ import org.jetbrains.kotlin.idea.base.analysis.api.utils.shortenReferences
14
+ import org.jetbrains.kotlin.psi.KtElement
15
+ import org.jetbrains.kotlin.psi.KtNamedFunction
16
+ import org.jetbrains.kotlin.psi.KtPsiFactory
17
+ import org.jetbrains.kotlin.psi.addRemoveModifier.setModifierList
18
+ import org.jetbrains.kotlin.utils.addToStdlib.firstIsInstanceOrNull
19
+
20
+ class CreateContextualOverloadIntention : PsiElementBaseIntentionAction () {
21
+ override fun isAvailable (project : Project , editor : Editor ? , element : PsiElement ): Boolean {
22
+ val function = element.findFunctionParent() ? : return false
23
+ return function.nameIdentifier == element
24
+ && function.valueParameters.singleOrNull()?.typeReference?.text == " FirSession"
25
+ && function.contextReceiverList == null
26
+ && function.hasBody()
27
+ }
28
+
29
+ @OptIn(KaIdeApi ::class )
30
+ override fun invoke (project : Project , editor : Editor ? , element : PsiElement ) {
31
+ val factory = KtPsiFactory (project)
32
+ val function = element.findFunctionParent() ? : return
33
+ val parameter = function.valueParameters.singleOrNull() ? : return
34
+ val functionName = function.name
35
+
36
+ val copy1 = function.parent.addAfter((function.copy() as KtNamedFunction ).apply {
37
+ equalsToken?.delete()
38
+ bodyExpression?.replace(
39
+ factory.createBlock(
40
+ " return $functionName ()"
41
+ )
42
+ )
43
+ valueParameters.first().run {
44
+ addAnnotationEntry(factory.createAnnotationEntry(""" @Suppress("unused")""" ))
45
+ setName(" s" )
46
+ }
47
+ setModifierList(factory.createModifierList(" context(sessionHolder: org.jetbrains.kotlin.fir.SessionHolder)\n " ))
48
+ addAnnotationEntry(factory.createAnnotationEntry(""" @Deprecated("Use parameterless overload", replaceWith = ReplaceWith("$functionName ()"))""" ))
49
+ }, function) as KtElement
50
+
51
+ val copy2 = function.parent.addAfter((function.copy() as KtNamedFunction ).apply {
52
+ equalsToken?.delete()
53
+ bodyExpression?.replace(
54
+ factory.createBlock(
55
+ " return $functionName (${parameter.nameAsName} = sessionHolder.session)"
56
+ )
57
+ )
58
+ valueParameters.first().delete()
59
+ setModifierList(factory.createModifierList(" context(sessionHolder: org.jetbrains.kotlin.fir.SessionHolder)\n " ))
60
+ }, function) as KtElement
61
+
62
+ shortenReferences(listOf (copy1, copy2))
63
+ }
64
+
65
+ private fun PsiElement.findFunctionParent (): KtNamedFunction ? {
66
+ return parents(withSelf = true ).firstIsInstanceOrNull<KtNamedFunction >()
67
+ }
68
+
69
+ override fun generatePreview (project : Project , editor : Editor , psiFile : PsiFile ): IntentionPreviewInfo {
70
+ return IntentionPreviewInfo .EMPTY
71
+ }
72
+
73
+ override fun startInWriteAction (): Boolean = true
74
+ override fun getText (): @IntentionName String = familyName
75
+ override fun getFamilyName (): @IntentionFamilyName String = " Add contextual overloads"
76
+ }
0 commit comments