From a170de2c56345eda0e64dc27ab93e4cadb42cc32 Mon Sep 17 00:00:00 2001 From: Dmitry Gridin Date: Thu, 20 Jun 2019 18:12:39 +0700 Subject: [PATCH] RemoveRedundantQualifierNameInspection: support class literal expression #KT-32046 Fixed --- .../RemoveRedundantQualifierNameInspection.kt | 21 ++++++++++++---- .../classLiteral.kt | 8 ++++++ .../classLiteral.kt.after | 8 ++++++ .../classLiteral2.kt | 8 ++++++ .../classLiteral2.kt.after | 8 ++++++ .../classLiteral3.kt | 17 +++++++++++++ .../classLiteral3.kt.after | 17 +++++++++++++ .../classLiteral4.kt | 14 +++++++++++ .../classLiteral4.kt.after | 14 +++++++++++ .../classLiteral5.kt | 14 +++++++++++ .../classLiteral5.kt.after | 14 +++++++++++ .../LocalInspectionTestGenerated.java | 25 +++++++++++++++++++ 12 files changed, 163 insertions(+), 5 deletions(-) create mode 100644 idea/testData/inspectionsLocal/removeRedundantQualifierName/classLiteral.kt create mode 100644 idea/testData/inspectionsLocal/removeRedundantQualifierName/classLiteral.kt.after create mode 100644 idea/testData/inspectionsLocal/removeRedundantQualifierName/classLiteral2.kt create mode 100644 idea/testData/inspectionsLocal/removeRedundantQualifierName/classLiteral2.kt.after create mode 100644 idea/testData/inspectionsLocal/removeRedundantQualifierName/classLiteral3.kt create mode 100644 idea/testData/inspectionsLocal/removeRedundantQualifierName/classLiteral3.kt.after create mode 100644 idea/testData/inspectionsLocal/removeRedundantQualifierName/classLiteral4.kt create mode 100644 idea/testData/inspectionsLocal/removeRedundantQualifierName/classLiteral4.kt.after create mode 100644 idea/testData/inspectionsLocal/removeRedundantQualifierName/classLiteral5.kt create mode 100644 idea/testData/inspectionsLocal/removeRedundantQualifierName/classLiteral5.kt.after diff --git a/idea/src/org/jetbrains/kotlin/idea/inspections/RemoveRedundantQualifierNameInspection.kt b/idea/src/org/jetbrains/kotlin/idea/inspections/RemoveRedundantQualifierNameInspection.kt index bee8f6ca57e..75437c282f7 100644 --- a/idea/src/org/jetbrains/kotlin/idea/inspections/RemoveRedundantQualifierNameInspection.kt +++ b/idea/src/org/jetbrains/kotlin/idea/inspections/RemoveRedundantQualifierNameInspection.kt @@ -20,7 +20,6 @@ import org.jetbrains.kotlin.name.FqName import org.jetbrains.kotlin.psi.* import org.jetbrains.kotlin.psi.psiUtil.* import org.jetbrains.kotlin.resolve.BindingContext -import org.jetbrains.kotlin.resolve.calls.callUtil.getResolvedCall import org.jetbrains.kotlin.resolve.descriptorUtil.isCompanionObject import org.jetbrains.kotlin.resolve.scopes.utils.findFirstClassifierWithDeprecationStatus @@ -28,16 +27,23 @@ class RemoveRedundantQualifierNameInspection : AbstractKotlinInspection(), Clean override fun buildVisitor(holder: ProblemsHolder, isOnTheFly: Boolean): PsiElementVisitor = object : KtVisitorVoid() { override fun visitDotQualifiedExpression(expression: KtDotQualifiedExpression) { - if (expression.parent is KtDotQualifiedExpression? || expression.isInImportDirective()) return + if (expression.parent is KtDotQualifiedExpression || expression.isInImportDirective()) return val expressionForAnalyze = expression.firstExpressionWithoutReceiver() ?: return - val context = expressionForAnalyze.analyze() + val parent = expressionForAnalyze.parent + @Suppress("USELESS_CAST") val originalExpression = if (parent is KtClassLiteralExpression) + parent as KtExpression + else + expressionForAnalyze + + val context = originalExpression.analyze() + val importableFqName = expressionForAnalyze.getQualifiedElementSelector() ?.mainReference?.resolveToDescriptors(context)?.firstOrNull() ?.importableFqName ?: return val applicableExpression = expressionForAnalyze.firstApplicableExpression(validator = { - applicableExpression(expressionForAnalyze, context, importableFqName) + applicableExpression(originalExpression, context, importableFqName) }) { firstChild as? KtDotQualifiedExpression } ?: return @@ -78,13 +84,18 @@ private fun KtDotQualifiedExpression.applicableExpression( val expressionText = originalExpression.text.substring(lastChild.startOffset - originalExpression.startOffset) val newExpression = KtPsiFactory(originalExpression).createExpressionIfPossible(expressionText) ?: return null val newContext = newExpression.analyzeAsReplacement(originalExpression, oldContext) - val newDescriptor = newExpression.getQualifiedElementSelector()?.getResolvedCall(newContext)?.resultingDescriptor ?: return null + val newDescriptor = newExpression.selector() + ?.mainReference?.resolveToDescriptors(newContext) + ?.firstOrNull() ?: return null return takeIf { importableFqName == newDescriptor.importableFqName } } +private fun KtExpression.selector(): KtElement? = if (this is KtClassLiteralExpression) receiverExpression?.getQualifiedElementSelector() +else getQualifiedElementSelector() + private fun KtExpression.isApplicableReceiver(context: BindingContext): Boolean { if (this is KtInstanceExpressionWithLabel) return false diff --git a/idea/testData/inspectionsLocal/removeRedundantQualifierName/classLiteral.kt b/idea/testData/inspectionsLocal/removeRedundantQualifierName/classLiteral.kt new file mode 100644 index 00000000000..5972702c77a --- /dev/null +++ b/idea/testData/inspectionsLocal/removeRedundantQualifierName/classLiteral.kt @@ -0,0 +1,8 @@ +// WITH_RUNTIME +package foo + +class Foo + +fun bar() { + foo.Foo::class +} diff --git a/idea/testData/inspectionsLocal/removeRedundantQualifierName/classLiteral.kt.after b/idea/testData/inspectionsLocal/removeRedundantQualifierName/classLiteral.kt.after new file mode 100644 index 00000000000..123cd207dd1 --- /dev/null +++ b/idea/testData/inspectionsLocal/removeRedundantQualifierName/classLiteral.kt.after @@ -0,0 +1,8 @@ +// WITH_RUNTIME +package foo + +class Foo + +fun bar() { + Foo::class +} diff --git a/idea/testData/inspectionsLocal/removeRedundantQualifierName/classLiteral2.kt b/idea/testData/inspectionsLocal/removeRedundantQualifierName/classLiteral2.kt new file mode 100644 index 00000000000..6a6ac17b579 --- /dev/null +++ b/idea/testData/inspectionsLocal/removeRedundantQualifierName/classLiteral2.kt @@ -0,0 +1,8 @@ +// WITH_RUNTIME +package foo + +class Foo + +fun bar() { + foo.Foo::class.java +} diff --git a/idea/testData/inspectionsLocal/removeRedundantQualifierName/classLiteral2.kt.after b/idea/testData/inspectionsLocal/removeRedundantQualifierName/classLiteral2.kt.after new file mode 100644 index 00000000000..338e7f10347 --- /dev/null +++ b/idea/testData/inspectionsLocal/removeRedundantQualifierName/classLiteral2.kt.after @@ -0,0 +1,8 @@ +// WITH_RUNTIME +package foo + +class Foo + +fun bar() { + Foo::class.java +} diff --git a/idea/testData/inspectionsLocal/removeRedundantQualifierName/classLiteral3.kt b/idea/testData/inspectionsLocal/removeRedundantQualifierName/classLiteral3.kt new file mode 100644 index 00000000000..629f1058ea8 --- /dev/null +++ b/idea/testData/inspectionsLocal/removeRedundantQualifierName/classLiteral3.kt @@ -0,0 +1,17 @@ +// WITH_RUNTIME +// DISABLE-ERRORS +package foo.www.ddd + +class Check { + class BBD { + class Bwd { + fun dad() { + val Bwd = 42 + + class BBD + + val a = foo.www.ddd.Check.BBD.Bwd::class.java.annotatedInterfaces.size + } + } + } +} diff --git a/idea/testData/inspectionsLocal/removeRedundantQualifierName/classLiteral3.kt.after b/idea/testData/inspectionsLocal/removeRedundantQualifierName/classLiteral3.kt.after new file mode 100644 index 00000000000..1cba03c6be1 --- /dev/null +++ b/idea/testData/inspectionsLocal/removeRedundantQualifierName/classLiteral3.kt.after @@ -0,0 +1,17 @@ +// WITH_RUNTIME +// DISABLE-ERRORS +package foo.www.ddd + +class Check { + class BBD { + class Bwd { + fun dad() { + val Bwd = 42 + + class BBD + + val a = Check.BBD.Bwd::class.java.annotatedInterfaces.size + } + } + } +} diff --git a/idea/testData/inspectionsLocal/removeRedundantQualifierName/classLiteral4.kt b/idea/testData/inspectionsLocal/removeRedundantQualifierName/classLiteral4.kt new file mode 100644 index 00000000000..cbcd1c749b4 --- /dev/null +++ b/idea/testData/inspectionsLocal/removeRedundantQualifierName/classLiteral4.kt @@ -0,0 +1,14 @@ +// WITH_RUNTIME +// DISABLE-ERRORS +package foo.www.ddd + +class Check { + class BBD { + class Bwd { + fun dad() { + fun Bwd(): String = "" + val a = foo.www.ddd.Check.BBD.Bwd::class.java.annotatedInterfaces.size + } + } + } +} diff --git a/idea/testData/inspectionsLocal/removeRedundantQualifierName/classLiteral4.kt.after b/idea/testData/inspectionsLocal/removeRedundantQualifierName/classLiteral4.kt.after new file mode 100644 index 00000000000..e16d991dbe5 --- /dev/null +++ b/idea/testData/inspectionsLocal/removeRedundantQualifierName/classLiteral4.kt.after @@ -0,0 +1,14 @@ +// WITH_RUNTIME +// DISABLE-ERRORS +package foo.www.ddd + +class Check { + class BBD { + class Bwd { + fun dad() { + fun Bwd(): String = "" + val a = Bwd::class.java.annotatedInterfaces.size + } + } + } +} diff --git a/idea/testData/inspectionsLocal/removeRedundantQualifierName/classLiteral5.kt b/idea/testData/inspectionsLocal/removeRedundantQualifierName/classLiteral5.kt new file mode 100644 index 00000000000..45fce877e9b --- /dev/null +++ b/idea/testData/inspectionsLocal/removeRedundantQualifierName/classLiteral5.kt @@ -0,0 +1,14 @@ +// WITH_RUNTIME +// DISABLE-ERRORS +package foo.www.ddd + +class Check { + class BBD { + class Bwd { + fun dad() { + class Bwd + val a = foo.www.ddd.Check.BBD.Bwd::class.java.annotatedInterfaces.size + } + } + } +} diff --git a/idea/testData/inspectionsLocal/removeRedundantQualifierName/classLiteral5.kt.after b/idea/testData/inspectionsLocal/removeRedundantQualifierName/classLiteral5.kt.after new file mode 100644 index 00000000000..10b062b9b58 --- /dev/null +++ b/idea/testData/inspectionsLocal/removeRedundantQualifierName/classLiteral5.kt.after @@ -0,0 +1,14 @@ +// WITH_RUNTIME +// DISABLE-ERRORS +package foo.www.ddd + +class Check { + class BBD { + class Bwd { + fun dad() { + class Bwd + val a = BBD.Bwd::class.java.annotatedInterfaces.size + } + } + } +} diff --git a/idea/tests/org/jetbrains/kotlin/idea/inspections/LocalInspectionTestGenerated.java b/idea/tests/org/jetbrains/kotlin/idea/inspections/LocalInspectionTestGenerated.java index 4b8b0da62a0..e9b69af783d 100644 --- a/idea/tests/org/jetbrains/kotlin/idea/inspections/LocalInspectionTestGenerated.java +++ b/idea/tests/org/jetbrains/kotlin/idea/inspections/LocalInspectionTestGenerated.java @@ -7631,6 +7631,31 @@ public class LocalInspectionTestGenerated extends AbstractLocalInspectionTest { runTest("idea/testData/inspectionsLocal/removeRedundantQualifierName/asReceiverProperty.kt"); } + @TestMetadata("classLiteral.kt") + public void testClassLiteral() throws Exception { + runTest("idea/testData/inspectionsLocal/removeRedundantQualifierName/classLiteral.kt"); + } + + @TestMetadata("classLiteral2.kt") + public void testClassLiteral2() throws Exception { + runTest("idea/testData/inspectionsLocal/removeRedundantQualifierName/classLiteral2.kt"); + } + + @TestMetadata("classLiteral3.kt") + public void testClassLiteral3() throws Exception { + runTest("idea/testData/inspectionsLocal/removeRedundantQualifierName/classLiteral3.kt"); + } + + @TestMetadata("classLiteral4.kt") + public void testClassLiteral4() throws Exception { + runTest("idea/testData/inspectionsLocal/removeRedundantQualifierName/classLiteral4.kt"); + } + + @TestMetadata("classLiteral5.kt") + public void testClassLiteral5() throws Exception { + runTest("idea/testData/inspectionsLocal/removeRedundantQualifierName/classLiteral5.kt"); + } + @TestMetadata("companionCollision.kt") public void testCompanionCollision() throws Exception { runTest("idea/testData/inspectionsLocal/removeRedundantQualifierName/companionCollision.kt");