Redundant 'inner' modifier: fix false positive/negative with constructor call
#KT-40879 Fixed #KT-41223 Fixed #KT-41311 Fixed #KT-41680 Fixed
This commit is contained in:
committed by
Dmitry Gridin
parent
e9669bf5cb
commit
09e1bed5c9
+13
-9
@@ -21,6 +21,7 @@ import org.jetbrains.kotlin.idea.search.usagesSearch.descriptor
|
|||||||
import org.jetbrains.kotlin.lexer.KtTokens
|
import org.jetbrains.kotlin.lexer.KtTokens
|
||||||
import org.jetbrains.kotlin.psi.*
|
import org.jetbrains.kotlin.psi.*
|
||||||
import org.jetbrains.kotlin.psi.psiUtil.anyDescendantOfType
|
import org.jetbrains.kotlin.psi.psiUtil.anyDescendantOfType
|
||||||
|
import org.jetbrains.kotlin.psi.psiUtil.containingClass
|
||||||
import org.jetbrains.kotlin.psi.psiUtil.getStrictParentOfType
|
import org.jetbrains.kotlin.psi.psiUtil.getStrictParentOfType
|
||||||
import org.jetbrains.kotlin.resolve.BindingContext
|
import org.jetbrains.kotlin.resolve.BindingContext
|
||||||
import org.jetbrains.kotlin.resolve.descriptorUtil.isSubclassOf
|
import org.jetbrains.kotlin.resolve.descriptorUtil.isSubclassOf
|
||||||
@@ -54,18 +55,21 @@ class RedundantInnerClassModifierInspection : AbstractKotlinInspection() {
|
|||||||
return anyDescendantOfType<KtExpression> { expression ->
|
return anyDescendantOfType<KtExpression> { expression ->
|
||||||
when (expression) {
|
when (expression) {
|
||||||
is KtNameReferenceExpression -> {
|
is KtNameReferenceExpression -> {
|
||||||
val reference = expression.mainReference.resolve()
|
val reference = expression.mainReference.resolve()?.let {
|
||||||
val referenceClass = reference?.getStrictParentOfType<KtClass>()
|
(it as? KtConstructor<*>)?.containingClass() ?: it
|
||||||
if (expression.getStrictParentOfType<KtSuperTypeCallEntry>() != null) {
|
|
||||||
return@anyDescendantOfType reference is KtClass && reference.isInner()
|
|
||||||
|| reference is KtPrimaryConstructor && referenceClass?.isInner() == true
|
|
||||||
}
|
}
|
||||||
if (referenceClass != null) {
|
if (reference is PsiClass && reference.parent is PsiClass) {
|
||||||
if (referenceClass == targetClass) return@anyDescendantOfType false
|
return@anyDescendantOfType reference.getJavaClassDescriptor()?.isInner == true
|
||||||
if (referenceClass in outerClasses) return@anyDescendantOfType true
|
}
|
||||||
|
val referenceContainingClass = reference?.getStrictParentOfType<KtClass>()
|
||||||
|
if (referenceContainingClass != null) {
|
||||||
|
if (referenceContainingClass == targetClass) return@anyDescendantOfType false
|
||||||
|
if (referenceContainingClass in outerClasses) {
|
||||||
|
return@anyDescendantOfType reference !is KtClass || reference.isInner()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
if (!hasSuperType) return@anyDescendantOfType false
|
if (!hasSuperType) return@anyDescendantOfType false
|
||||||
val referenceClassDescriptor = referenceClass?.descriptor as? ClassDescriptor
|
val referenceClassDescriptor = referenceContainingClass?.descriptor as? ClassDescriptor
|
||||||
?: reference?.getStrictParentOfType<PsiClass>()?.getJavaClassDescriptor()
|
?: reference?.getStrictParentOfType<PsiClass>()?.getJavaClassDescriptor()
|
||||||
?: (expression.resolveToCall()?.resultingDescriptor as? SyntheticJavaPropertyDescriptor)
|
?: (expression.resolveToCall()?.resultingDescriptor as? SyntheticJavaPropertyDescriptor)
|
||||||
?.getMethod?.containingDeclaration as? ClassDescriptor
|
?.getMethod?.containingDeclaration as? ClassDescriptor
|
||||||
|
|||||||
+3
@@ -0,0 +1,3 @@
|
|||||||
|
public class Java {
|
||||||
|
public abstract class NestedClass {}
|
||||||
|
}
|
||||||
+4
@@ -0,0 +1,4 @@
|
|||||||
|
// PROBLEM: none
|
||||||
|
class Test : Java() {
|
||||||
|
<caret>inner class Foo : Java.NestedClass()
|
||||||
|
}
|
||||||
Vendored
+3
@@ -0,0 +1,3 @@
|
|||||||
|
public class Java {
|
||||||
|
public interface NestedInterface {}
|
||||||
|
}
|
||||||
Vendored
+3
@@ -0,0 +1,3 @@
|
|||||||
|
public class Java {
|
||||||
|
public interface NestedInterface {}
|
||||||
|
}
|
||||||
+3
@@ -0,0 +1,3 @@
|
|||||||
|
class Test : Java() {
|
||||||
|
<caret>inner class Foo : Java.NestedInterface
|
||||||
|
}
|
||||||
Vendored
+3
@@ -0,0 +1,3 @@
|
|||||||
|
class Test : Java() {
|
||||||
|
class Foo : Java.NestedInterface
|
||||||
|
}
|
||||||
Vendored
+3
@@ -0,0 +1,3 @@
|
|||||||
|
public class Java {
|
||||||
|
public abstract static class NestedStaticClass {}
|
||||||
|
}
|
||||||
Vendored
+3
@@ -0,0 +1,3 @@
|
|||||||
|
public class Java {
|
||||||
|
public abstract static class NestedStaticClass {}
|
||||||
|
}
|
||||||
+3
@@ -0,0 +1,3 @@
|
|||||||
|
class Test : Java() {
|
||||||
|
<caret>inner class Foo2 : Java.NestedStaticClass()
|
||||||
|
}
|
||||||
Vendored
+3
@@ -0,0 +1,3 @@
|
|||||||
|
class Test : Java() {
|
||||||
|
class Foo2 : Java.NestedStaticClass()
|
||||||
|
}
|
||||||
Vendored
+8
@@ -0,0 +1,8 @@
|
|||||||
|
// PROBLEM: none
|
||||||
|
class Test {
|
||||||
|
private <caret>inner class Inner {
|
||||||
|
val inner2 = Inner2()
|
||||||
|
}
|
||||||
|
|
||||||
|
private inner class Inner2
|
||||||
|
}
|
||||||
Vendored
+8
@@ -0,0 +1,8 @@
|
|||||||
|
// PROBLEM: none
|
||||||
|
class Test {
|
||||||
|
private <caret>inner class Inner {
|
||||||
|
val inner2 = Inner2()
|
||||||
|
}
|
||||||
|
|
||||||
|
private inner class Inner2()
|
||||||
|
}
|
||||||
Vendored
+7
@@ -0,0 +1,7 @@
|
|||||||
|
class Test {
|
||||||
|
private <caret>inner class Inner {
|
||||||
|
val inner2 = Inner2()
|
||||||
|
}
|
||||||
|
|
||||||
|
private class Inner2
|
||||||
|
}
|
||||||
+7
@@ -0,0 +1,7 @@
|
|||||||
|
class Test {
|
||||||
|
private class Inner {
|
||||||
|
val inner2 = Inner2()
|
||||||
|
}
|
||||||
|
|
||||||
|
private class Inner2
|
||||||
|
}
|
||||||
+11
@@ -0,0 +1,11 @@
|
|||||||
|
// PROBLEM: none
|
||||||
|
abstract class Base(val x: Int)
|
||||||
|
|
||||||
|
open class Outer(val x: Int) {
|
||||||
|
<caret>inner class Inner {
|
||||||
|
fun useX() {
|
||||||
|
object : Base(x) {
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
+6
@@ -0,0 +1,6 @@
|
|||||||
|
// PROBLEM: none
|
||||||
|
class A(private val someText: String) {
|
||||||
|
private <caret>inner class B() : C(someText)
|
||||||
|
}
|
||||||
|
|
||||||
|
abstract class C(private val text: String)
|
||||||
+40
@@ -7978,6 +7978,36 @@ public class LocalInspectionTestGenerated extends AbstractLocalInspectionTest {
|
|||||||
runTest("idea/testData/inspectionsLocal/redundantInnerClassModifier/extendInnerClass2.kt");
|
runTest("idea/testData/inspectionsLocal/redundantInnerClassModifier/extendInnerClass2.kt");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@TestMetadata("extendJavaNestedClass.kt")
|
||||||
|
public void testExtendJavaNestedClass() throws Exception {
|
||||||
|
runTest("idea/testData/inspectionsLocal/redundantInnerClassModifier/extendJavaNestedClass.kt");
|
||||||
|
}
|
||||||
|
|
||||||
|
@TestMetadata("extendJavaNestedInterface.kt")
|
||||||
|
public void testExtendJavaNestedInterface() throws Exception {
|
||||||
|
runTest("idea/testData/inspectionsLocal/redundantInnerClassModifier/extendJavaNestedInterface.kt");
|
||||||
|
}
|
||||||
|
|
||||||
|
@TestMetadata("extendJavaNestedStaticClass.kt")
|
||||||
|
public void testExtendJavaNestedStaticClass() throws Exception {
|
||||||
|
runTest("idea/testData/inspectionsLocal/redundantInnerClassModifier/extendJavaNestedStaticClass.kt");
|
||||||
|
}
|
||||||
|
|
||||||
|
@TestMetadata("hasConstructorCallOfOuterClassMember.kt")
|
||||||
|
public void testHasConstructorCallOfOuterClassMember() throws Exception {
|
||||||
|
runTest("idea/testData/inspectionsLocal/redundantInnerClassModifier/hasConstructorCallOfOuterClassMember.kt");
|
||||||
|
}
|
||||||
|
|
||||||
|
@TestMetadata("hasConstructorCallOfOuterClassMember2.kt")
|
||||||
|
public void testHasConstructorCallOfOuterClassMember2() throws Exception {
|
||||||
|
runTest("idea/testData/inspectionsLocal/redundantInnerClassModifier/hasConstructorCallOfOuterClassMember2.kt");
|
||||||
|
}
|
||||||
|
|
||||||
|
@TestMetadata("hasConstructorCallOfOuterClassMember3.kt")
|
||||||
|
public void testHasConstructorCallOfOuterClassMember3() throws Exception {
|
||||||
|
runTest("idea/testData/inspectionsLocal/redundantInnerClassModifier/hasConstructorCallOfOuterClassMember3.kt");
|
||||||
|
}
|
||||||
|
|
||||||
@TestMetadata("hasOuterClassMemberReference.kt")
|
@TestMetadata("hasOuterClassMemberReference.kt")
|
||||||
public void testHasOuterClassMemberReference() throws Exception {
|
public void testHasOuterClassMemberReference() throws Exception {
|
||||||
runTest("idea/testData/inspectionsLocal/redundantInnerClassModifier/hasOuterClassMemberReference.kt");
|
runTest("idea/testData/inspectionsLocal/redundantInnerClassModifier/hasOuterClassMemberReference.kt");
|
||||||
@@ -8003,6 +8033,16 @@ public class LocalInspectionTestGenerated extends AbstractLocalInspectionTest {
|
|||||||
runTest("idea/testData/inspectionsLocal/redundantInnerClassModifier/hasOuterClassMemberReference5.kt");
|
runTest("idea/testData/inspectionsLocal/redundantInnerClassModifier/hasOuterClassMemberReference5.kt");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@TestMetadata("hasOuterClassMemberReferenceInSuperTypeConstructorCall.kt")
|
||||||
|
public void testHasOuterClassMemberReferenceInSuperTypeConstructorCall() throws Exception {
|
||||||
|
runTest("idea/testData/inspectionsLocal/redundantInnerClassModifier/hasOuterClassMemberReferenceInSuperTypeConstructorCall.kt");
|
||||||
|
}
|
||||||
|
|
||||||
|
@TestMetadata("hasOuterClassMemberReferenceInSuperTypeConstructorCall2.kt")
|
||||||
|
public void testHasOuterClassMemberReferenceInSuperTypeConstructorCall2() throws Exception {
|
||||||
|
runTest("idea/testData/inspectionsLocal/redundantInnerClassModifier/hasOuterClassMemberReferenceInSuperTypeConstructorCall2.kt");
|
||||||
|
}
|
||||||
|
|
||||||
@TestMetadata("hasOuterClassTypeReference.kt")
|
@TestMetadata("hasOuterClassTypeReference.kt")
|
||||||
public void testHasOuterClassTypeReference() throws Exception {
|
public void testHasOuterClassTypeReference() throws Exception {
|
||||||
runTest("idea/testData/inspectionsLocal/redundantInnerClassModifier/hasOuterClassTypeReference.kt");
|
runTest("idea/testData/inspectionsLocal/redundantInnerClassModifier/hasOuterClassTypeReference.kt");
|
||||||
|
|||||||
Reference in New Issue
Block a user