From c3b726f10a1d1de1db5f3414d82c42291f911663 Mon Sep 17 00:00:00 2001 From: Dmitry Gridin Date: Fri, 26 Jun 2020 10:11:50 +0700 Subject: [PATCH] Inline refactoring: should add explicit type argument for parameters #KT-17402 Fixed --- .../kotlin/idea/codeInliner/CodeInliner.kt | 31 +++++++++++++++---- ...omplexExpressionUsedTwice5Runtime.kt.after | 2 +- .../expressionBody/GenericTypeArgument.kt | 8 +++++ .../GenericTypeArgument.kt.after | 7 +++++ .../explicitTypeArgumentComplex.kt | 1 - .../explicitTypeArgumentComplex.kt.after | 3 +- .../returnAtEnd/GenericTypeArgument.kt | 13 ++++++++ .../returnAtEnd/GenericTypeArgument.kt.after | 11 +++++++ .../returnAtEnd/GenericTypeArgument2.dep.kt | 7 +++++ .../GenericTypeArgument2.dep.kt.after | 6 ++++ .../returnAtEnd/GenericTypeArgument2.kt | 8 +++++ .../returnAtEnd/GenericTypeArgument2.kt.after | 8 +++++ .../returnAtEnd/ReturnFromLambda.kt.after | 2 +- .../inline/InlineTestGenerated.java | 15 +++++++++ 14 files changed, 111 insertions(+), 11 deletions(-) create mode 100644 idea/testData/refactoring/inline/function/expressionBody/GenericTypeArgument.kt create mode 100644 idea/testData/refactoring/inline/function/expressionBody/GenericTypeArgument.kt.after create mode 100644 idea/testData/refactoring/inline/function/returnAtEnd/GenericTypeArgument.kt create mode 100644 idea/testData/refactoring/inline/function/returnAtEnd/GenericTypeArgument.kt.after create mode 100644 idea/testData/refactoring/inline/function/returnAtEnd/GenericTypeArgument2.dep.kt create mode 100644 idea/testData/refactoring/inline/function/returnAtEnd/GenericTypeArgument2.dep.kt.after create mode 100644 idea/testData/refactoring/inline/function/returnAtEnd/GenericTypeArgument2.kt create mode 100644 idea/testData/refactoring/inline/function/returnAtEnd/GenericTypeArgument2.kt.after diff --git a/idea/src/org/jetbrains/kotlin/idea/codeInliner/CodeInliner.kt b/idea/src/org/jetbrains/kotlin/idea/codeInliner/CodeInliner.kt index 9759eb744c7..93fbca185ce 100644 --- a/idea/src/org/jetbrains/kotlin/idea/codeInliner/CodeInliner.kt +++ b/idea/src/org/jetbrains/kotlin/idea/codeInliner/CodeInliner.kt @@ -16,6 +16,7 @@ import org.jetbrains.kotlin.idea.caches.resolve.resolveImportReference import org.jetbrains.kotlin.idea.caches.resolve.resolveToCall import org.jetbrains.kotlin.idea.core.* import org.jetbrains.kotlin.idea.inspections.RedundantUnitExpressionInspection +import org.jetbrains.kotlin.idea.intentions.InsertExplicitTypeArgumentsIntention import org.jetbrains.kotlin.idea.intentions.RemoveExplicitTypeArgumentsIntention import org.jetbrains.kotlin.idea.util.CommentSaver import org.jetbrains.kotlin.idea.util.IdeDescriptorRenderers @@ -35,6 +36,7 @@ import org.jetbrains.kotlin.resolve.scopes.receivers.ImplicitReceiver import org.jetbrains.kotlin.types.KotlinType import org.jetbrains.kotlin.types.isError import org.jetbrains.kotlin.utils.addIfNotNull +import org.jetbrains.kotlin.utils.addToStdlib.safeAs class CodeInliner( private val nameExpression: KtSimpleNameExpression, @@ -175,7 +177,13 @@ class CodeInliner( for (parameter in descriptor.valueParameters.asReversed()) { val argument = argumentForParameter(parameter, descriptor) ?: continue - argument.expression.put(PARAMETER_VALUE_KEY, parameter) + val expression = argument.expression.apply { + if (this is KtCallElement) { + insertExplicitTypeArgument() + } + + put(PARAMETER_VALUE_KEY, parameter) + } val parameterName = parameter.name val usages = codeToInline.collectDescendantsOfType { @@ -191,19 +199,30 @@ class CodeInliner( usageArgument?.mark(DEFAULT_PARAMETER_VALUE_KEY) } - codeToInline.replaceExpression(it, argument.expression.copied()) + codeToInline.replaceExpression(it, expression.copied()) } - //TODO: sometimes we need to add explicit type arguments here because we don't have expected type in the new context - - if (argument.expression.shouldKeepValue(usageCount = usages.size)) { - introduceValuesForParameters.add(IntroduceValueForParameter(parameter, argument.expression, argument.expressionType)) + if (expression.shouldKeepValue(usageCount = usages.size)) { + introduceValuesForParameters.add(IntroduceValueForParameter(parameter, expression, argument.expressionType)) } } return introduceValuesForParameters } + private fun KtCallElement.insertExplicitTypeArgument() { + if (InsertExplicitTypeArgumentsIntention.isApplicableTo(this, bindingContext)) { + InsertExplicitTypeArgumentsIntention.createTypeArguments(this, bindingContext)?.let { typeArgumentList -> + clear(USER_CODE_KEY) + for (child in children) { + child.safeAs()?.mark(USER_CODE_KEY) + } + + addAfter(typeArgumentList, calleeExpression) + } + } + } + private data class IntroduceValueForParameter( val parameter: ValueParameterDescriptor, val value: KtExpression, diff --git a/idea/testData/quickfix/deprecatedSymbolUsage/argumentSideEffects/complexExpressionUsedTwice5Runtime.kt.after b/idea/testData/quickfix/deprecatedSymbolUsage/argumentSideEffects/complexExpressionUsedTwice5Runtime.kt.after index c51aaddfd78..c8e20031794 100644 --- a/idea/testData/quickfix/deprecatedSymbolUsage/argumentSideEffects/complexExpressionUsedTwice5Runtime.kt.after +++ b/idea/testData/quickfix/deprecatedSymbolUsage/argumentSideEffects/complexExpressionUsedTwice5Runtime.kt.after @@ -11,7 +11,7 @@ fun oldFun(p: List) { fun newFun(p1: List, p2: List){} fun foo() { - val p: List = bar() + val p = bar() newFun(p, p) } diff --git a/idea/testData/refactoring/inline/function/expressionBody/GenericTypeArgument.kt b/idea/testData/refactoring/inline/function/expressionBody/GenericTypeArgument.kt new file mode 100644 index 00000000000..a8521597877 --- /dev/null +++ b/idea/testData/refactoring/inline/function/expressionBody/GenericTypeArgument.kt @@ -0,0 +1,8 @@ +interface SomeFace +interface GeneOut {} +object Empty : GeneOut +fun downUnder(): GeneOut = Empty +fun downReturn(): GeneOut = downUnder() +fun callDown() { + val v1 = downReturn() +} \ No newline at end of file diff --git a/idea/testData/refactoring/inline/function/expressionBody/GenericTypeArgument.kt.after b/idea/testData/refactoring/inline/function/expressionBody/GenericTypeArgument.kt.after new file mode 100644 index 00000000000..46d849d5929 --- /dev/null +++ b/idea/testData/refactoring/inline/function/expressionBody/GenericTypeArgument.kt.after @@ -0,0 +1,7 @@ +interface SomeFace +interface GeneOut {} +object Empty : GeneOut +fun downUnder(): GeneOut = Empty +fun callDown() { + val v1 = downUnder() +} \ No newline at end of file diff --git a/idea/testData/refactoring/inline/function/expressionBody/explicitTypeArgumentComplex.kt b/idea/testData/refactoring/inline/function/expressionBody/explicitTypeArgumentComplex.kt index 84b7657fed9..8b007b07c27 100644 --- a/idea/testData/refactoring/inline/function/expressionBody/explicitTypeArgumentComplex.kt +++ b/idea/testData/refactoring/inline/function/expressionBody/explicitTypeArgumentComplex.kt @@ -5,6 +5,5 @@ fun downUnder(): GeneOut = Empty fun downParameter(p: GeneOut) = p fun callDown() { - // BUG: KT-17402 val v2 = downParameter(downUnder()) } \ No newline at end of file diff --git a/idea/testData/refactoring/inline/function/expressionBody/explicitTypeArgumentComplex.kt.after b/idea/testData/refactoring/inline/function/expressionBody/explicitTypeArgumentComplex.kt.after index b253891f80a..c439030d9b0 100644 --- a/idea/testData/refactoring/inline/function/expressionBody/explicitTypeArgumentComplex.kt.after +++ b/idea/testData/refactoring/inline/function/expressionBody/explicitTypeArgumentComplex.kt.after @@ -4,6 +4,5 @@ object Empty : GeneOut fun downUnder(): GeneOut = Empty fun callDown() { - // BUG: KT-17402 - val v2 = downUnder() + val v2 = downUnder() } \ No newline at end of file diff --git a/idea/testData/refactoring/inline/function/returnAtEnd/GenericTypeArgument.kt b/idea/testData/refactoring/inline/function/returnAtEnd/GenericTypeArgument.kt new file mode 100644 index 00000000000..a7c574b557d --- /dev/null +++ b/idea/testData/refactoring/inline/function/returnAtEnd/GenericTypeArgument.kt @@ -0,0 +1,13 @@ +package test.pack.one + +interface SomeFace +interface GeneOut {} +object Empty : GeneOut +fun downUnder(): GeneOut = Empty +fun downParameter(p: GeneOut): GeneOut { + p + return p +} +fun callDown() { + val v2 = downParameter(downUnder()) +} \ No newline at end of file diff --git a/idea/testData/refactoring/inline/function/returnAtEnd/GenericTypeArgument.kt.after b/idea/testData/refactoring/inline/function/returnAtEnd/GenericTypeArgument.kt.after new file mode 100644 index 00000000000..f597a290108 --- /dev/null +++ b/idea/testData/refactoring/inline/function/returnAtEnd/GenericTypeArgument.kt.after @@ -0,0 +1,11 @@ +package test.pack.one + +interface SomeFace +interface GeneOut {} +object Empty : GeneOut +fun downUnder(): GeneOut = Empty +fun callDown() { + val p = downUnder() + p + val v2 = p +} \ No newline at end of file diff --git a/idea/testData/refactoring/inline/function/returnAtEnd/GenericTypeArgument2.dep.kt b/idea/testData/refactoring/inline/function/returnAtEnd/GenericTypeArgument2.dep.kt new file mode 100644 index 00000000000..1b0be814e29 --- /dev/null +++ b/idea/testData/refactoring/inline/function/returnAtEnd/GenericTypeArgument2.dep.kt @@ -0,0 +1,7 @@ +package test.pack.one + +interface SomeFace +interface GeneOut {} +object Empty : GeneOut +fun downUnder(): GeneOut = Empty +fun downParameter(p: GeneOut): GeneOut = p \ No newline at end of file diff --git a/idea/testData/refactoring/inline/function/returnAtEnd/GenericTypeArgument2.dep.kt.after b/idea/testData/refactoring/inline/function/returnAtEnd/GenericTypeArgument2.dep.kt.after new file mode 100644 index 00000000000..350746e9dd5 --- /dev/null +++ b/idea/testData/refactoring/inline/function/returnAtEnd/GenericTypeArgument2.dep.kt.after @@ -0,0 +1,6 @@ +package test.pack.one + +interface SomeFace +interface GeneOut {} +object Empty : GeneOut +fun downUnder(): GeneOut = Empty diff --git a/idea/testData/refactoring/inline/function/returnAtEnd/GenericTypeArgument2.kt b/idea/testData/refactoring/inline/function/returnAtEnd/GenericTypeArgument2.kt new file mode 100644 index 00000000000..38d010524a8 --- /dev/null +++ b/idea/testData/refactoring/inline/function/returnAtEnd/GenericTypeArgument2.kt @@ -0,0 +1,8 @@ +package adadawwq32q + +import test.pack.one.downParameter +import test.pack.one.downUnder + +fun callDown() { + val result = downParameter(downUnder()) +} \ No newline at end of file diff --git a/idea/testData/refactoring/inline/function/returnAtEnd/GenericTypeArgument2.kt.after b/idea/testData/refactoring/inline/function/returnAtEnd/GenericTypeArgument2.kt.after new file mode 100644 index 00000000000..031851cb5e4 --- /dev/null +++ b/idea/testData/refactoring/inline/function/returnAtEnd/GenericTypeArgument2.kt.after @@ -0,0 +1,8 @@ +package adadawwq32q + +import test.pack.one.SomeFace +import test.pack.one.downUnder + +fun callDown() { + val result = downUnder() +} \ No newline at end of file diff --git a/idea/testData/refactoring/inline/function/returnAtEnd/ReturnFromLambda.kt.after b/idea/testData/refactoring/inline/function/returnAtEnd/ReturnFromLambda.kt.after index 7edca71c0e8..2d6755c789d 100644 --- a/idea/testData/refactoring/inline/function/returnAtEnd/ReturnFromLambda.kt.after +++ b/idea/testData/refactoring/inline/function/returnAtEnd/ReturnFromLambda.kt.after @@ -3,4 +3,4 @@ fun g() { if (it.isEmpty()) return@any false it.length < 10 }) -} +} \ No newline at end of file diff --git a/idea/tests/org/jetbrains/kotlin/idea/refactoring/inline/InlineTestGenerated.java b/idea/tests/org/jetbrains/kotlin/idea/refactoring/inline/InlineTestGenerated.java index d9a81fde51e..c1d04b425b9 100644 --- a/idea/tests/org/jetbrains/kotlin/idea/refactoring/inline/InlineTestGenerated.java +++ b/idea/tests/org/jetbrains/kotlin/idea/refactoring/inline/InlineTestGenerated.java @@ -237,6 +237,11 @@ public class InlineTestGenerated extends AbstractInlineTest { runTest("idea/testData/refactoring/inline/function/expressionBody/FunctionalType.kt"); } + @TestMetadata("GenericTypeArgument.kt") + public void testGenericTypeArgument() throws Exception { + runTest("idea/testData/refactoring/inline/function/expressionBody/GenericTypeArgument.kt"); + } + @TestMetadata("Lambda.kt") public void testLambda() throws Exception { runTest("idea/testData/refactoring/inline/function/expressionBody/Lambda.kt"); @@ -448,6 +453,16 @@ public class InlineTestGenerated extends AbstractInlineTest { runTest("idea/testData/refactoring/inline/function/returnAtEnd/DefaultParameter.kt"); } + @TestMetadata("GenericTypeArgument.kt") + public void testGenericTypeArgument() throws Exception { + runTest("idea/testData/refactoring/inline/function/returnAtEnd/GenericTypeArgument.kt"); + } + + @TestMetadata("GenericTypeArgument2.kt") + public void testGenericTypeArgument2() throws Exception { + runTest("idea/testData/refactoring/inline/function/returnAtEnd/GenericTypeArgument2.kt"); + } + @TestMetadata("InnerFunction.kt") public void testInnerFunction() throws Exception { runTest("idea/testData/refactoring/inline/function/returnAtEnd/InnerFunction.kt");