Move: Warn about moving public declaration to non-public class

#KT-22771 Fixed
This commit is contained in:
Alexey Sedunov
2018-02-08 21:34:55 +03:00
parent acf6408474
commit 1af21dd160
9 changed files with 53 additions and 5 deletions
@@ -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?
@@ -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<KtClassOrObject>().all { it.isPublic }) continue
val container = element.getUsageContext()
if (!declarationToContainers.getOrPut(referencedElement) { HashSet<PsiElement>() }.add(container)) continue
@@ -0,0 +1,7 @@
package test
private class PrivateClass {
class NestedClass {
val valInNestedC = 42
}
}
@@ -0,0 +1,8 @@
package test
class SomeClass {
}
fun main(args: Array<String>) {
val test = PrivateClass.NestedClass().valInNestedC
}
@@ -0,0 +1,3 @@
package test
private class PrivateClass
@@ -0,0 +1,11 @@
package test
class SomeClass {
class <caret>NestedClass {
val valInNestedC = 42
}
}
fun main(args: Array<String>) {
val test = SomeClass.NestedClass().valInNestedC
}
@@ -0,0 +1 @@
Variable test uses class NestedClass which will be inaccessible after move
@@ -0,0 +1,6 @@
{
"mainFile": "test/test.kt",
"type": "MOVE_KOTLIN_NESTED_CLASS",
"targetClass": "test.PrivateClass",
"withRuntime": "true"
}
@@ -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");