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 1a5fc1152a1..cc1014b2f07 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 @@ -166,6 +166,8 @@ object DIAGNOSTICS_LIST : DiagnosticList() { val INAPPLICABLE_LATEINIT_MODIFIER by error(PositioningStrategy.LATEINIT_MODIFIER) { parameter("reason") } + + val VARARG_OUTSIDE_PARENTHESES by error() } val AMBIGUITY by object : DiagnosticGroup("Ambiguity") { 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 cf3f00d299a..8d43990af5f 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 @@ -145,6 +145,7 @@ object FirErrors { val NONE_APPLICABLE by error1>>(SourceElementPositioningStrategies.REFERENCE_BY_QUALIFIED) val INAPPLICABLE_CANDIDATE by error1>(SourceElementPositioningStrategies.REFERENCE_BY_QUALIFIED) val INAPPLICABLE_LATEINIT_MODIFIER by error1(SourceElementPositioningStrategies.LATEINIT_MODIFIER) + val VARARG_OUTSIDE_PARENTHESES by error0() // Ambiguity val AMBIGUITY by error1>>(SourceElementPositioningStrategies.REFERENCE_BY_QUALIFIED) diff --git a/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/diagnostics/FirDefaultErrorMessages.kt b/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/diagnostics/FirDefaultErrorMessages.kt index a8f93e6c14a..1a369ce9bd6 100644 --- a/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/diagnostics/FirDefaultErrorMessages.kt +++ b/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/diagnostics/FirDefaultErrorMessages.kt @@ -173,6 +173,7 @@ import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.UPPER_BOUND_VIOLA import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.USELESS_VARARG_ON_PARAMETER import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.VAL_REASSIGNMENT import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.VAL_WITH_SETTER +import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.VARARG_OUTSIDE_PARENTHESES import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.VARIABLE_EXPECTED import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.VARIABLE_INITIALIZER_IS_REDUNDANT import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.VARIABLE_NEVER_READ @@ -323,6 +324,7 @@ class FirDefaultErrorMessages : DefaultErrorMessages.Extension { map.put(NONE_APPLICABLE, "None of the following functions are applicable: {0}", SYMBOLS) map.put(INAPPLICABLE_CANDIDATE, "Inapplicable candidate(s): {0}", SYMBOL) map.put(INAPPLICABLE_LATEINIT_MODIFIER, "''lateinit'' modifier {0}", TO_STRING) + map.put(VARARG_OUTSIDE_PARENTHESES, "Passing value as a vararg is only allowed inside a parenthesized argument list") // Ambiguity map.put(AMBIGUITY, "Ambiguity between candidates: {0}", SYMBOLS) diff --git a/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/diagnostics/coneDiagnosticToFirDiagnostic.kt b/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/diagnostics/coneDiagnosticToFirDiagnostic.kt index b5b953cde2e..3eafa0579cd 100644 --- a/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/diagnostics/coneDiagnosticToFirDiagnostic.kt +++ b/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/diagnostics/coneDiagnosticToFirDiagnostic.kt @@ -14,6 +14,7 @@ import org.jetbrains.kotlin.fir.declarations.isInfix import org.jetbrains.kotlin.fir.declarations.isOperator import org.jetbrains.kotlin.fir.diagnostics.* import org.jetbrains.kotlin.fir.resolve.calls.InapplicableWrongReceiver +import org.jetbrains.kotlin.fir.resolve.calls.VarargArgumentOutsideParentheses import org.jetbrains.kotlin.fir.resolve.diagnostics.* import org.jetbrains.kotlin.fir.types.* import org.jetbrains.kotlin.lexer.KtTokens @@ -95,7 +96,11 @@ private fun mapInapplicableCandidateError( return FirErrors.UNSAFE_CALL.on(source, rootCause.actualType!!) } - return FirErrors.INAPPLICABLE_CANDIDATE.on(source, diagnostic.candidate.symbol) + + return when (rootCause) { + is VarargArgumentOutsideParentheses -> FirErrors.VARARG_OUTSIDE_PARENTHESES.on(rootCause.argument.source ?: source) + else -> FirErrors.INAPPLICABLE_CANDIDATE.on(source, diagnostic.candidate.symbol) + } } private fun ConeSimpleDiagnostic.getFactory(): FirDiagnosticFactory0 { @@ -126,4 +131,4 @@ private fun ConeSimpleDiagnostic.getFactory(): FirDiagnosticFactory0 FirErrors.OTHER_ERROR else -> throw IllegalArgumentException("Unsupported diagnostic kind: $kind at $javaClass") } -} \ No newline at end of file +} diff --git a/compiler/testData/diagnostics/tests/Varargs.fir.kt b/compiler/testData/diagnostics/tests/Varargs.fir.kt index eaf84907d22..310854f59e0 100644 --- a/compiler/testData/diagnostics/tests/Varargs.fir.kt +++ b/compiler/testData/diagnostics/tests/Varargs.fir.kt @@ -12,6 +12,6 @@ fun test() { v1({}, {}) v1({}, 1, {}) v1({}, {}, {it}) - v1({}) {} - v1 {} -} \ No newline at end of file + v1({}) {} + v1 {} +} diff --git a/compiler/testData/diagnostics/tests/resolve/newLineLambda.fir.kt b/compiler/testData/diagnostics/tests/resolve/newLineLambda.fir.kt index a6deacbc8f9..94f3778182d 100644 --- a/compiler/testData/diagnostics/tests/resolve/newLineLambda.fir.kt +++ b/compiler/testData/diagnostics/tests/resolve/newLineLambda.fir.kt @@ -69,23 +69,23 @@ fun testLambdaArg() { fun testVararg() { varargFn(1,2,3) - varargFn {} - varargFn(1,2,3) {} + varargFn {} + varargFn(1,2,3) {} varargFn(1,2,3) // {} - varargFn(1,2,3) /* */ {} - varargFn(1,2,3) /* + varargFn(1,2,3) /* */ {} + varargFn(1,2,3) /* block comment, no new line - */ {} - varargFn(1,2,3) + */ {} + varargFn(1,2,3) /* block comment with new line - */ {} - varargFn(1,2,3) // comment + */ {} + varargFn(1,2,3) // comment // comment - {} - varargFn(1,2,3) {} {} - varargFn(1,2,3) {} - {} + {} + varargFn(1,2,3) {} {} + varargFn(1,2,3) {} + {} } fun testTwoLambdas() { diff --git a/idea/idea-frontend-fir/src/org/jetbrains/kotlin/idea/frontend/api/fir/diagnostics/KtFirDataClassConverters.kt b/idea/idea-frontend-fir/src/org/jetbrains/kotlin/idea/frontend/api/fir/diagnostics/KtFirDataClassConverters.kt index 416a9f2a196..1130250376c 100644 --- a/idea/idea-frontend-fir/src/org/jetbrains/kotlin/idea/frontend/api/fir/diagnostics/KtFirDataClassConverters.kt +++ b/idea/idea-frontend-fir/src/org/jetbrains/kotlin/idea/frontend/api/fir/diagnostics/KtFirDataClassConverters.kt @@ -24,6 +24,7 @@ import org.jetbrains.kotlin.psi.KtFunction import org.jetbrains.kotlin.psi.KtIfExpression import org.jetbrains.kotlin.psi.KtModifierListOwner import org.jetbrains.kotlin.psi.KtNamedDeclaration +import org.jetbrains.kotlin.psi.KtObjectDeclaration import org.jetbrains.kotlin.psi.KtParameter import org.jetbrains.kotlin.psi.KtProperty import org.jetbrains.kotlin.psi.KtPropertyAccessor @@ -539,6 +540,12 @@ internal val KT_DIAGNOSTIC_CONVERTER = KtDiagnosticConverterBuilder.buildConvert token, ) } + add(FirErrors.VARARG_OUTSIDE_PARENTHESES) { firDiagnostic -> + VarargOutsideParenthesesImpl( + firDiagnostic as FirPsiDiagnostic<*>, + token, + ) + } add(FirErrors.AMBIGUITY) { firDiagnostic -> AmbiguityImpl( firDiagnostic.a.map { abstractFirBasedSymbol -> diff --git a/idea/idea-frontend-fir/src/org/jetbrains/kotlin/idea/frontend/api/fir/diagnostics/KtFirDiagnostics.kt b/idea/idea-frontend-fir/src/org/jetbrains/kotlin/idea/frontend/api/fir/diagnostics/KtFirDiagnostics.kt index ba273c43063..23da3e760bc 100644 --- a/idea/idea-frontend-fir/src/org/jetbrains/kotlin/idea/frontend/api/fir/diagnostics/KtFirDiagnostics.kt +++ b/idea/idea-frontend-fir/src/org/jetbrains/kotlin/idea/frontend/api/fir/diagnostics/KtFirDiagnostics.kt @@ -28,6 +28,7 @@ import org.jetbrains.kotlin.psi.KtFunction import org.jetbrains.kotlin.psi.KtIfExpression import org.jetbrains.kotlin.psi.KtModifierListOwner import org.jetbrains.kotlin.psi.KtNamedDeclaration +import org.jetbrains.kotlin.psi.KtObjectDeclaration import org.jetbrains.kotlin.psi.KtParameter import org.jetbrains.kotlin.psi.KtProperty import org.jetbrains.kotlin.psi.KtPropertyAccessor @@ -389,6 +390,10 @@ sealed class KtFirDiagnostic : KtDiagnosticWithPsi { abstract val reason: String } + abstract class VarargOutsideParentheses : KtFirDiagnostic() { + override val diagnosticClass get() = VarargOutsideParentheses::class + } + abstract class Ambiguity : KtFirDiagnostic() { override val diagnosticClass get() = Ambiguity::class abstract val candidates: List @@ -535,7 +540,7 @@ sealed class KtFirDiagnostic : KtDiagnosticWithPsi { override val diagnosticClass get() = NonFinalMemberInObject::class } - abstract class ManyCompanionObjects : KtFirDiagnostic() { + abstract class ManyCompanionObjects : KtFirDiagnostic() { override val diagnosticClass get() = ManyCompanionObjects::class } diff --git a/idea/idea-frontend-fir/src/org/jetbrains/kotlin/idea/frontend/api/fir/diagnostics/KtFirDiagnosticsImpl.kt b/idea/idea-frontend-fir/src/org/jetbrains/kotlin/idea/frontend/api/fir/diagnostics/KtFirDiagnosticsImpl.kt index cd6c39f9402..a0ac3680b5f 100644 --- a/idea/idea-frontend-fir/src/org/jetbrains/kotlin/idea/frontend/api/fir/diagnostics/KtFirDiagnosticsImpl.kt +++ b/idea/idea-frontend-fir/src/org/jetbrains/kotlin/idea/frontend/api/fir/diagnostics/KtFirDiagnosticsImpl.kt @@ -30,6 +30,7 @@ import org.jetbrains.kotlin.psi.KtFunction import org.jetbrains.kotlin.psi.KtIfExpression import org.jetbrains.kotlin.psi.KtModifierListOwner import org.jetbrains.kotlin.psi.KtNamedDeclaration +import org.jetbrains.kotlin.psi.KtObjectDeclaration import org.jetbrains.kotlin.psi.KtParameter import org.jetbrains.kotlin.psi.KtProperty import org.jetbrains.kotlin.psi.KtPropertyAccessor @@ -618,6 +619,13 @@ internal class InapplicableLateinitModifierImpl( override val firDiagnostic: FirPsiDiagnostic<*> by weakRef(firDiagnostic) } +internal class VarargOutsideParenthesesImpl( + firDiagnostic: FirPsiDiagnostic<*>, + override val token: ValidityToken, +) : KtFirDiagnostic.VarargOutsideParentheses(), KtAbstractFirDiagnostic { + override val firDiagnostic: FirPsiDiagnostic<*> by weakRef(firDiagnostic) +} + internal class AmbiguityImpl( override val candidates: List, firDiagnostic: FirPsiDiagnostic<*>, @@ -857,7 +865,7 @@ internal class NonFinalMemberInObjectImpl( internal class ManyCompanionObjectsImpl( firDiagnostic: FirPsiDiagnostic<*>, override val token: ValidityToken, -) : KtFirDiagnostic.ManyCompanionObjects(), KtAbstractFirDiagnostic { +) : KtFirDiagnostic.ManyCompanionObjects(), KtAbstractFirDiagnostic { override val firDiagnostic: FirPsiDiagnostic<*> by weakRef(firDiagnostic) }