diff --git a/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/diagnostics/FirDiagnosticRenderers.kt b/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/diagnostics/FirDiagnosticRenderers.kt index 70312ce5b7c..bff4bc2427b 100644 --- a/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/diagnostics/FirDiagnosticRenderers.kt +++ b/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/diagnostics/FirDiagnosticRenderers.kt @@ -42,7 +42,7 @@ object FirDiagnosticRenderers { propertyAccessorRenderer = null, callArgumentsRenderer = FirCallNoArgumentsRenderer(), modifierRenderer = FirPartialModifierRenderer(), - valueParameterRenderer = FirValueParameterRendererNoDefaultValue(), + valueParameterRenderer = FirValueParameterRendererForReadability(), declarationRenderer = FirDeclarationRenderer("local "), annotationRenderer = FirAnnotationRendererForReadability(), lineBreakAfterContextReceivers = false, diff --git a/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/diagnostics/FirExpectActualAnnotationIncompatibilityDiagnosticRenderers.kt b/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/diagnostics/FirExpectActualAnnotationIncompatibilityDiagnosticRenderers.kt index 51012c01399..106be9916e3 100644 --- a/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/diagnostics/FirExpectActualAnnotationIncompatibilityDiagnosticRenderers.kt +++ b/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/diagnostics/FirExpectActualAnnotationIncompatibilityDiagnosticRenderers.kt @@ -25,7 +25,7 @@ internal object FirExpectActualAnnotationIncompatibilityDiagnosticRenderers { annotationRenderer = null, modifierRenderer = null, contractRenderer = null, - valueParameterRenderer = FirValueParameterRendererNoDefaultValue(), + valueParameterRenderer = FirValueParameterRendererForReadability(), ).renderElementAsString(it.fir, trim = true) // Write property accessors on the same line as the property .run { replace(Printer.LINE_SEPARATOR, "") } diff --git a/compiler/fir/providers/src/org/jetbrains/kotlin/fir/types/ArrayUtils.kt b/compiler/fir/providers/src/org/jetbrains/kotlin/fir/types/ArrayUtils.kt index 78e4e09ee77..358c5727eb6 100644 --- a/compiler/fir/providers/src/org/jetbrains/kotlin/fir/types/ArrayUtils.kt +++ b/compiler/fir/providers/src/org/jetbrains/kotlin/fir/types/ArrayUtils.kt @@ -6,7 +6,6 @@ package org.jetbrains.kotlin.fir.types import org.jetbrains.kotlin.name.StandardClassIds -import org.jetbrains.kotlin.utils.addToStdlib.runIf val ConeKotlinType.isArrayOrPrimitiveArray: Boolean get() = arrayElementTypeArgument() != null @@ -35,30 +34,6 @@ fun ConeTypeProjection.createArrayType(nullable: Boolean = false, createPrimitiv return StandardClassIds.Array.constructClassLikeType(arrayOf(this), nullable) } -fun ConeKotlinType.arrayElementType(checkUnsignedArrays: Boolean = true): ConeKotlinType? { - return when (val argument = arrayElementTypeArgument(checkUnsignedArrays)) { - is ConeKotlinTypeProjection -> argument.type - else -> null - } -} - -private fun ConeKotlinType.arrayElementTypeArgument(checkUnsignedArrays: Boolean = true): ConeTypeProjection? { - val type = this.lowerBoundIfFlexible() - if (type !is ConeClassLikeType) return null - val classId = type.lookupTag.classId - if (classId == StandardClassIds.Array) { - return type.typeArguments.first() - } - val elementType = StandardClassIds.elementTypeByPrimitiveArrayType[classId] ?: runIf(checkUnsignedArrays) { - StandardClassIds.elementTypeByUnsignedArrayType[classId] - } - if (elementType != null) { - return elementType.constructClassLikeType(emptyArray(), isNullable = false) - } - - return null -} - fun ConeKotlinType.varargElementType(): ConeKotlinType { return this.arrayElementType() ?: this } diff --git a/compiler/fir/tree/src/org/jetbrains/kotlin/fir/renderer/FirRenderer.kt b/compiler/fir/tree/src/org/jetbrains/kotlin/fir/renderer/FirRenderer.kt index 1a67a66df1b..c40948f54a4 100644 --- a/compiler/fir/tree/src/org/jetbrains/kotlin/fir/renderer/FirRenderer.kt +++ b/compiler/fir/tree/src/org/jetbrains/kotlin/fir/renderer/FirRenderer.kt @@ -78,7 +78,7 @@ class FirRenderer( propertyAccessorRenderer = null, callArgumentsRenderer = FirCallNoArgumentsRenderer(), modifierRenderer = FirPartialModifierRenderer(), - valueParameterRenderer = FirValueParameterRendererNoDefaultValue(), + valueParameterRenderer = FirValueParameterRendererForReadability(), declarationRenderer = FirDeclarationRenderer("local ") ) } diff --git a/compiler/fir/tree/src/org/jetbrains/kotlin/fir/renderer/FirValueParameterRenderer.kt b/compiler/fir/tree/src/org/jetbrains/kotlin/fir/renderer/FirValueParameterRenderer.kt index d279c950381..9b22d61f065 100644 --- a/compiler/fir/tree/src/org/jetbrains/kotlin/fir/renderer/FirValueParameterRenderer.kt +++ b/compiler/fir/tree/src/org/jetbrains/kotlin/fir/renderer/FirValueParameterRenderer.kt @@ -15,6 +15,7 @@ open class FirValueParameterRenderer { private val annotationRenderer get() = components.annotationRenderer protected val declarationRenderer get() = components.declarationRenderer private val modifierRenderer get() = components.modifierRenderer + protected val typeRenderer get() = components.typeRenderer fun renderParameters(valueParameters: List) { printer.print("(") @@ -34,10 +35,15 @@ open class FirValueParameterRenderer { if (valueParameter.name != SpecialNames.NO_NAME_PROVIDED) { printer.print(valueParameter.name.toString() + ": ") } - valueParameter.returnTypeRef.accept(visitor) + + renderParameterType(valueParameter) renderDefaultValue(valueParameter) } + protected open fun renderParameterType(valueParameter: FirValueParameter) { + valueParameter.returnTypeRef.accept(visitor) + } + protected open fun renderDefaultValue(valueParameter: FirValueParameter) { valueParameter.defaultValue?.let { printer.print(" = ") diff --git a/compiler/fir/tree/src/org/jetbrains/kotlin/fir/renderer/FirValueParameterRendererForReadability.kt b/compiler/fir/tree/src/org/jetbrains/kotlin/fir/renderer/FirValueParameterRendererForReadability.kt new file mode 100644 index 00000000000..5d8f1029730 --- /dev/null +++ b/compiler/fir/tree/src/org/jetbrains/kotlin/fir/renderer/FirValueParameterRendererForReadability.kt @@ -0,0 +1,32 @@ +/* + * Copyright 2010-2022 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.renderer + +import org.jetbrains.kotlin.fir.declarations.FirValueParameter +import org.jetbrains.kotlin.fir.types.FirResolvedTypeRef +import org.jetbrains.kotlin.fir.types.arrayElementType + +class FirValueParameterRendererForReadability : FirValueParameterRenderer() { + override fun renderParameterType(valueParameter: FirValueParameter) { + val returnTypeRef = valueParameter.returnTypeRef + + if (valueParameter.isVararg && returnTypeRef is FirResolvedTypeRef) { + val arrayElementType = returnTypeRef.type.arrayElementType() + if (arrayElementType != null) { + typeRenderer.render(arrayElementType) + return + } + } + + super.renderParameterType(valueParameter) + } + + override fun renderDefaultValue(valueParameter: FirValueParameter) { + valueParameter.defaultValue?.let { + printer.print(" = ...") + } + } +} diff --git a/compiler/fir/tree/src/org/jetbrains/kotlin/fir/renderer/FirValueParameterRendererNoDefaultValue.kt b/compiler/fir/tree/src/org/jetbrains/kotlin/fir/renderer/FirValueParameterRendererNoDefaultValue.kt deleted file mode 100644 index 8507c01506b..00000000000 --- a/compiler/fir/tree/src/org/jetbrains/kotlin/fir/renderer/FirValueParameterRendererNoDefaultValue.kt +++ /dev/null @@ -1,16 +0,0 @@ -/* - * Copyright 2010-2022 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.renderer - -import org.jetbrains.kotlin.fir.declarations.FirValueParameter - -class FirValueParameterRendererNoDefaultValue : FirValueParameterRenderer() { - override fun renderDefaultValue(valueParameter: FirValueParameter) { - valueParameter.defaultValue?.let { - printer.print(" = ...") - } - } -} diff --git a/compiler/fir/tree/src/org/jetbrains/kotlin/fir/types/FirTypeUtils.kt b/compiler/fir/tree/src/org/jetbrains/kotlin/fir/types/FirTypeUtils.kt index 636673d37d3..e6912cec87e 100644 --- a/compiler/fir/tree/src/org/jetbrains/kotlin/fir/types/FirTypeUtils.kt +++ b/compiler/fir/tree/src/org/jetbrains/kotlin/fir/types/FirTypeUtils.kt @@ -11,6 +11,7 @@ import org.jetbrains.kotlin.fir.utils.exceptions.withFirEntry import org.jetbrains.kotlin.name.ClassId import org.jetbrains.kotlin.name.StandardClassIds import org.jetbrains.kotlin.types.ConstantValueKind +import org.jetbrains.kotlin.utils.addToStdlib.runIf import org.jetbrains.kotlin.utils.exceptions.errorWithAttachment import kotlin.contracts.ExperimentalContracts import kotlin.contracts.contract @@ -155,3 +156,27 @@ fun FirTypeProjection.toConeTypeProjection(): ConeTypeProjection = when (this) { } else -> errorWithAttachment("Unexpected ${this::class.simpleName}") { withFirEntry("projection", this@toConeTypeProjection) } } + +fun ConeKotlinType.arrayElementType(checkUnsignedArrays: Boolean = true): ConeKotlinType? { + return when (val argument = arrayElementTypeArgument(checkUnsignedArrays)) { + is ConeKotlinTypeProjection -> argument.type + else -> null + } +} + +fun ConeKotlinType.arrayElementTypeArgument(checkUnsignedArrays: Boolean = true): ConeTypeProjection? { + val type = this.lowerBoundIfFlexible() + if (type !is ConeClassLikeType) return null + val classId = type.lookupTag.classId + if (classId == StandardClassIds.Array) { + return type.typeArguments.first() + } + val elementType = StandardClassIds.elementTypeByPrimitiveArrayType[classId] ?: runIf(checkUnsignedArrays) { + StandardClassIds.elementTypeByUnsignedArrayType[classId] + } + if (elementType != null) { + return elementType.constructClassLikeType(emptyArray(), isNullable = false) + } + + return null +} \ No newline at end of file diff --git a/compiler/testData/diagnostics/tests/varargs/AmbiguousVararg.diag.txt b/compiler/testData/diagnostics/tests/varargs/AmbiguousVararg.diag.txt new file mode 100644 index 00000000000..21d85a766ec --- /dev/null +++ b/compiler/testData/diagnostics/tests/varargs/AmbiguousVararg.diag.txt @@ -0,0 +1,5 @@ +/AmbiguousVararg.kt:7:5: error: overload resolution ambiguity: +public fun foo(vararg t: String): String defined in root package in file AmbiguousVararg.kt +public fun foo(vararg t: Int): String defined in root package in file AmbiguousVararg.kt + foo() + ^^^ diff --git a/compiler/testData/diagnostics/tests/varargs/AmbiguousVararg.fir.diag.txt b/compiler/testData/diagnostics/tests/varargs/AmbiguousVararg.fir.diag.txt new file mode 100644 index 00000000000..13d55742f7c --- /dev/null +++ b/compiler/testData/diagnostics/tests/varargs/AmbiguousVararg.fir.diag.txt @@ -0,0 +1 @@ +/AmbiguousVararg.kt:(128,131): error: Overload resolution ambiguity between candidates: [fun foo(vararg t: String): String, fun foo(vararg t: Int): String] diff --git a/compiler/testData/diagnostics/tests/varargs/AmbiguousVararg.kt b/compiler/testData/diagnostics/tests/varargs/AmbiguousVararg.kt index 325421019b7..e00aaa4e562 100644 --- a/compiler/testData/diagnostics/tests/varargs/AmbiguousVararg.kt +++ b/compiler/testData/diagnostics/tests/varargs/AmbiguousVararg.kt @@ -1,4 +1,5 @@ // FIR_IDENTICAL +// RENDER_DIAGNOSTICS_FULL_TEXT fun foo(vararg t : String) = "" fun foo(vararg t : Int) = "" diff --git a/compiler/testData/integration/ant/jvm/overloadResolutionOnCollectionLiteral/build.log.expected b/compiler/testData/integration/ant/jvm/overloadResolutionOnCollectionLiteral/build.log.expected index f3652135c3b..1e1396e9ab5 100644 --- a/compiler/testData/integration/ant/jvm/overloadResolutionOnCollectionLiteral/build.log.expected +++ b/compiler/testData/integration/ant/jvm/overloadResolutionOnCollectionLiteral/build.log.expected @@ -5,13 +5,13 @@ build: [mkdir] Created dir: [Temp]/classes [javac] Compiling 2 source files to [Temp]/classes [javac] Compiling [[TestData]] => [[Temp]/classes] - [javac] [TestData]/literals.kt:9:9: error: overload resolution ambiguity between candidates: [fun intArrayOf(vararg elements: IntArray): IntArray, fun intArrayOf(vararg elements: IntArray): IntArray] + [javac] [TestData]/literals.kt:9:9: error: overload resolution ambiguity between candidates: [fun intArrayOf(vararg elements: Int): IntArray, fun intArrayOf(vararg elements: Int): IntArray] [javac] @AnnInt(intArrayOf(1, 2)) [javac] ^^^^^^^^^^ - [javac] [TestData]/myArrayOf.kt:3:1: error: conflicting overloads: [fun intArrayOf(vararg elements: IntArray): IntArray] + [javac] [TestData]/myArrayOf.kt:3:1: error: conflicting overloads: [fun intArrayOf(vararg elements: Int): IntArray] [javac] public fun intArrayOf(vararg elements: Int): IntArray = TODO() [javac] ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - [javac] [TestData]/myArrayOf.kt:4:1: error: conflicting overloads: [fun intArrayOf(vararg elements: IntArray): IntArray] + [javac] [TestData]/myArrayOf.kt:4:1: error: conflicting overloads: [fun intArrayOf(vararg elements: Int): IntArray] [javac] public fun intArrayOf(vararg elements: Int): IntArray = TODO() [javac] ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ diff --git a/compiler/testData/multiplatform/incompatibleCallables/output.txt b/compiler/testData/multiplatform/incompatibleCallables/output.txt index 317ae70ca64..1c4ce51dc97 100644 --- a/compiler/testData/multiplatform/incompatibleCallables/output.txt +++ b/compiler/testData/multiplatform/incompatibleCallables/output.txt @@ -88,11 +88,11 @@ actual fun f16(s: String = "") {} ^^^^^^^^^^^^^^ compiler/testData/multiplatform/incompatibleCallables/jvm.kt:28:12: error: 'actual fun f17(s: Array): Unit' has no corresponding expected declaration The following declaration is incompatible because some value parameter is vararg in one declaration and non-vararg in the other: - expect fun f17(vararg s: Array): Unit + expect fun f17(vararg s: String): Unit actual fun f17(s: Array) {} ^^^ -compiler/testData/multiplatform/incompatibleCallables/jvm.kt:29:12: error: 'actual fun f18(vararg s: Array): Unit' has no corresponding expected declaration +compiler/testData/multiplatform/incompatibleCallables/jvm.kt:29:12: error: 'actual fun f18(vararg s: String): Unit' has no corresponding expected declaration The following declaration is incompatible because some value parameter is vararg in one declaration and non-vararg in the other: expect fun f18(s: Array): Unit