Skip to content

Commit

Permalink
Fix Then0 cases, add thenIf/thenIfThis to ThenXX cases
Browse files Browse the repository at this point in the history
  • Loading branch information
deusaquilus committed Jan 10, 2024
1 parent e87cd3d commit dbc3584
Show file tree
Hide file tree
Showing 8 changed files with 116 additions and 26 deletions.
4 changes: 2 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -232,11 +232,11 @@ data class Customer(val something: String, @Component val name: Name, @Component
on(something).match(
case( Customer[Name[Is(), Is()], Partner(Is())] )
.thenThis {{ first, last, id ->
.thenThis { first, last, id ->
// You can use the `this` keyword to refer to the `Customer` instance (also `this` can be omitted entirely).
// (the components first, last, id are also available here for convenience)
this.something + this.somethingElse
}}
}
// Other cases...
)
```
Expand Down
4 changes: 2 additions & 2 deletions build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ apply(plugin = "io.github.gradle-nexus.publish-plugin")
allprojects {

group = "io.exoquery"
version = "0.0.2"
version = "0.0.3"

apply(plugin = "kotlin")
apply(plugin = "maven-publish")
Expand Down Expand Up @@ -151,7 +151,7 @@ subprojects {
}

// Check the 'skipSigning' project property
if (!project.hasProperty("skipSigning")) {
if (!project.hasProperty("nosign")) {
// If 'skipSigning' is not present, apply the signing plugin and configure it
apply(plugin = "signing")

Expand Down
6 changes: 6 additions & 0 deletions decomat-core/build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,12 @@ tasks.register<TemplateTask>("template_base", TemplateTask::class) {
into("build/templates/io/decomat")
}

//tasks.withType<org.jetbrains.kotlin.gradle.tasks.KotlinCompile> {
// kotlinOptions{
// freeCompilerArgs = listOf("-Xno-optimize")
// }
//}

//tasks.register("template", Sync::class) {
// dependsOn("template_base")
// from("build/templates/io/decomat")
Expand Down
38 changes: 28 additions & 10 deletions decomat-core/src/main/kotlin/io/decomat/ThenPattern1.kt
Original file line number Diff line number Diff line change
@@ -1,20 +1,38 @@
package io.decomat

fun <R> case(pat: Pattern0<R>) = ThenIs(pat, {true})

class ThenIs<R>(
override val pat: Pattern0<R>,
override val check: (R) -> Boolean
): Stage<Pattern0<R>, R> {
inline fun <O> useComponents(r: R, f: (R) -> O): O {
return f(r)
}

inline fun thenIf(crossinline f: (R) -> Boolean) = ThenIs(pat) { r: R -> useComponents(r, f) }
inline fun thenIfThis(crossinline f: R.(R) -> Boolean) = ThenIs(pat) { r: R -> useComponents(r, { c -> f(r, c) }) }
inline fun <O> then(crossinline f: (R) -> O): Case<O, R> = StageCase(pat, check) { r: R -> useComponents(r, f) }
inline fun <O> thenThis(crossinline f: R.(R) -> O): Case<O, R> = StageCase(pat, check) { r: R -> useComponents(r, { c -> f(r, c) }) }
}



fun <P1: Pattern0<R1>, R1, R> case(pat: Pattern1<P1, R1, R>) = Then0(pat, {true})

class Then0<P1: Pattern0<R1>, R1, R>(
override val pat: Pattern1<P1, R1, R>,
override val check: (R) -> Boolean
): Stage<Pattern1<P1, R1, R>, R> {
inline fun <O> useComponents(r: R, f: (Components1<R1>) -> O): O {
inline fun <O> useComponents(r: R, f: (R1) -> O): O {
val (r1) = pat.divideIntoComponentsAny(r as Any)
return f(Components1(r1))
return f(r1)
}

inline fun thenIf(crossinline f: (Components1<R1>) -> Boolean) = Then0(pat) { r: R -> useComponents(r, f) }
inline fun thenIfThis(crossinline f: R.() -> (Components1<R1>) -> Boolean) = Then0(pat) { r: R -> useComponents(r, f(r)) }
inline fun <O> then(crossinline f: (Components1<R1>) -> O): Case<O, R> = StageCase(pat, check) { r: R -> useComponents(r, f) }
inline fun <O> thenThis(crossinline f: R.() -> (Components1<R1>) -> O): Case<O, R> = StageCase(pat, check) { r: R -> useComponents(r, f(r)) }
inline fun thenIf(crossinline f: (R1) -> Boolean) = Then0(pat) { r: R -> useComponents(r, f) }
inline fun thenIfThis(crossinline f: R.(R1) -> Boolean) = Then0(pat) { r: R -> useComponents(r, { c -> f(r, c) }) }
inline fun <O> then(crossinline f: (R1) -> O): Case<O, R> = StageCase(pat, check) { r: R -> useComponents(r, f) }
inline fun <O> thenThis(crossinline f: R.(R1) -> O): Case<O, R> = StageCase(pat, check) { r: R -> useComponents(r, { c -> f(r, c) }) }
}

fun <P1: Pattern1<P11, R11, R1>, P11: Pattern<R11>, R11, R1, R> case(pat: Pattern1<P1, R1, R>) = Then1(pat, {true})
Expand All @@ -30,9 +48,9 @@ class Then1<P1: Pattern1<P11, R11, R1>, P11: Pattern<R11>, R11, R1, R>(
}

inline fun thenIf(crossinline f: (Components1<R11>) -> Boolean) = Then1(pat) { r: R -> useComponents(r, f) }
inline fun thenIfThis(crossinline f: R.() -> (Components1<R11>) -> Boolean) = Then1(pat) { r: R -> useComponents(r, f(r)) }
inline fun thenIfThis(crossinline f: R.(Components1<R11>) -> Boolean) = Then1(pat) { r: R -> useComponents(r, { c -> f(r, c) }) }
inline fun <O> then(crossinline f: (Components1<R11>) -> O) = StageCase(pat, check) { r: R -> useComponents(r, f) }
inline fun <O> thenThis(crossinline f: R.() -> (Components1<R11>) -> O) = StageCase(pat, check) { r: R -> useComponents(r, f(r)) }
inline fun <O> thenThis(crossinline f: R.(Components1<R11>) -> O) = StageCase(pat, check) { r: R -> useComponents(r, { c -> f(r, c) }) }
}

/** Generic match for Pattern2<PatternA, PatternB> where we don't know what A and B are */
Expand All @@ -51,9 +69,9 @@ class Then2<P1: Pattern2<P11, P12, R11, R12, R1>, P11: Pattern<R11>, R11, P12: P
}

inline fun thenIf(crossinline f: (Components2<R11, R12>) -> Boolean) = Then2(pat) { r: R -> useComponents(r, f) }
inline fun thenIfThis(crossinline f: R.() -> (Components2<R11, R12>) -> Boolean) = Then2(pat) { r: R -> useComponents(r, f(r)) }
inline fun thenIfThis(crossinline f: R.(Components2<R11, R12>) -> Boolean) = Then2(pat) { r: R -> useComponents(r, { c -> f(r, c) }) }
inline fun <O> then(crossinline f: (Components2<R11, R12>) -> O) = StageCase(pat, check) { r: R -> useComponents(r, f) }
inline fun <O> thenThis(crossinline f: R.() -> (Components2<R11, R12>) -> O) = StageCase(pat, check) { r: R -> useComponents(r, f(r)) }
inline fun <O> thenThis(crossinline f: R.(Components2<R11, R12>) -> O) = StageCase(pat, check) { r: R -> useComponents(r, { c -> f(r, c) }) }
}

//fun <P: Pattern2<P1, P2, R1, R2, R>, P1: Pattern<R1>, P2: Pattern<R2>, R1, R2, R> case(pat: Pattern2<P1, P2, R1, R2, R>) = GenericThen2X(pat, {true})
Expand Down
18 changes: 12 additions & 6 deletions decomat-core/src/templates/Pattern3.ftl
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
[#ftl]



[#macro Pattern num]
[@compress single_line=true]
[#if num == 0]Pattern0<R>
Expand Down Expand Up @@ -96,11 +95,13 @@
[/@compress]
[/#macro]



[@output file="decomat-core/build/templates/io/decomat/Then2.kt"]
package io.decomat

[#list 0..3 as i1]
[#list 0..3 as i2]
[#list 0..2 as i1]
[#list 0..2 as i2]
[#-- fun <P1: Pattern1<P11, R11, R1>, P2: Pattern0<R2>, P11: Pattern<R11>, R11, R1, R2, R> case(pat: Pattern2<P1, P2, R1, R2, R>) = Then10(pat, {true}) --]

fun <P1: [@PatternVars 1 i1 /], P2: [@PatternVars 2 i2 /], R> case(pat: [@Pattern 2 /]) = Then${i1}${i2}(pat, {true})
Expand All @@ -116,12 +117,17 @@ class Then${i1}${i2}<P1: [@PatternVars 1 i1 /], P2: [@PatternVars 2 i2 /], R>(
[#if i2 != 0]val [@vars 2 i2 /] = pat.pattern2.divideIntoComponentsAny(r2 as Any)[#else]//skip[/#if]
return f([@compVars2 i1, i2 /])
}
inline fun thenIf(crossinline f: ([@Components 1 i1 /], [@Components 2 i2 /]) -> Boolean) =
Then${i1}${i2}(pat) { v -> useComponents(v, { c1, c2 -> f(c1, c2) }) }

inline fun thenIfThis(crossinline f: R.([@Components 1 i1 /], [@Components 2 i2 /]) -> Boolean) =
Then${i1}${i2}(pat) { v -> useComponents(v, { c1, c2 -> f(v, c1, c2) }) }

inline fun <O> then(crossinline f: ([@Components 1 i1 /], [@Components 2 i2 /]) -> O) =
StageCase(pat, check) { value -> useComponents(value, f) }
StageCase(pat, check) { v -> useComponents(v, { c1, c2 -> f(c1, c2) }) }

inline fun <O> thenThis(crossinline f: R.() -> ([@Components 1 i1 /], [@Components 2 i2 /]) -> O) =
StageCase(pat, check) { v -> useComponents(v, f(v)) }
inline fun <O> thenThis(crossinline f: R.([@Components 1 i1 /], [@Components 2 i2 /]) -> O) =
StageCase(pat, check) { v -> useComponents(v, { c1, c2 -> f(v, c1, c2) }) }
}
[/#list]
[/#list]
Expand Down
66 changes: 63 additions & 3 deletions decomat-core/src/test/kotlin/io/decomat/ThenTest.kt
Original file line number Diff line number Diff line change
@@ -1,14 +1,46 @@
package io.decomat

import kotlin.test.Test
import kotlin.test.assertEquals
import kotlin.test.assertNull

public class ThenTest: DecomatTest {
// Just check that the types don't fail
@Test
fun `ThenIs - Is`() =
assert(
case(Is<Entity>()).then { a -> Res1(a) }.eval(foo) == Res1(foo)
)

@Test
fun typesTest() {
case(FlatMap_M(Is(), Is())).then { a: Query, b: Query -> Res2(a, b) }
}

@Test
fun `Then0 - distinct(Is) - Filter`() =
assertEquals<Res1<Entity>>(
case(Distinct_M(Is<Entity>())).then { a -> Res1(a) }.eval(Distinct(foo)), Res1(foo)
)

@Test
fun `Then0 - distinct(Is)`() =
assertEquals(
case(Distinct_M(Is<Entity>())).then { a -> Res1(a) }.eval(Distinct(foo)), Res1(foo)
)

@Test
fun `Then1 - distinct(distinct(Is))`() =
assert(
case(Distinct_M(Distinct_M(Is<Entity>()))).then { (a) -> Res1(a) }.eval(Distinct(Distinct(foo))) == Res1(foo)
)

@Test
fun `Then2 - distinct(flatMap(Is, Is))`() =
assert(
case(Distinct_M(FlatMap_M(Is(), Is()))).then { (a, b) -> Res2(a, b) }.eval(Distinct(FlatMap(foo, bar))) == Res2(foo, bar)
)

@Test
fun `Then00 - flatMap(Is, Is) - Filter`() =
assert(
Expand All @@ -18,7 +50,7 @@ public class ThenTest: DecomatTest {
@Test
fun `Then00 - flatMap(Is, Is) - thenThis`() =
assert(
case(FlatMap_M(Is(), Is())).thenThis {{ a, b -> Res3(a, b, body) }}.eval(FlatMap(foo, bar)) == Res3(foo, bar, bar)
case(FlatMap_M(Is(), Is())).thenThis { a, b -> Res3(a, b, body) }.eval(FlatMap(foo, bar)) == Res3(foo, bar, bar)
)

@Test
Expand All @@ -27,6 +59,36 @@ public class ThenTest: DecomatTest {
case(FlatMap_M(Is(), Is())).then { a, b -> Res2(a, b) }.eval(FlatMap(foo, bar)) == Res2(foo, bar)
)

@Test
fun `Then00-thenIf - flatMap(Is, Is)`() =
assert(
case(FlatMap_M(Is(), Is())).thenIf { a, b -> a == foo && b == bar }.then { a, b -> Res2(a, b) }.eval(FlatMap(foo, bar)) == Res2(foo, bar)
)

@Test
fun `Then00-!thenIf - flatMap(Is, Is)`() =
assert(
case(FlatMap_M(Is(), Is())).thenIf { a, b -> a != foo || b != bar }.then { a, b -> Res2(a, b) }.evalSafe(FlatMap(foo, bar)) == null
)

@Test
fun `Then00-thenIfThis - flatMap(Is, Is)`() =
assertEquals<Res2<Query, Query>>(
case(FlatMap_M(Is(), Is())).thenIfThis { a, b ->
a == foo && b == bar && this.head == foo && this.body == bar
}.then { a, b -> Res2(a, b) }.eval(FlatMap(foo, bar)),
// ==
Res2(foo, bar)
)

@Test
fun `Then00-!thenIfThis - flatMap(Is, Is)`() =
assertNull(
case(FlatMap_M(Is(), Is())).thenIfThis { a, b ->
a != foo || b != bar || this.head != foo || this.body != bar
}.then { a, b -> Res2(a, b) }.evalSafe(FlatMap(foo, bar))
)

@Test
fun `Then01 - flatMap(Is, Distinct)`() =
assert(
Expand Down Expand Up @@ -74,6 +136,4 @@ public class ThenTest: DecomatTest {
assert(
case(FlatMap_M(Map_M(Is(), Is()), Map_M(Is(), Is()))).then { (a1, a2), (b1, b2) -> Res4(a1, a2, b1, b2) }.eval(FlatMap(Map(foo, bar), Map(baz, waz))) == Res4(foo, bar, baz, waz)
)

// TODO Need test for Then31-33 and Then000-Then333
}
2 changes: 1 addition & 1 deletion decomat-ksp/build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ plugins {

dependencies {
project(":decomat-core")
implementation("com.google.devtools.ksp:symbol-processing-api:1.8.20-1.0.11")
implementation("com.google.devtools.ksp:symbol-processing-api:2.0.0-Beta2-1.0.16")
implementation(kotlin("stdlib-jdk8"))
testImplementation(kotlin("test"))
//implementation("com.facebook:ktfmt:0.43")
Expand Down
4 changes: 2 additions & 2 deletions settings.gradle.kts
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
pluginManagement {
plugins {
id("com.google.devtools.ksp") version "1.8.20-1.0.11"
kotlin("jvm") version "1.8.20"
id("com.google.devtools.ksp") version "2.0.0-Beta2-1.0.16"
kotlin("jvm") version "2.0.0-Beta2"
id("dev.anies.gradle.template") version "0.0.2"
}
repositories {
Expand Down

0 comments on commit dbc3584

Please sign in to comment.