From aadb4a5166c8a9dd72b410e77586c21455cd9258 Mon Sep 17 00:00:00 2001 From: stefankoppier Date: Tue, 25 Jun 2024 16:54:27 +0200 Subject: [PATCH] Added fromValue and deprecated fromConstant --- .../tech/mappie/generation/IrTransformer.kt | 3 +-- .../kotlin/tech/mappie/resolving/Identifiers.kt | 2 ++ .../classes/ObjectMappingBodyCollector.kt | 8 +++++++- .../resolving/classes/ObjectMappingSource.kt | 10 +--------- .../classes/ObjectMappingsConstructor.kt | 2 +- .../kotlin/tech/mappie/api/ObjectMappie.kt | 15 ++++++++++++++- .../src/main/kotlin/testing/ExpressionMapper.kt | 2 +- testing/src/main/kotlin/testing/PersonMapper.kt | 4 ++-- .../src/main/kotlin/testing/PrivateConstructor.kt | 2 +- website/src/changelog.md | 1 + .../src/posts/object-mapping/posts/resolving.md | 10 +++++----- 11 files changed, 36 insertions(+), 23 deletions(-) diff --git a/compiler-plugin/src/main/kotlin/tech/mappie/generation/IrTransformer.kt b/compiler-plugin/src/main/kotlin/tech/mappie/generation/IrTransformer.kt index e7c4a8bc..bf91f9ad 100644 --- a/compiler-plugin/src/main/kotlin/tech/mappie/generation/IrTransformer.kt +++ b/compiler-plugin/src/main/kotlin/tech/mappie/generation/IrTransformer.kt @@ -93,9 +93,8 @@ class IrTransformer : IrElementTransformerVoidWithContext() { fun ObjectMappingSource.toIr(builder: IrBuilderWithScope): IrExpression = when (this) { is PropertySource -> toIr(builder) - is DefaultParameterValueSource -> value is ExpressionSource -> toIr(builder) - is ConstantSource<*> -> value + is ValueSource -> value } fun ExpressionSource.toIr(builder: IrBuilderWithScope): IrExpression { diff --git a/compiler-plugin/src/main/kotlin/tech/mappie/resolving/Identifiers.kt b/compiler-plugin/src/main/kotlin/tech/mappie/resolving/Identifiers.kt index 4515e105..a5028232 100644 --- a/compiler-plugin/src/main/kotlin/tech/mappie/resolving/Identifiers.kt +++ b/compiler-plugin/src/main/kotlin/tech/mappie/resolving/Identifiers.kt @@ -16,6 +16,8 @@ val IDENTIFIER_MAPPED_FROM_PROPERTY = Name.identifier("fromProperty") val IDENTIFIER_MAPPED_FROM_CONSTANT = Name.identifier("fromConstant") +val IDENTIFIER_MAPPED_FROM_VALUE = Name.identifier("fromValue") + val IDENTIFIER_MAPPED_FROM_EXPRESSION = Name.identifier("fromExpression") val IDENTIFIER_PARAMETER = Name.identifier("parameter") diff --git a/compiler-plugin/src/main/kotlin/tech/mappie/resolving/classes/ObjectMappingBodyCollector.kt b/compiler-plugin/src/main/kotlin/tech/mappie/resolving/classes/ObjectMappingBodyCollector.kt index a817ea3c..11254e28 100644 --- a/compiler-plugin/src/main/kotlin/tech/mappie/resolving/classes/ObjectMappingBodyCollector.kt +++ b/compiler-plugin/src/main/kotlin/tech/mappie/resolving/classes/ObjectMappingBodyCollector.kt @@ -67,6 +67,12 @@ private class ObjectBodyStatementCollector( target to source } + IDENTIFIER_MAPPED_FROM_VALUE -> { + val target = expression.extensionReceiver!!.accept(TargetValueCollector(file!!), data) + val source = expression.valueArguments.first()!! + + target to ValueSource(source) + } IDENTIFIER_MAPPED_FROM_EXPRESSION -> { val target = expression.extensionReceiver!!.accept(TargetValueCollector(file!!), data) val source = expression.valueArguments.first() as IrFunctionExpression @@ -207,7 +213,7 @@ private class SourceValueCollector( } override fun visitConst(expression: IrConst<*>, data: Unit): ObjectMappingSource { - return ConstantSource(expression.type, expression) + return ValueSource(expression) } } diff --git a/compiler-plugin/src/main/kotlin/tech/mappie/resolving/classes/ObjectMappingSource.kt b/compiler-plugin/src/main/kotlin/tech/mappie/resolving/classes/ObjectMappingSource.kt index e060c61e..a4eb1627 100644 --- a/compiler-plugin/src/main/kotlin/tech/mappie/resolving/classes/ObjectMappingSource.kt +++ b/compiler-plugin/src/main/kotlin/tech/mappie/resolving/classes/ObjectMappingSource.kt @@ -1,6 +1,5 @@ package tech.mappie.resolving.classes -import org.jetbrains.kotlin.ir.expressions.IrConst import org.jetbrains.kotlin.ir.expressions.IrExpression import org.jetbrains.kotlin.ir.expressions.IrFunctionExpression import org.jetbrains.kotlin.ir.symbols.IrSimpleFunctionSymbol @@ -41,15 +40,8 @@ data class ExpressionSource( override fun resolveType() = type } -data class DefaultParameterValueSource( +data class ValueSource( val value: IrExpression, ) : ObjectMappingSource { override fun resolveType() = value.type } - -data class ConstantSource( - val type: IrType, - val value: IrConst, -) : ObjectMappingSource { - override fun resolveType() = type -} diff --git a/compiler-plugin/src/main/kotlin/tech/mappie/resolving/classes/ObjectMappingsConstructor.kt b/compiler-plugin/src/main/kotlin/tech/mappie/resolving/classes/ObjectMappingsConstructor.kt index 4882df98..502e1533 100644 --- a/compiler-plugin/src/main/kotlin/tech/mappie/resolving/classes/ObjectMappingsConstructor.kt +++ b/compiler-plugin/src/main/kotlin/tech/mappie/resolving/classes/ObjectMappingsConstructor.kt @@ -33,7 +33,7 @@ class ObjectMappingsConstructor(val targetType: IrType, val source: IrValueParam if (getter != null) { listOf(PropertySource(getter.symbol, getter.returnType, source.symbol, true)) } else if (target.hasDefaultValue()) { - listOf(DefaultParameterValueSource(target.defaultValue!!.expression)) + listOf(ValueSource(target.defaultValue!!.expression)) } else { emptyList() } diff --git a/mappie-api/src/commonMain/kotlin/tech/mappie/api/ObjectMappie.kt b/mappie-api/src/commonMain/kotlin/tech/mappie/api/ObjectMappie.kt index a5bfecc4..424c8076 100644 --- a/mappie-api/src/commonMain/kotlin/tech/mappie/api/ObjectMappie.kt +++ b/mappie-api/src/commonMain/kotlin/tech/mappie/api/ObjectMappie.kt @@ -54,15 +54,28 @@ public abstract class ObjectMappie : Mappie() { * ``` * will generate an explicit mapping, setting constructor parameter `Person.name` to `"John Doe"`. */ + @Deprecated("This function is unnecessarily limiting.", replaceWith = ReplaceWith("this fromValue value")) protected infix fun KProperty1.fromConstant(value: TO_TYPE): Unit = generated() + /** + * Explicitly construct a mapping to [TO] from a value source [value]. + * + * For example + * ```kotlin + * Person::name fromValue "John Doe" + * ``` + * will generate an explicit mapping, setting constructor parameter `Person.name` to `"John Doe"`. + */ + protected infix fun KProperty1.fromValue(value: TO_TYPE): Unit = + generated() + /** * Explicitly construct a mapping to [TO] from expression source [function]. * * For example * ```kotlin - * Person::name fromConstant { personDto -> personDto.fullName + " (full)" } + * Person::name fromExpression { personDto -> personDto.fullName + " (full)" } * ``` * will generate an explicit mapping, setting constructor parameter `Person.name` to `"John Doe (full)"`, * assuming `personDto.fullName == "John Doe"`. diff --git a/testing/src/main/kotlin/testing/ExpressionMapper.kt b/testing/src/main/kotlin/testing/ExpressionMapper.kt index 902021e2..54a1746e 100644 --- a/testing/src/main/kotlin/testing/ExpressionMapper.kt +++ b/testing/src/main/kotlin/testing/ExpressionMapper.kt @@ -4,7 +4,7 @@ import tech.mappie.api.ObjectMappie object ExpressionMapper : ObjectMappie() { override fun map(from: Person): PersonDto = mapping { - PersonDto::age fromConstant 10 + PersonDto::age fromValue 10 PersonDto::description fromExpression { it::class.simpleName!! } } } \ No newline at end of file diff --git a/testing/src/main/kotlin/testing/PersonMapper.kt b/testing/src/main/kotlin/testing/PersonMapper.kt index dfc15917..9dcd786c 100644 --- a/testing/src/main/kotlin/testing/PersonMapper.kt +++ b/testing/src/main/kotlin/testing/PersonMapper.kt @@ -11,7 +11,7 @@ object PersonMapper : ObjectMappie() { override fun map(from: Person): PersonDto = mapping { PersonDto::description fromProperty Person::name - PersonDto::age fromConstant 26 + PersonDto::age fromValue 26 } } @@ -27,6 +27,6 @@ object TransformingPersonMapper : ObjectMappie() { override fun map(from: Person): PersonDto = mapping { PersonDto::description fromProperty Person::name transform { "$it Surname" } - PersonDto::age fromConstant 24 + PersonDto::age fromValue 24 } } \ No newline at end of file diff --git a/testing/src/main/kotlin/testing/PrivateConstructor.kt b/testing/src/main/kotlin/testing/PrivateConstructor.kt index f07e6971..f3b36ecd 100644 --- a/testing/src/main/kotlin/testing/PrivateConstructor.kt +++ b/testing/src/main/kotlin/testing/PrivateConstructor.kt @@ -10,6 +10,6 @@ data class PrivateConstructorDto constructor(val string: String, val int: Int) { object PrivateConstructorMapper : ObjectMappie() { override fun map(from: PrivateConstructor): PrivateConstructorDto = mapping { - PrivateConstructorDto::int fromConstant 1 + PrivateConstructorDto::int fromValue 1 } } \ No newline at end of file diff --git a/website/src/changelog.md b/website/src/changelog.md index 71eb640f..d0fea82c 100644 --- a/website/src/changelog.md +++ b/website/src/changelog.md @@ -8,6 +8,7 @@ changelog: - "[#13](https://github.com/Mr-Mappie/mappie/issues/13) added support for declaring a mapper without an implementation of map." - "[#16](https://github.com/Mr-Mappie/mappie/issues/16) improved resolution of explicit parameter names." - "[#21](https://github.com/Mr-Mappie/mappie/issues/21) added global configuration option to report all warnings as errors." + - "[#24](https://github.com/Mr-Mappie/mappie/issues/24) added explicit mapping fromValue as a replacement of the much more restricting fromConstant." - date: "2024-06-22" title: "v0.1.0" items: diff --git a/website/src/posts/object-mapping/posts/resolving.md b/website/src/posts/object-mapping/posts/resolving.md index 2724bfc3..ff9a59b3 100644 --- a/website/src/posts/object-mapping/posts/resolving.md +++ b/website/src/posts/object-mapping/posts/resolving.md @@ -41,13 +41,13 @@ will set `PersonDto.description` to `Person.name`. Sometimes, you want to map from a source property, but tweak the value, handle nullability, or transform the source in some other way. See [Transforming](/object-mapping/transforming/) for some guidelines. -## Mapping via a Constant -Targets can be set via the operator `fromConstant`. This will set the target to the given constant. +## Mapping via a Value +Targets can be set via the operator `fromValue`. This will set the target to the given value. For example ```kotlin object PersonMapper : ObjectMappie() { override fun map(from: Person): PersonDto = mapping { - PersonDto::description fromConstant "unknown" + PersonDto::description fromValue "unknown" } } ``` @@ -56,7 +56,7 @@ will always set `PersonDto.description` to `"unknown`. ## Mapping via an Expression Targets can be set via the operator `fromExpression`. This will set the target to the given lambda result. -The difference between `fromExpression` and `fromConstant` is that `fromExpression` will take a lambda +The difference between `fromExpression` and `fromValue` is that `fromExpression` will take a lambda function as a parameter, which takes the original `source` as a parameter. Allowing for more flexibility. For example @@ -86,7 +86,7 @@ we can use `parameter("description")` to reference the constructor parameter ```kotlin object PersonMapper : ObjectMappie() { override fun map(from: Person): PersonDto = mapping { - parameter("description") fromConstant "a constant" + parameter("description") fromValue "a constant" } } ``` \ No newline at end of file