1
1
package dev.adamko.kxstsgen.core
2
2
3
- import dev.adamko.kxstsgen.core.util.MutableMapWithDefaultPut
4
3
import kotlinx.serialization.KSerializer
5
4
import kotlinx.serialization.descriptors.*
5
+ import kotlinx.serialization.modules.SerializersModule
6
+
6
7
7
8
8
9
/* *
@@ -14,8 +15,20 @@ fun interface SerializerDescriptorsExtractor {
14
15
serializer : KSerializer <* >
15
16
): Set <SerialDescriptor >
16
17
18
+ companion object {
19
+ /* * The default [SerializerDescriptorsExtractor], for easy use. */
20
+ fun default (
21
+ serializersModule : SerializersModule ,
22
+ ): SerializerDescriptorsExtractor {
23
+ return Default (
24
+ elementDescriptorsExtractor = TsElementDescriptorsExtractor .default(serializersModule)
25
+ )
26
+ }
27
+ }
17
28
18
- object Default : SerializerDescriptorsExtractor {
29
+ class Default (
30
+ private val elementDescriptorsExtractor : TsElementDescriptorsExtractor ,
31
+ ) : SerializerDescriptorsExtractor {
19
32
20
33
override operator fun invoke (
21
34
serializer : KSerializer <* >
@@ -25,7 +38,6 @@ fun interface SerializerDescriptorsExtractor {
25
38
.toSet()
26
39
}
27
40
28
-
29
41
private tailrec fun extractDescriptors (
30
42
current : SerialDescriptor ? = null,
31
43
queue : ArrayDeque <SerialDescriptor > = ArrayDeque (),
@@ -34,55 +46,63 @@ fun interface SerializerDescriptorsExtractor {
34
46
return if (current == null ) {
35
47
extracted
36
48
} else {
37
- val currentDescriptors = elementDescriptors.getValue (current)
49
+ val currentDescriptors = elementDescriptorsExtractor.elementDescriptors (current)
38
50
queue.addAll(currentDescriptors - extracted)
39
51
extractDescriptors(queue.removeFirstOrNull(), queue, extracted + current)
40
52
}
41
53
}
54
+ }
55
+ }
42
56
43
57
44
- private val elementDescriptors by MutableMapWithDefaultPut <SerialDescriptor , Iterable <SerialDescriptor >> { descriptor ->
45
- when (descriptor.kind) {
46
- SerialKind .ENUM -> emptyList()
47
-
48
- SerialKind .CONTEXTUAL -> emptyList()
49
-
50
- PrimitiveKind .BOOLEAN ,
51
- PrimitiveKind .BYTE ,
52
- PrimitiveKind .CHAR ,
53
- PrimitiveKind .SHORT ,
54
- PrimitiveKind .INT ,
55
- PrimitiveKind .LONG ,
56
- PrimitiveKind .FLOAT ,
57
- PrimitiveKind .DOUBLE ,
58
- PrimitiveKind .STRING -> emptyList()
59
-
60
- StructureKind .CLASS ,
61
- StructureKind .LIST ,
62
- StructureKind .MAP ,
63
- StructureKind .OBJECT -> descriptor.elementDescriptors
64
-
65
- PolymorphicKind .SEALED ,
66
- PolymorphicKind .OPEN ->
67
- // Polymorphic descriptors have 2 elements, the 'type' and 'value' - we don't need either
68
- // for generation, they're metadata that will be used later.
69
- // The elements of 'value' are similarly unneeded, but their elements might contain new
70
- // descriptors - so extract them
71
- descriptor.elementDescriptors
72
- .flatMap { it.elementDescriptors }
73
- .flatMap { it.elementDescriptors }
74
-
75
- // Example:
76
- // com.application.Polymorphic<MySealedClass>
77
- // ├── 'type' descriptor (ignore / it's a String, so check its elements, it doesn't hurt)
78
- // └── 'value' descriptor (check elements...)
79
- // ├── com.application.Polymorphic<Subclass1> (ignore)
80
- // │ ├── Double (extract!)
81
- // │ └── com.application.SomeOtherClass (extract!)
82
- // └── com.application.Polymorphic<Subclass2> (ignore)
83
- // ├── UInt (extract!)
84
- // └── List<com.application.AnotherClass (extract!
58
+ fun interface TsElementDescriptorsExtractor {
59
+ fun elementDescriptors (descriptor : SerialDescriptor ): Iterable <SerialDescriptor >
60
+
61
+ companion object {
62
+
63
+ fun default (serializersModule : SerializersModule ) =
64
+ TsElementDescriptorsExtractor { descriptor ->
65
+ when (descriptor.kind) {
66
+ SerialKind .ENUM -> emptyList()
67
+
68
+ SerialKind .CONTEXTUAL -> emptyList()
69
+
70
+ PrimitiveKind .BOOLEAN ,
71
+ PrimitiveKind .BYTE ,
72
+ PrimitiveKind .CHAR ,
73
+ PrimitiveKind .SHORT ,
74
+ PrimitiveKind .INT ,
75
+ PrimitiveKind .LONG ,
76
+ PrimitiveKind .FLOAT ,
77
+ PrimitiveKind .DOUBLE ,
78
+ PrimitiveKind .STRING -> emptyList()
79
+
80
+ StructureKind .CLASS ,
81
+ StructureKind .LIST ,
82
+ StructureKind .MAP ,
83
+ StructureKind .OBJECT -> descriptor.elementDescriptors
84
+
85
+ PolymorphicKind .SEALED ,
86
+ PolymorphicKind .OPEN ->
87
+ // Polymorphic descriptors have 2 elements, the 'type' and 'value' - we don't need either
88
+ // for generation, they're metadata that will be used later.
89
+ // The elements of 'value' are similarly unneeded, but their elements might contain new
90
+ // descriptors - so extract them
91
+ descriptor.elementDescriptors
92
+ .flatMap { it.elementDescriptors }
93
+ .flatMap { it.elementDescriptors }
94
+
95
+ // Example:
96
+ // com.application.Polymorphic<MySealedClass>
97
+ // ├── 'type' descriptor (ignore / it's a String, so check its elements, it doesn't hurt)
98
+ // └── 'value' descriptor (check elements...)
99
+ // ├── com.application.Polymorphic<Subclass1> (ignore)
100
+ // │ ├── Double (extract!)
101
+ // │ └── com.application.SomeOtherClass (extract!)
102
+ // └── com.application.Polymorphic<Subclass2> (ignore)
103
+ // ├── UInt (extract!)
104
+ // └── List<com.application.AnotherClass (extract!
105
+ }
85
106
}
86
- }
87
107
}
88
108
}
0 commit comments