diff --git a/idea/src/org/jetbrains/jet/plugin/refactoring/extractFunction/extractableAnalysisUtil.kt b/idea/src/org/jetbrains/jet/plugin/refactoring/extractFunction/extractableAnalysisUtil.kt index 02acc488bf8..58ceff42c40 100644 --- a/idea/src/org/jetbrains/jet/plugin/refactoring/extractFunction/extractableAnalysisUtil.kt +++ b/idea/src/org/jetbrains/jet/plugin/refactoring/extractFunction/extractableAnalysisUtil.kt @@ -69,6 +69,8 @@ import org.jetbrains.jet.plugin.caches.resolve.findModuleDescriptor import org.jetbrains.jet.plugin.caches.resolve.analyze import org.jetbrains.kotlin.psi.psiUtil.getStrictParentOfType import org.jetbrains.jet.plugin.refactoring.comparePossiblyOverridingDescriptors +import org.jetbrains.kotlin.plugin.util.makeNullable +import org.jetbrains.kotlin.plugin.util.makeNotNullable private val DEFAULT_FUNCTION_NAME = "myFun" private val DEFAULT_RETURN_TYPE = KotlinBuiltIns.getInstance().getUnitType() @@ -473,8 +475,26 @@ private class MutableParameter( override val parameterTypeCandidates: List by Delegates.lazy { writable = false - val superTypes = TypeUtils.getAllSupertypes(defaultType).filter(and(typePredicates)) - (Collections.singletonList(defaultType) + superTypes).filter { it.isExtractable() } + + 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) + } + else arrayListOf(defaultType) + + val addNullableTypes = typeList.size() > 1 + val superTypes = TypeUtils.getAllSupertypes(defaultType).filter(typePredicate) + + for (superType in superTypes) { + if (addNullableTypes) { + typeList.add(superType.makeNullable()) + } + typeList.add(superType) + } + + typeList.filter { it.isExtractable() } } override val parameterType: JetType by Delegates.lazy { parameterTypeCandidates.firstOrNull() ?: defaultType } diff --git a/idea/testData/refactoring/extractFunction/parameters/candidateTypes/flexibleTypesWithNull.kt b/idea/testData/refactoring/extractFunction/parameters/candidateTypes/flexibleTypesWithNull.kt new file mode 100644 index 00000000000..1e522fabc5d --- /dev/null +++ b/idea/testData/refactoring/extractFunction/parameters/candidateTypes/flexibleTypesWithNull.kt @@ -0,0 +1,7 @@ +// WITH_RUNTIME +// PARAM_TYPES: String?, String, kotlin.CharSequence?, CharSequence +// PARAM_DESCRIPTOR: val property: (String..String?) defined in test +fun test() { + val property = System.getProperty("some") + val n = property?.length() +} \ No newline at end of file diff --git a/idea/testData/refactoring/extractFunction/parameters/candidateTypes/flexibleTypesWithNull.kt.after b/idea/testData/refactoring/extractFunction/parameters/candidateTypes/flexibleTypesWithNull.kt.after new file mode 100644 index 00000000000..c937a1cf21d --- /dev/null +++ b/idea/testData/refactoring/extractFunction/parameters/candidateTypes/flexibleTypesWithNull.kt.after @@ -0,0 +1,11 @@ +// WITH_RUNTIME +// PARAM_TYPES: String?, String, kotlin.CharSequence?, CharSequence +// PARAM_DESCRIPTOR: val property: (String..String?) defined in test +fun test() { + val property = System.getProperty("some") + val n = i(property) +} + +private fun i(property: String?): Int? { + return property?.length() +} \ No newline at end of file diff --git a/idea/testData/refactoring/extractFunction/parameters/candidateTypes/flexibleTypesWithoutNull.kt b/idea/testData/refactoring/extractFunction/parameters/candidateTypes/flexibleTypesWithoutNull.kt new file mode 100644 index 00000000000..e95f1420d5e --- /dev/null +++ b/idea/testData/refactoring/extractFunction/parameters/candidateTypes/flexibleTypesWithoutNull.kt @@ -0,0 +1,7 @@ +// WITH_RUNTIME +// PARAM_TYPES: String, CharSequence +// PARAM_DESCRIPTOR: val property: (String..String?) defined in test +fun test() { + val property = System.getProperty("some") + val n = property.length() +} \ No newline at end of file diff --git a/idea/testData/refactoring/extractFunction/parameters/candidateTypes/flexibleTypesWithoutNull.kt.after b/idea/testData/refactoring/extractFunction/parameters/candidateTypes/flexibleTypesWithoutNull.kt.after new file mode 100644 index 00000000000..e5d8c2e4f9f --- /dev/null +++ b/idea/testData/refactoring/extractFunction/parameters/candidateTypes/flexibleTypesWithoutNull.kt.after @@ -0,0 +1,11 @@ +// WITH_RUNTIME +// PARAM_TYPES: String, CharSequence +// PARAM_DESCRIPTOR: val property: (String..String?) defined in test +fun test() { + val property = System.getProperty("some") + val n = i(property) +} + +private fun i(property: String): Int { + return property.length() +} \ No newline at end of file diff --git a/idea/tests/org/jetbrains/jet/plugin/refactoring/introduce/introduceVariable/JetExtractionTestGenerated.java b/idea/tests/org/jetbrains/jet/plugin/refactoring/introduce/introduceVariable/JetExtractionTestGenerated.java index eb1ef45f46f..328564143d1 100644 --- a/idea/tests/org/jetbrains/jet/plugin/refactoring/introduce/introduceVariable/JetExtractionTestGenerated.java +++ b/idea/tests/org/jetbrains/jet/plugin/refactoring/introduce/introduceVariable/JetExtractionTestGenerated.java @@ -1421,6 +1421,18 @@ public class JetExtractionTestGenerated extends AbstractJetExtractionTest { doExtractFunctionTest(fileName); } + @TestMetadata("flexibleTypesWithNull.kt") + public void testFlexibleTypesWithNull() throws Exception { + String fileName = JetTestUtils.navigationMetadata("idea/testData/refactoring/extractFunction/parameters/candidateTypes/flexibleTypesWithNull.kt"); + doExtractFunctionTest(fileName); + } + + @TestMetadata("flexibleTypesWithoutNull.kt") + public void testFlexibleTypesWithoutNull() throws Exception { + String fileName = JetTestUtils.navigationMetadata("idea/testData/refactoring/extractFunction/parameters/candidateTypes/flexibleTypesWithoutNull.kt"); + doExtractFunctionTest(fileName); + } + @TestMetadata("liftAnonymousToSupertype1.kt") public void testLiftAnonymousToSupertype1() throws Exception { String fileName = JetTestUtils.navigationMetadata("idea/testData/refactoring/extractFunction/parameters/candidateTypes/liftAnonymousToSupertype1.kt");