Skip to content

Commit 2c83718

Browse files
committed
Prohibit having duplicate parameter names in functional types
#KT-15804 Fixed
1 parent 9908212 commit 2c83718

File tree

6 files changed

+33
-0
lines changed

6 files changed

+33
-0
lines changed

compiler/frontend/src/org/jetbrains/kotlin/diagnostics/Errors.java

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -79,6 +79,7 @@ public interface Errors {
7979
DiagnosticFactory1.create(ERROR, FOR_REDECLARATION);
8080
DiagnosticFactory1<PsiElement, String> PACKAGE_OR_CLASSIFIER_REDECLARATION =
8181
DiagnosticFactory1.create(ERROR, FOR_REDECLARATION);
82+
DiagnosticFactory0<KtParameter> DUPLICATE_PARAMETER_NAME_IN_FUNCTION_TYPE = DiagnosticFactory0.create(ERROR, DECLARATION_NAME);
8283

8384
DiagnosticFactory1<KtDeclaration, CallableMemberDescriptor> EXTENSION_SHADOWED_BY_MEMBER =
8485
DiagnosticFactory1.create(WARNING, FOR_REDECLARATION);

compiler/frontend/src/org/jetbrains/kotlin/diagnostics/rendering/DefaultErrorMessages.java

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -114,6 +114,7 @@ public static DiagnosticRenderer getRendererForDiagnostic(@NotNull Diagnostic di
114114

115115
MAP.put(REDECLARATION, "Conflicting declarations: {0}", commaSeparated(COMPACT_WITH_MODIFIERS));
116116
MAP.put(PACKAGE_OR_CLASSIFIER_REDECLARATION, "Redeclaration: {0}", STRING);
117+
MAP.put(DUPLICATE_PARAMETER_NAME_IN_FUNCTION_TYPE, "Duplicate parameter name in function type");
117118

118119
MAP.put(NAME_SHADOWING, "Name shadowed: {0}", STRING);
119120
MAP.put(ACCESSOR_PARAMETER_NAME_SHADOWING, "Accessor parameter name 'field' is shadowed by backing field variable");

compiler/frontend/src/org/jetbrains/kotlin/resolve/TypeResolver.kt

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -48,13 +48,15 @@ import org.jetbrains.kotlin.resolve.scopes.LexicalScopeKind
4848
import org.jetbrains.kotlin.resolve.scopes.MemberScope
4949
import org.jetbrains.kotlin.resolve.scopes.utils.findFirstFromMeAndParent
5050
import org.jetbrains.kotlin.resolve.source.KotlinSourceElement
51+
import org.jetbrains.kotlin.resolve.source.getPsi
5152
import org.jetbrains.kotlin.resolve.source.toSourceElement
5253
import org.jetbrains.kotlin.storage.LockBasedStorageManager
5354
import org.jetbrains.kotlin.types.*
5455
import org.jetbrains.kotlin.types.Variance.*
5556
import org.jetbrains.kotlin.types.typeUtil.containsTypeAliasParameters
5657
import org.jetbrains.kotlin.types.typeUtil.containsTypeAliases
5758
import org.jetbrains.kotlin.types.typeUtil.isArrayOfNothing
59+
import org.jetbrains.kotlin.utils.addToStdlib.safeAs
5860

5961
class TypeResolver(
6062
private val annotationResolver: AnnotationResolver,
@@ -231,6 +233,7 @@ class TypeResolver(
231233
val receiverType = if (receiverTypeRef == null) null else resolveType(c.noBareTypes(), receiverTypeRef)
232234

233235
val parameterDescriptors = resolveParametersOfFunctionType(type.parameters)
236+
checkParametersOfFunctionType(parameterDescriptors)
234237

235238
val returnTypeRef = type.returnTypeReference
236239
val returnType = if (returnTypeRef != null) resolveType(c.noBareTypes(), returnTypeRef)
@@ -245,6 +248,17 @@ class TypeResolver(
245248
))
246249
}
247250

251+
private fun checkParametersOfFunctionType(parameterDescriptors: List<VariableDescriptor>) {
252+
val parametersByName = parameterDescriptors.filter { !it.name.isSpecial }.groupBy { it.name }
253+
for (parametersGroup in parametersByName.values) {
254+
if (parametersGroup.size < 2) continue
255+
for (parameter in parametersGroup) {
256+
val ktParameter = parameter.source.getPsi()?.safeAs<KtParameter>() ?: continue
257+
c.trace.report(DUPLICATE_PARAMETER_NAME_IN_FUNCTION_TYPE.on(ktParameter))
258+
}
259+
}
260+
}
261+
248262
private fun resolveParametersOfFunctionType(parameters: List<KtParameter>): List<VariableDescriptor> {
249263
class ParameterOfFunctionTypeDescriptor(
250264
containingDeclaration: DeclarationDescriptor,
Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
fun test0(f: (String, String) -> Unit) {
2+
f("", "")
3+
}
4+
5+
fun test1(f: (<!DUPLICATE_PARAMETER_NAME_IN_FUNCTION_TYPE!>a<!>: Int, <!DUPLICATE_PARAMETER_NAME_IN_FUNCTION_TYPE!>a<!>: Int) -> Unit) {
6+
f(1, 1)
7+
}
Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
package
2+
3+
public fun test0(/*0*/ f: (kotlin.String, kotlin.String) -> kotlin.Unit): kotlin.Unit
4+
public fun test1(/*0*/ f: (a: kotlin.Int, a: kotlin.Int) -> kotlin.Unit): kotlin.Unit

compiler/tests/org/jetbrains/kotlin/checkers/DiagnosticsTestGenerated.java

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16099,6 +16099,12 @@ public void testConflictingExtensionProperties() throws Exception {
1609916099
doTest(fileName);
1610016100
}
1610116101

16102+
@TestMetadata("DuplicateParameterNamesInFunctionType.kt")
16103+
public void testDuplicateParameterNamesInFunctionType() throws Exception {
16104+
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/diagnostics/tests/redeclarations/DuplicateParameterNamesInFunctionType.kt");
16105+
doTest(fileName);
16106+
}
16107+
1610216108
@TestMetadata("EnumName.kt")
1610316109
public void testEnumName() throws Exception {
1610416110
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/diagnostics/tests/redeclarations/EnumName.kt");

0 commit comments

Comments
 (0)