[kotlin] K2 IDE: Add fix for FINAL_SUPERTYPE

^KTIJ-23928 Fixed

closes https://github.com/JetBrains/intellij-community/pull/2332

GitOrigin-RevId: 064e38feaea811c1e3a55a862b48e96f24663cdd
This commit is contained in:
Toshiaki Kameyama
2023-02-22 09:49:46 +00:00
committed by intellij-monorepo-bot
parent a26ecf7a5a
commit f811fb689f
10 changed files with 142 additions and 6 deletions
@@ -71,6 +71,7 @@ class KotlinK2QuickFixRegistrar : KotlinQuickFixRegistrar() {
registerPsiQuickFixes(KtFirDiagnostic.ValOrVarOnFunParameter::class, RemoveValVarFromParameterFix)
registerPsiQuickFixes(KtFirDiagnostic.ValOrVarOnCatchParameter::class, RemoveValVarFromParameterFix)
registerPsiQuickFixes(KtFirDiagnostic.ValOrVarOnSecondaryConstructorParameter::class, RemoveValVarFromParameterFix)
registerApplicators(MakeSuperTypeOpenFixFactory.makeSuperTypeOpenFixFactory)
}
private val propertyInitialization = KtQuickFixesListBuilder.registerPsiQuickFix {
@@ -0,0 +1,24 @@
// Copyright 2000-2023 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license.
package org.jetbrains.kotlin.idea.quickfix.fixes
import org.jetbrains.kotlin.analysis.api.fir.diagnostics.KtFirDiagnostic.FinalSupertype
import org.jetbrains.kotlin.analysis.api.fir.diagnostics.KtFirDiagnostic.FinalUpperBound
import org.jetbrains.kotlin.analysis.api.symbols.psiSafe
import org.jetbrains.kotlin.idea.codeinsight.api.applicators.fixes.diagnosticFixFactories
import org.jetbrains.kotlin.idea.quickfix.AddModifierFix
import org.jetbrains.kotlin.idea.refactoring.canRefactor
import org.jetbrains.kotlin.lexer.KtTokens
import org.jetbrains.kotlin.psi.KtClassOrObject
import org.jetbrains.kotlin.psi.KtTypeReference
object MakeSuperTypeOpenFixFactory {
val makeSuperTypeOpenFixFactory = diagnosticFixFactories(
FinalSupertype::class,
FinalUpperBound::class
) { diagnostic ->
val typeRef = diagnostic.psi as? KtTypeReference ?: return@diagnosticFixFactories emptyList()
val superType = typeRef.getKtType().expandedClassSymbol?.psiSafe<KtClassOrObject>() ?: return@diagnosticFixFactories emptyList()
if (!superType.canRefactor()) return@diagnosticFixFactories emptyList()
listOfNotNull(AddModifierFix.createIfApplicable(superType, KtTokens.OPEN_KEYWORD))
}
}
@@ -1225,6 +1225,104 @@ public abstract class HighLevelQuickFixTestGenerated extends AbstractHighLevelQu
}
}
@RunWith(JUnit3RunnerWithInners.class)
@TestMetadata("../idea/tests/testData/quickfix/modifiers/addOpenToClassDeclaration")
public static class AddOpenToClassDeclaration extends AbstractHighLevelQuickFixTest {
private void runTest(String testDataFilePath) throws Exception {
KotlinTestUtils.runTest(this::doTest, this, testDataFilePath);
}
@TestMetadata("annotationSuperType.kt")
public void testAnnotationSuperType() throws Exception {
runTest("../idea/tests/testData/quickfix/modifiers/addOpenToClassDeclaration/annotationSuperType.kt");
}
@TestMetadata("dataSuperType.kt")
public void testDataSuperType() throws Exception {
runTest("../idea/tests/testData/quickfix/modifiers/addOpenToClassDeclaration/dataSuperType.kt");
}
@TestMetadata("enumSupertype.kt")
public void testEnumSupertype() throws Exception {
runTest("../idea/tests/testData/quickfix/modifiers/addOpenToClassDeclaration/enumSupertype.kt");
}
@TestMetadata("enumUpperBound.kt")
public void testEnumUpperBound() throws Exception {
runTest("../idea/tests/testData/quickfix/modifiers/addOpenToClassDeclaration/enumUpperBound.kt");
}
@TestMetadata("explicitlyFinalSupertype.kt")
public void testExplicitlyFinalSupertype() throws Exception {
runTest("../idea/tests/testData/quickfix/modifiers/addOpenToClassDeclaration/explicitlyFinalSupertype.kt");
}
@TestMetadata("explicitlyFinalUpperBound.kt")
public void testExplicitlyFinalUpperBound() throws Exception {
runTest("../idea/tests/testData/quickfix/modifiers/addOpenToClassDeclaration/explicitlyFinalUpperBound.kt");
}
@TestMetadata("finalLibrarySupertype.kt")
public void testFinalLibrarySupertype() throws Exception {
runTest("../idea/tests/testData/quickfix/modifiers/addOpenToClassDeclaration/finalLibrarySupertype.kt");
}
@TestMetadata("finalLibraryUpperBound.kt")
public void testFinalLibraryUpperBound() throws Exception {
runTest("../idea/tests/testData/quickfix/modifiers/addOpenToClassDeclaration/finalLibraryUpperBound.kt");
}
@TestMetadata("finalSupertype.kt")
public void testFinalSupertype() throws Exception {
runTest("../idea/tests/testData/quickfix/modifiers/addOpenToClassDeclaration/finalSupertype.kt");
}
@TestMetadata("finalUpperBound.kt")
public void testFinalUpperBound() throws Exception {
runTest("../idea/tests/testData/quickfix/modifiers/addOpenToClassDeclaration/finalUpperBound.kt");
}
@TestMetadata("implementInterfaceFinalSupertype.kt")
public void testImplementInterfaceFinalSupertype() throws Exception {
runTest("../idea/tests/testData/quickfix/modifiers/addOpenToClassDeclaration/implementInterfaceFinalSupertype.kt");
}
@TestMetadata("inlineSuperType.kt")
public void testInlineSuperType() throws Exception {
runTest("../idea/tests/testData/quickfix/modifiers/addOpenToClassDeclaration/inlineSuperType.kt");
}
@TestMetadata("nestedFinalClass.kt")
public void testNestedFinalClass() throws Exception {
runTest("../idea/tests/testData/quickfix/modifiers/addOpenToClassDeclaration/nestedFinalClass.kt");
}
@TestMetadata("openInCompanion.kt")
public void testOpenInCompanion() throws Exception {
runTest("../idea/tests/testData/quickfix/modifiers/addOpenToClassDeclaration/openInCompanion.kt");
}
@TestMetadata("secondaryCtrDelegationInHeader.kt")
public void testSecondaryCtrDelegationInHeader() throws Exception {
runTest("../idea/tests/testData/quickfix/modifiers/addOpenToClassDeclaration/secondaryCtrDelegationInHeader.kt");
}
@TestMetadata("secondaryCtrDelegationInSecondary.kt")
public void testSecondaryCtrDelegationInSecondary() throws Exception {
runTest("../idea/tests/testData/quickfix/modifiers/addOpenToClassDeclaration/secondaryCtrDelegationInSecondary.kt");
}
@TestMetadata("valueSuperType.kt")
public void testValueSuperType() throws Exception {
runTest("../idea/tests/testData/quickfix/modifiers/addOpenToClassDeclaration/valueSuperType.kt");
}
@TestMetadata("withConstructor.kt")
public void testWithConstructor() throws Exception {
runTest("../idea/tests/testData/quickfix/modifiers/addOpenToClassDeclaration/withConstructor.kt");
}
}
@RunWith(JUnit3RunnerWithInners.class)
@TestMetadata("../idea/tests/testData/quickfix/nullables")
public abstract static class Nullables extends AbstractHighLevelQuickFixTest {
@@ -1,5 +1,8 @@
// "class org.jetbrains.kotlin.idea.quickfix.AddModifierFix" "false"
// "Make 'E' open" "false"
// ERROR: This type is final, so it cannot be inherited from
// ERROR: Cannot access '<init>': it is private in 'E'
// ACTION: Introduce import alias
// ACTION: Make '<init>' internal
// ACTION: Make '<init>' public
enum class E {}
class A : E<caret>() {}
@@ -1,3 +1,6 @@
// "class org.jetbrains.kotlin.idea.quickfix.AddModifierFix" "false"
// "Make 'E' open" "false"
// ACTION: Create test
// ACTION: Enable a trailing comma by default in the formatter
// ACTION: Introduce import alias
enum class E {}
class A<T : E<caret>> {}
@@ -1,4 +1,4 @@
// "class org.jetbrains.kotlin.idea.quickfix.AddModifierFix" "false"
// "Make 'JavaClass' open" "false"
// ERROR: This type is final, so it cannot be inherited from
// ACTION: Create test
// ACTION: Introduce import alias
@@ -1,4 +1,4 @@
// "class org.jetbrains.kotlin.idea.quickfix.AddModifierFix" "false"
// "Make 'JavaClass' open" "false"
// ACTION: Convert to secondary constructor
// ACTION: Create test
// ACTION: Enable a trailing comma by default in the formatter
@@ -1,3 +1,4 @@
// "class org.jetbrains.kotlin.idea.quickfix.AddModifierFix" "false"
// "Make 'String' open" "false"
// ERROR: This type is final, so it cannot be inherited from
// ACTION: Add full qualifier
class A : String<caret>() {}
@@ -1,2 +1,7 @@
// "class org.jetbrains.kotlin.idea.quickfix.AddModifierFix" "false"
// "Make 'String' open" "false"
// ACTION: Add full qualifier
// ACTION: Create test
// ACTION: Enable a trailing comma by default in the formatter
// ACTION: Inline type parameter
// ACTION: Remove final upper bound
class A<T : String<caret>> {}
@@ -103,6 +103,7 @@ private fun assembleWorkspace(): TWorkspace = workspace {
model("quickfix/lateinit", pattern = pattern)
model("quickfix/localVariableWithTypeParameters", pattern = pattern)
model("quickfix/modifiers", pattern = pattern, isRecursive = false)
model("quickfix/modifiers/addOpenToClassDeclaration", pattern = pattern)
model("quickfix/nullables", pattern = pattern)
model("quickfix/override", pattern = pattern, isRecursive = false)
model("quickfix/override/typeMismatchOnOverride", pattern = pattern, isRecursive = false)