KT-11806: increase visibility quick fix: private / internal -> public #KT-11806 Fixed

This commit is contained in:
Mikhail Glukhikh
2016-04-08 16:49:17 +03:00
parent f12a9b7b95
commit 80e41c5298
7 changed files with 60 additions and 12 deletions
@@ -162,16 +162,18 @@ fun PsiElement.deleteSingle() {
fun KtClass.getOrCreateCompanionObject() : KtObjectDeclaration { fun KtClass.getOrCreateCompanionObject() : KtObjectDeclaration {
getCompanionObjects().firstOrNull()?.let { return it } getCompanionObjects().firstOrNull()?.let { return it }
return addDeclaration(KtPsiFactory(this).createCompanionObject()) as KtObjectDeclaration return addDeclaration(KtPsiFactory(this).createCompanionObject())
} }
//TODO: code style option whether to insert redundant 'public' keyword or not //TODO: code style option whether to insert redundant 'public' keyword or not
fun KtDeclaration.setVisibility(visibilityModifier: KtModifierKeywordToken) { fun KtModifierListOwner.setVisibility(visibilityModifier: KtModifierKeywordToken) {
val defaultVisibilityKeyword = implicitVisibility() if (this is KtDeclaration) {
val defaultVisibilityKeyword = implicitVisibility()
if (visibilityModifier == defaultVisibilityKeyword) { if (visibilityModifier == defaultVisibilityKeyword) {
this.visibilityModifierType()?.let { removeModifier(it) } this.visibilityModifierType()?.let { removeModifier(it) }
return return
}
} }
addModifier(visibilityModifier) addModifier(visibilityModifier)
@@ -35,6 +35,7 @@ import org.jetbrains.kotlin.resolve.DescriptorToSourceUtils
import org.jetbrains.kotlin.resolve.DescriptorUtils import org.jetbrains.kotlin.resolve.DescriptorUtils
import org.jetbrains.kotlin.resolve.descriptorUtil.module import org.jetbrains.kotlin.resolve.descriptorUtil.module
import org.jetbrains.kotlin.resolve.lazy.BodyResolveMode import org.jetbrains.kotlin.resolve.lazy.BodyResolveMode
import org.jetbrains.kotlin.idea.core.setVisibility
class IncreaseVisibilityFix( class IncreaseVisibilityFix(
element: KtModifierListOwner, element: KtModifierListOwner,
@@ -46,7 +47,7 @@ class IncreaseVisibilityFix(
override fun getFamilyName() = "Make $visibilityModifier" override fun getFamilyName() = "Make $visibilityModifier"
override fun invoke(project: Project, editor: Editor?, file: KtFile) { override fun invoke(project: Project, editor: Editor?, file: KtFile) {
element.addModifier(visibilityModifier) element.setVisibility(visibilityModifier)
} }
companion object : KotlinSingleIntentionActionFactory() { companion object : KotlinSingleIntentionActionFactory() {
@@ -54,17 +55,20 @@ class IncreaseVisibilityFix(
val element = diagnostic.psiElement as? KtElement ?: return null val element = diagnostic.psiElement as? KtElement ?: return null
val context = element.analyze(BodyResolveMode.PARTIAL) val context = element.analyze(BodyResolveMode.PARTIAL)
val usageModule = context.get(BindingContext.FILE_TO_PACKAGE_FRAGMENT, element.getContainingKtFile())?.module val usageModule = context.get(BindingContext.FILE_TO_PACKAGE_FRAGMENT, element.getContainingKtFile())?.module
?: return null
@Suppress("UNCHECKED_CAST") @Suppress("UNCHECKED_CAST")
val factory = diagnostic.factory as DiagnosticFactory3<*, DeclarationDescriptor, *, DeclarationDescriptor> val factory = diagnostic.factory as DiagnosticFactory3<*, DeclarationDescriptor, *, DeclarationDescriptor>
val descriptor = factory.cast(diagnostic).c as? DeclarationDescriptorWithVisibility ?: return null val descriptor = factory.cast(diagnostic).c as? DeclarationDescriptorWithVisibility ?: return null
val declaration = DescriptorToSourceUtils.getSourceFromDescriptor(descriptor) as? KtModifierListOwner ?: return null
val module = DescriptorUtils.getContainingModule(descriptor) val module = DescriptorUtils.getContainingModule(descriptor)
if (module != usageModule) return null val modifier = if (module != usageModule || descriptor.visibility != Visibilities.PRIVATE) {
val declaration = DescriptorToSourceUtils.getSourceFromDescriptor(descriptor) as? KtModifierListOwner ?: return null KtTokens.PUBLIC_KEYWORD
if (descriptor.visibility != Visibilities.PRIVATE) return null }
return IncreaseVisibilityFix(declaration, descriptor.name.asString(), KtTokens.INTERNAL_KEYWORD) else {
KtTokens.INTERNAL_KEYWORD
}
return IncreaseVisibilityFix(declaration, descriptor.name.asString(), modifier)
} }
} }
} }
@@ -0,0 +1,9 @@
// "Make x public" "true"
open class Base(protected open val x: Int)
class First(override val x: Int) : Base(x)
class Second(f: First) {
val y = f.<caret>x
}
@@ -0,0 +1,9 @@
// "Make x public" "true"
open class Base(protected open val x: Int)
class First(public override val x: Int) : Base(x)
class Second(f: First) {
val y = f.x
}
@@ -0,0 +1,6 @@
// "Make x public" "true"
class First(protected val x: Int)
class Second(f: First) {
val y = f.<caret>x
}
@@ -0,0 +1,6 @@
// "Make x public" "true"
class First(val x: Int)
class Second(f: First) {
val y = f.x
}
@@ -4719,11 +4719,23 @@ public class QuickFixTestGenerated extends AbstractQuickFixTest {
KotlinTestUtils.assertAllTestsPresentByMetadata(this.getClass(), new File("idea/testData/quickfix/increaseVisibility"), Pattern.compile("^([\\w\\-_]+)\\.kt$"), true); KotlinTestUtils.assertAllTestsPresentByMetadata(this.getClass(), new File("idea/testData/quickfix/increaseVisibility"), Pattern.compile("^([\\w\\-_]+)\\.kt$"), true);
} }
@TestMetadata("overriddenProtectedMemberToPublicSingleFile.kt")
public void testOverriddenProtectedMemberToPublicSingleFile() throws Exception {
String fileName = KotlinTestUtils.navigationMetadata("idea/testData/quickfix/increaseVisibility/overriddenProtectedMemberToPublicSingleFile.kt");
doTest(fileName);
}
@TestMetadata("privateMemberToInternalSingleFile.kt") @TestMetadata("privateMemberToInternalSingleFile.kt")
public void testPrivateMemberToInternalSingleFile() throws Exception { public void testPrivateMemberToInternalSingleFile() throws Exception {
String fileName = KotlinTestUtils.navigationMetadata("idea/testData/quickfix/increaseVisibility/privateMemberToInternalSingleFile.kt"); String fileName = KotlinTestUtils.navigationMetadata("idea/testData/quickfix/increaseVisibility/privateMemberToInternalSingleFile.kt");
doTest(fileName); doTest(fileName);
} }
@TestMetadata("protectedMemberToPublicSingleFile.kt")
public void testProtectedMemberToPublicSingleFile() throws Exception {
String fileName = KotlinTestUtils.navigationMetadata("idea/testData/quickfix/increaseVisibility/protectedMemberToPublicSingleFile.kt");
doTest(fileName);
}
} }
@TestMetadata("idea/testData/quickfix/initializeWithConstructorParameter") @TestMetadata("idea/testData/quickfix/initializeWithConstructorParameter")