Add new functionality to "Change signature" refactoring
Extract single point of entry for all change signature refactorings and fixes (remove parameter, add parameter) Change signature now affects overriding functions as well Ask the user whether he wants to refactor base function(s) or the selected one if appropiate Fix a problem with descriptorToDeclaration in JetChangeSignatureHandler Rename: JetFunctionPlatformDescriptor -> JetMethodDescriptor
This commit is contained in:
@@ -357,4 +357,35 @@ public class BindingContextUtils {
|
||||
}
|
||||
return OverridingUtil.filterOutOverridden(result);
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public static Set<FunctionDescriptor> getDirectlyOverriddenDeclarations(@NotNull FunctionDescriptor descriptor) {
|
||||
//noinspection unchecked
|
||||
return (Set) getDirectlyOverriddenDeclarations((CallableMemberDescriptor) descriptor);
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public static Set<PropertyDescriptor> getDirectlyOverriddenDeclarations(@NotNull PropertyDescriptor descriptor) {
|
||||
//noinspection unchecked
|
||||
return (Set) getDirectlyOverriddenDeclarations((CallableMemberDescriptor) descriptor);
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public static Set<FunctionDescriptor> getAllOverriddenDeclarations(@NotNull FunctionDescriptor functionDescriptor) {
|
||||
Set<FunctionDescriptor> result = Sets.newHashSet();
|
||||
for (FunctionDescriptor overriddenDeclaration : functionDescriptor.getOverriddenDescriptors()) {
|
||||
CallableMemberDescriptor.Kind kind = overriddenDeclaration.getKind();
|
||||
if (kind == DECLARATION) {
|
||||
result.add(overriddenDeclaration);
|
||||
}
|
||||
else if (kind == DELEGATION || kind == FAKE_OVERRIDE || kind == SYNTHESIZED) {
|
||||
//do nothing
|
||||
}
|
||||
else {
|
||||
throw new AssertionError("Unexpected callable kind " + kind);
|
||||
}
|
||||
result.addAll(getAllOverriddenDeclarations(overriddenDeclaration));
|
||||
}
|
||||
return result;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -16,7 +16,6 @@
|
||||
|
||||
package org.jetbrains.jet.plugin.quickfix;
|
||||
|
||||
import com.intellij.openapi.application.ApplicationManager;
|
||||
import com.intellij.openapi.editor.Editor;
|
||||
import com.intellij.openapi.project.Project;
|
||||
import com.intellij.psi.PsiElement;
|
||||
@@ -33,13 +32,13 @@ import org.jetbrains.jet.lang.types.checker.JetTypeChecker;
|
||||
import org.jetbrains.jet.plugin.JetBundle;
|
||||
import org.jetbrains.jet.plugin.project.AnalyzerFacadeWithCache;
|
||||
import org.jetbrains.jet.plugin.refactoring.JetNameValidator;
|
||||
import org.jetbrains.jet.plugin.refactoring.changeSignature.JetChangeSignatureDialog;
|
||||
import org.jetbrains.jet.plugin.refactoring.changeSignature.JetFunctionPlatformDescriptorImpl;
|
||||
import org.jetbrains.jet.plugin.refactoring.changeSignature.JetParameterInfo;
|
||||
import org.jetbrains.jet.plugin.refactoring.changeSignature.*;
|
||||
import org.jetbrains.jet.renderer.DescriptorRenderer;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import static org.jetbrains.jet.plugin.refactoring.changeSignature.ChangeSignaturePackage.runChangeSignature;
|
||||
|
||||
public class AddFunctionParametersFix extends ChangeFunctionSignatureFix {
|
||||
private final JetCallElement callElement;
|
||||
private final boolean hasTypeMismatches;
|
||||
@@ -85,45 +84,43 @@ public class AddFunctionParametersFix extends ChangeFunctionSignatureFix {
|
||||
@Override
|
||||
protected void invoke(@NotNull Project project, Editor editor, JetFile file) {
|
||||
BindingContext bindingContext = AnalyzerFacadeWithCache.analyzeFileWithCache((JetFile) callElement.getContainingFile()).getBindingContext();
|
||||
JetFunctionPlatformDescriptorImpl platformDescriptor = new JetFunctionPlatformDescriptorImpl(functionDescriptor, element);
|
||||
final List<ValueParameterDescriptor> parameters = functionDescriptor.getValueParameters();
|
||||
List<? extends ValueArgument> arguments = callElement.getValueArguments();
|
||||
JetNameValidator validator = JetNameValidator.getCollectingValidator(callElement.getProject());
|
||||
boolean performSilently = !hasTypeMismatches && !(functionDescriptor instanceof ConstructorDescriptor) && !hasOtherUsages();
|
||||
runChangeSignature(project, functionDescriptor, addParameterConfiguration(), bindingContext, callElement, getText(), performSilently);
|
||||
}
|
||||
|
||||
for (int i = 0; i < arguments.size(); i ++) {
|
||||
ValueArgument argument = arguments.get(i);
|
||||
JetExpression expression = argument.getArgumentExpression();
|
||||
|
||||
if (i < parameters.size()) {
|
||||
validator.validateName(parameters.get(i).getName().asString());
|
||||
JetType argumentType = expression != null ? bindingContext.get(BindingContext.EXPRESSION_TYPE, expression) : null;
|
||||
JetType parameterType = parameters.get(i).getType();
|
||||
|
||||
if (argumentType != null && !JetTypeChecker.INSTANCE.isSubtypeOf(argumentType, parameterType))
|
||||
platformDescriptor.getParameters().get(i).setTypeText(DescriptorRenderer.SHORT_NAMES_IN_TYPES.renderType(argumentType));
|
||||
}
|
||||
else {
|
||||
JetParameterInfo parameterInfo = getNewParameterInfo(bindingContext, argument, validator);
|
||||
|
||||
if (expression != null)
|
||||
parameterInfo.setDefaultValueText(expression.getText());
|
||||
|
||||
platformDescriptor.addParameter(parameterInfo);
|
||||
}
|
||||
}
|
||||
|
||||
JetChangeSignatureDialog dialog = new JetChangeSignatureDialog(project, platformDescriptor, callElement, getText()) {
|
||||
private JetChangeSignatureConfiguration addParameterConfiguration() {
|
||||
return new JetChangeSignatureConfiguration() {
|
||||
@Override
|
||||
protected int getSelectedIdx() {
|
||||
return parameters.size();
|
||||
public void configure(
|
||||
@NotNull JetChangeSignatureData changeSignatureData, @NotNull BindingContext bindingContext
|
||||
) {
|
||||
List<ValueParameterDescriptor> parameters = functionDescriptor.getValueParameters();
|
||||
List<? extends ValueArgument> arguments = callElement.getValueArguments();
|
||||
JetNameValidator validator = JetNameValidator.getCollectingValidator(callElement.getProject());
|
||||
|
||||
for (int i = 0; i < arguments.size(); i ++) {
|
||||
ValueArgument argument = arguments.get(i);
|
||||
JetExpression expression = argument.getArgumentExpression();
|
||||
|
||||
if (i < parameters.size()) {
|
||||
validator.validateName(parameters.get(i).getName().asString());
|
||||
JetType argumentType = expression != null ? bindingContext.get(BindingContext.EXPRESSION_TYPE, expression) : null;
|
||||
JetType parameterType = parameters.get(i).getType();
|
||||
|
||||
if (argumentType != null && !JetTypeChecker.INSTANCE.isSubtypeOf(argumentType, parameterType))
|
||||
changeSignatureData.getParameters().get(i).setTypeText(DescriptorRenderer.SHORT_NAMES_IN_TYPES.renderType(argumentType));
|
||||
}
|
||||
else {
|
||||
JetParameterInfo parameterInfo = getNewParameterInfo(bindingContext, argument, validator);
|
||||
|
||||
if (expression != null)
|
||||
parameterInfo.setDefaultValueText(expression.getText());
|
||||
|
||||
changeSignatureData.addParameter(parameterInfo);
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
if (ApplicationManager.getApplication().isUnitTestMode() ||
|
||||
!hasTypeMismatches && !(functionDescriptor instanceof ConstructorDescriptor) && !hasOtherUsages())
|
||||
performRefactoringSilently(dialog);
|
||||
else
|
||||
dialog.show();
|
||||
}
|
||||
|
||||
private boolean hasOtherUsages() {
|
||||
|
||||
@@ -22,15 +22,20 @@ import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.jet.lang.descriptors.FunctionDescriptor;
|
||||
import org.jetbrains.jet.lang.psi.JetFile;
|
||||
import org.jetbrains.jet.lang.psi.JetFunctionLiteral;
|
||||
import org.jetbrains.jet.lang.resolve.BindingContext;
|
||||
import org.jetbrains.jet.lang.types.JetType;
|
||||
import org.jetbrains.jet.plugin.JetBundle;
|
||||
import org.jetbrains.jet.plugin.project.AnalyzerFacadeWithCache;
|
||||
import org.jetbrains.jet.plugin.refactoring.JetNameSuggester;
|
||||
import org.jetbrains.jet.plugin.refactoring.JetNameValidator;
|
||||
import org.jetbrains.jet.plugin.refactoring.changeSignature.JetFunctionPlatformDescriptorImpl;
|
||||
import org.jetbrains.jet.plugin.refactoring.changeSignature.JetChangeSignatureConfiguration;
|
||||
import org.jetbrains.jet.plugin.refactoring.changeSignature.JetChangeSignatureData;
|
||||
import org.jetbrains.jet.plugin.refactoring.changeSignature.JetParameterInfo;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import static org.jetbrains.jet.plugin.refactoring.changeSignature.ChangeSignaturePackage.runChangeSignature;
|
||||
|
||||
public class ChangeFunctionLiteralSignatureFix extends ChangeFunctionSignatureFix {
|
||||
private final List<JetType> parameterTypes;
|
||||
|
||||
@@ -49,16 +54,18 @@ public class ChangeFunctionLiteralSignatureFix extends ChangeFunctionSignatureFi
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void invoke(@NotNull Project project, Editor editor, JetFile file) {
|
||||
JetFunctionPlatformDescriptorImpl platformDescriptor = new JetFunctionPlatformDescriptorImpl(functionDescriptor, element);
|
||||
JetNameValidator validator = JetNameValidator.getCollectingValidator(project);
|
||||
platformDescriptor.clearParameters();
|
||||
|
||||
for (JetType type : parameterTypes) {
|
||||
String name = JetNameSuggester.suggestNames(type, validator, "param")[0];
|
||||
platformDescriptor.addParameter(new JetParameterInfo(name, type));
|
||||
}
|
||||
|
||||
showDialog(project, platformDescriptor);
|
||||
protected void invoke(@NotNull final Project project, Editor editor, JetFile file) {
|
||||
BindingContext bindingContext = AnalyzerFacadeWithCache.analyzeFileWithCache(file).getBindingContext();
|
||||
runChangeSignature(project, functionDescriptor, new JetChangeSignatureConfiguration() {
|
||||
@Override
|
||||
public void configure(@NotNull JetChangeSignatureData changeSignatureData, @NotNull BindingContext bindingContext) {
|
||||
JetNameValidator validator = JetNameValidator.getCollectingValidator(project);
|
||||
changeSignatureData.clearParameters();
|
||||
for (JetType type : parameterTypes) {
|
||||
String name = JetNameSuggester.suggestNames(type, validator, "param")[0];
|
||||
changeSignatureData.addParameter(new JetParameterInfo(name, type));
|
||||
}
|
||||
}
|
||||
}, bindingContext, context, getText(), false);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -16,9 +16,6 @@
|
||||
|
||||
package org.jetbrains.jet.plugin.quickfix;
|
||||
|
||||
import com.intellij.openapi.application.ApplicationManager;
|
||||
import com.intellij.openapi.project.Project;
|
||||
import com.intellij.openapi.util.Disposer;
|
||||
import com.intellij.psi.PsiElement;
|
||||
import com.intellij.psi.PsiNameIdentifierOwner;
|
||||
import com.intellij.psi.util.PsiTreeUtil;
|
||||
@@ -41,12 +38,12 @@ import org.jetbrains.jet.plugin.JetBundle;
|
||||
import org.jetbrains.jet.plugin.project.AnalyzerFacadeWithCache;
|
||||
import org.jetbrains.jet.plugin.refactoring.JetNameSuggester;
|
||||
import org.jetbrains.jet.plugin.refactoring.JetNameValidator;
|
||||
import org.jetbrains.jet.plugin.refactoring.changeSignature.*;
|
||||
import org.jetbrains.jet.plugin.refactoring.changeSignature.JetParameterInfo;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
public abstract class ChangeFunctionSignatureFix extends JetIntentionAction<PsiElement> {
|
||||
private final PsiElement context;
|
||||
protected final PsiElement context;
|
||||
protected final FunctionDescriptor functionDescriptor;
|
||||
|
||||
public ChangeFunctionSignatureFix(
|
||||
@@ -70,21 +67,13 @@ public abstract class ChangeFunctionSignatureFix extends JetIntentionAction<PsiE
|
||||
return false;
|
||||
}
|
||||
|
||||
protected void showDialog(Project project, JetFunctionPlatformDescriptorImpl platformDescriptor) {
|
||||
JetChangeSignatureDialog dialog = new JetChangeSignatureDialog(project, platformDescriptor, context, getText());
|
||||
|
||||
if (ApplicationManager.getApplication().isUnitTestMode())
|
||||
performRefactoringSilently(dialog);
|
||||
else
|
||||
dialog.show();
|
||||
}
|
||||
|
||||
protected static String getNewArgumentName(ValueArgument argument, JetNameValidator validator) {
|
||||
JetValueArgumentName argumentName = argument.getArgumentName();
|
||||
JetExpression expression = argument.getArgumentExpression();
|
||||
|
||||
if (argumentName != null)
|
||||
if (argumentName != null) {
|
||||
return validator.validateName(argumentName.getName());
|
||||
}
|
||||
else if (expression != null) {
|
||||
return JetNameSuggester.suggestNames(expression, validator, "param")[0];
|
||||
}
|
||||
@@ -92,7 +81,11 @@ public abstract class ChangeFunctionSignatureFix extends JetIntentionAction<PsiE
|
||||
return validator.validateName("param");
|
||||
}
|
||||
|
||||
protected static JetParameterInfo getNewParameterInfo(BindingContext bindingContext, ValueArgument argument, JetNameValidator validator) {
|
||||
protected static JetParameterInfo getNewParameterInfo(
|
||||
BindingContext bindingContext,
|
||||
ValueArgument argument,
|
||||
JetNameValidator validator
|
||||
) {
|
||||
String name = getNewArgumentName(argument, validator);
|
||||
JetExpression expression = argument.getArgumentExpression();
|
||||
JetType type = expression != null ? bindingContext.get(BindingContext.EXPRESSION_TYPE, expression) : null;
|
||||
@@ -100,32 +93,28 @@ public abstract class ChangeFunctionSignatureFix extends JetIntentionAction<PsiE
|
||||
return new JetParameterInfo(name, type);
|
||||
}
|
||||
|
||||
private static boolean hasTypeMismatches(List<ValueParameterDescriptor> parameters, List<? extends ValueArgument> arguments, BindingContext bindingContext) {
|
||||
private static boolean hasTypeMismatches(
|
||||
List<ValueParameterDescriptor> parameters,
|
||||
List<? extends ValueArgument> arguments,
|
||||
BindingContext bindingContext
|
||||
) {
|
||||
for (int i = 0; i < parameters.size(); i++) {
|
||||
assert i < arguments.size(); // number of parameters must not be greater than the number of arguments (it's called only for TOO_MANY_ARGUMENTS error)
|
||||
assert i <
|
||||
arguments
|
||||
.size(); // number of parameters must not be greater than the number of arguments (it's called only for TOO_MANY_ARGUMENTS error)
|
||||
JetExpression argumentExpression = arguments.get(i).getArgumentExpression();
|
||||
JetType argumentType = argumentExpression != null ? bindingContext.get(BindingContext.EXPRESSION_TYPE, argumentExpression) : null;
|
||||
JetType argumentType =
|
||||
argumentExpression != null ? bindingContext.get(BindingContext.EXPRESSION_TYPE, argumentExpression) : null;
|
||||
JetType parameterType = parameters.get(i).getType();
|
||||
|
||||
if (argumentType == null || !JetTypeChecker.INSTANCE.isSubtypeOf(argumentType, parameterType))
|
||||
if (argumentType == null || !JetTypeChecker.INSTANCE.isSubtypeOf(argumentType, parameterType)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
protected void performRefactoringSilently(final JetChangeSignatureDialog dialog) {
|
||||
ApplicationManager.getApplication().runWriteAction(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
JetChangeInfo changeInfo = dialog.evaluateChangeInfo();
|
||||
JetChangeSignatureProcessor processor = new JetChangeSignatureProcessor(element.getProject(), changeInfo, getText());
|
||||
processor.run();
|
||||
Disposer.dispose(dialog.getDisposable());
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
public static JetSingleIntentionActionFactory createFactory() {
|
||||
return new JetSingleIntentionActionFactory() {
|
||||
@Override
|
||||
@@ -134,8 +123,9 @@ public abstract class ChangeFunctionSignatureFix extends JetIntentionAction<PsiE
|
||||
@SuppressWarnings("unchecked")
|
||||
CallableDescriptor descriptor = ((DiagnosticWithParameters1<PsiElement, CallableDescriptor>) diagnostic).getA();
|
||||
|
||||
if (callElement != null)
|
||||
if (callElement != null) {
|
||||
return createFix(callElement, callElement, descriptor);
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
@@ -150,13 +140,17 @@ public abstract class ChangeFunctionSignatureFix extends JetIntentionAction<PsiE
|
||||
DiagnosticWithParameters2<JetFunctionLiteral, Integer, List<JetType>> diagnosticWithParameters =
|
||||
(DiagnosticWithParameters2<JetFunctionLiteral, Integer, List<JetType>>) diagnostic;
|
||||
JetFunctionLiteral functionLiteral = diagnosticWithParameters.getPsiElement();
|
||||
BindingContext bindingContext = AnalyzerFacadeWithCache.analyzeFileWithCache((JetFile) functionLiteral.getContainingFile()).getBindingContext();
|
||||
BindingContext bindingContext =
|
||||
AnalyzerFacadeWithCache.analyzeFileWithCache((JetFile) functionLiteral.getContainingFile()).getBindingContext();
|
||||
DeclarationDescriptor descriptor = bindingContext.get(BindingContext.DECLARATION_TO_DESCRIPTOR, functionLiteral);
|
||||
|
||||
if (descriptor instanceof FunctionDescriptor)
|
||||
return new ChangeFunctionLiteralSignatureFix(functionLiteral, (FunctionDescriptor) descriptor, diagnosticWithParameters.getB());
|
||||
else
|
||||
if (descriptor instanceof FunctionDescriptor) {
|
||||
return new ChangeFunctionLiteralSignatureFix(functionLiteral, (FunctionDescriptor) descriptor,
|
||||
diagnosticWithParameters.getB());
|
||||
}
|
||||
else {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
@@ -168,10 +162,12 @@ public abstract class ChangeFunctionSignatureFix extends JetIntentionAction<PsiE
|
||||
@SuppressWarnings("unchecked")
|
||||
Object descriptor = ((DiagnosticWithParameters1<PsiNameIdentifierOwner, Object>) diagnostic).getA();
|
||||
|
||||
if (descriptor instanceof ValueParameterDescriptor)
|
||||
if (descriptor instanceof ValueParameterDescriptor) {
|
||||
return createFix(null, diagnostic.getPsiElement(), (CallableDescriptor) descriptor);
|
||||
else
|
||||
}
|
||||
else {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
@@ -180,31 +176,37 @@ public abstract class ChangeFunctionSignatureFix extends JetIntentionAction<PsiE
|
||||
private static ChangeFunctionSignatureFix createFix(JetCallElement callElement, PsiElement context, CallableDescriptor descriptor) {
|
||||
FunctionDescriptor functionDescriptor = null;
|
||||
|
||||
if (descriptor instanceof FunctionDescriptor)
|
||||
if (descriptor instanceof FunctionDescriptor) {
|
||||
functionDescriptor = (FunctionDescriptor) descriptor;
|
||||
}
|
||||
else if (descriptor instanceof ValueParameterDescriptor) {
|
||||
DeclarationDescriptor containingDescriptor = descriptor.getContainingDeclaration();
|
||||
|
||||
if (containingDescriptor instanceof FunctionDescriptor)
|
||||
if (containingDescriptor instanceof FunctionDescriptor) {
|
||||
functionDescriptor = (FunctionDescriptor) containingDescriptor;
|
||||
}
|
||||
}
|
||||
|
||||
if (functionDescriptor != null) {
|
||||
BindingContext bindingContext = AnalyzerFacadeWithCache.analyzeFileWithCache((JetFile) context.getContainingFile()).getBindingContext();
|
||||
PsiElement declaration = BindingContextUtils.descriptorToDeclaration(bindingContext, functionDescriptor);
|
||||
if (functionDescriptor == null) {
|
||||
return null;
|
||||
}
|
||||
BindingContext bindingContext =
|
||||
AnalyzerFacadeWithCache.analyzeFileWithCache((JetFile) context.getContainingFile()).getBindingContext();
|
||||
PsiElement declaration = BindingContextUtils.descriptorToDeclaration(bindingContext, functionDescriptor);
|
||||
|
||||
if (declaration != null) {
|
||||
if (descriptor instanceof ValueParameterDescriptor)
|
||||
return new RemoveFunctionParametersFix(declaration, context, functionDescriptor, (ValueParameterDescriptor) descriptor);
|
||||
else {
|
||||
List<ValueParameterDescriptor> parameters = functionDescriptor.getValueParameters();
|
||||
List<? extends ValueArgument> arguments = callElement.getValueArguments();
|
||||
if (declaration == null) {
|
||||
return null;
|
||||
}
|
||||
if (descriptor instanceof ValueParameterDescriptor) {
|
||||
return new RemoveFunctionParametersFix(declaration, context, functionDescriptor, (ValueParameterDescriptor) descriptor);
|
||||
}
|
||||
else {
|
||||
List<ValueParameterDescriptor> parameters = functionDescriptor.getValueParameters();
|
||||
List<? extends ValueArgument> arguments = callElement.getValueArguments();
|
||||
|
||||
if (arguments.size() > parameters.size()) {
|
||||
boolean hasTypeMismatches = hasTypeMismatches(parameters, arguments, bindingContext);
|
||||
return new AddFunctionParametersFix(declaration, callElement, functionDescriptor, hasTypeMismatches);
|
||||
}
|
||||
}
|
||||
if (arguments.size() > parameters.size()) {
|
||||
boolean hasTypeMismatches = hasTypeMismatches(parameters, arguments, bindingContext);
|
||||
return new AddFunctionParametersFix(declaration, callElement, functionDescriptor, hasTypeMismatches);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -23,11 +23,16 @@ import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.jet.lang.descriptors.FunctionDescriptor;
|
||||
import org.jetbrains.jet.lang.descriptors.ValueParameterDescriptor;
|
||||
import org.jetbrains.jet.lang.psi.JetFile;
|
||||
import org.jetbrains.jet.lang.resolve.BindingContext;
|
||||
import org.jetbrains.jet.plugin.JetBundle;
|
||||
import org.jetbrains.jet.plugin.refactoring.changeSignature.JetFunctionPlatformDescriptorImpl;
|
||||
import org.jetbrains.jet.plugin.project.AnalyzerFacadeWithCache;
|
||||
import org.jetbrains.jet.plugin.refactoring.changeSignature.JetChangeSignatureConfiguration;
|
||||
import org.jetbrains.jet.plugin.refactoring.changeSignature.JetChangeSignatureData;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import static org.jetbrains.jet.plugin.refactoring.changeSignature.ChangeSignaturePackage.runChangeSignature;
|
||||
|
||||
public class RemoveFunctionParametersFix extends ChangeFunctionSignatureFix {
|
||||
private final ValueParameterDescriptor parameterToRemove;
|
||||
|
||||
@@ -49,9 +54,15 @@ public class RemoveFunctionParametersFix extends ChangeFunctionSignatureFix {
|
||||
|
||||
@Override
|
||||
protected void invoke(@NotNull Project project, Editor editor, JetFile file) {
|
||||
JetFunctionPlatformDescriptorImpl platformDescriptor = new JetFunctionPlatformDescriptorImpl(functionDescriptor, element);
|
||||
List<ValueParameterDescriptor> parameters = functionDescriptor.getValueParameters();
|
||||
platformDescriptor.removeParameter(parameters.indexOf(parameterToRemove));
|
||||
showDialog(project, platformDescriptor);
|
||||
BindingContext bindingContext = AnalyzerFacadeWithCache.analyzeFileWithCache(file).getBindingContext();
|
||||
runChangeSignature(project, functionDescriptor, new JetChangeSignatureConfiguration() {
|
||||
@Override
|
||||
public void configure(
|
||||
@NotNull JetChangeSignatureData changeSignatureData, @NotNull BindingContext bindingContext
|
||||
) {
|
||||
List<ValueParameterDescriptor> parameters = functionDescriptor.getValueParameters();
|
||||
changeSignatureData.removeParameter(parameters.indexOf(parameterToRemove));
|
||||
}
|
||||
}, bindingContext, context, getText(), false);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -32,12 +32,13 @@ import org.jetbrains.jet.lang.types.lang.KotlinBuiltIns;
|
||||
import org.jetbrains.jet.lexer.JetTokens;
|
||||
import org.jetbrains.jet.plugin.JetLanguage;
|
||||
|
||||
import java.util.Collection;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
public class JetChangeInfo implements ChangeInfo {
|
||||
private final JetFunctionPlatformDescriptor oldDescriptor;
|
||||
private final JetMethodDescriptor oldDescriptor;
|
||||
private String newName;
|
||||
private final JetType newReturnType;
|
||||
private String newReturnTypeText;
|
||||
@@ -49,7 +50,7 @@ public class JetChangeInfo implements ChangeInfo {
|
||||
private Map<String, Integer> oldNameToParameterIndex;
|
||||
|
||||
public JetChangeInfo(
|
||||
JetFunctionPlatformDescriptor oldDescriptor,
|
||||
JetMethodDescriptor oldDescriptor,
|
||||
String newName,
|
||||
JetType newReturnType,
|
||||
String newReturnTypeText,
|
||||
@@ -215,7 +216,7 @@ public class JetChangeInfo implements ChangeInfo {
|
||||
return oldDescriptor.getDescriptor();
|
||||
}
|
||||
|
||||
public JetFunctionPlatformDescriptor getFunctionDescriptor() {
|
||||
public JetMethodDescriptor getFunctionDescriptor() {
|
||||
return oldDescriptor;
|
||||
}
|
||||
|
||||
@@ -259,4 +260,9 @@ public class JetChangeInfo implements ChangeInfo {
|
||||
public Language getLanguage() {
|
||||
return JetLanguage.INSTANCE;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public Collection<PsiElement> getAffectedFunctions() {
|
||||
return oldDescriptor.getAffectedFunctions();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,206 @@
|
||||
/*
|
||||
* Copyright 2010-2013 JetBrains s.r.o.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.jetbrains.jet.plugin.refactoring.changeSignature
|
||||
|
||||
import com.intellij.ide.IdeBundle
|
||||
import com.intellij.openapi.application.ApplicationManager
|
||||
import com.intellij.openapi.diagnostic.Logger
|
||||
import com.intellij.openapi.project.Project
|
||||
import com.intellij.openapi.ui.Messages
|
||||
import com.intellij.openapi.util.Disposer
|
||||
import com.intellij.psi.PsiElement
|
||||
import org.jetbrains.jet.lang.descriptors.*
|
||||
import org.jetbrains.jet.lang.resolve.BindingContext
|
||||
import org.jetbrains.jet.lang.resolve.OverridingUtil
|
||||
import org.jetbrains.jet.plugin.JetBundle
|
||||
import org.jetbrains.jet.renderer.DescriptorRenderer
|
||||
import java.util.*
|
||||
import org.jetbrains.jet.lang.descriptors.CallableMemberDescriptor.Kind.*
|
||||
import org.jetbrains.jet.lang.resolve.BindingContextUtils.*
|
||||
import org.jetbrains.annotations.TestOnly
|
||||
|
||||
public trait JetChangeSignatureConfiguration {
|
||||
fun configure(changeSignatureData: JetChangeSignatureData, bindingContext: BindingContext)
|
||||
}
|
||||
|
||||
public fun runChangeSignature(project: Project,
|
||||
functionDescriptor: FunctionDescriptor,
|
||||
configuration: JetChangeSignatureConfiguration,
|
||||
bindingContext: BindingContext,
|
||||
defaultValueContext: PsiElement,
|
||||
commandName: String? = null,
|
||||
performSilently: Boolean = false): Unit {
|
||||
JetChangeSignature(project, functionDescriptor, configuration, bindingContext, defaultValueContext, commandName, performSilently).run()
|
||||
}
|
||||
|
||||
public class JetChangeSignature(val project: Project,
|
||||
val functionDescriptor: FunctionDescriptor,
|
||||
val configuration: JetChangeSignatureConfiguration,
|
||||
val bindingContext: BindingContext,
|
||||
val defaultValueContext: PsiElement,
|
||||
val commandName: String?,
|
||||
val performSilently: Boolean) {
|
||||
|
||||
private val LOG = Logger.getInstance(javaClass<JetChangeSignature>())
|
||||
|
||||
public fun run() {
|
||||
if (functionDescriptor.getKind() == SYNTHESIZED) {
|
||||
LOG.error("Change signature refactoring should not be called for synthesized member " + functionDescriptor)
|
||||
return
|
||||
}
|
||||
|
||||
val closestModifiableDescriptors = getClosestModifiableDescriptors()
|
||||
assert(!closestModifiableDescriptors.isEmpty()) { "Should contain functionDescriptor itself or some of its super declarations" }
|
||||
val deepestSuperDeclarations = getDeepestSuperDeclarations()
|
||||
if (ApplicationManager.getApplication()!!.isUnitTestMode()) {
|
||||
showChangeSignatureDialog(deepestSuperDeclarations)
|
||||
return
|
||||
}
|
||||
|
||||
if ((closestModifiableDescriptors.size()) == 1 && deepestSuperDeclarations.equals(closestModifiableDescriptors)) {
|
||||
showChangeSignatureDialog(closestModifiableDescriptors)
|
||||
return
|
||||
}
|
||||
|
||||
val isSingleFunctionSelected = closestModifiableDescriptors.size() == 1
|
||||
val selectedFunction = if (isSingleFunctionSelected) closestModifiableDescriptors.first() else functionDescriptor
|
||||
val optionsForDialog = buildDialogOptions(isSingleFunctionSelected)
|
||||
val code = showSuperFunctionWarningDialog(deepestSuperDeclarations, selectedFunction, optionsForDialog.copyToArray())
|
||||
when {
|
||||
performForWholeHierarchy(optionsForDialog, code) -> {
|
||||
showChangeSignatureDialog(deepestSuperDeclarations)
|
||||
}
|
||||
performForSelectedFunctionOnly(optionsForDialog, code) -> {
|
||||
showChangeSignatureDialog(closestModifiableDescriptors)
|
||||
}
|
||||
else -> {
|
||||
//do nothing
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private fun getClosestModifiableDescriptors(): Set<FunctionDescriptor> {
|
||||
val kind = functionDescriptor.getKind()
|
||||
if (kind == DELEGATION || kind == FAKE_OVERRIDE) {
|
||||
return getDirectlyOverriddenDeclarations(functionDescriptor)
|
||||
}
|
||||
|
||||
assert(kind == DECLARATION) { "Unexpected callable kind: " + kind }
|
||||
return Collections.singleton(functionDescriptor)
|
||||
}
|
||||
|
||||
fun getDeepestSuperDeclarations(): Set<FunctionDescriptor> {
|
||||
val overriddenDeclarations = getAllOverriddenDeclarations(functionDescriptor)
|
||||
if (overriddenDeclarations.isEmpty()) {
|
||||
return Collections.singleton(functionDescriptor)
|
||||
}
|
||||
|
||||
return OverridingUtil.filterOutOverriding(overriddenDeclarations)
|
||||
}
|
||||
|
||||
private fun showChangeSignatureDialog(descriptorsForSignatureChange: Collection<FunctionDescriptor>) {
|
||||
val dialog = createChangeSignatureDialog(descriptorsForSignatureChange)
|
||||
if (dialog == null) {
|
||||
return
|
||||
}
|
||||
|
||||
if (performSilently || ApplicationManager.getApplication()!!.isUnitTestMode()) {
|
||||
performRefactoringSilently(dialog)
|
||||
}
|
||||
else {
|
||||
dialog.show()
|
||||
}
|
||||
}
|
||||
|
||||
fun createChangeSignatureDialog(descriptorsForSignatureChange: Collection<FunctionDescriptor>): JetChangeSignatureDialog? {
|
||||
val baseDescriptor = preferContainedInClass(descriptorsForSignatureChange)
|
||||
val functionDeclaration = callableDescriptorToDeclaration(bindingContext, baseDescriptor)
|
||||
if (functionDeclaration == null) {
|
||||
LOG.error("Could not find declaration for " + baseDescriptor)
|
||||
return null
|
||||
}
|
||||
|
||||
val changeSignatureData = JetChangeSignatureData(baseDescriptor, functionDeclaration, bindingContext, descriptorsForSignatureChange)
|
||||
configuration.configure(changeSignatureData, bindingContext)
|
||||
return JetChangeSignatureDialog(project, changeSignatureData, defaultValueContext, commandName)
|
||||
}
|
||||
|
||||
private fun performRefactoringSilently(dialog: JetChangeSignatureDialog) {
|
||||
ApplicationManager.getApplication()!!.runWriteAction {
|
||||
dialog.createRefactoringProcessor().run()
|
||||
Disposer.dispose(dialog.getDisposable()!!)
|
||||
}
|
||||
}
|
||||
|
||||
private fun preferContainedInClass(descriptorsForSignatureChange: Collection<FunctionDescriptor>): FunctionDescriptor {
|
||||
for (descriptor in descriptorsForSignatureChange) {
|
||||
val containingDeclaration = descriptor.getContainingDeclaration()
|
||||
if (containingDeclaration is ClassDescriptor && containingDeclaration.getKind() != ClassKind.TRAIT) {
|
||||
return descriptor
|
||||
}
|
||||
|
||||
}
|
||||
//choose at random
|
||||
return descriptorsForSignatureChange.first()
|
||||
}
|
||||
|
||||
private fun buildDialogOptions(isSingleFunctionSelected: Boolean): List<String> {
|
||||
val optionsForDialog = ArrayList<String>()
|
||||
optionsForDialog.add(if (isSingleFunctionSelected) Messages.YES_BUTTON else Messages.OK_BUTTON)
|
||||
if (isSingleFunctionSelected) {
|
||||
optionsForDialog.add(Messages.NO_BUTTON)
|
||||
}
|
||||
optionsForDialog.add(Messages.CANCEL_BUTTON)
|
||||
return optionsForDialog
|
||||
}
|
||||
|
||||
private fun performForWholeHierarchy(optionsForDialog: List<String>, code: Int): Boolean {
|
||||
return buttonPressed(code, optionsForDialog, Messages.YES_BUTTON) || buttonPressed(code, optionsForDialog, Messages.OK_BUTTON)
|
||||
}
|
||||
|
||||
private fun performForSelectedFunctionOnly(dialogButtons: List<String>, code: Int): Boolean {
|
||||
return buttonPressed(code, dialogButtons, Messages.NO_BUTTON)
|
||||
}
|
||||
|
||||
private fun buttonPressed(code: Int, dialogButtons: List<String>, button: String): Boolean {
|
||||
return code == dialogButtons.indexOf(button) && dialogButtons.contains(button)
|
||||
}
|
||||
|
||||
private fun showSuperFunctionWarningDialog(superFunctions: Collection<FunctionDescriptor>,
|
||||
functionFromEditor: FunctionDescriptor,
|
||||
options: Array<String>): Int {
|
||||
val superString = superFunctions.map {
|
||||
it.getContainingDeclaration().getName().asString()
|
||||
}.makeString(prefix = "\n ", separator = ",\n ", postfix = ".\n\n")
|
||||
val message = JetBundle.message("x.overrides.y.in.class.list",
|
||||
DescriptorRenderer.COMPACT.render(functionFromEditor),
|
||||
functionFromEditor.getContainingDeclaration().getName().asString(), superString,
|
||||
"refactor")
|
||||
val title = IdeBundle.message("title.warning")
|
||||
val icon = Messages.getQuestionIcon()
|
||||
return Messages.showDialog(message, title!!, options, 0, icon!!)
|
||||
}
|
||||
}
|
||||
|
||||
TestOnly public fun getChangeSignatureDialog(project: Project,
|
||||
functionDescriptor: FunctionDescriptor,
|
||||
configuration: JetChangeSignatureConfiguration,
|
||||
bindingContext: BindingContext,
|
||||
defaultValueContext: PsiElement): JetChangeSignatureDialog? {
|
||||
val jetChangeSignature = JetChangeSignature(project, functionDescriptor, configuration, bindingContext, defaultValueContext, null, true)
|
||||
return jetChangeSignature.createChangeSignatureDialog(jetChangeSignature.getDeepestSuperDeclarations())
|
||||
}
|
||||
+213
@@ -0,0 +1,213 @@
|
||||
/*
|
||||
* Copyright 2010-2013 JetBrains s.r.o.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.jetbrains.jet.plugin.refactoring.changeSignature;
|
||||
|
||||
import com.google.common.collect.Sets;
|
||||
import com.intellij.openapi.util.Condition;
|
||||
import com.intellij.psi.PsiElement;
|
||||
import com.intellij.psi.PsiMethod;
|
||||
import com.intellij.psi.search.searches.OverridingMethodsSearch;
|
||||
import com.intellij.refactoring.changeSignature.MethodDescriptor;
|
||||
import com.intellij.util.Function;
|
||||
import com.intellij.util.containers.ContainerUtil;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
import org.jetbrains.jet.asJava.LightClassUtil;
|
||||
import org.jetbrains.jet.lang.descriptors.*;
|
||||
import org.jetbrains.jet.lang.descriptors.impl.AnonymousFunctionDescriptor;
|
||||
import org.jetbrains.jet.lang.psi.*;
|
||||
import org.jetbrains.jet.lang.resolve.BindingContext;
|
||||
import org.jetbrains.jet.lang.resolve.BindingContextUtils;
|
||||
import org.jetbrains.jet.lang.resolve.java.jetAsJava.JetClsMethod;
|
||||
import org.jetbrains.jet.lang.types.JetType;
|
||||
import org.jetbrains.jet.renderer.DescriptorRenderer;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
|
||||
public final class JetChangeSignatureData implements JetMethodDescriptor {
|
||||
@NotNull
|
||||
private final FunctionDescriptor baseDescriptor;
|
||||
@NotNull
|
||||
private final PsiElement baseDeclaration;
|
||||
@NotNull
|
||||
private final List<JetParameterInfo> parameters;
|
||||
@NotNull
|
||||
private final BindingContext bindingContext;
|
||||
@NotNull
|
||||
private final Collection<FunctionDescriptor> descriptorsForSignatureChange;
|
||||
|
||||
public JetChangeSignatureData(
|
||||
@NotNull FunctionDescriptor baseDescriptor,
|
||||
@NotNull PsiElement baseDeclaration,
|
||||
@NotNull BindingContext bindingContext,
|
||||
@NotNull Collection<FunctionDescriptor> descriptorsForSignatureChange
|
||||
) {
|
||||
this.baseDescriptor = baseDescriptor;
|
||||
this.baseDeclaration = baseDeclaration;
|
||||
this.bindingContext = bindingContext;
|
||||
this.descriptorsForSignatureChange = descriptorsForSignatureChange;
|
||||
final List<JetParameter> valueParameters = this.baseDeclaration instanceof JetFunction
|
||||
? ((JetFunction) this.baseDeclaration).getValueParameters()
|
||||
: ((JetClass) this.baseDeclaration).getPrimaryConstructorParameters();
|
||||
this.parameters = new ArrayList<JetParameterInfo>(
|
||||
ContainerUtil.map(this.baseDescriptor.getValueParameters(), new Function<ValueParameterDescriptor, JetParameterInfo>() {
|
||||
@Override
|
||||
public JetParameterInfo fun(ValueParameterDescriptor param) {
|
||||
JetParameter parameter = valueParameters.get(param.getIndex());
|
||||
return new JetParameterInfo(param.getIndex(), param.getName().asString(), param.getType(),
|
||||
parameter.getDefaultValue(), parameter.getValOrVarNode());
|
||||
}
|
||||
}));
|
||||
}
|
||||
|
||||
@Override
|
||||
@NotNull
|
||||
public List<JetParameterInfo> getParameters() {
|
||||
return parameters;
|
||||
}
|
||||
|
||||
public void addParameter(JetParameterInfo parameter) {
|
||||
parameters.add(parameter);
|
||||
}
|
||||
|
||||
public void removeParameter(int index) {
|
||||
parameters.remove(index);
|
||||
}
|
||||
|
||||
public void clearParameters() {
|
||||
parameters.clear();
|
||||
}
|
||||
|
||||
@Override
|
||||
@NotNull
|
||||
public Collection<PsiElement> getAffectedFunctions() {
|
||||
Set<PsiElement> result = Sets.newHashSet();
|
||||
for (FunctionDescriptor descriptor : descriptorsForSignatureChange) {
|
||||
result.addAll(computeHierarchyFrom(descriptor));
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
private Collection<PsiElement> computeHierarchyFrom(@NotNull FunctionDescriptor baseDescriptor) {
|
||||
PsiElement declaration = BindingContextUtils.callableDescriptorToDeclaration(bindingContext, baseDescriptor);
|
||||
Set<PsiElement> result = Sets.newHashSet();
|
||||
result.add(declaration);
|
||||
if (!(declaration instanceof JetNamedFunction)) {
|
||||
return result;
|
||||
}
|
||||
PsiMethod lightMethod = LightClassUtil.getLightClassMethod((JetNamedFunction) declaration);
|
||||
// there are valid situations when light method is null: local functions and literals
|
||||
if (lightMethod == null) {
|
||||
return result;
|
||||
}
|
||||
Collection<PsiMethod> overridingMethods = OverridingMethodsSearch.search(lightMethod).findAll();
|
||||
List<PsiMethod> jetLightMethods = ContainerUtil.filter(overridingMethods, new Condition<PsiMethod>() {
|
||||
@Override
|
||||
public boolean value(PsiMethod method) {
|
||||
return method instanceof JetClsMethod;
|
||||
}
|
||||
});
|
||||
List<JetDeclaration> jetFunctions = ContainerUtil.map(jetLightMethods, new Function<PsiMethod, JetDeclaration>() {
|
||||
@Override
|
||||
public JetDeclaration fun(PsiMethod method) {
|
||||
return ((JetClsMethod) method).getOrigin();
|
||||
}
|
||||
});
|
||||
result.addAll(jetFunctions);
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public String getName() {
|
||||
if (baseDescriptor instanceof ConstructorDescriptor) {
|
||||
return baseDescriptor.getContainingDeclaration().getName().asString();
|
||||
}
|
||||
else if (baseDescriptor instanceof AnonymousFunctionDescriptor) {
|
||||
return "";
|
||||
}
|
||||
else {
|
||||
return baseDescriptor.getName().asString();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getParametersCount() {
|
||||
return baseDescriptor.getValueParameters().size();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Visibility getVisibility() {
|
||||
return baseDescriptor.getVisibility();
|
||||
}
|
||||
|
||||
@Override
|
||||
public PsiElement getMethod() {
|
||||
return baseDeclaration;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean canChangeVisibility() {
|
||||
DeclarationDescriptor parent = baseDescriptor.getContainingDeclaration();
|
||||
return !(baseDescriptor instanceof AnonymousFunctionDescriptor ||
|
||||
parent instanceof ClassDescriptor && ((ClassDescriptor) parent).getKind() == ClassKind.TRAIT);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean canChangeParameters() {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean canChangeName() {
|
||||
return !(baseDescriptor instanceof ConstructorDescriptor ||
|
||||
baseDescriptor instanceof AnonymousFunctionDescriptor);
|
||||
}
|
||||
|
||||
@Override
|
||||
public MethodDescriptor.ReadWriteOption canChangeReturnType() {
|
||||
return baseDescriptor instanceof ConstructorDescriptor ? ReadWriteOption.None : ReadWriteOption.ReadWrite;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isConstructor() {
|
||||
return baseDescriptor instanceof ConstructorDescriptor;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
public PsiElement getContext() {
|
||||
return baseDeclaration;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
@Override
|
||||
public FunctionDescriptor getDescriptor() {
|
||||
return baseDescriptor;
|
||||
}
|
||||
|
||||
@Override
|
||||
@Nullable
|
||||
public String getReturnTypeText() {
|
||||
JetType returnType = baseDescriptor.getReturnType();
|
||||
return returnType != null ? DescriptorRenderer.SHORT_NAMES_IN_TYPES.renderType(returnType) : null;
|
||||
}
|
||||
}
|
||||
+7
-9
@@ -71,7 +71,7 @@ public class JetChangeSignatureDialog extends ChangeSignatureDialogBase<
|
||||
JetParameterInfo,
|
||||
PsiElement,
|
||||
Visibility,
|
||||
JetFunctionPlatformDescriptor,
|
||||
JetMethodDescriptor,
|
||||
ParameterTableModelItemBase<JetParameterInfo>,
|
||||
JetFunctionParameterTableModel
|
||||
>
|
||||
@@ -79,12 +79,8 @@ public class JetChangeSignatureDialog extends ChangeSignatureDialogBase<
|
||||
private final JetGeneratedInfo generatedInfo = new JetGeneratedInfo();
|
||||
private final String commandName;
|
||||
|
||||
public JetChangeSignatureDialog(Project project, JetFunctionPlatformDescriptor descriptor, PsiElement context) {
|
||||
this(project, descriptor, context, null);
|
||||
}
|
||||
|
||||
public JetChangeSignatureDialog(Project project, JetFunctionPlatformDescriptor descriptor, PsiElement context, String commandName) {
|
||||
super(project, descriptor, false, context);
|
||||
public JetChangeSignatureDialog(Project project, @NotNull JetMethodDescriptor methodDescriptor, PsiElement context, String commandName) {
|
||||
super(project, methodDescriptor, false, context);
|
||||
this.commandName = commandName;
|
||||
}
|
||||
|
||||
@@ -94,7 +90,7 @@ public class JetChangeSignatureDialog extends ChangeSignatureDialogBase<
|
||||
}
|
||||
|
||||
@Override
|
||||
protected JetFunctionParameterTableModel createParametersInfoModel(JetFunctionPlatformDescriptor descriptor) {
|
||||
protected JetFunctionParameterTableModel createParametersInfoModel(JetMethodDescriptor descriptor) {
|
||||
if (descriptor.isConstructor())
|
||||
return new JetConstructorParameterTableModel(myDefaultValueContext);
|
||||
else
|
||||
@@ -399,6 +395,7 @@ public class JetChangeSignatureDialog extends ChangeSignatureDialogBase<
|
||||
}
|
||||
|
||||
@Override
|
||||
@NotNull
|
||||
protected BaseRefactoringProcessor createRefactoringProcessor() {
|
||||
return new JetChangeSignatureProcessor(myProject, evaluateChangeInfo(), commandName != null ? commandName : getTitle());
|
||||
}
|
||||
@@ -414,6 +411,7 @@ public class JetChangeSignatureDialog extends ChangeSignatureDialogBase<
|
||||
|
||||
String returnTypeText = myReturnTypeCodeFragment != null ? myReturnTypeCodeFragment.getText().trim() : "";
|
||||
return new JetChangeInfo(myMethod, getMethodName(), getReturnType(), returnTypeText,
|
||||
getVisibility(), parameters, myDefaultValueContext, generatedInfo);
|
||||
getVisibility(), parameters, myDefaultValueContext, generatedInfo
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
+89
-49
@@ -31,27 +31,21 @@ import com.intellij.refactoring.changeSignature.ChangeSignatureHandler;
|
||||
import com.intellij.refactoring.util.CommonRefactoringUtil;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
import org.jetbrains.annotations.TestOnly;
|
||||
import org.jetbrains.jet.lang.descriptors.ClassDescriptor;
|
||||
import org.jetbrains.jet.lang.descriptors.DeclarationDescriptor;
|
||||
import org.jetbrains.jet.lang.descriptors.FunctionDescriptor;
|
||||
import org.jetbrains.jet.lang.descriptors.ValueParameterDescriptor;
|
||||
import org.jetbrains.jet.lang.descriptors.impl.FunctionDescriptorImpl;
|
||||
import org.jetbrains.jet.lang.psi.*;
|
||||
import org.jetbrains.jet.lang.resolve.BindingContext;
|
||||
import org.jetbrains.jet.lang.resolve.BindingContextUtils;
|
||||
import org.jetbrains.jet.plugin.project.AnalyzerFacadeWithCache;
|
||||
import org.jetbrains.jet.plugin.refactoring.JetRefactoringBundle;
|
||||
|
||||
import static org.jetbrains.jet.plugin.refactoring.changeSignature.ChangeSignaturePackage.runChangeSignature;
|
||||
|
||||
public class JetChangeSignatureHandler implements ChangeSignatureHandler {
|
||||
@Nullable
|
||||
@Override
|
||||
public PsiElement findTargetMember(PsiFile file, Editor editor) {
|
||||
return findTargetMember(file.findElementAt(editor.getCaretModel().getOffset()));
|
||||
}
|
||||
|
||||
@Nullable
|
||||
@Override
|
||||
public PsiElement findTargetMember(PsiElement element) {
|
||||
public static PsiElement findTargetForRefactoring(@NotNull PsiElement element) {
|
||||
if (PsiTreeUtil.getParentOfType(element, JetParameterList.class) != null) {
|
||||
return PsiTreeUtil.getParentOfType(element, JetFunction.class, JetClass.class);
|
||||
}
|
||||
@@ -62,35 +56,77 @@ public class JetChangeSignatureHandler implements ChangeSignatureHandler {
|
||||
}
|
||||
|
||||
PsiElement elementParent = element.getParent();
|
||||
if (elementParent instanceof JetNamedFunction && ((JetNamedFunction)elementParent).getNameIdentifier()==element) {
|
||||
if (elementParent instanceof JetNamedFunction && ((JetNamedFunction) elementParent).getNameIdentifier() == element) {
|
||||
return elementParent;
|
||||
}
|
||||
if (elementParent instanceof JetClass && ((JetClass)elementParent).getNameIdentifier()==element) {
|
||||
if (elementParent instanceof JetClass && ((JetClass) elementParent).getNameIdentifier() == element) {
|
||||
return elementParent;
|
||||
}
|
||||
|
||||
JetCallElement call = PsiTreeUtil.getParentOfType(element, JetCallExpression.class, JetDelegatorToSuperCall.class);
|
||||
if (call != null) {
|
||||
JetExpression receiverExpr = call instanceof JetCallExpression ? call.getCalleeExpression() :
|
||||
((JetDelegatorToSuperCall)call).getCalleeExpression().getConstructorReferenceExpression();
|
||||
if (call == null) {
|
||||
return null;
|
||||
}
|
||||
JetExpression receiverExpr = call instanceof JetCallExpression ? call.getCalleeExpression() :
|
||||
((JetDelegatorToSuperCall) call).getCalleeExpression().getConstructorReferenceExpression();
|
||||
|
||||
if (receiverExpr instanceof JetSimpleNameExpression) {
|
||||
BindingContext bindingContext = AnalyzerFacadeWithCache.analyzeFileWithCache((JetFile) element.getContainingFile()).getBindingContext();
|
||||
DeclarationDescriptor descriptor = bindingContext.get(BindingContext.REFERENCE_TARGET, (JetSimpleNameExpression) receiverExpr);
|
||||
if (receiverExpr instanceof JetSimpleNameExpression) {
|
||||
BindingContext bindingContext =
|
||||
AnalyzerFacadeWithCache.analyzeFileWithCache((JetFile) element.getContainingFile()).getBindingContext();
|
||||
DeclarationDescriptor descriptor =
|
||||
bindingContext.get(BindingContext.REFERENCE_TARGET, (JetSimpleNameExpression) receiverExpr);
|
||||
|
||||
if (descriptor != null) {
|
||||
PsiElement declaration = BindingContextUtils.descriptorToDeclaration(bindingContext, descriptor);
|
||||
|
||||
if (declaration instanceof JetNamedFunction || declaration instanceof JetClass) {
|
||||
return declaration;
|
||||
}
|
||||
}
|
||||
if (descriptor instanceof ClassDescriptor || descriptor instanceof FunctionDescriptor) {
|
||||
return receiverExpr;
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
public static void invokeChangeSignature(
|
||||
@NotNull PsiElement element,
|
||||
@NotNull PsiElement context,
|
||||
@NotNull Project project,
|
||||
@Nullable Editor editor
|
||||
) {
|
||||
BindingContext bindingContext =
|
||||
AnalyzerFacadeWithCache.analyzeFileWithCache((JetFile) element.getContainingFile()).getBindingContext();
|
||||
FunctionDescriptor functionDescriptor = findDescriptor(element, project, editor, bindingContext);
|
||||
if (functionDescriptor == null) {
|
||||
return;
|
||||
}
|
||||
runChangeSignature(project, functionDescriptor, emptyConfiguration(), bindingContext, context, null, false);
|
||||
}
|
||||
|
||||
@TestOnly
|
||||
public static JetChangeSignatureConfiguration getConfiguration() {
|
||||
return emptyConfiguration();
|
||||
}
|
||||
|
||||
private static JetChangeSignatureConfiguration emptyConfiguration() {
|
||||
return new JetChangeSignatureConfiguration() {
|
||||
@Override
|
||||
public void configure(
|
||||
@NotNull JetChangeSignatureData changeSignatureData, @NotNull BindingContext bindingContext
|
||||
) {
|
||||
//do nothing
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
@Nullable
|
||||
@Override
|
||||
public PsiElement findTargetMember(PsiFile file, Editor editor) {
|
||||
return findTargetMember(file.findElementAt(editor.getCaretModel().getOffset()));
|
||||
}
|
||||
|
||||
@Nullable
|
||||
@Override
|
||||
public PsiElement findTargetMember(PsiElement element) {
|
||||
return findTargetForRefactoring(element);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void invoke(@NotNull Project project, Editor editor, PsiFile file, DataContext dataContext) {
|
||||
editor.getScrollingModel().scrollToCaret(ScrollType.MAKE_VISIBLE);
|
||||
@@ -99,12 +135,9 @@ public class JetChangeSignatureHandler implements ChangeSignatureHandler {
|
||||
element = LangDataKeys.PSI_ELEMENT.getData(dataContext);
|
||||
}
|
||||
|
||||
if (element != null) {
|
||||
JetChangeSignatureDialog dialog = createDialog(element, file.findElementAt(editor.getCaretModel().getOffset()), project, editor);
|
||||
|
||||
if (dialog != null) {
|
||||
dialog.show();
|
||||
}
|
||||
PsiElement elementAtCaret = file.findElementAt(editor.getCaretModel().getOffset());
|
||||
if (element != null && elementAtCaret != null) {
|
||||
invokeChangeSignature(element, elementAtCaret, project, editor);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -112,32 +145,45 @@ public class JetChangeSignatureHandler implements ChangeSignatureHandler {
|
||||
public void invoke(@NotNull Project project, @NotNull PsiElement[] elements, @Nullable DataContext dataContext) {
|
||||
if (elements.length != 1) return;
|
||||
Editor editor = dataContext != null ? PlatformDataKeys.EDITOR.getData(dataContext) : null;
|
||||
JetChangeSignatureDialog dialog = createDialog(elements[0], elements[0], project, editor);
|
||||
|
||||
if (dialog != null) {
|
||||
dialog.show();
|
||||
}
|
||||
invokeChangeSignature(elements[0], elements[0], project, editor);
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public static JetChangeSignatureDialog createDialog(@NotNull PsiElement element, PsiElement context, Project project, Editor editor) {
|
||||
if (!CommonRefactoringUtil.checkReadOnlyStatus(project, element)) return null;
|
||||
BindingContext bindingContext = AnalyzerFacadeWithCache.analyzeFileWithCache((JetFile)element.getContainingFile()).getBindingContext();
|
||||
DeclarationDescriptor descriptor = bindingContext.get(BindingContext.DECLARATION_TO_DESCRIPTOR, element);
|
||||
@Override
|
||||
public String getTargetNotFoundMessage() {
|
||||
return JetRefactoringBundle.message("error.wrong.caret.position.function.or.constructor.name");
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public static FunctionDescriptor findDescriptor(
|
||||
@NotNull PsiElement element,
|
||||
@NotNull Project project,
|
||||
@Nullable Editor editor,
|
||||
BindingContext bindingContext
|
||||
) {
|
||||
if (!CommonRefactoringUtil.checkReadOnlyStatus(project, element)) return null;
|
||||
|
||||
DeclarationDescriptor descriptor;
|
||||
if (element instanceof JetSimpleNameExpression) {
|
||||
descriptor = bindingContext.get(BindingContext.REFERENCE_TARGET, (JetReferenceExpression) element);
|
||||
} else {
|
||||
descriptor = bindingContext.get(BindingContext.DECLARATION_TO_DESCRIPTOR, element);
|
||||
}
|
||||
if (descriptor instanceof ClassDescriptor) {
|
||||
descriptor = ((ClassDescriptor) descriptor).getUnsubstitutedPrimaryConstructor();
|
||||
}
|
||||
if (descriptor instanceof FunctionDescriptorImpl) {
|
||||
if (descriptor instanceof FunctionDescriptor) {
|
||||
for (ValueParameterDescriptor parameter : ((FunctionDescriptor) descriptor).getValueParameters()) {
|
||||
if (parameter.getVarargElementType() != null) {
|
||||
String message = JetRefactoringBundle.message("error.cant.refactor.vararg.functions");
|
||||
CommonRefactoringUtil.showErrorHint(project, editor, message, REFACTORING_NAME, HelpID.CHANGE_SIGNATURE);
|
||||
CommonRefactoringUtil.showErrorHint(project, editor, message,
|
||||
REFACTORING_NAME,
|
||||
HelpID.CHANGE_SIGNATURE);
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
return new JetChangeSignatureDialog(project, new JetFunctionPlatformDescriptorImpl((FunctionDescriptor) descriptor, element), context);
|
||||
return (FunctionDescriptor) descriptor;
|
||||
}
|
||||
else {
|
||||
String message = RefactoringBundle.getCannotRefactorMessage(JetRefactoringBundle.message(
|
||||
@@ -146,10 +192,4 @@ public class JetChangeSignatureHandler implements ChangeSignatureHandler {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
@Nullable
|
||||
@Override
|
||||
public String getTargetNotFoundMessage() {
|
||||
return JetRefactoringBundle.message("error.wrong.caret.position.function.or.constructor.name");
|
||||
}
|
||||
}
|
||||
|
||||
+3
-6
@@ -66,12 +66,9 @@ public class JetChangeSignatureUsageProcessor implements ChangeSignatureUsagePro
|
||||
}
|
||||
|
||||
private static void findAllMethodUsages(JetChangeInfo changeInfo, Set<UsageInfo> result) {
|
||||
PsiElement method = changeInfo.getMethod();
|
||||
|
||||
if (method != null)
|
||||
findOneMethodUsages(method, changeInfo, result, false);
|
||||
|
||||
//TODO overridden methods, tests for different parameter names in overridden methods
|
||||
for (PsiElement affectedFunction : changeInfo.getAffectedFunctions()) {
|
||||
findOneMethodUsages(affectedFunction, changeInfo, result, false);
|
||||
}
|
||||
}
|
||||
|
||||
private static void findOneMethodUsages(@NotNull PsiElement functionPsi, JetChangeInfo changeInfo,
|
||||
|
||||
-140
@@ -1,140 +0,0 @@
|
||||
/*
|
||||
* Copyright 2010-2013 JetBrains s.r.o.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.jetbrains.jet.plugin.refactoring.changeSignature;
|
||||
|
||||
import com.intellij.psi.PsiElement;
|
||||
import com.intellij.util.Function;
|
||||
import com.intellij.util.containers.ContainerUtil;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
import org.jetbrains.jet.lang.descriptors.*;
|
||||
import org.jetbrains.jet.lang.descriptors.impl.AnonymousFunctionDescriptor;
|
||||
import org.jetbrains.jet.lang.psi.JetClass;
|
||||
import org.jetbrains.jet.lang.psi.JetFunction;
|
||||
import org.jetbrains.jet.lang.psi.JetParameter;
|
||||
import org.jetbrains.jet.lang.types.JetType;
|
||||
import org.jetbrains.jet.renderer.DescriptorRenderer;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
public class JetFunctionPlatformDescriptorImpl implements JetFunctionPlatformDescriptor {
|
||||
private final FunctionDescriptor funDescriptor;
|
||||
private final PsiElement funElement;
|
||||
private final List<JetParameterInfo> parameters;
|
||||
|
||||
public JetFunctionPlatformDescriptorImpl(FunctionDescriptor descriptor, PsiElement element) {
|
||||
funDescriptor = descriptor;
|
||||
funElement = element;
|
||||
final List<JetParameter> valueParameters = funElement instanceof JetFunction
|
||||
? ((JetFunction) funElement).getValueParameters()
|
||||
: ((JetClass) funElement).getPrimaryConstructorParameters();
|
||||
parameters = new ArrayList<JetParameterInfo>(ContainerUtil.map(funDescriptor.getValueParameters(), new Function<ValueParameterDescriptor, JetParameterInfo>() {
|
||||
@Override
|
||||
public JetParameterInfo fun(ValueParameterDescriptor param) {
|
||||
JetParameter parameter = valueParameters.get(param.getIndex());
|
||||
return new JetParameterInfo(param.getIndex(), param.getName().asString(), param.getType(), parameter.getDefaultValue(), parameter.getValOrVarNode());
|
||||
}
|
||||
}));
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getName() {
|
||||
if (funDescriptor instanceof ConstructorDescriptor)
|
||||
return funDescriptor.getContainingDeclaration().getName().asString();
|
||||
else if (funDescriptor instanceof AnonymousFunctionDescriptor)
|
||||
return "";
|
||||
else
|
||||
return funDescriptor.getName().asString();
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<JetParameterInfo> getParameters() {
|
||||
return parameters;
|
||||
}
|
||||
|
||||
public void addParameter(JetParameterInfo parameter) {
|
||||
parameters.add(parameter);
|
||||
}
|
||||
|
||||
public void removeParameter(int index) {
|
||||
parameters.remove(index);
|
||||
}
|
||||
|
||||
public void clearParameters() {
|
||||
parameters.clear();
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getParametersCount() {
|
||||
return funDescriptor.getValueParameters().size();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Visibility getVisibility() {
|
||||
return funDescriptor.getVisibility();
|
||||
}
|
||||
|
||||
@Override
|
||||
public PsiElement getMethod() {
|
||||
return funElement;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
public PsiElement getContext() {
|
||||
return funElement;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isConstructor() {
|
||||
return funDescriptor instanceof ConstructorDescriptor;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean canChangeVisibility() {
|
||||
DeclarationDescriptor parent = funDescriptor.getContainingDeclaration();
|
||||
return !(funDescriptor instanceof AnonymousFunctionDescriptor || parent instanceof ClassDescriptor && ((ClassDescriptor) parent).getKind() == ClassKind.TRAIT);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean canChangeParameters() {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean canChangeName() {
|
||||
return !(funDescriptor instanceof ConstructorDescriptor || funDescriptor instanceof AnonymousFunctionDescriptor);
|
||||
}
|
||||
|
||||
@Override
|
||||
public ReadWriteOption canChangeReturnType() {
|
||||
return isConstructor() ? ReadWriteOption.None : ReadWriteOption.ReadWrite;
|
||||
}
|
||||
|
||||
@Override
|
||||
public FunctionDescriptor getDescriptor() {
|
||||
return funDescriptor;
|
||||
}
|
||||
|
||||
@Override
|
||||
@Nullable
|
||||
public String getReturnTypeText() {
|
||||
JetType returnType = funDescriptor.getReturnType();
|
||||
return returnType != null ? DescriptorRenderer.SHORT_NAMES_IN_TYPES.renderType(returnType) : null;
|
||||
}
|
||||
}
|
||||
+6
-1
@@ -23,7 +23,12 @@ import org.jetbrains.annotations.Nullable;
|
||||
import org.jetbrains.jet.lang.descriptors.FunctionDescriptor;
|
||||
import org.jetbrains.jet.lang.descriptors.Visibility;
|
||||
|
||||
public interface JetFunctionPlatformDescriptor extends MethodDescriptor<JetParameterInfo, Visibility> {
|
||||
import java.util.Collection;
|
||||
|
||||
public interface JetMethodDescriptor extends MethodDescriptor<JetParameterInfo, Visibility> {
|
||||
@NotNull
|
||||
Collection<PsiElement> getAffectedFunctions();
|
||||
|
||||
boolean isConstructor();
|
||||
|
||||
@Nullable
|
||||
@@ -76,7 +76,7 @@ public class JetParameterInfo implements ParameterInfo {
|
||||
return name;
|
||||
}
|
||||
|
||||
public String getInheritedName(boolean isInherited, @Nullable PsiElement inheritedFunction, @NotNull JetFunctionPlatformDescriptor baseFunction) {
|
||||
public String getInheritedName(boolean isInherited, @Nullable PsiElement inheritedFunction, @NotNull JetMethodDescriptor baseFunction) {
|
||||
if (!(inheritedFunction instanceof JetFunction))
|
||||
return name;
|
||||
|
||||
@@ -165,7 +165,7 @@ public class JetParameterInfo implements ParameterInfo {
|
||||
this.valOrVar = valOrVar;
|
||||
}
|
||||
|
||||
public String getDeclarationSignature(boolean isInherited, PsiElement inheritedFunction, JetFunctionPlatformDescriptor baseFunction) {
|
||||
public String getDeclarationSignature(boolean isInherited, PsiElement inheritedFunction, JetMethodDescriptor baseFunction) {
|
||||
StringBuilder buffer = new StringBuilder();
|
||||
JetValVar valVar = getValOrVar();
|
||||
|
||||
|
||||
@@ -0,0 +1,65 @@
|
||||
// "Add parameter to function 'f'" "true"
|
||||
trait OA {
|
||||
fun f(a: Int,
|
||||
i: Int)
|
||||
}
|
||||
|
||||
trait OB {
|
||||
fun f(a: Int,
|
||||
i: Int)
|
||||
}
|
||||
|
||||
trait O : OA, OB {
|
||||
override fun f(a: Int,
|
||||
i: Int)
|
||||
}
|
||||
|
||||
trait OO : O {
|
||||
override fun f(a: Int,
|
||||
i: Int) {
|
||||
}
|
||||
}
|
||||
|
||||
trait OOO : OO {
|
||||
override fun f(a: Int,
|
||||
i: Int) {}
|
||||
}
|
||||
|
||||
trait OOOA : OOO {
|
||||
override fun f(a: Int,
|
||||
i: Int) {
|
||||
}
|
||||
}
|
||||
|
||||
trait OOOB : OOO {
|
||||
override fun f(a: Int,
|
||||
i: Int) {
|
||||
}
|
||||
}
|
||||
|
||||
fun usage(o: OA) {
|
||||
o.f(1, 12)
|
||||
}
|
||||
fun usage(o: OB) {
|
||||
o.f(1, 12)
|
||||
}
|
||||
|
||||
fun usage(o: O) {
|
||||
o.f(1, 12)
|
||||
}
|
||||
|
||||
fun usage(o: OO) {
|
||||
o.f(13, 12)
|
||||
}
|
||||
|
||||
fun usage(o: OOO) {
|
||||
o.f(3, 12)
|
||||
}
|
||||
|
||||
fun usage(o: OOOA) {
|
||||
o.f(3, 12)
|
||||
}
|
||||
|
||||
fun usage(o: OOOB) {
|
||||
o.f(3, 12)
|
||||
}
|
||||
@@ -0,0 +1,58 @@
|
||||
// "Remove parameter 'a'" "true"
|
||||
trait OA {
|
||||
fun f()
|
||||
}
|
||||
|
||||
trait OB {
|
||||
fun f(a: Int)
|
||||
}
|
||||
|
||||
trait O : OA, OB {
|
||||
override fun f()
|
||||
}
|
||||
|
||||
trait OO : O {
|
||||
override fun f() {
|
||||
}
|
||||
}
|
||||
|
||||
trait OOO : OO {
|
||||
override fun f() {}
|
||||
}
|
||||
|
||||
trait OOOA : OOO {
|
||||
override fun f() {
|
||||
}
|
||||
}
|
||||
|
||||
trait OOOB : OOO {
|
||||
override fun f() {
|
||||
}
|
||||
}
|
||||
|
||||
fun usage(o: OA) {
|
||||
o.f()
|
||||
}
|
||||
fun usage(o: OB) {
|
||||
o.f(1)
|
||||
}
|
||||
|
||||
fun usage(o: O) {
|
||||
o.f()
|
||||
}
|
||||
|
||||
fun usage(o: OO) {
|
||||
o.f()
|
||||
}
|
||||
|
||||
fun usage(o: OOO) {
|
||||
o.f()
|
||||
}
|
||||
|
||||
fun usage(o: OOOA) {
|
||||
o.f()
|
||||
}
|
||||
|
||||
fun usage(o: OOOB) {
|
||||
o.f()
|
||||
}
|
||||
@@ -0,0 +1,65 @@
|
||||
// "Add parameter to function 'f'" "true"
|
||||
trait OA {
|
||||
fun f(a: Int,
|
||||
s: String)
|
||||
}
|
||||
|
||||
trait OB {
|
||||
fun f(a: Int,
|
||||
s: String)
|
||||
}
|
||||
|
||||
trait O : OA, OB {
|
||||
override fun f(a: Int,
|
||||
s: String)
|
||||
}
|
||||
|
||||
trait OO : O {
|
||||
override fun f(a: Int,
|
||||
s: String) {
|
||||
}
|
||||
}
|
||||
|
||||
trait OOO : OO {
|
||||
override fun f(a: Int,
|
||||
s: String) {}
|
||||
}
|
||||
|
||||
trait OOOA : OOO {
|
||||
override fun f(a: Int,
|
||||
s: String) {
|
||||
}
|
||||
}
|
||||
|
||||
trait OOOB : OOO {
|
||||
override fun f(a: Int,
|
||||
s: String) {
|
||||
}
|
||||
}
|
||||
|
||||
fun usage(o: OA) {
|
||||
o.f(1, "asdv")
|
||||
}
|
||||
fun usage(o: OB) {
|
||||
o.f(1, "asdv")
|
||||
}
|
||||
|
||||
fun usage(o: O) {
|
||||
o.f(1, "asdv")
|
||||
}
|
||||
|
||||
fun usage(o: OO) {
|
||||
o.f(13, "asdv")
|
||||
}
|
||||
|
||||
fun usage(o: OOO) {
|
||||
o.f(3, "asdv")
|
||||
}
|
||||
|
||||
fun usage(o: OOOA) {
|
||||
o.f(3, "asdv")
|
||||
}
|
||||
|
||||
fun usage(o: OOOB) {
|
||||
o.f(3, "asdv")
|
||||
}
|
||||
@@ -0,0 +1,28 @@
|
||||
// "Add parameter to function 'f'" "true"
|
||||
trait O {
|
||||
fun f(a: Int,
|
||||
i: Int)
|
||||
}
|
||||
|
||||
trait OO : O {
|
||||
override fun f(a: Int,
|
||||
i: Int) {
|
||||
}
|
||||
}
|
||||
|
||||
trait OOO : OO {
|
||||
override fun f(a: Int,
|
||||
i: Int) {}
|
||||
}
|
||||
|
||||
fun usage(o: O) {
|
||||
o.f(1, 12)
|
||||
}
|
||||
|
||||
fun usage(o: OO) {
|
||||
o.f(13, 12)
|
||||
}
|
||||
|
||||
fun usage(o: OOO) {
|
||||
o.f(3, 12)
|
||||
}
|
||||
@@ -0,0 +1,58 @@
|
||||
// "Add parameter to function 'f'" "true"
|
||||
trait OA {
|
||||
fun f(a: Int)
|
||||
}
|
||||
|
||||
trait OB {
|
||||
fun f(a: Int)
|
||||
}
|
||||
|
||||
trait O : OA, OB {
|
||||
override fun f(a: Int)
|
||||
}
|
||||
|
||||
trait OO : O {
|
||||
override fun f(a: Int) {
|
||||
}
|
||||
}
|
||||
|
||||
trait OOO : OO {
|
||||
override fun f(a: Int) {}
|
||||
}
|
||||
|
||||
trait OOOA : OOO {
|
||||
override fun f(a: Int) {
|
||||
}
|
||||
}
|
||||
|
||||
trait OOOB : OOO {
|
||||
override fun f(a: Int) {
|
||||
}
|
||||
}
|
||||
|
||||
fun usage(o: OA) {
|
||||
o.f(1)
|
||||
}
|
||||
fun usage(o: OB) {
|
||||
o.f(1)
|
||||
}
|
||||
|
||||
fun usage(o: O) {
|
||||
o.f(1)
|
||||
}
|
||||
|
||||
fun usage(o: OO) {
|
||||
o.f(13, <caret>12)
|
||||
}
|
||||
|
||||
fun usage(o: OOO) {
|
||||
o.f(3)
|
||||
}
|
||||
|
||||
fun usage(o: OOOA) {
|
||||
o.f(3)
|
||||
}
|
||||
|
||||
fun usage(o: OOOB) {
|
||||
o.f(3)
|
||||
}
|
||||
@@ -0,0 +1,58 @@
|
||||
// "Remove parameter 'a'" "true"
|
||||
trait OA {
|
||||
fun f(a: Int)
|
||||
}
|
||||
|
||||
trait OB {
|
||||
fun f(a: Int)
|
||||
}
|
||||
|
||||
trait O : OA, OB {
|
||||
override fun f(a: Int)
|
||||
}
|
||||
|
||||
trait OO : O {
|
||||
override fun f(a: Int) {
|
||||
}
|
||||
}
|
||||
|
||||
trait OOO : OO {
|
||||
override fun f(a: Int) {}
|
||||
}
|
||||
|
||||
trait OOOA : OOO {
|
||||
override fun f(a: Int) {
|
||||
}
|
||||
}
|
||||
|
||||
trait OOOB : OOO {
|
||||
override fun f(a: Int) {
|
||||
}
|
||||
}
|
||||
|
||||
fun usage(o: OA) {
|
||||
o.f(<caret>)
|
||||
}
|
||||
fun usage(o: OB) {
|
||||
o.f(1)
|
||||
}
|
||||
|
||||
fun usage(o: O) {
|
||||
o.f(1)
|
||||
}
|
||||
|
||||
fun usage(o: OO) {
|
||||
o.f(13)
|
||||
}
|
||||
|
||||
fun usage(o: OOO) {
|
||||
o.f(3)
|
||||
}
|
||||
|
||||
fun usage(o: OOOA) {
|
||||
o.f(3)
|
||||
}
|
||||
|
||||
fun usage(o: OOOB) {
|
||||
o.f(3)
|
||||
}
|
||||
@@ -0,0 +1,58 @@
|
||||
// "Add parameter to function 'f'" "true"
|
||||
trait OA {
|
||||
fun f(a: Int)
|
||||
}
|
||||
|
||||
trait OB {
|
||||
fun f(a: Int)
|
||||
}
|
||||
|
||||
trait O : OA, OB {
|
||||
override fun f(a: Int)
|
||||
}
|
||||
|
||||
trait OO : O {
|
||||
override fun f(a: Int) {
|
||||
}
|
||||
}
|
||||
|
||||
trait OOO : OO {
|
||||
override fun f(a: Int) {}
|
||||
}
|
||||
|
||||
trait OOOA : OOO {
|
||||
override fun f(a: Int) {
|
||||
}
|
||||
}
|
||||
|
||||
trait OOOB : OOO {
|
||||
override fun f(a: Int) {
|
||||
}
|
||||
}
|
||||
|
||||
fun usage(o: OA) {
|
||||
o.f(1)
|
||||
}
|
||||
fun usage(o: OB) {
|
||||
o.f(1)
|
||||
}
|
||||
|
||||
fun usage(o: O) {
|
||||
o.f(1)
|
||||
}
|
||||
|
||||
fun usage(o: OO) {
|
||||
o.f(13)
|
||||
}
|
||||
|
||||
fun usage(o: OOO) {
|
||||
o.f(3)
|
||||
}
|
||||
|
||||
fun usage(o: OOOA) {
|
||||
o.f(3)
|
||||
}
|
||||
|
||||
fun usage(o: OOOB) {
|
||||
o.f(3, <caret>"asdv")
|
||||
}
|
||||
@@ -0,0 +1,25 @@
|
||||
// "Add parameter to function 'f'" "true"
|
||||
trait O {
|
||||
fun f(a: Int)
|
||||
}
|
||||
|
||||
trait OO : O {
|
||||
override fun f(a: Int) {
|
||||
}
|
||||
}
|
||||
|
||||
trait OOO : OO {
|
||||
override fun f(a: Int) {}
|
||||
}
|
||||
|
||||
fun usage(o: O) {
|
||||
o.f(1)
|
||||
}
|
||||
|
||||
fun usage(o: OO) {
|
||||
o.f(13, <caret>12)
|
||||
}
|
||||
|
||||
fun usage(o: OOO) {
|
||||
o.f(3)
|
||||
}
|
||||
@@ -0,0 +1,15 @@
|
||||
trait A {
|
||||
fun f(i: Int) {}
|
||||
}
|
||||
|
||||
trait B {
|
||||
fun f(i: Int) {}
|
||||
}
|
||||
|
||||
trait C : A, B {
|
||||
|
||||
}
|
||||
|
||||
fun usage(c: C) {
|
||||
c.f()
|
||||
}
|
||||
@@ -0,0 +1,15 @@
|
||||
trait A {
|
||||
fun f() {}
|
||||
}
|
||||
|
||||
trait B {
|
||||
fun f() {}
|
||||
}
|
||||
|
||||
trait C : A, B {
|
||||
|
||||
}
|
||||
|
||||
fun usage(c: C) {
|
||||
c.<caret>f()
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
class A {
|
||||
fun f(param: Int)
|
||||
}
|
||||
|
||||
trait B {
|
||||
fun f(p: Int)
|
||||
}
|
||||
|
||||
class C : A, B {
|
||||
override fun <caret>f(p: Int) {}
|
||||
}
|
||||
@@ -389,6 +389,26 @@ public class QuickFixTestGenerated extends AbstractQuickFixTest {
|
||||
doTest("idea/testData/quickfix/changeSignature/beforeChangeFunctionLiteralParameters2.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("beforeComplexHierarchy.kt")
|
||||
public void testComplexHierarchy() throws Exception {
|
||||
doTest("idea/testData/quickfix/changeSignature/beforeComplexHierarchy.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("beforeComplexHierarchyHead.kt")
|
||||
public void testComplexHierarchyHead() throws Exception {
|
||||
doTest("idea/testData/quickfix/changeSignature/beforeComplexHierarchyHead.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("beforeComplexHierarchyTail.kt")
|
||||
public void testComplexHierarchyTail() throws Exception {
|
||||
doTest("idea/testData/quickfix/changeSignature/beforeComplexHierarchyTail.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("beforeLinearHierarchy.kt")
|
||||
public void testLinearHierarchy() throws Exception {
|
||||
doTest("idea/testData/quickfix/changeSignature/beforeLinearHierarchy.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("beforeRemoveConstructorParameter.kt")
|
||||
public void testRemoveConstructorParameter() throws Exception {
|
||||
doTest("idea/testData/quickfix/changeSignature/beforeRemoveConstructorParameter.kt");
|
||||
|
||||
+28
-2
@@ -17,6 +17,7 @@
|
||||
package org.jetbrains.jet.plugin.refactoring.changeSignature;
|
||||
|
||||
import com.intellij.openapi.editor.Editor;
|
||||
import com.intellij.openapi.project.Project;
|
||||
import com.intellij.openapi.util.Disposer;
|
||||
import com.intellij.openapi.util.text.StringUtil;
|
||||
import com.intellij.psi.PsiElement;
|
||||
@@ -25,16 +26,22 @@ import com.intellij.refactoring.BaseRefactoringProcessor;
|
||||
import com.intellij.refactoring.util.CommonRefactoringUtil;
|
||||
import com.intellij.testFramework.LightCodeInsightTestCase;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.jet.lang.descriptors.FunctionDescriptor;
|
||||
import org.jetbrains.jet.lang.descriptors.Visibilities;
|
||||
import org.jetbrains.jet.lang.psi.JetFile;
|
||||
import org.jetbrains.jet.lang.psi.JetPsiFactory;
|
||||
import org.jetbrains.jet.lang.resolve.BindingContext;
|
||||
import org.jetbrains.jet.lang.types.lang.KotlinBuiltIns;
|
||||
import org.jetbrains.jet.plugin.PluginTestCaseBase;
|
||||
import org.jetbrains.jet.plugin.project.AnalyzerFacadeWithCache;
|
||||
|
||||
import java.io.File;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
|
||||
import static org.jetbrains.jet.plugin.refactoring.changeSignature.ChangeSignaturePackage.getChangeSignatureDialog;
|
||||
|
||||
public class JetChangeSignatureTest extends LightCodeInsightTestCase {
|
||||
public void testBadSelection() throws Exception {
|
||||
configureByFile(getTestName(false) + "Before.kt");
|
||||
@@ -73,6 +80,11 @@ public class JetChangeSignatureTest extends LightCodeInsightTestCase {
|
||||
doTest(changeInfo);
|
||||
}
|
||||
|
||||
public void testPreferContainedInClass() throws Exception {
|
||||
JetChangeInfo changeInfo = getChangeInfo();
|
||||
assertEquals("param", changeInfo.getNewParameters()[0].getName());
|
||||
}
|
||||
|
||||
public void testAddConstructorVisibility() throws Exception {
|
||||
JetChangeInfo changeInfo = getChangeInfo();
|
||||
changeInfo.setNewVisibility(Visibilities.PROTECTED);
|
||||
@@ -134,6 +146,13 @@ public class JetChangeSignatureTest extends LightCodeInsightTestCase {
|
||||
doTest(changeInfo);
|
||||
}
|
||||
|
||||
public void testFakeOverride() throws Exception {
|
||||
JetChangeInfo changeInfo = getChangeInfo();
|
||||
JetParameterInfo newParameter = new JetParameterInfo("i", KotlinBuiltIns.getInstance().getIntType());
|
||||
changeInfo.addParameter(newParameter);
|
||||
doTest(changeInfo);
|
||||
}
|
||||
|
||||
public void testFunctionLiteral() throws Exception {
|
||||
JetChangeInfo changeInfo = getChangeInfo();
|
||||
changeInfo.getNewParameters()[1].setName("y1");
|
||||
@@ -194,8 +213,15 @@ public class JetChangeSignatureTest extends LightCodeInsightTestCase {
|
||||
PsiFile file = getFile();
|
||||
PsiElement element = new JetChangeSignatureHandler().findTargetMember(file, editor);
|
||||
assertNotNull("Target element is null", element);
|
||||
JetChangeSignatureDialog dialog =
|
||||
JetChangeSignatureHandler.createDialog(element, file.findElementAt(editor.getCaretModel().getOffset()), getProject(), editor);
|
||||
Project project = getProject();
|
||||
BindingContext bindingContext =
|
||||
AnalyzerFacadeWithCache.analyzeFileWithCache((JetFile) element.getContainingFile()).getBindingContext();
|
||||
PsiElement context = file.findElementAt(editor.getCaretModel().getOffset());
|
||||
assertNotNull(context);
|
||||
FunctionDescriptor functionDescriptor = JetChangeSignatureHandler.findDescriptor(element, project, editor, bindingContext);
|
||||
assertNotNull(functionDescriptor);
|
||||
JetChangeSignatureDialog dialog = getChangeSignatureDialog(project, functionDescriptor,
|
||||
JetChangeSignatureHandler.getConfiguration(), bindingContext, context);
|
||||
assertNotNull(dialog);
|
||||
dialog.canRun();
|
||||
Disposer.register(getTestRootDisposable(), dialog.getDisposable());
|
||||
|
||||
Reference in New Issue
Block a user