diff --git a/idea/idea-analysis/src/org/jetbrains/kotlin/idea/references/KtSimpleNameReference.kt b/idea/idea-analysis/src/org/jetbrains/kotlin/idea/references/KtSimpleNameReference.kt index 9098382f2ee..4353f9f790f 100644 --- a/idea/idea-analysis/src/org/jetbrains/kotlin/idea/references/KtSimpleNameReference.kt +++ b/idea/idea-analysis/src/org/jetbrains/kotlin/idea/references/KtSimpleNameReference.kt @@ -29,6 +29,7 @@ import org.jetbrains.kotlin.idea.codeInsight.shorten.addToShorteningWaitSet import org.jetbrains.kotlin.idea.core.ShortenReferences import org.jetbrains.kotlin.idea.core.copied import org.jetbrains.kotlin.idea.core.quoteIfNeeded +import org.jetbrains.kotlin.idea.core.replaced import org.jetbrains.kotlin.idea.intentions.OperatorToFunctionIntention import org.jetbrains.kotlin.idea.refactoring.fqName.getKotlinFqName import org.jetbrains.kotlin.lexer.KtToken @@ -206,7 +207,7 @@ class KtSimpleNameReference(expression: KtSimpleNameExpression) : KtSimpleRefere val typeText = "$text${elementToReplace.typeArgumentList?.text ?: ""}" elementToReplace.replace(psiFactory.createType(typeText).typeElement!!) } - else -> elementToReplace.replace(psiFactory.createExpression(text)) + else -> KtPsiUtil.safeDeparenthesize(elementToReplace.replaced(psiFactory.createExpression(text))) } as KtElement val selector = (newElement as? KtCallableReferenceExpression)?.callableReference diff --git a/idea/idea-core/src/org/jetbrains/kotlin/idea/core/ShortenReferences.kt b/idea/idea-core/src/org/jetbrains/kotlin/idea/core/ShortenReferences.kt index d7f2052b24f..68d122a2cea 100644 --- a/idea/idea-core/src/org/jetbrains/kotlin/idea/core/ShortenReferences.kt +++ b/idea/idea-core/src/org/jetbrains/kotlin/idea/core/ShortenReferences.kt @@ -562,7 +562,11 @@ class ShortenReferences(val options: (KtElement) -> Options = { Options.DEFAULT } override fun shortenElement(element: KtDotQualifiedExpression): KtElement { - return element.replace(element.selectorExpression!!) as KtElement + val parens = element.parent as? KtParenthesizedExpression + val requiredParens = parens != null && !KtPsiUtil.areParenthesesUseless(parens) + val shortenedElement = element.replace(element.selectorExpression!!) as KtElement + if (requiredParens) return shortenedElement.parent.replaced(shortenedElement) + return shortenedElement } } diff --git a/idea/testData/refactoring/copy/copyFunCallQualificationWithParentheses/after/bar/some2.kt b/idea/testData/refactoring/copy/copyFunCallQualificationWithParentheses/after/bar/some2.kt new file mode 100644 index 00000000000..35c16cb247e --- /dev/null +++ b/idea/testData/refactoring/copy/copyFunCallQualificationWithParentheses/after/bar/some2.kt @@ -0,0 +1,15 @@ +package bar + +import foo.parenB +import foo.parenBP +import foo.parenP +import foo.parenPB +import foo.parenPP + +fun some2(p1: () -> Unit, p2: (() -> Unit) -> Unit) { + parenB { p1() } + parenP() + parenBP { p1 }() + parenPP()() + parenPB(p2) {} +} \ No newline at end of file diff --git a/idea/testData/refactoring/copy/copyFunCallQualificationWithParentheses/after/foo/test.kt b/idea/testData/refactoring/copy/copyFunCallQualificationWithParentheses/after/foo/test.kt new file mode 100644 index 00000000000..0f4cd760465 --- /dev/null +++ b/idea/testData/refactoring/copy/copyFunCallQualificationWithParentheses/after/foo/test.kt @@ -0,0 +1,15 @@ +package foo + +fun parenB(p: () -> Unit) = p() +fun parenP() {} +fun parenBP(p: () -> () -> Unit): () -> Unit = p() +fun parenPP(): () -> Unit = {} +fun parenPB(p: (() -> Unit) -> Unit): (() -> Unit) -> Unit = p + +fun some(p1: () -> Unit, p2: (() -> Unit) -> Unit) { + parenB { p1() } + parenP() + parenBP { p1 }() + parenPP()() + (parenPB(p2)) {} +} \ No newline at end of file diff --git a/idea/testData/refactoring/copy/copyFunCallQualificationWithParentheses/before/foo/test.kt b/idea/testData/refactoring/copy/copyFunCallQualificationWithParentheses/before/foo/test.kt new file mode 100644 index 00000000000..48ca6711dcc --- /dev/null +++ b/idea/testData/refactoring/copy/copyFunCallQualificationWithParentheses/before/foo/test.kt @@ -0,0 +1,15 @@ +package foo + +fun parenB(p: () -> Unit) = p() +fun parenP() {} +fun parenBP(p: () -> () -> Unit): () -> Unit = p() +fun parenPP(): () -> Unit = {} +fun parenPB(p: (() -> Unit) -> Unit): (() -> Unit) -> Unit = p + +fun some(p1: () -> Unit, p2: (() -> Unit) -> Unit) { + parenB { p1() } + parenP() + parenBP { p1 }() + parenPP()() + (parenPB(p2)) {} +} \ No newline at end of file diff --git a/idea/testData/refactoring/copy/copyFunCallQualificationWithParentheses/copyFunCallQualificationWithParentheses.test b/idea/testData/refactoring/copy/copyFunCallQualificationWithParentheses/copyFunCallQualificationWithParentheses.test new file mode 100644 index 00000000000..38d0a19562e --- /dev/null +++ b/idea/testData/refactoring/copy/copyFunCallQualificationWithParentheses/copyFunCallQualificationWithParentheses.test @@ -0,0 +1,5 @@ +{ + "mainFile": "foo/test.kt", + "targetPackage": "bar", + "newName": "some2" +} diff --git a/idea/tests/org/jetbrains/kotlin/idea/refactoring/copy/CopyTestGenerated.java b/idea/tests/org/jetbrains/kotlin/idea/refactoring/copy/CopyTestGenerated.java index 2d1f98329f3..03798a70972 100644 --- a/idea/tests/org/jetbrains/kotlin/idea/refactoring/copy/CopyTestGenerated.java +++ b/idea/tests/org/jetbrains/kotlin/idea/refactoring/copy/CopyTestGenerated.java @@ -72,6 +72,12 @@ public class CopyTestGenerated extends AbstractCopyTest { doTest(fileName); } + @TestMetadata("copyFunCallQualificationWithParentheses/copyFunCallQualificationWithParentheses.test") + public void testCopyFunCallQualificationWithParentheses_CopyFunCallQualificationWithParentheses() throws Exception { + String fileName = KotlinTestUtils.navigationMetadata("idea/testData/refactoring/copy/copyFunCallQualificationWithParentheses/copyFunCallQualificationWithParentheses.test"); + doTest(fileName); + } + @TestMetadata("copyLocalClass/copyLocalClass.test") public void testCopyLocalClass_CopyLocalClass() throws Exception { String fileName = KotlinTestUtils.navigationMetadata("idea/testData/refactoring/copy/copyLocalClass/copyLocalClass.test");