Constructor usages are replaced too
This commit is contained in:
+30
-4
@@ -18,17 +18,19 @@ package org.jetbrains.kotlin.idea.quickfix.replaceWith
|
|||||||
|
|
||||||
import org.jetbrains.kotlin.idea.core.replaced
|
import org.jetbrains.kotlin.idea.core.replaced
|
||||||
import org.jetbrains.kotlin.idea.util.ShortenReferences
|
import org.jetbrains.kotlin.idea.util.ShortenReferences
|
||||||
import org.jetbrains.kotlin.psi.JetElement
|
import org.jetbrains.kotlin.psi.*
|
||||||
import org.jetbrains.kotlin.psi.JetNameReferenceExpression
|
import org.jetbrains.kotlin.psi.psiUtil.getQualifiedExpressionForSelectorOrThis
|
||||||
import org.jetbrains.kotlin.psi.JetSimpleNameExpression
|
|
||||||
import org.jetbrains.kotlin.psi.JetUserType
|
|
||||||
|
|
||||||
class ClassUsageReplacementStrategy(
|
class ClassUsageReplacementStrategy(
|
||||||
private val replacement: JetUserType
|
private val replacement: JetUserType
|
||||||
) : UsageReplacementStrategy {
|
) : UsageReplacementStrategy {
|
||||||
|
|
||||||
|
private val factory = JetPsiFactory(replacement)
|
||||||
|
private val qualifierAsExpression = replacement.qualifier?.let { factory.createExpression(it.text) }
|
||||||
|
|
||||||
override fun createReplacer(usage: JetSimpleNameExpression): (() -> JetElement)? {
|
override fun createReplacer(usage: JetSimpleNameExpression): (() -> JetElement)? {
|
||||||
if (usage !is JetNameReferenceExpression) return null
|
if (usage !is JetNameReferenceExpression) return null
|
||||||
|
if (replacement.referenceExpression == null) return null
|
||||||
|
|
||||||
val parent = usage.parent
|
val parent = usage.parent
|
||||||
when (parent) {
|
when (parent) {
|
||||||
@@ -39,7 +41,31 @@ class ClassUsageReplacementStrategy(
|
|||||||
} //TODO: type arguments and type arguments of outer class are lost
|
} //TODO: type arguments and type arguments of outer class are lost
|
||||||
}
|
}
|
||||||
|
|
||||||
|
is JetCallExpression -> {
|
||||||
|
if (usage != parent.calleeExpression) return null
|
||||||
|
return { replaceConstructorCall(parent) }
|
||||||
|
}
|
||||||
|
|
||||||
else -> return null //TODO
|
else -> return null //TODO
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private fun replaceConstructorCall(callExpression: JetCallExpression): JetElement {
|
||||||
|
callExpression.calleeExpression!!.replace(replacement.referenceExpression!!)
|
||||||
|
|
||||||
|
val expressionToReplace = callExpression.getQualifiedExpressionForSelectorOrThis()
|
||||||
|
val newExpression = if (qualifierAsExpression != null)
|
||||||
|
factory.createExpressionByPattern("$0.$1", qualifierAsExpression, callExpression)
|
||||||
|
else
|
||||||
|
callExpression
|
||||||
|
|
||||||
|
val result = if (expressionToReplace != newExpression) {
|
||||||
|
expressionToReplace.replaced(newExpression)
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
expressionToReplace
|
||||||
|
}
|
||||||
|
|
||||||
|
return ShortenReferences.DEFAULT.process(result)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
@@ -18,6 +18,7 @@ package org.jetbrains.kotlin.idea.quickfix.replaceWith
|
|||||||
|
|
||||||
import org.jetbrains.kotlin.descriptors.CallableDescriptor
|
import org.jetbrains.kotlin.descriptors.CallableDescriptor
|
||||||
import org.jetbrains.kotlin.descriptors.ClassDescriptor
|
import org.jetbrains.kotlin.descriptors.ClassDescriptor
|
||||||
|
import org.jetbrains.kotlin.descriptors.ConstructorDescriptor
|
||||||
import org.jetbrains.kotlin.idea.caches.resolve.getResolutionFacade
|
import org.jetbrains.kotlin.idea.caches.resolve.getResolutionFacade
|
||||||
import org.jetbrains.kotlin.idea.references.mainReference
|
import org.jetbrains.kotlin.idea.references.mainReference
|
||||||
import org.jetbrains.kotlin.psi.JetElement
|
import org.jetbrains.kotlin.psi.JetElement
|
||||||
@@ -32,10 +33,16 @@ interface UsageReplacementStrategy {
|
|||||||
fun build(element: JetSimpleNameExpression, replaceWith: ReplaceWith): UsageReplacementStrategy? {
|
fun build(element: JetSimpleNameExpression, replaceWith: ReplaceWith): UsageReplacementStrategy? {
|
||||||
val resolutionFacade = element.getResolutionFacade()
|
val resolutionFacade = element.getResolutionFacade()
|
||||||
val bindingContext = resolutionFacade.analyze(element, BodyResolveMode.PARTIAL)
|
val bindingContext = resolutionFacade.analyze(element, BodyResolveMode.PARTIAL)
|
||||||
val target = element.mainReference.resolveToDescriptors(bindingContext).singleOrNull() ?: return null
|
var target = element.mainReference.resolveToDescriptors(bindingContext).singleOrNull() ?: return null
|
||||||
|
|
||||||
|
var replacePatternFromSymbol = DeprecatedSymbolUsageFixBase.replaceWithPattern(target, resolutionFacade.project)
|
||||||
|
if (replacePatternFromSymbol == null && target is ConstructorDescriptor) {
|
||||||
|
target = target.containingDeclaration
|
||||||
|
replacePatternFromSymbol = DeprecatedSymbolUsageFixBase.replaceWithPattern(target, resolutionFacade.project)
|
||||||
|
}
|
||||||
|
|
||||||
// check that ReplaceWith hasn't changed
|
// check that ReplaceWith hasn't changed
|
||||||
if (DeprecatedSymbolUsageFixBase.replaceWithPattern(target, resolutionFacade.project) != replaceWith) return null
|
if (replacePatternFromSymbol != replaceWith) return null
|
||||||
|
|
||||||
when (target) {
|
when (target) {
|
||||||
is CallableDescriptor -> {
|
is CallableDescriptor -> {
|
||||||
|
|||||||
+10
@@ -0,0 +1,10 @@
|
|||||||
|
// "Replace with 'NewClass'" "true"
|
||||||
|
|
||||||
|
@deprecated("", ReplaceWith("NewClass"))
|
||||||
|
class OldClass(p: Int)
|
||||||
|
|
||||||
|
class NewClass(p: Int)
|
||||||
|
|
||||||
|
fun foo() {
|
||||||
|
<caret>OldClass(1)
|
||||||
|
}
|
||||||
+10
@@ -0,0 +1,10 @@
|
|||||||
|
// "Replace with 'NewClass'" "true"
|
||||||
|
|
||||||
|
@deprecated("", ReplaceWith("NewClass"))
|
||||||
|
class OldClass(p: Int)
|
||||||
|
|
||||||
|
class NewClass(p: Int)
|
||||||
|
|
||||||
|
fun foo() {
|
||||||
|
NewClass(1)
|
||||||
|
}
|
||||||
@@ -0,0 +1,8 @@
|
|||||||
|
// "Replace with 'java.util.Random'" "true"
|
||||||
|
|
||||||
|
@deprecated("", ReplaceWith("java.util.Random"))
|
||||||
|
class OldClass
|
||||||
|
|
||||||
|
fun foo() {
|
||||||
|
<caret>OldClass(1)
|
||||||
|
}
|
||||||
+10
@@ -0,0 +1,10 @@
|
|||||||
|
import java.util.Random
|
||||||
|
|
||||||
|
// "Replace with 'java.util.Random'" "true"
|
||||||
|
|
||||||
|
@deprecated("", ReplaceWith("java.util.Random"))
|
||||||
|
class OldClass
|
||||||
|
|
||||||
|
fun foo() {
|
||||||
|
Random(1)
|
||||||
|
}
|
||||||
+11
@@ -0,0 +1,11 @@
|
|||||||
|
// "Replace with 'NewClass'" "true"
|
||||||
|
package ppp
|
||||||
|
|
||||||
|
@deprecated("", ReplaceWith("NewClass"))
|
||||||
|
class OldClass(p: Int)
|
||||||
|
|
||||||
|
class NewClass(p: Int)
|
||||||
|
|
||||||
|
fun foo() {
|
||||||
|
ppp.<caret>OldClass(1)
|
||||||
|
}
|
||||||
+11
@@ -0,0 +1,11 @@
|
|||||||
|
// "Replace with 'NewClass'" "true"
|
||||||
|
package ppp
|
||||||
|
|
||||||
|
@deprecated("", ReplaceWith("NewClass"))
|
||||||
|
class OldClass(p: Int)
|
||||||
|
|
||||||
|
class NewClass(p: Int)
|
||||||
|
|
||||||
|
fun foo() {
|
||||||
|
NewClass(1)
|
||||||
|
}
|
||||||
@@ -3312,6 +3312,24 @@ public class QuickFixTestGenerated extends AbstractQuickFixTest {
|
|||||||
JetTestUtils.assertAllTestsPresentByMetadata(this.getClass(), new File("idea/testData/quickfix/deprecatedSymbolUsage/classUsages"), Pattern.compile("^([\\w\\-_]+)\\.kt$"), true);
|
JetTestUtils.assertAllTestsPresentByMetadata(this.getClass(), new File("idea/testData/quickfix/deprecatedSymbolUsage/classUsages"), Pattern.compile("^([\\w\\-_]+)\\.kt$"), true);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@TestMetadata("constructorUsage1.kt")
|
||||||
|
public void testConstructorUsage1() throws Exception {
|
||||||
|
String fileName = JetTestUtils.navigationMetadata("idea/testData/quickfix/deprecatedSymbolUsage/classUsages/constructorUsage1.kt");
|
||||||
|
doTest(fileName);
|
||||||
|
}
|
||||||
|
|
||||||
|
@TestMetadata("constructorUsage2.kt")
|
||||||
|
public void testConstructorUsage2() throws Exception {
|
||||||
|
String fileName = JetTestUtils.navigationMetadata("idea/testData/quickfix/deprecatedSymbolUsage/classUsages/constructorUsage2.kt");
|
||||||
|
doTest(fileName);
|
||||||
|
}
|
||||||
|
|
||||||
|
@TestMetadata("constructorUsage3.kt")
|
||||||
|
public void testConstructorUsage3() throws Exception {
|
||||||
|
String fileName = JetTestUtils.navigationMetadata("idea/testData/quickfix/deprecatedSymbolUsage/classUsages/constructorUsage3.kt");
|
||||||
|
doTest(fileName);
|
||||||
|
}
|
||||||
|
|
||||||
@TestMetadata("imports.kt")
|
@TestMetadata("imports.kt")
|
||||||
public void testImports() throws Exception {
|
public void testImports() throws Exception {
|
||||||
String fileName = JetTestUtils.navigationMetadata("idea/testData/quickfix/deprecatedSymbolUsage/classUsages/imports.kt");
|
String fileName = JetTestUtils.navigationMetadata("idea/testData/quickfix/deprecatedSymbolUsage/classUsages/imports.kt");
|
||||||
|
|||||||
Reference in New Issue
Block a user