diff --git a/plugins/kotlin/base/resources/resources-en/messages/KotlinBundle.properties b/plugins/kotlin/base/resources/resources-en/messages/KotlinBundle.properties index cf319bd8ea99..30562e56949a 100644 --- a/plugins/kotlin/base/resources/resources-en/messages/KotlinBundle.properties +++ b/plugins/kotlin/base/resources/resources-en/messages/KotlinBundle.properties @@ -1687,6 +1687,7 @@ convert.to.lambda.expression=Convert to a lambda expression put.arguments.on.separate.lines=Put arguments on separate lines put.parameters.on.separate.lines=Put parameters on separate lines put.expressions.on.separate.lines=Put expressions on separate lines +put.calls.on.separate.lines=Put calls on separate lines demorgan.law=DeMorgan Law replace.with.end.of.line.comment=Replace with end of line comment convert.collection.constructor.to.function=Convert Collection constructor to function diff --git a/plugins/kotlin/code-insight/intentions-shared/resources-en/intentionDescriptions/PutCallsOnSeparateLinesIntention/after.kt.template b/plugins/kotlin/code-insight/intentions-shared/resources-en/intentionDescriptions/PutCallsOnSeparateLinesIntention/after.kt.template new file mode 100644 index 000000000000..875731ef9144 --- /dev/null +++ b/plugins/kotlin/code-insight/intentions-shared/resources-en/intentionDescriptions/PutCallsOnSeparateLinesIntention/after.kt.template @@ -0,0 +1,7 @@ +fun calculate(): Int { + return call1().call2() + .call3() + .call5() + .call6() + .call7() +} diff --git a/plugins/kotlin/code-insight/intentions-shared/resources-en/intentionDescriptions/PutCallsOnSeparateLinesIntention/before.kt.template b/plugins/kotlin/code-insight/intentions-shared/resources-en/intentionDescriptions/PutCallsOnSeparateLinesIntention/before.kt.template new file mode 100644 index 000000000000..4934b2395f31 --- /dev/null +++ b/plugins/kotlin/code-insight/intentions-shared/resources-en/intentionDescriptions/PutCallsOnSeparateLinesIntention/before.kt.template @@ -0,0 +1,3 @@ +fun calculate(): Int { + return call1().call2().call3().call5().call6().call7() +} diff --git a/plugins/kotlin/code-insight/intentions-shared/resources-en/intentionDescriptions/PutCallsOnSeparateLinesIntention/description.html b/plugins/kotlin/code-insight/intentions-shared/resources-en/intentionDescriptions/PutCallsOnSeparateLinesIntention/description.html new file mode 100644 index 000000000000..c48f7b93847f --- /dev/null +++ b/plugins/kotlin/code-insight/intentions-shared/resources-en/intentionDescriptions/PutCallsOnSeparateLinesIntention/description.html @@ -0,0 +1,5 @@ + + +Formats call chain by placing each call on a separate line. + + \ No newline at end of file diff --git a/plugins/kotlin/code-insight/intentions-shared/resources/kotlin.code-insight.intentions-shared.xml b/plugins/kotlin/code-insight/intentions-shared/resources/kotlin.code-insight.intentions-shared.xml index 656e0aca0324..bf997d85ffb7 100644 --- a/plugins/kotlin/code-insight/intentions-shared/resources/kotlin.code-insight.intentions-shared.xml +++ b/plugins/kotlin/code-insight/intentions-shared/resources/kotlin.code-insight.intentions-shared.xml @@ -98,6 +98,13 @@ group.names.kotlin + + kotlin + org.jetbrains.kotlin.idea.codeInsight.intentions.shared.PutCallsOnSeparateLinesIntention + messages.KotlinBundle + group.names.kotlin + + kotlin org.jetbrains.kotlin.idea.codeInsight.intentions.shared.JoinArgumentListIntention diff --git a/plugins/kotlin/code-insight/intentions-shared/src/org/jetbrains/kotlin/idea/codeInsight/intentions/shared/PutCallsOnSeparateLinesIntention.kt b/plugins/kotlin/code-insight/intentions-shared/src/org/jetbrains/kotlin/idea/codeInsight/intentions/shared/PutCallsOnSeparateLinesIntention.kt new file mode 100644 index 000000000000..42dd30569665 --- /dev/null +++ b/plugins/kotlin/code-insight/intentions-shared/src/org/jetbrains/kotlin/idea/codeInsight/intentions/shared/PutCallsOnSeparateLinesIntention.kt @@ -0,0 +1,78 @@ +// Copyright 2000-2022 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license. +package org.jetbrains.kotlin.idea.codeInsight.intentions.shared + +import com.intellij.application.options.CodeStyle +import com.intellij.openapi.editor.Editor +import com.intellij.openapi.project.Project +import com.intellij.psi.PsiElement +import com.intellij.psi.PsiWhiteSpace +import com.intellij.psi.codeStyle.CodeStyleManager +import com.intellij.psi.impl.source.PostprocessReformattingAspect +import com.intellij.psi.util.descendants +import com.intellij.psi.util.parents +import org.jetbrains.kotlin.idea.base.resources.KotlinBundle +import org.jetbrains.kotlin.idea.codeinsight.api.applicable.intentions.AbstractKotlinApplicableIntention +import org.jetbrains.kotlin.idea.codeinsight.api.applicators.KotlinApplicabilityRange +import org.jetbrains.kotlin.idea.codeinsight.api.applicators.applicabilityRange +import org.jetbrains.kotlin.idea.formatter.kotlinCommonSettings +import org.jetbrains.kotlin.psi.KtImportDirective +import org.jetbrains.kotlin.psi.KtPsiFactory +import org.jetbrains.kotlin.psi.KtQualifiedExpression +import org.jetbrains.kotlin.util.takeWhileIsInstance + +internal class PutCallsOnSeparateLinesIntention : + AbstractKotlinApplicableIntention(KtQualifiedExpression::class) { + override fun getActionName(element: KtQualifiedExpression): String = familyName + override fun getFamilyName(): String = KotlinBundle.message("put.calls.on.separate.lines") + + override fun apply(element: KtQualifiedExpression, project: Project, editor: Editor?) { + val rootQualifierExpression = element.topmostQualifierExpression() ?: return + PostprocessReformattingAspect.getInstance(project).disablePostprocessFormattingInside { + val psiFactory = KtPsiFactory(project) + rootQualifierExpression.visitOperations(transformation = callChainTransformation(element)) { qualifierExpression -> + val operationReference = qualifierExpression.operationTokenNode as? PsiElement ?: return@visitOperations + val whiteSpace = operationReference.prevSibling as? PsiWhiteSpace + when { + whiteSpace == null -> qualifierExpression.addBefore(psiFactory.createNewLine(), operationReference) + !whiteSpace.textContains('\n') -> whiteSpace.replace(psiFactory.createWhiteSpace("\n${whiteSpace.text}")) + } + } + } + + CodeStyleManager.getInstance(project).reformat(/* element = */ rootQualifierExpression, /* canChangeWhiteSpacesOnly = */ true) + } + + override fun getApplicabilityRange(): KotlinApplicabilityRange = applicabilityRange { + (it.operationTokenNode as? PsiElement)?.textRangeInParent + } + + override fun isApplicableByPsi(element: KtQualifiedExpression): Boolean { + val topmostQualifierExpression = element.topmostQualifierExpression() ?: return false + if (topmostQualifierExpression.parent is KtImportDirective) return false + + topmostQualifierExpression.visitOperations(transformation = callChainTransformation(element)) { + val nextSibling = it.operationTokenNode.treePrev as? PsiWhiteSpace ?: return true + if (!nextSibling.textContains('\n')) return true + } + + return false + } + + private fun callChainTransformation(element: PsiElement): Sequence.() -> Sequence { + val wrapFirstCall = CodeStyle.getSettings(element.containingFile).kotlinCommonSettings.WRAP_FIRST_METHOD_IN_CALL_CHAIN + return { if (wrapFirstCall) this else drop(1) } + } +} + +private inline fun KtQualifiedExpression.visitOperations( + transformation: Sequence.() -> Sequence, + action: (KtQualifiedExpression) -> Unit, +) { + descendants(childrenFirst = true) { it is KtQualifiedExpression } + .filterIsInstance() + .transformation() + .forEach(action) +} + +private fun KtQualifiedExpression.topmostQualifierExpression(): KtQualifiedExpression? = + parents(withSelf = true).takeWhileIsInstance().lastOrNull() diff --git a/plugins/kotlin/code-insight/intentions-shared/tests/k1/test/org/jetbrains/kotlin/idea/codeInsight/intentions/shared/SharedK1IntentionTestGenerated.java b/plugins/kotlin/code-insight/intentions-shared/tests/k1/test/org/jetbrains/kotlin/idea/codeInsight/intentions/shared/SharedK1IntentionTestGenerated.java index 06b9399bcd77..076262858d9c 100644 --- a/plugins/kotlin/code-insight/intentions-shared/tests/k1/test/org/jetbrains/kotlin/idea/codeInsight/intentions/shared/SharedK1IntentionTestGenerated.java +++ b/plugins/kotlin/code-insight/intentions-shared/tests/k1/test/org/jetbrains/kotlin/idea/codeInsight/intentions/shared/SharedK1IntentionTestGenerated.java @@ -445,6 +445,69 @@ public abstract class SharedK1IntentionTestGenerated extends AbstractSharedK1Int } } + @RunWith(JUnit3RunnerWithInners.class) + @TestMetadata("../testData/intentions/putCallsOnSeparateLines") + public static class PutCallsOnSeparateLines extends AbstractSharedK1IntentionTest { + private void runTest(String testDataFilePath) throws Exception { + KotlinTestUtils.runTest(this::doTest, this, testDataFilePath); + } + + @TestMetadata("doNotWrapFirstElement.kt") + public void testDoNotWrapFirstElement() throws Exception { + runTest("../testData/intentions/putCallsOnSeparateLines/doNotWrapFirstElement.kt"); + } + + @TestMetadata("doNotWrapFirstElement2.kt") + public void testDoNotWrapFirstElement2() throws Exception { + runTest("../testData/intentions/putCallsOnSeparateLines/doNotWrapFirstElement2.kt"); + } + + @TestMetadata("doNotWrapFirstElement3.kt") + public void testDoNotWrapFirstElement3() throws Exception { + runTest("../testData/intentions/putCallsOnSeparateLines/doNotWrapFirstElement3.kt"); + } + + @TestMetadata("dotChain.kt") + public void testDotChain() throws Exception { + runTest("../testData/intentions/putCallsOnSeparateLines/dotChain.kt"); + } + + @TestMetadata("dotChainWithParenthesis.kt") + public void testDotChainWithParenthesis() throws Exception { + runTest("../testData/intentions/putCallsOnSeparateLines/dotChainWithParenthesis.kt"); + } + + @TestMetadata("import.kt") + public void testImport() throws Exception { + runTest("../testData/intentions/putCallsOnSeparateLines/import.kt"); + } + + @TestMetadata("mixWithMultilineBody.kt") + public void testMixWithMultilineBody() throws Exception { + runTest("../testData/intentions/putCallsOnSeparateLines/mixWithMultilineBody.kt"); + } + + @TestMetadata("mixWithMultilineBodyInFirstPosition.kt") + public void testMixWithMultilineBodyInFirstPosition() throws Exception { + runTest("../testData/intentions/putCallsOnSeparateLines/mixWithMultilineBodyInFirstPosition.kt"); + } + + @TestMetadata("safeChain.kt") + public void testSafeChain() throws Exception { + runTest("../testData/intentions/putCallsOnSeparateLines/safeChain.kt"); + } + + @TestMetadata("safeChainWithLineBreaks.kt") + public void testSafeChainWithLineBreaks() throws Exception { + runTest("../testData/intentions/putCallsOnSeparateLines/safeChainWithLineBreaks.kt"); + } + + @TestMetadata("safeChainWithOneLineBreak.kt") + public void testSafeChainWithOneLineBreak() throws Exception { + runTest("../testData/intentions/putCallsOnSeparateLines/safeChainWithOneLineBreak.kt"); + } + } + @RunWith(JUnit3RunnerWithInners.class) @TestMetadata("../testData/intentions/putExpressionsOnSeparateLines") public static class PutExpressionsOnSeparateLines extends AbstractSharedK1IntentionTest { diff --git a/plugins/kotlin/code-insight/intentions-shared/tests/k2/test/org/jetbrains/kotlin/idea/k2/codeInsight/intentions/shared/SharedK2IntentionTestGenerated.java b/plugins/kotlin/code-insight/intentions-shared/tests/k2/test/org/jetbrains/kotlin/idea/k2/codeInsight/intentions/shared/SharedK2IntentionTestGenerated.java index 3c7aac7cee07..1f12ddc71740 100644 --- a/plugins/kotlin/code-insight/intentions-shared/tests/k2/test/org/jetbrains/kotlin/idea/k2/codeInsight/intentions/shared/SharedK2IntentionTestGenerated.java +++ b/plugins/kotlin/code-insight/intentions-shared/tests/k2/test/org/jetbrains/kotlin/idea/k2/codeInsight/intentions/shared/SharedK2IntentionTestGenerated.java @@ -445,6 +445,69 @@ public abstract class SharedK2IntentionTestGenerated extends AbstractSharedK2Int } } + @RunWith(JUnit3RunnerWithInners.class) + @TestMetadata("../testData/intentions/putCallsOnSeparateLines") + public static class PutCallsOnSeparateLines extends AbstractSharedK2IntentionTest { + private void runTest(String testDataFilePath) throws Exception { + KotlinTestUtils.runTest(this::doTest, this, testDataFilePath); + } + + @TestMetadata("doNotWrapFirstElement.kt") + public void testDoNotWrapFirstElement() throws Exception { + runTest("../testData/intentions/putCallsOnSeparateLines/doNotWrapFirstElement.kt"); + } + + @TestMetadata("doNotWrapFirstElement2.kt") + public void testDoNotWrapFirstElement2() throws Exception { + runTest("../testData/intentions/putCallsOnSeparateLines/doNotWrapFirstElement2.kt"); + } + + @TestMetadata("doNotWrapFirstElement3.kt") + public void testDoNotWrapFirstElement3() throws Exception { + runTest("../testData/intentions/putCallsOnSeparateLines/doNotWrapFirstElement3.kt"); + } + + @TestMetadata("dotChain.kt") + public void testDotChain() throws Exception { + runTest("../testData/intentions/putCallsOnSeparateLines/dotChain.kt"); + } + + @TestMetadata("dotChainWithParenthesis.kt") + public void testDotChainWithParenthesis() throws Exception { + runTest("../testData/intentions/putCallsOnSeparateLines/dotChainWithParenthesis.kt"); + } + + @TestMetadata("import.kt") + public void testImport() throws Exception { + runTest("../testData/intentions/putCallsOnSeparateLines/import.kt"); + } + + @TestMetadata("mixWithMultilineBody.kt") + public void testMixWithMultilineBody() throws Exception { + runTest("../testData/intentions/putCallsOnSeparateLines/mixWithMultilineBody.kt"); + } + + @TestMetadata("mixWithMultilineBodyInFirstPosition.kt") + public void testMixWithMultilineBodyInFirstPosition() throws Exception { + runTest("../testData/intentions/putCallsOnSeparateLines/mixWithMultilineBodyInFirstPosition.kt"); + } + + @TestMetadata("safeChain.kt") + public void testSafeChain() throws Exception { + runTest("../testData/intentions/putCallsOnSeparateLines/safeChain.kt"); + } + + @TestMetadata("safeChainWithLineBreaks.kt") + public void testSafeChainWithLineBreaks() throws Exception { + runTest("../testData/intentions/putCallsOnSeparateLines/safeChainWithLineBreaks.kt"); + } + + @TestMetadata("safeChainWithOneLineBreak.kt") + public void testSafeChainWithOneLineBreak() throws Exception { + runTest("../testData/intentions/putCallsOnSeparateLines/safeChainWithOneLineBreak.kt"); + } + } + @RunWith(JUnit3RunnerWithInners.class) @TestMetadata("../testData/intentions/putExpressionsOnSeparateLines") public static class PutExpressionsOnSeparateLines extends AbstractSharedK2IntentionTest { diff --git a/plugins/kotlin/code-insight/intentions-shared/tests/testData/intentions/putCallsOnSeparateLines/.intention b/plugins/kotlin/code-insight/intentions-shared/tests/testData/intentions/putCallsOnSeparateLines/.intention new file mode 100644 index 000000000000..0cb8b9a993d4 --- /dev/null +++ b/plugins/kotlin/code-insight/intentions-shared/tests/testData/intentions/putCallsOnSeparateLines/.intention @@ -0,0 +1 @@ +org.jetbrains.kotlin.idea.codeInsight.intentions.shared.PutCallsOnSeparateLinesIntention diff --git a/plugins/kotlin/code-insight/intentions-shared/tests/testData/intentions/putCallsOnSeparateLines/doNotWrapFirstElement.kt b/plugins/kotlin/code-insight/intentions-shared/tests/testData/intentions/putCallsOnSeparateLines/doNotWrapFirstElement.kt new file mode 100644 index 000000000000..bf939449aea5 --- /dev/null +++ b/plugins/kotlin/code-insight/intentions-shared/tests/testData/intentions/putCallsOnSeparateLines/doNotWrapFirstElement.kt @@ -0,0 +1,6 @@ +// DISABLE-ERRORS +fun calculate(): Int { + return call1().call2().call3().call5().ref6.call7() +} + +// SET_TRUE: WRAP_FIRST_METHOD_IN_CALL_CHAIN diff --git a/plugins/kotlin/code-insight/intentions-shared/tests/testData/intentions/putCallsOnSeparateLines/doNotWrapFirstElement.kt.after b/plugins/kotlin/code-insight/intentions-shared/tests/testData/intentions/putCallsOnSeparateLines/doNotWrapFirstElement.kt.after new file mode 100644 index 000000000000..d29198d34b3c --- /dev/null +++ b/plugins/kotlin/code-insight/intentions-shared/tests/testData/intentions/putCallsOnSeparateLines/doNotWrapFirstElement.kt.after @@ -0,0 +1,11 @@ +// DISABLE-ERRORS +fun calculate(): Int { + return call1() + .call2() + .call3() + .call5() + .ref6 + .call7() +} + +// SET_TRUE: WRAP_FIRST_METHOD_IN_CALL_CHAIN diff --git a/plugins/kotlin/code-insight/intentions-shared/tests/testData/intentions/putCallsOnSeparateLines/doNotWrapFirstElement2.kt b/plugins/kotlin/code-insight/intentions-shared/tests/testData/intentions/putCallsOnSeparateLines/doNotWrapFirstElement2.kt new file mode 100644 index 000000000000..c8dba92e5983 --- /dev/null +++ b/plugins/kotlin/code-insight/intentions-shared/tests/testData/intentions/putCallsOnSeparateLines/doNotWrapFirstElement2.kt @@ -0,0 +1,6 @@ +// DISABLE-ERRORS +fun calculate(): Int { + return call1().call2() +} + +// SET_TRUE: WRAP_FIRST_METHOD_IN_CALL_CHAIN diff --git a/plugins/kotlin/code-insight/intentions-shared/tests/testData/intentions/putCallsOnSeparateLines/doNotWrapFirstElement2.kt.after b/plugins/kotlin/code-insight/intentions-shared/tests/testData/intentions/putCallsOnSeparateLines/doNotWrapFirstElement2.kt.after new file mode 100644 index 000000000000..d974fccc6ff6 --- /dev/null +++ b/plugins/kotlin/code-insight/intentions-shared/tests/testData/intentions/putCallsOnSeparateLines/doNotWrapFirstElement2.kt.after @@ -0,0 +1,7 @@ +// DISABLE-ERRORS +fun calculate(): Int { + return call1() + .call2() +} + +// SET_TRUE: WRAP_FIRST_METHOD_IN_CALL_CHAIN diff --git a/plugins/kotlin/code-insight/intentions-shared/tests/testData/intentions/putCallsOnSeparateLines/doNotWrapFirstElement3.kt b/plugins/kotlin/code-insight/intentions-shared/tests/testData/intentions/putCallsOnSeparateLines/doNotWrapFirstElement3.kt new file mode 100644 index 000000000000..aa472892d70a --- /dev/null +++ b/plugins/kotlin/code-insight/intentions-shared/tests/testData/intentions/putCallsOnSeparateLines/doNotWrapFirstElement3.kt @@ -0,0 +1,8 @@ +// IS_APPLICABLE: false +// DISABLE-ERRORS +fun calculate(): Int { + return call1() + .call2() +} + +// SET_TRUE: WRAP_FIRST_METHOD_IN_CALL_CHAIN diff --git a/plugins/kotlin/code-insight/intentions-shared/tests/testData/intentions/putCallsOnSeparateLines/dotChain.kt b/plugins/kotlin/code-insight/intentions-shared/tests/testData/intentions/putCallsOnSeparateLines/dotChain.kt new file mode 100644 index 000000000000..d783ca24a57c --- /dev/null +++ b/plugins/kotlin/code-insight/intentions-shared/tests/testData/intentions/putCallsOnSeparateLines/dotChain.kt @@ -0,0 +1,4 @@ +// DISABLE-ERRORS +fun calculate(): Int { + return call1().call2().call3().call5().ref6.call7() +} diff --git a/plugins/kotlin/code-insight/intentions-shared/tests/testData/intentions/putCallsOnSeparateLines/dotChain.kt.after b/plugins/kotlin/code-insight/intentions-shared/tests/testData/intentions/putCallsOnSeparateLines/dotChain.kt.after new file mode 100644 index 000000000000..9a2ee8e0f24e --- /dev/null +++ b/plugins/kotlin/code-insight/intentions-shared/tests/testData/intentions/putCallsOnSeparateLines/dotChain.kt.after @@ -0,0 +1,8 @@ +// DISABLE-ERRORS +fun calculate(): Int { + return call1().call2() + .call3() + .call5() + .ref6 + .call7() +} diff --git a/plugins/kotlin/code-insight/intentions-shared/tests/testData/intentions/putCallsOnSeparateLines/dotChainWithParenthesis.kt b/plugins/kotlin/code-insight/intentions-shared/tests/testData/intentions/putCallsOnSeparateLines/dotChainWithParenthesis.kt new file mode 100644 index 000000000000..95d6031c1459 --- /dev/null +++ b/plugins/kotlin/code-insight/intentions-shared/tests/testData/intentions/putCallsOnSeparateLines/dotChainWithParenthesis.kt @@ -0,0 +1,4 @@ +// DISABLE-ERRORS +fun calculate(): Int { + return (call1().call2().call3().call5()).ref6.call7() +} diff --git a/plugins/kotlin/code-insight/intentions-shared/tests/testData/intentions/putCallsOnSeparateLines/dotChainWithParenthesis.kt.after b/plugins/kotlin/code-insight/intentions-shared/tests/testData/intentions/putCallsOnSeparateLines/dotChainWithParenthesis.kt.after new file mode 100644 index 000000000000..0d8f8e869fc3 --- /dev/null +++ b/plugins/kotlin/code-insight/intentions-shared/tests/testData/intentions/putCallsOnSeparateLines/dotChainWithParenthesis.kt.after @@ -0,0 +1,6 @@ +// DISABLE-ERRORS +fun calculate(): Int { + return (call1().call2() + .call3() + .call5()).ref6.call7() +} diff --git a/plugins/kotlin/code-insight/intentions-shared/tests/testData/intentions/putCallsOnSeparateLines/import.kt b/plugins/kotlin/code-insight/intentions-shared/tests/testData/intentions/putCallsOnSeparateLines/import.kt new file mode 100644 index 000000000000..e838739ccef3 --- /dev/null +++ b/plugins/kotlin/code-insight/intentions-shared/tests/testData/intentions/putCallsOnSeparateLines/import.kt @@ -0,0 +1,4 @@ +// IS_APPLICABLE: false +// DISABLE-ERRORS + +import a.n.c.d \ No newline at end of file diff --git a/plugins/kotlin/code-insight/intentions-shared/tests/testData/intentions/putCallsOnSeparateLines/mixWithMultilineBody.kt b/plugins/kotlin/code-insight/intentions-shared/tests/testData/intentions/putCallsOnSeparateLines/mixWithMultilineBody.kt new file mode 100644 index 000000000000..f54dc51c20c1 --- /dev/null +++ b/plugins/kotlin/code-insight/intentions-shared/tests/testData/intentions/putCallsOnSeparateLines/mixWithMultilineBody.kt @@ -0,0 +1,6 @@ +// DISABLE-ERRORS +fun calculate(): Int { + return call1().call2().call3().call5 { + doSmth() + }?.ref6?.call7() +} diff --git a/plugins/kotlin/code-insight/intentions-shared/tests/testData/intentions/putCallsOnSeparateLines/mixWithMultilineBody.kt.after b/plugins/kotlin/code-insight/intentions-shared/tests/testData/intentions/putCallsOnSeparateLines/mixWithMultilineBody.kt.after new file mode 100644 index 000000000000..56daa858f1ec --- /dev/null +++ b/plugins/kotlin/code-insight/intentions-shared/tests/testData/intentions/putCallsOnSeparateLines/mixWithMultilineBody.kt.after @@ -0,0 +1,10 @@ +// DISABLE-ERRORS +fun calculate(): Int { + return call1().call2() + .call3() + .call5 { + doSmth() + } + ?.ref6 + ?.call7() +} diff --git a/plugins/kotlin/code-insight/intentions-shared/tests/testData/intentions/putCallsOnSeparateLines/mixWithMultilineBodyInFirstPosition.kt b/plugins/kotlin/code-insight/intentions-shared/tests/testData/intentions/putCallsOnSeparateLines/mixWithMultilineBodyInFirstPosition.kt new file mode 100644 index 000000000000..c50a90a9b60e --- /dev/null +++ b/plugins/kotlin/code-insight/intentions-shared/tests/testData/intentions/putCallsOnSeparateLines/mixWithMultilineBodyInFirstPosition.kt @@ -0,0 +1,6 @@ +// DISABLE-ERRORS +fun calculate(): Int { + return call1().call5 { + doSmth() + }?.ref6?.call7() +} diff --git a/plugins/kotlin/code-insight/intentions-shared/tests/testData/intentions/putCallsOnSeparateLines/mixWithMultilineBodyInFirstPosition.kt.after b/plugins/kotlin/code-insight/intentions-shared/tests/testData/intentions/putCallsOnSeparateLines/mixWithMultilineBodyInFirstPosition.kt.after new file mode 100644 index 000000000000..d9b48bd37d17 --- /dev/null +++ b/plugins/kotlin/code-insight/intentions-shared/tests/testData/intentions/putCallsOnSeparateLines/mixWithMultilineBodyInFirstPosition.kt.after @@ -0,0 +1,8 @@ +// DISABLE-ERRORS +fun calculate(): Int { + return call1().call5 { + doSmth() + } + ?.ref6 + ?.call7() +} diff --git a/plugins/kotlin/code-insight/intentions-shared/tests/testData/intentions/putCallsOnSeparateLines/safeChain.kt b/plugins/kotlin/code-insight/intentions-shared/tests/testData/intentions/putCallsOnSeparateLines/safeChain.kt new file mode 100644 index 000000000000..bec982cf54c4 --- /dev/null +++ b/plugins/kotlin/code-insight/intentions-shared/tests/testData/intentions/putCallsOnSeparateLines/safeChain.kt @@ -0,0 +1,4 @@ +// DISABLE-ERRORS +fun calculate(): Int { + return call1()?.call2()?.call3()?.call5()?.ref6?.call7() +} diff --git a/plugins/kotlin/code-insight/intentions-shared/tests/testData/intentions/putCallsOnSeparateLines/safeChain.kt.after b/plugins/kotlin/code-insight/intentions-shared/tests/testData/intentions/putCallsOnSeparateLines/safeChain.kt.after new file mode 100644 index 000000000000..d173c9d19343 --- /dev/null +++ b/plugins/kotlin/code-insight/intentions-shared/tests/testData/intentions/putCallsOnSeparateLines/safeChain.kt.after @@ -0,0 +1,8 @@ +// DISABLE-ERRORS +fun calculate(): Int { + return call1()?.call2() + ?.call3() + ?.call5() + ?.ref6 + ?.call7() +} diff --git a/plugins/kotlin/code-insight/intentions-shared/tests/testData/intentions/putCallsOnSeparateLines/safeChainWithLineBreaks.kt b/plugins/kotlin/code-insight/intentions-shared/tests/testData/intentions/putCallsOnSeparateLines/safeChainWithLineBreaks.kt new file mode 100644 index 000000000000..268f24ed953b --- /dev/null +++ b/plugins/kotlin/code-insight/intentions-shared/tests/testData/intentions/putCallsOnSeparateLines/safeChainWithLineBreaks.kt @@ -0,0 +1,9 @@ +// IS_APPLICABLE: false +// DISABLE-ERRORS +fun calculate(): Int { + return call1()?.call2() + ?.call3() + ?.call5() + ?.ref6 + ?.call7() +} diff --git a/plugins/kotlin/code-insight/intentions-shared/tests/testData/intentions/putCallsOnSeparateLines/safeChainWithOneLineBreak.kt b/plugins/kotlin/code-insight/intentions-shared/tests/testData/intentions/putCallsOnSeparateLines/safeChainWithOneLineBreak.kt new file mode 100644 index 000000000000..80478b3d5433 --- /dev/null +++ b/plugins/kotlin/code-insight/intentions-shared/tests/testData/intentions/putCallsOnSeparateLines/safeChainWithOneLineBreak.kt @@ -0,0 +1,7 @@ +// DISABLE-ERRORS +fun calculate(): Int { + return call1()?.call2() + ?.call3() + ?.call5()?.ref6 + ?.call7() +} diff --git a/plugins/kotlin/code-insight/intentions-shared/tests/testData/intentions/putCallsOnSeparateLines/safeChainWithOneLineBreak.kt.after b/plugins/kotlin/code-insight/intentions-shared/tests/testData/intentions/putCallsOnSeparateLines/safeChainWithOneLineBreak.kt.after new file mode 100644 index 000000000000..d173c9d19343 --- /dev/null +++ b/plugins/kotlin/code-insight/intentions-shared/tests/testData/intentions/putCallsOnSeparateLines/safeChainWithOneLineBreak.kt.after @@ -0,0 +1,8 @@ +// DISABLE-ERRORS +fun calculate(): Int { + return call1()?.call2() + ?.call3() + ?.call5() + ?.ref6 + ?.call7() +} diff --git a/plugins/kotlin/idea/tests/testData/quickfix/createFromUsage/createClass/referenceExpression/classByNestedGroovyQualifier.before.Main.kt b/plugins/kotlin/idea/tests/testData/quickfix/createFromUsage/createClass/referenceExpression/classByNestedGroovyQualifier.before.Main.kt index e857559c0238..f21e632770fd 100644 --- a/plugins/kotlin/idea/tests/testData/quickfix/createFromUsage/createClass/referenceExpression/classByNestedGroovyQualifier.before.Main.kt +++ b/plugins/kotlin/idea/tests/testData/quickfix/createFromUsage/createClass/referenceExpression/classByNestedGroovyQualifier.before.Main.kt @@ -1,5 +1,6 @@ // "Create class 'A'" "false" // ACTION: Introduce local variable +// ACTION: Put calls on separate lines // ACTION: Rename reference // ERROR: Unresolved reference: A fun foo() = J.A.B diff --git a/plugins/kotlin/idea/tests/testData/quickfix/declaringJavaClass/customEnum.kt b/plugins/kotlin/idea/tests/testData/quickfix/declaringJavaClass/customEnum.kt index 2f59e32c7e6f..ca9e0fcc89e7 100644 --- a/plugins/kotlin/idea/tests/testData/quickfix/declaringJavaClass/customEnum.kt +++ b/plugins/kotlin/idea/tests/testData/quickfix/declaringJavaClass/customEnum.kt @@ -1,6 +1,7 @@ // "Replace with 'declaringJavaClass'" "true" // ACTION: Add method contract to 'getDeclaringClass()' // ACTION: Introduce local variable +// ACTION: Put calls on separate lines // ACTION: Replace with 'declaringJavaClass' // API_VERSION: 1.7 // WITH_STDLIB diff --git a/plugins/kotlin/idea/tests/testData/quickfix/declaringJavaClass/customEnum.kt.after b/plugins/kotlin/idea/tests/testData/quickfix/declaringJavaClass/customEnum.kt.after index 2c64aeaa9115..f59662b718a6 100644 --- a/plugins/kotlin/idea/tests/testData/quickfix/declaringJavaClass/customEnum.kt.after +++ b/plugins/kotlin/idea/tests/testData/quickfix/declaringJavaClass/customEnum.kt.after @@ -1,6 +1,7 @@ // "Replace with 'declaringJavaClass'" "true" // ACTION: Add method contract to 'getDeclaringClass()' // ACTION: Introduce local variable +// ACTION: Put calls on separate lines // ACTION: Replace with 'declaringJavaClass' // API_VERSION: 1.7 // WITH_STDLIB diff --git a/plugins/kotlin/idea/tests/testData/quickfix/importAlias/unresolvedReference.kt b/plugins/kotlin/idea/tests/testData/quickfix/importAlias/unresolvedReference.kt index adb1f67ed90e..f725eefca02c 100644 --- a/plugins/kotlin/idea/tests/testData/quickfix/importAlias/unresolvedReference.kt +++ b/plugins/kotlin/idea/tests/testData/quickfix/importAlias/unresolvedReference.kt @@ -1,4 +1,5 @@ // "Introduce import alias" "false" +// ACTION: Put calls on separate lines // WITH_STDLIB // ERROR: Overload resolution ambiguity:
public inline fun Iterable.forEach(action: (TypeVariable(T)) -> Unit): Unit defined in kotlin.collections
public inline fun Map.forEach(action: (Map.Entry) -> Unit): Unit defined in kotlin.collections // ERROR: Unresolved reference: a diff --git a/plugins/kotlin/idea/tests/testData/quickfix/surroundWithNullCheck/chainedUnsafeCall.kt b/plugins/kotlin/idea/tests/testData/quickfix/surroundWithNullCheck/chainedUnsafeCall.kt index f29732dc983e..2c3769a9e6dd 100644 --- a/plugins/kotlin/idea/tests/testData/quickfix/surroundWithNullCheck/chainedUnsafeCall.kt +++ b/plugins/kotlin/idea/tests/testData/quickfix/surroundWithNullCheck/chainedUnsafeCall.kt @@ -1,6 +1,7 @@ // "Surround with null check" "false" // ACTION: Add non-null asserted (!!) call // ACTION: Introduce local variable +// ACTION: Put calls on separate lines // ACTION: Replace with safe (?.) call // ERROR: Only safe (?.) or non-null asserted (!!.) calls are allowed on a nullable receiver of type Int? diff --git a/plugins/kotlin/idea/tests/testData/quickfix/wrapWithSafeLetCall/chainedUnsafeCall.kt b/plugins/kotlin/idea/tests/testData/quickfix/wrapWithSafeLetCall/chainedUnsafeCall.kt index c6f27e5cef01..1e5daf919b10 100644 --- a/plugins/kotlin/idea/tests/testData/quickfix/wrapWithSafeLetCall/chainedUnsafeCall.kt +++ b/plugins/kotlin/idea/tests/testData/quickfix/wrapWithSafeLetCall/chainedUnsafeCall.kt @@ -2,6 +2,7 @@ // WITH_STDLIB // ACTION: Add non-null asserted (!!) call // ACTION: Introduce local variable +// ACTION: Put calls on separate lines // ACTION: Replace with safe (?.) call // ERROR: Only safe (?.) or non-null asserted (!!.) calls are allowed on a nullable receiver of type Int? diff --git a/plugins/kotlin/idea/tests/testData/quickfix/wrapWithSafeLetCall/nullableReceiver.kt b/plugins/kotlin/idea/tests/testData/quickfix/wrapWithSafeLetCall/nullableReceiver.kt index 222423ff6773..657591b31bd3 100644 --- a/plugins/kotlin/idea/tests/testData/quickfix/wrapWithSafeLetCall/nullableReceiver.kt +++ b/plugins/kotlin/idea/tests/testData/quickfix/wrapWithSafeLetCall/nullableReceiver.kt @@ -2,6 +2,7 @@ // ACTION: Add non-null asserted (!!) call // ACTION: Convert to run // ACTION: Convert to with +// ACTION: Put calls on separate lines // ACTION: Replace with safe (?.) call // ACTION: Surround with null check // ERROR: Only safe (?.) or non-null asserted (!!.) calls are allowed on a nullable receiver of type B?