diff --git a/build-support/src/main/java/dev/drewhamilton/poko/build/PokoBuildPlugin.kt b/build-support/src/main/java/dev/drewhamilton/poko/build/PokoBuildPlugin.kt index a8b66fb6..08cd24d2 100644 --- a/build-support/src/main/java/dev/drewhamilton/poko/build/PokoBuildPlugin.kt +++ b/build-support/src/main/java/dev/drewhamilton/poko/build/PokoBuildPlugin.kt @@ -107,7 +107,6 @@ class PokoBuildPlugin : Plugin { buildConfigField("COMPILER_PLUGIN_ARTIFACT", "poko-compiler-plugin") buildConfigField("DEFAULT_POKO_ENABLED", true) buildConfigField("DEFAULT_POKO_ANNOTATION", "dev/drewhamilton/poko/Poko") - buildConfigField("SKIP_ANNOTATION_SHORT_NAME", "Skip") } } } diff --git a/poko-compiler-plugin/src/main/kotlin/dev/drewhamilton/poko/PokoAnnotationNames.kt b/poko-compiler-plugin/src/main/kotlin/dev/drewhamilton/poko/PokoAnnotationNames.kt new file mode 100644 index 00000000..4e36bce0 --- /dev/null +++ b/poko-compiler-plugin/src/main/kotlin/dev/drewhamilton/poko/PokoAnnotationNames.kt @@ -0,0 +1,8 @@ +package dev.drewhamilton.poko + +import org.jetbrains.kotlin.name.Name + +internal object PokoAnnotationNames { + val ReadArrayContent = Name.identifier("ReadArrayContent") + val Skip = Name.identifier("Skip") +} diff --git a/poko-compiler-plugin/src/main/kotlin/dev/drewhamilton/poko/fir/PokoFirCheckersExtension.kt b/poko-compiler-plugin/src/main/kotlin/dev/drewhamilton/poko/fir/PokoFirCheckersExtension.kt index 9b2a957b..80f43cc7 100644 --- a/poko-compiler-plugin/src/main/kotlin/dev/drewhamilton/poko/fir/PokoFirCheckersExtension.kt +++ b/poko-compiler-plugin/src/main/kotlin/dev/drewhamilton/poko/fir/PokoFirCheckersExtension.kt @@ -19,6 +19,7 @@ import org.jetbrains.kotlin.fir.analysis.checkers.declaration.DeclarationChecker import org.jetbrains.kotlin.fir.analysis.checkers.declaration.FirRegularClassChecker import org.jetbrains.kotlin.fir.analysis.checkers.hasModifier import org.jetbrains.kotlin.fir.analysis.extensions.FirAdditionalCheckersExtension +import org.jetbrains.kotlin.fir.declarations.FirDeclaration import org.jetbrains.kotlin.fir.declarations.FirProperty import org.jetbrains.kotlin.fir.declarations.FirRegularClass import org.jetbrains.kotlin.fir.declarations.primaryConstructorIfAny @@ -28,6 +29,7 @@ import org.jetbrains.kotlin.fir.expressions.FirAnnotation import org.jetbrains.kotlin.fir.types.classId import org.jetbrains.kotlin.fir.types.coneTypeOrNull import org.jetbrains.kotlin.lexer.KtTokens +import org.jetbrains.kotlin.name.ClassId internal class PokoFirCheckersExtension( session: FirSession, @@ -46,8 +48,8 @@ internal class PokoFirCheckersExtension( context: CheckerContext, reporter: DiagnosticReporter, ) { - val matcher = context.session.pokoFirExtensionSessionComponent - if (matcher.pokoAnnotation(declaration) == null) return + val sessionComponent = context.session.pokoFirExtensionSessionComponent + if (!declaration.hasAnnotation(sessionComponent.pokoAnnotation)) return val errorFactory = when { declaration.classKind != ClassKind.CLASS -> Diagnostics.PokoOnNonClass @@ -72,11 +74,9 @@ internal class PokoFirCheckersExtension( it.source?.kind is KtFakeSourceElementKind.PropertyFromParameter } .filter { - val skipAnnotation = matcher.pokoSkipAnnotation(it) - if ( - skipAnnotation != null && - !skipAnnotation.isNestedInDefaultPokoAnnotation() - ) { + val skipAnnotation = sessionComponent.pokoSkipAnnotation + val hasSkipAnnotation = it.hasAnnotation(skipAnnotation) + if (hasSkipAnnotation && !skipAnnotation.isNestedInDefaultPokoAnnotation()) { // Pseudo-opt-in warning for custom annotation consumers: reporter.reportOn( source = it.source, @@ -84,7 +84,7 @@ internal class PokoFirCheckersExtension( context = context, ) } - skipAnnotation == null + !hasSkipAnnotation } if (constructorProperties.isEmpty()) { reporter.reportOn( @@ -95,13 +95,23 @@ internal class PokoFirCheckersExtension( } } - private fun FirAnnotation.isNestedInDefaultPokoAnnotation(): Boolean { - val outerFqName = annotationTypeRef.coneTypeOrNull!!.classId!! - .outerClassId!! - .asFqNameString() + private fun FirDeclaration.hasAnnotation( + annotation: ClassId, + ): Boolean { + return annotations.any { firAnnotation -> + firAnnotation.classId() == annotation + } + } + + private fun FirAnnotation.classId(): ClassId? { + return annotationTypeRef.coneTypeOrNull?.classId + } + + private fun ClassId.isNestedInDefaultPokoAnnotation(): Boolean { + val outerFqName = outerClassId?.asFqNameString() return outerFqName == DEFAULT_POKO_ANNOTATION || // Multiplatform FqName has "." instead of "/" for package: - outerFqName.replace(".", "/") == DEFAULT_POKO_ANNOTATION + outerFqName?.replace(".", "/") == DEFAULT_POKO_ANNOTATION } } diff --git a/poko-compiler-plugin/src/main/kotlin/dev/drewhamilton/poko/fir/PokoFirExtensionSessionComponent.kt b/poko-compiler-plugin/src/main/kotlin/dev/drewhamilton/poko/fir/PokoFirExtensionSessionComponent.kt index c3499804..485937d7 100644 --- a/poko-compiler-plugin/src/main/kotlin/dev/drewhamilton/poko/fir/PokoFirExtensionSessionComponent.kt +++ b/poko-compiler-plugin/src/main/kotlin/dev/drewhamilton/poko/fir/PokoFirExtensionSessionComponent.kt @@ -1,38 +1,18 @@ package dev.drewhamilton.poko.fir -import dev.drewhamilton.poko.BuildConfig.SKIP_ANNOTATION_SHORT_NAME +import dev.drewhamilton.poko.PokoAnnotationNames import org.jetbrains.kotlin.fir.FirSession -import org.jetbrains.kotlin.fir.declarations.FirDeclaration -import org.jetbrains.kotlin.fir.expressions.FirAnnotation import org.jetbrains.kotlin.fir.extensions.FirExtensionSessionComponent import org.jetbrains.kotlin.fir.extensions.FirExtensionSessionComponent.Factory -import org.jetbrains.kotlin.fir.types.classId -import org.jetbrains.kotlin.fir.types.coneTypeOrNull import org.jetbrains.kotlin.name.ClassId -import org.jetbrains.kotlin.name.Name internal class PokoFirExtensionSessionComponent( session: FirSession, - private val pokoAnnotation: ClassId, + internal val pokoAnnotation: ClassId, ) : FirExtensionSessionComponent(session) { - fun pokoAnnotation(declaration: FirDeclaration): FirAnnotation? { - return declaration.annotations.firstOrNull { firAnnotation -> - firAnnotation.classId() == pokoAnnotation - } - } - - fun pokoSkipAnnotation(declaration: FirDeclaration): FirAnnotation? { - val skipAnnotation = pokoAnnotation.createNestedClassId( - name = Name.identifier(SKIP_ANNOTATION_SHORT_NAME), - ) - return declaration.annotations.firstOrNull { firAnnotation -> - firAnnotation.classId() == skipAnnotation - } - } - private fun FirAnnotation.classId(): ClassId? { - return annotationTypeRef.coneTypeOrNull?.classId - } + internal val pokoSkipAnnotation: ClassId = + pokoAnnotation.createNestedClassId(PokoAnnotationNames.Skip) internal companion object { internal fun getFactory(pokoAnnotation: ClassId): Factory { diff --git a/poko-compiler-plugin/src/main/kotlin/dev/drewhamilton/poko/ir/PokoMembersTransformer.kt b/poko-compiler-plugin/src/main/kotlin/dev/drewhamilton/poko/ir/PokoMembersTransformer.kt index f2bb543f..d46e41d2 100644 --- a/poko-compiler-plugin/src/main/kotlin/dev/drewhamilton/poko/ir/PokoMembersTransformer.kt +++ b/poko-compiler-plugin/src/main/kotlin/dev/drewhamilton/poko/ir/PokoMembersTransformer.kt @@ -1,6 +1,6 @@ package dev.drewhamilton.poko.ir -import dev.drewhamilton.poko.BuildConfig.SKIP_ANNOTATION_SHORT_NAME +import dev.drewhamilton.poko.PokoAnnotationNames import org.jetbrains.kotlin.KtFakeSourceElementKind import org.jetbrains.kotlin.backend.common.IrElementTransformerVoidWithContext import org.jetbrains.kotlin.backend.common.extensions.IrPluginContext @@ -134,9 +134,7 @@ internal class PokoMembersTransformer( } .filter { !it.hasAnnotation( - classId = ClassId.fromString( - string = "${pokoAnnotationName}.$SKIP_ANNOTATION_SHORT_NAME" - ), + classId = pokoAnnotationName.createNestedClassId(PokoAnnotationNames.Skip), ) } if (properties.isEmpty()) { diff --git a/poko-compiler-plugin/src/main/kotlin/dev/drewhamilton/poko/ir/functionGeneration.kt b/poko-compiler-plugin/src/main/kotlin/dev/drewhamilton/poko/ir/functionGeneration.kt index bcb8e73b..f08b45e0 100644 --- a/poko-compiler-plugin/src/main/kotlin/dev/drewhamilton/poko/ir/functionGeneration.kt +++ b/poko-compiler-plugin/src/main/kotlin/dev/drewhamilton/poko/ir/functionGeneration.kt @@ -1,5 +1,6 @@ package dev.drewhamilton.poko.ir +import dev.drewhamilton.poko.PokoAnnotationNames import org.jetbrains.kotlin.builtins.PrimitiveType import org.jetbrains.kotlin.ir.builders.IrBlockBodyBuilder import org.jetbrains.kotlin.ir.builders.IrGeneratorContextInterface @@ -25,7 +26,6 @@ import org.jetbrains.kotlin.ir.util.isAnnotationClass import org.jetbrains.kotlin.ir.util.isInterface import org.jetbrains.kotlin.ir.util.render import org.jetbrains.kotlin.name.ClassId -import org.jetbrains.kotlin.name.Name /** * The type of an [IrProperty]. @@ -62,7 +62,7 @@ internal fun IrBlockBodyBuilder.IrGetValueImpl( internal fun IrProperty.hasReadArrayContentAnnotation( pokoAnnotation: ClassId, ): Boolean = hasAnnotation( - classId = pokoAnnotation.createNestedClassId(Name.identifier("ReadArrayContent")), + classId = pokoAnnotation.createNestedClassId(PokoAnnotationNames.ReadArrayContent), ) /**