FIR: introduce ThrowableSubclassChecker
This commit is contained in:
committed by
Mikhail Glukhikh
parent
cd189c0812
commit
a564f92eef
+5
@@ -419,6 +419,11 @@ public class LazyBodyIsNotTouchedTilContractsPhaseTestGenerated extends Abstract
|
||||
runTest("compiler/fir/analysis-tests/testData/resolve/syntheticsVsNormalProperties.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("throwableSubclass.kt")
|
||||
public void testThrowableSubclass() throws Exception {
|
||||
runTest("compiler/fir/analysis-tests/testData/resolve/throwableSubclass.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("treeSet.kt")
|
||||
public void testTreeSet() throws Exception {
|
||||
runTest("compiler/fir/analysis-tests/testData/resolve/treeSet.kt");
|
||||
|
||||
@@ -0,0 +1,67 @@
|
||||
FILE: throwableSubclass.kt
|
||||
public final class Test1<T, B> : R|kotlin/Exception| {
|
||||
public constructor<T, B>(): R|Test1<T, B>| {
|
||||
super<R|kotlin/Exception|>()
|
||||
}
|
||||
|
||||
public final inner class Test2<S, T, B> : R|kotlin/Throwable| {
|
||||
public constructor<S>(): R|Test1.Test2<S, T, B>| {
|
||||
super<R|kotlin/Throwable|>()
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public final class Test3 : R|kotlin/NullPointerException| {
|
||||
public constructor(): R|Test1.Test3| {
|
||||
super<R|kotlin/NullPointerException|>()
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public final object Test4 : R|kotlin/Throwable| {
|
||||
private constructor(): R|Test1.Test4| {
|
||||
super<R|kotlin/Throwable|>()
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
public final class Test5<T, B> : R|kotlin/Any| {
|
||||
public constructor<T, B>(): R|Test5<T, B>| {
|
||||
super<R|kotlin/Any|>()
|
||||
}
|
||||
|
||||
public final inner class Test6<T, B> : R|kotlin/Exception| {
|
||||
public constructor(): R|Test5.Test6<T, B>| {
|
||||
super<R|kotlin/Exception|>()
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public final fun foo(): R|kotlin/Unit| {
|
||||
local final class Test7 : R|kotlin/Throwable| {
|
||||
public constructor(): R|Test5.Test7| {
|
||||
super<R|kotlin/Throwable|>()
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
public final fun <Z> topLevelFun(): R|kotlin/Unit| {
|
||||
local final class Test8 : R|kotlin/Error| {
|
||||
public constructor(): R|Test8| {
|
||||
super<R|kotlin/Error|>()
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
lval obj: R|<anonymous><Z>| = object : R|kotlin/Throwable| {
|
||||
private constructor(): R|<anonymous><Z>| {
|
||||
super<R|kotlin/Throwable|>()
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,18 @@
|
||||
class Test1<<!GENERIC_THROWABLE_SUBCLASS!>T<!>, B> : Exception() {
|
||||
inner <!INNER_CLASS_OF_GENERIC_THROWABLE_SUBCLASS!>class Test2<!><<!GENERIC_THROWABLE_SUBCLASS!>S<!>> : Throwable()
|
||||
class Test3 : NullPointerException()
|
||||
object Test4 : Throwable() {}
|
||||
}
|
||||
|
||||
class Test5<T, B> {
|
||||
inner <!INNER_CLASS_OF_GENERIC_THROWABLE_SUBCLASS!>class Test6<!> : Exception()
|
||||
|
||||
fun foo() {
|
||||
<!INNER_CLASS_OF_GENERIC_THROWABLE_SUBCLASS!>class Test7<!> : Throwable()
|
||||
}
|
||||
}
|
||||
|
||||
fun <Z> topLevelFun() {
|
||||
<!INNER_CLASS_OF_GENERIC_THROWABLE_SUBCLASS!>class Test8<!> : Error()
|
||||
val obj = <!INNER_CLASS_OF_GENERIC_THROWABLE_SUBCLASS{LT}!><!INNER_CLASS_OF_GENERIC_THROWABLE_SUBCLASS{PSI}!>object<!> : Throwable() {}<!>
|
||||
}
|
||||
+6
@@ -494,6 +494,12 @@ public class FirDiagnosticTestGenerated extends AbstractFirDiagnosticTest {
|
||||
runTest("compiler/fir/analysis-tests/testData/resolve/syntheticsVsNormalProperties.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("throwableSubclass.kt")
|
||||
public void testThrowableSubclass() throws Exception {
|
||||
runTest("compiler/fir/analysis-tests/testData/resolve/throwableSubclass.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("treeSet.kt")
|
||||
public void testTreeSet() throws Exception {
|
||||
|
||||
+6
@@ -497,6 +497,12 @@ public class FirDiagnosticsWithLightTreeTestGenerated extends AbstractFirDiagnos
|
||||
runTest("compiler/fir/analysis-tests/testData/resolve/syntheticsVsNormalProperties.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("throwableSubclass.kt")
|
||||
public void testThrowableSubclass() throws Exception {
|
||||
runTest("compiler/fir/analysis-tests/testData/resolve/throwableSubclass.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("treeSet.kt")
|
||||
public void testTreeSet() throws Exception {
|
||||
|
||||
+1
@@ -31,6 +31,7 @@ fun main(args: Array<String>) {
|
||||
alias<FirMemberDeclaration>("MemberDeclarationChecker")
|
||||
alias<FirFunction<*>>("FunctionChecker")
|
||||
alias<FirProperty>("PropertyChecker")
|
||||
alias<FirClass<*>>("ClassChecker")
|
||||
alias<FirRegularClass>("RegularClassChecker")
|
||||
alias<FirConstructor>("ConstructorChecker")
|
||||
alias<FirFile>("FileChecker")
|
||||
|
||||
+4
@@ -23,6 +23,8 @@ internal class ComposedDeclarationCheckers : DeclarationCheckers() {
|
||||
get() = _functionCheckers
|
||||
override val propertyCheckers: Set<FirPropertyChecker>
|
||||
get() = _propertyCheckers
|
||||
override val classCheckers: Set<FirClassChecker>
|
||||
get() = _classCheckers
|
||||
override val regularClassCheckers: Set<FirRegularClassChecker>
|
||||
get() = _regularClassCheckers
|
||||
override val constructorCheckers: Set<FirConstructorChecker>
|
||||
@@ -38,6 +40,7 @@ internal class ComposedDeclarationCheckers : DeclarationCheckers() {
|
||||
private val _memberDeclarationCheckers: MutableSet<FirMemberDeclarationChecker> = mutableSetOf()
|
||||
private val _functionCheckers: MutableSet<FirFunctionChecker> = mutableSetOf()
|
||||
private val _propertyCheckers: MutableSet<FirPropertyChecker> = mutableSetOf()
|
||||
private val _classCheckers: MutableSet<FirClassChecker> = mutableSetOf()
|
||||
private val _regularClassCheckers: MutableSet<FirRegularClassChecker> = mutableSetOf()
|
||||
private val _constructorCheckers: MutableSet<FirConstructorChecker> = mutableSetOf()
|
||||
private val _fileCheckers: MutableSet<FirFileChecker> = mutableSetOf()
|
||||
@@ -50,6 +53,7 @@ internal class ComposedDeclarationCheckers : DeclarationCheckers() {
|
||||
_memberDeclarationCheckers += checkers.allMemberDeclarationCheckers
|
||||
_functionCheckers += checkers.allFunctionCheckers
|
||||
_propertyCheckers += checkers.allPropertyCheckers
|
||||
_classCheckers += checkers.allClassCheckers
|
||||
_regularClassCheckers += checkers.allRegularClassCheckers
|
||||
_constructorCheckers += checkers.allConstructorCheckers
|
||||
_fileCheckers += checkers.allFileCheckers
|
||||
|
||||
+3
-1
@@ -23,6 +23,7 @@ abstract class DeclarationCheckers {
|
||||
open val memberDeclarationCheckers: Set<FirMemberDeclarationChecker> = emptySet()
|
||||
open val functionCheckers: Set<FirFunctionChecker> = emptySet()
|
||||
open val propertyCheckers: Set<FirPropertyChecker> = emptySet()
|
||||
open val classCheckers: Set<FirClassChecker> = emptySet()
|
||||
open val regularClassCheckers: Set<FirRegularClassChecker> = emptySet()
|
||||
open val constructorCheckers: Set<FirConstructorChecker> = emptySet()
|
||||
open val fileCheckers: Set<FirFileChecker> = emptySet()
|
||||
@@ -34,7 +35,8 @@ abstract class DeclarationCheckers {
|
||||
@CheckersComponentInternal internal val allMemberDeclarationCheckers: Set<FirMemberDeclarationChecker> get() = memberDeclarationCheckers + allBasicDeclarationCheckers
|
||||
@CheckersComponentInternal internal val allFunctionCheckers: Set<FirFunctionChecker> get() = functionCheckers + allBasicDeclarationCheckers
|
||||
@CheckersComponentInternal internal val allPropertyCheckers: Set<FirPropertyChecker> get() = propertyCheckers + allMemberDeclarationCheckers
|
||||
@CheckersComponentInternal internal val allRegularClassCheckers: Set<FirRegularClassChecker> get() = regularClassCheckers + allMemberDeclarationCheckers
|
||||
@CheckersComponentInternal internal val allClassCheckers: Set<FirClassChecker> get() = classCheckers + allBasicDeclarationCheckers
|
||||
@CheckersComponentInternal internal val allRegularClassCheckers: Set<FirRegularClassChecker> get() = regularClassCheckers + allMemberDeclarationCheckers + allClassCheckers
|
||||
@CheckersComponentInternal internal val allConstructorCheckers: Set<FirConstructorChecker> get() = constructorCheckers + allFunctionCheckers
|
||||
@CheckersComponentInternal internal val allFileCheckers: Set<FirFileChecker> get() = fileCheckers + allBasicDeclarationCheckers
|
||||
}
|
||||
|
||||
+2
@@ -10,6 +10,7 @@ package org.jetbrains.kotlin.fir.analysis.checkers.declaration
|
||||
* DO NOT MODIFY IT MANUALLY
|
||||
*/
|
||||
|
||||
import org.jetbrains.kotlin.fir.declarations.FirClass
|
||||
import org.jetbrains.kotlin.fir.declarations.FirConstructor
|
||||
import org.jetbrains.kotlin.fir.declarations.FirDeclaration
|
||||
import org.jetbrains.kotlin.fir.declarations.FirFile
|
||||
@@ -22,6 +23,7 @@ typealias FirBasicDeclarationChecker = FirDeclarationChecker<FirDeclaration>
|
||||
typealias FirMemberDeclarationChecker = FirDeclarationChecker<FirMemberDeclaration>
|
||||
typealias FirFunctionChecker = FirDeclarationChecker<FirFunction<*>>
|
||||
typealias FirPropertyChecker = FirDeclarationChecker<FirProperty>
|
||||
typealias FirClassChecker = FirDeclarationChecker<FirClass<*>>
|
||||
typealias FirRegularClassChecker = FirDeclarationChecker<FirRegularClass>
|
||||
typealias FirConstructorChecker = FirDeclarationChecker<FirConstructor>
|
||||
typealias FirFileChecker = FirDeclarationChecker<FirFile>
|
||||
|
||||
@@ -38,6 +38,7 @@ import org.jetbrains.kotlin.fir.types.*
|
||||
import org.jetbrains.kotlin.lexer.KtModifierKeywordToken
|
||||
import org.jetbrains.kotlin.lexer.KtTokens
|
||||
import org.jetbrains.kotlin.psi.KtModifierList
|
||||
import org.jetbrains.kotlin.psi.KtObjectLiteralExpression
|
||||
import org.jetbrains.kotlin.psi.psiUtil.visibilityModifierType
|
||||
import org.jetbrains.kotlin.utils.addToStdlib.safeAs
|
||||
|
||||
@@ -318,3 +319,9 @@ fun Modality.toToken(): KtModifierKeywordToken = when (this) {
|
||||
|
||||
val FirFunctionCall.isIterator
|
||||
get() = this.calleeReference.name.asString() == "<iterator>"
|
||||
|
||||
internal val throwableClassLikeType =
|
||||
StandardClassIds.byName("Throwable").constructClassLikeType(emptyArray(), false)
|
||||
|
||||
fun ConeKotlinType.isThrowable(session: FirSession) =
|
||||
throwableClassLikeType.isSupertypeOf(session.typeCheckerContext, this.fullyExpandedType(session))
|
||||
+51
@@ -0,0 +1,51 @@
|
||||
/*
|
||||
* Copyright 2010-2021 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.declaration
|
||||
|
||||
import org.jetbrains.kotlin.fir.FirSourceElement
|
||||
import org.jetbrains.kotlin.fir.analysis.checkers.context.CheckerContext
|
||||
import org.jetbrains.kotlin.fir.analysis.checkers.isThrowable
|
||||
import org.jetbrains.kotlin.fir.analysis.diagnostics.DiagnosticReporter
|
||||
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors
|
||||
import org.jetbrains.kotlin.fir.declarations.*
|
||||
import org.jetbrains.kotlin.fir.types.ConeClassErrorType
|
||||
|
||||
object FirThrowableSubclassChecker : FirClassChecker() {
|
||||
override fun check(declaration: FirClass<*>, context: CheckerContext, reporter: DiagnosticReporter) {
|
||||
if (!declaration.hasThrowableSupertype(context))
|
||||
return
|
||||
|
||||
if (declaration.typeParameters.isNotEmpty()) {
|
||||
reporter.reportGenericThrowableSubclass(declaration.typeParameters.firstOrNull()?.source)
|
||||
|
||||
val source = when {
|
||||
(declaration as? FirRegularClass)?.isInner == true -> declaration.source
|
||||
declaration is FirAnonymousObject -> (declaration.declarations.firstOrNull())?.source
|
||||
else -> null
|
||||
}
|
||||
reporter.reportInnerClassOfGenericThrowableSubclass(source)
|
||||
} else if (declaration.hasGenericOuterDeclaration(context)) {
|
||||
reporter.reportInnerClassOfGenericThrowableSubclass(declaration.source)
|
||||
}
|
||||
}
|
||||
|
||||
private fun FirClass<*>.hasThrowableSupertype(context: CheckerContext) =
|
||||
superConeTypes.any { it !is ConeClassErrorType && it.isThrowable(context.session) }
|
||||
|
||||
private fun FirClass<*>.hasGenericOuterDeclaration(context: CheckerContext) =
|
||||
classId.isLocal && context.containingDeclarations.anyIsGeneric()
|
||||
|
||||
private fun Collection<FirDeclaration>.anyIsGeneric() =
|
||||
any { it is FirTypeParameterRefsOwner && it.typeParameters.isNotEmpty() }
|
||||
|
||||
private fun DiagnosticReporter.reportGenericThrowableSubclass(source: FirSourceElement?) {
|
||||
source?.let { report(FirErrors.GENERIC_THROWABLE_SUBCLASS.on(it)) }
|
||||
}
|
||||
|
||||
private fun DiagnosticReporter.reportInnerClassOfGenericThrowableSubclass(source: FirSourceElement?) {
|
||||
source?.let { report(FirErrors.INNER_CLASS_OF_GENERIC_THROWABLE_SUBCLASS.on(it)) }
|
||||
}
|
||||
}
|
||||
+3
-7
@@ -8,6 +8,8 @@ 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.checkers.isThrowable
|
||||
import org.jetbrains.kotlin.fir.analysis.checkers.throwableClassLikeType
|
||||
import org.jetbrains.kotlin.fir.analysis.diagnostics.DiagnosticReporter
|
||||
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors
|
||||
import org.jetbrains.kotlin.fir.expressions.FirTryExpression
|
||||
@@ -20,9 +22,6 @@ 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
|
||||
@@ -45,10 +44,7 @@ object FirCatchParameterChecker : FirTryExpressionChecker() {
|
||||
}
|
||||
|
||||
if (!coneType.isThrowable(context.session))
|
||||
catchParameter.source?.let { reporter.report(FirErrors.TYPE_MISMATCH.on(it, throwable, coneType), context) }
|
||||
catchParameter.source?.let { reporter.report(FirErrors.TYPE_MISMATCH.on(it, throwableClassLikeType, coneType), context) }
|
||||
}
|
||||
}
|
||||
|
||||
private fun ConeKotlinType.isThrowable(session: FirSession) =
|
||||
throwable.isSupertypeOf(session.typeCheckerContext, this.fullyExpandedType(session))
|
||||
}
|
||||
|
||||
+5
-1
@@ -25,6 +25,10 @@ class DeclarationCheckersDiagnosticComponent(
|
||||
(checkers.memberDeclarationCheckers + checkers.propertyCheckers).check(property, data, reporter)
|
||||
}
|
||||
|
||||
override fun <F : FirClass<F>> visitClass(klass: FirClass<F>, data: CheckerContext) {
|
||||
checkers.classCheckers.check(klass, data, reporter)
|
||||
}
|
||||
|
||||
override fun visitRegularClass(regularClass: FirRegularClass, data: CheckerContext) {
|
||||
checkers.regularClassCheckers.check(regularClass, data, reporter)
|
||||
}
|
||||
@@ -62,7 +66,7 @@ class DeclarationCheckersDiagnosticComponent(
|
||||
}
|
||||
|
||||
override fun visitAnonymousObject(anonymousObject: FirAnonymousObject, data: CheckerContext) {
|
||||
checkers.basicDeclarationCheckers.check(anonymousObject, data, reporter)
|
||||
(checkers.classCheckers + checkers.basicDeclarationCheckers).check(anonymousObject, data, reporter)
|
||||
}
|
||||
|
||||
override fun visitAnonymousInitializer(anonymousInitializer: FirAnonymousInitializer, data: CheckerContext) {
|
||||
|
||||
+10
@@ -71,6 +71,7 @@ import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.EXPOSED_SUPER_INT
|
||||
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.EXPOSED_TYPEALIAS_EXPANDED_TYPE
|
||||
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.EXPOSED_TYPE_PARAMETER_BOUND
|
||||
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.FUNCTION_DECLARATION_WITH_NO_NAME
|
||||
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.GENERIC_THROWABLE_SUBCLASS
|
||||
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.HIDDEN
|
||||
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.ILLEGAL_CONST_EXPRESSION
|
||||
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.ILLEGAL_UNDERSCORE
|
||||
@@ -80,6 +81,7 @@ import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.INAPPLICABLE_LATE
|
||||
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.INCOMPATIBLE_MODIFIERS
|
||||
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.INFERENCE_ERROR
|
||||
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.INITIALIZER_REQUIRED_FOR_DESTRUCTURING_DECLARATION
|
||||
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.INNER_CLASS_OF_GENERIC_THROWABLE_SUBCLASS
|
||||
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.INSTANCE_ACCESS_BEFORE_SUPER_CALL
|
||||
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.INTERFACE_WITH_SUPERCLASS
|
||||
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.INVALID_TYPE_OF_ANNOTATION_MEMBER
|
||||
@@ -378,6 +380,14 @@ class FirDefaultErrorMessages : DefaultErrorMessages.Extension {
|
||||
FQ_NAMES_IN_TYPES,
|
||||
FQ_NAMES_IN_TYPES
|
||||
)
|
||||
map.put(
|
||||
GENERIC_THROWABLE_SUBCLASS,
|
||||
"Subclass of 'Throwable' may not have type parameters"
|
||||
)
|
||||
map.put(
|
||||
INNER_CLASS_OF_GENERIC_THROWABLE_SUBCLASS,
|
||||
"Inner class of generic class extending 'Throwable' is prohibited"
|
||||
)
|
||||
|
||||
// Redeclarations
|
||||
map.put(MANY_COMPANION_OBJECTS, "Only one companion object is allowed per class")
|
||||
|
||||
@@ -139,6 +139,8 @@ object FirErrors {
|
||||
val CATCH_PARAMETER_WITH_DEFAULT_VALUE by error0<FirSourceElement, PsiElement>()
|
||||
val REIFIED_TYPE_IN_CATCH_CLAUSE by error0<FirSourceElement, PsiElement>()
|
||||
val TYPE_PARAMETER_IN_CATCH_CLAUSE by error0<FirSourceElement, PsiElement>()
|
||||
val GENERIC_THROWABLE_SUBCLASS by error0<FirSourceElement, KtTypeParameterList>()
|
||||
val INNER_CLASS_OF_GENERIC_THROWABLE_SUBCLASS by error0<FirSourceElement, KtClassOrObject>(SourceElementPositioningStrategies.DECLARATION_NAME)
|
||||
|
||||
// Overrides
|
||||
val NOTHING_TO_OVERRIDE by error1<FirSourceElement, KtModifierListOwner, FirMemberDeclaration>(SourceElementPositioningStrategies.OVERRIDE_MODIFIER)
|
||||
|
||||
+4
@@ -35,6 +35,10 @@ object CommonDeclarationCheckers : DeclarationCheckers() {
|
||||
FirDestructuringDeclarationChecker,
|
||||
)
|
||||
|
||||
override val classCheckers: Set<FirClassChecker> = setOf(
|
||||
FirThrowableSubclassChecker,
|
||||
)
|
||||
|
||||
override val regularClassCheckers: Set<FirRegularClassChecker> = setOf(
|
||||
FirAnnotationClassDeclarationChecker,
|
||||
FirCommonConstructorDelegationIssuesChecker,
|
||||
|
||||
@@ -2,11 +2,11 @@
|
||||
// See KT-9816, KT-9742
|
||||
|
||||
// Not allowed in Java
|
||||
class ZException<T>(val p: T) : Exception()
|
||||
class ZException<<!GENERIC_THROWABLE_SUBCLASS!>T<!>>(val p: T) : Exception()
|
||||
|
||||
class YException<T>(val p: T): java.lang.RuntimeException()
|
||||
class YException<<!GENERIC_THROWABLE_SUBCLASS!>T<!>>(val p: T): java.lang.RuntimeException()
|
||||
|
||||
class XException<T>(val p: T): Throwable()
|
||||
class XException<<!GENERIC_THROWABLE_SUBCLASS!>T<!>>(val p: T): Throwable()
|
||||
|
||||
fun bar() {
|
||||
try {
|
||||
|
||||
-41
@@ -1,41 +0,0 @@
|
||||
// !LANGUAGE: +ProhibitInnerClassesOfGenericClassExtendingThrowable
|
||||
// !DIAGNOSTICS: -UNUSED_VARIABLE
|
||||
// JAVAC_EXPECTED_FILE
|
||||
|
||||
class OuterGeneric<T> {
|
||||
inner class ErrorInnerExn : Exception()
|
||||
|
||||
inner class InnerA {
|
||||
inner class ErrorInnerExn2 : Exception()
|
||||
}
|
||||
|
||||
class OkNestedExn : Exception()
|
||||
|
||||
val errorAnonymousObjectExn = object : Exception() {}
|
||||
|
||||
fun foo() {
|
||||
class OkLocalExn : Exception()
|
||||
|
||||
val errorAnonymousObjectExn = object : Exception() {}
|
||||
}
|
||||
|
||||
fun <X> genericFoo() {
|
||||
class OkLocalExn : Exception()
|
||||
|
||||
class LocalGeneric<Y> {
|
||||
inner class ErrorInnerExnOfLocalGeneric : Exception()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
class Outer {
|
||||
inner class InnerGeneric<T> {
|
||||
inner class ErrorInnerExn : Exception()
|
||||
}
|
||||
}
|
||||
|
||||
fun <T> genericFoo() {
|
||||
class ErrorLocalExnInGenericFun : Exception()
|
||||
|
||||
val errorkAnonymousObjectExnInGenericFun = object : Exception() {}
|
||||
}
|
||||
+1
@@ -1,3 +1,4 @@
|
||||
// FIR_IDENTICAL
|
||||
// !LANGUAGE: +ProhibitInnerClassesOfGenericClassExtendingThrowable
|
||||
// !DIAGNOSTICS: -UNUSED_VARIABLE
|
||||
// JAVAC_EXPECTED_FILE
|
||||
|
||||
compiler/testData/diagnostics/tests/controlStructures/catchInnerClassesOfGenerics_deprecation.fir.kt
Vendored
+10
-10
@@ -3,39 +3,39 @@
|
||||
// JAVAC_EXPECTED_FILE
|
||||
|
||||
class OuterGeneric<T> {
|
||||
inner class ErrorInnerExn : Exception()
|
||||
inner <!INNER_CLASS_OF_GENERIC_THROWABLE_SUBCLASS!>class ErrorInnerExn<!> : Exception()
|
||||
|
||||
inner class InnerA {
|
||||
inner class ErrorInnerExn2 : Exception()
|
||||
inner <!INNER_CLASS_OF_GENERIC_THROWABLE_SUBCLASS!>class ErrorInnerExn2<!> : Exception()
|
||||
}
|
||||
|
||||
class OkNestedExn : Exception()
|
||||
|
||||
val errorAnonymousObjectExn = object : Exception() {}
|
||||
val errorAnonymousObjectExn = <!INNER_CLASS_OF_GENERIC_THROWABLE_SUBCLASS!>object<!> : Exception() {}
|
||||
|
||||
fun foo() {
|
||||
class OkLocalExn : Exception()
|
||||
<!INNER_CLASS_OF_GENERIC_THROWABLE_SUBCLASS!>class OkLocalExn<!> : Exception()
|
||||
|
||||
val errorAnonymousObjectExn = object : Exception() {}
|
||||
val errorAnonymousObjectExn = <!INNER_CLASS_OF_GENERIC_THROWABLE_SUBCLASS!>object<!> : Exception() {}
|
||||
}
|
||||
|
||||
fun <X> genericFoo() {
|
||||
class OkLocalExn : Exception()
|
||||
<!INNER_CLASS_OF_GENERIC_THROWABLE_SUBCLASS!>class OkLocalExn<!> : Exception()
|
||||
|
||||
class LocalGeneric<Y> {
|
||||
inner class ErrorInnerExnOfLocalGeneric : Exception()
|
||||
inner <!INNER_CLASS_OF_GENERIC_THROWABLE_SUBCLASS!>class ErrorInnerExnOfLocalGeneric<!> : Exception()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
class Outer {
|
||||
inner class InnerGeneric<T> {
|
||||
inner class ErrorInnerExn : Exception()
|
||||
inner <!INNER_CLASS_OF_GENERIC_THROWABLE_SUBCLASS!>class ErrorInnerExn<!> : Exception()
|
||||
}
|
||||
}
|
||||
|
||||
fun <T> genericFoo() {
|
||||
class ErrorLocalExnInGenericFun : Exception()
|
||||
<!INNER_CLASS_OF_GENERIC_THROWABLE_SUBCLASS!>class ErrorLocalExnInGenericFun<!> : Exception()
|
||||
|
||||
val errorkAnonymousObjectExnInGenericFun = object : Exception() {}
|
||||
val errorkAnonymousObjectExnInGenericFun = <!INNER_CLASS_OF_GENERIC_THROWABLE_SUBCLASS!>object<!> : Exception() {}
|
||||
}
|
||||
|
||||
-27
@@ -1,27 +0,0 @@
|
||||
// !LANGUAGE: +ProhibitInnerClassesOfGenericClassExtendingThrowable
|
||||
package test
|
||||
|
||||
var global: Throwable? = null
|
||||
|
||||
fun <T> foo(x: Throwable, z: T, b: (T) -> Unit) {
|
||||
class A(val y : T) : Exception()
|
||||
|
||||
try {
|
||||
throw x
|
||||
} catch (a: A) {
|
||||
b(a.y)
|
||||
} catch (e: Throwable) {
|
||||
global = A(z)
|
||||
}
|
||||
}
|
||||
|
||||
fun main() {
|
||||
foo(RuntimeException(), 1) { throw IllegalStateException() }
|
||||
foo(global!!, "") { it.length } // (*)
|
||||
}
|
||||
|
||||
// (*):
|
||||
//Exception in thread "main" java.lang.ClassCastException: java.lang.Integer cannot be cast to java.lang.String
|
||||
// at test.TestKt$main$2.invoke(test.kt)
|
||||
// at test.TestKt.foo(test.kt:12)
|
||||
// at test.TestKt.main(test.kt:21)
|
||||
compiler/testData/diagnostics/tests/controlStructures/catchingLocalClassesCapturingTypeParameters.kt
Vendored
+1
@@ -1,3 +1,4 @@
|
||||
// FIR_IDENTICAL
|
||||
// !LANGUAGE: +ProhibitInnerClassesOfGenericClassExtendingThrowable
|
||||
package test
|
||||
|
||||
|
||||
Reference in New Issue
Block a user