[FIR] add RedundantReturnUnitTypeChecker

This commit is contained in:
vladislavf7@gmail.com
2020-07-14 09:58:36 +03:00
committed by Mikhail Glukhikh
parent 5c88b1e80a
commit 275ce16faa
6 changed files with 162 additions and 1 deletions
@@ -0,0 +1,46 @@
class A {
fun foo(): <!REDUNDANT_RETURN_UNIT_TYPE!>Unit<!>
{
}
fun bar(): <!REDUNDANT_RETURN_UNIT_TYPE!>Unit<!>
{
return Unit
}
fun baz(): Unit = bar()
fun f1(): Int = 1
fun f2(): <!REDUNDANT_RETURN_UNIT_TYPE!>Unit<!>
{
throw UnsupportedOperationException("")
}
fun f3(): Unit = throw UnsupportedOperationException("")
}
class B {
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()
}
}
@@ -0,0 +1,76 @@
FILE: RedundantReturnUnitTypeChecker.kt
public final class A : R|kotlin/Any| {
public constructor(): R|A| {
super<R|kotlin/Any|>()
}
public final fun foo(): R|kotlin/Unit| {
}
public final fun bar(): R|kotlin/Unit| {
^bar Q|kotlin/Unit|
}
public final fun baz(): R|kotlin/Unit| {
^baz this@R|/A|.R|/A.bar|()
}
public final fun f1(): R|kotlin/Int| {
^f1 Int(1)
}
public final fun f2(): R|kotlin/Unit| {
throw R|java/lang/UnsupportedOperationException.UnsupportedOperationException|(String())
}
public final fun f3(): R|kotlin/Unit| {
^f3 throw R|java/lang/UnsupportedOperationException.UnsupportedOperationException|(String())
}
}
public final class B : R|kotlin/Any| {
public constructor(): R|B| {
super<R|kotlin/Any|>()
}
public final fun <T> run(f: R|() -> T|): R|T| {
^run R|<local>/f|.R|FakeOverride<kotlin/Function0.invoke: R|T|>|()
}
public final fun foo(): R|kotlin/Unit| {
^foo this@R|/B|.R|/B.run|<R|kotlin/Int|>(<L> = run@fun <anonymous>(): R|kotlin/Int| {
^ this@R|/B|.R|/B.bar|()
}
)
}
public final fun bar(): R|kotlin/Int| {
^bar Int(1)
}
public final fun call(f: R|() -> kotlin/Unit|): R|kotlin/Unit| {
^call R|<local>/f|.R|FakeOverride<kotlin/Function0.invoke: R|kotlin/Unit|>|()
}
public final fun boo(): R|kotlin/Unit| {
^boo this@R|/B|.R|/B.call|(<L> = call@fun <anonymous>(): R|kotlin/Unit| {
this@R|/B|.R|/B.baz|()
}
)
}
public final fun baz(): R|kotlin/Unit| {
}
public final fun <T, R> R|T|.let(f: R|(T) -> R|): R|R| {
^let R|<local>/f|.R|FakeOverride<kotlin/Function1.invoke: R|R|>|(this@R|/B.let|)
}
public final fun goo(): R|kotlin/Unit| {
^goo (this@R|/B|, Int(1)).R|/B.let|<R|kotlin/Int|, R|kotlin/Int|>(<L> = let@fun <anonymous>(it: R|kotlin/Int|): R|kotlin/Int| {
^ this@R|/B|.R|/B.bar|()
}
)
}
}
@@ -28,6 +28,11 @@ public class ExtendedFirDiagnosticsTestGenerated extends AbstractExtendedFirDiag
KotlinTestUtils.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("compiler/fir/analysis-tests/testData/extendedCheckers"), Pattern.compile("^([^.]+)\\.kt$"), null, true);
}
@TestMetadata("RedundantReturnUnitTypeChecker.kt")
public void testRedundantReturnUnitTypeChecker() throws Exception {
runTest("compiler/fir/analysis-tests/testData/extendedCheckers/RedundantReturnUnitTypeChecker.kt");
}
@TestMetadata("RedundantVisibilityModifierChecker.kt")
public void testRedundantVisibilityModifierChecker() throws Exception {
runTest("compiler/fir/analysis-tests/testData/extendedCheckers/RedundantVisibilityModifierChecker.kt");
@@ -5,13 +5,15 @@
package org.jetbrains.kotlin.fir.analysis.checkers.declaration
import org.jetbrains.kotlin.fir.analysis.checkers.extended.RedundantReturnUnitType
import org.jetbrains.kotlin.fir.analysis.checkers.extended.RedundantVisibilityModifierChecker
object CommonDeclarationCheckers : DeclarationCheckers() {
override val declarationCheckers: List<FirBasicDeclarationChecker> = listOf(
FirAnnotationClassDeclarationChecker,
FirModifierChecker,
RedundantVisibilityModifierChecker
RedundantVisibilityModifierChecker,
RedundantReturnUnitType
)
override val memberDeclarationCheckers: List<FirMemberDeclarationChecker> = listOf(
@@ -0,0 +1,30 @@
/*
* Copyright 2010-2020 JetBrains s.r.o. and Kotlin Programming Language contributors.
* Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
*/
package org.jetbrains.kotlin.fir.analysis.checkers.extended
import org.jetbrains.kotlin.fir.analysis.checkers.context.CheckerContext
import org.jetbrains.kotlin.fir.analysis.checkers.declaration.FirBasicDeclarationChecker
import org.jetbrains.kotlin.fir.analysis.diagnostics.DiagnosticReporter
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors
import org.jetbrains.kotlin.fir.declarations.FirDeclaration
import org.jetbrains.kotlin.fir.declarations.FirSimpleFunction
import org.jetbrains.kotlin.fir.expressions.impl.FirSingleExpressionBlock
import org.jetbrains.kotlin.fir.types.isUnit
object RedundantReturnUnitType : FirBasicDeclarationChecker() {
override val isExtended = true
override fun check(declaration: FirDeclaration, context: CheckerContext, reporter: DiagnosticReporter) {
if (declaration !is FirSimpleFunction) return
if (declaration.body is FirSingleExpressionBlock) return
if (declaration.returnTypeRef.source == null) return
if (declaration.returnTypeRef.isUnit) {
reporter.report(declaration.returnTypeRef.source, FirErrors.REDUNDANT_RETURN_UNIT_TYPE)
}
}
}
@@ -6,6 +6,7 @@
package org.jetbrains.kotlin.fir.analysis.diagnostics
import com.intellij.psi.PsiElement
import com.intellij.psi.PsiTypeElement
import org.jetbrains.kotlin.diagnostics.Errors
import org.jetbrains.kotlin.fir.FirEffectiveVisibility
import org.jetbrains.kotlin.fir.FirSourceElement
@@ -83,6 +84,7 @@ object FirErrors {
// Extended checkers group
val REDUNDANT_VISIBILITY_MODIFIER by warning0<FirSourceElement, PsiElement>()
val REDUNDANT_RETURN_UNIT_TYPE by warning0<FirSourceElement, PsiTypeElement>()
}