[kotlin] Port AddGenericUpperBoundFix to K2

This quick is for the UPPER_BOUND_VIOLATED and UPPER_BOUND_VIOLATED_BASED_ON_JAVA_ANNOTATIONS compiler errors.

^KTIJ-29567

GitOrigin-RevId: b1741545da363c64cc3df770f5ce5443221536d9
This commit is contained in:
Andrey Cherkasov
2024-09-21 02:56:36 +00:00
committed by intellij-monorepo-bot
parent 5423cde31a
commit 1e90f85566
13 changed files with 128 additions and 9 deletions
@@ -0,0 +1,46 @@
// Copyright 2000-2024 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license.
package org.jetbrains.kotlin.idea.k2.codeinsight.fixes
import com.intellij.modcommand.ModCommandAction
import org.jetbrains.kotlin.analysis.api.KaExperimentalApi
import org.jetbrains.kotlin.analysis.api.KaSession
import org.jetbrains.kotlin.analysis.api.fir.diagnostics.KaFirDiagnostic
import org.jetbrains.kotlin.analysis.api.renderer.types.impl.KaTypeRendererForSource
import org.jetbrains.kotlin.analysis.api.types.KaType
import org.jetbrains.kotlin.analysis.api.types.KaTypeParameterType
import org.jetbrains.kotlin.idea.codeinsight.api.applicators.fixes.KotlinQuickFixFactory
import org.jetbrains.kotlin.idea.quickfix.AddGenericUpperBoundFix
import org.jetbrains.kotlin.psi.KtTypeParameter
import org.jetbrains.kotlin.types.Variance
internal object AddGenericUpperBoundFixFactories {
val upperBoundViolatedFixFactory = KotlinQuickFixFactory.ModCommandBased { diagnostic: KaFirDiagnostic.UpperBoundViolated ->
listOfNotNull(
createActionIfAvailable(diagnostic.expectedUpperBound, diagnostic.actualUpperBound)
)
}
val upperBoundViolatedBasedOnJavaAnnotationsFixFactory = KotlinQuickFixFactory.ModCommandBased { diagnostic: KaFirDiagnostic.UpperBoundViolatedBasedOnJavaAnnotations ->
listOfNotNull(
createActionIfAvailable(diagnostic.expectedUpperBound, diagnostic.actualUpperBound)
)
}
@OptIn(KaExperimentalApi::class)
private fun KaSession.createActionIfAvailable(
expectedUpperBound: KaType,
actualUpperBound: KaType,
): ModCommandAction? {
val typeParameter = (actualUpperBound as? KaTypeParameterType)?.symbol?.psi as? KtTypeParameter ?: return null
if (typeParameter.name == null || typeParameter.extendsBound != null) return null
return AddGenericUpperBoundFix(
element = typeParameter,
renderedUpperBound = expectedUpperBound.render(
renderer = KaTypeRendererForSource.WITH_QUALIFIED_NAMES,
position = Variance.IN_VARIANCE,
)
)
}
}
@@ -180,6 +180,8 @@ class KotlinK2QuickFixRegistrar : KotlinQuickFixRegistrar() {
registerFactory(ConvertKClassToClassFixFactories.initializerTypeMismatchFixFactory)
registerFactory(ConvertKClassToClassFixFactories.returnTypeMismatchFixFactory)
registerFactory(PropertyInitializerInInterfaceFixFactories.convertPropertyInitializerToGetterFixFactory)
registerFactory(AddGenericUpperBoundFixFactories.upperBoundViolatedFixFactory)
registerFactory(AddGenericUpperBoundFixFactories.upperBoundViolatedBasedOnJavaAnnotationsFixFactory)
}
private val addAbstract = KtQuickFixesListBuilder.registerPsiQuickFix {
@@ -1059,4 +1059,23 @@ public abstract class HighLevelQuickFixMultiFileTestGenerated extends AbstractHi
runTest("../../../idea/tests/testData/quickfix/modifiers/addOpenToClassDeclaration/finalJavaUpperBound.before.Main.kt");
}
}
@RunWith(JUnit3RunnerWithInners.class)
@TestMetadata("../../../idea/tests/testData/quickfix/addGenericUpperBound")
public static class AddGenericUpperBound extends AbstractHighLevelQuickFixMultiFileTest {
@java.lang.Override
@org.jetbrains.annotations.NotNull
public final KotlinPluginMode getPluginMode() {
return KotlinPluginMode.K2;
}
private void runTest(String testDataFilePath) throws Exception {
KotlinTestUtils.runTest(this::doTestWithExtraFile, this, testDataFilePath);
}
@TestMetadata("javaUpperBoundViolated.test")
public void testJavaUpperBoundViolated() throws Exception {
runTest("../../../idea/tests/testData/quickfix/addGenericUpperBound/javaUpperBoundViolated.test");
}
}
}
@@ -6129,7 +6129,44 @@ public abstract class HighLevelQuickFixTestGenerated extends AbstractHighLevelQu
}
}
@RunWith(JUnit3RunnerWithInners.class)
@TestMetadata("../../../idea/tests/testData/quickfix/addGenericUpperBound")
public static class AddGenericUpperBound extends AbstractHighLevelQuickFixTest {
@java.lang.Override
@org.jetbrains.annotations.NotNull
public final KotlinPluginMode getPluginMode() {
return KotlinPluginMode.K2;
}
private void runTest(String testDataFilePath) throws Exception {
KotlinTestUtils.runTest(this::doTest, this, testDataFilePath);
}
@TestMetadata("basic.kt")
public void testBasic() throws Exception {
runTest("../../../idea/tests/testData/quickfix/addGenericUpperBound/basic.kt");
}
@TestMetadata("boundAlreadyExists.kt")
public void testBoundAlreadyExists() throws Exception {
runTest("../../../idea/tests/testData/quickfix/addGenericUpperBound/boundAlreadyExists.kt");
}
@TestMetadata("inferenceTwoParams.kt")
public void testInferenceTwoParams() throws Exception {
runTest("../../../idea/tests/testData/quickfix/addGenericUpperBound/inferenceTwoParams.kt");
}
@TestMetadata("paramAsBound.kt")
public void testParamAsBound() throws Exception {
runTest("../../../idea/tests/testData/quickfix/addGenericUpperBound/paramAsBound.kt");
}
@TestMetadata("withinDeclaration.kt")
public void testWithinDeclaration() throws Exception {
runTest("../../../idea/tests/testData/quickfix/addGenericUpperBound/withinDeclaration.kt");
}
}
@RunWith(JUnit3RunnerWithInners.class)
@TestMetadata("../../../idea/tests/testData/quickfix/addInline")
@@ -4,4 +4,5 @@ fun <T : Any> foo() = 1
fun <E> bar() = foo<E<caret>>()
// FUS_QUICKFIX_NAME: org.jetbrains.kotlin.idea.quickfix.AddGenericUpperBoundFix
// FUS_QUICKFIX_NAME: org.jetbrains.kotlin.idea.quickfix.AddGenericUpperBoundFix
// FUS_K2_QUICKFIX_NAME: org.jetbrains.kotlin.idea.quickfix.AddGenericUpperBoundFix
@@ -4,4 +4,5 @@ fun <T : Any> foo() = 1
fun <E : Any> bar() = foo<E>()
// FUS_QUICKFIX_NAME: org.jetbrains.kotlin.idea.quickfix.AddGenericUpperBoundFix
// FUS_QUICKFIX_NAME: org.jetbrains.kotlin.idea.quickfix.AddGenericUpperBoundFix
// FUS_K2_QUICKFIX_NAME: org.jetbrains.kotlin.idea.quickfix.AddGenericUpperBoundFix
@@ -5,4 +5,6 @@ fun <T : Any, U: Any> foo(x: T, y: U) = 1
fun <E, F> bar(x: E, y: F) = foo(<caret>x, y)
// FUS_QUICKFIX_NAME: org.jetbrains.kotlin.idea.quickfix.HighPriorityMakeUpperBoundNonNullableFix
// FUS_QUICKFIX_NAME: org.jetbrains.kotlin.idea.quickfix.HighPriorityMakeUpperBoundNonNullableFix
// TODO: KTIJ-29580
/* IGNORE_K2 */
@@ -5,4 +5,6 @@ fun <T : Any, U: Any> foo(x: T, y: U) = 1
fun <E : Any, F> bar(x: E, y: F) = foo(<caret>x, y)
// FUS_QUICKFIX_NAME: org.jetbrains.kotlin.idea.quickfix.HighPriorityMakeUpperBoundNonNullableFix
// FUS_QUICKFIX_NAME: org.jetbrains.kotlin.idea.quickfix.HighPriorityMakeUpperBoundNonNullableFix
// TODO: KTIJ-29580
/* IGNORE_K2 */
@@ -4,4 +4,5 @@ fun <T, U : T> foo() = 1
fun <E, F> bar() = foo<E, F<caret>>()
// FUS_QUICKFIX_NAME: org.jetbrains.kotlin.idea.quickfix.AddGenericUpperBoundFix
// FUS_QUICKFIX_NAME: org.jetbrains.kotlin.idea.quickfix.AddGenericUpperBoundFix
// FUS_K2_QUICKFIX_NAME: org.jetbrains.kotlin.idea.quickfix.AddGenericUpperBoundFix
@@ -4,4 +4,5 @@ fun <T, U : T> foo() = 1
fun <E, F : E> bar() = foo<E, F<caret>>()
// FUS_QUICKFIX_NAME: org.jetbrains.kotlin.idea.quickfix.AddGenericUpperBoundFix
// FUS_QUICKFIX_NAME: org.jetbrains.kotlin.idea.quickfix.AddGenericUpperBoundFix
// FUS_K2_QUICKFIX_NAME: org.jetbrains.kotlin.idea.quickfix.AddGenericUpperBoundFix
@@ -3,4 +3,5 @@
class A<T : Any>
fun <E> bar(x: A<E<caret>>) {}
// FUS_QUICKFIX_NAME: org.jetbrains.kotlin.idea.quickfix.AddGenericUpperBoundFix
// FUS_QUICKFIX_NAME: org.jetbrains.kotlin.idea.quickfix.AddGenericUpperBoundFix
// FUS_K2_QUICKFIX_NAME: org.jetbrains.kotlin.idea.quickfix.AddGenericUpperBoundFix
@@ -3,4 +3,5 @@
class A<T : Any>
fun <E : Any> bar(x: A<E<caret>>) {}
// FUS_QUICKFIX_NAME: org.jetbrains.kotlin.idea.quickfix.AddGenericUpperBoundFix
// FUS_QUICKFIX_NAME: org.jetbrains.kotlin.idea.quickfix.AddGenericUpperBoundFix
// FUS_K2_QUICKFIX_NAME: org.jetbrains.kotlin.idea.quickfix.AddGenericUpperBoundFix
@@ -73,7 +73,7 @@ internal fun MutableTWorkspace.generateK2FixTests() {
model("$idea/quickfix/addEmptyArgumentList", pattern = pattern)
model("$idea/quickfix/addEqEqTrue", pattern = pattern)
model("$idea/quickfix/addFunModifier", pattern = pattern)
model("$idea/quickfix/addGenericUpperBound", pattern = pattern, isIgnored = true)
model("$idea/quickfix/addGenericUpperBound", pattern = pattern)
model("$idea/quickfix/addInline", pattern = pattern)
model("$idea/quickfix/addInlineToReifiedFunctionFix", pattern = pattern)
model("$idea/quickfix/addIsToWhenCondition", pattern = pattern)
@@ -228,6 +228,11 @@ internal fun MutableTWorkspace.generateK2FixTests() {
pattern = pattern,
testMethodName = testMethodName,
)
model(
"$idea/quickfix/addGenericUpperBound",
pattern = pattern,
testMethodName = testMethodName,
)
}
testClass<AbstractHighLevelQuickFixMultiModuleTest> {