'Change parameter type' Quick-Fix: Use Change Signature API

#KT-9812 Fixed
This commit is contained in:
Alexey Sedunov
2015-12-23 18:59:08 +03:00
committed by Alexey
parent 9180a99342
commit 5b5e7fb9b7
6 changed files with 73 additions and 4 deletions
@@ -18,12 +18,17 @@ package org.jetbrains.kotlin.idea.quickfix
import com.intellij.openapi.editor.Editor
import com.intellij.openapi.project.Project
import com.intellij.psi.PsiElement
import com.intellij.psi.PsiFile
import com.intellij.psi.util.PsiTreeUtil
import org.jetbrains.kotlin.descriptors.FunctionDescriptor
import org.jetbrains.kotlin.idea.KotlinBundle
import org.jetbrains.kotlin.idea.caches.resolve.analyze
import org.jetbrains.kotlin.idea.refactoring.changeSignature.*
import org.jetbrains.kotlin.idea.util.IdeDescriptorRenderers
import org.jetbrains.kotlin.idea.util.ShortenReferences
import org.jetbrains.kotlin.psi.*
import org.jetbrains.kotlin.psi.psiUtil.getStrictParentOfType
import org.jetbrains.kotlin.resolve.BindingContext
import org.jetbrains.kotlin.types.KotlinType
class ChangeParameterTypeFix(element: KtParameter, private val type: KotlinType) : KotlinQuickFixAction<KtParameter>(element) {
@@ -52,9 +57,17 @@ class ChangeParameterTypeFix(element: KtParameter, private val type: KotlinType)
override fun getFamilyName() = KotlinBundle.message("change.type.family")
public override operator fun invoke(project: Project, editor: Editor?, file: KtFile) {
val newTypeRef = KtPsiFactory(file).createType(IdeDescriptorRenderers.SOURCE_CODE.renderType(type))
element.setTypeReference(newTypeRef)?.let {
ShortenReferences.DEFAULT.process(it)
val function = element.getStrictParentOfType<KtFunction>() ?: return
val parameterIndex = function.valueParameters.indexOf(element)
val context = function.analyze()
val descriptor = context[BindingContext.DECLARATION_TO_DESCRIPTOR, function] as? FunctionDescriptor ?: return
val configuration = object : KotlinChangeSignatureConfiguration {
override fun configure(originalDescriptor: KotlinMethodDescriptor) = originalDescriptor.apply {
parameters[if (receiver != null) parameterIndex + 1 else parameterIndex].currentTypeInfo = KotlinTypeInfo(false, type)
}
override fun performSilently(affectedFunctions: Collection<PsiElement>) = true
}
runChangeSignature(element.project, descriptor, configuration, element, text)
}
}
@@ -0,0 +1,11 @@
// "Change parameter 'a' type of function 'test.B.foo' to 'String'" "true"
package test;
import org.jetbrains.annotations.NotNull;
class J extends B {
@Override
void foo(@NotNull String a) {
super.foo(a);
}
}
@@ -0,0 +1,15 @@
// "Change parameter 'a' type of function 'test.B.foo' to 'String'" "true"
// DISABLE-ERRORS
package test
open class B {
open fun foo(a: String) {}
}
class C : B() {
override fun foo(a: String) = super.foo(a)
}
fun test(b: B) {
b.foo("")
}
@@ -0,0 +1,9 @@
// "Change parameter 'a' type of function 'test.B.foo' to 'String'" "true"
package test;
class J extends B {
@Override
void foo(int a) {
super.foo(a);
}
}
@@ -0,0 +1,15 @@
// "Change parameter 'a' type of function 'test.B.foo' to 'String'" "true"
// DISABLE-ERRORS
package test
open class B {
open fun foo(a: Int) {}
}
class C : B() {
override fun foo(a: Int) = super.foo(a)
}
fun test(b: B) {
b.foo(<caret>"")
}
@@ -1490,6 +1490,12 @@ public class QuickFixMultiFileTestGenerated extends AbstractQuickFixMultiFileTes
KotlinTestUtils.assertAllTestsPresentByMetadata(this.getClass(), new File("idea/testData/quickfix/typeMismatch"), Pattern.compile("^(\\w+)\\.((before\\.Main\\.\\w+)|(test))$"), true);
}
@TestMetadata("paramTypeInOverrides.before.Main.kt")
public void testParamTypeInOverrides() throws Exception {
String fileName = KotlinTestUtils.navigationMetadata("idea/testData/quickfix/typeMismatch/paramTypeInOverrides.before.Main.kt");
doTestWithExtraFile(fileName);
}
@TestMetadata("idea/testData/quickfix/typeMismatch/genericVarianceViolation")
@TestDataPath("$PROJECT_ROOT")
@RunWith(JUnit3RunnerWithInners.class)