From 1ffdc11d3101c1f98676ddcee3641cdda6697ff3 Mon Sep 17 00:00:00 2001 From: Valentin Kipyatkov Date: Thu, 26 Mar 2020 19:37:07 +0200 Subject: [PATCH] Suggest signature refactoring also for members of expect class --- ...linSuggestedRefactoringAvailability.kt.201 | 13 +++++- ...uggestedRefactoringAvailabilityTest.kt.201 | 45 +++++++++++++++++++ 2 files changed, 57 insertions(+), 1 deletion(-) diff --git a/idea/src/org/jetbrains/kotlin/idea/refactoring/suggested/KotlinSuggestedRefactoringAvailability.kt.201 b/idea/src/org/jetbrains/kotlin/idea/refactoring/suggested/KotlinSuggestedRefactoringAvailability.kt.201 index bd9bd7fa77e..288bb7f2f25 100644 --- a/idea/src/org/jetbrains/kotlin/idea/refactoring/suggested/KotlinSuggestedRefactoringAvailability.kt.201 +++ b/idea/src/org/jetbrains/kotlin/idea/refactoring/suggested/KotlinSuggestedRefactoringAvailability.kt.201 @@ -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() + .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 } diff --git a/idea/tests/org/jetbrains/kotlin/idea/refactoring/suggested/KotlinSuggestedRefactoringAvailabilityTest.kt.201 b/idea/tests/org/jetbrains/kotlin/idea/refactoring/suggested/KotlinSuggestedRefactoringAvailabilityTest.kt.201 index 7473e95b834..70d79859999 100644 --- a/idea/tests/org/jetbrains/kotlin/idea/refactoring/suggested/KotlinSuggestedRefactoringAvailabilityTest.kt.201 +++ b/idea/tests/org/jetbrains/kotlin/idea/refactoring/suggested/KotlinSuggestedRefactoringAvailabilityTest.kt.201 @@ -530,6 +530,51 @@ class KotlinSuggestedRefactoringAvailabilityTest : BaseSuggestedRefactoringAvail ) } + fun testExpectedFunction() { + ignoreErrors = true + doTest( + """ + expect fun foo() + """.trimIndent(), + { + myFixture.type(": Int") + }, + expectedAvailability = Availability.Available(changeSignatureAvailableTooltip("foo", "actual declarations")), + ) + } + + fun testMemberInsideExpectedClass() { + ignoreErrors = true + doTest( + """ + expect class C { + fun foo() + } + """.trimIndent(), + { + myFixture.type(": Int") + }, + expectedAvailability = Availability.Available(changeSignatureAvailableTooltip("foo", "actual declarations")), + ) + } + + fun testMemberDeepInsideExpectedClass() { + ignoreErrors = true + doTest( + """ + expect class C { + class Nested { + fun foo() + } + } + """.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))) }