@@ -27,32 +27,38 @@ import com.squareup.anvil.compiler.internal.fqName
27
27
import com.squareup.anvil.compiler.internal.reference.*
28
28
import com.squareup.kotlinpoet.*
29
29
import com.squareup.kotlinpoet.ParameterizedTypeName.Companion.parameterizedBy
30
- import java.io.File
31
- import javax.inject.Inject
32
30
import org.jetbrains.kotlin.descriptors.ModuleDescriptor
33
31
import org.jetbrains.kotlin.name.FqName
34
32
import org.jetbrains.kotlin.psi.KtFile
33
+ import java.io.File
34
+ import javax.inject.Inject
35
35
36
36
/* * This Anvil code generator allows generates a backend service API and its dagger bindings. */
37
37
@OptIn(ExperimentalAnvilApi ::class )
38
38
@AutoService(CodeGenerator ::class )
39
39
class ContributeToActivityStarterCodeGenerator : CodeGenerator {
40
-
41
40
override fun isApplicable (context : AnvilContext ): Boolean = true
42
41
43
- override fun generateCode (codeGenDir : File , module : ModuleDescriptor , projectFiles : Collection <KtFile >): Collection <GeneratedFileWithSources > {
44
- return projectFiles.classAndInnerClassReferences(module)
42
+ override fun generateCode (
43
+ codeGenDir : File ,
44
+ module : ModuleDescriptor ,
45
+ projectFiles : Collection <KtFile >,
46
+ ): Collection <GeneratedFileWithSources > =
47
+ projectFiles
48
+ .classAndInnerClassReferences(module)
45
49
.toList()
46
50
.filter { it.isAnnotatedWith(ContributeToActivityStarter ::class .fqName) }
47
51
.flatMap {
48
52
listOf (
49
53
generateParameterToActivityMapper(it, codeGenDir, module),
50
54
)
51
- }
52
- .toList()
53
- }
55
+ }.toList()
54
56
55
- private fun generateParameterToActivityMapper (vmClass : ClassReference .Psi , codeGenDir : File , module : ModuleDescriptor ): GeneratedFileWithSources {
57
+ private fun generateParameterToActivityMapper (
58
+ vmClass : ClassReference .Psi ,
59
+ codeGenDir : File ,
60
+ module : ModuleDescriptor ,
61
+ ): GeneratedFileWithSources {
56
62
val generatedPackage = vmClass.packageFqName.toString()
57
63
val moduleClassName = " ${vmClass.shortName} _ActivityMapper"
58
64
@@ -65,13 +71,14 @@ class ContributeToActivityStarterCodeGenerator : CodeGenerator {
65
71
66
72
val mapperAnnotations = vmClass.annotations.filter { it.fqName == ContributeToActivityStarter ::class .fqName }
67
73
68
- val content = FileSpec .buildFile(generatedPackage, moduleClassName) {
69
- for (annotation in mapperAnnotations) {
70
- val paramsType = annotation.paramsTypeOrNull()!!
71
- val screenName = annotation.screenNameOrNull().orEmpty()
72
- addType(createMapperClass(paramsType, screenName, vmClass, module)).build()
74
+ val content =
75
+ FileSpec .buildFile(generatedPackage, moduleClassName) {
76
+ for (annotation in mapperAnnotations) {
77
+ val paramsType = annotation.paramsTypeOrNull()!!
78
+ val screenName = annotation.screenNameOrNull().orEmpty()
79
+ addType(createMapperClass(paramsType, screenName, vmClass, module)).build()
80
+ }
73
81
}
74
- }
75
82
76
83
return createGeneratedFile(codeGenDir, generatedPackage, moduleClassName, content, vmClass.containingFileAsJavaFile)
77
84
}
@@ -84,172 +91,166 @@ class ContributeToActivityStarterCodeGenerator : CodeGenerator {
84
91
): TypeSpec {
85
92
val moduleClassName = " ${vmClass.shortName} _${paramsType.shortName} _Mapper"
86
93
87
- return TypeSpec .classBuilder(moduleClassName)
94
+ return TypeSpec
95
+ .classBuilder(moduleClassName)
88
96
.addAnnotation(
89
97
AnnotationSpec
90
- .builder(ContributesMultibinding ::class ).addMember(" scope = %T::class" , appScopeFqName.asClassName(module))
98
+ .builder(ContributesMultibinding ::class )
99
+ .addMember(" scope = %T::class" , appScopeFqName.asClassName(module))
91
100
.build(),
92
- )
93
- .addSuperinterface(paramToActivityMapperFqName.asClassName(module))
101
+ ).addSuperinterface(paramToActivityMapperFqName.asClassName(module))
94
102
.addPrimaryConstructor()
95
103
.addProperty(
96
- PropertySpec .builder(" moshi" , moshi.asClassName(module), KModifier .PRIVATE )
104
+ PropertySpec
105
+ .builder(" moshi" , moshi.asClassName(module), KModifier .PRIVATE )
97
106
.initializer(" Moshi.Builder().add(%T()).build()" , kotlinJsonObjectAdapter.asClassName(module))
98
107
.build(),
99
- )
100
- .addFunction(
101
- FunSpec .builder(" map" )
108
+ ).addFunction(
109
+ FunSpec
110
+ .builder(" map" )
102
111
.addModifiers(KModifier .OVERRIDE )
103
112
.addParameter(
104
113
" activityParams" ,
105
114
activityParamsFqName.asClassName(module),
106
- )
107
- .returns(
108
- Class :: class .asClassName().parameterizedBy(
109
- WildcardTypeName .producerOf(appCompatActivityFqName.asClassName(module)),
110
- ).copy(nullable = true ),
111
- )
112
- .addCode(
115
+ ).returns(
116
+ Class :: class
117
+ .asClassName()
118
+ .parameterizedBy(
119
+ WildcardTypeName .producerOf(appCompatActivityFqName.asClassName(module) ),
120
+ ).copy(nullable = true ),
121
+ ) .addCode(
113
122
"""
114
- return if (activityParams is %T) {
115
- %T::class.java
116
- } else {
117
- null
118
- }
123
+ return if (activityParams is %T) {
124
+ %T::class.java
125
+ } else {
126
+ null
127
+ }
119
128
""" .trimIndent(),
120
129
paramsType.asClassName(),
121
130
vmClass.asClassName(),
122
- )
123
- .build(),
124
- )
125
- .apply {
131
+ ).build(),
132
+ ).apply {
126
133
if (screenName.isBlank()) {
127
134
addFunction(emptyDeepLinkMapper(module))
128
135
} else {
129
136
addFunction(createDeeplinkMapper(module, paramsType, screenName))
130
137
addFunction(createTryCreateObjectInstance(module))
131
138
addFunction(createTryCreateActivityParamsInstance(module))
132
139
}
133
- }
134
- .build()
140
+ }.build()
135
141
}
136
142
137
143
private fun TypeSpec.Builder.addPrimaryConstructor (): TypeSpec .Builder {
138
- val constructor = FunSpec .constructorBuilder()
139
- .addAnnotation(AnnotationSpec .builder(Inject ::class ).build())
140
- .build()
144
+ val constructor =
145
+ FunSpec
146
+ .constructorBuilder()
147
+ .addAnnotation(AnnotationSpec .builder(Inject ::class ).build())
148
+ .build()
141
149
142
150
return this .primaryConstructor(constructor )
143
151
}
144
152
145
- private fun AnnotationReference.paramsTypeOrNull (): ClassReference ? {
146
- return argumentAt(" paramsType" , 0 )?.value()
147
- }
153
+ private fun AnnotationReference.paramsTypeOrNull (): ClassReference ? = argumentAt(" paramsType" , 0 )?.value()
148
154
149
- private fun AnnotationReference.screenNameOrNull (): String? {
150
- return argumentAt(" screenName" , 1 )?.value() as ? String?
151
- }
155
+ private fun AnnotationReference.screenNameOrNull (): String? = argumentAt(" screenName" , 1 )?.value() as ? String?
152
156
153
- private fun emptyDeepLinkMapper (module : ModuleDescriptor ): FunSpec {
154
- return FunSpec .builder(" map" )
157
+ private fun emptyDeepLinkMapper (module : ModuleDescriptor ): FunSpec =
158
+ FunSpec
159
+ .builder(" map" )
155
160
.addModifiers(KModifier .OVERRIDE )
156
161
.addParameter(
157
162
" deeplinkActivityParams" ,
158
163
deeplinkActivityParamsFqName.asClassName(module),
159
- )
160
- .returns(
164
+ ).returns(
161
165
activityParamsFqName.asClassName(module).copy(nullable = true ),
162
- )
163
- .addCode(
166
+ ).addCode(
164
167
"""
165
- return null
168
+ return null
166
169
""" .trimIndent(),
167
- )
168
- .build()
169
- }
170
+ ).build()
170
171
171
- private fun createDeeplinkMapper (module : ModuleDescriptor , paramsType : ClassReference , screenName : String ): FunSpec {
172
- return FunSpec .builder(" map" )
172
+ private fun createDeeplinkMapper (
173
+ module : ModuleDescriptor ,
174
+ paramsType : ClassReference ,
175
+ screenName : String ,
176
+ ): FunSpec =
177
+ FunSpec
178
+ .builder(" map" )
173
179
.addModifiers(KModifier .OVERRIDE )
174
180
.addParameter(
175
181
" deeplinkActivityParams" ,
176
182
deeplinkActivityParamsFqName.asClassName(module),
177
- )
178
- .returns(
183
+ ).returns(
179
184
activityParamsFqName.asClassName(module).copy(nullable = true ),
180
- )
181
- .addCode(
185
+ ).addCode(
182
186
"""
183
- val screenName = deeplinkActivityParams.screenName
184
- if (screenName.isNullOrEmpty()) {
185
- return null
186
- }
187
-
188
- val definedScreenName = %S
189
- if (definedScreenName.isNullOrEmpty()) {
190
- return null
191
- }
192
-
193
- return if (screenName == definedScreenName) {
194
- if (deeplinkActivityParams.jsonArguments.isEmpty()) {
195
- val instance = tryCreateObjectInstance(%T::class.java)
196
- if (instance != null) {
197
- return instance
198
- }
187
+ val screenName = deeplinkActivityParams.screenName
188
+ if (screenName.isNullOrEmpty()) {
189
+ return null
190
+ }
191
+
192
+ val definedScreenName = %S
193
+ if (definedScreenName.isNullOrEmpty()) {
194
+ return null
195
+ }
196
+
197
+ return if (screenName == definedScreenName) {
198
+ if (deeplinkActivityParams.jsonArguments.isEmpty()) {
199
+ val instance = tryCreateObjectInstance(%T::class.java)
200
+ if (instance != null) {
201
+ return instance
199
202
}
200
- tryCreateActivityParams(%T::class.java, deeplinkActivityParams)
201
- } else {
202
- null
203
203
}
204
+ tryCreateActivityParams(%T::class.java, deeplinkActivityParams)
205
+ } else {
206
+ null
207
+ }
204
208
""" .trimIndent(),
205
209
screenName,
206
210
paramsType.asClassName(),
207
211
paramsType.asClassName(),
208
- )
209
- .build()
210
- }
212
+ ).build()
211
213
212
- private fun createTryCreateObjectInstance (module : ModuleDescriptor ): FunSpec {
213
- return FunSpec .builder(" tryCreateObjectInstance" )
214
+ private fun createTryCreateObjectInstance (module : ModuleDescriptor ): FunSpec =
215
+ FunSpec
216
+ .builder(" tryCreateObjectInstance" )
214
217
.addModifiers(KModifier .PRIVATE )
215
218
.addParameter(" clazz" , Class ::class .asClassName().parameterizedBy(WildcardTypeName .producerOf(activityParamsFqName.asClassName(module))))
216
219
.addCode(
217
- CodeBlock .builder()
220
+ CodeBlock
221
+ .builder()
218
222
.add(
219
223
"""
220
- return kotlin.runCatching {
221
- %T.getRawType(clazz).kotlin.objectInstance as %T
222
- }.getOrNull()
224
+ return kotlin.runCatching {
225
+ %T.getRawType(clazz).kotlin.objectInstance as %T
226
+ }.getOrNull()
223
227
""" .trimIndent(),
224
228
moshiTypes.asClassName(module),
225
229
activityParamsFqName.asClassName(module),
226
230
).build(),
227
- )
228
- .returns(activityParamsFqName.asClassName(module).copy(nullable = true ))
231
+ ).returns(activityParamsFqName.asClassName(module).copy(nullable = true ))
229
232
.build()
230
- }
231
233
232
- private fun createTryCreateActivityParamsInstance (module : ModuleDescriptor ): FunSpec {
233
- return FunSpec .builder(" tryCreateActivityParams" )
234
+ private fun createTryCreateActivityParamsInstance (module : ModuleDescriptor ): FunSpec =
235
+ FunSpec
236
+ .builder(" tryCreateActivityParams" )
234
237
.addModifiers(KModifier .PRIVATE )
235
238
.addParameter(" clazz" , Class ::class .asClassName().parameterizedBy(WildcardTypeName .producerOf(activityParamsFqName.asClassName(module))))
236
239
.addParameter(
237
240
" deeplinkActivityParams" ,
238
241
deeplinkActivityParamsFqName.asClassName(module),
239
- )
240
- .addCode(
241
- CodeBlock .builder()
242
+ ).addCode(
243
+ CodeBlock
244
+ .builder()
242
245
.add(
243
246
"""
244
- return kotlin.runCatching {
245
- moshi.adapter(clazz).fromJson(deeplinkActivityParams.jsonArguments)
246
- }.getOrNull()
247
+ return kotlin.runCatching {
248
+ moshi.adapter(clazz).fromJson(deeplinkActivityParams.jsonArguments)
249
+ }.getOrNull()
247
250
""" .trimIndent(),
248
251
).build(),
249
- )
250
- .returns(activityParamsFqName.asClassName(module).copy(nullable = true ))
252
+ ).returns(activityParamsFqName.asClassName(module).copy(nullable = true ))
251
253
.build()
252
- }
253
254
254
255
companion object {
255
256
private val appScopeFqName = FqName (" com.duckduckgo.di.scopes.AppScope" )
0 commit comments