diff --git a/compiler-plugin/compiler-plugin-k2/src/main/core/kotlinx/rpc/codegen/FirRpcPredicates.kt b/compiler-plugin/compiler-plugin-k2/src/main/core/kotlinx/rpc/codegen/FirRpcPredicates.kt index 0ae4f297..a8bae872 100644 --- a/compiler-plugin/compiler-plugin-k2/src/main/core/kotlinx/rpc/codegen/FirRpcPredicates.kt +++ b/compiler-plugin/compiler-plugin-k2/src/main/core/kotlinx/rpc/codegen/FirRpcPredicates.kt @@ -1,5 +1,5 @@ /* - * Copyright 2023-2024 JetBrains s.r.o and contributors. Use of this source code is governed by the Apache 2.0 license. + * Copyright 2023-2025 JetBrains s.r.o and contributors. Use of this source code is governed by the Apache 2.0 license. */ package kotlinx.rpc.codegen @@ -12,6 +12,10 @@ object FirRpcPredicates { annotated(RpcClassId.rpcAnnotation.asSingleFqName()) // @Rpc } + internal val rpcMeta = DeclarationPredicate.create { + metaAnnotated(RpcClassId.rpcAnnotation.asSingleFqName(), includeItself = true) + } + internal val checkedAnnotationMeta = DeclarationPredicate.create { metaAnnotated(RpcClassId.checkedTypeAnnotation.asSingleFqName(), includeItself = false) } diff --git a/compiler-plugin/compiler-plugin-k2/src/main/core/kotlinx/rpc/codegen/checkers/FirRpcAnnotationChecker.kt b/compiler-plugin/compiler-plugin-k2/src/main/core/kotlinx/rpc/codegen/checkers/FirRpcAnnotationChecker.kt index a7e05366..4221420b 100644 --- a/compiler-plugin/compiler-plugin-k2/src/main/core/kotlinx/rpc/codegen/checkers/FirRpcAnnotationChecker.kt +++ b/compiler-plugin/compiler-plugin-k2/src/main/core/kotlinx/rpc/codegen/checkers/FirRpcAnnotationChecker.kt @@ -1,5 +1,5 @@ /* - * Copyright 2023-2024 JetBrains s.r.o and contributors. Use of this source code is governed by the Apache 2.0 license. + * Copyright 2023-2025 JetBrains s.r.o and contributors. Use of this source code is governed by the Apache 2.0 license. */ package kotlinx.rpc.codegen.checkers @@ -9,7 +9,9 @@ import kotlinx.rpc.codegen.FirRpcPredicates import kotlinx.rpc.codegen.checkers.diagnostics.FirRpcDiagnostics import kotlinx.rpc.codegen.isRemoteService import kotlinx.rpc.codegen.remoteServiceSupertypeSource +import kotlinx.rpc.codegen.rpcAnnotation import kotlinx.rpc.codegen.rpcAnnotationSource +import org.jetbrains.kotlin.descriptors.ClassKind import org.jetbrains.kotlin.diagnostics.DiagnosticReporter import org.jetbrains.kotlin.diagnostics.reportOn import org.jetbrains.kotlin.fir.analysis.checkers.MppCheckerKind @@ -18,6 +20,7 @@ import org.jetbrains.kotlin.fir.analysis.checkers.declaration.FirRegularClassChe import org.jetbrains.kotlin.fir.declarations.FirRegularClass import org.jetbrains.kotlin.fir.declarations.utils.isInterface import org.jetbrains.kotlin.fir.extensions.predicateBasedProvider +import org.jetbrains.kotlin.fir.types.resolvedType class FirRpcAnnotationChecker(private val ctx: FirCheckersContext) : FirRegularClassChecker(MppCheckerKind.Common) { override fun check( @@ -26,12 +29,15 @@ class FirRpcAnnotationChecker(private val ctx: FirCheckersContext) : FirRegularC reporter: DiagnosticReporter, ) { val rpcAnnotated = context.session.predicateBasedProvider.matches(FirRpcPredicates.rpc, declaration) + val rpcMetaAnnotated = context.session.predicateBasedProvider.matches(FirRpcPredicates.rpcMeta, declaration) - if (!declaration.isInterface && rpcAnnotated) { + if (!declaration.isInterface && declaration.classKind != ClassKind.ANNOTATION_CLASS && rpcMetaAnnotated) { reporter.reportOn( source = declaration.symbol.rpcAnnotationSource(context.session), factory = FirRpcDiagnostics.WRONG_RPC_ANNOTATION_TARGET, context = context, + a = declaration.symbol.rpcAnnotation(context.session)?.resolvedType + ?: error("Unexpected unresolved annotation type for declaration: ${declaration.symbol.classId.asSingleFqName()}"), ) } diff --git a/compiler-plugin/compiler-plugin-k2/src/main/core/kotlinx/rpc/codegen/checkers/diagnostics/FirRpcDiagnostics.kt b/compiler-plugin/compiler-plugin-k2/src/main/core/kotlinx/rpc/codegen/checkers/diagnostics/FirRpcDiagnostics.kt index dc9701e8..ecb6e253 100644 --- a/compiler-plugin/compiler-plugin-k2/src/main/core/kotlinx/rpc/codegen/checkers/diagnostics/FirRpcDiagnostics.kt +++ b/compiler-plugin/compiler-plugin-k2/src/main/core/kotlinx/rpc/codegen/checkers/diagnostics/FirRpcDiagnostics.kt @@ -1,5 +1,5 @@ /* - * Copyright 2023-2024 JetBrains s.r.o and contributors. Use of this source code is governed by the Apache 2.0 license. + * Copyright 2023-2025 JetBrains s.r.o and contributors. Use of this source code is governed by the Apache 2.0 license. */ package kotlinx.rpc.codegen.checkers.diagnostics @@ -19,7 +19,7 @@ import org.jetbrains.kotlin.psi.KtAnnotationEntry object FirRpcDiagnostics { val MISSING_RPC_ANNOTATION by error0() val MISSING_SERIALIZATION_MODULE by warning0() - val WRONG_RPC_ANNOTATION_TARGET by error0() + val WRONG_RPC_ANNOTATION_TARGET by error1() val CHECKED_ANNOTATION_VIOLATION by error1() val NON_SUSPENDING_REQUEST_WITHOUT_STREAMING_RETURN_TYPE by error0() val AD_HOC_POLYMORPHISM_IN_RPC_SERVICE by error2() diff --git a/compiler-plugin/compiler-plugin-k2/src/main/core/kotlinx/rpc/codegen/checkers/diagnostics/RpcDiagnosticRendererFactory.kt b/compiler-plugin/compiler-plugin-k2/src/main/core/kotlinx/rpc/codegen/checkers/diagnostics/RpcDiagnosticRendererFactory.kt index 4c642500..20ca86be 100644 --- a/compiler-plugin/compiler-plugin-k2/src/main/core/kotlinx/rpc/codegen/checkers/diagnostics/RpcDiagnosticRendererFactory.kt +++ b/compiler-plugin/compiler-plugin-k2/src/main/core/kotlinx/rpc/codegen/checkers/diagnostics/RpcDiagnosticRendererFactory.kt @@ -1,5 +1,5 @@ /* - * Copyright 2023-2024 JetBrains s.r.o and contributors. Use of this source code is governed by the Apache 2.0 license. + * Copyright 2023-2025 JetBrains s.r.o and contributors. Use of this source code is governed by the Apache 2.0 license. */ package kotlinx.rpc.codegen.checkers.diagnostics @@ -29,7 +29,8 @@ object RpcDiagnosticRendererFactory : BaseDiagnosticRendererFactory() { put( factory = FirRpcDiagnostics.WRONG_RPC_ANNOTATION_TARGET, - message = "@Rpc annotation is only applicable to interfaces.", + message = "@{0} annotation is only applicable to interfaces and annotation classes.", + rendererA = FirDiagnosticRenderers.RENDER_TYPE, ) put( diff --git a/tests/compiler-plugin-tests/src/test-gen/kotlinx/rpc/codegen/test/runners/BoxTestGenerated.java b/tests/compiler-plugin-tests/src/test-gen/kotlinx/rpc/codegen/test/runners/BoxTestGenerated.java index 9afb1df1..ea1dbe62 100644 --- a/tests/compiler-plugin-tests/src/test-gen/kotlinx/rpc/codegen/test/runners/BoxTestGenerated.java +++ b/tests/compiler-plugin-tests/src/test-gen/kotlinx/rpc/codegen/test/runners/BoxTestGenerated.java @@ -11,6 +11,7 @@ import org.jetbrains.kotlin.test.TargetBackend; import org.jetbrains.kotlin.test.TestMetadata; import org.junit.Ignore; +import org.junit.jupiter.api.Disabled; import org.junit.jupiter.api.Test; import java.io.File; @@ -20,7 +21,7 @@ @SuppressWarnings("all") @TestMetadata("src/testData/box") @TestDataPath("$PROJECT_ROOT") -@Ignore +@Disabled("KRPC-137") public class BoxTestGenerated extends AbstractBoxTest { @Test public void testAllFilesPresentInBox() { diff --git a/tests/compiler-plugin-tests/src/test-gen/kotlinx/rpc/codegen/test/runners/DiagnosticTestGenerated.java b/tests/compiler-plugin-tests/src/test-gen/kotlinx/rpc/codegen/test/runners/DiagnosticTestGenerated.java index 380c3bed..94cdb931 100644 --- a/tests/compiler-plugin-tests/src/test-gen/kotlinx/rpc/codegen/test/runners/DiagnosticTestGenerated.java +++ b/tests/compiler-plugin-tests/src/test-gen/kotlinx/rpc/codegen/test/runners/DiagnosticTestGenerated.java @@ -9,9 +9,8 @@ import com.intellij.testFramework.TestDataPath; import org.jetbrains.kotlin.test.util.KtTestUtil; import org.jetbrains.kotlin.test.TestMetadata; -import org.junit.Ignore; +import org.junit.jupiter.api.Disabled; import org.junit.jupiter.api.Test; - import java.io.File; import java.util.regex.Pattern; @@ -19,7 +18,7 @@ @SuppressWarnings("all") @TestMetadata("src/testData/diagnostics") @TestDataPath("$PROJECT_ROOT") -@Ignore +@Disabled("KRPC-137") public class DiagnosticTestGenerated extends AbstractDiagnosticTest { @Test public void testAllFilesPresentInDiagnostics() { diff --git a/tests/compiler-plugin-tests/src/testData/diagnostics/rpcChecked.kt b/tests/compiler-plugin-tests/src/testData/diagnostics/rpcChecked.kt index 51efbb45..a478a830 100644 --- a/tests/compiler-plugin-tests/src/testData/diagnostics/rpcChecked.kt +++ b/tests/compiler-plugin-tests/src/testData/diagnostics/rpcChecked.kt @@ -1,5 +1,5 @@ /* - * Copyright 2023-2024 JetBrains s.r.o and contributors. Use of this source code is governed by the Apache 2.0 license. + * Copyright 2023-2025 JetBrains s.r.o and contributors. Use of this source code is governed by the Apache 2.0 license. */ @file:OptIn(ExperimentalRpcApi::class) @@ -61,3 +61,15 @@ inline suspend fun fail(client: RpcClient, server: RpcServer, serviceDescriptorOf<NotAService>() serviceDescriptorOf<T>() } + +@Rpc +annotation class Grpc + +@Grpc +interface MyGrpcService + +@Grpc +class WrongGrpcTarget + +@Rpc +class WrongRpcTarget