[FIR] Add INVALID_DEFAULT_FUNCTIONAL_PARAMETER_FOR_INLINE diagnostic

This commit is contained in:
Andrey Zinovyev
2021-07-21 16:22:30 +03:00
committed by teamcityserver
parent efce3fc2e0
commit dabc983f6a
9 changed files with 59 additions and 4 deletions
@@ -1179,6 +1179,11 @@ object DIAGNOSTICS_LIST : DiagnosticList("FirErrors") {
val OVERRIDE_BY_INLINE by warning<KtDeclaration>(PositioningStrategy.DECLARATION_SIGNATURE)
val NON_INTERNAL_PUBLISHED_API by error<KtElement>()
val INVALID_DEFAULT_FUNCTIONAL_PARAMETER_FOR_INLINE by error<KtElement>() {
parameter<FirExpression>("defaultValue")
parameter<FirValueParameterSymbol>("parameter")
}
val REIFIED_TYPE_PARAMETER_IN_OVERRIDE by error<KtElement>(PositioningStrategy.REIFIED_MODIFIER)
@@ -611,6 +611,7 @@ object FirErrors {
val DECLARATION_CANT_BE_INLINED by error0<KtDeclaration>(SourceElementPositioningStrategies.DECLARATION_SIGNATURE)
val OVERRIDE_BY_INLINE by warning0<KtDeclaration>(SourceElementPositioningStrategies.DECLARATION_SIGNATURE)
val NON_INTERNAL_PUBLISHED_API by error0<KtElement>()
val INVALID_DEFAULT_FUNCTIONAL_PARAMETER_FOR_INLINE by error2<KtElement, FirExpression, FirValueParameterSymbol>()
val REIFIED_TYPE_PARAMETER_IN_OVERRIDE by error0<KtElement>(SourceElementPositioningStrategies.REIFIED_MODIFIER)
val INLINE_PROPERTY_WITH_BACKING_FIELD by error0<KtDeclaration>(SourceElementPositioningStrategies.DECLARATION_SIGNATURE)
@@ -344,7 +344,9 @@ object FirInlineDeclarationChecker : FirFunctionChecker() {
if (param.isNoinline) continue
val coneType = param.returnTypeRef.coneType
if (function.isSuspend && param.defaultValue != null && coneType.isSuspendFunctionType(context.session)) {
val isFunctionalType = coneType.isFunctionalType(context.session)
val defaultValue = param.defaultValue
if (function.isSuspend && defaultValue != null && coneType.isSuspendFunctionType(context.session)) {
reporter.reportOn(
param.source,
FirErrors.NOT_YET_SUPPORTED_IN_INLINE,
@@ -353,7 +355,7 @@ object FirInlineDeclarationChecker : FirFunctionChecker() {
)
}
if (coneType.isNullable && coneType.isFunctionalType(context.session)) {
if (coneType.isNullable && isFunctionalType) {
reporter.reportOn(
param.source,
FirErrors.NULLABLE_INLINE_PARAMETER,
@@ -362,6 +364,16 @@ object FirInlineDeclarationChecker : FirFunctionChecker() {
context
)
}
if (isFunctionalType && defaultValue != null && !isInlinableDefaultValue(defaultValue)) {
reporter.reportOn(
defaultValue.source,
FirErrors.INVALID_DEFAULT_FUNCTIONAL_PARAMETER_FOR_INLINE,
defaultValue,
param.symbol,
context
)
}
}
if (overriddenSymbols.isNotEmpty()) {
@@ -432,6 +444,13 @@ object FirInlineDeclarationChecker : FirFunctionChecker() {
return true
}
private fun isInlinableDefaultValue(expression: FirExpression): Boolean =
expression is FirCallableReferenceAccess ||
expression is FirFunctionCall ||
expression is FirLambdaArgumentExpression ||
expression is FirAnonymousFunctionExpression ||
(expression is FirConstExpression<*> && expression.value == null) //this will be reported separately
internal fun checkCallableDeclaration(declaration: FirCallableDeclaration, context: CheckerContext, reporter: DiagnosticReporter) {
if (declaration is FirPropertyAccessor) return
val overriddenSymbols = declaration.getOverriddenSymbols(context)
@@ -230,6 +230,7 @@ import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.INNER_CLASS_INSID
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.INNER_CLASS_OF_GENERIC_THROWABLE_SUBCLASS
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.INSTANCE_ACCESS_BEFORE_SUPER_CALL
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.INTERFACE_WITH_SUPERCLASS
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.INVALID_DEFAULT_FUNCTIONAL_PARAMETER_FOR_INLINE
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.INVALID_CHARACTERS
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.INVALID_IF_AS_EXPRESSION
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.INVALID_TYPE_OF_ANNOTATION_MEMBER
@@ -938,6 +939,12 @@ class FirDefaultErrorMessages {
map.put(REIFIED_TYPE_PARAMETER_IN_OVERRIDE, "Override by a function with reified type parameter")
map.put(INLINE_PROPERTY_WITH_BACKING_FIELD, "Inline property cannot have backing field")
map.put(NON_INTERNAL_PUBLISHED_API, "@PublishedApi annotation is only applicable for internal declaration")
map.put(
INVALID_DEFAULT_FUNCTIONAL_PARAMETER_FOR_INLINE,
"Invalid default value for inline parameter: ''{0}''. Only lambdas, anonymous functions, and callable references are supported",
FIR,
DECLARATION_NAME
)
map.put(RESERVED_MEMBER_INSIDE_INLINE_CLASS, "Member with the name ''{0}'' is reserved for future releases", TO_STRING)
map.put(
SECONDARY_CONSTRUCTOR_WITH_BODY_INSIDE_INLINE_CLASS,
@@ -28,7 +28,7 @@ val a = Foo()
inline fun default8(s : () -> String = a::test) {}
inline fun default9(s : () -> String = a::prop) {}
inline fun default10(s : () -> String = object : Function0<String> {
inline fun default10(s : () -> String = <!INVALID_DEFAULT_FUNCTIONAL_PARAMETER_FOR_INLINE!>object<!> : Function0<String> {
override fun invoke(): String {
return "FAIL"
}
@@ -28,7 +28,7 @@ val a = Foo()
inline fun default8(s : () -> String = a::test) {}
inline fun default9(s : () -> String = a::prop) {}
inline fun default10(s : () -> String = object : Function0<String> {
inline fun default10(s : () -> String = <!INVALID_DEFAULT_FUNCTIONAL_PARAMETER_FOR_INLINE!>object<!> : Function0<String> {
override fun invoke(): String {
return "FAIL"
}
@@ -3185,6 +3185,14 @@ internal val KT_DIAGNOSTIC_CONVERTER = KtDiagnosticConverterBuilder.buildConvert
token,
)
}
add(FirErrors.INVALID_DEFAULT_FUNCTIONAL_PARAMETER_FOR_INLINE) { firDiagnostic ->
InvalidDefaultFunctionalParameterForInlineImpl(
firDiagnostic.a.source!!.psi as KtExpression,
firSymbolBuilder.buildSymbol(firDiagnostic.b.fir),
firDiagnostic as FirPsiDiagnostic,
token,
)
}
add(FirErrors.REIFIED_TYPE_PARAMETER_IN_OVERRIDE) { firDiagnostic ->
ReifiedTypeParameterInOverrideImpl(
firDiagnostic as FirPsiDiagnostic,
@@ -2222,6 +2222,12 @@ sealed class KtFirDiagnostic<PSI : PsiElement> : KtDiagnosticWithPsi<PSI> {
override val diagnosticClass get() = NonInternalPublishedApi::class
}
abstract class InvalidDefaultFunctionalParameterForInline : KtFirDiagnostic<KtElement>() {
override val diagnosticClass get() = InvalidDefaultFunctionalParameterForInline::class
abstract val defaultValue: KtExpression
abstract val parameter: KtSymbol
}
abstract class ReifiedTypeParameterInOverride : KtFirDiagnostic<KtElement>() {
override val diagnosticClass get() = ReifiedTypeParameterInOverride::class
}
@@ -3588,6 +3588,15 @@ internal class NonInternalPublishedApiImpl(
override val firDiagnostic: FirPsiDiagnostic by weakRef(firDiagnostic)
}
internal class InvalidDefaultFunctionalParameterForInlineImpl(
override val defaultValue: KtExpression,
override val parameter: KtSymbol,
firDiagnostic: FirPsiDiagnostic,
override val token: ValidityToken,
) : KtFirDiagnostic.InvalidDefaultFunctionalParameterForInline(), KtAbstractFirDiagnostic<KtElement> {
override val firDiagnostic: FirPsiDiagnostic by weakRef(firDiagnostic)
}
internal class ReifiedTypeParameterInOverrideImpl(
firDiagnostic: FirPsiDiagnostic,
override val token: ValidityToken,