Sealed sub-class -> object: handle equals, suggest "add equals"
Before this commit, sealed sub-class without state was considered a style issue. After this commit, sealed sub-class without state AND custom equals is considered a probable bug, because comparison of its instances is very fragile. Alternative fix (generate equals & hashCode by identity) is added.
This commit is contained in:
+12
-12
@@ -4,47 +4,47 @@
|
||||
<line>8</line>
|
||||
<module>light_idea_test_case</module>
|
||||
<entry_point TYPE="file" FQNAME="temp:///src/sealed.kt" />
|
||||
<problem_class severity="INFORMATION" attribute_key="INFO_ATTRIBUTES">Sealed Sub-class should be changed To Object</problem_class>
|
||||
<description>Sealed Sub-class should be changed To Object</description>
|
||||
<problem_class severity="WEAK WARNING" attribute_key="INFO_ATTRIBUTES">Sealed sub-class without state and overridden equals</problem_class>
|
||||
<description>Sealed sub-class has no state and no overridden equals</description>
|
||||
</problem>
|
||||
<problem>
|
||||
<file>sealed.kt</file>
|
||||
<line>10</line>
|
||||
<module>light_idea_test_case</module>
|
||||
<entry_point TYPE="file" FQNAME="temp:///src/sealed.kt" />
|
||||
<problem_class severity="INFORMATION" attribute_key="INFO_ATTRIBUTES">Sealed Sub-class should be changed To Object</problem_class>
|
||||
<description>Sealed Sub-class should be changed To Object</description>
|
||||
<problem_class severity="WEAK WARNING" attribute_key="INFO_ATTRIBUTES">Sealed sub-class without state and overridden equals</problem_class>
|
||||
<description>Sealed sub-class has no state and no overridden equals</description>
|
||||
</problem>
|
||||
<problem>
|
||||
<file>sealed.kt</file>
|
||||
<line>13</line>
|
||||
<module>light_idea_test_case</module>
|
||||
<entry_point TYPE="file" FQNAME="temp:///src/sealed.kt" />
|
||||
<problem_class severity="INFORMATION" attribute_key="INFO_ATTRIBUTES">Sealed Sub-class should be changed To Object</problem_class>
|
||||
<description>Sealed Sub-class should be changed To Object</description>
|
||||
<problem_class severity="WEAK WARNING" attribute_key="INFO_ATTRIBUTES">Sealed sub-class without state and overridden equals</problem_class>
|
||||
<description>Sealed sub-class has no state and no overridden equals</description>
|
||||
</problem>
|
||||
<problem>
|
||||
<file>sealed.kt</file>
|
||||
<line>15</line>
|
||||
<module>light_idea_test_case</module>
|
||||
<entry_point TYPE="file" FQNAME="temp:///src/sealed.kt" />
|
||||
<problem_class severity="INFORMATION" attribute_key="INFO_ATTRIBUTES">Sealed Sub-class should be changed To Object</problem_class>
|
||||
<description>Sealed Sub-class should be changed To Object</description>
|
||||
<problem_class severity="WEAK WARNING" attribute_key="INFO_ATTRIBUTES">Sealed sub-class without state and overridden equals</problem_class>
|
||||
<description>Sealed sub-class has no state and no overridden equals</description>
|
||||
</problem>
|
||||
<problem>
|
||||
<file>sealed.kt</file>
|
||||
<line>41</line>
|
||||
<module>light_idea_test_case</module>
|
||||
<entry_point TYPE="file" FQNAME="temp:///src/sealed.kt" />
|
||||
<problem_class severity="INFORMATION" attribute_key="INFO_ATTRIBUTES">Sealed Sub-class should be changed To Object</problem_class>
|
||||
<description>Sealed Sub-class should be changed To Object</description>
|
||||
<problem_class severity="WEAK WARNING" attribute_key="INFO_ATTRIBUTES">Sealed sub-class without state and overridden equals</problem_class>
|
||||
<description>Sealed sub-class has no state and no overridden equals</description>
|
||||
</problem>
|
||||
<problem>
|
||||
<file>sealed.kt</file>
|
||||
<line>45</line>
|
||||
<module>light_idea_test_case</module>
|
||||
<entry_point TYPE="file" FQNAME="temp:///src/sealed.kt" />
|
||||
<problem_class severity="INFORMATION" attribute_key="INFO_ATTRIBUTES">Sealed Sub-class should be changed To Object</problem_class>
|
||||
<description>Sealed Sub-class should be changed To Object</description>
|
||||
<problem_class severity="WEAK WARNING" attribute_key="INFO_ATTRIBUTES">Sealed sub-class without state and overridden equals</problem_class>
|
||||
<description>Sealed sub-class has no state and no overridden equals</description>
|
||||
</problem>
|
||||
</problems>
|
||||
@@ -0,0 +1,18 @@
|
||||
// PROBLEM: none
|
||||
|
||||
abstract class Base {
|
||||
open val prop: Int
|
||||
get() = 13
|
||||
|
||||
override fun equals(other: Any?): Boolean {
|
||||
if (other !is Base) return false
|
||||
return prop == other.prop
|
||||
}
|
||||
}
|
||||
|
||||
sealed class SC : Base() {
|
||||
<caret>class U : SC()
|
||||
|
||||
override val prop: Int
|
||||
get() = 42
|
||||
}
|
||||
Vendored
+2
@@ -1,3 +1,5 @@
|
||||
// FIX: Convert sealed sub-class to object
|
||||
|
||||
sealed class Sealed
|
||||
|
||||
private <caret>class SubSealed : Sealed()
|
||||
Vendored
+2
@@ -1,3 +1,5 @@
|
||||
// FIX: Convert sealed sub-class to object
|
||||
|
||||
sealed class Sealed
|
||||
|
||||
private object SubSealed : Sealed()
|
||||
Vendored
+2
@@ -1,3 +1,5 @@
|
||||
// FIX: Convert sealed sub-class to object
|
||||
|
||||
sealed class Sealed
|
||||
|
||||
<caret>class SubSealed() : Sealed()
|
||||
idea/testData/inspectionsLocal/convertSealedSubClassToObject/convertSubClassWithParentheses.kt.after
Vendored
+2
@@ -1,3 +1,5 @@
|
||||
// FIX: Convert sealed sub-class to object
|
||||
|
||||
sealed class Sealed
|
||||
|
||||
object SubSealed : Sealed()
|
||||
Vendored
+2
@@ -1,3 +1,5 @@
|
||||
// FIX: Convert sealed sub-class to object
|
||||
|
||||
sealed class Sealed
|
||||
|
||||
<caret>class SubSealed : Sealed()
|
||||
+2
@@ -1,3 +1,5 @@
|
||||
// FIX: Convert sealed sub-class to object
|
||||
|
||||
sealed class Sealed
|
||||
|
||||
object SubSealed : Sealed()
|
||||
@@ -1,3 +1,4 @@
|
||||
// FIX: Convert sealed sub-class to object
|
||||
// WITH_RUNTIME
|
||||
|
||||
abstract class Base {
|
||||
|
||||
+1
@@ -1,3 +1,4 @@
|
||||
// FIX: Convert sealed sub-class to object
|
||||
// WITH_RUNTIME
|
||||
|
||||
abstract class Base {
|
||||
|
||||
@@ -0,0 +1,13 @@
|
||||
// FIX: Generate equals & hashCode by identity
|
||||
|
||||
abstract class Base {
|
||||
open val prop: Int
|
||||
get() = 13
|
||||
}
|
||||
|
||||
sealed class SC : Base() {
|
||||
<caret>class U : SC()
|
||||
|
||||
override val prop: Int
|
||||
get() = 42
|
||||
}
|
||||
+21
@@ -0,0 +1,21 @@
|
||||
// FIX: Generate equals & hashCode by identity
|
||||
|
||||
abstract class Base {
|
||||
open val prop: Int
|
||||
get() = 13
|
||||
}
|
||||
|
||||
sealed class SC : Base() {
|
||||
class U : SC() {
|
||||
override fun equals(other: Any?): Boolean {
|
||||
return this === other
|
||||
}
|
||||
|
||||
override fun hashCode(): Int {
|
||||
return System.identityHashCode(this)
|
||||
}
|
||||
}
|
||||
|
||||
override val prop: Int
|
||||
get() = 42
|
||||
}
|
||||
@@ -0,0 +1,9 @@
|
||||
// PROBLEM: none
|
||||
|
||||
sealed class SC {
|
||||
<caret>class U : SC() {
|
||||
override fun equals(other: Any?): Boolean {
|
||||
return this === other
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,12 @@
|
||||
// PROBLEM: none
|
||||
|
||||
sealed class SC {
|
||||
<caret>class U : SC()
|
||||
|
||||
fun foo() = 42
|
||||
|
||||
override fun equals(other: Any?): Boolean {
|
||||
if (other !is SC) return false
|
||||
return foo() == other.foo()
|
||||
}
|
||||
}
|
||||
+1
-1
@@ -1,5 +1,5 @@
|
||||
{
|
||||
"mainFile": "Seal.kt",
|
||||
"inspectionClass": "org.jetbrains.kotlin.idea.inspections.CanSealedSubClassBeObjectInspection",
|
||||
"fix": "Convert Sealed Sub-class to Object"
|
||||
"fix": "Convert sealed sub-class to object"
|
||||
}
|
||||
+1
-1
@@ -1,5 +1,5 @@
|
||||
{
|
||||
"mainFile": "Seal.kt",
|
||||
"inspectionClass": "org.jetbrains.kotlin.idea.inspections.CanSealedSubClassBeObjectInspection",
|
||||
"fix": "Convert Sealed Sub-class to Object"
|
||||
"fix": "Convert sealed sub-class to object"
|
||||
}
|
||||
Reference in New Issue
Block a user