mirror of
https://github.com/digital-asset/daml.git
synced 2024-09-20 01:07:18 +03:00
minimal Scala codegen interface support (#13858)
* add inherited choices for Scala codegen, test output exercises CHANGELOG_BEGIN - [scala codegen] Choices inherited from interfaces may be exercised directly from those templates via ``createAnd``, contract ID, or exercise-by-key. Exercise by interface-contract-ID and interface-contract-ID types in signatures are not supported. See `issue #13858 <https://github.com/digital-asset/daml/pull/13858>`__. CHANGELOG_END
This commit is contained in:
parent
59498586a5
commit
30e9b87279
@ -17,16 +17,19 @@ load(
|
|||||||
"lf_version_configuration",
|
"lf_version_configuration",
|
||||||
)
|
)
|
||||||
|
|
||||||
|
# TODO(#13296) change to "latest" when interfaces released
|
||||||
|
tested_lf_config = "dev"
|
||||||
|
|
||||||
daml_compile(
|
daml_compile(
|
||||||
name = "MyMain",
|
name = "MyMain",
|
||||||
srcs = ["src/main/daml/MyMain.daml"],
|
srcs = ["src/main/daml/MyMain.daml"],
|
||||||
target = lf_version_configuration.get("latest"),
|
target = lf_version_configuration.get(tested_lf_config),
|
||||||
)
|
)
|
||||||
|
|
||||||
daml_compile(
|
daml_compile(
|
||||||
name = "MySecondMain",
|
name = "MySecondMain",
|
||||||
srcs = ["src/main/daml/MySecondMain.daml"],
|
srcs = ["src/main/daml/MySecondMain.daml"],
|
||||||
target = lf_version_configuration.get("latest"),
|
target = lf_version_configuration.get(tested_lf_config),
|
||||||
)
|
)
|
||||||
|
|
||||||
dar_to_scala(
|
dar_to_scala(
|
||||||
@ -34,7 +37,7 @@ dar_to_scala(
|
|||||||
srcs = [
|
srcs = [
|
||||||
":MyMain.dar",
|
":MyMain.dar",
|
||||||
":MySecondMain.dar",
|
":MySecondMain.dar",
|
||||||
"//daml-lf/encoder:testing-dar-latest",
|
"//daml-lf/encoder:testing-dar-%s" % tested_lf_config,
|
||||||
],
|
],
|
||||||
package_prefix = "com.daml.sample",
|
package_prefix = "com.daml.sample",
|
||||||
srcjar_out = "MyMain.srcjar",
|
srcjar_out = "MyMain.srcjar",
|
||||||
|
@ -590,3 +590,24 @@ template JustMapUser
|
|||||||
aMap: JustMap Int Int
|
aMap: JustMap Int Int
|
||||||
where
|
where
|
||||||
signatory party
|
signatory party
|
||||||
|
|
||||||
|
interface InterfaceToMix where
|
||||||
|
getOwner: Party
|
||||||
|
choice InheritedOnly: () with
|
||||||
|
controller getOwner this
|
||||||
|
do return ()
|
||||||
|
{- TODO(#13349) uncomment when overloaded choices compile
|
||||||
|
choice OverloadedInTemplate: () with
|
||||||
|
controller getOwner this
|
||||||
|
do return ()
|
||||||
|
-}
|
||||||
|
|
||||||
|
template InterfaceMixer with
|
||||||
|
party: Party
|
||||||
|
where
|
||||||
|
signatory party
|
||||||
|
choice OverloadedInTemplate: () with
|
||||||
|
controller party
|
||||||
|
do return ()
|
||||||
|
implements InterfaceToMix where
|
||||||
|
getOwner = party
|
||||||
|
@ -3,7 +3,9 @@
|
|||||||
|
|
||||||
package com.daml.codegen
|
package com.daml.codegen
|
||||||
|
|
||||||
import com.daml.sample.MyMain.{Increment, KeyedNumber, SimpleListExample}
|
import com.daml.sample.MyMain
|
||||||
|
import MyMain.{KeyedNumber, Increment, SimpleListExample}
|
||||||
|
import com.daml.ledger.api.refinements.ApiTypes
|
||||||
import com.daml.ledger.api.v1.{commands => rpccmd}
|
import com.daml.ledger.api.v1.{commands => rpccmd}
|
||||||
import com.daml.ledger.client.binding.{Primitive => P}
|
import com.daml.ledger.client.binding.{Primitive => P}
|
||||||
|
|
||||||
@ -33,6 +35,42 @@ class GeneratedCommandsUT extends AnyWordSpec with Matchers with Inside {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
"exercise" should {
|
||||||
|
import com.daml.ledger.client.binding.Value.encode
|
||||||
|
val imId: P.ContractId[MyMain.InterfaceMixer] = P.ContractId("fakeimid")
|
||||||
|
val DirectTemplateId = ApiTypes.TemplateId unwrap MyMain.InterfaceMixer.id
|
||||||
|
|
||||||
|
"invoke directly-defined choices" in {
|
||||||
|
inside(imId.exerciseOverloadedInTemplate(alice).command.command) {
|
||||||
|
case rpccmd.Command.Command.Exercise(
|
||||||
|
rpccmd.ExerciseCommand(
|
||||||
|
Some(DirectTemplateId),
|
||||||
|
cid,
|
||||||
|
"OverloadedInTemplate",
|
||||||
|
Some(choiceArg),
|
||||||
|
)
|
||||||
|
) =>
|
||||||
|
cid should ===(imId)
|
||||||
|
choiceArg should ===(encode(MyMain.OverloadedInTemplate()))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
"invoke interface-inherited choices, directly from template" in {
|
||||||
|
inside(imId.exerciseInheritedOnly(alice).command.command) {
|
||||||
|
case rpccmd.Command.Command.Exercise(
|
||||||
|
rpccmd.ExerciseCommand(
|
||||||
|
Some(DirectTemplateId), // TODO(#13349, #13668) must be interface ID
|
||||||
|
cid,
|
||||||
|
"InheritedOnly",
|
||||||
|
Some(choiceArg),
|
||||||
|
)
|
||||||
|
) =>
|
||||||
|
cid should ===(imId)
|
||||||
|
choiceArg should ===(encode(MyMain.InheritedOnly()))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
"key" should {
|
"key" should {
|
||||||
"make an exercise-by-key command" in {
|
"make an exercise-by-key command" in {
|
||||||
inside((KeyedNumber.key(alice).exerciseIncrement(alice, 42)).command.command) {
|
inside((KeyedNumber.key(alice).exerciseIncrement(alice, 42)).command.command) {
|
||||||
|
@ -74,7 +74,7 @@ object CodeGen {
|
|||||||
roots: Seq[String],
|
roots: Seq[String],
|
||||||
): ValidationNel[String, Unit] =
|
): ValidationNel[String, Unit] =
|
||||||
decodeInterfaces(files).map { interfaces: NonEmptyList[EnvironmentInterface] =>
|
decodeInterfaces(files).map { interfaces: NonEmptyList[EnvironmentInterface] =>
|
||||||
val combined = interfaces.suml1
|
val combined = interfaces.suml1.resolveChoices
|
||||||
val interface = combined.copy(
|
val interface = combined.copy(
|
||||||
typeDecls = Util.filterTemplatesBy(roots.map(_.r))(combined.typeDecls)
|
typeDecls = Util.filterTemplatesBy(roots.map(_.r))(combined.typeDecls)
|
||||||
)
|
)
|
||||||
@ -134,7 +134,7 @@ object CodeGen {
|
|||||||
val typeDeclarationsToGenerate =
|
val typeDeclarationsToGenerate =
|
||||||
DependencyGraph.transitiveClosure(
|
DependencyGraph.transitiveClosure(
|
||||||
serializableTypes = util.iface.typeDecls,
|
serializableTypes = util.iface.typeDecls,
|
||||||
interfaces = Map.empty, // TODO(#13349)
|
interfaces = util.iface.astInterfaces,
|
||||||
)
|
)
|
||||||
|
|
||||||
// Each record/variant has Scala code generated for it individually, unless their names are related
|
// Each record/variant has Scala code generated for it individually, unless their names are related
|
||||||
@ -164,6 +164,7 @@ object CodeGen {
|
|||||||
// 1. collect records, search variants and splat/filter
|
// 1. collect records, search variants and splat/filter
|
||||||
val (unassociatedRecords, splattedVariants, enums) = splatVariants(definitions)
|
val (unassociatedRecords, splattedVariants, enums) = splatVariants(definitions)
|
||||||
|
|
||||||
|
// TODO(#13349) include interfaces as well
|
||||||
// 2. put templates/types into single Namespace.fromHierarchy
|
// 2. put templates/types into single Namespace.fromHierarchy
|
||||||
val treeified: Namespace[String, Option[lf.HierarchicalOutput.TemplateOrDatatype]] =
|
val treeified: Namespace[String, Option[lf.HierarchicalOutput.TemplateOrDatatype]] =
|
||||||
Namespace.fromHierarchy {
|
Namespace.fromHierarchy {
|
||||||
|
Loading…
Reference in New Issue
Block a user