FIR checker: report non-typed LHS of callable references
This commit is contained in:
committed by
Mikhail Glukhikh
parent
329be4f906
commit
33c5b49632
+12
@@ -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)
|
||||
|
||||
|
||||
+58
@@ -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
|
||||
}
|
||||
+13
@@ -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)
|
||||
|
||||
|
||||
+1
@@ -22,6 +22,7 @@ object CommonExpressionCheckers : ExpressionCheckers() {
|
||||
FirProjectionsOnNonClassTypeArgumentChecker,
|
||||
FirUpperBoundViolatedChecker,
|
||||
FirTypeArgumentsNotAllowedExpressionChecker,
|
||||
FirTypeParameterInQualifiedAccessChecker,
|
||||
FirSealedClassConstructorCallChecker,
|
||||
)
|
||||
override val functionCallCheckers: Set<FirFunctionCallChecker> = setOf()
|
||||
|
||||
+4
@@ -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()
|
||||
|
||||
+8
-4
@@ -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()}")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
+6
-6
@@ -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() {
|
||||
|
||||
+11
-11
@@ -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
|
||||
|
||||
-8
@@ -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> {
|
||||
|
||||
+1
-1
@@ -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<!>()
|
||||
}
|
||||
|
||||
+20
@@ -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,
|
||||
|
||||
+14
@@ -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
|
||||
|
||||
+23
@@ -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<*>,
|
||||
|
||||
Reference in New Issue
Block a user