KT-8169 Strange exception when replacing function call to its only argument
#KT-8169 Fixed
This commit is contained in:
@@ -153,21 +153,21 @@ public abstract class DeprecatedSymbolUsageFixBase(
|
|||||||
|
|
||||||
receiver?.mark(RECEIVER_VALUE_KEY)
|
receiver?.mark(RECEIVER_VALUE_KEY)
|
||||||
|
|
||||||
|
val wrapper = ConstructedExpressionWrapper(replacement.expression, expressionToBeReplaced, bindingContext)
|
||||||
|
|
||||||
//TODO: this@
|
//TODO: this@
|
||||||
for (thisExpression in replacement.expression.collectDescendantsOfType<JetThisExpression>()) {
|
for (thisExpression in replacement.expression.collectDescendantsOfType<JetThisExpression>()) {
|
||||||
if (receiver != null) {
|
if (receiver != null) {
|
||||||
thisExpression.replace(receiver)
|
wrapper.replaceExpression(thisExpression, receiver)
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
thisExpression.mark(RECEIVER_VALUE_KEY)
|
thisExpression.mark(RECEIVER_VALUE_KEY)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
val introduceValuesForParameters = processValueParameterUsages(resolvedCall, replacement, bindingContext, project)
|
val introduceValuesForParameters = wrapper.processValueParameterUsages(resolvedCall, project)
|
||||||
|
|
||||||
processTypeParameterUsages(resolvedCall, replacement)
|
wrapper.processTypeParameterUsages(resolvedCall)
|
||||||
|
|
||||||
val wrapper = ConstructedExpressionWrapper(replacement.expression, expressionToBeReplaced, bindingContext)
|
|
||||||
|
|
||||||
if (qualifiedExpression is JetSafeQualifiedExpression) {
|
if (qualifiedExpression is JetSafeQualifiedExpression) {
|
||||||
wrapper.wrapExpressionForSafeCall(receiver!!, receiverType)
|
wrapper.wrapExpressionForSafeCall(receiver!!, receiverType)
|
||||||
@@ -209,10 +209,8 @@ public abstract class DeprecatedSymbolUsageFixBase(
|
|||||||
return resultRange.last as JetExpression
|
return resultRange.last as JetExpression
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun processValueParameterUsages(
|
private fun ConstructedExpressionWrapper.processValueParameterUsages(
|
||||||
resolvedCall: ResolvedCall<out CallableDescriptor>,
|
resolvedCall: ResolvedCall<out CallableDescriptor>,
|
||||||
replacement: ReplaceWithAnnotationAnalyzer.ReplacementExpression,
|
|
||||||
bindingContext: BindingContext,
|
|
||||||
project: Project
|
project: Project
|
||||||
): Collection<IntroduceValueForParameter> {
|
): Collection<IntroduceValueForParameter> {
|
||||||
val introduceValuesForParameters = ArrayList<IntroduceValueForParameter>()
|
val introduceValuesForParameters = ArrayList<IntroduceValueForParameter>()
|
||||||
@@ -225,7 +223,7 @@ public abstract class DeprecatedSymbolUsageFixBase(
|
|||||||
argument.expression.put(PARAMETER_VALUE_KEY, parameter)
|
argument.expression.put(PARAMETER_VALUE_KEY, parameter)
|
||||||
|
|
||||||
val parameterName = parameter.getName()
|
val parameterName = parameter.getName()
|
||||||
val usages = replacement.expression.collectDescendantsOfType<JetExpression> {
|
val usages = expression.collectDescendantsOfType<JetExpression> {
|
||||||
it[ReplaceWithAnnotationAnalyzer.PARAMETER_USAGE_KEY] == parameterName
|
it[ReplaceWithAnnotationAnalyzer.PARAMETER_USAGE_KEY] == parameterName
|
||||||
}
|
}
|
||||||
usages.forEach {
|
usages.forEach {
|
||||||
@@ -236,7 +234,7 @@ public abstract class DeprecatedSymbolUsageFixBase(
|
|||||||
if (argument.isDefaultValue) {
|
if (argument.isDefaultValue) {
|
||||||
usageArgument?.mark(DEFAULT_PARAMETER_VALUE_KEY)
|
usageArgument?.mark(DEFAULT_PARAMETER_VALUE_KEY)
|
||||||
}
|
}
|
||||||
it.replace(argument.expression)
|
replaceExpression(it, argument.expression)
|
||||||
}
|
}
|
||||||
|
|
||||||
//TODO: sometimes we need to add explicit type arguments here because we don't have expected type in the new context
|
//TODO: sometimes we need to add explicit type arguments here because we don't have expected type in the new context
|
||||||
@@ -254,7 +252,7 @@ public abstract class DeprecatedSymbolUsageFixBase(
|
|||||||
val value: JetExpression,
|
val value: JetExpression,
|
||||||
val valueType: JetType?)
|
val valueType: JetType?)
|
||||||
|
|
||||||
private fun processTypeParameterUsages(resolvedCall: ResolvedCall<out CallableDescriptor>, replacement: ReplaceWithAnnotationAnalyzer.ReplacementExpression) {
|
private fun ConstructedExpressionWrapper.processTypeParameterUsages(resolvedCall: ResolvedCall<out CallableDescriptor>) {
|
||||||
val typeParameters = resolvedCall.getResultingDescriptor().getOriginal().getTypeParameters()
|
val typeParameters = resolvedCall.getResultingDescriptor().getOriginal().getTypeParameters()
|
||||||
|
|
||||||
val callElement = resolvedCall.getCall().getCallElement()
|
val callElement = resolvedCall.getCall().getCallElement()
|
||||||
@@ -264,7 +262,7 @@ public abstract class DeprecatedSymbolUsageFixBase(
|
|||||||
|
|
||||||
for ((index, typeParameter) in typeParameters.withIndex()) {
|
for ((index, typeParameter) in typeParameters.withIndex()) {
|
||||||
val parameterName = typeParameter.getName()
|
val parameterName = typeParameter.getName()
|
||||||
val usages = replacement.expression.collectDescendantsOfType<JetExpression> {
|
val usages = expression.collectDescendantsOfType<JetExpression> {
|
||||||
it[ReplaceWithAnnotationAnalyzer.TYPE_PARAMETER_USAGE_KEY] == parameterName
|
it[ReplaceWithAnnotationAnalyzer.TYPE_PARAMETER_USAGE_KEY] == parameterName
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -285,7 +283,7 @@ public abstract class DeprecatedSymbolUsageFixBase(
|
|||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
//TODO: tests for this?
|
//TODO: tests for this?
|
||||||
usage.replace(JetPsiFactory(usage).createExpression(typeElement.getText()))
|
replaceExpression(usage, JetPsiFactory(usage).createExpression(typeElement.getText()))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -639,6 +637,15 @@ public abstract class DeprecatedSymbolUsageFixBase(
|
|||||||
|
|
||||||
val psiFactory = JetPsiFactory(expressionToBeReplaced)
|
val psiFactory = JetPsiFactory(expressionToBeReplaced)
|
||||||
|
|
||||||
|
public fun replaceExpression(oldExpression: JetExpression, newExpression: JetExpression): JetExpression {
|
||||||
|
assert(expression.isAncestor(oldExpression))
|
||||||
|
val result = oldExpression.replace(newExpression) as JetExpression
|
||||||
|
if (oldExpression == expression) {
|
||||||
|
expression = result
|
||||||
|
}
|
||||||
|
return result
|
||||||
|
}
|
||||||
|
|
||||||
public fun introduceValue(
|
public fun introduceValue(
|
||||||
value: JetExpression,
|
value: JetExpression,
|
||||||
valueType: JetType?,
|
valueType: JetType?,
|
||||||
|
|||||||
@@ -0,0 +1,7 @@
|
|||||||
|
// "Replace with 'p'" "true"
|
||||||
|
deprecated("", ReplaceWith("p"))
|
||||||
|
fun oldFun(p: Int): Int = p
|
||||||
|
|
||||||
|
fun foo() {
|
||||||
|
<caret>oldFun(0)
|
||||||
|
}
|
||||||
@@ -0,0 +1,7 @@
|
|||||||
|
// "Replace with 'p'" "true"
|
||||||
|
deprecated("", ReplaceWith("p"))
|
||||||
|
fun oldFun(p: Int): Int = p
|
||||||
|
|
||||||
|
fun foo() {
|
||||||
|
<caret>0
|
||||||
|
}
|
||||||
@@ -0,0 +1,9 @@
|
|||||||
|
// "Replace with 'this'" "true"
|
||||||
|
class C {
|
||||||
|
deprecated("", ReplaceWith("this"))
|
||||||
|
fun oldFun(): C = this
|
||||||
|
}
|
||||||
|
|
||||||
|
fun foo() {
|
||||||
|
C().<caret>oldFun()
|
||||||
|
}
|
||||||
@@ -0,0 +1,9 @@
|
|||||||
|
// "Replace with 'this'" "true"
|
||||||
|
class C {
|
||||||
|
deprecated("", ReplaceWith("this"))
|
||||||
|
fun oldFun(): C = this
|
||||||
|
}
|
||||||
|
|
||||||
|
fun foo() {
|
||||||
|
<caret>C()
|
||||||
|
}
|
||||||
@@ -3034,6 +3034,18 @@ public class QuickFixTestGenerated extends AbstractQuickFixTest {
|
|||||||
doTest(fileName);
|
doTest(fileName);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@TestMetadata("replaceCallWithArgument.kt")
|
||||||
|
public void testReplaceCallWithArgument() throws Exception {
|
||||||
|
String fileName = JetTestUtils.navigationMetadata("idea/testData/quickfix/deprecatedSymbolUsage/replaceCallWithArgument.kt");
|
||||||
|
doTest(fileName);
|
||||||
|
}
|
||||||
|
|
||||||
|
@TestMetadata("replaceCallWithReceiver.kt")
|
||||||
|
public void testReplaceCallWithReceiver() throws Exception {
|
||||||
|
String fileName = JetTestUtils.navigationMetadata("idea/testData/quickfix/deprecatedSymbolUsage/replaceCallWithReceiver.kt");
|
||||||
|
doTest(fileName);
|
||||||
|
}
|
||||||
|
|
||||||
@TestMetadata("shortenReferences.kt")
|
@TestMetadata("shortenReferences.kt")
|
||||||
public void testShortenReferences() throws Exception {
|
public void testShortenReferences() throws Exception {
|
||||||
String fileName = JetTestUtils.navigationMetadata("idea/testData/quickfix/deprecatedSymbolUsage/shortenReferences.kt");
|
String fileName = JetTestUtils.navigationMetadata("idea/testData/quickfix/deprecatedSymbolUsage/shortenReferences.kt");
|
||||||
|
|||||||
Reference in New Issue
Block a user