From 8ba7f2c238019384469edc4ba0d0f35521b2d877 Mon Sep 17 00:00:00 2001 From: Valentin Kipyatkov Date: Mon, 14 Sep 2015 18:34:41 +0300 Subject: [PATCH] KT-9128 ReplaceWith incorrectly converts javaClass() to X::class.java for type with arguments #KT-9128 Fixed --- .../CallableUsageReplacementStrategy.kt | 18 ++++++++++++++++-- .../classLiteralAndTypeArgsRuntime.kt | 10 ++++++++++ .../classLiteralAndTypeArgsRuntime.kt.after | 10 ++++++++++ .../idea/quickfix/QuickFixTestGenerated.java | 6 ++++++ 4 files changed, 42 insertions(+), 2 deletions(-) create mode 100644 idea/testData/quickfix/deprecatedSymbolUsage/classLiteralAndTypeArgsRuntime.kt create mode 100644 idea/testData/quickfix/deprecatedSymbolUsage/classLiteralAndTypeArgsRuntime.kt.after diff --git a/idea/src/org/jetbrains/kotlin/idea/quickfix/replaceWith/CallableUsageReplacementStrategy.kt b/idea/src/org/jetbrains/kotlin/idea/quickfix/replaceWith/CallableUsageReplacementStrategy.kt index 6217c70ea6a..d6d0a0823c8 100644 --- a/idea/src/org/jetbrains/kotlin/idea/quickfix/replaceWith/CallableUsageReplacementStrategy.kt +++ b/idea/src/org/jetbrains/kotlin/idea/quickfix/replaceWith/CallableUsageReplacementStrategy.kt @@ -207,19 +207,33 @@ private fun ConstructedExpressionWrapper.processTypeParameterUsages(resolvedCall } val factory = JetPsiFactory(callElement) + val type = resolvedCall.typeArguments[typeParameter]!! val typeElement = if (explicitTypeArgs != null) { // we use explicit type arguments if available to avoid shortening val _typeElement = explicitTypeArgs[index].typeReference?.typeElement ?: continue _typeElement.marked(USER_CODE_KEY) } else { - val type = resolvedCall.typeArguments[typeParameter]!! factory.createType(IdeDescriptorRenderers.SOURCE_CODE.renderType(type)).typeElement!! } + // for class literal ("X::class") we need type arguments only for kotlin.Array + val typeClassifier = type.constructor.declarationDescriptor + val classLiteralTypeElement = if (typeElement is JetUserType && typeElement.typeArgumentList == null || typeClassifier == null || KotlinBuiltIns.isArray(type)) { + typeElement + } + else { + factory.createType(IdeDescriptorRenderers.SOURCE_CODE.renderClassifierName(typeClassifier)).typeElement!! + } + for (usage in usages) { val parent = usage.parent if (parent is JetUserType) { - parent.replace(typeElement) + if (parent.parent is JetTypeReference && parent.parent.parent is JetClassLiteralExpression) { + parent.replace(classLiteralTypeElement) + } + else { + parent.replace(typeElement) + } } else { //TODO: tests for this? diff --git a/idea/testData/quickfix/deprecatedSymbolUsage/classLiteralAndTypeArgsRuntime.kt b/idea/testData/quickfix/deprecatedSymbolUsage/classLiteralAndTypeArgsRuntime.kt new file mode 100644 index 00000000000..37583e3edf5 --- /dev/null +++ b/idea/testData/quickfix/deprecatedSymbolUsage/classLiteralAndTypeArgsRuntime.kt @@ -0,0 +1,10 @@ +// "Replace usages of 'myJavaClass(): Class' in whole project" "true" + +@Deprecated("", ReplaceWith("T::class.java")) +inline fun myJavaClass(): Class = T::class.java + +fun foo() { + val v1 = myJavaClass>() + val v2 = myJavaClass>() + val v3 = myJavaClass>() +} \ No newline at end of file diff --git a/idea/testData/quickfix/deprecatedSymbolUsage/classLiteralAndTypeArgsRuntime.kt.after b/idea/testData/quickfix/deprecatedSymbolUsage/classLiteralAndTypeArgsRuntime.kt.after new file mode 100644 index 00000000000..7203bad5768 --- /dev/null +++ b/idea/testData/quickfix/deprecatedSymbolUsage/classLiteralAndTypeArgsRuntime.kt.after @@ -0,0 +1,10 @@ +// "Replace usages of 'myJavaClass(): Class' in whole project" "true" + +@Deprecated("", ReplaceWith("T::class.java")) +inline fun myJavaClass(): Class = T::class.java + +fun foo() { + val v1 = List::class.java + val v2 = List::class.java + val v3 = Array::class.java +} \ No newline at end of file diff --git a/idea/tests/org/jetbrains/kotlin/idea/quickfix/QuickFixTestGenerated.java b/idea/tests/org/jetbrains/kotlin/idea/quickfix/QuickFixTestGenerated.java index 12f979dfe43..69d1f3795c4 100644 --- a/idea/tests/org/jetbrains/kotlin/idea/quickfix/QuickFixTestGenerated.java +++ b/idea/tests/org/jetbrains/kotlin/idea/quickfix/QuickFixTestGenerated.java @@ -2998,6 +2998,12 @@ public class QuickFixTestGenerated extends AbstractQuickFixTest { doTest(fileName); } + @TestMetadata("classLiteralAndTypeArgsRuntime.kt") + public void testClassLiteralAndTypeArgsRuntime() throws Exception { + String fileName = JetTestUtils.navigationMetadata("idea/testData/quickfix/deprecatedSymbolUsage/classLiteralAndTypeArgsRuntime.kt"); + doTest(fileName); + } + @TestMetadata("doNotShortenUserReferences.kt") public void testDoNotShortenUserReferences() throws Exception { String fileName = JetTestUtils.navigationMetadata("idea/testData/quickfix/deprecatedSymbolUsage/doNotShortenUserReferences.kt");