KT-46146 'protected' and 'private' only for sealed constructors
Prior to this commit we suggested two invalid intentions for sealed class constructors: change visibility to 'public' and 'internal'. ^KT-46146 Fixed
This commit is contained in:
@@ -14,7 +14,6 @@ import com.intellij.psi.util.PsiTreeUtil
|
|||||||
import com.intellij.psi.util.elementType
|
import com.intellij.psi.util.elementType
|
||||||
import org.jetbrains.kotlin.builtins.isFunctionOrSuspendFunctionType
|
import org.jetbrains.kotlin.builtins.isFunctionOrSuspendFunctionType
|
||||||
import org.jetbrains.kotlin.config.LanguageFeature
|
import org.jetbrains.kotlin.config.LanguageFeature
|
||||||
import org.jetbrains.kotlin.config.LanguageVersionSettings
|
|
||||||
import org.jetbrains.kotlin.descriptors.*
|
import org.jetbrains.kotlin.descriptors.*
|
||||||
import org.jetbrains.kotlin.extensions.DeclarationAttributeAltererExtension
|
import org.jetbrains.kotlin.extensions.DeclarationAttributeAltererExtension
|
||||||
import org.jetbrains.kotlin.idea.FrontendInternals
|
import org.jetbrains.kotlin.idea.FrontendInternals
|
||||||
@@ -358,6 +357,8 @@ fun KtModifierListOwner.canBePrivate(): Boolean {
|
|||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fun KtModifierListOwner.canBePublic(): Boolean = !isSealedClassConstructor()
|
||||||
|
|
||||||
fun KtModifierListOwner.canBeProtected(): Boolean {
|
fun KtModifierListOwner.canBeProtected(): Boolean {
|
||||||
val parent = when (this) {
|
val parent = when (this) {
|
||||||
is KtPropertyAccessor -> this.property.parent
|
is KtPropertyAccessor -> this.property.parent
|
||||||
@@ -376,12 +377,18 @@ fun KtModifierListOwner.canBeInternal(): Boolean {
|
|||||||
val objectDeclaration = getStrictParentOfType<KtObjectDeclaration>() ?: return false
|
val objectDeclaration = getStrictParentOfType<KtObjectDeclaration>() ?: return false
|
||||||
if (objectDeclaration.isCompanion() && hasJvmFieldAnnotation()) return false
|
if (objectDeclaration.isCompanion() && hasJvmFieldAnnotation()) return false
|
||||||
}
|
}
|
||||||
return !isAnnotationClassPrimaryConstructor()
|
return !isAnnotationClassPrimaryConstructor() && !isSealedClassConstructor()
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun KtModifierListOwner.isAnnotationClassPrimaryConstructor(): Boolean =
|
private fun KtModifierListOwner.isAnnotationClassPrimaryConstructor(): Boolean =
|
||||||
this is KtPrimaryConstructor && (this.parent as? KtClass)?.hasModifier(KtTokens.ANNOTATION_KEYWORD) ?: false
|
this is KtPrimaryConstructor && (this.parent as? KtClass)?.hasModifier(KtTokens.ANNOTATION_KEYWORD) ?: false
|
||||||
|
|
||||||
|
private fun KtModifierListOwner.isSealedClassConstructor(): Boolean {
|
||||||
|
if (this !is KtConstructor<*>) return false
|
||||||
|
val ktClass = getContainingClassOrObject().safeAs<KtClass>() ?: return false
|
||||||
|
return ktClass.isSealed()
|
||||||
|
}
|
||||||
|
|
||||||
fun KtClass.isInheritable(): Boolean {
|
fun KtClass.isInheritable(): Boolean {
|
||||||
return when (getModalityFromDescriptor()) {
|
return when (getModalityFromDescriptor()) {
|
||||||
KtTokens.ABSTRACT_KEYWORD, KtTokens.OPEN_KEYWORD, KtTokens.SEALED_KEYWORD -> true
|
KtTokens.ABSTRACT_KEYWORD, KtTokens.OPEN_KEYWORD, KtTokens.SEALED_KEYWORD -> true
|
||||||
|
|||||||
@@ -97,7 +97,10 @@ open class ChangeVisibilityModifierIntention protected constructor(val modifier:
|
|||||||
else -> null
|
else -> null
|
||||||
}
|
}
|
||||||
|
|
||||||
class Public : ChangeVisibilityModifierIntention(KtTokens.PUBLIC_KEYWORD), HighPriorityAction
|
class Public : ChangeVisibilityModifierIntention(KtTokens.PUBLIC_KEYWORD), HighPriorityAction {
|
||||||
|
override fun applicabilityRange(element: KtDeclaration): TextRange? =
|
||||||
|
if (element.canBePublic()) super.applicabilityRange(element) else null
|
||||||
|
}
|
||||||
|
|
||||||
class Private : ChangeVisibilityModifierIntention(KtTokens.PRIVATE_KEYWORD), HighPriorityAction {
|
class Private : ChangeVisibilityModifierIntention(KtTokens.PRIVATE_KEYWORD), HighPriorityAction {
|
||||||
override fun applicabilityRange(element: KtDeclaration): TextRange? =
|
override fun applicabilityRange(element: KtDeclaration): TextRange? =
|
||||||
|
|||||||
@@ -16,10 +16,7 @@ import org.jetbrains.kotlin.descriptors.DescriptorVisibility
|
|||||||
import org.jetbrains.kotlin.diagnostics.Diagnostic
|
import org.jetbrains.kotlin.diagnostics.Diagnostic
|
||||||
import org.jetbrains.kotlin.diagnostics.DiagnosticFactory0
|
import org.jetbrains.kotlin.diagnostics.DiagnosticFactory0
|
||||||
import org.jetbrains.kotlin.idea.KotlinBundle
|
import org.jetbrains.kotlin.idea.KotlinBundle
|
||||||
import org.jetbrains.kotlin.idea.core.canBeInternal
|
import org.jetbrains.kotlin.idea.core.*
|
||||||
import org.jetbrains.kotlin.idea.core.canBePrivate
|
|
||||||
import org.jetbrains.kotlin.idea.core.canBeProtected
|
|
||||||
import org.jetbrains.kotlin.idea.core.setVisibility
|
|
||||||
import org.jetbrains.kotlin.idea.inspections.RemoveRedundantSetterFix
|
import org.jetbrains.kotlin.idea.inspections.RemoveRedundantSetterFix
|
||||||
import org.jetbrains.kotlin.idea.inspections.isRedundantSetter
|
import org.jetbrains.kotlin.idea.inspections.isRedundantSetter
|
||||||
import org.jetbrains.kotlin.idea.project.languageVersionSettings
|
import org.jetbrains.kotlin.idea.project.languageVersionSettings
|
||||||
@@ -62,7 +59,13 @@ open class ChangeVisibilityFix(
|
|||||||
}
|
}
|
||||||
|
|
||||||
protected class ChangeToPublicFix(element: KtModifierListOwner, elementName: String) :
|
protected class ChangeToPublicFix(element: KtModifierListOwner, elementName: String) :
|
||||||
ChangeVisibilityFix(element, elementName, KtTokens.PUBLIC_KEYWORD), HighPriorityAction
|
ChangeVisibilityFix(element, elementName, KtTokens.PUBLIC_KEYWORD), HighPriorityAction {
|
||||||
|
|
||||||
|
override fun isAvailable(project: Project, editor: Editor?, file: KtFile): Boolean {
|
||||||
|
val element = element ?: return false
|
||||||
|
return element.canBePublic()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
protected class ChangeToProtectedFix(element: KtModifierListOwner, elementName: String) :
|
protected class ChangeToProtectedFix(element: KtModifierListOwner, elementName: String) :
|
||||||
ChangeVisibilityFix(element, elementName, KtTokens.PROTECTED_KEYWORD) {
|
ChangeVisibilityFix(element, elementName, KtTokens.PROTECTED_KEYWORD) {
|
||||||
|
|||||||
+2
@@ -0,0 +1,2 @@
|
|||||||
|
// IS_APPLICABLE: false
|
||||||
|
sealed class C <caret>private constructor()
|
||||||
+4
@@ -0,0 +1,4 @@
|
|||||||
|
// IS_APPLICABLE: false
|
||||||
|
sealed class C {
|
||||||
|
<caret>private constructor()
|
||||||
|
}
|
||||||
+2
@@ -0,0 +1,2 @@
|
|||||||
|
// IS_APPLICABLE: false
|
||||||
|
sealed class C <caret>private constructor()
|
||||||
+4
@@ -0,0 +1,4 @@
|
|||||||
|
// IS_APPLICABLE: false
|
||||||
|
sealed class C {
|
||||||
|
<caret>private constructor()
|
||||||
|
}
|
||||||
@@ -3402,6 +3402,16 @@ public class IntentionTestGenerated extends AbstractIntentionTest {
|
|||||||
runTest("idea/testData/intentions/changeVisibility/internal/notForAnnotationClassPrimaryConstructor.kt");
|
runTest("idea/testData/intentions/changeVisibility/internal/notForAnnotationClassPrimaryConstructor.kt");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@TestMetadata("notForSealedPrimaryConstructor.kt")
|
||||||
|
public void testNotForSealedPrimaryConstructor() throws Exception {
|
||||||
|
runTest("idea/testData/intentions/changeVisibility/internal/notForSealedPrimaryConstructor.kt");
|
||||||
|
}
|
||||||
|
|
||||||
|
@TestMetadata("notForSealedSecondaryConstructor.kt")
|
||||||
|
public void testNotForSealedSecondaryConstructor() throws Exception {
|
||||||
|
runTest("idea/testData/intentions/changeVisibility/internal/notForSealedSecondaryConstructor.kt");
|
||||||
|
}
|
||||||
|
|
||||||
@TestMetadata("propertySetter.kt")
|
@TestMetadata("propertySetter.kt")
|
||||||
public void testPropertySetter() throws Exception {
|
public void testPropertySetter() throws Exception {
|
||||||
runTest("idea/testData/intentions/changeVisibility/internal/propertySetter.kt");
|
runTest("idea/testData/intentions/changeVisibility/internal/propertySetter.kt");
|
||||||
@@ -3726,6 +3736,16 @@ public class IntentionTestGenerated extends AbstractIntentionTest {
|
|||||||
runTest("idea/testData/intentions/changeVisibility/public/destructuringPropertyException.kt");
|
runTest("idea/testData/intentions/changeVisibility/public/destructuringPropertyException.kt");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@TestMetadata("notForSealedPrimaryConstructor.kt")
|
||||||
|
public void testNotForSealedPrimaryConstructor() throws Exception {
|
||||||
|
runTest("idea/testData/intentions/changeVisibility/public/notForSealedPrimaryConstructor.kt");
|
||||||
|
}
|
||||||
|
|
||||||
|
@TestMetadata("notForSealedSecondaryConstructor.kt")
|
||||||
|
public void testNotForSealedSecondaryConstructor() throws Exception {
|
||||||
|
runTest("idea/testData/intentions/changeVisibility/public/notForSealedSecondaryConstructor.kt");
|
||||||
|
}
|
||||||
|
|
||||||
@TestMetadata("primaryConstructor.kt")
|
@TestMetadata("primaryConstructor.kt")
|
||||||
public void testPrimaryConstructor() throws Exception {
|
public void testPrimaryConstructor() throws Exception {
|
||||||
runTest("idea/testData/intentions/changeVisibility/public/primaryConstructor.kt");
|
runTest("idea/testData/intentions/changeVisibility/public/primaryConstructor.kt");
|
||||||
|
|||||||
Reference in New Issue
Block a user