RemoveRedundantQualifierNameInspection: support class literal expression
#KT-32046 Fixed
This commit is contained in:
+16
-5
@@ -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
|
||||
|
||||
|
||||
@@ -0,0 +1,8 @@
|
||||
// WITH_RUNTIME
|
||||
package foo
|
||||
|
||||
class Foo
|
||||
|
||||
fun bar() {
|
||||
foo<caret>.Foo::class
|
||||
}
|
||||
+8
@@ -0,0 +1,8 @@
|
||||
// WITH_RUNTIME
|
||||
package foo
|
||||
|
||||
class Foo
|
||||
|
||||
fun bar() {
|
||||
Foo::class
|
||||
}
|
||||
@@ -0,0 +1,8 @@
|
||||
// WITH_RUNTIME
|
||||
package foo
|
||||
|
||||
class Foo
|
||||
|
||||
fun bar() {
|
||||
foo<caret>.Foo::class.java
|
||||
}
|
||||
+8
@@ -0,0 +1,8 @@
|
||||
// WITH_RUNTIME
|
||||
package foo
|
||||
|
||||
class Foo
|
||||
|
||||
fun bar() {
|
||||
Foo::class.java
|
||||
}
|
||||
@@ -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<caret>.Check.BBD.Bwd::class.java.annotatedInterfaces.size
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
+17
@@ -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
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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.<caret>Check.BBD.Bwd::class.java.annotatedInterfaces.size
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
+14
@@ -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
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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.<caret>Check.BBD.Bwd::class.java.annotatedInterfaces.size
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
+14
@@ -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
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
+25
@@ -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");
|
||||
|
||||
Reference in New Issue
Block a user