Introduce Parameter/Lambda Parameter: Parenthesize binary expressions if operation reference starts with a new line
This commit is contained in:
+1
-1
@@ -248,7 +248,7 @@ public class KotlinInplaceParameterIntroducer(
|
|||||||
return descriptor.copy(
|
return descriptor.copy(
|
||||||
originalRange = originalRange,
|
originalRange = originalRange,
|
||||||
occurrencesToReplace = if (replaceAll) getOccurrences().map { it.toRange() } else originalRange.singletonList(),
|
occurrencesToReplace = if (replaceAll) getOccurrences().map { it.toRange() } else originalRange.singletonList(),
|
||||||
newArgumentValue = getExpr()!!
|
argumentValue = getExpr()!!
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+2
-7
@@ -19,14 +19,11 @@ package org.jetbrains.kotlin.idea.refactoring.introduce.introduceParameter
|
|||||||
import com.intellij.openapi.command.impl.FinishMarkAction
|
import com.intellij.openapi.command.impl.FinishMarkAction
|
||||||
import com.intellij.openapi.command.impl.StartMarkAction
|
import com.intellij.openapi.command.impl.StartMarkAction
|
||||||
import com.intellij.openapi.editor.Editor
|
import com.intellij.openapi.editor.Editor
|
||||||
import com.intellij.openapi.options.ConfigurationException
|
|
||||||
import com.intellij.openapi.project.Project
|
import com.intellij.openapi.project.Project
|
||||||
import com.intellij.psi.PsiElement
|
|
||||||
import com.intellij.refactoring.BaseRefactoringProcessor
|
import com.intellij.refactoring.BaseRefactoringProcessor
|
||||||
import com.intellij.refactoring.ui.NameSuggestionsField
|
import com.intellij.refactoring.ui.NameSuggestionsField
|
||||||
import com.intellij.refactoring.ui.RefactoringDialog
|
import com.intellij.refactoring.ui.RefactoringDialog
|
||||||
import com.intellij.ui.NonFocusableCheckBox
|
import com.intellij.ui.NonFocusableCheckBox
|
||||||
import com.intellij.ui.TitledSeparator
|
|
||||||
import com.intellij.usageView.BaseUsageViewDescriptor
|
import com.intellij.usageView.BaseUsageViewDescriptor
|
||||||
import com.intellij.usageView.UsageInfo
|
import com.intellij.usageView.UsageInfo
|
||||||
import org.jetbrains.kotlin.idea.KotlinFileType
|
import org.jetbrains.kotlin.idea.KotlinFileType
|
||||||
@@ -38,13 +35,11 @@ import org.jetbrains.kotlin.idea.refactoring.introduce.extractFunction.ui.Kotlin
|
|||||||
import org.jetbrains.kotlin.idea.refactoring.introduce.extractionEngine.*
|
import org.jetbrains.kotlin.idea.refactoring.introduce.extractionEngine.*
|
||||||
import org.jetbrains.kotlin.idea.util.IdeDescriptorRenderers
|
import org.jetbrains.kotlin.idea.util.IdeDescriptorRenderers
|
||||||
import org.jetbrains.kotlin.psi.*
|
import org.jetbrains.kotlin.psi.*
|
||||||
import org.jetbrains.kotlin.resolve.AnalyzingUtils
|
|
||||||
import org.jetbrains.kotlin.types.KotlinType
|
import org.jetbrains.kotlin.types.KotlinType
|
||||||
import java.awt.GridBagConstraints
|
import java.awt.GridBagConstraints
|
||||||
import java.awt.GridBagLayout
|
import java.awt.GridBagLayout
|
||||||
import java.awt.Insets
|
import java.awt.Insets
|
||||||
import java.util.Collections
|
import java.util.*
|
||||||
import java.util.LinkedHashMap
|
|
||||||
import javax.swing.JCheckBox
|
import javax.swing.JCheckBox
|
||||||
import javax.swing.JComponent
|
import javax.swing.JComponent
|
||||||
import javax.swing.JLabel
|
import javax.swing.JLabel
|
||||||
@@ -301,7 +296,7 @@ public class KotlinIntroduceParameterDialog private constructor(
|
|||||||
val descriptorToRefactor = descriptor.copy(
|
val descriptorToRefactor = descriptor.copy(
|
||||||
newParameterName = chosenName,
|
newParameterName = chosenName,
|
||||||
newParameterTypeText = chosenType,
|
newParameterTypeText = chosenType,
|
||||||
newArgumentValue = newArgumentValue,
|
argumentValue = newArgumentValue,
|
||||||
withDefaultValue = defaultValueCheckBox!!.isSelected(),
|
withDefaultValue = defaultValueCheckBox!!.isSelected(),
|
||||||
occurrencesToReplace = with(descriptor) {
|
occurrencesToReplace = with(descriptor) {
|
||||||
if (replaceAllCheckBox?.isSelected() ?: true) {
|
if (replaceAllCheckBox?.isSelected() ?: true) {
|
||||||
|
|||||||
+13
-3
@@ -70,13 +70,22 @@ public data class IntroduceParameterDescriptor(
|
|||||||
val callableDescriptor: FunctionDescriptor,
|
val callableDescriptor: FunctionDescriptor,
|
||||||
val newParameterName: String,
|
val newParameterName: String,
|
||||||
val newParameterTypeText: String,
|
val newParameterTypeText: String,
|
||||||
val newArgumentValue: KtExpression,
|
val argumentValue: KtExpression,
|
||||||
val withDefaultValue: Boolean,
|
val withDefaultValue: Boolean,
|
||||||
val parametersUsages: MultiMap<KtElement, KtElement>,
|
val parametersUsages: MultiMap<KtElement, KtElement>,
|
||||||
val occurrencesToReplace: List<KotlinPsiRange>,
|
val occurrencesToReplace: List<KotlinPsiRange>,
|
||||||
val parametersToRemove: List<KtElement> = getParametersToRemove(withDefaultValue, parametersUsages, occurrencesToReplace),
|
val parametersToRemove: List<KtElement> = getParametersToRemove(withDefaultValue, parametersUsages, occurrencesToReplace),
|
||||||
val occurrenceReplacer: IntroduceParameterDescriptor.(KotlinPsiRange) -> Unit = {}
|
val occurrenceReplacer: IntroduceParameterDescriptor.(KotlinPsiRange) -> Unit = {}
|
||||||
) {
|
) {
|
||||||
|
val newArgumentValue: KtExpression by lazy {
|
||||||
|
if (argumentValue.mustBeParenthesizedInInitializerPosition()) {
|
||||||
|
KtPsiFactory(callable).createExpressionByPattern("($0)", argumentValue)
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
argumentValue
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
val originalOccurrence: KotlinPsiRange
|
val originalOccurrence: KotlinPsiRange
|
||||||
get() = occurrencesToReplace.first { it.getTextRange().intersects(originalRange.getTextRange()) }
|
get() = occurrencesToReplace.first { it.getTextRange().intersects(originalRange.getTextRange()) }
|
||||||
val valVar: KotlinValVar
|
val valVar: KotlinValVar
|
||||||
@@ -271,6 +280,7 @@ public open class KotlinIntroduceParameterHandler(
|
|||||||
&& !isTestMode
|
&& !isTestMode
|
||||||
&& !haveLambdaArgumentsToReplace
|
&& !haveLambdaArgumentsToReplace
|
||||||
&& expression.extractableSubstringInfo == null
|
&& expression.extractableSubstringInfo == null
|
||||||
|
&& !expression.mustBeParenthesizedInInitializerPosition()
|
||||||
|
|
||||||
val originalExpression = KtPsiUtil.safeDeparenthesize(expression)
|
val originalExpression = KtPsiUtil.safeDeparenthesize(expression)
|
||||||
val psiFactory = KtPsiFactory(project)
|
val psiFactory = KtPsiFactory(project)
|
||||||
@@ -282,7 +292,7 @@ public open class KotlinIntroduceParameterHandler(
|
|||||||
callableDescriptor = functionDescriptor,
|
callableDescriptor = functionDescriptor,
|
||||||
newParameterName = suggestedNames.first(),
|
newParameterName = suggestedNames.first(),
|
||||||
newParameterTypeText = IdeDescriptorRenderers.SOURCE_CODE_SHORT_NAMES_IN_TYPES.renderType(replacementType),
|
newParameterTypeText = IdeDescriptorRenderers.SOURCE_CODE_SHORT_NAMES_IN_TYPES.renderType(replacementType),
|
||||||
newArgumentValue = originalExpression,
|
argumentValue = originalExpression,
|
||||||
withDefaultValue = false,
|
withDefaultValue = false,
|
||||||
parametersUsages = parametersUsages,
|
parametersUsages = parametersUsages,
|
||||||
occurrencesToReplace = occurrencesToReplace,
|
occurrencesToReplace = occurrencesToReplace,
|
||||||
@@ -435,7 +445,7 @@ public open class KotlinIntroduceLambdaParameterHandler(
|
|||||||
callableDescriptor = callableDescriptor,
|
callableDescriptor = callableDescriptor,
|
||||||
newParameterName = "", // to be chosen in the dialog
|
newParameterName = "", // to be chosen in the dialog
|
||||||
newParameterTypeText = "", // to be chosen in the dialog
|
newParameterTypeText = "", // to be chosen in the dialog
|
||||||
newArgumentValue = KtPsiFactory(project).createExpression("{}"), // substituted later
|
argumentValue = KtPsiFactory(project).createExpression("{}"), // substituted later
|
||||||
withDefaultValue = false,
|
withDefaultValue = false,
|
||||||
parametersUsages = findInternalUsagesOfParametersAndReceiver(callable, callableDescriptor),
|
parametersUsages = findInternalUsagesOfParametersAndReceiver(callable, callableDescriptor),
|
||||||
occurrencesToReplace = listOf(originalRange),
|
occurrencesToReplace = listOf(originalRange),
|
||||||
|
|||||||
@@ -21,6 +21,7 @@ import com.intellij.openapi.editor.ScrollType
|
|||||||
import com.intellij.openapi.project.Project
|
import com.intellij.openapi.project.Project
|
||||||
import com.intellij.openapi.util.Key
|
import com.intellij.openapi.util.Key
|
||||||
import com.intellij.openapi.util.TextRange
|
import com.intellij.openapi.util.TextRange
|
||||||
|
import com.intellij.psi.PsiComment
|
||||||
import com.intellij.psi.PsiElement
|
import com.intellij.psi.PsiElement
|
||||||
import com.intellij.psi.PsiWhiteSpace
|
import com.intellij.psi.PsiWhiteSpace
|
||||||
import com.intellij.psi.util.PsiTreeUtil
|
import com.intellij.psi.util.PsiTreeUtil
|
||||||
|
|||||||
-7
@@ -132,13 +132,6 @@ object KotlinIntroduceVariableHandler : KotlinIntroduceHandlerBase() {
|
|||||||
return result
|
return result
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun KtExpression.mustBeParenthesizedInInitializerPosition(): Boolean {
|
|
||||||
if (this !is KtBinaryExpression) return false
|
|
||||||
|
|
||||||
if (left?.mustBeParenthesizedInInitializerPosition() ?: false) return true
|
|
||||||
return PsiChildRange(left, operationReference).any { (it is PsiWhiteSpace) && it.textContains('\n') }
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun runRefactoring (
|
private fun runRefactoring (
|
||||||
expression: KtExpression,
|
expression: KtExpression,
|
||||||
commonContainer: PsiElement,
|
commonContainer: PsiElement,
|
||||||
|
|||||||
+6
@@ -0,0 +1,6 @@
|
|||||||
|
fun foo(i: Int) { }
|
||||||
|
|
||||||
|
fun test() {
|
||||||
|
foo(<selection>1
|
||||||
|
+ 2</selection>)
|
||||||
|
}
|
||||||
Vendored
+8
@@ -0,0 +1,8 @@
|
|||||||
|
fun foo(i: Int) { }
|
||||||
|
|
||||||
|
fun test(i: () -> Int = {
|
||||||
|
(1
|
||||||
|
+ 2)
|
||||||
|
}) {
|
||||||
|
foo(i())
|
||||||
|
}
|
||||||
+6
@@ -0,0 +1,6 @@
|
|||||||
|
fun foo(i: Int) { }
|
||||||
|
|
||||||
|
fun test() {
|
||||||
|
foo(<selection>1 // abc
|
||||||
|
/*def*/ + 2</selection>)
|
||||||
|
}
|
||||||
+8
@@ -0,0 +1,8 @@
|
|||||||
|
fun foo(i: Int) { }
|
||||||
|
|
||||||
|
fun test(i: () -> Int = {
|
||||||
|
(1 // abc
|
||||||
|
/*def*/ + 2)
|
||||||
|
}) {
|
||||||
|
foo(i())
|
||||||
|
}
|
||||||
Vendored
+6
@@ -0,0 +1,6 @@
|
|||||||
|
fun foo(i: Int) { }
|
||||||
|
|
||||||
|
fun test() {
|
||||||
|
foo(<selection>1
|
||||||
|
+ 2 - 3</selection>)
|
||||||
|
}
|
||||||
+8
@@ -0,0 +1,8 @@
|
|||||||
|
fun foo(i: Int) { }
|
||||||
|
|
||||||
|
fun test(i: () -> Int = {
|
||||||
|
(1
|
||||||
|
+ 2 - 3)
|
||||||
|
}) {
|
||||||
|
foo(i())
|
||||||
|
}
|
||||||
Vendored
+6
@@ -0,0 +1,6 @@
|
|||||||
|
fun foo(i: Int) { }
|
||||||
|
|
||||||
|
fun test() {
|
||||||
|
foo(<selection>1 + 2
|
||||||
|
- 3</selection>)
|
||||||
|
}
|
||||||
+8
@@ -0,0 +1,8 @@
|
|||||||
|
fun foo(i: Int) { }
|
||||||
|
|
||||||
|
fun test(i: () -> Int = {
|
||||||
|
(1 + 2
|
||||||
|
- 3)
|
||||||
|
}) {
|
||||||
|
foo(i())
|
||||||
|
}
|
||||||
+6
@@ -0,0 +1,6 @@
|
|||||||
|
fun foo(i: Int) { }
|
||||||
|
|
||||||
|
fun test() {
|
||||||
|
foo(<selection>1
|
||||||
|
+ 2</selection>)
|
||||||
|
}
|
||||||
+6
@@ -0,0 +1,6 @@
|
|||||||
|
fun foo(i: Int) { }
|
||||||
|
|
||||||
|
fun test(i: Int = (1
|
||||||
|
+ 2)) {
|
||||||
|
foo(i)
|
||||||
|
}
|
||||||
Vendored
+6
@@ -0,0 +1,6 @@
|
|||||||
|
fun foo(i: Int) { }
|
||||||
|
|
||||||
|
fun test() {
|
||||||
|
foo(<selection>1 // abc
|
||||||
|
/*def*/ + 2</selection>)
|
||||||
|
}
|
||||||
+6
@@ -0,0 +1,6 @@
|
|||||||
|
fun foo(i: Int) { }
|
||||||
|
|
||||||
|
fun test(i: Int = (1 // abc
|
||||||
|
/*def*/ + 2)) {
|
||||||
|
foo(i)
|
||||||
|
}
|
||||||
+6
@@ -0,0 +1,6 @@
|
|||||||
|
fun foo(i: Int) { }
|
||||||
|
|
||||||
|
fun test() {
|
||||||
|
foo(<selection>1
|
||||||
|
+ 2 - 3</selection>)
|
||||||
|
}
|
||||||
Vendored
+6
@@ -0,0 +1,6 @@
|
|||||||
|
fun foo(i: Int) { }
|
||||||
|
|
||||||
|
fun test(i: Int = (1
|
||||||
|
+ 2 - 3)) {
|
||||||
|
foo(i)
|
||||||
|
}
|
||||||
+6
@@ -0,0 +1,6 @@
|
|||||||
|
fun foo(i: Int) { }
|
||||||
|
|
||||||
|
fun test() {
|
||||||
|
foo(<selection>1 + 2
|
||||||
|
- 3</selection>)
|
||||||
|
}
|
||||||
Vendored
+6
@@ -0,0 +1,6 @@
|
|||||||
|
fun foo(i: Int) { }
|
||||||
|
|
||||||
|
fun test(i: Int = (1 + 2
|
||||||
|
- 3)) {
|
||||||
|
foo(i)
|
||||||
|
}
|
||||||
+66
@@ -3502,6 +3502,39 @@ public class ExtractionTestGenerated extends AbstractExtractionTest {
|
|||||||
doIntroduceSimpleParameterTest(fileName);
|
doIntroduceSimpleParameterTest(fileName);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@TestMetadata("idea/testData/refactoring/introduceParameter/multiline")
|
||||||
|
@TestDataPath("$PROJECT_ROOT")
|
||||||
|
@RunWith(JUnit3RunnerWithInners.class)
|
||||||
|
public static class Multiline extends AbstractExtractionTest {
|
||||||
|
public void testAllFilesPresentInMultiline() throws Exception {
|
||||||
|
KotlinTestUtils.assertAllTestsPresentByMetadata(this.getClass(), new File("idea/testData/refactoring/introduceParameter/multiline"), Pattern.compile("^(.+)\\.(kt|kts)$"), true);
|
||||||
|
}
|
||||||
|
|
||||||
|
@TestMetadata("multilineBinaryExpression.kt")
|
||||||
|
public void testMultilineBinaryExpression() throws Exception {
|
||||||
|
String fileName = KotlinTestUtils.navigationMetadata("idea/testData/refactoring/introduceParameter/multiline/multilineBinaryExpression.kt");
|
||||||
|
doIntroduceSimpleParameterTest(fileName);
|
||||||
|
}
|
||||||
|
|
||||||
|
@TestMetadata("multilineBinaryExpressionWithComments.kt")
|
||||||
|
public void testMultilineBinaryExpressionWithComments() throws Exception {
|
||||||
|
String fileName = KotlinTestUtils.navigationMetadata("idea/testData/refactoring/introduceParameter/multiline/multilineBinaryExpressionWithComments.kt");
|
||||||
|
doIntroduceSimpleParameterTest(fileName);
|
||||||
|
}
|
||||||
|
|
||||||
|
@TestMetadata("multilineNestedBinaryExpression1.kt")
|
||||||
|
public void testMultilineNestedBinaryExpression1() throws Exception {
|
||||||
|
String fileName = KotlinTestUtils.navigationMetadata("idea/testData/refactoring/introduceParameter/multiline/multilineNestedBinaryExpression1.kt");
|
||||||
|
doIntroduceSimpleParameterTest(fileName);
|
||||||
|
}
|
||||||
|
|
||||||
|
@TestMetadata("multilineNestedBinaryExpression2.kt")
|
||||||
|
public void testMultilineNestedBinaryExpression2() throws Exception {
|
||||||
|
String fileName = KotlinTestUtils.navigationMetadata("idea/testData/refactoring/introduceParameter/multiline/multilineNestedBinaryExpression2.kt");
|
||||||
|
doIntroduceSimpleParameterTest(fileName);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@TestMetadata("idea/testData/refactoring/introduceParameter/script")
|
@TestMetadata("idea/testData/refactoring/introduceParameter/script")
|
||||||
@TestDataPath("$PROJECT_ROOT")
|
@TestDataPath("$PROJECT_ROOT")
|
||||||
@RunWith(JUnit3RunnerWithInners.class)
|
@RunWith(JUnit3RunnerWithInners.class)
|
||||||
@@ -3697,6 +3730,39 @@ public class ExtractionTestGenerated extends AbstractExtractionTest {
|
|||||||
doIntroduceLambdaParameterTest(fileName);
|
doIntroduceLambdaParameterTest(fileName);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@TestMetadata("idea/testData/refactoring/introduceLambdaParameter/multiline")
|
||||||
|
@TestDataPath("$PROJECT_ROOT")
|
||||||
|
@RunWith(JUnit3RunnerWithInners.class)
|
||||||
|
public static class Multiline extends AbstractExtractionTest {
|
||||||
|
public void testAllFilesPresentInMultiline() throws Exception {
|
||||||
|
KotlinTestUtils.assertAllTestsPresentByMetadata(this.getClass(), new File("idea/testData/refactoring/introduceLambdaParameter/multiline"), Pattern.compile("^(.+)\\.(kt|kts)$"), true);
|
||||||
|
}
|
||||||
|
|
||||||
|
@TestMetadata("multilineBinaryExpression.kt")
|
||||||
|
public void testMultilineBinaryExpression() throws Exception {
|
||||||
|
String fileName = KotlinTestUtils.navigationMetadata("idea/testData/refactoring/introduceLambdaParameter/multiline/multilineBinaryExpression.kt");
|
||||||
|
doIntroduceLambdaParameterTest(fileName);
|
||||||
|
}
|
||||||
|
|
||||||
|
@TestMetadata("multilineBinaryExpressionWithComments.kt")
|
||||||
|
public void testMultilineBinaryExpressionWithComments() throws Exception {
|
||||||
|
String fileName = KotlinTestUtils.navigationMetadata("idea/testData/refactoring/introduceLambdaParameter/multiline/multilineBinaryExpressionWithComments.kt");
|
||||||
|
doIntroduceLambdaParameterTest(fileName);
|
||||||
|
}
|
||||||
|
|
||||||
|
@TestMetadata("multilineNestedBinaryExpression1.kt")
|
||||||
|
public void testMultilineNestedBinaryExpression1() throws Exception {
|
||||||
|
String fileName = KotlinTestUtils.navigationMetadata("idea/testData/refactoring/introduceLambdaParameter/multiline/multilineNestedBinaryExpression1.kt");
|
||||||
|
doIntroduceLambdaParameterTest(fileName);
|
||||||
|
}
|
||||||
|
|
||||||
|
@TestMetadata("multilineNestedBinaryExpression2.kt")
|
||||||
|
public void testMultilineNestedBinaryExpression2() throws Exception {
|
||||||
|
String fileName = KotlinTestUtils.navigationMetadata("idea/testData/refactoring/introduceLambdaParameter/multiline/multilineNestedBinaryExpression2.kt");
|
||||||
|
doIntroduceLambdaParameterTest(fileName);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@TestMetadata("idea/testData/refactoring/introduceLambdaParameter/stringTemplates")
|
@TestMetadata("idea/testData/refactoring/introduceLambdaParameter/stringTemplates")
|
||||||
@TestDataPath("$PROJECT_ROOT")
|
@TestDataPath("$PROJECT_ROOT")
|
||||||
@RunWith(JUnit3RunnerWithInners.class)
|
@RunWith(JUnit3RunnerWithInners.class)
|
||||||
|
|||||||
Reference in New Issue
Block a user