diff --git a/idea/src/org/jetbrains/kotlin/idea/refactoring/introduce/extractionEngine/extractableAnalysisUtil.kt b/idea/src/org/jetbrains/kotlin/idea/refactoring/introduce/extractionEngine/extractableAnalysisUtil.kt index 0af7fe15f79..dce71379e7e 100644 --- a/idea/src/org/jetbrains/kotlin/idea/refactoring/introduce/extractionEngine/extractableAnalysisUtil.kt +++ b/idea/src/org/jetbrains/kotlin/idea/refactoring/introduce/extractionEngine/extractableAnalysisUtil.kt @@ -541,23 +541,26 @@ private class MutableParameter( val typePredicate = and(typePredicates) - val typeList = if (defaultType.isNullabilityFlexible()) { - val bounds = defaultType.getCapability(javaClass()) - if (typePredicate(bounds!!.upperBound)) arrayListOf(bounds.upperBound, bounds.lowerBound) else arrayListOf(bounds.lowerBound) + val typeSet = if (defaultType.isFlexible()) { + val bounds = defaultType.getCapability(javaClass())!! + LinkedHashSet().apply { + if (typePredicate(bounds.upperBound)) add(bounds.upperBound) + if (typePredicate(bounds.lowerBound)) add(bounds.lowerBound) + } } - else arrayListOf(defaultType) + else linkedSetOf(defaultType) - val addNullableTypes = typeList.size() > 1 + val addNullableTypes = defaultType.isNullabilityFlexible() && typeSet.size() > 1 val superTypes = TypeUtils.getAllSupertypes(defaultType).filter(typePredicate) for (superType in superTypes) { if (addNullableTypes) { - typeList.add(superType.makeNullable()) + typeSet.add(superType.makeNullable()) } - typeList.add(superType) + typeSet.add(superType) } - typeList + typeSet.toList() } override fun getParameterTypeCandidates(allowSpecialClassNames: Boolean): List { diff --git a/idea/testData/refactoring/extractFunction/parameters/candidateTypes/mutablyFlexibleType.java b/idea/testData/refactoring/extractFunction/parameters/candidateTypes/mutablyFlexibleType.java new file mode 100644 index 00000000000..54022cc9ba7 --- /dev/null +++ b/idea/testData/refactoring/extractFunction/parameters/candidateTypes/mutablyFlexibleType.java @@ -0,0 +1,7 @@ +import java.util.*; + +class J { + public List getData() { + return new ArrayList(); + } +} \ No newline at end of file diff --git a/idea/testData/refactoring/extractFunction/parameters/candidateTypes/mutablyFlexibleType.kt b/idea/testData/refactoring/extractFunction/parameters/candidateTypes/mutablyFlexibleType.kt new file mode 100644 index 00000000000..2c1ef2084b2 --- /dev/null +++ b/idea/testData/refactoring/extractFunction/parameters/candidateTypes/mutablyFlexibleType.kt @@ -0,0 +1,8 @@ +// WITH_RUNTIME +// PARAM_DESCRIPTOR: val data: (kotlin.MutableList<(kotlin.String..kotlin.String?)>..kotlin.List<(kotlin.String..kotlin.String?)>) defined in test +// PARAM_TYPES: kotlin.List<(kotlin.String..kotlin.String?)>, kotlin.MutableList<(kotlin.String..kotlin.String?)>, kotlin.MutableCollection<(kotlin.String..kotlin.String?)>, kotlin.Collection<(kotlin.String..kotlin.String?)> +fun test(): Boolean { + val j: J? = null + val data = j?.getData() ?: return false + return data.contains("foo") +} \ No newline at end of file diff --git a/idea/testData/refactoring/extractFunction/parameters/candidateTypes/mutablyFlexibleType.kt.after b/idea/testData/refactoring/extractFunction/parameters/candidateTypes/mutablyFlexibleType.kt.after new file mode 100644 index 00000000000..d4dc8ce0e3b --- /dev/null +++ b/idea/testData/refactoring/extractFunction/parameters/candidateTypes/mutablyFlexibleType.kt.after @@ -0,0 +1,10 @@ +// WITH_RUNTIME +// PARAM_DESCRIPTOR: val data: (kotlin.MutableList<(kotlin.String..kotlin.String?)>..kotlin.List<(kotlin.String..kotlin.String?)>) defined in test +// PARAM_TYPES: kotlin.List<(kotlin.String..kotlin.String?)>, kotlin.MutableList<(kotlin.String..kotlin.String?)>, kotlin.MutableCollection<(kotlin.String..kotlin.String?)>, kotlin.Collection<(kotlin.String..kotlin.String?)> +fun test(): Boolean { + val j: J? = null + val data = j?.getData() ?: return false + return b(data) +} + +private fun b(data: List) = data.contains("foo") \ No newline at end of file diff --git a/idea/tests/org/jetbrains/kotlin/idea/refactoring/introduce/JetExtractionTestGenerated.java b/idea/tests/org/jetbrains/kotlin/idea/refactoring/introduce/JetExtractionTestGenerated.java index 1d659de3d14..8a115ac8f4d 100644 --- a/idea/tests/org/jetbrains/kotlin/idea/refactoring/introduce/JetExtractionTestGenerated.java +++ b/idea/tests/org/jetbrains/kotlin/idea/refactoring/introduce/JetExtractionTestGenerated.java @@ -1802,6 +1802,12 @@ public class JetExtractionTestGenerated extends AbstractJetExtractionTest { doExtractFunctionTest(fileName); } + @TestMetadata("mutablyFlexibleType.kt") + public void testMutablyFlexibleType() throws Exception { + String fileName = JetTestUtils.navigationMetadata("idea/testData/refactoring/extractFunction/parameters/candidateTypes/mutablyFlexibleType.kt"); + doExtractFunctionTest(fileName); + } + @TestMetadata("nonNullableTypes.kt") public void testNonNullableTypes() throws Exception { String fileName = JetTestUtils.navigationMetadata("idea/testData/refactoring/extractFunction/parameters/candidateTypes/nonNullableTypes.kt");