Corrected quickfix to correct signature of method with 'override' to:

- not loose annotations and other stuff
  - not include visibility modifiers into the name and into the code generated
This commit is contained in:
Valentin Kipyatkov
2014-10-04 01:30:57 +04:00
parent 89ea4d5a85
commit 317607db70
9 changed files with 60 additions and 41 deletions
@@ -28,12 +28,13 @@ import com.intellij.psi.PsiDocumentManager;
import com.intellij.util.PlatformIcons;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.jet.lang.descriptors.FunctionDescriptor;
import org.jetbrains.jet.lang.psi.JetExpression;
import org.jetbrains.jet.lang.psi.JetNamedFunction;
import org.jetbrains.jet.lang.psi.JetPsiFactory;
import org.jetbrains.jet.lang.psi.JetTypeReference;
import org.jetbrains.jet.plugin.JetBundle;
import org.jetbrains.jet.plugin.codeInsight.CodeInsightUtils;
import org.jetbrains.jet.plugin.codeInsight.ShortenReferences;
import org.jetbrains.jet.renderer.DescriptorRenderer;
import org.jetbrains.jet.renderer.DescriptorRendererBuilder;
import javax.swing.*;
import java.util.ArrayList;
@@ -47,6 +48,12 @@ import static org.jetbrains.jet.lang.psi.PsiPackage.JetPsiFactory;
* Based on {@link JetAddImportAction}
*/
public class JetChangeFunctionSignatureAction implements QuestionAction {
public static final DescriptorRenderer SIGNATURE_RENDERER = new DescriptorRendererBuilder()
.setWithDefinedIn(false)
.setModifiers(DescriptorRenderer.Modifier.OVERRIDE)
.setShortNames(true)
.setOverrideRenderingPolicy(DescriptorRenderer.OverrideRenderingPolicy.RENDER_OVERRIDE)
.setUnitReturnType(false).build();
private final Project project;
private final Editor editor;
@@ -113,46 +120,32 @@ public class JetChangeFunctionSignatureAction implements QuestionAction {
@NotNull
@Override
public String getTextFor(FunctionDescriptor aValue) {
return CodeInsightUtils.createFunctionSignatureStringFromDescriptor(
aValue,
/* shortTypeNames = */ true);
return SIGNATURE_RENDERER.render(aValue);
}
};
}
private static void changeSignature(final JetNamedFunction element, Project project, FunctionDescriptor signature) {
final String signatureString = CodeInsightUtils.createFunctionSignatureStringFromDescriptor(
signature,
/* shortTypeNames = */ false);
private static void changeSignature(final JetNamedFunction function, Project project, FunctionDescriptor patternDescriptor) {
final String signatureString = DescriptorRenderer.SOURCE_CODE.render(patternDescriptor);
PsiDocumentManager.getInstance(project).commitAllDocuments();
final JetPsiFactory psiFactory = JetPsiFactory(element);
final JetPsiFactory psiFactory = JetPsiFactory(project);
CommandProcessor.getInstance().executeCommand(project, new Runnable() {
@Override
public void run() {
ApplicationManager.getApplication().runWriteAction(new Runnable() {
@Override
public void run() {
JetExpression bodyExpression = element.getBodyExpression();
JetNamedFunction newElement;
JetNamedFunction patternFunction = psiFactory.createFunction(signatureString);
if (bodyExpression != null) {
if (element.hasBlockBody()) {
newElement = psiFactory.createFunction(signatureString + "{}");
}
else {
newElement = psiFactory.createFunction(signatureString + "= \"dummy\"");
}
JetExpression newBodyExpression = newElement.getBodyExpression();
assert newBodyExpression != null;
newBodyExpression.replace(bodyExpression);
JetTypeReference newTypeRef = function.setReturnTypeRef(patternFunction.getReturnTypeRef());
if (newTypeRef != null) {
ShortenReferences.INSTANCE$.process(newTypeRef);
}
else {
newElement = psiFactory.createFunction(signatureString);
}
newElement = (JetNamedFunction) element.replace(newElement);
ShortenReferences.INSTANCE$.process(newElement);
function.getValueParameterList().replace(patternFunction.getValueParameterList());
ShortenReferences.INSTANCE$.process(function.getValueParameterList());
}
});
}
@@ -43,7 +43,6 @@ import org.jetbrains.jet.lang.types.checker.JetTypeChecker;
import org.jetbrains.jet.plugin.JetBundle;
import org.jetbrains.jet.plugin.actions.JetChangeFunctionSignatureAction;
import org.jetbrains.jet.plugin.caches.resolve.ResolvePackage;
import org.jetbrains.jet.plugin.codeInsight.CodeInsightUtils;
import java.util.*;
@@ -68,17 +67,14 @@ public class ChangeMemberFunctionSignatureFix extends JetHintAction<JetNamedFunc
public String getText() {
if (possibleSignatures.size() == 1)
return JetBundle.message("change.function.signature.action.single",
getFunctionSignatureString(
possibleSignatures.get(0),
/* shortTypeNames = */ true));
getFunctionSignatureString(possibleSignatures.get(0)));
else
return JetBundle.message("change.function.signature.action.multiple");
}
@NotNull
private static String getFunctionSignatureString(@NotNull FunctionDescriptor functionSignature, boolean shortTypeNames) {
return CodeInsightUtils.createFunctionSignatureStringFromDescriptor(
functionSignature, shortTypeNames);
private static String getFunctionSignatureString(@NotNull FunctionDescriptor functionSignature) {
return JetChangeFunctionSignatureAction.SIGNATURE_RENDERER.render(functionSignature);
}
@NotNull
@@ -107,7 +103,11 @@ public class ChangeMemberFunctionSignatureFix extends JetHintAction<JetNamedFunc
* Computes all the signatures a 'functionElement' could be changed to in order to remove NOTHING_TO_OVERRIDE error.
*/
@NotNull
private static List<FunctionDescriptor> computePossibleSignatures(JetNamedFunction functionElement) {
private static List<FunctionDescriptor> computePossibleSignatures(@NotNull JetNamedFunction functionElement) {
if (functionElement.getValueParameterList() == null) { // we won't be able to modify its signature
return Collections.emptyList();
}
BindingContext context = ResolvePackage.getBindingContext(functionElement);
FunctionDescriptor functionDescriptor = context.get(BindingContext.FUNCTION, functionElement);
if (functionDescriptor == null) return Lists.newArrayList();
@@ -116,7 +116,7 @@ public class ChangeMemberFunctionSignatureFix extends JetHintAction<JetNamedFunc
for (FunctionDescriptor superFunction : superFunctions) {
if (!superFunction.getKind().isReal()) continue;
FunctionDescriptor signature = changeSignatureToMatch(functionDescriptor, superFunction);
possibleSignatures.put(getFunctionSignatureString(signature, /* shortTypeNames = */ false), signature);
possibleSignatures.put(getFunctionSignatureString(signature), signature);
}
return Lists.newArrayList(possibleSignatures.values());
}
@@ -1,4 +1,4 @@
// "Change function signature to 'public override fun f(a: Int)'" "true"
// "Change function signature to 'override fun f(a: Int)'" "true"
trait A {
fun f(a: Int)
}
@@ -0,0 +1,10 @@
// "Change function signature to 'override fun f(a: Int)'" "true"
annotation class annon
open class A {
open fun f(a: Int) {}
}
class B : A(){
annon <caret>override fun f(a: Int) {}
}
@@ -1,6 +1,6 @@
// "Change function signature to 'protected override fun next(p0: Int): Int'" "true"
// "Change function signature to 'override fun next(p0: Int): Int'" "true"
import java.util.Random
class MyRandom : Random() {
<caret>protected override fun next(p0: Int): Int = 4
<caret>override fun next(p0: Int): Int = 4
}
@@ -1,4 +1,4 @@
// "Change function signature to 'public override fun f(a: Int)'" "true"
// "Change function signature to 'override fun f(a: Int)'" "true"
trait A {
fun f(a: Int)
}
@@ -0,0 +1,10 @@
// "Change function signature to 'override fun f(a: Int)'" "true"
annotation class annon
open class A {
open fun f(a: Int) {}
}
class B : A(){
annon <caret>override fun f(a: String) {}
}
@@ -1,4 +1,4 @@
// "Change function signature to 'protected override fun next(p0: Int): Int'" "true"
// "Change function signature to 'override fun next(p0: Int): Int'" "true"
import java.util.Random
class MyRandom : Random() {
@@ -2219,6 +2219,12 @@ public class QuickFixTestGenerated extends AbstractQuickFixTest {
doTest(fileName);
}
@TestMetadata("beforeDoNotLooseAnnotations.kt")
public void testDoNotLooseAnnotations() throws Exception {
String fileName = JetTestUtils.navigationMetadata("idea/testData/quickfix/override/nothingToOverride/beforeDoNotLooseAnnotations.kt");
doTest(fileName);
}
@TestMetadata("beforeNoOpenSuperFunction.kt")
public void testNoOpenSuperFunction() throws Exception {
String fileName = JetTestUtils.navigationMetadata("idea/testData/quickfix/override/nothingToOverride/beforeNoOpenSuperFunction.kt");