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-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-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
|
||||
|
||||
|
||||
+7
-1
@@ -145,7 +145,13 @@ class ExtractSuperRefactoring(
|
||||
else {
|
||||
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) {
|
||||
runReadAction {
|
||||
|
||||
+4
-3
@@ -51,7 +51,8 @@ class MoveConflictChecker(
|
||||
private val project: Project,
|
||||
private val elementsToMove: Collection<KtElement>,
|
||||
private val moveTarget: KotlinMoveTarget,
|
||||
contextElement: KtElement
|
||||
contextElement: KtElement,
|
||||
private val doNotGoIn: Collection<KtElement> = emptyList()
|
||||
) {
|
||||
private val resolutionFacade = contextElement.getResolutionFacade()
|
||||
|
||||
@@ -148,7 +149,7 @@ class MoveConflictChecker(
|
||||
val sourceRoot = moveTarget.targetFile ?: return
|
||||
val targetModule = ModuleUtilCore.findModuleForFile(sourceRoot, project) ?: return
|
||||
val resolveScope = GlobalSearchScope.moduleWithDependenciesAndLibrariesScope(targetModule)
|
||||
for (declaration in elementsToMove) {
|
||||
for (declaration in elementsToMove - doNotGoIn) {
|
||||
declaration.forEachDescendantOfType<KtReferenceExpression> { refExpr ->
|
||||
val targetDescriptor = refExpr.analyze(BodyResolveMode.PARTIAL)[BindingContext.REFERENCE_TARGET, refExpr] ?: return@forEachDescendantOfType
|
||||
|
||||
@@ -206,7 +207,7 @@ class MoveConflictChecker(
|
||||
|
||||
fun checkVisibilityInDeclarations(conflicts: MultiMap<PsiElement, String>) {
|
||||
val targetContainer = moveTarget.getContainerDescriptor() ?: return
|
||||
for (declaration in elementsToMove) {
|
||||
for (declaration in elementsToMove - doNotGoIn) {
|
||||
declaration.forEachDescendantOfType<KtReferenceExpression> { refExpr ->
|
||||
refExpr.references
|
||||
.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);
|
||||
}
|
||||
|
||||
@TestMetadata("noWarningOnVisibilityInsideAbstractedMember.kt")
|
||||
public void testNoWarningOnVisibilityInsideAbstractedMember() throws Exception {
|
||||
String fileName = KotlinTestUtils.navigationMetadata("idea/testData/refactoring/extractSuperclass/noWarningOnVisibilityInsideAbstractedMember.kt");
|
||||
doExtractSuperclassTest(fileName);
|
||||
}
|
||||
|
||||
@TestMetadata("privateClass.kt")
|
||||
public void testPrivateClass() throws Exception {
|
||||
String fileName = KotlinTestUtils.navigationMetadata("idea/testData/refactoring/extractSuperclass/privateClass.kt");
|
||||
@@ -4376,6 +4382,12 @@ public class ExtractionTestGenerated extends AbstractExtractionTest {
|
||||
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")
|
||||
public void testPrivateMemberWithUsages() throws Exception {
|
||||
String fileName = KotlinTestUtils.navigationMetadata("idea/testData/refactoring/extractInterface/privateMemberWithUsages.kt");
|
||||
|
||||
Reference in New Issue
Block a user