Skip to content

Commit

Permalink
Fix issue by finding the all name ref for a var
Browse files Browse the repository at this point in the history
Fix violations
Add PR TC
  • Loading branch information
atulgpt committed Mar 25, 2023
1 parent 56f4987 commit 4285945
Show file tree
Hide file tree
Showing 2 changed files with 242 additions and 172 deletions.
Expand Up @@ -17,6 +17,8 @@ import io.gitlab.arturbosch.detekt.rules.isOverride
import org.jetbrains.kotlin.descriptors.CallableDescriptor
import org.jetbrains.kotlin.descriptors.DeclarationDescriptor
import org.jetbrains.kotlin.descriptors.PropertyDescriptor
import org.jetbrains.kotlin.descriptors.ValueParameterDescriptor
import org.jetbrains.kotlin.js.translate.callTranslator.getReturnType
import org.jetbrains.kotlin.lexer.KtTokens
import org.jetbrains.kotlin.name.FqName
import org.jetbrains.kotlin.psi.KtBinaryExpression
Expand Down Expand Up @@ -231,25 +233,37 @@ class CanBeNonNullable(config: Config = Config.empty) : Rule(config) {
}

override fun visitWhenExpression(expression: KtWhenExpression) {
val subjectDescriptor = expression.subjectExpression
?.let { it as? KtNameReferenceExpression }
?.getResolvedCall(bindingContext)
?.resultingDescriptor
val nullCheckedDescriptor =
(expression.subjectExpression?.collectDescendantsOfType<KtNameReferenceExpression>() ?: emptyList())

Check warning

Code scanning / detekt

Use `orEmpty()` call instead of `?:` with empty collection factory methods Warning

This '?: emptyList()' can be replaced with 'orEmpty()' call
.mapNotNull {
val callDescriptor =
it.getResolvedCall(bindingContext)
val valueParameterDescriptor =
callDescriptor?.resultingDescriptor as? ValueParameterDescriptor
if (valueParameterDescriptor != null && callDescriptor.getReturnType().isNullable()) {
valueParameterDescriptor
} else {
null
}
}
val whenConditions = expression.entries.flatMap { it.conditions.asList() }
if (subjectDescriptor != null) {
whenConditions.evaluateSubjectWhenExpression(expression, subjectDescriptor)
if (nullCheckedDescriptor.isNotEmpty()) {
whenConditions.evaluateSubjectWhenExpression(expression, nullCheckedDescriptor)
} else {
whenConditions.forEach { whenCondition ->
if (whenCondition is KtWhenConditionWithExpression) {
whenCondition.expression.evaluateCheckStatement(expression.elseExpression)
whenCondition.expression.evaluateCheckStatement(
expression.elseExpression,
emptyList()
)
}
}
}
super.visitWhenExpression(expression)
}

override fun visitIfExpression(expression: KtIfExpression) {
expression.condition.evaluateCheckStatement(expression.`else`)
expression.condition.evaluateCheckStatement(expression.`else`, emptyList())
if (expression.isFirstStatement()) {
evaluateNullCheckReturnsUnit(expression.condition, expression.then)
}
Expand Down Expand Up @@ -332,7 +346,10 @@ class CanBeNonNullable(config: Config = Config.empty) : Rule(config) {
}
}

private fun KtExpression?.evaluateCheckStatement(elseExpression: KtExpression?) {
private fun KtExpression?.evaluateCheckStatement(
elseExpression: KtExpression?,
nullCheckedExpression: List<CallableDescriptor>,
) {
this.getNonNullChecks()?.let { nonNullChecks ->
val nullableParamCallback = if (elseExpression.isValidElseExpression()) {
{ nullableParam: NullableParam ->
Expand All @@ -342,7 +359,9 @@ class CanBeNonNullable(config: Config = Config.empty) : Rule(config) {
} else {
{ nullableParam -> nullableParam.isNonNullChecked = true }
}
nonNullChecks.forEach { nullableParams[it]?.let(nullableParamCallback) }
nonNullChecks.filter { nullCheckedExpression.contains(it).not() }.forEach {
nullableParams[it]?.let(nullableParamCallback)
}
}
}

Expand Down Expand Up @@ -389,7 +408,7 @@ class CanBeNonNullable(config: Config = Config.empty) : Rule(config) {

private fun List<KtWhenCondition>.evaluateSubjectWhenExpression(
expression: KtWhenExpression,
subjectDescriptor: CallableDescriptor
subjectDescriptor: List<CallableDescriptor>,
) {
var isNonNullChecked = false
var isNullChecked = false
Expand All @@ -416,9 +435,11 @@ class CanBeNonNullable(config: Config = Config.empty) : Rule(config) {
isNullChecked = true
}
}
nullableParams[subjectDescriptor]?.let {
if (isNullChecked) it.isNullChecked = true
if (isNonNullChecked) it.isNonNullChecked = true
subjectDescriptor.forEach {
nullableParams[it]?.let {
if (isNullChecked) it.isNullChecked = true
if (isNonNullChecked) it.isNonNullChecked = true
}

Check warning

Code scanning / detekt

Disallow shadowing variable declarations. Warning

Name shadowed: implicit lambda parameter 'it'
}
}

Expand Down

0 comments on commit 4285945

Please sign in to comment.