@@ -17,8 +17,9 @@ class AnnotatedMethodVisitor(
1717 private val customPreviewAnnotations : Map <String , CustomPreviewAnnotation > = emptyMap()
1818) : MethodVisitor(api) {
1919
20- private val methodNamesToAdd = mutableListOf<ComposePreviewSnapshotConfig >()
20+ private val methodNamesToAdd = mutableListOf<PreviewConfig >()
2121 private var foundIgnoreAnnotation = false
22+ private var foundAppStoreSnapshot = false
2223
2324 // Parameter and preview parameter info
2425 private val parameterPreviewInfoMap = mutableMapOf<Int , PreviewParameterInfo >()
@@ -31,161 +32,37 @@ class AnnotatedMethodVisitor(
3132 val index : Int? = null
3233 )
3334
34- @Suppress(" detekt.ReturnCount" , " detekt.ThrowsCount" )
35- private fun createComposePreviewConfigs (forAnnotation : String ): List <ComposePreviewSnapshotConfig > {
36- val composeConfig = ComposePreviewSnapshotConfig (
37- originalFqn = className.cleanName().removeClassName() + " ." + methodName,
38- sourceFileName = fileName.cleanName().cleanFileName(),
39- fullyQualifiedClassName = className.cleanName(),
40- )
41-
42- when (forAnnotation) {
43- PREVIEW_ANNOTATION_DESC -> {
44- return listOf (composeConfig)
45- }
46-
47- PREVIEW_LIGHT_DARK_ANNOTATION_DESC -> {
48- return listOf (
49- composeConfig.copy(name = " light" ),
50- composeConfig.copy(name = " dark" , uiMode = UI_MODE_NIGHT_YES or UI_MODE_TYPE_NORMAL )
51- )
52- }
53-
54- PREVIEW_SCREEN_SIZES_ANNOTATION_DESC -> {
55- return listOf (
56- composeConfig.copy(name = " Phone" , device = PHONE , showSystemUi = true ),
57- composeConfig.copy(
58- name = " Phone - Landscape" ,
59- device = " spec:width = 411dp, height = 891dp, orientation = landscape, dpi = 420" ,
60- showSystemUi = true
61- ),
62- composeConfig.copy(name = " Unfolded Foldable" , device = FOLDABLE , showSystemUi = true ),
63- composeConfig.copy(name = " Tablet" , device = TABLET , showSystemUi = true ),
64- composeConfig.copy(name = " Desktop" , device = DESKTOP , showSystemUi = true )
65- )
66- }
67-
68- PREVIEW_FONT_SCALE_ANNOTATION_DESC -> {
69- return listOf (
70- composeConfig.copy(name = " 85%" , fontScale = 0.85f ),
71- composeConfig.copy(name = " 100%" , fontScale = 1.0f ),
72- composeConfig.copy(name = " 115%" , fontScale = 1.15f ),
73- composeConfig.copy(name = " 130%" , fontScale = 1.3f ),
74- composeConfig.copy(name = " 150%" , fontScale = 1.5f ),
75- composeConfig.copy(name = " 180%" , fontScale = 1.8f ),
76- composeConfig.copy(name = " 200%" , fontScale = 2f )
77- )
78- }
79-
80- EMERGE_APP_STORE_SNAPSHOT -> {
81- throw IllegalArgumentException (" Emerge app store snapshot should should be handled elsewhere" )
82- }
83-
84- EMERGE_IGNORE_SNAPSHOT -> {
85- throw IllegalArgumentException (" Emerge ignore snapshot should should be handled elsewhere" )
86- }
87-
88- PREVIEW_CONTAINER_ANNOTATION_DESC -> {
89- throw IllegalArgumentException (" Preview container annotation should be handled as individual annotations" )
90- }
91-
92- else -> {
93- // Check if this is a custom preview annotations
94- val customAnnotation = customPreviewAnnotations[forAnnotation]
95- if (customAnnotation != null ) {
96- // Create configs based on the custom annotation
97- return createConfigsFromCustomAnnotation(composeConfig, customAnnotation)
98- }
99- return emptyList()
100- }
35+ private fun createComposePreviewConfigs (forAnnotation : String ): List <PreviewConfig > {
36+ val previewConfigs = previewConfigForAnnotation(forAnnotation)
37+ if (previewConfigs != null ) {
38+ return previewConfigs
10139 }
102- }
103-
104- /* *
105- * Creates ComposePreviewSnapshotConfig objects from a custom annotation
106- */
107- private fun createConfigsFromCustomAnnotation (
108- baseConfig : ComposePreviewSnapshotConfig ,
109- customAnnotation : CustomPreviewAnnotation
110- ): List <ComposePreviewSnapshotConfig > {
111- val configs = mutableListOf<ComposePreviewSnapshotConfig >()
112-
113- if (customAnnotation.hasPreviewArray && customAnnotation.previewConfigs.isNotEmpty()) {
114- // Create a config for each @Preview in the array
115- for ((index, previewConfig) in customAnnotation.previewConfigs.withIndex()) {
116- val name = previewConfig.name ? : " preview-${index + 1 } "
117-
118- configs.add(
119- baseConfig.copy(
120- name = name,
121- group = previewConfig.group,
122- showBackground = previewConfig.showBackground,
123- backgroundColor = previewConfig.backgroundColor,
124- widthDp = previewConfig.widthDp,
125- heightDp = previewConfig.heightDp,
126- showSystemUi = previewConfig.showSystemUi,
127- device = previewConfig.device,
128- fontScale = previewConfig.fontScale,
129- locale = previewConfig.locale,
130- uiMode = previewConfig.uiMode,
131- apiLevel = previewConfig.apiLevel,
132- wallpaper = previewConfig.wallpaper,
133- isAppStoreSnapshot = customAnnotation.isAppStoreSnapshot
134- )
135- )
136- }
137- } else if (customAnnotation.hasPreviewAnnotation) {
138- // Create a single config for the direct @Preview
139- configs.add(
140- baseConfig.copy(
141- name = customAnnotation.name,
142- group = customAnnotation.group,
143- showBackground = customAnnotation.showBackground,
144- backgroundColor = customAnnotation.backgroundColor,
145- widthDp = customAnnotation.widthDp,
146- heightDp = customAnnotation.heightDp,
147- showSystemUi = customAnnotation.showSystemUi,
148- device = customAnnotation.device,
149- fontScale = customAnnotation.fontScale,
150- locale = customAnnotation.locale,
151- uiMode = customAnnotation.uiMode,
152- apiLevel = customAnnotation.apiLevel,
153- wallpaper = customAnnotation.wallpaper,
154- isAppStoreSnapshot = customAnnotation.isAppStoreSnapshot
155- )
156- )
157- } else if (customAnnotation.isAppStoreSnapshot) {
158- // Only has @EmergeAppStoreSnapshot
159- configs.add(baseConfig.copy(isAppStoreSnapshot = true ))
40+ require(forAnnotation != PREVIEW_ANNOTATION_DESC ) { " $forAnnotation annotation should be handled in the visitor" }
41+ require(forAnnotation != EMERGE_APP_STORE_SNAPSHOT ) { " $forAnnotation annotation should be handled in the visitor" }
42+ require(forAnnotation != EMERGE_IGNORE_SNAPSHOT ) { " $forAnnotation annotation should be handled in the visitor" }
43+ require(forAnnotation != PREVIEW_ANNOTATION_DESC ) { " $forAnnotation annotation should be handled in the visitor" }
44+ // Check if this is a custom preview annotations
45+ val customAnnotation = customPreviewAnnotations[forAnnotation]
46+ if (customAnnotation != null ) {
47+ if (customAnnotation.isAppStoreSnapshot) {
48+ foundAppStoreSnapshot = true
49+ }
50+ return customAnnotation.previewConfigs
16051 }
161-
162- return configs
52+ return emptyList()
16353 }
16454
16555 @Suppress(" detekt.ReturnCount" )
16656 override fun visitAnnotation (descriptor : String? , visible : Boolean ): AnnotationVisitor ? {
16757 return when (descriptor) {
16858 PREVIEW_ANNOTATION_DESC -> {
169- val previewConfig = createComposePreviewConfigs( PREVIEW_ANNOTATION_DESC ).first ()
59+ val previewConfig = PreviewConfig ()
17060 methodNamesToAdd.add(previewConfig)
171- return PreviewAnnotationVisitor (api, previewConfig)
172- }
173-
174- PREVIEW_LIGHT_DARK_ANNOTATION_DESC -> {
175- val snapshotConfig = createComposePreviewConfigs(PREVIEW_LIGHT_DARK_ANNOTATION_DESC )
176- methodNamesToAdd.addAll(snapshotConfig)
177- return super .visitAnnotation(descriptor, visible)
178- }
179-
180- PREVIEW_FONT_SCALE_ANNOTATION_DESC -> {
181- val snapshotConfig = createComposePreviewConfigs(PREVIEW_FONT_SCALE_ANNOTATION_DESC )
182- methodNamesToAdd.addAll(snapshotConfig)
183- return super .visitAnnotation(descriptor, visible)
61+ return PreviewAnnotationVisitor (previewConfig)
18462 }
18563
18664 EMERGE_APP_STORE_SNAPSHOT -> {
187- val snapshotConfig = createComposePreviewConfigs(EMERGE_APP_STORE_SNAPSHOT )
188- methodNamesToAdd.addAll(snapshotConfig)
65+ foundAppStoreSnapshot = true
18966 return super .visitAnnotation(descriptor, visible)
19067 }
19168
@@ -204,9 +81,9 @@ class AnnotatedMethodVisitor(
20481 descriptor : String?
20582 ): AnnotationVisitor ? {
20683 if (descriptor == PREVIEW_ANNOTATION_DESC ) {
207- val config = createComposePreviewConfigs(descriptor).first ()
84+ val config = PreviewConfig ()
20885 methodNamesToAdd.add(config)
209- return PreviewAnnotationVisitor (api, config)
86+ return PreviewAnnotationVisitor (config)
21087 }
21188 return super .visitAnnotation(name, descriptor)
21289 }
@@ -218,11 +95,9 @@ class AnnotatedMethodVisitor(
21895 }
21996
22097 else -> {
221- // Check if this is a custom preview annotation we discovered in the first pass
222- // Handle null descriptor safely
223- if (descriptor != null && customPreviewAnnotations.containsKey(descriptor)) {
224- val configs = createComposePreviewConfigs(descriptor)
225- methodNamesToAdd.addAll(configs)
98+ if (descriptor != null ) {
99+ val previewConfig = createComposePreviewConfigs(descriptor)
100+ methodNamesToAdd.addAll(previewConfig)
226101 }
227102
228103 // This is just another annotation or it could be a custom annotation that includes a preview.
@@ -292,22 +167,21 @@ class AnnotatedMethodVisitor(
292167 }
293168
294169 override fun visitEnd () {
295- // Apply any preview parameter information to the configs
296- if (parameterPreviewInfoMap.isNotEmpty()) {
297- applyPreviewParameterInfo()
298- }
170+ val previewConfigs =
171+ applyPreviewParameterInfo(methodNamesToAdd.toComposePreviewSnapshotConfig())
299172
300173 // We only add the method names in the end in case we find the ignore annotation and then we ignore what we found.
301174 if (! foundIgnoreAnnotation) {
302- fullPreviewConfigList.addAll(methodNamesToAdd )
175+ fullPreviewConfigList.addAll(previewConfigs )
303176 }
304177 super .visitEnd()
305178 }
306179
307- /* *
308- * Apply the preview parameter information to all method configs.
309- */
310- private fun applyPreviewParameterInfo () {
180+ private fun applyPreviewParameterInfo (composePreviews : List <ComposePreviewSnapshotConfig >):
181+ List <ComposePreviewSnapshotConfig > {
182+ if (parameterPreviewInfoMap.isEmpty()) {
183+ return composePreviews
184+ }
311185 // We only handle the first preview parameter for simplicity.
312186 require(
313187 parameterPreviewInfoMap.entries.size == 1
@@ -326,12 +200,33 @@ class AnnotatedMethodVisitor(
326200 index = previewInfo.index
327201 )
328202
329- val updatedConfigs = methodNamesToAdd .map { config ->
203+ val updatedConfigs = composePreviews .map { config ->
330204 config.copy(previewParameter = previewParam)
331205 }
206+ return updatedConfigs
207+ }
332208
333- // Replace the old configs with the updated ones
334- methodNamesToAdd.clear()
335- methodNamesToAdd.addAll(updatedConfigs)
209+ private fun List<PreviewConfig>.toComposePreviewSnapshotConfig (): List <ComposePreviewSnapshotConfig > {
210+ return map { previewConfig ->
211+ ComposePreviewSnapshotConfig (
212+ fullyQualifiedClassName = className.cleanName(),
213+ originalFqn = className.cleanName().removeClassName() + " ." + methodName,
214+ sourceFileName = fileName.cleanName().cleanFileName(),
215+ name = previewConfig.name,
216+ group = previewConfig.group,
217+ uiMode = previewConfig.uiMode,
218+ locale = previewConfig.locale,
219+ fontScale = previewConfig.fontScale,
220+ heightDp = previewConfig.heightDp,
221+ widthDp = previewConfig.widthDp,
222+ showBackground = previewConfig.showBackground,
223+ backgroundColor = previewConfig.backgroundColor,
224+ showSystemUi = previewConfig.showSystemUi,
225+ device = previewConfig.device,
226+ apiLevel = previewConfig.apiLevel,
227+ wallpaper = previewConfig.wallpaper,
228+ isAppStoreSnapshot = foundAppStoreSnapshot
229+ )
230+ }
336231 }
337232}
0 commit comments