From cfe1c4426010ae811aeeab5c42b3b82457ac8541 Mon Sep 17 00:00:00 2001 From: Alexey Sedunov Date: Wed, 16 Dec 2015 16:28:14 +0300 Subject: [PATCH] Introduce Variable: Add type argument to initializer if they can't be inferred from the context #KT-5466 Fixed --- .../inline/KotlinInlineValHandler.kt | 41 +++-------------- .../KotlinIntroduceVariableHandler.kt | 36 ++++++++++++--- .../KotlinVariableInplaceIntroducer.kt | 8 ++-- .../idea/refactoring/jetRefactoringUtil.kt | 29 ++++++++++++ .../DeeperNestedCall.kt | 6 +++ .../DeeperNestedCall.kt.after | 7 +++ .../explicateTypeArguments/NestedCall.kt | 6 +++ .../NestedCall.kt.after | 7 +++ .../explicateTypeArguments/Parenthesized.kt | 4 ++ .../Parenthesized.kt.after | 5 +++ .../explicateTypeArguments/Qualified.kt | 6 +++ .../explicateTypeArguments/Qualified.kt.after | 7 +++ .../explicateTypeArguments/Simple.kt | 4 ++ .../explicateTypeArguments/Simple.kt.after | 5 +++ .../UnmatchedOccurrences.kt | 5 +++ .../UnmatchedOccurrences.kt.after | 6 +++ .../introduce/ExtractionTestGenerated.java | 45 +++++++++++++++++++ 17 files changed, 181 insertions(+), 46 deletions(-) create mode 100644 idea/testData/refactoring/introduceVariable/explicateTypeArguments/DeeperNestedCall.kt create mode 100644 idea/testData/refactoring/introduceVariable/explicateTypeArguments/DeeperNestedCall.kt.after create mode 100644 idea/testData/refactoring/introduceVariable/explicateTypeArguments/NestedCall.kt create mode 100644 idea/testData/refactoring/introduceVariable/explicateTypeArguments/NestedCall.kt.after create mode 100644 idea/testData/refactoring/introduceVariable/explicateTypeArguments/Parenthesized.kt create mode 100644 idea/testData/refactoring/introduceVariable/explicateTypeArguments/Parenthesized.kt.after create mode 100644 idea/testData/refactoring/introduceVariable/explicateTypeArguments/Qualified.kt create mode 100644 idea/testData/refactoring/introduceVariable/explicateTypeArguments/Qualified.kt.after create mode 100644 idea/testData/refactoring/introduceVariable/explicateTypeArguments/Simple.kt create mode 100644 idea/testData/refactoring/introduceVariable/explicateTypeArguments/Simple.kt.after create mode 100644 idea/testData/refactoring/introduceVariable/explicateTypeArguments/UnmatchedOccurrences.kt create mode 100644 idea/testData/refactoring/introduceVariable/explicateTypeArguments/UnmatchedOccurrences.kt.after diff --git a/idea/src/org/jetbrains/kotlin/idea/refactoring/inline/KotlinInlineValHandler.kt b/idea/src/org/jetbrains/kotlin/idea/refactoring/inline/KotlinInlineValHandler.kt index 56539afa7ce..d743d9db794 100644 --- a/idea/src/org/jetbrains/kotlin/idea/refactoring/inline/KotlinInlineValHandler.kt +++ b/idea/src/org/jetbrains/kotlin/idea/refactoring/inline/KotlinInlineValHandler.kt @@ -41,7 +41,9 @@ import org.jetbrains.kotlin.idea.KotlinLanguage import org.jetbrains.kotlin.idea.caches.resolve.analyze import org.jetbrains.kotlin.idea.caches.resolve.getResolutionFacade import org.jetbrains.kotlin.idea.codeInsight.shorten.performDelayedShortening +import org.jetbrains.kotlin.idea.core.refactoring.addTypeArgumentsIfNeeded import org.jetbrains.kotlin.idea.core.refactoring.checkConflictsInteractively +import org.jetbrains.kotlin.idea.core.refactoring.getQualifiedTypeArgumentList import org.jetbrains.kotlin.idea.core.replaced import org.jetbrains.kotlin.idea.refactoring.move.PackageNameInfo import org.jetbrains.kotlin.idea.refactoring.move.lazilyProcessInternalReferencesToUpdateOnPackageNameChange @@ -55,8 +57,6 @@ import org.jetbrains.kotlin.name.FqName import org.jetbrains.kotlin.psi.* import org.jetbrains.kotlin.psi.psiUtil.* import org.jetbrains.kotlin.resolve.BindingContext -import org.jetbrains.kotlin.resolve.calls.callUtil.getCallWithAssert -import org.jetbrains.kotlin.resolve.calls.callUtil.getResolvedCall import org.jetbrains.kotlin.resolve.lazy.BodyResolveMode import org.jetbrains.kotlin.types.ErrorUtils import org.jetbrains.kotlin.types.expressions.OperatorConventions @@ -156,7 +156,7 @@ class KotlinInlineValHandler : InlineActionHandler() { ?: return reportAmbiguousAssignment(project, editor, name, assignments) } - val typeArgumentsForCall = getTypeArgumentsStringForCall(initializer) + val typeArgumentsForCall = getQualifiedTypeArgumentList(initializer) val parametersForFunctionLiteral = getParametersForFunctionLiteral(initializer) val referencesInOriginalFile = referenceExpressions.filter { it.containingFile == file } @@ -217,7 +217,9 @@ class KotlinInlineValHandler : InlineActionHandler() { declaration.delete() if (inlinedExpressions.isNotEmpty()) { - typeArgumentsForCall?.let { addTypeArguments(it, inlinedExpressions) } + if (typeArgumentsForCall != null) { + inlinedExpressions.forEach { addTypeArgumentsIfNeeded(it, typeArgumentsForCall) } + } parametersForFunctionLiteral?.let { addFunctionLiteralParameterTypes(it, inlinedExpressions) } @@ -348,35 +350,4 @@ class KotlinInlineValHandler : InlineActionHandler() { hasCantInferParameter || hasUnresolvedItOrThis } } - - private fun addTypeArguments(typeArguments: String, inlinedExpressions: List) { - val containingFile = inlinedExpressions.first().getContainingKtFile() - val callsToAddArguments = inlinedExpressions.mapNotNull { - val context = it.analyze(BodyResolveMode.PARTIAL) - val call = it.getCallWithAssert(context) - val callElement = call.callElement - if (callElement is KtCallExpression && - hasIncompleteTypeInferenceDiagnostic(call, context) && - call.typeArgumentList == null) callElement else null - } - - val psiFactory = KtPsiFactory(containingFile) - for (call in callsToAddArguments) { - call.addAfter(psiFactory.createTypeArguments("<$typeArguments>"), call.calleeExpression) - ShortenReferences.DEFAULT.process(call.typeArgumentList!!) - } - } - - private fun getTypeArgumentsStringForCall(initializer: KtExpression): String? { - val context = initializer.analyze(BodyResolveMode.PARTIAL) - val call = initializer.getResolvedCall(context) ?: return null - val typeArgumentMap = call.typeArguments - val typeArguments = call.candidateDescriptor.typeParameters.mapNotNull { typeArgumentMap[it] } - return typeArguments.joinToString { IdeDescriptorRenderers.SOURCE_CODE_FOR_TYPE_ARGUMENTS.renderType(it) } - } - - private fun hasIncompleteTypeInferenceDiagnostic(call: Call, context: BindingContext): Boolean { - val callee = call.calleeExpression ?: return false - return context.diagnostics.forElement(callee).any { it.factory == Errors.TYPE_INFERENCE_NO_INFORMATION_FOR_PARAMETER } - } } 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 3e753fb5e0b..905fa9082c8 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 @@ -42,9 +42,7 @@ import org.jetbrains.kotlin.idea.analysis.computeTypeInfoInContext import org.jetbrains.kotlin.idea.caches.resolve.getResolutionFacade import org.jetbrains.kotlin.idea.codeInsight.DescriptorToSourceUtilsIde import org.jetbrains.kotlin.idea.core.* -import org.jetbrains.kotlin.idea.core.refactoring.Pass -import org.jetbrains.kotlin.idea.core.refactoring.chooseContainerElementIfNecessary -import org.jetbrains.kotlin.idea.core.refactoring.removeTemplateEntryBracesIfPossible +import org.jetbrains.kotlin.idea.core.refactoring.* import org.jetbrains.kotlin.idea.intentions.ConvertToBlockBodyIntention import org.jetbrains.kotlin.idea.refactoring.KotlinRefactoringBundle import org.jetbrains.kotlin.idea.refactoring.KotlinRefactoringUtil @@ -411,7 +409,9 @@ object KotlinIntroduceVariableHandler : KotlinIntroduceHandlerBase() { project: Project, editor: Editor, declaration: KtDestructuringDeclaration, - suggestedNames: List>) { + suggestedNames: List>, + postProcess: (KtDeclaration) -> Unit + ) { StartMarkAction.canStart(project)?.let { return } val builder = TemplateBuilderImpl(declaration) @@ -441,6 +441,9 @@ object KotlinIntroduceVariableHandler : KotlinIntroduceHandlerBase() { } override fun templateFinished(template: Template?, brokenOff: Boolean) { + if (!brokenOff) { + postProcess(declaration) + } finishMarkAction() } @@ -518,12 +521,24 @@ object KotlinIntroduceVariableHandler : KotlinIntroduceHandlerBase() { return showErrorHint(project, editor, KotlinRefactoringBundle.message("cannot.refactor.expression.has.unit.type")) } + val typeArgumentList = getQualifiedTypeArgumentList(KtPsiUtil.safeDeparenthesize(physicalExpression)) + val isInplaceAvailable = editor != null && editor.settings.isVariableInplaceRenameEnabled && !ApplicationManager.getApplication().isUnitTestMode val allOccurrences = occurrencesToReplace ?: expression.findOccurrences(occurrenceContainer) + fun postProcess(declaration: KtDeclaration) { + if (typeArgumentList == null) return + val initializer = when (declaration) { + is KtProperty -> declaration.initializer + is KtDestructuringDeclaration -> declaration.initializer + else -> null + } ?: return + runWriteAction { addTypeArgumentsIfNeeded(initializer, typeArgumentList) } + } + val callback = Pass { replaceChoice -> val allReplaces = when (replaceChoice) { OccurrencesChooser.ReplaceChoice.ALL -> allOccurrences @@ -545,6 +560,7 @@ object KotlinIntroduceVariableHandler : KotlinIntroduceHandlerBase() { calculateAnchor(commonParent, commonContainer, allReplaces), NewDeclarationNameValidator.Target.VARIABLES ) + val suggestedNames = if (componentFunctions.isNotEmpty()) { val collectingValidator = CollectingNameValidator(filter = validator) componentFunctions.map { suggestNamesForComponent(it, project, collectingValidator) } @@ -556,10 +572,12 @@ object KotlinIntroduceVariableHandler : KotlinIntroduceHandlerBase() { validator, "value").singletonList() } + val introduceVariableContext = IntroduceVariableContext( expression, suggestedNames, allReplaces, commonContainer, commonParent, replaceOccurrence, noTypeInference, expressionType, componentFunctions, bindingContext, resolutionFacade ) + project.executeCommand(INTRODUCE_VARIABLE, null) { runWriteAction { introduceVariableContext.runRefactoring() } @@ -573,7 +591,10 @@ object KotlinIntroduceVariableHandler : KotlinIntroduceHandlerBase() { editor.caretModel.moveToOffset(property.textOffset) editor.selectionModel.removeSelection() - if (!isInplaceAvailable) return@executeCommand + if (!isInplaceAvailable) { + postProcess(property) + return@executeCommand + } PsiDocumentManager.getInstance(project).commitDocument(editor.document) PsiDocumentManager.getInstance(project).doPostponedOperationsAndUnblockDocument(editor.document) @@ -590,12 +611,13 @@ object KotlinIntroduceVariableHandler : KotlinIntroduceHandlerBase() { expressionType, noTypeInference, project, - editor + editor, + ::postProcess ).startInplaceIntroduceTemplate() } is KtDestructuringDeclaration -> { - executeMultiDeclarationTemplate(project, editor, property, suggestedNames) + executeMultiDeclarationTemplate(project, editor, property, suggestedNames, ::postProcess) } else -> throw AssertionError("Unexpected declaration: ${property.getElementTextWithContext()}") diff --git a/idea/src/org/jetbrains/kotlin/idea/refactoring/introduce/introduceVariable/KotlinVariableInplaceIntroducer.kt b/idea/src/org/jetbrains/kotlin/idea/refactoring/introduce/introduceVariable/KotlinVariableInplaceIntroducer.kt index fc2a82a9a12..5dff79fac47 100644 --- a/idea/src/org/jetbrains/kotlin/idea/refactoring/introduce/introduceVariable/KotlinVariableInplaceIntroducer.kt +++ b/idea/src/org/jetbrains/kotlin/idea/refactoring/introduce/introduceVariable/KotlinVariableInplaceIntroducer.kt @@ -33,9 +33,7 @@ import org.jetbrains.kotlin.idea.intentions.SpecifyTypeExplicitlyIntention import org.jetbrains.kotlin.idea.refactoring.introduce.AbstractKotlinInplaceIntroducer import org.jetbrains.kotlin.idea.util.IdeDescriptorRenderers import org.jetbrains.kotlin.idea.util.application.executeWriteCommand -import org.jetbrains.kotlin.psi.KtExpression -import org.jetbrains.kotlin.psi.KtProperty -import org.jetbrains.kotlin.psi.KtPsiFactory +import org.jetbrains.kotlin.psi.* import org.jetbrains.kotlin.psi.psiUtil.startOffset import org.jetbrains.kotlin.types.KotlinType import java.awt.BorderLayout @@ -50,7 +48,8 @@ public class KotlinVariableInplaceIntroducer( val expressionType: KotlinType?, val noTypeInference: Boolean, project: Project, - editor: Editor + editor: Editor, + private val postProcess: (KtDeclaration) -> Unit ): AbstractKotlinInplaceIntroducer( addedVariable, originalExpression, @@ -155,5 +154,6 @@ public class KotlinVariableInplaceIntroducer( it.replace(replacement) } } + postProcess(addedVariable) } } \ No newline at end of file diff --git a/idea/src/org/jetbrains/kotlin/idea/refactoring/jetRefactoringUtil.kt b/idea/src/org/jetbrains/kotlin/idea/refactoring/jetRefactoringUtil.kt index c9bcb9c0a89..a345bc3f1c8 100644 --- a/idea/src/org/jetbrains/kotlin/idea/refactoring/jetRefactoringUtil.kt +++ b/idea/src/org/jetbrains/kotlin/idea/refactoring/jetRefactoringUtil.kt @@ -63,6 +63,7 @@ import org.jetbrains.kotlin.descriptors.CallableDescriptor import org.jetbrains.kotlin.descriptors.ClassDescriptor import org.jetbrains.kotlin.descriptors.ClassKind import org.jetbrains.kotlin.descriptors.FunctionDescriptor +import org.jetbrains.kotlin.diagnostics.Errors import org.jetbrains.kotlin.idea.KotlinFileType import org.jetbrains.kotlin.idea.caches.resolve.analyze import org.jetbrains.kotlin.idea.caches.resolve.getJavaMemberDescriptor @@ -71,7 +72,9 @@ import org.jetbrains.kotlin.idea.core.KotlinNameSuggester import org.jetbrains.kotlin.idea.core.getPackage import org.jetbrains.kotlin.idea.intentions.RemoveCurlyBracesFromTemplateIntention import org.jetbrains.kotlin.idea.j2k.IdeaJavaToKotlinServices +import org.jetbrains.kotlin.idea.util.IdeDescriptorRenderers import org.jetbrains.kotlin.idea.util.ProjectRootsUtil +import org.jetbrains.kotlin.idea.util.ShortenReferences import org.jetbrains.kotlin.idea.util.string.collapseSpaces import org.jetbrains.kotlin.j2k.ConverterSettings import org.jetbrains.kotlin.j2k.JavaToKotlinConverter @@ -83,6 +86,9 @@ import org.jetbrains.kotlin.psi.psiUtil.* import org.jetbrains.kotlin.renderer.DescriptorRenderer import org.jetbrains.kotlin.resolve.AnalyzingUtils import org.jetbrains.kotlin.resolve.BindingContext +import org.jetbrains.kotlin.resolve.calls.callUtil.getCallWithAssert +import org.jetbrains.kotlin.resolve.calls.callUtil.getResolvedCall +import org.jetbrains.kotlin.resolve.lazy.BodyResolveMode import java.io.File import java.lang.annotation.Retention import java.util.* @@ -769,4 +775,27 @@ fun dropOverrideKeywordIfNecessary(element: KtNamedDeclaration) { if (callableDescriptor.overriddenDescriptors.isEmpty()) { element.removeModifier(KtTokens.OVERRIDE_KEYWORD) } +} + +fun getQualifiedTypeArgumentList(initializer: KtExpression): KtTypeArgumentList? { + val context = initializer.analyze(BodyResolveMode.PARTIAL) + val call = initializer.getResolvedCall(context) ?: return null + val typeArgumentMap = call.typeArguments + val typeArguments = call.candidateDescriptor.typeParameters.mapNotNull { typeArgumentMap[it] } + val renderedList = typeArguments.joinToString(prefix = "<", postfix = ">") { + IdeDescriptorRenderers.SOURCE_CODE_FOR_TYPE_ARGUMENTS.renderType(it) + } + return KtPsiFactory(initializer).createTypeArguments(renderedList) +} + +fun addTypeArgumentsIfNeeded(expression: KtExpression, typeArgumentList: KtTypeArgumentList) { + val context = expression.analyze(BodyResolveMode.PARTIAL) + val call = expression.getCallWithAssert(context) + val callElement = call.callElement as? KtCallExpression ?: return + if (call.typeArgumentList != null) return + val callee = call.calleeExpression ?: return + if (context.diagnostics.forElement(callee).all { it.factory != Errors.TYPE_INFERENCE_NO_INFORMATION_FOR_PARAMETER }) return + + callElement.addAfter(typeArgumentList, callElement.calleeExpression) + ShortenReferences.DEFAULT.process(callElement.typeArgumentList!!) } \ No newline at end of file diff --git a/idea/testData/refactoring/introduceVariable/explicateTypeArguments/DeeperNestedCall.kt b/idea/testData/refactoring/introduceVariable/explicateTypeArguments/DeeperNestedCall.kt new file mode 100644 index 00000000000..3b709875367 --- /dev/null +++ b/idea/testData/refactoring/introduceVariable/explicateTypeArguments/DeeperNestedCall.kt @@ -0,0 +1,6 @@ +// WITH_RUNTIME +import java.util.ArrayList + +fun f() { + val list: List>> = ArrayList(ArrayList(listOf())) +} diff --git a/idea/testData/refactoring/introduceVariable/explicateTypeArguments/DeeperNestedCall.kt.after b/idea/testData/refactoring/introduceVariable/explicateTypeArguments/DeeperNestedCall.kt.after new file mode 100644 index 00000000000..ac1e9d1a10d --- /dev/null +++ b/idea/testData/refactoring/introduceVariable/explicateTypeArguments/DeeperNestedCall.kt.after @@ -0,0 +1,7 @@ +// WITH_RUNTIME +import java.util.ArrayList + +fun f() { + val p0 = ArrayList>>(listOf()) + val list: List>> = ArrayList(p0) +} diff --git a/idea/testData/refactoring/introduceVariable/explicateTypeArguments/NestedCall.kt b/idea/testData/refactoring/introduceVariable/explicateTypeArguments/NestedCall.kt new file mode 100644 index 00000000000..d506c740c3e --- /dev/null +++ b/idea/testData/refactoring/introduceVariable/explicateTypeArguments/NestedCall.kt @@ -0,0 +1,6 @@ +// WITH_RUNTIME +import java.util.ArrayList + +fun f() { + val v : List> = ArrayList(listOf()) +} diff --git a/idea/testData/refactoring/introduceVariable/explicateTypeArguments/NestedCall.kt.after b/idea/testData/refactoring/introduceVariable/explicateTypeArguments/NestedCall.kt.after new file mode 100644 index 00000000000..c024ec2578e --- /dev/null +++ b/idea/testData/refactoring/introduceVariable/explicateTypeArguments/NestedCall.kt.after @@ -0,0 +1,7 @@ +// WITH_RUNTIME +import java.util.ArrayList + +fun f() { + val p0 = listOf>() + val v : List> = ArrayList(p0) +} diff --git a/idea/testData/refactoring/introduceVariable/explicateTypeArguments/Parenthesized.kt b/idea/testData/refactoring/introduceVariable/explicateTypeArguments/Parenthesized.kt new file mode 100644 index 00000000000..50698ea82c6 --- /dev/null +++ b/idea/testData/refactoring/introduceVariable/explicateTypeArguments/Parenthesized.kt @@ -0,0 +1,4 @@ +// WITH_RUNTIME +fun f() { + val v : List = (listOf()) +} diff --git a/idea/testData/refactoring/introduceVariable/explicateTypeArguments/Parenthesized.kt.after b/idea/testData/refactoring/introduceVariable/explicateTypeArguments/Parenthesized.kt.after new file mode 100644 index 00000000000..0c20568e981 --- /dev/null +++ b/idea/testData/refactoring/introduceVariable/explicateTypeArguments/Parenthesized.kt.after @@ -0,0 +1,5 @@ +// WITH_RUNTIME +fun f() { + val listOf = listOf() + val v : List = listOf +} diff --git a/idea/testData/refactoring/introduceVariable/explicateTypeArguments/Qualified.kt b/idea/testData/refactoring/introduceVariable/explicateTypeArguments/Qualified.kt new file mode 100644 index 00000000000..cd6abf58bec --- /dev/null +++ b/idea/testData/refactoring/introduceVariable/explicateTypeArguments/Qualified.kt @@ -0,0 +1,6 @@ +// WITH_RUNTIME +fun String.ext(): List = listOf() + +fun f() { + val v : List = "".ext() +} diff --git a/idea/testData/refactoring/introduceVariable/explicateTypeArguments/Qualified.kt.after b/idea/testData/refactoring/introduceVariable/explicateTypeArguments/Qualified.kt.after new file mode 100644 index 00000000000..334b080fb88 --- /dev/null +++ b/idea/testData/refactoring/introduceVariable/explicateTypeArguments/Qualified.kt.after @@ -0,0 +1,7 @@ +// WITH_RUNTIME +fun String.ext(): List = listOf() + +fun f() { + val ext = "".ext() + val v : List = ext +} diff --git a/idea/testData/refactoring/introduceVariable/explicateTypeArguments/Simple.kt b/idea/testData/refactoring/introduceVariable/explicateTypeArguments/Simple.kt new file mode 100644 index 00000000000..5cae582bdac --- /dev/null +++ b/idea/testData/refactoring/introduceVariable/explicateTypeArguments/Simple.kt @@ -0,0 +1,4 @@ +// WITH_RUNTIME +fun f() { + val v : List = listOf() +} diff --git a/idea/testData/refactoring/introduceVariable/explicateTypeArguments/Simple.kt.after b/idea/testData/refactoring/introduceVariable/explicateTypeArguments/Simple.kt.after new file mode 100644 index 00000000000..0c20568e981 --- /dev/null +++ b/idea/testData/refactoring/introduceVariable/explicateTypeArguments/Simple.kt.after @@ -0,0 +1,5 @@ +// WITH_RUNTIME +fun f() { + val listOf = listOf() + val v : List = listOf +} diff --git a/idea/testData/refactoring/introduceVariable/explicateTypeArguments/UnmatchedOccurrences.kt b/idea/testData/refactoring/introduceVariable/explicateTypeArguments/UnmatchedOccurrences.kt new file mode 100644 index 00000000000..102821f5dd5 --- /dev/null +++ b/idea/testData/refactoring/introduceVariable/explicateTypeArguments/UnmatchedOccurrences.kt @@ -0,0 +1,5 @@ +// WITH_RUNTIME +fun f() { + val v : List = listOf() + val u : List = listOf() +} diff --git a/idea/testData/refactoring/introduceVariable/explicateTypeArguments/UnmatchedOccurrences.kt.after b/idea/testData/refactoring/introduceVariable/explicateTypeArguments/UnmatchedOccurrences.kt.after new file mode 100644 index 00000000000..b592f4f761f --- /dev/null +++ b/idea/testData/refactoring/introduceVariable/explicateTypeArguments/UnmatchedOccurrences.kt.after @@ -0,0 +1,6 @@ +// WITH_RUNTIME +fun f() { + val listOf = listOf() + val v : List = listOf + val u : List = listOf() +} 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 6aff4d945a7..d741e1669d1 100644 --- a/idea/tests/org/jetbrains/kotlin/idea/refactoring/introduce/ExtractionTestGenerated.java +++ b/idea/tests/org/jetbrains/kotlin/idea/refactoring/introduce/ExtractionTestGenerated.java @@ -457,6 +457,51 @@ public class ExtractionTestGenerated extends AbstractExtractionTest { doIntroduceVariableTest(fileName); } + @TestMetadata("idea/testData/refactoring/introduceVariable/explicateTypeArguments") + @TestDataPath("$PROJECT_ROOT") + @RunWith(JUnit3RunnerWithInners.class) + public static class ExplicateTypeArguments extends AbstractExtractionTest { + public void testAllFilesPresentInExplicateTypeArguments() throws Exception { + KotlinTestUtils.assertAllTestsPresentByMetadata(this.getClass(), new File("idea/testData/refactoring/introduceVariable/explicateTypeArguments"), Pattern.compile("^(.+)\\.(kt|kts)$"), true); + } + + @TestMetadata("DeeperNestedCall.kt") + public void testDeeperNestedCall() throws Exception { + String fileName = KotlinTestUtils.navigationMetadata("idea/testData/refactoring/introduceVariable/explicateTypeArguments/DeeperNestedCall.kt"); + doIntroduceVariableTest(fileName); + } + + @TestMetadata("NestedCall.kt") + public void testNestedCall() throws Exception { + String fileName = KotlinTestUtils.navigationMetadata("idea/testData/refactoring/introduceVariable/explicateTypeArguments/NestedCall.kt"); + doIntroduceVariableTest(fileName); + } + + @TestMetadata("Parenthesized.kt") + public void testParenthesized() throws Exception { + String fileName = KotlinTestUtils.navigationMetadata("idea/testData/refactoring/introduceVariable/explicateTypeArguments/Parenthesized.kt"); + doIntroduceVariableTest(fileName); + } + + @TestMetadata("Qualified.kt") + public void testQualified() throws Exception { + String fileName = KotlinTestUtils.navigationMetadata("idea/testData/refactoring/introduceVariable/explicateTypeArguments/Qualified.kt"); + doIntroduceVariableTest(fileName); + } + + @TestMetadata("Simple.kt") + public void testSimple() throws Exception { + String fileName = KotlinTestUtils.navigationMetadata("idea/testData/refactoring/introduceVariable/explicateTypeArguments/Simple.kt"); + doIntroduceVariableTest(fileName); + } + + @TestMetadata("UnmatchedOccurrences.kt") + public void testUnmatchedOccurrences() throws Exception { + String fileName = KotlinTestUtils.navigationMetadata("idea/testData/refactoring/introduceVariable/explicateTypeArguments/UnmatchedOccurrences.kt"); + doIntroduceVariableTest(fileName); + } + } + @TestMetadata("idea/testData/refactoring/introduceVariable/extractToScope") @TestDataPath("$PROJECT_ROOT") @RunWith(JUnit3RunnerWithInners.class)