Introduce Parameter: Implement "Introduce lambda parameter"
This commit is contained in:
@@ -617,7 +617,8 @@ fun main(args: Array<String>) {
|
|||||||
model("refactoring/introduceVariable", extension = "kt", testMethod = "doIntroduceVariableTest")
|
model("refactoring/introduceVariable", extension = "kt", testMethod = "doIntroduceVariableTest")
|
||||||
model("refactoring/extractFunction", extension = "kt", testMethod = "doExtractFunctionTest")
|
model("refactoring/extractFunction", extension = "kt", testMethod = "doExtractFunctionTest")
|
||||||
model("refactoring/introduceProperty", extension = "kt", testMethod = "doIntroducePropertyTest")
|
model("refactoring/introduceProperty", extension = "kt", testMethod = "doIntroducePropertyTest")
|
||||||
model("refactoring/introduceParameter", extension = "kt", testMethod = "doIntroduceParameterTest")
|
model("refactoring/introduceParameter", extension = "kt", testMethod = "doIntroduceSimpleParameterTest")
|
||||||
|
model("refactoring/introduceLambdaParameter", extension = "kt", testMethod = "doIntroduceLambdaParameterTest")
|
||||||
}
|
}
|
||||||
|
|
||||||
testClass(javaClass<AbstractSelectExpressionForDebuggerTest>()) {
|
testClass(javaClass<AbstractSelectExpressionForDebuggerTest>()) {
|
||||||
|
|||||||
@@ -106,6 +106,13 @@
|
|||||||
<add-to-group group-id="IntroduceActionsGroup" anchor="after" relative-to-action="IntroduceField"/>
|
<add-to-group group-id="IntroduceActionsGroup" anchor="after" relative-to-action="IntroduceField"/>
|
||||||
</action>
|
</action>
|
||||||
|
|
||||||
|
<action id="IntroduceLambdaParameter"
|
||||||
|
class="org.jetbrains.kotlin.idea.refactoring.introduce.introduceParameter.IntroduceLambdaParameterAction"
|
||||||
|
text="Introduce Lambda Parameter...">
|
||||||
|
<keyboard-shortcut keymap="$default" first-keystroke="control shift P"/>
|
||||||
|
<add-to-group group-id="IntroduceActionsGroup" anchor="after" relative-to-action="IntroduceParameter"/>
|
||||||
|
</action>
|
||||||
|
|
||||||
<action id="CopyAsDiagnosticTest" class="org.jetbrains.kotlin.idea.actions.internal.CopyAsDiagnosticTestAction"
|
<action id="CopyAsDiagnosticTest" class="org.jetbrains.kotlin.idea.actions.internal.CopyAsDiagnosticTestAction"
|
||||||
text="Copy Current File As Diagnostic Test">
|
text="Copy Current File As Diagnostic Test">
|
||||||
<keyboard-shortcut keymap="$default" first-keystroke="control alt shift T"/>
|
<keyboard-shortcut keymap="$default" first-keystroke="control alt shift T"/>
|
||||||
|
|||||||
+1
-1
@@ -91,7 +91,7 @@ fun getFunctionForExtractedFragment(
|
|||||||
val options = ExtractionOptions(inferUnitTypeForUnusedValues = false,
|
val options = ExtractionOptions(inferUnitTypeForUnusedValues = false,
|
||||||
enableListBoxing = true,
|
enableListBoxing = true,
|
||||||
allowSpecialClassNames = true)
|
allowSpecialClassNames = true)
|
||||||
val analysisResult = ExtractionData(tmpFile, newDebugExpression.toRange(), targetSibling, options).performAnalysis()
|
val analysisResult = ExtractionData(tmpFile, newDebugExpression.toRange(), targetSibling, null, options).performAnalysis()
|
||||||
if (analysisResult.status != Status.SUCCESS) {
|
if (analysisResult.status != Status.SUCCESS) {
|
||||||
throw EvaluateExceptionUtil.createEvaluateException(getErrorMessageForExtractFunctionResult(analysisResult))
|
throw EvaluateExceptionUtil.createEvaluateException(getErrorMessageForExtractFunctionResult(analysisResult))
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -24,6 +24,7 @@ import org.jetbrains.annotations.NotNull;
|
|||||||
import org.jetbrains.annotations.Nullable;
|
import org.jetbrains.annotations.Nullable;
|
||||||
import org.jetbrains.kotlin.idea.refactoring.changeSignature.JetChangeSignatureHandler;
|
import org.jetbrains.kotlin.idea.refactoring.changeSignature.JetChangeSignatureHandler;
|
||||||
import org.jetbrains.kotlin.idea.refactoring.introduce.extractFunction.ExtractKotlinFunctionHandler;
|
import org.jetbrains.kotlin.idea.refactoring.introduce.extractFunction.ExtractKotlinFunctionHandler;
|
||||||
|
import org.jetbrains.kotlin.idea.refactoring.introduce.introduceParameter.KotlinIntroduceLambdaParameterHandler;
|
||||||
import org.jetbrains.kotlin.idea.refactoring.introduce.introduceParameter.KotlinIntroduceParameterHandler;
|
import org.jetbrains.kotlin.idea.refactoring.introduce.introduceParameter.KotlinIntroduceParameterHandler;
|
||||||
import org.jetbrains.kotlin.idea.refactoring.introduce.introduceProperty.KotlinIntroducePropertyHandler;
|
import org.jetbrains.kotlin.idea.refactoring.introduce.introduceProperty.KotlinIntroducePropertyHandler;
|
||||||
import org.jetbrains.kotlin.idea.refactoring.introduce.introduceVariable.KotlinIntroduceVariableHandler;
|
import org.jetbrains.kotlin.idea.refactoring.introduce.introduceVariable.KotlinIntroduceVariableHandler;
|
||||||
@@ -47,6 +48,11 @@ public class JetRefactoringSupportProvider extends RefactoringSupportProvider {
|
|||||||
return new KotlinIntroduceParameterHandler();
|
return new KotlinIntroduceParameterHandler();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@NotNull
|
||||||
|
public RefactoringActionHandler getIntroduceLambdaParameterHandler() {
|
||||||
|
return new KotlinIntroduceLambdaParameterHandler();
|
||||||
|
}
|
||||||
|
|
||||||
@NotNull
|
@NotNull
|
||||||
public RefactoringActionHandler getIntroducePropertyHandler() {
|
public RefactoringActionHandler getIntroducePropertyHandler() {
|
||||||
return new KotlinIntroducePropertyHandler();
|
return new KotlinIntroducePropertyHandler();
|
||||||
|
|||||||
+24
-16
@@ -210,16 +210,29 @@ public class KotlinExtractFunctionDialog extends DialogWrapper {
|
|||||||
|
|
||||||
@NotNull
|
@NotNull
|
||||||
private ExtractableCodeDescriptor createDescriptor() {
|
private ExtractableCodeDescriptor createDescriptor() {
|
||||||
ExtractableCodeDescriptor descriptor = originalDescriptor.getDescriptor();
|
return createNewDescriptor(originalDescriptor.getDescriptor(),
|
||||||
|
getFunctionName(),
|
||||||
|
getVisibility(),
|
||||||
|
parameterTablePanel.getParameterInfos());
|
||||||
|
}
|
||||||
|
|
||||||
List<KotlinParameterTablePanel.ParameterInfo> parameterInfos = parameterTablePanel.getParameterInfos();
|
@NotNull
|
||||||
|
public ExtractionGeneratorConfiguration getCurrentConfiguration() {
|
||||||
|
return new ExtractionGeneratorConfiguration(currentDescriptor, ExtractionGeneratorOptions.DEFAULT);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static ExtractableCodeDescriptor createNewDescriptor(
|
||||||
|
@NotNull ExtractableCodeDescriptor originalDescriptor,
|
||||||
|
@NotNull String newName,
|
||||||
|
@NotNull String newVisibility,
|
||||||
|
@NotNull List<KotlinParameterTablePanel.ParameterInfo> newParameterInfos
|
||||||
|
) {
|
||||||
Map<Parameter, Parameter> oldToNewParameters = ContainerUtil.newLinkedHashMap();
|
Map<Parameter, Parameter> oldToNewParameters = ContainerUtil.newLinkedHashMap();
|
||||||
for (KotlinParameterTablePanel.ParameterInfo parameterInfo : parameterInfos) {
|
for (KotlinParameterTablePanel.ParameterInfo parameterInfo : newParameterInfos) {
|
||||||
oldToNewParameters.put(parameterInfo.getOriginalParameter(), parameterInfo.toParameter());
|
oldToNewParameters.put(parameterInfo.getOriginalParameter(), parameterInfo.toParameter());
|
||||||
}
|
}
|
||||||
|
|
||||||
ControlFlow controlFlow = descriptor.getControlFlow();
|
ControlFlow controlFlow = originalDescriptor.getControlFlow();
|
||||||
List<OutputValue> outputValues = new ArrayList<OutputValue>(controlFlow.getOutputValues());
|
List<OutputValue> outputValues = new ArrayList<OutputValue>(controlFlow.getOutputValues());
|
||||||
for (int i = 0; i < outputValues.size(); i++) {
|
for (int i = 0; i < outputValues.size(); i++) {
|
||||||
OutputValue outputValue = outputValues.get(i);
|
OutputValue outputValue = outputValues.get(i);
|
||||||
@@ -231,7 +244,7 @@ public class KotlinExtractFunctionDialog extends DialogWrapper {
|
|||||||
controlFlow = new ControlFlow(outputValues, controlFlow.getBoxerFactory(), controlFlow.getDeclarationsToCopy());
|
controlFlow = new ControlFlow(outputValues, controlFlow.getBoxerFactory(), controlFlow.getDeclarationsToCopy());
|
||||||
|
|
||||||
Map<Integer, Replacement> replacementMap = ContainerUtil.newHashMap();
|
Map<Integer, Replacement> replacementMap = ContainerUtil.newHashMap();
|
||||||
for (Map.Entry<Integer, Replacement> e : descriptor.getReplacementMap().entrySet()) {
|
for (Map.Entry<Integer, Replacement> e : originalDescriptor.getReplacementMap().entrySet()) {
|
||||||
Integer offset = e.getKey();
|
Integer offset = e.getKey();
|
||||||
Replacement replacement = e.getValue();
|
Replacement replacement = e.getValue();
|
||||||
|
|
||||||
@@ -250,20 +263,15 @@ public class KotlinExtractFunctionDialog extends DialogWrapper {
|
|||||||
}
|
}
|
||||||
|
|
||||||
return new ExtractableCodeDescriptor(
|
return new ExtractableCodeDescriptor(
|
||||||
descriptor.getExtractionData(),
|
originalDescriptor.getExtractionData(),
|
||||||
descriptor.getOriginalContext(),
|
originalDescriptor.getOriginalContext(),
|
||||||
Collections.singletonList(getFunctionName()),
|
Collections.singletonList(newName),
|
||||||
getVisibility(),
|
newVisibility,
|
||||||
ContainerUtil.newArrayList(oldToNewParameters.values()),
|
ContainerUtil.newArrayList(oldToNewParameters.values()),
|
||||||
descriptor.getReceiverParameter(),
|
originalDescriptor.getReceiverParameter(),
|
||||||
descriptor.getTypeParameters(),
|
originalDescriptor.getTypeParameters(),
|
||||||
replacementMap,
|
replacementMap,
|
||||||
controlFlow
|
controlFlow
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
@NotNull
|
|
||||||
public ExtractionGeneratorConfiguration getCurrentConfiguration() {
|
|
||||||
return new ExtractionGeneratorConfiguration(currentDescriptor, ExtractionGeneratorOptions.DEFAULT);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|||||||
+6
@@ -313,6 +313,12 @@ enum class ExtractionTarget(val name: String) {
|
|||||||
override fun isAvailable(descriptor: ExtractableCodeDescriptor) = true
|
override fun isAvailable(descriptor: ExtractableCodeDescriptor) = true
|
||||||
}
|
}
|
||||||
|
|
||||||
|
FAKE_LAMBDALIKE_FUNCTION : ExtractionTarget("lambda parameter") {
|
||||||
|
override fun isAvailable(descriptor: ExtractableCodeDescriptor): Boolean {
|
||||||
|
return checkSimpleControlFlow(descriptor) || descriptor.controlFlow.outputValues.isEmpty()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
PROPERTY_WITH_INITIALIZER : ExtractionTarget("property with initializer") {
|
PROPERTY_WITH_INITIALIZER : ExtractionTarget("property with initializer") {
|
||||||
override fun isAvailable(descriptor: ExtractableCodeDescriptor): Boolean {
|
override fun isAvailable(descriptor: ExtractableCodeDescriptor): Boolean {
|
||||||
return checkSignatureAndParent(descriptor)
|
return checkSignatureAndParent(descriptor)
|
||||||
|
|||||||
+1
@@ -72,6 +72,7 @@ data class ExtractionData(
|
|||||||
val originalFile: JetFile,
|
val originalFile: JetFile,
|
||||||
val originalRange: JetPsiRange,
|
val originalRange: JetPsiRange,
|
||||||
val targetSibling: PsiElement,
|
val targetSibling: PsiElement,
|
||||||
|
val duplicateContainer: PsiElement? = null,
|
||||||
val options: ExtractionOptions = ExtractionOptions.DEFAULT
|
val options: ExtractionOptions = ExtractionOptions.DEFAULT
|
||||||
) {
|
) {
|
||||||
val project: Project = originalFile.getProject()
|
val project: Project = originalFile.getProject()
|
||||||
|
|||||||
+21
-11
@@ -61,7 +61,10 @@ fun ExtractionGeneratorConfiguration.getDeclarationText(
|
|||||||
throw IllegalArgumentException("Can't generate ${extractionTarget.name}: ${descriptor.extractionData.codeFragmentText}")
|
throw IllegalArgumentException("Can't generate ${extractionTarget.name}: ${descriptor.extractionData.codeFragmentText}")
|
||||||
}
|
}
|
||||||
|
|
||||||
val builderTarget = if (extractionTarget == ExtractionTarget.FUNCTION) CallableBuilder.Target.FUNCTION else CallableBuilder.Target.READ_ONLY_PROPERTY
|
val builderTarget = when (extractionTarget) {
|
||||||
|
ExtractionTarget.FUNCTION, ExtractionTarget.FAKE_LAMBDALIKE_FUNCTION -> CallableBuilder.Target.FUNCTION
|
||||||
|
else -> CallableBuilder.Target.READ_ONLY_PROPERTY
|
||||||
|
}
|
||||||
return CallableBuilder(builderTarget).let { builder ->
|
return CallableBuilder(builderTarget).let { builder ->
|
||||||
builder.modifier(descriptor.visibility)
|
builder.modifier(descriptor.visibility)
|
||||||
|
|
||||||
@@ -95,7 +98,9 @@ fun ExtractionGeneratorConfiguration.getDeclarationText(
|
|||||||
if (withBody) {
|
if (withBody) {
|
||||||
val bodyText = descriptor.extractionData.codeFragmentText
|
val bodyText = descriptor.extractionData.codeFragmentText
|
||||||
when (extractionTarget) {
|
when (extractionTarget) {
|
||||||
ExtractionTarget.FUNCTION, ExtractionTarget.PROPERTY_WITH_GETTER -> builder.blockBody(bodyText)
|
ExtractionTarget.FUNCTION,
|
||||||
|
ExtractionTarget.FAKE_LAMBDALIKE_FUNCTION,
|
||||||
|
ExtractionTarget.PROPERTY_WITH_GETTER -> builder.blockBody(bodyText)
|
||||||
ExtractionTarget.PROPERTY_WITH_INITIALIZER -> builder.initializer(bodyText)
|
ExtractionTarget.PROPERTY_WITH_INITIALIZER -> builder.initializer(bodyText)
|
||||||
ExtractionTarget.LAZY_PROPERTY -> builder.lazyBody(bodyText)
|
ExtractionTarget.LAZY_PROPERTY -> builder.lazyBody(bodyText)
|
||||||
}
|
}
|
||||||
@@ -186,7 +191,7 @@ fun ExtractableCodeDescriptor.findDuplicates(): List<DuplicateInfo> {
|
|||||||
|
|
||||||
val unifier = JetPsiUnifier(unifierParameters, true)
|
val unifier = JetPsiUnifier(unifierParameters, true)
|
||||||
|
|
||||||
val scopeElement = extractionData.targetSibling.getParent() ?: return Collections.emptyList()
|
val scopeElement = extractionData.duplicateContainer ?: extractionData.targetSibling.getParent() ?: return Collections.emptyList()
|
||||||
val originalTextRange = extractionData.originalRange.getTextRange()
|
val originalTextRange = extractionData.originalRange.getTextRange()
|
||||||
return extractionData
|
return extractionData
|
||||||
.originalRange
|
.originalRange
|
||||||
@@ -513,13 +518,15 @@ fun ExtractionGeneratorConfiguration.generateDeclaration(
|
|||||||
val returnExpression = descriptor.controlFlow.outputValueBoxer.getReturnExpression(getReturnArguments(defaultExpression), psiFactory)
|
val returnExpression = descriptor.controlFlow.outputValueBoxer.getReturnExpression(getReturnArguments(defaultExpression), psiFactory)
|
||||||
if (returnExpression == null) return
|
if (returnExpression == null) return
|
||||||
|
|
||||||
if (generatorOptions.target == ExtractionTarget.LAZY_PROPERTY) {
|
when(generatorOptions.target) {
|
||||||
// In the case of lazy property absence of default value means that output values are of OutputValue.Initializer type
|
ExtractionTarget.LAZY_PROPERTY, ExtractionTarget.FAKE_LAMBDALIKE_FUNCTION -> {
|
||||||
// We just add resulting expressions without return, since returns are prohibited in the body of lazy property
|
// In the case of lazy property absence of default value means that output values are of OutputValue.Initializer type
|
||||||
if (defaultValue == null) {
|
// We just add resulting expressions without return, since returns are prohibited in the body of lazy property
|
||||||
body.appendElement(returnExpression.getReturnedExpression()!!)
|
if (defaultValue == null) {
|
||||||
|
body.appendElement(returnExpression.getReturnedExpression()!!)
|
||||||
|
}
|
||||||
|
return
|
||||||
}
|
}
|
||||||
return
|
|
||||||
}
|
}
|
||||||
|
|
||||||
when {
|
when {
|
||||||
@@ -579,7 +586,8 @@ fun ExtractionGeneratorConfiguration.generateDeclaration(
|
|||||||
marginalCandidate.parents().first { it.getParent() == targetParent }
|
marginalCandidate.parents().first { it.getParent() == targetParent }
|
||||||
}
|
}
|
||||||
|
|
||||||
val declaration = createDeclaration().let { if (generatorOptions.inTempFile) it else insertDeclaration(it, anchor) }
|
val shouldInsert = !(generatorOptions.inTempFile || generatorOptions.target == ExtractionTarget.FAKE_LAMBDALIKE_FUNCTION)
|
||||||
|
val declaration = createDeclaration().let { if (shouldInsert) insertDeclaration(it, anchor) else it }
|
||||||
adjustDeclarationBody(declaration)
|
adjustDeclarationBody(declaration)
|
||||||
|
|
||||||
if (declaration is JetNamedFunction && declaration.getContainingJetFile().suppressDiagnosticsInDebugMode) {
|
if (declaration is JetNamedFunction && declaration.getContainingJetFile().suppressDiagnosticsInDebugMode) {
|
||||||
@@ -597,7 +605,9 @@ fun ExtractionGeneratorConfiguration.generateDeclaration(
|
|||||||
if (generatorOptions.inTempFile) return ExtractionResult(this, declaration, Collections.emptyMap(), nameByOffset)
|
if (generatorOptions.inTempFile) return ExtractionResult(this, declaration, Collections.emptyMap(), nameByOffset)
|
||||||
|
|
||||||
makeCall(descriptor, declaration, descriptor.controlFlow, descriptor.extractionData.originalRange, descriptor.parameters.map { it.argumentText })
|
makeCall(descriptor, declaration, descriptor.controlFlow, descriptor.extractionData.originalRange, descriptor.parameters.map { it.argumentText })
|
||||||
ShortenReferences.DEFAULT.process(declaration)
|
if (shouldInsert) {
|
||||||
|
ShortenReferences.DEFAULT.process(declaration)
|
||||||
|
}
|
||||||
|
|
||||||
val duplicateReplacers = duplicates.map { it.range to { makeCall(descriptor, declaration, it.controlFlow, it.range, it.arguments) } }.toMap()
|
val duplicateReplacers = duplicates.map { it.range to { makeCall(descriptor, declaration, it.controlFlow, it.range, it.arguments) } }.toMap()
|
||||||
return ExtractionResult(this, declaration, duplicateReplacers, nameByOffset)
|
return ExtractionResult(this, declaration, duplicateReplacers, nameByOffset)
|
||||||
|
|||||||
+27
@@ -0,0 +1,27 @@
|
|||||||
|
/*
|
||||||
|
* 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.introduce.introduceParameter
|
||||||
|
|
||||||
|
import com.intellij.lang.refactoring.RefactoringSupportProvider
|
||||||
|
import com.intellij.refactoring.RefactoringActionHandler
|
||||||
|
import org.jetbrains.kotlin.idea.refactoring.JetRefactoringSupportProvider
|
||||||
|
import org.jetbrains.kotlin.idea.refactoring.introduce.AbstractIntroduceAction
|
||||||
|
|
||||||
|
public class IntroduceLambdaParameterAction : AbstractIntroduceAction() {
|
||||||
|
override fun getRefactoringHandler(provider: RefactoringSupportProvider): RefactoringActionHandler? =
|
||||||
|
(provider as? JetRefactoringSupportProvider)?.getIntroduceLambdaParameterHandler()
|
||||||
|
}
|
||||||
+15
-6
@@ -68,20 +68,22 @@ import kotlin.properties.Delegates
|
|||||||
|
|
||||||
public class KotlinInplaceParameterIntroducer(
|
public class KotlinInplaceParameterIntroducer(
|
||||||
val originalDescriptor: IntroduceParameterDescriptor,
|
val originalDescriptor: IntroduceParameterDescriptor,
|
||||||
|
val addedParameter: JetParameter,
|
||||||
|
val parameterType: JetType,
|
||||||
editor: Editor,
|
editor: Editor,
|
||||||
project: Project
|
project: Project
|
||||||
): KotlinInplaceVariableIntroducer<JetParameter>(
|
): KotlinInplaceVariableIntroducer<JetParameter>(
|
||||||
originalDescriptor.addedParameter,
|
addedParameter,
|
||||||
editor,
|
editor,
|
||||||
project,
|
project,
|
||||||
INTRODUCE_PARAMETER,
|
INTRODUCE_PARAMETER,
|
||||||
JetExpression.EMPTY_ARRAY,
|
JetExpression.EMPTY_ARRAY,
|
||||||
null,
|
null,
|
||||||
false,
|
false,
|
||||||
originalDescriptor.addedParameter,
|
addedParameter,
|
||||||
false,
|
false,
|
||||||
true,
|
true,
|
||||||
originalDescriptor.parameterType,
|
parameterType,
|
||||||
false
|
false
|
||||||
) {
|
) {
|
||||||
companion object {
|
companion object {
|
||||||
@@ -137,7 +139,7 @@ public class KotlinInplaceParameterIntroducer(
|
|||||||
val parameterName = currentName ?: parameter.getName()
|
val parameterName = currentName ?: parameter.getName()
|
||||||
val parameterType = currentType ?: parameter.getTypeReference()!!.getText()
|
val parameterType = currentType ?: parameter.getTypeReference()!!.getText()
|
||||||
val modifier = if (valVar != JetValVar.None) "${valVar.name} " else ""
|
val modifier = if (valVar != JetValVar.None) "${valVar.name} " else ""
|
||||||
val defaultValue = if (withDefaultValue) " = ${originalExpression.getText()}" else ""
|
val defaultValue = if (withDefaultValue) " = ${newArgumentValue.getText()}" else ""
|
||||||
|
|
||||||
"$modifier$parameterName: $parameterType$defaultValue"
|
"$modifier$parameterName: $parameterType$defaultValue"
|
||||||
}
|
}
|
||||||
@@ -280,13 +282,18 @@ public class KotlinInplaceParameterIntroducer(
|
|||||||
return descriptor.callable
|
return descriptor.callable
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private fun removeAddedParameter() {
|
||||||
|
runWriteAction { JetPsiUtil.deleteElementWithDelimiters(addedParameter) }
|
||||||
|
}
|
||||||
|
|
||||||
override fun performRefactoring(): Boolean {
|
override fun performRefactoring(): Boolean {
|
||||||
|
removeAddedParameter()
|
||||||
descriptor.performRefactoring()
|
descriptor.performRefactoring()
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun performCleanup() {
|
override fun performCleanup() {
|
||||||
runWriteAction { JetPsiUtil.deleteElementWithDelimiters(descriptor.addedParameter) }
|
removeAddedParameter()
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun releaseResources() {
|
override fun releaseResources() {
|
||||||
@@ -301,9 +308,11 @@ public class KotlinInplaceParameterIntroducer(
|
|||||||
stopIntroduce()
|
stopIntroduce()
|
||||||
with (originalDescriptor) {
|
with (originalDescriptor) {
|
||||||
KotlinIntroduceParameterDialog(myProject,
|
KotlinIntroduceParameterDialog(myProject,
|
||||||
|
myEditor,
|
||||||
this,
|
this,
|
||||||
myNameSuggestions.copyToArray(),
|
myNameSuggestions.copyToArray(),
|
||||||
listOf(parameterType) + parameterType.supertypes()).show()
|
listOf(parameterType) + parameterType.supertypes(),
|
||||||
|
KotlinIntroduceParameterHelper.Default).show()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
+141
-31
@@ -16,31 +16,29 @@
|
|||||||
|
|
||||||
package org.jetbrains.kotlin.idea.refactoring.introduce.introduceParameter
|
package org.jetbrains.kotlin.idea.refactoring.introduce.introduceParameter
|
||||||
|
|
||||||
|
import com.intellij.openapi.editor.Editor
|
||||||
import com.intellij.openapi.options.ConfigurationException
|
import com.intellij.openapi.options.ConfigurationException
|
||||||
import com.intellij.openapi.project.Project
|
import com.intellij.openapi.project.Project
|
||||||
import com.intellij.openapi.ui.DialogWrapper
|
|
||||||
import com.intellij.psi.PsiElement
|
import com.intellij.psi.PsiElement
|
||||||
import com.intellij.psi.PsiNameHelper
|
|
||||||
import com.intellij.refactoring.BaseRefactoringProcessor
|
import com.intellij.refactoring.BaseRefactoringProcessor
|
||||||
import com.intellij.refactoring.ui.NameSuggestionsField
|
import com.intellij.refactoring.ui.NameSuggestionsField
|
||||||
import com.intellij.refactoring.ui.RefactoringDialog
|
import com.intellij.refactoring.ui.RefactoringDialog
|
||||||
import com.intellij.ui.NonFocusableCheckBox
|
import com.intellij.ui.NonFocusableCheckBox
|
||||||
|
import com.intellij.ui.TitledSeparator
|
||||||
import com.intellij.usageView.BaseUsageViewDescriptor
|
import com.intellij.usageView.BaseUsageViewDescriptor
|
||||||
import com.intellij.usageView.UsageInfo
|
import com.intellij.usageView.UsageInfo
|
||||||
import com.intellij.usageView.UsageViewDescriptor
|
|
||||||
import org.jetbrains.kotlin.idea.JetFileType
|
import org.jetbrains.kotlin.idea.JetFileType
|
||||||
|
import org.jetbrains.kotlin.idea.core.refactoring.isMultiLine
|
||||||
|
import org.jetbrains.kotlin.idea.refactoring.introduce.extractFunction.ui.KotlinExtractFunctionDialog
|
||||||
|
import org.jetbrains.kotlin.idea.refactoring.introduce.extractFunction.ui.KotlinParameterTablePanel
|
||||||
|
import org.jetbrains.kotlin.idea.refactoring.introduce.extractionEngine.*
|
||||||
import org.jetbrains.kotlin.idea.util.IdeDescriptorRenderers
|
import org.jetbrains.kotlin.idea.util.IdeDescriptorRenderers
|
||||||
import org.jetbrains.kotlin.idea.util.application.executeCommand
|
import org.jetbrains.kotlin.psi.*
|
||||||
import org.jetbrains.kotlin.idea.util.application.runWriteAction
|
|
||||||
import org.jetbrains.kotlin.psi.JetParameter
|
|
||||||
import org.jetbrains.kotlin.psi.JetPsiFactory
|
|
||||||
import org.jetbrains.kotlin.psi.JetPsiUtil
|
|
||||||
import org.jetbrains.kotlin.resolve.AnalyzingUtils
|
import org.jetbrains.kotlin.resolve.AnalyzingUtils
|
||||||
import org.jetbrains.kotlin.types.JetType
|
import org.jetbrains.kotlin.types.JetType
|
||||||
import java.awt.GridBagConstraints
|
import java.awt.GridBagConstraints
|
||||||
import java.awt.GridBagLayout
|
import java.awt.GridBagLayout
|
||||||
import java.awt.Insets
|
import java.awt.Insets
|
||||||
import java.util.ArrayList
|
|
||||||
import java.util.Collections
|
import java.util.Collections
|
||||||
import java.util.LinkedHashMap
|
import java.util.LinkedHashMap
|
||||||
import javax.swing.JCheckBox
|
import javax.swing.JCheckBox
|
||||||
@@ -48,12 +46,39 @@ import javax.swing.JComponent
|
|||||||
import javax.swing.JLabel
|
import javax.swing.JLabel
|
||||||
import javax.swing.JPanel
|
import javax.swing.JPanel
|
||||||
|
|
||||||
public class KotlinIntroduceParameterDialog(
|
public class KotlinIntroduceParameterDialog private (
|
||||||
project: Project,
|
project: Project,
|
||||||
|
val editor: Editor,
|
||||||
val descriptor: IntroduceParameterDescriptor,
|
val descriptor: IntroduceParameterDescriptor,
|
||||||
|
val lambdaExtractionDescriptor: ExtractableCodeDescriptor?,
|
||||||
nameSuggestions: Array<String>,
|
nameSuggestions: Array<String>,
|
||||||
val typeSuggestions: List<JetType>
|
val typeSuggestions: List<JetType>,
|
||||||
|
val helper: KotlinIntroduceParameterHelper
|
||||||
): RefactoringDialog(project, true) {
|
): RefactoringDialog(project, true) {
|
||||||
|
constructor(
|
||||||
|
project: Project,
|
||||||
|
editor: Editor,
|
||||||
|
descriptor: IntroduceParameterDescriptor,
|
||||||
|
nameSuggestions: Array<String>,
|
||||||
|
typeSuggestions: List<JetType>,
|
||||||
|
helper: KotlinIntroduceParameterHelper
|
||||||
|
): this(project, editor, descriptor, null, nameSuggestions, typeSuggestions, helper)
|
||||||
|
|
||||||
|
constructor(project: Project,
|
||||||
|
editor: Editor,
|
||||||
|
introduceParameterDescriptor: IntroduceParameterDescriptor,
|
||||||
|
lambdaExtractionDescriptor: ExtractableCodeDescriptor,
|
||||||
|
helper: KotlinIntroduceParameterHelper
|
||||||
|
) : this(
|
||||||
|
project,
|
||||||
|
editor,
|
||||||
|
introduceParameterDescriptor,
|
||||||
|
lambdaExtractionDescriptor,
|
||||||
|
lambdaExtractionDescriptor.suggestedNames.copyToArray(),
|
||||||
|
listOf(lambdaExtractionDescriptor.controlFlow.outputValueBoxer.returnType),
|
||||||
|
helper
|
||||||
|
)
|
||||||
|
|
||||||
private val typeNameSuggestions = typeSuggestions
|
private val typeNameSuggestions = typeSuggestions
|
||||||
.map { IdeDescriptorRenderers.SOURCE_CODE_SHORT_NAMES_IN_TYPES.renderType(it) }
|
.map { IdeDescriptorRenderers.SOURCE_CODE_SHORT_NAMES_IN_TYPES.renderType(it) }
|
||||||
.copyToArray()
|
.copyToArray()
|
||||||
@@ -62,9 +87,10 @@ public class KotlinIntroduceParameterDialog(
|
|||||||
private val typeField = NameSuggestionsField(typeNameSuggestions, project, JetFileType.INSTANCE)
|
private val typeField = NameSuggestionsField(typeNameSuggestions, project, JetFileType.INSTANCE)
|
||||||
private var replaceAllCheckBox: JCheckBox? = null
|
private var replaceAllCheckBox: JCheckBox? = null
|
||||||
private val removeParamsCheckBoxes = LinkedHashMap<JCheckBox, JetParameter>(descriptor.parametersToRemove.size())
|
private val removeParamsCheckBoxes = LinkedHashMap<JCheckBox, JetParameter>(descriptor.parametersToRemove.size())
|
||||||
|
private var parameterTablePanel: KotlinParameterTablePanel? = null
|
||||||
|
|
||||||
init {
|
init {
|
||||||
setTitle(INTRODUCE_PARAMETER)
|
setTitle(if (lambdaExtractionDescriptor != null) INTRODUCE_LAMBDA_PARAMETER else INTRODUCE_PARAMETER)
|
||||||
init()
|
init()
|
||||||
|
|
||||||
nameField.addDataChangedListener { validateButtons() }
|
nameField.addDataChangedListener { validateButtons() }
|
||||||
@@ -87,7 +113,7 @@ public class KotlinIntroduceParameterDialog(
|
|||||||
gbConstraints.weightx = 0.0
|
gbConstraints.weightx = 0.0
|
||||||
gbConstraints.weighty = 0.0
|
gbConstraints.weighty = 0.0
|
||||||
gbConstraints.gridy = 0
|
gbConstraints.gridy = 0
|
||||||
val nameLabel = JLabel("Parameter name:")
|
val nameLabel = JLabel("Parameter name: ")
|
||||||
nameLabel.setDisplayedMnemonic('n')
|
nameLabel.setDisplayedMnemonic('n')
|
||||||
nameLabel.setLabelFor(nameField)
|
nameLabel.setLabelFor(nameField)
|
||||||
panel.add(nameLabel, gbConstraints)
|
panel.add(nameLabel, gbConstraints)
|
||||||
@@ -102,9 +128,9 @@ public class KotlinIntroduceParameterDialog(
|
|||||||
gbConstraints.gridwidth = 1
|
gbConstraints.gridwidth = 1
|
||||||
gbConstraints.weightx = 0.0
|
gbConstraints.weightx = 0.0
|
||||||
gbConstraints.gridx = 0
|
gbConstraints.gridx = 0
|
||||||
gbConstraints.gridy = 1
|
gbConstraints.gridy++
|
||||||
gbConstraints.fill = GridBagConstraints.NONE
|
gbConstraints.fill = GridBagConstraints.NONE
|
||||||
val typeLabel = JLabel("Parameter type: ")
|
val typeLabel = JLabel(if (lambdaExtractionDescriptor != null) "Lambda return type" else "Parameter type: ")
|
||||||
typeLabel.setDisplayedMnemonic('t')
|
typeLabel.setDisplayedMnemonic('t')
|
||||||
typeLabel.setLabelFor(typeField)
|
typeLabel.setLabelFor(typeField)
|
||||||
panel.add(typeLabel, gbConstraints)
|
panel.add(typeLabel, gbConstraints)
|
||||||
@@ -115,6 +141,39 @@ public class KotlinIntroduceParameterDialog(
|
|||||||
gbConstraints.fill = GridBagConstraints.BOTH
|
gbConstraints.fill = GridBagConstraints.BOTH
|
||||||
panel.add(typeField, gbConstraints)
|
panel.add(typeField, gbConstraints)
|
||||||
|
|
||||||
|
if (lambdaExtractionDescriptor != null && lambdaExtractionDescriptor.parameters.isNotEmpty()) {
|
||||||
|
val parameterTablePanel = object : KotlinParameterTablePanel() {
|
||||||
|
override fun onEnterAction() {
|
||||||
|
doOKAction()
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun onCancelAction() {
|
||||||
|
doCancelAction()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
parameterTablePanel.init(lambdaExtractionDescriptor!!.parameters)
|
||||||
|
|
||||||
|
gbConstraints.insets = Insets(4, 4, 4, 8)
|
||||||
|
gbConstraints.gridwidth = 1
|
||||||
|
gbConstraints.weightx = 0.0
|
||||||
|
gbConstraints.gridx = 0
|
||||||
|
gbConstraints.gridy++
|
||||||
|
gbConstraints.fill = GridBagConstraints.NONE
|
||||||
|
val parametersLabel = JLabel("Lambda parameters: ")
|
||||||
|
parametersLabel.setDisplayedMnemonic('p')
|
||||||
|
parametersLabel.setLabelFor(parameterTablePanel)
|
||||||
|
panel.add(parametersLabel, gbConstraints)
|
||||||
|
|
||||||
|
gbConstraints.gridx++
|
||||||
|
gbConstraints.insets = Insets(4, 4, 4, 8)
|
||||||
|
gbConstraints.weightx = 1.0
|
||||||
|
gbConstraints.fill = GridBagConstraints.BOTH
|
||||||
|
panel.add(parameterTablePanel, gbConstraints)
|
||||||
|
|
||||||
|
this.parameterTablePanel = parameterTablePanel
|
||||||
|
}
|
||||||
|
|
||||||
|
gbConstraints.fill = GridBagConstraints.HORIZONTAL
|
||||||
gbConstraints.gridx = 0
|
gbConstraints.gridx = 0
|
||||||
gbConstraints.insets = Insets(4, 0, 4, 8)
|
gbConstraints.insets = Insets(4, 0, 4, 8)
|
||||||
gbConstraints.gridwidth = 2
|
gbConstraints.gridwidth = 2
|
||||||
@@ -169,31 +228,82 @@ public class KotlinIntroduceParameterDialog(
|
|||||||
}
|
}
|
||||||
|
|
||||||
override fun doAction() {
|
override fun doAction() {
|
||||||
val descriptorToRefactor = descriptor.copy(
|
performRefactoring()
|
||||||
addedParameter = JetPsiFactory(myProject).createParameter("${nameField.getEnteredName()}: ${typeField.getEnteredName()}"),
|
}
|
||||||
occurrencesToReplace = with(descriptor) {
|
|
||||||
if (replaceAllCheckBox?.isSelected() ?: true) {
|
public fun performRefactoring() {
|
||||||
occurrencesToReplace
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
Collections.singletonList(originalOccurrence)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
)
|
|
||||||
invokeRefactoring(
|
invokeRefactoring(
|
||||||
object: BaseRefactoringProcessor(myProject) {
|
object : BaseRefactoringProcessor(myProject) {
|
||||||
override fun findUsages() = UsageInfo.EMPTY_ARRAY
|
override fun findUsages() = UsageInfo.EMPTY_ARRAY
|
||||||
|
|
||||||
override fun performRefactoring(usages: Array<out UsageInfo>) {
|
override fun performRefactoring(usages: Array<out UsageInfo>) {
|
||||||
descriptorToRefactor.performRefactoring(
|
fun createLambdaForArgument(function: JetFunction): JetExpression {
|
||||||
parametersToRemove =
|
val statement = (function.getBodyExpression() as JetBlockExpression).getStatements().single()
|
||||||
removeParamsCheckBoxes.filter { it.key.isEnabled() && it.key.isSelected() }.map { it.value }
|
val space = if (statement.isMultiLine()) "\n" else " "
|
||||||
|
val parameters = function.getValueParameters()
|
||||||
|
val parametersText = if (parameters.isNotEmpty()) {
|
||||||
|
" " + parameters.map { it.getName() }.joinToString() + " ->"
|
||||||
|
} else ""
|
||||||
|
val text = "{$parametersText$space${statement.getText()}$space}"
|
||||||
|
|
||||||
|
return JetPsiFactory(myProject).createExpression(text)
|
||||||
|
}
|
||||||
|
|
||||||
|
val chosenName = nameField.getEnteredName()
|
||||||
|
var chosenType = typeField.getEnteredName()
|
||||||
|
var newArgumentValue = descriptor.newArgumentValue
|
||||||
|
var newReplacer = descriptor.occurrenceReplacer
|
||||||
|
|
||||||
|
lambdaExtractionDescriptor?.let { oldDescriptor ->
|
||||||
|
val newDescriptor = KotlinExtractFunctionDialog.createNewDescriptor(
|
||||||
|
oldDescriptor,
|
||||||
|
chosenName,
|
||||||
|
"",
|
||||||
|
parameterTablePanel?.getParameterInfos() ?: listOf()
|
||||||
|
)
|
||||||
|
val options = ExtractionGeneratorOptions.DEFAULT.copy(
|
||||||
|
target = ExtractionTarget.FAKE_LAMBDALIKE_FUNCTION,
|
||||||
|
allowExpressionBody = false
|
||||||
|
)
|
||||||
|
with (ExtractionGeneratorConfiguration(newDescriptor, options).generateDeclaration()) {
|
||||||
|
val function = declaration as JetFunction
|
||||||
|
val receiverType = function.getReceiverTypeReference()?.getText()
|
||||||
|
val parameterTypes = function
|
||||||
|
.getValueParameters()
|
||||||
|
.map { it.getTypeReference()!!.getText() }
|
||||||
|
.joinToString()
|
||||||
|
val returnType = function.getTypeReference()?.getText() ?: "Unit"
|
||||||
|
|
||||||
|
chosenType = (receiverType?.let { "$it." } ?: "") + "($parameterTypes) -> $returnType"
|
||||||
|
newArgumentValue = createLambdaForArgument(function)
|
||||||
|
newReplacer = { }
|
||||||
|
|
||||||
|
processDuplicates(duplicateReplacers, myProject, editor)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
val descriptorToRefactor = descriptor.copy(
|
||||||
|
newParameterName = chosenName,
|
||||||
|
newParameterTypeText = chosenType,
|
||||||
|
newArgumentValue = newArgumentValue,
|
||||||
|
occurrencesToReplace = with(descriptor) {
|
||||||
|
if (replaceAllCheckBox?.isSelected() ?: true) {
|
||||||
|
occurrencesToReplace
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
Collections.singletonList(originalOccurrence)
|
||||||
|
}
|
||||||
|
},
|
||||||
|
parametersToRemove = removeParamsCheckBoxes.filter { it.key.isEnabled() && it.key.isSelected() }.map { it.value },
|
||||||
|
occurrenceReplacer = newReplacer
|
||||||
)
|
)
|
||||||
|
|
||||||
|
helper.configure(descriptorToRefactor).performRefactoring()
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun createUsageViewDescriptor(usages: Array<out UsageInfo>) = BaseUsageViewDescriptor()
|
override fun createUsageViewDescriptor(usages: Array<out UsageInfo>) = BaseUsageViewDescriptor()
|
||||||
|
|
||||||
override fun getCommandName() = INTRODUCE_PARAMETER
|
override fun getCommandName() = if (lambdaExtractionDescriptor != null) INTRODUCE_LAMBDA_PARAMETER else INTRODUCE_PARAMETER
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|||||||
+217
-101
@@ -20,21 +20,21 @@ import com.intellij.openapi.actionSystem.DataContext
|
|||||||
import com.intellij.openapi.application.ApplicationManager
|
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.openapi.util.TextRange
|
|
||||||
import com.intellij.psi.PsiDocumentManager
|
import com.intellij.psi.PsiDocumentManager
|
||||||
import com.intellij.psi.PsiElement
|
import com.intellij.psi.PsiElement
|
||||||
import com.intellij.psi.PsiFile
|
import com.intellij.psi.PsiFile
|
||||||
import com.intellij.psi.PsiReference
|
import com.intellij.psi.PsiReference
|
||||||
import com.intellij.psi.search.LocalSearchScope
|
import com.intellij.psi.util.PsiTreeUtil
|
||||||
import org.jetbrains.kotlin.builtins.KotlinBuiltIns
|
|
||||||
import org.jetbrains.kotlin.descriptors.ClassDescriptor
|
import org.jetbrains.kotlin.descriptors.ClassDescriptor
|
||||||
import org.jetbrains.kotlin.descriptors.FunctionDescriptor
|
import org.jetbrains.kotlin.descriptors.FunctionDescriptor
|
||||||
import org.jetbrains.kotlin.idea.caches.resolve.analyze
|
import org.jetbrains.kotlin.idea.caches.resolve.analyze
|
||||||
|
import org.jetbrains.kotlin.idea.caches.resolve.resolveToDescriptor
|
||||||
import org.jetbrains.kotlin.idea.core.refactoring.JetNameSuggester
|
import org.jetbrains.kotlin.idea.core.refactoring.JetNameSuggester
|
||||||
import org.jetbrains.kotlin.idea.refactoring.JetNameValidatorImpl
|
import org.jetbrains.kotlin.idea.refactoring.JetNameValidatorImpl
|
||||||
import org.jetbrains.kotlin.idea.refactoring.JetRefactoringBundle
|
import org.jetbrains.kotlin.idea.refactoring.JetRefactoringBundle
|
||||||
import org.jetbrains.kotlin.idea.refactoring.changeSignature.*
|
import org.jetbrains.kotlin.idea.refactoring.changeSignature.*
|
||||||
import org.jetbrains.kotlin.idea.refactoring.introduce.KotlinIntroduceHandlerBase
|
import org.jetbrains.kotlin.idea.refactoring.introduce.KotlinIntroduceHandlerBase
|
||||||
|
import org.jetbrains.kotlin.idea.refactoring.introduce.extractionEngine.*
|
||||||
import org.jetbrains.kotlin.idea.refactoring.introduce.introduceVariable.KotlinInplaceVariableIntroducer
|
import org.jetbrains.kotlin.idea.refactoring.introduce.introduceVariable.KotlinInplaceVariableIntroducer
|
||||||
import org.jetbrains.kotlin.idea.refactoring.introduce.selectElementsWithTargetParent
|
import org.jetbrains.kotlin.idea.refactoring.introduce.selectElementsWithTargetParent
|
||||||
import org.jetbrains.kotlin.idea.refactoring.introduce.showErrorHint
|
import org.jetbrains.kotlin.idea.refactoring.introduce.showErrorHint
|
||||||
@@ -45,31 +45,32 @@ import org.jetbrains.kotlin.idea.search.usagesSearch.search
|
|||||||
import org.jetbrains.kotlin.idea.util.*
|
import org.jetbrains.kotlin.idea.util.*
|
||||||
import org.jetbrains.kotlin.idea.util.application.executeCommand
|
import org.jetbrains.kotlin.idea.util.application.executeCommand
|
||||||
import org.jetbrains.kotlin.idea.util.application.runWriteAction
|
import org.jetbrains.kotlin.idea.util.application.runWriteAction
|
||||||
|
import org.jetbrains.kotlin.idea.util.psi.patternMatching.JetPsiRange
|
||||||
import org.jetbrains.kotlin.idea.util.psi.patternMatching.JetPsiUnifier
|
import org.jetbrains.kotlin.idea.util.psi.patternMatching.JetPsiUnifier
|
||||||
import org.jetbrains.kotlin.idea.util.psi.patternMatching.toRange
|
import org.jetbrains.kotlin.idea.util.psi.patternMatching.toRange
|
||||||
import org.jetbrains.kotlin.idea.util.supertypes
|
|
||||||
import org.jetbrains.kotlin.psi.*
|
import org.jetbrains.kotlin.psi.*
|
||||||
import org.jetbrains.kotlin.psi.psiUtil.*
|
import org.jetbrains.kotlin.psi.psiUtil.*
|
||||||
import org.jetbrains.kotlin.resolve.BindingContext
|
import org.jetbrains.kotlin.resolve.BindingContext
|
||||||
import org.jetbrains.kotlin.resolve.scopes.JetScopeUtils
|
import org.jetbrains.kotlin.resolve.scopes.JetScopeUtils
|
||||||
import org.jetbrains.kotlin.types.JetType
|
|
||||||
import java.util.Collections
|
import java.util.Collections
|
||||||
import kotlin.test.fail
|
import kotlin.test.fail
|
||||||
|
|
||||||
public data class IntroduceParameterDescriptor(
|
public data class IntroduceParameterDescriptor(
|
||||||
val originalExpression: JetExpression,
|
val originalRange: JetPsiRange,
|
||||||
val callable: JetNamedDeclaration,
|
val callable: JetNamedDeclaration,
|
||||||
val callableDescriptor: FunctionDescriptor,
|
val callableDescriptor: FunctionDescriptor,
|
||||||
val addedParameter: JetParameter,
|
val newParameterName: String,
|
||||||
val parameterType: JetType,
|
val newParameterTypeText: String,
|
||||||
|
val newArgumentValue: JetExpression,
|
||||||
val withDefaultValue: Boolean,
|
val withDefaultValue: Boolean,
|
||||||
val parametersUsages: Map<JetParameter, List<PsiReference>>,
|
val parametersUsages: Map<JetParameter, List<PsiReference>>,
|
||||||
val occurrencesToReplace: List<JetExpression>
|
val occurrencesToReplace: List<JetPsiRange>,
|
||||||
|
val parametersToRemove: List<JetParameter> = getParametersToRemove(withDefaultValue, parametersUsages, occurrencesToReplace),
|
||||||
|
val occurrenceReplacer: (JetPsiRange) -> Unit = {}
|
||||||
) {
|
) {
|
||||||
val originalOccurrence: JetExpression
|
val originalOccurrence: JetPsiRange
|
||||||
get() = occurrencesToReplace.first { it.isAncestor(originalExpression) }
|
get() = occurrencesToReplace.first { it.getTextRange().intersects(originalRange.getTextRange()) }
|
||||||
val valVar: JetValVar
|
val valVar: JetValVar
|
||||||
val parametersToRemove: List<JetParameter>
|
|
||||||
|
|
||||||
init {
|
init {
|
||||||
valVar = if (callable is JetClass) {
|
valVar = if (callable is JetClass) {
|
||||||
@@ -79,47 +80,52 @@ public data class IntroduceParameterDescriptor(
|
|||||||
false
|
false
|
||||||
it is JetClassInitializer ->
|
it is JetClassInitializer ->
|
||||||
true
|
true
|
||||||
it is JetProperty && it.getInitializer()?.getTextRange()?.intersects(originalExpression.getTextRange()) ?: false ->
|
it is JetProperty && it.getInitializer()?.getTextRange()?.intersects(originalRange.getTextRange()) ?: false ->
|
||||||
true
|
true
|
||||||
else ->
|
else ->
|
||||||
false
|
false
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (occurrencesToReplace.all { it.parents().any(modifierIsUnnecessary) }) JetValVar.None else JetValVar.Val
|
if (occurrencesToReplace.all {
|
||||||
|
PsiTreeUtil.findCommonParent(it.elements)?.parents()?.any(modifierIsUnnecessary) ?: false
|
||||||
|
}) JetValVar.None else JetValVar.Val
|
||||||
}
|
}
|
||||||
else JetValVar.None
|
else JetValVar.None
|
||||||
|
|
||||||
parametersToRemove =
|
|
||||||
if (withDefaultValue) Collections.emptyList()
|
|
||||||
else {
|
|
||||||
val occurrenceRanges = occurrencesToReplace.map { it.getTextRange() }
|
|
||||||
parametersUsages.entrySet()
|
|
||||||
.filter {
|
|
||||||
it.value.all { paramRef ->
|
|
||||||
occurrenceRanges.any { occurrenceRange -> occurrenceRange.contains(paramRef.getElement().getTextRange()) }
|
|
||||||
}
|
|
||||||
}
|
|
||||||
.map { it.key }
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fun IntroduceParameterDescriptor.performRefactoring(parametersToRemove: List<JetParameter> = this.parametersToRemove) {
|
fun getParametersToRemove(
|
||||||
runWriteAction {
|
withDefaultValue: Boolean,
|
||||||
JetPsiUtil.deleteElementWithDelimiters(addedParameter)
|
parametersUsages: Map<JetParameter, List<PsiReference>>,
|
||||||
|
occurrencesToReplace: List<JetPsiRange>
|
||||||
|
): List<JetParameter> {
|
||||||
|
if (withDefaultValue) return Collections.emptyList()
|
||||||
|
|
||||||
val config = object: JetChangeSignatureConfiguration {
|
val occurrenceRanges = occurrencesToReplace.map { it.getTextRange() }
|
||||||
|
return parametersUsages.entrySet()
|
||||||
|
.filter {
|
||||||
|
it.value.all { paramRef ->
|
||||||
|
occurrenceRanges.any { occurrenceRange -> occurrenceRange.contains(paramRef.getElement().getTextRange()) }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
.map { it.key }
|
||||||
|
}
|
||||||
|
|
||||||
|
fun IntroduceParameterDescriptor.performRefactoring() {
|
||||||
|
runWriteAction {
|
||||||
|
val config = object : JetChangeSignatureConfiguration {
|
||||||
override fun configure(originalDescriptor: JetMethodDescriptor, bindingContext: BindingContext): JetMethodDescriptor {
|
override fun configure(originalDescriptor: JetMethodDescriptor, bindingContext: BindingContext): JetMethodDescriptor {
|
||||||
return originalDescriptor.modify {
|
return originalDescriptor.modify {
|
||||||
val parameters = callable.getValueParameters()
|
if (!withDefaultValue) {
|
||||||
parametersToRemove.map { parameters.indexOf(it) }.sortDescending().forEach { removeParameter(it) }
|
val parameters = callable.getValueParameters()
|
||||||
|
parametersToRemove.map { parameters.indexOf(it) }.sortDescending().forEach { removeParameter(it) }
|
||||||
|
}
|
||||||
|
|
||||||
val parameterInfo = JetParameterInfo(name = addedParameter.getName()!!,
|
val parameterInfo = JetParameterInfo(name = newParameterName,
|
||||||
type = parameterType,
|
defaultValueForCall = if (withDefaultValue) "" else newArgumentValue.getText(),
|
||||||
defaultValueForCall = if (withDefaultValue) "" else originalExpression.getText(),
|
defaultValueForParameter = if (withDefaultValue) newArgumentValue else null,
|
||||||
defaultValueForParameter = if (withDefaultValue) originalExpression else null,
|
|
||||||
valOrVar = valVar)
|
valOrVar = valVar)
|
||||||
parameterInfo.currentTypeText = addedParameter.getTypeReference()?.getText() ?: "Any"
|
parameterInfo.currentTypeText = newParameterTypeText
|
||||||
addParameter(parameterInfo)
|
addParameter(parameterInfo)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -127,19 +133,49 @@ fun IntroduceParameterDescriptor.performRefactoring(parametersToRemove: List<Jet
|
|||||||
override fun performSilently(affectedFunctions: Collection<PsiElement>): Boolean = true
|
override fun performSilently(affectedFunctions: Collection<PsiElement>): Boolean = true
|
||||||
}
|
}
|
||||||
if (runChangeSignature(callable.getProject(), callableDescriptor, config, callable.analyze(), callable, INTRODUCE_PARAMETER)) {
|
if (runChangeSignature(callable.getProject(), callableDescriptor, config, callable.analyze(), callable, INTRODUCE_PARAMETER)) {
|
||||||
val paramRef = JetPsiFactory(callable).createSimpleName(addedParameter.getName()!!)
|
occurrencesToReplace.forEach(occurrenceReplacer)
|
||||||
occurrencesToReplace.forEach { it.replace(paramRef) }
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public open class KotlinIntroduceParameterHandler: KotlinIntroduceHandlerBase() {
|
private fun isObjectOrNonInnerClass(e: PsiElement): Boolean = e is JetObjectDeclaration || (e is JetClass && !e.isInner())
|
||||||
open fun configure(descriptor: IntroduceParameterDescriptor): IntroduceParameterDescriptor = descriptor
|
|
||||||
|
|
||||||
private fun isObjectOrNonInnerClass(e: PsiElement): Boolean =
|
fun selectNewParameterContext(
|
||||||
e is JetObjectDeclaration || (e is JetClass && !e.isInner())
|
editor: Editor,
|
||||||
|
file: PsiFile,
|
||||||
|
continuation: (elements: List<PsiElement>, targetParent: PsiElement) -> Unit
|
||||||
|
) {
|
||||||
|
selectElementsWithTargetParent(
|
||||||
|
operationName = INTRODUCE_PARAMETER,
|
||||||
|
editor = editor,
|
||||||
|
file = file,
|
||||||
|
getContainers = { elements, parent ->
|
||||||
|
val parents = parent.parents(withItself = false)
|
||||||
|
val stopAt = (parent.parents(withItself = false) zip parent.parents(withItself = false).drop(1))
|
||||||
|
.firstOrNull { isObjectOrNonInnerClass(it.first) }
|
||||||
|
?.second
|
||||||
|
|
||||||
fun invoke(project: Project, editor: Editor, expression: JetExpression, targetParent: JetNamedDeclaration) {
|
(if (stopAt != null) parent.parents(withItself = false).takeWhile { it != stopAt } else parents)
|
||||||
|
.filter {
|
||||||
|
((it is JetClass && !it.isTrait() && it !is JetEnumEntry) || it is JetNamedFunction || it is JetSecondaryConstructor) &&
|
||||||
|
((it as JetNamedDeclaration).getValueParameterList() != null || it.getNameIdentifier() != null)
|
||||||
|
}
|
||||||
|
.toList()
|
||||||
|
},
|
||||||
|
continuation = continuation
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
public trait KotlinIntroduceParameterHelper {
|
||||||
|
object Default: KotlinIntroduceParameterHelper
|
||||||
|
|
||||||
|
fun configure(descriptor: IntroduceParameterDescriptor): IntroduceParameterDescriptor = descriptor
|
||||||
|
}
|
||||||
|
|
||||||
|
public open class KotlinIntroduceParameterHandler(
|
||||||
|
val helper: KotlinIntroduceParameterHelper = KotlinIntroduceParameterHelper.Default
|
||||||
|
): KotlinIntroduceHandlerBase() {
|
||||||
|
open fun invoke(project: Project, editor: Editor, expression: JetExpression, targetParent: JetNamedDeclaration) {
|
||||||
val context = expression.analyze()
|
val context = expression.analyze()
|
||||||
|
|
||||||
val expressionType = context.getType(expression)
|
val expressionType = context.getType(expression)
|
||||||
@@ -161,7 +197,7 @@ public open class KotlinIntroduceParameterHandler: KotlinIntroduceHandlerBase()
|
|||||||
is ClassDescriptor -> descriptor.getUnsubstitutedPrimaryConstructor()
|
is ClassDescriptor -> descriptor.getUnsubstitutedPrimaryConstructor()
|
||||||
else -> null
|
else -> null
|
||||||
} ?: throw AssertionError("Unexpected element type: ${targetParent.getElementTextWithContext()}")
|
} ?: throw AssertionError("Unexpected element type: ${targetParent.getElementTextWithContext()}")
|
||||||
val parameterType = expressionType.approximateWithResolvableType(JetScopeUtils.getResolutionScope(targetParent, context), false)
|
val replacementType = expressionType.approximateWithResolvableType(JetScopeUtils.getResolutionScope(targetParent, context), false)
|
||||||
|
|
||||||
val body = when (targetParent) {
|
val body = when (targetParent) {
|
||||||
is JetFunction -> targetParent.getBodyExpression()
|
is JetFunction -> targetParent.getBodyExpression()
|
||||||
@@ -169,18 +205,13 @@ public open class KotlinIntroduceParameterHandler: KotlinIntroduceHandlerBase()
|
|||||||
else -> null
|
else -> null
|
||||||
} ?: throw AssertionError("Body element is not found: ${targetParent.getElementTextWithContext()}")
|
} ?: throw AssertionError("Body element is not found: ${targetParent.getElementTextWithContext()}")
|
||||||
val nameValidator = JetNameValidatorImpl(body, null, JetNameValidatorImpl.Target.PROPERTIES)
|
val nameValidator = JetNameValidatorImpl(body, null, JetNameValidatorImpl.Target.PROPERTIES)
|
||||||
val suggestedNames = linkedSetOf(*JetNameSuggester.suggestNames(parameterType, nameValidator, "p"))
|
val suggestedNames = linkedSetOf(*JetNameSuggester.suggestNames(replacementType, nameValidator, "p"))
|
||||||
|
|
||||||
val parametersUsages = targetParent.getValueParameters()
|
val parametersUsages = findInternalParameterUsages(targetParent)
|
||||||
.filter { !it.hasValOrVarNode() }
|
|
||||||
.map {
|
val psiFactory = JetPsiFactory(project)
|
||||||
it to DefaultSearchHelper<JetParameter>()
|
val renderedType = IdeDescriptorRenderers.SOURCE_CODE_SHORT_NAMES_IN_TYPES.renderType(replacementType)
|
||||||
.newRequest(UsagesSearchTarget(element = it))
|
val newParameter = psiFactory.createParameter("${suggestedNames.first()}: $renderedType")
|
||||||
.search()
|
|
||||||
.toList()
|
|
||||||
}
|
|
||||||
.filter { it.second.isNotEmpty() }
|
|
||||||
.toMap()
|
|
||||||
|
|
||||||
val forbiddenRanges =
|
val forbiddenRanges =
|
||||||
if (targetParent is JetClass) {
|
if (targetParent is JetClass) {
|
||||||
@@ -204,16 +235,12 @@ public open class KotlinIntroduceParameterHandler: KotlinIntroduceHandlerBase()
|
|||||||
} as? JetExpression
|
} as? JetExpression
|
||||||
}
|
}
|
||||||
.filterNotNull()
|
.filterNotNull()
|
||||||
|
.map { it.toRange() }
|
||||||
|
|
||||||
project.executeCommand(
|
project.executeCommand(
|
||||||
INTRODUCE_PARAMETER,
|
INTRODUCE_PARAMETER,
|
||||||
null,
|
null,
|
||||||
fun() {
|
fun() {
|
||||||
val psiFactory = JetPsiFactory(project)
|
|
||||||
|
|
||||||
val renderedType = IdeDescriptorRenderers.SOURCE_CODE_SHORT_NAMES_IN_TYPES.renderType(parameterType)
|
|
||||||
val newParameter = psiFactory.createParameter("${suggestedNames.first()}: $renderedType")
|
|
||||||
|
|
||||||
val isTestMode = ApplicationManager.getApplication().isUnitTestMode()
|
val isTestMode = ApplicationManager.getApplication().isUnitTestMode()
|
||||||
val inplaceIsAvailable = editor.getSettings().isVariableInplaceRenameEnabled() && !isTestMode
|
val inplaceIsAvailable = editor.getSettings().isVariableInplaceRenameEnabled() && !isTestMode
|
||||||
|
|
||||||
@@ -243,15 +270,24 @@ public open class KotlinIntroduceParameterHandler: KotlinIntroduceHandlerBase()
|
|||||||
}
|
}
|
||||||
else newParameter
|
else newParameter
|
||||||
|
|
||||||
|
val originalExpression = JetPsiUtil.safeDeparenthesize(expression)
|
||||||
|
val newParameterName = addedParameter.getName()!!
|
||||||
|
val replacement = psiFactory.createExpression(newParameterName)
|
||||||
val introduceParameterDescriptor =
|
val introduceParameterDescriptor =
|
||||||
configure(IntroduceParameterDescriptor(JetPsiUtil.deparenthesize(expression)!!,
|
helper.configure(
|
||||||
targetParent,
|
IntroduceParameterDescriptor(
|
||||||
functionDescriptor,
|
originalRange = originalExpression.toRange(),
|
||||||
addedParameter,
|
callable = targetParent,
|
||||||
parameterType,
|
callableDescriptor = functionDescriptor,
|
||||||
false,
|
newParameterName = newParameterName,
|
||||||
parametersUsages,
|
newParameterTypeText = renderedType,
|
||||||
occurrencesToReplace))
|
newArgumentValue = originalExpression,
|
||||||
|
withDefaultValue = false,
|
||||||
|
parametersUsages = parametersUsages,
|
||||||
|
occurrencesToReplace = occurrencesToReplace,
|
||||||
|
occurrenceReplacer = { it.elements.single().replace(replacement) }
|
||||||
|
)
|
||||||
|
)
|
||||||
if (isTestMode) {
|
if (isTestMode) {
|
||||||
introduceParameterDescriptor.performRefactoring()
|
introduceParameterDescriptor.performRefactoring()
|
||||||
return
|
return
|
||||||
@@ -263,14 +299,20 @@ public open class KotlinIntroduceParameterHandler: KotlinIntroduceHandlerBase()
|
|||||||
doPostponedOperationsAndUnblockDocument(editor.getDocument())
|
doPostponedOperationsAndUnblockDocument(editor.getDocument())
|
||||||
}
|
}
|
||||||
|
|
||||||
if (KotlinInplaceParameterIntroducer(introduceParameterDescriptor, editor, project)
|
val introducer = KotlinInplaceParameterIntroducer(introduceParameterDescriptor,
|
||||||
.startRefactoring(suggestedNames)) return
|
addedParameter,
|
||||||
|
replacementType,
|
||||||
|
editor,
|
||||||
|
project)
|
||||||
|
if (introducer.startRefactoring(suggestedNames)) return
|
||||||
}
|
}
|
||||||
|
|
||||||
KotlinIntroduceParameterDialog(project,
|
KotlinIntroduceParameterDialog(project,
|
||||||
|
editor,
|
||||||
introduceParameterDescriptor,
|
introduceParameterDescriptor,
|
||||||
suggestedNames.copyToArray(),
|
suggestedNames.copyToArray(),
|
||||||
listOf(parameterType) + parameterType.supertypes()).show()
|
listOf(replacementType) + replacementType.supertypes(),
|
||||||
|
helper).show()
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
@@ -282,33 +324,15 @@ public open class KotlinIntroduceParameterHandler: KotlinIntroduceHandlerBase()
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (file !is JetFile) return
|
if (file !is JetFile) return
|
||||||
selectElementsWithTargetParent(
|
selectNewParameterContext(editor, file) { elements, targetParent ->
|
||||||
operationName = INTRODUCE_PARAMETER,
|
val expression = ((elements.singleOrNull() as? JetBlockExpression)?.getStatements() ?: elements).singleOrNull()
|
||||||
editor = editor,
|
if (expression is JetExpression) {
|
||||||
file = file,
|
invoke(project, editor, expression, targetParent as JetNamedDeclaration)
|
||||||
getContainers = { elements, parent ->
|
}
|
||||||
val parents = parent.parents(withItself = false)
|
else {
|
||||||
val stopAt = (parent.parents(withItself = false) zip parent.parents(withItself = false).drop(1))
|
showErrorHintByKey(project, editor, "cannot.refactor.no.expression", INTRODUCE_PARAMETER)
|
||||||
.firstOrNull { isObjectOrNonInnerClass(it.first) }
|
}
|
||||||
?.second
|
}
|
||||||
|
|
||||||
(if (stopAt != null) parent.parents(withItself = false).takeWhile { it != stopAt } else parents)
|
|
||||||
.filter {
|
|
||||||
((it is JetClass && !it.isTrait() && it !is JetEnumEntry) || it is JetNamedFunction || it is JetSecondaryConstructor) &&
|
|
||||||
((it as JetNamedDeclaration).getValueParameterList() != null || it.getNameIdentifier() != null)
|
|
||||||
}
|
|
||||||
.toList()
|
|
||||||
},
|
|
||||||
continuation = { elements, targetParent ->
|
|
||||||
val expression = ((elements.singleOrNull() as? JetBlockExpression)?.getStatements() ?: elements).singleOrNull()
|
|
||||||
if (expression is JetExpression) {
|
|
||||||
invoke(project, editor, expression, targetParent as JetNamedDeclaration)
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
showErrorHintByKey(project, editor, "cannot.refactor.no.expression", INTRODUCE_PARAMETER)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun invoke(project: Project, elements: Array<out PsiElement>, dataContext: DataContext?) {
|
override fun invoke(project: Project, elements: Array<out PsiElement>, dataContext: DataContext?) {
|
||||||
@@ -316,4 +340,96 @@ public open class KotlinIntroduceParameterHandler: KotlinIntroduceHandlerBase()
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
val INTRODUCE_PARAMETER: String = JetRefactoringBundle.message("introduce.parameter")
|
private fun findInternalParameterUsages(targetParent: JetNamedDeclaration): Map<JetParameter, List<PsiReference>> {
|
||||||
|
return targetParent.getValueParameters()
|
||||||
|
.filter { !it.hasValOrVarNode() }
|
||||||
|
.map {
|
||||||
|
it to DefaultSearchHelper<JetParameter>()
|
||||||
|
.newRequest(UsagesSearchTarget(element = it))
|
||||||
|
.search()
|
||||||
|
.toList()
|
||||||
|
}
|
||||||
|
.filter { it.second.isNotEmpty() }
|
||||||
|
.toMap()
|
||||||
|
}
|
||||||
|
|
||||||
|
trait KotlinIntroduceLambdaParameterHelper: KotlinIntroduceParameterHelper {
|
||||||
|
object Default: KotlinIntroduceLambdaParameterHelper
|
||||||
|
|
||||||
|
fun configureExtractLambda(descriptor: ExtractableCodeDescriptor): ExtractableCodeDescriptor = descriptor
|
||||||
|
}
|
||||||
|
|
||||||
|
public open class KotlinIntroduceLambdaParameterHandler(
|
||||||
|
helper: KotlinIntroduceLambdaParameterHelper = KotlinIntroduceLambdaParameterHelper.Default
|
||||||
|
): KotlinIntroduceParameterHandler(helper) {
|
||||||
|
val extractLambdaHelper = object: ExtractionEngineHelper(INTRODUCE_LAMBDA_PARAMETER) {
|
||||||
|
private fun createDialog(
|
||||||
|
project: Project,
|
||||||
|
editor: Editor,
|
||||||
|
lambdaExtractionDescriptor: ExtractableCodeDescriptor
|
||||||
|
): KotlinIntroduceParameterDialog {
|
||||||
|
val callable = lambdaExtractionDescriptor.extractionData.targetSibling as JetNamedDeclaration
|
||||||
|
val descriptor = callable.resolveToDescriptor()
|
||||||
|
val callableDescriptor: FunctionDescriptor =
|
||||||
|
when (descriptor) {
|
||||||
|
is FunctionDescriptor -> descriptor : FunctionDescriptor
|
||||||
|
is ClassDescriptor -> descriptor.getUnsubstitutedPrimaryConstructor()
|
||||||
|
else -> null
|
||||||
|
} ?: throw AssertionError("Unexpected element type: ${callable.getElementTextWithContext()}")
|
||||||
|
val originalRange = lambdaExtractionDescriptor.extractionData.originalRange
|
||||||
|
val introduceParameterDescriptor = IntroduceParameterDescriptor(
|
||||||
|
originalRange = originalRange,
|
||||||
|
callable = callable,
|
||||||
|
callableDescriptor = callableDescriptor,
|
||||||
|
newParameterName = "", // to be chosen in the dialog
|
||||||
|
newParameterTypeText = "", // to be chosen in the dialog
|
||||||
|
newArgumentValue = JetPsiFactory(project).createExpression("{}"), // substituted later
|
||||||
|
withDefaultValue = false,
|
||||||
|
parametersUsages = findInternalParameterUsages(callable),
|
||||||
|
occurrencesToReplace = listOf(originalRange),
|
||||||
|
parametersToRemove = listOf()
|
||||||
|
)
|
||||||
|
|
||||||
|
return KotlinIntroduceParameterDialog(project, editor, introduceParameterDescriptor, lambdaExtractionDescriptor, helper)
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun configureAndRun(
|
||||||
|
project: Project,
|
||||||
|
editor: Editor,
|
||||||
|
descriptorWithConflicts: ExtractableCodeDescriptorWithConflicts,
|
||||||
|
onFinish: (ExtractionResult) -> Unit
|
||||||
|
) {
|
||||||
|
val lambdaExtractionDescriptor = helper.configureExtractLambda(descriptorWithConflicts.descriptor)
|
||||||
|
if (!ExtractionTarget.FAKE_LAMBDALIKE_FUNCTION.isAvailable(lambdaExtractionDescriptor)) {
|
||||||
|
showErrorHint(project, editor, "Can't introduce lambda parameter for this expression", INTRODUCE_LAMBDA_PARAMETER)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
val dialog = createDialog(project, editor, lambdaExtractionDescriptor)
|
||||||
|
if (ApplicationManager.getApplication()!!.isUnitTestMode()) {
|
||||||
|
dialog.performRefactoring()
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
dialog.show()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun invoke(project: Project, editor: Editor, expression: JetExpression, targetParent: JetNamedDeclaration) {
|
||||||
|
val duplicateContainer =
|
||||||
|
when (targetParent) {
|
||||||
|
is JetFunction -> targetParent.getBodyExpression()
|
||||||
|
is JetClass -> targetParent.getBody()
|
||||||
|
else -> null
|
||||||
|
} ?: throw AssertionError("Body element is not found: ${targetParent.getElementTextWithContext()}")
|
||||||
|
val extractionData = ExtractionData(expression.getContainingJetFile(),
|
||||||
|
expression.toRange(),
|
||||||
|
targetParent,
|
||||||
|
duplicateContainer,
|
||||||
|
ExtractionOptions.DEFAULT)
|
||||||
|
ExtractionEngine(extractLambdaHelper).run(editor, extractionData)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
val INTRODUCE_PARAMETER: String = "Introduce Parameter"
|
||||||
|
val INTRODUCE_LAMBDA_PARAMETER: String = "Introduce Lambda Parameter"
|
||||||
|
|||||||
+1
-1
@@ -65,7 +65,7 @@ public class KotlinIntroducePropertyHandler(
|
|||||||
val adjustedElements = (elements.singleOrNull() as? JetBlockExpression)?.getStatements() ?: elements
|
val adjustedElements = (elements.singleOrNull() as? JetBlockExpression)?.getStatements() ?: elements
|
||||||
if (adjustedElements.isNotEmpty()) {
|
if (adjustedElements.isNotEmpty()) {
|
||||||
val options = ExtractionOptions(extractAsProperty = true)
|
val options = ExtractionOptions(extractAsProperty = true)
|
||||||
val extractionData = ExtractionData(file, adjustedElements.toRange(), targetSibling, options)
|
val extractionData = ExtractionData(file, adjustedElements.toRange(), targetSibling, null, options)
|
||||||
ExtractionEngine(helper).run(editor, extractionData) {
|
ExtractionEngine(helper).run(editor, extractionData) {
|
||||||
val property = it.declaration as JetProperty
|
val property = it.declaration as JetProperty
|
||||||
val descriptor = it.config.descriptor
|
val descriptor = it.config.descriptor
|
||||||
|
|||||||
@@ -0,0 +1,12 @@
|
|||||||
|
// WITH_DEFAULT_VALUE: false
|
||||||
|
// TARGET:
|
||||||
|
class Foo(val a: Int) {
|
||||||
|
fun foo(n: Int): Int {
|
||||||
|
val t = a + n + 1
|
||||||
|
return <selection>a - n</selection> - t
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fun test() {
|
||||||
|
Foo(1).foo(2)
|
||||||
|
}
|
||||||
+12
@@ -0,0 +1,12 @@
|
|||||||
|
// WITH_DEFAULT_VALUE: false
|
||||||
|
// TARGET:
|
||||||
|
class Foo(val a: Int, val i: Foo.(Int) -> Int) {
|
||||||
|
fun foo(n: Int): Int {
|
||||||
|
val t = a + n + 1
|
||||||
|
return i(n) - t
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fun test() {
|
||||||
|
Foo(1) { n -> a - n }.foo(2)
|
||||||
|
}
|
||||||
@@ -0,0 +1,11 @@
|
|||||||
|
// WITH_DEFAULT_VALUE: false
|
||||||
|
fun foo(a: Int, s: String): Int {
|
||||||
|
val t = a + 1 + 2
|
||||||
|
return <selection>a
|
||||||
|
.plus(1)
|
||||||
|
.plus(2)</selection> - t
|
||||||
|
}
|
||||||
|
|
||||||
|
fun test() {
|
||||||
|
foo(1, "2")
|
||||||
|
}
|
||||||
@@ -0,0 +1,13 @@
|
|||||||
|
// WITH_DEFAULT_VALUE: false
|
||||||
|
fun foo(a: Int, s: String, i: (Int) -> Int): Int {
|
||||||
|
val t = i(a)
|
||||||
|
return i(a) - t
|
||||||
|
}
|
||||||
|
|
||||||
|
fun test() {
|
||||||
|
foo(1, "2") { a ->
|
||||||
|
a
|
||||||
|
.plus(1)
|
||||||
|
.plus(2)
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,9 @@
|
|||||||
|
// WITH_DEFAULT_VALUE: false
|
||||||
|
fun foo(a: Int, s: String): Int {
|
||||||
|
val t = (a + 1) * 2
|
||||||
|
return <selection>a + 1</selection> - t
|
||||||
|
}
|
||||||
|
|
||||||
|
fun test() {
|
||||||
|
foo(1, "2")
|
||||||
|
}
|
||||||
@@ -0,0 +1,9 @@
|
|||||||
|
// WITH_DEFAULT_VALUE: false
|
||||||
|
fun foo(a: Int, s: String, i: (Int) -> Int): Int {
|
||||||
|
val t = i(a) * 2
|
||||||
|
return i(a) - t
|
||||||
|
}
|
||||||
|
|
||||||
|
fun test() {
|
||||||
|
foo(1, "2") { a -> a + 1 }
|
||||||
|
}
|
||||||
+9
@@ -0,0 +1,9 @@
|
|||||||
|
// WITH_DEFAULT_VALUE: false
|
||||||
|
fun foo(a: Int, s: () -> String): Int {
|
||||||
|
val t = (a + 1) * 2
|
||||||
|
return <selection>a + 1</selection> - t
|
||||||
|
}
|
||||||
|
|
||||||
|
fun test() {
|
||||||
|
foo(1) { "2" }
|
||||||
|
}
|
||||||
+9
@@ -0,0 +1,9 @@
|
|||||||
|
// WITH_DEFAULT_VALUE: false
|
||||||
|
fun foo(a: Int, s: () -> String, i: (Int) -> Int): Int {
|
||||||
|
val t = i(a) * 2
|
||||||
|
return i(a) - t
|
||||||
|
}
|
||||||
|
|
||||||
|
fun test() {
|
||||||
|
foo(1, { "2" }) { a -> a + 1 }
|
||||||
|
}
|
||||||
@@ -0,0 +1,9 @@
|
|||||||
|
// WITH_DEFAULT_VALUE: false
|
||||||
|
fun foo(a: Int, s: String): Int {
|
||||||
|
val t = (a + 1) * 2
|
||||||
|
return <selection>1 + 2</selection> - t
|
||||||
|
}
|
||||||
|
|
||||||
|
fun test() {
|
||||||
|
foo(1, "2")
|
||||||
|
}
|
||||||
@@ -0,0 +1,9 @@
|
|||||||
|
// WITH_DEFAULT_VALUE: false
|
||||||
|
fun foo(a: Int, s: String, i: () -> Int): Int {
|
||||||
|
val t = (a + 1) * 2
|
||||||
|
return i() - t
|
||||||
|
}
|
||||||
|
|
||||||
|
fun test() {
|
||||||
|
foo(1, "2") { 1 + 2 }
|
||||||
|
}
|
||||||
@@ -0,0 +1,8 @@
|
|||||||
|
// WITH_DEFAULT_VALUE: false
|
||||||
|
fun foo(a: Int) {
|
||||||
|
<selection>throw Exception("Error: $a")</selection>
|
||||||
|
}
|
||||||
|
|
||||||
|
fun test() {
|
||||||
|
foo(1)
|
||||||
|
}
|
||||||
@@ -0,0 +1,8 @@
|
|||||||
|
// WITH_DEFAULT_VALUE: false
|
||||||
|
fun foo(a: Int, __dummyTestFun__: (Int) -> Unit) {
|
||||||
|
__dummyTestFun__(a)
|
||||||
|
}
|
||||||
|
|
||||||
|
fun test() {
|
||||||
|
foo(1) { a -> throw Exception("Error: $a") }
|
||||||
|
}
|
||||||
@@ -0,0 +1,12 @@
|
|||||||
|
// WITH_DEFAULT_VALUE: false
|
||||||
|
fun foo(a: Int) {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
fun bar(a: Int) {
|
||||||
|
<selection>foo(a + 1)</selection>
|
||||||
|
}
|
||||||
|
|
||||||
|
fun test() {
|
||||||
|
bar(1)
|
||||||
|
}
|
||||||
@@ -0,0 +1,12 @@
|
|||||||
|
// WITH_DEFAULT_VALUE: false
|
||||||
|
fun foo(a: Int) {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
fun bar(a: Int, __dummyTestFun__: (Int) -> Unit) {
|
||||||
|
__dummyTestFun__(a)
|
||||||
|
}
|
||||||
|
|
||||||
|
fun test() {
|
||||||
|
bar(1) { a -> foo(a + 1) }
|
||||||
|
}
|
||||||
@@ -0,0 +1,8 @@
|
|||||||
|
fun foo(a: Int, s: String): Int {
|
||||||
|
val t = (a + 1) * 2
|
||||||
|
return <selection>a + 1</selection> - t
|
||||||
|
}
|
||||||
|
|
||||||
|
fun test() {
|
||||||
|
foo(1, "2")
|
||||||
|
}
|
||||||
+8
@@ -0,0 +1,8 @@
|
|||||||
|
fun foo(a: Int, s: String, i: (Int) -> Int = { a -> a + 1 }): Int {
|
||||||
|
val t = i(a) * 2
|
||||||
|
return i(a) - t
|
||||||
|
}
|
||||||
|
|
||||||
|
fun test() {
|
||||||
|
foo(1, "2")
|
||||||
|
}
|
||||||
+31
-8
@@ -27,8 +27,7 @@ import org.jetbrains.kotlin.idea.refactoring.JetRefactoringUtil
|
|||||||
import org.jetbrains.kotlin.idea.refactoring.introduce.extractFunction.EXTRACT_FUNCTION
|
import org.jetbrains.kotlin.idea.refactoring.introduce.extractFunction.EXTRACT_FUNCTION
|
||||||
import org.jetbrains.kotlin.idea.refactoring.introduce.extractFunction.ExtractKotlinFunctionHandler
|
import org.jetbrains.kotlin.idea.refactoring.introduce.extractFunction.ExtractKotlinFunctionHandler
|
||||||
import org.jetbrains.kotlin.idea.refactoring.introduce.extractionEngine.*
|
import org.jetbrains.kotlin.idea.refactoring.introduce.extractionEngine.*
|
||||||
import org.jetbrains.kotlin.idea.refactoring.introduce.introduceParameter.IntroduceParameterDescriptor
|
import org.jetbrains.kotlin.idea.refactoring.introduce.introduceParameter.*
|
||||||
import org.jetbrains.kotlin.idea.refactoring.introduce.introduceParameter.KotlinIntroduceParameterHandler
|
|
||||||
import org.jetbrains.kotlin.idea.refactoring.introduce.introduceProperty.INTRODUCE_PROPERTY
|
import org.jetbrains.kotlin.idea.refactoring.introduce.introduceProperty.INTRODUCE_PROPERTY
|
||||||
import org.jetbrains.kotlin.idea.refactoring.introduce.introduceProperty.KotlinIntroducePropertyHandler
|
import org.jetbrains.kotlin.idea.refactoring.introduce.introduceProperty.KotlinIntroducePropertyHandler
|
||||||
import org.jetbrains.kotlin.idea.refactoring.introduce.introduceVariable.KotlinIntroduceVariableHandler
|
import org.jetbrains.kotlin.idea.refactoring.introduce.introduceVariable.KotlinIntroduceVariableHandler
|
||||||
@@ -62,21 +61,37 @@ public abstract class AbstractJetExtractionTest() : JetLightCodeInsightFixtureTe
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
protected fun doIntroduceParameterTest(path: String) {
|
private fun doIntroduceParameterTest(path: String, asLambda: Boolean) {
|
||||||
doTest(path) { file ->
|
doTest(path) { file ->
|
||||||
val handler = object: KotlinIntroduceParameterHandler() {
|
val fileText = file.getText()
|
||||||
|
|
||||||
|
open class HelperImpl: KotlinIntroduceParameterHelper {
|
||||||
override fun configure(descriptor: IntroduceParameterDescriptor): IntroduceParameterDescriptor {
|
override fun configure(descriptor: IntroduceParameterDescriptor): IntroduceParameterDescriptor {
|
||||||
val fileText = file.getText()
|
|
||||||
val singleReplace = InTextDirectivesUtils.isDirectiveDefined(fileText, "// SINGLE_REPLACE")
|
|
||||||
val withDefaultValue = InTextDirectivesUtils.getPrefixedBoolean(fileText, "// WITH_DEFAULT_VALUE:") ?: true
|
|
||||||
return with (descriptor) {
|
return with (descriptor) {
|
||||||
|
val singleReplace = InTextDirectivesUtils.isDirectiveDefined(fileText, "// SINGLE_REPLACE")
|
||||||
|
val withDefaultValue = InTextDirectivesUtils.getPrefixedBoolean(fileText, "// WITH_DEFAULT_VALUE:") ?: true
|
||||||
|
|
||||||
copy(occurrencesToReplace = if (singleReplace) Collections.singletonList(originalOccurrence) else occurrencesToReplace,
|
copy(occurrencesToReplace = if (singleReplace) Collections.singletonList(originalOccurrence) else occurrencesToReplace,
|
||||||
withDefaultValue = withDefaultValue)
|
withDefaultValue = withDefaultValue)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
class LambdaHelperImpl: HelperImpl(), KotlinIntroduceLambdaParameterHelper {
|
||||||
|
override fun configureExtractLambda(descriptor: ExtractableCodeDescriptor): ExtractableCodeDescriptor {
|
||||||
|
return with(descriptor) {
|
||||||
|
if (name.isNullOrEmpty()) copy(suggestedNames = listOf("__dummyTestFun__")) else this
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
val handler = if (asLambda) {
|
||||||
|
KotlinIntroduceLambdaParameterHandler(LambdaHelperImpl())
|
||||||
|
} else {
|
||||||
|
KotlinIntroduceParameterHandler(HelperImpl())
|
||||||
|
}
|
||||||
with (handler) {
|
with (handler) {
|
||||||
val target = file.findElementByComment("// TARGET:") as? JetNamedDeclaration
|
val target = (file as JetFile).findElementByComment("// TARGET:") as? JetNamedDeclaration
|
||||||
if (target != null) {
|
if (target != null) {
|
||||||
JetRefactoringUtil.selectExpression(fixture.getEditor(), file, true) { expression ->
|
JetRefactoringUtil.selectExpression(fixture.getEditor(), file, true) { expression ->
|
||||||
invoke(fixture.getProject(), fixture.getEditor(), expression!!, target)
|
invoke(fixture.getProject(), fixture.getEditor(), expression!!, target)
|
||||||
@@ -89,6 +104,14 @@ public abstract class AbstractJetExtractionTest() : JetLightCodeInsightFixtureTe
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
protected fun doIntroduceSimpleParameterTest(path: String) {
|
||||||
|
doIntroduceParameterTest(path, false)
|
||||||
|
}
|
||||||
|
|
||||||
|
protected fun doIntroduceLambdaParameterTest(path: String) {
|
||||||
|
doIntroduceParameterTest(path, true)
|
||||||
|
}
|
||||||
|
|
||||||
protected fun doIntroducePropertyTest(path: String) {
|
protected fun doIntroducePropertyTest(path: String) {
|
||||||
doTest(path) { file ->
|
doTest(path) { file ->
|
||||||
val extractionTarget = propertyTargets.single {
|
val extractionTarget = propertyTargets.single {
|
||||||
|
|||||||
+88
-31
@@ -2203,187 +2203,244 @@ public class JetExtractionTestGenerated extends AbstractJetExtractionTest {
|
|||||||
@TestMetadata("assignment.kt")
|
@TestMetadata("assignment.kt")
|
||||||
public void testAssignment() throws Exception {
|
public void testAssignment() throws Exception {
|
||||||
String fileName = JetTestUtils.navigationMetadata("idea/testData/refactoring/introduceParameter/assignment.kt");
|
String fileName = JetTestUtils.navigationMetadata("idea/testData/refactoring/introduceParameter/assignment.kt");
|
||||||
doIntroduceParameterTest(fileName);
|
doIntroduceSimpleParameterTest(fileName);
|
||||||
}
|
}
|
||||||
|
|
||||||
@TestMetadata("classInAnonymousInitializer.kt")
|
@TestMetadata("classInAnonymousInitializer.kt")
|
||||||
public void testClassInAnonymousInitializer() throws Exception {
|
public void testClassInAnonymousInitializer() throws Exception {
|
||||||
String fileName = JetTestUtils.navigationMetadata("idea/testData/refactoring/introduceParameter/classInAnonymousInitializer.kt");
|
String fileName = JetTestUtils.navigationMetadata("idea/testData/refactoring/introduceParameter/classInAnonymousInitializer.kt");
|
||||||
doIntroduceParameterTest(fileName);
|
doIntroduceSimpleParameterTest(fileName);
|
||||||
}
|
}
|
||||||
|
|
||||||
@TestMetadata("classInPropertyInitializer.kt")
|
@TestMetadata("classInPropertyInitializer.kt")
|
||||||
public void testClassInPropertyInitializer() throws Exception {
|
public void testClassInPropertyInitializer() throws Exception {
|
||||||
String fileName = JetTestUtils.navigationMetadata("idea/testData/refactoring/introduceParameter/classInPropertyInitializer.kt");
|
String fileName = JetTestUtils.navigationMetadata("idea/testData/refactoring/introduceParameter/classInPropertyInitializer.kt");
|
||||||
doIntroduceParameterTest(fileName);
|
doIntroduceSimpleParameterTest(fileName);
|
||||||
}
|
}
|
||||||
|
|
||||||
@TestMetadata("classMultipleUsages1.kt")
|
@TestMetadata("classMultipleUsages1.kt")
|
||||||
public void testClassMultipleUsages1() throws Exception {
|
public void testClassMultipleUsages1() throws Exception {
|
||||||
String fileName = JetTestUtils.navigationMetadata("idea/testData/refactoring/introduceParameter/classMultipleUsages1.kt");
|
String fileName = JetTestUtils.navigationMetadata("idea/testData/refactoring/introduceParameter/classMultipleUsages1.kt");
|
||||||
doIntroduceParameterTest(fileName);
|
doIntroduceSimpleParameterTest(fileName);
|
||||||
}
|
}
|
||||||
|
|
||||||
@TestMetadata("classMultipleUsages2.kt")
|
@TestMetadata("classMultipleUsages2.kt")
|
||||||
public void testClassMultipleUsages2() throws Exception {
|
public void testClassMultipleUsages2() throws Exception {
|
||||||
String fileName = JetTestUtils.navigationMetadata("idea/testData/refactoring/introduceParameter/classMultipleUsages2.kt");
|
String fileName = JetTestUtils.navigationMetadata("idea/testData/refactoring/introduceParameter/classMultipleUsages2.kt");
|
||||||
doIntroduceParameterTest(fileName);
|
doIntroduceSimpleParameterTest(fileName);
|
||||||
}
|
}
|
||||||
|
|
||||||
@TestMetadata("classMultipleUsagesOutsideScope.kt")
|
@TestMetadata("classMultipleUsagesOutsideScope.kt")
|
||||||
public void testClassMultipleUsagesOutsideScope() throws Exception {
|
public void testClassMultipleUsagesOutsideScope() throws Exception {
|
||||||
String fileName = JetTestUtils.navigationMetadata("idea/testData/refactoring/introduceParameter/classMultipleUsagesOutsideScope.kt");
|
String fileName = JetTestUtils.navigationMetadata("idea/testData/refactoring/introduceParameter/classMultipleUsagesOutsideScope.kt");
|
||||||
doIntroduceParameterTest(fileName);
|
doIntroduceSimpleParameterTest(fileName);
|
||||||
}
|
}
|
||||||
|
|
||||||
@TestMetadata("classMultipleUsagesSingleReplace1.kt")
|
@TestMetadata("classMultipleUsagesSingleReplace1.kt")
|
||||||
public void testClassMultipleUsagesSingleReplace1() throws Exception {
|
public void testClassMultipleUsagesSingleReplace1() throws Exception {
|
||||||
String fileName = JetTestUtils.navigationMetadata("idea/testData/refactoring/introduceParameter/classMultipleUsagesSingleReplace1.kt");
|
String fileName = JetTestUtils.navigationMetadata("idea/testData/refactoring/introduceParameter/classMultipleUsagesSingleReplace1.kt");
|
||||||
doIntroduceParameterTest(fileName);
|
doIntroduceSimpleParameterTest(fileName);
|
||||||
}
|
}
|
||||||
|
|
||||||
@TestMetadata("classMultipleUsagesSingleReplace2.kt")
|
@TestMetadata("classMultipleUsagesSingleReplace2.kt")
|
||||||
public void testClassMultipleUsagesSingleReplace2() throws Exception {
|
public void testClassMultipleUsagesSingleReplace2() throws Exception {
|
||||||
String fileName = JetTestUtils.navigationMetadata("idea/testData/refactoring/introduceParameter/classMultipleUsagesSingleReplace2.kt");
|
String fileName = JetTestUtils.navigationMetadata("idea/testData/refactoring/introduceParameter/classMultipleUsagesSingleReplace2.kt");
|
||||||
doIntroduceParameterTest(fileName);
|
doIntroduceSimpleParameterTest(fileName);
|
||||||
}
|
}
|
||||||
|
|
||||||
@TestMetadata("classNoParams.kt")
|
@TestMetadata("classNoParams.kt")
|
||||||
public void testClassNoParams() throws Exception {
|
public void testClassNoParams() throws Exception {
|
||||||
String fileName = JetTestUtils.navigationMetadata("idea/testData/refactoring/introduceParameter/classNoParams.kt");
|
String fileName = JetTestUtils.navigationMetadata("idea/testData/refactoring/introduceParameter/classNoParams.kt");
|
||||||
doIntroduceParameterTest(fileName);
|
doIntroduceSimpleParameterTest(fileName);
|
||||||
}
|
}
|
||||||
|
|
||||||
@TestMetadata("classParameterInFunctionBody.kt")
|
@TestMetadata("classParameterInFunctionBody.kt")
|
||||||
public void testClassParameterInFunctionBody() throws Exception {
|
public void testClassParameterInFunctionBody() throws Exception {
|
||||||
String fileName = JetTestUtils.navigationMetadata("idea/testData/refactoring/introduceParameter/classParameterInFunctionBody.kt");
|
String fileName = JetTestUtils.navigationMetadata("idea/testData/refactoring/introduceParameter/classParameterInFunctionBody.kt");
|
||||||
doIntroduceParameterTest(fileName);
|
doIntroduceSimpleParameterTest(fileName);
|
||||||
}
|
}
|
||||||
|
|
||||||
@TestMetadata("classParameterUsedOutside.kt")
|
@TestMetadata("classParameterUsedOutside.kt")
|
||||||
public void testClassParameterUsedOutside() throws Exception {
|
public void testClassParameterUsedOutside() throws Exception {
|
||||||
String fileName = JetTestUtils.navigationMetadata("idea/testData/refactoring/introduceParameter/classParameterUsedOutside.kt");
|
String fileName = JetTestUtils.navigationMetadata("idea/testData/refactoring/introduceParameter/classParameterUsedOutside.kt");
|
||||||
doIntroduceParameterTest(fileName);
|
doIntroduceSimpleParameterTest(fileName);
|
||||||
}
|
}
|
||||||
|
|
||||||
@TestMetadata("classUnusedParameter.kt")
|
@TestMetadata("classUnusedParameter.kt")
|
||||||
public void testClassUnusedParameter() throws Exception {
|
public void testClassUnusedParameter() throws Exception {
|
||||||
String fileName = JetTestUtils.navigationMetadata("idea/testData/refactoring/introduceParameter/classUnusedParameter.kt");
|
String fileName = JetTestUtils.navigationMetadata("idea/testData/refactoring/introduceParameter/classUnusedParameter.kt");
|
||||||
doIntroduceParameterTest(fileName);
|
doIntroduceSimpleParameterTest(fileName);
|
||||||
}
|
}
|
||||||
|
|
||||||
@TestMetadata("classUsedParameter.kt")
|
@TestMetadata("classUsedParameter.kt")
|
||||||
public void testClassUsedParameter() throws Exception {
|
public void testClassUsedParameter() throws Exception {
|
||||||
String fileName = JetTestUtils.navigationMetadata("idea/testData/refactoring/introduceParameter/classUsedParameter.kt");
|
String fileName = JetTestUtils.navigationMetadata("idea/testData/refactoring/introduceParameter/classUsedParameter.kt");
|
||||||
doIntroduceParameterTest(fileName);
|
doIntroduceSimpleParameterTest(fileName);
|
||||||
}
|
}
|
||||||
|
|
||||||
@TestMetadata("defaultValueInParens.kt")
|
@TestMetadata("defaultValueInParens.kt")
|
||||||
public void testDefaultValueInParens() throws Exception {
|
public void testDefaultValueInParens() throws Exception {
|
||||||
String fileName = JetTestUtils.navigationMetadata("idea/testData/refactoring/introduceParameter/defaultValueInParens.kt");
|
String fileName = JetTestUtils.navigationMetadata("idea/testData/refactoring/introduceParameter/defaultValueInParens.kt");
|
||||||
doIntroduceParameterTest(fileName);
|
doIntroduceSimpleParameterTest(fileName);
|
||||||
}
|
}
|
||||||
|
|
||||||
@TestMetadata("forbiddenUsages.kt")
|
@TestMetadata("forbiddenUsages.kt")
|
||||||
public void testForbiddenUsages() throws Exception {
|
public void testForbiddenUsages() throws Exception {
|
||||||
String fileName = JetTestUtils.navigationMetadata("idea/testData/refactoring/introduceParameter/forbiddenUsages.kt");
|
String fileName = JetTestUtils.navigationMetadata("idea/testData/refactoring/introduceParameter/forbiddenUsages.kt");
|
||||||
doIntroduceParameterTest(fileName);
|
doIntroduceSimpleParameterTest(fileName);
|
||||||
}
|
}
|
||||||
|
|
||||||
@TestMetadata("fun.kt")
|
@TestMetadata("fun.kt")
|
||||||
public void testFun() throws Exception {
|
public void testFun() throws Exception {
|
||||||
String fileName = JetTestUtils.navigationMetadata("idea/testData/refactoring/introduceParameter/fun.kt");
|
String fileName = JetTestUtils.navigationMetadata("idea/testData/refactoring/introduceParameter/fun.kt");
|
||||||
doIntroduceParameterTest(fileName);
|
doIntroduceSimpleParameterTest(fileName);
|
||||||
}
|
}
|
||||||
|
|
||||||
@TestMetadata("functionMultipleUnusedParameters.kt")
|
@TestMetadata("functionMultipleUnusedParameters.kt")
|
||||||
public void testFunctionMultipleUnusedParameters() throws Exception {
|
public void testFunctionMultipleUnusedParameters() throws Exception {
|
||||||
String fileName = JetTestUtils.navigationMetadata("idea/testData/refactoring/introduceParameter/functionMultipleUnusedParameters.kt");
|
String fileName = JetTestUtils.navigationMetadata("idea/testData/refactoring/introduceParameter/functionMultipleUnusedParameters.kt");
|
||||||
doIntroduceParameterTest(fileName);
|
doIntroduceSimpleParameterTest(fileName);
|
||||||
}
|
}
|
||||||
|
|
||||||
@TestMetadata("functionMultipleUsages.kt")
|
@TestMetadata("functionMultipleUsages.kt")
|
||||||
public void testFunctionMultipleUsages() throws Exception {
|
public void testFunctionMultipleUsages() throws Exception {
|
||||||
String fileName = JetTestUtils.navigationMetadata("idea/testData/refactoring/introduceParameter/functionMultipleUsages.kt");
|
String fileName = JetTestUtils.navigationMetadata("idea/testData/refactoring/introduceParameter/functionMultipleUsages.kt");
|
||||||
doIntroduceParameterTest(fileName);
|
doIntroduceSimpleParameterTest(fileName);
|
||||||
}
|
}
|
||||||
|
|
||||||
@TestMetadata("functionMultipleUsagesSingleReplace.kt")
|
@TestMetadata("functionMultipleUsagesSingleReplace.kt")
|
||||||
public void testFunctionMultipleUsagesSingleReplace() throws Exception {
|
public void testFunctionMultipleUsagesSingleReplace() throws Exception {
|
||||||
String fileName = JetTestUtils.navigationMetadata("idea/testData/refactoring/introduceParameter/functionMultipleUsagesSingleReplace.kt");
|
String fileName = JetTestUtils.navigationMetadata("idea/testData/refactoring/introduceParameter/functionMultipleUsagesSingleReplace.kt");
|
||||||
doIntroduceParameterTest(fileName);
|
doIntroduceSimpleParameterTest(fileName);
|
||||||
}
|
}
|
||||||
|
|
||||||
@TestMetadata("functionUnusedParameter.kt")
|
@TestMetadata("functionUnusedParameter.kt")
|
||||||
public void testFunctionUnusedParameter() throws Exception {
|
public void testFunctionUnusedParameter() throws Exception {
|
||||||
String fileName = JetTestUtils.navigationMetadata("idea/testData/refactoring/introduceParameter/functionUnusedParameter.kt");
|
String fileName = JetTestUtils.navigationMetadata("idea/testData/refactoring/introduceParameter/functionUnusedParameter.kt");
|
||||||
doIntroduceParameterTest(fileName);
|
doIntroduceSimpleParameterTest(fileName);
|
||||||
}
|
}
|
||||||
|
|
||||||
@TestMetadata("functionUsedParameter.kt")
|
@TestMetadata("functionUsedParameter.kt")
|
||||||
public void testFunctionUsedParameter() throws Exception {
|
public void testFunctionUsedParameter() throws Exception {
|
||||||
String fileName = JetTestUtils.navigationMetadata("idea/testData/refactoring/introduceParameter/functionUsedParameter.kt");
|
String fileName = JetTestUtils.navigationMetadata("idea/testData/refactoring/introduceParameter/functionUsedParameter.kt");
|
||||||
doIntroduceParameterTest(fileName);
|
doIntroduceSimpleParameterTest(fileName);
|
||||||
}
|
}
|
||||||
|
|
||||||
@TestMetadata("functionWithApproximatedType.kt")
|
@TestMetadata("functionWithApproximatedType.kt")
|
||||||
public void testFunctionWithApproximatedType() throws Exception {
|
public void testFunctionWithApproximatedType() throws Exception {
|
||||||
String fileName = JetTestUtils.navigationMetadata("idea/testData/refactoring/introduceParameter/functionWithApproximatedType.kt");
|
String fileName = JetTestUtils.navigationMetadata("idea/testData/refactoring/introduceParameter/functionWithApproximatedType.kt");
|
||||||
doIntroduceParameterTest(fileName);
|
doIntroduceSimpleParameterTest(fileName);
|
||||||
}
|
}
|
||||||
|
|
||||||
@TestMetadata("functionWithDefaultValue.kt")
|
@TestMetadata("functionWithDefaultValue.kt")
|
||||||
public void testFunctionWithDefaultValue() throws Exception {
|
public void testFunctionWithDefaultValue() throws Exception {
|
||||||
String fileName = JetTestUtils.navigationMetadata("idea/testData/refactoring/introduceParameter/functionWithDefaultValue.kt");
|
String fileName = JetTestUtils.navigationMetadata("idea/testData/refactoring/introduceParameter/functionWithDefaultValue.kt");
|
||||||
doIntroduceParameterTest(fileName);
|
doIntroduceSimpleParameterTest(fileName);
|
||||||
}
|
}
|
||||||
|
|
||||||
@TestMetadata("localVar.kt")
|
@TestMetadata("localVar.kt")
|
||||||
public void testLocalVar() throws Exception {
|
public void testLocalVar() throws Exception {
|
||||||
String fileName = JetTestUtils.navigationMetadata("idea/testData/refactoring/introduceParameter/localVar.kt");
|
String fileName = JetTestUtils.navigationMetadata("idea/testData/refactoring/introduceParameter/localVar.kt");
|
||||||
doIntroduceParameterTest(fileName);
|
doIntroduceSimpleParameterTest(fileName);
|
||||||
}
|
}
|
||||||
|
|
||||||
@TestMetadata("propertyAccessor.kt")
|
@TestMetadata("propertyAccessor.kt")
|
||||||
public void testPropertyAccessor() throws Exception {
|
public void testPropertyAccessor() throws Exception {
|
||||||
String fileName = JetTestUtils.navigationMetadata("idea/testData/refactoring/introduceParameter/propertyAccessor.kt");
|
String fileName = JetTestUtils.navigationMetadata("idea/testData/refactoring/introduceParameter/propertyAccessor.kt");
|
||||||
doIntroduceParameterTest(fileName);
|
doIntroduceSimpleParameterTest(fileName);
|
||||||
}
|
}
|
||||||
|
|
||||||
@TestMetadata("return.kt")
|
@TestMetadata("return.kt")
|
||||||
public void testReturn() throws Exception {
|
public void testReturn() throws Exception {
|
||||||
String fileName = JetTestUtils.navigationMetadata("idea/testData/refactoring/introduceParameter/return.kt");
|
String fileName = JetTestUtils.navigationMetadata("idea/testData/refactoring/introduceParameter/return.kt");
|
||||||
doIntroduceParameterTest(fileName);
|
doIntroduceSimpleParameterTest(fileName);
|
||||||
}
|
}
|
||||||
|
|
||||||
@TestMetadata("secondaryConstructorWithDefaultValue.kt")
|
@TestMetadata("secondaryConstructorWithDefaultValue.kt")
|
||||||
public void testSecondaryConstructorWithDefaultValue() throws Exception {
|
public void testSecondaryConstructorWithDefaultValue() throws Exception {
|
||||||
String fileName = JetTestUtils.navigationMetadata("idea/testData/refactoring/introduceParameter/secondaryConstructorWithDefaultValue.kt");
|
String fileName = JetTestUtils.navigationMetadata("idea/testData/refactoring/introduceParameter/secondaryConstructorWithDefaultValue.kt");
|
||||||
doIntroduceParameterTest(fileName);
|
doIntroduceSimpleParameterTest(fileName);
|
||||||
}
|
}
|
||||||
|
|
||||||
@TestMetadata("throw.kt")
|
@TestMetadata("throw.kt")
|
||||||
public void testThrow() throws Exception {
|
public void testThrow() throws Exception {
|
||||||
String fileName = JetTestUtils.navigationMetadata("idea/testData/refactoring/introduceParameter/throw.kt");
|
String fileName = JetTestUtils.navigationMetadata("idea/testData/refactoring/introduceParameter/throw.kt");
|
||||||
doIntroduceParameterTest(fileName);
|
doIntroduceSimpleParameterTest(fileName);
|
||||||
}
|
}
|
||||||
|
|
||||||
@TestMetadata("valueAtCallSite.kt")
|
@TestMetadata("valueAtCallSite.kt")
|
||||||
public void testValueAtCallSite() throws Exception {
|
public void testValueAtCallSite() throws Exception {
|
||||||
String fileName = JetTestUtils.navigationMetadata("idea/testData/refactoring/introduceParameter/valueAtCallSite.kt");
|
String fileName = JetTestUtils.navigationMetadata("idea/testData/refactoring/introduceParameter/valueAtCallSite.kt");
|
||||||
doIntroduceParameterTest(fileName);
|
doIntroduceSimpleParameterTest(fileName);
|
||||||
}
|
}
|
||||||
|
|
||||||
@TestMetadata("valueAtCallSiteMultipleUsages.kt")
|
@TestMetadata("valueAtCallSiteMultipleUsages.kt")
|
||||||
public void testValueAtCallSiteMultipleUsages() throws Exception {
|
public void testValueAtCallSiteMultipleUsages() throws Exception {
|
||||||
String fileName = JetTestUtils.navigationMetadata("idea/testData/refactoring/introduceParameter/valueAtCallSiteMultipleUsages.kt");
|
String fileName = JetTestUtils.navigationMetadata("idea/testData/refactoring/introduceParameter/valueAtCallSiteMultipleUsages.kt");
|
||||||
doIntroduceParameterTest(fileName);
|
doIntroduceSimpleParameterTest(fileName);
|
||||||
}
|
}
|
||||||
|
|
||||||
@TestMetadata("while.kt")
|
@TestMetadata("while.kt")
|
||||||
public void testWhile() throws Exception {
|
public void testWhile() throws Exception {
|
||||||
String fileName = JetTestUtils.navigationMetadata("idea/testData/refactoring/introduceParameter/while.kt");
|
String fileName = JetTestUtils.navigationMetadata("idea/testData/refactoring/introduceParameter/while.kt");
|
||||||
doIntroduceParameterTest(fileName);
|
doIntroduceSimpleParameterTest(fileName);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@TestMetadata("idea/testData/refactoring/introduceLambdaParameter")
|
||||||
|
@TestDataPath("$PROJECT_ROOT")
|
||||||
|
@RunWith(JUnit3RunnerWithInners.class)
|
||||||
|
public static class IntroduceLambdaParameter extends AbstractJetExtractionTest {
|
||||||
|
public void testAllFilesPresentInIntroduceLambdaParameter() throws Exception {
|
||||||
|
JetTestUtils.assertAllTestsPresentByMetadata(this.getClass(), new File("idea/testData/refactoring/introduceLambdaParameter"), Pattern.compile("^(.+)\\.kt$"), true);
|
||||||
|
}
|
||||||
|
|
||||||
|
@TestMetadata("lambdaParamInPrimaryConstructor.kt")
|
||||||
|
public void testLambdaParamInPrimaryConstructor() throws Exception {
|
||||||
|
String fileName = JetTestUtils.navigationMetadata("idea/testData/refactoring/introduceLambdaParameter/lambdaParamInPrimaryConstructor.kt");
|
||||||
|
doIntroduceLambdaParameterTest(fileName);
|
||||||
|
}
|
||||||
|
|
||||||
|
@TestMetadata("lambdaParamMultiline.kt")
|
||||||
|
public void testLambdaParamMultiline() throws Exception {
|
||||||
|
String fileName = JetTestUtils.navigationMetadata("idea/testData/refactoring/introduceLambdaParameter/lambdaParamMultiline.kt");
|
||||||
|
doIntroduceLambdaParameterTest(fileName);
|
||||||
|
}
|
||||||
|
|
||||||
|
@TestMetadata("lambdaParamNoDefaultValue.kt")
|
||||||
|
public void testLambdaParamNoDefaultValue() throws Exception {
|
||||||
|
String fileName = JetTestUtils.navigationMetadata("idea/testData/refactoring/introduceLambdaParameter/lambdaParamNoDefaultValue.kt");
|
||||||
|
doIntroduceLambdaParameterTest(fileName);
|
||||||
|
}
|
||||||
|
|
||||||
|
@TestMetadata("lambdaParamNoDefaultValueSecondLambda.kt")
|
||||||
|
public void testLambdaParamNoDefaultValueSecondLambda() throws Exception {
|
||||||
|
String fileName = JetTestUtils.navigationMetadata("idea/testData/refactoring/introduceLambdaParameter/lambdaParamNoDefaultValueSecondLambda.kt");
|
||||||
|
doIntroduceLambdaParameterTest(fileName);
|
||||||
|
}
|
||||||
|
|
||||||
|
@TestMetadata("lambdaParamNoParams.kt")
|
||||||
|
public void testLambdaParamNoParams() throws Exception {
|
||||||
|
String fileName = JetTestUtils.navigationMetadata("idea/testData/refactoring/introduceLambdaParameter/lambdaParamNoParams.kt");
|
||||||
|
doIntroduceLambdaParameterTest(fileName);
|
||||||
|
}
|
||||||
|
|
||||||
|
@TestMetadata("lambdaParamOfNothing.kt")
|
||||||
|
public void testLambdaParamOfNothing() throws Exception {
|
||||||
|
String fileName = JetTestUtils.navigationMetadata("idea/testData/refactoring/introduceLambdaParameter/lambdaParamOfNothing.kt");
|
||||||
|
doIntroduceLambdaParameterTest(fileName);
|
||||||
|
}
|
||||||
|
|
||||||
|
@TestMetadata("lambdaParamOfUnit.kt")
|
||||||
|
public void testLambdaParamOfUnit() throws Exception {
|
||||||
|
String fileName = JetTestUtils.navigationMetadata("idea/testData/refactoring/introduceLambdaParameter/lambdaParamOfUnit.kt");
|
||||||
|
doIntroduceLambdaParameterTest(fileName);
|
||||||
|
}
|
||||||
|
|
||||||
|
@TestMetadata("lambdaParamWithDefaultValue.kt")
|
||||||
|
public void testLambdaParamWithDefaultValue() throws Exception {
|
||||||
|
String fileName = JetTestUtils.navigationMetadata("idea/testData/refactoring/introduceLambdaParameter/lambdaParamWithDefaultValue.kt");
|
||||||
|
doIntroduceLambdaParameterTest(fileName);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user