[FIR] Add POSITIONED_VALUE_ARGUMENT_FOR_JAVA_ANNOTATION
This commit is contained in:
committed by
teamcityserver
parent
dd46c36b24
commit
e97933a9e5
+1
-1
@@ -9,7 +9,7 @@ public @interface Ann {
|
||||
// FILE: main.kt
|
||||
|
||||
@Ann(x = 10, s = "")
|
||||
<!REPEATED_ANNOTATION!>@Ann(<!ARGUMENT_TYPE_MISMATCH!>10<!>, <!ARGUMENT_TYPE_MISMATCH!>""<!>)<!>
|
||||
<!REPEATED_ANNOTATION!>@Ann(<!ARGUMENT_TYPE_MISMATCH, POSITIONED_VALUE_ARGUMENT_FOR_JAVA_ANNOTATION!>10<!>, <!ARGUMENT_TYPE_MISMATCH, POSITIONED_VALUE_ARGUMENT_FOR_JAVA_ANNOTATION!>""<!>)<!>
|
||||
<!REPEATED_ANNOTATION!>@Ann(x = 10, s = "", y = 10)<!>
|
||||
class A
|
||||
|
||||
|
||||
+2
-2
@@ -11,7 +11,7 @@ public @interface Nls {
|
||||
import some.Nls.Capitalization.*
|
||||
import some.Nls
|
||||
|
||||
@Nls(Title)
|
||||
@Nls(<!POSITIONED_VALUE_ARGUMENT_FOR_JAVA_ANNOTATION!>Title<!>)
|
||||
fun f() {
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
+2
@@ -69,6 +69,8 @@ object JVM_DIAGNOSTICS_LIST : DiagnosticList("FirJvmErrors") {
|
||||
val JVM_PACKAGE_NAME_CANNOT_BE_EMPTY by error<KtAnnotationEntry>()
|
||||
val JVM_PACKAGE_NAME_MUST_BE_VALID_NAME by error<KtAnnotationEntry>()
|
||||
val JVM_PACKAGE_NAME_NOT_SUPPORTED_IN_FILES_WITH_CLASSES by error<KtAnnotationEntry>()
|
||||
|
||||
val POSITIONED_VALUE_ARGUMENT_FOR_JAVA_ANNOTATION by error<KtExpression>()
|
||||
}
|
||||
|
||||
val SUPER by object : DiagnosticGroup("Super") {
|
||||
|
||||
+1
@@ -60,6 +60,7 @@ object FirJvmErrors {
|
||||
val JVM_PACKAGE_NAME_CANNOT_BE_EMPTY by error0<KtAnnotationEntry>()
|
||||
val JVM_PACKAGE_NAME_MUST_BE_VALID_NAME by error0<KtAnnotationEntry>()
|
||||
val JVM_PACKAGE_NAME_NOT_SUPPORTED_IN_FILES_WITH_CLASSES by error0<KtAnnotationEntry>()
|
||||
val POSITIONED_VALUE_ARGUMENT_FOR_JAVA_ANNOTATION by error0<KtExpression>()
|
||||
|
||||
// Super
|
||||
val SUPER_CALL_WITH_DEFAULT_PARAMETERS by error1<PsiElement, String>()
|
||||
|
||||
+1
-1
@@ -27,7 +27,7 @@ object JvmExpressionCheckers : ExpressionCheckers() {
|
||||
|
||||
override val annotationCheckers: Set<FirAnnotationChecker>
|
||||
get() = setOf(
|
||||
FirDeprecatedJavaAnnotationsChecker,
|
||||
FirJavaAnnotationsChecker,
|
||||
FirJvmPackageNameAnnotationsChecker,
|
||||
)
|
||||
}
|
||||
|
||||
+20
-1
@@ -9,17 +9,23 @@ import org.jetbrains.kotlin.builtins.StandardNames
|
||||
import org.jetbrains.kotlin.fir.FirRealSourceElementKind
|
||||
import org.jetbrains.kotlin.fir.analysis.checkers.context.CheckerContext
|
||||
import org.jetbrains.kotlin.fir.analysis.checkers.expression.FirAnnotationChecker
|
||||
import org.jetbrains.kotlin.fir.analysis.checkers.toRegularClassSymbol
|
||||
import org.jetbrains.kotlin.fir.analysis.diagnostics.DiagnosticReporter
|
||||
import org.jetbrains.kotlin.fir.analysis.diagnostics.jvm.FirJvmErrors
|
||||
import org.jetbrains.kotlin.fir.analysis.diagnostics.reportOn
|
||||
import org.jetbrains.kotlin.fir.declarations.FirDeclarationOrigin
|
||||
import org.jetbrains.kotlin.fir.expressions.FirAnnotation
|
||||
import org.jetbrains.kotlin.fir.expressions.FirAnnotationCall
|
||||
import org.jetbrains.kotlin.fir.expressions.FirWrappedArgumentExpression
|
||||
import org.jetbrains.kotlin.fir.expressions.impl.FirResolvedArgumentList
|
||||
import org.jetbrains.kotlin.fir.types.ConeClassLikeType
|
||||
import org.jetbrains.kotlin.fir.types.coneTypeSafe
|
||||
import org.jetbrains.kotlin.load.java.JvmAnnotationNames
|
||||
import org.jetbrains.kotlin.load.java.JvmAnnotationNames.DEFAULT_ANNOTATION_MEMBER_NAME
|
||||
import org.jetbrains.kotlin.name.ClassId
|
||||
import org.jetbrains.kotlin.name.FqName
|
||||
|
||||
object FirDeprecatedJavaAnnotationsChecker : FirAnnotationChecker() {
|
||||
object FirJavaAnnotationsChecker : FirAnnotationChecker() {
|
||||
|
||||
private val javaToKotlinNameMap: Map<ClassId, FqName> =
|
||||
mapOf(
|
||||
@@ -31,10 +37,23 @@ object FirDeprecatedJavaAnnotationsChecker : FirAnnotationChecker() {
|
||||
|
||||
override fun check(expression: FirAnnotation, context: CheckerContext, reporter: DiagnosticReporter) {
|
||||
if (context.containingDeclarations.lastOrNull()?.source?.kind != FirRealSourceElementKind) return
|
||||
val callableSymbol = expression.annotationTypeRef.toRegularClassSymbol(context.session)
|
||||
if (callableSymbol?.origin != FirDeclarationOrigin.Java) return
|
||||
|
||||
val lookupTag = expression.annotationTypeRef.coneTypeSafe<ConeClassLikeType>()?.lookupTag ?: return
|
||||
javaToKotlinNameMap[lookupTag.classId]?.let { betterName ->
|
||||
reporter.reportOn(expression.source, FirJvmErrors.DEPRECATED_JAVA_ANNOTATION, betterName, context)
|
||||
}
|
||||
|
||||
if (expression is FirAnnotationCall) {
|
||||
val argumentList = expression.argumentList
|
||||
if (argumentList is FirResolvedArgumentList) {
|
||||
for ((key, value) in argumentList.mapping) {
|
||||
if (value.name != DEFAULT_ANNOTATION_MEMBER_NAME && key !is FirWrappedArgumentExpression) {
|
||||
reporter.reportOn(key.source, FirJvmErrors.POSITIONED_VALUE_ARGUMENT_FOR_JAVA_ANNOTATION, context)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
+2
@@ -59,6 +59,7 @@ import org.jetbrains.kotlin.fir.analysis.diagnostics.jvm.FirJvmErrors.OVERLOADS_
|
||||
import org.jetbrains.kotlin.fir.analysis.diagnostics.jvm.FirJvmErrors.OVERLOADS_PRIVATE
|
||||
import org.jetbrains.kotlin.fir.analysis.diagnostics.jvm.FirJvmErrors.OVERLOADS_WITHOUT_DEFAULT_ARGUMENTS
|
||||
import org.jetbrains.kotlin.fir.analysis.diagnostics.jvm.FirJvmErrors.OVERRIDE_CANNOT_BE_STATIC
|
||||
import org.jetbrains.kotlin.fir.analysis.diagnostics.jvm.FirJvmErrors.POSITIONED_VALUE_ARGUMENT_FOR_JAVA_ANNOTATION
|
||||
import org.jetbrains.kotlin.fir.analysis.diagnostics.jvm.FirJvmErrors.REPEATABLE_ANNOTATION_HAS_NESTED_CLASS_NAMED_CONTAINER
|
||||
import org.jetbrains.kotlin.fir.analysis.diagnostics.jvm.FirJvmErrors.REPEATABLE_CONTAINER_HAS_NON_DEFAULT_PARAMETER
|
||||
import org.jetbrains.kotlin.fir.analysis.diagnostics.jvm.FirJvmErrors.REPEATABLE_CONTAINER_HAS_SHORTER_RETENTION
|
||||
@@ -98,6 +99,7 @@ object FirJvmDefaultErrorMessages {
|
||||
"'@JvmOverloads' annotation cannot be used on constructors of annotation classes"
|
||||
)
|
||||
map.put(DEPRECATED_JAVA_ANNOTATION, "This annotation is deprecated in Kotlin. Use ''@{0}'' instead", TO_STRING)
|
||||
map.put(POSITIONED_VALUE_ARGUMENT_FOR_JAVA_ANNOTATION, "Only named arguments are available for Java annotations")
|
||||
map.put(JVM_PACKAGE_NAME_CANNOT_BE_EMPTY, "''@JvmPackageName'' annotation value cannot be empty")
|
||||
map.put(
|
||||
JVM_PACKAGE_NAME_MUST_BE_VALID_NAME,
|
||||
|
||||
+1
-1
@@ -25,5 +25,5 @@ public @interface A {
|
||||
@A fun test8() {}
|
||||
|
||||
@<!INAPPLICABLE_CANDIDATE!>A<!>(x = Any::class, *arrayOf("5", "6"), "7", y = 3) fun test9() {}
|
||||
@<!INAPPLICABLE_CANDIDATE!>A<!>(x = Any::class, value = ["5", "6"], "7", y = 3) fun test10() {}
|
||||
@<!INAPPLICABLE_CANDIDATE!>A<!>(x = Any::class, value = ["5", "6"], <!POSITIONED_VALUE_ARGUMENT_FOR_JAVA_ANNOTATION!>"7"<!>, y = 3) fun test10() {}
|
||||
@A(x = Any::class, value = ["5", "6", "7"], y = 3) fun test11() {}
|
||||
|
||||
+3
-3
@@ -6,6 +6,6 @@ public @interface A {
|
||||
}
|
||||
|
||||
// FILE: b.kt
|
||||
@A(false,
|
||||
1.0,
|
||||
false, <!TOO_MANY_ARGUMENTS!>1<!>, <!TOO_MANY_ARGUMENTS!>2<!>) fun foo1() {}
|
||||
@A(<!POSITIONED_VALUE_ARGUMENT_FOR_JAVA_ANNOTATION!>false<!>,
|
||||
<!POSITIONED_VALUE_ARGUMENT_FOR_JAVA_ANNOTATION!>1.0<!>,
|
||||
<!POSITIONED_VALUE_ARGUMENT_FOR_JAVA_ANNOTATION!>false<!>, <!TOO_MANY_ARGUMENTS!>1<!>, <!TOO_MANY_ARGUMENTS!>2<!>) fun foo1() {}
|
||||
|
||||
+4
-4
@@ -6,8 +6,8 @@ public @interface A {
|
||||
}
|
||||
|
||||
// FILE: b.kt
|
||||
@A(<!ARGUMENT_TYPE_MISMATCH!>false<!>,
|
||||
1.0,
|
||||
false) fun foo1() {}
|
||||
@A(<!ARGUMENT_TYPE_MISMATCH, POSITIONED_VALUE_ARGUMENT_FOR_JAVA_ANNOTATION!>false<!>,
|
||||
<!POSITIONED_VALUE_ARGUMENT_FOR_JAVA_ANNOTATION!>1.0<!>,
|
||||
<!POSITIONED_VALUE_ARGUMENT_FOR_JAVA_ANNOTATION!>false<!>) fun foo1() {}
|
||||
|
||||
@A(<!ARGUMENT_TYPE_MISMATCH!>2.0<!>, x = true, b = 2.0) fun foo2() {}
|
||||
@A(<!ARGUMENT_TYPE_MISMATCH, POSITIONED_VALUE_ARGUMENT_FOR_JAVA_ANNOTATION!>2.0<!>, x = true, b = 2.0) fun foo2() {}
|
||||
|
||||
-17
@@ -1,17 +0,0 @@
|
||||
// FILE: A.java
|
||||
public @interface A {
|
||||
int a();
|
||||
double b();
|
||||
String value();
|
||||
boolean x();
|
||||
}
|
||||
|
||||
// FILE: b.kt
|
||||
@A("v1", 1,
|
||||
1.0,
|
||||
false) fun foo1() {}
|
||||
|
||||
@A("v2", 2, x = true, b = 2.0) fun foo2() {}
|
||||
|
||||
@A("v2", x = true, b = 3.0, a = 4) fun foo3() {}
|
||||
@A(value = "v2", x = true, b = 3.0, a = 4) fun foo4() {}
|
||||
Vendored
+1
@@ -1,3 +1,4 @@
|
||||
// FIR_IDENTICAL
|
||||
// FILE: A.java
|
||||
public @interface A {
|
||||
int a();
|
||||
|
||||
-17
@@ -1,17 +0,0 @@
|
||||
// FILE: A.java
|
||||
public @interface A {
|
||||
int a();
|
||||
double b();
|
||||
boolean x();
|
||||
}
|
||||
|
||||
// FILE: b.kt
|
||||
@A(1,
|
||||
1.0,
|
||||
false) fun foo1() {}
|
||||
|
||||
@A(2, x = true, b = 2.0) fun foo2() {}
|
||||
|
||||
@A(x = true, b = 3.0, a = 4) fun foo3() {}
|
||||
|
||||
|
||||
compiler/testData/diagnostics/testsWithStdLib/annotations/prohibitPositionedArgument/withoutValue.kt
Vendored
+1
@@ -1,3 +1,4 @@
|
||||
// FIR_IDENTICAL
|
||||
// FILE: A.java
|
||||
public @interface A {
|
||||
int a();
|
||||
|
||||
+6
@@ -3743,6 +3743,12 @@ internal val KT_DIAGNOSTIC_CONVERTER = KtDiagnosticConverterBuilder.buildConvert
|
||||
token,
|
||||
)
|
||||
}
|
||||
add(FirJvmErrors.POSITIONED_VALUE_ARGUMENT_FOR_JAVA_ANNOTATION) { firDiagnostic ->
|
||||
PositionedValueArgumentForJavaAnnotationImpl(
|
||||
firDiagnostic as FirPsiDiagnostic,
|
||||
token,
|
||||
)
|
||||
}
|
||||
add(FirJvmErrors.LOCAL_JVM_RECORD) { firDiagnostic ->
|
||||
LocalJvmRecordImpl(
|
||||
firDiagnostic as FirPsiDiagnostic,
|
||||
|
||||
+4
@@ -2604,6 +2604,10 @@ sealed class KtFirDiagnostic<PSI : PsiElement> : KtDiagnosticWithPsi<PSI> {
|
||||
override val diagnosticClass get() = JvmPackageNameNotSupportedInFilesWithClasses::class
|
||||
}
|
||||
|
||||
abstract class PositionedValueArgumentForJavaAnnotation : KtFirDiagnostic<KtExpression>() {
|
||||
override val diagnosticClass get() = PositionedValueArgumentForJavaAnnotation::class
|
||||
}
|
||||
|
||||
abstract class LocalJvmRecord : KtFirDiagnostic<PsiElement>() {
|
||||
override val diagnosticClass get() = LocalJvmRecord::class
|
||||
}
|
||||
|
||||
+7
@@ -4231,6 +4231,13 @@ internal class JvmPackageNameNotSupportedInFilesWithClassesImpl(
|
||||
override val firDiagnostic: FirPsiDiagnostic by weakRef(firDiagnostic)
|
||||
}
|
||||
|
||||
internal class PositionedValueArgumentForJavaAnnotationImpl(
|
||||
firDiagnostic: FirPsiDiagnostic,
|
||||
override val token: ValidityToken,
|
||||
) : KtFirDiagnostic.PositionedValueArgumentForJavaAnnotation(), KtAbstractFirDiagnostic<KtExpression> {
|
||||
override val firDiagnostic: FirPsiDiagnostic by weakRef(firDiagnostic)
|
||||
}
|
||||
|
||||
internal class LocalJvmRecordImpl(
|
||||
firDiagnostic: FirPsiDiagnostic,
|
||||
override val token: ValidityToken,
|
||||
|
||||
Reference in New Issue
Block a user