Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion gradle.properties
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
kotlin.code.style=official
group=io.github.eventhorizonlab
baseVersion=0.1.21
baseVersion=0.1.23
org.gradle.jvmargs=-Xmx2g -Dfile.encoding=UTF-8
Original file line number Diff line number Diff line change
Expand Up @@ -98,27 +98,33 @@ class ServiceSchemeProcessor : AbstractProcessor() {

roundEnv.rootElements
.filterIsInstance<TypeElement>()
.filter { it.kind == ElementKind.CLASS }
.forEach { clazz ->
val implementsContract =
contractTypeMirrors.any { ct ->
processingEnv.typeUtils.isAssignable(clazz.asType(), ct)
}
val hasServiceProvider =
clazz.annotationMirrors.any {
(it.annotationType.asElement() as TypeElement).qualifiedName.toString() ==
// Only check concrete classes; skip interfaces and abstract
if (clazz.kind != ElementKind.CLASS) return@forEach
if (clazz.modifiers.contains(javax.lang.model.element.Modifier.ABSTRACT)) return@forEach

// Skip common Kotlin synthetic helper classes, but DO NOT skip nested user classes
val simple = clazz.simpleName.toString()
if (simple == "DefaultImpls") return@forEach
Comment on lines +106 to +108

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟠 Major | ⚑ Quick win

Narrow the synthetic-class filter to binary-name pattern, not simple name.

At Line 108, simple == "DefaultImpls" can skip real user classes named DefaultImpls, which suppresses required missing-@ServiceProvider errors. Filter by binary name suffix (e.g., "$DefaultImpls") instead.

Proposed fix
-                val simple = clazz.simpleName.toString()
-                if (simple == "DefaultImpls") return@forEach
+                val binaryName = processingEnv.getStringifiedBinaryName(clazz)
+                if (binaryName.endsWith("\$DefaultImpls")) return@forEach
πŸ€– Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In
`@modules/processor/src/main/kotlin/com/github/eventhorizonlab/spi/ServiceSchemeProcessor.kt`
around lines 106 - 108, The current filter in ServiceSchemeProcessor uses
clazz.simpleName == "DefaultImpls" which incorrectly excludes real user classes
named "DefaultImpls"; update the check to inspect the class binary name and only
skip when the binary name ends with "$DefaultImpls" (e.g., use clazz.name or
binary-name equivalent and test endsWith("$DefaultImpls")) so nested/synthetic
helper classes are filtered but real top-level classes named DefaultImpls are
not; keep the surrounding comment and ensure the condition is applied where
clazz and simple are used (replace the simple == "DefaultImpls" check).


val implementsContract = contractTypeMirrors.any { ct ->
processingEnv.typeUtils.isAssignable(clazz.asType(), ct)
}
if (!implementsContract) return@forEach

val hasServiceProvider = clazz.annotationMirrors.any {
(it.annotationType.asElement() as TypeElement).qualifiedName.toString() ==
ServiceProvider::class.java.canonicalName
}
if (implementsContract && !hasServiceProvider) {
val contractName =
contractTypes
.first {
processingEnv.typeUtils.isAssignable(clazz.asType(), it.asType())
}.qualifiedName
.toString()
}
if (!hasServiceProvider) {
// Find the contract name for the message
val contractName = contractTypes.first {
processingEnv.typeUtils.isAssignable(clazz.asType(), it.asType())
}.qualifiedName.toString()

processingEnv.messager.printMessage(
Diagnostic.Kind.ERROR,
missingServiceProviderErrorMessage(contractName),
missingServiceProviderErrorMessage(contractName)
)
}
}
Expand Down