diff --git a/compiler/fir/checkers/checkers-component-generator/src/org/jetbrains/kotlin/fir/checkers/generator/diagnostics/FirDiagnosticsList.kt b/compiler/fir/checkers/checkers-component-generator/src/org/jetbrains/kotlin/fir/checkers/generator/diagnostics/FirDiagnosticsList.kt index 1bbfb698156..9dc3675f375 100644 --- a/compiler/fir/checkers/checkers-component-generator/src/org/jetbrains/kotlin/fir/checkers/generator/diagnostics/FirDiagnosticsList.kt +++ b/compiler/fir/checkers/checkers-component-generator/src/org/jetbrains/kotlin/fir/checkers/generator/diagnostics/FirDiagnosticsList.kt @@ -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() + val CLASS_LITERAL_LHS_NOT_A_CLASS by error() val NULLABLE_TYPE_IN_CLASS_LITERAL_LHS by error() } @@ -448,6 +451,15 @@ object DIAGNOSTICS_LIST : DiagnosticList() { val INVALID_IF_AS_EXPRESSION by error(PositioningStrategy.IF_EXPRESSION) } + val CONTEXT_TRACKING by object : DiagnosticGroup("Context tracking") { + val TYPE_PARAMETER_IS_NOT_AN_EXPRESSION by error { + parameter("typeParameter") + } + val TYPE_PARAMETER_ON_LHS_OF_DOT by error { + parameter("typeParameter") + } + } + val FUNCTION_CONTRACTS by object : DiagnosticGroup("Function contracts") { val ERROR_IN_CONTRACT_DESCRIPTION by error(PositioningStrategy.SELECTOR_BY_QUALIFIED) { parameter("reason") diff --git a/compiler/fir/checkers/gen/org/jetbrains/kotlin/fir/analysis/diagnostics/FirErrors.kt b/compiler/fir/checkers/gen/org/jetbrains/kotlin/fir/analysis/diagnostics/FirErrors.kt index 81e27adae71..7176661165f 100644 --- a/compiler/fir/checkers/gen/org/jetbrains/kotlin/fir/analysis/diagnostics/FirErrors.kt +++ b/compiler/fir/checkers/gen/org/jetbrains/kotlin/fir/analysis/diagnostics/FirErrors.kt @@ -195,6 +195,7 @@ object FirErrors { val INNER_CLASS_OF_GENERIC_THROWABLE_SUBCLASS by error0(SourceElementPositioningStrategies.DECLARATION_NAME) // Reflection + val CALLABLE_REFERENCE_LHS_NOT_A_CLASS by error0() val CLASS_LITERAL_LHS_NOT_A_CLASS by error0() val NULLABLE_TYPE_IN_CLASS_LITERAL_LHS by error0() @@ -284,6 +285,10 @@ object FirErrors { val NO_ELSE_IN_WHEN by error1>(SourceElementPositioningStrategies.WHEN_EXPRESSION) val INVALID_IF_AS_EXPRESSION by error0(SourceElementPositioningStrategies.IF_EXPRESSION) + // Context tracking + val TYPE_PARAMETER_IS_NOT_AN_EXPRESSION by error1() + val TYPE_PARAMETER_ON_LHS_OF_DOT by error1() + // Function contracts val ERROR_IN_CONTRACT_DESCRIPTION by error1(SourceElementPositioningStrategies.SELECTOR_BY_QUALIFIED) diff --git a/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/checkers/expression/FirTypeParameterInQualifiedAccessChecker.kt b/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/checkers/expression/FirTypeParameterInQualifiedAccessChecker.kt new file mode 100644 index 00000000000..8666d6026fc --- /dev/null +++ b/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/checkers/expression/FirTypeParameterInQualifiedAccessChecker.kt @@ -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 +} diff --git a/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/diagnostics/FirDefaultErrorMessages.kt b/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/diagnostics/FirDefaultErrorMessages.kt index 3aaff9a6bcb..603bb256d17 100644 --- a/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/diagnostics/FirDefaultErrorMessages.kt +++ b/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/diagnostics/FirDefaultErrorMessages.kt @@ -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) diff --git a/compiler/fir/entrypoint/src/org/jetbrains/kotlin/fir/checkers/CommonExpressionCheckers.kt b/compiler/fir/entrypoint/src/org/jetbrains/kotlin/fir/checkers/CommonExpressionCheckers.kt index 7e9d8df84e2..5063c6cf324 100644 --- a/compiler/fir/entrypoint/src/org/jetbrains/kotlin/fir/checkers/CommonExpressionCheckers.kt +++ b/compiler/fir/entrypoint/src/org/jetbrains/kotlin/fir/checkers/CommonExpressionCheckers.kt @@ -22,6 +22,7 @@ object CommonExpressionCheckers : ExpressionCheckers() { FirProjectionsOnNonClassTypeArgumentChecker, FirUpperBoundViolatedChecker, FirTypeArgumentsNotAllowedExpressionChecker, + FirTypeParameterInQualifiedAccessChecker, FirSealedClassConstructorCallChecker, ) override val functionCallCheckers: Set = setOf() diff --git a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/diagnostics/FirDiagnostics.kt b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/diagnostics/FirDiagnostics.kt index d51ffb8f043..b6cf27c2414 100644 --- a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/diagnostics/FirDiagnostics.kt +++ b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/diagnostics/FirDiagnostics.kt @@ -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() diff --git a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/transformers/FirCallCompletionResultsWriterTransformer.kt b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/transformers/FirCallCompletionResultsWriterTransformer.kt index c00c59688d2..4972ea4e9aa 100644 --- a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/transformers/FirCallCompletionResultsWriterTransformer.kt +++ b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/transformers/FirCallCompletionResultsWriterTransformer.kt @@ -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()}") + } } } diff --git a/compiler/testData/diagnostics/tests/MultipleBounds.fir.kt b/compiler/testData/diagnostics/tests/MultipleBounds.fir.kt index 6ca630b3548..82718934296 100644 --- a/compiler/testData/diagnostics/tests/MultipleBounds.fir.kt +++ b/compiler/testData/diagnostics/tests/MultipleBounds.fir.kt @@ -28,8 +28,8 @@ class Test1() { fun test(t : T) { - T.foo() - T.bar() + T.foo() + T.bar() t.foo() t.bar() } @@ -56,8 +56,8 @@ fun test2(t : T) T : B, B : T { - T.foo() - T.bar() + T.foo() + T.bar() t.foo() t.bar() } @@ -66,4 +66,4 @@ val t1 = test2(A()) val t2 = test2(C()) val t3 = test2(C()) -val x : Int = 0 \ No newline at end of file +val x : Int = 0 diff --git a/compiler/testData/diagnostics/tests/callableReference/function/lhsNotAClass.fir.kt b/compiler/testData/diagnostics/tests/callableReference/function/lhsNotAClass.fir.kt index af2b7e5bc06..8961f52447d 100644 --- a/compiler/testData/diagnostics/tests/callableReference/function/lhsNotAClass.fir.kt +++ b/compiler/testData/diagnostics/tests/callableReference/function/lhsNotAClass.fir.kt @@ -1,19 +1,19 @@ // !WITH_NEW_INFERENCE class A { - fun foo() = T::toString + fun foo() = T::toString - fun bar() = U::toString + fun bar() = U::toString fun baz() { - take(T::toString) + take(T::toString) - take(U::toString) + take(U::toString) } } -fun foo() = T::toString +fun foo() = T::toString -fun bar() = U::toString +fun bar() = U::toString fun take(arg: Any) {} diff --git a/compiler/testData/diagnostics/tests/classLiteral/nonClassesOnLHS.fir.kt b/compiler/testData/diagnostics/tests/classLiteral/nonClassesOnLHS.fir.kt index 6fd94cfa680..de0e5ae1eb9 100644 --- a/compiler/testData/diagnostics/tests/classLiteral/nonClassesOnLHS.fir.kt +++ b/compiler/testData/diagnostics/tests/classLiteral/nonClassesOnLHS.fir.kt @@ -9,8 +9,8 @@ val l1 = List?::class val l2 = List?::class fun foo() { - val t1 = T::class - val t2 = T?::class + val t1 = T::class + val t2 = T?::class } inline fun bar() { diff --git a/compiler/testData/diagnostics/tests/declarationChecks/kClassInSignature.fir.kt b/compiler/testData/diagnostics/tests/declarationChecks/kClassInSignature.fir.kt index f6b043ae163..a0692f9641c 100644 --- a/compiler/testData/diagnostics/tests/declarationChecks/kClassInSignature.fir.kt +++ b/compiler/testData/diagnostics/tests/declarationChecks/kClassInSignature.fir.kt @@ -1,23 +1,23 @@ // !DIAGNOSTICS: -TYPE_PARAMETER_AS_REIFIED -TYPE_PARAMETER_OF_PROPERTY_NOT_USED_IN_RECEIVER -UNUSED_VARIABLE -UNUSED_PARAMETER -fun test1() = T::class -fun test2() = T::class +fun test1() = T::class +fun test2() = T::class -val test3 = T::class -val test4 get() = T::class +val test3 = T::class +val test4 get() = T::class -fun test5() = listOf(T::class) +fun test5() = listOf(T::class) -fun test6(): kotlin.reflect.KClass = T::class -fun test7(): kotlin.reflect.KClass<*> = T::class +fun test6(): kotlin.reflect.KClass = T::class +fun test7(): kotlin.reflect.KClass<*> = T::class fun test8() = String?::class fun listOf(e: T): List = null!! fun locals() { - fun test1() = T::class - fun test2() = T::class + fun test1() = T::class + fun test2() = T::class - val test3 = L::class - fun test4() = L::class + val test3 = L::class + fun test4() = L::class } diff --git a/compiler/testData/diagnostics/tests/generics/tpAsReified/InFunction.fir.kt b/compiler/testData/diagnostics/tests/generics/tpAsReified/InFunction.fir.kt index fd1d243cb7e..8153c980f63 100644 --- a/compiler/testData/diagnostics/tests/generics/tpAsReified/InFunction.fir.kt +++ b/compiler/testData/diagnostics/tests/generics/tpAsReified/InFunction.fir.kt @@ -1,5 +1,9 @@ // !WITH_NEW_INFERENCE -// !DIAGNOSTICS: -UNUSED_PARAMETER +// !DIAGNOSTICS: -UNUSED_PARAMETER, -UNUSED_EXPRESSION + +inline fun foo() { + T::toString +} inline fun f(): T = throw UnsupportedOperationException() diff --git a/compiler/testData/diagnostics/tests/generics/tpAsReified/InFunction.kt b/compiler/testData/diagnostics/tests/generics/tpAsReified/InFunction.kt index 154c954adb1..624c7012a32 100644 --- a/compiler/testData/diagnostics/tests/generics/tpAsReified/InFunction.kt +++ b/compiler/testData/diagnostics/tests/generics/tpAsReified/InFunction.kt @@ -1,5 +1,9 @@ // !WITH_NEW_INFERENCE -// !DIAGNOSTICS: -UNUSED_PARAMETER +// !DIAGNOSTICS: -UNUSED_PARAMETER, -UNUSED_EXPRESSION + +inline fun foo() { + T::toString +} inline fun f(): T = throw UnsupportedOperationException() diff --git a/compiler/testData/diagnostics/tests/generics/tpAsReified/InFunction.txt b/compiler/testData/diagnostics/tests/generics/tpAsReified/InFunction.txt index 70264cf24be..6280da0791d 100644 --- a/compiler/testData/diagnostics/tests/generics/tpAsReified/InFunction.txt +++ b/compiler/testData/diagnostics/tests/generics/tpAsReified/InFunction.txt @@ -1,5 +1,6 @@ package public inline fun f(): T +public inline fun foo(): kotlin.Unit public fun id(/*0*/ p: T): T public fun main(): kotlin.Unit diff --git a/compiler/testData/diagnostics/tests/incompleteCode/typeParameterOnLhsOfDot.fir.kt b/compiler/testData/diagnostics/tests/incompleteCode/typeParameterOnLhsOfDot.fir.kt deleted file mode 100644 index f4e1f12e1ff..00000000000 --- a/compiler/testData/diagnostics/tests/incompleteCode/typeParameterOnLhsOfDot.fir.kt +++ /dev/null @@ -1,8 +0,0 @@ -package bar - -class S { - fun foo() { - T - T.create() - } -} \ No newline at end of file diff --git a/compiler/testData/diagnostics/tests/incompleteCode/typeParameterOnLhsOfDot.kt b/compiler/testData/diagnostics/tests/incompleteCode/typeParameterOnLhsOfDot.kt index f0df88331c0..7f9b7f02e62 100644 --- a/compiler/testData/diagnostics/tests/incompleteCode/typeParameterOnLhsOfDot.kt +++ b/compiler/testData/diagnostics/tests/incompleteCode/typeParameterOnLhsOfDot.kt @@ -1,3 +1,4 @@ +// FIR_IDENTICAL package bar class S { diff --git a/compiler/testData/diagnostics/tests/resolve/noCandidates/resolvedToClassifier.fir.kt b/compiler/testData/diagnostics/tests/resolve/noCandidates/resolvedToClassifier.fir.kt index 27bed3b5177..31df993c2fa 100644 --- a/compiler/testData/diagnostics/tests/resolve/noCandidates/resolvedToClassifier.fir.kt +++ b/compiler/testData/diagnostics/tests/resolve/noCandidates/resolvedToClassifier.fir.kt @@ -14,6 +14,6 @@ fun test() { } fun bar() { - val typeParameter_as_val = T + val typeParameter_as_val = T val typeParameter_as_fun = T() } diff --git a/idea/idea-frontend-fir/src/org/jetbrains/kotlin/idea/frontend/api/fir/diagnostics/KtFirDataClassConverters.kt b/idea/idea-frontend-fir/src/org/jetbrains/kotlin/idea/frontend/api/fir/diagnostics/KtFirDataClassConverters.kt index 01bb47fd451..9ba5e884745 100644 --- a/idea/idea-frontend-fir/src/org/jetbrains/kotlin/idea/frontend/api/fir/diagnostics/KtFirDataClassConverters.kt +++ b/idea/idea-frontend-fir/src/org/jetbrains/kotlin/idea/frontend/api/fir/diagnostics/KtFirDataClassConverters.kt @@ -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, diff --git a/idea/idea-frontend-fir/src/org/jetbrains/kotlin/idea/frontend/api/fir/diagnostics/KtFirDiagnostics.kt b/idea/idea-frontend-fir/src/org/jetbrains/kotlin/idea/frontend/api/fir/diagnostics/KtFirDiagnostics.kt index c6cb524d35d..2982aac2ee0 100644 --- a/idea/idea-frontend-fir/src/org/jetbrains/kotlin/idea/frontend/api/fir/diagnostics/KtFirDiagnostics.kt +++ b/idea/idea-frontend-fir/src/org/jetbrains/kotlin/idea/frontend/api/fir/diagnostics/KtFirDiagnostics.kt @@ -564,6 +564,10 @@ sealed class KtFirDiagnostic : KtDiagnosticWithPsi { override val diagnosticClass get() = InnerClassOfGenericThrowableSubclass::class } + abstract class CallableReferenceLhsNotAClass : KtFirDiagnostic() { + override val diagnosticClass get() = CallableReferenceLhsNotAClass::class + } + abstract class ClassLiteralLhsNotAClass : KtFirDiagnostic() { override val diagnosticClass get() = ClassLiteralLhsNotAClass::class } @@ -886,6 +890,16 @@ sealed class KtFirDiagnostic : KtDiagnosticWithPsi { override val diagnosticClass get() = InvalidIfAsExpression::class } + abstract class TypeParameterIsNotAnExpression : KtFirDiagnostic() { + override val diagnosticClass get() = TypeParameterIsNotAnExpression::class + abstract val typeParameter: KtTypeParameterSymbol + } + + abstract class TypeParameterOnLhsOfDot : KtFirDiagnostic() { + override val diagnosticClass get() = TypeParameterOnLhsOfDot::class + abstract val typeParameter: KtTypeParameterSymbol + } + abstract class ErrorInContractDescription : KtFirDiagnostic() { override val diagnosticClass get() = ErrorInContractDescription::class abstract val reason: String diff --git a/idea/idea-frontend-fir/src/org/jetbrains/kotlin/idea/frontend/api/fir/diagnostics/KtFirDiagnosticsImpl.kt b/idea/idea-frontend-fir/src/org/jetbrains/kotlin/idea/frontend/api/fir/diagnostics/KtFirDiagnosticsImpl.kt index 73a21eddc08..ddaaa1c0ccd 100644 --- a/idea/idea-frontend-fir/src/org/jetbrains/kotlin/idea/frontend/api/fir/diagnostics/KtFirDiagnosticsImpl.kt +++ b/idea/idea-frontend-fir/src/org/jetbrains/kotlin/idea/frontend/api/fir/diagnostics/KtFirDiagnosticsImpl.kt @@ -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 { + 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 { + override val firDiagnostic: FirPsiDiagnostic<*> by weakRef(firDiagnostic) +} + +internal class TypeParameterOnLhsOfDotImpl( + override val typeParameter: KtTypeParameterSymbol, + firDiagnostic: FirPsiDiagnostic<*>, + override val token: ValidityToken, +) : KtFirDiagnostic.TypeParameterOnLhsOfDot(), KtAbstractFirDiagnostic { + override val firDiagnostic: FirPsiDiagnostic<*> by weakRef(firDiagnostic) +} + internal class ErrorInContractDescriptionImpl( override val reason: String, firDiagnostic: FirPsiDiagnostic<*>,