FIR checker: report type parameters on anonymous objects
This commit is contained in:
committed by
TeamCityServer
parent
4d9102f749
commit
a18daa5d62
+1
@@ -500,6 +500,7 @@ object DIAGNOSTICS_LIST : DiagnosticList("FirErrors") {
|
||||
parameter<FirRegularClassSymbol>("outer")
|
||||
}
|
||||
val TYPE_PARAMETERS_IN_OBJECT by error<PsiElement>(PositioningStrategy.TYPE_PARAMETERS_LIST)
|
||||
val TYPE_PARAMETERS_IN_ANONYMOUS_OBJECT by error<PsiElement>(PositioningStrategy.TYPE_PARAMETERS_LIST)
|
||||
val ILLEGAL_PROJECTION_USAGE by error<PsiElement>()
|
||||
val TYPE_PARAMETERS_IN_ENUM by error<PsiElement>()
|
||||
val CONFLICTING_PROJECTION by error<KtTypeProjection>(PositioningStrategy.VARIANCE_MODIFIER) {
|
||||
|
||||
@@ -333,6 +333,7 @@ object FirErrors {
|
||||
val NO_TYPE_ARGUMENTS_ON_RHS by error2<PsiElement, Int, FirClassLikeSymbol<*>>()
|
||||
val OUTER_CLASS_ARGUMENTS_REQUIRED by error1<PsiElement, FirRegularClassSymbol>()
|
||||
val TYPE_PARAMETERS_IN_OBJECT by error0<PsiElement>(SourceElementPositioningStrategies.TYPE_PARAMETERS_LIST)
|
||||
val TYPE_PARAMETERS_IN_ANONYMOUS_OBJECT by error0<PsiElement>(SourceElementPositioningStrategies.TYPE_PARAMETERS_LIST)
|
||||
val ILLEGAL_PROJECTION_USAGE by error0<PsiElement>()
|
||||
val TYPE_PARAMETERS_IN_ENUM by error0<PsiElement>()
|
||||
val CONFLICTING_PROJECTION by error1<KtTypeProjection, ConeKotlinType>(SourceElementPositioningStrategies.VARIANCE_MODIFIER)
|
||||
|
||||
+1
-1
@@ -72,6 +72,7 @@ object CommonDeclarationCheckers : DeclarationCheckers() {
|
||||
FirMemberFunctionsChecker,
|
||||
FirMemberPropertiesChecker,
|
||||
FirImplementationMismatchChecker,
|
||||
FirTypeParametersInObjectChecker,
|
||||
)
|
||||
|
||||
override val regularClassCheckers: Set<FirRegularClassChecker>
|
||||
@@ -89,7 +90,6 @@ object CommonDeclarationCheckers : DeclarationCheckers() {
|
||||
FirMethodOfAnyImplementedInInterfaceChecker,
|
||||
FirDataClassPrimaryConstructorChecker,
|
||||
FirPrimaryConstructorSuperTypeChecker,
|
||||
FirTypeParametersInObjectChecker,
|
||||
FirFunInterfaceDeclarationChecker,
|
||||
FirNestedClassChecker,
|
||||
FirInlineClassDeclarationChecker,
|
||||
|
||||
+21
-4
@@ -5,21 +5,38 @@
|
||||
|
||||
package org.jetbrains.kotlin.fir.analysis.checkers.declaration
|
||||
|
||||
import org.jetbrains.kotlin.KtNodeTypes
|
||||
import org.jetbrains.kotlin.config.LanguageFeature
|
||||
import org.jetbrains.kotlin.descriptors.ClassKind
|
||||
import org.jetbrains.kotlin.fir.analysis.checkers.context.CheckerContext
|
||||
import org.jetbrains.kotlin.fir.analysis.diagnostics.DiagnosticReporter
|
||||
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors
|
||||
import org.jetbrains.kotlin.fir.analysis.diagnostics.reportOn
|
||||
import org.jetbrains.kotlin.fir.analysis.getChild
|
||||
import org.jetbrains.kotlin.fir.declarations.FirAnonymousObject
|
||||
import org.jetbrains.kotlin.fir.declarations.FirClass
|
||||
import org.jetbrains.kotlin.fir.declarations.FirRegularClass
|
||||
import org.jetbrains.kotlin.fir.languageVersionSettings
|
||||
|
||||
object FirTypeParametersInObjectChecker : FirRegularClassChecker() {
|
||||
override fun check(declaration: FirRegularClass, context: CheckerContext, reporter: DiagnosticReporter) {
|
||||
object FirTypeParametersInObjectChecker : FirClassChecker() {
|
||||
override fun check(declaration: FirClass, context: CheckerContext, reporter: DiagnosticReporter) {
|
||||
if (declaration.classKind != ClassKind.OBJECT) {
|
||||
return
|
||||
}
|
||||
|
||||
if (declaration.typeParameters.isNotEmpty()) {
|
||||
reporter.reportOn(declaration.source, FirErrors.TYPE_PARAMETERS_IN_OBJECT, context)
|
||||
when (declaration) {
|
||||
is FirRegularClass -> if (declaration.typeParameters.isNotEmpty()) {
|
||||
reporter.reportOn(declaration.source, FirErrors.TYPE_PARAMETERS_IN_OBJECT, context)
|
||||
}
|
||||
is FirAnonymousObject -> if (declaration.source?.getChild(KtNodeTypes.TYPE_PARAMETER_LIST, depth = 1) != null) {
|
||||
val diagnosticFactory =
|
||||
if (context.session.languageVersionSettings.supportsFeature(LanguageFeature.ProhibitTypeParametersInAnonymousObjects)) {
|
||||
FirErrors.TYPE_PARAMETERS_IN_OBJECT
|
||||
} else {
|
||||
FirErrors.TYPE_PARAMETERS_IN_ANONYMOUS_OBJECT
|
||||
}
|
||||
reporter.reportOn(declaration.source, diagnosticFactory, context)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
+3
@@ -406,6 +406,7 @@ import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.TYPE_ARGUMENTS_NO
|
||||
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.TYPE_ARGUMENTS_REDUNDANT_IN_SUPER_QUALIFIER
|
||||
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.TYPE_CANT_BE_USED_FOR_CONST_VAL
|
||||
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.TYPE_MISMATCH
|
||||
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.TYPE_PARAMETERS_IN_ANONYMOUS_OBJECT
|
||||
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.TYPE_PARAMETERS_IN_ENUM
|
||||
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.TYPE_PARAMETERS_IN_OBJECT
|
||||
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.TYPE_PARAMETERS_NOT_ALLOWED
|
||||
@@ -825,6 +826,8 @@ class FirDefaultErrorMessages {
|
||||
RENDER_CLASS_OR_OBJECT_NAME
|
||||
)
|
||||
map.put(TYPE_PARAMETERS_IN_OBJECT, "Type parameters are not allowed for objects")
|
||||
map.put(TYPE_PARAMETERS_IN_ANONYMOUS_OBJECT, "Type parameters for anonymous objects are deprecated")
|
||||
|
||||
// map.put(ILLEGAL_PROJECTION_USAGE, ...) // &
|
||||
map.put(TYPE_PARAMETERS_IN_ENUM, "Enum class cannot have type parameters")
|
||||
map.put(
|
||||
|
||||
+7
-7
@@ -3,23 +3,23 @@
|
||||
// ISSUE: KT-28999
|
||||
|
||||
fun case_1() {
|
||||
val x = object<T> { } // type of x is <anonymous object><T>
|
||||
val x = object<!TYPE_PARAMETERS_IN_ANONYMOUS_OBJECT!><T><!> { } // type of x is <anonymous object><T>
|
||||
}
|
||||
|
||||
fun case_2() {
|
||||
val x = object<T : Number, K: Comparable<K>> { }
|
||||
val x = object<!TYPE_PARAMETERS_IN_ANONYMOUS_OBJECT!><T : Number, K: Comparable<K>><!> { }
|
||||
}
|
||||
|
||||
fun case_3() {
|
||||
val x = object<T> <!SYNTAX!>where T : Comparable<T><!> { } // ERROR: Where clause is not allowed for objects
|
||||
val x = object<!TYPE_PARAMETERS_IN_ANONYMOUS_OBJECT!><T><!> <!SYNTAX!>where T : Comparable<T><!> { } // ERROR: Where clause is not allowed for objects
|
||||
}
|
||||
|
||||
val x = object<T, K: Comparable<K>> {
|
||||
val x = object<!TYPE_PARAMETERS_IN_ANONYMOUS_OBJECT!><T, K: Comparable<K>><!> {
|
||||
fun test() = 10 as <!UNRESOLVED_REFERENCE!>T<!> // OK
|
||||
}
|
||||
|
||||
fun case_4() {
|
||||
val x = object<T> {
|
||||
val x = object<!TYPE_PARAMETERS_IN_ANONYMOUS_OBJECT!><T><!> {
|
||||
fun test() = 10 as <!UNRESOLVED_REFERENCE!>T<!>
|
||||
}
|
||||
|
||||
@@ -27,7 +27,7 @@ fun case_4() {
|
||||
}
|
||||
|
||||
inline fun <reified T> case_5() {
|
||||
val x = object<T> {
|
||||
val x = object<!TYPE_PARAMETERS_IN_ANONYMOUS_OBJECT!><T><!> {
|
||||
fun test() = 10 as T
|
||||
}
|
||||
|
||||
@@ -38,7 +38,7 @@ inline fun <reified T> case_5() {
|
||||
<!UNRESOLVED_REFERENCE!>println<!>(z)
|
||||
}
|
||||
|
||||
val a = object<A> {
|
||||
val a = object<!TYPE_PARAMETERS_IN_ANONYMOUS_OBJECT!><A><!> {
|
||||
fun test() = 42 as <!UNRESOLVED_REFERENCE!>A<!>
|
||||
}
|
||||
|
||||
|
||||
Vendored
+7
-7
@@ -3,23 +3,23 @@
|
||||
// ISSUE: KT-28999
|
||||
|
||||
fun case_1() {
|
||||
val x = object<T> { } // type of x is <anonymous object><T>
|
||||
val x = object<!TYPE_PARAMETERS_IN_OBJECT!><T><!> { } // type of x is <anonymous object><T>
|
||||
}
|
||||
|
||||
fun case_2() {
|
||||
val x = object<T : Number, K: Comparable<K>> { }
|
||||
val x = object<!TYPE_PARAMETERS_IN_OBJECT!><T : Number, K: Comparable<K>><!> { }
|
||||
}
|
||||
|
||||
fun case_3() {
|
||||
val x = object<T> <!SYNTAX!>where T : Comparable<T><!> { } // ERROR: Where clause is not allowed for objects
|
||||
val x = object<!TYPE_PARAMETERS_IN_OBJECT!><T><!> <!SYNTAX!>where T : Comparable<T><!> { } // ERROR: Where clause is not allowed for objects
|
||||
}
|
||||
|
||||
val x = object<T, K: Comparable<K>> {
|
||||
val x = object<!TYPE_PARAMETERS_IN_OBJECT!><T, K: Comparable<K>><!> {
|
||||
fun test() = 10 as <!UNRESOLVED_REFERENCE!>T<!> // OK
|
||||
}
|
||||
|
||||
fun case_4() {
|
||||
val x = object<T> {
|
||||
val x = object<!TYPE_PARAMETERS_IN_OBJECT!><T><!> {
|
||||
fun test() = 10 as <!UNRESOLVED_REFERENCE!>T<!>
|
||||
}
|
||||
|
||||
@@ -27,7 +27,7 @@ fun case_4() {
|
||||
}
|
||||
|
||||
inline fun <reified T> case_5() {
|
||||
val x = object<T> {
|
||||
val x = object<!TYPE_PARAMETERS_IN_OBJECT!><T><!> {
|
||||
fun test() = 10 as T
|
||||
}
|
||||
|
||||
@@ -38,7 +38,7 @@ inline fun <reified T> case_5() {
|
||||
<!UNRESOLVED_REFERENCE!>println<!>(z)
|
||||
}
|
||||
|
||||
val a = object<A> {
|
||||
val a = object<!TYPE_PARAMETERS_IN_OBJECT!><A><!> {
|
||||
fun test() = 42 as <!UNRESOLVED_REFERENCE!>A<!>
|
||||
}
|
||||
|
||||
|
||||
+6
@@ -1486,6 +1486,12 @@ internal val KT_DIAGNOSTIC_CONVERTER = KtDiagnosticConverterBuilder.buildConvert
|
||||
token,
|
||||
)
|
||||
}
|
||||
add(FirErrors.TYPE_PARAMETERS_IN_ANONYMOUS_OBJECT) { firDiagnostic ->
|
||||
TypeParametersInAnonymousObjectImpl(
|
||||
firDiagnostic as FirPsiDiagnostic,
|
||||
token,
|
||||
)
|
||||
}
|
||||
add(FirErrors.ILLEGAL_PROJECTION_USAGE) { firDiagnostic ->
|
||||
IllegalProjectionUsageImpl(
|
||||
firDiagnostic as FirPsiDiagnostic,
|
||||
|
||||
+4
@@ -1057,6 +1057,10 @@ sealed class KtFirDiagnostic<PSI : PsiElement> : KtDiagnosticWithPsi<PSI> {
|
||||
override val diagnosticClass get() = TypeParametersInObject::class
|
||||
}
|
||||
|
||||
abstract class TypeParametersInAnonymousObject : KtFirDiagnostic<PsiElement>() {
|
||||
override val diagnosticClass get() = TypeParametersInAnonymousObject::class
|
||||
}
|
||||
|
||||
abstract class IllegalProjectionUsage : KtFirDiagnostic<PsiElement>() {
|
||||
override val diagnosticClass get() = IllegalProjectionUsage::class
|
||||
}
|
||||
|
||||
+7
@@ -1691,6 +1691,13 @@ internal class TypeParametersInObjectImpl(
|
||||
override val firDiagnostic: FirPsiDiagnostic by weakRef(firDiagnostic)
|
||||
}
|
||||
|
||||
internal class TypeParametersInAnonymousObjectImpl(
|
||||
firDiagnostic: FirPsiDiagnostic,
|
||||
override val token: ValidityToken,
|
||||
) : KtFirDiagnostic.TypeParametersInAnonymousObject(), KtAbstractFirDiagnostic<PsiElement> {
|
||||
override val firDiagnostic: FirPsiDiagnostic by weakRef(firDiagnostic)
|
||||
}
|
||||
|
||||
internal class IllegalProjectionUsageImpl(
|
||||
firDiagnostic: FirPsiDiagnostic,
|
||||
override val token: ValidityToken,
|
||||
|
||||
Reference in New Issue
Block a user