diff --git a/idea/src/org/jetbrains/kotlin/idea/quickfix/createFromUsage/createVariable/CreateParameterByNamedArgumentActionFactory.kt b/idea/src/org/jetbrains/kotlin/idea/quickfix/createFromUsage/createVariable/CreateParameterByNamedArgumentActionFactory.kt index 613e3a4d243..73b2bcade70 100644 --- a/idea/src/org/jetbrains/kotlin/idea/quickfix/createFromUsage/createVariable/CreateParameterByNamedArgumentActionFactory.kt +++ b/idea/src/org/jetbrains/kotlin/idea/quickfix/createFromUsage/createVariable/CreateParameterByNamedArgumentActionFactory.kt @@ -25,6 +25,7 @@ import org.jetbrains.kotlin.idea.refactoring.canRefactor import org.jetbrains.kotlin.idea.quickfix.createFromUsage.callableBuilder.guessTypes import org.jetbrains.kotlin.idea.refactoring.changeSignature.KotlinParameterInfo import org.jetbrains.kotlin.idea.refactoring.changeSignature.KotlinTypeInfo +import org.jetbrains.kotlin.idea.refactoring.changeSignature.KotlinValVar import org.jetbrains.kotlin.psi.* import org.jetbrains.kotlin.psi.psiUtil.getStrictParentOfType import org.jetbrains.kotlin.resolve.calls.callUtil.getResolvedCall @@ -58,11 +59,14 @@ object CreateParameterByNamedArgumentActionFactory: CreateParameterFromUsageFact } ?: anyType if (paramType.hasTypeParametersToAdd(functionDescriptor, context)) return null + val needVal = callable is KtPrimaryConstructor && ((callable.getContainingClassOrObject() as? KtClass)?.isData() ?: false) + val parameterInfo = KotlinParameterInfo( callableDescriptor = functionDescriptor, name = name, originalTypeInfo = KotlinTypeInfo(false, paramType), - defaultValueForCall = argumentExpression + defaultValueForCall = argumentExpression, + valOrVar = if (needVal) KotlinValVar.Val else KotlinValVar.None ) return CreateParameterData(parameterInfo, element) diff --git a/idea/src/org/jetbrains/kotlin/idea/refactoring/kotlinRefactoringUtil.kt b/idea/src/org/jetbrains/kotlin/idea/refactoring/kotlinRefactoringUtil.kt index 6cfa6460e88..88978d1b09c 100644 --- a/idea/src/org/jetbrains/kotlin/idea/refactoring/kotlinRefactoringUtil.kt +++ b/idea/src/org/jetbrains/kotlin/idea/refactoring/kotlinRefactoringUtil.kt @@ -761,11 +761,25 @@ fun replaceListPsiAndKeepDelimiters( if (commonCount == 0) return originalList.listReplacer(newList) + val lastOriginalParameter = oldParameters.last() + if (oldCount > commonCount) { - originalList.deleteChildRange(oldParameters[commonCount - 1].nextSibling, oldParameters.last()) + originalList.deleteChildRange(oldParameters[commonCount - 1].nextSibling, lastOriginalParameter) } else if (newCount > commonCount) { - originalList.addRangeAfter(newParameters[commonCount - 1].nextSibling, newParameters.last(), oldParameters.last()) + val psiBeforeLastParameter = lastOriginalParameter.prevSibling + val withMultiline = (psiBeforeLastParameter is PsiWhiteSpace || psiBeforeLastParameter is PsiComment) && psiBeforeLastParameter.textContains('\n') + val extraSpace = if (withMultiline) KtPsiFactory(originalList).createNewLine() else null + originalList.addRangeAfter(newParameters[commonCount - 1].nextSibling, newParameters.last(), lastOriginalParameter) + if (extraSpace != null) { + val addedItems = originalList.itemsFun().subList(commonCount, newCount) + for (addedItem in addedItems) { + val elementBefore = addedItem.prevSibling + if ((elementBefore !is PsiWhiteSpace && elementBefore !is PsiComment) || !elementBefore.textContains('\n')) { + addedItem.parent.addBefore(extraSpace, addedItem) + } + } + } } return originalList diff --git a/idea/testData/quickfix/createFromUsage/createVariable/parameter/dataClassPropertyByNamedArgument.kt b/idea/testData/quickfix/createFromUsage/createVariable/parameter/dataClassPropertyByNamedArgument.kt new file mode 100644 index 00000000000..d5d236274a5 --- /dev/null +++ b/idea/testData/quickfix/createFromUsage/createVariable/parameter/dataClassPropertyByNamedArgument.kt @@ -0,0 +1,11 @@ +// "Create property 'parameter4' as constructor parameter" "true" + +data class MyDto( + val parameter1:String, + val parameter2:String ="", + val parameter3:String ="" +) + +fun main(args: Array) { + println(MyDto(parameter1 = "value1", parameter4 = "value4")) +} \ No newline at end of file diff --git a/idea/testData/quickfix/createFromUsage/createVariable/parameter/dataClassPropertyByNamedArgument.kt.after b/idea/testData/quickfix/createFromUsage/createVariable/parameter/dataClassPropertyByNamedArgument.kt.after new file mode 100644 index 00000000000..a280e115b1c --- /dev/null +++ b/idea/testData/quickfix/createFromUsage/createVariable/parameter/dataClassPropertyByNamedArgument.kt.after @@ -0,0 +1,12 @@ +// "Create property 'parameter4' as constructor parameter" "true" + +data class MyDto( + val parameter1: String, + val parameter2: String = "", + val parameter3: String = "", + val parameter4: String +) + +fun main(args: Array) { + println(MyDto(parameter1 = "value1", parameter4 = "value4")) +} \ No newline at end of file diff --git a/idea/tests/org/jetbrains/kotlin/idea/quickfix/QuickFixTestGenerated.java b/idea/tests/org/jetbrains/kotlin/idea/quickfix/QuickFixTestGenerated.java index 9169bb14e14..21f460ac3ac 100644 --- a/idea/tests/org/jetbrains/kotlin/idea/quickfix/QuickFixTestGenerated.java +++ b/idea/tests/org/jetbrains/kotlin/idea/quickfix/QuickFixTestGenerated.java @@ -4248,6 +4248,12 @@ public class QuickFixTestGenerated extends AbstractQuickFixTest { doTest(fileName); } + @TestMetadata("dataClassPropertyByNamedArgument.kt") + public void testDataClassPropertyByNamedArgument() throws Exception { + String fileName = KotlinTestUtils.navigationMetadata("idea/testData/quickfix/createFromUsage/createVariable/parameter/dataClassPropertyByNamedArgument.kt"); + doTest(fileName); + } + @TestMetadata("inAccessorInClass.kt") public void testInAccessorInClass() throws Exception { String fileName = KotlinTestUtils.navigationMetadata("idea/testData/quickfix/createFromUsage/createVariable/parameter/inAccessorInClass.kt");