[FIR] Remove FirLambdaArgumentExpression

It's not really necessary if the information about if the lambda was a
trailing lambda can be directly saved in FirAnonymousFunctionExpression.

Removing the FIR node uncovered a couple of bugs
(UNINITIALIZED_ENUM_ENTRY, ERROR_IN_CONTRACT_DESCRIPTION) that were
caused by assuming that a lambda is always a trailing lambda.

#KT-66124
This commit is contained in:
Kirill Rakhman
2024-03-04 11:59:13 +01:00
committed by Space Team
parent 1a5fa8d3f6
commit 03fc0fd381
66 changed files with 302 additions and 351 deletions
@@ -630,7 +630,7 @@ object DIAGNOSTICS_LIST : DiagnosticList("FirErrors") {
parameter<ConeKotlinType>("actualType")
}
val MANY_LAMBDA_EXPRESSION_ARGUMENTS by error<KtValueArgument>()
val MANY_LAMBDA_EXPRESSION_ARGUMENTS by error<KtLambdaExpression>()
val NEW_INFERENCE_NO_INFORMATION_FOR_PARAMETER by error<KtElement> {
parameter<String>("name")
@@ -96,6 +96,7 @@ import org.jetbrains.kotlin.psi.KtFunction
import org.jetbrains.kotlin.psi.KtIfExpression
import org.jetbrains.kotlin.psi.KtImportDirective
import org.jetbrains.kotlin.psi.KtLabelReferenceExpression
import org.jetbrains.kotlin.psi.KtLambdaExpression
import org.jetbrains.kotlin.psi.KtModifierListOwner
import org.jetbrains.kotlin.psi.KtNameReferenceExpression
import org.jetbrains.kotlin.psi.KtNamedDeclaration
@@ -406,7 +407,7 @@ object FirErrors {
val NAME_FOR_AMBIGUOUS_PARAMETER: KtDiagnosticFactory0 by error0<KtValueArgument>(SourceElementPositioningStrategies.NAME_OF_NAMED_ARGUMENT)
val ASSIGNMENT_TYPE_MISMATCH: KtDiagnosticFactory3<ConeKotlinType, ConeKotlinType, Boolean> by error3<KtExpression, ConeKotlinType, ConeKotlinType, Boolean>()
val RESULT_TYPE_MISMATCH: KtDiagnosticFactory2<ConeKotlinType, ConeKotlinType> by error2<KtExpression, ConeKotlinType, ConeKotlinType>()
val MANY_LAMBDA_EXPRESSION_ARGUMENTS: KtDiagnosticFactory0 by error0<KtValueArgument>()
val MANY_LAMBDA_EXPRESSION_ARGUMENTS: KtDiagnosticFactory0 by error0<KtLambdaExpression>()
val NEW_INFERENCE_NO_INFORMATION_FOR_PARAMETER: KtDiagnosticFactory1<String> by error1<KtElement, String>()
val SPREAD_OF_NULLABLE: KtDiagnosticFactory0 by error0<PsiElement>(SourceElementPositioningStrategies.SPREAD_OPERATOR)
val ASSIGNING_SINGLE_ELEMENT_TO_VARARG_IN_NAMED_FORM_FUNCTION: KtDiagnosticFactoryForDeprecation1<ConeKotlinType> by deprecationError1<KtExpression, ConeKotlinType>(ProhibitAssigningSingleElementsToVarargsInNamedForm)
@@ -488,7 +488,6 @@ object FirInlineDeclarationChecker : FirFunctionChecker(MppCheckerKind.Common) {
private fun isInlinableDefaultValue(expression: FirExpression): Boolean =
expression is FirCallableReferenceAccess ||
expression is FirFunctionCall ||
expression is FirLambdaArgumentExpression ||
expression is FirAnonymousFunctionExpression ||
(expression is FirLiteralExpression<*> && expression.value == null) //this will be reported separately
@@ -14,7 +14,6 @@ import org.jetbrains.kotlin.fir.analysis.checkers.hasDiagnosticKind
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors
import org.jetbrains.kotlin.fir.diagnostics.DiagnosticKind
import org.jetbrains.kotlin.fir.expressions.FirExpression
import org.jetbrains.kotlin.fir.expressions.FirLambdaArgumentExpression
import org.jetbrains.kotlin.fir.expressions.FirStatement
import org.jetbrains.kotlin.fir.types.ConeClassLikeType
import org.jetbrains.kotlin.fir.types.ConeKotlinType
@@ -32,7 +31,7 @@ object FirRecursiveProblemChecker : FirBasicExpressionChecker(MppCheckerKind.Com
fun checkConeType(coneType: ConeKotlinType?) {
if (coneType?.hasDiagnosticKind(DiagnosticKind.RecursionInImplicitTypes) == true) {
val source = ((expression as? FirLambdaArgumentExpression)?.expression ?: expression).source
val source = expression.source
reporter.reportOn(source, FirErrors.TYPECHECKER_HAS_RUN_INTO_RECURSIVE_PROBLEM, context)
} else if (coneType is ConeClassLikeType) {
for (typeArgument in coneType.typeArguments) {
@@ -44,8 +44,7 @@ object FirReturnSyntaxAndLabelChecker : FirReturnExpressionChecker(MppCheckerKin
}
if (functionCall is FirFunctionCall &&
functionCall.arguments.any {
it is FirLambdaArgumentExpression &&
(it.expression as? FirAnonymousFunctionExpression)?.anonymousFunction?.symbol == targetSymbol
it is FirAnonymousFunctionExpression && it.anonymousFunction.symbol == targetSymbol
}
) {
reporter.reportOn(source, FirErrors.RETURN_FOR_BUILT_IN_SUSPEND, context)
@@ -116,7 +116,7 @@ object FirSuspendCallChecker : FirQualifiedAccessExpressionChecker(MppCheckerKin
val reference = this.calleeReference
if (reference is FirResolvedCallableReference) return null
if (typeArguments.any { it.source != null }) return null
if (arguments.singleOrNull() is FirLambdaArgumentExpression) {
if (arguments.singleOrNull().let { it is FirAnonymousFunctionExpression && it.isTrailingLambda }) {
// No brackets should be in a selector call
val callExpressionSource =
if (explicitReceiver == null) source
@@ -236,8 +236,8 @@ object FirUninitializedEnumChecker : FirQualifiedAccessExpressionChecker(MppChec
val delegateCall = property.delegate as FirFunctionCall
val calleeSymbol = delegateCall.calleeReference.toResolvedNamedFunctionSymbol() ?: return null
if (calleeSymbol.callableId.asSingleFqName().asString() != "kotlin.lazy") return null
val lazyCallArgument = delegateCall.argumentList.arguments.singleOrNull() as? FirLambdaArgumentExpression ?: return null
return (lazyCallArgument.expression as? FirAnonymousFunctionExpression)?.anonymousFunction
val lazyCallArgument = delegateCall.argumentList.arguments.singleOrNull() as? FirAnonymousFunctionExpression ?: return null
return lazyCallArgument.anonymousFunction
}
private fun FirDeclaration.isEnumEntryInitializer(): Boolean {
@@ -217,10 +217,6 @@ class ExpressionCheckersDiagnosticComponent(
checkers.allBasicExpressionCheckers.check(namedArgumentExpression, data)
}
override fun visitLambdaArgumentExpression(lambdaArgumentExpression: FirLambdaArgumentExpression, data: CheckerContext) {
checkers.allBasicExpressionCheckers.check(lambdaArgumentExpression, data)
}
override fun visitSmartCastExpression(smartCastExpression: FirSmartCastExpression, data: CheckerContext) {
checkers.allBasicExpressionCheckers.check(smartCastExpression, data)
}