diff --git a/idea/src/org/jetbrains/kotlin/idea/refactoring/introduce/extractionEngine/ExtractableCodeDescriptor.kt b/idea/src/org/jetbrains/kotlin/idea/refactoring/introduce/extractionEngine/ExtractableCodeDescriptor.kt index c469421ce64..1678e0f46a0 100644 --- a/idea/src/org/jetbrains/kotlin/idea/refactoring/introduce/extractionEngine/ExtractableCodeDescriptor.kt +++ b/idea/src/org/jetbrains/kotlin/idea/refactoring/introduce/extractionEngine/ExtractableCodeDescriptor.kt @@ -16,33 +16,30 @@ package org.jetbrains.kotlin.idea.refactoring.introduce.extractionEngine -import org.jetbrains.kotlin.types.JetType import org.jetbrains.kotlin.builtins.KotlinBuiltIns import com.intellij.util.containers.MultiMap import com.intellij.psi.PsiElement import org.jetbrains.kotlin.idea.references.JetSimpleNameReference import org.jetbrains.kotlin.name.FqName import org.jetbrains.kotlin.idea.references.JetSimpleNameReference.ShorteningMode -import org.jetbrains.kotlin.psi.psiUtil.replaced import org.jetbrains.kotlin.idea.refactoring.introduce.extractionEngine.AnalysisResult.Status import org.jetbrains.kotlin.idea.refactoring.JetRefactoringBundle import org.jetbrains.kotlin.idea.refactoring.introduce.extractionEngine.AnalysisResult.ErrorMessage import org.jetbrains.kotlin.descriptors.DeclarationDescriptor import com.intellij.openapi.util.text.StringUtil -import org.jetbrains.kotlin.types.CommonSupertypes import org.jetbrains.kotlin.resolve.DescriptorUtils import org.jetbrains.kotlin.idea.refactoring.introduce.extractionEngine.OutputValue.* import org.jetbrains.kotlin.descriptors.ModuleDescriptor -import org.jetbrains.kotlin.types.TypeUtils import kotlin.properties.Delegates import com.intellij.util.containers.ContainerUtil -import org.jetbrains.kotlin.psi.psiUtil.getQualifiedElementSelector import org.jetbrains.kotlin.idea.util.psi.patternMatching.JetPsiRange import org.jetbrains.kotlin.resolve.BindingContext import org.jetbrains.kotlin.idea.util.isUnit import org.jetbrains.kotlin.resolve.descriptorUtil.resolveTopLevelClass import org.jetbrains.kotlin.psi.* import java.util.* +import org.jetbrains.kotlin.types.* +import org.jetbrains.kotlin.psi.psiUtil.* trait Parameter { val argumentText: String @@ -310,7 +307,10 @@ enum class ExtractionTarget(val name: String) { PROPERTY_WITH_INITIALIZER : ExtractionTarget("property with initializer") { override fun isAvailable(descriptor: ExtractableCodeDescriptor): Boolean { - return checkSignatureAndParent(descriptor) && checkSimpleControlFlow(descriptor) && checkSimpleBody(descriptor) + return checkSignatureAndParent(descriptor) + && checkSimpleControlFlow(descriptor) + && checkSimpleBody(descriptor) + && checkNotTrait(descriptor) } } @@ -322,13 +322,20 @@ enum class ExtractionTarget(val name: String) { LAZY_PROPERTY : ExtractionTarget("lazy property") { override fun isAvailable(descriptor: ExtractableCodeDescriptor): Boolean { - return checkSignatureAndParent(descriptor) && checkSimpleControlFlow(descriptor) + return checkSignatureAndParent(descriptor) + && checkSimpleControlFlow(descriptor) + && checkNotTrait(descriptor) } } abstract fun isAvailable(descriptor: ExtractableCodeDescriptor): Boolean class object { + fun checkNotTrait(descriptor: ExtractableCodeDescriptor): Boolean { + val parent = descriptor.extractionData.targetSibling.getStrictParentOfType() + return !(parent is JetClass && parent.isTrait()) + } + fun checkSimpleBody(descriptor: ExtractableCodeDescriptor): Boolean { val expression = descriptor.extractionData.getExpressions().singleOrNull() return expression != null && expression !is JetDeclaration && expression !is JetBlockExpression diff --git a/idea/testData/refactoring/introduceProperty/extractLazyToTrait.kt b/idea/testData/refactoring/introduceProperty/extractLazyToTrait.kt new file mode 100644 index 00000000000..d9d3464f4ef --- /dev/null +++ b/idea/testData/refactoring/introduceProperty/extractLazyToTrait.kt @@ -0,0 +1,6 @@ +// EXTRACTION_TARGET: lazy property + +trait T { + fun foo(): Int = 1 +} + diff --git a/idea/testData/refactoring/introduceProperty/extractLazyToTrait.kt.conflicts b/idea/testData/refactoring/introduceProperty/extractLazyToTrait.kt.conflicts new file mode 100644 index 00000000000..775727b201f --- /dev/null +++ b/idea/testData/refactoring/introduceProperty/extractLazyToTrait.kt.conflicts @@ -0,0 +1 @@ +Can't generate lazy property: 1 \ No newline at end of file diff --git a/idea/testData/refactoring/introduceProperty/extractWithGetterToTrait.kt b/idea/testData/refactoring/introduceProperty/extractWithGetterToTrait.kt new file mode 100644 index 00000000000..6cdb56977ec --- /dev/null +++ b/idea/testData/refactoring/introduceProperty/extractWithGetterToTrait.kt @@ -0,0 +1,7 @@ +// EXTRACTION_TARGET: property with getter +trait T { + fun foo(): Int { + return 1 + } +} + diff --git a/idea/testData/refactoring/introduceProperty/extractWithGetterToTrait.kt.after b/idea/testData/refactoring/introduceProperty/extractWithGetterToTrait.kt.after new file mode 100644 index 00000000000..d03952a6543 --- /dev/null +++ b/idea/testData/refactoring/introduceProperty/extractWithGetterToTrait.kt.after @@ -0,0 +1,12 @@ +// EXTRACTION_TARGET: property with getter +trait T { + private val i: Int + get() { + return 1 + } + + fun foo(): Int { + return i + } +} + diff --git a/idea/testData/refactoring/introduceProperty/extractWithInitializerToTrait.kt b/idea/testData/refactoring/introduceProperty/extractWithInitializerToTrait.kt new file mode 100644 index 00000000000..c8f9403011d --- /dev/null +++ b/idea/testData/refactoring/introduceProperty/extractWithInitializerToTrait.kt @@ -0,0 +1,6 @@ +// EXTRACTION_TARGET: property with initializer + +trait T { + fun foo(): Int = 1 +} + diff --git a/idea/testData/refactoring/introduceProperty/extractWithInitializerToTrait.kt.conflicts b/idea/testData/refactoring/introduceProperty/extractWithInitializerToTrait.kt.conflicts new file mode 100644 index 00000000000..9e38823cedc --- /dev/null +++ b/idea/testData/refactoring/introduceProperty/extractWithInitializerToTrait.kt.conflicts @@ -0,0 +1 @@ +Can't generate property with initializer: 1 \ No newline at end of file diff --git a/idea/tests/org/jetbrains/kotlin/idea/refactoring/introduce/JetExtractionTestGenerated.java b/idea/tests/org/jetbrains/kotlin/idea/refactoring/introduce/JetExtractionTestGenerated.java index e366e0f9643..fdb9e5ee677 100644 --- a/idea/tests/org/jetbrains/kotlin/idea/refactoring/introduce/JetExtractionTestGenerated.java +++ b/idea/tests/org/jetbrains/kotlin/idea/refactoring/introduce/JetExtractionTestGenerated.java @@ -1947,6 +1947,12 @@ public class JetExtractionTestGenerated extends AbstractJetExtractionTest { doIntroducePropertyTest(fileName); } + @TestMetadata("extractLazyToTrait.kt") + public void testExtractLazyToTrait() throws Exception { + String fileName = JetTestUtils.navigationMetadata("idea/testData/refactoring/introduceProperty/extractLazyToTrait.kt"); + doIntroducePropertyTest(fileName); + } + @TestMetadata("extractLazyWithBlock.kt") public void testExtractLazyWithBlock() throws Exception { String fileName = JetTestUtils.navigationMetadata("idea/testData/refactoring/introduceProperty/extractLazyWithBlock.kt"); @@ -2007,6 +2013,12 @@ public class JetExtractionTestGenerated extends AbstractJetExtractionTest { doIntroducePropertyTest(fileName); } + @TestMetadata("extractWithGetterToTrait.kt") + public void testExtractWithGetterToTrait() throws Exception { + String fileName = JetTestUtils.navigationMetadata("idea/testData/refactoring/introduceProperty/extractWithGetterToTrait.kt"); + doIntroducePropertyTest(fileName); + } + @TestMetadata("extractWithInitializerAndBlock.kt") public void testExtractWithInitializerAndBlock() throws Exception { String fileName = JetTestUtils.navigationMetadata("idea/testData/refactoring/introduceProperty/extractWithInitializerAndBlock.kt"); @@ -2043,6 +2055,12 @@ public class JetExtractionTestGenerated extends AbstractJetExtractionTest { doIntroducePropertyTest(fileName); } + @TestMetadata("extractWithInitializerToTrait.kt") + public void testExtractWithInitializerToTrait() throws Exception { + String fileName = JetTestUtils.navigationMetadata("idea/testData/refactoring/introduceProperty/extractWithInitializerToTrait.kt"); + doIntroducePropertyTest(fileName); + } + @TestMetadata("extractWithParams.kt") public void testExtractWithParams() throws Exception { String fileName = JetTestUtils.navigationMetadata("idea/testData/refactoring/introduceProperty/extractWithParams.kt");