From 9d4fb237aa35f8ece7408e9af3c5f63d68fbee90 Mon Sep 17 00:00:00 2001 From: LMLiam <46268350+TheRealEmissions@users.noreply.github.com> Date: Thu, 30 Oct 2025 15:02:06 +0000 Subject: [PATCH 1/3] Attempt fix --- gradle.properties | 2 +- .../spi/ServiceSchemeProcessor.kt | 47 ++++++++++++------- 2 files changed, 30 insertions(+), 19 deletions(-) diff --git a/gradle.properties b/gradle.properties index bc35d3a..1896268 100644 --- a/gradle.properties +++ b/gradle.properties @@ -1,4 +1,4 @@ kotlin.code.style=official group=io.github.eventhorizonlab -baseVersion=0.1.21 +baseVersion=0.1.22 org.gradle.jvmargs=-Xmx2g -Dfile.encoding=UTF-8 diff --git a/modules/processor/src/main/kotlin/com/github/eventhorizonlab/spi/ServiceSchemeProcessor.kt b/modules/processor/src/main/kotlin/com/github/eventhorizonlab/spi/ServiceSchemeProcessor.kt index e3ad51b..110aebe 100644 --- a/modules/processor/src/main/kotlin/com/github/eventhorizonlab/spi/ServiceSchemeProcessor.kt +++ b/modules/processor/src/main/kotlin/com/github/eventhorizonlab/spi/ServiceSchemeProcessor.kt @@ -96,31 +96,42 @@ class ServiceSchemeProcessor : AbstractProcessor() { val contractTypes = contracts.mapNotNull { processingEnv.elementUtils.getTypeElement(it) } val contractTypeMirrors = contractTypes.map { it.asType() }.toSet() + val contractsWithProviders = providers.map { it.contractCanonical }.toSet() + val declaredHereNoProviders = contracts + .filter { canonical -> canonical !in contractsWithProviders } + .toSet() + roundEnv.rootElements .filterIsInstance() .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() == + val hasServiceProvider = clazz.annotationMirrors.any { + (it.annotationType.asElement() as TypeElement).qualifiedName.toString() == ServiceProvider::class.java.canonicalName + } + + // Only consider classes that explicitly declare one of our contracts in 'implements' + val implementsContractDirectly = clazz.interfaces.any { tm -> + contractTypeMirrors.any { ct -> + processingEnv.typeUtils.isSameType(tm, ct) } - if (implementsContract && !hasServiceProvider) { - val contractName = - contractTypes - .first { - processingEnv.typeUtils.isAssignable(clazz.asType(), it.asType()) - }.qualifiedName - .toString() - processingEnv.messager.printMessage( - Diagnostic.Kind.ERROR, - missingServiceProviderErrorMessage(contractName), - ) } + if (!implementsContractDirectly || hasServiceProvider) return@forEach + + // Identify the specific contract name for the message + val contractName = contractTypes.first { + clazz.interfaces.any { im -> + processingEnv.typeUtils.isSameType(im, it.asType()) + } + }.qualifiedName.toString() + + // Do not error for contracts declared in this module that currently have no providers + if (contractName in declaredHereNoProviders) return@forEach + + processingEnv.messager.printMessage( + Diagnostic.Kind.ERROR, + missingServiceProviderErrorMessage(contractName) + ) } } From bf263d9e3f1d07e679b2baa2cf40e8383ad401b3 Mon Sep 17 00:00:00 2001 From: LMLiam <46268350+TheRealEmissions@users.noreply.github.com> Date: Thu, 30 Oct 2025 15:08:00 +0000 Subject: [PATCH 2/3] Attempt fix --- .../spi/ServiceSchemeProcessor.kt | 49 +++++++++---------- 1 file changed, 22 insertions(+), 27 deletions(-) diff --git a/modules/processor/src/main/kotlin/com/github/eventhorizonlab/spi/ServiceSchemeProcessor.kt b/modules/processor/src/main/kotlin/com/github/eventhorizonlab/spi/ServiceSchemeProcessor.kt index 110aebe..4ce7347 100644 --- a/modules/processor/src/main/kotlin/com/github/eventhorizonlab/spi/ServiceSchemeProcessor.kt +++ b/modules/processor/src/main/kotlin/com/github/eventhorizonlab/spi/ServiceSchemeProcessor.kt @@ -96,42 +96,37 @@ class ServiceSchemeProcessor : AbstractProcessor() { val contractTypes = contracts.mapNotNull { processingEnv.elementUtils.getTypeElement(it) } val contractTypeMirrors = contractTypes.map { it.asType() }.toSet() - val contractsWithProviders = providers.map { it.contractCanonical }.toSet() - val declaredHereNoProviders = contracts - .filter { canonical -> canonical !in contractsWithProviders } - .toSet() - roundEnv.rootElements .filterIsInstance() - .filter { it.kind == ElementKind.CLASS } .forEach { clazz -> + // 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 + + 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 (!hasServiceProvider) { + // Find the contract name for the message + val contractName = contractTypes.first { + processingEnv.typeUtils.isAssignable(clazz.asType(), it.asType()) + }.qualifiedName.toString() - // Only consider classes that explicitly declare one of our contracts in 'implements' - val implementsContractDirectly = clazz.interfaces.any { tm -> - contractTypeMirrors.any { ct -> - processingEnv.typeUtils.isSameType(tm, ct) - } + processingEnv.messager.printMessage( + Diagnostic.Kind.ERROR, + missingServiceProviderErrorMessage(contractName) + ) } - if (!implementsContractDirectly || hasServiceProvider) return@forEach - - // Identify the specific contract name for the message - val contractName = contractTypes.first { - clazz.interfaces.any { im -> - processingEnv.typeUtils.isSameType(im, it.asType()) - } - }.qualifiedName.toString() - - // Do not error for contracts declared in this module that currently have no providers - if (contractName in declaredHereNoProviders) return@forEach - - processingEnv.messager.printMessage( - Diagnostic.Kind.ERROR, - missingServiceProviderErrorMessage(contractName) - ) } } From 44a3ea5afb58bdfeade8ae0f602eaf022418983b Mon Sep 17 00:00:00 2001 From: LMLiam <46268350+TheRealEmissions@users.noreply.github.com> Date: Thu, 30 Oct 2025 15:20:53 +0000 Subject: [PATCH 3/3] Bump version --- gradle.properties | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/gradle.properties b/gradle.properties index 1896268..246458d 100644 --- a/gradle.properties +++ b/gradle.properties @@ -1,4 +1,4 @@ kotlin.code.style=official group=io.github.eventhorizonlab -baseVersion=0.1.22 +baseVersion=0.1.23 org.gradle.jvmargs=-Xmx2g -Dfile.encoding=UTF-8