diff --git a/idea/src/org/jetbrains/kotlin/idea/refactoring/introduce/extractionEngine/ExtractableCodeDescriptor.kt b/idea/src/org/jetbrains/kotlin/idea/refactoring/introduce/extractionEngine/ExtractableCodeDescriptor.kt index 058d6cd4af1..389328bcd9b 100644 --- a/idea/src/org/jetbrains/kotlin/idea/refactoring/introduce/extractionEngine/ExtractableCodeDescriptor.kt +++ b/idea/src/org/jetbrains/kotlin/idea/refactoring/introduce/extractionEngine/ExtractableCodeDescriptor.kt @@ -23,6 +23,7 @@ import com.intellij.util.containers.MultiMap import org.jetbrains.kotlin.builtins.KotlinBuiltIns import org.jetbrains.kotlin.descriptors.DeclarationDescriptor import org.jetbrains.kotlin.descriptors.ModuleDescriptor +import org.jetbrains.kotlin.idea.core.refactoring.JetNameSuggester import org.jetbrains.kotlin.idea.core.replaced import org.jetbrains.kotlin.idea.refactoring.JetRefactoringBundle import org.jetbrains.kotlin.idea.refactoring.introduce.extractionEngine.AnalysisResult.ErrorMessage @@ -82,13 +83,16 @@ class RenameReplacement(override val parameter: Parameter): ParameterReplacement override fun invoke(e: JetElement): JetElement { var expressionToReplace = (e.getParent() as? JetThisExpression ?: e).getQualifiedExpressionForSelectorOrThis() + val parameterName = JetPsiUtil.unquoteIdentifier(parameter.nameForRef) + val replacingName = + if (e.getText().startsWith('`') || !JetNameSuggester.isIdentifier(parameterName)) "`$parameterName`" else parameterName val psiFactory = JetPsiFactory(e) val replacement = if (expressionToReplace is JetOperationReferenceExpression) { - psiFactory.createOperationName(parameter.nameForRef) + psiFactory.createOperationName(replacingName) } else { - psiFactory.createSimpleName(parameter.nameForRef) + psiFactory.createSimpleName(replacingName) } return expressionToReplace.replaced(replacement) } diff --git a/idea/src/org/jetbrains/kotlin/idea/refactoring/introduce/extractionEngine/ExtractionData.kt b/idea/src/org/jetbrains/kotlin/idea/refactoring/introduce/extractionEngine/ExtractionData.kt index 4c2a105d12c..aca42b16c17 100644 --- a/idea/src/org/jetbrains/kotlin/idea/refactoring/introduce/extractionEngine/ExtractionData.kt +++ b/idea/src/org/jetbrains/kotlin/idea/refactoring/introduce/extractionEngine/ExtractionData.kt @@ -21,6 +21,7 @@ import org.jetbrains.kotlin.descriptors.DeclarationDescriptor import org.jetbrains.kotlin.resolve.calls.model.ResolvedCall import com.intellij.openapi.project.Project import com.intellij.openapi.util.TextRange +import com.intellij.psi.PsiNameIdentifierOwner import kotlin.properties.Delegates import java.util.HashMap import org.jetbrains.kotlin.idea.codeInsight.JetFileReferencesResolver @@ -63,7 +64,7 @@ data class ExtractionOptions( data class ResolveResult( val originalRefExpr: JetSimpleNameExpression, - val declaration: PsiNamedElement, + val declaration: PsiNameIdentifierOwner, val descriptor: DeclarationDescriptor, val resolvedCall: ResolvedCall<*>? ) @@ -148,7 +149,7 @@ data class ExtractionData( val resolvedCall = ref.getResolvedCall(context) val descriptor = context[BindingContext.REFERENCE_TARGET, ref] ?: return - val declaration = DescriptorToSourceUtilsIde.getAnyDeclaration(project, descriptor) as? PsiNamedElement + val declaration = DescriptorToSourceUtilsIde.getAnyDeclaration(project, descriptor) as? PsiNameIdentifierOwner ?: if (isExtractableIt(descriptor, context)) itFakeDeclaration else if (isSynthesizedInvoke(descriptor)) synthesizedInvokeDeclaration else return diff --git a/idea/src/org/jetbrains/kotlin/idea/refactoring/introduce/extractionEngine/extractableAnalysisUtil.kt b/idea/src/org/jetbrains/kotlin/idea/refactoring/introduce/extractionEngine/extractableAnalysisUtil.kt index 2af0d1492e7..272ef1293fa 100644 --- a/idea/src/org/jetbrains/kotlin/idea/refactoring/introduce/extractionEngine/extractableAnalysisUtil.kt +++ b/idea/src/org/jetbrains/kotlin/idea/refactoring/introduce/extractionEngine/extractableAnalysisUtil.kt @@ -709,7 +709,7 @@ private fun ExtractionData.inferParametersInfo( } if (!extractThis) { - parameter.currentName = originalDeclaration.getName() + parameter.currentName = originalDeclaration.getNameIdentifier()?.getText() } parameter.refCount++ diff --git a/idea/testData/refactoring/extractFunction/parameters/misc/addPrefixToBackticks.kt b/idea/testData/refactoring/extractFunction/parameters/misc/addPrefixToBackticks.kt new file mode 100644 index 00000000000..60482eec91f --- /dev/null +++ b/idea/testData/refactoring/extractFunction/parameters/misc/addPrefixToBackticks.kt @@ -0,0 +1,12 @@ +// PARAM_TYPES: X +// PARAM_TYPES: Y +// PARAM_DESCRIPTOR: internal final fun X.test(): kotlin.Unit defined in Y +// PARAM_DESCRIPTOR: internal final class Y defined in root package +class X(val x: Int) + +// SIBLING: +class Y(val y: Int) { + fun X.test() { + `x`plus y + } +} \ No newline at end of file diff --git a/idea/testData/refactoring/extractFunction/parameters/misc/addPrefixToBackticks.kt.after b/idea/testData/refactoring/extractFunction/parameters/misc/addPrefixToBackticks.kt.after new file mode 100644 index 00000000000..22b88796757 --- /dev/null +++ b/idea/testData/refactoring/extractFunction/parameters/misc/addPrefixToBackticks.kt.after @@ -0,0 +1,16 @@ +// PARAM_TYPES: X +// PARAM_TYPES: Y +// PARAM_DESCRIPTOR: internal final fun X.test(): kotlin.Unit defined in Y +// PARAM_DESCRIPTOR: internal final class Y defined in root package +class X(val x: Int) + +// SIBLING: +class Y(val y: Int) { + fun X.test() { + __dummyTestFun__(this, this@Y) + } +} + +private fun __dummyTestFun__(x: X, y1: Y) { + x.`x`plus y1.y +} \ No newline at end of file diff --git a/idea/testData/refactoring/extractFunction/parameters/misc/idWithBackticks.kt b/idea/testData/refactoring/extractFunction/parameters/misc/idWithBackticks.kt new file mode 100644 index 00000000000..27029d42c82 --- /dev/null +++ b/idea/testData/refactoring/extractFunction/parameters/misc/idWithBackticks.kt @@ -0,0 +1,6 @@ +// PARAM_TYPES: kotlin.Int +// PARAM_DESCRIPTOR: val i: kotlin.Int defined in test +fun test() { + val `i` = 0 + `i`plus i +} \ No newline at end of file diff --git a/idea/testData/refactoring/extractFunction/parameters/misc/idWithBackticks.kt.after b/idea/testData/refactoring/extractFunction/parameters/misc/idWithBackticks.kt.after new file mode 100644 index 00000000000..3bda48a1406 --- /dev/null +++ b/idea/testData/refactoring/extractFunction/parameters/misc/idWithBackticks.kt.after @@ -0,0 +1,10 @@ +// PARAM_TYPES: kotlin.Int +// PARAM_DESCRIPTOR: val i: kotlin.Int defined in test +fun test() { + val `i` = 0 + __dummyTestFun__(`i`) +} + +private fun __dummyTestFun__(`i`: Int) { + `i`plus i +} \ No newline at end of file diff --git a/idea/testData/refactoring/extractFunction/parameters/misc/idWithRequiredBackticks.kt b/idea/testData/refactoring/extractFunction/parameters/misc/idWithRequiredBackticks.kt new file mode 100644 index 00000000000..d3a9827f62d --- /dev/null +++ b/idea/testData/refactoring/extractFunction/parameters/misc/idWithRequiredBackticks.kt @@ -0,0 +1,6 @@ +// PARAM_TYPES: kotlin.Int +// PARAM_DESCRIPTOR: val 0: kotlin.Int defined in test +fun test() { + val `0` = 0 + `0`plus 1 +} \ No newline at end of file diff --git a/idea/testData/refactoring/extractFunction/parameters/misc/idWithRequiredBackticks.kt.after b/idea/testData/refactoring/extractFunction/parameters/misc/idWithRequiredBackticks.kt.after new file mode 100644 index 00000000000..c18d5704c85 --- /dev/null +++ b/idea/testData/refactoring/extractFunction/parameters/misc/idWithRequiredBackticks.kt.after @@ -0,0 +1,10 @@ +// PARAM_TYPES: kotlin.Int +// PARAM_DESCRIPTOR: val 0: kotlin.Int defined in test +fun test() { + val `0` = 0 + __dummyTestFun__(`0`) +} + +private fun __dummyTestFun__(`0`: Int) { + `0`plus 1 +} \ No newline at end of file diff --git a/idea/testData/refactoring/extractFunction/parameters/misc/replaceWithBackticks.kt b/idea/testData/refactoring/extractFunction/parameters/misc/replaceWithBackticks.kt new file mode 100644 index 00000000000..9519a6abd89 --- /dev/null +++ b/idea/testData/refactoring/extractFunction/parameters/misc/replaceWithBackticks.kt @@ -0,0 +1,6 @@ +// PARAM_TYPES: kotlin.Int +// PARAM_DESCRIPTOR: val i: kotlin.Int defined in test +fun test() { + val i = 0 + `i`plus i +} \ No newline at end of file diff --git a/idea/testData/refactoring/extractFunction/parameters/misc/replaceWithBackticks.kt.after b/idea/testData/refactoring/extractFunction/parameters/misc/replaceWithBackticks.kt.after new file mode 100644 index 00000000000..944d1e7b4b4 --- /dev/null +++ b/idea/testData/refactoring/extractFunction/parameters/misc/replaceWithBackticks.kt.after @@ -0,0 +1,10 @@ +// PARAM_TYPES: kotlin.Int +// PARAM_DESCRIPTOR: val i: kotlin.Int defined in test +fun test() { + val i = 0 + __dummyTestFun__(`i`) +} + +private fun __dummyTestFun__(i: Int) { + `i`plus i +} \ No newline at end of file diff --git a/idea/testData/refactoring/extractFunction/parameters/misc/replaceWithBackticks2.kt b/idea/testData/refactoring/extractFunction/parameters/misc/replaceWithBackticks2.kt new file mode 100644 index 00000000000..f6e02abdaa5 --- /dev/null +++ b/idea/testData/refactoring/extractFunction/parameters/misc/replaceWithBackticks2.kt @@ -0,0 +1,6 @@ +// PARAM_TYPES: kotlin.Int +// PARAM_DESCRIPTOR: val i: kotlin.Int defined in test +fun test() { + val i = 0 + i plus `i` +} \ No newline at end of file diff --git a/idea/testData/refactoring/extractFunction/parameters/misc/replaceWithBackticks2.kt.after b/idea/testData/refactoring/extractFunction/parameters/misc/replaceWithBackticks2.kt.after new file mode 100644 index 00000000000..c1d98eb3943 --- /dev/null +++ b/idea/testData/refactoring/extractFunction/parameters/misc/replaceWithBackticks2.kt.after @@ -0,0 +1,10 @@ +// PARAM_TYPES: kotlin.Int +// PARAM_DESCRIPTOR: val i: kotlin.Int defined in test +fun test() { + val i = 0 + __dummyTestFun__(i) +} + +private fun __dummyTestFun__(i: Int) { + i plus `i` +} \ No newline at end of file diff --git a/idea/tests/org/jetbrains/kotlin/idea/refactoring/introduce/JetExtractionTestGenerated.java b/idea/tests/org/jetbrains/kotlin/idea/refactoring/introduce/JetExtractionTestGenerated.java index e009781251e..3d9d93a3d07 100644 --- a/idea/tests/org/jetbrains/kotlin/idea/refactoring/introduce/JetExtractionTestGenerated.java +++ b/idea/tests/org/jetbrains/kotlin/idea/refactoring/introduce/JetExtractionTestGenerated.java @@ -1873,6 +1873,12 @@ public class JetExtractionTestGenerated extends AbstractJetExtractionTest { @TestDataPath("$PROJECT_ROOT") @RunWith(JUnit3RunnerWithInners.class) public static class Misc extends AbstractJetExtractionTest { + @TestMetadata("addPrefixToBackticks.kt") + public void testAddPrefixToBackticks() throws Exception { + String fileName = JetTestUtils.navigationMetadata("idea/testData/refactoring/extractFunction/parameters/misc/addPrefixToBackticks.kt"); + doExtractFunctionTest(fileName); + } + public void testAllFilesPresentInMisc() throws Exception { JetTestUtils.assertAllTestsPresentByMetadata(this.getClass(), new File("idea/testData/refactoring/extractFunction/parameters/misc"), Pattern.compile("^(.+)\\.kt$"), true); } @@ -1895,6 +1901,18 @@ public class JetExtractionTestGenerated extends AbstractJetExtractionTest { doExtractFunctionTest(fileName); } + @TestMetadata("idWithBackticks.kt") + public void testIdWithBackticks() throws Exception { + String fileName = JetTestUtils.navigationMetadata("idea/testData/refactoring/extractFunction/parameters/misc/idWithBackticks.kt"); + doExtractFunctionTest(fileName); + } + + @TestMetadata("idWithRequiredBackticks.kt") + public void testIdWithRequiredBackticks() throws Exception { + String fileName = JetTestUtils.navigationMetadata("idea/testData/refactoring/extractFunction/parameters/misc/idWithRequiredBackticks.kt"); + doExtractFunctionTest(fileName); + } + @TestMetadata("innerClassObject.kt") public void testInnerClassObject() throws Exception { String fileName = JetTestUtils.navigationMetadata("idea/testData/refactoring/extractFunction/parameters/misc/innerClassObject.kt"); @@ -1979,6 +1997,18 @@ public class JetExtractionTestGenerated extends AbstractJetExtractionTest { doExtractFunctionTest(fileName); } + @TestMetadata("replaceWithBackticks.kt") + public void testReplaceWithBackticks() throws Exception { + String fileName = JetTestUtils.navigationMetadata("idea/testData/refactoring/extractFunction/parameters/misc/replaceWithBackticks.kt"); + doExtractFunctionTest(fileName); + } + + @TestMetadata("replaceWithBackticks2.kt") + public void testReplaceWithBackticks2() throws Exception { + String fileName = JetTestUtils.navigationMetadata("idea/testData/refactoring/extractFunction/parameters/misc/replaceWithBackticks2.kt"); + doExtractFunctionTest(fileName); + } + @TestMetadata("thisInObject.kt") public void testThisInObject() throws Exception { String fileName = JetTestUtils.navigationMetadata("idea/testData/refactoring/extractFunction/parameters/misc/thisInObject.kt");