Suggest signature refactoring also for members of expect class

This commit is contained in:
Valentin Kipyatkov
2020-03-26 19:37:07 +02:00
parent a5dc2b5b2a
commit 1ffdc11d31
2 changed files with 57 additions and 1 deletions
@@ -4,6 +4,7 @@ import com.intellij.openapi.util.Key
import com.intellij.psi.PsiNamedElement
import com.intellij.psi.search.LocalSearchScope
import com.intellij.psi.search.searches.ReferencesSearch
import com.intellij.psi.util.parents
import com.intellij.refactoring.suggested.*
import com.intellij.refactoring.suggested.SuggestedRefactoringSupport.Parameter
import com.intellij.refactoring.suggested.SuggestedRefactoringSupport.Signature
@@ -14,9 +15,12 @@ import org.jetbrains.kotlin.idea.caches.resolve.resolveToDescriptorIfAny
import org.jetbrains.kotlin.idea.refactoring.isInterfaceClass
import org.jetbrains.kotlin.lexer.KtTokens
import org.jetbrains.kotlin.psi.KtCallableDeclaration
import org.jetbrains.kotlin.psi.KtClassOrObject
import org.jetbrains.kotlin.psi.KtDeclaration
import org.jetbrains.kotlin.psi.KtParameter
import org.jetbrains.kotlin.psi.psiUtil.containingClassOrObject
import org.jetbrains.kotlin.psi.psiUtil.hasBody
import org.jetbrains.kotlin.psi.psiUtil.parentsWithSelf
import org.jetbrains.kotlin.renderer.DescriptorRenderer
import org.jetbrains.kotlin.types.KotlinType
import org.jetbrains.kotlin.types.isError
@@ -211,11 +215,18 @@ class KotlinSuggestedRefactoringAvailability(refactoringSupport: SuggestedRefact
hasModifier(KtTokens.ABSTRACT_KEYWORD) -> IMPLEMENTATIONS
hasModifier(KtTokens.OPEN_KEYWORD) -> OVERRIDES
containingClassOrObject?.isInterfaceClass() == true -> if (hasBody()) OVERRIDES else IMPLEMENTATIONS
hasModifier(KtTokens.EXPECT_KEYWORD) -> "actual declarations"
isExpectDeclaration() -> "actual declarations"
else -> null
}
}
private fun KtCallableDeclaration.isExpectDeclaration(): Boolean {
return parentsWithSelf
.filterIsInstance<KtDeclaration>()
.takeWhile { it == this || it is KtClassOrObject }
.any { it.hasModifier(KtTokens.EXPECT_KEYWORD) }
}
override fun hasTypeChanges(oldSignature: Signature, newSignature: Signature): Boolean {
return super.hasTypeChanges(oldSignature, newSignature) || oldSignature.receiverType != newSignature.receiverType
}
@@ -530,6 +530,51 @@ class KotlinSuggestedRefactoringAvailabilityTest : BaseSuggestedRefactoringAvail
)
}
fun testExpectedFunction() {
ignoreErrors = true
doTest(
"""
expect fun foo()<caret>
""".trimIndent(),
{
myFixture.type(": Int")
},
expectedAvailability = Availability.Available(changeSignatureAvailableTooltip("foo", "actual declarations")),
)
}
fun testMemberInsideExpectedClass() {
ignoreErrors = true
doTest(
"""
expect class C {
fun foo()<caret>
}
""".trimIndent(),
{
myFixture.type(": Int")
},
expectedAvailability = Availability.Available(changeSignatureAvailableTooltip("foo", "actual declarations")),
)
}
fun testMemberDeepInsideExpectedClass() {
ignoreErrors = true
doTest(
"""
expect class C {
class Nested {
fun foo()<caret>
}
}
""".trimIndent(),
{
myFixture.type(": Int")
},
expectedAvailability = Availability.Available(changeSignatureAvailableTooltip("foo", "actual declarations")),
)
}
private fun addImport(fqName: String) {
(file as KtFile).importList!!.add(KtPsiFactory(project).createImportDirective(ImportPath.fromString(fqName)))
}