Extract Superclass/Interface: Fix bogus visibility warning inside a member when it's being moved as abstract
#KT-15635 Fixed
This commit is contained in:
@@ -482,6 +482,7 @@ These artifacts include extensions for the types available in the latter JDKs, s
|
|||||||
- [`KT-15640`](https://youtrack.jetbrains.com/issue/KT-15640) Extract Interface/Pull Up: Drop 'final' modifier when moving to an interface
|
- [`KT-15640`](https://youtrack.jetbrains.com/issue/KT-15640) Extract Interface/Pull Up: Drop 'final' modifier when moving to an interface
|
||||||
- [`KT-15639`](https://youtrack.jetbrains.com/issue/KT-15639) Extract Superclass/Interface/Pull Up: Add spaces between 'abstract' modifier and annotations
|
- [`KT-15639`](https://youtrack.jetbrains.com/issue/KT-15639) Extract Superclass/Interface/Pull Up: Add spaces between 'abstract' modifier and annotations
|
||||||
- [`KT-15606`](https://youtrack.jetbrains.com/issue/KT-15606) Extract Interface/Pull Up: Warn about private members with usages in the original class
|
- [`KT-15606`](https://youtrack.jetbrains.com/issue/KT-15606) Extract Interface/Pull Up: Warn about private members with usages in the original class
|
||||||
|
- [`KT-15635`](https://youtrack.jetbrains.com/issue/KT-15635) Extract Superclass/Interface: Fix bogus visibility warning inside a member when it's being moved as abstract
|
||||||
|
|
||||||
#### Intention actions, inspections and quickfixes
|
#### Intention actions, inspections and quickfixes
|
||||||
|
|
||||||
|
|||||||
+7
-1
@@ -145,7 +145,13 @@ class ExtractSuperRefactoring(
|
|||||||
else {
|
else {
|
||||||
KotlinMoveTargetForExistingElement(targetParent as KtElement)
|
KotlinMoveTargetForExistingElement(targetParent as KtElement)
|
||||||
}
|
}
|
||||||
val conflictChecker = MoveConflictChecker(project, elementsToMove, moveTarget, originalClass)
|
val conflictChecker = MoveConflictChecker(
|
||||||
|
project,
|
||||||
|
elementsToMove,
|
||||||
|
moveTarget,
|
||||||
|
originalClass,
|
||||||
|
memberInfos.filter { it.isToAbstract }.mapNotNull { it.member }
|
||||||
|
)
|
||||||
|
|
||||||
project.runSynchronouslyWithProgress(RefactoringBundle.message("detecting.possible.conflicts"), true) {
|
project.runSynchronouslyWithProgress(RefactoringBundle.message("detecting.possible.conflicts"), true) {
|
||||||
runReadAction {
|
runReadAction {
|
||||||
|
|||||||
+4
-3
@@ -51,7 +51,8 @@ class MoveConflictChecker(
|
|||||||
private val project: Project,
|
private val project: Project,
|
||||||
private val elementsToMove: Collection<KtElement>,
|
private val elementsToMove: Collection<KtElement>,
|
||||||
private val moveTarget: KotlinMoveTarget,
|
private val moveTarget: KotlinMoveTarget,
|
||||||
contextElement: KtElement
|
contextElement: KtElement,
|
||||||
|
private val doNotGoIn: Collection<KtElement> = emptyList()
|
||||||
) {
|
) {
|
||||||
private val resolutionFacade = contextElement.getResolutionFacade()
|
private val resolutionFacade = contextElement.getResolutionFacade()
|
||||||
|
|
||||||
@@ -148,7 +149,7 @@ class MoveConflictChecker(
|
|||||||
val sourceRoot = moveTarget.targetFile ?: return
|
val sourceRoot = moveTarget.targetFile ?: return
|
||||||
val targetModule = ModuleUtilCore.findModuleForFile(sourceRoot, project) ?: return
|
val targetModule = ModuleUtilCore.findModuleForFile(sourceRoot, project) ?: return
|
||||||
val resolveScope = GlobalSearchScope.moduleWithDependenciesAndLibrariesScope(targetModule)
|
val resolveScope = GlobalSearchScope.moduleWithDependenciesAndLibrariesScope(targetModule)
|
||||||
for (declaration in elementsToMove) {
|
for (declaration in elementsToMove - doNotGoIn) {
|
||||||
declaration.forEachDescendantOfType<KtReferenceExpression> { refExpr ->
|
declaration.forEachDescendantOfType<KtReferenceExpression> { refExpr ->
|
||||||
val targetDescriptor = refExpr.analyze(BodyResolveMode.PARTIAL)[BindingContext.REFERENCE_TARGET, refExpr] ?: return@forEachDescendantOfType
|
val targetDescriptor = refExpr.analyze(BodyResolveMode.PARTIAL)[BindingContext.REFERENCE_TARGET, refExpr] ?: return@forEachDescendantOfType
|
||||||
|
|
||||||
@@ -206,7 +207,7 @@ class MoveConflictChecker(
|
|||||||
|
|
||||||
fun checkVisibilityInDeclarations(conflicts: MultiMap<PsiElement, String>) {
|
fun checkVisibilityInDeclarations(conflicts: MultiMap<PsiElement, String>) {
|
||||||
val targetContainer = moveTarget.getContainerDescriptor() ?: return
|
val targetContainer = moveTarget.getContainerDescriptor() ?: return
|
||||||
for (declaration in elementsToMove) {
|
for (declaration in elementsToMove - doNotGoIn) {
|
||||||
declaration.forEachDescendantOfType<KtReferenceExpression> { refExpr ->
|
declaration.forEachDescendantOfType<KtReferenceExpression> { refExpr ->
|
||||||
refExpr.references
|
refExpr.references
|
||||||
.forEach { ref ->
|
.forEach { ref ->
|
||||||
|
|||||||
+12
@@ -0,0 +1,12 @@
|
|||||||
|
// NAME: I
|
||||||
|
// SIBLING:
|
||||||
|
class <caret>BrokenRef {
|
||||||
|
private fun fun1() {}
|
||||||
|
fun fun2() {}
|
||||||
|
|
||||||
|
// INFO: {checked: "true", toAbstract: "true"}
|
||||||
|
fun refer() {
|
||||||
|
fun1()
|
||||||
|
fun2()
|
||||||
|
}
|
||||||
|
}
|
||||||
Vendored
+17
@@ -0,0 +1,17 @@
|
|||||||
|
interface I {
|
||||||
|
// INFO: {checked: "true", toAbstract: "true"}
|
||||||
|
fun refer()
|
||||||
|
}
|
||||||
|
|
||||||
|
// NAME: I
|
||||||
|
// SIBLING:
|
||||||
|
class BrokenRef : I {
|
||||||
|
private fun fun1() {}
|
||||||
|
fun fun2() {}
|
||||||
|
|
||||||
|
// INFO: {checked: "true", toAbstract: "true"}
|
||||||
|
override fun refer() {
|
||||||
|
fun1()
|
||||||
|
fun2()
|
||||||
|
}
|
||||||
|
}
|
||||||
+12
@@ -0,0 +1,12 @@
|
|||||||
|
// NAME: A
|
||||||
|
// SIBLING:
|
||||||
|
class <caret>BrokenRef {
|
||||||
|
private fun fun1() {}
|
||||||
|
fun fun2() {}
|
||||||
|
|
||||||
|
// INFO: {checked: "true", toAbstract: "true"}
|
||||||
|
fun refer() {
|
||||||
|
fun1()
|
||||||
|
fun2()
|
||||||
|
}
|
||||||
|
}
|
||||||
Vendored
+17
@@ -0,0 +1,17 @@
|
|||||||
|
abstract class A {
|
||||||
|
// INFO: {checked: "true", toAbstract: "true"}
|
||||||
|
abstract fun refer()
|
||||||
|
}
|
||||||
|
|
||||||
|
// NAME: A
|
||||||
|
// SIBLING:
|
||||||
|
class BrokenRef : A() {
|
||||||
|
private fun fun1() {}
|
||||||
|
fun fun2() {}
|
||||||
|
|
||||||
|
// INFO: {checked: "true", toAbstract: "true"}
|
||||||
|
override fun refer() {
|
||||||
|
fun1()
|
||||||
|
fun2()
|
||||||
|
}
|
||||||
|
}
|
||||||
+12
@@ -4295,6 +4295,12 @@ public class ExtractionTestGenerated extends AbstractExtractionTest {
|
|||||||
doExtractSuperclassTest(fileName);
|
doExtractSuperclassTest(fileName);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@TestMetadata("noWarningOnVisibilityInsideAbstractedMember.kt")
|
||||||
|
public void testNoWarningOnVisibilityInsideAbstractedMember() throws Exception {
|
||||||
|
String fileName = KotlinTestUtils.navigationMetadata("idea/testData/refactoring/extractSuperclass/noWarningOnVisibilityInsideAbstractedMember.kt");
|
||||||
|
doExtractSuperclassTest(fileName);
|
||||||
|
}
|
||||||
|
|
||||||
@TestMetadata("privateClass.kt")
|
@TestMetadata("privateClass.kt")
|
||||||
public void testPrivateClass() throws Exception {
|
public void testPrivateClass() throws Exception {
|
||||||
String fileName = KotlinTestUtils.navigationMetadata("idea/testData/refactoring/extractSuperclass/privateClass.kt");
|
String fileName = KotlinTestUtils.navigationMetadata("idea/testData/refactoring/extractSuperclass/privateClass.kt");
|
||||||
@@ -4376,6 +4382,12 @@ public class ExtractionTestGenerated extends AbstractExtractionTest {
|
|||||||
doExtractInterfaceTest(fileName);
|
doExtractInterfaceTest(fileName);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@TestMetadata("noWarningOnVisibilityInsideAbstractedMember.kt")
|
||||||
|
public void testNoWarningOnVisibilityInsideAbstractedMember() throws Exception {
|
||||||
|
String fileName = KotlinTestUtils.navigationMetadata("idea/testData/refactoring/extractInterface/noWarningOnVisibilityInsideAbstractedMember.kt");
|
||||||
|
doExtractInterfaceTest(fileName);
|
||||||
|
}
|
||||||
|
|
||||||
@TestMetadata("privateMemberWithUsages.kt")
|
@TestMetadata("privateMemberWithUsages.kt")
|
||||||
public void testPrivateMemberWithUsages() throws Exception {
|
public void testPrivateMemberWithUsages() throws Exception {
|
||||||
String fileName = KotlinTestUtils.navigationMetadata("idea/testData/refactoring/extractInterface/privateMemberWithUsages.kt");
|
String fileName = KotlinTestUtils.navigationMetadata("idea/testData/refactoring/extractInterface/privateMemberWithUsages.kt");
|
||||||
|
|||||||
Reference in New Issue
Block a user