Extract Superclass: Allow extraction to existing file
#KT-15351 Fixed
This commit is contained in:
@@ -677,8 +677,8 @@ fun main(args: Array<String>) {
|
||||
model("refactoring/introduceJavaParameter", extension = "java", testMethod = "doIntroduceJavaParameterTest")
|
||||
model("refactoring/introduceTypeParameter", pattern = KT_OR_KTS, testMethod = "doIntroduceTypeParameterTest")
|
||||
model("refactoring/introduceTypeAlias", pattern = KT_OR_KTS, testMethod = "doIntroduceTypeAliasTest")
|
||||
model("refactoring/extractSuperclass", pattern = KT_OR_KTS, testMethod = "doExtractSuperclassTest")
|
||||
model("refactoring/extractInterface", pattern = KT_OR_KTS, testMethod = "doExtractInterfaceTest")
|
||||
model("refactoring/extractSuperclass", pattern = KT_OR_KTS_WITHOUT_DOTS_IN_NAME, testMethod = "doExtractSuperclassTest")
|
||||
model("refactoring/extractInterface", pattern = KT_OR_KTS_WITHOUT_DOTS_IN_NAME, testMethod = "doExtractInterfaceTest")
|
||||
}
|
||||
|
||||
testClass<AbstractPullUpTest> {
|
||||
|
||||
@@ -675,8 +675,8 @@ fun main(args: Array<String>) {
|
||||
model("refactoring/introduceJavaParameter", extension = "java", testMethod = "doIntroduceJavaParameterTest")
|
||||
model("refactoring/introduceTypeParameter", pattern = KT_OR_KTS, testMethod = "doIntroduceTypeParameterTest")
|
||||
model("refactoring/introduceTypeAlias", pattern = KT_OR_KTS, testMethod = "doIntroduceTypeAliasTest")
|
||||
model("refactoring/extractSuperclass", pattern = KT_OR_KTS, testMethod = "doExtractSuperclassTest")
|
||||
model("refactoring/extractInterface", pattern = KT_OR_KTS, testMethod = "doExtractInterfaceTest")
|
||||
model("refactoring/extractSuperclass", pattern = KT_OR_KTS_WITHOUT_DOTS_IN_NAME, testMethod = "doExtractSuperclassTest")
|
||||
model("refactoring/extractInterface", pattern = KT_OR_KTS_WITHOUT_DOTS_IN_NAME, testMethod = "doExtractInterfaceTest")
|
||||
}
|
||||
|
||||
testClass<AbstractPullUpTest> {
|
||||
|
||||
@@ -673,8 +673,8 @@ fun main(args: Array<String>) {
|
||||
model("refactoring/introduceJavaParameter", extension = "java", testMethod = "doIntroduceJavaParameterTest")
|
||||
model("refactoring/introduceTypeParameter", pattern = KT_OR_KTS, testMethod = "doIntroduceTypeParameterTest")
|
||||
model("refactoring/introduceTypeAlias", pattern = KT_OR_KTS, testMethod = "doIntroduceTypeAliasTest")
|
||||
model("refactoring/extractSuperclass", pattern = KT_OR_KTS, testMethod = "doExtractSuperclassTest")
|
||||
model("refactoring/extractInterface", pattern = KT_OR_KTS, testMethod = "doExtractInterfaceTest")
|
||||
model("refactoring/extractSuperclass", pattern = KT_OR_KTS_WITHOUT_DOTS_IN_NAME, testMethod = "doExtractSuperclassTest")
|
||||
model("refactoring/extractInterface", pattern = KT_OR_KTS_WITHOUT_DOTS_IN_NAME, testMethod = "doExtractInterfaceTest")
|
||||
}
|
||||
|
||||
testClass<AbstractPullUpTest> {
|
||||
|
||||
@@ -673,8 +673,8 @@ fun main(args: Array<String>) {
|
||||
model("refactoring/introduceJavaParameter", extension = "java", testMethod = "doIntroduceJavaParameterTest")
|
||||
model("refactoring/introduceTypeParameter", pattern = KT_OR_KTS, testMethod = "doIntroduceTypeParameterTest")
|
||||
model("refactoring/introduceTypeAlias", pattern = KT_OR_KTS, testMethod = "doIntroduceTypeAliasTest")
|
||||
model("refactoring/extractSuperclass", pattern = KT_OR_KTS, testMethod = "doExtractSuperclassTest")
|
||||
model("refactoring/extractInterface", pattern = KT_OR_KTS, testMethod = "doExtractInterfaceTest")
|
||||
model("refactoring/extractSuperclass", pattern = KT_OR_KTS_WITHOUT_DOTS_IN_NAME, testMethod = "doExtractSuperclassTest")
|
||||
model("refactoring/extractInterface", pattern = KT_OR_KTS_WITHOUT_DOTS_IN_NAME, testMethod = "doExtractInterfaceTest")
|
||||
}
|
||||
|
||||
testClass<AbstractPullUpTest> {
|
||||
|
||||
+7
-5
@@ -226,7 +226,7 @@ class ExtractSuperRefactoring(
|
||||
.forEach { it.accept(visitor) }
|
||||
}
|
||||
|
||||
private fun createClass(superClassEntry: KtSuperTypeListEntry?): KtClass {
|
||||
private fun createClass(superClassEntry: KtSuperTypeListEntry?): KtClass? {
|
||||
val targetParent = extractInfo.targetParent
|
||||
val newClassName = extractInfo.newClassName.quoteIfNeeded()
|
||||
val originalClass = extractInfo.originalClass
|
||||
@@ -234,9 +234,11 @@ class ExtractSuperRefactoring(
|
||||
val kind = if (extractInfo.isInterface) "interface" else "class"
|
||||
val prototype = psiFactory.createClass("$kind $newClassName")
|
||||
val newClass = if (targetParent is PsiDirectory) {
|
||||
val template = FileTemplateManager.getInstance(project).getInternalTemplate("Kotlin File")
|
||||
val newFile = NewKotlinFileAction.createFileFromTemplate(extractInfo.targetFileName, template, targetParent) as KtFile
|
||||
newFile.add(prototype) as KtClass
|
||||
val file = targetParent.findFile(extractInfo.targetFileName) ?: run {
|
||||
val template = FileTemplateManager.getInstance(project).getInternalTemplate("Kotlin File")
|
||||
NewKotlinFileAction.createFileFromTemplate(extractInfo.targetFileName, template, targetParent) ?: return null
|
||||
}
|
||||
file.add(prototype) as KtClass
|
||||
}
|
||||
else {
|
||||
val targetSibling = originalClass.parentsWithSelf.first { it.parent == targetParent }
|
||||
@@ -312,7 +314,7 @@ class ExtractSuperRefactoring(
|
||||
project.runSynchronouslyWithProgress(RefactoringBundle.message("progress.text"), true) { runReadAction { analyzeContext() } }
|
||||
|
||||
project.executeWriteCommand(KotlinExtractSuperclassHandler.REFACTORING_NAME) {
|
||||
val newClass = createClass(superClassEntry)
|
||||
val newClass = createClass(superClassEntry) ?: return@executeWriteCommand
|
||||
|
||||
val subClass = extractInfo.originalClass.toLightClass()
|
||||
val superClass = newClass.toLightClass()
|
||||
|
||||
@@ -0,0 +1 @@
|
||||
class Foo
|
||||
@@ -0,0 +1,5 @@
|
||||
class Foo
|
||||
interface ISomething {
|
||||
// INFO: {checked: "true"}
|
||||
var independent: Int
|
||||
}
|
||||
@@ -0,0 +1,6 @@
|
||||
// NAME: ISomething
|
||||
// TARGET_FILE_NAME: extractToExistingFile.1.kt
|
||||
class <caret>Something {
|
||||
// INFO: {checked: "true"}
|
||||
var independent = 1
|
||||
}
|
||||
@@ -0,0 +1,6 @@
|
||||
// NAME: ISomething
|
||||
// TARGET_FILE_NAME: extractToExistingFile.1.kt
|
||||
class Something : ISomething {
|
||||
// INFO: {checked: "true"}
|
||||
override var independent = 1
|
||||
}
|
||||
@@ -0,0 +1 @@
|
||||
class Foo
|
||||
@@ -0,0 +1,5 @@
|
||||
class Foo
|
||||
open class SomethingBase {
|
||||
// INFO: {checked: "true"}
|
||||
var independent = 1
|
||||
}
|
||||
@@ -0,0 +1,6 @@
|
||||
// NAME: SomethingBase
|
||||
// TARGET_FILE_NAME: extractToExistingFile.1.kt
|
||||
class <caret>Something {
|
||||
// INFO: {checked: "true"}
|
||||
var independent = 1
|
||||
}
|
||||
@@ -0,0 +1,4 @@
|
||||
// NAME: SomethingBase
|
||||
// TARGET_FILE_NAME: extractToExistingFile.1.kt
|
||||
class Something : SomethingBase() {
|
||||
}
|
||||
+4
-2
@@ -298,7 +298,7 @@ abstract class AbstractExtractionTest : KotlinLightCodeInsightFixtureTestCase()
|
||||
}
|
||||
|
||||
protected fun doExtractSuperTest(path: String, isInterface: Boolean) {
|
||||
doTest(path) { file ->
|
||||
doTest(path, true) { file ->
|
||||
file as KtFile
|
||||
|
||||
markMembersInfo(file)
|
||||
@@ -306,6 +306,8 @@ abstract class AbstractExtractionTest : KotlinLightCodeInsightFixtureTestCase()
|
||||
val targetParent = file.findElementByCommentPrefix("// SIBLING:")?.parent ?: file.parent!!
|
||||
val fileText = file.text
|
||||
val className = InTextDirectivesUtils.findStringWithPrefixes(fileText, "// NAME:")!!
|
||||
val targetFileName = InTextDirectivesUtils.findStringWithPrefixes(fileText, "// TARGET_FILE_NAME:")
|
||||
?: "$className.${KotlinFileType.EXTENSION}"
|
||||
val editor = fixture.editor
|
||||
val originalClass = file.findElementAt(editor.caretModel.offset)?.getStrictParentOfType<KtClassOrObject>()!!
|
||||
val memberInfos = chooseMembers(extractClassMembers(originalClass))
|
||||
@@ -315,7 +317,7 @@ abstract class AbstractExtractionTest : KotlinLightCodeInsightFixtureTestCase()
|
||||
originalClass,
|
||||
memberInfos,
|
||||
targetParent,
|
||||
"$className.${KotlinFileType.EXTENSION}",
|
||||
targetFileName,
|
||||
className,
|
||||
isInterface,
|
||||
DocCommentPolicy<PsiComment>(DocCommentPolicy.ASIS)
|
||||
|
||||
+12
-2
@@ -3957,7 +3957,7 @@ public class ExtractionTestGenerated extends AbstractExtractionTest {
|
||||
}
|
||||
|
||||
public void testAllFilesPresentInExtractSuperclass() throws Exception {
|
||||
KotlinTestUtils.assertAllTestsPresentByMetadata(this.getClass(), new File("idea/testData/refactoring/extractSuperclass"), Pattern.compile("^(.+)\\.(kt|kts)$"), TargetBackend.ANY, true);
|
||||
KotlinTestUtils.assertAllTestsPresentByMetadata(this.getClass(), new File("idea/testData/refactoring/extractSuperclass"), Pattern.compile("^([^.]+)\\.(kt|kts)$"), TargetBackend.ANY, true);
|
||||
}
|
||||
|
||||
@TestMetadata("annotation.kt")
|
||||
@@ -3975,6 +3975,11 @@ public class ExtractionTestGenerated extends AbstractExtractionTest {
|
||||
runTest("idea/testData/refactoring/extractSuperclass/enum.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("extractToExistingFile.kt")
|
||||
public void testExtractToExistingFile() throws Exception {
|
||||
runTest("idea/testData/refactoring/extractSuperclass/extractToExistingFile.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("interface.kt")
|
||||
public void testInterface() throws Exception {
|
||||
runTest("idea/testData/refactoring/extractSuperclass/interface.kt");
|
||||
@@ -4045,7 +4050,7 @@ public class ExtractionTestGenerated extends AbstractExtractionTest {
|
||||
}
|
||||
|
||||
public void testAllFilesPresentInExtractInterface() throws Exception {
|
||||
KotlinTestUtils.assertAllTestsPresentByMetadata(this.getClass(), new File("idea/testData/refactoring/extractInterface"), Pattern.compile("^(.+)\\.(kt|kts)$"), TargetBackend.ANY, true);
|
||||
KotlinTestUtils.assertAllTestsPresentByMetadata(this.getClass(), new File("idea/testData/refactoring/extractInterface"), Pattern.compile("^([^.]+)\\.(kt|kts)$"), TargetBackend.ANY, true);
|
||||
}
|
||||
|
||||
@TestMetadata("annotation.kt")
|
||||
@@ -4058,6 +4063,11 @@ public class ExtractionTestGenerated extends AbstractExtractionTest {
|
||||
runTest("idea/testData/refactoring/extractInterface/dropFinal.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("extractToExistingFile.kt")
|
||||
public void testExtractToExistingFile() throws Exception {
|
||||
runTest("idea/testData/refactoring/extractInterface/extractToExistingFile.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("noWarningOnVisibilityInsideAbstractedMember.kt")
|
||||
public void testNoWarningOnVisibilityInsideAbstractedMember() throws Exception {
|
||||
runTest("idea/testData/refactoring/extractInterface/noWarningOnVisibilityInsideAbstractedMember.kt");
|
||||
|
||||
Reference in New Issue
Block a user