FIR: fix false positives of INNER_CLASS_OF_GENERIC_THROWABLE_SUBCLASS

#KT-49129 Fixed
This commit is contained in:
Mikhail Glukhikh
2021-10-12 15:27:10 +03:00
committed by TeamCityServer
parent e3b92fe5f3
commit 31db76da56
6 changed files with 108 additions and 5 deletions
@@ -5075,6 +5075,12 @@ public class DiagnosisCompilerFirTestdataTestGenerated extends AbstractDiagnosis
runTest("compiler/fir/analysis-tests/testData/resolveWithStdlib/intellij/FieldVsSyntheticAccessor.kt");
}
@Test
@TestMetadata("InnerClassOfThrowableOnObject.kt")
public void testInnerClassOfThrowableOnObject() throws Exception {
runTest("compiler/fir/analysis-tests/testData/resolveWithStdlib/intellij/InnerClassOfThrowableOnObject.kt");
}
@Test
@TestMetadata("IntersectionWithJavaString.kt")
public void testIntersectionWithJavaString() throws Exception {
@@ -0,0 +1,58 @@
FILE: InnerClassOfThrowableOnObject.kt
public final class Generic<T> : R|kotlin/Any| {
public constructor<T>(): R|Generic<T>| {
super<R|kotlin/Any|>()
}
public final companion object Companion : R|kotlin/Any| {
private constructor(): R|Generic.Companion| {
super<R|kotlin/Any|>()
}
public final fun foo(): R|kotlin/Unit| {
lval x: R|<anonymous>| = object : R|kotlin/Exception| {
private constructor(): R|<anonymous>| {
super<R|kotlin/Exception|>()
}
}
}
}
public final class Nested : R|kotlin/Any| {
public constructor(): R|Generic.Nested| {
super<R|kotlin/Any|>()
}
public final fun foo(): R|kotlin/Unit| {
lval x: R|<anonymous>| = object : R|kotlin/Exception| {
private constructor(): R|<anonymous>| {
super<R|kotlin/Exception|>()
}
}
}
}
public final inner class Inner<T> : R|kotlin/Any| {
public Generic<T>.constructor(): R|Generic.Inner<T>| {
super<R|kotlin/Any|>()
}
public final fun foo(): R|kotlin/Unit| {
lval x: R|<anonymous><T>| = object : R|kotlin/Exception| {
private constructor(): R|<anonymous><T>| {
super<R|kotlin/Exception|>()
}
}
}
}
}
@@ -0,0 +1,19 @@
// See KT-49129
class Generic<T> {
companion object {
fun foo() {
val x = object : Exception() {}
}
}
class Nested {
fun foo() {
val x = object : Exception() {}
}
}
inner class Inner {
fun foo() {
val x = <!INNER_CLASS_OF_GENERIC_THROWABLE_SUBCLASS!>object<!> : Exception() {}
}
}
}
@@ -5075,6 +5075,12 @@ public class FirDiagnosticTestGenerated extends AbstractFirDiagnosticTest {
runTest("compiler/fir/analysis-tests/testData/resolveWithStdlib/intellij/FieldVsSyntheticAccessor.kt");
}
@Test
@TestMetadata("InnerClassOfThrowableOnObject.kt")
public void testInnerClassOfThrowableOnObject() throws Exception {
runTest("compiler/fir/analysis-tests/testData/resolveWithStdlib/intellij/InnerClassOfThrowableOnObject.kt");
}
@Test
@TestMetadata("IntersectionWithJavaString.kt")
public void testIntersectionWithJavaString() throws Exception {
@@ -5075,6 +5075,12 @@ public class FirDiagnosticsWithLightTreeTestGenerated extends AbstractFirDiagnos
runTest("compiler/fir/analysis-tests/testData/resolveWithStdlib/intellij/FieldVsSyntheticAccessor.kt");
}
@Test
@TestMetadata("InnerClassOfThrowableOnObject.kt")
public void testInnerClassOfThrowableOnObject() throws Exception {
runTest("compiler/fir/analysis-tests/testData/resolveWithStdlib/intellij/InnerClassOfThrowableOnObject.kt");
}
@Test
@TestMetadata("IntersectionWithJavaString.kt")
public void testIntersectionWithJavaString() throws Exception {
@@ -13,6 +13,7 @@ import org.jetbrains.kotlin.fir.analysis.diagnostics.reportOn
import org.jetbrains.kotlin.fir.declarations.*
import org.jetbrains.kotlin.fir.declarations.utils.classId
import org.jetbrains.kotlin.fir.declarations.utils.isInner
import org.jetbrains.kotlin.fir.declarations.utils.isLocal
import org.jetbrains.kotlin.fir.declarations.utils.superConeTypes
import org.jetbrains.kotlin.fir.types.ConeClassErrorType
@@ -38,9 +39,16 @@ object FirThrowableSubclassChecker : FirClassChecker() {
private fun FirClass.hasThrowableSupertype(context: CheckerContext) =
superConeTypes.any { it !is ConeClassErrorType && it.isSubtypeOfThrowable(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 FirClass.hasGenericOuterDeclaration(context: CheckerContext): Boolean {
if (!classId.isLocal) return false
for (containingDeclaration in context.containingDeclarations.asReversed()) {
if (containingDeclaration is FirTypeParameterRefsOwner && containingDeclaration.typeParameters.isNotEmpty()) {
return true
}
if (containingDeclaration is FirRegularClass && !containingDeclaration.isLocal && !containingDeclaration.isInner) {
return false
}
}
return false
}
}