Change Signature: Substitute parameter references in default values of call expression arguments
This commit is contained in:
+5
-1
@@ -54,6 +54,7 @@ import org.jetbrains.kotlin.descriptors.Visibilities;
|
||||
import org.jetbrains.kotlin.descriptors.Visibility;
|
||||
import org.jetbrains.kotlin.idea.JetFileType;
|
||||
import org.jetbrains.kotlin.idea.refactoring.JetRefactoringBundle;
|
||||
import org.jetbrains.kotlin.psi.JetExpression;
|
||||
import org.jetbrains.kotlin.psi.JetExpressionCodeFragment;
|
||||
import org.jetbrains.kotlin.psi.JetTypeCodeFragment;
|
||||
import org.jetbrains.kotlin.types.JetType;
|
||||
@@ -459,7 +460,10 @@ public class JetChangeSignatureDialog extends ChangeSignatureDialogBase<
|
||||
parameter.setCurrentTypeText(myParametersTableModel.getItems().get(i).typeCodeFragment.getText().trim());
|
||||
JetExpressionCodeFragment codeFragment =
|
||||
(JetExpressionCodeFragment) myParametersTableModel.getItems().get(i).defaultValueCodeFragment;
|
||||
parameter.setDefaultValueForCall(codeFragment.getContentElement());
|
||||
JetExpression oldDefaultValue = parameter.getDefaultValueForCall();
|
||||
if (!codeFragment.getText().equals(oldDefaultValue != null ? oldDefaultValue.getText() : "")) {
|
||||
parameter.setDefaultValueForCall(codeFragment.getContentElement());
|
||||
}
|
||||
}
|
||||
|
||||
String returnTypeText = myReturnTypeCodeFragment != null ? myReturnTypeCodeFragment.getText().trim() : "";
|
||||
|
||||
@@ -17,16 +17,22 @@
|
||||
package org.jetbrains.kotlin.idea.refactoring.changeSignature
|
||||
|
||||
import com.intellij.psi.PsiElement
|
||||
import com.intellij.psi.PsiReference
|
||||
import com.intellij.refactoring.changeSignature.ParameterInfo
|
||||
import org.jetbrains.kotlin.descriptors.FunctionDescriptor
|
||||
import org.jetbrains.kotlin.descriptors.*
|
||||
import org.jetbrains.kotlin.descriptors.impl.AnonymousFunctionDescriptor
|
||||
import org.jetbrains.kotlin.idea.caches.resolve.analyze
|
||||
import org.jetbrains.kotlin.idea.refactoring.changeSignature.usages.JetFunctionDefinitionUsage
|
||||
import org.jetbrains.kotlin.idea.references.JetReference
|
||||
import org.jetbrains.kotlin.idea.util.IdeDescriptorRenderers
|
||||
import org.jetbrains.kotlin.psi.JetExpression
|
||||
import org.jetbrains.kotlin.psi.JetModifierList
|
||||
import org.jetbrains.kotlin.psi.JetParameter
|
||||
import org.jetbrains.kotlin.psi.*
|
||||
import org.jetbrains.kotlin.resolve.BindingContext
|
||||
import org.jetbrains.kotlin.resolve.DescriptorToSourceUtils
|
||||
import org.jetbrains.kotlin.resolve.calls.callUtil.getResolvedCall
|
||||
import org.jetbrains.kotlin.resolve.lazy.BodyResolveMode
|
||||
import org.jetbrains.kotlin.resolve.scopes.receivers.ThisReceiver
|
||||
import org.jetbrains.kotlin.types.JetType
|
||||
import java.util.LinkedHashMap
|
||||
|
||||
public class JetParameterInfo(
|
||||
val functionDescriptor: FunctionDescriptor,
|
||||
@@ -41,6 +47,54 @@ public class JetParameterInfo(
|
||||
val originalType: JetType? = type
|
||||
var currentTypeText: String = getOldTypeText()
|
||||
|
||||
public val defaultValueParameterReferences: Map<PsiReference, DeclarationDescriptor>
|
||||
|
||||
init {
|
||||
val file = defaultValueForCall?.getContainingFile() as? JetFile
|
||||
defaultValueParameterReferences =
|
||||
if (defaultValueForCall != null && file != null && (file.isPhysical() || file.analysisContext != null)) {
|
||||
val map = LinkedHashMap<PsiReference, DeclarationDescriptor>()
|
||||
|
||||
defaultValueForCall!!.accept(
|
||||
object : JetTreeVisitorVoid() {
|
||||
private fun getRelevantDescriptor(
|
||||
expression: JetSimpleNameExpression,
|
||||
ref: JetReference
|
||||
): DeclarationDescriptor? {
|
||||
val context = expression.analyze(BodyResolveMode.PARTIAL)
|
||||
|
||||
val descriptor = ref.resolveToDescriptors(context).singleOrNull()
|
||||
if (descriptor is ValueParameterDescriptor) return descriptor
|
||||
|
||||
if (descriptor is PropertyDescriptor && functionDescriptor is ConstructorDescriptor) {
|
||||
val parameter = DescriptorToSourceUtils.getSourceFromDescriptor(descriptor) as? JetParameter
|
||||
return parameter?.let { context[BindingContext.VALUE_PARAMETER, it] }
|
||||
}
|
||||
|
||||
val resolvedCall = expression.getResolvedCall(context) ?: return null
|
||||
(resolvedCall.getResultingDescriptor() as? ReceiverParameterDescriptor)?.let { return it }
|
||||
|
||||
(resolvedCall.getExtensionReceiver() as? ThisReceiver)?.let { return it.getDeclarationDescriptor() }
|
||||
(resolvedCall.getDispatchReceiver() as? ThisReceiver)?.let { return it.getDeclarationDescriptor() }
|
||||
|
||||
return null
|
||||
}
|
||||
|
||||
override fun visitSimpleNameExpression(expression: JetSimpleNameExpression) {
|
||||
val ref = expression.getReference() as? JetReference ?: return
|
||||
val descriptor = getRelevantDescriptor(expression, ref) ?: return
|
||||
map[ref] = descriptor
|
||||
}
|
||||
}
|
||||
)
|
||||
|
||||
map
|
||||
}
|
||||
else {
|
||||
emptyMap()
|
||||
}
|
||||
}
|
||||
|
||||
private fun getOldTypeText() = originalType?.let { IdeDescriptorRenderers.SOURCE_CODE_SHORT_NAMES_IN_TYPES.renderType(it) } ?: ""
|
||||
|
||||
override fun getOldIndex(): Int = originalIndex
|
||||
|
||||
+180
-17
@@ -17,32 +17,63 @@
|
||||
package org.jetbrains.kotlin.idea.refactoring.changeSignature.usages;
|
||||
|
||||
import com.intellij.psi.PsiElement;
|
||||
import com.intellij.psi.PsiReference;
|
||||
import com.intellij.psi.util.PsiTreeUtil;
|
||||
import com.intellij.util.containers.ContainerUtil;
|
||||
import gnu.trove.TIntArrayList;
|
||||
import gnu.trove.TIntProcedure;
|
||||
import kotlin.Function1;
|
||||
import kotlin.KotlinPackage;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
import org.jetbrains.kotlin.descriptors.CallableDescriptor;
|
||||
import org.jetbrains.kotlin.descriptors.ClassDescriptor;
|
||||
import org.jetbrains.kotlin.descriptors.DeclarationDescriptor;
|
||||
import org.jetbrains.kotlin.descriptors.*;
|
||||
import org.jetbrains.kotlin.idea.caches.resolve.ResolvePackage;
|
||||
import org.jetbrains.kotlin.idea.refactoring.changeSignature.JetChangeInfo;
|
||||
import org.jetbrains.kotlin.idea.refactoring.changeSignature.JetParameterInfo;
|
||||
import org.jetbrains.kotlin.idea.refactoring.introduce.extractionEngine.ExtractionEnginePackage;
|
||||
import org.jetbrains.kotlin.idea.util.ShortenReferences;
|
||||
import org.jetbrains.kotlin.idea.util.psiModificationUtil.PsiModificationUtilPackage;
|
||||
import org.jetbrains.kotlin.psi.*;
|
||||
import org.jetbrains.kotlin.resolve.calls.callUtil.CallUtilPackage;
|
||||
import org.jetbrains.kotlin.resolve.calls.model.ExpressionValueArgument;
|
||||
import org.jetbrains.kotlin.resolve.calls.model.ResolvedCall;
|
||||
import org.jetbrains.kotlin.resolve.calls.model.ResolvedValueArgument;
|
||||
import org.jetbrains.kotlin.resolve.lazy.BodyResolveMode;
|
||||
import org.jetbrains.kotlin.resolve.scopes.receivers.ExpressionReceiver;
|
||||
import org.jetbrains.kotlin.resolve.scopes.receivers.ExtensionReceiver;
|
||||
import org.jetbrains.kotlin.resolve.scopes.receivers.ReceiverValue;
|
||||
import org.jetbrains.kotlin.resolve.scopes.receivers.ThisReceiver;
|
||||
import org.jetbrains.kotlin.types.JetType;
|
||||
import org.jetbrains.kotlin.types.checker.JetTypeChecker;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.*;
|
||||
|
||||
import static org.jetbrains.kotlin.psi.PsiPackage.JetPsiFactory;
|
||||
|
||||
public class JetFunctionCallUsage extends JetUsageInfo<JetCallElement> {
|
||||
private static final Comparator<Map.Entry<PsiReference, DeclarationDescriptor>>
|
||||
REVERSE_TEXT_OFFSET_COMPARATOR = new Comparator<Map.Entry<PsiReference, DeclarationDescriptor>>() {
|
||||
@Override
|
||||
public int compare(
|
||||
@NotNull Map.Entry<PsiReference, DeclarationDescriptor> o1,
|
||||
@NotNull Map.Entry<PsiReference, DeclarationDescriptor> o2
|
||||
) {
|
||||
int offset1 = o1.getKey().getElement().getTextRange().getStartOffset();
|
||||
int offset2 = o2.getKey().getElement().getTextRange().getStartOffset();
|
||||
return offset1 < offset2 ? 1
|
||||
: offset1 > offset2 ? -1
|
||||
: 0;
|
||||
}
|
||||
};
|
||||
|
||||
private static final Function1<JetElement, ShortenReferences.Options>
|
||||
SHORTEN_ARGUMENTS_OPTIONS = new Function1<JetElement, ShortenReferences.Options>() {
|
||||
@Override
|
||||
public ShortenReferences.Options invoke(JetElement element) {
|
||||
return new ShortenReferences.Options(true, true);
|
||||
}
|
||||
};
|
||||
|
||||
private final JetFunctionDefinitionUsage<?> callee;
|
||||
private final ResolvedCall<? extends CallableDescriptor> resolvedCall;
|
||||
|
||||
@@ -84,6 +115,111 @@ public class JetFunctionCallUsage extends JetUsageInfo<JetCallElement> {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
private JetExpression getReceiverExpressionIfMatched(
|
||||
@NotNull ReceiverValue receiverValue,
|
||||
@NotNull DeclarationDescriptor originalDescriptor,
|
||||
@NotNull JetPsiFactory psiFactory
|
||||
) {
|
||||
if (!receiverValue.exists()) return null;
|
||||
|
||||
// Replace descriptor of extension function/property with descriptor of its receiver
|
||||
// to simplify checking against receiver value in the corresponding resolved call
|
||||
if (originalDescriptor instanceof CallableDescriptor && !(originalDescriptor instanceof ReceiverParameterDescriptor)) {
|
||||
ReceiverParameterDescriptor receiverParameter = ((CallableDescriptor) originalDescriptor).getExtensionReceiverParameter();
|
||||
if (receiverParameter == null) return null;
|
||||
originalDescriptor = receiverParameter;
|
||||
}
|
||||
|
||||
boolean currentIsExtension = resolvedCall.getExtensionReceiver() == receiverValue;
|
||||
boolean originalIsExtension =
|
||||
originalDescriptor instanceof ReceiverParameterDescriptor &&
|
||||
((ReceiverParameterDescriptor) originalDescriptor).getValue() instanceof ExtensionReceiver;
|
||||
if (currentIsExtension != originalIsExtension) return null;
|
||||
|
||||
JetType originalType = originalDescriptor instanceof ReceiverParameterDescriptor
|
||||
? ((ReceiverParameterDescriptor) originalDescriptor).getType()
|
||||
: originalDescriptor instanceof ClassDescriptor
|
||||
? ((ClassDescriptor) originalDescriptor).getDefaultType()
|
||||
: null;
|
||||
if (originalType == null || !JetTypeChecker.DEFAULT.isSubtypeOf(receiverValue.getType(), originalType)) return null;
|
||||
|
||||
return getReceiverExpression(receiverValue, psiFactory);
|
||||
}
|
||||
|
||||
@NotNull
|
||||
private JetExpression substituteReferences(
|
||||
@NotNull JetExpression expression,
|
||||
@NotNull Map<PsiReference, DeclarationDescriptor> referenceMap,
|
||||
@NotNull JetPsiFactory psiFactory
|
||||
) {
|
||||
if (referenceMap.isEmpty() || resolvedCall == null) return expression;
|
||||
|
||||
JetExpression newExpression = (JetExpression) expression.copy();
|
||||
|
||||
Map<JetSimpleNameExpression, JetSimpleNameExpression> nameCounterpartMap =
|
||||
ExtractionEnginePackage.createNameCounterpartMap(expression, newExpression);
|
||||
|
||||
Map<ValueParameterDescriptor, ResolvedValueArgument> valueArguments = resolvedCall.getValueArguments();
|
||||
// Sort by descending offset so that call arguments are replaced before call itself
|
||||
List<Map.Entry<PsiReference, DeclarationDescriptor>> sortedEntries =
|
||||
ContainerUtil.sorted(referenceMap.entrySet(), REVERSE_TEXT_OFFSET_COMPARATOR);
|
||||
for (Map.Entry<PsiReference, DeclarationDescriptor> e : sortedEntries) {
|
||||
DeclarationDescriptor descriptor = e.getValue();
|
||||
|
||||
JetExpression argumentExpression;
|
||||
boolean addReceiver = false;
|
||||
if (descriptor instanceof ValueParameterDescriptor) { // Ordinary parameter
|
||||
// Find corresponding parameter in the current function (may differ from 'descriptor' if original function is part of override hierarchy)
|
||||
ValueParameterDescriptor parameterDescriptor =
|
||||
resolvedCall.getResultingDescriptor().getValueParameters().get(((ValueParameterDescriptor) descriptor).getIndex());
|
||||
|
||||
ResolvedValueArgument resolvedValueArgument = valueArguments.get(parameterDescriptor);
|
||||
if (!(resolvedValueArgument instanceof ExpressionValueArgument)) continue;
|
||||
|
||||
ValueArgument argument = ((ExpressionValueArgument) resolvedValueArgument).getValueArgument();
|
||||
if (argument == null) continue;
|
||||
|
||||
argumentExpression = argument.getArgumentExpression();
|
||||
}
|
||||
else {
|
||||
addReceiver = !(descriptor instanceof ReceiverParameterDescriptor);
|
||||
argumentExpression = getReceiverExpressionIfMatched(resolvedCall.getExtensionReceiver(), descriptor, psiFactory);
|
||||
if (argumentExpression == null) {
|
||||
argumentExpression = getReceiverExpressionIfMatched(resolvedCall.getDispatchReceiver(), descriptor, psiFactory);
|
||||
}
|
||||
}
|
||||
if (argumentExpression == null) continue;
|
||||
|
||||
//noinspection SuspiciousMethodCalls
|
||||
JetExpression expressionToReplace = nameCounterpartMap.get(e.getKey().getElement());
|
||||
if (expressionToReplace == null) continue;
|
||||
PsiElement parent = expressionToReplace.getParent();
|
||||
if (parent instanceof JetThisExpression) {
|
||||
expressionToReplace = (JetThisExpression) parent;
|
||||
}
|
||||
|
||||
if (addReceiver) {
|
||||
JetCallExpression callExpression = PsiTreeUtil.getParentOfType(expressionToReplace, JetCallExpression.class, true);
|
||||
if (callExpression != null && PsiTreeUtil.isAncestor(callExpression.getCalleeExpression(), expressionToReplace, false)) {
|
||||
expressionToReplace = callExpression;
|
||||
} else {
|
||||
// Do not substitute operation references in infix/prefix calls
|
||||
if (parent instanceof JetOperationExpression
|
||||
&& ((JetOperationExpression) parent).getOperationReference() == expressionToReplace) {
|
||||
continue;
|
||||
}
|
||||
}
|
||||
expressionToReplace.replace(psiFactory.createExpression(argumentExpression.getText() + "." + expressionToReplace.getText()));
|
||||
}
|
||||
else {
|
||||
expressionToReplace.replace(argumentExpression);
|
||||
}
|
||||
}
|
||||
|
||||
return newExpression;
|
||||
}
|
||||
|
||||
private void updateArgumentsAndReceiver(JetChangeInfo changeInfo, JetCallElement element) {
|
||||
JetValueArgumentList arguments = element.getValueArgumentList();
|
||||
assert arguments != null : "Argument list is expected: " + element.getText();
|
||||
@@ -93,15 +229,25 @@ public class JetFunctionCallUsage extends JetUsageInfo<JetCallElement> {
|
||||
StringBuilder parametersBuilder = new StringBuilder("(");
|
||||
boolean isFirst = true;
|
||||
|
||||
TIntArrayList indicesOfArgumentsWithDefaultValues = new TIntArrayList();
|
||||
|
||||
JetPsiFactory psiFactory = new JetPsiFactory(element.getProject());
|
||||
|
||||
List<JetParameterInfo> newSignatureParameters = changeInfo.getNonReceiverParameters();
|
||||
for (JetParameterInfo parameterInfo : newSignatureParameters) {
|
||||
if (isFirst)
|
||||
if (isFirst) {
|
||||
isFirst = false;
|
||||
else
|
||||
}
|
||||
else {
|
||||
parametersBuilder.append(',');
|
||||
}
|
||||
|
||||
JetExpression defaultValueForCall = parameterInfo.getDefaultValueForCall();
|
||||
String defaultValueText = defaultValueForCall != null ? defaultValueForCall.getText() : "";
|
||||
String defaultValueText = defaultValueForCall != null
|
||||
? substituteReferences(defaultValueForCall,
|
||||
parameterInfo.getDefaultValueParameterReferences(),
|
||||
psiFactory).getText()
|
||||
: "";
|
||||
|
||||
if (isNamedCall) {
|
||||
String newName = parameterInfo.getInheritedName(callee);
|
||||
@@ -112,10 +258,9 @@ public class JetFunctionCallUsage extends JetUsageInfo<JetCallElement> {
|
||||
}
|
||||
|
||||
parametersBuilder.append(')');
|
||||
JetValueArgumentList newArguments = JetPsiFactory(getProject()).createCallArguments(parametersBuilder.toString());
|
||||
JetValueArgumentList newArgumentList = JetPsiFactory(getProject()).createCallArguments(parametersBuilder.toString());
|
||||
|
||||
Map<Integer, ? extends ValueArgument> argumentMap = getParamIndexToArgumentMap(changeInfo, oldArguments);
|
||||
int argIndex = 0;
|
||||
|
||||
JetParameterInfo newReceiverInfo = changeInfo.getReceiverParameterInfo();
|
||||
JetParameterInfo originalReceiverInfo = changeInfo.getMethodDescriptor().getReceiver();
|
||||
@@ -123,8 +268,6 @@ public class JetFunctionCallUsage extends JetUsageInfo<JetCallElement> {
|
||||
ReceiverValue extensionReceiver = resolvedCall != null ? resolvedCall.getExtensionReceiver() : ReceiverValue.NO_RECEIVER;
|
||||
ReceiverValue dispatchReceiver = resolvedCall != null ? resolvedCall.getDispatchReceiver() : ReceiverValue.NO_RECEIVER;
|
||||
|
||||
JetPsiFactory psiFactory = new JetPsiFactory(element.getProject());
|
||||
|
||||
PsiElement elementToReplace = element;
|
||||
PsiElement parent = element.getParent();
|
||||
if (parent instanceof JetQualifiedExpression && ((JetQualifiedExpression) parent).getSelectorExpression() == element) {
|
||||
@@ -136,13 +279,17 @@ public class JetFunctionCallUsage extends JetUsageInfo<JetCallElement> {
|
||||
&& elementToReplace instanceof JetQualifiedExpression
|
||||
&& dispatchReceiver instanceof ExpressionReceiver) return;
|
||||
|
||||
for (JetValueArgument newArgument : newArguments.getArguments()) {
|
||||
JetParameterInfo parameterInfo = newSignatureParameters.get(argIndex++);
|
||||
List<JetValueArgument> newArguments = newArgumentList.getArguments();
|
||||
int actualIndex = 0;
|
||||
for (int i = 0; i < newArguments.size(); i++) {
|
||||
JetValueArgument newArgument = newArguments.get(i);
|
||||
JetParameterInfo parameterInfo = newSignatureParameters.get(i);
|
||||
if (parameterInfo == originalReceiverInfo) {
|
||||
JetExpression receiverExpression = getReceiverExpression(extensionReceiver, psiFactory);
|
||||
if (receiverExpression != null) {
|
||||
newArgument.replace(receiverExpression);
|
||||
}
|
||||
actualIndex++;
|
||||
continue;
|
||||
}
|
||||
|
||||
@@ -166,6 +313,9 @@ public class JetFunctionCallUsage extends JetUsageInfo<JetCallElement> {
|
||||
newArgument.delete();
|
||||
}
|
||||
}
|
||||
else {
|
||||
indicesOfArgumentsWithDefaultValues.add(actualIndex++);
|
||||
}
|
||||
}
|
||||
|
||||
List<JetFunctionLiteralArgument> lambdaArguments = element.getFunctionLiteralArguments();
|
||||
@@ -173,10 +323,23 @@ public class JetFunctionCallUsage extends JetUsageInfo<JetCallElement> {
|
||||
element.deleteChildRange(KotlinPackage.first(lambdaArguments), KotlinPackage.last(lambdaArguments));
|
||||
}
|
||||
|
||||
JetValueArgument lastArgument = KotlinPackage.lastOrNull(newArguments.getArguments());
|
||||
JetValueArgument lastArgument = KotlinPackage.lastOrNull(newArgumentList.getArguments());
|
||||
boolean hasTrailingLambdaInArgumentListAfter = lastArgument != null && lastArgument.getArgumentExpression() instanceof JetFunctionLiteralExpression;
|
||||
|
||||
arguments.replace(newArguments);
|
||||
arguments = (JetValueArgumentList) arguments.replace(newArgumentList);
|
||||
|
||||
final List<JetElement> argumentsToShorten = new ArrayList<JetElement>(indicesOfArgumentsWithDefaultValues.size());
|
||||
final List<JetValueArgument> argumentList = arguments.getArguments();
|
||||
indicesOfArgumentsWithDefaultValues.forEach(
|
||||
new TIntProcedure() {
|
||||
@Override
|
||||
public boolean execute(int i) {
|
||||
argumentsToShorten.add(argumentList.get(i));
|
||||
return true;
|
||||
}
|
||||
}
|
||||
);
|
||||
new ShortenReferences(SHORTEN_ARGUMENTS_OPTIONS).process(argumentsToShorten);
|
||||
|
||||
JetElement newElement = element;
|
||||
if (newReceiverInfo != originalReceiverInfo) {
|
||||
|
||||
@@ -0,0 +1,9 @@
|
||||
// WITH_DEFAULT_VALUE: false
|
||||
fun foo(a: Int): Int {
|
||||
val b = 1
|
||||
return (<selection>a + b</selection>) * 2
|
||||
}
|
||||
|
||||
fun test() {
|
||||
foo(1)
|
||||
}
|
||||
@@ -0,0 +1,9 @@
|
||||
// WITH_DEFAULT_VALUE: false
|
||||
fun foo(i: Int): Int {
|
||||
val b = 1
|
||||
return i * 2
|
||||
}
|
||||
|
||||
fun test() {
|
||||
foo(1 + b)
|
||||
}
|
||||
@@ -0,0 +1,9 @@
|
||||
// WITH_DEFAULT_VALUE: false
|
||||
|
||||
fun foo(a: Int, b: Int): Int {
|
||||
return <selection>a * b</selection> / 2
|
||||
}
|
||||
|
||||
fun test() {
|
||||
foo(1 + 2, 3 - 4)
|
||||
}
|
||||
@@ -0,0 +1,9 @@
|
||||
// WITH_DEFAULT_VALUE: false
|
||||
|
||||
fun foo(i: Int): Int {
|
||||
return i / 2
|
||||
}
|
||||
|
||||
fun test() {
|
||||
foo((1 + 2) * (3 - 4))
|
||||
}
|
||||
@@ -0,0 +1,18 @@
|
||||
// WITH_DEFAULT_VALUE: false
|
||||
public inline fun <T, R> with(receiver: T, f: T.() -> R): R = receiver.f()
|
||||
|
||||
class A(val a: Int) {
|
||||
fun A.foo(): Int {
|
||||
return (<selection>this@A.a + a</selection>) / 2
|
||||
}
|
||||
|
||||
fun test() {
|
||||
A(1).foo()
|
||||
}
|
||||
}
|
||||
|
||||
fun test() {
|
||||
val t = with(A(1)) {
|
||||
A(2).foo()
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,18 @@
|
||||
// WITH_DEFAULT_VALUE: false
|
||||
public inline fun <T, R> with(receiver: T, f: T.() -> R): R = receiver.f()
|
||||
|
||||
class A(val a: Int) {
|
||||
fun A.foo(i: Int): Int {
|
||||
return i / 2
|
||||
}
|
||||
|
||||
fun test() {
|
||||
A(1).foo(a + A(1).a)
|
||||
}
|
||||
}
|
||||
|
||||
fun test() {
|
||||
val t = with(A(1)) {
|
||||
A(2).foo(a + A(2).a)
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,16 @@
|
||||
// WITH_DEFAULT_VALUE: false
|
||||
public inline fun <T, R> with(receiver: T, f: T.() -> R): R = receiver.f()
|
||||
|
||||
class A(val a: Int) {
|
||||
fun foo(x: A): Int {
|
||||
return (<selection>this.a + x.a</selection>) / 2
|
||||
}
|
||||
}
|
||||
|
||||
fun test() {
|
||||
A(1).foo(A(2))
|
||||
with(A(1)) {
|
||||
foo(A(2))
|
||||
this.foo(A(2))
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,16 @@
|
||||
// WITH_DEFAULT_VALUE: false
|
||||
public inline fun <T, R> with(receiver: T, f: T.() -> R): R = receiver.f()
|
||||
|
||||
class A(val a: Int) {
|
||||
fun foo(i: Int): Int {
|
||||
return i / 2
|
||||
}
|
||||
}
|
||||
|
||||
fun test() {
|
||||
A(1).foo(A(1).a + A(2).a)
|
||||
with(A(1)) {
|
||||
foo(a + A(2).a)
|
||||
this.foo(a + A(2).a)
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,16 @@
|
||||
// WITH_DEFAULT_VALUE: false
|
||||
public inline fun <T, R> with(receiver: T, f: T.() -> R): R = receiver.f()
|
||||
|
||||
class A(val a: Int) {
|
||||
fun foo(x: A): Int {
|
||||
return (<selection>a + x.a</selection>) / 2
|
||||
}
|
||||
}
|
||||
|
||||
fun test() {
|
||||
A(1).foo(A(2))
|
||||
with(A(1)) {
|
||||
foo(A(2))
|
||||
this.foo(A(2))
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,16 @@
|
||||
// WITH_DEFAULT_VALUE: false
|
||||
public inline fun <T, R> with(receiver: T, f: T.() -> R): R = receiver.f()
|
||||
|
||||
class A(val a: Int) {
|
||||
fun foo(i: Int): Int {
|
||||
return i / 2
|
||||
}
|
||||
}
|
||||
|
||||
fun test() {
|
||||
A(1).foo(A(1).a + A(2).a)
|
||||
with(A(1)) {
|
||||
foo(a + A(2).a)
|
||||
this.foo(a + A(2).a)
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,19 @@
|
||||
// WITH_DEFAULT_VALUE: false
|
||||
// TARGET:
|
||||
open class A(val a: Int) {
|
||||
constructor(): this(1)
|
||||
|
||||
fun foo(): Int {
|
||||
return (<selection>a + 1</selection>) / 2
|
||||
}
|
||||
}
|
||||
|
||||
class B: A(1) {
|
||||
|
||||
}
|
||||
|
||||
class C: A {
|
||||
constructor(n: Int): super(n + 1)
|
||||
}
|
||||
|
||||
fun test() = A(1)
|
||||
+19
@@ -0,0 +1,19 @@
|
||||
// WITH_DEFAULT_VALUE: false
|
||||
// TARGET:
|
||||
open class A(val a: Int, val i: Int) {
|
||||
constructor(): this(1, 1 + 1)
|
||||
|
||||
fun foo(): Int {
|
||||
return i / 2
|
||||
}
|
||||
}
|
||||
|
||||
class B: A(1, 1 + 1) {
|
||||
|
||||
}
|
||||
|
||||
class C: A {
|
||||
constructor(n: Int): super(n + 1, n + 1 + 1)
|
||||
}
|
||||
|
||||
fun test() = A(1, 1 + 1)
|
||||
@@ -0,0 +1,18 @@
|
||||
// WITH_DEFAULT_VALUE: false
|
||||
open class A {
|
||||
constructor(): this(1)
|
||||
|
||||
constructor(a: Int) {
|
||||
val t = (<selection>a + 1</selection>) / 2
|
||||
}
|
||||
}
|
||||
|
||||
class B: A {
|
||||
constructor(n: Int): super(n + 1)
|
||||
}
|
||||
|
||||
class C: A(1) {
|
||||
|
||||
}
|
||||
|
||||
fun test() = A(1)
|
||||
+18
@@ -0,0 +1,18 @@
|
||||
// WITH_DEFAULT_VALUE: false
|
||||
open class A {
|
||||
constructor(): this(1 + 1)
|
||||
|
||||
constructor(i: Int) {
|
||||
val t = i / 2
|
||||
}
|
||||
}
|
||||
|
||||
class B: A {
|
||||
constructor(n: Int): super(n + 1 + 1)
|
||||
}
|
||||
|
||||
class C: A(1 + 1) {
|
||||
|
||||
}
|
||||
|
||||
fun test() = A(1 + 1)
|
||||
@@ -0,0 +1,10 @@
|
||||
// WITH_DEFAULT_VALUE: false
|
||||
fun foo(a: Int): Int {
|
||||
fun Int.bar(n: Int) = this + n
|
||||
|
||||
return (<selection>a bar 1</selection>) * 2
|
||||
}
|
||||
|
||||
fun test() {
|
||||
foo(2)
|
||||
}
|
||||
@@ -0,0 +1,10 @@
|
||||
// WITH_DEFAULT_VALUE: false
|
||||
fun foo(i: Int): Int {
|
||||
fun Int.bar(n: Int) = this + n
|
||||
|
||||
return i * 2
|
||||
}
|
||||
|
||||
fun test() {
|
||||
foo(2 bar 1)
|
||||
}
|
||||
@@ -5,5 +5,5 @@ fun foo(a: Int, i: Int): Int {
|
||||
}
|
||||
|
||||
fun test() {
|
||||
foo(1, a + 1)
|
||||
foo(1, 1 + 1)
|
||||
}
|
||||
@@ -5,5 +5,5 @@ fun foo(i: Int): Int {
|
||||
}
|
||||
|
||||
fun test() {
|
||||
foo(a + 1)
|
||||
foo(1 + 1)
|
||||
}
|
||||
@@ -0,0 +1,10 @@
|
||||
// WITH_DEFAULT_VALUE: false
|
||||
fun foo(vararg a: Int): Int {
|
||||
return (<selection>a.size() + 1</selection>) * 2
|
||||
}
|
||||
|
||||
fun test() {
|
||||
foo()
|
||||
foo(1)
|
||||
foo(1, 2)
|
||||
}
|
||||
@@ -0,0 +1,10 @@
|
||||
// WITH_DEFAULT_VALUE: false
|
||||
fun foo(i: Int): Int {
|
||||
return i * 2
|
||||
}
|
||||
|
||||
fun test() {
|
||||
foo(a.size() + 1)
|
||||
foo(a.size() + 1)
|
||||
foo(a.size() + 1)
|
||||
}
|
||||
+54
@@ -2344,6 +2344,12 @@ public class JetExtractionTestGenerated extends AbstractJetExtractionTest {
|
||||
doIntroduceSimpleParameterTest(fileName);
|
||||
}
|
||||
|
||||
@TestMetadata("partialSubstitution.kt")
|
||||
public void testPartialSubstitution() throws Exception {
|
||||
String fileName = JetTestUtils.navigationMetadata("idea/testData/refactoring/introduceParameter/partialSubstitution.kt");
|
||||
doIntroduceSimpleParameterTest(fileName);
|
||||
}
|
||||
|
||||
@TestMetadata("propertyAccessor.kt")
|
||||
public void testPropertyAccessor() throws Exception {
|
||||
String fileName = JetTestUtils.navigationMetadata("idea/testData/refactoring/introduceParameter/propertyAccessor.kt");
|
||||
@@ -2362,6 +2368,48 @@ public class JetExtractionTestGenerated extends AbstractJetExtractionTest {
|
||||
doIntroduceSimpleParameterTest(fileName);
|
||||
}
|
||||
|
||||
@TestMetadata("substituteComplexExpressions.kt")
|
||||
public void testSubstituteComplexExpressions() throws Exception {
|
||||
String fileName = JetTestUtils.navigationMetadata("idea/testData/refactoring/introduceParameter/substituteComplexExpressions.kt");
|
||||
doIntroduceSimpleParameterTest(fileName);
|
||||
}
|
||||
|
||||
@TestMetadata("substituteDoubleReceiver.kt")
|
||||
public void testSubstituteDoubleReceiver() throws Exception {
|
||||
String fileName = JetTestUtils.navigationMetadata("idea/testData/refactoring/introduceParameter/substituteDoubleReceiver.kt");
|
||||
doIntroduceSimpleParameterTest(fileName);
|
||||
}
|
||||
|
||||
@TestMetadata("substituteExplicitThisInMember.kt")
|
||||
public void testSubstituteExplicitThisInMember() throws Exception {
|
||||
String fileName = JetTestUtils.navigationMetadata("idea/testData/refactoring/introduceParameter/substituteExplicitThisInMember.kt");
|
||||
doIntroduceSimpleParameterTest(fileName);
|
||||
}
|
||||
|
||||
@TestMetadata("substituteImplicitThisInMember.kt")
|
||||
public void testSubstituteImplicitThisInMember() throws Exception {
|
||||
String fileName = JetTestUtils.navigationMetadata("idea/testData/refactoring/introduceParameter/substituteImplicitThisInMember.kt");
|
||||
doIntroduceSimpleParameterTest(fileName);
|
||||
}
|
||||
|
||||
@TestMetadata("substituteInPrimaryConstructorCall.kt")
|
||||
public void testSubstituteInPrimaryConstructorCall() throws Exception {
|
||||
String fileName = JetTestUtils.navigationMetadata("idea/testData/refactoring/introduceParameter/substituteInPrimaryConstructorCall.kt");
|
||||
doIntroduceSimpleParameterTest(fileName);
|
||||
}
|
||||
|
||||
@TestMetadata("substituteInSecondaryConstructorCall.kt")
|
||||
public void testSubstituteInSecondaryConstructorCall() throws Exception {
|
||||
String fileName = JetTestUtils.navigationMetadata("idea/testData/refactoring/introduceParameter/substituteInSecondaryConstructorCall.kt");
|
||||
doIntroduceSimpleParameterTest(fileName);
|
||||
}
|
||||
|
||||
@TestMetadata("substituteInfixCall.kt")
|
||||
public void testSubstituteInfixCall() throws Exception {
|
||||
String fileName = JetTestUtils.navigationMetadata("idea/testData/refactoring/introduceParameter/substituteInfixCall.kt");
|
||||
doIntroduceSimpleParameterTest(fileName);
|
||||
}
|
||||
|
||||
@TestMetadata("throw.kt")
|
||||
public void testThrow() throws Exception {
|
||||
String fileName = JetTestUtils.navigationMetadata("idea/testData/refactoring/introduceParameter/throw.kt");
|
||||
@@ -2380,6 +2428,12 @@ public class JetExtractionTestGenerated extends AbstractJetExtractionTest {
|
||||
doIntroduceSimpleParameterTest(fileName);
|
||||
}
|
||||
|
||||
@TestMetadata("varargs.kt")
|
||||
public void testVarargs() throws Exception {
|
||||
String fileName = JetTestUtils.navigationMetadata("idea/testData/refactoring/introduceParameter/varargs.kt");
|
||||
doIntroduceSimpleParameterTest(fileName);
|
||||
}
|
||||
|
||||
@TestMetadata("while.kt")
|
||||
public void testWhile() throws Exception {
|
||||
String fileName = JetTestUtils.navigationMetadata("idea/testData/refactoring/introduceParameter/while.kt");
|
||||
|
||||
Reference in New Issue
Block a user