diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index fab0cca..70c7e45 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -1,17 +1,22 @@ -name: "Build and run tests" -on: [push, pull_request] +name: "Build and Run Tests" +on: + push: + branches: [main] + pull_request: jobs: test: runs-on: ubuntu-latest strategy: matrix: - java: [ 8, 9, 10, 11 ] + java: [8, 11, 17] steps: - uses: actions/checkout@v2 - name: Use Java ${{ matrix.java }} - uses: actions/setup-java@v1 + uses: actions/setup-java@v3 with: + distribution: 'corretto' java-version: ${{ matrix.java }} - - name: Build and test + cache: gradle + - name: Build and Test run: ./gradlew build diff --git a/README.md b/README.md index e29524b..4956511 100644 --- a/README.md +++ b/README.md @@ -83,7 +83,7 @@ To obtain the `pig` executable: - Execute `./gradlew assemble` After the build completes, the `pig` executable and dependencies will be located -in `pig/build/distributions/pig/pig-x.y.z.[tar.gz|zip]`. +in `./pig/build/install/pig/bin/pig`. **Finally, make sure that the version of the `partiql-ir-generator-runtime` library that you are using corresponds to the version of the executable.** diff --git a/pig-runtime/src/main/kotlin/org/partiql/pig/runtime/Experimental.kt b/pig-runtime/src/main/kotlin/org/partiql/pig/runtime/Experimental.kt new file mode 100644 index 0000000..a02713c --- /dev/null +++ b/pig-runtime/src/main/kotlin/org/partiql/pig/runtime/Experimental.kt @@ -0,0 +1,7 @@ +package org.partiql.pig.runtime + +@RequiresOptIn( + message = "This DomainNode is marked as experimental", + level = RequiresOptIn.Level.WARNING +) +annotation class Experimental diff --git a/pig-tests/src/main/kotlin/org/partiql/pig/tests/generated/TestDomain.generated.kt b/pig-tests/src/main/kotlin/org/partiql/pig/tests/generated/TestDomain.generated.kt index c504ff5..9da8506 100644 --- a/pig-tests/src/main/kotlin/org/partiql/pig/tests/generated/TestDomain.generated.kt +++ b/pig-tests/src/main/kotlin/org/partiql/pig/tests/generated/TestDomain.generated.kt @@ -1073,6 +1073,76 @@ class TestDomain private constructor() { ) + /** + * Creates an instance of [TestDomain.ExperimentalProduct]. + */ + @Experimental + fun experimentalProduct( + first: Boolean, + second: Boolean, + metas: MetaContainer = emptyMetaContainer() + ): TestDomain.ExperimentalProduct = + TestDomain.ExperimentalProduct( + first = first.asPrimitive(), + second = second.asPrimitive(), + metas = newMetaContainer() + metas + ) + + /** + * Creates an instance of [TestDomain.ExperimentalProduct]. + * + * Use this variant when metas must be passed to primitive child elements. + * + * (The "_" suffix is needed to work-around conflicts due to type erasure and ambiguities with null arguments.) + */ + @Experimental + fun experimentalProduct_( + first: org.partiql.pig.runtime.BoolPrimitive, + second: org.partiql.pig.runtime.BoolPrimitive, + metas: MetaContainer = emptyMetaContainer() + ): TestDomain.ExperimentalProduct = + TestDomain.ExperimentalProduct( + first = first, + second = second, + metas = newMetaContainer() + metas + ) + + + /** + * Creates an instance of [TestDomain.DeprecatedProduct]. + */ + @Deprecated("This node is marked as deprecated") + fun deprecatedProduct( + first: Long, + second: Long, + metas: MetaContainer = emptyMetaContainer() + ): TestDomain.DeprecatedProduct = + TestDomain.DeprecatedProduct( + first = first.asPrimitive(), + second = second.asPrimitive(), + metas = newMetaContainer() + metas + ) + + /** + * Creates an instance of [TestDomain.DeprecatedProduct]. + * + * Use this variant when metas must be passed to primitive child elements. + * + * (The "_" suffix is needed to work-around conflicts due to type erasure and ambiguities with null arguments.) + */ + @Deprecated("This node is marked as deprecated") + fun deprecatedProduct_( + first: org.partiql.pig.runtime.LongPrimitive, + second: org.partiql.pig.runtime.LongPrimitive, + metas: MetaContainer = emptyMetaContainer() + ): TestDomain.DeprecatedProduct = + TestDomain.DeprecatedProduct( + first = first, + second = second, + metas = newMetaContainer() + metas + ) + + /** * Creates an instance of [TestDomain.DomainLevelRecord]. */ @@ -1332,6 +1402,110 @@ class TestDomain private constructor() { ) + // Variants for Sum: ExperimentalSum + /** + * Creates an instance of [TestDomain.ExperimentalSum.ExA]. + */ + fun exA( + metas: MetaContainer = emptyMetaContainer() + ): TestDomain.ExperimentalSum.ExA = + TestDomain.ExperimentalSum.ExA( + metas = newMetaContainer() + metas + ) + + + /** + * Creates an instance of [TestDomain.ExperimentalSum.ExB]. + */ + fun exB( + metas: MetaContainer = emptyMetaContainer() + ): TestDomain.ExperimentalSum.ExB = + TestDomain.ExperimentalSum.ExB( + metas = newMetaContainer() + metas + ) + + + /** + * Creates an instance of [TestDomain.ExperimentalSum.ExC]. + */ + fun exC( + metas: MetaContainer = emptyMetaContainer() + ): TestDomain.ExperimentalSum.ExC = + TestDomain.ExperimentalSum.ExC( + metas = newMetaContainer() + metas + ) + + + // Variants for Sum: DeprecatedSum + /** + * Creates an instance of [TestDomain.DeprecatedSum.DepA]. + */ + fun depA( + metas: MetaContainer = emptyMetaContainer() + ): TestDomain.DeprecatedSum.DepA = + TestDomain.DeprecatedSum.DepA( + metas = newMetaContainer() + metas + ) + + + /** + * Creates an instance of [TestDomain.DeprecatedSum.DepB]. + */ + fun depB( + metas: MetaContainer = emptyMetaContainer() + ): TestDomain.DeprecatedSum.DepB = + TestDomain.DeprecatedSum.DepB( + metas = newMetaContainer() + metas + ) + + + /** + * Creates an instance of [TestDomain.DeprecatedSum.DepC]. + */ + fun depC( + metas: MetaContainer = emptyMetaContainer() + ): TestDomain.DeprecatedSum.DepC = + TestDomain.DeprecatedSum.DepC( + metas = newMetaContainer() + metas + ) + + + // Variants for Sum: EvolvingSum + /** + * Creates an instance of [TestDomain.EvolvingSum.Old]. + */ + @Deprecated("This node is marked as deprecated") + fun old( + metas: MetaContainer = emptyMetaContainer() + ): TestDomain.EvolvingSum.Old = + TestDomain.EvolvingSum.Old( + metas = newMetaContainer() + metas + ) + + + /** + * Creates an instance of [TestDomain.EvolvingSum.Current]. + */ + fun current( + metas: MetaContainer = emptyMetaContainer() + ): TestDomain.EvolvingSum.Current = + TestDomain.EvolvingSum.Current( + metas = newMetaContainer() + metas + ) + + + /** + * Creates an instance of [TestDomain.EvolvingSum.Next]. + */ + @Experimental + fun next( + metas: MetaContainer = emptyMetaContainer() + ): TestDomain.EvolvingSum.Next = + TestDomain.EvolvingSum.Next( + metas = newMetaContainer() + metas + ) + + // Variants for Sum: Entity /** * Creates an instance of [TestDomain.Entity.Slug]. @@ -3021,6 +3195,122 @@ class TestDomain private constructor() { override fun hashCode(): Int = myHashCode } + @Experimental + class ExperimentalProduct( + val first: org.partiql.pig.runtime.BoolPrimitive, + val second: org.partiql.pig.runtime.BoolPrimitive, + override val metas: MetaContainer = emptyMetaContainer() + ): TestDomainNode() { + + override fun copy(metas: MetaContainer): ExperimentalProduct = + ExperimentalProduct( + first = first, + second = second, + metas = metas) + + override fun withMeta(metaKey: String, metaValue: Any): ExperimentalProduct = + ExperimentalProduct( + first = first, + second = second, + metas = metas + metaContainerOf(metaKey to metaValue)) + + override fun toIonElement(): SexpElement { + val elements = ionSexpOf( + ionSymbol("experimental_product"), + first.toIonElement(), + second.toIonElement(), + metas = metas) + return elements + } + + fun copy( + first: org.partiql.pig.runtime.BoolPrimitive = this.first, + second: org.partiql.pig.runtime.BoolPrimitive = this.second, + metas: MetaContainer = this.metas + ) = + ExperimentalProduct( + first, + second, + metas) + + override fun equals(other: Any?): Boolean { + if (other == null) return false + if (this === other) return true + if (other.javaClass != ExperimentalProduct::class.java) return false + + other as ExperimentalProduct + if (first != other.first) return false + if (second != other.second) return false + return true + } + + private val myHashCode by lazy(LazyThreadSafetyMode.PUBLICATION) { + var hc = first.hashCode() + hc = 31 * hc + second.hashCode() + hc + } + + override fun hashCode(): Int = myHashCode + } + + @Deprecated("This node is marked as deprecated") + class DeprecatedProduct( + val first: org.partiql.pig.runtime.LongPrimitive, + val second: org.partiql.pig.runtime.LongPrimitive, + override val metas: MetaContainer = emptyMetaContainer() + ): TestDomainNode() { + + override fun copy(metas: MetaContainer): DeprecatedProduct = + DeprecatedProduct( + first = first, + second = second, + metas = metas) + + override fun withMeta(metaKey: String, metaValue: Any): DeprecatedProduct = + DeprecatedProduct( + first = first, + second = second, + metas = metas + metaContainerOf(metaKey to metaValue)) + + override fun toIonElement(): SexpElement { + val elements = ionSexpOf( + ionSymbol("deprecated_product"), + first.toIonElement(), + second.toIonElement(), + metas = metas) + return elements + } + + fun copy( + first: org.partiql.pig.runtime.LongPrimitive = this.first, + second: org.partiql.pig.runtime.LongPrimitive = this.second, + metas: MetaContainer = this.metas + ) = + DeprecatedProduct( + first, + second, + metas) + + override fun equals(other: Any?): Boolean { + if (other == null) return false + if (this === other) return true + if (other.javaClass != DeprecatedProduct::class.java) return false + + other as DeprecatedProduct + if (first != other.first) return false + if (second != other.second) return false + return true + } + + private val myHashCode by lazy(LazyThreadSafetyMode.PUBLICATION) { + var hc = first.hashCode() + hc = 31 * hc + second.hashCode() + hc + } + + override fun hashCode(): Int = myHashCode + } + class DomainLevelRecord( val someField: org.partiql.pig.runtime.LongPrimitive, val anotherField: org.partiql.pig.runtime.SymbolPrimitive, @@ -3618,29 +3908,30 @@ class TestDomain private constructor() { } } - sealed class Entity(override val metas: MetaContainer = emptyMetaContainer()) : TestDomainNode() { - override fun copy(metas: MetaContainer): Entity = + @Experimental + sealed class ExperimentalSum(override val metas: MetaContainer = emptyMetaContainer()) : TestDomainNode() { + override fun copy(metas: MetaContainer): ExperimentalSum = when (this) { - is Slug -> copy(metas = metas) - is Android -> copy(metas = metas) - is Human -> copy(metas = metas) + is ExA -> copy(metas = metas) + is ExB -> copy(metas = metas) + is ExC -> copy(metas = metas) } - class Slug( + class ExA( override val metas: MetaContainer = emptyMetaContainer() - ): Entity() { + ): ExperimentalSum() { - override fun copy(metas: MetaContainer): Slug = - Slug( + override fun copy(metas: MetaContainer): ExA = + ExA( metas = metas) - override fun withMeta(metaKey: String, metaValue: Any): Slug = - Slug( + override fun withMeta(metaKey: String, metaValue: Any): ExA = + ExA( metas = metas + metaContainerOf(metaKey to metaValue)) override fun toIonElement(): SexpElement { val elements = ionSexpOf( - ionSymbol("slug"), + ionSymbol("ex_a"), metas = metas) return elements } @@ -3649,7 +3940,7 @@ class TestDomain private constructor() { override fun equals(other: Any?): Boolean { if (other == null) return false if (this === other) return true - if (other.javaClass != Slug::class.java) return false + if (other.javaClass != ExA::class.java) return false return true } @@ -3657,63 +3948,411 @@ class TestDomain private constructor() { override fun hashCode(): Int = 4000 } - class Android( - val id: org.partiql.pig.runtime.LongPrimitive, + class ExB( override val metas: MetaContainer = emptyMetaContainer() - ): Entity() { + ): ExperimentalSum() { - override fun copy(metas: MetaContainer): Android = - Android( - id = id, + override fun copy(metas: MetaContainer): ExB = + ExB( metas = metas) - override fun withMeta(metaKey: String, metaValue: Any): Android = - Android( - id = id, + override fun withMeta(metaKey: String, metaValue: Any): ExB = + ExB( metas = metas + metaContainerOf(metaKey to metaValue)) override fun toIonElement(): SexpElement { val elements = ionSexpOf( - ionSymbol("android"), - id.toIonElement(), + ionSymbol("ex_b"), metas = metas) return elements } - fun copy( - id: org.partiql.pig.runtime.LongPrimitive = this.id, - metas: MetaContainer = this.metas - ) = - Android( - id, - metas) override fun equals(other: Any?): Boolean { if (other == null) return false if (this === other) return true - if (other.javaClass != Android::class.java) return false + if (other.javaClass != ExB::class.java) return false - other as Android - if (id != other.id) return false return true } - private val myHashCode by lazy(LazyThreadSafetyMode.PUBLICATION) { - var hc = id.hashCode() - hc - } - - override fun hashCode(): Int = myHashCode + override fun hashCode(): Int = 4001 } - class Human( - val firstName: org.partiql.pig.runtime.SymbolPrimitive, - val middleNames: kotlin.collections.List, - val lastName: org.partiql.pig.runtime.SymbolPrimitive, - val title: org.partiql.pig.runtime.SymbolPrimitive?, - val parent: Entity?, + class ExC( override val metas: MetaContainer = emptyMetaContainer() - ): Entity() { + ): ExperimentalSum() { + + override fun copy(metas: MetaContainer): ExC = + ExC( + metas = metas) + + override fun withMeta(metaKey: String, metaValue: Any): ExC = + ExC( + metas = metas + metaContainerOf(metaKey to metaValue)) + + override fun toIonElement(): SexpElement { + val elements = ionSexpOf( + ionSymbol("ex_c"), + metas = metas) + return elements + } + + + override fun equals(other: Any?): Boolean { + if (other == null) return false + if (this === other) return true + if (other.javaClass != ExC::class.java) return false + + return true + } + + override fun hashCode(): Int = 4002 + } + + /** Converts instances of [TestDomain.ExperimentalSum] to any [T]. */ + interface Converter { + fun convert(node: TestDomain.ExperimentalSum): T = when(node) { + is TestDomain.ExperimentalSum.ExA -> convertExA(node) + is TestDomain.ExperimentalSum.ExB -> convertExB(node) + is TestDomain.ExperimentalSum.ExC -> convertExC(node) + } + + fun convertExA(node: TestDomain.ExperimentalSum.ExA): T + fun convertExB(node: TestDomain.ExperimentalSum.ExB): T + fun convertExC(node: TestDomain.ExperimentalSum.ExC): T + } + } + + @Deprecated("This node is marked as deprecated") + sealed class DeprecatedSum(override val metas: MetaContainer = emptyMetaContainer()) : TestDomainNode() { + override fun copy(metas: MetaContainer): DeprecatedSum = + when (this) { + is DepA -> copy(metas = metas) + is DepB -> copy(metas = metas) + is DepC -> copy(metas = metas) + } + + class DepA( + override val metas: MetaContainer = emptyMetaContainer() + ): DeprecatedSum() { + + override fun copy(metas: MetaContainer): DepA = + DepA( + metas = metas) + + override fun withMeta(metaKey: String, metaValue: Any): DepA = + DepA( + metas = metas + metaContainerOf(metaKey to metaValue)) + + override fun toIonElement(): SexpElement { + val elements = ionSexpOf( + ionSymbol("dep_a"), + metas = metas) + return elements + } + + + override fun equals(other: Any?): Boolean { + if (other == null) return false + if (this === other) return true + if (other.javaClass != DepA::class.java) return false + + return true + } + + override fun hashCode(): Int = 5000 + } + + class DepB( + override val metas: MetaContainer = emptyMetaContainer() + ): DeprecatedSum() { + + override fun copy(metas: MetaContainer): DepB = + DepB( + metas = metas) + + override fun withMeta(metaKey: String, metaValue: Any): DepB = + DepB( + metas = metas + metaContainerOf(metaKey to metaValue)) + + override fun toIonElement(): SexpElement { + val elements = ionSexpOf( + ionSymbol("dep_b"), + metas = metas) + return elements + } + + + override fun equals(other: Any?): Boolean { + if (other == null) return false + if (this === other) return true + if (other.javaClass != DepB::class.java) return false + + return true + } + + override fun hashCode(): Int = 5001 + } + + class DepC( + override val metas: MetaContainer = emptyMetaContainer() + ): DeprecatedSum() { + + override fun copy(metas: MetaContainer): DepC = + DepC( + metas = metas) + + override fun withMeta(metaKey: String, metaValue: Any): DepC = + DepC( + metas = metas + metaContainerOf(metaKey to metaValue)) + + override fun toIonElement(): SexpElement { + val elements = ionSexpOf( + ionSymbol("dep_c"), + metas = metas) + return elements + } + + + override fun equals(other: Any?): Boolean { + if (other == null) return false + if (this === other) return true + if (other.javaClass != DepC::class.java) return false + + return true + } + + override fun hashCode(): Int = 5002 + } + + /** Converts instances of [TestDomain.DeprecatedSum] to any [T]. */ + interface Converter { + fun convert(node: TestDomain.DeprecatedSum): T = when(node) { + is TestDomain.DeprecatedSum.DepA -> convertDepA(node) + is TestDomain.DeprecatedSum.DepB -> convertDepB(node) + is TestDomain.DeprecatedSum.DepC -> convertDepC(node) + } + + fun convertDepA(node: TestDomain.DeprecatedSum.DepA): T + fun convertDepB(node: TestDomain.DeprecatedSum.DepB): T + fun convertDepC(node: TestDomain.DeprecatedSum.DepC): T + } + } + + sealed class EvolvingSum(override val metas: MetaContainer = emptyMetaContainer()) : TestDomainNode() { + override fun copy(metas: MetaContainer): EvolvingSum = + when (this) { + is Old -> copy(metas = metas) + is Current -> copy(metas = metas) + is Next -> copy(metas = metas) + } + + @Deprecated("This node is marked as deprecated") + class Old( + override val metas: MetaContainer = emptyMetaContainer() + ): EvolvingSum() { + + override fun copy(metas: MetaContainer): Old = + Old( + metas = metas) + + override fun withMeta(metaKey: String, metaValue: Any): Old = + Old( + metas = metas + metaContainerOf(metaKey to metaValue)) + + override fun toIonElement(): SexpElement { + val elements = ionSexpOf( + ionSymbol("old"), + metas = metas) + return elements + } + + + override fun equals(other: Any?): Boolean { + if (other == null) return false + if (this === other) return true + if (other.javaClass != Old::class.java) return false + + return true + } + + override fun hashCode(): Int = 6000 + } + + class Current( + override val metas: MetaContainer = emptyMetaContainer() + ): EvolvingSum() { + + override fun copy(metas: MetaContainer): Current = + Current( + metas = metas) + + override fun withMeta(metaKey: String, metaValue: Any): Current = + Current( + metas = metas + metaContainerOf(metaKey to metaValue)) + + override fun toIonElement(): SexpElement { + val elements = ionSexpOf( + ionSymbol("current"), + metas = metas) + return elements + } + + + override fun equals(other: Any?): Boolean { + if (other == null) return false + if (this === other) return true + if (other.javaClass != Current::class.java) return false + + return true + } + + override fun hashCode(): Int = 6001 + } + + @Experimental + class Next( + override val metas: MetaContainer = emptyMetaContainer() + ): EvolvingSum() { + + override fun copy(metas: MetaContainer): Next = + Next( + metas = metas) + + override fun withMeta(metaKey: String, metaValue: Any): Next = + Next( + metas = metas + metaContainerOf(metaKey to metaValue)) + + override fun toIonElement(): SexpElement { + val elements = ionSexpOf( + ionSymbol("next"), + metas = metas) + return elements + } + + + override fun equals(other: Any?): Boolean { + if (other == null) return false + if (this === other) return true + if (other.javaClass != Next::class.java) return false + + return true + } + + override fun hashCode(): Int = 6002 + } + + /** Converts instances of [TestDomain.EvolvingSum] to any [T]. */ + interface Converter { + fun convert(node: TestDomain.EvolvingSum): T = when(node) { + is TestDomain.EvolvingSum.Old -> convertOld(node) + is TestDomain.EvolvingSum.Current -> convertCurrent(node) + is TestDomain.EvolvingSum.Next -> convertNext(node) + } + + fun convertOld(node: TestDomain.EvolvingSum.Old): T + fun convertCurrent(node: TestDomain.EvolvingSum.Current): T + fun convertNext(node: TestDomain.EvolvingSum.Next): T + } + } + + sealed class Entity(override val metas: MetaContainer = emptyMetaContainer()) : TestDomainNode() { + override fun copy(metas: MetaContainer): Entity = + when (this) { + is Slug -> copy(metas = metas) + is Android -> copy(metas = metas) + is Human -> copy(metas = metas) + } + + class Slug( + override val metas: MetaContainer = emptyMetaContainer() + ): Entity() { + + override fun copy(metas: MetaContainer): Slug = + Slug( + metas = metas) + + override fun withMeta(metaKey: String, metaValue: Any): Slug = + Slug( + metas = metas + metaContainerOf(metaKey to metaValue)) + + override fun toIonElement(): SexpElement { + val elements = ionSexpOf( + ionSymbol("slug"), + metas = metas) + return elements + } + + + override fun equals(other: Any?): Boolean { + if (other == null) return false + if (this === other) return true + if (other.javaClass != Slug::class.java) return false + + return true + } + + override fun hashCode(): Int = 7000 + } + + class Android( + val id: org.partiql.pig.runtime.LongPrimitive, + override val metas: MetaContainer = emptyMetaContainer() + ): Entity() { + + override fun copy(metas: MetaContainer): Android = + Android( + id = id, + metas = metas) + + override fun withMeta(metaKey: String, metaValue: Any): Android = + Android( + id = id, + metas = metas + metaContainerOf(metaKey to metaValue)) + + override fun toIonElement(): SexpElement { + val elements = ionSexpOf( + ionSymbol("android"), + id.toIonElement(), + metas = metas) + return elements + } + + fun copy( + id: org.partiql.pig.runtime.LongPrimitive = this.id, + metas: MetaContainer = this.metas + ) = + Android( + id, + metas) + + override fun equals(other: Any?): Boolean { + if (other == null) return false + if (this === other) return true + if (other.javaClass != Android::class.java) return false + + other as Android + if (id != other.id) return false + return true + } + + private val myHashCode by lazy(LazyThreadSafetyMode.PUBLICATION) { + var hc = id.hashCode() + hc + } + + override fun hashCode(): Int = myHashCode + } + + class Human( + val firstName: org.partiql.pig.runtime.SymbolPrimitive, + val middleNames: kotlin.collections.List, + val lastName: org.partiql.pig.runtime.SymbolPrimitive, + val title: org.partiql.pig.runtime.SymbolPrimitive?, + val parent: Entity?, + override val metas: MetaContainer = emptyMetaContainer() + ): Entity() { override fun copy(metas: MetaContainer): Human = Human( @@ -4064,6 +4703,24 @@ class TestDomain private constructor() { third, metas = sexp.metas) } + "experimental_product" -> { + sexp.requireArityOrMalformed(IntRange(2, 2)) + val first = sexp.getRequired(0).toBoolPrimitive() + val second = sexp.getRequired(1).toBoolPrimitive() + TestDomain.ExperimentalProduct( + first, + second, + metas = sexp.metas) + } + "deprecated_product" -> { + sexp.requireArityOrMalformed(IntRange(2, 2)) + val first = sexp.getRequired(0).toLongPrimitive() + val second = sexp.getRequired(1).toLongPrimitive() + TestDomain.DeprecatedProduct( + first, + second, + metas = sexp.metas) + } "domain_level_record" -> { val ir = sexp.transformToIntermediateRecord() @@ -4160,6 +4817,60 @@ class TestDomain private constructor() { metas = sexp.metas) } ////////////////////////////////////// + // Variants for Sum Type 'ExperimentalSum' + ////////////////////////////////////// + "ex_a" -> { + sexp.requireArityOrMalformed(IntRange(0, 0)) + TestDomain.ExperimentalSum.ExA( + metas = sexp.metas) + } + "ex_b" -> { + sexp.requireArityOrMalformed(IntRange(0, 0)) + TestDomain.ExperimentalSum.ExB( + metas = sexp.metas) + } + "ex_c" -> { + sexp.requireArityOrMalformed(IntRange(0, 0)) + TestDomain.ExperimentalSum.ExC( + metas = sexp.metas) + } + ////////////////////////////////////// + // Variants for Sum Type 'DeprecatedSum' + ////////////////////////////////////// + "dep_a" -> { + sexp.requireArityOrMalformed(IntRange(0, 0)) + TestDomain.DeprecatedSum.DepA( + metas = sexp.metas) + } + "dep_b" -> { + sexp.requireArityOrMalformed(IntRange(0, 0)) + TestDomain.DeprecatedSum.DepB( + metas = sexp.metas) + } + "dep_c" -> { + sexp.requireArityOrMalformed(IntRange(0, 0)) + TestDomain.DeprecatedSum.DepC( + metas = sexp.metas) + } + ////////////////////////////////////// + // Variants for Sum Type 'EvolvingSum' + ////////////////////////////////////// + "old" -> { + sexp.requireArityOrMalformed(IntRange(0, 0)) + TestDomain.EvolvingSum.Old( + metas = sexp.metas) + } + "current" -> { + sexp.requireArityOrMalformed(IntRange(0, 0)) + TestDomain.EvolvingSum.Current( + metas = sexp.metas) + } + "next" -> { + sexp.requireArityOrMalformed(IntRange(0, 0)) + TestDomain.EvolvingSum.Next( + metas = sexp.metas) + } + ////////////////////////////////////// // Variants for Sum Type 'Entity' ////////////////////////////////////// "slug" -> { @@ -4228,6 +4939,8 @@ class TestDomain private constructor() { open fun visitOptionalVariadic(node: TestDomain.OptionalVariadic) { } open fun visitRequiredOptionalVariadic(node: TestDomain.RequiredOptionalVariadic) { } open fun visitOptionalRequiredVariadic(node: TestDomain.OptionalRequiredVariadic) { } + open fun visitExperimentalProduct(node: TestDomain.ExperimentalProduct) { } + open fun visitDeprecatedProduct(node: TestDomain.DeprecatedProduct) { } open fun visitDomainLevelRecord(node: TestDomain.DomainLevelRecord) { } open fun visitProductWithRecord(node: TestDomain.ProductWithRecord) { } open fun visitTestSumTriplet(node: TestDomain.TestSumTriplet) { } @@ -4251,6 +4964,27 @@ class TestDomain private constructor() { protected open fun visitTestSumTwo(node: TestDomain.TestSum.Two) { } protected open fun visitTestSumThree(node: TestDomain.TestSum.Three) { } ////////////////////////////////////// + // Sum Type: ExperimentalSum + ////////////////////////////////////// + protected open fun visitExperimentalSum(node: TestDomain.ExperimentalSum) { } + protected open fun visitExperimentalSumExA(node: TestDomain.ExperimentalSum.ExA) { } + protected open fun visitExperimentalSumExB(node: TestDomain.ExperimentalSum.ExB) { } + protected open fun visitExperimentalSumExC(node: TestDomain.ExperimentalSum.ExC) { } + ////////////////////////////////////// + // Sum Type: DeprecatedSum + ////////////////////////////////////// + protected open fun visitDeprecatedSum(node: TestDomain.DeprecatedSum) { } + protected open fun visitDeprecatedSumDepA(node: TestDomain.DeprecatedSum.DepA) { } + protected open fun visitDeprecatedSumDepB(node: TestDomain.DeprecatedSum.DepB) { } + protected open fun visitDeprecatedSumDepC(node: TestDomain.DeprecatedSum.DepC) { } + ////////////////////////////////////// + // Sum Type: EvolvingSum + ////////////////////////////////////// + protected open fun visitEvolvingSum(node: TestDomain.EvolvingSum) { } + protected open fun visitEvolvingSumOld(node: TestDomain.EvolvingSum.Old) { } + protected open fun visitEvolvingSumCurrent(node: TestDomain.EvolvingSum.Current) { } + protected open fun visitEvolvingSumNext(node: TestDomain.EvolvingSum.Next) { } + ////////////////////////////////////// // Sum Type: Entity ////////////////////////////////////// protected open fun visitEntity(node: TestDomain.Entity) { } @@ -4271,179 +5005,153 @@ class TestDomain private constructor() { walkBoolPrimitive(node.second) walkMetas(node.metas) } - open fun walkIntPair(node: TestDomain.IntPair) { visitIntPair(node) walkLongPrimitive(node.first) walkLongPrimitive(node.second) walkMetas(node.metas) } - open fun walkSymbolPair(node: TestDomain.SymbolPair) { visitSymbolPair(node) walkSymbolPrimitive(node.first) walkSymbolPrimitive(node.second) walkMetas(node.metas) } - open fun walkIonPair(node: TestDomain.IonPair) { visitIonPair(node) walkAnyElement(node.first) walkAnyElement(node.second) walkMetas(node.metas) } - open fun walkIntSymbolPair(node: TestDomain.IntSymbolPair) { visitIntSymbolPair(node) walkLongPrimitive(node.first) walkSymbolPrimitive(node.second) walkMetas(node.metas) } - open fun walkSymbolIntPair(node: TestDomain.SymbolIntPair) { visitSymbolIntPair(node) walkSymbolPrimitive(node.first) walkLongPrimitive(node.second) walkMetas(node.metas) } - open fun walkIonIntPair(node: TestDomain.IonIntPair) { visitIonIntPair(node) walkAnyElement(node.first) walkLongPrimitive(node.second) walkMetas(node.metas) } - open fun walkIonSymbolPair(node: TestDomain.IonSymbolPair) { visitIonSymbolPair(node) walkAnyElement(node.first) walkAnyElement(node.second) walkMetas(node.metas) } - open fun walkIntPairPair(node: TestDomain.IntPairPair) { visitIntPairPair(node) walkIntPair(node.first) walkIntPair(node.second) walkMetas(node.metas) } - open fun walkSymbolPairPair(node: TestDomain.SymbolPairPair) { visitSymbolPairPair(node) walkSymbolPair(node.first) walkSymbolPair(node.second) walkMetas(node.metas) } - open fun walkIonPairPair(node: TestDomain.IonPairPair) { visitIonPairPair(node) walkIonPair(node.first) walkIonPair(node.second) walkMetas(node.metas) } - open fun walkRecursivePair(node: TestDomain.RecursivePair) { visitRecursivePair(node) walkLongPrimitive(node.first) node.second?.let { walkRecursivePair(it) } walkMetas(node.metas) } - open fun walkAnswerPair(node: TestDomain.AnswerPair) { visitAnswerPair(node) walkAnswer(node.first) walkAnswer(node.second) walkMetas(node.metas) } - open fun walkAnswerIntPair(node: TestDomain.AnswerIntPair) { visitAnswerIntPair(node) walkAnswer(node.first) walkLongPrimitive(node.second) walkMetas(node.metas) } - open fun walkIntAnswerPair(node: TestDomain.IntAnswerPair) { visitIntAnswerPair(node) walkLongPrimitive(node.first) walkAnswer(node.second) walkMetas(node.metas) } - open fun walkSymbolAnswerPair(node: TestDomain.SymbolAnswerPair) { visitSymbolAnswerPair(node) walkSymbolPrimitive(node.first) walkAnswer(node.second) walkMetas(node.metas) } - open fun walkAnswerSymbolPair(node: TestDomain.AnswerSymbolPair) { visitAnswerSymbolPair(node) walkAnswer(node.first) walkSymbolPrimitive(node.second) walkMetas(node.metas) } - open fun walkOptional1(node: TestDomain.Optional1) { visitOptional1(node) node.value?.let { walkLongPrimitive(it) } walkMetas(node.metas) } - open fun walkOptional2(node: TestDomain.Optional2) { visitOptional2(node) node.first?.let { walkLongPrimitive(it) } node.second?.let { walkLongPrimitive(it) } walkMetas(node.metas) } - open fun walkRequiredOptional(node: TestDomain.RequiredOptional) { visitRequiredOptional(node) walkLongPrimitive(node.first) node.second?.let { walkLongPrimitive(it) } walkMetas(node.metas) } - open fun walkOptionalRequired(node: TestDomain.OptionalRequired) { visitOptionalRequired(node) node.first?.let { walkLongPrimitive(it) } walkLongPrimitive(node.second) walkMetas(node.metas) } - open fun walkVariadicMin0(node: TestDomain.VariadicMin0) { visitVariadicMin0(node) node.ints.map { walkLongPrimitive(it) } walkMetas(node.metas) } - open fun walkVariadicMin1(node: TestDomain.VariadicMin1) { visitVariadicMin1(node) node.ints.map { walkLongPrimitive(it) } walkMetas(node.metas) } - open fun walkElementVariadic(node: TestDomain.ElementVariadic) { visitElementVariadic(node) walkSymbolPrimitive(node.name) node.ints.map { walkLongPrimitive(it) } walkMetas(node.metas) } - open fun walkRequiredVariadic(node: TestDomain.RequiredVariadic) { visitRequiredVariadic(node) walkLongPrimitive(node.first) node.second.map { walkLongPrimitive(it) } walkMetas(node.metas) } - open fun walkOptionalVariadic(node: TestDomain.OptionalVariadic) { visitOptionalVariadic(node) node.first?.let { walkLongPrimitive(it) } node.second.map { walkLongPrimitive(it) } walkMetas(node.metas) } - open fun walkRequiredOptionalVariadic(node: TestDomain.RequiredOptionalVariadic) { visitRequiredOptionalVariadic(node) walkLongPrimitive(node.first) @@ -4451,7 +5159,6 @@ class TestDomain private constructor() { node.third.map { walkLongPrimitive(it) } walkMetas(node.metas) } - open fun walkOptionalRequiredVariadic(node: TestDomain.OptionalRequiredVariadic) { visitOptionalRequiredVariadic(node) node.first?.let { walkLongPrimitive(it) } @@ -4459,7 +5166,18 @@ class TestDomain private constructor() { node.third.map { walkLongPrimitive(it) } walkMetas(node.metas) } - + open fun walkExperimentalProduct(node: TestDomain.ExperimentalProduct) { + visitExperimentalProduct(node) + walkBoolPrimitive(node.first) + walkBoolPrimitive(node.second) + walkMetas(node.metas) + } + open fun walkDeprecatedProduct(node: TestDomain.DeprecatedProduct) { + visitDeprecatedProduct(node) + walkLongPrimitive(node.first) + walkLongPrimitive(node.second) + walkMetas(node.metas) + } open fun walkDomainLevelRecord(node: TestDomain.DomainLevelRecord) { visitDomainLevelRecord(node) walkLongPrimitive(node.someField) @@ -4467,14 +5185,12 @@ class TestDomain private constructor() { node.optionalField?.let { walkLongPrimitive(it) } walkMetas(node.metas) } - open fun walkProductWithRecord(node: TestDomain.ProductWithRecord) { visitProductWithRecord(node) walkLongPrimitive(node.value) walkDomainLevelRecord(node.dlr) walkMetas(node.metas) } - open fun walkTestSumTriplet(node: TestDomain.TestSumTriplet) { visitTestSumTriplet(node) walkTestSum(node.a) @@ -4482,14 +5198,12 @@ class TestDomain private constructor() { walkTestSum(node.c) walkMetas(node.metas) } - open fun walkEntityPair(node: TestDomain.EntityPair) { visitEntityPair(node) walkEntity(node.first) walkEntity(node.second) walkMetas(node.metas) } - ////////////////////////////////////// // Sum Type: Answer ////////////////////////////////////// @@ -4515,44 +5229,116 @@ class TestDomain private constructor() { open fun walkSumWithRecord(node: TestDomain.SumWithRecord) { visitSumWithRecord(node) when(node) { - is TestDomain.SumWithRecord.VariantWithRecord -> walkSumWithRecordVariantWithRecord(node) + is TestDomain.SumWithRecord.VariantWithRecord -> walkSumWithRecordVariantWithRecord(node) + } + } + + open fun walkSumWithRecordVariantWithRecord(node: TestDomain.SumWithRecord.VariantWithRecord) { + visitSumWithRecordVariantWithRecord(node) + walkLongPrimitive(node.value) + walkDomainLevelRecord(node.dlr) + walkMetas(node.metas) + } + ////////////////////////////////////// + // Sum Type: TestSum + ////////////////////////////////////// + open fun walkTestSum(node: TestDomain.TestSum) { + visitTestSum(node) + when(node) { + is TestDomain.TestSum.One -> walkTestSumOne(node) + is TestDomain.TestSum.Two -> walkTestSumTwo(node) + is TestDomain.TestSum.Three -> walkTestSumThree(node) + } + } + + open fun walkTestSumOne(node: TestDomain.TestSum.One) { + visitTestSumOne(node) + walkLongPrimitive(node.a) + walkMetas(node.metas) + } + open fun walkTestSumTwo(node: TestDomain.TestSum.Two) { + visitTestSumTwo(node) + walkLongPrimitive(node.a) + walkLongPrimitive(node.b) + walkMetas(node.metas) + } + open fun walkTestSumThree(node: TestDomain.TestSum.Three) { + visitTestSumThree(node) + walkLongPrimitive(node.a) + walkLongPrimitive(node.b) + walkLongPrimitive(node.c) + walkMetas(node.metas) + } + ////////////////////////////////////// + // Sum Type: ExperimentalSum + ////////////////////////////////////// + open fun walkExperimentalSum(node: TestDomain.ExperimentalSum) { + visitExperimentalSum(node) + when(node) { + is TestDomain.ExperimentalSum.ExA -> walkExperimentalSumExA(node) + is TestDomain.ExperimentalSum.ExB -> walkExperimentalSumExB(node) + is TestDomain.ExperimentalSum.ExC -> walkExperimentalSumExC(node) + } + } + + open fun walkExperimentalSumExA(node: TestDomain.ExperimentalSum.ExA) { + visitExperimentalSumExA(node) + walkMetas(node.metas) + } + open fun walkExperimentalSumExB(node: TestDomain.ExperimentalSum.ExB) { + visitExperimentalSumExB(node) + walkMetas(node.metas) + } + open fun walkExperimentalSumExC(node: TestDomain.ExperimentalSum.ExC) { + visitExperimentalSumExC(node) + walkMetas(node.metas) + } + ////////////////////////////////////// + // Sum Type: DeprecatedSum + ////////////////////////////////////// + open fun walkDeprecatedSum(node: TestDomain.DeprecatedSum) { + visitDeprecatedSum(node) + when(node) { + is TestDomain.DeprecatedSum.DepA -> walkDeprecatedSumDepA(node) + is TestDomain.DeprecatedSum.DepB -> walkDeprecatedSumDepB(node) + is TestDomain.DeprecatedSum.DepC -> walkDeprecatedSumDepC(node) } } - open fun walkSumWithRecordVariantWithRecord(node: TestDomain.SumWithRecord.VariantWithRecord) { - visitSumWithRecordVariantWithRecord(node) - walkLongPrimitive(node.value) - walkDomainLevelRecord(node.dlr) + open fun walkDeprecatedSumDepA(node: TestDomain.DeprecatedSum.DepA) { + visitDeprecatedSumDepA(node) + walkMetas(node.metas) + } + open fun walkDeprecatedSumDepB(node: TestDomain.DeprecatedSum.DepB) { + visitDeprecatedSumDepB(node) + walkMetas(node.metas) + } + open fun walkDeprecatedSumDepC(node: TestDomain.DeprecatedSum.DepC) { + visitDeprecatedSumDepC(node) walkMetas(node.metas) } ////////////////////////////////////// - // Sum Type: TestSum + // Sum Type: EvolvingSum ////////////////////////////////////// - open fun walkTestSum(node: TestDomain.TestSum) { - visitTestSum(node) + open fun walkEvolvingSum(node: TestDomain.EvolvingSum) { + visitEvolvingSum(node) when(node) { - is TestDomain.TestSum.One -> walkTestSumOne(node) - is TestDomain.TestSum.Two -> walkTestSumTwo(node) - is TestDomain.TestSum.Three -> walkTestSumThree(node) + is TestDomain.EvolvingSum.Old -> walkEvolvingSumOld(node) + is TestDomain.EvolvingSum.Current -> walkEvolvingSumCurrent(node) + is TestDomain.EvolvingSum.Next -> walkEvolvingSumNext(node) } } - open fun walkTestSumOne(node: TestDomain.TestSum.One) { - visitTestSumOne(node) - walkLongPrimitive(node.a) + open fun walkEvolvingSumOld(node: TestDomain.EvolvingSum.Old) { + visitEvolvingSumOld(node) walkMetas(node.metas) } - open fun walkTestSumTwo(node: TestDomain.TestSum.Two) { - visitTestSumTwo(node) - walkLongPrimitive(node.a) - walkLongPrimitive(node.b) + open fun walkEvolvingSumCurrent(node: TestDomain.EvolvingSum.Current) { + visitEvolvingSumCurrent(node) walkMetas(node.metas) } - open fun walkTestSumThree(node: TestDomain.TestSum.Three) { - visitTestSumThree(node) - walkLongPrimitive(node.a) - walkLongPrimitive(node.b) - walkLongPrimitive(node.c) + open fun walkEvolvingSumNext(node: TestDomain.EvolvingSum.Next) { + visitEvolvingSumNext(node) walkMetas(node.metas) } ////////////////////////////////////// @@ -4622,6 +5408,8 @@ class TestDomain private constructor() { open protected fun visitOptionalVariadic(node: TestDomain.OptionalVariadic, accumulator: T): T = accumulator open protected fun visitRequiredOptionalVariadic(node: TestDomain.RequiredOptionalVariadic, accumulator: T): T = accumulator open protected fun visitOptionalRequiredVariadic(node: TestDomain.OptionalRequiredVariadic, accumulator: T): T = accumulator + open protected fun visitExperimentalProduct(node: TestDomain.ExperimentalProduct, accumulator: T): T = accumulator + open protected fun visitDeprecatedProduct(node: TestDomain.DeprecatedProduct, accumulator: T): T = accumulator open protected fun visitDomainLevelRecord(node: TestDomain.DomainLevelRecord, accumulator: T): T = accumulator open protected fun visitProductWithRecord(node: TestDomain.ProductWithRecord, accumulator: T): T = accumulator open protected fun visitTestSumTriplet(node: TestDomain.TestSumTriplet, accumulator: T): T = accumulator @@ -4645,6 +5433,27 @@ class TestDomain private constructor() { open protected fun visitTestSumTwo(node: TestDomain.TestSum.Two, accumulator: T): T = accumulator open protected fun visitTestSumThree(node: TestDomain.TestSum.Three, accumulator: T): T = accumulator ////////////////////////////////////// + // Sum Type: ExperimentalSum + ////////////////////////////////////// + open protected fun visitExperimentalSum(node: TestDomain.ExperimentalSum, accumulator: T): T = accumulator + open protected fun visitExperimentalSumExA(node: TestDomain.ExperimentalSum.ExA, accumulator: T): T = accumulator + open protected fun visitExperimentalSumExB(node: TestDomain.ExperimentalSum.ExB, accumulator: T): T = accumulator + open protected fun visitExperimentalSumExC(node: TestDomain.ExperimentalSum.ExC, accumulator: T): T = accumulator + ////////////////////////////////////// + // Sum Type: DeprecatedSum + ////////////////////////////////////// + open protected fun visitDeprecatedSum(node: TestDomain.DeprecatedSum, accumulator: T): T = accumulator + open protected fun visitDeprecatedSumDepA(node: TestDomain.DeprecatedSum.DepA, accumulator: T): T = accumulator + open protected fun visitDeprecatedSumDepB(node: TestDomain.DeprecatedSum.DepB, accumulator: T): T = accumulator + open protected fun visitDeprecatedSumDepC(node: TestDomain.DeprecatedSum.DepC, accumulator: T): T = accumulator + ////////////////////////////////////// + // Sum Type: EvolvingSum + ////////////////////////////////////// + open protected fun visitEvolvingSum(node: TestDomain.EvolvingSum, accumulator: T): T = accumulator + open protected fun visitEvolvingSumOld(node: TestDomain.EvolvingSum.Old, accumulator: T): T = accumulator + open protected fun visitEvolvingSumCurrent(node: TestDomain.EvolvingSum.Current, accumulator: T): T = accumulator + open protected fun visitEvolvingSumNext(node: TestDomain.EvolvingSum.Next, accumulator: T): T = accumulator + ////////////////////////////////////// // Sum Type: Entity ////////////////////////////////////// open protected fun visitEntity(node: TestDomain.Entity, accumulator: T): T = accumulator @@ -4910,6 +5719,24 @@ class TestDomain private constructor() { return current } + open fun walkExperimentalProduct(node: TestDomain.ExperimentalProduct, accumulator: T): T { + var current = accumulator + current = visitExperimentalProduct(node, current) + current = walkBoolPrimitive(node.first, current) + current = walkBoolPrimitive(node.second, current) + current = walkMetas(node.metas, current) + return current + } + + open fun walkDeprecatedProduct(node: TestDomain.DeprecatedProduct, accumulator: T): T { + var current = accumulator + current = visitDeprecatedProduct(node, current) + current = walkLongPrimitive(node.first, current) + current = walkLongPrimitive(node.second, current) + current = walkMetas(node.metas, current) + return current + } + open fun walkDomainLevelRecord(node: TestDomain.DomainLevelRecord, accumulator: T): T { var current = accumulator current = visitDomainLevelRecord(node, current) @@ -5031,6 +5858,105 @@ class TestDomain private constructor() { return current } + ////////////////////////////////////// + // Sum Type: ExperimentalSum + ////////////////////////////////////// + open fun walkExperimentalSum(node: TestDomain.ExperimentalSum, accumulator: T): T { + val current = visitExperimentalSum(node, accumulator) + return when(node) { + is TestDomain.ExperimentalSum.ExA -> walkExperimentalSumExA(node, current) + is TestDomain.ExperimentalSum.ExB -> walkExperimentalSumExB(node, current) + is TestDomain.ExperimentalSum.ExC -> walkExperimentalSumExC(node, current) + } + } + + open fun walkExperimentalSumExA(node: TestDomain.ExperimentalSum.ExA, accumulator: T): T { + var current = accumulator + current = visitExperimentalSumExA(node, current) + current = walkMetas(node.metas, current) + return current + } + + open fun walkExperimentalSumExB(node: TestDomain.ExperimentalSum.ExB, accumulator: T): T { + var current = accumulator + current = visitExperimentalSumExB(node, current) + current = walkMetas(node.metas, current) + return current + } + + open fun walkExperimentalSumExC(node: TestDomain.ExperimentalSum.ExC, accumulator: T): T { + var current = accumulator + current = visitExperimentalSumExC(node, current) + current = walkMetas(node.metas, current) + return current + } + + ////////////////////////////////////// + // Sum Type: DeprecatedSum + ////////////////////////////////////// + open fun walkDeprecatedSum(node: TestDomain.DeprecatedSum, accumulator: T): T { + val current = visitDeprecatedSum(node, accumulator) + return when(node) { + is TestDomain.DeprecatedSum.DepA -> walkDeprecatedSumDepA(node, current) + is TestDomain.DeprecatedSum.DepB -> walkDeprecatedSumDepB(node, current) + is TestDomain.DeprecatedSum.DepC -> walkDeprecatedSumDepC(node, current) + } + } + + open fun walkDeprecatedSumDepA(node: TestDomain.DeprecatedSum.DepA, accumulator: T): T { + var current = accumulator + current = visitDeprecatedSumDepA(node, current) + current = walkMetas(node.metas, current) + return current + } + + open fun walkDeprecatedSumDepB(node: TestDomain.DeprecatedSum.DepB, accumulator: T): T { + var current = accumulator + current = visitDeprecatedSumDepB(node, current) + current = walkMetas(node.metas, current) + return current + } + + open fun walkDeprecatedSumDepC(node: TestDomain.DeprecatedSum.DepC, accumulator: T): T { + var current = accumulator + current = visitDeprecatedSumDepC(node, current) + current = walkMetas(node.metas, current) + return current + } + + ////////////////////////////////////// + // Sum Type: EvolvingSum + ////////////////////////////////////// + open fun walkEvolvingSum(node: TestDomain.EvolvingSum, accumulator: T): T { + val current = visitEvolvingSum(node, accumulator) + return when(node) { + is TestDomain.EvolvingSum.Old -> walkEvolvingSumOld(node, current) + is TestDomain.EvolvingSum.Current -> walkEvolvingSumCurrent(node, current) + is TestDomain.EvolvingSum.Next -> walkEvolvingSumNext(node, current) + } + } + + open fun walkEvolvingSumOld(node: TestDomain.EvolvingSum.Old, accumulator: T): T { + var current = accumulator + current = visitEvolvingSumOld(node, current) + current = walkMetas(node.metas, current) + return current + } + + open fun walkEvolvingSumCurrent(node: TestDomain.EvolvingSum.Current, accumulator: T): T { + var current = accumulator + current = visitEvolvingSumCurrent(node, current) + current = walkMetas(node.metas, current) + return current + } + + open fun walkEvolvingSumNext(node: TestDomain.EvolvingSum.Next, accumulator: T): T { + var current = accumulator + current = visitEvolvingSumNext(node, current) + current = walkMetas(node.metas, current) + return current + } + ////////////////////////////////////// // Sum Type: Entity ////////////////////////////////////// @@ -5798,6 +6724,58 @@ class TestDomain private constructor() { open fun transformOptionalRequiredVariadic_metas(node: TestDomain.OptionalRequiredVariadic) = transformMetas(node.metas) + // Tuple ExperimentalProduct + open fun transformExperimentalProduct(node: TestDomain.ExperimentalProduct): TestDomain.ExperimentalProduct { + val new_first = transformExperimentalProduct_first(node) + val new_second = transformExperimentalProduct_second(node) + val new_metas = transformExperimentalProduct_metas(node) + return if ( + node.first !== new_first || + node.second !== new_second || + node.metas !== new_metas + ) { + TestDomain.ExperimentalProduct( + first = new_first, + second = new_second, + metas = new_metas + ) + } else { + node + } + } + open fun transformExperimentalProduct_first(node: TestDomain.ExperimentalProduct) = + transformBoolPrimitive(node.first) + open fun transformExperimentalProduct_second(node: TestDomain.ExperimentalProduct) = + transformBoolPrimitive(node.second) + open fun transformExperimentalProduct_metas(node: TestDomain.ExperimentalProduct) = + transformMetas(node.metas) + + // Tuple DeprecatedProduct + open fun transformDeprecatedProduct(node: TestDomain.DeprecatedProduct): TestDomain.DeprecatedProduct { + val new_first = transformDeprecatedProduct_first(node) + val new_second = transformDeprecatedProduct_second(node) + val new_metas = transformDeprecatedProduct_metas(node) + return if ( + node.first !== new_first || + node.second !== new_second || + node.metas !== new_metas + ) { + TestDomain.DeprecatedProduct( + first = new_first, + second = new_second, + metas = new_metas + ) + } else { + node + } + } + open fun transformDeprecatedProduct_first(node: TestDomain.DeprecatedProduct) = + transformLongPrimitive(node.first) + open fun transformDeprecatedProduct_second(node: TestDomain.DeprecatedProduct) = + transformLongPrimitive(node.second) + open fun transformDeprecatedProduct_metas(node: TestDomain.DeprecatedProduct) = + transformMetas(node.metas) + // Tuple DomainLevelRecord open fun transformDomainLevelRecord(node: TestDomain.DomainLevelRecord): TestDomain.DomainLevelRecord { val new_someField = transformDomainLevelRecord_someField(node) @@ -6072,6 +7050,177 @@ class TestDomain private constructor() { open fun transformTestSumThree_metas(node: TestDomain.TestSum.Three) = transformMetas(node.metas) + ////////////////////////////////////// + // Sum Type: ExperimentalSum + ////////////////////////////////////// + open fun transformExperimentalSum(node: TestDomain.ExperimentalSum): TestDomain.ExperimentalSum = + when(node) { + is TestDomain.ExperimentalSum.ExA -> transformExperimentalSumExA(node) + is TestDomain.ExperimentalSum.ExB -> transformExperimentalSumExB(node) + is TestDomain.ExperimentalSum.ExC -> transformExperimentalSumExC(node) + } + // Variant ExperimentalSumExA + open fun transformExperimentalSumExA(node: TestDomain.ExperimentalSum.ExA): TestDomain.ExperimentalSum { + val new_metas = transformExperimentalSumExA_metas(node) + return if ( + node.metas !== new_metas + ) { + TestDomain.ExperimentalSum.ExA( + metas = new_metas + ) + } else { + node + } + } + open fun transformExperimentalSumExA_metas(node: TestDomain.ExperimentalSum.ExA) = + transformMetas(node.metas) + + // Variant ExperimentalSumExB + open fun transformExperimentalSumExB(node: TestDomain.ExperimentalSum.ExB): TestDomain.ExperimentalSum { + val new_metas = transformExperimentalSumExB_metas(node) + return if ( + node.metas !== new_metas + ) { + TestDomain.ExperimentalSum.ExB( + metas = new_metas + ) + } else { + node + } + } + open fun transformExperimentalSumExB_metas(node: TestDomain.ExperimentalSum.ExB) = + transformMetas(node.metas) + + // Variant ExperimentalSumExC + open fun transformExperimentalSumExC(node: TestDomain.ExperimentalSum.ExC): TestDomain.ExperimentalSum { + val new_metas = transformExperimentalSumExC_metas(node) + return if ( + node.metas !== new_metas + ) { + TestDomain.ExperimentalSum.ExC( + metas = new_metas + ) + } else { + node + } + } + open fun transformExperimentalSumExC_metas(node: TestDomain.ExperimentalSum.ExC) = + transformMetas(node.metas) + + ////////////////////////////////////// + // Sum Type: DeprecatedSum + ////////////////////////////////////// + open fun transformDeprecatedSum(node: TestDomain.DeprecatedSum): TestDomain.DeprecatedSum = + when(node) { + is TestDomain.DeprecatedSum.DepA -> transformDeprecatedSumDepA(node) + is TestDomain.DeprecatedSum.DepB -> transformDeprecatedSumDepB(node) + is TestDomain.DeprecatedSum.DepC -> transformDeprecatedSumDepC(node) + } + // Variant DeprecatedSumDepA + open fun transformDeprecatedSumDepA(node: TestDomain.DeprecatedSum.DepA): TestDomain.DeprecatedSum { + val new_metas = transformDeprecatedSumDepA_metas(node) + return if ( + node.metas !== new_metas + ) { + TestDomain.DeprecatedSum.DepA( + metas = new_metas + ) + } else { + node + } + } + open fun transformDeprecatedSumDepA_metas(node: TestDomain.DeprecatedSum.DepA) = + transformMetas(node.metas) + + // Variant DeprecatedSumDepB + open fun transformDeprecatedSumDepB(node: TestDomain.DeprecatedSum.DepB): TestDomain.DeprecatedSum { + val new_metas = transformDeprecatedSumDepB_metas(node) + return if ( + node.metas !== new_metas + ) { + TestDomain.DeprecatedSum.DepB( + metas = new_metas + ) + } else { + node + } + } + open fun transformDeprecatedSumDepB_metas(node: TestDomain.DeprecatedSum.DepB) = + transformMetas(node.metas) + + // Variant DeprecatedSumDepC + open fun transformDeprecatedSumDepC(node: TestDomain.DeprecatedSum.DepC): TestDomain.DeprecatedSum { + val new_metas = transformDeprecatedSumDepC_metas(node) + return if ( + node.metas !== new_metas + ) { + TestDomain.DeprecatedSum.DepC( + metas = new_metas + ) + } else { + node + } + } + open fun transformDeprecatedSumDepC_metas(node: TestDomain.DeprecatedSum.DepC) = + transformMetas(node.metas) + + ////////////////////////////////////// + // Sum Type: EvolvingSum + ////////////////////////////////////// + open fun transformEvolvingSum(node: TestDomain.EvolvingSum): TestDomain.EvolvingSum = + when(node) { + is TestDomain.EvolvingSum.Old -> transformEvolvingSumOld(node) + is TestDomain.EvolvingSum.Current -> transformEvolvingSumCurrent(node) + is TestDomain.EvolvingSum.Next -> transformEvolvingSumNext(node) + } + // Variant EvolvingSumOld + open fun transformEvolvingSumOld(node: TestDomain.EvolvingSum.Old): TestDomain.EvolvingSum { + val new_metas = transformEvolvingSumOld_metas(node) + return if ( + node.metas !== new_metas + ) { + TestDomain.EvolvingSum.Old( + metas = new_metas + ) + } else { + node + } + } + open fun transformEvolvingSumOld_metas(node: TestDomain.EvolvingSum.Old) = + transformMetas(node.metas) + + // Variant EvolvingSumCurrent + open fun transformEvolvingSumCurrent(node: TestDomain.EvolvingSum.Current): TestDomain.EvolvingSum { + val new_metas = transformEvolvingSumCurrent_metas(node) + return if ( + node.metas !== new_metas + ) { + TestDomain.EvolvingSum.Current( + metas = new_metas + ) + } else { + node + } + } + open fun transformEvolvingSumCurrent_metas(node: TestDomain.EvolvingSum.Current) = + transformMetas(node.metas) + + // Variant EvolvingSumNext + open fun transformEvolvingSumNext(node: TestDomain.EvolvingSum.Next): TestDomain.EvolvingSum { + val new_metas = transformEvolvingSumNext_metas(node) + return if ( + node.metas !== new_metas + ) { + TestDomain.EvolvingSum.Next( + metas = new_metas + ) + } else { + node + } + } + open fun transformEvolvingSumNext_metas(node: TestDomain.EvolvingSum.Next) = + transformMetas(node.metas) + ////////////////////////////////////// // Sum Type: Entity ////////////////////////////////////// diff --git a/pig-tests/src/test/pig/sample-universe.ion b/pig-tests/src/test/pig/sample-universe.ion index 03aecf2..46601ea 100644 --- a/pig-tests/src/test/pig/sample-universe.ion +++ b/pig-tests/src/test/pig/sample-universe.ion @@ -10,6 +10,7 @@ - other user defined types - sum - variant + - experimental or deprecated annotations - Products... - Product with no fields (definitely possible for sum variants--possible with top-level products too?)- with only required fields @@ -22,6 +23,7 @@ - Sum variants... - product variant (repeat as above) - Records with more than one required, optional and variadic field. + - variant with experimental or deprecated annotations */ (define test_domain @@ -63,6 +65,10 @@ (product required_optional_variadic first::int second::(? int) third::(* int 0 )) (product optional_required_variadic first::(? int) second::int third::(* int 0 )) + experimental::(product experimental_product first::bool second::bool) + + deprecated::(product deprecated_product first::int second::int) + (record domain_level_record (some_field int) (another_field symbol) @@ -75,7 +81,14 @@ (sum test_sum (one a::int) (two a::int b::int) - (three a::int b::int c::int)) + (three a::int b::int c::int) + ) + + experimental::(sum experimental_sum (ex_a) (ex_b) (ex_c)) + + deprecated::(sum deprecated_sum (dep_a) (dep_b) (dep_c)) + + (sum evolving_sum deprecated::(old) (current) experimental::(next)) (product test_sum_triplet a::test_sum b::test_sum c::test_sum) diff --git a/pig/src/main/kotlin/org/partiql/pig/domain/Utils.kt b/pig/src/main/kotlin/org/partiql/pig/domain/Utils.kt index de5c979..c02e118 100644 --- a/pig/src/main/kotlin/org/partiql/pig/domain/Utils.kt +++ b/pig/src/main/kotlin/org/partiql/pig/domain/Utils.kt @@ -89,7 +89,7 @@ internal fun DataType.toIonElement(includeTypeTag: Boolean): IonElement = when ( ionSymbol(tag), *namedElements.map { it.toIonElement(this.tupleType) }.toTypedArray() ) - ) + ).withAnnotations(annotations.map { it.toString().toLowerCase() }) is DataType.UserType.Sum -> ionSexpOf( ionSymbol("sum"), @@ -97,7 +97,7 @@ internal fun DataType.toIonElement(includeTypeTag: Boolean): IonElement = when ( *variants .filterNot { it.isDifferent } .map { it.toIonElement(includeTypeTag = false) }.toTypedArray() - ) + ).withAnnotations(annotations.map { it.toString().toLowerCase() }) } internal fun NamedElement.toIonElement(tupleType: TupleType) = diff --git a/pig/src/main/kotlin/org/partiql/pig/domain/model/DataType.kt b/pig/src/main/kotlin/org/partiql/pig/domain/model/DataType.kt index 0201059..f40d964 100644 --- a/pig/src/main/kotlin/org/partiql/pig/domain/model/DataType.kt +++ b/pig/src/main/kotlin/org/partiql/pig/domain/model/DataType.kt @@ -108,6 +108,8 @@ sealed class DataType { abstract fun copyAsDifferent(): UserType + abstract val annotations: List + /** * A product type consisting of a [tag] and one or more [namedElements]. * @@ -119,7 +121,8 @@ sealed class DataType { val tupleType: TupleType, val namedElements: List, override val metas: MetaContainer, - override val isDifferent: Boolean = false + override val isDifferent: Boolean = false, + override val annotations: List = emptyList() ) : UserType() { fun computeArity(): IntRange { @@ -171,7 +174,8 @@ sealed class DataType { override val tag: String, val variants: List, override val metas: MetaContainer, - override val isDifferent: Boolean = false + override val isDifferent: Boolean = false, + override val annotations: List = emptyList() ) : UserType() { override fun copyAsDifferent(): UserType = this.copy( diff --git a/pig/src/main/kotlin/org/partiql/pig/domain/model/TypeAnnotation.kt b/pig/src/main/kotlin/org/partiql/pig/domain/model/TypeAnnotation.kt new file mode 100644 index 0000000..f32fdde --- /dev/null +++ b/pig/src/main/kotlin/org/partiql/pig/domain/model/TypeAnnotation.kt @@ -0,0 +1,34 @@ +package org.partiql.pig.domain.model + +/** + * Annotations that are allowed on a UserType definition + * + * Example: + * ``` + * (sum my_sum_type + * (deprecated::first_variant ...) + * (second_variant ...) + * (experimental::third_variant ...) + * ) + * ``` + */ +enum class TypeAnnotation { + DEPRECATED, + EXPERIMENTAL; + + companion object { + + /** + * TODO "safe" valueOf until it's decided what to do with + * - Field identifier used in place of type name (in same sum) + * - Variant identifier used in place of type name (in a different sum) + * + * These two TypeDomainSemanticCheckerTests appear to be asserting on missing(?) functionality + */ + fun of(v: String): TypeAnnotation? = try { + valueOf(v.toUpperCase()) + } catch (ex: IllegalArgumentException) { + null + } + } +} diff --git a/pig/src/main/kotlin/org/partiql/pig/domain/parser/ParserErrorContext.kt b/pig/src/main/kotlin/org/partiql/pig/domain/parser/ParserErrorContext.kt index eeab107..a3cf009 100644 --- a/pig/src/main/kotlin/org/partiql/pig/domain/parser/ParserErrorContext.kt +++ b/pig/src/main/kotlin/org/partiql/pig/domain/parser/ParserErrorContext.kt @@ -20,6 +20,7 @@ import com.amazon.ionelement.api.IonElement import com.amazon.ionelement.api.IonElementException import com.amazon.ionelement.api.IonLocation import com.amazon.ionelement.api.location +import org.partiql.pig.domain.model.TypeAnnotation import org.partiql.pig.errors.ErrorContext import org.partiql.pig.errors.PigError import org.partiql.pig.errors.PigException @@ -77,6 +78,9 @@ sealed class ParserErrorContext(val msgFormatter: () -> String) : ErrorContext { object MultipleElementIdentifierAnnotations : ParserErrorContext({ "Element has multiple name annotations" }) + + object MultipleTypeAnnotations : + ParserErrorContext({ "Only one TypeAnnotation (${TypeAnnotation.values().joinToString()}) is supported" }) } fun parseError(blame: IonLocation?, context: ErrorContext): Nothing = diff --git a/pig/src/main/kotlin/org/partiql/pig/domain/parser/TypeDomainParser.kt b/pig/src/main/kotlin/org/partiql/pig/domain/parser/TypeDomainParser.kt index 44ceda0..4f7d031 100644 --- a/pig/src/main/kotlin/org/partiql/pig/domain/parser/TypeDomainParser.kt +++ b/pig/src/main/kotlin/org/partiql/pig/domain/parser/TypeDomainParser.kt @@ -33,6 +33,7 @@ import org.partiql.pig.domain.model.PermutedSum import org.partiql.pig.domain.model.Statement import org.partiql.pig.domain.model.Transform import org.partiql.pig.domain.model.TupleType +import org.partiql.pig.domain.model.TypeAnnotation import org.partiql.pig.domain.model.TypeDomain import org.partiql.pig.domain.model.TypeRef import org.partiql.pig.domain.model.TypeUniverse @@ -111,22 +112,24 @@ private fun parseTypeDomain(domainName: String, sexp: SexpElement): TypeDomain { ) } -private fun parseDomainLevelStatement(tlvs: SexpElement): DataType.UserType { - return when (tlvs.tag) { - "product" -> parseProductBody(tlvs.tail, tlvs.metas) - "record" -> parseRecordBody(tlvs.tail, tlvs.metas) - "sum" -> parseSum(tlvs) - else -> parseError(tlvs.head, ParserErrorContext.InvalidDomainLevelTag(tlvs.tag)) +private fun parseDomainLevelStatement(sexp: SexpElement): DataType.UserType { + if (sexp.annotations.size > 1) { + parseError(sexp, ParserErrorContext.MultipleTypeAnnotations) + } + val annotations = sexp.annotations.mapNotNull { TypeAnnotation.of(it) } + return when (sexp.tag) { + "product" -> parseProductBody(sexp.tail, sexp.metas, annotations) + "record" -> parseRecordBody(sexp.tail, sexp.metas, annotations) + "sum" -> parseSum(sexp, annotations) + else -> parseError(sexp.head, ParserErrorContext.InvalidDomainLevelTag(sexp.tag)) } } -private fun parseTypeRefs(values: List): List = - values.map { parseSingleTypeRef(it) } - // Parses a sum-variant product or record (depending on the syntax used) private fun parseVariant( bodyArguments: List, - metas: MetaContainer + metas: MetaContainer, + annotations: List, ): DataType.UserType.Tuple { val elements = bodyArguments.tail @@ -149,20 +152,21 @@ private fun parseVariant( return when { isRecord -> { - parseRecordBody(bodyArguments, metas) + parseRecordBody(bodyArguments, metas, annotations) } else -> { - parseProductBody(bodyArguments, metas) + parseProductBody(bodyArguments, metas, annotations) } } } -private fun parseProductBody(bodyArguments: List, metas: MetaContainer): DataType.UserType.Tuple { - val typeName = bodyArguments.head.symbolValue - - val namedElements = parseProductElements(bodyArguments.tail) - - return DataType.UserType.Tuple(typeName, TupleType.PRODUCT, namedElements, metas) -} +private fun parseProductBody(args: List, metas: MetaContainer, annotations: List) = + DataType.UserType.Tuple( + tag = args.head.symbolValue, + tupleType = TupleType.PRODUCT, + namedElements = parseProductElements(args.tail), + metas = metas, + annotations = annotations + ) private fun parseProductElements(values: List): List = values.map { @@ -181,11 +185,15 @@ private fun parseProductElements(values: List): List = ) } -private fun parseRecordBody(bodyArguments: List, metas: MetaContainer): DataType.UserType.Tuple { - val typeName = bodyArguments.head.symbolValue - val namedElements = parseRecordElements(bodyArguments.tail) - return DataType.UserType.Tuple(typeName, TupleType.RECORD, namedElements, metas) -} +private fun parseRecordBody(bodyArguments: List, metas: MetaContainer, annotations: List) = + DataType.UserType.Tuple( + tag = bodyArguments.head.symbolValue, + tupleType = TupleType.RECORD, + namedElements = parseRecordElements(bodyArguments.tail), + metas = metas, + isDifferent = false, + annotations = annotations + ) fun parseRecordElements(elementSexps: List): List = elementSexps.asSequence() @@ -210,19 +218,21 @@ fun parseRecordElements(elementSexps: List): List = } .toList() -private fun parseSum(sexp: SexpElement): DataType.UserType.Sum { - val args = sexp.tail // Skip tag - val typeName = args.head.symbolValue - - val variants = args.tail.map { - parseSumVariant(it.asSexp()) - } - - return DataType.UserType.Sum(typeName, variants.toList(), sexp.metas) -} +private fun parseSum(sexp: SexpElement, annotations: List) = + DataType.UserType.Sum( + tag = sexp.tail.head.symbolValue, + variants = sexp.tail.tail.map { parseSumVariant(it.asSexp()) }, + metas = sexp.metas, + isDifferent = false, + annotations = annotations + ) private fun parseSumVariant(sexp: SexpElement): DataType.UserType.Tuple { - return parseVariant(sexp.values, sexp.metas) + if (sexp.annotations.size > 1) { + parseError(sexp, ParserErrorContext.MultipleTypeAnnotations) + } + val annotations = sexp.annotations.mapNotNull { TypeAnnotation.of(it) } + return parseVariant(sexp.values, sexp.metas, annotations) } private fun parseSingleTypeRef(typeRefExp: IonElement): TypeRef { diff --git a/pig/src/main/kotlin/org/partiql/pig/generator/custom/CTypeDomain.kt b/pig/src/main/kotlin/org/partiql/pig/generator/custom/CTypeDomain.kt index 796b0b7..bf543da 100644 --- a/pig/src/main/kotlin/org/partiql/pig/generator/custom/CTypeDomain.kt +++ b/pig/src/main/kotlin/org/partiql/pig/generator/custom/CTypeDomain.kt @@ -44,7 +44,8 @@ data class CTuple( val memberOfType: String?, val elements: List, val arity: IntRange, - val tupleType: TupleType + val tupleType: TupleType, + val annotations: List = emptyList() ) { /** All of the elements excluding the variadic element. */ @Suppress("unused") @@ -88,7 +89,8 @@ private fun DataType.UserType.Tuple.toCTuple(memberOfType: String?) = memberOfType = memberOfType, elements = this.namedElements.map { it.toCElement() }, arity = this.computeArity(), - tupleType = this.tupleType + tupleType = this.tupleType, + annotations = this.annotations.map { it.toString() } ) private fun NamedElement.toCElement(): CElement { diff --git a/pig/src/main/kotlin/org/partiql/pig/generator/kotlin/KTypeDomain.kt b/pig/src/main/kotlin/org/partiql/pig/generator/kotlin/KTypeDomain.kt index 52088db..9f2d3c0 100644 --- a/pig/src/main/kotlin/org/partiql/pig/generator/kotlin/KTypeDomain.kt +++ b/pig/src/main/kotlin/org/partiql/pig/generator/kotlin/KTypeDomain.kt @@ -95,7 +95,8 @@ data class KTuple( * `true`, its generated visitor transform `transform*` method will be `abstract`. */ val isTransformAbstract: Boolean, - val hasVariadicElement: Boolean + val hasVariadicElement: Boolean, + val annotations: List, ) data class KSum( @@ -107,5 +108,6 @@ data class KSum( * two type domains and this particular sum has been removed from the second. When this is `true`, its * generated visitor transform `transform*` method will be `abstract`. */ - val isTransformAbstract: Boolean + val isTransformAbstract: Boolean, + val annotations: List, ) diff --git a/pig/src/main/kotlin/org/partiql/pig/generator/kotlin/KTypeDomainConverter.kt b/pig/src/main/kotlin/org/partiql/pig/generator/kotlin/KTypeDomainConverter.kt index 9c693c6..2cc962f 100644 --- a/pig/src/main/kotlin/org/partiql/pig/generator/kotlin/KTypeDomainConverter.kt +++ b/pig/src/main/kotlin/org/partiql/pig/generator/kotlin/KTypeDomainConverter.kt @@ -26,6 +26,7 @@ import org.partiql.pig.domain.model.DataType import org.partiql.pig.domain.model.NamedElement import org.partiql.pig.domain.model.Transform import org.partiql.pig.domain.model.TupleType +import org.partiql.pig.domain.model.TypeAnnotation import org.partiql.pig.domain.model.TypeDomain import org.partiql.pig.domain.model.TypeRef import org.partiql.pig.domain.model.TypeUniverse @@ -97,7 +98,8 @@ private class KTypeDomainConverter( constructorName = "${it.tag.snakeToPascalCase()}.${v.tag.snakeToPascalCase()}" ) }, - isTransformAbstract = it.isDifferent + isTransformAbstract = it.isDifferent, + annotations = it.annotations.map { a -> a.kotlinString() } ) ) } @@ -125,7 +127,8 @@ private class KTypeDomainConverter( TupleType.RECORD -> true }, hasVariadicElement = hasVariadicElement(), - isTransformAbstract = this.isDifferent + isTransformAbstract = this.isDifferent, + annotations = annotations.map { a -> a.kotlinString() } ) } @@ -426,4 +429,9 @@ private class KTypeDomainConverter( else -> this.typeName.snakeToPascalCase() } } + + private fun TypeAnnotation.kotlinString(): String = when (this) { + TypeAnnotation.DEPRECATED -> "@Deprecated(\"This node is marked as deprecated\")" + TypeAnnotation.EXPERIMENTAL -> "@Experimental" + } } diff --git a/pig/src/main/resources/org/partiql/pig/templates/html.ftl b/pig/src/main/resources/org/partiql/pig/templates/html.ftl index 1946ce8..4f345de 100644 --- a/pig/src/main/resources/org/partiql/pig/templates/html.ftl +++ b/pig/src/main/resources/org/partiql/pig/templates/html.ftl @@ -85,9 +85,12 @@ [#list tuples as tuple] - ${tuple.tag} +
+ [#list tuple.annotations as annotation] + ${annotation} + [/#list] ${tuple.tupleType} diff --git a/pig/src/main/resources/org/partiql/pig/templates/kotlin-domain.ftl b/pig/src/main/resources/org/partiql/pig/templates/kotlin-domain.ftl index 03c8054..f659147 100644 --- a/pig/src/main/resources/org/partiql/pig/templates/kotlin-domain.ftl +++ b/pig/src/main/resources/org/partiql/pig/templates/kotlin-domain.ftl @@ -26,6 +26,9 @@ https://freemarker.apache.org/docs/dgui_misc_whitespace.html [#-- Template to generate a tuple type class. --] [#macro tuple t index] +[#list t.annotations as annotation] +${annotation} +[/#list] class ${t.kotlinName}( [#list t.properties as p] val ${p.kotlinName}: ${p.kotlinTypeName}, @@ -146,6 +149,9 @@ metas: MetaContainer = emptyMetaContainer() * (The "_" suffix is needed to work-around conflicts due to type erasure and ambiguities with null arguments.) [/#if] */ +[#list t.annotations as annotation] +${annotation} +[/#list] fun ${bf.kotlinName}( [@indent count=4] [@builder_fun_parameter_list bf.parameters/] @@ -234,6 +240,9 @@ abstract class ${domain.kotlinName}Node : DomainNode { ///////////////////////////////////////////////////////////////////////////// [#list domain.sums as s] +[#list s.annotations as annotation] +${annotation} +[/#list] sealed class ${s.kotlinName}(override val metas: MetaContainer = emptyMetaContainer()) : ${s.superClass}() { override fun copy(metas: MetaContainer): ${s.kotlinName} = when (this) { diff --git a/pig/src/main/resources/org/partiql/pig/templates/kotlin-visitor.ftl b/pig/src/main/resources/org/partiql/pig/templates/kotlin-visitor.ftl index 4eaaef6..047a18e 100644 --- a/pig/src/main/resources/org/partiql/pig/templates/kotlin-visitor.ftl +++ b/pig/src/main/resources/org/partiql/pig/templates/kotlin-visitor.ftl @@ -53,7 +53,6 @@ open class Visitor : DomainVisitorBase() { open fun walk${t.kotlinName}(node: ${domain.kotlinName}.${t.kotlinName}) { [@tuple_visitor_walker_body t t.kotlinName/][#t] } - [/#items] [/#list] [#list domain.sums as s] diff --git a/pig/src/test/kotlin/org/partiql/pig/domain/TypeAnnotationParserTests.kt b/pig/src/test/kotlin/org/partiql/pig/domain/TypeAnnotationParserTests.kt new file mode 100644 index 0000000..baccf02 --- /dev/null +++ b/pig/src/test/kotlin/org/partiql/pig/domain/TypeAnnotationParserTests.kt @@ -0,0 +1,88 @@ +package org.partiql.pig.domain + +import com.amazon.ion.system.IonReaderBuilder +import org.junit.jupiter.api.Test +import org.junit.jupiter.params.ParameterizedTest +import org.junit.jupiter.params.provider.MethodSource +import org.partiql.pig.domain.model.DataType +import org.partiql.pig.domain.model.TypeAnnotation +import org.partiql.pig.domain.parser.parseTypeUniverse + +class TypeAnnotationParserTests { + + @ParameterizedTest + @MethodSource("typeAnnotationCases") + fun typeAnnotationTests(tc: TestCase) { + val universe = "(define foo (domain ${tc.definition}))" + val reader = IonReaderBuilder.standard().build(universe) + val parsed = parseTypeUniverse(reader) + val domains = parsed.computeTypeDomains() + assert(domains.size == 1) + val domain = domains.first() + val types = domain.userTypes + assert(types.size == 1) + val type = types.first() + tc.assertion(type) + } + + @Test + internal fun annotationsCarryOverTest() { + val universe = """ + (define domain_a + (domain + deprecated::(sum sum_keep (a) (b) (c)) + deprecated::(sum sum_exclude (x) (y) (z)) + deprecated::(product product_keep v::int) + deprecated::(product product_exclude u::int) + ) + ) + (define domain_b + (permute_domain domain_a + (exclude sum_exclude product_exclude) + ) + ) + """.trimIndent() + val reader = IonReaderBuilder.standard().build(universe) + val parsed = parseTypeUniverse(reader) + val domains = parsed.computeTypeDomains() + domains.forEach { + // every type should have an annotation + it.userTypes.forEach { t -> + assert(t.annotations.isNotEmpty()) + } + } + } + + companion object { + + data class TestCase( + val definition: String, + val assertion: (type: DataType.UserType) -> Unit, + ) + + @JvmStatic + fun typeAnnotationCases() = listOf( + TestCase("experimental::(product window_partition_list)") { + assert(it.annotations.contains(TypeAnnotation.EXPERIMENTAL)) + }, + TestCase("experimental::(sum ordering_spec (asc) (desc))") { + assert(it.annotations.contains(TypeAnnotation.EXPERIMENTAL)) + }, + TestCase("deprecated::(product window_partition_list)") { + assert(it.annotations.contains(TypeAnnotation.DEPRECATED)) + }, + TestCase("deprecated::(sum ordering_spec (asc) (desc))") { + assert(it.annotations.contains(TypeAnnotation.DEPRECATED)) + }, + TestCase("(sum ordering_spec deprecated::(asc) experimental::(desc) (other))") { + (it as DataType.UserType.Sum).variants.forEach { v -> + when (v.tag) { + "asc" -> assert(v.annotations.contains(TypeAnnotation.DEPRECATED)) + "desc" -> assert(v.annotations.contains(TypeAnnotation.EXPERIMENTAL)) + "other" -> assert(v.annotations.isEmpty()) + } + } + }, + ) + } +}