Do not report "redundant Unit" for generic calls coerced to Unit

So #KT-18999 Fixed
This commit is contained in:
Mikhail Glukhikh
2017-07-19 20:44:23 +03:00
parent c554bfa20d
commit 39f1ef390e
3 changed files with 50 additions and 8 deletions
@@ -20,12 +20,14 @@ import com.intellij.codeInspection.IntentionWrapper
import com.intellij.codeInspection.ProblemHighlightType
import com.intellij.codeInspection.ProblemsHolder
import com.intellij.psi.PsiElementVisitor
import org.jetbrains.kotlin.descriptors.FunctionDescriptor
import org.jetbrains.kotlin.idea.caches.resolve.analyze
import org.jetbrains.kotlin.idea.intentions.RemoveExplicitTypeIntention
import org.jetbrains.kotlin.idea.search.usagesSearch.descriptor
import org.jetbrains.kotlin.psi.KtCodeFragment
import org.jetbrains.kotlin.psi.KtNamedFunction
import org.jetbrains.kotlin.psi.KtVisitorVoid
import org.jetbrains.kotlin.resolve.BindingContext
import org.jetbrains.kotlin.resolve.calls.callUtil.getResolvedCall
import org.jetbrains.kotlin.resolve.lazy.BodyResolveMode
import org.jetbrains.kotlin.types.typeUtil.isUnit
class RedundantUnitReturnTypeInspection : AbstractKotlinInspection() {
@@ -34,13 +36,24 @@ class RedundantUnitReturnTypeInspection : AbstractKotlinInspection() {
override fun visitNamedFunction(function: KtNamedFunction) {
super.visitNamedFunction(function)
if (function.containingFile is KtCodeFragment) return
if ((function.descriptor as? FunctionDescriptor)?.returnType?.isUnit() == true) {
function.typeReference?.typeElement?.let {
holder.registerProblem(it,
"Redundant 'Unit' return type",
ProblemHighlightType.LIKE_UNUSED_SYMBOL,
IntentionWrapper(RemoveExplicitTypeIntention(), function.containingKtFile))
val typeElement = function.typeReference?.typeElement ?: return
val context = function.analyze(BodyResolveMode.PARTIAL)
val descriptor = context[BindingContext.FUNCTION, function] ?: return
if (descriptor.returnType?.isUnit() == true) {
if (!function.hasBlockBody()) {
val bodyExpression = function.bodyExpression
if (bodyExpression != null) {
val resolvedCall = bodyExpression.getResolvedCall(bodyExpression.analyze(BodyResolveMode.PARTIAL))
if (resolvedCall != null) {
if (resolvedCall.candidateDescriptor.returnType?.isUnit() != true) return
}
}
}
holder.registerProblem(typeElement,
"Redundant 'Unit' return type",
ProblemHighlightType.LIKE_UNUSED_SYMBOL,
IntentionWrapper(RemoveExplicitTypeIntention(), function.containingKtFile))
}
}
}
@@ -0,0 +1,21 @@
fun <T> run(f: () -> T) = f()
fun foo(): Unit = run {
bar()
}
fun bar() = 1
fun call(f: () -> Unit) = f()
fun boo(): Unit = call {
baz()
}
fun baz() {}
fun <T, R> T.let(f: (T) -> R) = f(this)
fun goo(): Unit = 1.let {
bar()
}
@@ -23,4 +23,12 @@
<problem_class severity="WARNING" attribute_key="NOT_USED_ELEMENT_ATTRIBUTES">Redundant 'Unit' return type</problem_class>
<description>Redundant Unit return type</description>
</problem>
<problem>
<file>WithLambda.kt</file>
<line>11</line>
<module>light_idea_test_case</module>
<entry_point TYPE="file" FQNAME="temp:///src/WithLambda.kt" />
<problem_class severity="WARNING" attribute_key="NOT_USED_ELEMENT_ATTRIBUTES">Redundant 'Unit' return type</problem_class>
<description>Redundant 'Unit' return type</description>
</problem>
</problems>