Skip to content

Commit

Permalink
Cleanup processor to remove preview param support
Browse files Browse the repository at this point in the history
  • Loading branch information
geoff-powell committed May 14, 2024
1 parent 7638efa commit 66494fd
Show file tree
Hide file tree
Showing 2 changed files with 19 additions and 102 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -38,28 +38,30 @@ internal object PaparazziPoet {
if (functions.count() == 0) {
addEmpty()
} else {
functions.process { func, preview, previewParam ->
val visibilityCheck = checkVisibility(func, previewParam)
functions.process { func, previewParam ->
val visibilityCheck = checkVisibility(func)
val snapshotName = func.snapshotName(env)

when {
visibilityCheck.isPrivate -> addError(
visibilityCheck = visibilityCheck,
function = func,
snapshotName = snapshotName,
preview = preview,
previewParam = previewParam
buildErrorMessage = {
"$it is private. Make it internal or public to generate a snapshot."
},
)
previewParam != null -> addProvider(
previewParam != null -> addError(
visibilityCheck = visibilityCheck,
function = func,
snapshotName = snapshotName,
preview = preview,
previewParam = previewParam
buildErrorMessage = {
"$it preview uses PreviewParameters which aren't currently supported."
},
)
else -> addDefault(
function = func,
snapshotName = snapshotName,
preview = preview
)
}
}
Expand All @@ -76,102 +78,56 @@ internal object PaparazziPoet {
}

private fun Sequence<KSFunctionDeclaration>.process(
block: (KSFunctionDeclaration, PreviewModel, KSValueParameter?) -> Unit
block: (KSFunctionDeclaration, KSValueParameter?) -> Unit
) =
flatMap { func ->
val previewParam = func.previewParam()
func.findDistinctPreviews()
.map { Triple(func, it, previewParam) }
}.forEach { (func, preview, previewParam) ->
block(func, preview, previewParam)
.map { Pair(func, previewParam) }
}.forEach { (func, previewParam) ->
block(func, previewParam)
}

private fun CodeBlock.Builder.addError(
visibilityCheck: VisibilityCheck,
function: KSFunctionDeclaration,
snapshotName: String,
preview: PreviewModel,
previewParam: KSValueParameter?
buildErrorMessage: (String?) -> String,
) {
val qualifiedName = if (visibilityCheck.isFunctionPrivate) {
function.qualifiedName?.asString()
} else {
previewParam?.previewParamProvider()?.qualifiedName?.asString()
null
}

addStatement("%L.PaparazziPreviewData.Error(", PACKAGE_NAME)
indent()
addStatement("snapshotName = %S,", snapshotName)
addStatement("message = %S,", "$qualifiedName is private. Make it internal or public to generate a snapshot.")
addPreviewData(preview)
addStatement("message = %S,", buildErrorMessage(qualifiedName))
unindent()
addStatement("),")
}

private fun CodeBlock.Builder.addProvider(
function: KSFunctionDeclaration,
snapshotName: String,
preview: PreviewModel,
previewParam: KSValueParameter
) {
addStatement("%L.PaparazziPreviewData.Provider(", PACKAGE_NAME)
indent()
addStatement("snapshotName = %S,", snapshotName)
addStatement("composable = { %L(it) },", function.qualifiedName?.asString())
addPreviewParameterData(previewParam)
addPreviewData(preview)
unindent()
addStatement("),")
}

private fun CodeBlock.Builder.addDefault(
function: KSFunctionDeclaration,
snapshotName: String,
preview: PreviewModel
) {
addStatement("%L.PaparazziPreviewData.Default(", PACKAGE_NAME)
indent()
addStatement("snapshotName = %S,", snapshotName)
addStatement("composable = { %L() },", function.qualifiedName?.asString())
addPreviewData(preview)
unindent()
addStatement("),")
}

private fun CodeBlock.Builder.addPreviewData(preview: PreviewModel) {
addStatement("preview = %L.PreviewData(", PACKAGE_NAME)
indent()

preview.fontScale.takeIf { it != 1f }
?.let { addStatement("fontScale = %Lf,", it) }

preview.device.takeIf { it.isNotEmpty() }
?.let { addStatement("device = %S,", it) }

preview.widthDp.takeIf { it > -1 }
?.let { addStatement("widthDp = %L,", it) }

preview.heightDp.takeIf { it > -1 }
?.let { addStatement("heightDp = %L,", it) }

preview.uiMode.takeIf { it != 0 }
?.let { addStatement("uiMode = %L,", it) }

preview.locale.takeIf { it.isNotEmpty() }
?.let { addStatement("locale = %S,", it) }

preview.backgroundColor.takeIf { it != 0L && preview.showBackground }
?.let { addStatement("backgroundColor = %S", it.toString(16)) }

unindent()
addStatement("),")
}

private fun CodeBlock.Builder.addPreviewParameterData(previewParam: KSValueParameter) {
addStatement("previewParameter = %L.PreviewParameterData(", PACKAGE_NAME)
indent()
addStatement("name = %S,", previewParam.name?.asString())
addStatement("values = %L().values,", previewParam.previewParamProvider().qualifiedName?.asString())
unindent()
addStatement("),")
}
Expand All @@ -188,16 +144,13 @@ internal object PaparazziPoet {

private fun checkVisibility(
function: KSFunctionDeclaration,
previewParam: KSValueParameter?
) = VisibilityCheck(
isFunctionPrivate = function.getVisibility() == Visibility.PRIVATE,
isPreviewParamProviderPrivate = previewParam?.previewParamProvider()?.getVisibility() == Visibility.PRIVATE
)
}

internal data class VisibilityCheck(
val isFunctionPrivate: Boolean,
val isPreviewParamProviderPrivate: Boolean
) {
val isPrivate = isFunctionPrivate || isPreviewParamProviderPrivate
val isPrivate = isFunctionPrivate
}
Original file line number Diff line number Diff line change
Expand Up @@ -16,11 +16,6 @@ internal fun KSAnnotation.isPreviewParameter() = qualifiedName() == "androidx.co
internal fun KSAnnotation.qualifiedName() = declaration().qualifiedName?.asString() ?: ""
internal fun KSAnnotation.declaration() = annotationType.resolve().declaration

@Suppress("UNCHECKED_CAST")
internal fun <T> KSAnnotation.previewArg(name: String): T = arguments
.first { it.name?.asString() == name }
.let { it.value as T }

internal fun Sequence<KSAnnotated>.findPaparazzi() =
filterIsInstance<KSFunctionDeclaration>()
.filter {
Expand All @@ -42,43 +37,12 @@ internal fun Sequence<KSAnnotation>.findPreviews(stack: Set<KSAnnotation> = setO
return direct.plus(indirect)
}

internal fun KSFunctionDeclaration.findDistinctPreviews() = annotations.findPreviews().toList()
.map { preview ->
PreviewModel(
fontScale = preview.previewArg("fontScale"),
device = preview.previewArg("device"),
widthDp = preview.previewArg("widthDp"),
heightDp = preview.previewArg("heightDp"),
uiMode = preview.previewArg("uiMode"),
locale = preview.previewArg("locale"),
backgroundColor = preview.previewArg("backgroundColor"),
showBackground = preview.previewArg("showBackground")
)
}
.distinct()
internal fun KSFunctionDeclaration.findDistinctPreviews() = annotations.findPreviews().distinct()

internal fun KSFunctionDeclaration.previewParam() = parameters.firstOrNull { param ->
param.annotations.any { it.isPreviewParameter() }
}

internal fun KSValueParameter.previewParamProvider() = annotations
.first { it.isPreviewParameter() }
.arguments
.first { arg -> arg.name?.asString() == "provider" }
.let { it.value as KSType }
.declaration

internal data class PreviewModel(
val fontScale: Float,
val device: String,
val widthDp: Int,
val heightDp: Int,
val uiMode: Int,
val locale: String,
val backgroundColor: Long,
val showBackground: Boolean
)

internal data class EnvironmentOptions(
val namespace: String
)

0 comments on commit 66494fd

Please sign in to comment.