[FIR] Add UPPER_BOUND_IS_EXTENSION_FUNCTION_TYPE diagnostic

This commit is contained in:
Andrey Zinovyev
2021-04-05 17:15:32 +03:00
committed by GitHub
parent 451fc8e9df
commit e10df86037
8 changed files with 30 additions and 4 deletions
@@ -294,6 +294,8 @@ object DIAGNOSTICS_LIST : DiagnosticList() {
val FINAL_UPPER_BOUND by warning<FirSourceElement, PsiElement> {
parameter<ConeKotlinType>("type")
}
val UPPER_BOUND_IS_EXTENSION_FUNCTION_TYPE by error<FirSourceElement, PsiElement>()
}
val REFLECTION by object : DiagnosticGroup("Reflection") {
@@ -217,6 +217,7 @@ object FirErrors {
val KCLASS_WITH_NULLABLE_TYPE_PARAMETER_IN_SIGNATURE by error1<FirSourceElement, KtNamedDeclaration, FirTypeParameterSymbol>(SourceElementPositioningStrategies.DECLARATION_NAME)
val TYPE_PARAMETER_AS_REIFIED by error1<FirSourceElement, PsiElement, FirTypeParameterSymbol>()
val FINAL_UPPER_BOUND by warning1<FirSourceElement, PsiElement, ConeKotlinType>()
val UPPER_BOUND_IS_EXTENSION_FUNCTION_TYPE by error0<FirSourceElement, PsiElement>()
// Reflection
val EXTENSION_IN_CLASS_REFERENCE_NOT_ALLOWED by error1<FirSourceElement, KtExpression, FirCallableDeclaration<*>>(SourceElementPositioningStrategies.REFERENCE_BY_QUALIFIED)
@@ -12,6 +12,7 @@ import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors
import org.jetbrains.kotlin.fir.analysis.diagnostics.reportOn
import org.jetbrains.kotlin.fir.declarations.*
import org.jetbrains.kotlin.fir.types.coneType
import org.jetbrains.kotlin.fir.types.isExtensionFunctionType
object FirTypeParameterBoundsChecker : FirTypeParameterChecker() {
@@ -25,6 +26,9 @@ object FirTypeParameterBoundsChecker : FirTypeParameterChecker() {
if (!bound.coneType.canHaveSubtypes(context.session)) {
reporter.reportOn(bound.source, FirErrors.FINAL_UPPER_BOUND, bound.coneType, context)
}
if (bound.isExtensionFunctionType(context.session)) {
reporter.reportOn(bound.source, FirErrors.UPPER_BOUND_IS_EXTENSION_FUNCTION_TYPE, context)
}
}
}
}
@@ -220,6 +220,7 @@ import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.UNSAFE_OPERATOR_C
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.UNSUPPORTED
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.UNSUPPORTED_FEATURE
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.UNUSED_VARIABLE
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.UPPER_BOUND_IS_EXTENSION_FUNCTION_TYPE
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.UPPER_BOUND_VIOLATED
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.USELESS_VARARG_ON_PARAMETER
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.VALUE_CLASS_CANNOT_BE_CLONEABLE
@@ -447,6 +448,7 @@ class FirDefaultErrorMessages : DefaultErrorMessages.Extension {
"''{0}'' is a final type, and thus a value of the type parameter is predetermined",
RENDER_TYPE
)
map.put(UPPER_BOUND_IS_EXTENSION_FUNCTION_TYPE, "Extension function type can not be used as an upper bound")
// Reflection
map.put(
@@ -1,7 +1,7 @@
fun <T: Int.() -> String> foo() {}
fun <T: <!UPPER_BOUND_IS_EXTENSION_FUNCTION_TYPE!>Int.() -> String<!>> foo() {}
val <T: Int.() -> String> bar = fun (x: Int): String { return x.toString() }
val <T: <!UPPER_BOUND_IS_EXTENSION_FUNCTION_TYPE!>Int.() -> String<!>> bar = fun (x: Int): String { return x.toString() }
class A<T> where T : Double.(Int) -> Unit
class A<T> where T : <!UPPER_BOUND_IS_EXTENSION_FUNCTION_TYPE!>Double.(Int) -> Unit<!>
interface B<T, U : T.() -> Unit>
interface B<T, U : <!UPPER_BOUND_IS_EXTENSION_FUNCTION_TYPE!>T.() -> Unit<!>>
@@ -895,6 +895,12 @@ internal val KT_DIAGNOSTIC_CONVERTER = KtDiagnosticConverterBuilder.buildConvert
token,
)
}
add(FirErrors.UPPER_BOUND_IS_EXTENSION_FUNCTION_TYPE) { firDiagnostic ->
UpperBoundIsExtensionFunctionTypeImpl(
firDiagnostic as FirPsiDiagnostic<*>,
token,
)
}
add(FirErrors.EXTENSION_IN_CLASS_REFERENCE_NOT_ALLOWED) { firDiagnostic ->
ExtensionInClassReferenceNotAllowedImpl(
firSymbolBuilder.callableBuilder.buildCallableSymbol(firDiagnostic.a as FirCallableDeclaration),
@@ -638,6 +638,10 @@ sealed class KtFirDiagnostic<PSI: PsiElement> : KtDiagnosticWithPsi<PSI> {
abstract val type: KtType
}
abstract class UpperBoundIsExtensionFunctionType : KtFirDiagnostic<PsiElement>() {
override val diagnosticClass get() = UpperBoundIsExtensionFunctionType::class
}
abstract class ExtensionInClassReferenceNotAllowed : KtFirDiagnostic<KtExpression>() {
override val diagnosticClass get() = ExtensionInClassReferenceNotAllowed::class
abstract val referencedDeclaration: KtCallableSymbol
@@ -1026,6 +1026,13 @@ internal class FinalUpperBoundImpl(
override val firDiagnostic: FirPsiDiagnostic<*> by weakRef(firDiagnostic)
}
internal class UpperBoundIsExtensionFunctionTypeImpl(
firDiagnostic: FirPsiDiagnostic<*>,
override val token: ValidityToken,
) : KtFirDiagnostic.UpperBoundIsExtensionFunctionType(), KtAbstractFirDiagnostic<PsiElement> {
override val firDiagnostic: FirPsiDiagnostic<*> by weakRef(firDiagnostic)
}
internal class ExtensionInClassReferenceNotAllowedImpl(
override val referencedDeclaration: KtCallableSymbol,
firDiagnostic: FirPsiDiagnostic<*>,