From 299027b4b9939ecf741e8abeebbf2437b984198b Mon Sep 17 00:00:00 2001 From: Robin Krom Date: Tue, 7 Dec 2021 06:49:42 +0100 Subject: [PATCH] interfaces: doc generation for interfaces (#11971) * interfaces: doc generation for interfaces This adds generated documentation for interface choices. CHANGELOG_BEGIN CHANGELOG_END * added issue to todo * refactor getTemplateDocs/getInterfaceDocs * refactor template/interface doc extraction --- .../damlc/daml-doc/src/DA/Daml/Doc/Extract.hs | 1 + .../src/DA/Daml/Doc/Extract/Templates.hs | 137 +++++++++++++----- .../daml-doc/src/DA/Daml/Doc/Render/Output.hs | 14 ++ .../src/DA/Daml/Doc/Transform/Annotations.hs | 3 +- .../src/DA/Daml/Doc/Transform/Instances.hs | 1 + .../damlc/daml-doc/src/DA/Daml/Doc/Types.hs | 8 + .../daml-doc/test/DA/Daml/Doc/Render/Tests.hs | 15 +- .../damlc/daml-doc/test/DA/Daml/Doc/Tests.hs | 1 + .../daml-test-files/Interface.EXPECTED.md | 42 +++++- .../daml-test-files/Interface.EXPECTED.rst | 73 +++++++++- 10 files changed, 235 insertions(+), 60 deletions(-) diff --git a/compiler/damlc/daml-doc/src/DA/Daml/Doc/Extract.hs b/compiler/damlc/daml-doc/src/DA/Daml/Doc/Extract.hs index 42adca1659..f84a98006f 100644 --- a/compiler/damlc/daml-doc/src/DA/Daml/Doc/Extract.hs +++ b/compiler/damlc/daml-doc/src/DA/Daml/Doc/Extract.hs @@ -92,6 +92,7 @@ extractDocs extractOpts diagsLogger ideOpts fp = do md_anchor = Just (moduleAnchor md_name) md_descr = modDoc tcmod md_templates = getTemplateDocs ctx typeMap templateInstanceClassMap + md_interfaces = getInterfaceDocs ctx typeMap md_functions = mapMaybe (getFctDocs ctx) dc_decls md_instances = map (getInstanceDocs ctx) dc_insts diff --git a/compiler/damlc/daml-doc/src/DA/Daml/Doc/Extract/Templates.hs b/compiler/damlc/daml-doc/src/DA/Daml/Doc/Extract/Templates.hs index d223bfbcff..6d9a7dcb84 100644 --- a/compiler/damlc/daml-doc/src/DA/Daml/Doc/Extract/Templates.hs +++ b/compiler/damlc/daml-doc/src/DA/Daml/Doc/Extract/Templates.hs @@ -5,6 +5,7 @@ module DA.Daml.Doc.Extract.Templates ( getTemplateDocs , getTemplateData , getInstanceDocs + , getInterfaceDocs , stripInstanceSuffix ) where @@ -45,49 +46,35 @@ getTemplateDocs DocCtx{..} typeMap templateInstanceMap = , td_descr = ad_descr tmplADT , td_payload = getFields tmplADT -- assumes exactly one record constructor (syntactic, template syntax) - , td_choices = map mkChoiceDoc choices + , td_choices = map (mkChoiceDoc typeMap) choices -- is filled via distributeInstanceDocs , td_impls = [] } where - tmplADT = asADT name + tmplADT = asADT typeMap name choices = Set.toList . fromMaybe Set.empty $ MS.lookup name dc_choices - mkChoiceDoc :: Typename -> ChoiceDoc - mkChoiceDoc name = ChoiceDoc - { cd_name = ad_name choiceADT - , cd_descr = ad_descr choiceADT - -- assumes exactly one constructor (syntactic in the template syntax), or - -- uses a dummy value otherwise. - , cd_fields = getFields choiceADT + +-- | Build interface docs up from class docs. +getInterfaceDocs :: DocCtx + -> MS.Map Typename ADTDoc -- ^ maps template names to their ADT docs + -> [InterfaceDoc] +getInterfaceDocs DocCtx{..} typeMap = + map mkInterfaceDoc $ Set.toList dc_interfaces + where + -- The following functions use the type map and choice map in scope, so + -- defined internally, and not expected to fail on consistent arguments. + mkInterfaceDoc :: Typename -> InterfaceDoc + mkInterfaceDoc name = InterfaceDoc + { if_anchor = ad_anchor ifADT + , if_name = ad_name ifADT + , if_descr = ad_descr ifADT + , if_choices = map (mkChoiceDoc typeMap) choices + , if_methods = [] -- TODO (drsk) https://github.com/digital-asset/daml/issues/11347 } - where choiceADT = asADT name - - asADT n = fromMaybe dummyDT $ - MS.lookup n typeMap - -- returns a dummy ADT if the choice argument is not in the local type map - -- (possible if choice instances are defined directly outside the template). - -- This wouldn't be necessary if we used the type-checked AST. - where dummyDT = ADTDoc { ad_anchor = Nothing - , ad_name = dummyName n - , ad_descr = Nothing - , ad_args = [] - , ad_constrs = [] - , ad_instances = Nothing - } - - dummyName (Typename "Archive") = Typename "Archive" - dummyName (Typename t) = Typename $ "External:" <> t - - -- Assuming one constructor (record or prefix), extract the fields, if any. - -- For choices without arguments, GHC returns a prefix constructor, so we - -- need to cater for this case specially. - getFields adt = case ad_constrs adt of - [PrefixC{}] -> [] - [RecordC{ ac_fields = fields }] -> fields - [] -> [] -- catching the dummy case here, see above - _other -> error "getFields: found multiple constructors" - + where + ifADT = asADT typeMap name + choices = Set.toList . fromMaybe Set.empty $ MS.lookup name dc_choices -- | Extracts all names of templates defined in a module, -- and a map of template names to its set of choices @@ -103,7 +90,8 @@ getTemplateData ParsedModule{..} = interfaces = mapMaybe isInterface dataDs choiceMap = MS.fromListWith (<>) $ map (second Set.singleton) $ - mapMaybe isChoice instDs + mapMaybe isChoice instDs ++ + mapMaybe isIfaceChoice instDs in (Set.fromList templates, Set.fromList interfaces, choiceMap) where @@ -137,7 +125,11 @@ isChoice :: ClsInstDecl GhcPs -> Maybe (Typename, Typename) isChoice (XClsInstDecl _) = Nothing isChoice ClsInstDecl{..} | L _ ty <- getLHsInstDeclHead cid_poly_ty - , HsAppTy _ (L _ cApp1) (L _ _cArgs) <- ty + = isChoiceTy ty + +isChoiceTy :: HsType GhcPs -> Maybe (Typename, Typename) +isChoiceTy ty + | HsAppTy _ (L _ cApp1) (L _ _cArgs) <- ty , HsAppTy _ (L _ cApp2) cName <- cApp1 , HsAppTy _ (L _ choice) cTmpl <- cApp2 , HsTyVar _ _ (L _ choiceClass) <- choice @@ -150,6 +142,34 @@ isChoice ClsInstDecl{..} | otherwise = Nothing +-- | If the given instance declaration is declaring an interface choice instance, return interface +-- name and choice name. +isIfaceChoice :: ClsInstDecl GhcPs -> Maybe (Typename, Typename) +isIfaceChoice (XClsInstDecl _) = Nothing +isIfaceChoice decl@ClsInstDecl{} + | Just (ifaceName, ty) <- hasImplementsConstraint decl + , Just (_templ, choiceName) <- isChoiceTy ty + = Just (Typename . packRdrName $ ifaceName, choiceName) + + | otherwise = Nothing + +-- | Matches on a DA.Internal.Desugar.Implements interface constraint in the context of the instance +-- declaration. Returns the interface name and the body of the instance in case the constraint is +-- present, else nothing. +hasImplementsConstraint :: ClsInstDecl GhcPs -> Maybe (RdrName, HsType GhcPs) +hasImplementsConstraint (XClsInstDecl _) = Nothing +hasImplementsConstraint ClsInstDecl{..} + | (L _ [L _ ctx], L _ ty) <- splitLHsQualTy $ hsSigType cid_poly_ty + , HsParTy _ (L _ (HsAppTy _ (L _ app1) (L _ iface))) <- ctx + , HsTyVar _ _ (L _ ifaceName) <- iface + , HsAppTy _ (L _ impl) (L _ _t) <- app1 + , HsTyVar _ _ (L _ implCls) <- impl + , Qual implClsModule implClassOcc <- implCls + , moduleNameString implClsModule == "DA.Internal.Desugar" + , occNameString implClassOcc == "Implements" + = Just (ifaceName, ty) + | otherwise = Nothing + -- | Strip the @Instance@ suffix off of a typename, if it's there. -- Otherwise returns 'Nothing'. stripInstanceSuffix :: Typename -> Maybe Typename @@ -167,3 +187,44 @@ getInstanceDocs ctx ClsInst{..} = , id_type = typeToType ctx ty , id_isOrphan = isOrphan is_orphan } + +-- Utilities common to templates and interfaces +----------------------------------------------- + +-- | Create an ADT from a Typename +asADT :: MS.Map Typename ADTDoc -> Typename -> ADTDoc +asADT typeMap n = fromMaybe dummyDT $ MS.lookup n typeMap + where + dummyDT = + ADTDoc + { ad_anchor = Nothing + , ad_name = dummyName n + , ad_descr = Nothing + , ad_args = [] + , ad_constrs = [] + , ad_instances = Nothing + } + dummyName (Typename "Archive") = Typename "Archive" + dummyName (Typename t) = Typename $ "External:" <> t + +-- | Assuming one constructor (record or prefix), extract the fields, if any. For choices without +-- arguments, GHC returns a prefix constructor, so we need to cater for this case specially. +getFields :: ADTDoc -> [FieldDoc] +getFields adt = + case ad_constrs adt of + [PrefixC {}] -> [] + [RecordC {ac_fields = fields}] -> fields + [] -> [] -- catching the dummy case here, see above + _other -> error "getFields: found multiple constructors" + +mkChoiceDoc :: MS.Map Typename ADTDoc -> Typename -> ChoiceDoc +mkChoiceDoc typeMap name = + ChoiceDoc + { cd_name = ad_name choiceADT + , cd_descr = ad_descr choiceADT + -- assumes exactly one constructor (syntactic in the template syntax), or + -- uses a dummy value otherwise. + , cd_fields = getFields choiceADT + } + where + choiceADT = asADT typeMap name diff --git a/compiler/damlc/daml-doc/src/DA/Daml/Doc/Render/Output.hs b/compiler/damlc/daml-doc/src/DA/Daml/Doc/Render/Output.hs index f3eaee2c22..7aed29e240 100644 --- a/compiler/damlc/daml-doc/src/DA/Daml/Doc/Render/Output.hs +++ b/compiler/damlc/daml-doc/src/DA/Daml/Doc/Render/Output.hs @@ -41,6 +41,7 @@ instance RenderDoc ModuleDoc where , RenderModuleHeader ("Module " <> unModulename md_name) , renderDoc md_descr , section "Templates" md_templates + , section "Interfaces" md_interfaces , section "Typeclasses" md_classes , section "Orphan Typeclass Instances" (filter id_isOrphan md_instances) , section "Data Types" md_adts @@ -82,6 +83,19 @@ instance RenderDoc TemplateDoc where ] ] +instance RenderDoc InterfaceDoc where + renderDoc InterfaceDoc{..} = mconcat + [ renderDoc if_anchor + , RenderParagraph . renderUnwords . concat $ + [ [RenderStrong "interface"] + , [maybeAnchorLink if_anchor (unTypename if_name)] + ] + , RenderBlock $ mconcat + [ renderDoc if_descr + , RenderList (map renderDoc if_choices) + ] + ] + instance RenderDoc ImplDoc where renderDoc ImplDoc {..} = RenderParagraph $ diff --git a/compiler/damlc/daml-doc/src/DA/Daml/Doc/Transform/Annotations.hs b/compiler/damlc/daml-doc/src/DA/Daml/Doc/Transform/Annotations.hs index 64523fc341..63146ec995 100644 --- a/compiler/damlc/daml-doc/src/DA/Daml/Doc/Transform/Annotations.hs +++ b/compiler/damlc/daml-doc/src/DA/Daml/Doc/Transform/Annotations.hs @@ -49,7 +49,8 @@ applyMove -- module description. , md_adts = md_adts m1 ++ md_adts m2 , md_functions = md_functions m1 ++ md_functions m2 - , md_templates = md_templates m2 ++ md_templates m2 + , md_templates = md_templates m1 ++ md_templates m2 + , md_interfaces = md_interfaces m1 ++ md_interfaces m2 , md_classes = md_classes m1 ++ md_classes m2 , md_instances = md_instances m1 ++ md_instances m2 } diff --git a/compiler/damlc/daml-doc/src/DA/Daml/Doc/Transform/Instances.hs b/compiler/damlc/daml-doc/src/DA/Daml/Doc/Transform/Instances.hs index c23a927b8a..791262fe00 100644 --- a/compiler/damlc/daml-doc/src/DA/Daml/Doc/Transform/Instances.hs +++ b/compiler/damlc/daml-doc/src/DA/Daml/Doc/Transform/Instances.hs @@ -55,6 +55,7 @@ distributeInstanceDocs opts docs = , md_descr = md_descr , md_functions = md_functions , md_templates = map (addIfaceImpls imap) md_templates + , md_interfaces = md_interfaces , md_classes = map (addClassInstances imap) md_classes , md_adts = map (addTypeInstances imap) md_adts , md_instances = diff --git a/compiler/damlc/daml-doc/src/DA/Daml/Doc/Types.hs b/compiler/damlc/daml-doc/src/DA/Daml/Doc/Types.hs index 05df3b1be8..2c850fc4d7 100644 --- a/compiler/damlc/daml-doc/src/DA/Daml/Doc/Types.hs +++ b/compiler/damlc/daml-doc/src/DA/Daml/Doc/Types.hs @@ -94,6 +94,7 @@ data ModuleDoc = ModuleDoc , md_name :: Modulename , md_descr :: Maybe DocText , md_templates :: [TemplateDoc] + , md_interfaces :: [InterfaceDoc] , md_adts :: [ADTDoc] , md_functions :: [FunctionDoc] , md_classes :: [ClassDoc] @@ -125,6 +126,7 @@ data InterfaceDoc = InterfaceDoc , if_methods :: [ClassMethodDoc] , if_descr :: Maybe DocText } + deriving (Eq, Show, Generic) data ImplDoc = ImplDoc { impl_iface :: Type @@ -327,6 +329,12 @@ instance ToJSON TemplateDoc where instance FromJSON TemplateDoc where parseJSON = genericParseJSON aesonOptions +instance ToJSON InterfaceDoc where + toJSON = genericToJSON aesonOptions + +instance FromJSON InterfaceDoc where + parseJSON = genericParseJSON aesonOptions + instance ToJSON InstanceDoc where toJSON = genericToJSON aesonOptions diff --git a/compiler/damlc/daml-doc/test/DA/Daml/Doc/Render/Tests.hs b/compiler/damlc/daml-doc/test/DA/Daml/Doc/Render/Tests.hs index 63c97ea2d6..2e9b963cb8 100644 --- a/compiler/damlc/daml-doc/test/DA/Daml/Doc/Render/Tests.hs +++ b/compiler/damlc/daml-doc/test/DA/Daml/Doc/Render/Tests.hs @@ -28,29 +28,29 @@ mkTestTree externalAnchors = do cases :: [(String, ModuleDoc)] cases = [ ("Empty module", - ModuleDoc Nothing "Empty" Nothing [] [] [] [] []) + ModuleDoc Nothing "Empty" Nothing [] [] [] [] [] []) , ("Type def with argument", - ModuleDoc (Just "module-typedef") "Typedef" Nothing [] + ModuleDoc (Just "module-typedef") "Typedef" Nothing [] [] [TypeSynDoc (Just "type-typedef-t") "T" (Just "T descr") ["a"] (TypeApp Nothing "TT" [TypeApp Nothing "TTT" []]) Nothing] [] [] [] ) , ("Two types", - ModuleDoc (Just "module-twotypes") "TwoTypes" Nothing [] + ModuleDoc (Just "module-twotypes") "TwoTypes" Nothing [] [] [ TypeSynDoc (Just "type-twotypes-t") "T" (Just "T descr") ["a"] (TypeApp Nothing "TT" []) Nothing , ADTDoc (Just "data-twotypes-d") "D" Nothing ["d"] [PrefixC (Just "constr-twotypes-d") "D" (Just "D descr") [TypeApp Nothing "a" []]] Nothing ] [] [] [] ) , ("Documented function", - ModuleDoc (Just "module-function1") "Function1" Nothing [] [] + ModuleDoc (Just "module-function1") "Function1" Nothing [] [] [] [FunctionDoc (Just "function-function1-f") "f" Nothing (TypeApp Nothing "TheType" []) (Just "the doc")] [] [] ) , ("Undocumented function", - ModuleDoc (Just "module-function3") "Function3" Nothing [] [] + ModuleDoc (Just "module-function3") "Function3" Nothing [] [] [] [FunctionDoc (Just "function-function3-f") "f" Nothing (TypeApp Nothing "TheType" []) Nothing] [] [] ) , ("Module with only a type class", - ModuleDoc (Just "module-onlyclass") "OnlyClass" Nothing [] [] [] + ModuleDoc (Just "module-onlyclass") "OnlyClass" Nothing [] [] [] [] [ClassDoc (Just "class-onlyclass-c") "C" Nothing Nothing ["a"] [ClassMethodDoc (Just "function-onlyclass-member") "member" False Nothing Nothing (TypeApp Nothing "a" []) Nothing] Nothing] []) , ("Multiline field description", ModuleDoc @@ -58,6 +58,7 @@ cases = [ ("Empty module", "MultiLineField" Nothing [] + [] [ADTDoc (Just "data-multilinefield-d") "D" @@ -72,7 +73,7 @@ cases = [ ("Empty module", , ("Functions with context", ModuleDoc (Just "module-functionctx") "FunctionCtx" - Nothing [] [] + Nothing [] [] [] [ FunctionDoc (Just "function-g") "g" (Just $ TypeTuple [TypeApp Nothing "Eq" [TypeApp Nothing "t" []]]) (TypeFun [TypeApp Nothing "t" [], TypeApp Nothing "Bool" []]) diff --git a/compiler/damlc/daml-doc/test/DA/Daml/Doc/Tests.hs b/compiler/damlc/daml-doc/test/DA/Daml/Doc/Tests.hs index b5133d8d7e..7866e9e75b 100644 --- a/compiler/damlc/daml-doc/test/DA/Daml/Doc/Tests.hs +++ b/compiler/damlc/daml-doc/test/DA/Daml/Doc/Tests.hs @@ -251,6 +251,7 @@ emptyDocs name = md_functions = [] md_classes = [] md_instances = [] + md_interfaces = [] in ModuleDoc {..} -- | Compiles the given input string (in a tmp file) and checks generated doc.s diff --git a/compiler/damlc/tests/daml-test-files/Interface.EXPECTED.md b/compiler/damlc/tests/daml-test-files/Interface.EXPECTED.md index 3927d3439f..6372045ecf 100644 --- a/compiler/damlc/tests/daml-test-files/Interface.EXPECTED.md +++ b/compiler/damlc/tests/daml-test-files/Interface.EXPECTED.md @@ -14,30 +14,58 @@ > > (no fields) -> * **implements** Token +> * **implements** [Token](#type-interface-token-72202) + +## Interfaces + +**interface** [Token](#type-interface-token-72202) + +> * **Choice GetRich** +> +> | Field | Type | Description | +> | :----------------------------------------------------------------------------- | :----------------------------------------------------------------------------- | :---------- | +> | byHowMuch | [Int](https://docs.daml.com/daml/stdlib/Prelude.html#type-ghc-types-int-68728) | | +> +> * **Choice Noop** +> +> | Field | Type | Description | +> | :------ | :------ | :---------- | +> | nothing | () | | +> +> * **Choice Split** +> +> | Field | Type | Description | +> | :----------------------------------------------------------------------------- | :----------------------------------------------------------------------------- | :---------- | +> | splitAmount | [Int](https://docs.daml.com/daml/stdlib/Prelude.html#type-ghc-types-int-68728) | | +> +> * **Choice Transfer** +> +> | Field | Type | Description | +> | :-------------------------------------------------------------------------------------- | :-------------------------------------------------------------------------------------- | :---------- | +> | newOwner | [Party](https://docs.daml.com/daml/stdlib/Prelude.html#type-da-internal-lf-party-50311) | | ## Functions [noopImpl](#function-interface-noopimpl-83220) -> : Implements t Token =\> t -\> () -\> [Update](https://docs.daml.com/daml/stdlib/Prelude.html#type-da-internal-lf-update-36457) () +> : Implements t [Token](#type-interface-token-72202) =\> t -\> () -\> [Update](https://docs.daml.com/daml/stdlib/Prelude.html#type-da-internal-lf-update-36457) () [transferImpl](#function-interface-transferimpl-81005) -> : Implements t Token =\> t -\> [Party](https://docs.daml.com/daml/stdlib/Prelude.html#type-da-internal-lf-party-50311) -\> [Update](https://docs.daml.com/daml/stdlib/Prelude.html#type-da-internal-lf-update-36457) ([ContractId](https://docs.daml.com/daml/stdlib/Prelude.html#type-da-internal-lf-contractid-47171) Token) +> : Implements t [Token](#type-interface-token-72202) =\> t -\> [Party](https://docs.daml.com/daml/stdlib/Prelude.html#type-da-internal-lf-party-50311) -\> [Update](https://docs.daml.com/daml/stdlib/Prelude.html#type-da-internal-lf-update-36457) ([ContractId](https://docs.daml.com/daml/stdlib/Prelude.html#type-da-internal-lf-contractid-47171) [Token](#type-interface-token-72202)) [splitImpl](#function-interface-splitimpl-48531) -> : Implements t Token =\> t -\> [Int](https://docs.daml.com/daml/stdlib/Prelude.html#type-ghc-types-int-68728) -\> [Update](https://docs.daml.com/daml/stdlib/Prelude.html#type-da-internal-lf-update-36457) ([ContractId](https://docs.daml.com/daml/stdlib/Prelude.html#type-da-internal-lf-contractid-47171) Token, [ContractId](https://docs.daml.com/daml/stdlib/Prelude.html#type-da-internal-lf-contractid-47171) Token) +> : Implements t [Token](#type-interface-token-72202) =\> t -\> [Int](https://docs.daml.com/daml/stdlib/Prelude.html#type-ghc-types-int-68728) -\> [Update](https://docs.daml.com/daml/stdlib/Prelude.html#type-da-internal-lf-update-36457) ([ContractId](https://docs.daml.com/daml/stdlib/Prelude.html#type-da-internal-lf-contractid-47171) [Token](#type-interface-token-72202), [ContractId](https://docs.daml.com/daml/stdlib/Prelude.html#type-da-internal-lf-contractid-47171) [Token](#type-interface-token-72202)) [setAmount](#function-interface-setamount-71357) -> : Implements t Token =\> t -\> [Int](https://docs.daml.com/daml/stdlib/Prelude.html#type-ghc-types-int-68728) -\> Token +> : Implements t [Token](#type-interface-token-72202) =\> t -\> [Int](https://docs.daml.com/daml/stdlib/Prelude.html#type-ghc-types-int-68728) -\> [Token](#type-interface-token-72202) [getAmount](#function-interface-getamount-93321) -> : Implements t Token =\> t -\> [Int](https://docs.daml.com/daml/stdlib/Prelude.html#type-ghc-types-int-68728) +> : Implements t [Token](#type-interface-token-72202) =\> t -\> [Int](https://docs.daml.com/daml/stdlib/Prelude.html#type-ghc-types-int-68728) [getOwner](#function-interface-getowner-9315) -> : Implements t Token =\> t -\> [Party](https://docs.daml.com/daml/stdlib/Prelude.html#type-da-internal-lf-party-50311) +> : Implements t [Token](#type-interface-token-72202) =\> t -\> [Party](https://docs.daml.com/daml/stdlib/Prelude.html#type-da-internal-lf-party-50311) diff --git a/compiler/damlc/tests/daml-test-files/Interface.EXPECTED.rst b/compiler/damlc/tests/daml-test-files/Interface.EXPECTED.rst index f967176aeb..faac12b6ca 100644 --- a/compiler/damlc/tests/daml-test-files/Interface.EXPECTED.rst +++ b/compiler/damlc/tests/daml-test-files/Interface.EXPECTED.rst @@ -30,7 +30,66 @@ Templates + **Choice Archive** - + **implements** Token + + **implements** `Token `_ + +Interfaces +^^^^^^^^^^ + +.. _type-interface-token-72202: + +**interface** `Token `_ + + + **Choice GetRich** + + .. list-table:: + :widths: 15 10 30 + :header-rows: 1 + + * - Field + - Type + - Description + * - byHowMuch + - `Int `_ + - + + + **Choice Noop** + + .. list-table:: + :widths: 15 10 30 + :header-rows: 1 + + * - Field + - Type + - Description + * - nothing + - () + - + + + **Choice Split** + + .. list-table:: + :widths: 15 10 30 + :header-rows: 1 + + * - Field + - Type + - Description + * - splitAmount + - `Int `_ + - + + + **Choice Transfer** + + .. list-table:: + :widths: 15 10 30 + :header-rows: 1 + + * - Field + - Type + - Description + * - newOwner + - `Party `_ + - Functions ^^^^^^^^^ @@ -38,29 +97,29 @@ Functions .. _function-interface-noopimpl-83220: `noopImpl `_ - \: Implements t Token \=\> t \-\> () \-\> `Update `_ () + \: Implements t `Token `_ \=\> t \-\> () \-\> `Update `_ () .. _function-interface-transferimpl-81005: `transferImpl `_ - \: Implements t Token \=\> t \-\> `Party `_ \-\> `Update `_ (`ContractId `_ Token) + \: Implements t `Token `_ \=\> t \-\> `Party `_ \-\> `Update `_ (`ContractId `_ `Token `_) .. _function-interface-splitimpl-48531: `splitImpl `_ - \: Implements t Token \=\> t \-\> `Int `_ \-\> `Update `_ (`ContractId `_ Token, `ContractId `_ Token) + \: Implements t `Token `_ \=\> t \-\> `Int `_ \-\> `Update `_ (`ContractId `_ `Token `_, `ContractId `_ `Token `_) .. _function-interface-setamount-71357: `setAmount `_ - \: Implements t Token \=\> t \-\> `Int `_ \-\> Token + \: Implements t `Token `_ \=\> t \-\> `Int `_ \-\> `Token `_ .. _function-interface-getamount-93321: `getAmount `_ - \: Implements t Token \=\> t \-\> `Int `_ + \: Implements t `Token `_ \=\> t \-\> `Int `_ .. _function-interface-getowner-9315: `getOwner `_ - \: Implements t Token \=\> t \-\> `Party `_ + \: Implements t `Token `_ \=\> t \-\> `Party `_