FIR: introduce parameter type is Throwable check
This commit is contained in:
committed by
Mikhail Glukhikh
parent
5c0231b727
commit
9ad88a5a0d
@@ -1,5 +1,6 @@
|
||||
FILE: catchParameter.kt
|
||||
public final fun <T> test(): R|kotlin/Unit| {
|
||||
public final typealias StringType = R|kotlin/String|
|
||||
public final fun <T : R|kotlin/Throwable|> test(): R|kotlin/Unit| {
|
||||
try {
|
||||
}
|
||||
catch (e: R|kotlin/NullPointerException| = R|java/lang/NullPointerException.NullPointerException|()) {
|
||||
@@ -10,6 +11,26 @@ FILE: catchParameter.kt
|
||||
catch (e: R|T|) {
|
||||
}
|
||||
|
||||
try {
|
||||
}
|
||||
catch (e: R|() -> kotlin/Int|) {
|
||||
}
|
||||
|
||||
try {
|
||||
}
|
||||
catch (e: R|StringType|) {
|
||||
}
|
||||
|
||||
try {
|
||||
}
|
||||
catch (e: R|kotlin/Int| = Int(5)) {
|
||||
}
|
||||
|
||||
try {
|
||||
}
|
||||
catch (e: R|kotlin/Throwable|) {
|
||||
}
|
||||
|
||||
}
|
||||
public final inline fun <reified T> anotherTest(): R|kotlin/Unit| {
|
||||
try {
|
||||
@@ -17,4 +38,4 @@ FILE: catchParameter.kt
|
||||
catch (e: R|T|) {
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,4 +1,6 @@
|
||||
fun <T> test() {
|
||||
typealias StringType = String
|
||||
|
||||
fun <T : Throwable> test() {
|
||||
try {
|
||||
|
||||
} catch (<!CATCH_PARAMETER_WITH_DEFAULT_VALUE!>e: NullPointerException = NullPointerException()<!>) {
|
||||
@@ -6,8 +8,16 @@ fun <T> test() {
|
||||
}
|
||||
|
||||
try {} catch (<!TYPE_PARAMETER_IN_CATCH_CLAUSE!>e: T<!>) {}
|
||||
|
||||
try {} catch (<!TYPE_MISMATCH!>e: () -> Int<!>) {}
|
||||
|
||||
try {} catch (<!TYPE_MISMATCH!>e: StringType<!>) {}
|
||||
|
||||
try {} catch (<!CATCH_PARAMETER_WITH_DEFAULT_VALUE, TYPE_MISMATCH!>e: Int = 5<!>) {}
|
||||
|
||||
try {} catch (e: Throwable) {}
|
||||
}
|
||||
|
||||
inline fun <reified T> anotherTest() {
|
||||
try {} catch (<!REIFIED_TYPE_IN_CATCH_CLAUSE!>e: T<!>) {}
|
||||
}
|
||||
try {} catch (<!REIFIED_TYPE_IN_CATCH_CLAUSE, TYPE_MISMATCH!>e: T<!>) {}
|
||||
}
|
||||
|
||||
@@ -11,6 +11,7 @@ import org.jetbrains.kotlin.descriptors.Visibilities
|
||||
import org.jetbrains.kotlin.descriptors.Visibility
|
||||
import org.jetbrains.kotlin.fir.FirSession
|
||||
import org.jetbrains.kotlin.fir.FirSymbolOwner
|
||||
import org.jetbrains.kotlin.fir.analysis.cfa.FirReturnsImpliesAnalyzer.isSupertypeOf
|
||||
import org.jetbrains.kotlin.fir.analysis.checkers.context.CheckerContext
|
||||
import org.jetbrains.kotlin.fir.analysis.diagnostics.modalityModifier
|
||||
import org.jetbrains.kotlin.fir.analysis.diagnostics.overrideModifier
|
||||
@@ -22,18 +23,18 @@ import org.jetbrains.kotlin.fir.expressions.FirQualifiedAccessExpression
|
||||
import org.jetbrains.kotlin.fir.expressions.impl.FirEmptyExpressionBlock
|
||||
import org.jetbrains.kotlin.fir.references.FirResolvedNamedReference
|
||||
import org.jetbrains.kotlin.fir.resolve.firSymbolProvider
|
||||
import org.jetbrains.kotlin.fir.resolve.fullyExpandedType
|
||||
import org.jetbrains.kotlin.fir.resolve.toSymbol
|
||||
import org.jetbrains.kotlin.fir.resolve.transformers.firClassLike
|
||||
import org.jetbrains.kotlin.fir.scopes.ProcessorAction
|
||||
import org.jetbrains.kotlin.fir.scopes.processOverriddenFunctions
|
||||
import org.jetbrains.kotlin.fir.scopes.unsubstitutedScope
|
||||
import org.jetbrains.kotlin.fir.symbols.StandardClassIds
|
||||
import org.jetbrains.kotlin.fir.symbols.impl.FirFunctionSymbol
|
||||
import org.jetbrains.kotlin.fir.symbols.impl.FirNamedFunctionSymbol
|
||||
import org.jetbrains.kotlin.fir.symbols.impl.FirRegularClassSymbol
|
||||
import org.jetbrains.kotlin.fir.types.ConeClassLikeType
|
||||
import org.jetbrains.kotlin.fir.types.ConeKotlinType
|
||||
import org.jetbrains.kotlin.fir.types.FirResolvedTypeRef
|
||||
import org.jetbrains.kotlin.fir.types.FirTypeRef
|
||||
import org.jetbrains.kotlin.fir.typeCheckerContext
|
||||
import org.jetbrains.kotlin.fir.types.*
|
||||
import org.jetbrains.kotlin.lexer.KtModifierKeywordToken
|
||||
import org.jetbrains.kotlin.lexer.KtTokens
|
||||
import org.jetbrains.kotlin.psi.KtModifierList
|
||||
|
||||
+24
-5
@@ -5,31 +5,50 @@
|
||||
|
||||
package org.jetbrains.kotlin.fir.analysis.checkers.expression
|
||||
|
||||
import org.jetbrains.kotlin.fir.FirSession
|
||||
import org.jetbrains.kotlin.fir.analysis.cfa.FirReturnsImpliesAnalyzer.isSupertypeOf
|
||||
import org.jetbrains.kotlin.fir.analysis.checkers.context.CheckerContext
|
||||
import org.jetbrains.kotlin.fir.analysis.diagnostics.DiagnosticReporter
|
||||
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors
|
||||
import org.jetbrains.kotlin.fir.expressions.FirTryExpression
|
||||
import org.jetbrains.kotlin.fir.resolve.fullyExpandedType
|
||||
import org.jetbrains.kotlin.fir.symbols.StandardClassIds
|
||||
import org.jetbrains.kotlin.fir.typeCheckerContext
|
||||
import org.jetbrains.kotlin.fir.types.ConeKotlinType
|
||||
import org.jetbrains.kotlin.fir.types.ConeTypeParameterType
|
||||
import org.jetbrains.kotlin.fir.types.FirResolvedTypeRef
|
||||
import org.jetbrains.kotlin.fir.types.constructClassLikeType
|
||||
|
||||
object FirCatchParameterChecker : FirTryExpressionChecker() {
|
||||
private val throwable = StandardClassIds.byName("Throwable")
|
||||
.constructClassLikeType(emptyArray(), false)
|
||||
|
||||
override fun check(expression: FirTryExpression, context: CheckerContext, reporter: DiagnosticReporter) {
|
||||
for (catchEntry in expression.catches) {
|
||||
val catchParameter = catchEntry.parameter
|
||||
|
||||
if (catchParameter.defaultValue != null)
|
||||
reporter.report(catchParameter.source?.let { FirErrors.CATCH_PARAMETER_WITH_DEFAULT_VALUE.on(it) })
|
||||
catchParameter.source?.let { reporter.report(FirErrors.CATCH_PARAMETER_WITH_DEFAULT_VALUE.on(it)) }
|
||||
|
||||
val typeRef = catchParameter.returnTypeRef
|
||||
if (typeRef is FirResolvedTypeRef && typeRef.type is ConeTypeParameterType) {
|
||||
val isReified = (typeRef.type as ConeTypeParameterType).lookupTag.typeParameterSymbol.fir.isReified
|
||||
if (typeRef !is FirResolvedTypeRef) return
|
||||
|
||||
val coneType = typeRef.type
|
||||
if (coneType is ConeTypeParameterType) {
|
||||
val isReified = coneType.lookupTag.typeParameterSymbol.fir.isReified
|
||||
|
||||
if (isReified) {
|
||||
reporter.report(catchParameter.source?.let { FirErrors.REIFIED_TYPE_IN_CATCH_CLAUSE.on(it) })
|
||||
catchParameter.source?.let { reporter.report(FirErrors.REIFIED_TYPE_IN_CATCH_CLAUSE.on(it)) }
|
||||
} else {
|
||||
reporter.report(catchParameter.source?.let { FirErrors.TYPE_PARAMETER_IN_CATCH_CLAUSE.on(it) })
|
||||
catchParameter.source?.let { reporter.report(FirErrors.TYPE_PARAMETER_IN_CATCH_CLAUSE.on(it)) }
|
||||
}
|
||||
}
|
||||
|
||||
if (!coneType.isThrowable(context.session))
|
||||
catchParameter.source?.let { reporter.report(FirErrors.TYPE_MISMATCH.on(it, throwable, coneType)) }
|
||||
}
|
||||
}
|
||||
|
||||
private fun ConeKotlinType.isThrowable(session: FirSession) =
|
||||
throwable.isSupertypeOf(session.typeCheckerContext, this.fullyExpandedType(session))
|
||||
}
|
||||
Vendored
+2
-2
@@ -109,7 +109,7 @@ fun t7() : Int {
|
||||
return 1
|
||||
2
|
||||
}
|
||||
catch (e : Any) {
|
||||
catch (<!TYPE_MISMATCH!>e : Any<!>) {
|
||||
2
|
||||
}
|
||||
return 1 // this is OK, like in Java
|
||||
@@ -120,7 +120,7 @@ fun t8() : Int {
|
||||
return 1
|
||||
2
|
||||
}
|
||||
catch (e : Any) {
|
||||
catch (<!TYPE_MISMATCH!>e : Any<!>) {
|
||||
return 1
|
||||
2
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user