Don't suggest to move type to separate file for sealed classes
So #KT-23321 Fixed
This commit is contained in:
committed by
Mikhail Glukhikh
parent
02578bc378
commit
a8d0e8995d
+37
-23
@@ -24,6 +24,10 @@ import com.intellij.openapi.fileEditor.FileEditorManager
|
||||
import com.intellij.openapi.util.TextRange
|
||||
import com.intellij.refactoring.move.MoveCallback
|
||||
import com.intellij.refactoring.util.CommonRefactoringUtil
|
||||
import org.jetbrains.kotlin.descriptors.ClassDescriptor
|
||||
import org.jetbrains.kotlin.descriptors.Modality
|
||||
import org.jetbrains.kotlin.idea.caches.resolve.analyze
|
||||
import org.jetbrains.kotlin.idea.caches.resolve.resolveToDescriptorIfAny
|
||||
import org.jetbrains.kotlin.idea.intentions.SelfTargetingRangeIntention
|
||||
import org.jetbrains.kotlin.idea.core.moveCaret
|
||||
import org.jetbrains.kotlin.idea.refactoring.createKotlinFile
|
||||
@@ -35,16 +39,24 @@ import org.jetbrains.kotlin.psi.KtFile
|
||||
import org.jetbrains.kotlin.psi.KtObjectDeclaration
|
||||
import org.jetbrains.kotlin.psi.psiUtil.endOffset
|
||||
import org.jetbrains.kotlin.psi.psiUtil.startOffset
|
||||
import org.jetbrains.kotlin.resolve.BindingContext
|
||||
import org.jetbrains.kotlin.resolve.lazy.BodyResolveMode
|
||||
|
||||
class MoveDeclarationToSeparateFileIntention :
|
||||
SelfTargetingRangeIntention<KtClassOrObject>(KtClassOrObject::class.java, "Move declaration to separate file"),
|
||||
LowPriorityAction {
|
||||
SelfTargetingRangeIntention<KtClassOrObject>(KtClassOrObject::class.java, "Move declaration to separate file"),
|
||||
LowPriorityAction {
|
||||
override fun applicabilityRange(element: KtClassOrObject): TextRange? {
|
||||
if (element.name == null) return null
|
||||
if (element.parent !is KtFile) return null
|
||||
if (element.hasModifier(KtTokens.PRIVATE_KEYWORD)) return null
|
||||
if (element.containingKtFile.declarations.size == 1) return null
|
||||
|
||||
if (element.resolveToDescriptorIfAny()?.sealedSubclasses?.isNotEmpty() == true) return null
|
||||
if (element.superTypeListEntries.any {
|
||||
val superType = it.analyze(BodyResolveMode.PARTIAL)[BindingContext.TYPE, it.typeReference]
|
||||
(superType?.constructor?.declarationDescriptor as? ClassDescriptor)?.modality == Modality.SEALED
|
||||
}) return null
|
||||
|
||||
val keyword = when (element) {
|
||||
is KtClass -> element.getClassOrInterfaceKeyword()
|
||||
is KtObjectDeclaration -> element.getObjectKeyword()
|
||||
@@ -76,15 +88,17 @@ class MoveDeclarationToSeparateFileIntention :
|
||||
|
||||
// If automatic move is not possible, fall back to full-fledged Move Declarations refactoring
|
||||
ApplicationManager.getApplication().invokeLater {
|
||||
MoveKotlinTopLevelDeclarationsDialog(project,
|
||||
setOf(element),
|
||||
packageName.asString(),
|
||||
directory,
|
||||
targetFile as? KtFile,
|
||||
true,
|
||||
true,
|
||||
true,
|
||||
null).show()
|
||||
MoveKotlinTopLevelDeclarationsDialog(
|
||||
project,
|
||||
setOf(element),
|
||||
packageName.asString(),
|
||||
directory,
|
||||
targetFile as? KtFile,
|
||||
true,
|
||||
true,
|
||||
true,
|
||||
null
|
||||
).show()
|
||||
}
|
||||
return
|
||||
}
|
||||
@@ -92,18 +106,18 @@ class MoveDeclarationToSeparateFileIntention :
|
||||
createKotlinFile(targetFileName, directory, packageName.asString())
|
||||
}
|
||||
val descriptor = MoveDeclarationsDescriptor(
|
||||
project = project,
|
||||
elementsToMove = listOf(element),
|
||||
moveTarget = moveTarget,
|
||||
delegate = MoveDeclarationsDelegate.TopLevel,
|
||||
searchInCommentsAndStrings = false,
|
||||
searchInNonCode = false,
|
||||
moveCallback = MoveCallback {
|
||||
val newFile = directory.findFile(targetFileName) as KtFile
|
||||
val newDeclaration = newFile.declarations.first()
|
||||
NavigationUtil.activateFileWithPsiElement(newFile)
|
||||
FileEditorManager.getInstance(project).selectedTextEditor?.moveCaret(newDeclaration.startOffset + originalOffset)
|
||||
}
|
||||
project = project,
|
||||
elementsToMove = listOf(element),
|
||||
moveTarget = moveTarget,
|
||||
delegate = MoveDeclarationsDelegate.TopLevel,
|
||||
searchInCommentsAndStrings = false,
|
||||
searchInNonCode = false,
|
||||
moveCallback = MoveCallback {
|
||||
val newFile = directory.findFile(targetFileName) as KtFile
|
||||
val newDeclaration = newFile.declarations.first()
|
||||
NavigationUtil.activateFileWithPsiElement(newFile)
|
||||
FileEditorManager.getInstance(project).selectedTextEditor?.moveCaret(newDeclaration.startOffset + originalOffset)
|
||||
}
|
||||
)
|
||||
|
||||
MoveKotlinDeclarationsProcessor(descriptor).run()
|
||||
|
||||
@@ -0,0 +1 @@
|
||||
org.jetbrains.kotlin.idea.refactoring.move.moveDeclarations.MoveDeclarationToSeparateFileIntention
|
||||
@@ -0,0 +1,3 @@
|
||||
// IS_APPLICABLE: false
|
||||
sealed class A
|
||||
class B<caret> : A()
|
||||
@@ -0,0 +1,3 @@
|
||||
// IS_APPLICABLE: false
|
||||
sealed class A<caret>
|
||||
class B : A()
|
||||
@@ -11824,6 +11824,27 @@ public class IntentionTestGenerated extends AbstractIntentionTest {
|
||||
}
|
||||
}
|
||||
|
||||
@TestMetadata("idea/testData/intentions/moveDeclarationToSeparateFile")
|
||||
@TestDataPath("$PROJECT_ROOT")
|
||||
@RunWith(JUnit3RunnerWithInners.class)
|
||||
public static class MoveDeclarationToSeparateFile extends AbstractIntentionTest {
|
||||
public void testAllFilesPresentInMoveDeclarationToSeparateFile() throws Exception {
|
||||
KotlinTestUtils.assertAllTestsPresentByMetadata(this.getClass(), new File("idea/testData/intentions/moveDeclarationToSeparateFile"), Pattern.compile("^([\\w\\-_]+)\\.(kt|kts)$"), TargetBackend.ANY, true);
|
||||
}
|
||||
|
||||
@TestMetadata("extendSealed.kt")
|
||||
public void testExtendSealed() throws Exception {
|
||||
String fileName = KotlinTestUtils.navigationMetadata("idea/testData/intentions/moveDeclarationToSeparateFile/extendSealed.kt");
|
||||
doTest(fileName);
|
||||
}
|
||||
|
||||
@TestMetadata("sealed.kt")
|
||||
public void testSealed() throws Exception {
|
||||
String fileName = KotlinTestUtils.navigationMetadata("idea/testData/intentions/moveDeclarationToSeparateFile/sealed.kt");
|
||||
doTest(fileName);
|
||||
}
|
||||
}
|
||||
|
||||
@TestMetadata("idea/testData/intentions/moveLambdaInsideParentheses")
|
||||
@TestDataPath("$PROJECT_ROOT")
|
||||
@RunWith(JUnit3RunnerWithInners.class)
|
||||
|
||||
Reference in New Issue
Block a user