-
-
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
Split UnusedPrivateMember #5722
Merged
Merged
Changes from 28 commits
Commits
Show all changes
29 commits
Select commit
Hold shift + click to select a range
968683f
Run ktlint --format on files about to be touched
drawers 7cb6c0f
Make UnusedPrivateMember focus on private functions
drawers 806a415
Extract UnusedParameter
drawers 429142c
Extract UnusedParameter
drawers 09a7c6b
Extract UnusedPrivateProperty
drawers 7c50787
Move first batch of property tests from inside UnusedPrivateMemberSpec
drawers eb11585
Move second batch of property tests from inside UnusedPrivateMemberSpec
drawers a86e950
Readjust expectations in test now that subject only detects unused pr…
drawers 7ff9c21
Move over next batch of property tests from UnusedPrivateMemberSpec
drawers 39491ae
Move one test from "unused class declarations which are allowed"
drawers 49df7cb
Move "nested class declarations" from UnusedPrivateMemberSpec
drawers 939c679
Split "error messages"
drawers f6ffe46
Move "suppress unused property warning annotations"
drawers 2406a24
Move "main methods" inner test class
drawers 8048a00
Move "backtick identifiers" inner test class
drawers 4376627
Move "backtick identifiers" inner test class for unused private param…
drawers 93f090d
Split "highlights declaration name"
drawers 99a350b
Move "parameter with the same name as named argument"
drawers 636b3ad
Split "actual functions and classes"
drawers 18830f8
Move "properties in primary constructors"
drawers 5227986
Fix typo
drawers 9241ae4
Fix disabled tests
drawers 8c4c509
Add alias "UnusedPrivateMember" to UnusedParameter and UnusedPrivateP…
drawers b563ece
Rename "UnusedPrivateParameterSpec" to "UnusedParameterSpec"
drawers 5a3a901
Adjust KDoc to say "source file" instead of "class etc." for clarity
drawers 5897a31
Adjust KDoc to explain how UnusedPrivateProperty can detect unused co…
drawers 1e4bcb8
inline method
chao2zhang 8f9a9e5
Merge branch 'main' into fix-3418-split
schalkms ddd19eb
Remove duplicate `main methods` inner class after merge
drawers File filter
Filter by extension
Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
137 changes: 137 additions & 0 deletions
137
...kt-rules-style/src/main/kotlin/io/gitlab/arturbosch/detekt/rules/style/UnusedParameter.kt
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,137 @@ | ||
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.Debt | ||
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.api.config | ||
import io.gitlab.arturbosch.detekt.api.internal.ActiveByDefault | ||
import io.gitlab.arturbosch.detekt.api.internal.Configuration | ||
import io.gitlab.arturbosch.detekt.rules.isAbstract | ||
import io.gitlab.arturbosch.detekt.rules.isActual | ||
import io.gitlab.arturbosch.detekt.rules.isExpect | ||
import io.gitlab.arturbosch.detekt.rules.isExternal | ||
import io.gitlab.arturbosch.detekt.rules.isMainFunction | ||
import io.gitlab.arturbosch.detekt.rules.isOpen | ||
import io.gitlab.arturbosch.detekt.rules.isOperator | ||
import io.gitlab.arturbosch.detekt.rules.isOverride | ||
import org.jetbrains.kotlin.psi.KtClass | ||
import org.jetbrains.kotlin.psi.KtClassOrObject | ||
import org.jetbrains.kotlin.psi.KtFile | ||
import org.jetbrains.kotlin.psi.KtNamedFunction | ||
import org.jetbrains.kotlin.psi.KtParameter | ||
import org.jetbrains.kotlin.psi.KtProperty | ||
import org.jetbrains.kotlin.psi.KtReferenceExpression | ||
import org.jetbrains.kotlin.psi.KtValueArgumentName | ||
import org.jetbrains.kotlin.psi.psiUtil.isProtected | ||
|
||
/** | ||
* An unused parameter can be removed to simplify the signature of the function. | ||
* | ||
* <noncompliant> | ||
* fun foo(unused: String) { | ||
* println() | ||
* } | ||
* </noncompliant> | ||
* | ||
* <compliant> | ||
* fun foo(used: String) { | ||
* println(used) | ||
* } | ||
* </compliant> | ||
*/ | ||
@ActiveByDefault(since = "1.23.0") | ||
class UnusedParameter(config: Config = Config.empty) : Rule(config) { | ||
override val defaultRuleIdAliases: Set<String> = | ||
setOf("UNUSED_VARIABLE", "UNUSED_PARAMETER", "unused", "UnusedPrivateMember") | ||
|
||
override val issue: Issue = Issue( | ||
"UnusedParameter", | ||
Severity.Maintainability, | ||
"Function parameter is unused and should be removed.", | ||
Debt.FIVE_MINS, | ||
) | ||
|
||
@Configuration("unused parameter names matching this regex are ignored") | ||
private val allowedNames: Regex by config("(_|ignored|expected|serialVersionUID)", String::toRegex) | ||
|
||
override fun visit(root: KtFile) { | ||
super.visit(root) | ||
val visitor = UnusedParameterVisitor(allowedNames) | ||
root.accept(visitor) | ||
visitor.getUnusedReports(issue).forEach { report(it) } | ||
} | ||
} | ||
|
||
private class UnusedParameterVisitor(private val allowedNames: Regex) : DetektVisitor() { | ||
|
||
private val unusedParameters: MutableSet<KtParameter> = mutableSetOf() | ||
|
||
fun getUnusedReports(issue: Issue): List<CodeSmell> { | ||
return unusedParameters.map { | ||
CodeSmell(issue, Entity.atName(it), "Function parameter `${it.nameAsSafeName.identifier}` is unused.") | ||
} | ||
} | ||
|
||
override fun visitClassOrObject(klassOrObject: KtClassOrObject) { | ||
if (klassOrObject.isExpect()) return | ||
|
||
super.visitClassOrObject(klassOrObject) | ||
} | ||
|
||
override fun visitClass(klass: KtClass) { | ||
if (klass.isInterface()) return | ||
if (klass.isExternal()) return | ||
|
||
super.visitClass(klass) | ||
} | ||
|
||
override fun visitNamedFunction(function: KtNamedFunction) { | ||
if (!function.isRelevant()) { | ||
return | ||
} | ||
|
||
collectParameters(function) | ||
|
||
super.visitNamedFunction(function) | ||
} | ||
|
||
private fun collectParameters(function: KtNamedFunction) { | ||
val parameters = mutableMapOf<String, KtParameter>() | ||
function.valueParameterList?.parameters?.forEach { parameter -> | ||
val name = parameter.nameAsSafeName.identifier | ||
if (!allowedNames.matches(name)) { | ||
parameters[name] = parameter | ||
} | ||
} | ||
|
||
function.accept(object : DetektVisitor() { | ||
override fun visitProperty(property: KtProperty) { | ||
if (property.isLocal) { | ||
val name = property.nameAsSafeName.identifier | ||
parameters.remove(name) | ||
} | ||
super.visitProperty(property) | ||
} | ||
|
||
override fun visitReferenceExpression(expression: KtReferenceExpression) { | ||
if (expression.parent !is KtValueArgumentName) { | ||
parameters.remove(expression.text.removeSurrounding("`")) | ||
} | ||
super.visitReferenceExpression(expression) | ||
} | ||
}) | ||
|
||
unusedParameters.addAll(parameters.values) | ||
} | ||
|
||
private fun KtNamedFunction.isRelevant() = !isAllowedToHaveUnusedParameters() | ||
|
||
private fun KtNamedFunction.isAllowedToHaveUnusedParameters() = | ||
isAbstract() || isOpen() || isOverride() || isOperator() || isMainFunction() || isExternal() || | ||
isExpect() || isActual() || isProtected() | ||
} |
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
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.
serialVersionUID
is not likely to be a parameter name we want to ignore but I wanted to make this a non-breaking change.I would suggest a follow up issue for all of the breaking changes that will further the clean up here (including things like renaming
UnusedPrivateMember
toUnusedPrivateFunction
)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.
I guess we don't usually have parameters with names like
ignored
,expected
, andserialVersionUID
.