Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Error on calls on compile dsl #134

Merged
merged 4 commits into from
Nov 21, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions .github/workflows/build.yml
Original file line number Diff line number Diff line change
Expand Up @@ -39,9 +39,11 @@ jobs:
run: ./gradlew build

- name: Coverage Report
if: github.ref == 'refs/heads/main'
run: ./gradlew testCodeCoverageReport

- name: Sonar
if: github.ref == 'refs/heads/main'
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
SONAR_TOKEN: ${{ secrets.SONAR_TOKEN }}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
package tech.mappie.util

import org.jetbrains.kotlin.name.ClassId
import org.jetbrains.kotlin.name.FqName
import org.jetbrains.kotlin.name.Name

Expand Down Expand Up @@ -31,4 +32,8 @@ val IDENTIFIER_TRANSFORM = Name.identifier("transform")

val IDENTIFIER_VIA = Name.identifier("via")

val PACKAGE_TECH_MAPPIE_API_CONFIG = FqName("tech.mappie.api.config")
val PACKAGE_TECH_MAPPIE_API = FqName("tech.mappie.api")

val PACKAGE_TECH_MAPPIE_API_CONFIG = FqName("tech.mappie.api.config")

val CLASS_ID_OBJECT_MAPPING_CONSTRUCTOR = ClassId(PACKAGE_TECH_MAPPIE_API, Name.identifier("ObjectMappingConstructor"))
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@ interface MappingValidation {
addAll(MapperGenerationRequestProblems.of(context, mapping).all())
addAll(ClassConfigProblems.of(context, mapping).all())
addAll(UnnecessaryFromPropertyNotNullProblems.of(context, mapping).all())
addAll(CompileTimeReceiverDslProblems.of(context, mapping).all())
}
}

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
package tech.mappie.validation.problems.classes

import org.jetbrains.kotlin.ir.expressions.IrCall
import org.jetbrains.kotlin.ir.types.classOrNull
import org.jetbrains.kotlin.ir.util.fileEntry
import tech.mappie.resolving.ClassMappingRequest
import tech.mappie.resolving.classes.sources.ValueMappingSource
import tech.mappie.util.CLASS_ID_OBJECT_MAPPING_CONSTRUCTOR
import tech.mappie.util.location
import org.jetbrains.kotlin.name.Name
import tech.mappie.validation.Problem
import tech.mappie.validation.ValidationContext

class CompileTimeReceiverDslProblems private constructor(
private val context: ValidationContext,
private val mappings: List<Pair<IrCall, ProblemSource>>,
) {
private enum class ProblemSource { EXTENSION, DISPATCH }

fun all(): List<Problem> = mappings.map { (call, source) ->
val name = call.symbol.owner.name.asString()
Problem.error(
when (source) {
ProblemSource.EXTENSION -> "The function $name was called as an extension method on the mapping dsl which does not exist after compilation"
ProblemSource.DISPATCH -> "The function $name was called on the mapping dsl which does not exist after compilation"
},
location(context.function.fileEntry, call),
buildList {
if (call.symbol.owner.name == Name.identifier("run")) {
add("Did you mean to use kotlin.run?")
}
}
)
}

companion object {
fun of(context: ValidationContext, mapping: ClassMappingRequest): CompileTimeReceiverDslProblems {
val mappings = mapping.mappings.values
.filter { it.size == 1 }
.map { it.single() }
.filterIsInstance<ValueMappingSource>()
.map { it.expression }
.filterIsInstance<IrCall>()

val dispatch = mappings
.filter { it.hasIncorrectDispatchReceiver(context) }
.map { it to ProblemSource.DISPATCH }

val extension = mappings
.filter { it.hasIncorrectExtensionReceiver(context) }
.map { it to ProblemSource.EXTENSION }

return CompileTimeReceiverDslProblems(context, dispatch + extension)
}

private fun IrCall.hasIncorrectExtensionReceiver(context: ValidationContext) =
extensionReceiver?.type?.classOrNull == context.pluginContext.referenceClass(CLASS_ID_OBJECT_MAPPING_CONSTRUCTOR)

private fun IrCall.hasIncorrectDispatchReceiver(context: ValidationContext) =
dispatchReceiver?.type?.classOrNull == context.pluginContext.referenceClass(CLASS_ID_OBJECT_MAPPING_CONSTRUCTOR)
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -71,4 +71,53 @@ class FromValueTest {
assertThat(mapper.map(Unit)).isEqualTo(Output(null))
}
}

@Test
fun `map property fromValue using extension receiver on mapping dsl should fail`() {
compile(directory) {
file("Test.kt",
"""
import tech.mappie.api.ObjectMappie
import tech.mappie.testing.objects.FromValueTest.*

class Mapper : ObjectMappie<Unit, Output>() {
override fun map(from: Unit) = mapping {
Output::value fromValue run {
"test"
}
}
}
"""
)
} satisfies {
isCompilationError()
hasErrorMessage(6,
"The function run was called as an extension method on the mapping dsl which does not exist after compilation",
listOf(
"Did you mean to use kotlin.run?"
)
)
}
}

@Test
fun `map property fromValue using dispatch receiver on mapping dsl should fail`() {
compile(directory) {
file("Test.kt",
"""
import tech.mappie.api.ObjectMappie
import tech.mappie.testing.objects.FromValueTest.*

class Mapper : ObjectMappie<Unit, Output>() {
override fun map(from: Unit) = mapping {
Output::value fromValue toString()
}
}
"""
)
} satisfies {
isCompilationError()
hasErrorMessage(6, "The function toString was called on the mapping dsl which does not exist after compilation")
}
}
}
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.10.0"
items:
- "Added an explicit error message when the compile-time mapping dsl is used during runtime."
- date: "2024-11-18"
title: "v0.9.2"
items:
Expand Down