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/extractFunction", extension = "kt", testMethod = "doExtractFunctionTest")
|
||||
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>()) {
|
||||
|
||||
@@ -106,6 +106,13 @@
|
||||
<add-to-group group-id="IntroduceActionsGroup" anchor="after" relative-to-action="IntroduceField"/>
|
||||
</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"
|
||||
text="Copy Current File As Diagnostic Test">
|
||||
<keyboard-shortcut keymap="$default" first-keystroke="control alt shift T"/>
|
||||
|
||||
+1
-1
@@ -91,7 +91,7 @@ fun getFunctionForExtractedFragment(
|
||||
val options = ExtractionOptions(inferUnitTypeForUnusedValues = false,
|
||||
enableListBoxing = 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) {
|
||||
throw EvaluateExceptionUtil.createEvaluateException(getErrorMessageForExtractFunctionResult(analysisResult))
|
||||
}
|
||||
|
||||
@@ -24,6 +24,7 @@ import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
import org.jetbrains.kotlin.idea.refactoring.changeSignature.JetChangeSignatureHandler;
|
||||
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.introduceProperty.KotlinIntroducePropertyHandler;
|
||||
import org.jetbrains.kotlin.idea.refactoring.introduce.introduceVariable.KotlinIntroduceVariableHandler;
|
||||
@@ -47,6 +48,11 @@ public class JetRefactoringSupportProvider extends RefactoringSupportProvider {
|
||||
return new KotlinIntroduceParameterHandler();
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public RefactoringActionHandler getIntroduceLambdaParameterHandler() {
|
||||
return new KotlinIntroduceLambdaParameterHandler();
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public RefactoringActionHandler getIntroducePropertyHandler() {
|
||||
return new KotlinIntroducePropertyHandler();
|
||||
|
||||
+24
-16
@@ -210,16 +210,29 @@ public class KotlinExtractFunctionDialog extends DialogWrapper {
|
||||
|
||||
@NotNull
|
||||
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();
|
||||
for (KotlinParameterTablePanel.ParameterInfo parameterInfo : parameterInfos) {
|
||||
for (KotlinParameterTablePanel.ParameterInfo parameterInfo : newParameterInfos) {
|
||||
oldToNewParameters.put(parameterInfo.getOriginalParameter(), parameterInfo.toParameter());
|
||||
}
|
||||
|
||||
ControlFlow controlFlow = descriptor.getControlFlow();
|
||||
ControlFlow controlFlow = originalDescriptor.getControlFlow();
|
||||
List<OutputValue> outputValues = new ArrayList<OutputValue>(controlFlow.getOutputValues());
|
||||
for (int i = 0; i < outputValues.size(); i++) {
|
||||
OutputValue outputValue = outputValues.get(i);
|
||||
@@ -231,7 +244,7 @@ public class KotlinExtractFunctionDialog extends DialogWrapper {
|
||||
controlFlow = new ControlFlow(outputValues, controlFlow.getBoxerFactory(), controlFlow.getDeclarationsToCopy());
|
||||
|
||||
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();
|
||||
Replacement replacement = e.getValue();
|
||||
|
||||
@@ -250,20 +263,15 @@ public class KotlinExtractFunctionDialog extends DialogWrapper {
|
||||
}
|
||||
|
||||
return new ExtractableCodeDescriptor(
|
||||
descriptor.getExtractionData(),
|
||||
descriptor.getOriginalContext(),
|
||||
Collections.singletonList(getFunctionName()),
|
||||
getVisibility(),
|
||||
originalDescriptor.getExtractionData(),
|
||||
originalDescriptor.getOriginalContext(),
|
||||
Collections.singletonList(newName),
|
||||
newVisibility,
|
||||
ContainerUtil.newArrayList(oldToNewParameters.values()),
|
||||
descriptor.getReceiverParameter(),
|
||||
descriptor.getTypeParameters(),
|
||||
originalDescriptor.getReceiverParameter(),
|
||||
originalDescriptor.getTypeParameters(),
|
||||
replacementMap,
|
||||
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
|
||||
}
|
||||
|
||||
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") {
|
||||
override fun isAvailable(descriptor: ExtractableCodeDescriptor): Boolean {
|
||||
return checkSignatureAndParent(descriptor)
|
||||
|
||||
+1
@@ -72,6 +72,7 @@ data class ExtractionData(
|
||||
val originalFile: JetFile,
|
||||
val originalRange: JetPsiRange,
|
||||
val targetSibling: PsiElement,
|
||||
val duplicateContainer: PsiElement? = null,
|
||||
val options: ExtractionOptions = ExtractionOptions.DEFAULT
|
||||
) {
|
||||
val project: Project = originalFile.getProject()
|
||||
|
||||
+21
-11
@@ -61,7 +61,10 @@ fun ExtractionGeneratorConfiguration.getDeclarationText(
|
||||
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 ->
|
||||
builder.modifier(descriptor.visibility)
|
||||
|
||||
@@ -95,7 +98,9 @@ fun ExtractionGeneratorConfiguration.getDeclarationText(
|
||||
if (withBody) {
|
||||
val bodyText = descriptor.extractionData.codeFragmentText
|
||||
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.LAZY_PROPERTY -> builder.lazyBody(bodyText)
|
||||
}
|
||||
@@ -186,7 +191,7 @@ fun ExtractableCodeDescriptor.findDuplicates(): List<DuplicateInfo> {
|
||||
|
||||
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()
|
||||
return extractionData
|
||||
.originalRange
|
||||
@@ -513,13 +518,15 @@ fun ExtractionGeneratorConfiguration.generateDeclaration(
|
||||
val returnExpression = descriptor.controlFlow.outputValueBoxer.getReturnExpression(getReturnArguments(defaultExpression), psiFactory)
|
||||
if (returnExpression == null) return
|
||||
|
||||
if (generatorOptions.target == ExtractionTarget.LAZY_PROPERTY) {
|
||||
// In the case of lazy property absence of default value means that output values are of OutputValue.Initializer type
|
||||
// We just add resulting expressions without return, since returns are prohibited in the body of lazy property
|
||||
if (defaultValue == null) {
|
||||
body.appendElement(returnExpression.getReturnedExpression()!!)
|
||||
when(generatorOptions.target) {
|
||||
ExtractionTarget.LAZY_PROPERTY, ExtractionTarget.FAKE_LAMBDALIKE_FUNCTION -> {
|
||||
// In the case of lazy property absence of default value means that output values are of OutputValue.Initializer type
|
||||
// We just add resulting expressions without return, since returns are prohibited in the body of lazy property
|
||||
if (defaultValue == null) {
|
||||
body.appendElement(returnExpression.getReturnedExpression()!!)
|
||||
}
|
||||
return
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
when {
|
||||
@@ -579,7 +586,8 @@ fun ExtractionGeneratorConfiguration.generateDeclaration(
|
||||
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)
|
||||
|
||||
if (declaration is JetNamedFunction && declaration.getContainingJetFile().suppressDiagnosticsInDebugMode) {
|
||||
@@ -597,7 +605,9 @@ fun ExtractionGeneratorConfiguration.generateDeclaration(
|
||||
if (generatorOptions.inTempFile) return ExtractionResult(this, declaration, Collections.emptyMap(), nameByOffset)
|
||||
|
||||
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()
|
||||
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(
|
||||
val originalDescriptor: IntroduceParameterDescriptor,
|
||||
val addedParameter: JetParameter,
|
||||
val parameterType: JetType,
|
||||
editor: Editor,
|
||||
project: Project
|
||||
): KotlinInplaceVariableIntroducer<JetParameter>(
|
||||
originalDescriptor.addedParameter,
|
||||
addedParameter,
|
||||
editor,
|
||||
project,
|
||||
INTRODUCE_PARAMETER,
|
||||
JetExpression.EMPTY_ARRAY,
|
||||
null,
|
||||
false,
|
||||
originalDescriptor.addedParameter,
|
||||
addedParameter,
|
||||
false,
|
||||
true,
|
||||
originalDescriptor.parameterType,
|
||||
parameterType,
|
||||
false
|
||||
) {
|
||||
companion object {
|
||||
@@ -137,7 +139,7 @@ public class KotlinInplaceParameterIntroducer(
|
||||
val parameterName = currentName ?: parameter.getName()
|
||||
val parameterType = currentType ?: parameter.getTypeReference()!!.getText()
|
||||
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"
|
||||
}
|
||||
@@ -280,13 +282,18 @@ public class KotlinInplaceParameterIntroducer(
|
||||
return descriptor.callable
|
||||
}
|
||||
|
||||
private fun removeAddedParameter() {
|
||||
runWriteAction { JetPsiUtil.deleteElementWithDelimiters(addedParameter) }
|
||||
}
|
||||
|
||||
override fun performRefactoring(): Boolean {
|
||||
removeAddedParameter()
|
||||
descriptor.performRefactoring()
|
||||
return true
|
||||
}
|
||||
|
||||
override fun performCleanup() {
|
||||
runWriteAction { JetPsiUtil.deleteElementWithDelimiters(descriptor.addedParameter) }
|
||||
removeAddedParameter()
|
||||
}
|
||||
|
||||
override fun releaseResources() {
|
||||
@@ -301,9 +308,11 @@ public class KotlinInplaceParameterIntroducer(
|
||||
stopIntroduce()
|
||||
with (originalDescriptor) {
|
||||
KotlinIntroduceParameterDialog(myProject,
|
||||
myEditor,
|
||||
this,
|
||||
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
|
||||
|
||||
import com.intellij.openapi.editor.Editor
|
||||
import com.intellij.openapi.options.ConfigurationException
|
||||
import com.intellij.openapi.project.Project
|
||||
import com.intellij.openapi.ui.DialogWrapper
|
||||
import com.intellij.psi.PsiElement
|
||||
import com.intellij.psi.PsiNameHelper
|
||||
import com.intellij.refactoring.BaseRefactoringProcessor
|
||||
import com.intellij.refactoring.ui.NameSuggestionsField
|
||||
import com.intellij.refactoring.ui.RefactoringDialog
|
||||
import com.intellij.ui.NonFocusableCheckBox
|
||||
import com.intellij.ui.TitledSeparator
|
||||
import com.intellij.usageView.BaseUsageViewDescriptor
|
||||
import com.intellij.usageView.UsageInfo
|
||||
import com.intellij.usageView.UsageViewDescriptor
|
||||
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.application.executeCommand
|
||||
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.psi.*
|
||||
import org.jetbrains.kotlin.resolve.AnalyzingUtils
|
||||
import org.jetbrains.kotlin.types.JetType
|
||||
import java.awt.GridBagConstraints
|
||||
import java.awt.GridBagLayout
|
||||
import java.awt.Insets
|
||||
import java.util.ArrayList
|
||||
import java.util.Collections
|
||||
import java.util.LinkedHashMap
|
||||
import javax.swing.JCheckBox
|
||||
@@ -48,12 +46,39 @@ import javax.swing.JComponent
|
||||
import javax.swing.JLabel
|
||||
import javax.swing.JPanel
|
||||
|
||||
public class KotlinIntroduceParameterDialog(
|
||||
public class KotlinIntroduceParameterDialog private (
|
||||
project: Project,
|
||||
val editor: Editor,
|
||||
val descriptor: IntroduceParameterDescriptor,
|
||||
val lambdaExtractionDescriptor: ExtractableCodeDescriptor?,
|
||||
nameSuggestions: Array<String>,
|
||||
val typeSuggestions: List<JetType>
|
||||
val typeSuggestions: List<JetType>,
|
||||
val helper: KotlinIntroduceParameterHelper
|
||||
): 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
|
||||
.map { IdeDescriptorRenderers.SOURCE_CODE_SHORT_NAMES_IN_TYPES.renderType(it) }
|
||||
.copyToArray()
|
||||
@@ -62,9 +87,10 @@ public class KotlinIntroduceParameterDialog(
|
||||
private val typeField = NameSuggestionsField(typeNameSuggestions, project, JetFileType.INSTANCE)
|
||||
private var replaceAllCheckBox: JCheckBox? = null
|
||||
private val removeParamsCheckBoxes = LinkedHashMap<JCheckBox, JetParameter>(descriptor.parametersToRemove.size())
|
||||
private var parameterTablePanel: KotlinParameterTablePanel? = null
|
||||
|
||||
init {
|
||||
setTitle(INTRODUCE_PARAMETER)
|
||||
setTitle(if (lambdaExtractionDescriptor != null) INTRODUCE_LAMBDA_PARAMETER else INTRODUCE_PARAMETER)
|
||||
init()
|
||||
|
||||
nameField.addDataChangedListener { validateButtons() }
|
||||
@@ -87,7 +113,7 @@ public class KotlinIntroduceParameterDialog(
|
||||
gbConstraints.weightx = 0.0
|
||||
gbConstraints.weighty = 0.0
|
||||
gbConstraints.gridy = 0
|
||||
val nameLabel = JLabel("Parameter name:")
|
||||
val nameLabel = JLabel("Parameter name: ")
|
||||
nameLabel.setDisplayedMnemonic('n')
|
||||
nameLabel.setLabelFor(nameField)
|
||||
panel.add(nameLabel, gbConstraints)
|
||||
@@ -102,9 +128,9 @@ public class KotlinIntroduceParameterDialog(
|
||||
gbConstraints.gridwidth = 1
|
||||
gbConstraints.weightx = 0.0
|
||||
gbConstraints.gridx = 0
|
||||
gbConstraints.gridy = 1
|
||||
gbConstraints.gridy++
|
||||
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.setLabelFor(typeField)
|
||||
panel.add(typeLabel, gbConstraints)
|
||||
@@ -115,6 +141,39 @@ public class KotlinIntroduceParameterDialog(
|
||||
gbConstraints.fill = GridBagConstraints.BOTH
|
||||
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.insets = Insets(4, 0, 4, 8)
|
||||
gbConstraints.gridwidth = 2
|
||||
@@ -169,31 +228,82 @@ public class KotlinIntroduceParameterDialog(
|
||||
}
|
||||
|
||||
override fun doAction() {
|
||||
val descriptorToRefactor = descriptor.copy(
|
||||
addedParameter = JetPsiFactory(myProject).createParameter("${nameField.getEnteredName()}: ${typeField.getEnteredName()}"),
|
||||
occurrencesToReplace = with(descriptor) {
|
||||
if (replaceAllCheckBox?.isSelected() ?: true) {
|
||||
occurrencesToReplace
|
||||
}
|
||||
else {
|
||||
Collections.singletonList(originalOccurrence)
|
||||
}
|
||||
}
|
||||
)
|
||||
performRefactoring()
|
||||
}
|
||||
|
||||
public fun performRefactoring() {
|
||||
invokeRefactoring(
|
||||
object: BaseRefactoringProcessor(myProject) {
|
||||
object : BaseRefactoringProcessor(myProject) {
|
||||
override fun findUsages() = UsageInfo.EMPTY_ARRAY
|
||||
|
||||
override fun performRefactoring(usages: Array<out UsageInfo>) {
|
||||
descriptorToRefactor.performRefactoring(
|
||||
parametersToRemove =
|
||||
removeParamsCheckBoxes.filter { it.key.isEnabled() && it.key.isSelected() }.map { it.value }
|
||||
fun createLambdaForArgument(function: JetFunction): JetExpression {
|
||||
val statement = (function.getBodyExpression() as JetBlockExpression).getStatements().single()
|
||||
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 getCommandName() = INTRODUCE_PARAMETER
|
||||
override fun getCommandName() = if (lambdaExtractionDescriptor != null) INTRODUCE_LAMBDA_PARAMETER else INTRODUCE_PARAMETER
|
||||
}
|
||||
)
|
||||
}
|
||||
|
||||
+218
-102
@@ -20,21 +20,21 @@ import com.intellij.openapi.actionSystem.DataContext
|
||||
import com.intellij.openapi.application.ApplicationManager
|
||||
import com.intellij.openapi.editor.Editor
|
||||
import com.intellij.openapi.project.Project
|
||||
import com.intellij.openapi.util.TextRange
|
||||
import com.intellij.psi.PsiDocumentManager
|
||||
import com.intellij.psi.PsiElement
|
||||
import com.intellij.psi.PsiFile
|
||||
import com.intellij.psi.PsiReference
|
||||
import com.intellij.psi.search.LocalSearchScope
|
||||
import org.jetbrains.kotlin.builtins.KotlinBuiltIns
|
||||
import com.intellij.psi.util.PsiTreeUtil
|
||||
import org.jetbrains.kotlin.descriptors.ClassDescriptor
|
||||
import org.jetbrains.kotlin.descriptors.FunctionDescriptor
|
||||
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.refactoring.JetNameValidatorImpl
|
||||
import org.jetbrains.kotlin.idea.refactoring.JetRefactoringBundle
|
||||
import org.jetbrains.kotlin.idea.refactoring.changeSignature.*
|
||||
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.selectElementsWithTargetParent
|
||||
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.application.executeCommand
|
||||
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.toRange
|
||||
import org.jetbrains.kotlin.idea.util.supertypes
|
||||
import org.jetbrains.kotlin.psi.*
|
||||
import org.jetbrains.kotlin.psi.psiUtil.*
|
||||
import org.jetbrains.kotlin.resolve.BindingContext
|
||||
import org.jetbrains.kotlin.resolve.scopes.JetScopeUtils
|
||||
import org.jetbrains.kotlin.types.JetType
|
||||
import java.util.Collections
|
||||
import kotlin.test.fail
|
||||
|
||||
public data class IntroduceParameterDescriptor(
|
||||
val originalExpression: JetExpression,
|
||||
val originalRange: JetPsiRange,
|
||||
val callable: JetNamedDeclaration,
|
||||
val callableDescriptor: FunctionDescriptor,
|
||||
val addedParameter: JetParameter,
|
||||
val parameterType: JetType,
|
||||
val newParameterName: String,
|
||||
val newParameterTypeText: String,
|
||||
val newArgumentValue: JetExpression,
|
||||
val withDefaultValue: Boolean,
|
||||
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
|
||||
get() = occurrencesToReplace.first { it.isAncestor(originalExpression) }
|
||||
val originalOccurrence: JetPsiRange
|
||||
get() = occurrencesToReplace.first { it.getTextRange().intersects(originalRange.getTextRange()) }
|
||||
val valVar: JetValVar
|
||||
val parametersToRemove: List<JetParameter>
|
||||
|
||||
init {
|
||||
valVar = if (callable is JetClass) {
|
||||
@@ -79,47 +80,52 @@ public data class IntroduceParameterDescriptor(
|
||||
false
|
||||
it is JetClassInitializer ->
|
||||
true
|
||||
it is JetProperty && it.getInitializer()?.getTextRange()?.intersects(originalExpression.getTextRange()) ?: false ->
|
||||
it is JetProperty && it.getInitializer()?.getTextRange()?.intersects(originalRange.getTextRange()) ?: false ->
|
||||
true
|
||||
else ->
|
||||
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
|
||||
|
||||
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(
|
||||
withDefaultValue: Boolean,
|
||||
parametersUsages: Map<JetParameter, List<PsiReference>>,
|
||||
occurrencesToReplace: List<JetPsiRange>
|
||||
): List<JetParameter> {
|
||||
if (withDefaultValue) return Collections.emptyList()
|
||||
|
||||
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 {
|
||||
JetPsiUtil.deleteElementWithDelimiters(addedParameter)
|
||||
|
||||
val config = object: JetChangeSignatureConfiguration {
|
||||
val config = object : JetChangeSignatureConfiguration {
|
||||
override fun configure(originalDescriptor: JetMethodDescriptor, bindingContext: BindingContext): JetMethodDescriptor {
|
||||
return originalDescriptor.modify {
|
||||
val parameters = callable.getValueParameters()
|
||||
parametersToRemove.map { parameters.indexOf(it) }.sortDescending().forEach { removeParameter(it) }
|
||||
|
||||
val parameterInfo = JetParameterInfo(name = addedParameter.getName()!!,
|
||||
type = parameterType,
|
||||
defaultValueForCall = if (withDefaultValue) "" else originalExpression.getText(),
|
||||
defaultValueForParameter = if (withDefaultValue) originalExpression else null,
|
||||
if (!withDefaultValue) {
|
||||
val parameters = callable.getValueParameters()
|
||||
parametersToRemove.map { parameters.indexOf(it) }.sortDescending().forEach { removeParameter(it) }
|
||||
}
|
||||
|
||||
val parameterInfo = JetParameterInfo(name = newParameterName,
|
||||
defaultValueForCall = if (withDefaultValue) "" else newArgumentValue.getText(),
|
||||
defaultValueForParameter = if (withDefaultValue) newArgumentValue else null,
|
||||
valOrVar = valVar)
|
||||
parameterInfo.currentTypeText = addedParameter.getTypeReference()?.getText() ?: "Any"
|
||||
parameterInfo.currentTypeText = newParameterTypeText
|
||||
addParameter(parameterInfo)
|
||||
}
|
||||
}
|
||||
@@ -127,19 +133,49 @@ fun IntroduceParameterDescriptor.performRefactoring(parametersToRemove: List<Jet
|
||||
override fun performSilently(affectedFunctions: Collection<PsiElement>): Boolean = true
|
||||
}
|
||||
if (runChangeSignature(callable.getProject(), callableDescriptor, config, callable.analyze(), callable, INTRODUCE_PARAMETER)) {
|
||||
val paramRef = JetPsiFactory(callable).createSimpleName(addedParameter.getName()!!)
|
||||
occurrencesToReplace.forEach { it.replace(paramRef) }
|
||||
occurrencesToReplace.forEach(occurrenceReplacer)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public open class KotlinIntroduceParameterHandler: KotlinIntroduceHandlerBase() {
|
||||
open fun configure(descriptor: IntroduceParameterDescriptor): IntroduceParameterDescriptor = descriptor
|
||||
private fun isObjectOrNonInnerClass(e: PsiElement): Boolean = e is JetObjectDeclaration || (e is JetClass && !e.isInner())
|
||||
|
||||
private fun isObjectOrNonInnerClass(e: PsiElement): Boolean =
|
||||
e is JetObjectDeclaration || (e is JetClass && !e.isInner())
|
||||
fun selectNewParameterContext(
|
||||
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 expressionType = context.getType(expression)
|
||||
@@ -161,7 +197,7 @@ public open class KotlinIntroduceParameterHandler: KotlinIntroduceHandlerBase()
|
||||
is ClassDescriptor -> descriptor.getUnsubstitutedPrimaryConstructor()
|
||||
else -> null
|
||||
} ?: 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) {
|
||||
is JetFunction -> targetParent.getBodyExpression()
|
||||
@@ -169,18 +205,13 @@ public open class KotlinIntroduceParameterHandler: KotlinIntroduceHandlerBase()
|
||||
else -> null
|
||||
} ?: throw AssertionError("Body element is not found: ${targetParent.getElementTextWithContext()}")
|
||||
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()
|
||||
.filter { !it.hasValOrVarNode() }
|
||||
.map {
|
||||
it to DefaultSearchHelper<JetParameter>()
|
||||
.newRequest(UsagesSearchTarget(element = it))
|
||||
.search()
|
||||
.toList()
|
||||
}
|
||||
.filter { it.second.isNotEmpty() }
|
||||
.toMap()
|
||||
val parametersUsages = findInternalParameterUsages(targetParent)
|
||||
|
||||
val psiFactory = JetPsiFactory(project)
|
||||
val renderedType = IdeDescriptorRenderers.SOURCE_CODE_SHORT_NAMES_IN_TYPES.renderType(replacementType)
|
||||
val newParameter = psiFactory.createParameter("${suggestedNames.first()}: $renderedType")
|
||||
|
||||
val forbiddenRanges =
|
||||
if (targetParent is JetClass) {
|
||||
@@ -204,16 +235,12 @@ public open class KotlinIntroduceParameterHandler: KotlinIntroduceHandlerBase()
|
||||
} as? JetExpression
|
||||
}
|
||||
.filterNotNull()
|
||||
.map { it.toRange() }
|
||||
|
||||
project.executeCommand(
|
||||
INTRODUCE_PARAMETER,
|
||||
null,
|
||||
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 inplaceIsAvailable = editor.getSettings().isVariableInplaceRenameEnabled() && !isTestMode
|
||||
|
||||
@@ -243,15 +270,24 @@ public open class KotlinIntroduceParameterHandler: KotlinIntroduceHandlerBase()
|
||||
}
|
||||
else newParameter
|
||||
|
||||
val originalExpression = JetPsiUtil.safeDeparenthesize(expression)
|
||||
val newParameterName = addedParameter.getName()!!
|
||||
val replacement = psiFactory.createExpression(newParameterName)
|
||||
val introduceParameterDescriptor =
|
||||
configure(IntroduceParameterDescriptor(JetPsiUtil.deparenthesize(expression)!!,
|
||||
targetParent,
|
||||
functionDescriptor,
|
||||
addedParameter,
|
||||
parameterType,
|
||||
false,
|
||||
parametersUsages,
|
||||
occurrencesToReplace))
|
||||
helper.configure(
|
||||
IntroduceParameterDescriptor(
|
||||
originalRange = originalExpression.toRange(),
|
||||
callable = targetParent,
|
||||
callableDescriptor = functionDescriptor,
|
||||
newParameterName = newParameterName,
|
||||
newParameterTypeText = renderedType,
|
||||
newArgumentValue = originalExpression,
|
||||
withDefaultValue = false,
|
||||
parametersUsages = parametersUsages,
|
||||
occurrencesToReplace = occurrencesToReplace,
|
||||
occurrenceReplacer = { it.elements.single().replace(replacement) }
|
||||
)
|
||||
)
|
||||
if (isTestMode) {
|
||||
introduceParameterDescriptor.performRefactoring()
|
||||
return
|
||||
@@ -263,14 +299,20 @@ public open class KotlinIntroduceParameterHandler: KotlinIntroduceHandlerBase()
|
||||
doPostponedOperationsAndUnblockDocument(editor.getDocument())
|
||||
}
|
||||
|
||||
if (KotlinInplaceParameterIntroducer(introduceParameterDescriptor, editor, project)
|
||||
.startRefactoring(suggestedNames)) return
|
||||
val introducer = KotlinInplaceParameterIntroducer(introduceParameterDescriptor,
|
||||
addedParameter,
|
||||
replacementType,
|
||||
editor,
|
||||
project)
|
||||
if (introducer.startRefactoring(suggestedNames)) return
|
||||
}
|
||||
|
||||
KotlinIntroduceParameterDialog(project,
|
||||
editor,
|
||||
introduceParameterDescriptor,
|
||||
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
|
||||
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
|
||||
|
||||
(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)
|
||||
}
|
||||
}
|
||||
)
|
||||
selectNewParameterContext(editor, file) { 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?) {
|
||||
@@ -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
|
||||
if (adjustedElements.isNotEmpty()) {
|
||||
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) {
|
||||
val property = it.declaration as JetProperty
|
||||
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.ExtractKotlinFunctionHandler
|
||||
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.KotlinIntroduceParameterHandler
|
||||
import org.jetbrains.kotlin.idea.refactoring.introduce.introduceParameter.*
|
||||
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.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 ->
|
||||
val handler = object: KotlinIntroduceParameterHandler() {
|
||||
val fileText = file.getText()
|
||||
|
||||
open class HelperImpl: KotlinIntroduceParameterHelper {
|
||||
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) {
|
||||
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,
|
||||
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) {
|
||||
val target = file.findElementByComment("// TARGET:") as? JetNamedDeclaration
|
||||
val target = (file as JetFile).findElementByComment("// TARGET:") as? JetNamedDeclaration
|
||||
if (target != null) {
|
||||
JetRefactoringUtil.selectExpression(fixture.getEditor(), file, true) { expression ->
|
||||
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) {
|
||||
doTest(path) { file ->
|
||||
val extractionTarget = propertyTargets.single {
|
||||
|
||||
+88
-31
@@ -2203,187 +2203,244 @@ public class JetExtractionTestGenerated extends AbstractJetExtractionTest {
|
||||
@TestMetadata("assignment.kt")
|
||||
public void testAssignment() throws Exception {
|
||||
String fileName = JetTestUtils.navigationMetadata("idea/testData/refactoring/introduceParameter/assignment.kt");
|
||||
doIntroduceParameterTest(fileName);
|
||||
doIntroduceSimpleParameterTest(fileName);
|
||||
}
|
||||
|
||||
@TestMetadata("classInAnonymousInitializer.kt")
|
||||
public void testClassInAnonymousInitializer() throws Exception {
|
||||
String fileName = JetTestUtils.navigationMetadata("idea/testData/refactoring/introduceParameter/classInAnonymousInitializer.kt");
|
||||
doIntroduceParameterTest(fileName);
|
||||
doIntroduceSimpleParameterTest(fileName);
|
||||
}
|
||||
|
||||
@TestMetadata("classInPropertyInitializer.kt")
|
||||
public void testClassInPropertyInitializer() throws Exception {
|
||||
String fileName = JetTestUtils.navigationMetadata("idea/testData/refactoring/introduceParameter/classInPropertyInitializer.kt");
|
||||
doIntroduceParameterTest(fileName);
|
||||
doIntroduceSimpleParameterTest(fileName);
|
||||
}
|
||||
|
||||
@TestMetadata("classMultipleUsages1.kt")
|
||||
public void testClassMultipleUsages1() throws Exception {
|
||||
String fileName = JetTestUtils.navigationMetadata("idea/testData/refactoring/introduceParameter/classMultipleUsages1.kt");
|
||||
doIntroduceParameterTest(fileName);
|
||||
doIntroduceSimpleParameterTest(fileName);
|
||||
}
|
||||
|
||||
@TestMetadata("classMultipleUsages2.kt")
|
||||
public void testClassMultipleUsages2() throws Exception {
|
||||
String fileName = JetTestUtils.navigationMetadata("idea/testData/refactoring/introduceParameter/classMultipleUsages2.kt");
|
||||
doIntroduceParameterTest(fileName);
|
||||
doIntroduceSimpleParameterTest(fileName);
|
||||
}
|
||||
|
||||
@TestMetadata("classMultipleUsagesOutsideScope.kt")
|
||||
public void testClassMultipleUsagesOutsideScope() throws Exception {
|
||||
String fileName = JetTestUtils.navigationMetadata("idea/testData/refactoring/introduceParameter/classMultipleUsagesOutsideScope.kt");
|
||||
doIntroduceParameterTest(fileName);
|
||||
doIntroduceSimpleParameterTest(fileName);
|
||||
}
|
||||
|
||||
@TestMetadata("classMultipleUsagesSingleReplace1.kt")
|
||||
public void testClassMultipleUsagesSingleReplace1() throws Exception {
|
||||
String fileName = JetTestUtils.navigationMetadata("idea/testData/refactoring/introduceParameter/classMultipleUsagesSingleReplace1.kt");
|
||||
doIntroduceParameterTest(fileName);
|
||||
doIntroduceSimpleParameterTest(fileName);
|
||||
}
|
||||
|
||||
@TestMetadata("classMultipleUsagesSingleReplace2.kt")
|
||||
public void testClassMultipleUsagesSingleReplace2() throws Exception {
|
||||
String fileName = JetTestUtils.navigationMetadata("idea/testData/refactoring/introduceParameter/classMultipleUsagesSingleReplace2.kt");
|
||||
doIntroduceParameterTest(fileName);
|
||||
doIntroduceSimpleParameterTest(fileName);
|
||||
}
|
||||
|
||||
@TestMetadata("classNoParams.kt")
|
||||
public void testClassNoParams() throws Exception {
|
||||
String fileName = JetTestUtils.navigationMetadata("idea/testData/refactoring/introduceParameter/classNoParams.kt");
|
||||
doIntroduceParameterTest(fileName);
|
||||
doIntroduceSimpleParameterTest(fileName);
|
||||
}
|
||||
|
||||
@TestMetadata("classParameterInFunctionBody.kt")
|
||||
public void testClassParameterInFunctionBody() throws Exception {
|
||||
String fileName = JetTestUtils.navigationMetadata("idea/testData/refactoring/introduceParameter/classParameterInFunctionBody.kt");
|
||||
doIntroduceParameterTest(fileName);
|
||||
doIntroduceSimpleParameterTest(fileName);
|
||||
}
|
||||
|
||||
@TestMetadata("classParameterUsedOutside.kt")
|
||||
public void testClassParameterUsedOutside() throws Exception {
|
||||
String fileName = JetTestUtils.navigationMetadata("idea/testData/refactoring/introduceParameter/classParameterUsedOutside.kt");
|
||||
doIntroduceParameterTest(fileName);
|
||||
doIntroduceSimpleParameterTest(fileName);
|
||||
}
|
||||
|
||||
@TestMetadata("classUnusedParameter.kt")
|
||||
public void testClassUnusedParameter() throws Exception {
|
||||
String fileName = JetTestUtils.navigationMetadata("idea/testData/refactoring/introduceParameter/classUnusedParameter.kt");
|
||||
doIntroduceParameterTest(fileName);
|
||||
doIntroduceSimpleParameterTest(fileName);
|
||||
}
|
||||
|
||||
@TestMetadata("classUsedParameter.kt")
|
||||
public void testClassUsedParameter() throws Exception {
|
||||
String fileName = JetTestUtils.navigationMetadata("idea/testData/refactoring/introduceParameter/classUsedParameter.kt");
|
||||
doIntroduceParameterTest(fileName);
|
||||
doIntroduceSimpleParameterTest(fileName);
|
||||
}
|
||||
|
||||
@TestMetadata("defaultValueInParens.kt")
|
||||
public void testDefaultValueInParens() throws Exception {
|
||||
String fileName = JetTestUtils.navigationMetadata("idea/testData/refactoring/introduceParameter/defaultValueInParens.kt");
|
||||
doIntroduceParameterTest(fileName);
|
||||
doIntroduceSimpleParameterTest(fileName);
|
||||
}
|
||||
|
||||
@TestMetadata("forbiddenUsages.kt")
|
||||
public void testForbiddenUsages() throws Exception {
|
||||
String fileName = JetTestUtils.navigationMetadata("idea/testData/refactoring/introduceParameter/forbiddenUsages.kt");
|
||||
doIntroduceParameterTest(fileName);
|
||||
doIntroduceSimpleParameterTest(fileName);
|
||||
}
|
||||
|
||||
@TestMetadata("fun.kt")
|
||||
public void testFun() throws Exception {
|
||||
String fileName = JetTestUtils.navigationMetadata("idea/testData/refactoring/introduceParameter/fun.kt");
|
||||
doIntroduceParameterTest(fileName);
|
||||
doIntroduceSimpleParameterTest(fileName);
|
||||
}
|
||||
|
||||
@TestMetadata("functionMultipleUnusedParameters.kt")
|
||||
public void testFunctionMultipleUnusedParameters() throws Exception {
|
||||
String fileName = JetTestUtils.navigationMetadata("idea/testData/refactoring/introduceParameter/functionMultipleUnusedParameters.kt");
|
||||
doIntroduceParameterTest(fileName);
|
||||
doIntroduceSimpleParameterTest(fileName);
|
||||
}
|
||||
|
||||
@TestMetadata("functionMultipleUsages.kt")
|
||||
public void testFunctionMultipleUsages() throws Exception {
|
||||
String fileName = JetTestUtils.navigationMetadata("idea/testData/refactoring/introduceParameter/functionMultipleUsages.kt");
|
||||
doIntroduceParameterTest(fileName);
|
||||
doIntroduceSimpleParameterTest(fileName);
|
||||
}
|
||||
|
||||
@TestMetadata("functionMultipleUsagesSingleReplace.kt")
|
||||
public void testFunctionMultipleUsagesSingleReplace() throws Exception {
|
||||
String fileName = JetTestUtils.navigationMetadata("idea/testData/refactoring/introduceParameter/functionMultipleUsagesSingleReplace.kt");
|
||||
doIntroduceParameterTest(fileName);
|
||||
doIntroduceSimpleParameterTest(fileName);
|
||||
}
|
||||
|
||||
@TestMetadata("functionUnusedParameter.kt")
|
||||
public void testFunctionUnusedParameter() throws Exception {
|
||||
String fileName = JetTestUtils.navigationMetadata("idea/testData/refactoring/introduceParameter/functionUnusedParameter.kt");
|
||||
doIntroduceParameterTest(fileName);
|
||||
doIntroduceSimpleParameterTest(fileName);
|
||||
}
|
||||
|
||||
@TestMetadata("functionUsedParameter.kt")
|
||||
public void testFunctionUsedParameter() throws Exception {
|
||||
String fileName = JetTestUtils.navigationMetadata("idea/testData/refactoring/introduceParameter/functionUsedParameter.kt");
|
||||
doIntroduceParameterTest(fileName);
|
||||
doIntroduceSimpleParameterTest(fileName);
|
||||
}
|
||||
|
||||
@TestMetadata("functionWithApproximatedType.kt")
|
||||
public void testFunctionWithApproximatedType() throws Exception {
|
||||
String fileName = JetTestUtils.navigationMetadata("idea/testData/refactoring/introduceParameter/functionWithApproximatedType.kt");
|
||||
doIntroduceParameterTest(fileName);
|
||||
doIntroduceSimpleParameterTest(fileName);
|
||||
}
|
||||
|
||||
@TestMetadata("functionWithDefaultValue.kt")
|
||||
public void testFunctionWithDefaultValue() throws Exception {
|
||||
String fileName = JetTestUtils.navigationMetadata("idea/testData/refactoring/introduceParameter/functionWithDefaultValue.kt");
|
||||
doIntroduceParameterTest(fileName);
|
||||
doIntroduceSimpleParameterTest(fileName);
|
||||
}
|
||||
|
||||
@TestMetadata("localVar.kt")
|
||||
public void testLocalVar() throws Exception {
|
||||
String fileName = JetTestUtils.navigationMetadata("idea/testData/refactoring/introduceParameter/localVar.kt");
|
||||
doIntroduceParameterTest(fileName);
|
||||
doIntroduceSimpleParameterTest(fileName);
|
||||
}
|
||||
|
||||
@TestMetadata("propertyAccessor.kt")
|
||||
public void testPropertyAccessor() throws Exception {
|
||||
String fileName = JetTestUtils.navigationMetadata("idea/testData/refactoring/introduceParameter/propertyAccessor.kt");
|
||||
doIntroduceParameterTest(fileName);
|
||||
doIntroduceSimpleParameterTest(fileName);
|
||||
}
|
||||
|
||||
@TestMetadata("return.kt")
|
||||
public void testReturn() throws Exception {
|
||||
String fileName = JetTestUtils.navigationMetadata("idea/testData/refactoring/introduceParameter/return.kt");
|
||||
doIntroduceParameterTest(fileName);
|
||||
doIntroduceSimpleParameterTest(fileName);
|
||||
}
|
||||
|
||||
@TestMetadata("secondaryConstructorWithDefaultValue.kt")
|
||||
public void testSecondaryConstructorWithDefaultValue() throws Exception {
|
||||
String fileName = JetTestUtils.navigationMetadata("idea/testData/refactoring/introduceParameter/secondaryConstructorWithDefaultValue.kt");
|
||||
doIntroduceParameterTest(fileName);
|
||||
doIntroduceSimpleParameterTest(fileName);
|
||||
}
|
||||
|
||||
@TestMetadata("throw.kt")
|
||||
public void testThrow() throws Exception {
|
||||
String fileName = JetTestUtils.navigationMetadata("idea/testData/refactoring/introduceParameter/throw.kt");
|
||||
doIntroduceParameterTest(fileName);
|
||||
doIntroduceSimpleParameterTest(fileName);
|
||||
}
|
||||
|
||||
@TestMetadata("valueAtCallSite.kt")
|
||||
public void testValueAtCallSite() throws Exception {
|
||||
String fileName = JetTestUtils.navigationMetadata("idea/testData/refactoring/introduceParameter/valueAtCallSite.kt");
|
||||
doIntroduceParameterTest(fileName);
|
||||
doIntroduceSimpleParameterTest(fileName);
|
||||
}
|
||||
|
||||
@TestMetadata("valueAtCallSiteMultipleUsages.kt")
|
||||
public void testValueAtCallSiteMultipleUsages() throws Exception {
|
||||
String fileName = JetTestUtils.navigationMetadata("idea/testData/refactoring/introduceParameter/valueAtCallSiteMultipleUsages.kt");
|
||||
doIntroduceParameterTest(fileName);
|
||||
doIntroduceSimpleParameterTest(fileName);
|
||||
}
|
||||
|
||||
@TestMetadata("while.kt")
|
||||
public void testWhile() throws Exception {
|
||||
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