detekt: UnnecessaryAbstractClass false positive
Expected Behavior
Don’t report following code:
abstract class Fake : Base() // UnnecessaryAbstractClass
abstract class Base {
open val order: Int get() = 0
abstract fun String.foo()
}
Observed Behavior
“An abstract class without a concrete member can be refactored to an interface.”
No, it can’t:
Fake
interface couldn’t extend a class.- it has concrete members inherited from
Base
- I get a detection even if I add an actual class using the “abstractness”:
class Foo : Fake() {
override fun String.foo() = TODO("not implemented")
}
Note: String.
might be a red herring, you can ignore that part, just wanted to report what I had. More minimal repro might exist.
Steps to Reproduce
Just copy above code into a test or code checked by Detekt 1.20.0.
Context
Real context is creating fakes for a test:
The abstract method is never invoked in the test, so there’s no need to implement it, hence using abstract class
. The class must be unique because it’s ::class
object is used.
Your Environment
- Version of detekt used: 1.20.0
- Version of Gradle used (if applicable): N/A
- Gradle scan link (add
--scan
option when running the gradle task): N/A - Operating System and version: all
- Link to your project (if it’s a public repository): https://github.com/TWiStErRob/net.twisterrob.cinema/pull/114/commits/0a43c8e914bcd46fd9db4a80baeba0470a7e07df in https://github.com/TWiStErRob/net.twisterrob.cinema/pull/114
About this issue
- Original URL
- State: closed
- Created 2 years ago
- Reactions: 6
- Comments: 20 (16 by maintainers)
Commits related to this issue
- Ignore UnnecessaryAbstractClass false positives https://github.com/detekt/detekt/issues/4753 — committed to TWiStErRob/net.twisterrob.cinema by TWiStErRob 2 years ago
- Update Detekt monorepo from 1.19.0 to 1.20.0 (minor) (#114) * Fix UnnecessaryAbstractClass * Ignore UnnecessaryAbstractClass false positives https://github.com/detekt/detekt/issues/4753 Co-author... — committed to TWiStErRob/net.twisterrob.cinema by renovate[bot] 2 years ago
Ask yourself if there’s a possibility for the case you’re flagging. Is it possible to write code that passes/fails the rule? And are both of them valid engineering choices? (i.e. due to decisions on preferences or restricted by constraints)
I’m fine with or without configuration. I suppose that in that case without is better because it keeps the api cleaner but that’s your call. I think that no one here have a hard opinion about this topic.
Go ahead
I think the rule of thumb is because
Interface can't extend abstract class
. I agree that we should at least provide a configuration to this rule.