Skip to content
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

MissingWhenCase false negative with nulls #3189

Closed
BraisGabin opened this issue Oct 31, 2020 · 6 comments · Fixed by #3194
Closed

MissingWhenCase false negative with nulls #3189

BraisGabin opened this issue Oct 31, 2020 · 6 comments · Fixed by #3194

Comments

@BraisGabin
Copy link
Member

Expected Behavior

MissingWhenCase should check for null case if the enum or sealed can be null

Observed Behavior

It doesn't check that.

Steps to Reproduce

fun whenOnEnumPass(c: Color?) {
    when(c) {
        Color.BLUE -> {}
        Color.GREEN -> {}
        Color.RED -> {}
    }
}

Your Environment

  • Version of detekt used: master (1.14.2)
@schalkms
Copy link
Member

schalkms commented Nov 2, 2020

@schalkms schalkms closed this as completed Nov 2, 2020
@BraisGabin
Copy link
Member Author

Should we create a tag "require smart cast" or something similar to track this issues? I mean, even if we close it to find them if we eventually implement it. Or if we want ro evaluate if it's worth it to implement it.

@schalkms
Copy link
Member

schalkms commented Nov 2, 2020

An available smart cast detection alone won't solve the problem here. You'll need more sophisticated analysis than that.

@BraisGabin
Copy link
Member Author

🤔 why not?

@schalkms
Copy link
Member

schalkms commented Nov 4, 2020

I didn't know that we already have dataflow analysis as part of the bindingContext. Great. Thanks for bringing this up.
This issue can be reopened.

expression.parent is KtStringTemplateEntry -> {
val compilerResources = compilerResources ?: return
val descriptor = expression.descriptor() ?: return
val originalType = descriptor.returnType ?.takeIf { it.isNullable() } ?: return
val dataFlowInfo =
bindingContext[BindingContext.EXPRESSION_TYPE_INFO, expression]?.dataFlowInfo ?: return
val dataFlowValue = compilerResources.dataFlowValueFactory.createDataFlowValue(
expression, originalType, bindingContext, descriptor
)
val dataFlowTypes =
dataFlowInfo.getStableTypes(dataFlowValue, compilerResources.languageVersionSettings)
if (dataFlowTypes.any { !it.isNullable() }) return
}

@schalkms schalkms reopened this Nov 4, 2020
@schalkms
Copy link
Member

schalkms commented Nov 4, 2020

By the way, this has nothing to do with smart casts per se. The enabler here is data flow analysis as part of the Kotlin compiler. With the help of data flow analysis we can detect whether null checks or the necessary casts have been made before the when clause.

@arturbosch arturbosch added this to the 1.15.0 milestone Nov 10, 2020
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging a pull request may close this issue.

3 participants