Skip to content

Commit

Permalink
Make template create Pattern2M cases
Browse files Browse the repository at this point in the history
  • Loading branch information
deusaquilus committed Feb 6, 2024
1 parent deadb49 commit f2f5227
Show file tree
Hide file tree
Showing 13 changed files with 637 additions and 466 deletions.
62 changes: 29 additions & 33 deletions build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,9 @@ plugins {
kotlin("jvm")
`java-library`
`maven-publish`
`signing`
id("io.github.gradle-nexus.publish-plugin") version "1.1.0"
id("org.jetbrains.dokka") version "1.8.10"
id("signing")
}

nexusPublishing {
Expand Down Expand Up @@ -110,46 +110,42 @@ subprojects {
}

publishing {
publications {
create<MavenPublication>("mavenJava") {
from(components["kotlin"])
artifactId = varintName

artifact(tasks["javadocJar"])
artifact(tasks["sourcesJar"])

pom {
name.set("decomat")
description.set("DecoMat - Deconstructive Pattern Matching for Kotlin")
url.set("https://github.com/exoquery/decomat")

licenses {
license {
name.set("The Apache Software License, Version 2.0")
url.set("http://www.apache.org/licenses/LICENSE-2.0.txt")
distribution.set("repo")
}
publications.withType<MavenPublication> {
pom {
name.set("decomat")
description.set("DecoMat - Deconstructive Pattern Matching for Kotlin")
url.set("https://github.com/deusaquilus/pprint-kotlin")

licenses {
license {
name.set("The Apache Software License, Version 2.0")
url.set("http://www.apache.org/licenses/LICENSE-2.0.txt")
distribution.set("repo")
}
}

developers {
developer {
name.set("Alexander Ioffe")
email.set("[email protected]")
organization.set("github")
organizationUrl.set("http://www.github.com")
}
developers {
developer {
name.set("Alexander Ioffe")
email.set("[email protected]")
organization.set("github")
organizationUrl.set("http://www.github.com")
}
}

scm {
url.set("https://github.com/exoquery/decomat/tree/main")
connection.set("scm:git:git://github.com/ExoQuery/DecoMat.git")
developerConnection.set("scm:git:ssh://github.com:ExoQuery/DecoMat.git")
}
scm {
url.set("https://github.com/exoquery/decomat/tree/main")
connection.set("scm:git:git://github.com/ExoQuery/DecoMat.git")
developerConnection.set("scm:git:ssh://github.com:ExoQuery/DecoMat.git")
}
}
}
}

tasks.withType<Sign> {
onlyIf { !project.hasProperty("nosign") }
}

// Check the 'skipSigning' project property
if (!project.hasProperty("nosign")) {
// If 'skipSigning' is not present, apply the signing plugin and configure it
Expand All @@ -158,7 +154,7 @@ subprojects {
signing {
// use the properties passed as command line args
// -Psigning.keyId=${{secrets.SIGNING_KEY_ID}} -Psigning.password=${{secrets.SIGNING_PASSWORD}} -Psigning.secretKeyRingFile=$(echo ~/.gradle/secring.gpg)
sign(publishing.publications["mavenJava"])
sign(publishing.publications)
}
}
}
6 changes: 6 additions & 0 deletions decomat-core/build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,12 @@ plugins {

sourceSets["main"].kotlin.srcDir(file("build/templates"))

/*
Note that the error "could not list directory ...git/DecoMat/decomat-core/src/templates
is actually misleading. The actual error will be something else in the freemarker template
but for some reason a higher level task can't list the directory of the ftl building fails.
In order to get the real error add --stacktrace to the './gradlew runFreemarkerTemplate' task
*/
tasks.register<TemplateTask>("template_base", TemplateTask::class) {
data = mutableMapOf("key" to "value")
from("src/templates/")
Expand Down
24 changes: 9 additions & 15 deletions decomat-core/src/main/kotlin/io/decomat/CustomPattern.kt
Original file line number Diff line number Diff line change
Expand Up @@ -13,13 +13,6 @@ inline fun <P1 : Pattern<R1>, P2 : Pattern<R2>, R1, R2, reified R> customPattern
noinline matchName: (R) -> Components2<R1, R2>?
): Pattern2<P1, P2, R1, R2, R> = CustomPattern2(nested1, nested2, matchName, Typed<R>())

inline fun <P1 : Pattern<R1>, P2 : Pattern<R2>, P3 : Pattern<R3>, R1, R2, R3, reified R> customPattern3(
nested1: P1,
nested2: P2,
nested3: P3,
noinline matchName: (R) -> Components3<R1, R2, R3>?
): Pattern3<P1, P2, P3, R1, R2, R3, R> = CustomPattern3(nested1, nested2, nested3, matchName, Typed<R>())

class CustomPattern1<P1 : Pattern<R1>, R1, R>(
val innerMatch: P1,
val match: (R) -> Components1<R1>?,
Expand Down Expand Up @@ -66,27 +59,28 @@ class CustomPattern2<P1 : Pattern<R1>, P2: Pattern<R2>, R1, R2, R>(
}


class CustomPattern3<P1 : Pattern<R1>, P2: Pattern<R2>, P3: Pattern<R3>, R1, R2, R3, R>(

class CustomPattern2M<P1 : Pattern<R1>, M, P2: Pattern<R2>, R1, R2, R>(
val innerMatchA: P1,
val innerMatchB: P2,
val innerMatchC: P3,
val match: (R) -> Components3<R1, R2, R3>?,
val match: (R) -> Components2M<R1, M, R2>?,
val tpe: Typed<R>
): Pattern3<P1, P2, P3, R1, R2, R3, R>(innerMatchA, innerMatchB, innerMatchC, tpe) {
): Pattern2M<P1, M, P2, R1, R2, R>(innerMatchA, innerMatchB, tpe) {
override fun matches(comps: ProductClass<R>): Boolean =
match(comps.value).let {
it != null &&
innerMatchA.matchesAny(it.a as Any) &&
innerMatchB.matchesAny(it.b as Any) &&
innerMatchC.matchesAny(it.c as Any)
innerMatchB.matchesAny(it.b as Any)
}

override fun divideIntoComponents(instance: ProductClass<R>): Components3<R1, R2, R3> =
override fun divideInto3Components(instance: ProductClass<R>): Components2M<R1, M, R2> =
match(instance.value) ?: failToDivide(instance)

override fun divideIntoComponentsAny(instance: kotlin.Any): Components3<R1, R2, R3> =
override fun divideInto3ComponentsAny(instance: kotlin.Any): Components2M<R1, M, R2> =
if (isType(instance, tpe.type))
match(instance as R) ?: failToDivide(instance)
else
failToDivide(instance)
}


33 changes: 0 additions & 33 deletions decomat-core/src/main/kotlin/io/decomat/Pattern.kt
Original file line number Diff line number Diff line change
Expand Up @@ -91,36 +91,3 @@ abstract class Pattern2<P1: Pattern<R1>, P2: Pattern<R2>, R1, R2, R>(val pattern
else -> fail("must match properly") // todo refine message
}
}

abstract class Pattern3<P1: Pattern<R1>, P2: Pattern<R2>, P3: Pattern<R3>, R1, R2, R3, R>(val pattern1: P1, val pattern2: P2, val pattern3: P3, override val typeR: Typed<R>):
Pattern<R> {
open override fun matches(comps: ProductClass<R>) =
comps.value.isType(typeR)
&&
when(val compsDef = comps.isIfHas()) {
is ProductClass3<*, *, *, *> ->
wrapNonComps<R1>(compsDef.a).let { pattern1.matches(it) }
&&
wrapNonComps<R2>(compsDef.b).let { pattern2.matches(it) }
&&
wrapNonComps<R3>(compsDef.c).let { pattern3.matches(it) }
else -> false
}

open fun divideIntoComponentsAny(instance: kotlin.Any): Components3<R1, R2, R3> =
when(instance) {
is HasProductClass<*> ->
divideIntoComponentsAny(instance.productComponents)
is ProductClass3<*, *, *, *> ->
if (!isType(instance.value, typeR.type)) fail("Invalid type of data") // todo refine message
else divideIntoComponents(instance as ProductClass<R>)
else -> fail("Cannot divide $instance into components. It is not a Product2 class.")
}

open fun divideIntoComponents(instance: ProductClass<R>): Components3<R1, R2, R3> =
when(val inst = instance.isIfHas()) {
is ProductClass3<*, *, *, *> ->
Components3(inst.a as R1, inst.b as R2, inst.c as R3)
else -> fail("must match properly") // todo refine message
}
}
14 changes: 9 additions & 5 deletions decomat-core/src/main/kotlin/io/decomat/PatternM.kt
Original file line number Diff line number Diff line change
Expand Up @@ -15,18 +15,22 @@ abstract class Pattern2M<P1: Pattern<R1>, M, P2: Pattern<R2>, R1, R2, R>(val pat
else -> false
}

// assumign the matches function already said 'false' if it doesn't match so at this point just throw an error
open fun divideIntoComponentsAny(instance: kotlin.Any): Components2M<R1, M, R2> =
// use 3-component division in then then-functions for Pattern2M-family but
// use the 2-component division in the superclass of this in the Pattenr2M family
// (the fact that we do this allows us to reuse then thenXX methods for the Pattern2M family
// otherwise would would need to reimplement all of them for Pattern2M giving it the performance
// probem of Pattern3)
open fun divideInto3ComponentsAny(instance: kotlin.Any): Components2M<R1, M, R2> =
when(instance) {
is HasProductClass<*> ->
divideIntoComponentsAny(instance.productComponents)
divideInto3ComponentsAny(instance.productComponents)
is ProductClass2M<*, *, *, *> ->
if (!isType(instance.value, typeR.type)) fail("Invalid type of data") // todo refine message
else divideIntoComponents(instance as ProductClass<R>)
else divideInto3Components(instance as ProductClass<R>)
else -> fail("Cannot divide $instance into components. It is not a Product2 class.")
}

open fun divideIntoComponents(instance: ProductClass<R>): Components2M<R1, M, R2> =
open fun divideInto3Components(instance: ProductClass<R>): Components2M<R1, M, R2> =
when(val inst = instance.isIfHas()) {
is ProductClass2M<*, *, *, *> ->
// for FlatMap_M: ~Pattern2<Query, Query> R1 and R2 will be Query
Expand Down
2 changes: 0 additions & 2 deletions decomat-core/src/main/kotlin/io/decomat/ProductClass.kt
Original file line number Diff line number Diff line change
Expand Up @@ -87,5 +87,3 @@ data class Components1<in A>(val a: @UnsafeVariance A): Components
data class Components2<in A, in B>(val a: @UnsafeVariance A, val b: @UnsafeVariance B): Components

data class Components2M<in A, in M, in B>(val a: @UnsafeVariance A, val m: @UnsafeVariance M, val b: @UnsafeVariance B): Components

data class Components3<in A, in B, in C>(val a: @UnsafeVariance A, val b: @UnsafeVariance B, val c: @UnsafeVariance C): Components
Loading

0 comments on commit f2f5227

Please sign in to comment.