Supported inline function for expression body case
This commit is contained in:
+7
-3
@@ -44,7 +44,8 @@ private val LOG = Logger.getInstance(UsageReplacementStrategy::class.java)
|
|||||||
fun UsageReplacementStrategy.replaceUsagesInWholeProject(
|
fun UsageReplacementStrategy.replaceUsagesInWholeProject(
|
||||||
targetPsiElement: PsiElement,
|
targetPsiElement: PsiElement,
|
||||||
progressTitle: String,
|
progressTitle: String,
|
||||||
commandName: String
|
commandName: String,
|
||||||
|
postAction: () -> Unit = {}
|
||||||
) {
|
) {
|
||||||
val project = targetPsiElement.project
|
val project = targetPsiElement.project
|
||||||
ProgressManager.getInstance().run(
|
ProgressManager.getInstance().run(
|
||||||
@@ -56,7 +57,7 @@ fun UsageReplacementStrategy.replaceUsagesInWholeProject(
|
|||||||
.filterIsInstance<KtSimpleNameReference>()
|
.filterIsInstance<KtSimpleNameReference>()
|
||||||
.map { ref -> ref.expression }
|
.map { ref -> ref.expression }
|
||||||
}
|
}
|
||||||
this@replaceUsagesInWholeProject.replaceUsages(usages, project, commandName)
|
this@replaceUsagesInWholeProject.replaceUsages(usages, project, commandName, postAction)
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
@@ -64,7 +65,8 @@ fun UsageReplacementStrategy.replaceUsagesInWholeProject(
|
|||||||
private fun UsageReplacementStrategy.replaceUsages(
|
private fun UsageReplacementStrategy.replaceUsages(
|
||||||
usages: Collection<KtSimpleNameExpression>,
|
usages: Collection<KtSimpleNameExpression>,
|
||||||
project: Project,
|
project: Project,
|
||||||
commandName: String
|
commandName: String,
|
||||||
|
postAction: () -> Unit
|
||||||
) {
|
) {
|
||||||
UIUtil.invokeLaterIfNeeded {
|
UIUtil.invokeLaterIfNeeded {
|
||||||
project.executeWriteCommand(commandName) {
|
project.executeWriteCommand(commandName) {
|
||||||
@@ -92,6 +94,8 @@ private fun UsageReplacementStrategy.replaceUsages(
|
|||||||
}
|
}
|
||||||
|
|
||||||
importsToDelete.forEach { it.delete() }
|
importsToDelete.forEach { it.delete() }
|
||||||
|
|
||||||
|
postAction()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -372,6 +372,7 @@
|
|||||||
<refactoring.introduceParameterMethodUsagesProcessor
|
<refactoring.introduceParameterMethodUsagesProcessor
|
||||||
implementation="org.jetbrains.kotlin.idea.refactoring.introduce.introduceParameter.KotlinIntroduceParameterMethodUsageProcessor"/>
|
implementation="org.jetbrains.kotlin.idea.refactoring.introduce.introduceParameter.KotlinIntroduceParameterMethodUsageProcessor"/>
|
||||||
<inlineActionHandler implementation="org.jetbrains.kotlin.idea.refactoring.inline.KotlinInlineValHandler"/>
|
<inlineActionHandler implementation="org.jetbrains.kotlin.idea.refactoring.inline.KotlinInlineValHandler"/>
|
||||||
|
<inlineActionHandler implementation="org.jetbrains.kotlin.idea.refactoring.inline.KotlinInlineFunctionHandler"/>
|
||||||
<inlineActionHandler implementation="org.jetbrains.kotlin.idea.refactoring.inline.KotlinInlineTypeAliasHandler"/>
|
<inlineActionHandler implementation="org.jetbrains.kotlin.idea.refactoring.inline.KotlinInlineTypeAliasHandler"/>
|
||||||
<treeStructureProvider implementation="org.jetbrains.kotlin.idea.projectView.KotlinSelectInProjectViewProvider"/>
|
<treeStructureProvider implementation="org.jetbrains.kotlin.idea.projectView.KotlinSelectInProjectViewProvider"/>
|
||||||
<treeStructureProvider implementation="org.jetbrains.kotlin.idea.projectView.KotlinExpandNodeProjectViewProvider" order="last"/>
|
<treeStructureProvider implementation="org.jetbrains.kotlin.idea.projectView.KotlinExpandNodeProjectViewProvider" order="last"/>
|
||||||
|
|||||||
@@ -0,0 +1,58 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2010-2015 JetBrains s.r.o.
|
||||||
|
*
|
||||||
|
* 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.refactoring.inline
|
||||||
|
|
||||||
|
import com.intellij.lang.Language
|
||||||
|
import com.intellij.lang.refactoring.InlineActionHandler
|
||||||
|
import com.intellij.openapi.editor.Editor
|
||||||
|
import com.intellij.openapi.project.Project
|
||||||
|
import com.intellij.psi.PsiElement
|
||||||
|
import com.intellij.psi.search.GlobalSearchScope
|
||||||
|
import com.intellij.refactoring.RefactoringBundle
|
||||||
|
import org.jetbrains.kotlin.descriptors.SimpleFunctionDescriptor
|
||||||
|
import org.jetbrains.kotlin.idea.KotlinLanguage
|
||||||
|
import org.jetbrains.kotlin.idea.caches.resolve.getResolutionFacade
|
||||||
|
import org.jetbrains.kotlin.idea.caches.resolve.resolveToDescriptor
|
||||||
|
import org.jetbrains.kotlin.idea.replacement.CallableUsageReplacementStrategy
|
||||||
|
import org.jetbrains.kotlin.idea.replacement.ReplacementBuilder
|
||||||
|
import org.jetbrains.kotlin.idea.replacement.replaceUsagesInWholeProject
|
||||||
|
import org.jetbrains.kotlin.idea.util.getResolutionScope
|
||||||
|
import org.jetbrains.kotlin.psi.KtNamedFunction
|
||||||
|
|
||||||
|
class KotlinInlineFunctionHandler: InlineActionHandler() {
|
||||||
|
override fun isEnabledForLanguage(language: Language) = language == KotlinLanguage.INSTANCE
|
||||||
|
|
||||||
|
override fun canInlineElement(element: PsiElement): Boolean {
|
||||||
|
return element is KtNamedFunction
|
||||||
|
&& element.hasBody() && !element.hasBlockBody() // TODO support multiline functions
|
||||||
|
&& element.getUseScope() is GlobalSearchScope // TODO support local functions
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun inlineElement(project: Project, editor: Editor?, element: PsiElement) {
|
||||||
|
element as KtNamedFunction
|
||||||
|
|
||||||
|
val descriptor = element.resolveToDescriptor() as SimpleFunctionDescriptor
|
||||||
|
|
||||||
|
val bodyExpression = element.bodyExpression!!
|
||||||
|
val replacement = ReplacementBuilder(descriptor, element.getResolutionFacade())
|
||||||
|
.buildReplacementExpression(bodyExpression, bodyExpression.getResolutionScope())
|
||||||
|
|
||||||
|
val commandName = RefactoringBundle.message("inline.command", element.name)
|
||||||
|
CallableUsageReplacementStrategy(replacement)
|
||||||
|
.replaceUsagesInWholeProject(element, commandName, commandName, postAction = { element.delete() })
|
||||||
|
}
|
||||||
|
}
|
||||||
+11
@@ -0,0 +1,11 @@
|
|||||||
|
fun <caret>f(p: Int) = g()
|
||||||
|
|
||||||
|
fun g() {
|
||||||
|
}
|
||||||
|
|
||||||
|
fun complexFun(): Int {
|
||||||
|
}
|
||||||
|
|
||||||
|
fun main(args: Array<String>) {
|
||||||
|
f(complexFun())
|
||||||
|
}
|
||||||
+10
@@ -0,0 +1,10 @@
|
|||||||
|
fun g() {
|
||||||
|
}
|
||||||
|
|
||||||
|
fun complexFun(): Int {
|
||||||
|
}
|
||||||
|
|
||||||
|
fun main(args: Array<String>) {
|
||||||
|
complexFun()
|
||||||
|
g()
|
||||||
|
}
|
||||||
+8
@@ -0,0 +1,8 @@
|
|||||||
|
fun <caret>f(p: Int) = p + p
|
||||||
|
|
||||||
|
fun complexFun(): Int {
|
||||||
|
}
|
||||||
|
|
||||||
|
fun main(args: Array<String>) {
|
||||||
|
f(complexFun())
|
||||||
|
}
|
||||||
+7
@@ -0,0 +1,7 @@
|
|||||||
|
fun complexFun(): Int {
|
||||||
|
}
|
||||||
|
|
||||||
|
fun main(args: Array<String>) {
|
||||||
|
val p = complexFun()
|
||||||
|
p + p
|
||||||
|
}
|
||||||
@@ -0,0 +1,5 @@
|
|||||||
|
fun <caret>f() = "foo"
|
||||||
|
|
||||||
|
fun main(args: Array<String>) {
|
||||||
|
println(f() + f())
|
||||||
|
}
|
||||||
@@ -0,0 +1,3 @@
|
|||||||
|
fun main(args: Array<String>) {
|
||||||
|
println("foo" + "foo")
|
||||||
|
}
|
||||||
@@ -0,0 +1,7 @@
|
|||||||
|
fun f(p1: Int, p2: Int) = p1 + p2
|
||||||
|
|
||||||
|
fun main(args: Array<String>) {
|
||||||
|
println(f(1, 2))
|
||||||
|
println(<caret>f(3, 4))
|
||||||
|
println(f(5, 6))
|
||||||
|
}
|
||||||
@@ -0,0 +1,5 @@
|
|||||||
|
fun main(args: Array<String>) {
|
||||||
|
println(1 + 2)
|
||||||
|
println(3 + 4)
|
||||||
|
println(5 + 6)
|
||||||
|
}
|
||||||
+10
@@ -0,0 +1,10 @@
|
|||||||
|
fun <caret>foo(p1: String, p2: () -> Boolean) = bar(p1, null, p2)
|
||||||
|
|
||||||
|
fun bar(p1: String, p2: String?, p3: () -> Boolean)
|
||||||
|
|
||||||
|
fun foo(i: I) {
|
||||||
|
foo("foo") {
|
||||||
|
println("bar")
|
||||||
|
println("baz")
|
||||||
|
}
|
||||||
|
}
|
||||||
Vendored
+8
@@ -0,0 +1,8 @@
|
|||||||
|
fun bar(p1: String, p2: String?, p3: () -> Boolean)
|
||||||
|
|
||||||
|
fun foo(i: I) {
|
||||||
|
bar("foo", null) {
|
||||||
|
println("bar")
|
||||||
|
println("baz")
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,5 @@
|
|||||||
|
fun <caret>f(p1: Int, p2: Int) = p1 + p2
|
||||||
|
|
||||||
|
fun main(args: Array<String>) {
|
||||||
|
println(f(3, 5))
|
||||||
|
}
|
||||||
@@ -0,0 +1,3 @@
|
|||||||
|
fun main(args: Array<String>) {
|
||||||
|
println(3 + 5)
|
||||||
|
}
|
||||||
@@ -35,6 +35,60 @@ public class InlineTestGenerated extends AbstractInlineTest {
|
|||||||
KotlinTestUtils.assertAllTestsPresentByMetadata(this.getClass(), new File("idea/testData/refactoring/inline"), Pattern.compile("^(\\w+)\\.kt$"), true);
|
KotlinTestUtils.assertAllTestsPresentByMetadata(this.getClass(), new File("idea/testData/refactoring/inline"), Pattern.compile("^(\\w+)\\.kt$"), true);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@TestMetadata("idea/testData/refactoring/inline/function")
|
||||||
|
@TestDataPath("$PROJECT_ROOT")
|
||||||
|
@RunWith(JUnit3RunnerWithInners.class)
|
||||||
|
public static class Function extends AbstractInlineTest {
|
||||||
|
public void testAllFilesPresentInFunction() throws Exception {
|
||||||
|
KotlinTestUtils.assertAllTestsPresentByMetadata(this.getClass(), new File("idea/testData/refactoring/inline/function"), Pattern.compile("^(\\w+)\\.kt$"), true);
|
||||||
|
}
|
||||||
|
|
||||||
|
@TestMetadata("idea/testData/refactoring/inline/function/expressionBody")
|
||||||
|
@TestDataPath("$PROJECT_ROOT")
|
||||||
|
@RunWith(JUnit3RunnerWithInners.class)
|
||||||
|
public static class ExpressionBody extends AbstractInlineTest {
|
||||||
|
public void testAllFilesPresentInExpressionBody() throws Exception {
|
||||||
|
KotlinTestUtils.assertAllTestsPresentByMetadata(this.getClass(), new File("idea/testData/refactoring/inline/function/expressionBody"), Pattern.compile("^(\\w+)\\.kt$"), true);
|
||||||
|
}
|
||||||
|
|
||||||
|
@TestMetadata("ComplexArgumentNotUsed.kt")
|
||||||
|
public void testComplexArgumentNotUsed() throws Exception {
|
||||||
|
String fileName = KotlinTestUtils.navigationMetadata("idea/testData/refactoring/inline/function/expressionBody/ComplexArgumentNotUsed.kt");
|
||||||
|
doTest(fileName);
|
||||||
|
}
|
||||||
|
|
||||||
|
@TestMetadata("ComplexArgumentUsedTwice.kt")
|
||||||
|
public void testComplexArgumentUsedTwice() throws Exception {
|
||||||
|
String fileName = KotlinTestUtils.navigationMetadata("idea/testData/refactoring/inline/function/expressionBody/ComplexArgumentUsedTwice.kt");
|
||||||
|
doTest(fileName);
|
||||||
|
}
|
||||||
|
|
||||||
|
@TestMetadata("Constant.kt")
|
||||||
|
public void testConstant() throws Exception {
|
||||||
|
String fileName = KotlinTestUtils.navigationMetadata("idea/testData/refactoring/inline/function/expressionBody/Constant.kt");
|
||||||
|
doTest(fileName);
|
||||||
|
}
|
||||||
|
|
||||||
|
@TestMetadata("FromUsage.kt")
|
||||||
|
public void testFromUsage() throws Exception {
|
||||||
|
String fileName = KotlinTestUtils.navigationMetadata("idea/testData/refactoring/inline/function/expressionBody/FromUsage.kt");
|
||||||
|
doTest(fileName);
|
||||||
|
}
|
||||||
|
|
||||||
|
@TestMetadata("FunctionalParameterPassed.kt")
|
||||||
|
public void testFunctionalParameterPassed() throws Exception {
|
||||||
|
String fileName = KotlinTestUtils.navigationMetadata("idea/testData/refactoring/inline/function/expressionBody/FunctionalParameterPassed.kt");
|
||||||
|
doTest(fileName);
|
||||||
|
}
|
||||||
|
|
||||||
|
@TestMetadata("Simple.kt")
|
||||||
|
public void testSimple() throws Exception {
|
||||||
|
String fileName = KotlinTestUtils.navigationMetadata("idea/testData/refactoring/inline/function/expressionBody/Simple.kt");
|
||||||
|
doTest(fileName);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@TestMetadata("idea/testData/refactoring/inline/inlineTypeAlias")
|
@TestMetadata("idea/testData/refactoring/inline/inlineTypeAlias")
|
||||||
@TestDataPath("$PROJECT_ROOT")
|
@TestDataPath("$PROJECT_ROOT")
|
||||||
@RunWith(JUnit3RunnerWithInners.class)
|
@RunWith(JUnit3RunnerWithInners.class)
|
||||||
|
|||||||
Reference in New Issue
Block a user