From 7b6160b92fc9bd5a6fb12a4d29472304bfe60434 Mon Sep 17 00:00:00 2001 From: Alexey Sedunov Date: Tue, 27 Jan 2015 16:04:35 +0300 Subject: [PATCH] Change Signature: Make JetChangeSignatureData read-only and use JetDelegatingMethodDescriptor for refactoring configuration --- .../quickfix/AddFunctionParametersFix.java | 70 +++++++++++-------- .../ChangeFunctionLiteralSignatureFix.java | 32 ++++++--- .../quickfix/RemoveFunctionParametersFix.java | 24 +++++-- .../CreateParameterFromUsageFix.kt | 7 +- .../changeSignature/JetChangeSignature.kt | 14 ++-- .../changeSignature/JetChangeSignatureData.kt | 22 +----- .../JetChangeSignatureDialog.java | 8 ++- .../JetChangeSignatureHandler.java | 6 +- .../JetMutableMethodDescriptor.kt | 47 +++++++++++++ .../JetChangeSignatureTest.java | 8 +-- 10 files changed, 153 insertions(+), 85 deletions(-) create mode 100644 idea/src/org/jetbrains/kotlin/idea/refactoring/changeSignature/JetMutableMethodDescriptor.kt diff --git a/idea/src/org/jetbrains/kotlin/idea/quickfix/AddFunctionParametersFix.java b/idea/src/org/jetbrains/kotlin/idea/quickfix/AddFunctionParametersFix.java index 8234f6b871d..147c4a21cdf 100644 --- a/idea/src/org/jetbrains/kotlin/idea/quickfix/AddFunctionParametersFix.java +++ b/idea/src/org/jetbrains/kotlin/idea/quickfix/AddFunctionParametersFix.java @@ -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 parameters = functionDescriptor.getValueParameters(); - List arguments = callElement.getValueArguments(); - JetNameValidator validator = new SimpleCollectingValidator(); + public JetMethodDescriptor configure(@NotNull JetMethodDescriptor originalDescriptor, @NotNull final BindingContext bindingContext) { + return ChangeSignaturePackage.modify( + originalDescriptor, + new ExtensionFunction0() { + @Override + public Unit invoke(JetMutableMethodDescriptor descriptor) { + List parameters = functionDescriptor.getValueParameters(); + List 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 diff --git a/idea/src/org/jetbrains/kotlin/idea/quickfix/ChangeFunctionLiteralSignatureFix.java b/idea/src/org/jetbrains/kotlin/idea/quickfix/ChangeFunctionLiteralSignatureFix.java index 98a03639b24..520e0a0ba39 100644 --- a/idea/src/org/jetbrains/kotlin/idea/quickfix/ChangeFunctionLiteralSignatureFix.java +++ b/idea/src/org/jetbrains/kotlin/idea/quickfix/ChangeFunctionLiteralSignatureFix.java @@ -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() { + @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 elements) { + public boolean performSilently(@NotNull Collection elements) { return false; } }, bindingContext, context, getText()); diff --git a/idea/src/org/jetbrains/kotlin/idea/quickfix/RemoveFunctionParametersFix.java b/idea/src/org/jetbrains/kotlin/idea/quickfix/RemoveFunctionParametersFix.java index 3da4f05c56d..ca7b068e499 100644 --- a/idea/src/org/jetbrains/kotlin/idea/quickfix/RemoveFunctionParametersFix.java +++ b/idea/src/org/jetbrains/kotlin/idea/quickfix/RemoveFunctionParametersFix.java @@ -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 parameters = functionDescriptor.getValueParameters(); - changeSignatureData.removeParameter(parameters.indexOf(parameterToRemove)); + public JetMethodDescriptor configure(@NotNull JetMethodDescriptor originalDescriptor, @NotNull BindingContext bindingContext) { + return ChangeSignaturePackage.modify( + originalDescriptor, + new ExtensionFunction0() { + @Override + public Unit invoke(JetMutableMethodDescriptor descriptor) { + List parameters = functionDescriptor.getValueParameters(); + descriptor.removeParameter(parameters.indexOf(parameterToRemove)); + return null; + } + } + ); } @Override diff --git a/idea/src/org/jetbrains/kotlin/idea/quickfix/createFromUsage/createVariable/CreateParameterFromUsageFix.kt b/idea/src/org/jetbrains/kotlin/idea/quickfix/createFromUsage/createVariable/CreateParameterFromUsageFix.kt index 2e8bc775d0e..49bfc790ee5 100644 --- a/idea/src/org/jetbrains/kotlin/idea/quickfix/createFromUsage/createVariable/CreateParameterFromUsageFix.kt +++ b/idea/src/org/jetbrains/kotlin/idea/quickfix/createFromUsage/createVariable/CreateParameterFromUsageFix.kt @@ -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): Boolean = false diff --git a/idea/src/org/jetbrains/kotlin/idea/refactoring/changeSignature/JetChangeSignature.kt b/idea/src/org/jetbrains/kotlin/idea/refactoring/changeSignature/JetChangeSignature.kt index 7dc6055e06b..84403d56709 100644 --- a/idea/src/org/jetbrains/kotlin/idea/refactoring/changeSignature/JetChangeSignature.kt +++ b/idea/src/org/jetbrains/kotlin/idea/refactoring/changeSignature/JetChangeSignature.kt @@ -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): 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) { diff --git a/idea/src/org/jetbrains/kotlin/idea/refactoring/changeSignature/JetChangeSignatureData.kt b/idea/src/org/jetbrains/kotlin/idea/refactoring/changeSignature/JetChangeSignatureData.kt index a286288d8de..d8083e652e7 100644 --- a/idea/src/org/jetbrains/kotlin/idea/refactoring/changeSignature/JetChangeSignatureData.kt +++ b/idea/src/org/jetbrains/kotlin/idea/refactoring/changeSignature/JetChangeSignatureData.kt @@ -42,14 +42,8 @@ public class JetChangeSignatureData( override val baseDeclaration: PsiElement, private val descriptorsForSignatureChange: Collection ) : JetMethodDescriptor { - private val parameters: MutableList - override var receiver: JetParameterInfo? - set(value: JetParameterInfo?) { - if (value != null && value !in parameters) { - parameters.add(value) - } - $receiver = value - } + private val parameters: List + 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() diff --git a/idea/src/org/jetbrains/kotlin/idea/refactoring/changeSignature/JetChangeSignatureDialog.java b/idea/src/org/jetbrains/kotlin/idea/refactoring/changeSignature/JetChangeSignatureDialog.java index 75b6797f267..264f6c12e82 100644 --- a/idea/src/org/jetbrains/kotlin/idea/refactoring/changeSignature/JetChangeSignatureDialog.java +++ b/idea/src/org/jetbrains/kotlin/idea/refactoring/changeSignature/JetChangeSignatureDialog.java @@ -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 diff --git a/idea/src/org/jetbrains/kotlin/idea/refactoring/changeSignature/JetChangeSignatureHandler.java b/idea/src/org/jetbrains/kotlin/idea/refactoring/changeSignature/JetChangeSignatureHandler.java index 296d5066b45..92257e9b551 100644 --- a/idea/src/org/jetbrains/kotlin/idea/refactoring/changeSignature/JetChangeSignatureHandler.java +++ b/idea/src/org/jetbrains/kotlin/idea/refactoring/changeSignature/JetChangeSignatureHandler.java @@ -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 diff --git a/idea/src/org/jetbrains/kotlin/idea/refactoring/changeSignature/JetMutableMethodDescriptor.kt b/idea/src/org/jetbrains/kotlin/idea/refactoring/changeSignature/JetMutableMethodDescriptor.kt new file mode 100644 index 00000000000..8ecd2c86ae1 --- /dev/null +++ b/idea/src/org/jetbrains/kotlin/idea/refactoring/changeSignature/JetMutableMethodDescriptor.kt @@ -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 = 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() + } +} \ No newline at end of file diff --git a/idea/tests/org/jetbrains/kotlin/idea/refactoring/changeSignature/JetChangeSignatureTest.java b/idea/tests/org/jetbrains/kotlin/idea/refactoring/changeSignature/JetChangeSignatureTest.java index 152eae7537f..99f9fbe341d 100644 --- a/idea/tests/org/jetbrains/kotlin/idea/refactoring/changeSignature/JetChangeSignatureTest.java +++ b/idea/tests/org/jetbrains/kotlin/idea/refactoring/changeSignature/JetChangeSignatureTest.java @@ -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 elements) { + public boolean performSilently(@NotNull Collection elements) { return true; } };