
arrow.meta.encoder.jvm.KotlinPoetEncoder.kt Maven / Gradle / Ivy
package arrow.meta.encoder.jvm
import arrow.meta.ast.Annotation
import arrow.meta.ast.Code
import arrow.meta.ast.Func
import arrow.meta.ast.Modifier
import arrow.meta.ast.PackageName
import arrow.meta.ast.Parameter
import arrow.meta.ast.TypeName
import arrow.meta.ast.UseSiteTarget
import arrow.meta.encoder.MetaApi
import com.squareup.kotlinpoet.AnnotationSpec
import com.squareup.kotlinpoet.ClassName
import com.squareup.kotlinpoet.KModifier
import com.squareup.kotlinpoet.ParameterizedTypeName
import com.squareup.kotlinpoet.TypeVariableName
import com.squareup.kotlinpoet.WildcardTypeName
import me.eugeniomarletti.kotlin.metadata.KotlinMetadataUtils
import javax.lang.model.element.ExecutableElement
interface KotlinPoetEncoder {
fun metaApi(): MetaApi
fun kotlinMetadataUtils(): KotlinMetadataUtils
private fun com.squareup.kotlinpoet.CodeBlock.toMeta(): Code =
Code(this.toString())
private fun com.squareup.kotlinpoet.AnnotationSpec.UseSiteTarget.toMeta(): UseSiteTarget =
when (this) {
AnnotationSpec.UseSiteTarget.FILE -> UseSiteTarget.File
AnnotationSpec.UseSiteTarget.PROPERTY -> UseSiteTarget.Property
AnnotationSpec.UseSiteTarget.FIELD -> UseSiteTarget.Field
AnnotationSpec.UseSiteTarget.GET -> UseSiteTarget.Get
AnnotationSpec.UseSiteTarget.SET -> UseSiteTarget.Set
AnnotationSpec.UseSiteTarget.RECEIVER -> UseSiteTarget.Receiver
AnnotationSpec.UseSiteTarget.PARAM -> UseSiteTarget.Param
AnnotationSpec.UseSiteTarget.SETPARAM -> UseSiteTarget.SetParam
AnnotationSpec.UseSiteTarget.DELEGATE -> UseSiteTarget.Delegate
}
private fun com.squareup.kotlinpoet.ParameterSpec.toMeta(): Parameter =
Parameter(
name = name,
modifiers = modifiers.map { it.toMeta() },
annotations = annotations.map { it.toMeta() },
type = type.toMeta(),
defaultValue = defaultValue?.toMeta()
)
fun com.squareup.kotlinpoet.FunSpec.toMeta(element: ExecutableElement): Func =
Func(
name = element.simpleName.toString(),
annotations = annotations.map { it.toMeta() },
typeVariables = typeVariables.map { it.toMeta() },
modifiers = modifiers.map { it.toMeta() },
returnType = returnType?.toMeta(),
receiverType = receiverType?.toMeta(),
kdoc = kdoc.toMeta(),
body = body.toMeta(),
parameters = parameters.map { it.toMeta() },
jvmMethodSignature = kotlinMetadataUtils().run { element.jvmMethodSignature }
)
fun com.squareup.kotlinpoet.AnnotationSpec.toMeta(): Annotation =
Annotation(className.toMeta(), members = members.map { it.toMeta() }, useSiteTarget = useSiteTarget?.toMeta())
private fun com.squareup.kotlinpoet.WildcardTypeName.toMeta(): TypeName.WildcardType =
TypeName.WildcardType(
name = toString().removeVariance().asKotlin(),
upperBounds = outTypes.map { it.toMeta() },
lowerBounds = inTypes.map { it.toMeta() },
nullable = isNullable,
annotations = annotations.map { it.toMeta() }
)
private fun com.squareup.kotlinpoet.ClassName.toMeta(): TypeName.Classy {
val fqNameAsKotlin = canonicalName.asKotlin()
return TypeName.Classy(
fqName = fqNameAsKotlin,
simpleName = fqNameAsKotlin.substringAfterLast("."),
pckg = PackageName(fqNameAsKotlin.substringBeforeLast(".")),
annotations = annotations.map { it.toMeta() },
nullable = isNullable
)
}
private fun com.squareup.kotlinpoet.ParameterizedTypeName.toMeta(): TypeName =
TypeName.ParameterizedType(
name = toString().removeVariance().asKotlin(),
nullable = isNullable,
annotations = annotations.map { it.toMeta() },
enclosingType = null,
rawType = rawType.toMeta(),
typeArguments = typeArguments.map { it.toMeta() }
)
@Suppress("ComplexMethod")
private fun com.squareup.kotlinpoet.KModifier.toMeta(): Modifier =
when (this) {
KModifier.PUBLIC -> Modifier.Public
KModifier.PROTECTED -> Modifier.Protected
KModifier.PRIVATE -> Modifier.Private
KModifier.INTERNAL -> Modifier.Internal
KModifier.EXPECT -> Modifier.Expect
KModifier.ACTUAL -> Modifier.Actual
KModifier.FINAL -> Modifier.Final
KModifier.OPEN -> Modifier.Open
KModifier.ABSTRACT -> Modifier.Abstract
KModifier.SEALED -> Modifier.Sealed
KModifier.CONST -> Modifier.Const
KModifier.EXTERNAL -> Modifier.External
KModifier.OVERRIDE -> Modifier.Override
KModifier.LATEINIT -> Modifier.LateInit
KModifier.TAILREC -> Modifier.Tailrec
KModifier.VARARG -> Modifier.VarArg
KModifier.SUSPEND -> Modifier.Suspend
KModifier.INNER -> Modifier.Inner
KModifier.ENUM -> Modifier.Enum
KModifier.ANNOTATION -> Modifier.Annotation
KModifier.COMPANION -> Modifier.CompanionObject
KModifier.INLINE -> Modifier.Inline
KModifier.NOINLINE -> Modifier.NoInline
KModifier.CROSSINLINE -> Modifier.CrossInline
KModifier.REIFIED -> Modifier.Reified
KModifier.INFIX -> Modifier.Infix
KModifier.OPERATOR -> Modifier.Operator
KModifier.DATA -> Modifier.Data
KModifier.IN -> Modifier.InVariance
KModifier.OUT -> Modifier.OutVariance
}
fun com.squareup.kotlinpoet.TypeVariableName.toMeta(): TypeName.TypeVariable =
TypeName.TypeVariable(
name = name.asKotlin(),
bounds = bounds.map
{ metaApi().run { it.toMeta().removeConstrains() } },
annotations = annotations.map
{ it.toMeta() },
nullable = isNullable,
reified = isReified,
variance = variance?.toMeta()
)
val typeNameToMeta: (typeName: com.squareup.kotlinpoet.TypeName) -> TypeName
fun com.squareup.kotlinpoet.TypeName.toMeta(): TypeName =
typeNameToMeta(this)
fun typeNameToMetaImpl(typeName: com.squareup.kotlinpoet.TypeName): TypeName =
when (typeName) {
is ClassName -> typeName.toMeta()
is ParameterizedTypeName -> typeName.toMeta()
is TypeVariableName -> typeName.toMeta()
is WildcardTypeName -> typeName.toMeta()
else -> throw IllegalArgumentException("arrow-meta has no bindings for unsupported type name: $typeName")
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy