DeprecatedSymbolUsageFix: keeping explicit type arguments in original form

This commit is contained in:
Valentin Kipyatkov
2015-06-03 21:54:52 +03:00
parent 9f1fbe20dc
commit 6751a1d440
4 changed files with 49 additions and 7 deletions
@@ -255,25 +255,37 @@ public abstract class DeprecatedSymbolUsageFixBase(
val valueType: JetType?)
private fun processTypeParameterUsages(resolvedCall: ResolvedCall<out CallableDescriptor>, replacement: ReplaceWithAnnotationAnalyzer.ReplacementExpression) {
val descriptor = resolvedCall.getResultingDescriptor().getOriginal()
for (typeParameter in descriptor.getTypeParameters()) {
val typeParameters = resolvedCall.getResultingDescriptor().getOriginal().getTypeParameters()
val callElement = resolvedCall.getCall().getCallElement()
val callExpression = callElement as? JetCallExpression
val explicitTypeArgs = callExpression?.getTypeArgumentList()?.getArguments()
if (explicitTypeArgs != null && explicitTypeArgs.size() != typeParameters.size()) return
for ((index, typeParameter) in typeParameters.withIndex()) {
val parameterName = typeParameter.getName()
val usages = replacement.expression.collectDescendantsOfType<JetExpression> {
it[ReplaceWithAnnotationAnalyzer.TYPE_PARAMETER_USAGE_KEY] == parameterName
}
val type = resolvedCall.getTypeArguments()[typeParameter]!!
val typeString = IdeDescriptorRenderers.SOURCE_CODE.renderType(type)
val factory = JetPsiFactory(callElement)
val typeElement = if (explicitTypeArgs != null) { // we use explicit type arguments if available to avoid shortening
val _typeElement = explicitTypeArgs[index].getTypeReference()?.getTypeElement() ?: continue
_typeElement.marked(USER_CODE_KEY)
}
else {
val type = resolvedCall.getTypeArguments()[typeParameter]!!
factory.createType(IdeDescriptorRenderers.SOURCE_CODE.renderType(type)).getTypeElement()!!
}
for (usage in usages) {
val parent = usage.getParent()
if (parent is JetUserType) {
val typeReference = JetPsiFactory(usage).createType(typeString)
parent.replace(typeReference.getTypeElement()!!)
parent.replace(typeElement)
}
else {
//TODO: tests for this?
usage.replace(JetPsiFactory(usage).createExpression(typeString))
usage.replace(JetPsiFactory(usage).createExpression(typeElement.getText()))
}
}
}
@@ -0,0 +1,12 @@
// "Replace with 'newFun<T>()'" "true"
@deprecated("", ReplaceWith("newFun<T>()"))
fun <T> oldFun() {
newFun<T>()
}
fun <T> newFun(){}
fun foo() {
<caret>oldFun<kotlin.Int>()
}
@@ -0,0 +1,12 @@
// "Replace with 'newFun<T>()'" "true"
@deprecated("", ReplaceWith("newFun<T>()"))
fun <T> oldFun() {
newFun<T>()
}
fun <T> newFun(){}
fun foo() {
<caret>newFun<kotlin.Int>()
}
@@ -3498,6 +3498,12 @@ public class QuickFixTestGenerated extends AbstractQuickFixTest {
doTest(fileName);
}
@TestMetadata("keepOriginalIfQualified.kt")
public void testKeepOriginalIfQualified() throws Exception {
String fileName = JetTestUtils.navigationMetadata("idea/testData/quickfix/deprecatedSymbolUsage/typeArguments/keepOriginalIfQualified.kt");
doTest(fileName);
}
@TestMetadata("noImplicitTypeArgImportRuntime.kt")
public void testNoImplicitTypeArgImportRuntime() throws Exception {
String fileName = JetTestUtils.navigationMetadata("idea/testData/quickfix/deprecatedSymbolUsage/typeArguments/noImplicitTypeArgImportRuntime.kt");