Change Signature: Make JetChangeSignatureData read-only and use JetDelegatingMethodDescriptor for refactoring configuration

This commit is contained in:
Alexey Sedunov
2015-01-27 16:04:35 +03:00
parent fecfc93e63
commit 7b6160b92f
10 changed files with 153 additions and 85 deletions
@@ -23,6 +23,8 @@ import com.intellij.psi.PsiFile;
import com.intellij.psi.PsiReference;
import com.intellij.psi.search.searches.ReferencesSearch;
import com.intellij.psi.util.PsiTreeUtil;
import kotlin.ExtensionFunction0;
import kotlin.Unit;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.kotlin.descriptors.ConstructorDescriptor;
import org.jetbrains.kotlin.descriptors.FunctionDescriptor;
@@ -31,9 +33,7 @@ import org.jetbrains.kotlin.idea.JetBundle;
import org.jetbrains.kotlin.idea.caches.resolve.ResolvePackage;
import org.jetbrains.kotlin.idea.refactoring.JetNameValidator;
import org.jetbrains.kotlin.idea.refactoring.SimpleCollectingValidator;
import org.jetbrains.kotlin.idea.refactoring.changeSignature.JetChangeSignatureConfiguration;
import org.jetbrains.kotlin.idea.refactoring.changeSignature.JetChangeSignatureData;
import org.jetbrains.kotlin.idea.refactoring.changeSignature.JetParameterInfo;
import org.jetbrains.kotlin.idea.refactoring.changeSignature.*;
import org.jetbrains.kotlin.idea.util.IdeDescriptorRenderers;
import org.jetbrains.kotlin.psi.JetCallElement;
import org.jetbrains.kotlin.psi.JetExpression;
@@ -120,39 +120,47 @@ public class AddFunctionParametersFix extends ChangeFunctionSignatureFix {
private JetChangeSignatureConfiguration addParameterConfiguration() {
return new JetChangeSignatureConfiguration() {
@NotNull
@Override
public void configure(@NotNull JetChangeSignatureData changeSignatureData, @NotNull BindingContext bindingContext) {
List<ValueParameterDescriptor> parameters = functionDescriptor.getValueParameters();
List<? extends ValueArgument> arguments = callElement.getValueArguments();
JetNameValidator validator = new SimpleCollectingValidator();
public JetMethodDescriptor configure(@NotNull JetMethodDescriptor originalDescriptor, @NotNull final BindingContext bindingContext) {
return ChangeSignaturePackage.modify(
originalDescriptor,
new ExtensionFunction0<JetMutableMethodDescriptor, Unit>() {
@Override
public Unit invoke(JetMutableMethodDescriptor descriptor) {
List<ValueParameterDescriptor> parameters = functionDescriptor.getValueParameters();
List<? extends ValueArgument> arguments = callElement.getValueArguments();
JetNameValidator validator = new SimpleCollectingValidator();
for (int i = 0; i < arguments.size(); i ++) {
ValueArgument argument = arguments.get(i);
JetExpression expression = argument.getArgumentExpression();
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 (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.DEFAULT.isSubtypeOf(argumentType, parameterType)) {
changeSignatureData.getParameters().get(i).setCurrentTypeText(
IdeDescriptorRenderers.SOURCE_CODE.renderType(argumentType)
);
typesToShorten.add(argumentType);
if (argumentType != null && !JetTypeChecker.DEFAULT.isSubtypeOf(argumentType, parameterType)) {
descriptor.getParameters().get(i).setCurrentTypeText(IdeDescriptorRenderers.SOURCE_CODE.renderType(argumentType));
typesToShorten.add(argumentType);
}
}
else {
JetParameterInfo parameterInfo = getNewParameterInfo(bindingContext, argument, validator);
typesToShorten.add(parameterInfo.getOriginalType());
if (expression != null) {
parameterInfo.setDefaultValueForCall(expression.getText());
}
descriptor.addParameter(parameterInfo);
}
}
return null;
}
}
}
else {
JetParameterInfo parameterInfo = getNewParameterInfo(bindingContext, argument, validator);
typesToShorten.add(parameterInfo.getOriginalType());
if (expression != null) {
parameterInfo.setDefaultValueForCall(expression.getText());
}
changeSignatureData.addParameter(parameterInfo);
}
}
);
}
@Override
@@ -19,6 +19,8 @@ package org.jetbrains.kotlin.idea.quickfix;
import com.intellij.openapi.editor.Editor;
import com.intellij.openapi.project.Project;
import com.intellij.psi.PsiElement;
import kotlin.ExtensionFunction0;
import kotlin.Unit;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.kotlin.descriptors.FunctionDescriptor;
import org.jetbrains.kotlin.idea.JetBundle;
@@ -26,9 +28,7 @@ import org.jetbrains.kotlin.idea.caches.resolve.ResolvePackage;
import org.jetbrains.kotlin.idea.refactoring.JetNameSuggester;
import org.jetbrains.kotlin.idea.refactoring.JetNameValidator;
import org.jetbrains.kotlin.idea.refactoring.SimpleCollectingValidator;
import org.jetbrains.kotlin.idea.refactoring.changeSignature.JetChangeSignatureConfiguration;
import org.jetbrains.kotlin.idea.refactoring.changeSignature.JetChangeSignatureData;
import org.jetbrains.kotlin.idea.refactoring.changeSignature.JetParameterInfo;
import org.jetbrains.kotlin.idea.refactoring.changeSignature.*;
import org.jetbrains.kotlin.psi.JetFile;
import org.jetbrains.kotlin.psi.JetFunctionLiteral;
import org.jetbrains.kotlin.resolve.BindingContext;
@@ -60,18 +60,28 @@ public class ChangeFunctionLiteralSignatureFix extends ChangeFunctionSignatureFi
protected void invoke(@NotNull Project project, Editor editor, JetFile file) {
BindingContext bindingContext = ResolvePackage.analyzeFully(file);
runChangeSignature(project, functionDescriptor, new JetChangeSignatureConfiguration() {
@NotNull
@Override
public void configure(@NotNull JetChangeSignatureData changeSignatureData, @NotNull BindingContext bindingContext) {
JetNameValidator validator = new SimpleCollectingValidator();
changeSignatureData.clearParameters();
for (JetType type : parameterTypes) {
String name = JetNameSuggester.suggestNames(type, validator, "param")[0];
changeSignatureData.addParameter(new JetParameterInfo(-1, name, type, null, "", null, null));
}
public JetMethodDescriptor configure(@NotNull JetMethodDescriptor originalDescriptor, @NotNull BindingContext bindingContext) {
return ChangeSignaturePackage.modify(
originalDescriptor,
new ExtensionFunction0<JetMutableMethodDescriptor, Unit>() {
@Override
public Unit invoke(JetMutableMethodDescriptor descriptor) {
JetNameValidator validator = new SimpleCollectingValidator();
descriptor.clearParameters();
for (JetType type : parameterTypes) {
String name = JetNameSuggester.suggestNames(type, validator, "param")[0];
descriptor.addParameter(new JetParameterInfo(-1, name, type, null, "", null, null));
}
return null;
}
}
);
}
@Override
public boolean performSilently(Collection<? extends PsiElement> elements) {
public boolean performSilently(@NotNull Collection<? extends PsiElement> elements) {
return false;
}
}, bindingContext, context, getText());
@@ -19,13 +19,17 @@ package org.jetbrains.kotlin.idea.quickfix;
import com.intellij.openapi.editor.Editor;
import com.intellij.openapi.project.Project;
import com.intellij.psi.PsiElement;
import kotlin.ExtensionFunction0;
import kotlin.Unit;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.kotlin.descriptors.FunctionDescriptor;
import org.jetbrains.kotlin.descriptors.ValueParameterDescriptor;
import org.jetbrains.kotlin.idea.JetBundle;
import org.jetbrains.kotlin.idea.caches.resolve.ResolvePackage;
import org.jetbrains.kotlin.idea.refactoring.changeSignature.ChangeSignaturePackage;
import org.jetbrains.kotlin.idea.refactoring.changeSignature.JetChangeSignatureConfiguration;
import org.jetbrains.kotlin.idea.refactoring.changeSignature.JetChangeSignatureData;
import org.jetbrains.kotlin.idea.refactoring.changeSignature.JetMutableMethodDescriptor;
import org.jetbrains.kotlin.idea.refactoring.changeSignature.JetMethodDescriptor;
import org.jetbrains.kotlin.psi.JetFile;
import org.jetbrains.kotlin.resolve.BindingContext;
@@ -56,12 +60,20 @@ public class RemoveFunctionParametersFix extends ChangeFunctionSignatureFix {
protected void invoke(@NotNull Project project, Editor editor, JetFile file) {
BindingContext bindingContext = ResolvePackage.analyzeFully(file);
runChangeSignature(project, functionDescriptor, new JetChangeSignatureConfiguration() {
@NotNull
@Override
public void configure(
@NotNull JetChangeSignatureData changeSignatureData, @NotNull BindingContext bindingContext
) {
List<ValueParameterDescriptor> parameters = functionDescriptor.getValueParameters();
changeSignatureData.removeParameter(parameters.indexOf(parameterToRemove));
public JetMethodDescriptor configure(@NotNull JetMethodDescriptor originalDescriptor, @NotNull BindingContext bindingContext) {
return ChangeSignaturePackage.modify(
originalDescriptor,
new ExtensionFunction0<JetMutableMethodDescriptor, Unit>() {
@Override
public Unit invoke(JetMutableMethodDescriptor descriptor) {
List<ValueParameterDescriptor> parameters = functionDescriptor.getValueParameters();
descriptor.removeParameter(parameters.indexOf(parameterToRemove));
return null;
}
}
);
}
@Override
@@ -23,12 +23,13 @@ import com.intellij.openapi.project.Project
import com.intellij.openapi.editor.Editor
import org.jetbrains.kotlin.psi.JetFile
import org.jetbrains.kotlin.idea.refactoring.changeSignature.JetChangeSignatureConfiguration
import org.jetbrains.kotlin.idea.refactoring.changeSignature.JetChangeSignatureData
import org.jetbrains.kotlin.resolve.BindingContext
import com.intellij.psi.PsiElement
import org.jetbrains.kotlin.idea.refactoring.changeSignature.runChangeSignature
import org.jetbrains.kotlin.idea.refactoring.changeSignature.JetParameterInfo
import org.jetbrains.kotlin.descriptors.FunctionDescriptor
import org.jetbrains.kotlin.idea.refactoring.changeSignature.JetMethodDescriptor
import org.jetbrains.kotlin.idea.refactoring.changeSignature.modify
public class CreateParameterFromUsageFix(
val functionDescriptor: FunctionDescriptor,
@@ -42,8 +43,8 @@ public class CreateParameterFromUsageFix(
override fun invoke(project: Project, editor: Editor?, file: JetFile?) {
val config = object : JetChangeSignatureConfiguration {
override fun configure(changeSignatureData: JetChangeSignatureData, bindingContext: BindingContext) {
changeSignatureData.addParameter(parameterInfo)
override fun configure(originalDescriptor: JetMethodDescriptor, bindingContext: BindingContext): JetMethodDescriptor {
return originalDescriptor.modify { addParameter(parameterInfo) }
}
override fun performSilently(affectedFunctions: Collection<PsiElement>): Boolean = false
@@ -38,13 +38,19 @@ import org.jetbrains.kotlin.resolve.OverrideResolver
import org.jetbrains.kotlin.idea.refactoring.CallableRefactoring
public trait JetChangeSignatureConfiguration {
fun configure(changeSignatureData: JetChangeSignatureData, bindingContext: BindingContext)
fun configure(originalDescriptor: JetMethodDescriptor, bindingContext: BindingContext): JetMethodDescriptor
fun performSilently(affectedFunctions: Collection<PsiElement>): Boolean {
return false
}
}
fun JetMethodDescriptor.modify(action: JetMutableMethodDescriptor.() -> Unit): JetMethodDescriptor {
val newDescriptor = JetMutableMethodDescriptor(this)
newDescriptor.action()
return newDescriptor
}
public fun runChangeSignature(project: Project,
functionDescriptor: FunctionDescriptor,
configuration: JetChangeSignatureConfiguration,
@@ -97,9 +103,9 @@ public class JetChangeSignature(project: Project,
return null
}
val changeSignatureData = JetChangeSignatureData(baseDescriptor, functionDeclaration, descriptorsForSignatureChange)
configuration.configure(changeSignatureData, bindingContext)
return JetChangeSignatureDialog(project, changeSignatureData, defaultValueContext, commandName)
val originalDescriptor = JetChangeSignatureData(baseDescriptor, functionDeclaration, descriptorsForSignatureChange)
val adjustedDescriptor = configuration.configure(originalDescriptor, bindingContext)
return JetChangeSignatureDialog(project, adjustedDescriptor, defaultValueContext, commandName)
}
private fun performRefactoringSilently(dialog: JetChangeSignatureDialog) {
@@ -42,14 +42,8 @@ public class JetChangeSignatureData(
override val baseDeclaration: PsiElement,
private val descriptorsForSignatureChange: Collection<FunctionDescriptor>
) : JetMethodDescriptor {
private val parameters: MutableList<JetParameterInfo>
override var receiver: JetParameterInfo?
set(value: JetParameterInfo?) {
if (value != null && value !in parameters) {
parameters.add(value)
}
$receiver = value
}
private val parameters: List<JetParameterInfo>
override val receiver: JetParameterInfo?
;{
$receiver = createReceiverInfoIfNeeded()
@@ -120,18 +114,6 @@ public class JetChangeSignatureData(
return parameters
}
public fun addParameter(parameter: JetParameterInfo) {
parameters.add(parameter)
}
public fun removeParameter(index: Int) {
parameters.remove(index)
}
public fun clearParameters() {
parameters.clear()
}
override fun getName(): String {
if (baseDescriptor is ConstructorDescriptor) {
return baseDescriptor.getContainingDeclaration().getName().asString()
@@ -452,9 +452,11 @@ public class JetChangeSignatureDialog extends ChangeSignatureDialogBase<
}
String returnTypeText = myReturnTypeCodeFragment != null ? myReturnTypeCodeFragment.getText().trim() : "";
return new JetChangeInfo(myMethod, getMethodName(), getReturnType(), returnTypeText,
getVisibility(), parameters, myParametersTableModel.getReceiver(), myDefaultValueContext
);
JetMethodDescriptor descriptor = myMethod instanceof JetMutableMethodDescriptor
? ((JetMutableMethodDescriptor) myMethod).getOriginal()
: myMethod;
return new JetChangeInfo(descriptor, getMethodName(), getReturnType(), returnTypeText,
getVisibility(), parameters, myParametersTableModel.getReceiver(), myDefaultValueContext);
}
@Override
@@ -138,11 +138,11 @@ public class JetChangeSignatureHandler implements ChangeSignatureHandler {
private static JetChangeSignatureConfiguration emptyConfiguration() {
return new JetChangeSignatureConfiguration() {
@NotNull
@Override
public void configure(
@NotNull JetChangeSignatureData changeSignatureData, @NotNull BindingContext bindingContext
) {
public JetMethodDescriptor configure(@NotNull JetMethodDescriptor originalDescriptor, @NotNull BindingContext bindingContext) {
//do nothing
return originalDescriptor;
}
@Override
@@ -0,0 +1,47 @@
/*
* Copyright 2010-2015 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.kotlin.idea.refactoring.changeSignature
import org.jetbrains.kotlin.descriptors.Visibility
public class JetMutableMethodDescriptor(val original: JetMethodDescriptor): JetMethodDescriptor by original {
private val parameters: MutableList<JetParameterInfo> = original.getParameters()
override var receiver: JetParameterInfo? = original.receiver
set(value: JetParameterInfo?) {
if (value != null && value !in parameters) {
parameters.add(value)
}
$receiver = value
}
public fun addParameter(parameter: JetParameterInfo) {
parameters.add(parameter)
}
public fun removeParameter(index: Int) {
parameters.remove(index)
}
public fun clearParameters() {
parameters.clear()
}
override fun getVisibility(): Visibility? {
return original.getVisibility()
}
}
@@ -227,14 +227,14 @@ public class JetChangeSignatureTest extends KotlinCodeInsightTestCase {
JetChangeInfo changeInfo = getChangeInfo();
JetElement method = (JetElement) changeInfo.getMethod();
JetChangeSignatureConfiguration empty = new JetChangeSignatureConfiguration() {
@NotNull
@Override
public void configure(
JetChangeSignatureData data, BindingContext bindingContext
) {
public JetMethodDescriptor configure(@NotNull JetMethodDescriptor originalDescriptor, @NotNull BindingContext bindingContext) {
return originalDescriptor;
}
@Override
public boolean performSilently(Collection<? extends PsiElement> elements) {
public boolean performSilently(@NotNull Collection<? extends PsiElement> elements) {
return true;
}
};