diff --git a/idea/src/org/jetbrains/kotlin/idea/codeInliner/CodeInliner.kt b/idea/src/org/jetbrains/kotlin/idea/codeInliner/CodeInliner.kt index 491edec64e9..77a93483c56 100644 --- a/idea/src/org/jetbrains/kotlin/idea/codeInliner/CodeInliner.kt +++ b/idea/src/org/jetbrains/kotlin/idea/codeInliner/CodeInliner.kt @@ -593,15 +593,15 @@ class CodeInliner( val callExpression = argumentList.parent as? KtCallExpression ?: return if (callExpression.lambdaArguments.isNotEmpty()) return - val resolvedCall = callExpression.resolveToCall() ?: return - if (!resolvedCall.isReallySuccess()) return - val argumentMatch = resolvedCall.getArgumentMapping(argument) as ArgumentMatch - if (argumentMatch.valueParameter != resolvedCall.resultingDescriptor.valueParameters.last()) return - + callExpression.resolveToCall() ?: return callExpressions.add(callExpression) }) - callExpressions.forEach { it.moveFunctionLiteralOutsideParentheses() } + callExpressions.forEach { + if (it.canMoveLambdaOutsideParentheses()) { + it.moveFunctionLiteralOutsideParentheses() + } + } } private operator fun PsiElement.get(key: Key): T? = getCopyableUserData(key) diff --git a/idea/testData/quickfix/deprecatedSymbolUsage/optionalParameters/optionalParameterAndLambda.kt b/idea/testData/quickfix/deprecatedSymbolUsage/optionalParameters/optionalParameterAndLambda.kt new file mode 100644 index 00000000000..52978d6c824 --- /dev/null +++ b/idea/testData/quickfix/deprecatedSymbolUsage/optionalParameters/optionalParameterAndLambda.kt @@ -0,0 +1,24 @@ +// "Replace with 'useSimple(simple(init))'" "true" + +fun simple(param: Int = 0, init: () -> Unit): Int { + init() + return param +} + +@Deprecated("Use useSimple instead", ReplaceWith("useSimple(simple(init))")) +fun use(init: () -> Unit): Int { + init() + return 0 +} + +fun useSimple(s: Int): Int { + return s +} + +fun println(s: String) {} + +fun useIt() { + val t = use { + println("abc") + } +} \ No newline at end of file diff --git a/idea/testData/quickfix/deprecatedSymbolUsage/optionalParameters/optionalParameterAndLambda.kt.after b/idea/testData/quickfix/deprecatedSymbolUsage/optionalParameters/optionalParameterAndLambda.kt.after new file mode 100644 index 00000000000..f926222f2b9 --- /dev/null +++ b/idea/testData/quickfix/deprecatedSymbolUsage/optionalParameters/optionalParameterAndLambda.kt.after @@ -0,0 +1,24 @@ +// "Replace with 'useSimple(simple(init))'" "true" + +fun simple(param: Int = 0, init: () -> Unit): Int { + init() + return param +} + +@Deprecated("Use useSimple instead", ReplaceWith("useSimple(simple(init))")) +fun use(init: () -> Unit): Int { + init() + return 0 +} + +fun useSimple(s: Int): Int { + return s +} + +fun println(s: String) {} + +fun useIt() { + val t = useSimple(simple { + println("abc") + }) +} \ No newline at end of file diff --git a/idea/testData/quickfix/deprecatedSymbolUsage/optionalParameters/optionalParameterAndLambdaComplex.kt b/idea/testData/quickfix/deprecatedSymbolUsage/optionalParameters/optionalParameterAndLambdaComplex.kt new file mode 100644 index 00000000000..d984532dafd --- /dev/null +++ b/idea/testData/quickfix/deprecatedSymbolUsage/optionalParameters/optionalParameterAndLambdaComplex.kt @@ -0,0 +1,39 @@ +// "Replace with 'addA(d(createDummy, dummyParam1, initDummy), dummyParam)'" "true" +// WITH_RUNTIME + +typealias NewDummyRef = (Any) -> V + +inline fun Any.d( + createDummy: NewDummyRef, + dummyParam1: Int = 0, + dummyParam2: Int = 0, + initDummy: A.() -> Unit = {} +) = createDummy(this).also(initDummy).also { dummyParam1 + dummyParam2 } + +@Deprecated("Use d instead", ReplaceWith("addA(d(createDummy, dummyParam1, initDummy), dummyParam)")) +inline fun MutableList.addA( + createDummy: NewDummyRef, + dummyParam1: Int = 0, + dummyParam: Unit, + initDummy: A.() -> Unit = {} +) = createDummy(this).also(initDummy).also { dummyParam1 }.also { add(it) } + +@Deprecated("Use d instead", ReplaceWith("addA(d(createDummy, dummyParam1, dummyParam2, initDummy), dummyParam)")) +inline fun MutableList.addA( + createDummy: NewDummyRef, + dummyParam1: Int = 0, + dummyParam2: Int = 0, + dummyParam: Unit, + initDummy: A.() -> Unit = {} +) = createDummy(this).also(initDummy).also { dummyParam1 + dummyParam2 }.also { add(it) } + +@Suppress("NOTHING_TO_INLINE") +inline fun MutableList.addA(a: A, dummyParam: Unit): A = a.also { add(a) } + +fun createHi(any: Any) = "Hi $any" + +val unDeprecateMe = mutableListOf("Hello").apply { + addA(::createHi, 1, Unit) { // Run the quick fix from the IDE and watch it produce broken code. + println("Yo") + } +} \ No newline at end of file diff --git a/idea/testData/quickfix/deprecatedSymbolUsage/optionalParameters/optionalParameterAndLambdaComplex.kt.after b/idea/testData/quickfix/deprecatedSymbolUsage/optionalParameters/optionalParameterAndLambdaComplex.kt.after new file mode 100644 index 00000000000..37c9b8a78ad --- /dev/null +++ b/idea/testData/quickfix/deprecatedSymbolUsage/optionalParameters/optionalParameterAndLambdaComplex.kt.after @@ -0,0 +1,39 @@ +// "Replace with 'addA(d(createDummy, dummyParam1, initDummy), dummyParam)'" "true" +// WITH_RUNTIME + +typealias NewDummyRef = (Any) -> V + +inline fun Any.d( + createDummy: NewDummyRef, + dummyParam1: Int = 0, + dummyParam2: Int = 0, + initDummy: A.() -> Unit = {} +) = createDummy(this).also(initDummy).also { dummyParam1 + dummyParam2 } + +@Deprecated("Use d instead", ReplaceWith("addA(d(createDummy, dummyParam1, initDummy), dummyParam)")) +inline fun MutableList.addA( + createDummy: NewDummyRef, + dummyParam1: Int = 0, + dummyParam: Unit, + initDummy: A.() -> Unit = {} +) = createDummy(this).also(initDummy).also { dummyParam1 }.also { add(it) } + +@Deprecated("Use d instead", ReplaceWith("addA(d(createDummy, dummyParam1, dummyParam2, initDummy), dummyParam)")) +inline fun MutableList.addA( + createDummy: NewDummyRef, + dummyParam1: Int = 0, + dummyParam2: Int = 0, + dummyParam: Unit, + initDummy: A.() -> Unit = {} +) = createDummy(this).also(initDummy).also { dummyParam1 + dummyParam2 }.also { add(it) } + +@Suppress("NOTHING_TO_INLINE") +inline fun MutableList.addA(a: A, dummyParam: Unit): A = a.also { add(a) } + +fun createHi(any: Any) = "Hi $any" + +val unDeprecateMe = mutableListOf("Hello").apply { + addA(d(::createHi, 1 ) { // Run the quick fix from the IDE and watch it produce broken code. + println("Yo") + }, Unit) +} \ No newline at end of file diff --git a/idea/tests/org/jetbrains/kotlin/idea/quickfix/QuickFixTestGenerated.java b/idea/tests/org/jetbrains/kotlin/idea/quickfix/QuickFixTestGenerated.java index 3ab630f6c47..b45a0a2ad1c 100644 --- a/idea/tests/org/jetbrains/kotlin/idea/quickfix/QuickFixTestGenerated.java +++ b/idea/tests/org/jetbrains/kotlin/idea/quickfix/QuickFixTestGenerated.java @@ -5602,6 +5602,16 @@ public class QuickFixTestGenerated extends AbstractQuickFixTest { runTest("idea/testData/quickfix/deprecatedSymbolUsage/optionalParameters/namedArgument.kt"); } + @TestMetadata("optionalParameterAndLambda.kt") + public void testOptionalParameterAndLambda() throws Exception { + runTest("idea/testData/quickfix/deprecatedSymbolUsage/optionalParameters/optionalParameterAndLambda.kt"); + } + + @TestMetadata("optionalParameterAndLambdaComplex.kt") + public void testOptionalParameterAndLambdaComplex() throws Exception { + runTest("idea/testData/quickfix/deprecatedSymbolUsage/optionalParameters/optionalParameterAndLambdaComplex.kt"); + } + @TestMetadata("optionalParameters1.kt") public void testOptionalParameters1() throws Exception { runTest("idea/testData/quickfix/deprecatedSymbolUsage/optionalParameters/optionalParameters1.kt");