diff --git a/compiler/frontend/src/org/jetbrains/kotlin/psi/psiUtil/ktPsiUtil.kt b/compiler/frontend/src/org/jetbrains/kotlin/psi/psiUtil/ktPsiUtil.kt index 01295c0b5c6..fe7e31bbc44 100644 --- a/compiler/frontend/src/org/jetbrains/kotlin/psi/psiUtil/ktPsiUtil.kt +++ b/compiler/frontend/src/org/jetbrains/kotlin/psi/psiUtil/ktPsiUtil.kt @@ -431,6 +431,13 @@ fun KtModifierList.visibilityModifierType(): KtModifierKeywordToken? = visibilit fun KtModifierListOwner.visibilityModifier() = modifierList?.modifierFromTokenSet(KtTokens.VISIBILITY_MODIFIERS) +val KtModifierListOwner.isPublic: Boolean + get() { + if (this is KtDeclaration && KtPsiUtil.isLocal(this)) return false + val visibilityModifier = visibilityModifierType() + return visibilityModifier == null || visibilityModifier == KtTokens.PUBLIC_KEYWORD + } + fun KtModifierListOwner.visibilityModifierType(): KtModifierKeywordToken? = visibilityModifier()?.node?.elementType as KtModifierKeywordToken? diff --git a/idea/src/org/jetbrains/kotlin/idea/refactoring/move/moveDeclarations/moveConflictUtils.kt b/idea/src/org/jetbrains/kotlin/idea/refactoring/move/moveDeclarations/moveConflictUtils.kt index 704594e6d3f..73e212917a7 100644 --- a/idea/src/org/jetbrains/kotlin/idea/refactoring/move/moveDeclarations/moveConflictUtils.kt +++ b/idea/src/org/jetbrains/kotlin/idea/refactoring/move/moveDeclarations/moveConflictUtils.kt @@ -52,10 +52,7 @@ import org.jetbrains.kotlin.idea.util.projectStructure.getModule import org.jetbrains.kotlin.idea.util.projectStructure.module import org.jetbrains.kotlin.lexer.KtTokens import org.jetbrains.kotlin.psi.* -import org.jetbrains.kotlin.psi.psiUtil.contains -import org.jetbrains.kotlin.psi.psiUtil.forEachDescendantOfType -import org.jetbrains.kotlin.psi.psiUtil.getStrictParentOfType -import org.jetbrains.kotlin.psi.psiUtil.isAncestor +import org.jetbrains.kotlin.psi.psiUtil.* import org.jetbrains.kotlin.renderer.ClassifierNamePolicy import org.jetbrains.kotlin.renderer.DescriptorRenderer import org.jetbrains.kotlin.renderer.ParameterNameRenderingPolicy @@ -331,7 +328,9 @@ class MoveConflictChecker( val referencedDescriptor = resolutionFacade.resolveToDescriptor(referencedElement) if (referencedDescriptor is DeclarationDescriptorWithVisibility - && referencedDescriptor.visibility == Visibilities.PUBLIC) continue + && referencedDescriptor.visibility == Visibilities.PUBLIC + && moveTarget is KotlinMoveTargetForExistingElement + && moveTarget.targetElement.parentsWithSelf.filterIsInstance().all { it.isPublic }) continue val container = element.getUsageContext() if (!declarationToContainers.getOrPut(referencedElement) { HashSet() }.add(container)) continue diff --git a/idea/testData/refactoring/move/kotlin/moveNestedClass/nonInnerToTopLevelPrivateClass/after/test/PrivateClass.kt b/idea/testData/refactoring/move/kotlin/moveNestedClass/nonInnerToTopLevelPrivateClass/after/test/PrivateClass.kt new file mode 100644 index 00000000000..88ee90c3235 --- /dev/null +++ b/idea/testData/refactoring/move/kotlin/moveNestedClass/nonInnerToTopLevelPrivateClass/after/test/PrivateClass.kt @@ -0,0 +1,7 @@ +package test + +private class PrivateClass { + class NestedClass { + val valInNestedC = 42 + } +} \ No newline at end of file diff --git a/idea/testData/refactoring/move/kotlin/moveNestedClass/nonInnerToTopLevelPrivateClass/after/test/test.kt b/idea/testData/refactoring/move/kotlin/moveNestedClass/nonInnerToTopLevelPrivateClass/after/test/test.kt new file mode 100644 index 00000000000..38d077737b3 --- /dev/null +++ b/idea/testData/refactoring/move/kotlin/moveNestedClass/nonInnerToTopLevelPrivateClass/after/test/test.kt @@ -0,0 +1,8 @@ +package test + +class SomeClass { +} + +fun main(args: Array) { + val test = PrivateClass.NestedClass().valInNestedC +} \ No newline at end of file diff --git a/idea/testData/refactoring/move/kotlin/moveNestedClass/nonInnerToTopLevelPrivateClass/before/test/PrivateClass.kt b/idea/testData/refactoring/move/kotlin/moveNestedClass/nonInnerToTopLevelPrivateClass/before/test/PrivateClass.kt new file mode 100644 index 00000000000..fd11b9157d2 --- /dev/null +++ b/idea/testData/refactoring/move/kotlin/moveNestedClass/nonInnerToTopLevelPrivateClass/before/test/PrivateClass.kt @@ -0,0 +1,3 @@ +package test + +private class PrivateClass \ No newline at end of file diff --git a/idea/testData/refactoring/move/kotlin/moveNestedClass/nonInnerToTopLevelPrivateClass/before/test/test.kt b/idea/testData/refactoring/move/kotlin/moveNestedClass/nonInnerToTopLevelPrivateClass/before/test/test.kt new file mode 100644 index 00000000000..ba1aa6b77c0 --- /dev/null +++ b/idea/testData/refactoring/move/kotlin/moveNestedClass/nonInnerToTopLevelPrivateClass/before/test/test.kt @@ -0,0 +1,11 @@ +package test + +class SomeClass { + class NestedClass { + val valInNestedC = 42 + } +} + +fun main(args: Array) { + val test = SomeClass.NestedClass().valInNestedC +} \ No newline at end of file diff --git a/idea/testData/refactoring/move/kotlin/moveNestedClass/nonInnerToTopLevelPrivateClass/conflicts.txt b/idea/testData/refactoring/move/kotlin/moveNestedClass/nonInnerToTopLevelPrivateClass/conflicts.txt new file mode 100644 index 00000000000..f84111a1784 --- /dev/null +++ b/idea/testData/refactoring/move/kotlin/moveNestedClass/nonInnerToTopLevelPrivateClass/conflicts.txt @@ -0,0 +1 @@ +Variable test uses class NestedClass which will be inaccessible after move diff --git a/idea/testData/refactoring/move/kotlin/moveNestedClass/nonInnerToTopLevelPrivateClass/nonInnerToTopLevelPrivateClass.test b/idea/testData/refactoring/move/kotlin/moveNestedClass/nonInnerToTopLevelPrivateClass/nonInnerToTopLevelPrivateClass.test new file mode 100644 index 00000000000..d667bbc7775 --- /dev/null +++ b/idea/testData/refactoring/move/kotlin/moveNestedClass/nonInnerToTopLevelPrivateClass/nonInnerToTopLevelPrivateClass.test @@ -0,0 +1,6 @@ +{ + "mainFile": "test/test.kt", + "type": "MOVE_KOTLIN_NESTED_CLASS", + "targetClass": "test.PrivateClass", + "withRuntime": "true" +} \ No newline at end of file diff --git a/idea/tests/org/jetbrains/kotlin/idea/refactoring/move/MoveTestGenerated.java b/idea/tests/org/jetbrains/kotlin/idea/refactoring/move/MoveTestGenerated.java index bb5c7dcde4e..3143e2c1deb 100644 --- a/idea/tests/org/jetbrains/kotlin/idea/refactoring/move/MoveTestGenerated.java +++ b/idea/tests/org/jetbrains/kotlin/idea/refactoring/move/MoveTestGenerated.java @@ -403,6 +403,12 @@ public class MoveTestGenerated extends AbstractMoveTest { doTest(fileName); } + @TestMetadata("kotlin/moveNestedClass/nonInnerToTopLevelPrivateClass/nonInnerToTopLevelPrivateClass.test") + public void testKotlin_moveNestedClass_nonInnerToTopLevelPrivateClass_NonInnerToTopLevelPrivateClass() throws Exception { + String fileName = KotlinTestUtils.navigationMetadata("idea/testData/refactoring/move/kotlin/moveNestedClass/nonInnerToTopLevelPrivateClass/nonInnerToTopLevelPrivateClass.test"); + doTest(fileName); + } + @TestMetadata("kotlin/moveNestedClass/objectToTopLevel/objectToTopLevel.test") public void testKotlin_moveNestedClass_objectToTopLevel_ObjectToTopLevel() throws Exception { String fileName = KotlinTestUtils.navigationMetadata("idea/testData/refactoring/move/kotlin/moveNestedClass/objectToTopLevel/objectToTopLevel.test");