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);
|
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;
|
package org.jetbrains.jet.plugin.quickfix;
|
||||||
|
|
||||||
import com.intellij.openapi.application.ApplicationManager;
|
|
||||||
import com.intellij.openapi.editor.Editor;
|
import com.intellij.openapi.editor.Editor;
|
||||||
import com.intellij.openapi.project.Project;
|
import com.intellij.openapi.project.Project;
|
||||||
import com.intellij.psi.PsiElement;
|
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.JetBundle;
|
||||||
import org.jetbrains.jet.plugin.project.AnalyzerFacadeWithCache;
|
import org.jetbrains.jet.plugin.project.AnalyzerFacadeWithCache;
|
||||||
import org.jetbrains.jet.plugin.refactoring.JetNameValidator;
|
import org.jetbrains.jet.plugin.refactoring.JetNameValidator;
|
||||||
import org.jetbrains.jet.plugin.refactoring.changeSignature.JetChangeSignatureDialog;
|
import org.jetbrains.jet.plugin.refactoring.changeSignature.*;
|
||||||
import org.jetbrains.jet.plugin.refactoring.changeSignature.JetFunctionPlatformDescriptorImpl;
|
|
||||||
import org.jetbrains.jet.plugin.refactoring.changeSignature.JetParameterInfo;
|
|
||||||
import org.jetbrains.jet.renderer.DescriptorRenderer;
|
import org.jetbrains.jet.renderer.DescriptorRenderer;
|
||||||
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
|
import static org.jetbrains.jet.plugin.refactoring.changeSignature.ChangeSignaturePackage.runChangeSignature;
|
||||||
|
|
||||||
public class AddFunctionParametersFix extends ChangeFunctionSignatureFix {
|
public class AddFunctionParametersFix extends ChangeFunctionSignatureFix {
|
||||||
private final JetCallElement callElement;
|
private final JetCallElement callElement;
|
||||||
private final boolean hasTypeMismatches;
|
private final boolean hasTypeMismatches;
|
||||||
@@ -85,45 +84,43 @@ public class AddFunctionParametersFix extends ChangeFunctionSignatureFix {
|
|||||||
@Override
|
@Override
|
||||||
protected void invoke(@NotNull Project project, Editor editor, JetFile file) {
|
protected void invoke(@NotNull Project project, Editor editor, JetFile file) {
|
||||||
BindingContext bindingContext = AnalyzerFacadeWithCache.analyzeFileWithCache((JetFile) callElement.getContainingFile()).getBindingContext();
|
BindingContext bindingContext = AnalyzerFacadeWithCache.analyzeFileWithCache((JetFile) callElement.getContainingFile()).getBindingContext();
|
||||||
JetFunctionPlatformDescriptorImpl platformDescriptor = new JetFunctionPlatformDescriptorImpl(functionDescriptor, element);
|
boolean performSilently = !hasTypeMismatches && !(functionDescriptor instanceof ConstructorDescriptor) && !hasOtherUsages();
|
||||||
final List<ValueParameterDescriptor> parameters = functionDescriptor.getValueParameters();
|
runChangeSignature(project, functionDescriptor, addParameterConfiguration(), bindingContext, callElement, getText(), performSilently);
|
||||||
List<? extends ValueArgument> arguments = callElement.getValueArguments();
|
}
|
||||||
JetNameValidator validator = JetNameValidator.getCollectingValidator(callElement.getProject());
|
|
||||||
|
|
||||||
for (int i = 0; i < arguments.size(); i ++) {
|
private JetChangeSignatureConfiguration addParameterConfiguration() {
|
||||||
ValueArgument argument = arguments.get(i);
|
return new JetChangeSignatureConfiguration() {
|
||||||
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()) {
|
|
||||||
@Override
|
@Override
|
||||||
protected int getSelectedIdx() {
|
public void configure(
|
||||||
return parameters.size();
|
@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() {
|
private boolean hasOtherUsages() {
|
||||||
|
|||||||
@@ -22,15 +22,20 @@ import org.jetbrains.annotations.NotNull;
|
|||||||
import org.jetbrains.jet.lang.descriptors.FunctionDescriptor;
|
import org.jetbrains.jet.lang.descriptors.FunctionDescriptor;
|
||||||
import org.jetbrains.jet.lang.psi.JetFile;
|
import org.jetbrains.jet.lang.psi.JetFile;
|
||||||
import org.jetbrains.jet.lang.psi.JetFunctionLiteral;
|
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.lang.types.JetType;
|
||||||
import org.jetbrains.jet.plugin.JetBundle;
|
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.JetNameSuggester;
|
||||||
import org.jetbrains.jet.plugin.refactoring.JetNameValidator;
|
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 org.jetbrains.jet.plugin.refactoring.changeSignature.JetParameterInfo;
|
||||||
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
|
import static org.jetbrains.jet.plugin.refactoring.changeSignature.ChangeSignaturePackage.runChangeSignature;
|
||||||
|
|
||||||
public class ChangeFunctionLiteralSignatureFix extends ChangeFunctionSignatureFix {
|
public class ChangeFunctionLiteralSignatureFix extends ChangeFunctionSignatureFix {
|
||||||
private final List<JetType> parameterTypes;
|
private final List<JetType> parameterTypes;
|
||||||
|
|
||||||
@@ -49,16 +54,18 @@ public class ChangeFunctionLiteralSignatureFix extends ChangeFunctionSignatureFi
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void invoke(@NotNull Project project, Editor editor, JetFile file) {
|
protected void invoke(@NotNull final Project project, Editor editor, JetFile file) {
|
||||||
JetFunctionPlatformDescriptorImpl platformDescriptor = new JetFunctionPlatformDescriptorImpl(functionDescriptor, element);
|
BindingContext bindingContext = AnalyzerFacadeWithCache.analyzeFileWithCache(file).getBindingContext();
|
||||||
JetNameValidator validator = JetNameValidator.getCollectingValidator(project);
|
runChangeSignature(project, functionDescriptor, new JetChangeSignatureConfiguration() {
|
||||||
platformDescriptor.clearParameters();
|
@Override
|
||||||
|
public void configure(@NotNull JetChangeSignatureData changeSignatureData, @NotNull BindingContext bindingContext) {
|
||||||
for (JetType type : parameterTypes) {
|
JetNameValidator validator = JetNameValidator.getCollectingValidator(project);
|
||||||
String name = JetNameSuggester.suggestNames(type, validator, "param")[0];
|
changeSignatureData.clearParameters();
|
||||||
platformDescriptor.addParameter(new JetParameterInfo(name, type));
|
for (JetType type : parameterTypes) {
|
||||||
}
|
String name = JetNameSuggester.suggestNames(type, validator, "param")[0];
|
||||||
|
changeSignatureData.addParameter(new JetParameterInfo(name, type));
|
||||||
showDialog(project, platformDescriptor);
|
}
|
||||||
|
}
|
||||||
|
}, bindingContext, context, getText(), false);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -16,9 +16,6 @@
|
|||||||
|
|
||||||
package org.jetbrains.jet.plugin.quickfix;
|
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.PsiElement;
|
||||||
import com.intellij.psi.PsiNameIdentifierOwner;
|
import com.intellij.psi.PsiNameIdentifierOwner;
|
||||||
import com.intellij.psi.util.PsiTreeUtil;
|
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.project.AnalyzerFacadeWithCache;
|
||||||
import org.jetbrains.jet.plugin.refactoring.JetNameSuggester;
|
import org.jetbrains.jet.plugin.refactoring.JetNameSuggester;
|
||||||
import org.jetbrains.jet.plugin.refactoring.JetNameValidator;
|
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;
|
import java.util.List;
|
||||||
|
|
||||||
public abstract class ChangeFunctionSignatureFix extends JetIntentionAction<PsiElement> {
|
public abstract class ChangeFunctionSignatureFix extends JetIntentionAction<PsiElement> {
|
||||||
private final PsiElement context;
|
protected final PsiElement context;
|
||||||
protected final FunctionDescriptor functionDescriptor;
|
protected final FunctionDescriptor functionDescriptor;
|
||||||
|
|
||||||
public ChangeFunctionSignatureFix(
|
public ChangeFunctionSignatureFix(
|
||||||
@@ -70,21 +67,13 @@ public abstract class ChangeFunctionSignatureFix extends JetIntentionAction<PsiE
|
|||||||
return false;
|
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) {
|
protected static String getNewArgumentName(ValueArgument argument, JetNameValidator validator) {
|
||||||
JetValueArgumentName argumentName = argument.getArgumentName();
|
JetValueArgumentName argumentName = argument.getArgumentName();
|
||||||
JetExpression expression = argument.getArgumentExpression();
|
JetExpression expression = argument.getArgumentExpression();
|
||||||
|
|
||||||
if (argumentName != null)
|
if (argumentName != null) {
|
||||||
return validator.validateName(argumentName.getName());
|
return validator.validateName(argumentName.getName());
|
||||||
|
}
|
||||||
else if (expression != null) {
|
else if (expression != null) {
|
||||||
return JetNameSuggester.suggestNames(expression, validator, "param")[0];
|
return JetNameSuggester.suggestNames(expression, validator, "param")[0];
|
||||||
}
|
}
|
||||||
@@ -92,7 +81,11 @@ public abstract class ChangeFunctionSignatureFix extends JetIntentionAction<PsiE
|
|||||||
return validator.validateName("param");
|
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);
|
String name = getNewArgumentName(argument, validator);
|
||||||
JetExpression expression = argument.getArgumentExpression();
|
JetExpression expression = argument.getArgumentExpression();
|
||||||
JetType type = expression != null ? bindingContext.get(BindingContext.EXPRESSION_TYPE, expression) : null;
|
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);
|
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++) {
|
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();
|
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();
|
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 true;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return false;
|
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() {
|
public static JetSingleIntentionActionFactory createFactory() {
|
||||||
return new JetSingleIntentionActionFactory() {
|
return new JetSingleIntentionActionFactory() {
|
||||||
@Override
|
@Override
|
||||||
@@ -134,8 +123,9 @@ public abstract class ChangeFunctionSignatureFix extends JetIntentionAction<PsiE
|
|||||||
@SuppressWarnings("unchecked")
|
@SuppressWarnings("unchecked")
|
||||||
CallableDescriptor descriptor = ((DiagnosticWithParameters1<PsiElement, CallableDescriptor>) diagnostic).getA();
|
CallableDescriptor descriptor = ((DiagnosticWithParameters1<PsiElement, CallableDescriptor>) diagnostic).getA();
|
||||||
|
|
||||||
if (callElement != null)
|
if (callElement != null) {
|
||||||
return createFix(callElement, callElement, descriptor);
|
return createFix(callElement, callElement, descriptor);
|
||||||
|
}
|
||||||
|
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
@@ -150,13 +140,17 @@ public abstract class ChangeFunctionSignatureFix extends JetIntentionAction<PsiE
|
|||||||
DiagnosticWithParameters2<JetFunctionLiteral, Integer, List<JetType>> diagnosticWithParameters =
|
DiagnosticWithParameters2<JetFunctionLiteral, Integer, List<JetType>> diagnosticWithParameters =
|
||||||
(DiagnosticWithParameters2<JetFunctionLiteral, Integer, List<JetType>>) diagnostic;
|
(DiagnosticWithParameters2<JetFunctionLiteral, Integer, List<JetType>>) diagnostic;
|
||||||
JetFunctionLiteral functionLiteral = diagnosticWithParameters.getPsiElement();
|
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);
|
DeclarationDescriptor descriptor = bindingContext.get(BindingContext.DECLARATION_TO_DESCRIPTOR, functionLiteral);
|
||||||
|
|
||||||
if (descriptor instanceof FunctionDescriptor)
|
if (descriptor instanceof FunctionDescriptor) {
|
||||||
return new ChangeFunctionLiteralSignatureFix(functionLiteral, (FunctionDescriptor) descriptor, diagnosticWithParameters.getB());
|
return new ChangeFunctionLiteralSignatureFix(functionLiteral, (FunctionDescriptor) descriptor,
|
||||||
else
|
diagnosticWithParameters.getB());
|
||||||
|
}
|
||||||
|
else {
|
||||||
return null;
|
return null;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
@@ -168,10 +162,12 @@ public abstract class ChangeFunctionSignatureFix extends JetIntentionAction<PsiE
|
|||||||
@SuppressWarnings("unchecked")
|
@SuppressWarnings("unchecked")
|
||||||
Object descriptor = ((DiagnosticWithParameters1<PsiNameIdentifierOwner, Object>) diagnostic).getA();
|
Object descriptor = ((DiagnosticWithParameters1<PsiNameIdentifierOwner, Object>) diagnostic).getA();
|
||||||
|
|
||||||
if (descriptor instanceof ValueParameterDescriptor)
|
if (descriptor instanceof ValueParameterDescriptor) {
|
||||||
return createFix(null, diagnostic.getPsiElement(), (CallableDescriptor) descriptor);
|
return createFix(null, diagnostic.getPsiElement(), (CallableDescriptor) descriptor);
|
||||||
else
|
}
|
||||||
|
else {
|
||||||
return null;
|
return null;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
@@ -180,31 +176,37 @@ public abstract class ChangeFunctionSignatureFix extends JetIntentionAction<PsiE
|
|||||||
private static ChangeFunctionSignatureFix createFix(JetCallElement callElement, PsiElement context, CallableDescriptor descriptor) {
|
private static ChangeFunctionSignatureFix createFix(JetCallElement callElement, PsiElement context, CallableDescriptor descriptor) {
|
||||||
FunctionDescriptor functionDescriptor = null;
|
FunctionDescriptor functionDescriptor = null;
|
||||||
|
|
||||||
if (descriptor instanceof FunctionDescriptor)
|
if (descriptor instanceof FunctionDescriptor) {
|
||||||
functionDescriptor = (FunctionDescriptor) descriptor;
|
functionDescriptor = (FunctionDescriptor) descriptor;
|
||||||
|
}
|
||||||
else if (descriptor instanceof ValueParameterDescriptor) {
|
else if (descriptor instanceof ValueParameterDescriptor) {
|
||||||
DeclarationDescriptor containingDescriptor = descriptor.getContainingDeclaration();
|
DeclarationDescriptor containingDescriptor = descriptor.getContainingDeclaration();
|
||||||
|
|
||||||
if (containingDescriptor instanceof FunctionDescriptor)
|
if (containingDescriptor instanceof FunctionDescriptor) {
|
||||||
functionDescriptor = (FunctionDescriptor) containingDescriptor;
|
functionDescriptor = (FunctionDescriptor) containingDescriptor;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (functionDescriptor != null) {
|
if (functionDescriptor == null) {
|
||||||
BindingContext bindingContext = AnalyzerFacadeWithCache.analyzeFileWithCache((JetFile) context.getContainingFile()).getBindingContext();
|
return null;
|
||||||
PsiElement declaration = BindingContextUtils.descriptorToDeclaration(bindingContext, functionDescriptor);
|
}
|
||||||
|
BindingContext bindingContext =
|
||||||
|
AnalyzerFacadeWithCache.analyzeFileWithCache((JetFile) context.getContainingFile()).getBindingContext();
|
||||||
|
PsiElement declaration = BindingContextUtils.descriptorToDeclaration(bindingContext, functionDescriptor);
|
||||||
|
|
||||||
if (declaration != null) {
|
if (declaration == null) {
|
||||||
if (descriptor instanceof ValueParameterDescriptor)
|
return null;
|
||||||
return new RemoveFunctionParametersFix(declaration, context, functionDescriptor, (ValueParameterDescriptor) descriptor);
|
}
|
||||||
else {
|
if (descriptor instanceof ValueParameterDescriptor) {
|
||||||
List<ValueParameterDescriptor> parameters = functionDescriptor.getValueParameters();
|
return new RemoveFunctionParametersFix(declaration, context, functionDescriptor, (ValueParameterDescriptor) descriptor);
|
||||||
List<? extends ValueArgument> arguments = callElement.getValueArguments();
|
}
|
||||||
|
else {
|
||||||
|
List<ValueParameterDescriptor> parameters = functionDescriptor.getValueParameters();
|
||||||
|
List<? extends ValueArgument> arguments = callElement.getValueArguments();
|
||||||
|
|
||||||
if (arguments.size() > parameters.size()) {
|
if (arguments.size() > parameters.size()) {
|
||||||
boolean hasTypeMismatches = hasTypeMismatches(parameters, arguments, bindingContext);
|
boolean hasTypeMismatches = hasTypeMismatches(parameters, arguments, bindingContext);
|
||||||
return new AddFunctionParametersFix(declaration, callElement, functionDescriptor, hasTypeMismatches);
|
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.FunctionDescriptor;
|
||||||
import org.jetbrains.jet.lang.descriptors.ValueParameterDescriptor;
|
import org.jetbrains.jet.lang.descriptors.ValueParameterDescriptor;
|
||||||
import org.jetbrains.jet.lang.psi.JetFile;
|
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.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 java.util.List;
|
||||||
|
|
||||||
|
import static org.jetbrains.jet.plugin.refactoring.changeSignature.ChangeSignaturePackage.runChangeSignature;
|
||||||
|
|
||||||
public class RemoveFunctionParametersFix extends ChangeFunctionSignatureFix {
|
public class RemoveFunctionParametersFix extends ChangeFunctionSignatureFix {
|
||||||
private final ValueParameterDescriptor parameterToRemove;
|
private final ValueParameterDescriptor parameterToRemove;
|
||||||
|
|
||||||
@@ -49,9 +54,15 @@ public class RemoveFunctionParametersFix extends ChangeFunctionSignatureFix {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void invoke(@NotNull Project project, Editor editor, JetFile file) {
|
protected void invoke(@NotNull Project project, Editor editor, JetFile file) {
|
||||||
JetFunctionPlatformDescriptorImpl platformDescriptor = new JetFunctionPlatformDescriptorImpl(functionDescriptor, element);
|
BindingContext bindingContext = AnalyzerFacadeWithCache.analyzeFileWithCache(file).getBindingContext();
|
||||||
List<ValueParameterDescriptor> parameters = functionDescriptor.getValueParameters();
|
runChangeSignature(project, functionDescriptor, new JetChangeSignatureConfiguration() {
|
||||||
platformDescriptor.removeParameter(parameters.indexOf(parameterToRemove));
|
@Override
|
||||||
showDialog(project, platformDescriptor);
|
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.lexer.JetTokens;
|
||||||
import org.jetbrains.jet.plugin.JetLanguage;
|
import org.jetbrains.jet.plugin.JetLanguage;
|
||||||
|
|
||||||
|
import java.util.Collection;
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
|
||||||
public class JetChangeInfo implements ChangeInfo {
|
public class JetChangeInfo implements ChangeInfo {
|
||||||
private final JetFunctionPlatformDescriptor oldDescriptor;
|
private final JetMethodDescriptor oldDescriptor;
|
||||||
private String newName;
|
private String newName;
|
||||||
private final JetType newReturnType;
|
private final JetType newReturnType;
|
||||||
private String newReturnTypeText;
|
private String newReturnTypeText;
|
||||||
@@ -49,7 +50,7 @@ public class JetChangeInfo implements ChangeInfo {
|
|||||||
private Map<String, Integer> oldNameToParameterIndex;
|
private Map<String, Integer> oldNameToParameterIndex;
|
||||||
|
|
||||||
public JetChangeInfo(
|
public JetChangeInfo(
|
||||||
JetFunctionPlatformDescriptor oldDescriptor,
|
JetMethodDescriptor oldDescriptor,
|
||||||
String newName,
|
String newName,
|
||||||
JetType newReturnType,
|
JetType newReturnType,
|
||||||
String newReturnTypeText,
|
String newReturnTypeText,
|
||||||
@@ -215,7 +216,7 @@ public class JetChangeInfo implements ChangeInfo {
|
|||||||
return oldDescriptor.getDescriptor();
|
return oldDescriptor.getDescriptor();
|
||||||
}
|
}
|
||||||
|
|
||||||
public JetFunctionPlatformDescriptor getFunctionDescriptor() {
|
public JetMethodDescriptor getFunctionDescriptor() {
|
||||||
return oldDescriptor;
|
return oldDescriptor;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -259,4 +260,9 @@ public class JetChangeInfo implements ChangeInfo {
|
|||||||
public Language getLanguage() {
|
public Language getLanguage() {
|
||||||
return JetLanguage.INSTANCE;
|
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,
|
JetParameterInfo,
|
||||||
PsiElement,
|
PsiElement,
|
||||||
Visibility,
|
Visibility,
|
||||||
JetFunctionPlatformDescriptor,
|
JetMethodDescriptor,
|
||||||
ParameterTableModelItemBase<JetParameterInfo>,
|
ParameterTableModelItemBase<JetParameterInfo>,
|
||||||
JetFunctionParameterTableModel
|
JetFunctionParameterTableModel
|
||||||
>
|
>
|
||||||
@@ -79,12 +79,8 @@ public class JetChangeSignatureDialog extends ChangeSignatureDialogBase<
|
|||||||
private final JetGeneratedInfo generatedInfo = new JetGeneratedInfo();
|
private final JetGeneratedInfo generatedInfo = new JetGeneratedInfo();
|
||||||
private final String commandName;
|
private final String commandName;
|
||||||
|
|
||||||
public JetChangeSignatureDialog(Project project, JetFunctionPlatformDescriptor descriptor, PsiElement context) {
|
public JetChangeSignatureDialog(Project project, @NotNull JetMethodDescriptor methodDescriptor, PsiElement context, String commandName) {
|
||||||
this(project, descriptor, context, null);
|
super(project, methodDescriptor, false, context);
|
||||||
}
|
|
||||||
|
|
||||||
public JetChangeSignatureDialog(Project project, JetFunctionPlatformDescriptor descriptor, PsiElement context, String commandName) {
|
|
||||||
super(project, descriptor, false, context);
|
|
||||||
this.commandName = commandName;
|
this.commandName = commandName;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -94,7 +90,7 @@ public class JetChangeSignatureDialog extends ChangeSignatureDialogBase<
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected JetFunctionParameterTableModel createParametersInfoModel(JetFunctionPlatformDescriptor descriptor) {
|
protected JetFunctionParameterTableModel createParametersInfoModel(JetMethodDescriptor descriptor) {
|
||||||
if (descriptor.isConstructor())
|
if (descriptor.isConstructor())
|
||||||
return new JetConstructorParameterTableModel(myDefaultValueContext);
|
return new JetConstructorParameterTableModel(myDefaultValueContext);
|
||||||
else
|
else
|
||||||
@@ -399,6 +395,7 @@ public class JetChangeSignatureDialog extends ChangeSignatureDialogBase<
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@NotNull
|
||||||
protected BaseRefactoringProcessor createRefactoringProcessor() {
|
protected BaseRefactoringProcessor createRefactoringProcessor() {
|
||||||
return new JetChangeSignatureProcessor(myProject, evaluateChangeInfo(), commandName != null ? commandName : getTitle());
|
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() : "";
|
String returnTypeText = myReturnTypeCodeFragment != null ? myReturnTypeCodeFragment.getText().trim() : "";
|
||||||
return new JetChangeInfo(myMethod, getMethodName(), getReturnType(), returnTypeText,
|
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 com.intellij.refactoring.util.CommonRefactoringUtil;
|
||||||
import org.jetbrains.annotations.NotNull;
|
import org.jetbrains.annotations.NotNull;
|
||||||
import org.jetbrains.annotations.Nullable;
|
import org.jetbrains.annotations.Nullable;
|
||||||
|
import org.jetbrains.annotations.TestOnly;
|
||||||
import org.jetbrains.jet.lang.descriptors.ClassDescriptor;
|
import org.jetbrains.jet.lang.descriptors.ClassDescriptor;
|
||||||
import org.jetbrains.jet.lang.descriptors.DeclarationDescriptor;
|
import org.jetbrains.jet.lang.descriptors.DeclarationDescriptor;
|
||||||
import org.jetbrains.jet.lang.descriptors.FunctionDescriptor;
|
import org.jetbrains.jet.lang.descriptors.FunctionDescriptor;
|
||||||
import org.jetbrains.jet.lang.descriptors.ValueParameterDescriptor;
|
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.psi.*;
|
||||||
import org.jetbrains.jet.lang.resolve.BindingContext;
|
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.project.AnalyzerFacadeWithCache;
|
||||||
import org.jetbrains.jet.plugin.refactoring.JetRefactoringBundle;
|
import org.jetbrains.jet.plugin.refactoring.JetRefactoringBundle;
|
||||||
|
|
||||||
|
import static org.jetbrains.jet.plugin.refactoring.changeSignature.ChangeSignaturePackage.runChangeSignature;
|
||||||
|
|
||||||
public class JetChangeSignatureHandler implements ChangeSignatureHandler {
|
public class JetChangeSignatureHandler implements ChangeSignatureHandler {
|
||||||
@Nullable
|
@Nullable
|
||||||
@Override
|
public static PsiElement findTargetForRefactoring(@NotNull PsiElement element) {
|
||||||
public PsiElement findTargetMember(PsiFile file, Editor editor) {
|
|
||||||
return findTargetMember(file.findElementAt(editor.getCaretModel().getOffset()));
|
|
||||||
}
|
|
||||||
|
|
||||||
@Nullable
|
|
||||||
@Override
|
|
||||||
public PsiElement findTargetMember(PsiElement element) {
|
|
||||||
if (PsiTreeUtil.getParentOfType(element, JetParameterList.class) != null) {
|
if (PsiTreeUtil.getParentOfType(element, JetParameterList.class) != null) {
|
||||||
return PsiTreeUtil.getParentOfType(element, JetFunction.class, JetClass.class);
|
return PsiTreeUtil.getParentOfType(element, JetFunction.class, JetClass.class);
|
||||||
}
|
}
|
||||||
@@ -62,35 +56,77 @@ public class JetChangeSignatureHandler implements ChangeSignatureHandler {
|
|||||||
}
|
}
|
||||||
|
|
||||||
PsiElement elementParent = element.getParent();
|
PsiElement elementParent = element.getParent();
|
||||||
if (elementParent instanceof JetNamedFunction && ((JetNamedFunction)elementParent).getNameIdentifier()==element) {
|
if (elementParent instanceof JetNamedFunction && ((JetNamedFunction) elementParent).getNameIdentifier() == element) {
|
||||||
return elementParent;
|
return elementParent;
|
||||||
}
|
}
|
||||||
if (elementParent instanceof JetClass && ((JetClass)elementParent).getNameIdentifier()==element) {
|
if (elementParent instanceof JetClass && ((JetClass) elementParent).getNameIdentifier() == element) {
|
||||||
return elementParent;
|
return elementParent;
|
||||||
}
|
}
|
||||||
|
|
||||||
JetCallElement call = PsiTreeUtil.getParentOfType(element, JetCallExpression.class, JetDelegatorToSuperCall.class);
|
JetCallElement call = PsiTreeUtil.getParentOfType(element, JetCallExpression.class, JetDelegatorToSuperCall.class);
|
||||||
if (call != null) {
|
if (call == null) {
|
||||||
JetExpression receiverExpr = call instanceof JetCallExpression ? call.getCalleeExpression() :
|
return null;
|
||||||
((JetDelegatorToSuperCall)call).getCalleeExpression().getConstructorReferenceExpression();
|
}
|
||||||
|
JetExpression receiverExpr = call instanceof JetCallExpression ? call.getCalleeExpression() :
|
||||||
|
((JetDelegatorToSuperCall) call).getCalleeExpression().getConstructorReferenceExpression();
|
||||||
|
|
||||||
if (receiverExpr instanceof JetSimpleNameExpression) {
|
if (receiverExpr instanceof JetSimpleNameExpression) {
|
||||||
BindingContext bindingContext = AnalyzerFacadeWithCache.analyzeFileWithCache((JetFile) element.getContainingFile()).getBindingContext();
|
BindingContext bindingContext =
|
||||||
DeclarationDescriptor descriptor = bindingContext.get(BindingContext.REFERENCE_TARGET, (JetSimpleNameExpression) receiverExpr);
|
AnalyzerFacadeWithCache.analyzeFileWithCache((JetFile) element.getContainingFile()).getBindingContext();
|
||||||
|
DeclarationDescriptor descriptor =
|
||||||
|
bindingContext.get(BindingContext.REFERENCE_TARGET, (JetSimpleNameExpression) receiverExpr);
|
||||||
|
|
||||||
if (descriptor != null) {
|
if (descriptor instanceof ClassDescriptor || descriptor instanceof FunctionDescriptor) {
|
||||||
PsiElement declaration = BindingContextUtils.descriptorToDeclaration(bindingContext, descriptor);
|
return receiverExpr;
|
||||||
|
|
||||||
if (declaration instanceof JetNamedFunction || declaration instanceof JetClass) {
|
|
||||||
return declaration;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return null;
|
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
|
@Override
|
||||||
public void invoke(@NotNull Project project, Editor editor, PsiFile file, DataContext dataContext) {
|
public void invoke(@NotNull Project project, Editor editor, PsiFile file, DataContext dataContext) {
|
||||||
editor.getScrollingModel().scrollToCaret(ScrollType.MAKE_VISIBLE);
|
editor.getScrollingModel().scrollToCaret(ScrollType.MAKE_VISIBLE);
|
||||||
@@ -99,12 +135,9 @@ public class JetChangeSignatureHandler implements ChangeSignatureHandler {
|
|||||||
element = LangDataKeys.PSI_ELEMENT.getData(dataContext);
|
element = LangDataKeys.PSI_ELEMENT.getData(dataContext);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (element != null) {
|
PsiElement elementAtCaret = file.findElementAt(editor.getCaretModel().getOffset());
|
||||||
JetChangeSignatureDialog dialog = createDialog(element, file.findElementAt(editor.getCaretModel().getOffset()), project, editor);
|
if (element != null && elementAtCaret != null) {
|
||||||
|
invokeChangeSignature(element, elementAtCaret, project, editor);
|
||||||
if (dialog != null) {
|
|
||||||
dialog.show();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -112,32 +145,45 @@ public class JetChangeSignatureHandler implements ChangeSignatureHandler {
|
|||||||
public void invoke(@NotNull Project project, @NotNull PsiElement[] elements, @Nullable DataContext dataContext) {
|
public void invoke(@NotNull Project project, @NotNull PsiElement[] elements, @Nullable DataContext dataContext) {
|
||||||
if (elements.length != 1) return;
|
if (elements.length != 1) return;
|
||||||
Editor editor = dataContext != null ? PlatformDataKeys.EDITOR.getData(dataContext) : null;
|
Editor editor = dataContext != null ? PlatformDataKeys.EDITOR.getData(dataContext) : null;
|
||||||
JetChangeSignatureDialog dialog = createDialog(elements[0], elements[0], project, editor);
|
invokeChangeSignature(elements[0], elements[0], project, editor);
|
||||||
|
|
||||||
if (dialog != null) {
|
|
||||||
dialog.show();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Nullable
|
@Nullable
|
||||||
public static JetChangeSignatureDialog createDialog(@NotNull PsiElement element, PsiElement context, Project project, Editor editor) {
|
@Override
|
||||||
if (!CommonRefactoringUtil.checkReadOnlyStatus(project, element)) return null;
|
public String getTargetNotFoundMessage() {
|
||||||
BindingContext bindingContext = AnalyzerFacadeWithCache.analyzeFileWithCache((JetFile)element.getContainingFile()).getBindingContext();
|
return JetRefactoringBundle.message("error.wrong.caret.position.function.or.constructor.name");
|
||||||
DeclarationDescriptor descriptor = bindingContext.get(BindingContext.DECLARATION_TO_DESCRIPTOR, element);
|
}
|
||||||
|
|
||||||
|
@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) {
|
if (descriptor instanceof ClassDescriptor) {
|
||||||
descriptor = ((ClassDescriptor) descriptor).getUnsubstitutedPrimaryConstructor();
|
descriptor = ((ClassDescriptor) descriptor).getUnsubstitutedPrimaryConstructor();
|
||||||
}
|
}
|
||||||
if (descriptor instanceof FunctionDescriptorImpl) {
|
if (descriptor instanceof FunctionDescriptor) {
|
||||||
for (ValueParameterDescriptor parameter : ((FunctionDescriptor) descriptor).getValueParameters()) {
|
for (ValueParameterDescriptor parameter : ((FunctionDescriptor) descriptor).getValueParameters()) {
|
||||||
if (parameter.getVarargElementType() != null) {
|
if (parameter.getVarargElementType() != null) {
|
||||||
String message = JetRefactoringBundle.message("error.cant.refactor.vararg.functions");
|
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 null;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return new JetChangeSignatureDialog(project, new JetFunctionPlatformDescriptorImpl((FunctionDescriptor) descriptor, element), context);
|
return (FunctionDescriptor) descriptor;
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
String message = RefactoringBundle.getCannotRefactorMessage(JetRefactoringBundle.message(
|
String message = RefactoringBundle.getCannotRefactorMessage(JetRefactoringBundle.message(
|
||||||
@@ -146,10 +192,4 @@ public class JetChangeSignatureHandler implements ChangeSignatureHandler {
|
|||||||
return null;
|
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) {
|
private static void findAllMethodUsages(JetChangeInfo changeInfo, Set<UsageInfo> result) {
|
||||||
PsiElement method = changeInfo.getMethod();
|
for (PsiElement affectedFunction : changeInfo.getAffectedFunctions()) {
|
||||||
|
findOneMethodUsages(affectedFunction, changeInfo, result, false);
|
||||||
if (method != null)
|
}
|
||||||
findOneMethodUsages(method, changeInfo, result, false);
|
|
||||||
|
|
||||||
//TODO overridden methods, tests for different parameter names in overridden methods
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private static void findOneMethodUsages(@NotNull PsiElement functionPsi, JetChangeInfo changeInfo,
|
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.FunctionDescriptor;
|
||||||
import org.jetbrains.jet.lang.descriptors.Visibility;
|
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();
|
boolean isConstructor();
|
||||||
|
|
||||||
@Nullable
|
@Nullable
|
||||||
@@ -76,7 +76,7 @@ public class JetParameterInfo implements ParameterInfo {
|
|||||||
return name;
|
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))
|
if (!(inheritedFunction instanceof JetFunction))
|
||||||
return name;
|
return name;
|
||||||
|
|
||||||
@@ -165,7 +165,7 @@ public class JetParameterInfo implements ParameterInfo {
|
|||||||
this.valOrVar = valOrVar;
|
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();
|
StringBuilder buffer = new StringBuilder();
|
||||||
JetValVar valVar = getValOrVar();
|
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");
|
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")
|
@TestMetadata("beforeRemoveConstructorParameter.kt")
|
||||||
public void testRemoveConstructorParameter() throws Exception {
|
public void testRemoveConstructorParameter() throws Exception {
|
||||||
doTest("idea/testData/quickfix/changeSignature/beforeRemoveConstructorParameter.kt");
|
doTest("idea/testData/quickfix/changeSignature/beforeRemoveConstructorParameter.kt");
|
||||||
|
|||||||
+28
-2
@@ -17,6 +17,7 @@
|
|||||||
package org.jetbrains.jet.plugin.refactoring.changeSignature;
|
package org.jetbrains.jet.plugin.refactoring.changeSignature;
|
||||||
|
|
||||||
import com.intellij.openapi.editor.Editor;
|
import com.intellij.openapi.editor.Editor;
|
||||||
|
import com.intellij.openapi.project.Project;
|
||||||
import com.intellij.openapi.util.Disposer;
|
import com.intellij.openapi.util.Disposer;
|
||||||
import com.intellij.openapi.util.text.StringUtil;
|
import com.intellij.openapi.util.text.StringUtil;
|
||||||
import com.intellij.psi.PsiElement;
|
import com.intellij.psi.PsiElement;
|
||||||
@@ -25,16 +26,22 @@ import com.intellij.refactoring.BaseRefactoringProcessor;
|
|||||||
import com.intellij.refactoring.util.CommonRefactoringUtil;
|
import com.intellij.refactoring.util.CommonRefactoringUtil;
|
||||||
import com.intellij.testFramework.LightCodeInsightTestCase;
|
import com.intellij.testFramework.LightCodeInsightTestCase;
|
||||||
import org.jetbrains.annotations.NotNull;
|
import org.jetbrains.annotations.NotNull;
|
||||||
|
import org.jetbrains.jet.lang.descriptors.FunctionDescriptor;
|
||||||
import org.jetbrains.jet.lang.descriptors.Visibilities;
|
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.psi.JetPsiFactory;
|
||||||
|
import org.jetbrains.jet.lang.resolve.BindingContext;
|
||||||
import org.jetbrains.jet.lang.types.lang.KotlinBuiltIns;
|
import org.jetbrains.jet.lang.types.lang.KotlinBuiltIns;
|
||||||
import org.jetbrains.jet.plugin.PluginTestCaseBase;
|
import org.jetbrains.jet.plugin.PluginTestCaseBase;
|
||||||
|
import org.jetbrains.jet.plugin.project.AnalyzerFacadeWithCache;
|
||||||
|
|
||||||
import java.io.File;
|
import java.io.File;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.Collections;
|
import java.util.Collections;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
|
import static org.jetbrains.jet.plugin.refactoring.changeSignature.ChangeSignaturePackage.getChangeSignatureDialog;
|
||||||
|
|
||||||
public class JetChangeSignatureTest extends LightCodeInsightTestCase {
|
public class JetChangeSignatureTest extends LightCodeInsightTestCase {
|
||||||
public void testBadSelection() throws Exception {
|
public void testBadSelection() throws Exception {
|
||||||
configureByFile(getTestName(false) + "Before.kt");
|
configureByFile(getTestName(false) + "Before.kt");
|
||||||
@@ -73,6 +80,11 @@ public class JetChangeSignatureTest extends LightCodeInsightTestCase {
|
|||||||
doTest(changeInfo);
|
doTest(changeInfo);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void testPreferContainedInClass() throws Exception {
|
||||||
|
JetChangeInfo changeInfo = getChangeInfo();
|
||||||
|
assertEquals("param", changeInfo.getNewParameters()[0].getName());
|
||||||
|
}
|
||||||
|
|
||||||
public void testAddConstructorVisibility() throws Exception {
|
public void testAddConstructorVisibility() throws Exception {
|
||||||
JetChangeInfo changeInfo = getChangeInfo();
|
JetChangeInfo changeInfo = getChangeInfo();
|
||||||
changeInfo.setNewVisibility(Visibilities.PROTECTED);
|
changeInfo.setNewVisibility(Visibilities.PROTECTED);
|
||||||
@@ -134,6 +146,13 @@ public class JetChangeSignatureTest extends LightCodeInsightTestCase {
|
|||||||
doTest(changeInfo);
|
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 {
|
public void testFunctionLiteral() throws Exception {
|
||||||
JetChangeInfo changeInfo = getChangeInfo();
|
JetChangeInfo changeInfo = getChangeInfo();
|
||||||
changeInfo.getNewParameters()[1].setName("y1");
|
changeInfo.getNewParameters()[1].setName("y1");
|
||||||
@@ -194,8 +213,15 @@ public class JetChangeSignatureTest extends LightCodeInsightTestCase {
|
|||||||
PsiFile file = getFile();
|
PsiFile file = getFile();
|
||||||
PsiElement element = new JetChangeSignatureHandler().findTargetMember(file, editor);
|
PsiElement element = new JetChangeSignatureHandler().findTargetMember(file, editor);
|
||||||
assertNotNull("Target element is null", element);
|
assertNotNull("Target element is null", element);
|
||||||
JetChangeSignatureDialog dialog =
|
Project project = getProject();
|
||||||
JetChangeSignatureHandler.createDialog(element, file.findElementAt(editor.getCaretModel().getOffset()), getProject(), editor);
|
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);
|
assertNotNull(dialog);
|
||||||
dialog.canRun();
|
dialog.canRun();
|
||||||
Disposer.register(getTestRootDisposable(), dialog.getDisposable());
|
Disposer.register(getTestRootDisposable(), dialog.getDisposable());
|
||||||
|
|||||||
Reference in New Issue
Block a user