[FIR] Report NON_SOURCE_ANNOTATION_ON_INLINED_LAMBDA_EXPRESSION

^KT-59422 Fixed
This commit is contained in:
Nikolay Lunyak
2023-08-22 09:49:40 +03:00
committed by Space Team
parent ed6a0af0a6
commit 6e732f2f4d
10 changed files with 60 additions and 2 deletions
@@ -1165,6 +1165,12 @@ internal val KT_DIAGNOSTIC_CONVERTER = KtDiagnosticConverterBuilder.buildConvert
token,
)
}
add(FirErrors.NON_SOURCE_ANNOTATION_ON_INLINED_LAMBDA_EXPRESSION) { firDiagnostic ->
NonSourceAnnotationOnInlinedLambdaExpressionImpl(
firDiagnostic as KtPsiDiagnostic,
token,
)
}
add(FirJsErrors.WRONG_JS_QUALIFIER) { firDiagnostic ->
WrongJsQualifierImpl(
firDiagnostic as KtPsiDiagnostic,
@@ -844,6 +844,10 @@ sealed interface KtFirDiagnostic<PSI : PsiElement> : KtDiagnosticWithPsi<PSI> {
override val diagnosticClass get() = VolatileOnDelegate::class
}
interface NonSourceAnnotationOnInlinedLambdaExpression : KtFirDiagnostic<KtAnnotationEntry> {
override val diagnosticClass get() = NonSourceAnnotationOnInlinedLambdaExpression::class
}
interface WrongJsQualifier : KtFirDiagnostic<KtElement> {
override val diagnosticClass get() = WrongJsQualifier::class
}
@@ -1011,6 +1011,11 @@ internal class VolatileOnDelegateImpl(
token: KtLifetimeToken,
) : KtAbstractFirDiagnostic<KtAnnotationEntry>(firDiagnostic, token), KtFirDiagnostic.VolatileOnDelegate
internal class NonSourceAnnotationOnInlinedLambdaExpressionImpl(
firDiagnostic: KtPsiDiagnostic,
token: KtLifetimeToken,
) : KtAbstractFirDiagnostic<KtAnnotationEntry>(firDiagnostic, token), KtFirDiagnostic.NonSourceAnnotationOnInlinedLambdaExpression
internal class WrongJsQualifierImpl(
firDiagnostic: KtPsiDiagnostic,
token: KtLifetimeToken,
@@ -384,6 +384,8 @@ object DIAGNOSTICS_LIST : DiagnosticList("FirErrors") {
val VOLATILE_ON_VALUE by error<KtAnnotationEntry>()
val VOLATILE_ON_DELEGATE by error<KtAnnotationEntry>()
val NON_SOURCE_ANNOTATION_ON_INLINED_LAMBDA_EXPRESSION by error<KtAnnotationEntry>()
}
val OPT_IN by object : DiagnosticGroup("OptIn") {
@@ -293,6 +293,7 @@ object FirErrors {
val AMBIGUOUS_ANNOTATION_ARGUMENT by error1<PsiElement, List<FirBasedSymbol<*>>>()
val VOLATILE_ON_VALUE by error0<KtAnnotationEntry>()
val VOLATILE_ON_DELEGATE by error0<KtAnnotationEntry>()
val NON_SOURCE_ANNOTATION_ON_INLINED_LAMBDA_EXPRESSION by error0<KtAnnotationEntry>()
// OptIn
val OPT_IN_USAGE by warning2<PsiElement, FqName, String>(SourceElementPositioningStrategies.REFERENCE_BY_QUALIFIED)
@@ -155,6 +155,7 @@ val FIR_NON_SUPPRESSIBLE_ERROR_NAMES: Set<String> = setOf(
"AMBIGUOUS_ANNOTATION_ARGUMENT",
"VOLATILE_ON_VALUE",
"VOLATILE_ON_DELEGATE",
"NON_SOURCE_ANNOTATION_ON_INLINED_LAMBDA_EXPRESSION",
"WRONG_JS_QUALIFIER",
"JS_MODULE_PROHIBITED_ON_VAR",
"JS_MODULE_PROHIBITED_ON_NON_NATIVE",
@@ -12,6 +12,7 @@ import org.jetbrains.kotlin.fir.analysis.checkers.cfa.FirControlFlowChecker
import org.jetbrains.kotlin.fir.analysis.checkers.declaration.*
import org.jetbrains.kotlin.fir.analysis.checkers.expression.FirAnonymousFunctionParametersChecker
import org.jetbrains.kotlin.fir.analysis.checkers.declaration.FirFiniteBoundRestrictionChecker
import org.jetbrains.kotlin.fir.analysis.checkers.expression.FirInlinedLambdaNonSourceAnnotationsChecker
import org.jetbrains.kotlin.fir.analysis.checkers.syntax.*
object CommonDeclarationCheckers : DeclarationCheckers() {
@@ -173,6 +174,7 @@ object CommonDeclarationCheckers : DeclarationCheckers() {
override val anonymousFunctionCheckers: Set<FirAnonymousFunctionChecker>
get() = setOf(
FirAnonymousFunctionParametersChecker,
FirInlinedLambdaNonSourceAnnotationsChecker,
FirAnonymousFunctionSyntaxChecker,
)
@@ -0,0 +1,32 @@
/*
* Copyright 2010-2021 JetBrains s.r.o. and Kotlin Programming Language contributors.
* Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
*/
package org.jetbrains.kotlin.fir.analysis.checkers.expression
import org.jetbrains.kotlin.diagnostics.DiagnosticReporter
import org.jetbrains.kotlin.diagnostics.reportOn
import org.jetbrains.kotlin.fir.analysis.checkers.context.CheckerContext
import org.jetbrains.kotlin.fir.analysis.checkers.declaration.FirAnonymousFunctionChecker
import org.jetbrains.kotlin.fir.analysis.checkers.getAnnotationRetention
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors
import org.jetbrains.kotlin.fir.declarations.FirAnonymousFunction
import org.jetbrains.kotlin.fir.declarations.InlineStatus
import org.jetbrains.kotlin.fir.declarations.toAnnotationClassLikeSymbol
object FirInlinedLambdaNonSourceAnnotationsChecker : FirAnonymousFunctionChecker() {
override fun check(declaration: FirAnonymousFunction, context: CheckerContext, reporter: DiagnosticReporter) {
if (declaration.inlineStatus != InlineStatus.Inline && declaration.inlineStatus != InlineStatus.CrossInline) {
return
}
for (it in declaration.annotations) {
val annotationSymbol = it.toAnnotationClassLikeSymbol(context.session) ?: continue
if (annotationSymbol.getAnnotationRetention(context.session) != AnnotationRetention.SOURCE) {
reporter.reportOn(it.source, FirErrors.NON_SOURCE_ANNOTATION_ON_INLINED_LAMBDA_EXPRESSION, context)
}
}
}
}
@@ -399,6 +399,7 @@ import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.NON_MODIFIER_FORM
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.NON_PRIVATE_CONSTRUCTOR_IN_ENUM
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.NON_PRIVATE_OR_PROTECTED_CONSTRUCTOR_IN_SEALED
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.NON_PUBLIC_CALL_FROM_PUBLIC_INLINE
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.NON_SOURCE_ANNOTATION_ON_INLINED_LAMBDA_EXPRESSION
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.NON_TAIL_RECURSIVE_CALL
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.NON_VARARG_SPREAD
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.NOTHING_TO_INLINE
@@ -984,6 +985,10 @@ object FirErrorsDefaultMessages : BaseDiagnosticRendererFactory() {
map.put(NON_INTERNAL_PUBLISHED_API, "'@PublishedApi' annotation is only applicable to internal declaration.")
map.put(VOLATILE_ON_VALUE, "'@Volatile' annotation cannot be used on immutable properties.")
map.put(VOLATILE_ON_DELEGATE, "'@Volatile' annotation cannot be used on delegated properties.")
map.put(
NON_SOURCE_ANNOTATION_ON_INLINED_LAMBDA_EXPRESSION,
"The lambda expression here is an inlined argument, so this annotation cannot be stored anywhere.",
)
// OptIn
map.put(OPT_IN_USAGE, "{1}", TO_STRING, STRING)
@@ -21,8 +21,8 @@ fun foo(arg: Int) {
// Literal is annotatable
bar @FunAnn { arg }
// Annotatable in principle but useless, fast is inline
fast @FunAnn { arg }
fast2(1, @FunAnn { arg })
fast <!NON_SOURCE_ANNOTATION_ON_INLINED_LAMBDA_EXPRESSION!>@FunAnn<!> { arg }
fast2(1, <!NON_SOURCE_ANNOTATION_ON_INLINED_LAMBDA_EXPRESSION!>@FunAnn<!> { arg })
// Source annotation, ok
fast @SourceAnn { arg }
fast2(1, @SourceAnn { arg })