@@ -5,6 +5,7 @@ import com.google.devtools.ksp.processing.CodeGenerator
5
5
import com.google.devtools.ksp.processing.KSPLogger
6
6
import com.google.devtools.ksp.processing.Resolver
7
7
import com.google.devtools.ksp.processing.SymbolProcessor
8
+ import com.google.devtools.ksp.symbol.ClassKind
8
9
import com.google.devtools.ksp.symbol.KSAnnotated
9
10
import com.google.devtools.ksp.symbol.KSClassDeclaration
10
11
import com.google.devtools.ksp.symbol.KSPropertyDeclaration
@@ -23,10 +24,12 @@ import com.squareup.kotlinpoet.ParameterSpec
23
24
import com.squareup.kotlinpoet.PropertySpec
24
25
import com.squareup.kotlinpoet.TypeName
25
26
import com.squareup.kotlinpoet.TypeSpec
27
+ import com.squareup.kotlinpoet.ksp.toClassName
26
28
import com.squareup.kotlinpoet.ksp.toTypeName
27
29
import com.squareup.kotlinpoet.ksp.toTypeParameterResolver
28
30
import com.squareup.kotlinpoet.ksp.writeTo
29
31
import com.tobrun.datacompat.annotation.DataCompat
32
+ import java.util.Locale
30
33
31
34
/* *
32
35
* [DataCompatProcessor] is a concrete instance of the [SymbolProcessor] interface.
@@ -48,7 +51,8 @@ class DataCompatProcessor(
48
51
}
49
52
50
53
val unableToProcess = annotated.filterNot { it.validate() }
51
- annotated.filter { it is KSClassDeclaration && it.validate() }.forEach { it.accept(Visitor (), Unit ) }
54
+ annotated.filter { it is KSClassDeclaration && it.validate() }
55
+ .forEach { it.accept(Visitor (), Unit ) }
52
56
return unableToProcess.toList()
53
57
}
54
58
@@ -62,10 +66,17 @@ class DataCompatProcessor(
62
66
63
67
// Cleanup class name by dropping Data part
64
68
// TODO make this part more flexible with providing name inside the annotation
65
- val className = classDeclaration.simpleName.asString().dropLast(CLASS_NAME_DROP_LAST_CHARACTERS )
69
+ val className =
70
+ classDeclaration.simpleName.asString().dropLast(CLASS_NAME_DROP_LAST_CHARACTERS )
66
71
val classKdoc = classDeclaration.docString
67
72
val packageName = classDeclaration.packageName.asString()
68
73
74
+ val otherAnnotations = classDeclaration.annotations
75
+ .filter { it.annotationType.resolve().toString() != DataCompat ::class .simpleName }
76
+ val implementedInterfaces = classDeclaration
77
+ .superTypes
78
+ .filter { (it.resolve().declaration as ? KSClassDeclaration )?.classKind == ClassKind .INTERFACE }
79
+
69
80
// Map KSP properties with KoltinPoet TypeNames
70
81
val propertyMap = mutableMapOf<KSPropertyDeclaration , TypeName >()
71
82
for (property in classDeclaration.getAllProperties()) {
@@ -100,6 +111,18 @@ class DataCompatProcessor(
100
111
)
101
112
}
102
113
114
+ otherAnnotations.forEach {
115
+ addAnnotation(
116
+ it.annotationType.resolve().toClassName()
117
+ )
118
+ }
119
+
120
+ implementedInterfaces.forEach {
121
+ addSuperinterface(
122
+ it.resolve().toClassName()
123
+ )
124
+ }
125
+
103
126
// Constructor
104
127
val constructorBuilder = FunSpec .constructorBuilder()
105
128
constructorBuilder.addModifiers(KModifier .PRIVATE )
@@ -121,11 +144,12 @@ class DataCompatProcessor(
121
144
addFunction(
122
145
FunSpec .builder(" toString" )
123
146
.addModifiers(KModifier .OVERRIDE )
147
+ // using triple quote for long strings
124
148
.addStatement(
125
149
propertyMap.keys.joinToString(
126
- prefix = " return \" $className (" ,
150
+ prefix = " return \"\"\" $className (" ,
127
151
transform = { " $it =$$it " },
128
- postfix = " )\" "
152
+ postfix = " )\"\"\" .trimIndent() "
129
153
)
130
154
)
131
155
.build()
@@ -188,14 +212,21 @@ class DataCompatProcessor(
188
212
189
213
var kDocProperty = kdocPropertyList
190
214
.filter { it.startsWith(" $propertyName " ) }
191
- .joinToString { it.substringAfter(" $propertyName " ).toLowerCase() }
215
+ .joinToString {
216
+ it.substringAfter(" $propertyName " ).lowercase(Locale .getDefault())
217
+ }
192
218
193
219
if (kDocProperty.isEmpty()) {
194
220
kDocProperty = propertyName
195
221
}
196
222
197
223
builderBuilder.addFunction(
198
- FunSpec .builder(" set${propertyName.capitalize()} " )
224
+ FunSpec
225
+ .builder(
226
+ " set${propertyName.replaceFirstChar {
227
+ if (it.isLowerCase()) it.titlecase(Locale .getDefault()) else it.toString()
228
+ }} "
229
+ )
199
230
.addKdoc(
200
231
"""
201
232
|Set $kDocProperty
@@ -248,10 +279,12 @@ class DataCompatProcessor(
248
279
|
249
280
|This is a concrete implementation of the builder design pattern.
250
281
|
251
- |${kdocPropertyList.joinToString(
282
+ |${
283
+ kdocPropertyList.joinToString(
252
284
prefix = " $KDOC_PROPERTY_ANNOTATION " ,
253
285
separator = " \n $KDOC_PROPERTY_ANNOTATION "
254
- )}
286
+ )
287
+ }
255
288
""" .trimMargin()
256
289
)
257
290
builderBuilder.addFunction(buildFunction.build())
@@ -264,7 +297,7 @@ class DataCompatProcessor(
264
297
"""
265
298
|Creates a [$className ] through a DSL-style builder.
266
299
|
267
- |@param initializer the intialisation block
300
+ |@param initializer the initialisation block
268
301
|@return $className
269
302
""" .trimMargin()
270
303
)
0 commit comments