Skip to content

Commit

Permalink
Method references supported in transform and fromExpression (#133)
Browse files Browse the repository at this point in the history
* method references supported

* changelog

* feedback PR

* feedback PR - tests

---------

Co-authored-by: Abel <[email protected]>
  • Loading branch information
AbelPelser and Abel authored Nov 22, 2024
1 parent 975d3dc commit 1b7a86b
Show file tree
Hide file tree
Showing 5 changed files with 122 additions and 5 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,7 @@ private class ClassMappingStatementCollector(private val context: ResolverContex
}
IDENTIFIER_FROM_EXPRESSION -> {
val target = expression.extensionReceiver!!.accept(TargetNameCollector(context), data)
target to ExpressionMappingSource(expression.valueArguments.first() as IrFunctionExpression)
target to ExpressionMappingSource(expression.valueArguments.first()!!)
}
IDENTIFIER_VIA -> {
expression.dispatchReceiver!!.accept(data).let { (name, source) ->
Expand All @@ -66,7 +66,13 @@ private class ClassMappingStatementCollector(private val context: ResolverContex
IDENTIFIER_TRANSFORM -> {
expression.dispatchReceiver!!.accept(data).let { (name, source) ->
name to (source as ExplicitPropertyMappingSource).copy(
transformation = PropertyMappingTransformTranformation(expression.valueArguments.first()!! as IrFunctionExpression)
transformation = expression.valueArguments.first().let {
when (it) {
is IrFunctionExpression -> PropertyMappingTransformTranformation(it)
is IrFunctionReference -> PropertyMappingTransformTranformation(it)
else -> throw MappiePanicException("Unexpected expression type: ${expression.dumpKotlinLike()}")
}
}
)
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import org.jetbrains.kotlin.ir.declarations.IrProperty
import org.jetbrains.kotlin.ir.declarations.IrValueParameter
import org.jetbrains.kotlin.ir.expressions.IrExpression
import org.jetbrains.kotlin.ir.expressions.IrFunctionExpression
import org.jetbrains.kotlin.ir.expressions.IrFunctionReference
import org.jetbrains.kotlin.ir.expressions.IrPropertyReference
import org.jetbrains.kotlin.ir.types.*
import org.jetbrains.kotlin.name.Name
Expand Down Expand Up @@ -85,10 +86,12 @@ sealed interface PropertyMappingTransformation {
val type: IrType
}

data class PropertyMappingTransformTranformation(
val function: IrFunctionExpression,
data class PropertyMappingTransformTranformation private constructor(
val function: IrExpression,
override val type: IrType,
) : PropertyMappingTransformation {
override val type = function.function.returnType
constructor(functionReference: IrFunctionReference) : this(functionReference, functionReference.symbol.owner.returnType)
constructor(functionExpression: IrFunctionExpression) : this(functionExpression, functionExpression.function.returnType)
}

data class PropertyMappingViaMapperTransformation(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -42,4 +42,54 @@ class FromExpressionTest {
assertThat(mapper.map(Unit)).isEqualTo(Output(Unit::class.simpleName!!))
}
}

@Test
fun `map property fromExpression should succeed with method reference`() {
compile(directory) {
file("Test.kt",
"""
import tech.mappie.api.ObjectMappie
import tech.mappie.testing.objects.FromExpressionTest.*
class Mapper : ObjectMappie<Int, Output>() {
override fun map(from: Int) = mapping {
Output::value fromExpression Int::toString
}
}
"""
)
} satisfies {
isOk()
hasNoMessages()

val mapper = classLoader
.loadObjectMappieClass<Int, Output>("Mapper")
.constructors
.first()
.call()

assertThat(mapper.map(101)).isEqualTo(Output("101"))
}
}

@Test
fun `map property fromExpression should fail with method reference with wrong return type`() {
compile(directory) {
file("Test.kt",
"""
import tech.mappie.api.ObjectMappie
import tech.mappie.testing.objects.FromExpressionTest.*
class Mapper : ObjectMappie<Int, Output>() {
override fun map(from: Int) = mapping {
Output::value fromExpression Int::toInt
}
}
"""
)
} satisfies {
isCompilationError()
hasErrorMessage(6, "Target Output::value of type String cannot be assigned from expression of type Int")
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import org.junit.jupiter.api.io.TempDir
import tech.mappie.testing.compilation.compile
import tech.mappie.testing.loadObjectMappieClass
import java.io.File
import kotlin.random.Random

class ObjectWithDifferentValuesTest {

Expand Down Expand Up @@ -118,4 +119,57 @@ class ObjectWithDifferentValuesTest {
assertThat(mapper.map(Input("Sjon", 58))).isEqualTo(Output("Sjon", 58))
}
}

@Test
fun `map property fromProperty should succeed with method reference transform`() {
compile(directory) {
file("Test.kt",
"""
import tech.mappie.api.ObjectMappie
import tech.mappie.testing.objects.ObjectWithDifferentValuesTest.*
class Mapper : ObjectMappie<Input, Output>() {
override fun map(from: Input) = mapping {
Output::age fromProperty from::firstname transform String::toInt
Output::name fromProperty from::age transform Int::toString
}
}
"""
)
} satisfies {
isOk()
hasNoMessages()

val mapper = classLoader
.loadObjectMappieClass<Input, Output>("Mapper")
.constructors
.first()
.call()

assertThat(mapper.map(Input("101", 9))).isEqualTo(Output("9", 101))
}
}

@Test
fun `map property fromProperty should fail with method reference with wrong signature`() {
compile(directory) {
file("Test.kt",
"""
import tech.mappie.api.ObjectMappie
import tech.mappie.testing.objects.ObjectWithDifferentValuesTest.*
class Mapper : ObjectMappie<Input, Output>() {
override fun map(from: Input) = mapping {
Output::age fromProperty from::firstname transform String::toString
Output::name fromProperty from::age transform Int::toInt
}
}
"""
)
} satisfies {
isCompilationError()
hasErrorMessage(6, "Inapplicable candidate(s): fun toString(): String")
hasErrorMessage(7, "Inapplicable candidate(s): fun toInt(): Int")
}
}
}
4 changes: 4 additions & 0 deletions website/src/changelog.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,10 @@
title: "Changelog"
layout: "layouts/changelog.html"
changelog:
- date: "tbd"
title: "v0.11.0"
items:
- "Added support for method references in fromExpression and transform"
- date: "tbd"
title: "v0.10.0"
items:
Expand Down

0 comments on commit 1b7a86b

Please sign in to comment.