[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,
|
token,
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
add(FirErrors.ENUM_CLASS_CONSTRUCTOR_CALL) { firDiagnostic ->
|
||||||
|
EnumClassConstructorCallImpl(
|
||||||
|
firDiagnostic as KtPsiDiagnostic,
|
||||||
|
token,
|
||||||
|
)
|
||||||
|
}
|
||||||
add(FirErrors.NOT_AN_ANNOTATION_CLASS) { firDiagnostic ->
|
add(FirErrors.NOT_AN_ANNOTATION_CLASS) { firDiagnostic ->
|
||||||
NotAnAnnotationClassImpl(
|
NotAnAnnotationClassImpl(
|
||||||
firDiagnostic.a,
|
firDiagnostic.a,
|
||||||
|
|||||||
+4
@@ -635,6 +635,10 @@ sealed interface KtFirDiagnostic<PSI : PsiElement> : KtDiagnosticWithPsi<PSI> {
|
|||||||
override val diagnosticClass get() = AnnotationClassConstructorCall::class
|
override val diagnosticClass get() = AnnotationClassConstructorCall::class
|
||||||
}
|
}
|
||||||
|
|
||||||
|
interface EnumClassConstructorCall : KtFirDiagnostic<KtCallExpression> {
|
||||||
|
override val diagnosticClass get() = EnumClassConstructorCall::class
|
||||||
|
}
|
||||||
|
|
||||||
interface NotAnAnnotationClass : KtFirDiagnostic<PsiElement> {
|
interface NotAnAnnotationClass : KtFirDiagnostic<PsiElement> {
|
||||||
override val diagnosticClass get() = NotAnAnnotationClass::class
|
override val diagnosticClass get() = NotAnAnnotationClass::class
|
||||||
val annotationName: String
|
val annotationName: String
|
||||||
|
|||||||
+5
@@ -756,6 +756,11 @@ internal class AnnotationClassConstructorCallImpl(
|
|||||||
token: KtLifetimeToken,
|
token: KtLifetimeToken,
|
||||||
) : KtAbstractFirDiagnostic<KtCallExpression>(firDiagnostic, token), KtFirDiagnostic.AnnotationClassConstructorCall
|
) : KtAbstractFirDiagnostic<KtCallExpression>(firDiagnostic, token), KtFirDiagnostic.AnnotationClassConstructorCall
|
||||||
|
|
||||||
|
internal class EnumClassConstructorCallImpl(
|
||||||
|
firDiagnostic: KtPsiDiagnostic,
|
||||||
|
token: KtLifetimeToken,
|
||||||
|
) : KtAbstractFirDiagnostic<KtCallExpression>(firDiagnostic, token), KtFirDiagnostic.EnumClassConstructorCall
|
||||||
|
|
||||||
internal class NotAnAnnotationClassImpl(
|
internal class NotAnAnnotationClassImpl(
|
||||||
override val annotationName: String,
|
override val annotationName: String,
|
||||||
firDiagnostic: KtPsiDiagnostic,
|
firDiagnostic: KtPsiDiagnostic,
|
||||||
|
|||||||
+1
@@ -290,6 +290,7 @@ object DIAGNOSTICS_LIST : DiagnosticList("FirErrors") {
|
|||||||
val NON_CONST_VAL_USED_IN_CONSTANT_EXPRESSION by error<KtExpression>()
|
val NON_CONST_VAL_USED_IN_CONSTANT_EXPRESSION by error<KtExpression>()
|
||||||
val CYCLE_IN_ANNOTATION_PARAMETER by deprecationError<KtParameter>(LanguageFeature.ProhibitCyclesInAnnotations)
|
val CYCLE_IN_ANNOTATION_PARAMETER by deprecationError<KtParameter>(LanguageFeature.ProhibitCyclesInAnnotations)
|
||||||
val ANNOTATION_CLASS_CONSTRUCTOR_CALL by error<KtCallExpression>()
|
val ANNOTATION_CLASS_CONSTRUCTOR_CALL by error<KtCallExpression>()
|
||||||
|
val ENUM_CLASS_CONSTRUCTOR_CALL by error<KtCallExpression>()
|
||||||
val NOT_AN_ANNOTATION_CLASS by error<PsiElement> {
|
val NOT_AN_ANNOTATION_CLASS by error<PsiElement> {
|
||||||
parameter<String>("annotationName")
|
parameter<String>("annotationName")
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -248,6 +248,7 @@ object FirErrors {
|
|||||||
val NON_CONST_VAL_USED_IN_CONSTANT_EXPRESSION by error0<KtExpression>()
|
val NON_CONST_VAL_USED_IN_CONSTANT_EXPRESSION by error0<KtExpression>()
|
||||||
val CYCLE_IN_ANNOTATION_PARAMETER by deprecationError0<KtParameter>(ProhibitCyclesInAnnotations)
|
val CYCLE_IN_ANNOTATION_PARAMETER by deprecationError0<KtParameter>(ProhibitCyclesInAnnotations)
|
||||||
val ANNOTATION_CLASS_CONSTRUCTOR_CALL by error0<KtCallExpression>()
|
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 NOT_AN_ANNOTATION_CLASS by error1<PsiElement, String>()
|
||||||
val NULLABLE_TYPE_OF_ANNOTATION_MEMBER by error0<KtTypeReference>()
|
val NULLABLE_TYPE_OF_ANNOTATION_MEMBER by error0<KtTypeReference>()
|
||||||
val VAR_ANNOTATION_PARAMETER by error0<KtParameter>(SourceElementPositioningStrategies.VAL_OR_VAR_NODE)
|
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) {
|
override fun check(expression: FirFunctionCall, context: CheckerContext, reporter: DiagnosticReporter) {
|
||||||
val constructorSymbol = expression.calleeReference.toResolvedConstructorSymbol() ?: return
|
val constructorSymbol = expression.calleeReference.toResolvedConstructorSymbol() ?: return
|
||||||
val declarationClass = constructorSymbol.resolvedReturnTypeRef.coneType.toRegularClassSymbol(context.session)
|
val declarationClass = constructorSymbol.resolvedReturnTypeRef.coneType.toRegularClassSymbol(context.session)
|
||||||
|
?: return
|
||||||
|
|
||||||
if (declarationClass != null) {
|
if (declarationClass.classKind == ClassKind.ANNOTATION_CLASS &&
|
||||||
if (declarationClass.classKind == ClassKind.ANNOTATION_CLASS &&
|
context.callsOrAssignments.all { call ->
|
||||||
context.callsOrAssignments.all { call ->
|
call !is FirAnnotation
|
||||||
call !is FirAnnotation
|
} &&
|
||||||
} &&
|
context.containingDeclarations.all { klass ->
|
||||||
context.containingDeclarations.all { klass ->
|
klass !is FirRegularClass || klass.classKind != ClassKind.ANNOTATION_CLASS
|
||||||
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 (!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.ELSE_MISPLACED_IN_WHEN
|
||||||
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.EMPTY_CHARACTER_LITERAL
|
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.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.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
|
||||||
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.EQUALITY_NOT_APPLICABLE_WARNING
|
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(INVALID_TYPE_OF_ANNOTATION_MEMBER, "Invalid type of annotation member")
|
||||||
map.put(VAR_ANNOTATION_PARAMETER, "An annotation parameter cannot be 'var'")
|
map.put(VAR_ANNOTATION_PARAMETER, "An annotation parameter cannot be 'var'")
|
||||||
map.put(ANNOTATION_CLASS_CONSTRUCTOR_CALL, "Annotation class cannot be instantiated")
|
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(NOT_AN_ANNOTATION_CLASS, "Illegal annotation class: {0}", NULLABLE_STRING)
|
||||||
map.put(SUPERTYPES_FOR_ANNOTATION_CLASS, "Annotation class cannot have supertypes")
|
map.put(SUPERTYPES_FOR_ANNOTATION_CLASS, "Annotation class cannot have supertypes")
|
||||||
map.put(
|
map.put(
|
||||||
|
|||||||
@@ -6,5 +6,5 @@ enum class A(val c: Int) {
|
|||||||
|
|
||||||
fun createA(): A {
|
fun createA(): A {
|
||||||
// Error should be here!
|
// 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
|
// KT-7753: attempt to call enum constructor explicitly
|
||||||
enum class A(val c: Int) {
|
enum class A(val c: Int) {
|
||||||
ONE(1),
|
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
|
// KT-7753: attempt to call enum constructor explicitly
|
||||||
enum class A(val c: Int) {
|
enum class A(val c: Int) {
|
||||||
ONE(1) {
|
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
|
// KT-7753: attempt to call enum constructor explicitly
|
||||||
enum class A(val c: Int) {
|
enum class A(val c: Int) {
|
||||||
ONE(1),
|
ONE(1),
|
||||||
|
|||||||
+2
-2
@@ -12,8 +12,8 @@ val test2a = AnnotationClass()
|
|||||||
|
|
||||||
enum class EnumClass { VALUE1, VALUE2 }
|
enum class EnumClass { VALUE1, VALUE2 }
|
||||||
typealias Test3 = EnumClass
|
typealias Test3 = EnumClass
|
||||||
val test3 = <!INVISIBLE_REFERENCE!>Test3<!>()
|
val test3 = <!ENUM_CLASS_CONSTRUCTOR_CALL!><!INVISIBLE_REFERENCE!>Test3<!>()<!>
|
||||||
val test3a = <!INVISIBLE_REFERENCE!>EnumClass<!>()
|
val test3a = <!ENUM_CLASS_CONSTRUCTOR_CALL!><!INVISIBLE_REFERENCE!>EnumClass<!>()<!>
|
||||||
|
|
||||||
sealed class SealedClass
|
sealed class SealedClass
|
||||||
typealias Test4 = SealedClass
|
typealias Test4 = SealedClass
|
||||||
|
|||||||
Reference in New Issue
Block a user