Add quickfix for setting explicit public visibility for diagnostic reported in API mode

This commit is contained in:
Leonid Startsev
2019-09-16 14:51:12 +03:00
parent 2b708093c0
commit 7fada51c42
6 changed files with 48 additions and 39 deletions
@@ -288,9 +288,8 @@ fun KtDeclaration.toDescriptor(): DeclarationDescriptor? {
return descriptor
}
//TODO: code style option whether to insert redundant 'public' keyword or not
fun KtModifierListOwner.setVisibility(visibilityModifier: KtModifierKeywordToken) {
if (this is KtDeclaration) {
fun KtModifierListOwner.setVisibility(visibilityModifier: KtModifierKeywordToken, addImplicitVisibilityModifier: Boolean = false) {
if (this is KtDeclaration && !addImplicitVisibilityModifier) {
val defaultVisibilityKeyword = implicitVisibility()
if (visibilityModifier == defaultVisibilityKeyword) {
@@ -20,9 +20,12 @@ import com.intellij.codeInsight.intention.HighPriorityAction
import com.intellij.codeInsight.intention.IntentionAction
import com.intellij.openapi.editor.Editor
import com.intellij.openapi.project.Project
import org.jetbrains.kotlin.descriptors.DeclarationDescriptor
import org.jetbrains.kotlin.descriptors.DeclarationDescriptorWithVisibility
import org.jetbrains.kotlin.descriptors.Visibilities
import org.jetbrains.kotlin.descriptors.Visibility
import org.jetbrains.kotlin.diagnostics.Diagnostic
import org.jetbrains.kotlin.diagnostics.DiagnosticFactory1
import org.jetbrains.kotlin.idea.core.canBeInternal
import org.jetbrains.kotlin.idea.core.canBePrivate
import org.jetbrains.kotlin.idea.core.canBeProtected
@@ -42,7 +45,8 @@ import org.jetbrains.kotlin.resolve.ExposedVisibilityChecker
open class ChangeVisibilityFix(
element: KtModifierListOwner,
private val elementName: String,
private val visibilityModifier: KtModifierKeywordToken
private val visibilityModifier: KtModifierKeywordToken,
private val addImplicitVisibilityModifier: Boolean = false
) : KotlinQuickFixAction<KtModifierListOwner>(element) {
override fun getText() = "Make '$elementName' $visibilityModifier"
@@ -52,9 +56,9 @@ open class ChangeVisibilityFix(
val pointer = element?.createSmartPointer()
val originalElement = pointer?.element
if (originalElement is KtDeclaration) {
originalElement.runOnExpectAndAllActuals(useOnSelf = true) { it.setVisibility(visibilityModifier) }
originalElement.runOnExpectAndAllActuals(useOnSelf = true) { it.setVisibility(visibilityModifier, addImplicitVisibilityModifier) }
} else {
originalElement?.setVisibility(visibilityModifier)
originalElement?.setVisibility(visibilityModifier, addImplicitVisibilityModifier)
}
val propertyAccessor = pointer?.element as? KtPropertyAccessor
@@ -112,4 +116,21 @@ open class ChangeVisibilityFix(
}
}
}
object SetExplicitVisibilityFactory : KotlinIntentionActionsFactory() {
@Suppress("UNCHECKED_CAST")
override fun doCreateActions(diagnostic: Diagnostic): List<IntentionAction> {
val factory = diagnostic.factory as DiagnosticFactory1<*, DeclarationDescriptor>
val descriptor = factory.cast(diagnostic).a as? DeclarationDescriptorWithVisibility ?: return emptyList()
val element = diagnostic.psiElement as? KtModifierListOwner ?: return emptyList()
return listOf(
ChangeVisibilityFix(
element,
descriptor.name.asString(),
KtTokens.PUBLIC_KEYWORD,
addImplicitVisibilityModifier = true
)
)
}
}
}
@@ -151,6 +151,8 @@ class QuickFixRegistrar : QuickFixContributor {
FORBIDDEN_BINARY_MOD.registerFactory(removeModifierFactory)
FORBIDDEN_BINARY_MOD.registerFactory(RenameModToRemFix.Factory)
NO_EXPLICIT_VISIBILITY_IN_API_MODE.registerFactory(ChangeVisibilityFix.SetExplicitVisibilityFactory)
NO_EXPLICIT_VISIBILITY_IN_API_MODE_MIGRATION.registerFactory(ChangeVisibilityFix.SetExplicitVisibilityFactory)
NO_EXPLICIT_RETURN_TYPE_IN_API_MODE.registerActions(SpecifyTypeExplicitlyFix())
NO_EXPLICIT_RETURN_TYPE_IN_API_MODE_MIGRATION.registerActions(SpecifyTypeExplicitlyFix())