FIR checker: report non-typed LHS of callable references

This commit is contained in:
Jinseong Jeon
2021-03-04 09:44:34 -08:00
committed by Mikhail Glukhikh
parent 329be4f906
commit 33c5b49632
20 changed files with 195 additions and 39 deletions
@@ -8,6 +8,7 @@ package org.jetbrains.kotlin.fir.checkers.generator.diagnostics
import com.intellij.psi.PsiElement
import com.intellij.psi.PsiTypeElement
import org.jetbrains.kotlin.contracts.description.EventOccurrencesRange
import org.jetbrains.kotlin.descriptors.TypeParameterDescriptor
import org.jetbrains.kotlin.descriptors.Visibility
import org.jetbrains.kotlin.diagnostics.WhenMissingCase
import org.jetbrains.kotlin.resolve.ForbiddenNamedArgumentsTarget
@@ -248,6 +249,8 @@ object DIAGNOSTICS_LIST : DiagnosticList() {
}
val REFLECTION by object : DiagnosticGroup("Reflection") {
val CALLABLE_REFERENCE_LHS_NOT_A_CLASS by error<FirSourceElement, KtExpression>()
val CLASS_LITERAL_LHS_NOT_A_CLASS by error<FirSourceElement, KtExpression>()
val NULLABLE_TYPE_IN_CLASS_LITERAL_LHS by error<FirSourceElement, KtExpression>()
}
@@ -448,6 +451,15 @@ object DIAGNOSTICS_LIST : DiagnosticList() {
val INVALID_IF_AS_EXPRESSION by error<FirSourceElement, KtIfExpression>(PositioningStrategy.IF_EXPRESSION)
}
val CONTEXT_TRACKING by object : DiagnosticGroup("Context tracking") {
val TYPE_PARAMETER_IS_NOT_AN_EXPRESSION by error<FirSourceElement, KtSimpleNameExpression> {
parameter<FirTypeParameterSymbol>("typeParameter")
}
val TYPE_PARAMETER_ON_LHS_OF_DOT by error<FirSourceElement, KtSimpleNameExpression> {
parameter<FirTypeParameterSymbol>("typeParameter")
}
}
val FUNCTION_CONTRACTS by object : DiagnosticGroup("Function contracts") {
val ERROR_IN_CONTRACT_DESCRIPTION by error<FirSourceElement, KtElement>(PositioningStrategy.SELECTOR_BY_QUALIFIED) {
parameter<String>("reason")
@@ -195,6 +195,7 @@ object FirErrors {
val INNER_CLASS_OF_GENERIC_THROWABLE_SUBCLASS by error0<FirSourceElement, KtClassOrObject>(SourceElementPositioningStrategies.DECLARATION_NAME)
// Reflection
val CALLABLE_REFERENCE_LHS_NOT_A_CLASS by error0<FirSourceElement, KtExpression>()
val CLASS_LITERAL_LHS_NOT_A_CLASS by error0<FirSourceElement, KtExpression>()
val NULLABLE_TYPE_IN_CLASS_LITERAL_LHS by error0<FirSourceElement, KtExpression>()
@@ -284,6 +285,10 @@ object FirErrors {
val NO_ELSE_IN_WHEN by error1<FirSourceElement, KtWhenExpression, List<WhenMissingCase>>(SourceElementPositioningStrategies.WHEN_EXPRESSION)
val INVALID_IF_AS_EXPRESSION by error0<FirSourceElement, KtIfExpression>(SourceElementPositioningStrategies.IF_EXPRESSION)
// Context tracking
val TYPE_PARAMETER_IS_NOT_AN_EXPRESSION by error1<FirSourceElement, KtSimpleNameExpression, FirTypeParameterSymbol>()
val TYPE_PARAMETER_ON_LHS_OF_DOT by error1<FirSourceElement, KtSimpleNameExpression, FirTypeParameterSymbol>()
// Function contracts
val ERROR_IN_CONTRACT_DESCRIPTION by error1<FirSourceElement, KtElement, String>(SourceElementPositioningStrategies.SELECTOR_BY_QUALIFIED)
@@ -0,0 +1,58 @@
/*
* Copyright 2010-2021 JetBrains s.r.o. and Kotlin Programming Language contributors.
* Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
*/
package org.jetbrains.kotlin.fir.analysis.checkers.expression
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.expressions.FirCallableReferenceAccess
import org.jetbrains.kotlin.fir.expressions.FirQualifiedAccessExpression
import org.jetbrains.kotlin.fir.expressions.FirResolvedReifiedParameterReference
import org.jetbrains.kotlin.fir.resolve.diagnostics.ConeTypeParameterInQualifiedAccess
import org.jetbrains.kotlin.fir.types.FirErrorTypeRef
import org.jetbrains.kotlin.fir.types.FirTypeRef
object FirTypeParameterInQualifiedAccessChecker: FirQualifiedAccessChecker() {
override fun check(expression: FirQualifiedAccessExpression, context: CheckerContext, reporter: DiagnosticReporter) {
checkExplicitReceiver(expression, context, reporter)
checkExpressionItself(expression, context, reporter)
}
private fun checkExpressionItself(
expression: FirQualifiedAccessExpression,
context: CheckerContext,
reporter: DiagnosticReporter
) {
// Make sure the current qualified access is not part of another qualified access.
// E.g., for `T::toString`, which is a callable reference (a subtype of qualified access), type parameter T is checked once as an
// explicit receiver (or LHS). When we visit `T` (as a qualified access), we should not regard it as an expression here.
if (context.qualifiedAccesses.size > 1) return
val diagnostic = expression.typeRef.coneTypeParameterInQualifiedAccess ?: return
val source = expression.source ?: return
reporter.reportOn(source, FirErrors.TYPE_PARAMETER_IS_NOT_AN_EXPRESSION, diagnostic.symbol, context)
}
private fun checkExplicitReceiver(
expression: FirQualifiedAccessExpression,
context: CheckerContext,
reporter: DiagnosticReporter
) {
val typeParameterSymbol =
expression.explicitReceiver?.typeRef?.coneTypeParameterInQualifiedAccess?.symbol
?: (expression.explicitReceiver as? FirResolvedReifiedParameterReference)?.symbol
?: return
if (expression is FirCallableReferenceAccess) {
reporter.reportOn(expression.source, FirErrors.CALLABLE_REFERENCE_LHS_NOT_A_CLASS, context)
} else {
reporter.reportOn(expression.explicitReceiver?.source, FirErrors.TYPE_PARAMETER_ON_LHS_OF_DOT, typeParameterSymbol, context)
}
}
private val FirTypeRef.coneTypeParameterInQualifiedAccess: ConeTypeParameterInQualifiedAccess?
get() = (this as? FirErrorTypeRef)?.diagnostic as? ConeTypeParameterInQualifiedAccess
}
@@ -39,6 +39,7 @@ import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.ASSIGNED_VALUE_IS
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.ASSIGN_OPERATOR_AMBIGUITY
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.BACKING_FIELD_IN_INTERFACE
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.BREAK_OR_CONTINUE_OUTSIDE_A_LOOP
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.CALLABLE_REFERENCE_LHS_NOT_A_CLASS
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.CANNOT_CHANGE_ACCESS_PRIVILEGE
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.CANNOT_WEAKEN_ACCESS_PRIVILEGE
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.CAN_BE_REPLACED_WITH_OPERATOR_ASSIGNMENT
@@ -185,6 +186,8 @@ import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.TYPE_PARAMETERS_I
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.TYPE_PARAMETERS_IN_OBJECT
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.TYPE_PARAMETER_AS_SUPERTYPE
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.TYPE_PARAMETER_IN_CATCH_CLAUSE
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.TYPE_PARAMETER_IS_NOT_AN_EXPRESSION
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.TYPE_PARAMETER_ON_LHS_OF_DOT
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.UNINITIALIZED_VARIABLE
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.UNNECESSARY_LATEINIT
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.UNRESOLVED_LABEL
@@ -391,6 +394,8 @@ class FirDefaultErrorMessages : DefaultErrorMessages.Extension {
map.put(TYPE_PARAMETER_IN_CATCH_CLAUSE, "Type parameter is forbidden for catch parameter")
// Reflection
map.put(CALLABLE_REFERENCE_LHS_NOT_A_CLASS, "Left-hand side of a callable reference cannot be a type parameter")
map.put(CLASS_LITERAL_LHS_NOT_A_CLASS, "Only classes are allowed on the left hand side of a class literal")
map.put(NULLABLE_TYPE_IN_CLASS_LITERAL_LHS, "Type in a class literal must not be nullable")
@@ -611,6 +616,14 @@ class FirDefaultErrorMessages : DefaultErrorMessages.Extension {
map.put(NO_ELSE_IN_WHEN, "''when'' expression must be exhaustive, add necessary {0}", WHEN_MISSING_CASES)
map.put(INVALID_IF_AS_EXPRESSION, "'if' must have both main and 'else' branches if used as an expression")
// Context tracking
map.put(TYPE_PARAMETER_IS_NOT_AN_EXPRESSION, "Type parameter ''{0}'' is not an expression", SYMBOL)
map.put(
TYPE_PARAMETER_ON_LHS_OF_DOT,
"Type parameter ''{0}'' cannot have or inherit a companion object, so it cannot be on the left hand side of dot",
SYMBOL
)
// Function contracts
map.put(ERROR_IN_CONTRACT_DESCRIPTION, "Error in contract description", TO_STRING)
@@ -22,6 +22,7 @@ object CommonExpressionCheckers : ExpressionCheckers() {
FirProjectionsOnNonClassTypeArgumentChecker,
FirUpperBoundViolatedChecker,
FirTypeArgumentsNotAllowedExpressionChecker,
FirTypeParameterInQualifiedAccessChecker,
FirSealedClassConstructorCallChecker,
)
override val functionCallCheckers: Set<FirFunctionCallChecker> = setOf()
@@ -82,6 +82,10 @@ class ConeTypeParameterSupertype(val symbol: FirTypeParameterSymbol) : ConeDiagn
override val reason: String get() = "Type parameter ${symbol.fir.name} cannot be a supertype"
}
class ConeTypeParameterInQualifiedAccess(val symbol: FirTypeParameterSymbol) : ConeDiagnostic() {
override val reason: String get() = "Type parameter ${symbol.fir.name} in qualified access"
}
private fun describeSymbol(symbol: AbstractFirBasedSymbol<*>): String {
return when (symbol) {
is FirClassLikeSymbol<*> -> symbol.classId.asString()
@@ -17,6 +17,7 @@ import org.jetbrains.kotlin.fir.references.builder.buildResolvedNamedReference
import org.jetbrains.kotlin.fir.resolve.*
import org.jetbrains.kotlin.fir.resolve.calls.*
import org.jetbrains.kotlin.fir.resolve.dfa.FirDataFlowAnalyzer
import org.jetbrains.kotlin.fir.resolve.diagnostics.ConeTypeParameterInQualifiedAccess
import org.jetbrains.kotlin.fir.resolve.inference.*
import org.jetbrains.kotlin.fir.resolve.substitution.ConeSubstitutor
import org.jetbrains.kotlin.fir.resolve.transformers.body.resolve.FirArrayOfCallTransformer
@@ -89,11 +90,14 @@ class FirCallCompletionResultsWriterTransformer(
// e.g. `T::toString` where T is a generic type.
// in these cases we should report an error on
// the calleeReference.source which is not a fake source.
// uncommenting `?.fakeElement...` here removes reports
// of OTHER_ERROR from tests.
buildErrorTypeRef {
source = calleeReference.source //?.fakeElement(FirFakeSourceElementKind.ImplicitTypeRef)
diagnostic = ConeSimpleDiagnostic("Callee reference to candidate without return type: ${declaration.render()}")
source = calleeReference.source?.fakeElement(FirFakeSourceElementKind.ImplicitTypeRef)
diagnostic =
when (declaration) {
is FirTypeParameter -> ConeTypeParameterInQualifiedAccess(declaration.symbol)
is FirResolvedReifiedParameterReference -> ConeTypeParameterInQualifiedAccess(declaration.symbol)
else -> ConeSimpleDiagnostic("Callee reference to candidate without return type: ${declaration.render()}")
}
}
}
+5 -5
View File
@@ -28,8 +28,8 @@ class Test1<T>()
{
fun test(t : T) {
<!OTHER_ERROR!>T<!>.<!UNRESOLVED_REFERENCE!>foo<!>()
<!OTHER_ERROR!>T<!>.<!UNRESOLVED_REFERENCE!>bar<!>()
<!TYPE_PARAMETER_ON_LHS_OF_DOT!>T<!>.<!UNRESOLVED_REFERENCE!>foo<!>()
<!TYPE_PARAMETER_ON_LHS_OF_DOT!>T<!>.<!UNRESOLVED_REFERENCE!>bar<!>()
t.foo()
t.bar()
}
@@ -56,8 +56,8 @@ fun <T> test2(t : T)
T : B,
B : T
{
<!OTHER_ERROR!>T<!>.<!UNRESOLVED_REFERENCE!>foo<!>()
<!OTHER_ERROR!>T<!>.<!UNRESOLVED_REFERENCE!>bar<!>()
<!TYPE_PARAMETER_ON_LHS_OF_DOT!>T<!>.<!UNRESOLVED_REFERENCE!>foo<!>()
<!TYPE_PARAMETER_ON_LHS_OF_DOT!>T<!>.<!UNRESOLVED_REFERENCE!>bar<!>()
t.foo()
t.bar()
}
@@ -66,4 +66,4 @@ val t1 = <!INAPPLICABLE_CANDIDATE!>test2<!><A>(A())
val t2 = <!INAPPLICABLE_CANDIDATE!>test2<!><B>(C())
val t3 = test2<C>(C())
val <T, B : T> x : Int = 0
val <T, B : T> x : Int = 0
@@ -1,19 +1,19 @@
// !WITH_NEW_INFERENCE
class A<T, U : Any> {
fun foo() = <!OTHER_ERROR!>T<!>::toString
fun foo() = <!CALLABLE_REFERENCE_LHS_NOT_A_CLASS!>T::toString<!>
fun bar() = <!OTHER_ERROR!>U<!>::toString
fun bar() = <!CALLABLE_REFERENCE_LHS_NOT_A_CLASS!>U::toString<!>
fun baz() {
take(<!OTHER_ERROR!>T<!>::toString)
take(<!CALLABLE_REFERENCE_LHS_NOT_A_CLASS!>T::toString<!>)
take(<!OTHER_ERROR!>U<!>::toString)
take(<!CALLABLE_REFERENCE_LHS_NOT_A_CLASS!>U::toString<!>)
}
}
fun <T> foo() = <!OTHER_ERROR!>T<!>::toString
fun <T> foo() = <!CALLABLE_REFERENCE_LHS_NOT_A_CLASS!>T::toString<!>
fun <U : Any> bar() = <!OTHER_ERROR!>U<!>::toString
fun <U : Any> bar() = <!CALLABLE_REFERENCE_LHS_NOT_A_CLASS!>U::toString<!>
fun take(arg: Any) {}
@@ -9,8 +9,8 @@ val l1 = <!NULLABLE_TYPE_IN_CLASS_LITERAL_LHS!>List<String>?::class<!>
val l2 = <!NULLABLE_TYPE_IN_CLASS_LITERAL_LHS!>List?::class<!>
fun <T : Any> foo() {
val t1 = <!OTHER_ERROR!>T<!>::class
val t2 = <!OTHER_ERROR!>T<!>?::class
val t1 = <!TYPE_PARAMETER_IS_NOT_AN_EXPRESSION!>T<!>::class
val t2 = <!TYPE_PARAMETER_IS_NOT_AN_EXPRESSION!>T<!>?::class
}
inline fun <reified T : Any> bar() {
@@ -1,23 +1,23 @@
// !DIAGNOSTICS: -TYPE_PARAMETER_AS_REIFIED -TYPE_PARAMETER_OF_PROPERTY_NOT_USED_IN_RECEIVER -UNUSED_VARIABLE -UNUSED_PARAMETER
fun <T> test1() = <!OTHER_ERROR!>T<!>::class
fun <T : Any> test2() = <!OTHER_ERROR!>T<!>::class
fun <T> test1() = <!TYPE_PARAMETER_IS_NOT_AN_EXPRESSION!>T<!>::class
fun <T : Any> test2() = <!TYPE_PARAMETER_IS_NOT_AN_EXPRESSION!>T<!>::class
val <T> test3 = <!OTHER_ERROR!>T<!>::class
val <T> test4 get() = <!OTHER_ERROR!>T<!>::class
val <T> test3 = <!TYPE_PARAMETER_IS_NOT_AN_EXPRESSION!>T<!>::class
val <T> test4 get() = <!TYPE_PARAMETER_IS_NOT_AN_EXPRESSION!>T<!>::class
fun <T> test5() = listOf(<!OTHER_ERROR!>T<!>::class)
fun <T> test5() = listOf(T::class)
fun <T> test6(): kotlin.reflect.KClass<T> = <!OTHER_ERROR!>T<!>::class
fun <T> test7(): kotlin.reflect.KClass<*> = <!OTHER_ERROR!>T<!>::class
fun <T> test6(): kotlin.reflect.KClass<T> = <!TYPE_PARAMETER_IS_NOT_AN_EXPRESSION!>T<!>::class
fun <T> test7(): kotlin.reflect.KClass<*> = <!TYPE_PARAMETER_IS_NOT_AN_EXPRESSION!>T<!>::class
fun test8() = <!NULLABLE_TYPE_IN_CLASS_LITERAL_LHS!>String?::class<!>
fun <T> listOf(e: T): List<T> = null!!
fun <L> locals() {
fun <T> test1() = <!OTHER_ERROR!>T<!>::class
fun <T : Any> test2() = <!OTHER_ERROR!>T<!>::class
fun <T> test1() = <!TYPE_PARAMETER_IS_NOT_AN_EXPRESSION!>T<!>::class
fun <T : Any> test2() = <!TYPE_PARAMETER_IS_NOT_AN_EXPRESSION!>T<!>::class
val test3 = <!OTHER_ERROR!>L<!>::class
fun test4() = <!OTHER_ERROR!>L<!>::class
val test3 = <!TYPE_PARAMETER_IS_NOT_AN_EXPRESSION!>L<!>::class
fun test4() = <!TYPE_PARAMETER_IS_NOT_AN_EXPRESSION!>L<!>::class
}
@@ -1,5 +1,9 @@
// !WITH_NEW_INFERENCE
// !DIAGNOSTICS: -UNUSED_PARAMETER
// !DIAGNOSTICS: -UNUSED_PARAMETER, -UNUSED_EXPRESSION
inline fun <reified T> foo() {
<!CALLABLE_REFERENCE_LHS_NOT_A_CLASS!>T::toString<!>
}
inline fun <reified T> f(): T = throw UnsupportedOperationException()
@@ -1,5 +1,9 @@
// !WITH_NEW_INFERENCE
// !DIAGNOSTICS: -UNUSED_PARAMETER
// !DIAGNOSTICS: -UNUSED_PARAMETER, -UNUSED_EXPRESSION
inline fun <reified T> foo() {
<!CALLABLE_REFERENCE_LHS_NOT_A_CLASS!>T::<!UNRESOLVED_REFERENCE!>toString<!><!>
}
inline fun <reified T> f(): T = throw UnsupportedOperationException()
@@ -1,5 +1,6 @@
package
public inline fun </*0*/ reified T> f(): T
public inline fun </*0*/ reified T> foo(): kotlin.Unit
public fun </*0*/ T> id(/*0*/ p: T): T
public fun </*0*/ A> main(): kotlin.Unit
@@ -1,8 +0,0 @@
package bar
class S<T> {
fun foo() {
<!OTHER_ERROR!>T<!>
<!OTHER_ERROR!>T<!>.<!UNRESOLVED_REFERENCE!>create<!>()
}
}
@@ -1,3 +1,4 @@
// FIR_IDENTICAL
package bar
class S<T> {
@@ -14,6 +14,6 @@ fun test() {
}
fun <T> bar() {
val typeParameter_as_val = <!OTHER_ERROR!>T<!>
val typeParameter_as_val = <!TYPE_PARAMETER_IS_NOT_AN_EXPRESSION!>T<!>
val typeParameter_as_fun = <!UNRESOLVED_REFERENCE!>T<!>()
}
@@ -797,6 +797,12 @@ internal val KT_DIAGNOSTIC_CONVERTER = KtDiagnosticConverterBuilder.buildConvert
token,
)
}
add(FirErrors.CALLABLE_REFERENCE_LHS_NOT_A_CLASS) { firDiagnostic ->
CallableReferenceLhsNotAClassImpl(
firDiagnostic as FirPsiDiagnostic<*>,
token,
)
}
add(FirErrors.CLASS_LITERAL_LHS_NOT_A_CLASS) { firDiagnostic ->
ClassLiteralLhsNotAClassImpl(
firDiagnostic as FirPsiDiagnostic<*>,
@@ -1263,6 +1269,20 @@ internal val KT_DIAGNOSTIC_CONVERTER = KtDiagnosticConverterBuilder.buildConvert
token,
)
}
add(FirErrors.TYPE_PARAMETER_IS_NOT_AN_EXPRESSION) { firDiagnostic ->
TypeParameterIsNotAnExpressionImpl(
firSymbolBuilder.buildTypeParameterSymbol(firDiagnostic.a.fir as FirTypeParameter),
firDiagnostic as FirPsiDiagnostic<*>,
token,
)
}
add(FirErrors.TYPE_PARAMETER_ON_LHS_OF_DOT) { firDiagnostic ->
TypeParameterOnLhsOfDotImpl(
firSymbolBuilder.buildTypeParameterSymbol(firDiagnostic.a.fir as FirTypeParameter),
firDiagnostic as FirPsiDiagnostic<*>,
token,
)
}
add(FirErrors.ERROR_IN_CONTRACT_DESCRIPTION) { firDiagnostic ->
ErrorInContractDescriptionImpl(
firDiagnostic.a,
@@ -564,6 +564,10 @@ sealed class KtFirDiagnostic<PSI: PsiElement> : KtDiagnosticWithPsi<PSI> {
override val diagnosticClass get() = InnerClassOfGenericThrowableSubclass::class
}
abstract class CallableReferenceLhsNotAClass : KtFirDiagnostic<KtExpression>() {
override val diagnosticClass get() = CallableReferenceLhsNotAClass::class
}
abstract class ClassLiteralLhsNotAClass : KtFirDiagnostic<KtExpression>() {
override val diagnosticClass get() = ClassLiteralLhsNotAClass::class
}
@@ -886,6 +890,16 @@ sealed class KtFirDiagnostic<PSI: PsiElement> : KtDiagnosticWithPsi<PSI> {
override val diagnosticClass get() = InvalidIfAsExpression::class
}
abstract class TypeParameterIsNotAnExpression : KtFirDiagnostic<KtSimpleNameExpression>() {
override val diagnosticClass get() = TypeParameterIsNotAnExpression::class
abstract val typeParameter: KtTypeParameterSymbol
}
abstract class TypeParameterOnLhsOfDot : KtFirDiagnostic<KtSimpleNameExpression>() {
override val diagnosticClass get() = TypeParameterOnLhsOfDot::class
abstract val typeParameter: KtTypeParameterSymbol
}
abstract class ErrorInContractDescription : KtFirDiagnostic<KtElement>() {
override val diagnosticClass get() = ErrorInContractDescription::class
abstract val reason: String
@@ -913,6 +913,13 @@ internal class InnerClassOfGenericThrowableSubclassImpl(
override val firDiagnostic: FirPsiDiagnostic<*> by weakRef(firDiagnostic)
}
internal class CallableReferenceLhsNotAClassImpl(
firDiagnostic: FirPsiDiagnostic<*>,
override val token: ValidityToken,
) : KtFirDiagnostic.CallableReferenceLhsNotAClass(), KtAbstractFirDiagnostic<KtExpression> {
override val firDiagnostic: FirPsiDiagnostic<*> by weakRef(firDiagnostic)
}
internal class ClassLiteralLhsNotAClassImpl(
firDiagnostic: FirPsiDiagnostic<*>,
override val token: ValidityToken,
@@ -1439,6 +1446,22 @@ internal class InvalidIfAsExpressionImpl(
override val firDiagnostic: FirPsiDiagnostic<*> by weakRef(firDiagnostic)
}
internal class TypeParameterIsNotAnExpressionImpl(
override val typeParameter: KtTypeParameterSymbol,
firDiagnostic: FirPsiDiagnostic<*>,
override val token: ValidityToken,
) : KtFirDiagnostic.TypeParameterIsNotAnExpression(), KtAbstractFirDiagnostic<KtSimpleNameExpression> {
override val firDiagnostic: FirPsiDiagnostic<*> by weakRef(firDiagnostic)
}
internal class TypeParameterOnLhsOfDotImpl(
override val typeParameter: KtTypeParameterSymbol,
firDiagnostic: FirPsiDiagnostic<*>,
override val token: ValidityToken,
) : KtFirDiagnostic.TypeParameterOnLhsOfDot(), KtAbstractFirDiagnostic<KtSimpleNameExpression> {
override val firDiagnostic: FirPsiDiagnostic<*> by weakRef(firDiagnostic)
}
internal class ErrorInContractDescriptionImpl(
override val reason: String,
firDiagnostic: FirPsiDiagnostic<*>,