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.*
import org.jetbrains.kotlin.psi.addRemoveModifier.MODIFIERS_ORDER import org.jetbrains.kotlin.psi.addRemoveModifier.MODIFIERS_ORDER
import org.jetbrains.kotlin.psi.psiUtil.* import org.jetbrains.kotlin.psi.psiUtil.*
import org.jetbrains.kotlin.psi.synthetics.findClassDescriptor
import org.jetbrains.kotlin.psi.typeRefHelpers.setReceiverTypeReference import org.jetbrains.kotlin.psi.typeRefHelpers.setReceiverTypeReference
import org.jetbrains.kotlin.resolve.BindingContext import org.jetbrains.kotlin.resolve.BindingContext
import org.jetbrains.kotlin.resolve.OverridingUtil 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.types.typeUtil.isTypeParameter
import org.jetbrains.kotlin.utils.KotlinExceptionWithAttachments import org.jetbrains.kotlin.utils.KotlinExceptionWithAttachments
import org.jetbrains.kotlin.utils.SmartList import org.jetbrains.kotlin.utils.SmartList
import org.jetbrains.kotlin.utils.addToStdlib.safeAs
fun KtLambdaArgument.moveInsideParentheses(bindingContext: BindingContext): KtCallExpression { fun KtLambdaArgument.moveInsideParentheses(bindingContext: BindingContext): KtCallExpression {
val ktExpression = this.getArgumentExpression() val ktExpression = this.getArgumentExpression()
@@ -365,9 +367,9 @@ fun KtModifierListOwner.canBeProtected(): Boolean {
else -> this.parent else -> this.parent
} }
return when (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 KtParameterList -> parent.parent is KtPrimaryConstructor
is KtClass -> !this.isAnnotationClassPrimaryConstructor() is KtClass -> !this.isAnnotationClassPrimaryConstructor() && !this.isFinalClassConstructor()
else -> false else -> false
} }
} }
@@ -383,6 +385,12 @@ fun KtModifierListOwner.canBeInternal(): Boolean {
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.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 { private fun KtModifierListOwner.isSealedClassConstructor(): Boolean {
if (this !is KtConstructor<*>) return false if (this !is KtConstructor<*>) return false
val ktClass = getContainingClassOrObject().safeAs<KtClass>() ?: 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: Convert to primary constructor
// ACTION: Make internal // ACTION: Make internal
// ACTION: Make private // ACTION: Make private
// ACTION: Make protected
class Ctor { class Ctor {
<caret>constructor(p: Int) <caret>constructor(p: Int)
@@ -2,7 +2,6 @@
// ACTION: Convert to primary constructor // ACTION: Convert to primary constructor
// ACTION: Make internal // ACTION: Make internal
// ACTION: Make private // ACTION: Make private
// ACTION: Make protected
class CtorUsedByOtherCtor { class CtorUsedByOtherCtor {
<caret>constructor() <caret>constructor()
@@ -2,7 +2,6 @@
// ACTION: Create test // ACTION: Create test
// ACTION: Make primary constructor internal // ACTION: Make primary constructor internal
// ACTION: Make primary constructor private // ACTION: Make primary constructor private
// ACTION: Make primary constructor protected
// ACTION: Enable a trailing comma by default in the formatter // ACTION: Enable a trailing comma by default in the formatter
// ACTION: Extract 'C' from current file // ACTION: Extract 'C' from current file
// ACTION: Rename file to C.kt // ACTION: Rename file to C.kt
@@ -3673,6 +3673,31 @@ public class IntentionTestGenerated extends AbstractIntentionTest {
runTest("idea/testData/intentions/changeVisibility/protected/notForAnnotationPrimaryConstructor.kt"); 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") @TestMetadata("notForNonValParameter.kt")
public void testNotForNonValParameter() throws Exception { public void testNotForNonValParameter() throws Exception {
runTest("idea/testData/intentions/changeVisibility/protected/notForNonValParameter.kt"); runTest("idea/testData/intentions/changeVisibility/protected/notForNonValParameter.kt");