Inline refactoring: fix case with introduction of variable to return
#KT-39818 Fixed
This commit is contained in:
@@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright 2010-2019 JetBrains s.r.o. and Kotlin Programming Language contributors.
|
* Copyright 2010-2020 JetBrains s.r.o. and Kotlin Programming Language contributors.
|
||||||
* Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
|
* Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
@@ -181,6 +181,7 @@ class CodeInliner<TCallElement : KtElement>(
|
|||||||
val usages = codeToInline.collectDescendantsOfType<KtExpression> {
|
val usages = codeToInline.collectDescendantsOfType<KtExpression> {
|
||||||
it[CodeToInline.PARAMETER_USAGE_KEY] == parameterName
|
it[CodeToInline.PARAMETER_USAGE_KEY] == parameterName
|
||||||
}
|
}
|
||||||
|
|
||||||
usages.forEach {
|
usages.forEach {
|
||||||
val usageArgument = it.parent as? KtValueArgument
|
val usageArgument = it.parent as? KtValueArgument
|
||||||
if (argument.isNamed) {
|
if (argument.isNamed) {
|
||||||
@@ -189,7 +190,8 @@ class CodeInliner<TCallElement : KtElement>(
|
|||||||
if (argument.isDefaultValue) {
|
if (argument.isDefaultValue) {
|
||||||
usageArgument?.mark(DEFAULT_PARAMETER_VALUE_KEY)
|
usageArgument?.mark(DEFAULT_PARAMETER_VALUE_KEY)
|
||||||
}
|
}
|
||||||
codeToInline.replaceExpression(it, argument.expression)
|
|
||||||
|
codeToInline.replaceExpression(it, argument.expression.copied())
|
||||||
}
|
}
|
||||||
|
|
||||||
//TODO: sometimes we need to add explicit type arguments here because we don't have expected type in the new context
|
//TODO: sometimes we need to add explicit type arguments here because we don't have expected type in the new context
|
||||||
|
|||||||
@@ -72,13 +72,7 @@ internal class MutableCodeToInline(
|
|||||||
val expressions: Collection<KtExpression>
|
val expressions: Collection<KtExpression>
|
||||||
get() = statementsBefore + listOfNotNull(mainExpression)
|
get() = statementsBefore + listOfNotNull(mainExpression)
|
||||||
|
|
||||||
operator fun contains(element: PsiElement): Boolean {
|
operator fun contains(element: PsiElement): Boolean = expressions.any { it.isAncestor(element) }
|
||||||
return expressions.any { it.isAncestor(element) }
|
|
||||||
}
|
|
||||||
|
|
||||||
fun containsStrictlyInside(element: PsiElement): Boolean {
|
|
||||||
return expressions.any { it.isAncestor(element, strict = true) }
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
internal fun CodeToInline.toMutable(): MutableCodeToInline {
|
internal fun CodeToInline.toMutable(): MutableCodeToInline {
|
||||||
|
|||||||
@@ -1,17 +1,6 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright 2010-2016 JetBrains s.r.o.
|
* Copyright 2010-2020 JetBrains s.r.o. and Kotlin Programming Language contributors.
|
||||||
*
|
* Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
||||||
* you may not use this file except in compliance with the License.
|
|
||||||
* You may obtain a copy of the License at
|
|
||||||
*
|
|
||||||
* http://www.apache.org/licenses/LICENSE-2.0
|
|
||||||
*
|
|
||||||
* Unless required by applicable law or agreed to in writing, software
|
|
||||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
||||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
||||||
* See the License for the specific language governing permissions and
|
|
||||||
* limitations under the License.
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
package org.jetbrains.kotlin.idea.codeInliner
|
package org.jetbrains.kotlin.idea.codeInliner
|
||||||
@@ -57,7 +46,7 @@ internal fun MutableCodeToInline.introduceValue(
|
|||||||
nameSuggestion: String? = null,
|
nameSuggestion: String? = null,
|
||||||
safeCall: Boolean = false
|
safeCall: Boolean = false
|
||||||
) {
|
) {
|
||||||
assert(usages.all { this.containsStrictlyInside(it) })
|
assert(usages.all { it in this })
|
||||||
|
|
||||||
val psiFactory = KtPsiFactory(value)
|
val psiFactory = KtPsiFactory(value)
|
||||||
|
|
||||||
@@ -68,7 +57,7 @@ internal fun MutableCodeToInline.introduceValue(
|
|||||||
for (usage in usages) {
|
for (usage in usages) {
|
||||||
// there can be parenthesis around the expression which will become unnecessary
|
// there can be parenthesis around the expression which will become unnecessary
|
||||||
val usageToReplace = (usage.parent as? KtParenthesizedExpression) ?: usage
|
val usageToReplace = (usage.parent as? KtParenthesizedExpression) ?: usage
|
||||||
usageToReplace.replace(nameInCode)
|
replaceExpression(usageToReplace, nameInCode)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -166,7 +166,7 @@ internal fun buildCodeToInline(
|
|||||||
}
|
}
|
||||||
|
|
||||||
return builder.prepareCodeToInline(
|
return builder.prepareCodeToInline(
|
||||||
lastReturn?.returnedExpression,
|
lastReturn?.returnedExpression?.copied(),
|
||||||
statements.dropLast(returnStatements.size), ::analyzeExpressionInContext, reformat = true
|
statements.dropLast(returnStatements.size), ::analyzeExpressionInContext, reformat = true
|
||||||
)
|
)
|
||||||
} else {
|
} else {
|
||||||
|
|||||||
@@ -0,0 +1,10 @@
|
|||||||
|
fun downUnder(): Int = 4
|
||||||
|
fun downParameter<caret>(p: Int): Int {
|
||||||
|
"first $p"
|
||||||
|
"second $p"
|
||||||
|
p
|
||||||
|
return p
|
||||||
|
}
|
||||||
|
fun callDown() {
|
||||||
|
val result = downParameter(downUnder())
|
||||||
|
}
|
||||||
@@ -0,0 +1,8 @@
|
|||||||
|
fun downUnder(): Int = 4
|
||||||
|
fun callDown() {
|
||||||
|
val p = downUnder()
|
||||||
|
"first ${p}"
|
||||||
|
"second ${p}"
|
||||||
|
p
|
||||||
|
val result = p
|
||||||
|
}
|
||||||
+5
@@ -65,6 +65,11 @@ public class InlineTestGenerated extends AbstractInlineTest {
|
|||||||
runTest("idea/testData/refactoring/inline/function/Kt30131.kt");
|
runTest("idea/testData/refactoring/inline/function/Kt30131.kt");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@TestMetadata("Kt39818.kt")
|
||||||
|
public void testKt39818() throws Exception {
|
||||||
|
runTest("idea/testData/refactoring/inline/function/Kt39818.kt");
|
||||||
|
}
|
||||||
|
|
||||||
@TestMetadata("LocalCapturing.kt")
|
@TestMetadata("LocalCapturing.kt")
|
||||||
public void testLocalCapturing() throws Exception {
|
public void testLocalCapturing() throws Exception {
|
||||||
runTest("idea/testData/refactoring/inline/function/LocalCapturing.kt");
|
runTest("idea/testData/refactoring/inline/function/LocalCapturing.kt");
|
||||||
|
|||||||
Reference in New Issue
Block a user