[FIR] Add NULLABLE_INLINE_PARAMETER diagnostic
This commit is contained in:
committed by
teamcityserver
parent
015c2d1875
commit
4e06814bc5
+5
@@ -1136,6 +1136,11 @@ object DIAGNOSTICS_LIST : DiagnosticList("FirErrors") {
|
||||
|
||||
val NOTHING_TO_INLINE by warning<KtDeclaration>(PositioningStrategy.NOT_SUPPORTED_IN_INLINE_MOST_RELEVANT)
|
||||
|
||||
val NULLABLE_INLINE_PARAMETER by error<KtDeclaration>() {
|
||||
parameter<FirValueParameterSymbol>("parameter")
|
||||
parameter<Symbol>("function")
|
||||
}
|
||||
|
||||
val RECURSION_IN_INLINE by error<KtElement>(PositioningStrategy.REFERENCE_BY_QUALIFIED) {
|
||||
parameter<Symbol>("symbol")
|
||||
}
|
||||
|
||||
@@ -600,6 +600,7 @@ object FirErrors {
|
||||
val NON_LOCAL_RETURN_NOT_ALLOWED by error1<KtElement, FirBasedSymbol<*>>(SourceElementPositioningStrategies.REFERENCE_BY_QUALIFIED)
|
||||
val NOT_YET_SUPPORTED_IN_INLINE by error1<KtDeclaration, String>(SourceElementPositioningStrategies.NOT_SUPPORTED_IN_INLINE_MOST_RELEVANT)
|
||||
val NOTHING_TO_INLINE by warning0<KtDeclaration>(SourceElementPositioningStrategies.NOT_SUPPORTED_IN_INLINE_MOST_RELEVANT)
|
||||
val NULLABLE_INLINE_PARAMETER by error2<KtDeclaration, FirValueParameterSymbol, FirBasedSymbol<*>>()
|
||||
val RECURSION_IN_INLINE by error1<KtElement, FirBasedSymbol<*>>(SourceElementPositioningStrategies.REFERENCE_BY_QUALIFIED)
|
||||
val NON_PUBLIC_CALL_FROM_PUBLIC_INLINE by error2<KtElement, FirBasedSymbol<*>, FirBasedSymbol<*>>(SourceElementPositioningStrategies.REFERENCE_BY_QUALIFIED)
|
||||
val PROTECTED_CONSTRUCTOR_CALL_FROM_PUBLIC_INLINE by error2<KtElement, FirBasedSymbol<*>, FirBasedSymbol<*>>(SourceElementPositioningStrategies.REFERENCE_BY_QUALIFIED)
|
||||
|
||||
+22
-11
@@ -338,17 +338,28 @@ object FirInlineDeclarationChecker : FirFunctionChecker() {
|
||||
private fun checkParameters(function: FirFunction, context: CheckerContext, reporter: DiagnosticReporter) {
|
||||
if (function !is FirSimpleFunction) return
|
||||
|
||||
if (function.isSuspend) {
|
||||
function.valueParameters
|
||||
.filter { !it.isNoinline && it.defaultValue != null && it.returnTypeRef.coneType.isSuspendFunctionType(context.session) }
|
||||
.forEach { param ->
|
||||
reporter.reportOn(
|
||||
param.source,
|
||||
FirErrors.NOT_YET_SUPPORTED_IN_INLINE,
|
||||
"Suspend functional parameters with default values",
|
||||
context
|
||||
)
|
||||
}
|
||||
for (param in function.valueParameters) {
|
||||
if (param.isNoinline) continue
|
||||
|
||||
val coneType = param.returnTypeRef.coneType
|
||||
if (function.isSuspend && param.defaultValue != null && coneType.isSuspendFunctionType(context.session)) {
|
||||
reporter.reportOn(
|
||||
param.source,
|
||||
FirErrors.NOT_YET_SUPPORTED_IN_INLINE,
|
||||
"Suspend functional parameters with default values",
|
||||
context
|
||||
)
|
||||
}
|
||||
|
||||
if (coneType.isNullable && coneType.isFunctionalType(context.session)) {
|
||||
reporter.reportOn(
|
||||
param.source,
|
||||
FirErrors.NULLABLE_INLINE_PARAMETER,
|
||||
param.symbol,
|
||||
function.symbol,
|
||||
context
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
//check for inherited default values
|
||||
|
||||
+8
@@ -288,6 +288,7 @@ import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.NO_RETURN_IN_FUNC
|
||||
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.NO_SET_METHOD
|
||||
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.NO_THIS
|
||||
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.NO_VALUE_FOR_PARAMETER
|
||||
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.NULLABLE_INLINE_PARAMETER
|
||||
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.NULLABLE_SUPERTYPE
|
||||
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.NULLABLE_TYPE_IN_CLASS_LITERAL_LHS
|
||||
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.NULLABLE_TYPE_OF_ANNOTATION_MEMBER
|
||||
@@ -1488,6 +1489,13 @@ class FirDefaultErrorMessages {
|
||||
NOTHING_TO_INLINE,
|
||||
"Expected performance impact from inlining is insignificant. Inlining works best for functions with parameters of functional types"
|
||||
)
|
||||
map.put(
|
||||
NULLABLE_INLINE_PARAMETER,
|
||||
"Inline-parameter ''{0}'' of ''{1}'' must not be nullable. Add ''noinline'' modifier to the parameter declaration or make its type not nullable",
|
||||
SYMBOL,
|
||||
SYMBOL
|
||||
)
|
||||
|
||||
map.put(SUPER_CALL_FROM_PUBLIC_INLINE, "Accessing super members from public-API inline function is deprecated", SYMBOL)
|
||||
|
||||
//imports
|
||||
|
||||
@@ -1,4 +0,0 @@
|
||||
inline fun test(s: () -> Unit, p: (() -> Unit)?) {
|
||||
s()
|
||||
p?.invoke()
|
||||
}
|
||||
@@ -1,3 +1,4 @@
|
||||
// FIR_IDENTICAL
|
||||
inline fun test(s: () -> Unit, <!NULLABLE_INLINE_PARAMETER!>p: (() -> Unit)?<!>) {
|
||||
s()
|
||||
p?.invoke()
|
||||
|
||||
@@ -1,21 +0,0 @@
|
||||
// !DIAGNOSTICS: -UNUSED_EXPRESSION -UNUSED_PARAMETER -UNUSED_VARIABLE -CONFLICTING_JVM_DECLARATIONS
|
||||
|
||||
public inline fun <T> Function1<Int, Int>?.submit(action: ()->T) {
|
||||
this?.invoke(11)
|
||||
}
|
||||
|
||||
public inline fun <T> submit(action: Function1<Int, Int>?, s: () -> Int) {
|
||||
action?.invoke(10)
|
||||
}
|
||||
|
||||
public inline fun <T> submitNoInline(noinline action: Function1<Int, Int>?, s: () -> Int) {
|
||||
action?.invoke(10)
|
||||
}
|
||||
|
||||
public <!NOTHING_TO_INLINE!>inline<!> fun <T> Function1<Int, Int>?.submit() {
|
||||
|
||||
}
|
||||
|
||||
public <!NOTHING_TO_INLINE!>inline<!> fun <T> submit(action: Function1<Int, Int>?) {
|
||||
|
||||
}
|
||||
@@ -1,3 +1,4 @@
|
||||
// FIR_IDENTICAL
|
||||
// !DIAGNOSTICS: -UNUSED_EXPRESSION -UNUSED_PARAMETER -UNUSED_VARIABLE -CONFLICTING_JVM_DECLARATIONS
|
||||
|
||||
public inline fun <T> Function1<Int, Int>?.submit(action: ()->T) {
|
||||
|
||||
+8
@@ -3105,6 +3105,14 @@ internal val KT_DIAGNOSTIC_CONVERTER = KtDiagnosticConverterBuilder.buildConvert
|
||||
token,
|
||||
)
|
||||
}
|
||||
add(FirErrors.NULLABLE_INLINE_PARAMETER) { firDiagnostic ->
|
||||
NullableInlineParameterImpl(
|
||||
firSymbolBuilder.buildSymbol(firDiagnostic.a.fir),
|
||||
firSymbolBuilder.buildSymbol(firDiagnostic.b.fir),
|
||||
firDiagnostic as FirPsiDiagnostic,
|
||||
token,
|
||||
)
|
||||
}
|
||||
add(FirErrors.RECURSION_IN_INLINE) { firDiagnostic ->
|
||||
RecursionInInlineImpl(
|
||||
firSymbolBuilder.buildSymbol(firDiagnostic.a.fir),
|
||||
|
||||
+6
@@ -2164,6 +2164,12 @@ sealed class KtFirDiagnostic<PSI : PsiElement> : KtDiagnosticWithPsi<PSI> {
|
||||
override val diagnosticClass get() = NothingToInline::class
|
||||
}
|
||||
|
||||
abstract class NullableInlineParameter : KtFirDiagnostic<KtDeclaration>() {
|
||||
override val diagnosticClass get() = NullableInlineParameter::class
|
||||
abstract val parameter: KtSymbol
|
||||
abstract val function: KtSymbol
|
||||
}
|
||||
|
||||
abstract class RecursionInInline : KtFirDiagnostic<KtElement>() {
|
||||
override val diagnosticClass get() = RecursionInInline::class
|
||||
abstract val symbol: KtSymbol
|
||||
|
||||
+9
@@ -3497,6 +3497,15 @@ internal class NothingToInlineImpl(
|
||||
override val firDiagnostic: FirPsiDiagnostic by weakRef(firDiagnostic)
|
||||
}
|
||||
|
||||
internal class NullableInlineParameterImpl(
|
||||
override val parameter: KtSymbol,
|
||||
override val function: KtSymbol,
|
||||
firDiagnostic: FirPsiDiagnostic,
|
||||
override val token: ValidityToken,
|
||||
) : KtFirDiagnostic.NullableInlineParameter(), KtAbstractFirDiagnostic<KtDeclaration> {
|
||||
override val firDiagnostic: FirPsiDiagnostic by weakRef(firDiagnostic)
|
||||
}
|
||||
|
||||
internal class RecursionInInlineImpl(
|
||||
override val symbol: KtSymbol,
|
||||
firDiagnostic: FirPsiDiagnostic,
|
||||
|
||||
Reference in New Issue
Block a user