[FIR] Implement MANY_LAMBDA_EXPRESSION_ARGUMENTS diagnostics, fix tests
This commit is contained in:
committed by
TeamCityServer
parent
b8002cb54f
commit
525cc6df97
+2
@@ -255,6 +255,8 @@ object DIAGNOSTICS_LIST : DiagnosticList() {
|
|||||||
val NAMED_PARAMETER_NOT_FOUND by error<KtValueArgument>(PositioningStrategy.NAME_OF_NAMED_ARGUMENT) {
|
val NAMED_PARAMETER_NOT_FOUND by error<KtValueArgument>(PositioningStrategy.NAME_OF_NAMED_ARGUMENT) {
|
||||||
parameter<String>("name")
|
parameter<String>("name")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
val MANY_LAMBDA_EXPRESSION_ARGUMENTS by error<KtValueArgument>()
|
||||||
}
|
}
|
||||||
|
|
||||||
val AMBIGUITY by object : DiagnosticGroup("Ambiguity") {
|
val AMBIGUITY by object : DiagnosticGroup("Ambiguity") {
|
||||||
|
|||||||
@@ -212,6 +212,7 @@ object FirErrors {
|
|||||||
val TOO_MANY_ARGUMENTS by error1<PsiElement, FirCallableDeclaration<*>>()
|
val TOO_MANY_ARGUMENTS by error1<PsiElement, FirCallableDeclaration<*>>()
|
||||||
val NO_VALUE_FOR_PARAMETER by error1<KtElement, FirValueParameter>(SourceElementPositioningStrategies.VALUE_ARGUMENTS)
|
val NO_VALUE_FOR_PARAMETER by error1<KtElement, FirValueParameter>(SourceElementPositioningStrategies.VALUE_ARGUMENTS)
|
||||||
val NAMED_PARAMETER_NOT_FOUND by error1<KtValueArgument, String>(SourceElementPositioningStrategies.NAME_OF_NAMED_ARGUMENT)
|
val NAMED_PARAMETER_NOT_FOUND by error1<KtValueArgument, String>(SourceElementPositioningStrategies.NAME_OF_NAMED_ARGUMENT)
|
||||||
|
val MANY_LAMBDA_EXPRESSION_ARGUMENTS by error0<KtValueArgument>()
|
||||||
|
|
||||||
// Ambiguity
|
// Ambiguity
|
||||||
val OVERLOAD_RESOLUTION_AMBIGUITY by error1<PsiElement, Collection<AbstractFirBasedSymbol<*>>>(SourceElementPositioningStrategies.REFERENCE_BY_QUALIFIED)
|
val OVERLOAD_RESOLUTION_AMBIGUITY by error1<PsiElement, Collection<AbstractFirBasedSymbol<*>>>(SourceElementPositioningStrategies.REFERENCE_BY_QUALIFIED)
|
||||||
|
|||||||
+2
@@ -155,6 +155,7 @@ import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.LOCAL_OBJECT_NOT_
|
|||||||
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.MANY_COMPANION_OBJECTS
|
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.MANY_COMPANION_OBJECTS
|
||||||
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.MANY_IMPL_MEMBER_NOT_IMPLEMENTED
|
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.MANY_IMPL_MEMBER_NOT_IMPLEMENTED
|
||||||
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.MANY_INTERFACES_MEMBER_NOT_IMPLEMENTED
|
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.MANY_INTERFACES_MEMBER_NOT_IMPLEMENTED
|
||||||
|
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.MANY_LAMBDA_EXPRESSION_ARGUMENTS
|
||||||
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.METHOD_OF_ANY_IMPLEMENTED_IN_INTERFACE
|
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.METHOD_OF_ANY_IMPLEMENTED_IN_INTERFACE
|
||||||
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.MISPLACED_TYPE_PARAMETER_CONSTRAINTS
|
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.MISPLACED_TYPE_PARAMETER_CONSTRAINTS
|
||||||
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.MISSING_VAL_ON_ANNOTATION_PARAMETER
|
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.MISSING_VAL_ON_ANNOTATION_PARAMETER
|
||||||
@@ -461,6 +462,7 @@ class FirDefaultErrorMessages : DefaultErrorMessages.Extension {
|
|||||||
map.put(ARGUMENT_PASSED_TWICE, "An argument is already passed for this parameter")
|
map.put(ARGUMENT_PASSED_TWICE, "An argument is already passed for this parameter")
|
||||||
map.put(NO_VALUE_FOR_PARAMETER, "No value passed for parameter ''{0}''", NAME)
|
map.put(NO_VALUE_FOR_PARAMETER, "No value passed for parameter ''{0}''", NAME)
|
||||||
map.put(NAMED_PARAMETER_NOT_FOUND, "Cannot find a parameter with this name: {0}", TO_STRING)
|
map.put(NAMED_PARAMETER_NOT_FOUND, "Cannot find a parameter with this name: {0}", TO_STRING)
|
||||||
|
map.put(MANY_LAMBDA_EXPRESSION_ARGUMENTS, "Only one lambda expression is allowed outside a parenthesized argument list")
|
||||||
|
|
||||||
map.put(ARGUMENT_TYPE_MISMATCH, "Argument type mismatch: actual type is {1} but {0} was expected", TO_STRING, TO_STRING)
|
map.put(ARGUMENT_TYPE_MISMATCH, "Argument type mismatch: actual type is {1} but {0} was expected", TO_STRING, TO_STRING)
|
||||||
|
|
||||||
|
|||||||
+1
@@ -142,6 +142,7 @@ private fun mapInapplicableCandidateError(
|
|||||||
rootCause.argument.name.asString()
|
rootCause.argument.name.asString()
|
||||||
)
|
)
|
||||||
is UnsafeCall -> mapUnsafeCallError(diagnostic.candidate, rootCause, source, qualifiedAccessSource)
|
is UnsafeCall -> mapUnsafeCallError(diagnostic.candidate, rootCause, source, qualifiedAccessSource)
|
||||||
|
is ManyLambdaExpressionArguments -> FirErrors.MANY_LAMBDA_EXPRESSION_ARGUMENTS.on(rootCause.argument.source ?: source)
|
||||||
else -> null
|
else -> null
|
||||||
}
|
}
|
||||||
}.ifEmpty { listOf(FirErrors.INAPPLICABLE_CANDIDATE.on(source, diagnostic.candidate.symbol)) }
|
}.ifEmpty { listOf(FirErrors.INAPPLICABLE_CANDIDATE.on(source, diagnostic.candidate.symbol)) }
|
||||||
|
|||||||
+21
-6
@@ -61,11 +61,20 @@ fun BodyResolveComponents.mapArguments(
|
|||||||
if (arguments.isEmpty() && function.valueParameters.isEmpty()) {
|
if (arguments.isEmpty() && function.valueParameters.isEmpty()) {
|
||||||
return EmptyArgumentMapping
|
return EmptyArgumentMapping
|
||||||
}
|
}
|
||||||
val externalArgument: FirExpression? = arguments.lastOrNull { it is FirLambdaArgumentExpression }
|
|
||||||
var argumentsInParenthesis: List<FirExpression> = if (externalArgument == null) {
|
val argumentsInParenthesis: MutableList<FirExpression> = mutableListOf()
|
||||||
arguments
|
val excessLambdaArguments: MutableList<FirExpression> = mutableListOf()
|
||||||
} else {
|
var externalArgument: FirExpression? = null
|
||||||
arguments.subList(0, arguments.size - 1)
|
for (argument in arguments) {
|
||||||
|
if (argument is FirLambdaArgumentExpression) {
|
||||||
|
if (externalArgument == null) {
|
||||||
|
externalArgument = argument
|
||||||
|
} else {
|
||||||
|
excessLambdaArguments.add(argument)
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
argumentsInParenthesis.add(argument)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// If this is an overloading indexed access operator, it could have default values or a vararg parameter in the middle.
|
// If this is an overloading indexed access operator, it could have default values or a vararg parameter in the middle.
|
||||||
@@ -82,7 +91,8 @@ fun BodyResolveComponents.mapArguments(
|
|||||||
isSpread = false
|
isSpread = false
|
||||||
name = function.valueParameters.last().name
|
name = function.valueParameters.last().name
|
||||||
}
|
}
|
||||||
argumentsInParenthesis = argumentsInParenthesis.dropLast(1) + listOf(namedV)
|
argumentsInParenthesis.removeAt(argumentsInParenthesis.size - 1)
|
||||||
|
argumentsInParenthesis.add(namedV)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -91,6 +101,7 @@ fun BodyResolveComponents.mapArguments(
|
|||||||
if (externalArgument != null) {
|
if (externalArgument != null) {
|
||||||
processor.processExternalArgument(externalArgument)
|
processor.processExternalArgument(externalArgument)
|
||||||
}
|
}
|
||||||
|
processor.processExcessLambdaArguments(excessLambdaArguments)
|
||||||
processor.processDefaultsAndRunChecks()
|
processor.processDefaultsAndRunChecks()
|
||||||
|
|
||||||
return ArgumentMapping(processor.result, processor.diagnostics ?: emptyList())
|
return ArgumentMapping(processor.result, processor.diagnostics ?: emptyList())
|
||||||
@@ -212,6 +223,10 @@ private class FirCallArgumentsProcessor(
|
|||||||
result[lastParameter] = ResolvedCallArgument.SimpleArgument(externalArgument)
|
result[lastParameter] = ResolvedCallArgument.SimpleArgument(externalArgument)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fun processExcessLambdaArguments(excessLambdaArguments: List<FirExpression>) {
|
||||||
|
excessLambdaArguments.forEach { arg -> addDiagnostic(ManyLambdaExpressionArguments(arg)) }
|
||||||
|
}
|
||||||
|
|
||||||
fun processDefaultsAndRunChecks() {
|
fun processDefaultsAndRunChecks() {
|
||||||
for ((parameter, resolvedArgument) in result) {
|
for ((parameter, resolvedArgument) in result) {
|
||||||
if (!parameter.isVararg) {
|
if (!parameter.isVararg) {
|
||||||
|
|||||||
+5
-1
@@ -97,4 +97,8 @@ class ArgumentTypeMismatch(
|
|||||||
|
|
||||||
class NullForNotNullType(
|
class NullForNotNullType(
|
||||||
val argument: FirExpression
|
val argument: FirExpression
|
||||||
) : ResolutionDiagnostic(INAPPLICABLE)
|
) : ResolutionDiagnostic(INAPPLICABLE)
|
||||||
|
|
||||||
|
class ManyLambdaExpressionArguments(
|
||||||
|
val argument: FirExpression
|
||||||
|
) : ResolutionDiagnostic(INAPPLICABLE_ARGUMENTS_MAPPING_ERROR)
|
||||||
+1
-1
@@ -25,5 +25,5 @@ fun test() {
|
|||||||
|
|
||||||
foo("", 1) <!TOO_MANY_ARGUMENTS!>{}<!>
|
foo("", 1) <!TOO_MANY_ARGUMENTS!>{}<!>
|
||||||
|
|
||||||
foo("", 1) <!TOO_MANY_ARGUMENTS!>{}<!> <!TOO_MANY_ARGUMENTS!>{}<!>
|
foo("", 1) <!TOO_MANY_ARGUMENTS!>{}<!> <!MANY_LAMBDA_EXPRESSION_ARGUMENTS!>{}<!>
|
||||||
}
|
}
|
||||||
|
|||||||
+3
-3
@@ -6,9 +6,9 @@ fun test(x: () -> Unit, y: () -> Unit) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fun main() {
|
fun main() {
|
||||||
test {
|
<!NO_VALUE_FOR_PARAMETER!>test {
|
||||||
1
|
1
|
||||||
} {
|
} <!MANY_LAMBDA_EXPRESSION_ARGUMENTS!>{
|
||||||
2
|
2
|
||||||
}
|
}<!><!>
|
||||||
}
|
}
|
||||||
@@ -23,9 +23,9 @@ fun testNoArgs() {
|
|||||||
noArgs() // comment
|
noArgs() // comment
|
||||||
// comment
|
// comment
|
||||||
<!TOO_MANY_ARGUMENTS!>{}<!>
|
<!TOO_MANY_ARGUMENTS!>{}<!>
|
||||||
noArgs() <!TOO_MANY_ARGUMENTS!>{}<!> <!TOO_MANY_ARGUMENTS!>{}<!>
|
noArgs() <!TOO_MANY_ARGUMENTS!>{}<!> <!MANY_LAMBDA_EXPRESSION_ARGUMENTS!>{}<!>
|
||||||
noArgs() <!TOO_MANY_ARGUMENTS!>{}<!>
|
noArgs() <!TOO_MANY_ARGUMENTS!>{}<!>
|
||||||
<!TOO_MANY_ARGUMENTS!>{}<!>
|
<!MANY_LAMBDA_EXPRESSION_ARGUMENTS!>{}<!>
|
||||||
}
|
}
|
||||||
|
|
||||||
fun testLambdaArg() {
|
fun testLambdaArg() {
|
||||||
@@ -35,7 +35,7 @@ fun testLambdaArg() {
|
|||||||
{}
|
{}
|
||||||
oneLambdaArg()
|
oneLambdaArg()
|
||||||
{}
|
{}
|
||||||
<!TOO_MANY_ARGUMENTS!>{}<!>
|
<!MANY_LAMBDA_EXPRESSION_ARGUMENTS!>{}<!>
|
||||||
oneLambdaArg(
|
oneLambdaArg(
|
||||||
{},
|
{},
|
||||||
<!TOO_MANY_ARGUMENTS!>{}<!>
|
<!TOO_MANY_ARGUMENTS!>{}<!>
|
||||||
@@ -52,19 +52,19 @@ fun testLambdaArg() {
|
|||||||
{}
|
{}
|
||||||
oneLambdaArg() {}/*
|
oneLambdaArg() {}/*
|
||||||
block comment, no new line
|
block comment, no new line
|
||||||
*/ <!TOO_MANY_ARGUMENTS!>{}<!>
|
*/ <!MANY_LAMBDA_EXPRESSION_ARGUMENTS!>{}<!>
|
||||||
oneLambdaArg() {}/*
|
oneLambdaArg() {}/*
|
||||||
block comment with new line
|
block comment with new line
|
||||||
*/
|
*/
|
||||||
<!TOO_MANY_ARGUMENTS!>{}<!>
|
<!MANY_LAMBDA_EXPRESSION_ARGUMENTS!>{}<!>
|
||||||
oneLambdaArg() {}// comment
|
oneLambdaArg() {}// comment
|
||||||
// comment
|
// comment
|
||||||
<!TOO_MANY_ARGUMENTS!>{}<!>
|
<!MANY_LAMBDA_EXPRESSION_ARGUMENTS!>{}<!>
|
||||||
oneLambdaArg() {} <!TOO_MANY_ARGUMENTS!>{}<!>
|
oneLambdaArg() {} <!MANY_LAMBDA_EXPRESSION_ARGUMENTS!>{}<!>
|
||||||
oneLambdaArg() {}
|
oneLambdaArg() {}
|
||||||
<!TOO_MANY_ARGUMENTS!>{}<!>
|
<!MANY_LAMBDA_EXPRESSION_ARGUMENTS!>{}<!>
|
||||||
oneLambdaArg() {} // comment
|
oneLambdaArg() {} // comment
|
||||||
<!TOO_MANY_ARGUMENTS!>{}<!>
|
<!MANY_LAMBDA_EXPRESSION_ARGUMENTS!>{}<!>
|
||||||
}
|
}
|
||||||
|
|
||||||
fun testVararg() {
|
fun testVararg() {
|
||||||
@@ -83,9 +83,9 @@ fun testVararg() {
|
|||||||
varargFn(1,2,3) // comment
|
varargFn(1,2,3) // comment
|
||||||
// comment
|
// comment
|
||||||
<!VARARG_OUTSIDE_PARENTHESES!>{}<!>
|
<!VARARG_OUTSIDE_PARENTHESES!>{}<!>
|
||||||
varargFn(1,2,3) <!ARGUMENT_TYPE_MISMATCH!>{}<!> <!ARGUMENT_TYPE_MISMATCH, VARARG_OUTSIDE_PARENTHESES!>{}<!>
|
varargFn(1,2,3) {} <!MANY_LAMBDA_EXPRESSION_ARGUMENTS!>{}<!>
|
||||||
varargFn(1,2,3) <!ARGUMENT_TYPE_MISMATCH!>{}<!>
|
varargFn(1,2,3) {}
|
||||||
<!ARGUMENT_TYPE_MISMATCH, VARARG_OUTSIDE_PARENTHESES!>{}<!>
|
<!MANY_LAMBDA_EXPRESSION_ARGUMENTS!>{}<!>
|
||||||
}
|
}
|
||||||
|
|
||||||
fun testTwoLambdas() {
|
fun testTwoLambdas() {
|
||||||
@@ -96,14 +96,14 @@ fun testTwoLambdas() {
|
|||||||
)
|
)
|
||||||
|
|
||||||
fun bar(): () -> Unit {
|
fun bar(): () -> Unit {
|
||||||
twoLambdaArgs()
|
twoLambdaArgs(<!NO_VALUE_FOR_PARAMETER!>)<!>
|
||||||
{}
|
|
||||||
{}
|
{}
|
||||||
|
<!MANY_LAMBDA_EXPRESSION_ARGUMENTS!>{}<!>
|
||||||
|
|
||||||
return if (true) {
|
return if (true) {
|
||||||
twoLambdaArgs({})
|
twoLambdaArgs({})
|
||||||
{}
|
{}
|
||||||
<!TOO_MANY_ARGUMENTS!>{}<!>
|
<!MANY_LAMBDA_EXPRESSION_ARGUMENTS!>{}<!>
|
||||||
} else {
|
} else {
|
||||||
{}
|
{}
|
||||||
}
|
}
|
||||||
|
|||||||
+6
@@ -828,6 +828,12 @@ internal val KT_DIAGNOSTIC_CONVERTER = KtDiagnosticConverterBuilder.buildConvert
|
|||||||
token,
|
token,
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
add(FirErrors.MANY_LAMBDA_EXPRESSION_ARGUMENTS) { firDiagnostic ->
|
||||||
|
ManyLambdaExpressionArgumentsImpl(
|
||||||
|
firDiagnostic as FirPsiDiagnostic<*>,
|
||||||
|
token,
|
||||||
|
)
|
||||||
|
}
|
||||||
add(FirErrors.OVERLOAD_RESOLUTION_AMBIGUITY) { firDiagnostic ->
|
add(FirErrors.OVERLOAD_RESOLUTION_AMBIGUITY) { firDiagnostic ->
|
||||||
OverloadResolutionAmbiguityImpl(
|
OverloadResolutionAmbiguityImpl(
|
||||||
firDiagnostic.a.map { abstractFirBasedSymbol ->
|
firDiagnostic.a.map { abstractFirBasedSymbol ->
|
||||||
|
|||||||
+4
@@ -595,6 +595,10 @@ sealed class KtFirDiagnostic<PSI: PsiElement> : KtDiagnosticWithPsi<PSI> {
|
|||||||
abstract val name: String
|
abstract val name: String
|
||||||
}
|
}
|
||||||
|
|
||||||
|
abstract class ManyLambdaExpressionArguments : KtFirDiagnostic<KtValueArgument>() {
|
||||||
|
override val diagnosticClass get() = ManyLambdaExpressionArguments::class
|
||||||
|
}
|
||||||
|
|
||||||
abstract class OverloadResolutionAmbiguity : KtFirDiagnostic<PsiElement>() {
|
abstract class OverloadResolutionAmbiguity : KtFirDiagnostic<PsiElement>() {
|
||||||
override val diagnosticClass get() = OverloadResolutionAmbiguity::class
|
override val diagnosticClass get() = OverloadResolutionAmbiguity::class
|
||||||
abstract val candidates: List<KtSymbol>
|
abstract val candidates: List<KtSymbol>
|
||||||
|
|||||||
+7
@@ -953,6 +953,13 @@ internal class NamedParameterNotFoundImpl(
|
|||||||
override val firDiagnostic: FirPsiDiagnostic<*> by weakRef(firDiagnostic)
|
override val firDiagnostic: FirPsiDiagnostic<*> by weakRef(firDiagnostic)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
internal class ManyLambdaExpressionArgumentsImpl(
|
||||||
|
firDiagnostic: FirPsiDiagnostic<*>,
|
||||||
|
override val token: ValidityToken,
|
||||||
|
) : KtFirDiagnostic.ManyLambdaExpressionArguments(), KtAbstractFirDiagnostic<KtValueArgument> {
|
||||||
|
override val firDiagnostic: FirPsiDiagnostic<*> by weakRef(firDiagnostic)
|
||||||
|
}
|
||||||
|
|
||||||
internal class OverloadResolutionAmbiguityImpl(
|
internal class OverloadResolutionAmbiguityImpl(
|
||||||
override val candidates: List<KtSymbol>,
|
override val candidates: List<KtSymbol>,
|
||||||
firDiagnostic: FirPsiDiagnostic<*>,
|
firDiagnostic: FirPsiDiagnostic<*>,
|
||||||
|
|||||||
Reference in New Issue
Block a user