diff --git a/compiler/frontend/src/org/jetbrains/kotlin/psi/psiUtil/ktPsiUtil.kt b/compiler/frontend/src/org/jetbrains/kotlin/psi/psiUtil/ktPsiUtil.kt index 0650662d589..5819eb93832 100644 --- a/compiler/frontend/src/org/jetbrains/kotlin/psi/psiUtil/ktPsiUtil.kt +++ b/compiler/frontend/src/org/jetbrains/kotlin/psi/psiUtil/ktPsiUtil.kt @@ -421,4 +421,6 @@ public fun KtExpression.getOutermostParenthesizerOrThis(): KtExpression { else -> true } }?.first as KtExpression? ?: this -} \ No newline at end of file +} + +public fun PsiElement.isFunctionalExpression(): Boolean = this is KtNamedFunction && nameIdentifier == null \ No newline at end of file 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 80046fb9fa4..cbb5229a1c4 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 @@ -29,13 +29,18 @@ import com.intellij.psi.util.PsiTreeUtil import com.intellij.refactoring.HelpID import com.intellij.refactoring.introduce.inplace.OccurrencesChooser import com.intellij.refactoring.util.CommonRefactoringUtil +import com.intellij.util.SmartList import org.jetbrains.kotlin.builtins.KotlinBuiltIns +import org.jetbrains.kotlin.descriptors.ValueParameterDescriptor +import org.jetbrains.kotlin.idea.analysis.analyzeInContext import org.jetbrains.kotlin.idea.analysis.computeTypeInfoInContext import org.jetbrains.kotlin.idea.caches.resolve.getResolutionFacade import org.jetbrains.kotlin.idea.core.KotlinNameSuggester import org.jetbrains.kotlin.idea.core.NewDeclarationNameValidator +import org.jetbrains.kotlin.idea.core.compareDescriptors import org.jetbrains.kotlin.idea.core.moveInsideParenthesesAndReplaceWith import org.jetbrains.kotlin.idea.core.refactoring.Pass +import org.jetbrains.kotlin.idea.core.refactoring.chooseContainerElementIfNecessary import org.jetbrains.kotlin.idea.intentions.ConvertToBlockBodyIntention import org.jetbrains.kotlin.idea.intentions.RemoveCurlyBracesFromTemplateIntention import org.jetbrains.kotlin.idea.refactoring.KotlinRefactoringBundle @@ -61,9 +66,11 @@ import org.jetbrains.kotlin.resolve.ObservableBindingTrace import org.jetbrains.kotlin.resolve.bindingContextUtil.getDataFlowInfo import org.jetbrains.kotlin.resolve.bindingContextUtil.isUsedAsExpression import org.jetbrains.kotlin.resolve.lazy.BodyResolveMode +import org.jetbrains.kotlin.resolve.source.getPsi import org.jetbrains.kotlin.types.KotlinType import org.jetbrains.kotlin.types.checker.KotlinTypeChecker import org.jetbrains.kotlin.utils.addIfNotNull +import org.jetbrains.kotlin.utils.ifEmpty import org.jetbrains.kotlin.utils.sure import java.util.* @@ -314,7 +321,7 @@ object KotlinIntroduceVariableHandler : KotlinIntroduceHandlerBase() { return isUsedAsExpression(bindingContext) || container != parent } - private fun PsiElement.getContainer(): PsiElement? { + private fun KtElement.getContainer(): KtElement? { if (this is KtBlockExpression) return this return (parentsWithSelf zip parents).firstOrNull { @@ -326,7 +333,7 @@ object KotlinIntroduceVariableHandler : KotlinIntroduceHandlerBase() { is KtDeclarationWithBody -> parent.bodyExpression == place else -> false } - }?.second + }?.second as? KtElement } private fun KtContainerNode.isBadContainerNode(place: PsiElement): Boolean { @@ -339,8 +346,8 @@ object KotlinIntroduceVariableHandler : KotlinIntroduceHandlerBase() { } } - private fun PsiElement.getOccurrenceContainer(): PsiElement? { - var result: PsiElement? = null + private fun KtExpression.getOccurrenceContainer(): KtElement? { + var result: KtElement? = null for ((place, parent) in parentsWithSelf zip parents) { when { parent is KtContainerNode && place !is KtBlockExpression && !parent.isBadContainerNode(place) -> result = parent @@ -361,12 +368,14 @@ object KotlinIntroduceVariableHandler : KotlinIntroduceHandlerBase() { fun doRefactoring( project: Project, editor: Editor?, - expressionToExtract: KtExpression?, + expression: KtExpression, + container: KtElement, + occurrenceContainer: KtElement, + resolutionFacade: ResolutionFacade, + bindingContext: BindingContext, occurrencesToReplace: List?, onNonInteractiveFinish: ((KtProperty) -> Unit)? ) { - val expression = expressionToExtract?.let { KtPsiUtil.safeDeparenthesize(it) } - ?: return showErrorHint(project, editor, KotlinRefactoringBundle.message("cannot.refactor.no.expression")) val parent = expression.parent when { @@ -388,8 +397,6 @@ object KotlinIntroduceVariableHandler : KotlinIntroduceHandlerBase() { return showErrorHint(project, editor, KotlinRefactoringBundle.message("cannot.refactor.no.container")) } - val resolutionFacade = expression.getResolutionFacade() - val bindingContext = resolutionFacade.analyze(expression, BodyResolveMode.FULL) val expressionType = bindingContext.getType(expression) //can be null or error type val scope = expression.getResolutionScope(bindingContext, resolutionFacade) val dataFlowInfo = bindingContext.getDataFlowInfo(expression) @@ -408,11 +415,6 @@ object KotlinIntroduceVariableHandler : KotlinIntroduceHandlerBase() { return showErrorHint(project, editor, KotlinRefactoringBundle.message("cannot.refactor.expression.has.unit.type")) } - val container = expression.getContainer() - ?: return showErrorHint(project, editor, KotlinRefactoringBundle.message("cannot.refactor.no.container")) - val occurrenceContainer = expression.getOccurrenceContainer() - ?: return showErrorHint(project, editor, KotlinRefactoringBundle.message("cannot.refactor.no.container")) - val isInplaceAvailable = editor != null && editor.settings.isVariableInplaceRenameEnabled && !ApplicationManager.getApplication().isUnitTestMode @@ -427,7 +429,11 @@ object KotlinIntroduceVariableHandler : KotlinIntroduceHandlerBase() { val replaceOccurrence = expression.shouldReplaceOccurrence(bindingContext, container) || allReplaces.size > 1 val commonParent = PsiTreeUtil.findCommonParent(allReplaces) as KtElement - val commonContainer = commonParent.getContainer() as KtElement + var commonContainer = commonParent.getContainer()!! + if (commonContainer != container && container.isAncestor(commonContainer, true)) { + commonContainer = container + } + val validator = NewDeclarationNameValidator( commonContainer, calculateAnchor(commonParent, commonContainer, allReplaces), @@ -478,6 +484,100 @@ object KotlinIntroduceVariableHandler : KotlinIntroduceHandlerBase() { } } + private fun PsiElement.isFunExpressionOrLambdaBody(): Boolean { + if (isFunctionalExpression()) return true + val parent = parent as? KtFunction ?: return false + return parent.bodyExpression == this && (parent is KtFunctionLiteral || parent.isFunctionalExpression()) + } + + private fun KtExpression.getCandidateContainers( + resolutionFacade: ResolutionFacade, + originalContext: BindingContext + ): List> { + val file = getContainingKtFile() + + val references = collectDescendantsOfType() + + fun isResolvableNextTo(neighbour: KtExpression): Boolean { + val scope = neighbour.getResolutionScope(originalContext, resolutionFacade) + val newContext = analyzeInContext(scope, neighbour) + val project = file.project + return references.all { + val originalDescriptor = originalContext[BindingContext.REFERENCE_TARGET, it] + val newDescriptor = newContext[BindingContext.REFERENCE_TARGET, it] + + if (originalDescriptor is ValueParameterDescriptor + && (originalContext[BindingContext.AUTO_CREATED_IT, originalDescriptor] ?: false)) { + return@all originalDescriptor.containingDeclaration.source.getPsi().isAncestor(neighbour, true) + } + + compareDescriptors(project, newDescriptor, originalDescriptor) + } + } + + val firstContainer = getContainer() ?: return emptyList() + val firstOccurrenceContainer = getOccurrenceContainer() ?: return emptyList() + + val containers = SmartList(firstContainer) + val occurrenceContainers = SmartList(firstOccurrenceContainer) + + if (!firstContainer.isFunExpressionOrLambdaBody()) return listOf(firstContainer to firstOccurrenceContainer) + + val lambdasAndContainers = ArrayList>().apply { + var container = firstContainer + do { + var lambda: KtExpression = container.getNonStrictParentOfType()!! + if (lambda is KtFunctionLiteral) lambda = lambda.parent as? KtFunctionLiteralExpression ?: return@apply + if (!isResolvableNextTo(lambda)) return@apply + container = lambda.getContainer() ?: return@apply + add(lambda to container) + } while (container.isFunExpressionOrLambdaBody()) + } + + lambdasAndContainers.mapTo(containers) { it.second } + lambdasAndContainers.mapTo(occurrenceContainers) { it.first.getOccurrenceContainer() } + return ArrayList>().apply { + for ((container, occurrenceContainer) in (containers zip occurrenceContainers)) { + if (occurrenceContainer == null) continue + add(container to occurrenceContainer) + } + } + } + + fun doRefactoring( + project: Project, + editor: Editor?, + expressionToExtract: KtExpression?, + occurrencesToReplace: List?, + onNonInteractiveFinish: ((KtProperty) -> Unit)? + ) { + val expression = expressionToExtract?.let { KtPsiUtil.safeDeparenthesize(it) } + ?: return showErrorHint(project, editor, KotlinRefactoringBundle.message("cannot.refactor.no.expression")) + + val resolutionFacade = expression.getResolutionFacade() + val bindingContext = resolutionFacade.analyze(expression, BodyResolveMode.FULL) + + fun runWithChosenContainers(container: KtElement, occurrenceContainer: KtElement) { + doRefactoring(project, editor, expression, container, occurrenceContainer, resolutionFacade, bindingContext, occurrencesToReplace, onNonInteractiveFinish) + } + + val candidateContainers = expression.getCandidateContainers(resolutionFacade, bindingContext).ifEmpty { + return showErrorHint(project, editor, KotlinRefactoringBundle.message("cannot.refactor.no.container")) + } + + if (editor == null) { + return candidateContainers.first().let { runWithChosenContainers(it.first, it.second) } + } + + if (ApplicationManager.getApplication().isUnitTestMode) { + return candidateContainers.last().let { runWithChosenContainers(it.first, it.second) } + } + + chooseContainerElementIfNecessary(candidateContainers, editor, "Select target code block", true, { it.first }) { + runWithChosenContainers(it.first, it.second) + } + } + override fun invoke(project: Project, editor: Editor, file: PsiFile, dataContext: DataContext) { try { KotlinRefactoringUtil.selectExpression(editor, file) { doRefactoring(project, editor, it, null, null) } diff --git a/idea/testData/refactoring/introduceVariable/extractToScope/implicitOuterThisInsideNestedLamba.kt b/idea/testData/refactoring/introduceVariable/extractToScope/implicitOuterThisInsideNestedLamba.kt new file mode 100644 index 00000000000..0bd86fbfbc5 --- /dev/null +++ b/idea/testData/refactoring/introduceVariable/extractToScope/implicitOuterThisInsideNestedLamba.kt @@ -0,0 +1,9 @@ +class A(val a: Int) +class B(val b: Int) + +fun foo(f: A.() -> Int) = A(1).f() +fun bar(f: B.() -> Int) = B(2).f() + +fun test() { + foo { bar { a + b } } +} \ No newline at end of file diff --git a/idea/testData/refactoring/introduceVariable/extractToScope/implicitOuterThisInsideNestedLamba.kt.after b/idea/testData/refactoring/introduceVariable/extractToScope/implicitOuterThisInsideNestedLamba.kt.after new file mode 100644 index 00000000000..c58714d1b24 --- /dev/null +++ b/idea/testData/refactoring/introduceVariable/extractToScope/implicitOuterThisInsideNestedLamba.kt.after @@ -0,0 +1,10 @@ +class A(val a: Int) +class B(val b: Int) + +fun foo(f: A.() -> Int) = A(1).f() +fun bar(f: B.() -> Int) = B(2).f() + +fun test() { + foo { val a1 = a + bar { a1 + b } } +} \ No newline at end of file diff --git a/idea/testData/refactoring/introduceVariable/extractToScope/implicitThisInsideNestedLamba.kt b/idea/testData/refactoring/introduceVariable/extractToScope/implicitThisInsideNestedLamba.kt new file mode 100644 index 00000000000..5c7008cc016 --- /dev/null +++ b/idea/testData/refactoring/introduceVariable/extractToScope/implicitThisInsideNestedLamba.kt @@ -0,0 +1,9 @@ +class A(val a: Int) +class B(val b: Int) + +fun foo(f: A.() -> Int) = A(1).f() +fun bar(f: B.() -> Int) = B(2).f() + +fun test() { + foo { bar { a + b } } +} \ No newline at end of file diff --git a/idea/testData/refactoring/introduceVariable/extractToScope/implicitThisInsideNestedLamba.kt.after b/idea/testData/refactoring/introduceVariable/extractToScope/implicitThisInsideNestedLamba.kt.after new file mode 100644 index 00000000000..3d003b01df2 --- /dev/null +++ b/idea/testData/refactoring/introduceVariable/extractToScope/implicitThisInsideNestedLamba.kt.after @@ -0,0 +1,11 @@ +class A(val a: Int) +class B(val b: Int) + +fun foo(f: A.() -> Int) = A(1).f() +fun bar(f: B.() -> Int) = B(2).f() + +fun test() { + foo { bar { val b1 = b + a + b1 + } } +} \ No newline at end of file diff --git a/idea/testData/refactoring/introduceVariable/extractToScope/insideFunExpression.kt b/idea/testData/refactoring/introduceVariable/extractToScope/insideFunExpression.kt new file mode 100644 index 00000000000..5d66bd6bea9 --- /dev/null +++ b/idea/testData/refactoring/introduceVariable/extractToScope/insideFunExpression.kt @@ -0,0 +1,5 @@ +fun foo(f: () -> Int) { } + +fun test() { + foo(fun() = (1 + 2) * 3) +} \ No newline at end of file diff --git a/idea/testData/refactoring/introduceVariable/extractToScope/insideFunExpression.kt.after b/idea/testData/refactoring/introduceVariable/extractToScope/insideFunExpression.kt.after new file mode 100644 index 00000000000..a349cf092e1 --- /dev/null +++ b/idea/testData/refactoring/introduceVariable/extractToScope/insideFunExpression.kt.after @@ -0,0 +1,6 @@ +fun foo(f: () -> Int) { } + +fun test() { + val i = 1 + 2 + foo(fun() = i * 3) +} \ No newline at end of file diff --git a/idea/testData/refactoring/introduceVariable/extractToScope/insideFunExpressionWithBlock.kt b/idea/testData/refactoring/introduceVariable/extractToScope/insideFunExpressionWithBlock.kt new file mode 100644 index 00000000000..44fa912b736 --- /dev/null +++ b/idea/testData/refactoring/introduceVariable/extractToScope/insideFunExpressionWithBlock.kt @@ -0,0 +1,5 @@ +fun foo(f: () -> Int) { } + +fun test() { + foo(fun(): Int { return (1 + 2) * 3 }) +} \ No newline at end of file diff --git a/idea/testData/refactoring/introduceVariable/extractToScope/insideFunExpressionWithBlock.kt.after b/idea/testData/refactoring/introduceVariable/extractToScope/insideFunExpressionWithBlock.kt.after new file mode 100644 index 00000000000..63de8c4f090 --- /dev/null +++ b/idea/testData/refactoring/introduceVariable/extractToScope/insideFunExpressionWithBlock.kt.after @@ -0,0 +1,6 @@ +fun foo(f: () -> Int) { } + +fun test() { + val i = 1 + 2 + foo(fun(): Int { return i * 3 }) +} \ No newline at end of file diff --git a/idea/testData/refactoring/introduceVariable/extractToScope/insideLamba.kt b/idea/testData/refactoring/introduceVariable/extractToScope/insideLamba.kt new file mode 100644 index 00000000000..06eb39e0060 --- /dev/null +++ b/idea/testData/refactoring/introduceVariable/extractToScope/insideLamba.kt @@ -0,0 +1,5 @@ +fun foo(f: () -> Int) { } + +fun test() { + foo { (1 + 2) * 3 } +} \ No newline at end of file diff --git a/idea/testData/refactoring/introduceVariable/extractToScope/insideLamba.kt.after b/idea/testData/refactoring/introduceVariable/extractToScope/insideLamba.kt.after new file mode 100644 index 00000000000..acd2e900cc0 --- /dev/null +++ b/idea/testData/refactoring/introduceVariable/extractToScope/insideLamba.kt.after @@ -0,0 +1,6 @@ +fun foo(f: () -> Int) { } + +fun test() { + val i = 1 + 2 + foo { i * 3 } +} \ No newline at end of file diff --git a/idea/testData/refactoring/introduceVariable/extractToScope/insideNestedFunExpression.kt b/idea/testData/refactoring/introduceVariable/extractToScope/insideNestedFunExpression.kt new file mode 100644 index 00000000000..198789c8672 --- /dev/null +++ b/idea/testData/refactoring/introduceVariable/extractToScope/insideNestedFunExpression.kt @@ -0,0 +1,5 @@ +fun foo(f: () -> Int) = f() + +fun test() { + foo(fun() = foo(fun() = (1 + 2) * 3)) +} \ No newline at end of file diff --git a/idea/testData/refactoring/introduceVariable/extractToScope/insideNestedFunExpression.kt.after b/idea/testData/refactoring/introduceVariable/extractToScope/insideNestedFunExpression.kt.after new file mode 100644 index 00000000000..b0d64a20da0 --- /dev/null +++ b/idea/testData/refactoring/introduceVariable/extractToScope/insideNestedFunExpression.kt.after @@ -0,0 +1,6 @@ +fun foo(f: () -> Int) = f() + +fun test() { + val i = 1 + 2 + foo(fun() = foo(fun() = i * 3)) +} \ No newline at end of file diff --git a/idea/testData/refactoring/introduceVariable/extractToScope/insideNestedFunExpressionInLambda.kt b/idea/testData/refactoring/introduceVariable/extractToScope/insideNestedFunExpressionInLambda.kt new file mode 100644 index 00000000000..ce73561abc5 --- /dev/null +++ b/idea/testData/refactoring/introduceVariable/extractToScope/insideNestedFunExpressionInLambda.kt @@ -0,0 +1,5 @@ +fun foo(f: () -> Int) = f() + +fun test() { + foo { foo(fun() = (1 + 2) * 3) } +} \ No newline at end of file diff --git a/idea/testData/refactoring/introduceVariable/extractToScope/insideNestedFunExpressionInLambda.kt.after b/idea/testData/refactoring/introduceVariable/extractToScope/insideNestedFunExpressionInLambda.kt.after new file mode 100644 index 00000000000..d6b3724717f --- /dev/null +++ b/idea/testData/refactoring/introduceVariable/extractToScope/insideNestedFunExpressionInLambda.kt.after @@ -0,0 +1,6 @@ +fun foo(f: () -> Int) = f() + +fun test() { + val i = 1 + 2 + foo { foo(fun() = i * 3) } +} \ No newline at end of file diff --git a/idea/testData/refactoring/introduceVariable/extractToScope/insideNestedLamba.kt b/idea/testData/refactoring/introduceVariable/extractToScope/insideNestedLamba.kt new file mode 100644 index 00000000000..94f0469ccf6 --- /dev/null +++ b/idea/testData/refactoring/introduceVariable/extractToScope/insideNestedLamba.kt @@ -0,0 +1,5 @@ +fun foo(f: () -> Int) = f() + +fun test() { + foo { foo { (1 + 2) * 3 } } +} \ No newline at end of file diff --git a/idea/testData/refactoring/introduceVariable/extractToScope/insideNestedLamba.kt.after b/idea/testData/refactoring/introduceVariable/extractToScope/insideNestedLamba.kt.after new file mode 100644 index 00000000000..b94d5299db7 --- /dev/null +++ b/idea/testData/refactoring/introduceVariable/extractToScope/insideNestedLamba.kt.after @@ -0,0 +1,6 @@ +fun foo(f: () -> Int) = f() + +fun test() { + val i = 1 + 2 + foo { foo { i * 3 } } +} \ No newline at end of file diff --git a/idea/testData/refactoring/introduceVariable/extractToScope/insideNestedLambdaInFunExpression.kt b/idea/testData/refactoring/introduceVariable/extractToScope/insideNestedLambdaInFunExpression.kt new file mode 100644 index 00000000000..10217265721 --- /dev/null +++ b/idea/testData/refactoring/introduceVariable/extractToScope/insideNestedLambdaInFunExpression.kt @@ -0,0 +1,5 @@ +fun foo(f: () -> Int) = f() + +fun test() { + foo(fun() = foo { (1 + 2) * 3 }) +} \ No newline at end of file diff --git a/idea/testData/refactoring/introduceVariable/extractToScope/insideNestedLambdaInFunExpression.kt.after b/idea/testData/refactoring/introduceVariable/extractToScope/insideNestedLambdaInFunExpression.kt.after new file mode 100644 index 00000000000..ecdf68939f3 --- /dev/null +++ b/idea/testData/refactoring/introduceVariable/extractToScope/insideNestedLambdaInFunExpression.kt.after @@ -0,0 +1,6 @@ +fun foo(f: () -> Int) = f() + +fun test() { + val i = 1 + 2 + foo(fun() = foo { i * 3 }) +} \ No newline at end of file diff --git a/idea/testData/refactoring/introduceVariable/extractToScope/itInsideNestedLamba.kt b/idea/testData/refactoring/introduceVariable/extractToScope/itInsideNestedLamba.kt new file mode 100644 index 00000000000..3611a5917ac --- /dev/null +++ b/idea/testData/refactoring/introduceVariable/extractToScope/itInsideNestedLamba.kt @@ -0,0 +1,5 @@ +fun foo(f: (Int) -> Int) = f(0) + +fun test() { + foo { foo { (1 + 2) * it } } +} \ No newline at end of file diff --git a/idea/testData/refactoring/introduceVariable/extractToScope/itInsideNestedLamba.kt.after b/idea/testData/refactoring/introduceVariable/extractToScope/itInsideNestedLamba.kt.after new file mode 100644 index 00000000000..c76b210bfa4 --- /dev/null +++ b/idea/testData/refactoring/introduceVariable/extractToScope/itInsideNestedLamba.kt.after @@ -0,0 +1,7 @@ +fun foo(f: (Int) -> Int) = f(0) + +fun test() { + foo { foo { val it1 = it + (1 + 2) * it1 + } } +} \ No newline at end of file diff --git a/idea/testData/refactoring/introduceVariable/extractToScope/outerItInsideNestedLamba.kt b/idea/testData/refactoring/introduceVariable/extractToScope/outerItInsideNestedLamba.kt new file mode 100644 index 00000000000..ad01a40fa66 --- /dev/null +++ b/idea/testData/refactoring/introduceVariable/extractToScope/outerItInsideNestedLamba.kt @@ -0,0 +1,6 @@ +fun foo(f: (Int) -> Int) = f(0) +fun bar(f: () -> Int) = f() + +fun test() { + foo { bar { (1 + 2) * it } } +} \ No newline at end of file diff --git a/idea/testData/refactoring/introduceVariable/extractToScope/outerItInsideNestedLamba.kt.after b/idea/testData/refactoring/introduceVariable/extractToScope/outerItInsideNestedLamba.kt.after new file mode 100644 index 00000000000..b19dfef0e98 --- /dev/null +++ b/idea/testData/refactoring/introduceVariable/extractToScope/outerItInsideNestedLamba.kt.after @@ -0,0 +1,7 @@ +fun foo(f: (Int) -> Int) = f(0) +fun bar(f: () -> Int) = f() + +fun test() { + foo { val it1 = it + bar { (1 + 2) * it1 } } +} \ 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 fa4f68a6492..1f1abfd5543 100644 --- a/idea/tests/org/jetbrains/kotlin/idea/refactoring/introduce/ExtractionTestGenerated.java +++ b/idea/tests/org/jetbrains/kotlin/idea/refactoring/introduce/ExtractionTestGenerated.java @@ -432,6 +432,81 @@ public class ExtractionTestGenerated extends AbstractExtractionTest { String fileName = KotlinTestUtils.navigationMetadata("idea/testData/refactoring/introduceVariable/WhileCondition.kt"); doIntroduceVariableTest(fileName); } + + @TestMetadata("idea/testData/refactoring/introduceVariable/extractToScope") + @TestDataPath("$PROJECT_ROOT") + @RunWith(JUnit3RunnerWithInners.class) + public static class ExtractToScope extends AbstractExtractionTest { + public void testAllFilesPresentInExtractToScope() throws Exception { + KotlinTestUtils.assertAllTestsPresentByMetadata(this.getClass(), new File("idea/testData/refactoring/introduceVariable/extractToScope"), Pattern.compile("^(.+)\\.kt$"), true); + } + + @TestMetadata("implicitOuterThisInsideNestedLamba.kt") + public void testImplicitOuterThisInsideNestedLamba() throws Exception { + String fileName = KotlinTestUtils.navigationMetadata("idea/testData/refactoring/introduceVariable/extractToScope/implicitOuterThisInsideNestedLamba.kt"); + doIntroduceVariableTest(fileName); + } + + @TestMetadata("implicitThisInsideNestedLamba.kt") + public void testImplicitThisInsideNestedLamba() throws Exception { + String fileName = KotlinTestUtils.navigationMetadata("idea/testData/refactoring/introduceVariable/extractToScope/implicitThisInsideNestedLamba.kt"); + doIntroduceVariableTest(fileName); + } + + @TestMetadata("insideFunExpression.kt") + public void testInsideFunExpression() throws Exception { + String fileName = KotlinTestUtils.navigationMetadata("idea/testData/refactoring/introduceVariable/extractToScope/insideFunExpression.kt"); + doIntroduceVariableTest(fileName); + } + + @TestMetadata("insideFunExpressionWithBlock.kt") + public void testInsideFunExpressionWithBlock() throws Exception { + String fileName = KotlinTestUtils.navigationMetadata("idea/testData/refactoring/introduceVariable/extractToScope/insideFunExpressionWithBlock.kt"); + doIntroduceVariableTest(fileName); + } + + @TestMetadata("insideLamba.kt") + public void testInsideLamba() throws Exception { + String fileName = KotlinTestUtils.navigationMetadata("idea/testData/refactoring/introduceVariable/extractToScope/insideLamba.kt"); + doIntroduceVariableTest(fileName); + } + + @TestMetadata("insideNestedFunExpression.kt") + public void testInsideNestedFunExpression() throws Exception { + String fileName = KotlinTestUtils.navigationMetadata("idea/testData/refactoring/introduceVariable/extractToScope/insideNestedFunExpression.kt"); + doIntroduceVariableTest(fileName); + } + + @TestMetadata("insideNestedFunExpressionInLambda.kt") + public void testInsideNestedFunExpressionInLambda() throws Exception { + String fileName = KotlinTestUtils.navigationMetadata("idea/testData/refactoring/introduceVariable/extractToScope/insideNestedFunExpressionInLambda.kt"); + doIntroduceVariableTest(fileName); + } + + @TestMetadata("insideNestedLamba.kt") + public void testInsideNestedLamba() throws Exception { + String fileName = KotlinTestUtils.navigationMetadata("idea/testData/refactoring/introduceVariable/extractToScope/insideNestedLamba.kt"); + doIntroduceVariableTest(fileName); + } + + @TestMetadata("insideNestedLambdaInFunExpression.kt") + public void testInsideNestedLambdaInFunExpression() throws Exception { + String fileName = KotlinTestUtils.navigationMetadata("idea/testData/refactoring/introduceVariable/extractToScope/insideNestedLambdaInFunExpression.kt"); + doIntroduceVariableTest(fileName); + } + + @TestMetadata("itInsideNestedLamba.kt") + public void testItInsideNestedLamba() throws Exception { + String fileName = KotlinTestUtils.navigationMetadata("idea/testData/refactoring/introduceVariable/extractToScope/itInsideNestedLamba.kt"); + doIntroduceVariableTest(fileName); + } + + @TestMetadata("outerItInsideNestedLamba.kt") + public void testOuterItInsideNestedLamba() throws Exception { + String fileName = KotlinTestUtils.navigationMetadata("idea/testData/refactoring/introduceVariable/extractToScope/outerItInsideNestedLamba.kt"); + doIntroduceVariableTest(fileName); + } + } } @TestMetadata("idea/testData/refactoring/extractFunction")