[FIR] Support ENUM_CLASS_CONSTRUCTOR_CALL
^KT-59411 Fixed
This commit is contained in:
committed by
Space Team
parent
f4ffd479cc
commit
e4246e8f51
+6
@@ -863,6 +863,12 @@ internal val KT_DIAGNOSTIC_CONVERTER = KtDiagnosticConverterBuilder.buildConvert
|
||||
token,
|
||||
)
|
||||
}
|
||||
add(FirErrors.ENUM_CLASS_CONSTRUCTOR_CALL) { firDiagnostic ->
|
||||
EnumClassConstructorCallImpl(
|
||||
firDiagnostic as KtPsiDiagnostic,
|
||||
token,
|
||||
)
|
||||
}
|
||||
add(FirErrors.NOT_AN_ANNOTATION_CLASS) { firDiagnostic ->
|
||||
NotAnAnnotationClassImpl(
|
||||
firDiagnostic.a,
|
||||
|
||||
+4
@@ -635,6 +635,10 @@ sealed interface KtFirDiagnostic<PSI : PsiElement> : KtDiagnosticWithPsi<PSI> {
|
||||
override val diagnosticClass get() = AnnotationClassConstructorCall::class
|
||||
}
|
||||
|
||||
interface EnumClassConstructorCall : KtFirDiagnostic<KtCallExpression> {
|
||||
override val diagnosticClass get() = EnumClassConstructorCall::class
|
||||
}
|
||||
|
||||
interface NotAnAnnotationClass : KtFirDiagnostic<PsiElement> {
|
||||
override val diagnosticClass get() = NotAnAnnotationClass::class
|
||||
val annotationName: String
|
||||
|
||||
+5
@@ -756,6 +756,11 @@ internal class AnnotationClassConstructorCallImpl(
|
||||
token: KtLifetimeToken,
|
||||
) : KtAbstractFirDiagnostic<KtCallExpression>(firDiagnostic, token), KtFirDiagnostic.AnnotationClassConstructorCall
|
||||
|
||||
internal class EnumClassConstructorCallImpl(
|
||||
firDiagnostic: KtPsiDiagnostic,
|
||||
token: KtLifetimeToken,
|
||||
) : KtAbstractFirDiagnostic<KtCallExpression>(firDiagnostic, token), KtFirDiagnostic.EnumClassConstructorCall
|
||||
|
||||
internal class NotAnAnnotationClassImpl(
|
||||
override val annotationName: String,
|
||||
firDiagnostic: KtPsiDiagnostic,
|
||||
|
||||
+1
@@ -290,6 +290,7 @@ object DIAGNOSTICS_LIST : DiagnosticList("FirErrors") {
|
||||
val NON_CONST_VAL_USED_IN_CONSTANT_EXPRESSION by error<KtExpression>()
|
||||
val CYCLE_IN_ANNOTATION_PARAMETER by deprecationError<KtParameter>(LanguageFeature.ProhibitCyclesInAnnotations)
|
||||
val ANNOTATION_CLASS_CONSTRUCTOR_CALL by error<KtCallExpression>()
|
||||
val ENUM_CLASS_CONSTRUCTOR_CALL by error<KtCallExpression>()
|
||||
val NOT_AN_ANNOTATION_CLASS by error<PsiElement> {
|
||||
parameter<String>("annotationName")
|
||||
}
|
||||
|
||||
@@ -248,6 +248,7 @@ object FirErrors {
|
||||
val NON_CONST_VAL_USED_IN_CONSTANT_EXPRESSION by error0<KtExpression>()
|
||||
val CYCLE_IN_ANNOTATION_PARAMETER by deprecationError0<KtParameter>(ProhibitCyclesInAnnotations)
|
||||
val ANNOTATION_CLASS_CONSTRUCTOR_CALL by error0<KtCallExpression>()
|
||||
val ENUM_CLASS_CONSTRUCTOR_CALL by error0<KtCallExpression>()
|
||||
val NOT_AN_ANNOTATION_CLASS by error1<PsiElement, String>()
|
||||
val NULLABLE_TYPE_OF_ANNOTATION_MEMBER by error0<KtTypeReference>()
|
||||
val VAR_ANNOTATION_PARAMETER by error0<KtParameter>(SourceElementPositioningStrategies.VAL_OR_VAR_NODE)
|
||||
|
||||
+21
-14
@@ -22,22 +22,29 @@ object FirConstructorCallChecker : FirFunctionCallChecker() {
|
||||
override fun check(expression: FirFunctionCall, context: CheckerContext, reporter: DiagnosticReporter) {
|
||||
val constructorSymbol = expression.calleeReference.toResolvedConstructorSymbol() ?: return
|
||||
val declarationClass = constructorSymbol.resolvedReturnTypeRef.coneType.toRegularClassSymbol(context.session)
|
||||
?: return
|
||||
|
||||
if (declarationClass != null) {
|
||||
if (declarationClass.classKind == ClassKind.ANNOTATION_CLASS &&
|
||||
context.callsOrAssignments.all { call ->
|
||||
call !is FirAnnotation
|
||||
} &&
|
||||
context.containingDeclarations.all { klass ->
|
||||
klass !is FirRegularClass || klass.classKind != ClassKind.ANNOTATION_CLASS
|
||||
}
|
||||
) {
|
||||
if (!context.languageVersionSettings.supportsFeature(LanguageFeature.InstantiationOfAnnotationClasses)) reporter.reportOn(
|
||||
expression.source,
|
||||
FirErrors.ANNOTATION_CLASS_CONSTRUCTOR_CALL,
|
||||
context
|
||||
)
|
||||
if (declarationClass.classKind == ClassKind.ANNOTATION_CLASS &&
|
||||
context.callsOrAssignments.all { call ->
|
||||
call !is FirAnnotation
|
||||
} &&
|
||||
context.containingDeclarations.all { klass ->
|
||||
klass !is FirRegularClass || klass.classKind != ClassKind.ANNOTATION_CLASS
|
||||
}
|
||||
) {
|
||||
if (!context.languageVersionSettings.supportsFeature(LanguageFeature.InstantiationOfAnnotationClasses)) reporter.reportOn(
|
||||
expression.source,
|
||||
FirErrors.ANNOTATION_CLASS_CONSTRUCTOR_CALL,
|
||||
context
|
||||
)
|
||||
}
|
||||
|
||||
if (declarationClass.classKind == ClassKind.ENUM_CLASS) {
|
||||
reporter.reportOn(
|
||||
expression.source,
|
||||
FirErrors.ENUM_CLASS_CONSTRUCTOR_CALL,
|
||||
context
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
+2
@@ -194,6 +194,7 @@ import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.DYNAMIC_UPPER_BOU
|
||||
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.ELSE_MISPLACED_IN_WHEN
|
||||
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.EMPTY_CHARACTER_LITERAL
|
||||
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.EMPTY_RANGE
|
||||
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.ENUM_CLASS_CONSTRUCTOR_CALL
|
||||
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.ENUM_ENTRY_AS_TYPE
|
||||
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.EQUALITY_NOT_APPLICABLE
|
||||
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.EQUALITY_NOT_APPLICABLE_WARNING
|
||||
@@ -878,6 +879,7 @@ object FirErrorsDefaultMessages : BaseDiagnosticRendererFactory() {
|
||||
map.put(INVALID_TYPE_OF_ANNOTATION_MEMBER, "Invalid type of annotation member")
|
||||
map.put(VAR_ANNOTATION_PARAMETER, "An annotation parameter cannot be 'var'")
|
||||
map.put(ANNOTATION_CLASS_CONSTRUCTOR_CALL, "Annotation class cannot be instantiated")
|
||||
map.put(ENUM_CLASS_CONSTRUCTOR_CALL, "Enum types cannot be instantiated")
|
||||
map.put(NOT_AN_ANNOTATION_CLASS, "Illegal annotation class: {0}", NULLABLE_STRING)
|
||||
map.put(SUPERTYPES_FOR_ANNOTATION_CLASS, "Annotation class cannot have supertypes")
|
||||
map.put(
|
||||
|
||||
@@ -6,5 +6,5 @@ enum class A(val c: Int) {
|
||||
|
||||
fun createA(): A {
|
||||
// Error should be here!
|
||||
return <!INVISIBLE_REFERENCE!>A<!>(10)
|
||||
return <!ENUM_CLASS_CONSTRUCTOR_CALL!><!INVISIBLE_REFERENCE!>A<!>(10)<!>
|
||||
}
|
||||
|
||||
@@ -1,10 +0,0 @@
|
||||
// KT-7753: attempt to call enum constructor explicitly
|
||||
enum class A(val c: Int) {
|
||||
ONE(1),
|
||||
TWO(2);
|
||||
|
||||
fun createA(): A {
|
||||
// Error should be here!
|
||||
return A(10)
|
||||
}
|
||||
}
|
||||
@@ -1,3 +1,4 @@
|
||||
// FIR_IDENTICAL
|
||||
// KT-7753: attempt to call enum constructor explicitly
|
||||
enum class A(val c: Int) {
|
||||
ONE(1),
|
||||
|
||||
@@ -1,15 +0,0 @@
|
||||
// KT-7753: attempt to call enum constructor explicitly
|
||||
enum class A(val c: Int) {
|
||||
ONE(1) {
|
||||
override fun selfOrFriend(): A {
|
||||
return this
|
||||
}
|
||||
},
|
||||
TWO(2) {
|
||||
override fun selfOrFriend(): A {
|
||||
return A(42)
|
||||
}
|
||||
};
|
||||
|
||||
abstract fun selfOrFriend(): A
|
||||
}
|
||||
@@ -1,3 +1,4 @@
|
||||
// FIR_IDENTICAL
|
||||
// KT-7753: attempt to call enum constructor explicitly
|
||||
enum class A(val c: Int) {
|
||||
ONE(1) {
|
||||
|
||||
-13
@@ -1,13 +0,0 @@
|
||||
// KT-7753: attempt to call enum constructor explicitly
|
||||
enum class A(val c: Int) {
|
||||
ONE(1),
|
||||
TWO(2),
|
||||
THREE(3),
|
||||
FORTY_TWO();
|
||||
|
||||
var last: A? = null
|
||||
|
||||
constructor(): this(42) {
|
||||
last = A(13)
|
||||
}
|
||||
}
|
||||
@@ -1,3 +1,4 @@
|
||||
// FIR_IDENTICAL
|
||||
// KT-7753: attempt to call enum constructor explicitly
|
||||
enum class A(val c: Int) {
|
||||
ONE(1),
|
||||
|
||||
+2
-2
@@ -12,8 +12,8 @@ val test2a = AnnotationClass()
|
||||
|
||||
enum class EnumClass { VALUE1, VALUE2 }
|
||||
typealias Test3 = EnumClass
|
||||
val test3 = <!INVISIBLE_REFERENCE!>Test3<!>()
|
||||
val test3a = <!INVISIBLE_REFERENCE!>EnumClass<!>()
|
||||
val test3 = <!ENUM_CLASS_CONSTRUCTOR_CALL!><!INVISIBLE_REFERENCE!>Test3<!>()<!>
|
||||
val test3a = <!ENUM_CLASS_CONSTRUCTOR_CALL!><!INVISIBLE_REFERENCE!>EnumClass<!>()<!>
|
||||
|
||||
sealed class SealedClass
|
||||
typealias Test4 = SealedClass
|
||||
|
||||
Reference in New Issue
Block a user