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 3d5f73a6da1..de38d9771ae 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 @@ -408,6 +408,12 @@ internal val KT_DIAGNOSTIC_CONVERTER = KtDiagnosticConverterBuilder.buildConvert token, ) } + add(FirErrors.DUPLICATE_PARAMETER_NAME_IN_FUNCTION_TYPE) { firDiagnostic -> + DuplicateParameterNameInFunctionTypeImpl( + firDiagnostic as KtPsiDiagnostic, + token, + ) + } add(FirErrors.CREATING_AN_INSTANCE_OF_ABSTRACT_CLASS) { firDiagnostic -> CreatingAnInstanceOfAbstractClassImpl( firDiagnostic as KtPsiDiagnostic, 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 dc2144bbaa3..d89bc3fb1f7 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 @@ -331,6 +331,10 @@ sealed interface KtFirDiagnostic : KtDiagnosticWithPsi { val reference: String } + interface DuplicateParameterNameInFunctionType : KtFirDiagnostic { + override val diagnosticClass get() = DuplicateParameterNameInFunctionType::class + } + interface CreatingAnInstanceOfAbstractClass : KtFirDiagnostic { override val diagnosticClass get() = CreatingAnInstanceOfAbstractClass::class } 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 c8c19d508d8..c6b68fd7f2a 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 @@ -381,6 +381,11 @@ internal class UnresolvedImportImpl( token: KtLifetimeToken, ) : KtAbstractFirDiagnostic(firDiagnostic, token), KtFirDiagnostic.UnresolvedImport +internal class DuplicateParameterNameInFunctionTypeImpl( + firDiagnostic: KtPsiDiagnostic, + token: KtLifetimeToken, +) : KtAbstractFirDiagnostic(firDiagnostic, token), KtFirDiagnostic.DuplicateParameterNameInFunctionType + internal class CreatingAnInstanceOfAbstractClassImpl( firDiagnostic: KtPsiDiagnostic, token: KtLifetimeToken, 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 c4d17377f5f..b8192555a51 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 @@ -174,6 +174,8 @@ object DIAGNOSTICS_LIST : DiagnosticList("FirErrors") { val UNRESOLVED_IMPORT by error(PositioningStrategy.IMPORT_LAST_NAME) { parameter("reference") } + + val DUPLICATE_PARAMETER_NAME_IN_FUNCTION_TYPE by error() } val CALL_RESOLUTION by object : DiagnosticGroup("Call resolution") { 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 2270817803b..4893f9c5678 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 @@ -172,6 +172,7 @@ object FirErrors { val API_NOT_AVAILABLE by error2(SourceElementPositioningStrategies.SELECTOR_BY_QUALIFIED) val UNRESOLVED_REFERENCE_WRONG_RECEIVER by error1>>() val UNRESOLVED_IMPORT by error1(SourceElementPositioningStrategies.IMPORT_LAST_NAME) + val DUPLICATE_PARAMETER_NAME_IN_FUNCTION_TYPE by error0() // Call resolution val CREATING_AN_INSTANCE_OF_ABSTRACT_CLASS by error0() diff --git a/compiler/fir/checkers/gen/org/jetbrains/kotlin/fir/analysis/diagnostics/FirNonSuppressibleErrorNames.kt b/compiler/fir/checkers/gen/org/jetbrains/kotlin/fir/analysis/diagnostics/FirNonSuppressibleErrorNames.kt index 27a6ac623ea..8c499c24c9b 100644 --- a/compiler/fir/checkers/gen/org/jetbrains/kotlin/fir/analysis/diagnostics/FirNonSuppressibleErrorNames.kt +++ b/compiler/fir/checkers/gen/org/jetbrains/kotlin/fir/analysis/diagnostics/FirNonSuppressibleErrorNames.kt @@ -52,6 +52,7 @@ val FIR_NON_SUPPRESSIBLE_ERROR_NAMES: Set = setOf( "API_NOT_AVAILABLE", "UNRESOLVED_REFERENCE_WRONG_RECEIVER", "UNRESOLVED_IMPORT", + "DUPLICATE_PARAMETER_NAME_IN_FUNCTION_TYPE", "CREATING_AN_INSTANCE_OF_ABSTRACT_CLASS", "NO_CONSTRUCTOR", "FUNCTION_CALL_EXPECTED", diff --git a/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/checkers/CommonTypeCheckers.kt b/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/checkers/CommonTypeCheckers.kt index 367b663b1e5..0433132570d 100644 --- a/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/checkers/CommonTypeCheckers.kt +++ b/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/checkers/CommonTypeCheckers.kt @@ -17,6 +17,7 @@ object CommonTypeCheckers : TypeCheckers() { FirUnsupportedDefaultValueInFunctionTypeParameterChecker, FirUnsupportedModifiersInFunctionTypeParameterChecker, FirStarProjectionModifierChecker, + FirDuplicateParameterNameInFunctionTypeChecker, FirOptionalExpectationTypeChecker ) } diff --git a/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/checkers/type/FirDuplicateParameterNameInFunctionTypeChecker.kt b/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/checkers/type/FirDuplicateParameterNameInFunctionTypeChecker.kt new file mode 100644 index 00000000000..b2235d9f022 --- /dev/null +++ b/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/checkers/type/FirDuplicateParameterNameInFunctionTypeChecker.kt @@ -0,0 +1,37 @@ +/* + * 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.type + +import org.jetbrains.kotlin.builtins.StandardNames +import org.jetbrains.kotlin.diagnostics.DiagnosticReporter +import org.jetbrains.kotlin.diagnostics.reportOn +import org.jetbrains.kotlin.fir.analysis.checkers.context.CheckerContext +import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors +import org.jetbrains.kotlin.fir.declarations.getAnnotationByClassId +import org.jetbrains.kotlin.fir.expressions.FirConstExpression +import org.jetbrains.kotlin.fir.types.FirResolvedTypeRef +import org.jetbrains.kotlin.fir.types.FirTypeRef +import org.jetbrains.kotlin.fir.types.customAnnotations +import org.jetbrains.kotlin.fir.types.type + +object FirDuplicateParameterNameInFunctionTypeChecker : FirTypeRefChecker() { + override fun check(typeRef: FirTypeRef, context: CheckerContext, reporter: DiagnosticReporter) { + if (typeRef !is FirResolvedTypeRef) return + + val nameToArgumentProjection = typeRef.type.typeArguments.dropLast(1).groupBy { + val type = it.type ?: return@groupBy null + val annotation = type.customAnnotations.getAnnotationByClassId(StandardNames.FqNames.parameterNameClassId, context.session) + val nameEntry = annotation?.argumentMapping?.mapping?.get(StandardNames.NAME) + (nameEntry as? FirConstExpression<*>)?.value as? String + } + + for ((name, projections) in nameToArgumentProjection) { + if (name != null && projections.size >= 2) { + reporter.reportOn(typeRef.source, FirErrors.DUPLICATE_PARAMETER_NAME_IN_FUNCTION_TYPE, context) + } + } + } +} 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 9ea9d96c249..ba59fc31f37 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 @@ -192,6 +192,7 @@ import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.DESERIALIZATION_E import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.DIVISION_BY_ZERO import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.DSL_SCOPE_VIOLATION import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.DUPLICATE_LABEL_IN_WHEN +import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.DUPLICATE_PARAMETER_NAME_IN_FUNCTION_TYPE import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.DYNAMIC_NOT_ALLOWED import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.DYNAMIC_RECEIVER_NOT_ALLOWED import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.DYNAMIC_SUPERTYPE @@ -769,6 +770,7 @@ object FirErrorsDefaultMessages : BaseDiagnosticRendererFactory() { map.put(MISSING_CONSTRUCTOR_KEYWORD, "Use the 'constructor' keyword after the modifiers of the primary constructor.") map.put(UNRESOLVED_REFERENCE, "Unresolved reference ''{0}''.", NULLABLE_STRING) map.put(UNRESOLVED_IMPORT, "Unresolved reference ''{0}''.", NULLABLE_STRING) // & + map.put(DUPLICATE_PARAMETER_NAME_IN_FUNCTION_TYPE, "Duplicate parameter name in a function type.") map.put(UNRESOLVED_LABEL, "Unresolved label.") map.put(DESERIALIZATION_ERROR, "Deserialization error.") map.put(ERROR_FROM_JAVA_RESOLUTION, "Java resolution error.") diff --git a/compiler/testData/diagnostics/tests/redeclarations/DuplicateParameterNamesInFunctionType.fir.kt b/compiler/testData/diagnostics/tests/redeclarations/DuplicateParameterNamesInFunctionType.fir.kt index 5d6770c5b77..7966ee1d112 100644 --- a/compiler/testData/diagnostics/tests/redeclarations/DuplicateParameterNamesInFunctionType.fir.kt +++ b/compiler/testData/diagnostics/tests/redeclarations/DuplicateParameterNamesInFunctionType.fir.kt @@ -2,6 +2,6 @@ fun test0(f: (String, String) -> Unit) { f("", "") } -fun test1(f: (a: Int, a: Int) -> Unit) { +fun test1(f: (a: Int, a: Int) -> Unit) { f(1, 1) } \ No newline at end of file