-
-
Notifications
You must be signed in to change notification settings - Fork 755
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Nested class, interface or enum shouldn't be publicly visible #446
Changes from 9 commits
dd9a60e
fa812a7
635be63
361db80
f48f3c4
87c8e78
782f847
85db039
23eb25a
2ce304a
3c1f21e
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,42 @@ | ||
package io.gitlab.arturbosch.detekt.rules.style | ||
|
||
import io.gitlab.arturbosch.detekt.api.CodeSmell | ||
import io.gitlab.arturbosch.detekt.api.Config | ||
import io.gitlab.arturbosch.detekt.api.DetektVisitor | ||
import io.gitlab.arturbosch.detekt.api.Entity | ||
import io.gitlab.arturbosch.detekt.api.Issue | ||
import io.gitlab.arturbosch.detekt.api.Rule | ||
import io.gitlab.arturbosch.detekt.api.Severity | ||
import io.gitlab.arturbosch.detekt.rules.isInternal | ||
import org.jetbrains.kotlin.psi.KtClass | ||
import org.jetbrains.kotlin.psi.psiUtil.isPrivate | ||
|
||
class NestedClassesVisibility(config: Config = Config.empty) : Rule(config) { | ||
override val issue: Issue = Issue("NestedClassesVisibility", | ||
severity = Severity.Security, | ||
description = "Nested types are often used for implementing private functionality. " + | ||
"Therefore, they shouldn't be externally visible.") | ||
|
||
private val visitor = VisibilityVisitor() | ||
|
||
override fun visitClass(klass: KtClass) { | ||
super.visitClass(klass) | ||
if (klass.isInternal()) { | ||
klass.declarations.forEach { | ||
it.accept(visitor) | ||
} | ||
} | ||
} | ||
|
||
private fun handleClass(klass: KtClass) { | ||
report(CodeSmell(issue, Entity.from(klass))) | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Should we report the issue with a concrete description? Something along the lines of: `issue.copy(description = "Nested types are often used for implementing private functionality. However the visiblilty of ${klass.name} makes it visible externally.") That mentions the class name and might make the description of the user a bit clearer to the user. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I agree. Done |
||
} | ||
|
||
private inner class VisibilityVisitor : DetektVisitor() { | ||
override fun visitClass(klass: KtClass) { | ||
if (!klass.isInternal() && !klass.isPrivate()) { | ||
handleClass(klass) | ||
} | ||
} | ||
} | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,18 @@ | ||
package io.gitlab.arturbosch.detekt.rules.style | ||
|
||
import io.gitlab.arturbosch.detekt.rules.Case | ||
import io.gitlab.arturbosch.detekt.test.lint | ||
import org.assertj.core.api.Assertions | ||
import org.jetbrains.spek.api.dsl.given | ||
import org.jetbrains.spek.api.dsl.it | ||
import org.jetbrains.spek.subject.SubjectSpek | ||
|
||
class NestedClassesVisibilitySpec : SubjectSpek<NestedClassesVisibility>({ | ||
subject { NestedClassesVisibility() } | ||
|
||
given("several nested classes") { | ||
it("check interfaces,enums,classes") { | ||
Assertions.assertThat(subject.lint(Case.NestedClassesVisibility.path())).hasSize(3) | ||
} | ||
} | ||
}) |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,16 @@ | ||
package cases | ||
|
||
internal class ParentType { | ||
public class NestedType { // report | ||
} | ||
|
||
enum class NestedEnum { One, Two } // report | ||
|
||
private enum class NestedPrivateEnum { Three } // valid | ||
|
||
interface Test {} // report | ||
|
||
private interface PrivateTest {} // valid | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Please add some cases for nested classes (nest-level > 2) There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. done + fix for enums |
||
|
||
internal interface InternalTest {} // valid | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This method could be inlined.