diff --git a/idea/src/org/jetbrains/kotlin/idea/refactoring/introduce/introduceVariable/KotlinIntroduceVariableHandler.kt b/idea/src/org/jetbrains/kotlin/idea/refactoring/introduce/introduceVariable/KotlinIntroduceVariableHandler.kt index 23d7823e3f5..d3fae346459 100644 --- a/idea/src/org/jetbrains/kotlin/idea/refactoring/introduce/introduceVariable/KotlinIntroduceVariableHandler.kt +++ b/idea/src/org/jetbrains/kotlin/idea/refactoring/introduce/introduceVariable/KotlinIntroduceVariableHandler.kt @@ -26,10 +26,7 @@ import com.intellij.openapi.editor.Editor import com.intellij.openapi.project.Project import com.intellij.openapi.util.Key import com.intellij.openapi.util.TextRange -import com.intellij.psi.PsiDocumentManager -import com.intellij.psi.PsiElement -import com.intellij.psi.PsiFile -import com.intellij.psi.PsiWhiteSpace +import com.intellij.psi.* import com.intellij.psi.util.PsiTreeUtil import com.intellij.refactoring.HelpID import com.intellij.refactoring.RefactoringActionHandler @@ -115,8 +112,8 @@ object KotlinIntroduceVariableHandler : RefactoringActionHandler { private val psiFactory = KtPsiFactory(expression) var propertyRef: KtDeclaration? = null - var reference: KtExpression? = null - val references = ArrayList() + var reference: SmartPsiElementPointer? = null + val references = ArrayList>() private fun findElementByOffsetAndText(offset: Int, text: String, newContainer: PsiElement): PsiElement? { return newContainer.findElementAt(offset)?.parentsWithSelf?.firstOrNull { (it as? KtExpression)?.text == text } @@ -139,9 +136,13 @@ object KotlinIntroduceVariableHandler : RefactoringActionHandler { result = result.removeTemplateEntryBracesIfPossible() - if (addToReferences) references.addIfNotNull(result) + if (addToReferences) { + references.addIfNotNull(SmartPointerManager.createPointer(result)) + } - if (isActualExpression) reference = result + if (isActualExpression) { + reference = SmartPointerManager.createPointer(result) + } return result } @@ -214,24 +215,24 @@ object KotlinIntroduceVariableHandler : RefactoringActionHandler { } } //ugly logic to make sure we are working with right actual expression - var actualExpression = reference ?: return + var actualExpression = reference?.element ?: return var diff = actualExpression.textRange.startOffset - oldElement.textRange.startOffset var actualExpressionText = actualExpression.text val newElement = emptyBody.addAfter(oldElement, firstChild) var elem: PsiElement? = findElementByOffsetAndText(diff, actualExpressionText, newElement) if (elem != null) { - reference = elem as KtExpression + reference = SmartPointerManager.createPointer(elem as KtExpression) } emptyBody.addAfter(psiFactory.createNewLine(), firstChild) property = emptyBody.addAfter(property, firstChild) as KtProperty emptyBody.addAfter(psiFactory.createNewLine(), firstChild) - actualExpression = reference ?: return + actualExpression = reference?.element ?: return diff = actualExpression.textRange.startOffset - emptyBody.textRange.startOffset actualExpressionText = actualExpression.text emptyBody = anchor.replace(emptyBody) as KtBlockExpression elem = findElementByOffsetAndText(diff, actualExpressionText, emptyBody) if (elem != null) { - reference = elem as KtExpression + reference = SmartPointerManager.createPointer(elem as KtExpression) } emptyBody.accept( @@ -240,7 +241,7 @@ object KotlinIntroduceVariableHandler : RefactoringActionHandler { if (!expression.isOccurrence) return expression.isOccurrence = false - references.add(expression) + references.add(SmartPointerManager.createPointer(expression)) } }) } @@ -615,8 +616,8 @@ object KotlinIntroduceVariableHandler : RefactoringActionHandler { is KtProperty -> { KotlinVariableInplaceIntroducer( property, - introduceVariableContext.reference, - introduceVariableContext.references.toTypedArray(), + introduceVariableContext.reference?.element, + introduceVariableContext.references.mapNotNull { it.element }.toTypedArray(), suggestedNames.single(), isVar, /*todo*/ false, diff --git a/idea/testData/refactoring/introduceVariable/FromLambda.kt b/idea/testData/refactoring/introduceVariable/FromLambda.kt new file mode 100644 index 00000000000..cecb7e9a763 --- /dev/null +++ b/idea/testData/refactoring/introduceVariable/FromLambda.kt @@ -0,0 +1,4 @@ +fun foo() { + val z = 123 + val x: (Int) -> Int = { 123} +} \ No newline at end of file diff --git a/idea/testData/refactoring/introduceVariable/FromLambda.kt.after b/idea/testData/refactoring/introduceVariable/FromLambda.kt.after new file mode 100644 index 00000000000..9b8812d3228 --- /dev/null +++ b/idea/testData/refactoring/introduceVariable/FromLambda.kt.after @@ -0,0 +1,5 @@ +fun foo() { + val i = 123 + val z = i + val x: (Int) -> Int = { i } +} \ No newline at end of file diff --git a/idea/tests/org/jetbrains/kotlin/idea/refactoring/introduce/ExtractionTestGenerated.java b/idea/tests/org/jetbrains/kotlin/idea/refactoring/introduce/ExtractionTestGenerated.java index 4264a09b45d..2ae9e37cf41 100644 --- a/idea/tests/org/jetbrains/kotlin/idea/refactoring/introduce/ExtractionTestGenerated.java +++ b/idea/tests/org/jetbrains/kotlin/idea/refactoring/introduce/ExtractionTestGenerated.java @@ -110,6 +110,11 @@ public class ExtractionTestGenerated extends AbstractExtractionTest { runTest("idea/testData/refactoring/introduceVariable/FewOccurrences.kt"); } + @TestMetadata("FromLambda.kt") + public void testFromLambda() throws Exception { + runTest("idea/testData/refactoring/introduceVariable/FromLambda.kt"); + } + @TestMetadata("FunctionAddBlock.kt") public void testFunctionAddBlock() throws Exception { runTest("idea/testData/refactoring/introduceVariable/FunctionAddBlock.kt");