mirror of
https://gitflic.ru/project/openide/openide.git
synced 2026-09-27 10:03:11 +07:00
[kotlin] Port ChangeToUseSpreadOperatorFix to K2
^KTIJ-29614 GitOrigin-RevId: 12491bc9442c1df1cead4fe2f5932eaf7b310729
This commit is contained in:
committed by
intellij-monorepo-bot
parent
0ebe5ef4c9
commit
a8adbe84e9
+72
@@ -0,0 +1,72 @@
|
||||
// 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 org.jetbrains.kotlin.analysis.api.KaSession
|
||||
import org.jetbrains.kotlin.analysis.api.KaStarTypeProjection
|
||||
import org.jetbrains.kotlin.analysis.api.calls.KaErrorCallInfo
|
||||
import org.jetbrains.kotlin.analysis.api.calls.KaFunctionCall
|
||||
import org.jetbrains.kotlin.analysis.api.calls.symbol
|
||||
import org.jetbrains.kotlin.analysis.api.components.buildClassType
|
||||
import org.jetbrains.kotlin.analysis.api.fir.diagnostics.KaFirDiagnostic
|
||||
import org.jetbrains.kotlin.analysis.api.types.KaCapturedType
|
||||
import org.jetbrains.kotlin.analysis.api.types.KaNonErrorClassType
|
||||
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.ChangeToUseSpreadOperatorFix
|
||||
import org.jetbrains.kotlin.name.FqName
|
||||
import org.jetbrains.kotlin.psi.KtCallExpression
|
||||
import org.jetbrains.kotlin.psi.KtReferenceExpression
|
||||
import org.jetbrains.kotlin.psi.psiUtil.getStrictParentOfType
|
||||
|
||||
internal object ChangeToUseSpreadOperatorFixFactory {
|
||||
|
||||
val changeToUseSpreadOperatorFixFactory = KotlinQuickFixFactory.ModCommandBased { diagnostic: KaFirDiagnostic.ArgumentTypeMismatch ->
|
||||
val element = diagnostic.psi as? KtReferenceExpression ?: return@ModCommandBased emptyList()
|
||||
val callExpression = element.getStrictParentOfType<KtCallExpression>() ?: return@ModCommandBased emptyList()
|
||||
val arrayElementType = diagnostic.actualType.getArrayElementType()?.unwrap() ?: return@ModCommandBased emptyList()
|
||||
val functionCall = (callExpression.resolveCall() as? KaErrorCallInfo)?.candidateCalls?.singleOrNull() as? KaFunctionCall<*>
|
||||
?: return@ModCommandBased emptyList()
|
||||
|
||||
if (functionCall.argumentMapping[element]?.symbol?.isVararg != true &&
|
||||
functionCall.symbol.callableId?.asSingleFqName() != FqName("kotlin.collections.mapOf")
|
||||
) {
|
||||
return@ModCommandBased emptyList()
|
||||
}
|
||||
|
||||
val buildType = substituteTypeParameterTypesWithStarTypeProjections(diagnostic.expectedType) ?: return@ModCommandBased emptyList()
|
||||
if (!arrayElementType.isSubTypeOf(buildType)) return@ModCommandBased emptyList()
|
||||
|
||||
listOf(
|
||||
ChangeToUseSpreadOperatorFix(element)
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
private fun KaType.unwrap(): KaType {
|
||||
return (this as? KaCapturedType)?.projection?.type ?: this
|
||||
}
|
||||
|
||||
/**
|
||||
* Substitute type parameter types in the given [type] with star type projections.
|
||||
*
|
||||
* For instance, given Pair<T, Pair<Int, U>>, the function returns Pair<*, Pair<Int, *>>.
|
||||
*/
|
||||
context(KaSession)
|
||||
private fun substituteTypeParameterTypesWithStarTypeProjections(type: KaType): KaType? {
|
||||
return when (type) {
|
||||
is KaNonErrorClassType -> buildClassType(type.classSymbol) {
|
||||
type.ownTypeArguments.mapNotNull { it.type }.forEach {
|
||||
if (it is KaTypeParameterType) {
|
||||
argument(KaStarTypeProjection(token))
|
||||
} else {
|
||||
substituteTypeParameterTypesWithStarTypeProjections(it)?.let { type ->
|
||||
argument(type)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
else -> null
|
||||
}
|
||||
}
|
||||
+1
@@ -113,6 +113,7 @@ class KotlinK2QuickFixRegistrar : KotlinQuickFixRegistrar() {
|
||||
registerPsiQuickFixes(KaFirDiagnostic.InvalidIfAsExpression::class, AddIfElseBranchFix)
|
||||
registerFactory(RemoveSupertypeFixFactory.removeSupertypeFixFactory)
|
||||
registerFactory(NumberConversionFixFactory.numberConversionFixFactory)
|
||||
registerFactory(ChangeToUseSpreadOperatorFixFactory.changeToUseSpreadOperatorFixFactory)
|
||||
}
|
||||
|
||||
private val addAbstract = KtQuickFixesListBuilder.registerPsiQuickFix {
|
||||
|
||||
+62
@@ -6093,7 +6093,69 @@ public abstract class HighLevelQuickFixTestGenerated extends AbstractHighLevelQu
|
||||
|
||||
|
||||
|
||||
@RunWith(JUnit3RunnerWithInners.class)
|
||||
@TestMetadata("../../../idea/tests/testData/quickfix/changeToUseSpreadOperator")
|
||||
public static class ChangeToUseSpreadOperator 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("differentTypeParameter.kt")
|
||||
public void testDifferentTypeParameter() throws Exception {
|
||||
runTest("../../../idea/tests/testData/quickfix/changeToUseSpreadOperator/differentTypeParameter.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("differentTypeParameterGeneric.kt")
|
||||
public void testDifferentTypeParameterGeneric() throws Exception {
|
||||
runTest("../../../idea/tests/testData/quickfix/changeToUseSpreadOperator/differentTypeParameterGeneric.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("mapOf.kt")
|
||||
public void testMapOf() throws Exception {
|
||||
runTest("../../../idea/tests/testData/quickfix/changeToUseSpreadOperator/mapOf.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("multipleParams.kt")
|
||||
public void testMultipleParams() throws Exception {
|
||||
runTest("../../../idea/tests/testData/quickfix/changeToUseSpreadOperator/multipleParams.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("nestedGeneric.kt")
|
||||
public void testNestedGeneric() throws Exception {
|
||||
runTest("../../../idea/tests/testData/quickfix/changeToUseSpreadOperator/nestedGeneric.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("nonArray.kt")
|
||||
public void testNonArray() throws Exception {
|
||||
runTest("../../../idea/tests/testData/quickfix/changeToUseSpreadOperator/nonArray.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("nonVarArg.kt")
|
||||
public void testNonVarArg() throws Exception {
|
||||
runTest("../../../idea/tests/testData/quickfix/changeToUseSpreadOperator/nonVarArg.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("normal.kt")
|
||||
public void testNormal() throws Exception {
|
||||
runTest("../../../idea/tests/testData/quickfix/changeToUseSpreadOperator/normal.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("stdlibMapOf.kt")
|
||||
public void testStdlibMapOf() throws Exception {
|
||||
runTest("../../../idea/tests/testData/quickfix/changeToUseSpreadOperator/stdlibMapOf.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("vararg.kt")
|
||||
public void testVararg() throws Exception {
|
||||
runTest("../../../idea/tests/testData/quickfix/changeToUseSpreadOperator/vararg.kt");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
+10
@@ -3738,6 +3738,11 @@ public abstract class K1QuickFixTestGenerated extends AbstractK1QuickFixTest {
|
||||
runTest("testData/quickfix/changeToUseSpreadOperator/differentTypeParameter.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("differentTypeParameterGeneric.kt")
|
||||
public void testDifferentTypeParameterGeneric() throws Exception {
|
||||
runTest("testData/quickfix/changeToUseSpreadOperator/differentTypeParameterGeneric.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("mapOf.kt")
|
||||
public void testMapOf() throws Exception {
|
||||
runTest("testData/quickfix/changeToUseSpreadOperator/mapOf.kt");
|
||||
@@ -3748,6 +3753,11 @@ public abstract class K1QuickFixTestGenerated extends AbstractK1QuickFixTest {
|
||||
runTest("testData/quickfix/changeToUseSpreadOperator/multipleParams.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("nestedGeneric.kt")
|
||||
public void testNestedGeneric() throws Exception {
|
||||
runTest("testData/quickfix/changeToUseSpreadOperator/nestedGeneric.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("nonArray.kt")
|
||||
public void testNonArray() throws Exception {
|
||||
runTest("testData/quickfix/changeToUseSpreadOperator/nonArray.kt");
|
||||
|
||||
+8
@@ -0,0 +1,8 @@
|
||||
// "Change 'y' to '*y'" "false"
|
||||
|
||||
fun <T> foo(vararg x: Pair<List<String>, Pair<T, Number>>) {}
|
||||
|
||||
fun bar(y: Array<Pair<List<String>, Pair<Int, String>>>) = foo(<caret>y)
|
||||
|
||||
// IGNORE_K1
|
||||
// FUS_K2_QUICKFIX_NAME: org.jetbrains.kotlin.idea.quickfix.ChangeToUseSpreadOperatorFix
|
||||
@@ -6,4 +6,5 @@ fun <K, V> yourMapOf(vararg pairs: Pair<K, V>) {}
|
||||
fun myMapOf(vararg pairs: Pair<String,String>) {
|
||||
val myMap = yourMapOf(<caret>pairs)
|
||||
}
|
||||
// FUS_QUICKFIX_NAME: org.jetbrains.kotlin.idea.quickfix.ChangeToUseSpreadOperatorFix
|
||||
// FUS_QUICKFIX_NAME: org.jetbrains.kotlin.idea.quickfix.ChangeToUseSpreadOperatorFix
|
||||
// FUS_K2_QUICKFIX_NAME: org.jetbrains.kotlin.idea.quickfix.ChangeToUseSpreadOperatorFix
|
||||
+2
-1
@@ -6,4 +6,5 @@ fun <K, V> yourMapOf(vararg pairs: Pair<K, V>) {}
|
||||
fun myMapOf(vararg pairs: Pair<String,String>) {
|
||||
val myMap = yourMapOf(*pairs)
|
||||
}
|
||||
// FUS_QUICKFIX_NAME: org.jetbrains.kotlin.idea.quickfix.ChangeToUseSpreadOperatorFix
|
||||
// FUS_QUICKFIX_NAME: org.jetbrains.kotlin.idea.quickfix.ChangeToUseSpreadOperatorFix
|
||||
// FUS_K2_QUICKFIX_NAME: org.jetbrains.kotlin.idea.quickfix.ChangeToUseSpreadOperatorFix
|
||||
+2
-1
@@ -4,4 +4,5 @@ fun foo(a: String, vararg x: String, b: Int) {}
|
||||
|
||||
fun bar(array: Array<String>) = foo("aaa", array<caret>, b = 1)
|
||||
|
||||
// FUS_QUICKFIX_NAME: org.jetbrains.kotlin.idea.quickfix.ChangeToUseSpreadOperatorFix
|
||||
// FUS_QUICKFIX_NAME: org.jetbrains.kotlin.idea.quickfix.ChangeToUseSpreadOperatorFix
|
||||
// FUS_K2_QUICKFIX_NAME: org.jetbrains.kotlin.idea.quickfix.ChangeToUseSpreadOperatorFix
|
||||
+2
-1
@@ -4,4 +4,5 @@ fun foo(a: String, vararg x: String, b: Int) {}
|
||||
|
||||
fun bar(array: Array<String>) = foo("aaa", *array, b = 1)
|
||||
|
||||
// FUS_QUICKFIX_NAME: org.jetbrains.kotlin.idea.quickfix.ChangeToUseSpreadOperatorFix
|
||||
// FUS_QUICKFIX_NAME: org.jetbrains.kotlin.idea.quickfix.ChangeToUseSpreadOperatorFix
|
||||
// FUS_K2_QUICKFIX_NAME: org.jetbrains.kotlin.idea.quickfix.ChangeToUseSpreadOperatorFix
|
||||
@@ -0,0 +1,9 @@
|
||||
// "Change 'y' to '*y'" "true"
|
||||
// WITH_STDLIB
|
||||
|
||||
fun <T> foo(vararg x: Pair<List<String>, Pair<T, Number>>) {}
|
||||
|
||||
fun bar(y: Array<Pair<ArrayList<String>, Pair<Int, Int>>>) = foo(<caret>y)
|
||||
|
||||
// FUS_QUICKFIX_NAME: org.jetbrains.kotlin.idea.quickfix.ChangeToUseSpreadOperatorFix
|
||||
// FUS_K2_QUICKFIX_NAME: org.jetbrains.kotlin.idea.quickfix.ChangeToUseSpreadOperatorFix
|
||||
+9
@@ -0,0 +1,9 @@
|
||||
// "Change 'y' to '*y'" "true"
|
||||
// WITH_STDLIB
|
||||
|
||||
fun <T> foo(vararg x: Pair<List<String>, Pair<T, Number>>) {}
|
||||
|
||||
fun bar(y: Array<Pair<ArrayList<String>, Pair<Int, Int>>>) = foo(*y)
|
||||
|
||||
// FUS_QUICKFIX_NAME: org.jetbrains.kotlin.idea.quickfix.ChangeToUseSpreadOperatorFix
|
||||
// FUS_K2_QUICKFIX_NAME: org.jetbrains.kotlin.idea.quickfix.ChangeToUseSpreadOperatorFix
|
||||
@@ -4,4 +4,5 @@ fun foo(vararg x: String) {}
|
||||
|
||||
fun bar(y: Array<String>) = foo(y<caret>)
|
||||
|
||||
// FUS_QUICKFIX_NAME: org.jetbrains.kotlin.idea.quickfix.ChangeToUseSpreadOperatorFix
|
||||
// FUS_QUICKFIX_NAME: org.jetbrains.kotlin.idea.quickfix.ChangeToUseSpreadOperatorFix
|
||||
// FUS_K2_QUICKFIX_NAME: org.jetbrains.kotlin.idea.quickfix.ChangeToUseSpreadOperatorFix
|
||||
+2
-1
@@ -4,4 +4,5 @@ fun foo(vararg x: String) {}
|
||||
|
||||
fun bar(y: Array<String>) = foo(*y)
|
||||
|
||||
// FUS_QUICKFIX_NAME: org.jetbrains.kotlin.idea.quickfix.ChangeToUseSpreadOperatorFix
|
||||
// FUS_QUICKFIX_NAME: org.jetbrains.kotlin.idea.quickfix.ChangeToUseSpreadOperatorFix
|
||||
// FUS_K2_QUICKFIX_NAME: org.jetbrains.kotlin.idea.quickfix.ChangeToUseSpreadOperatorFix
|
||||
+2
-1
@@ -4,4 +4,5 @@
|
||||
fun myMapOf(vararg pairs: Pair<String,String>) {
|
||||
val myMap = mapOf(<caret>pairs)
|
||||
}
|
||||
// FUS_QUICKFIX_NAME: org.jetbrains.kotlin.idea.quickfix.ChangeToUseSpreadOperatorFix
|
||||
// FUS_QUICKFIX_NAME: org.jetbrains.kotlin.idea.quickfix.ChangeToUseSpreadOperatorFix
|
||||
// FUS_K2_QUICKFIX_NAME: org.jetbrains.kotlin.idea.quickfix.ChangeToUseSpreadOperatorFix
|
||||
+2
-1
@@ -4,4 +4,5 @@
|
||||
fun myMapOf(vararg pairs: Pair<String,String>) {
|
||||
val myMap = mapOf(*pairs)
|
||||
}
|
||||
// FUS_QUICKFIX_NAME: org.jetbrains.kotlin.idea.quickfix.ChangeToUseSpreadOperatorFix
|
||||
// FUS_QUICKFIX_NAME: org.jetbrains.kotlin.idea.quickfix.ChangeToUseSpreadOperatorFix
|
||||
// FUS_K2_QUICKFIX_NAME: org.jetbrains.kotlin.idea.quickfix.ChangeToUseSpreadOperatorFix
|
||||
@@ -4,4 +4,5 @@ fun foo(vararg x: String) {}
|
||||
|
||||
fun bar(vararg y: String) = foo(y<caret>)
|
||||
|
||||
// FUS_QUICKFIX_NAME: org.jetbrains.kotlin.idea.quickfix.ChangeToUseSpreadOperatorFix
|
||||
// FUS_QUICKFIX_NAME: org.jetbrains.kotlin.idea.quickfix.ChangeToUseSpreadOperatorFix
|
||||
// FUS_K2_QUICKFIX_NAME: org.jetbrains.kotlin.idea.quickfix.ChangeToUseSpreadOperatorFix
|
||||
+2
-1
@@ -4,4 +4,5 @@ fun foo(vararg x: String) {}
|
||||
|
||||
fun bar(vararg y: String) = foo(*y)
|
||||
|
||||
// FUS_QUICKFIX_NAME: org.jetbrains.kotlin.idea.quickfix.ChangeToUseSpreadOperatorFix
|
||||
// FUS_QUICKFIX_NAME: org.jetbrains.kotlin.idea.quickfix.ChangeToUseSpreadOperatorFix
|
||||
// FUS_K2_QUICKFIX_NAME: org.jetbrains.kotlin.idea.quickfix.ChangeToUseSpreadOperatorFix
|
||||
+1
-1
@@ -99,7 +99,7 @@ internal fun MutableTWorkspace.generateK2FixTests() {
|
||||
model("$idea/quickfix/changeSuperTypeListEntryTypeArgument", pattern = pattern, isIgnored = true)
|
||||
model("$idea/quickfix/changeToLabeledReturn", pattern = pattern)
|
||||
model("$idea/quickfix/changeToMutableCollection", pattern = pattern, isIgnored = true)
|
||||
model("$idea/quickfix/changeToUseSpreadOperator", pattern = pattern, isIgnored = true)
|
||||
model("$idea/quickfix/changeToUseSpreadOperator", pattern = pattern)
|
||||
model("$idea/quickfix/compilerError", pattern = pattern, isIgnored = true)
|
||||
model("$idea/quickfix/convertCollectionLiteralToIntArrayOf", pattern = pattern)
|
||||
model("$idea/quickfix/convertIllegalEscapeToUnicodeEscape", pattern = pattern, isIgnored = true)
|
||||
|
||||
Reference in New Issue
Block a user