Skip to content

Commit 048d6e3

Browse files
Scope enum -> Scope object change
1 parent 67aeb6b commit 048d6e3

23 files changed

Lines changed: 59 additions & 63 deletions

README.md

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -26,10 +26,14 @@ to generate converters for the targets you use — while remaining fully type-sa
2626
For Gradle with Kotlin DSL:
2727

2828
```kotlin
29+
plugins {
30+
id("com.google.devtools.ksp") version "2.1.21-2.0.1"
31+
}
32+
2933
dependencies {
30-
implementation("pro.vlprojects:convertible-core:0.0.1")
31-
implementation("pro.vlprojects:convertible-jpa:0.0.1") // or other scopes
32-
ksp("pro.vlprojects:convertible-core:0.0.1")
34+
implementation("pro.vlprojects:convertible-core:0.0.2")
35+
implementation("pro.vlprojects:convertible-jpa:0.0.2") // or other scopes
36+
ksp("pro.vlprojects:convertible-core:0.0.2")
3337
}
3438
```
3539

@@ -51,7 +55,7 @@ class User(
5155

5256
3. Auto-generated converter
5357
```kotlin
54-
@Component
58+
@Component(value = "jpa.UserIdConverter")
5559
@Converter(autoApply = true)
5660
class UserIdConverter : AttributeConverter<UserId, String> {
5761
override fun convertToDatabaseColumn(attribute: UserId): String = attribute.raw

convertible-core/build.gradle.kts

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -10,9 +10,9 @@ repositories {
1010
}
1111

1212
dependencies {
13-
implementation("com.squareup:kotlinpoet:2.1.0")
14-
implementation("com.squareup:kotlinpoet-ksp:2.1.0")
15-
implementation("com.google.devtools.ksp:symbol-processing-api:2.1.10-1.0.29")
13+
implementation("com.squareup:kotlinpoet:2.2.0")
14+
implementation("com.squareup:kotlinpoet-ksp:2.2.0")
15+
implementation("com.google.devtools.ksp:symbol-processing-api:2.1.21-2.0.1")
1616
testImplementation(kotlin("test"))
1717
}
1818

convertible-core/src/main/kotlin/pro/vlprojects/convertible/core/annotation/Convertible.kt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,6 @@ package pro.vlprojects.convertible.core.annotation
44
@Retention(AnnotationRetention.BINARY)
55
@Repeatable
66
annotation class Convertible(
7-
val scopes: Array<Scope> = [],
7+
val scopes: Array<String> = [],
88
val nullable: Boolean = false,
99
)

convertible-core/src/main/kotlin/pro/vlprojects/convertible/core/annotation/ConvertibleFactory.kt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,5 +3,5 @@ package pro.vlprojects.convertible.core.annotation
33
@Target(AnnotationTarget.FUNCTION, AnnotationTarget.CONSTRUCTOR)
44
@Retention(AnnotationRetention.SOURCE)
55
annotation class ConvertibleFactory(
6-
val scopes: Array<Scope> = [],
6+
val scopes: Array<String> = [],
77
)

convertible-core/src/main/kotlin/pro/vlprojects/convertible/core/annotation/ConvertibleValue.kt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,5 +3,5 @@ package pro.vlprojects.convertible.core.annotation
33
@Target(AnnotationTarget.FUNCTION, AnnotationTarget.FIELD, AnnotationTarget.VALUE_PARAMETER)
44
@Retention(AnnotationRetention.SOURCE)
55
annotation class ConvertibleValue(
6-
val scopes: Array<Scope> = [],
6+
val scopes: Array<String> = [],
77
)
Lines changed: 5 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,8 @@
11
package pro.vlprojects.convertible.core.annotation
22

3-
enum class Scope {
4-
JPA,
5-
MONGODB,
6-
JACKSON,
7-
MVC,
8-
;
9-
10-
companion object Factory {
11-
fun from(name: String) = entries.firstOrNull { it.name.equals(name, ignoreCase = true) }
12-
}
3+
object Scope {
4+
const val JPA = "jpa"
5+
const val MONGODB = "mongodb"
6+
const val JACKSON = "jackson"
7+
const val MVC = "mvc"
138
}

convertible-core/src/main/kotlin/pro/vlprojects/convertible/core/definition/ConvertibleDefinition.kt

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,11 +6,10 @@ import com.google.devtools.ksp.symbol.KSPropertyDeclaration
66
import com.squareup.kotlinpoet.ClassName
77
import com.squareup.kotlinpoet.TypeName
88
import com.squareup.kotlinpoet.ksp.toTypeName
9-
import pro.vlprojects.convertible.core.annotation.Scope
109

1110
data class ConvertibleDefinition(
1211
val objectClassName: ClassName,
13-
val scope: Scope,
12+
val scope: String,
1413
val nullable: Boolean,
1514
val valueAccessor: ValueAccessor,
1615
val factoryAccessor: FactoryAccessor,

convertible-core/src/main/kotlin/pro/vlprojects/convertible/core/processor/ConvertibleProcessor.kt

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,6 @@ import com.squareup.kotlinpoet.FileSpec
1212
import pro.vlprojects.convertible.core.annotation.Convertible
1313
import pro.vlprojects.convertible.core.definition.ConvertibleDefinition
1414
import pro.vlprojects.convertible.core.strategy.ConvertibleStrategy
15-
import pro.vlprojects.convertible.core.processor.ConvertibleVisitor
1615
import java.io.OutputStreamWriter
1716
import java.util.ServiceLoader
1817

@@ -40,7 +39,7 @@ class ConvertibleProcessor(
4039

4140
override fun finish() = definitions
4241
.forEach { definition ->
43-
val targetPackage = "${definition.objectClassName.packageName}.${definition.scope.name.lowercase()}"
42+
val targetPackage = "${definition.objectClassName.packageName}.${definition.scope.lowercase()}"
4443
strategies
4544
.filter { it.supports(definition) }
4645
.forEach { strategy ->

convertible-core/src/main/kotlin/pro/vlprojects/convertible/core/processor/ConvertibleVisitor.kt

Lines changed: 14 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,6 @@ import com.google.devtools.ksp.symbol.KSAnnotated
55
import com.google.devtools.ksp.symbol.KSAnnotation
66
import com.google.devtools.ksp.symbol.KSClassDeclaration
77
import com.google.devtools.ksp.symbol.KSDeclaration
8-
import com.google.devtools.ksp.symbol.KSType
98
import com.google.devtools.ksp.symbol.KSVisitorVoid
109
import com.google.devtools.ksp.symbol.Modifier
1110
import com.squareup.kotlinpoet.TypeName
@@ -14,8 +13,9 @@ import com.squareup.kotlinpoet.ksp.toTypeName
1413
import pro.vlprojects.convertible.core.annotation.Convertible
1514
import pro.vlprojects.convertible.core.annotation.ConvertibleFactory
1615
import pro.vlprojects.convertible.core.annotation.ConvertibleValue
17-
import pro.vlprojects.convertible.core.annotation.Scope
1816
import pro.vlprojects.convertible.core.definition.ConvertibleDefinition
17+
import pro.vlprojects.convertible.core.definition.ConvertibleDefinition.FactoryAccessor
18+
import pro.vlprojects.convertible.core.definition.ConvertibleDefinition.ValueAccessor
1919
import kotlin.reflect.KClass
2020

2121
class ConvertibleVisitor(
@@ -55,7 +55,7 @@ class ConvertibleVisitor(
5555
}
5656
}
5757

58-
private fun resolveValueAccessor(declaration: KSClassDeclaration, scope: Scope) : ConvertibleDefinition.ValueAccessor {
58+
private fun resolveValueAccessor(declaration: KSClassDeclaration, scope: String) : ValueAccessor {
5959

6060
val className = declaration.simpleName.asString()
6161

@@ -81,7 +81,7 @@ class ConvertibleVisitor(
8181
check(method.isPublic()) { "Method $className.$methodName must be public" }
8282
check(method.parameters.all { it.hasDefault }) { "Method $className.$methodName must have default params only" }
8383

84-
return ConvertibleDefinition.ValueAccessor.Factory.from(method)
84+
return ValueAccessor.Factory.from(method)
8585
}
8686

8787
if (properties.isNotEmpty()) {
@@ -92,7 +92,7 @@ class ConvertibleVisitor(
9292
check(property.isPublic()) { "Property $className.$propertyName must be public" }
9393
check(!type.isMarkedNullable) { "Type of $className.$propertyName must NOT be nullable" }
9494

95-
return ConvertibleDefinition.ValueAccessor.Factory.from(property)
95+
return ValueAccessor.Factory.from(property)
9696
}
9797

9898
// Fallback: use first public property as ValueAccessor
@@ -101,14 +101,14 @@ class ConvertibleVisitor(
101101
check(fallbackProperty != null) { "No public property found in $className to use as fallback ConvertibleValue for scope $scope" }
102102
check(!fallbackProperty.type.resolve().isMarkedNullable) { "Fallback property $className.$fallbackProperty must NOT be nullable" }
103103

104-
return ConvertibleDefinition.ValueAccessor.Factory.from(fallbackProperty)
104+
return ValueAccessor.Factory.from(fallbackProperty)
105105
}
106106

107107
private fun resolveFactoryAccessor(
108108
declaration: KSClassDeclaration,
109109
argumentType: TypeName,
110-
scope: Scope,
111-
) : ConvertibleDefinition.FactoryAccessor {
110+
scope: String,
111+
) : FactoryAccessor {
112112

113113
val className = declaration.simpleName.asString()
114114

@@ -133,7 +133,7 @@ class ConvertibleVisitor(
133133
check(method.isPublic()) { "Method $className.$methodName is not public" }
134134
check(arguments.size == 1) { "Exactly one argument of type $argumentType expected in method $className.$methodName" }
135135

136-
return ConvertibleDefinition.FactoryAccessor.Factory.from(method)
136+
return FactoryAccessor.Factory.from(method)
137137
}
138138

139139
// Fallback: use public constructor as FactoryAccessor
@@ -145,24 +145,17 @@ class ConvertibleVisitor(
145145
check(constructor != null) { "No public constructor found in $className" }
146146
check(constructorArguments?.size == 1) { "Exactly one argument of type $argumentType expected in constructor $className" }
147147

148-
return ConvertibleDefinition.FactoryAccessor.Factory.from(constructor)
148+
return FactoryAccessor.Factory.from(constructor)
149149
}
150150

151-
private fun KSAnnotated.hasAnnotationWithScope(annotation: KClass<*>, scope: Scope) = annotations
151+
private fun KSAnnotated.hasAnnotationWithScope(annotation: KClass<*>, scope: String) = annotations
152152
.filter { it.isOf(annotation) }
153153
.flatMap { it.getScopes() }
154154
.contains(scope)
155155

156-
private fun KSAnnotation.getScopes(): List<Scope> {
157-
val values = getArgument<List<*>>("scopes") ?: return emptyList()
158-
159-
return values
160-
.filterIsInstance<KSDeclaration>()
161-
.mapNotNull { type ->
162-
val typeName = type.simpleName.asString()
163-
Scope.entries.firstOrNull { it.name == typeName }
164-
}
165-
}
156+
private fun KSAnnotation.getScopes() = getArgument<List<*>>("scopes")
157+
?.filterIsInstance<String>()
158+
?: emptyList()
166159

167160
private fun KSAnnotation.isOf(annotation: KClass<*>) = shortName.asString() == annotation.simpleName
168161

convertible-jpa/build.gradle.kts

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -15,12 +15,12 @@ dependencies {
1515
implementation("jakarta.persistence:jakarta.persistence-api:3.1.0")
1616
implementation("org.springframework:spring-context:6.2.6")
1717

18-
implementation("com.squareup:kotlinpoet:2.1.0")
18+
implementation("com.squareup:kotlinpoet:2.2.0")
1919

2020
testImplementation(kotlin("test"))
2121

22-
testImplementation("dev.zacsweers.kctfork:core:0.7.0")
23-
testImplementation("dev.zacsweers.kctfork:ksp:0.7.0")
22+
testImplementation("dev.zacsweers.kctfork:core:0.7.1")
23+
testImplementation("dev.zacsweers.kctfork:ksp:0.7.1")
2424

2525
testImplementation(platform("org.junit:junit-bom:5.10.2"))
2626
testImplementation("org.junit.jupiter:junit-jupiter-api")

0 commit comments

Comments
 (0)