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:
Alexey Sedunov
2017-01-11 17:09:37 +03:00
parent 65b9049d59
commit 57d364e7d4
8 changed files with 82 additions and 4 deletions
+1
View File
@@ -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
@@ -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 {
@@ -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 ->
@@ -0,0 +1,12 @@
// NAME: I
// SIBLING:
class <caret>BrokenRef {
private fun fun1() {}
fun fun2() {}
// INFO: {checked: "true", toAbstract: "true"}
fun refer() {
fun1()
fun2()
}
}
@@ -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()
}
}
@@ -0,0 +1,12 @@
// NAME: A
// SIBLING:
class <caret>BrokenRef {
private fun fun1() {}
fun fun2() {}
// INFO: {checked: "true", toAbstract: "true"}
fun refer() {
fun1()
fun2()
}
}
@@ -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()
}
}
@@ -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");