diff --git a/analysis/analysis-api-fir/src/org/jetbrains/kotlin/analysis/api/fir/diagnostics/KtFirDataClassConverters.kt b/analysis/analysis-api-fir/src/org/jetbrains/kotlin/analysis/api/fir/diagnostics/KtFirDataClassConverters.kt index 4da5a350e6c..1a80ae100ea 100644 --- a/analysis/analysis-api-fir/src/org/jetbrains/kotlin/analysis/api/fir/diagnostics/KtFirDataClassConverters.kt +++ b/analysis/analysis-api-fir/src/org/jetbrains/kotlin/analysis/api/fir/diagnostics/KtFirDataClassConverters.kt @@ -2572,12 +2572,14 @@ internal val KT_DIAGNOSTIC_CONVERTER = KtDiagnosticConverterBuilder.buildConvert } add(FirErrors.DELEGATE_USES_EXTENSION_PROPERTY_TYPE_PARAMETER.errorFactory) { firDiagnostic -> DelegateUsesExtensionPropertyTypeParameterErrorImpl( + firSymbolBuilder.classifierBuilder.buildTypeParameterSymbol(firDiagnostic.a.fir), firDiagnostic as KtPsiDiagnostic, token, ) } add(FirErrors.DELEGATE_USES_EXTENSION_PROPERTY_TYPE_PARAMETER.warningFactory) { firDiagnostic -> DelegateUsesExtensionPropertyTypeParameterWarningImpl( + firSymbolBuilder.classifierBuilder.buildTypeParameterSymbol(firDiagnostic.a.fir), firDiagnostic as KtPsiDiagnostic, token, ) diff --git a/analysis/analysis-api-fir/src/org/jetbrains/kotlin/analysis/api/fir/diagnostics/KtFirDiagnostics.kt b/analysis/analysis-api-fir/src/org/jetbrains/kotlin/analysis/api/fir/diagnostics/KtFirDiagnostics.kt index 858671948fe..b15d8f68be3 100644 --- a/analysis/analysis-api-fir/src/org/jetbrains/kotlin/analysis/api/fir/diagnostics/KtFirDiagnostics.kt +++ b/analysis/analysis-api-fir/src/org/jetbrains/kotlin/analysis/api/fir/diagnostics/KtFirDiagnostics.kt @@ -1821,10 +1821,12 @@ sealed class KtFirDiagnostic : KtDiagnosticWithPsi { abstract class DelegateUsesExtensionPropertyTypeParameterError : KtFirDiagnostic() { override val diagnosticClass get() = DelegateUsesExtensionPropertyTypeParameterError::class + abstract val usedTypeParameter: KtTypeParameterSymbol } abstract class DelegateUsesExtensionPropertyTypeParameterWarning : KtFirDiagnostic() { override val diagnosticClass get() = DelegateUsesExtensionPropertyTypeParameterWarning::class + abstract val usedTypeParameter: KtTypeParameterSymbol } abstract class InitializerTypeMismatch : KtFirDiagnostic() { diff --git a/analysis/analysis-api-fir/src/org/jetbrains/kotlin/analysis/api/fir/diagnostics/KtFirDiagnosticsImpl.kt b/analysis/analysis-api-fir/src/org/jetbrains/kotlin/analysis/api/fir/diagnostics/KtFirDiagnosticsImpl.kt index f799915f5ac..7454b9a63f6 100644 --- a/analysis/analysis-api-fir/src/org/jetbrains/kotlin/analysis/api/fir/diagnostics/KtFirDiagnosticsImpl.kt +++ b/analysis/analysis-api-fir/src/org/jetbrains/kotlin/analysis/api/fir/diagnostics/KtFirDiagnosticsImpl.kt @@ -2188,11 +2188,13 @@ internal class WrongSetterParameterTypeImpl( ) : KtFirDiagnostic.WrongSetterParameterType(), KtAbstractFirDiagnostic internal class DelegateUsesExtensionPropertyTypeParameterErrorImpl( + override val usedTypeParameter: KtTypeParameterSymbol, override val firDiagnostic: KtPsiDiagnostic, override val token: ValidityToken, ) : KtFirDiagnostic.DelegateUsesExtensionPropertyTypeParameterError(), KtAbstractFirDiagnostic internal class DelegateUsesExtensionPropertyTypeParameterWarningImpl( + override val usedTypeParameter: KtTypeParameterSymbol, override val firDiagnostic: KtPsiDiagnostic, override val token: ValidityToken, ) : KtFirDiagnostic.DelegateUsesExtensionPropertyTypeParameterWarning(), KtAbstractFirDiagnostic 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 ac3badaf97e..452b2987db4 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 @@ -927,7 +927,9 @@ object DIAGNOSTICS_LIST : DiagnosticList("FirErrors") { val DELEGATE_USES_EXTENSION_PROPERTY_TYPE_PARAMETER by deprecationError( LanguageFeature.ForbidUsingExtensionPropertyTypeParameterInDelegate, PositioningStrategy.PROPERTY_DELEGATE - ) + ) { + parameter("usedTypeParameter") + } val INITIALIZER_TYPE_MISMATCH by error(PositioningStrategy.PROPERTY_INITIALIZER) { parameter("expectedType") parameter("actualType") 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 f232750c90a..cd4abf8e713 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 @@ -508,7 +508,7 @@ object FirErrors { val CONST_VAL_WITHOUT_INITIALIZER by error0(SourceElementPositioningStrategies.CONST_MODIFIER) val CONST_VAL_WITH_NON_CONST_INITIALIZER by error0() val WRONG_SETTER_PARAMETER_TYPE by error2() - val DELEGATE_USES_EXTENSION_PROPERTY_TYPE_PARAMETER by deprecationError0(ForbidUsingExtensionPropertyTypeParameterInDelegate, SourceElementPositioningStrategies.PROPERTY_DELEGATE) + val DELEGATE_USES_EXTENSION_PROPERTY_TYPE_PARAMETER by deprecationError1(ForbidUsingExtensionPropertyTypeParameterInDelegate, SourceElementPositioningStrategies.PROPERTY_DELEGATE) val INITIALIZER_TYPE_MISMATCH by error3(SourceElementPositioningStrategies.PROPERTY_INITIALIZER) val GETTER_VISIBILITY_DIFFERS_FROM_PROPERTY_VISIBILITY by error0(SourceElementPositioningStrategies.VISIBILITY_MODIFIER) val SETTER_VISIBILITY_INCONSISTENT_WITH_PROPERTY_VISIBILITY by error0(SourceElementPositioningStrategies.VISIBILITY_MODIFIER) diff --git a/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/checkers/declaration/FirDelegateUsesExtensionPropertyTypeParameterChecker.kt b/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/checkers/declaration/FirDelegateUsesExtensionPropertyTypeParameterChecker.kt index 01446e67313..fb4a6defb77 100644 --- a/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/checkers/declaration/FirDelegateUsesExtensionPropertyTypeParameterChecker.kt +++ b/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/checkers/declaration/FirDelegateUsesExtensionPropertyTypeParameterChecker.kt @@ -23,31 +23,29 @@ object FirDelegateUsesExtensionPropertyTypeParameterChecker : FirPropertyChecker val delegate = declaration.delegate.safeAs() ?: return val parameters = declaration.typeParameters.mapTo(hashSetOf()) { it.symbol } - val shouldReportError = delegate.typeRef.coneType.containsTypeParameterFrom(parameters, delegate, context, reporter) + val usedTypeParameterSymbol = delegate.typeRef.coneType.findUsedTypeParameterSymbol(parameters, delegate, context, reporter) + ?: return - if (shouldReportError) { - reporter.reportOn(declaration.source, FirErrors.DELEGATE_USES_EXTENSION_PROPERTY_TYPE_PARAMETER, context) - } + reporter.reportOn(declaration.source, FirErrors.DELEGATE_USES_EXTENSION_PROPERTY_TYPE_PARAMETER, usedTypeParameterSymbol, context) } - private fun ConeKotlinType.containsTypeParameterFrom( + private fun ConeKotlinType.findUsedTypeParameterSymbol( parameters: HashSet, delegate: FirFunctionCall, context: CheckerContext, reporter: DiagnosticReporter, - ): Boolean { + ): FirTypeParameterSymbol? { for (it in typeArguments) { val theType = it.type ?: continue - val symbol = theType.toSymbol(context.session) + val symbol = theType.toSymbol(context.session) as? FirTypeParameterSymbol - if ( - symbol in parameters || - theType.containsTypeParameterFrom(parameters, delegate, context, reporter) - ) { - return true + if (symbol in parameters) return symbol + val usedTypeParameterSymbol = theType.findUsedTypeParameterSymbol(parameters, delegate, context, reporter) + if (usedTypeParameterSymbol != null) { + return usedTypeParameterSymbol } } - return false + return null } } diff --git a/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/diagnostics/FirErrorsDefaultMessages.kt b/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/diagnostics/FirErrorsDefaultMessages.kt index d16460b57e1..71ea043224f 100644 --- a/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/diagnostics/FirErrorsDefaultMessages.kt +++ b/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/diagnostics/FirErrorsDefaultMessages.kt @@ -890,10 +890,10 @@ object FirErrorsDefaultMessages : BaseDiagnosticRendererFactory() { map.put(DEPRECATED_MODIFIER_PAIR, "Modifier ''{0}'' is deprecated in presence of ''{1}''", TO_STRING, TO_STRING) map.put(DEPRECATED_MODIFIER_FOR_TARGET, "Modifier ''{0}'' is deprecated for ''{1}''", TO_STRING, STRING) map.put(REDUNDANT_MODIFIER_FOR_TARGET, "Modifier ''{0}'' is redundant for ''{1}''", TO_STRING, STRING) - map.put(NO_EXPLICIT_VISIBILITY_IN_API_MODE, "Visibility must be specified in explicit API mode"); - map.put(NO_EXPLICIT_RETURN_TYPE_IN_API_MODE, "Return type must be specified in explicit API mode"); - map.put(NO_EXPLICIT_VISIBILITY_IN_API_MODE_WARNING, "Visibility must be specified in explicit API mode"); - map.put(NO_EXPLICIT_RETURN_TYPE_IN_API_MODE_WARNING, "Return type must be specified in explicit API mode"); + map.put(NO_EXPLICIT_VISIBILITY_IN_API_MODE, "Visibility must be specified in explicit API mode") + map.put(NO_EXPLICIT_RETURN_TYPE_IN_API_MODE, "Return type must be specified in explicit API mode") + map.put(NO_EXPLICIT_VISIBILITY_IN_API_MODE_WARNING, "Visibility must be specified in explicit API mode") + map.put(NO_EXPLICIT_RETURN_TYPE_IN_API_MODE_WARNING, "Return type must be specified in explicit API mode") map.put(INCOMPATIBLE_MODIFIERS, "Modifier ''{0}'' is incompatible with ''{1}''", TO_STRING, TO_STRING) map.put(REDUNDANT_OPEN_IN_INTERFACE, "Modifier 'open' is redundant for abstract interface members") @@ -1450,7 +1450,8 @@ object FirErrorsDefaultMessages : BaseDiagnosticRendererFactory() { ) map.put( DELEGATE_USES_EXTENSION_PROPERTY_TYPE_PARAMETER, - "It's forbidden using extension property type parameter in delegate" + "It''s forbidden using extension property type parameter ''{0}'' in delegate", + SYMBOL ) map.put(INITIALIZER_TYPE_MISMATCH, "Initializer type mismatch: expected {0}, actual {1}", RENDER_TYPE, RENDER_TYPE, NOT_RENDERED) map.put(GETTER_VISIBILITY_DIFFERS_FROM_PROPERTY_VISIBILITY, "Getter visibility must be the same as property visibility")