KT-46146 no 'protected' for final classes

Intention to change final class constructor visibility to 'protected'
was erroneous. This commit removes it.
This commit is contained in:
Andrei Klunnyi
2021-05-06 16:40:00 +03:00
committed by Space
parent e56a3b3c30
commit b7eded6e48
12 changed files with 47 additions and 7 deletions
@@ -32,6 +32,7 @@ import org.jetbrains.kotlin.name.Name
import org.jetbrains.kotlin.psi.*
import org.jetbrains.kotlin.psi.addRemoveModifier.MODIFIERS_ORDER
import org.jetbrains.kotlin.psi.psiUtil.*
import org.jetbrains.kotlin.psi.synthetics.findClassDescriptor
import org.jetbrains.kotlin.psi.typeRefHelpers.setReceiverTypeReference
import org.jetbrains.kotlin.resolve.BindingContext
import org.jetbrains.kotlin.resolve.OverridingUtil
@@ -47,6 +48,7 @@ import org.jetbrains.kotlin.types.isError
import org.jetbrains.kotlin.types.typeUtil.isTypeParameter
import org.jetbrains.kotlin.utils.KotlinExceptionWithAttachments
import org.jetbrains.kotlin.utils.SmartList
import org.jetbrains.kotlin.utils.addToStdlib.safeAs
fun KtLambdaArgument.moveInsideParentheses(bindingContext: BindingContext): KtCallExpression {
val ktExpression = this.getArgumentExpression()
@@ -365,9 +367,9 @@ fun KtModifierListOwner.canBeProtected(): Boolean {
else -> this.parent
}
return when (parent) {
is KtClassBody -> parent.parent is KtClass
is KtClassBody -> parent.parent is KtClass && !this.isFinalClassConstructor()
is KtParameterList -> parent.parent is KtPrimaryConstructor
is KtClass -> !this.isAnnotationClassPrimaryConstructor()
is KtClass -> !this.isAnnotationClassPrimaryConstructor() && !this.isFinalClassConstructor()
else -> false
}
}
@@ -383,6 +385,12 @@ fun KtModifierListOwner.canBeInternal(): Boolean {
private fun KtModifierListOwner.isAnnotationClassPrimaryConstructor(): Boolean =
this is KtPrimaryConstructor && (this.parent as? KtClass)?.hasModifier(KtTokens.ANNOTATION_KEYWORD) ?: false
private fun KtModifierListOwner.isFinalClassConstructor(): Boolean {
if (this !is KtConstructor<*>) return false
val ktClass = getContainingClassOrObject().safeAs<KtClass>() ?: return false
return ktClass.toDescriptor().safeAs<ClassDescriptor>()?.isFinalOrEnum ?: return false
}
private fun KtModifierListOwner.isSealedClassConstructor(): Boolean {
if (this !is KtConstructor<*>) return false
val ktClass = getContainingClassOrObject().safeAs<KtClass>() ?: return false
@@ -0,0 +1,2 @@
// IS_APPLICABLE: false
class ImplicitFinalClass <caret>public constructor()
@@ -0,0 +1,2 @@
// IS_APPLICABLE: false
final class ExplicitFinalClass <caret>public constructor()
@@ -0,0 +1,2 @@
// IS_APPLICABLE: false
data class DataClass(val a: Int) <caret>private constructor()
@@ -0,0 +1,2 @@
// IS_APPLICABLE: false
inline class InlineClass(val a: Int) <caret>private constructor()
@@ -0,0 +1,2 @@
// IS_APPLICABLE: false
enum class EnumClass(val a: Int) <caret>private constructor()
@@ -1 +1 @@
class RegularClass <caret>private constructor()
open class RegularClass <caret>private constructor()
@@ -1 +1 @@
class RegularClass <caret>protected constructor()
open class RegularClass <caret>protected constructor()
@@ -2,7 +2,6 @@
// ACTION: Convert to primary constructor
// ACTION: Make internal
// ACTION: Make private
// ACTION: Make protected
class Ctor {
<caret>constructor(p: Int)
@@ -2,7 +2,6 @@
// ACTION: Convert to primary constructor
// ACTION: Make internal
// ACTION: Make private
// ACTION: Make protected
class CtorUsedByOtherCtor {
<caret>constructor()
@@ -2,7 +2,6 @@
// ACTION: Create test
// ACTION: Make primary constructor internal
// ACTION: Make primary constructor private
// ACTION: Make primary constructor protected
// ACTION: Enable a trailing comma by default in the formatter
// ACTION: Extract 'C' from current file
// ACTION: Rename file to C.kt
@@ -3673,6 +3673,31 @@ public class IntentionTestGenerated extends AbstractIntentionTest {
runTest("idea/testData/intentions/changeVisibility/protected/notForAnnotationPrimaryConstructor.kt");
}
@TestMetadata("notForFinalClass1.kt")
public void testNotForFinalClass1() throws Exception {
runTest("idea/testData/intentions/changeVisibility/protected/notForFinalClass1.kt");
}
@TestMetadata("notForFinalClass2.kt")
public void testNotForFinalClass2() throws Exception {
runTest("idea/testData/intentions/changeVisibility/protected/notForFinalClass2.kt");
}
@TestMetadata("notForFinalClass3.kt")
public void testNotForFinalClass3() throws Exception {
runTest("idea/testData/intentions/changeVisibility/protected/notForFinalClass3.kt");
}
@TestMetadata("notForFinalClass4.kt")
public void testNotForFinalClass4() throws Exception {
runTest("idea/testData/intentions/changeVisibility/protected/notForFinalClass4.kt");
}
@TestMetadata("notForFinalClass5.kt")
public void testNotForFinalClass5() throws Exception {
runTest("idea/testData/intentions/changeVisibility/protected/notForFinalClass5.kt");
}
@TestMetadata("notForNonValParameter.kt")
public void testNotForNonValParameter() throws Exception {
runTest("idea/testData/intentions/changeVisibility/protected/notForNonValParameter.kt");