[kotlin] k2 extract function: don't introduce parameters for smart casts checks from inside selected fragment

^KTIJ-15585 fixed
^KTIJ-9061 fixed

GitOrigin-RevId: 367033f8125227e9de3ea5a8194b384cf8352a40
This commit is contained in:
Anna Kozlova
2024-03-27 19:30:23 +00:00
committed by intellij-monorepo-bot
parent d2091b0f94
commit 758d2627ed
7 changed files with 83 additions and 1 deletions
@@ -2491,6 +2491,16 @@ public abstract class ExtractionTestGenerated extends AbstractExtractionTest {
runTest("testData/refactoring/extractFunction/parameters/misc/runQualifier.kt");
}
@TestMetadata("smartCastInside.kt")
public void testSmartCastInside() throws Exception {
runTest("testData/refactoring/extractFunction/parameters/misc/smartCastInside.kt");
}
@TestMetadata("smartCastInside1.kt")
public void testSmartCastInside1() throws Exception {
runTest("testData/refactoring/extractFunction/parameters/misc/smartCastInside1.kt");
}
@TestMetadata("thisInObject.kt")
public void testThisInObject() throws Exception {
runTest("testData/refactoring/extractFunction/parameters/misc/thisInObject.kt");
@@ -0,0 +1,11 @@
class X(val field: Any?)
fun foo(list: List<X>) {
<selection>for (x in list) {
if (x.field != null) {
println(x.field.hashCode())
}
}</selection>
}
// IGNORE_K1
@@ -0,0 +1,15 @@
class X(val field: Any?)
fun foo(list: List<X>) {
__dummyTestFun__(list)
}
private fun __dummyTestFun__(list: List<X>) {
for (x in list) {
if (x.field != null) {
println(x.field.hashCode())
}
}
}
// IGNORE_K1
@@ -0,0 +1,9 @@
class C(val int: Int?)
fun test(x: Int, c: C): Int {
val a =
<selection>if (c.int != null) x + c.int else x</selection>
return a * a
}
// IGNORE_K1
@@ -0,0 +1,11 @@
class C(val int: Int?)
fun test(x: Int, c: C): Int {
val a =
i(c, x)
return a * a
}
private fun i(c: C, x: Int): Int = if (c.int != null) x + c.int else x
// IGNORE_K1
@@ -84,6 +84,7 @@ import org.jetbrains.kotlin.psi.psiUtil.getQualifiedExpressionForSelectorOrThis
import org.jetbrains.kotlin.psi.psiUtil.isInsideOf
import org.jetbrains.kotlin.types.Variance
import org.jetbrains.kotlin.types.expressions.OperatorConventions
import org.jetbrains.kotlin.idea.k2.refactoring.introduce.K2SemanticMatcher.isSemanticMatch
context(KtAnalysisSession)
internal fun ExtractionData.inferParametersInfo(
@@ -416,6 +417,7 @@ private fun createOriginalType(
private fun ExtractionData.getBrokenReferencesInfo(body: KtBlockExpression): List<ResolvedReferenceInfo<PsiNamedElement, KtSimpleNameExpression, KtType>> {
val newReferences = body.collectDescendantsOfType<KtSimpleNameExpression> { it.resolveResult != null }
val smartCastPossibleRoots = mutableSetOf<KtExpression>()
val referencesInfo = ArrayList<ResolvedReferenceInfo<PsiNamedElement, KtSimpleNameExpression, KtType>>()
for (newRef in newReferences) {
val originalResolveResult = newRef.resolveResult as? ResolveResult<PsiNamedElement, KtSimpleNameExpression> ?: continue
@@ -428,7 +430,21 @@ private fun ExtractionData.getBrokenReferencesInfo(body: KtBlockExpression): Lis
val qualifiedExpression = newRef.getQualifiedExpressionForSelector()
if (qualifiedExpression != null) {
val smartCastTarget = originalRefExpr.parent as KtExpression
smartCast = analyze(smartCastTarget) { smartCastTarget.getSmartCastInfo()?.smartCastType }
smartCast = analyze(smartCastTarget) {
val cast = smartCastTarget.getSmartCastInfo()?.smartCastType
when {
cast == null -> {
smartCastPossibleRoots.add(smartCastTarget)
null
}
//same qualified expressions without smartcast are present in the code fragment,
//so smart cast is done inside selection, no need to extract additional parameter
smartCastPossibleRoots.any { it.isSemanticMatch(smartCastTarget) } -> null
else -> cast
}
}
possibleTypes = analyze(smartCastTarget) { smartCastTarget.getExpectedType()?.let { setOf(it) } ?: emptySet() }
val (isCompanionObject, bothReceivers) = analyze(smartCastTarget) {
val symbol = originalRefExpr.resolveCall()?.singleCallOrNull<KtCallableMemberCall<*, *>>()?.partiallyAppliedSymbol
@@ -1649,6 +1649,16 @@ public abstract class K2IntroduceFunctionTestGenerated extends AbstractK2Introdu
runTest("../../idea/tests/testData/refactoring/extractFunction/parameters/misc/runQualifier.kt");
}
@TestMetadata("smartCastInside.kt")
public void testSmartCastInside() throws Exception {
runTest("../../idea/tests/testData/refactoring/extractFunction/parameters/misc/smartCastInside.kt");
}
@TestMetadata("smartCastInside1.kt")
public void testSmartCastInside1() throws Exception {
runTest("../../idea/tests/testData/refactoring/extractFunction/parameters/misc/smartCastInside1.kt");
}
@TestMetadata("thisInObject.kt")
public void testThisInObject() throws Exception {
runTest("../../idea/tests/testData/refactoring/extractFunction/parameters/misc/thisInObject.kt");