CanSealedSubClassBeObjectInspection: don't report if sub-class has classModifier
#KT-38790 Fixed
This commit is contained in:
committed by
Yan Zhulanow
parent
cea879cbd5
commit
3272b8fc2c
+18
-2
@@ -46,6 +46,7 @@ class CanSealedSubClassBeObjectInspection : AbstractKotlinInspection() {
|
||||
|
||||
val candidates = klass.getSubclasses()
|
||||
.withEmptyConstructors()
|
||||
.thatHasNoClassModifiers()
|
||||
.thatAreFinal()
|
||||
.thatHasNoTypeParameters()
|
||||
.thatHasNoInnerClasses()
|
||||
@@ -80,6 +81,13 @@ class CanSealedSubClassBeObjectInspection : AbstractKotlinInspection() {
|
||||
.filter { klass -> klass.secondaryConstructors.all { cons -> cons.valueParameters.isEmpty() } }.toList()
|
||||
}
|
||||
|
||||
private fun List<KtClass>.thatHasNoClassModifiers(): List<KtClass> {
|
||||
return filter { klass ->
|
||||
val modifierList = klass.modifierList ?: return@filter true
|
||||
CLASS_MODIFIERS.none { modifierList.hasModifier(it) }
|
||||
}
|
||||
}
|
||||
|
||||
private fun List<KtClass>.thatHasNoCompanionObjects(): List<KtClass> {
|
||||
return filter { klass -> klass.companionObjects.isEmpty() }
|
||||
}
|
||||
@@ -110,7 +118,7 @@ class CanSealedSubClassBeObjectInspection : AbstractKotlinInspection() {
|
||||
|
||||
private fun KtClass.hasNoStateOrEquals(): Boolean {
|
||||
if (primaryConstructor?.valueParameters?.isNotEmpty() == true) return false
|
||||
val body = getBody()
|
||||
val body = body
|
||||
return body == null || run {
|
||||
val declarations = body.declarations
|
||||
declarations.asSequence().filterIsInstance<KtProperty>().none { property ->
|
||||
@@ -132,7 +140,7 @@ class CanSealedSubClassBeObjectInspection : AbstractKotlinInspection() {
|
||||
}
|
||||
|
||||
private fun KtClass.hasNoInnerClass(): Boolean {
|
||||
val internalClasses = getBody()
|
||||
val internalClasses = body
|
||||
?.declarations
|
||||
?.filterIsInstance<KtClass>() ?: return true
|
||||
|
||||
@@ -143,5 +151,13 @@ class CanSealedSubClassBeObjectInspection : AbstractKotlinInspection() {
|
||||
val EQUALS = OperatorNameConventions.EQUALS.asString()
|
||||
|
||||
const val HASH_CODE = "hashCode"
|
||||
|
||||
val CLASS_MODIFIERS = listOf(
|
||||
KtTokens.ANNOTATION_KEYWORD,
|
||||
KtTokens.DATA_KEYWORD,
|
||||
KtTokens.ENUM_KEYWORD,
|
||||
KtTokens.INNER_KEYWORD,
|
||||
KtTokens.SEALED_KEYWORD,
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,5 @@
|
||||
// PROBLEM: none
|
||||
// DISABLE-ERRORS
|
||||
sealed class Bar
|
||||
|
||||
annotation <caret>class Foo : Bar()
|
||||
@@ -0,0 +1,5 @@
|
||||
// PROBLEM: none
|
||||
// DISABLE-ERRORS
|
||||
sealed class Bar
|
||||
|
||||
data <caret>class Foo : Bar()
|
||||
@@ -0,0 +1,5 @@
|
||||
// PROBLEM: none
|
||||
// DISABLE-ERRORS
|
||||
sealed class Bar
|
||||
|
||||
enum <caret>class Foo : Bar()
|
||||
@@ -0,0 +1,5 @@
|
||||
// PROBLEM: none
|
||||
// DISABLE-ERRORS
|
||||
sealed class Bar
|
||||
|
||||
inner <caret>class Foo : Bar()
|
||||
@@ -0,0 +1,4 @@
|
||||
// PROBLEM: none
|
||||
sealed class Bar
|
||||
|
||||
sealed <caret>class Foo : Bar()
|
||||
+25
@@ -3385,6 +3385,11 @@ public class LocalInspectionTestGenerated extends AbstractLocalInspectionTest {
|
||||
KotlinTestUtils.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("idea/testData/inspectionsLocal/convertSealedSubClassToObject"), Pattern.compile("^([\\w\\-_]+)\\.(kt|kts)$"), null, true);
|
||||
}
|
||||
|
||||
@TestMetadata("annotation.kt")
|
||||
public void testAnnotation() throws Exception {
|
||||
runTest("idea/testData/inspectionsLocal/convertSealedSubClassToObject/annotation.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("baseEquals.kt")
|
||||
public void testBaseEquals() throws Exception {
|
||||
runTest("idea/testData/inspectionsLocal/convertSealedSubClassToObject/baseEquals.kt");
|
||||
@@ -3415,6 +3420,16 @@ public class LocalInspectionTestGenerated extends AbstractLocalInspectionTest {
|
||||
runTest("idea/testData/inspectionsLocal/convertSealedSubClassToObject/convertSubClassWithoutParentheses.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("data.kt")
|
||||
public void testData() throws Exception {
|
||||
runTest("idea/testData/inspectionsLocal/convertSealedSubClassToObject/data.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("enum.kt")
|
||||
public void testEnum() throws Exception {
|
||||
runTest("idea/testData/inspectionsLocal/convertSealedSubClassToObject/enum.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("fakeState.kt")
|
||||
public void testFakeState() throws Exception {
|
||||
runTest("idea/testData/inspectionsLocal/convertSealedSubClassToObject/fakeState.kt");
|
||||
@@ -3425,6 +3440,11 @@ public class LocalInspectionTestGenerated extends AbstractLocalInspectionTest {
|
||||
runTest("idea/testData/inspectionsLocal/convertSealedSubClassToObject/generic.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("inner.kt")
|
||||
public void testInner() throws Exception {
|
||||
runTest("idea/testData/inspectionsLocal/convertSealedSubClassToObject/inner.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("noEquals.kt")
|
||||
public void testNoEquals() throws Exception {
|
||||
runTest("idea/testData/inspectionsLocal/convertSealedSubClassToObject/noEquals.kt");
|
||||
@@ -3450,6 +3470,11 @@ public class LocalInspectionTestGenerated extends AbstractLocalInspectionTest {
|
||||
runTest("idea/testData/inspectionsLocal/convertSealedSubClassToObject/ownState.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("sealed.kt")
|
||||
public void testSealed() throws Exception {
|
||||
runTest("idea/testData/inspectionsLocal/convertSealedSubClassToObject/sealed.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("sealedEquals.kt")
|
||||
public void testSealedEquals() throws Exception {
|
||||
runTest("idea/testData/inspectionsLocal/convertSealedSubClassToObject/sealedEquals.kt");
|
||||
|
||||
Reference in New Issue
Block a user