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
This commit is contained in:
Robin Krom 2021-12-07 06:49:42 +01:00 committed by GitHub
parent 9430ee3131
commit 299027b4b9
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
10 changed files with 235 additions and 60 deletions

View File

@ -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

View File

@ -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

View File

@ -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 $

View File

@ -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
}

View File

@ -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 =

View File

@ -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

View File

@ -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" []])

View File

@ -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

View File

@ -14,30 +14,58 @@
>
> (no fields)
> * **implements** Token
> * **implements** [Token](#type-interface-token-72202)
## Interfaces
<a name="type-interface-token-72202"></a>**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
<a name="function-interface-noopimpl-83220"></a>[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) ()
<a name="function-interface-transferimpl-81005"></a>[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))
<a name="function-interface-splitimpl-48531"></a>[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))
<a name="function-interface-setamount-71357"></a>[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)
<a name="function-interface-getamount-93321"></a>[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)
<a name="function-interface-getowner-9315"></a>[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)

View File

@ -30,7 +30,66 @@ Templates
+ **Choice Archive**
+ **implements** Token
+ **implements** `Token <type-interface-token-72202_>`_
Interfaces
^^^^^^^^^^
.. _type-interface-token-72202:
**interface** `Token <type-interface-token-72202_>`_
+ **Choice GetRich**
.. list-table::
:widths: 15 10 30
:header-rows: 1
* - Field
- Type
- Description
* - byHowMuch
- `Int <https://docs.daml.com/daml/stdlib/Prelude.html#type-ghc-types-int-68728>`_
-
+ **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 <https://docs.daml.com/daml/stdlib/Prelude.html#type-ghc-types-int-68728>`_
-
+ **Choice Transfer**
.. list-table::
:widths: 15 10 30
:header-rows: 1
* - Field
- Type
- Description
* - newOwner
- `Party <https://docs.daml.com/daml/stdlib/Prelude.html#type-da-internal-lf-party-50311>`_
-
Functions
^^^^^^^^^
@ -38,29 +97,29 @@ Functions
.. _function-interface-noopimpl-83220:
`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>`_ ()
.. _function-interface-transferimpl-81005:
`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_>`_)
.. _function-interface-splitimpl-48531:
`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_>`_)
.. _function-interface-setamount-71357:
`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_>`_
.. _function-interface-getamount-93321:
`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>`_
.. _function-interface-getowner-9315:
`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>`_