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() =
|
||||
hasModifier(KtTokens.HEADER_KEYWORD) || (containingClassOrObject?.hasModifier(KtTokens.HEADER_KEYWORD) ?: false)
|
||||
|
||||
private fun DeclarationDescriptor.liftToHeader(): DeclarationDescriptor? {
|
||||
internal fun DeclarationDescriptor.liftToHeader(): DeclarationDescriptor? {
|
||||
if (this is MemberDescriptor) {
|
||||
return when {
|
||||
isHeader -> this
|
||||
|
||||
+2
-4
@@ -19,15 +19,14 @@ package org.jetbrains.kotlin.idea.intentions
|
||||
import com.intellij.openapi.editor.Editor
|
||||
import com.intellij.psi.PsiElement
|
||||
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.KotlinMethodDescriptor
|
||||
import org.jetbrains.kotlin.idea.refactoring.changeSignature.modify
|
||||
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.KtParameter
|
||||
import org.jetbrains.kotlin.psi.psiUtil.getStrictParentOfType
|
||||
import org.jetbrains.kotlin.resolve.BindingContext
|
||||
|
||||
class ConvertParameterToReceiverIntention : SelfTargetingIntention<KtParameter>(KtParameter::class.java, "Convert parameter to receiver") {
|
||||
override fun isApplicableTo(element: KtParameter, caretOffset: Int): Boolean {
|
||||
@@ -53,8 +52,7 @@ class ConvertParameterToReceiverIntention : SelfTargetingIntention<KtParameter>(
|
||||
override fun applyTo(element: KtParameter, editor: Editor?) {
|
||||
val function = element.getStrictParentOfType<KtNamedFunction>() ?: return
|
||||
val parameterIndex = function.valueParameters.indexOf(element)
|
||||
val context = function.analyze()
|
||||
val descriptor = context[BindingContext.DECLARATION_TO_DESCRIPTOR, function] as? FunctionDescriptor ?: return
|
||||
val descriptor = function.resolveToHeaderDescriptorIfPossible() as? FunctionDescriptor ?: return
|
||||
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.PsiElement
|
||||
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.refactoring.changeSignature.*
|
||||
import org.jetbrains.kotlin.idea.refactoring.resolveToHeaderDescriptorIfPossible
|
||||
import org.jetbrains.kotlin.idea.util.application.executeWriteCommand
|
||||
import org.jetbrains.kotlin.idea.util.application.runWriteAction
|
||||
import org.jetbrains.kotlin.psi.KtNamedFunction
|
||||
@@ -61,7 +61,7 @@ class ConvertReceiverToParameterIntention : SelfTargetingOffsetIndependentIntent
|
||||
|
||||
override fun applyTo(element: KtTypeReference, editor: Editor?) {
|
||||
val function = element.parent as? KtNamedFunction ?: return
|
||||
val descriptor = function.resolveToDescriptor() as FunctionDescriptor
|
||||
val descriptor = function.resolveToHeaderDescriptorIfPossible() as FunctionDescriptor
|
||||
|
||||
val project = function.project
|
||||
|
||||
@@ -102,7 +102,7 @@ class ConvertReceiverToParameterIntention : SelfTargetingOffsetIndependentIntent
|
||||
if (!brokenOff) {
|
||||
runChangeSignature(
|
||||
element.project,
|
||||
function.resolveToDescriptor() as FunctionDescriptor,
|
||||
function.resolveToHeaderDescriptorIfPossible() as FunctionDescriptor,
|
||||
configureChangeSignature(newName),
|
||||
function.receiverTypeReference!!,
|
||||
text
|
||||
|
||||
@@ -970,4 +970,9 @@ internal fun KtDeclaration.withHeaderImplementations(): List<KtDeclaration> {
|
||||
val header = liftToHeader() ?: return listOf(this)
|
||||
val implementations = header.headerImplementations() ?: emptySet()
|
||||
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
|
||||
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