Parameter <-> Receiver Conversion: Support header/impl declarations
#KT-18907 Fixed
This commit is contained in:
@@ -68,7 +68,7 @@ internal fun KtDeclaration.headerDeclarationIfAny(): KtDeclaration? {
|
|||||||
internal fun KtDeclaration.isHeaderOrHeaderClassMember() =
|
internal fun KtDeclaration.isHeaderOrHeaderClassMember() =
|
||||||
hasModifier(KtTokens.HEADER_KEYWORD) || (containingClassOrObject?.hasModifier(KtTokens.HEADER_KEYWORD) ?: false)
|
hasModifier(KtTokens.HEADER_KEYWORD) || (containingClassOrObject?.hasModifier(KtTokens.HEADER_KEYWORD) ?: false)
|
||||||
|
|
||||||
private fun DeclarationDescriptor.liftToHeader(): DeclarationDescriptor? {
|
internal fun DeclarationDescriptor.liftToHeader(): DeclarationDescriptor? {
|
||||||
if (this is MemberDescriptor) {
|
if (this is MemberDescriptor) {
|
||||||
return when {
|
return when {
|
||||||
isHeader -> this
|
isHeader -> this
|
||||||
|
|||||||
+2
-4
@@ -19,15 +19,14 @@ package org.jetbrains.kotlin.idea.intentions
|
|||||||
import com.intellij.openapi.editor.Editor
|
import com.intellij.openapi.editor.Editor
|
||||||
import com.intellij.psi.PsiElement
|
import com.intellij.psi.PsiElement
|
||||||
import org.jetbrains.kotlin.descriptors.FunctionDescriptor
|
import org.jetbrains.kotlin.descriptors.FunctionDescriptor
|
||||||
import org.jetbrains.kotlin.idea.caches.resolve.analyze
|
|
||||||
import org.jetbrains.kotlin.idea.refactoring.changeSignature.KotlinChangeSignatureConfiguration
|
import org.jetbrains.kotlin.idea.refactoring.changeSignature.KotlinChangeSignatureConfiguration
|
||||||
import org.jetbrains.kotlin.idea.refactoring.changeSignature.KotlinMethodDescriptor
|
import org.jetbrains.kotlin.idea.refactoring.changeSignature.KotlinMethodDescriptor
|
||||||
import org.jetbrains.kotlin.idea.refactoring.changeSignature.modify
|
import org.jetbrains.kotlin.idea.refactoring.changeSignature.modify
|
||||||
import org.jetbrains.kotlin.idea.refactoring.changeSignature.runChangeSignature
|
import org.jetbrains.kotlin.idea.refactoring.changeSignature.runChangeSignature
|
||||||
|
import org.jetbrains.kotlin.idea.refactoring.resolveToHeaderDescriptorIfPossible
|
||||||
import org.jetbrains.kotlin.psi.KtNamedFunction
|
import org.jetbrains.kotlin.psi.KtNamedFunction
|
||||||
import org.jetbrains.kotlin.psi.KtParameter
|
import org.jetbrains.kotlin.psi.KtParameter
|
||||||
import org.jetbrains.kotlin.psi.psiUtil.getStrictParentOfType
|
import org.jetbrains.kotlin.psi.psiUtil.getStrictParentOfType
|
||||||
import org.jetbrains.kotlin.resolve.BindingContext
|
|
||||||
|
|
||||||
class ConvertParameterToReceiverIntention : SelfTargetingIntention<KtParameter>(KtParameter::class.java, "Convert parameter to receiver") {
|
class ConvertParameterToReceiverIntention : SelfTargetingIntention<KtParameter>(KtParameter::class.java, "Convert parameter to receiver") {
|
||||||
override fun isApplicableTo(element: KtParameter, caretOffset: Int): Boolean {
|
override fun isApplicableTo(element: KtParameter, caretOffset: Int): Boolean {
|
||||||
@@ -53,8 +52,7 @@ class ConvertParameterToReceiverIntention : SelfTargetingIntention<KtParameter>(
|
|||||||
override fun applyTo(element: KtParameter, editor: Editor?) {
|
override fun applyTo(element: KtParameter, editor: Editor?) {
|
||||||
val function = element.getStrictParentOfType<KtNamedFunction>() ?: return
|
val function = element.getStrictParentOfType<KtNamedFunction>() ?: return
|
||||||
val parameterIndex = function.valueParameters.indexOf(element)
|
val parameterIndex = function.valueParameters.indexOf(element)
|
||||||
val context = function.analyze()
|
val descriptor = function.resolveToHeaderDescriptorIfPossible() as? FunctionDescriptor ?: return
|
||||||
val descriptor = context[BindingContext.DECLARATION_TO_DESCRIPTOR, function] as? FunctionDescriptor ?: return
|
|
||||||
runChangeSignature(element.project, descriptor, configureChangeSignature(parameterIndex), element, text)
|
runChangeSignature(element.project, descriptor, configureChangeSignature(parameterIndex), element, text)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+3
-3
@@ -26,9 +26,9 @@ import com.intellij.openapi.editor.Editor
|
|||||||
import com.intellij.psi.PsiDocumentManager
|
import com.intellij.psi.PsiDocumentManager
|
||||||
import com.intellij.psi.PsiElement
|
import com.intellij.psi.PsiElement
|
||||||
import org.jetbrains.kotlin.descriptors.FunctionDescriptor
|
import org.jetbrains.kotlin.descriptors.FunctionDescriptor
|
||||||
import org.jetbrains.kotlin.idea.caches.resolve.resolveToDescriptor
|
|
||||||
import org.jetbrains.kotlin.idea.core.getOrCreateValueParameterList
|
import org.jetbrains.kotlin.idea.core.getOrCreateValueParameterList
|
||||||
import org.jetbrains.kotlin.idea.refactoring.changeSignature.*
|
import org.jetbrains.kotlin.idea.refactoring.changeSignature.*
|
||||||
|
import org.jetbrains.kotlin.idea.refactoring.resolveToHeaderDescriptorIfPossible
|
||||||
import org.jetbrains.kotlin.idea.util.application.executeWriteCommand
|
import org.jetbrains.kotlin.idea.util.application.executeWriteCommand
|
||||||
import org.jetbrains.kotlin.idea.util.application.runWriteAction
|
import org.jetbrains.kotlin.idea.util.application.runWriteAction
|
||||||
import org.jetbrains.kotlin.psi.KtNamedFunction
|
import org.jetbrains.kotlin.psi.KtNamedFunction
|
||||||
@@ -61,7 +61,7 @@ class ConvertReceiverToParameterIntention : SelfTargetingOffsetIndependentIntent
|
|||||||
|
|
||||||
override fun applyTo(element: KtTypeReference, editor: Editor?) {
|
override fun applyTo(element: KtTypeReference, editor: Editor?) {
|
||||||
val function = element.parent as? KtNamedFunction ?: return
|
val function = element.parent as? KtNamedFunction ?: return
|
||||||
val descriptor = function.resolveToDescriptor() as FunctionDescriptor
|
val descriptor = function.resolveToHeaderDescriptorIfPossible() as FunctionDescriptor
|
||||||
|
|
||||||
val project = function.project
|
val project = function.project
|
||||||
|
|
||||||
@@ -102,7 +102,7 @@ class ConvertReceiverToParameterIntention : SelfTargetingOffsetIndependentIntent
|
|||||||
if (!brokenOff) {
|
if (!brokenOff) {
|
||||||
runChangeSignature(
|
runChangeSignature(
|
||||||
element.project,
|
element.project,
|
||||||
function.resolveToDescriptor() as FunctionDescriptor,
|
function.resolveToHeaderDescriptorIfPossible() as FunctionDescriptor,
|
||||||
configureChangeSignature(newName),
|
configureChangeSignature(newName),
|
||||||
function.receiverTypeReference!!,
|
function.receiverTypeReference!!,
|
||||||
text
|
text
|
||||||
|
|||||||
@@ -970,4 +970,9 @@ internal fun KtDeclaration.withHeaderImplementations(): List<KtDeclaration> {
|
|||||||
val header = liftToHeader() ?: return listOf(this)
|
val header = liftToHeader() ?: return listOf(this)
|
||||||
val implementations = header.headerImplementations() ?: emptySet()
|
val implementations = header.headerImplementations() ?: emptySet()
|
||||||
return listOf(header) + implementations
|
return listOf(header) + implementations
|
||||||
|
}
|
||||||
|
|
||||||
|
internal fun KtDeclaration.resolveToHeaderDescriptorIfPossible(): DeclarationDescriptor {
|
||||||
|
val descriptor = resolveToDescriptor()
|
||||||
|
return descriptor.liftToHeader() ?: descriptor
|
||||||
}
|
}
|
||||||
+9
@@ -0,0 +1,9 @@
|
|||||||
|
// "Convert parameter to receiver" "true"
|
||||||
|
|
||||||
|
header class Foo {
|
||||||
|
fun foo(n: Int, <caret>s: String)
|
||||||
|
}
|
||||||
|
|
||||||
|
fun Foo.test() {
|
||||||
|
foo(1, "2")
|
||||||
|
}
|
||||||
Vendored
+9
@@ -0,0 +1,9 @@
|
|||||||
|
// "Convert parameter to receiver" "true"
|
||||||
|
|
||||||
|
header class Foo {
|
||||||
|
fun String.foo(n: Int)
|
||||||
|
}
|
||||||
|
|
||||||
|
fun Foo.test() {
|
||||||
|
"2".foo(1)
|
||||||
|
}
|
||||||
+9
@@ -0,0 +1,9 @@
|
|||||||
|
impl class Foo {
|
||||||
|
impl fun foo(n: Int, s: String) {
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fun Foo.test() {
|
||||||
|
foo(1, "2")
|
||||||
|
}
|
||||||
+9
@@ -0,0 +1,9 @@
|
|||||||
|
impl class Foo {
|
||||||
|
impl fun String.foo(n: Int) {
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fun Foo.test() {
|
||||||
|
"2".foo(1)
|
||||||
|
}
|
||||||
+9
@@ -0,0 +1,9 @@
|
|||||||
|
impl class Foo {
|
||||||
|
impl fun foo(n: Int, s: String) {
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fun Foo.test() {
|
||||||
|
foo(1, "2")
|
||||||
|
}
|
||||||
+9
@@ -0,0 +1,9 @@
|
|||||||
|
impl class Foo {
|
||||||
|
impl fun String.foo(n: Int) {
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fun Foo.test() {
|
||||||
|
"2".foo(1)
|
||||||
|
}
|
||||||
+7
@@ -0,0 +1,7 @@
|
|||||||
|
header class Foo {
|
||||||
|
fun foo(n: Int, s: String)
|
||||||
|
}
|
||||||
|
|
||||||
|
fun Foo.test() {
|
||||||
|
foo(1, "2")
|
||||||
|
}
|
||||||
Vendored
+7
@@ -0,0 +1,7 @@
|
|||||||
|
header class Foo {
|
||||||
|
fun String.foo(n: Int)
|
||||||
|
}
|
||||||
|
|
||||||
|
fun Foo.test() {
|
||||||
|
"2".foo(1)
|
||||||
|
}
|
||||||
+11
@@ -0,0 +1,11 @@
|
|||||||
|
// "Convert parameter to receiver" "true"
|
||||||
|
|
||||||
|
impl class Foo {
|
||||||
|
impl fun foo(n: Int, <caret>s: String) {
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fun Foo.test() {
|
||||||
|
foo(1, "2")
|
||||||
|
}
|
||||||
+11
@@ -0,0 +1,11 @@
|
|||||||
|
// "Convert parameter to receiver" "true"
|
||||||
|
|
||||||
|
impl class Foo {
|
||||||
|
impl fun String.foo(n: Int) {
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fun Foo.test() {
|
||||||
|
"2".foo(1)
|
||||||
|
}
|
||||||
+9
@@ -0,0 +1,9 @@
|
|||||||
|
impl class Foo {
|
||||||
|
impl fun foo(n: Int, s: String) {
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fun Foo.test() {
|
||||||
|
foo(1, "2")
|
||||||
|
}
|
||||||
+9
@@ -0,0 +1,9 @@
|
|||||||
|
impl class Foo {
|
||||||
|
impl fun String.foo(n: Int) {
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fun Foo.test() {
|
||||||
|
"2".foo(1)
|
||||||
|
}
|
||||||
+9
@@ -0,0 +1,9 @@
|
|||||||
|
// "Convert receiver to parameter" "true"
|
||||||
|
|
||||||
|
header class Foo {
|
||||||
|
fun <caret>String.foo(n: Int)
|
||||||
|
}
|
||||||
|
|
||||||
|
fun Foo.test() {
|
||||||
|
"1".foo(2)
|
||||||
|
}
|
||||||
Vendored
+9
@@ -0,0 +1,9 @@
|
|||||||
|
// "Convert receiver to parameter" "true"
|
||||||
|
|
||||||
|
header class Foo {
|
||||||
|
fun foo(s: String, n: Int)
|
||||||
|
}
|
||||||
|
|
||||||
|
fun Foo.test() {
|
||||||
|
foo("1", 2)
|
||||||
|
}
|
||||||
+9
@@ -0,0 +1,9 @@
|
|||||||
|
impl class Foo {
|
||||||
|
impl fun String.foo(n: Int) {
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fun Foo.test() {
|
||||||
|
"1".foo(2)
|
||||||
|
}
|
||||||
+9
@@ -0,0 +1,9 @@
|
|||||||
|
impl class Foo {
|
||||||
|
impl fun foo(s: String, n: Int) {
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fun Foo.test() {
|
||||||
|
foo("1", 2)
|
||||||
|
}
|
||||||
+9
@@ -0,0 +1,9 @@
|
|||||||
|
impl class Foo {
|
||||||
|
impl fun String.foo(n: Int) {
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fun Foo.test() {
|
||||||
|
"1".foo(2)
|
||||||
|
}
|
||||||
+9
@@ -0,0 +1,9 @@
|
|||||||
|
impl class Foo {
|
||||||
|
impl fun foo(s: String, n: Int) {
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fun Foo.test() {
|
||||||
|
foo("1", 2)
|
||||||
|
}
|
||||||
+7
@@ -0,0 +1,7 @@
|
|||||||
|
header class Foo {
|
||||||
|
fun String.foo(n: Int)
|
||||||
|
}
|
||||||
|
|
||||||
|
fun Foo.test() {
|
||||||
|
"1".foo(2)
|
||||||
|
}
|
||||||
Vendored
+7
@@ -0,0 +1,7 @@
|
|||||||
|
header class Foo {
|
||||||
|
fun foo(s: String, n: Int)
|
||||||
|
}
|
||||||
|
|
||||||
|
fun Foo.test() {
|
||||||
|
foo("1", 2)
|
||||||
|
}
|
||||||
+11
@@ -0,0 +1,11 @@
|
|||||||
|
// "Convert receiver to parameter" "true"
|
||||||
|
|
||||||
|
impl class Foo {
|
||||||
|
impl fun <caret>String.foo(n: Int) {
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fun Foo.test() {
|
||||||
|
"1".foo(2)
|
||||||
|
}
|
||||||
+11
@@ -0,0 +1,11 @@
|
|||||||
|
// "Convert receiver to parameter" "true"
|
||||||
|
|
||||||
|
impl class Foo {
|
||||||
|
impl fun foo(s: String, n: Int) {
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fun Foo.test() {
|
||||||
|
foo("1", 2)
|
||||||
|
}
|
||||||
+9
@@ -0,0 +1,9 @@
|
|||||||
|
impl class Foo {
|
||||||
|
impl fun String.foo(n: Int) {
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fun Foo.test() {
|
||||||
|
"1".foo(2)
|
||||||
|
}
|
||||||
+9
@@ -0,0 +1,9 @@
|
|||||||
|
impl class Foo {
|
||||||
|
impl fun foo(s: String, n: Int) {
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fun Foo.test() {
|
||||||
|
foo("1", 2)
|
||||||
|
}
|
||||||
@@ -129,4 +129,16 @@ class QuickFixMultiModuleTest : AbstractQuickFixMultiModuleTest() {
|
|||||||
|
|
||||||
@Test
|
@Test
|
||||||
fun testAddOperatorByImpl() = doTestHeaderWithJvmAndJs()
|
fun testAddOperatorByImpl() = doTestHeaderWithJvmAndJs()
|
||||||
|
|
||||||
|
@Test
|
||||||
|
fun testMemberFunReceiverToParameterByHeader() = doTestHeaderWithJvmAndJs()
|
||||||
|
|
||||||
|
@Test
|
||||||
|
fun testMemberFunReceiverToParameterByImpl() = doTestHeaderWithJvmAndJs()
|
||||||
|
|
||||||
|
@Test
|
||||||
|
fun testMemberFunParameterToReceiverByHeader() = doTestHeaderWithJvmAndJs()
|
||||||
|
|
||||||
|
@Test
|
||||||
|
fun testMemberFunParameterToReceiverByImpl() = doTestHeaderWithJvmAndJs()
|
||||||
}
|
}
|
||||||
Reference in New Issue
Block a user