Quick-fix "use spread operator": make working with mapOf #KT-14556 Fixed

This commit is contained in:
Toshiaki Kameyama
2018-04-10 07:53:24 +03:00
committed by Mikhail Glukhikh
parent a7110a1517
commit 5204c73bec
5 changed files with 30 additions and 22 deletions
@@ -28,6 +28,7 @@ import org.jetbrains.kotlin.idea.caches.resolve.getResolutionFacade
import org.jetbrains.kotlin.idea.core.quickfix.QuickFixUtil
import org.jetbrains.kotlin.idea.util.approximateWithResolvableType
import org.jetbrains.kotlin.idea.util.getResolutionScope
import org.jetbrains.kotlin.name.FqName
import org.jetbrains.kotlin.psi.*
import org.jetbrains.kotlin.psi.psiUtil.getQualifiedExpressionForSelectorOrThis
import org.jetbrains.kotlin.psi.psiUtil.getStrictParentOfType
@@ -38,6 +39,7 @@ import org.jetbrains.kotlin.resolve.calls.callUtil.getParentResolvedCall
import org.jetbrains.kotlin.resolve.calls.callUtil.getResolvedCall
import org.jetbrains.kotlin.resolve.calls.callUtil.getValueArgumentForExpression
import org.jetbrains.kotlin.resolve.calls.model.ResolvedCall
import org.jetbrains.kotlin.resolve.descriptorUtil.fqNameSafe
import org.jetbrains.kotlin.types.KotlinType
import org.jetbrains.kotlin.types.typeUtil.isInterface
import org.jetbrains.kotlin.types.typeUtil.isPrimitiveNumberType
@@ -101,8 +103,7 @@ class QuickFixFactoryForTypeMismatchError : KotlinIntentionActionsFactory() {
actions.add(NumberConversionFix(diagnosticElement, expectedType, wrongPrimitiveLiteralFix))
}
if (KotlinBuiltIns.isCharSequenceOrNullableCharSequence(expectedType)
|| KotlinBuiltIns.isStringOrNullableString(expectedType)) {
if (KotlinBuiltIns.isCharSequenceOrNullableCharSequence(expectedType) || KotlinBuiltIns.isStringOrNullableString(expectedType)) {
actions.add(AddToStringFix(diagnosticElement, false))
if (expectedType.isMarkedNullable && expressionType.isMarkedNullable) {
actions.add(AddToStringFix(diagnosticElement, true))
@@ -146,7 +147,9 @@ class QuickFixFactoryForTypeMismatchError : KotlinIntentionActionsFactory() {
if (property != null) {
val getter = property.getter
val initializer = property.initializer
if (QuickFixUtil.canEvaluateTo(initializer, diagnosticElement) || getter != null && QuickFixUtil.canFunctionOrGetterReturnExpression(getter, diagnosticElement)) {
if (QuickFixUtil.canEvaluateTo(initializer, diagnosticElement)
|| getter != null && QuickFixUtil.canFunctionOrGetterReturnExpression(getter, diagnosticElement)
) {
val scope = property.getResolutionScope(context, property.getResolutionFacade())
val typeToInsert = expressionType.approximateWithResolvableType(scope, false)
actions.add(ChangeVariableTypeFix(property, typeToInsert))
@@ -192,7 +195,9 @@ class QuickFixFactoryForTypeMismatchError : KotlinIntentionActionsFactory() {
// KT-10063: arrayOf() bounding single array element
val annotationEntry = PsiTreeUtil.getParentOfType(diagnosticElement, KtAnnotationEntry::class.java)
if (annotationEntry != null) {
if (KotlinBuiltIns.isArray(expectedType) && expressionType.isSubtypeOf(expectedType.arguments[0].type) || KotlinBuiltIns.isPrimitiveArray(expectedType)) {
if (KotlinBuiltIns.isArray(expectedType) && expressionType.isSubtypeOf(expectedType.arguments[0].type)
|| KotlinBuiltIns.isPrimitiveArray(expectedType)
) {
actions.add(AddArrayOfTypeFix(diagnosticElement, expectedType))
}
}
@@ -225,10 +230,12 @@ class QuickFixFactoryForTypeMismatchError : KotlinIntentionActionsFactory() {
val typeToInsert = valueArgumentType.approximateWithResolvableType(scope, true)
actions.add(ChangeParameterTypeFix(correspondingParameter, typeToInsert))
}
if (correspondingParameterDescriptor?.varargElementType != null
val parameterVarargType = correspondingParameterDescriptor?.varargElementType
if ((parameterVarargType != null || resolvedCall.resultingDescriptor.fqNameSafe == FqName("kotlin.collections.mapOf"))
&& KotlinBuiltIns.isArray(valueArgumentType)
&& expressionType.arguments.isNotEmpty()
&& expressionType.arguments[0].type.constructor == expectedType.constructor) {
&& expressionType.arguments[0].type.constructor == expectedType.constructor
) {
actions.add(ChangeToUseSpreadOperatorFix(diagnosticElement))
}
}
@@ -1,11 +0,0 @@
// "Change 'pairs' to '*pairs'" "false"
// WITH_RUNTIME
// ACTION: Create function 'mapOf'
// ERROR: Type inference failed: fun <K, V> mapOf(pair: Pair<K, V>): Map<K, V><br>cannot be applied to<br>(Array<out Pair<String, String>>)<br>
// ERROR: Type mismatch: inferred type is Array<out Pair<String, String>> but Pair<???, ???> was expected
fun myMapOf(vararg pairs: Pair<String,String>) {
// Does not work due to KT-15593
val myMap = mapOf(<caret>pairs)
}
@@ -0,0 +1,6 @@
// "Change 'pairs' to '*pairs'" "true"
// WITH_RUNTIME
fun myMapOf(vararg pairs: Pair<String,String>) {
val myMap = mapOf(<caret>pairs)
}
@@ -0,0 +1,6 @@
// "Change 'pairs' to '*pairs'" "true"
// WITH_RUNTIME
fun myMapOf(vararg pairs: Pair<String,String>) {
val myMap = mapOf(*pairs)
}
@@ -1717,11 +1717,6 @@ public class QuickFixTestGenerated extends AbstractQuickFixTest {
runTest("idea/testData/quickfix/changeToUseSpreadOperator/mapOf.kt");
}
@TestMetadata("mapOfBug.kt")
public void testMapOfBug() throws Exception {
runTest("idea/testData/quickfix/changeToUseSpreadOperator/mapOfBug.kt");
}
@TestMetadata("multipleParams.kt")
public void testMultipleParams() throws Exception {
runTest("idea/testData/quickfix/changeToUseSpreadOperator/multipleParams.kt");
@@ -1742,6 +1737,11 @@ public class QuickFixTestGenerated extends AbstractQuickFixTest {
runTest("idea/testData/quickfix/changeToUseSpreadOperator/normal.kt");
}
@TestMetadata("stdlibMapOf.kt")
public void testStdlibMapOf() throws Exception {
runTest("idea/testData/quickfix/changeToUseSpreadOperator/stdlibMapOf.kt");
}
@TestMetadata("vararg.kt")
public void testVararg() throws Exception {
runTest("idea/testData/quickfix/changeToUseSpreadOperator/vararg.kt");