[FIR] Make reporting of local class diagnostics more consistent with K1
It would be nice to report more appropriate diagnostics at the corresponding places, but right now it's more important to fix greenness-redness problems. Plus, this is already how K1 works. ^KT-59900 Fixed
This commit is contained in:
committed by
Space Team
parent
9b114335fb
commit
0d19942d2c
+1
-1
@@ -1,7 +1,7 @@
|
||||
// !DUMP_CFG
|
||||
|
||||
val x = object {
|
||||
class Nested {
|
||||
<!NESTED_CLASS_NOT_ALLOWED!>class Nested<!> {
|
||||
fun foo() {}
|
||||
}
|
||||
}
|
||||
|
||||
+4
-4
@@ -8,16 +8,16 @@ object A {
|
||||
val a = object : Any() {
|
||||
<!LOCAL_OBJECT_NOT_ALLOWED!>object D<!> {
|
||||
<!LOCAL_OBJECT_NOT_ALLOWED!>object G<!>
|
||||
<!LOCAL_INTERFACE_NOT_ALLOWED, NESTED_CLASS_NOT_ALLOWED!>interface Z<!>
|
||||
<!NESTED_CLASS_NOT_ALLOWED!>interface Z<!>
|
||||
}
|
||||
|
||||
<!LOCAL_INTERFACE_NOT_ALLOWED!>interface Y<!>
|
||||
<!NESTED_CLASS_NOT_ALLOWED!>interface Y<!>
|
||||
}
|
||||
|
||||
fun b() {
|
||||
<!LOCAL_OBJECT_NOT_ALLOWED!>object E<!> {
|
||||
<!LOCAL_OBJECT_NOT_ALLOWED!>object F<!>
|
||||
<!LOCAL_INTERFACE_NOT_ALLOWED, NESTED_CLASS_NOT_ALLOWED!>interface M<!>
|
||||
<!NESTED_CLASS_NOT_ALLOWED!>interface M<!>
|
||||
}
|
||||
|
||||
<!LOCAL_INTERFACE_NOT_ALLOWED!>interface N<!>
|
||||
@@ -25,7 +25,7 @@ object A {
|
||||
val c = object : Any() {
|
||||
val t = "test"
|
||||
|
||||
<!LOCAL_INTERFACE_NOT_ALLOWED!>interface U<!>
|
||||
<!NESTED_CLASS_NOT_ALLOWED!>interface U<!>
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
+4
-1
@@ -11,6 +11,7 @@ import org.jetbrains.kotlin.fir.analysis.checkers.context.CheckerContext
|
||||
import org.jetbrains.kotlin.diagnostics.DiagnosticReporter
|
||||
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors
|
||||
import org.jetbrains.kotlin.diagnostics.reportOn
|
||||
import org.jetbrains.kotlin.fir.declarations.FirClass
|
||||
import org.jetbrains.kotlin.fir.declarations.FirRegularClass
|
||||
import org.jetbrains.kotlin.fir.declarations.utils.isCompanion
|
||||
import org.jetbrains.kotlin.fir.declarations.utils.visibility
|
||||
@@ -21,10 +22,12 @@ object FirLocalEntityNotAllowedChecker : FirRegularClassChecker() {
|
||||
return
|
||||
}
|
||||
|
||||
val container = context.containingDeclarations.lastOrNull()
|
||||
|
||||
when {
|
||||
declaration.classKind == ClassKind.OBJECT && !declaration.isCompanion ->
|
||||
reporter.reportOn(declaration.source, FirErrors.LOCAL_OBJECT_NOT_ALLOWED, declaration.name, context)
|
||||
declaration.classKind == ClassKind.INTERFACE ->
|
||||
declaration.classKind == ClassKind.INTERFACE && container !is FirClass ->
|
||||
reporter.reportOn(declaration.source, FirErrors.LOCAL_INTERFACE_NOT_ALLOWED, declaration.name, context)
|
||||
else -> {
|
||||
}
|
||||
|
||||
+17
-17
@@ -6,12 +6,13 @@
|
||||
package org.jetbrains.kotlin.fir.analysis.checkers.declaration
|
||||
|
||||
import org.jetbrains.kotlin.descriptors.ClassKind
|
||||
import org.jetbrains.kotlin.descriptors.EffectiveVisibility
|
||||
import org.jetbrains.kotlin.fir.analysis.checkers.context.CheckerContext
|
||||
import org.jetbrains.kotlin.diagnostics.DiagnosticReporter
|
||||
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.NESTED_CLASS_NOT_ALLOWED
|
||||
import org.jetbrains.kotlin.diagnostics.reportOn
|
||||
import org.jetbrains.kotlin.fir.declarations.FirClass
|
||||
import org.jetbrains.kotlin.fir.declarations.FirRegularClass
|
||||
import org.jetbrains.kotlin.fir.declarations.*
|
||||
import org.jetbrains.kotlin.fir.declarations.utils.effectiveVisibility
|
||||
import org.jetbrains.kotlin.fir.declarations.utils.isCompanion
|
||||
import org.jetbrains.kotlin.fir.declarations.utils.isInner
|
||||
import org.jetbrains.kotlin.fir.declarations.utils.isLocal
|
||||
@@ -22,25 +23,24 @@ object FirNestedClassChecker : FirRegularClassChecker() {
|
||||
override fun check(declaration: FirRegularClass, context: CheckerContext, reporter: DiagnosticReporter) {
|
||||
// Local enums / objects / companion objects are handled with different diagnostic codes.
|
||||
if ((declaration.classKind.isSingleton || declaration.classKind == ClassKind.ENUM_CLASS) && declaration.isLocal) return
|
||||
val containingDeclaration = context.containingDeclarations.lastOrNull() ?: return
|
||||
val containingDeclaration = context.containingDeclarations.lastOrNull() as? FirClass ?: return
|
||||
|
||||
when (containingDeclaration) {
|
||||
is FirRegularClass -> {
|
||||
if (!declaration.isInner && (containingDeclaration.isInner || containingDeclaration.isLocal)) {
|
||||
reporter.reportOn(declaration.source, NESTED_CLASS_NOT_ALLOWED, declaration.description, context)
|
||||
}
|
||||
}
|
||||
is FirClass -> {
|
||||
// Since 1.3, enum entries can contain inner classes only.
|
||||
// Companion objects are reported with code WRONG_MODIFIER_CONTAINING_DECLARATION instead
|
||||
if (containingDeclaration.classKind == ClassKind.ENUM_ENTRY && !declaration.isInner && !declaration.isCompanion) {
|
||||
reporter.reportOn(declaration.source, NESTED_CLASS_NOT_ALLOWED, declaration.description, context)
|
||||
}
|
||||
}
|
||||
else -> {}
|
||||
// Since 1.3, enum entries can contain inner classes only.
|
||||
// Companion objects are reported with code WRONG_MODIFIER_CONTAINING_DECLARATION instead
|
||||
if (containingDeclaration.classKind == ClassKind.ENUM_ENTRY && !declaration.isInner && !declaration.isCompanion) {
|
||||
reporter.reportOn(declaration.source, NESTED_CLASS_NOT_ALLOWED, declaration.description, context)
|
||||
return
|
||||
}
|
||||
|
||||
val containerIsLocal = containingDeclaration.effectiveVisibility == EffectiveVisibility.Local
|
||||
|
||||
if (!declaration.isInner && (containingDeclaration.isInner || containerIsLocal || context.isInsideAnonymousObject)) {
|
||||
reporter.reportOn(declaration.source, NESTED_CLASS_NOT_ALLOWED, declaration.description, context)
|
||||
}
|
||||
}
|
||||
|
||||
private val CheckerContext.isInsideAnonymousObject get() = containingDeclarations.any { it is FirAnonymousObject }
|
||||
|
||||
// Note: here we don't differentiate anonymous object like in FE1.0
|
||||
// (org.jetbrains.kotlin.resolve.ModifiersChecker.DetailedClassKind) because this case has been ruled out in the first place.
|
||||
private val FirRegularClass.description: String
|
||||
|
||||
+1
-1
@@ -6,7 +6,7 @@ enum class Enum {
|
||||
|
||||
<!NESTED_CLASS_NOT_ALLOWED!>class TestNested<!>
|
||||
|
||||
<!LOCAL_INTERFACE_NOT_ALLOWED, NESTED_CLASS_NOT_ALLOWED!>interface TestInterface<!>
|
||||
<!NESTED_CLASS_NOT_ALLOWED!>interface TestInterface<!>
|
||||
|
||||
<!LOCAL_OBJECT_NOT_ALLOWED!>object TestObject<!>
|
||||
|
||||
|
||||
+1
-1
@@ -6,7 +6,7 @@ enum class Enum {
|
||||
|
||||
<!NESTED_CLASS_NOT_ALLOWED!>class TestNested<!>
|
||||
|
||||
<!LOCAL_INTERFACE_NOT_ALLOWED, NESTED_CLASS_NOT_ALLOWED!>interface TestInterface<!>
|
||||
<!NESTED_CLASS_NOT_ALLOWED!>interface TestInterface<!>
|
||||
|
||||
<!LOCAL_OBJECT_NOT_ALLOWED!>object TestObject<!>
|
||||
|
||||
|
||||
@@ -1,8 +0,0 @@
|
||||
// KT-6026 Exception on instantiating a nested class in an anonymous object
|
||||
|
||||
val oo = object {
|
||||
// Forbidden in KT-13510
|
||||
class Nested
|
||||
|
||||
fun f1() = Nested(<!TOO_MANY_ARGUMENTS!>11<!>)
|
||||
}
|
||||
@@ -1,3 +1,4 @@
|
||||
// FIR_IDENTICAL
|
||||
// KT-6026 Exception on instantiating a nested class in an anonymous object
|
||||
|
||||
val oo = object {
|
||||
|
||||
@@ -1,14 +0,0 @@
|
||||
// !DIAGNOSTICS: -UNUSED_VARIABLE
|
||||
|
||||
fun foo() {
|
||||
<!LOCAL_INTERFACE_NOT_ALLOWED!>interface a<!> {}
|
||||
val b = object {
|
||||
<!LOCAL_INTERFACE_NOT_ALLOWED!>interface c<!> {}
|
||||
}
|
||||
class A {
|
||||
<!LOCAL_INTERFACE_NOT_ALLOWED, NESTED_CLASS_NOT_ALLOWED!>interface d<!> {}
|
||||
}
|
||||
val f = {
|
||||
<!LOCAL_INTERFACE_NOT_ALLOWED!>interface e<!> {}
|
||||
}
|
||||
}
|
||||
@@ -1,3 +1,4 @@
|
||||
// FIR_IDENTICAL
|
||||
// !DIAGNOSTICS: -UNUSED_VARIABLE
|
||||
|
||||
fun foo() {
|
||||
|
||||
-11
@@ -1,11 +0,0 @@
|
||||
class X {
|
||||
val foo = object {
|
||||
class Foo
|
||||
}
|
||||
|
||||
fun test() {
|
||||
object {
|
||||
class Foo
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,3 +1,4 @@
|
||||
// FIR_IDENTICAL
|
||||
class X {
|
||||
val foo = object {
|
||||
<!NESTED_CLASS_NOT_ALLOWED!>class Foo<!>
|
||||
|
||||
Reference in New Issue
Block a user