From 6f4aa2296d52132c42cef94e7582f606437aa12d Mon Sep 17 00:00:00 2001 From: Denis Zharkov Date: Thu, 5 Jul 2018 14:27:04 +0300 Subject: [PATCH] Implement quickfix wrapping elements in collection literal calls #KT-25238 Fixed --- .../idea/quickfix/ConvertCollectionFix.kt | 27 ++++--- .../QuickFixFactoryForTypeMismatchError.kt | 6 +- .../WrapWithCollectionLiteralCallFix.kt | 77 ++++++++++++++++++ .../noMutableList.kt | 9 +++ .../nullToListOfNullable.kt | 8 ++ .../nullToListOfNullable.kt.after | 8 ++ .../returnEmptyArray.kt | 7 ++ .../returnEmptyArray.kt.after | 7 ++ .../returnEmptyCollection.kt | 7 ++ .../returnEmptyCollection.kt.after | 7 ++ .../returnEmptyList.kt | 7 ++ .../returnEmptyList.kt.after | 7 ++ .../returnEmptySequence.kt | 7 ++ .../returnEmptySequence.kt.after | 7 ++ .../returnEmptySet.kt | 7 ++ .../returnEmptySet.kt.after | 7 ++ .../wrapWithCollectionLiteral/toArray.kt | 8 ++ .../toArray.kt.after | 8 ++ .../wrapWithCollectionLiteral/toCollection.kt | 8 ++ .../toCollection.kt.after | 8 ++ .../wrapWithCollectionLiteral/toList.kt | 8 ++ .../wrapWithCollectionLiteral/toList.kt.after | 8 ++ .../toListInapplicableType.kt | 8 ++ .../wrapWithCollectionLiteral/toSequence.kt | 8 ++ .../toSequence.kt.after | 8 ++ .../wrapWithCollectionLiteral/toSet.kt | 8 ++ .../wrapWithCollectionLiteral/toSet.kt.after | 8 ++ .../QuickFixMultiFileTestGenerated.java | 34 +------- .../QuickFixMultiFileTestGenerated.java.172 | 13 ++++ .../idea/quickfix/QuickFixTestGenerated.java | 78 +++++++++++++++++++ 30 files changed, 375 insertions(+), 43 deletions(-) create mode 100644 idea/src/org/jetbrains/kotlin/idea/quickfix/WrapWithCollectionLiteralCallFix.kt create mode 100644 idea/testData/quickfix/typeMismatch/wrapWithCollectionLiteral/noMutableList.kt create mode 100644 idea/testData/quickfix/typeMismatch/wrapWithCollectionLiteral/nullToListOfNullable.kt create mode 100644 idea/testData/quickfix/typeMismatch/wrapWithCollectionLiteral/nullToListOfNullable.kt.after create mode 100644 idea/testData/quickfix/typeMismatch/wrapWithCollectionLiteral/returnEmptyArray.kt create mode 100644 idea/testData/quickfix/typeMismatch/wrapWithCollectionLiteral/returnEmptyArray.kt.after create mode 100644 idea/testData/quickfix/typeMismatch/wrapWithCollectionLiteral/returnEmptyCollection.kt create mode 100644 idea/testData/quickfix/typeMismatch/wrapWithCollectionLiteral/returnEmptyCollection.kt.after create mode 100644 idea/testData/quickfix/typeMismatch/wrapWithCollectionLiteral/returnEmptyList.kt create mode 100644 idea/testData/quickfix/typeMismatch/wrapWithCollectionLiteral/returnEmptyList.kt.after create mode 100644 idea/testData/quickfix/typeMismatch/wrapWithCollectionLiteral/returnEmptySequence.kt create mode 100644 idea/testData/quickfix/typeMismatch/wrapWithCollectionLiteral/returnEmptySequence.kt.after create mode 100644 idea/testData/quickfix/typeMismatch/wrapWithCollectionLiteral/returnEmptySet.kt create mode 100644 idea/testData/quickfix/typeMismatch/wrapWithCollectionLiteral/returnEmptySet.kt.after create mode 100644 idea/testData/quickfix/typeMismatch/wrapWithCollectionLiteral/toArray.kt create mode 100644 idea/testData/quickfix/typeMismatch/wrapWithCollectionLiteral/toArray.kt.after create mode 100644 idea/testData/quickfix/typeMismatch/wrapWithCollectionLiteral/toCollection.kt create mode 100644 idea/testData/quickfix/typeMismatch/wrapWithCollectionLiteral/toCollection.kt.after create mode 100644 idea/testData/quickfix/typeMismatch/wrapWithCollectionLiteral/toList.kt create mode 100644 idea/testData/quickfix/typeMismatch/wrapWithCollectionLiteral/toList.kt.after create mode 100644 idea/testData/quickfix/typeMismatch/wrapWithCollectionLiteral/toListInapplicableType.kt create mode 100644 idea/testData/quickfix/typeMismatch/wrapWithCollectionLiteral/toSequence.kt create mode 100644 idea/testData/quickfix/typeMismatch/wrapWithCollectionLiteral/toSequence.kt.after create mode 100644 idea/testData/quickfix/typeMismatch/wrapWithCollectionLiteral/toSet.kt create mode 100644 idea/testData/quickfix/typeMismatch/wrapWithCollectionLiteral/toSet.kt.after diff --git a/idea/src/org/jetbrains/kotlin/idea/quickfix/ConvertCollectionFix.kt b/idea/src/org/jetbrains/kotlin/idea/quickfix/ConvertCollectionFix.kt index cfc8ab5f64b..5bc1db73a76 100644 --- a/idea/src/org/jetbrains/kotlin/idea/quickfix/ConvertCollectionFix.kt +++ b/idea/src/org/jetbrains/kotlin/idea/quickfix/ConvertCollectionFix.kt @@ -42,19 +42,22 @@ class ConvertCollectionFix(element: KtExpression, val type: CollectionType) : Ko } enum class CollectionType( - val functionCall: String, - val fqName: FqName, - private val nameOverride: String? = null + val functionCall: String, + val fqName: FqName, + val literalFunctionName: String? = null, + val emptyCollectionFunction: String? = null, + private val nameOverride: String? = null ) { - List("toList()", FqName("kotlin.collections.List")), - Collection("toList()", FqName("kotlin.collections.Collection")), - Iterable("toList()", FqName("kotlin.collections.Iterable")), + List("toList()", FqName("kotlin.collections.List"), "listOf", "emptyList"), + Collection("toList()", FqName("kotlin.collections.Collection"), "listOf", "emptyList"), + Iterable("toList()", FqName("kotlin.collections.Iterable"), "listOf", "emptyList"), MutableList("toMutableList()", FqName("kotlin.collections.MutableList")), - Array("toTypedArray()", FqName("kotlin.Array")), - Sequence("asSequence()", FqName("kotlin.sequences.Sequence")), + Array("toTypedArray()", FqName("kotlin.Array"), "arrayOf", "emptyArray"), + Sequence("asSequence()", FqName("kotlin.sequences.Sequence"), "sequenceOf", "emptySequence"), + Set("toSet()", FqName("kotlin.collections.Set"), "setOf", "emptySet"), //specialized types must be last because iteration order is relevant for getCollectionType - ArrayViaList("toList().toTypedArray()", FqName("kotlin.Array"), "Array"), + ArrayViaList("toList().toTypedArray()", FqName("kotlin.Array"), nameOverride = "Array"), ; val displayName get() = nameOverride ?: name @@ -80,9 +83,9 @@ class ConvertCollectionFix(element: KtExpression, val type: CollectionType) : Ko return expectedCollectionType.specializeFor(expressionCollectionType) } - private fun KotlinType.getCollectionType(): CollectionType? { - if (isMarkedNullable) return null + fun KotlinType.getCollectionType(acceptNullableTypes: Boolean = false): CollectionType? { + if (isMarkedNullable && !acceptNullableTypes) return null return TYPES.firstOrNull { KotlinBuiltIns.isConstructedFromGivenClass(this, it.fqName) } } } -} \ No newline at end of file +} diff --git a/idea/src/org/jetbrains/kotlin/idea/quickfix/QuickFixFactoryForTypeMismatchError.kt b/idea/src/org/jetbrains/kotlin/idea/quickfix/QuickFixFactoryForTypeMismatchError.kt index b2d1895b30e..e7e2cc8b02d 100644 --- a/idea/src/org/jetbrains/kotlin/idea/quickfix/QuickFixFactoryForTypeMismatchError.kt +++ b/idea/src/org/jetbrains/kotlin/idea/quickfix/QuickFixFactoryForTypeMismatchError.kt @@ -19,8 +19,9 @@ package org.jetbrains.kotlin.idea.quickfix import com.intellij.codeInsight.intention.IntentionAction import com.intellij.openapi.diagnostic.Logger import com.intellij.psi.util.PsiTreeUtil -import org.jetbrains.kotlin.builtins.* +import org.jetbrains.kotlin.builtins.KotlinBuiltIns import org.jetbrains.kotlin.builtins.functions.FunctionClassDescriptor +import org.jetbrains.kotlin.builtins.getFunctionalClassKind import org.jetbrains.kotlin.diagnostics.Diagnostic import org.jetbrains.kotlin.diagnostics.Errors import org.jetbrains.kotlin.diagnostics.rendering.DefaultErrorMessages @@ -122,6 +123,9 @@ class QuickFixFactoryForTypeMismatchError : KotlinIntentionActionsFactory() { expressionTypeDeclaration?.let { actions.add(LetImplementInterfaceFix(it, expectedType, expressionType)) } } + + actions.addAll(WrapWithCollectionLiteralCallFix.create(expectedType, expressionType, diagnosticElement)) + ConvertCollectionFix.getConversionTypeOrNull(expressionType, expectedType)?.let { actions.add(ConvertCollectionFix(diagnosticElement, it)) } diff --git a/idea/src/org/jetbrains/kotlin/idea/quickfix/WrapWithCollectionLiteralCallFix.kt b/idea/src/org/jetbrains/kotlin/idea/quickfix/WrapWithCollectionLiteralCallFix.kt new file mode 100644 index 00000000000..81c4b83e62c --- /dev/null +++ b/idea/src/org/jetbrains/kotlin/idea/quickfix/WrapWithCollectionLiteralCallFix.kt @@ -0,0 +1,77 @@ +/* + * Copyright 2010-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license + * that can be found in the license/LICENSE.txt file. + */ + +package org.jetbrains.kotlin.idea.quickfix + +import com.intellij.openapi.editor.Editor +import com.intellij.openapi.project.Project +import org.jetbrains.kotlin.idea.core.replaced +import org.jetbrains.kotlin.idea.intentions.branchedTransformations.isNullExpression +import org.jetbrains.kotlin.psi.KtExpression +import org.jetbrains.kotlin.psi.KtFile +import org.jetbrains.kotlin.psi.KtPsiFactory +import org.jetbrains.kotlin.psi.createExpressionByPattern +import org.jetbrains.kotlin.psi.psiUtil.endOffset +import org.jetbrains.kotlin.types.KotlinType +import org.jetbrains.kotlin.types.Variance +import org.jetbrains.kotlin.types.typeUtil.isSubtypeOf + +class WrapWithCollectionLiteralCallFix private constructor( + element: KtExpression, + private val functionName: String, + private val wrapInitialElement: Boolean +) : KotlinQuickFixAction(element) { + + override fun invoke(project: Project, editor: Editor?, file: KtFile) { + val expression = element ?: return + val factory = KtPsiFactory(expression) + + val replaced = + if (wrapInitialElement) + expression.replaced(factory.createExpressionByPattern("$functionName($0)", expression)) + else + expression.replaced(factory.createExpression("$functionName()")) + + editor?.caretModel?.moveToOffset(replaced.endOffset) + } + + override fun getFamilyName(): String = "Wrap with collection literal call" + override fun getText() = + if (wrapInitialElement) + "Wrap element with '$functionName()' call" + else + "Replace with '$functionName()' call" + + companion object { + fun create(expectedType: KotlinType, expressionType: KotlinType, element: KtExpression): List { + val collectionType = + with(ConvertCollectionFix) { + expectedType.getCollectionType(acceptNullableTypes = true) + } ?: return emptyList() + + val expectedArgumentType = + expectedType + .arguments.singleOrNull() + ?.takeIf { it.projectionKind != Variance.IN_VARIANCE } + ?.type + ?: return emptyList() + + val result = mutableListOf() + + val isNullExpression = element.isNullExpression() + if ((expressionType.isSubtypeOf(expectedArgumentType) || isNullExpression) && collectionType.literalFunctionName != null) { + result += WrapWithCollectionLiteralCallFix(element, collectionType.literalFunctionName, wrapInitialElement = true) + } + + // Replace "null" with emptyList() + if (isNullExpression && collectionType.emptyCollectionFunction != null) { + result += WrapWithCollectionLiteralCallFix(element, collectionType.emptyCollectionFunction, wrapInitialElement = false) + } + + return result + } + } + +} diff --git a/idea/testData/quickfix/typeMismatch/wrapWithCollectionLiteral/noMutableList.kt b/idea/testData/quickfix/typeMismatch/wrapWithCollectionLiteral/noMutableList.kt new file mode 100644 index 00000000000..f8c8544a72e --- /dev/null +++ b/idea/testData/quickfix/typeMismatch/wrapWithCollectionLiteral/noMutableList.kt @@ -0,0 +1,9 @@ +// "class org.jetbrains.kotlin.idea.quickfix.WrapWithCollectionLiteralCallFix" "false" +// ERROR: Type mismatch: inferred type is String but MutableList was expected +// WITH_RUNTIME + +fun foo(a: String) { + bar(a) +} + +fun bar(a: MutableList) {} diff --git a/idea/testData/quickfix/typeMismatch/wrapWithCollectionLiteral/nullToListOfNullable.kt b/idea/testData/quickfix/typeMismatch/wrapWithCollectionLiteral/nullToListOfNullable.kt new file mode 100644 index 00000000000..ce2261ae3a9 --- /dev/null +++ b/idea/testData/quickfix/typeMismatch/wrapWithCollectionLiteral/nullToListOfNullable.kt @@ -0,0 +1,8 @@ +// "Wrap element with 'listOf()' call" "true" +// WITH_RUNTIME + +fun foo() { + bar(null) +} + +fun bar(a: List) {} diff --git a/idea/testData/quickfix/typeMismatch/wrapWithCollectionLiteral/nullToListOfNullable.kt.after b/idea/testData/quickfix/typeMismatch/wrapWithCollectionLiteral/nullToListOfNullable.kt.after new file mode 100644 index 00000000000..bcd84417e18 --- /dev/null +++ b/idea/testData/quickfix/typeMismatch/wrapWithCollectionLiteral/nullToListOfNullable.kt.after @@ -0,0 +1,8 @@ +// "Wrap element with 'listOf()' call" "true" +// WITH_RUNTIME + +fun foo() { + bar(listOf(null)) +} + +fun bar(a: List) {} diff --git a/idea/testData/quickfix/typeMismatch/wrapWithCollectionLiteral/returnEmptyArray.kt b/idea/testData/quickfix/typeMismatch/wrapWithCollectionLiteral/returnEmptyArray.kt new file mode 100644 index 00000000000..96361bdd676 --- /dev/null +++ b/idea/testData/quickfix/typeMismatch/wrapWithCollectionLiteral/returnEmptyArray.kt @@ -0,0 +1,7 @@ +// "Replace with 'emptyArray()' call" "true" +// WITH_RUNTIME + +fun foo(a: String?): Array { + val w = a ?: return null + return arrayOf(w) +} diff --git a/idea/testData/quickfix/typeMismatch/wrapWithCollectionLiteral/returnEmptyArray.kt.after b/idea/testData/quickfix/typeMismatch/wrapWithCollectionLiteral/returnEmptyArray.kt.after new file mode 100644 index 00000000000..e78b06e823e --- /dev/null +++ b/idea/testData/quickfix/typeMismatch/wrapWithCollectionLiteral/returnEmptyArray.kt.after @@ -0,0 +1,7 @@ +// "Replace with 'emptyArray()' call" "true" +// WITH_RUNTIME + +fun foo(a: String?): Array { + val w = a ?: return emptyArray() + return arrayOf(w) +} diff --git a/idea/testData/quickfix/typeMismatch/wrapWithCollectionLiteral/returnEmptyCollection.kt b/idea/testData/quickfix/typeMismatch/wrapWithCollectionLiteral/returnEmptyCollection.kt new file mode 100644 index 00000000000..3a82555aefa --- /dev/null +++ b/idea/testData/quickfix/typeMismatch/wrapWithCollectionLiteral/returnEmptyCollection.kt @@ -0,0 +1,7 @@ +// "Replace with 'emptyList()' call" "true" +// WITH_RUNTIME + +fun foo(a: String?): Collection { + val w = a ?: return null + return listOf(w) +} diff --git a/idea/testData/quickfix/typeMismatch/wrapWithCollectionLiteral/returnEmptyCollection.kt.after b/idea/testData/quickfix/typeMismatch/wrapWithCollectionLiteral/returnEmptyCollection.kt.after new file mode 100644 index 00000000000..b152321cd57 --- /dev/null +++ b/idea/testData/quickfix/typeMismatch/wrapWithCollectionLiteral/returnEmptyCollection.kt.after @@ -0,0 +1,7 @@ +// "Replace with 'emptyList()' call" "true" +// WITH_RUNTIME + +fun foo(a: String?): Collection { + val w = a ?: return emptyList() + return listOf(w) +} diff --git a/idea/testData/quickfix/typeMismatch/wrapWithCollectionLiteral/returnEmptyList.kt b/idea/testData/quickfix/typeMismatch/wrapWithCollectionLiteral/returnEmptyList.kt new file mode 100644 index 00000000000..df33acd5401 --- /dev/null +++ b/idea/testData/quickfix/typeMismatch/wrapWithCollectionLiteral/returnEmptyList.kt @@ -0,0 +1,7 @@ +// "Replace with 'emptyList()' call" "true" +// WITH_RUNTIME + +fun foo(a: String?): List { + val w = a ?: return null + return listOf(w) +} diff --git a/idea/testData/quickfix/typeMismatch/wrapWithCollectionLiteral/returnEmptyList.kt.after b/idea/testData/quickfix/typeMismatch/wrapWithCollectionLiteral/returnEmptyList.kt.after new file mode 100644 index 00000000000..3c8002be978 --- /dev/null +++ b/idea/testData/quickfix/typeMismatch/wrapWithCollectionLiteral/returnEmptyList.kt.after @@ -0,0 +1,7 @@ +// "Replace with 'emptyList()' call" "true" +// WITH_RUNTIME + +fun foo(a: String?): List { + val w = a ?: return emptyList() + return listOf(w) +} diff --git a/idea/testData/quickfix/typeMismatch/wrapWithCollectionLiteral/returnEmptySequence.kt b/idea/testData/quickfix/typeMismatch/wrapWithCollectionLiteral/returnEmptySequence.kt new file mode 100644 index 00000000000..afdef1006b1 --- /dev/null +++ b/idea/testData/quickfix/typeMismatch/wrapWithCollectionLiteral/returnEmptySequence.kt @@ -0,0 +1,7 @@ +// "Replace with 'emptySequence()' call" "true" +// WITH_RUNTIME + +fun foo(a: String?): Sequence { + val w = a ?: return null + return sequenceOf(w) +} diff --git a/idea/testData/quickfix/typeMismatch/wrapWithCollectionLiteral/returnEmptySequence.kt.after b/idea/testData/quickfix/typeMismatch/wrapWithCollectionLiteral/returnEmptySequence.kt.after new file mode 100644 index 00000000000..c8f82ad9db5 --- /dev/null +++ b/idea/testData/quickfix/typeMismatch/wrapWithCollectionLiteral/returnEmptySequence.kt.after @@ -0,0 +1,7 @@ +// "Replace with 'emptySequence()' call" "true" +// WITH_RUNTIME + +fun foo(a: String?): Sequence { + val w = a ?: return emptySequence() + return sequenceOf(w) +} diff --git a/idea/testData/quickfix/typeMismatch/wrapWithCollectionLiteral/returnEmptySet.kt b/idea/testData/quickfix/typeMismatch/wrapWithCollectionLiteral/returnEmptySet.kt new file mode 100644 index 00000000000..ccf4bb67984 --- /dev/null +++ b/idea/testData/quickfix/typeMismatch/wrapWithCollectionLiteral/returnEmptySet.kt @@ -0,0 +1,7 @@ +// "Replace with 'emptySet()' call" "true" +// WITH_RUNTIME + +fun foo(a: String?): Set { + val w = a ?: return null + return setOf(w) +} diff --git a/idea/testData/quickfix/typeMismatch/wrapWithCollectionLiteral/returnEmptySet.kt.after b/idea/testData/quickfix/typeMismatch/wrapWithCollectionLiteral/returnEmptySet.kt.after new file mode 100644 index 00000000000..5ec8d0e7861 --- /dev/null +++ b/idea/testData/quickfix/typeMismatch/wrapWithCollectionLiteral/returnEmptySet.kt.after @@ -0,0 +1,7 @@ +// "Replace with 'emptySet()' call" "true" +// WITH_RUNTIME + +fun foo(a: String?): Set { + val w = a ?: return emptySet() + return setOf(w) +} diff --git a/idea/testData/quickfix/typeMismatch/wrapWithCollectionLiteral/toArray.kt b/idea/testData/quickfix/typeMismatch/wrapWithCollectionLiteral/toArray.kt new file mode 100644 index 00000000000..652d2145daa --- /dev/null +++ b/idea/testData/quickfix/typeMismatch/wrapWithCollectionLiteral/toArray.kt @@ -0,0 +1,8 @@ +// "Wrap element with 'arrayOf()' call" "true" +// WITH_RUNTIME + +fun foo(a: String) { + bar(a) +} + +fun bar(a: Array) {} diff --git a/idea/testData/quickfix/typeMismatch/wrapWithCollectionLiteral/toArray.kt.after b/idea/testData/quickfix/typeMismatch/wrapWithCollectionLiteral/toArray.kt.after new file mode 100644 index 00000000000..6ed46e8337c --- /dev/null +++ b/idea/testData/quickfix/typeMismatch/wrapWithCollectionLiteral/toArray.kt.after @@ -0,0 +1,8 @@ +// "Wrap element with 'arrayOf()' call" "true" +// WITH_RUNTIME + +fun foo(a: String) { + bar(arrayOf(a)) +} + +fun bar(a: Array) {} diff --git a/idea/testData/quickfix/typeMismatch/wrapWithCollectionLiteral/toCollection.kt b/idea/testData/quickfix/typeMismatch/wrapWithCollectionLiteral/toCollection.kt new file mode 100644 index 00000000000..b709fadd858 --- /dev/null +++ b/idea/testData/quickfix/typeMismatch/wrapWithCollectionLiteral/toCollection.kt @@ -0,0 +1,8 @@ +// "Wrap element with 'listOf()' call" "true" +// WITH_RUNTIME + +fun foo(a: String) { + bar(a) +} + +fun bar(a: Collection) {} diff --git a/idea/testData/quickfix/typeMismatch/wrapWithCollectionLiteral/toCollection.kt.after b/idea/testData/quickfix/typeMismatch/wrapWithCollectionLiteral/toCollection.kt.after new file mode 100644 index 00000000000..825dea0a3bc --- /dev/null +++ b/idea/testData/quickfix/typeMismatch/wrapWithCollectionLiteral/toCollection.kt.after @@ -0,0 +1,8 @@ +// "Wrap element with 'listOf()' call" "true" +// WITH_RUNTIME + +fun foo(a: String) { + bar(listOf(a)) +} + +fun bar(a: Collection) {} diff --git a/idea/testData/quickfix/typeMismatch/wrapWithCollectionLiteral/toList.kt b/idea/testData/quickfix/typeMismatch/wrapWithCollectionLiteral/toList.kt new file mode 100644 index 00000000000..3b4e9afbbb3 --- /dev/null +++ b/idea/testData/quickfix/typeMismatch/wrapWithCollectionLiteral/toList.kt @@ -0,0 +1,8 @@ +// "Wrap element with 'listOf()' call" "true" +// WITH_RUNTIME + +fun foo(a: String) { + bar(a) +} + +fun bar(a: List) {} diff --git a/idea/testData/quickfix/typeMismatch/wrapWithCollectionLiteral/toList.kt.after b/idea/testData/quickfix/typeMismatch/wrapWithCollectionLiteral/toList.kt.after new file mode 100644 index 00000000000..c1dfe36b936 --- /dev/null +++ b/idea/testData/quickfix/typeMismatch/wrapWithCollectionLiteral/toList.kt.after @@ -0,0 +1,8 @@ +// "Wrap element with 'listOf()' call" "true" +// WITH_RUNTIME + +fun foo(a: String) { + bar(listOf(a)) +} + +fun bar(a: List) {} diff --git a/idea/testData/quickfix/typeMismatch/wrapWithCollectionLiteral/toListInapplicableType.kt b/idea/testData/quickfix/typeMismatch/wrapWithCollectionLiteral/toListInapplicableType.kt new file mode 100644 index 00000000000..835e36ec254 --- /dev/null +++ b/idea/testData/quickfix/typeMismatch/wrapWithCollectionLiteral/toListInapplicableType.kt @@ -0,0 +1,8 @@ +// "class org.jetbrains.kotlin.idea.quickfix.WrapWithCollectionLiteralCallFix" "false" +// ERROR: Type mismatch: inferred type is Int but List was expected + +fun foo(a: Int) { + bar(a) +} + +fun bar(a: List) {} diff --git a/idea/testData/quickfix/typeMismatch/wrapWithCollectionLiteral/toSequence.kt b/idea/testData/quickfix/typeMismatch/wrapWithCollectionLiteral/toSequence.kt new file mode 100644 index 00000000000..1650f715dac --- /dev/null +++ b/idea/testData/quickfix/typeMismatch/wrapWithCollectionLiteral/toSequence.kt @@ -0,0 +1,8 @@ +// "Wrap element with 'sequenceOf()' call" "true" +// WITH_RUNTIME + +fun foo(a: String) { + bar(a) +} + +fun bar(a: Sequence) {} diff --git a/idea/testData/quickfix/typeMismatch/wrapWithCollectionLiteral/toSequence.kt.after b/idea/testData/quickfix/typeMismatch/wrapWithCollectionLiteral/toSequence.kt.after new file mode 100644 index 00000000000..51e91b65dd6 --- /dev/null +++ b/idea/testData/quickfix/typeMismatch/wrapWithCollectionLiteral/toSequence.kt.after @@ -0,0 +1,8 @@ +// "Wrap element with 'sequenceOf()' call" "true" +// WITH_RUNTIME + +fun foo(a: String) { + bar(sequenceOf(a)) +} + +fun bar(a: Sequence) {} diff --git a/idea/testData/quickfix/typeMismatch/wrapWithCollectionLiteral/toSet.kt b/idea/testData/quickfix/typeMismatch/wrapWithCollectionLiteral/toSet.kt new file mode 100644 index 00000000000..9ee52dbcff1 --- /dev/null +++ b/idea/testData/quickfix/typeMismatch/wrapWithCollectionLiteral/toSet.kt @@ -0,0 +1,8 @@ +// "Wrap element with 'setOf()' call" "true" +// WITH_RUNTIME + +fun foo(a: String) { + bar(a) +} + +fun bar(a: Set) {} diff --git a/idea/testData/quickfix/typeMismatch/wrapWithCollectionLiteral/toSet.kt.after b/idea/testData/quickfix/typeMismatch/wrapWithCollectionLiteral/toSet.kt.after new file mode 100644 index 00000000000..05482949cde --- /dev/null +++ b/idea/testData/quickfix/typeMismatch/wrapWithCollectionLiteral/toSet.kt.after @@ -0,0 +1,8 @@ +// "Wrap element with 'setOf()' call" "true" +// WITH_RUNTIME + +fun foo(a: String) { + bar(setOf(a)) +} + +fun bar(a: Set) {} diff --git a/idea/tests/org/jetbrains/kotlin/idea/quickfix/QuickFixMultiFileTestGenerated.java b/idea/tests/org/jetbrains/kotlin/idea/quickfix/QuickFixMultiFileTestGenerated.java index 5dd4d35af59..209e34ddb7f 100644 --- a/idea/tests/org/jetbrains/kotlin/idea/quickfix/QuickFixMultiFileTestGenerated.java +++ b/idea/tests/org/jetbrains/kotlin/idea/quickfix/QuickFixMultiFileTestGenerated.java @@ -3937,42 +3937,16 @@ public class QuickFixMultiFileTestGenerated extends AbstractQuickFixMultiFileTes } } - @TestMetadata("idea/testData/quickfix/typeMismatch/numberConversion") + @TestMetadata("idea/testData/quickfix/typeMismatch/wrapWithCollectionLiteral") @TestDataPath("$PROJECT_ROOT") @RunWith(JUnit3RunnerWithInners.class) - public static class NumberConversion extends AbstractQuickFixMultiFileTest { + public static class WrapWithCollectionLiteral extends AbstractQuickFixMultiFileTest { private void runTest(String testDataFilePath) throws Exception { KotlinTestUtils.runTest(this::doTestWithExtraFile, TargetBackend.ANY, testDataFilePath); } - public void testAllFilesPresentInNumberConversion() throws Exception { - KotlinTestUtils.assertAllTestsPresentByMetadata(this.getClass(), new File("idea/testData/quickfix/typeMismatch/numberConversion"), Pattern.compile("^(\\w+)\\.((before\\.Main\\.\\w+)|(test))$"), TargetBackend.ANY, true); - } - } - - @TestMetadata("idea/testData/quickfix/typeMismatch/parameterTypeMismatch") - @TestDataPath("$PROJECT_ROOT") - @RunWith(JUnit3RunnerWithInners.class) - public static class ParameterTypeMismatch extends AbstractQuickFixMultiFileTest { - private void runTest(String testDataFilePath) throws Exception { - KotlinTestUtils.runTest(this::doTestWithExtraFile, TargetBackend.ANY, testDataFilePath); - } - - public void testAllFilesPresentInParameterTypeMismatch() throws Exception { - KotlinTestUtils.assertAllTestsPresentByMetadata(this.getClass(), new File("idea/testData/quickfix/typeMismatch/parameterTypeMismatch"), Pattern.compile("^(\\w+)\\.((before\\.Main\\.\\w+)|(test))$"), TargetBackend.ANY, true); - } - } - - @TestMetadata("idea/testData/quickfix/typeMismatch/typeMismatchOnReturnedExpression") - @TestDataPath("$PROJECT_ROOT") - @RunWith(JUnit3RunnerWithInners.class) - public static class TypeMismatchOnReturnedExpression extends AbstractQuickFixMultiFileTest { - private void runTest(String testDataFilePath) throws Exception { - KotlinTestUtils.runTest(this::doTestWithExtraFile, TargetBackend.ANY, testDataFilePath); - } - - public void testAllFilesPresentInTypeMismatchOnReturnedExpression() throws Exception { - KotlinTestUtils.assertAllTestsPresentByMetadata(this.getClass(), new File("idea/testData/quickfix/typeMismatch/typeMismatchOnReturnedExpression"), Pattern.compile("^(\\w+)\\.((before\\.Main\\.\\w+)|(test))$"), TargetBackend.ANY, true); + public void testAllFilesPresentInWrapWithCollectionLiteral() throws Exception { + KotlinTestUtils.assertAllTestsPresentByMetadata(this.getClass(), new File("idea/testData/quickfix/typeMismatch/wrapWithCollectionLiteral"), Pattern.compile("^(\\w+)\\.((before\\.Main\\.\\w+)|(test))$"), TargetBackend.ANY, true); } } diff --git a/idea/tests/org/jetbrains/kotlin/idea/quickfix/QuickFixMultiFileTestGenerated.java.172 b/idea/tests/org/jetbrains/kotlin/idea/quickfix/QuickFixMultiFileTestGenerated.java.172 index 88b23dccf11..d009241d5e8 100644 --- a/idea/tests/org/jetbrains/kotlin/idea/quickfix/QuickFixMultiFileTestGenerated.java.172 +++ b/idea/tests/org/jetbrains/kotlin/idea/quickfix/QuickFixMultiFileTestGenerated.java.172 @@ -2124,6 +2124,19 @@ public class QuickFixMultiFileTestGenerated extends AbstractQuickFixMultiFileTes runTest("idea/testData/quickfix/typeMismatch/genericVarianceViolation/basicMultiple.before.Main.kt"); } } + + @TestMetadata("idea/testData/quickfix/typeMismatch/wrapWithCollectionLiteral") + @TestDataPath("$PROJECT_ROOT") + @RunWith(JUnit3RunnerWithInners.class) + public static class WrapWithCollectionLiteral extends AbstractQuickFixMultiFileTest { + private void runTest(String testDataFilePath) throws Exception { + KotlinTestUtils.runTest(this::doTestWithExtraFile, TargetBackend.ANY, testDataFilePath); + } + + public void testAllFilesPresentInWrapWithCollectionLiteral() throws Exception { + KotlinTestUtils.assertAllTestsPresentByMetadata(this.getClass(), new File("idea/testData/quickfix/typeMismatch/wrapWithCollectionLiteral"), Pattern.compile("^(\\w+)\\.((before\\.Main\\.\\w+)|(test))$"), TargetBackend.ANY, true); + } + } } @TestMetadata("idea/testData/quickfix/variables") diff --git a/idea/tests/org/jetbrains/kotlin/idea/quickfix/QuickFixTestGenerated.java b/idea/tests/org/jetbrains/kotlin/idea/quickfix/QuickFixTestGenerated.java index f828c0c2ec0..d317b3a0f6c 100644 --- a/idea/tests/org/jetbrains/kotlin/idea/quickfix/QuickFixTestGenerated.java +++ b/idea/tests/org/jetbrains/kotlin/idea/quickfix/QuickFixTestGenerated.java @@ -11736,6 +11736,84 @@ public class QuickFixTestGenerated extends AbstractQuickFixTest { } } + @TestMetadata("idea/testData/quickfix/typeMismatch/wrapWithCollectionLiteral") + @TestDataPath("$PROJECT_ROOT") + @RunWith(JUnit3RunnerWithInners.class) + public static class WrapWithCollectionLiteral extends AbstractQuickFixTest { + private void runTest(String testDataFilePath) throws Exception { + KotlinTestUtils.runTest(this::doTest, TargetBackend.ANY, testDataFilePath); + } + + public void testAllFilesPresentInWrapWithCollectionLiteral() throws Exception { + KotlinTestUtils.assertAllTestsPresentByMetadata(this.getClass(), new File("idea/testData/quickfix/typeMismatch/wrapWithCollectionLiteral"), Pattern.compile("^([\\w\\-_]+)\\.kt$"), TargetBackend.ANY, true); + } + + @TestMetadata("noMutableList.kt") + public void testNoMutableList() throws Exception { + runTest("idea/testData/quickfix/typeMismatch/wrapWithCollectionLiteral/noMutableList.kt"); + } + + @TestMetadata("nullToListOfNullable.kt") + public void testNullToListOfNullable() throws Exception { + runTest("idea/testData/quickfix/typeMismatch/wrapWithCollectionLiteral/nullToListOfNullable.kt"); + } + + @TestMetadata("returnEmptyArray.kt") + public void testReturnEmptyArray() throws Exception { + runTest("idea/testData/quickfix/typeMismatch/wrapWithCollectionLiteral/returnEmptyArray.kt"); + } + + @TestMetadata("returnEmptyCollection.kt") + public void testReturnEmptyCollection() throws Exception { + runTest("idea/testData/quickfix/typeMismatch/wrapWithCollectionLiteral/returnEmptyCollection.kt"); + } + + @TestMetadata("returnEmptyList.kt") + public void testReturnEmptyList() throws Exception { + runTest("idea/testData/quickfix/typeMismatch/wrapWithCollectionLiteral/returnEmptyList.kt"); + } + + @TestMetadata("returnEmptySequence.kt") + public void testReturnEmptySequence() throws Exception { + runTest("idea/testData/quickfix/typeMismatch/wrapWithCollectionLiteral/returnEmptySequence.kt"); + } + + @TestMetadata("returnEmptySet.kt") + public void testReturnEmptySet() throws Exception { + runTest("idea/testData/quickfix/typeMismatch/wrapWithCollectionLiteral/returnEmptySet.kt"); + } + + @TestMetadata("toArray.kt") + public void testToArray() throws Exception { + runTest("idea/testData/quickfix/typeMismatch/wrapWithCollectionLiteral/toArray.kt"); + } + + @TestMetadata("toCollection.kt") + public void testToCollection() throws Exception { + runTest("idea/testData/quickfix/typeMismatch/wrapWithCollectionLiteral/toCollection.kt"); + } + + @TestMetadata("toList.kt") + public void testToList() throws Exception { + runTest("idea/testData/quickfix/typeMismatch/wrapWithCollectionLiteral/toList.kt"); + } + + @TestMetadata("toListInapplicableType.kt") + public void testToListInapplicableType() throws Exception { + runTest("idea/testData/quickfix/typeMismatch/wrapWithCollectionLiteral/toListInapplicableType.kt"); + } + + @TestMetadata("toSequence.kt") + public void testToSequence() throws Exception { + runTest("idea/testData/quickfix/typeMismatch/wrapWithCollectionLiteral/toSequence.kt"); + } + + @TestMetadata("toSet.kt") + public void testToSet() throws Exception { + runTest("idea/testData/quickfix/typeMismatch/wrapWithCollectionLiteral/toSet.kt"); + } + } + @TestMetadata("idea/testData/quickfix/typeMismatch/wrongPrimitive") @TestDataPath("$PROJECT_ROOT") @RunWith(JUnit3RunnerWithInners.class)