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?) val valueType: JetType?)
private fun processTypeParameterUsages(resolvedCall: ResolvedCall<out CallableDescriptor>, replacement: ReplaceWithAnnotationAnalyzer.ReplacementExpression) { private fun processTypeParameterUsages(resolvedCall: ResolvedCall<out CallableDescriptor>, replacement: ReplaceWithAnnotationAnalyzer.ReplacementExpression) {
val descriptor = resolvedCall.getResultingDescriptor().getOriginal() val typeParameters = resolvedCall.getResultingDescriptor().getOriginal().getTypeParameters()
for (typeParameter in descriptor.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 parameterName = typeParameter.getName()
val usages = replacement.expression.collectDescendantsOfType<JetExpression> { val usages = replacement.expression.collectDescendantsOfType<JetExpression> {
it[ReplaceWithAnnotationAnalyzer.TYPE_PARAMETER_USAGE_KEY] == parameterName it[ReplaceWithAnnotationAnalyzer.TYPE_PARAMETER_USAGE_KEY] == parameterName
} }
val type = resolvedCall.getTypeArguments()[typeParameter]!! val factory = JetPsiFactory(callElement)
val typeString = IdeDescriptorRenderers.SOURCE_CODE.renderType(type) 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) { for (usage in usages) {
val parent = usage.getParent() val parent = usage.getParent()
if (parent is JetUserType) { if (parent is JetUserType) {
val typeReference = JetPsiFactory(usage).createType(typeString) parent.replace(typeElement)
parent.replace(typeReference.getTypeElement()!!)
} }
else { else {
//TODO: tests for this? //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); 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") @TestMetadata("noImplicitTypeArgImportRuntime.kt")
public void testNoImplicitTypeArgImportRuntime() throws Exception { public void testNoImplicitTypeArgImportRuntime() throws Exception {
String fileName = JetTestUtils.navigationMetadata("idea/testData/quickfix/deprecatedSymbolUsage/typeArguments/noImplicitTypeArgImportRuntime.kt"); String fileName = JetTestUtils.navigationMetadata("idea/testData/quickfix/deprecatedSymbolUsage/typeArguments/noImplicitTypeArgImportRuntime.kt");